def validate_uncles(self): if utils.sha3(rlp.encode(self.uncles)) != self.uncles_hash: return False # Check uncle validity ancestor_chain = [self] # Uncle can have a block from 2-7 blocks ago as its parent for i in [1, 2, 3, 4, 5, 6, 7]: if ancestor_chain[-1].number > 0: ancestor_chain.append(ancestor_chain[-1].get_parent()) ineligible = [] # Uncles of this block cannot be direct ancestors and cannot also # be uncles included 1-6 blocks ago for ancestor in ancestor_chain[1:]: ineligible.extend(ancestor.uncles) ineligible.extend([b.list_header() for b in ancestor_chain]) eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]] for uncle in self.uncles: if not check_header_pow(uncle): return False # uncle's parent cannot be the block's own parent prevhash = uncle[block_structure_rev['prevhash'][0]] if prevhash not in eligible_ancestor_hashes: logger.debug("%r: Uncle does not have a valid ancestor", self) return False if uncle in ineligible: logger.debug("%r: Duplicate uncle %r", self, utils.sha3(rlp.encode(uncle)).encode('hex')) return False ineligible.append(uncle) return True
def check_header_pow(header): assert len(header[-1]) == 32 rlp_Hn = rlp.encode(header[:-1]) nonce = header[-1] diff = utils.decoders['int'](header[block_structure_rev['difficulty'][0]]) h = utils.sha3(utils.sha3(rlp_Hn) + nonce) return utils.big_endian_to_int(h) < 2 ** 256 / diff
def mine(self, steps=1000): """ It is formally defined as PoW: PoW(H, n) = BE(SHA3(SHA3(RLP(Hn)) o n)) where: RLP(Hn) is the RLP encoding of the block header H, not including the final nonce component; SHA3 is the SHA3 hash function accepting an arbitrary length series of bytes and evaluating to a series of 32 bytes (i.e. 256-bit); n is the nonce, a series of 32 bytes; o is the series concatenation operator; BE(X) evaluates to the value equal to X when interpreted as a big-endian-encoded integer. """ nonce_bin_prefix = '\x00' * (32 - len(struct.pack('>q', 0))) target = 2 ** 256 / self.block.difficulty rlp_Hn = self.block.serialize_header_without_nonce() for nonce in range(self.nonce, self.nonce + steps): nonce_bin = nonce_bin_prefix + struct.pack('>q', nonce) # BE(SHA3(SHA3(RLP(Hn)) o n)) h = utils.sha3(utils.sha3(rlp_Hn) + nonce_bin) l256 = utils.big_endian_to_int(h) if l256 < target: self.block.nonce = nonce_bin assert self.block.check_proof_of_work(self.block.nonce) is True assert self.block.get_parent() logger.debug( 'Nonce found %d %r', nonce, self.block) return self.block self.nonce = nonce return False
def check_proof_of_work(self, nonce): assert len(nonce) == 32 rlp_Hn = self.serialize_header_without_nonce() # BE(SHA3(SHA3(RLP(Hn)) o n)) h = utils.sha3(utils.sha3(rlp_Hn) + nonce) l256 = utils.big_endian_to_int(h) return l256 < 2 ** 256 / self.difficulty
def create_contract(block,tx,msg): oldroot = block.state.root senderstate = block.state.get(msg.sender) or ['','','',''] recvstate = ['','',sha3(msg.data),''] recvaddr = sha3(rlp.encode([msg.sender,senderstate[NONCE_INDEX]]))[12:] code = msg.data statedb.put(sha3(msg.data),msg.data) compustate = Compustate(gas=msg.gas) # Not enough vaue to send, instaquit if decode_int(senderstate[BALANCE_INDEX]) < msg.value: recvstate[2] = [] block.state.update(recvaddr,recvstate) return recvaddr, compustate.gas # Transfer value and update nonce senderstate[BALANCE_INDEX] = encode_int(decode_int(senderstate[BALANCE_INDEX])-msg.value) senderstate[NONCE_INDEX] = encode_int(decode_int(senderstate[NONCE_INDEX])+1) recvstate[BALANCE_INDEX] = encode_int(decode_int(senderstate[BALANCE_INDEX])+msg.value) block.state.update(msg.sender.decode('hex'),senderstate) block.state.update(recvaddr,recvstate) # Temporary pre-POC5: don't do the code/init thing return recvaddr, compustate.gas # Main loop while 1: o = apply_op(block,tx,msg,msg.data,compustate.op) if o is not None: if o == OUT_OF_GAS: block.state.root = oldroot return 0, 0 else: recvstate = block.state.get(recvaddr) recvstate[CODE_INDEX] = sha3(map(chr,o)) statedb.put(sha3(map(chr,o)),map(chr,o)) block.state.update(recvaddr,recvstate) return recvaddr, recvstate
def check_header_pow(header): assert len(header[-1]) == 32 rlp_Hn = rlp.encode(header[:-1]) nonce = header[-1] diff = utils.decoders['int'](header[block_structure_rev['difficulty'][0]]) h = utils.sha3(utils.sha3(rlp_Hn) + nonce) return utils.big_endian_to_int(h) < 2**256 / diff
def to_dict(self, with_state=False, full_transactions=False, with_storage_roots=False, with_uncles=False): """ serializes the block with_state: include state for all accounts full_transactions: include serialized tx (hashes otherwise) with_uncles: include uncle hashes """ b = {} for name, typ, default in block_structure: b[name] = utils.printers[typ](getattr(self, name)) txlist = [] for i in range(self.transaction_count): tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i))) tx, msr, gas = rlp.decode(tx_rlp) if full_transactions: txjson = transactions.Transaction.create(tx).to_dict() else: txjson = utils.sha3(rlp.descend(tx_rlp, 0)).encode('hex') # tx hash txlist.append({ "tx": txjson, "medstate": msr.encode('hex'), "gas": str(utils.decode_int(gas)) }) b["transactions"] = txlist if with_state: state_dump = {} for address, v in self.state.to_dict().iteritems(): state_dump[address.encode('hex')] = \ self.account_to_dict(address, with_storage_roots) b['state'] = state_dump if with_uncles: b['uncles'] = [utils.sha3(rlp.encode(u)).encode('hex') for u in self.uncles] return b
def mk_blank_acct(self): if not hasattr(self, '_blank_acct'): codehash = utils.sha3('') self.state.db.put(utils.sha3(''), '') self._blank_acct = [utils.encode_int(0), utils.encode_int(0), trie.BLANK_ROOT, codehash] return self._blank_acct[:]
def serialize(self): txlist = [x.serialize() for x in self.transactions] header = [ encode_int(self.number), self.prevhash, sha3(rlp.encode(self.uncles)), self.coinbase.decode('hex'), self.state.root, sha3(rlp.encode(txlist)), encode_int(self.difficulty), encode_int(self.timestamp), self.extradata, encode_int(self.nonce) ] return rlp.encode([header, txlist, self.uncles])
def serialize(self): txlist = [x.serialize() for x in self.transactions] header = [encode_int(self.number), self.prevhash, sha3(rlp.encode(self.uncles)), self.coinbase.decode('hex'), self.state.root, sha3(rlp.encode(txlist)), encode_int(self.difficulty), encode_int(self.timestamp), self.extradata, encode_int(self.nonce)] return rlp.encode([header, txlist, self.uncles])
def create_contract(block,tx,msg): snapshot = block.snapshot() sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender nonce = encode_int(block.get_nonce(msg.sender)) recvaddr = sha3(rlp.encode([sender,nonce]))[12:] code = msg.data # Transfer value, instaquit if not enough block.delta_balance(recvaddr,msg.value) o = block.delta_balance(msg.sender,msg.value) if not o: return 0, msg.gas block.set_code(recvaddr,msg.data) compustate = Compustate(gas=msg.gas) # Temporary pre-POC5: don't do the code/init thing return recvaddr, compustate.gas # Main loop while 1: o = apply_op(block,tx,msg,msg.data,compustate.op) if o is not None: if o == OUT_OF_GAS: block.state.root = oldroot return 0, 0 else: block.set_code(''.join(map(chr,o))) return recvaddr, compustate.gas
def sign(self, privkey): assert not self.signature assert isinstance(privkey, bytes) and len(privkey) == 32 h = sha3(_encode_optimized(self.serialize())) self.signature = c_ecdsa_sign_compact(h, privkey) assert len(self.signature) == 65 return self
def send(self, sender, host_port, data): print 'in send unreliable', self.network.counter, self.network.counter % self.droprate if self.network.counter % self.droprate: self.network.send(sender, host_port, data) else: self.network.track_send(sender, host_port, data) print('dropped data {}'.format(pex(sha3(data))))
def validate_uncles(self): if utils.sha3rlp(self.uncles) != self.uncles_hash: return False # Check uncle validity ancestor_chain = [a for a in self.get_ancestor_list(MAX_UNCLE_DEPTH + 1) if a] ineligible = [] # Uncles of this block cannot be direct ancestors and cannot also # be uncles included 1-6 blocks ago for ancestor in ancestor_chain[1:]: ineligible.extend(ancestor.uncles) ineligible.extend([b.list_header() for b in ancestor_chain]) eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]] for uncle in self.uncles: if not check_header_pow(uncle): return False prevhash = uncle[block_structure_rev['prevhash'][0]] if prevhash not in eligible_ancestor_hashes: log.error("Uncle does not have a valid ancestor", block=self) return False if uncle in ineligible: log.error("Duplicate uncle", block=self, uncle=utils.sha3( rlp.encode(uncle)).encode('hex')) return False ineligible.append(uncle) return True
def validate_uncles(self): if utils.sha3rlp(self.uncles) != self.uncles_hash: return False # Check uncle validity ancestor_chain = self.get_ancestor_list(MAX_UNCLE_DEPTH + 1) ineligible = [] # Uncles of this block cannot be direct ancestors and cannot also # be uncles included 1-6 blocks ago for ancestor in ancestor_chain[1:]: ineligible.extend(ancestor.uncles) ineligible.extend([b.list_header() for b in ancestor_chain]) eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]] for uncle in self.uncles: if not check_header_pow(uncle): return False prevhash = uncle[block_structure_rev['prevhash'][0]] if prevhash not in eligible_ancestor_hashes: log.error("Uncle does not have a valid ancestor", block=self) return False if uncle in ineligible: log.error("Duplicate uncle", block=self, uncle=utils.sha3( rlp.encode(uncle)).encode('hex')) return False ineligible.append(uncle) return True
def remote_blocks_received_handler(sender, block_lst, peer, **kwargs): logger.debug("received %d remote blocks", len(block_lst)) old_head = chain_manager.head # assuming chain order w/ newest block first for block_data in reversed(block_lst): try: block = blocks.Block.deserialize(rlp.encode(block_data)) except blocks.UnknownParentException: # no way to ask peers for older parts of chain bhash = utils.sha3(rlp.encode(block_data)).encode('hex')[:4] phash = block_data[0][0].encode('hex')[:4] number = utils.decode_int(block_data[0][6]) logger.debug('Block(#%d %s %s) with unknown parent, requesting ...', number, bhash, phash.encode('hex')[:4]) chain_manager.synchronize_blockchain() break if block.hash in chain_manager: logger.debug('Known %r', block) else: if block.has_parent(): # add block & set HEAD if it's longest chain success = chain_manager.add_block(block) if success: logger.debug('Added %r', block) else: logger.debug('Orphant %r', block) if chain_manager.head != old_head: chain_manager.synchronize_blockchain()
def create_contract(block, tx, msg): snapshot = block.snapshot() sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender nonce = encode_int(block.get_nonce(msg.sender)) recvaddr = sha3(rlp.encode([sender, nonce]))[12:] code = msg.data # Transfer value, instaquit if not enough block.delta_balance(recvaddr, msg.value) o = block.delta_balance(msg.sender, msg.value) if not o: return 0, msg.gas block.set_code(recvaddr, msg.data) compustate = Compustate(gas=msg.gas) # Temporary pre-POC5: don't do the code/init thing return recvaddr, compustate.gas # Main loop while 1: o = apply_op(block, tx, msg, msg.data, compustate.op) if o is not None: if o == OUT_OF_GAS: block.state.root = oldroot return 0, 0 else: block.set_code(''.join(map(chr, o))) return recvaddr, compustate.gas
def create_contract(block, tx, msg): snapshot = block.snapshot() sender = msg.sender.decode('hex') if len(msg.sender) == 40 else msg.sender nonce = utils.encode_int(block.get_nonce(msg.sender)) recvaddr = utils.sha3(rlp.encode([sender, nonce]))[12:] assert not block.get_code(recvaddr) msg.to = recvaddr block.increment_nonce(msg.sender) # Transfer value, instaquit if not enough o = block.transfer_value(msg.sender, msg.to, msg.value) if not o: return 0, msg.gas compustate = Compustate(gas=msg.gas) # Main loop while 1: o = apply_op(block, tx, msg, msg.data, compustate) if o is not None: if o == OUT_OF_GAS: block.revert(snapshot) return 0, 0, [] else: for s in block.suicides: block.state.delete(utils.encode_addr(s)) block.set_code(recvaddr, ''.join(map(chr, o))) return recvaddr, compustate.gas, o
def remote_blocks_received_handler(sender, block_lst, peer, **kwargs): logger.debug("received %d remote blocks", len(block_lst)) old_head = chain_manager.head # assuming chain order w/ newest block first for block_data in reversed(block_lst): try: block = blocks.Block.deserialize(rlp.encode(block_data)) except blocks.UnknownParentException: # no way to ask peers for older parts of chain bhash = utils.sha3(rlp.encode(block_data)).encode('hex')[:4] phash = block_data[0][0].encode('hex')[:4] number = utils.decode_int(block_data[0][6]) if phash == blocks.GENESIS_PREVHASH: logger.debug('Incompatible Genesis %r', block) peer.send_Disconnect(reason='Wrong genesis block') else: logger.debug( 'Block(#%d %s %s) with unknown parent, requesting ...', number, bhash, phash.encode('hex')[:4]) chain_manager.synchronize_blockchain() break if block.hash in chain_manager: logger.debug('Known %r', block) else: if block.has_parent(): # add block & set HEAD if it's longest chain success = chain_manager.add_block(block) if success: logger.debug('Added %r', block) else: logger.debug('Orphant %r', block) if chain_manager.head != old_head: chain_manager.synchronize_blockchain()
def to_dict(self, with_state=False, full_transactions=False): """ serializes the block with_state: include state for all accounts full_transactions: include serialized tx (hashes otherwise) """ self.commit_state() b = {} for name, typ, default in block_structure: b[name] = utils.printers[typ](getattr(self, name)) txlist = [] for i in range(self.transaction_count): tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i))) tx, msr, gas = rlp.decode(tx_rlp) if full_transactions: txjson = transactions.Transaction.create(tx).to_dict() else: txjson = utils.sha3(rlp.descend(tx_rlp, 0)).encode('hex') # tx hash txlist.append({ "tx": txjson, "medstate": msr.encode('hex'), "gas": str(utils.decode_int(gas)) }) b["transactions"] = txlist if with_state: state_dump = {} for address, v in self.state.to_dict().iteritems(): state_dump[address.encode('hex')] = self.account_to_dict( address) b['state'] = state_dump return b
def send(self, receiver_address, msg): assert isaddress(receiver_address) assert not isinstance(msg, (Ack, BaseError)), msg log.info("SENDING {} > {} : {}".format(pex(self.raiden.address), pex(receiver_address), msg)) host_port = self.discovery.get(receiver_address) data = msg.encode() msghash = sha3(data) self.tries[msghash] = self.max_tries log.debug("MSGHASH SENT", msghash=pex(msghash)) assert len(data) < self.max_message_size def repeater(): while self.tries.get(msghash, 0) > 0: if not self.repeat_messages and self.tries[msghash] < self.max_tries: raise Exception( "DEACTIVATED MSG resents {} {}".format(pex(receiver_address), msg)) self.tries[msghash] -= 1 self.transport.send(self.raiden, host_port, data) gevent.sleep(self.try_interval) # Each sent msg must be acked. When msg is acked its hash is removed from self.tries if msghash in self.tries: assert False, "Node does not reply, fixme suspend node" gevent.spawn(repeater)
def send(self, receiver_address, msg): assert isaddress(receiver_address) assert not isinstance(msg, (Ack, BaseError)), msg log.info("SENDING {} > {} : {}".format(pex(self.raiden.address), pex(receiver_address), msg)) host_port = self.discovery.get(receiver_address) data = msg.encode() msghash = sha3(data) self.tries[msghash] = self.max_tries log.debug("MSGHASH SENT", msghash=pex(msghash)) assert len(data) < self.max_message_size def repeater(): while self.tries.get(msghash, 0) > 0: if not self.repeat_messages and self.tries[ msghash] < self.max_tries: raise Exception("DEACTIVATED MSG resents {} {}".format( pex(receiver_address), msg)) self.tries[msghash] -= 1 self.transport.send(self.raiden, host_port, data) gevent.sleep(self.try_interval) # Each sent msg must be acked. When msg is acked its hash is removed from self.tries if msghash in self.tries: assert False, "Node does not reply, fixme suspend node" gevent.spawn(repeater)
def get_root_hash(self): if self.root_node == BLANK_NODE: return BLANK_ROOT assert isinstance(self.root_node, list) val = rlp.encode(self.root_node) key = utils.sha3(val) self.db.put(key, val) return key
def __init__(self, rlpdata): self.rlpdata = rlpdata self.hash = utils.sha3(rlpdata) header_args, transaction_list, uncles = rlp.decode(rlpdata) self.transaction_list = transaction_list # rlp encoded transactions self.uncles = uncles for i, (name, typ, default) in enumerate(block_structure): setattr(self, name, utils.decoders[typ](header_args[i]))
def _rlp_encode(self, node): rlpnode = rlp.encode(node) if len(rlpnode) < 32: return node hashkey = sha3(rlpnode) self.db.put(hashkey, rlpnode) return hashkey
def genesis(initial_alloc={}): # https://ethereum.etherpad.mozilla.org/11 block = Block(prevhash="\x00" * 32, coinbase="0" * 40, difficulty=2 ** 22, nonce=sha3(chr(42)), gas_limit=10 ** 6) for addr in initial_alloc: block.set_balance(addr, initial_alloc[addr]) return block
def list_header(self, exclude=[]): self.uncles_hash = utils.sha3(rlp.encode(self.uncles)) header = [] for name, typ, default in block_structure: # print name, typ, default , getattr(self, name) if name not in exclude: header.append(utils.encoders[typ](getattr(self, name))) return header
def sign(self, key, network_id=None): if network_id is None: rawhash = sha3(rlp.encode(self, UnsignedBlock)) else: assert 1 <= network_id < 2**63 - 18 rlpdata = rlp.encode( rlp.infer_sedes(self).serialize(self)[:-3] + [network_id, b'', b'']) rawhash = sha3(rlpdata) key = normalize_key(key) self.v, self.r, self.s = ecsign(rawhash, key) if network_id is not None: self.v += 8 + network_id * 2 self._signer = privtoaddr(key) return self
def transfer(self, amount, target, hashlock=None, secret=None): if target in self.assetmanager.channels and not hashlock: # direct connection channel = self.assetmanager.channels[target] transfer = channel.create_transfer(amount, secret=secret) self.raiden.sign(transfer) channel.register_transfer(transfer) self.raiden.protocol.send(transfer.recipient, transfer) else: if not (hashlock or secret): secret = sha3(hex(random.getrandbits(256))) hashlock = sha3(secret) # initiate mediated transfer t = TransferTask(self, amount, target, hashlock, expiration=None, originating_transfer=None, secret=secret) t.start() t.join()
def deserialize_child(self, rlpdata): """ deserialization w/ replaying transactions """ header_args, transaction_list, uncles = rlp.decode(rlpdata) assert len(header_args) == len(block_structure) kargs = dict(transaction_list=transaction_list, uncles=uncles) # Deserialize all properties for i, (name, typ, default) in enumerate(block_structure): kargs[name] = utils.decoders[typ](header_args[i]) block = Block.init_from_parent(self, kargs['coinbase'], extra_data=kargs['extra_data'], timestamp=kargs['timestamp'], uncles=uncles) # replay transactions for tx_lst_serialized, _state_root, _gas_used_encoded in \ transaction_list: tx = transactions.Transaction.create(tx_lst_serialized) # logger.debug('state:\n%s', utils.dump_state(block.state)) # logger.debug('applying %r', tx) success, output = processblock.apply_transaction(block, tx) #block.add_transaction_to_list(tx) # < this is done by processblock # logger.debug('state:\n%s', utils.dump_state(block.state)) logger.debug('d %s %s', _gas_used_encoded, block.gas_used) assert utils.decode_int(_gas_used_encoded) == block.gas_used, \ "Gas mismatch (ours %d, theirs %d) on block: %r" % \ (block.gas_used, _gas_used_encoded, block.to_dict(False, True, True)) assert _state_root == block.state.root_hash, \ "State root mismatch (ours %r theirs %r) on block: %r" % \ (block.state.root_hash.encode('hex'), _state_root.encode('hex'), block.to_dict(False, True, True)) block.finalize() block.uncles_hash = kargs['uncles_hash'] block.nonce = kargs['nonce'] block.min_gas_price = kargs['min_gas_price'] # checks assert block.prevhash == self.hash assert block.gas_used == kargs['gas_used'] assert block.gas_limit == kargs['gas_limit'] assert block.timestamp == kargs['timestamp'] assert block.difficulty == kargs['difficulty'] assert block.number == kargs['number'] assert block.extra_data == kargs['extra_data'] assert utils.sha3(rlp.encode(block.uncles)) == kargs['uncles_hash'] assert block.tx_list_root == kargs['tx_list_root'] assert block.state.root_hash == kargs['state_root'], ( block.state.root_hash, kargs['state_root']) return block
def to_dict(self, with_state=False, full_transactions=False, with_storage_roots=False, with_uncles=False): """ serializes the block with_state: include state for all accounts full_transactions: include serialized tx (hashes otherwise) with_uncles: include uncle hashes """ b = {} for name, typ, default in block_structure: b[name] = utils.printers[typ](getattr(self, name)) txlist = [] for i in range(self.transaction_count): tx_rlp = self.transactions.get(rlp.encode(utils.encode_int(i))) tx = rlp.decode(tx_rlp) receipt_rlp = self.receipts.get(rlp.encode(utils.encode_int(i))) msr, gas, mybloom, mylogs = rlp.decode(receipt_rlp) if full_transactions: txjson = transactions.Transaction.create(tx).to_dict() else: # tx hash txjson = utils.sha3(rlp.descend(tx_rlp, 0)).encode('hex') txlist.append({ "tx": txjson, "medstate": msr.encode('hex'), "gas": str(utils.decode_int(gas)), "logs": mylogs, "bloom": mybloom.encode('hex') }) b["transactions"] = txlist if with_state: state_dump = {} for address, v in self.state.to_dict().iteritems(): state_dump[address.encode('hex')] = \ self.account_to_dict(address, with_storage_roots) b['state'] = state_dump if with_uncles: b['uncles'] = [ utils.sha3(rlp.encode(u)).encode('hex') for u in self.uncles ] return b
def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data): # data comes in as array of byte array (bytes as ints, from js) tohash = byte_arrays_to_string(data) assert (msghash == utils.sha3(tohash)) X, Y = ecdsa_raw_recover(msghash, sig) pX = utils.int_to_big_endian(X).encode('hex') pY = utils.int_to_big_endian(Y).encode('hex') pub = '04' + pX + pY return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
def send(self, sender, host_port, data): log.debug('in send unreliable', counter=self.network.counter, drop_this_one=not(self.network.counter % self.droprate)) if self.network.counter % self.droprate: self.network.send(sender, host_port, data) else: self.network.track_send(sender, host_port, data) log.debug('dropped', data=format(pex(sha3(data))))
def verify_dc_sig(self, sig, msghash, msgsize, from_addr, data): # data comes in as array of byte array (bytes as ints, from js) tohash = byte_arrays_to_string(data) assert (msghash == utils.sha3(tohash)) X, Y = ecdsa_raw_recover(msghash, sig) pX = utils.int_to_big_endian(X).encode('hex') pY = utils.int_to_big_endian(Y).encode('hex') pub = '04'+pX+pY return ecdsa_raw_verify(msghash, sig, pub.decode('hex'))
def send(self, sender, host_port, message): for cb in self.on_send_cbs: cb(sender, host_port, message) print 'in send unreliable', self.counter, self.counter % self.droprate self.counter += 1 if (self.counter - 1) % self.droprate: self.protocols[host_port].receive(message) else: print('dropped message {}'.format(pex(sha3(message))))
def parse(cls, data): if re.match('^[0-9a-fA-F]*$', data): data = data.decode('hex') o = rlp.decode(data) tx = cls(decode_int(o[0]), decode_int(o[1]), decode_int(o[2]), decode_int(o[3]), o[4].encode('hex'), o[5], decode_int(o[6]), decode_int(o[7]), decode_int(o[8])) rawhash = sha3(rlp.encode(tx.serialize(False))) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (tx.v, tx.r, tx.s)), 'bin') tx.sender = sha3(pub[1:])[-20:].encode('hex') return tx
def quickcontract(self, gasprice, startgas, value, code, pkey_hex): sender = privtoaddr(pkey_hex) nonce = self.getnonce(sender) tx = contract(nonce, gasprice, startgas, value, code) formatted_rlp = [sender.decode('hex'), utils.int_to_big_endian(nonce)] addr = utils.sha3(rlp.encode(formatted_rlp))[12:].encode('hex') o = self.applytx(sign(tx, pkey_hex)) o['addr'] = addr return o
def __init__(self, data=None): self.reward = 10 ** 18 self.gas_consumed = 0 self.gaslimit = 1000000 # for now if not data: self.number = 0 self.prevhash = '' self.uncles_root = '' self.coinbase = '0' * 40 self.state = Trie(get_db_path()) self.transactions_root = '' self.transactions = [] self.uncles = [] self.difficulty = 2 ** 23 self.timestamp = 0 self.extradata = '' self.nonce = 0 return if re.match('^[0-9a-fA-F]*$', data): data = data.decode('hex') header, transaction_list, self.uncles = rlp.decode(data) self.number = decode_int(header[0]) self.prevhash = header[1] self.uncles_root = header[2] self.coinbase = header[3].encode('hex') self.state = Trie(STATEDB_DIR, header[4]) self.transactions_root = header[5] self.difficulty = decode_int(header[6]) self.timestamp = decode_int(header[7]) self.extradata = header[8] self.nonce = decode_int(header[9]) self.transactions = [Transaction(x) for x in transaction_list] # Verifications if self.state.root != '' and self.state.db.get(self.state.root) == '': raise Exception("State Merkle root not found in database!") if sha3(rlp.encode(transaction_list)) != self.transactions_root: raise Exception("Transaction list root hash does not match!") if sha3(rlp.encode(self.uncles)) != self.uncles_root: raise Exception("Uncle root hash does not match!")
def __init__(self, data=None): self.reward = 10**18 self.gas_consumed = 0 self.gaslimit = 1000000 # for now if not data: self.number = 0 self.prevhash = '' self.uncles_root = '' self.coinbase = '0' * 40 self.state = Trie('statedb') self.transactions_root = '' self.transactions = [] self.uncles = [] self.difficulty = 2**23 self.timestamp = 0 self.extradata = '' self.nonce = 0 return if re.match('^[0-9a-fA-F]*$', data): data = data.decode('hex') header, transaction_list, self.uncles = rlp.decode(data) self.number = decode_int(header[0]) self.prevhash = header[1] self.uncles_root = header[2] self.coinbase = header[3].encode('hex') self.state = Trie('statedb', header[4]) self.transactions_root = header[5] self.difficulty = decode_int(header[6]) self.timestamp = decode_int(header[7]) self.extradata = header[8] self.nonce = decode_int(header[9]) self.transactions = [Transaction(x) for x in transaction_list] # Verifications if self.state.root != '' and self.state.db.get(self.state.root) == '': raise Exception("State Merkle root not found in database!") if sha3(rlp.encode(transaction_list)) != self.transactions_root: raise Exception("Transaction list root hash does not match!") if sha3(rlp.encode(self.uncles)) != self.uncles_root: raise Exception("Uncle root hash does not match!")
def deserialize_child(self, rlpdata): """ deserialization w/ replaying transactions """ header_args, transaction_list, uncles = rlp.decode(rlpdata) assert len(header_args) == len(block_structure) kargs = dict(transaction_list=transaction_list, uncles=uncles) # Deserialize all properties for i, (name, typ, default) in enumerate(block_structure): kargs[name] = utils.decoders[typ](header_args[i]) block = Block.init_from_parent(self, kargs['coinbase'], extra_data=kargs['extra_data'], timestamp=kargs['timestamp'], uncles=uncles) # replay transactions for tx_lst_serialized, _state_root, _gas_used_encoded in \ transaction_list: tx = transactions.Transaction.create(tx_lst_serialized) # logger.debug('state:\n%s', utils.dump_state(block.state)) # logger.debug('applying %r', tx) success, output = processblock.apply_transaction(block, tx) #block.add_transaction_to_list(tx) # < this is done by processblock # logger.debug('state:\n%s', utils.dump_state(block.state)) logger.debug('d %s %s', _gas_used_encoded, block.gas_used) assert utils.decode_int(_gas_used_encoded) == block.gas_used, \ "Gas mismatch (ours %d, theirs %d) on block: %r" % \ (block.gas_used, _gas_used_encoded, block.to_dict(False, True, True)) assert _state_root == block.state.root_hash, \ "State root mismatch (ours %r theirs %r) on block: %r" % \ (block.state.root_hash.encode('hex'), _state_root.encode('hex'), block.to_dict(False, True, True)) block.finalize() block.uncles_hash = kargs['uncles_hash'] block.nonce = kargs['nonce'] block.min_gas_price = kargs['min_gas_price'] # checks assert block.prevhash == self.hash assert block.gas_used == kargs['gas_used'] assert block.gas_limit == kargs['gas_limit'] assert block.timestamp == kargs['timestamp'] assert block.difficulty == kargs['difficulty'] assert block.number == kargs['number'] assert block.extra_data == kargs['extra_data'] assert utils.sha3(rlp.encode(block.uncles)) == kargs['uncles_hash'] assert block.tx_list_root == kargs['tx_list_root'] assert block.state.root_hash == kargs['state_root'], (block.state.root_hash, kargs['state_root']) return block
def _add_transactions(self, blk): "'tx_hash' -> 'rlp([blockhash,tx_number])" for i in range(blk.transaction_count): i_enc = utils.encode_int(i) # work on rlp data to avoid unnecessary de/serialization td = blk.transactions.get(rlp.encode(i_enc)) tx = rlp.descend(td, 0) key = utils.sha3(tx) value = rlp.encode([blk.hash, i_enc]) self.db.put(key, value)
def root_with(self, lock=None, exclude=None): assert not lock or isinstance(lock, Lock) assert not exclude or isinstance(exclude, Lock) lock_hash = exclude_hash = None # temporarily add / remove if lock: lock_hash = sha3(lock.asstring) self._cached_lock_hashes.append(lock_hash) if exclude: exclude_hash = sha3(exclude.asstring) self._cached_lock_hashes.remove(exclude_hash) # calc r = merkleroot(self._cached_lock_hashes) # restore if lock_hash: assert lock_hash in self._cached_lock_hashes self._cached_lock_hashes.remove(lock_hash) if exclude: self._cached_lock_hashes.append(exclude_hash) return r
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0): self.nonce = nonce self.gasprice = gasprice self.startgas = startgas self.to = to self.value = value self.data = data self.v, self.r, self.s = v, r, s # Determine sender if self.r and self.s: rawhash = utils.sha3(self.serialize(False)) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)), 'bin') self.sender = utils.sha3(pub[1:])[-20:].encode('hex') # does not include signature else: self.sender = 0
def _encode_node(self, node): if node == BLANK_NODE: return BLANK_NODE assert isinstance(node, list) rlpnode = rlp.encode(node) if len(rlpnode) < 32: return node hashkey = utils.sha3(rlpnode) self.db.put(hashkey, rlpnode) return hashkey
def _encode_node(self, node, put_in_db=True): if node == BLANK_NODE: return BLANK_NODE rlpnode = encode_optimized(node) if len(rlpnode) < 32: return node hashkey = utils.sha3(rlpnode) if put_in_db: self.db.put(hashkey, str_to_bytes(rlpnode)) return hashkey
def hash_message(self, msg): prefix = b'' if self.category == 0: prefix = b'Allocate:\n' elif self.category == 1: prefix = b'Delegate:\n' elif self.category == 2: prefix = b'MapServer:\n' elif self.category == 3: prefix = b'Locator:\n' return sha3( int_to_bytes(len(prefix)) + prefix + int_to_bytes(len(msg)) + msg)
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0): self.nonce = nonce self.gasprice = gasprice self.startgas = startgas self.to = to self.value = value self.data = data self.v, self.r, self.s = v, r, s self.logs = [] # Determine sender if self.r < N and self.s < P and self.v >= 27 and self.v <= 28: rawhash = utils.sha3(self.serialize(False)) pub = encode_pubkey( ecdsa_raw_recover(rawhash, (self.v, self.r, self.s)), 'bin') self.sender = utils.sha3(pub[1:])[-20:].encode('hex') # does not include signature else: self.sender = 0
def close(self, sender, last_sent_transfers, *unlocked): """" can be called multiple times. lock period starts with first valid call. todo: if challenged, keep track of who provided the last valid answer, punish the wrongdoer here, check that participants only updates their own balance are counted, because they could sign something for the other party to blame it. last_sent_transfers: [rlp(transfer), ] max 2 unlocked: [(merkle_proof, locked_rlp, secret)), ...] """ assert sender in self.participants assert 0 <= len(last_sent_transfers) <= 2 # register / update claims for t in last_sent_transfers: # fixme rlp encoded # check transfer signature assert t.sender in self.participants # update valid claims if not self.participants[t.sender]['last_sent_transfer'] or \ self.participants[t.sender]['last_sent_transfer'].nonce < t.nonce: self.participants[t.sender]['last_sent_transfer'] = t # register un-locked last_sent = self.participants[self.partner( sender)]['last_sent_transfer'] for merkle_proof, locked_rlp, secret in unlocked: locked = rlp.decode(locked_rlp, messages.Lock) assert locked.hashlock == sha3(secret) assert check_proof(merkle_proof, last_sent.locksroot, sha3(locked_rlp)) self.participants[self.partner( t.sender)]['unlocked'].append(locked) # mark closed if not self.closed: self.closed = self.chain.block_number
def create_network(num_nodes=8, num_assets=1, channels_per_node=3, transport_class=DummyTransport): import random random.seed(42) # globals discovery = Discovery() chain = BlockChain() # create apps apps = [ mk_app(i, chain, discovery, transport_class) for i in range(num_nodes) ] # create assets for i in range(num_assets): chain.add_asset(asset_address=sha3('asset:%d' % i)[:20]) assert len(chain.asset_addresses) == num_assets # create channel contracts for asset_address in chain.asset_addresses: channelmanager = chain.channelmanager_by_asset(asset_address) assert isinstance(channelmanager, ChannelManagerContract) assert channels_per_node < len(apps) for app in apps: capps = list(apps) # copy capps.remove(app) netting_contracts = channelmanager.nettingcontracts_by_address( app.raiden.address) while len(netting_contracts) < channels_per_node and capps: a = random.choice(capps) assert a != app capps.remove(a) a_nettting_contracts = channelmanager.nettingcontracts_by_address( a.raiden.address) if not set(netting_contracts).intersection(set(a_nettting_contracts)) \ and len(a_nettting_contracts) < channels_per_node: # print pex(a.raiden.address), pex(app.raiden.address) c = channelmanager.new(a.raiden.address, app.raiden.address) netting_contracts.append(c) # add deposit of asset for address in (app.raiden.address, a.raiden.address): c.deposit(address, amount=2**240) for app in apps: app.raiden.setup_assets() return apps
def sha3(string): """Calculate the SHA3-256 hash of some input. This command calculates the 256-bit SHA3 hash of STRING and prints the result in hex-encoding. STRING is interpreted as a latin-1 encoded byte array. """ try: byte_array = string.encode('latin1') except UnicodeEncodeError: raise click.BadParameter('STRING must be encoded in latin-1') else: click.echo(utils.sha3(byte_array).encode('hex'))
def validate_uncles(self): if utils.sha3(rlp.encode(self.uncles)) != self.uncles_hash: sys.stderr.write( utils.sha3(rlp.encode(self.uncles)).encode('hex') + ' ' + self.uncles_hash.encode('hex') + '\n\n\n') return False # Check uncle validity ancestor_chain = [self] # Uncle can have a block from 2-7 blocks ago as its parent for i in [1, 2, 3, 4, 5, 6, 7]: if ancestor_chain[-1].number > 0: ancestor_chain.append(ancestor_chain[-1].get_parent()) ineligible = [] # Uncles of this block cannot be direct ancestors and cannot also # be uncles included 1-6 blocks ago for ancestor in ancestor_chain[1:]: ineligible.extend(ancestor.uncles) ineligible.extend([b.list_header() for b in ancestor_chain]) eligible_ancestor_hashes = [x.hash for x in ancestor_chain[2:]] for uncle in self.uncles: if not check_header_pow(uncle): sys.stderr.write('1\n\n') return False # uncle's parent cannot be the block's own parent prevhash = uncle[block_structure_rev['prevhash'][0]] if prevhash not in eligible_ancestor_hashes: logger.debug("%r: Uncle does not have a valid ancestor", self) sys.stderr.write('2 ' + prevhash.encode('hex') + ' ' + str( map(lambda x: x.encode('hex'), eligible_ancestor_hashes)) + '\n\n') return False if uncle in ineligible: sys.stderr.write('3\n\n') logger.debug("%r: Duplicate uncle %r", self, utils.sha3(rlp.encode(uncle)).encode('hex')) return False ineligible.append(uncle) return True