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 init_from_parent(cls, parent, coinbase, extra_data='', timestamp=int(time.time()), uncles=[]): b = Block(db=parent.db, prevhash=parent.hash, uncles_hash=utils.sha3rlp(uncles), coinbase=coinbase, state_root=parent.state.root_hash, tx_list_root=trie.BLANK_ROOT, receipts_root=trie.BLANK_ROOT, bloom=0, difficulty=calc_difficulty(parent, timestamp), number=parent.number + 1, gas_limit=calc_gaslimit(parent), gas_used=0, timestamp=timestamp, extra_data=extra_data, nonce='', transaction_list=[], uncles=uncles) b.ancestors += parent.ancestors return b
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 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] = self.decoders[typ](header_args[i]) block = Block.init_from_parent(self, kargs['coinbase'], extra_data=kargs['extra_data'], timestamp=kargs['timestamp'], uncles=uncles) # bloom_bits_expected = bloom.bits_in_number(kargs['bloom']) # replay transactions for tx_lst_serialized in transaction_list: tx = transactions.Transaction.create(tx_lst_serialized) success, output = processblock.apply_transaction(block, tx) block.finalize() block.uncles_hash = kargs['uncles_hash'] block.nonce = kargs['nonce'] # checks set_aux(block.to_dict()) must_equal('prev_hash', block.prevhash, self.hash) must_equal('gas_used', block.gas_used, kargs['gas_used']) must_equal('gas_limit', block.gas_limit, kargs['gas_limit']) must_equal('timestamp', block.timestamp, kargs['timestamp']) must_equal('difficulty', block.difficulty, kargs['difficulty']) must_equal('number', block.number, kargs['number']) must_equal('extra_data', block.extra_data, kargs['extra_data']) must_equal('uncles', utils.sha3rlp(block.uncles), kargs['uncles_hash']) must_equal('state_root', block.state.root_hash, kargs['state_root']) must_equal('tx_list_root', block.tx_list_root, kargs['tx_list_root']) # bloom_bits = bloom.bits_in_number(block.bloom) # bloom_bits_expected = bloom.bits_in_number(kargs['bloom']) # print 'computed', bloom_bits # print 'expected', bloom_bits_expected # print 'missing', sorted(set(bloom_bits_expected) - set(bloom_bits)) # print 'wrong', sorted(set(bloom_bits) - set(bloom_bits_expected)) must_equal('bloom', block.bloom, kargs['bloom']) must_equal('receipts_root', block.receipts.root_hash, kargs['receipts_root']) set_aux(None) if not check_header_pow(block.list_header()): raise VerificationFailed('invalid nonce') return block
def init_from_parent(cls, parent, coinbase, extra_data='', timestamp=int(time.time()), uncles=[]): b = Block( db=parent.db, prevhash=parent.hash, uncles_hash=utils.sha3rlp(uncles), coinbase=coinbase, state_root=parent.state.root_hash, tx_list_root=trie.BLANK_ROOT, receipts_root=trie.BLANK_ROOT, bloom=0, difficulty=calc_difficulty(parent, timestamp), number=parent.number + 1, gas_limit=calc_gaslimit(parent), gas_used=0, timestamp=timestamp, extra_data=extra_data, nonce='', transaction_list=[], uncles=uncles) b.ancestors += parent.ancestors return b
( NODE_TYPE_BLANK, NODE_TYPE_LEAF, NODE_TYPE_EXTENSION, NODE_TYPE_BRANCH ) = tuple(range(4)) def is_key_value_type(node_type): return node_type in [NODE_TYPE_LEAF, NODE_TYPE_EXTENSION] BLANK_NODE = '' BLANK_ROOT = utils.sha3rlp('') class Trie(object): def __init__(self, db, root_hash=BLANK_ROOT): '''it also present a dictionary like interface :param db key value database :root: blank or trie node in form of [key, value] or [v0,v1..v15,v] ''' self.db = db # Pass in a database object directly self.set_root_hash(root_hash) # def __init__(self, dbfile, root_hash=BLANK_ROOT): # '''it also present a dictionary like interface
import utils import rlp from rlp.utils import ascii_chr, str_to_bytes ( NODE_TYPE_BLANK, NODE_TYPE_LEAF, NODE_TYPE_EXTENSION, NODE_TYPE_BRANCH ) = tuple(range(4)) BLANK_NODE = b'' BLANK_ROOT = utils.sha3rlp(b'') bin_to_nibbles_cache = {} NIBBLE_TERMINATOR = 16 def is_key_value_type(node_type): return node_type in [NODE_TYPE_LEAF,NODE_TYPE_EXTENSION] def encode_optimized(item): if isinstance(item, bytes): if len(item) == 1 and ord(item) < 128: return item prefix = length_prefix(len(item), 128) else: item = b''.join([encode_optimized(x) for x in item]) prefix = length_prefix(len(item), 192) return prefix + item
BLKLIM_FACTOR_NOM = 6 BLKLIM_FACTOR_DEN = 5 # Block reward BLOCK_REWARD = 1500 * utils.denoms.finney # GHOST constants UNCLE_REWARD = 15 * BLOCK_REWARD / 16 NEPHEW_REWARD = BLOCK_REWARD / 32 MAX_UNCLE_DEPTH = 6 # max (block.number - uncle.number) # Difficulty adjustment constants DIFF_ADJUSTMENT_CUTOFF = 5 BLOCK_DIFF_FACTOR = 1024 # Block header parameters block_structure = [ ["prevhash", "bin", "\00" * 32], ["uncles_hash", "bin", utils.sha3rlp([])], ["coinbase", "addr", GENESIS_COINBASE], ["state_root", "trie_root", trie.BLANK_ROOT], ["tx_list_root", "trie_root", trie.BLANK_ROOT], ["receipts_root", "trie_root", trie.BLANK_ROOT], ["bloom", "int64", 0], ["difficulty", "int", GENESIS_DIFFICULTY], ["number", "int", 0], ["gas_limit", "int", GENESIS_GAS_LIMIT], ["gas_used", "int", 0], ["timestamp", "int", 0], ["extra_data", "bin", ""], ["nonce", "bin", ""], ] block_structure_rev = {}