Esempio n. 1
0
def make_head_candidate(chain,
                        txqueue=None,
                        parent=None,
                        timestamp=None,
                        coinbase='\x35' * 20,
                        extra_data='moo ha ha says the laughing cow.',
                        min_gasprice=0):
    log.info('Creating head candidate')
    if parent is None:
        temp_state = State.from_snapshot(
            chain.state.to_snapshot(root_only=True), chain.env)
    else:
        temp_state = chain.mk_poststate_of_blockhash(parent.hash)

    cs = get_consensus_strategy(chain.env.config)
    # Initialize a block with the given parent and variables
    blk = mk_block_from_prevstate(chain, temp_state, timestamp, coinbase,
                                  extra_data)
    # Find and set the uncles
    blk.uncles = cs.get_uncles(chain, temp_state)
    blk.header.uncles_hash = sha3(rlp.encode(blk.uncles))
    # Call the initialize state transition function
    cs.initialize(temp_state, blk)
    # Add transactions
    add_transactions(temp_state, blk, txqueue, min_gasprice)
    # Call the finalize state transition function
    cs.finalize(temp_state, blk)
    # Set state root, receipt root, etc
    set_execution_results(temp_state, blk)
    log.info('Created head candidate successfully')
    return blk, temp_state
Esempio n. 2
0
    def mk_poststate_of_blockhash(self, blockhash, convert=False):
        if blockhash not in self.db:
            raise Exception("Block hash %s not found" % encode_hex(blockhash))

        block_rlp = self.db.get(blockhash)
        if block_rlp == b'GENESIS':
            return State.from_snapshot(
                json.loads(self.db.get(b'GENESIS_STATE')), self.env)
        block = rlp.decode(block_rlp, Block)

        state = State(env=self.env)
        state.trie.root_hash = block.header.state_root if convert else self.db.get(
            b'state:' + blockhash)
        update_block_env_variables(state, block)
        state.gas_used = block.header.gas_used
        state.txindex = len(block.transactions)
        state.recent_uncles = {}
        state.prev_headers = []
        b = block
        header_depth = state.config['PREV_HEADER_DEPTH']
        for i in range(header_depth + 1):
            state.prev_headers.append(b.header)
            if i < 6:
                state.recent_uncles[state.block_number - i] = []
                for u in b.uncles:
                    state.recent_uncles[state.block_number - i].append(u.hash)
            try:
                b = rlp.decode(state.db.get(b.header.prevhash), Block)
            except:
                break
        if i < header_depth:
            if state.db.get(b.header.prevhash) == b'GENESIS':
                jsondata = json.loads(state.db.get(b'GENESIS_STATE'))
                for h in jsondata["prev_headers"][:header_depth - i]:
                    state.prev_headers.append(dict_to_prev_header(h))
                for blknum, uncles in jsondata["recent_uncles"].items():
                    if int(blknum) >= state.block_number - int(
                            state.config['MAX_UNCLE_DEPTH']):
                        state.recent_uncles[blknum] = [
                            parse_as_bin(u) for u in uncles
                        ]
            else:
                raise Exception("Dangling prevhash")
        assert len(state.journal) == 0, state.journal
        return state
Esempio n. 3
0
    def mk_poststate_of_collation_hash(self, collation_hash):
        """Return the post-state of the collation
        """
        if collation_hash not in self.db:
            raise Exception("Collation hash %s not found" %
                            encode_hex(collation_hash))

        collation_rlp = self.db.get(collation_hash)
        if collation_rlp == 'GENESIS':
            return State.from_snapshot(
                json.loads(self.db.get('GENESIS_STATE')), self.env)
        collation = rlp.decode(collation_rlp, Collation)

        state = State(env=self.env)
        state.trie.root_hash = collation.header.post_state_root

        update_collation_env_variables(state, collation)
        state.gas_used = 0
        state.txindex = len(collation.transactions)
        state.recent_uncles = {}
        state.prev_headers = []

        assert len(state.journal) == 0, state.journal
        return state
