Something went wrong on our end
'''
Created on 1 févr. 2014
@author: inso
'''
from ucoinpy import PROTOCOL_VERSION
from ucoinpy.api import bma
from ucoinpy.api.bma import ConnectionHandler
from ucoinpy.documents.peer import Peer
from ucoinpy.documents.certification import SelfCertification, Certification
from ucoinpy.documents.membership import Membership
from ucoinpy.key import SigningKey
import logging
import time
from PyQt5.QtCore import QObject, pyqtSignal, Qt
from .wallet import Wallet
from .community import Community
from .person import Person
from ..tools.exceptions import NoPeerAvailable, ContactAlreadyExists
def quantitative(units, community):
return int(units)
def relative(units, community):
ud = community.dividend
relative_value = units / float(ud)
return relative_value
def quantitative_zerosum(units, community):
median = community.monetary_mass / community.nb_members
return units - median
def relative_zerosum(units, community):
median = community.monetary_mass / community.nb_members
ud = community.dividend
relative_value = units / float(ud)
relative_median = median / ud
return relative_value - relative_median
class Account(QObject):
'''
An account is specific to a key.
Each account has only one key, and a key can
be locally referenced by only one account.
'''
referentials = {'Units': (quantitative, '{0}', quantitative, '{0}'),
'UD': (relative, 'ud {0}', relative, 'ud {0}'),
'Quant Z-sum': (quantitative_zerosum, 'q0 {0}',
quantitative, '{0}'),
'Relat Z-sum': (relative_zerosum, 'r0 {0}',
relative, 'ud {0}')
}
loading_progressed = pyqtSignal(int, int)
def __init__(self, salt, pubkey, name, communities, wallets, contacts,
dead_communities):
'''
Constructor
'''
super().__init__()
self.salt = salt
self.pubkey = pubkey
self.name = name
self.communities = communities
self.dead_communities = dead_communities
self.wallets = wallets
self.contacts = contacts
self.referential = 'Units'
@classmethod
def create(cls, name, communities, wallets, confpath):
'''
Constructor
'''
account = cls(None, None, name, communities, wallets, [], [])
return account
@classmethod
def load(cls, json_data):
salt = json_data['salt']
pubkey = json_data['pubkey']
name = json_data['name']
contacts = []
for contact_data in json_data['contacts']:
contacts.append(Person.from_json(contact_data))
wallets = []
for data in json_data['wallets']:
wallets.append(Wallet.load(data))
communities = []
dead_communities = []
for data in json_data['communities']:
community = Community.load(data)
communities.append(community)
account = cls(salt, pubkey, name, communities, wallets,
contacts, dead_communities)
return account
def __eq__(self, other):
if other is not None:
return other.pubkey == self.pubkey
else:
return False
def check_password(self, password):
key = SigningKey(self.salt, password)
return (key.pubkey == self.pubkey)
def add_contact(self, person):
same_contact = [contact for contact in self.contacts
if person.pubkey == contact.pubkey]
if len(same_contact) > 0:
raise ContactAlreadyExists(person.uid, same_contact[0].uid)
self.contacts.append(person)
def add_community(self, community):
logging.debug("Adding a community")
self.communities.append(community)
return community
def refresh_cache(self):
loaded_wallets = 0
def progressing(value, maximum):
account_value = maximum * len(self.communities) * loaded_wallets + value
account_max = maximum * len(self.communities) * len(self.wallets)
self.loading_progressed.emit(account_value, account_max)
for w in self.wallets:
w.refresh_progressed.connect(progressing, type=Qt.DirectConnection)
for c in self.communities:
w.refresh_cache(c)
loaded_wallets = loaded_wallets + 1
def set_display_referential(self, index):
self.referential = index
@property
def units_to_ref(self):
return Account.referentials[self.referential][0]
@property
def units_to_diff_ref(self):
return Account.referentials[self.referential][2]
def ref_name(self, currency):
return Account.referentials[self.referential][1].format(currency)
def diff_ref_name(self, currency):
return Account.referentials[self.referential][3].format(currency)
def set_walletpool_size(self, size, password):
logging.debug("Defining wallet pool size")
if len(self.wallets) < size:
for i in range(len(self.wallets), size):
wallet = Wallet.create(i, self.salt, password, "Wallet {0}".format(i))
self.wallets.append(wallet)
else:
self.wallets = self.wallets[:size]
def certify(self, password, community, pubkey):
certified = Person.lookup(pubkey, community)
blockid = community.current_blockid()
certification = Certification(PROTOCOL_VERSION, community.currency,
self.pubkey, certified.pubkey,
blockid['number'], blockid['hash'], None)
selfcert = certified.selfcert(community)
logging.debug("SelfCertification : {0}".format(selfcert.raw()))
key = SigningKey(self.salt, password)
certification.sign(selfcert, [key])
signed_cert = certification.signed_raw(selfcert)
logging.debug("Certification : {0}".format(signed_cert))
data = {'pubkey': certified.pubkey,
'self_': selfcert.signed_raw(),
'other': "{0}\n".format(certification.inline())}
logging.debug("Posted data : {0}".format(data))
community.broadcast(bma.wot.Add, {}, data)
def sources(self, community):
sources = []
for w in self.wallets:
for s in w.sources(community):
sources.append(s)
return sources
def transfers(self, community):
sent = []
for w in self.wallets:
for transfer in w.transfers(community):
sent.append(transfer)
return sent
def amount(self, community):
value = 0
for w in self.wallets:
value += w.value(community)
return value
def member_of(self, community):
pubkeys = community.members_pubkeys()
if self.pubkey not in pubkeys:
logging.debug("{0} not found in members : {1}".format(self.pubkey,
pubkeys))
return False
return True
def send_pubkey(self, password, community):
selfcert = SelfCertification(PROTOCOL_VERSION,
community.currency,
self.pubkey,
int(time.time()),
self.name,
None)
key = SigningKey(self.salt, password)
selfcert.sign([key])
logging.debug("Key publish : {0}".format(selfcert.signed_raw()))
community.broadcast(bma.wot.Add, {}, {'pubkey': self.pubkey,
'self_': selfcert.signed_raw(),
'other': []})
def send_membership(self, password, community, type):
self_ = Person.lookup(self.pubkey, community)
selfcert = self_.selfcert(community)
blockid = community.current_blockid()
membership = Membership(PROTOCOL_VERSION, community.currency,
selfcert.pubkey, blockid['number'],
blockid['hash'], type, selfcert.uid,
selfcert.timestamp, None)
key = SigningKey(self.salt, password)
membership.sign([key])
logging.debug("Membership : {0}".format(membership.signed_raw()))
community.broadcast(bma.blockchain.Membership, {},
{'membership': membership.signed_raw()})
def jsonify(self):
data_communities = []
communities = self.communities + self.dead_communities
for c in communities:
data_communities.append(c.jsonify())
data_wallets = []
for w in self.wallets:
data_wallets.append(w.jsonify())
data_contacts = []
for p in self.contacts:
data_contacts.append(p.jsonify())
data = {'name': self.name,
'salt': self.salt,
'pubkey': self.pubkey,
'communities': data_communities,
'wallets': data_wallets,
'contacts': data_contacts}
return data
def get_person(self):
return Person(self.name, self.pubkey)