def test_init_chain_ignores_invalid_init_chain_requests(b): validators = [generate_validator()] request = generate_init_chain_request('chain-XYZ', validators) res = App(b).init_chain(request) assert res == ResponseInitChain() validator_set = query.get_validator_set(b.connection) invalid_requests = [ request, # the same request again # different validator set generate_init_chain_request('chain-XYZ'), # different chain ID generate_init_chain_request('chain-ABC', validators), ] for r in invalid_requests: with pytest.raises(SystemExit): App(b).init_chain(r) # assert nothing changed - neither validator set, nor chain ID new_validator_set = query.get_validator_set(b.connection) assert new_validator_set == validator_set new_chain_id = query.get_latest_abci_chain(b.connection)['chain_id'] assert new_chain_id == 'chain-XYZ' assert query.get_latest_block(b.connection) == { 'height': 0, 'app_hash': '', 'transactions': [], }
def init_chain(self, genesis): """Initialize chain with block of height 0""" validator_set = [decode_validator(v) for v in genesis.validators] block = Block(app_hash='', height=0, transactions=[]) self.bigchaindb.store_block(block._asdict()) self.bigchaindb.store_validator_set(1, validator_set) return ResponseInitChain()
def test_init_chain_successfully_registers_chain(b): request = generate_init_chain_request('chain-XYZ') res = App(b).init_chain(request) assert res == ResponseInitChain() chain = query.get_latest_abci_chain(b.connection) assert chain == {'height': 0, 'chain_id': 'chain-XYZ', 'is_synced': True} assert query.get_latest_block(b.connection) == { 'height': 0, 'app_hash': '', 'transactions': [], }
def init_chain(self, genesis): """Initialize chain upon genesis or a migration""" app_hash = '' height = 0 known_chain = self.bigchaindb.get_latest_abci_chain() if known_chain is not None: chain_id = known_chain['chain_id'] if known_chain['is_synced']: msg = f'Got invalid InitChain ABCI request ({genesis}) - ' + \ 'the chain {chain_id} is already synced.' logger.error(msg) sys.exit(1) if chain_id != genesis.chain_id: validators = self.bigchaindb.get_validators() self.log_abci_migration_error(chain_id, validators) sys.exit(1) # set migration values for app hash and height block = self.bigchaindb.get_latest_block() app_hash = '' if block is None else block['app_hash'] height = 0 if block is None else block['height'] + 1 known_validators = self.bigchaindb.get_validators() validator_set = [ vutils.decode_validator(v) for v in genesis.validators ] if known_validators and known_validators != validator_set: self.log_abci_migration_error(known_chain['chain_id'], known_validators) sys.exit(1) block = Block(app_hash=app_hash, height=height, transactions=[]) self.bigchaindb.store_block(block._asdict()) self.bigchaindb.store_validator_set(height + 1, validator_set) abci_chain_height = 0 if known_chain is None else known_chain['height'] self.bigchaindb.store_abci_chain(abci_chain_height, genesis.chain_id, True) self.chain = { 'height': abci_chain_height, 'is_synced': True, 'chain_id': genesis.chain_id } return ResponseInitChain()
def init_chain(self, req): self.validators = req.validators return ResponseInitChain()
def test_init_chain_recognizes_new_chain_after_migration(b): validators = [generate_validator()] request = generate_init_chain_request('chain-XYZ', validators) res = App(b).init_chain(request) assert res == ResponseInitChain() validator_set = query.get_validator_set(b.connection)['validators'] # simulate a migration query.store_block(b.connection, Block(app_hash='', height=1, transactions=[])._asdict()) b.migrate_abci_chain() # the same or other mismatching requests are ignored invalid_requests = [ request, generate_init_chain_request('unknown', validators), generate_init_chain_request('chain-XYZ'), generate_init_chain_request('chain-XYZ-migrated-at-height-1'), ] for r in invalid_requests: with pytest.raises(SystemExit): App(b).init_chain(r) assert query.get_latest_abci_chain(b.connection) == { 'chain_id': 'chain-XYZ-migrated-at-height-1', 'is_synced': False, 'height': 2, } new_validator_set = query.get_validator_set(b.connection)['validators'] assert new_validator_set == validator_set # a request with the matching chain ID and matching validator set # completes the migration request = generate_init_chain_request('chain-XYZ-migrated-at-height-1', validators) res = App(b).init_chain(request) assert res == ResponseInitChain() assert query.get_latest_abci_chain(b.connection) == { 'chain_id': 'chain-XYZ-migrated-at-height-1', 'is_synced': True, 'height': 2, } assert query.get_latest_block(b.connection) == { 'height': 2, 'app_hash': '', 'transactions': [], } # requests with old chain ID and other requests are ignored invalid_requests = [ request, generate_init_chain_request('chain-XYZ', validators), generate_init_chain_request('chain-XYZ-migrated-at-height-1'), ] for r in invalid_requests: with pytest.raises(SystemExit): App(b).init_chain(r) assert query.get_latest_abci_chain(b.connection) == { 'chain_id': 'chain-XYZ-migrated-at-height-1', 'is_synced': True, 'height': 2, } new_validator_set = query.get_validator_set(b.connection)['validators'] assert new_validator_set == validator_set assert query.get_latest_block(b.connection) == { 'height': 2, 'app_hash': '', 'transactions': [], }
def init_chain(self, validators): """Initialize chain with block of height 0""" block = Block(app_hash='', height=0, transactions=[]) self.bigchaindb.store_block(block._asdict()) return ResponseInitChain()