Esempio n. 4
0
    def __init__(self,
                 genesis=None,
                 env=None,
                 coinbase=b'\x00' * 20,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 **kwargs):
        self.env = env or Env()
        # Initialize the state
        if b'head_hash' in self.db:  # new head tag
            self.state = self.mk_poststate_of_blockhash(
                self.db.get(b'head_hash'))
            print('Initializing chain from saved head, #%d (%s)' %
                  (self.state.prev_headers[0].number,
                   encode_hex(self.state.prev_headers[0].hash)))
        elif genesis is None:
            raise Exception("Need genesis decl!")
        elif isinstance(genesis, State):
            assert env is None
            self.state = genesis
            self.env = self.state.env
            print('Initializing chain from provided state')
        elif "extraData" in genesis:
            self.state = state_from_genesis_declaration(genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided genesis declaration')
        elif "prev_headers" in genesis:
            self.state = State.from_snapshot(genesis, self.env)
            reset_genesis = True
            print('Initializing chain from provided state snapshot, %d (%s)' %
                  (self.state.block_number,
                   encode_hex(self.state.prev_headers[0].hash[:8])))
        else:
            print('Initializing chain from new state based on alloc')
            self.state = mk_basic_state(
                genesis, {
                    "number":
                    kwargs.get('number', 0),
                    "gas_limit":
                    kwargs.get('gas_limit', 4712388),
                    "gas_used":
                    kwargs.get('gas_used', 0),
                    "timestamp":
                    kwargs.get('timestamp', 1467446877),
                    "difficulty":
                    kwargs.get('difficulty', 2**25),
                    "hash":
                    kwargs.get('prevhash', '00' * 32),
                    "uncles_hash":
                    kwargs.get('uncles_hash',
                               '0x' + encode_hex(BLANK_UNCLES_HASH))
                }, self.env)
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        self.head_hash = self.state.prev_headers[0].hash
        self.checkpoint_head_hash = b'\x00' * 32
        self.db.put(b'cp_subtree_score' + b'\x00' * 32, 2 / 3.)
        self.commit_logs = []
        self.casper_address = self.config['CASPER_ADDRESS']
        self.db.put(b'GENESIS_NUMBER', to_string(self.state.block_number))
        assert self.state.block_number == self.state.prev_headers[0].number
        if reset_genesis:
            self.genesis = Block(self.state.prev_headers[0], [], [])
            initialize_genesis_keys(self.state, self.genesis)
        else:
            self.genesis = self.get_block_by_number(0)
        self.db.put(b'cp_subtree_score' + self.genesis.hash, 2 / 3.)
        self.min_gasprice = kwargs.get('min_gasprice', 5 * 10**9)
        self.coinbase = coinbase
        self.extra_data = 'moo ha ha says the laughing cow.'
        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
Esempio n. 5
0
    def __init__(self,
                 genesis=None,
                 env=None,
                 new_head_cb=None,
                 reset_genesis=False,
                 localtime=None,
                 max_history=1000,
                 **kwargs):
        self.env = env or Env()
        # Initialize the state
        if b'head_hash' in self.db:  # new head tag
            self.state = self.mk_poststate_of_blockhash(
                self.db.get('head_hash'))
            self.state.executing_on_head = True
            print('Initializing chain from saved head, #%d (%s)' %
                  (self.state.prev_headers[0].number,
                   encode_hex(self.state.prev_headers[0].hash)))
        elif genesis is None:
            raise Exception("Need genesis decl!")
        elif isinstance(genesis, State):
            assert env is None
            self.state = genesis
            self.env = self.state.env
            print('Initializing chain from provided state')
            reset_genesis = True
        elif "extraData" in genesis:
            self.state = state_from_genesis_declaration(genesis,
                                                        self.env,
                                                        executing_on_head=True)
            reset_genesis = True
            print('Initializing chain from provided genesis declaration')
        elif "prev_headers" in genesis:
            self.state = State.from_snapshot(genesis,
                                             self.env,
                                             executing_on_head=True)
            reset_genesis = True
            print('Initializing chain from provided state snapshot, %d (%s)' %
                  (self.state.block_number,
                   encode_hex(self.state.prev_headers[0].hash[:8])))
        elif isinstance(genesis, dict):
            print('Initializing chain from new state based on alloc')
            self.state = mk_basic_state(
                genesis, {
                    "number":
                    kwargs.get('number', 0),
                    "gas_limit":
                    kwargs.get('gas_limit',
                               self.env.config['BLOCK_GAS_LIMIT']),
                    "gas_used":
                    kwargs.get('gas_used', 0),
                    "timestamp":
                    kwargs.get('timestamp', 1467446877),
                    "difficulty":
                    kwargs.get('difficulty', 2**25),
                    "hash":
                    kwargs.get('prevhash', '00' * 32),
                    "uncles_hash":
                    kwargs.get('uncles_hash',
                               '0x' + encode_hex(BLANK_UNCLES_HASH))
                }, self.env)
            reset_genesis = True

        assert self.env.db == self.state.db

        initialize(self.state)
        self.new_head_cb = new_head_cb

        if self.state.block_number == 0:
            assert self.state.block_number == self.state.prev_headers[0].number
        else:
            assert self.state.block_number - 1 == self.state.prev_headers[
                0].number

        if reset_genesis:
            if isinstance(self.state.prev_headers[0], FakeHeader):
                header = self.state.prev_headers[0].to_block_header()
            else:
                header = self.state.prev_headers[0]
            self.genesis = Block(header)
            self.state.prev_headers[0] = header
            initialize_genesis_keys(self.state, self.genesis)
        else:
            self.genesis = self.get_block_by_number(0)

        self.head_hash = self.state.prev_headers[0].hash
        self.time_queue = []
        self.parent_queue = {}
        self.localtime = time.time() if localtime is None else localtime
        self.max_history = max_history