def test_deliver_tx__double_spend_fails(b): from bigchaindb import App from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair alice = generate_key_pair() bob = generate_key_pair() tx = Transaction.create([alice.public_key], [([bob.public_key], 1)])\ .sign([alice.private_key]) app = App(b) app.init_chain(['ignore']) begin_block = RequestBeginBlock() app.begin_block(begin_block) result = app.deliver_tx(encode_tx_to_bytes(tx)) assert result.code == CodeTypeOk app.end_block(RequestEndBlock(height=99)) app.commit() assert b.get_transaction(tx.id).id == tx.id result = app.deliver_tx(encode_tx_to_bytes(tx)) assert result.code == CodeTypeError
def test_end_block_return_validator_updates(b): from bigchaindb import App from bigchaindb.backend import query from bigchaindb.core import encode_validator from bigchaindb.backend.query import VALIDATOR_UPDATE_ID app = App(b) app.init_chain(['ignore']) begin_block = RequestBeginBlock() app.begin_block(begin_block) validator = { 'pub_key': { 'type': 'ed25519', 'data': 'B0E42D2589A455EAD339A035D6CE1C8C3E25863F268120AA0162AD7D003A4014' }, 'power': 10 } validator_update = { 'validator': validator, 'update_id': VALIDATOR_UPDATE_ID } query.store_validator_update(b.connection, validator_update) resp = app.end_block(RequestEndBlock(height=99)) assert resp.validator_updates[0] == encode_validator(validator) updates = b.get_validator_update() assert updates == []
def test_store_pre_commit_state_in_end_block(b, alice): from bigchaindb import App from bigchaindb.backend import query from bigchaindb.models import Transaction from bigchaindb.backend.query import PRE_COMMIT_ID tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'msg': 'live long and prosper'})\ .sign([alice.private_key]) app = App(b) app.init_chain(['ignore']) begin_block = RequestBeginBlock() app.begin_block(begin_block) app.deliver_tx(encode_tx_to_bytes(tx)) app.end_block(RequestEndBlock(height=99)) resp = query.get_pre_commit_state(b.connection, PRE_COMMIT_ID) assert resp['commit_id'] == PRE_COMMIT_ID assert resp['height'] == 99 assert resp['transactions'] == [tx.id] app.begin_block(begin_block) app.deliver_tx(encode_tx_to_bytes(tx)) app.end_block(RequestEndBlock(height=100)) resp = query.get_pre_commit_state(b.connection, PRE_COMMIT_ID) assert resp['commit_id'] == PRE_COMMIT_ID assert resp['height'] == 100 assert resp['transactions'] == [tx.id]
def test_end_block_return_validator_updates(b, init_chain_request): app = App(b) app.init_chain(init_chain_request) begin_block = RequestBeginBlock() app.begin_block(begin_block) # generate a block containing a concluded validator election validators = generate_validators([1] * 4) b.store_validator_set(1, [v['storage'] for v in validators]) new_validator = generate_validators([1])[0] public_key = validators[0]['public_key'] private_key = validators[0]['private_key'] voter_keys = [v['private_key'] for v in validators] election, votes = generate_election(b, ValidatorElection, public_key, private_key, new_validator['election'], voter_keys) b.store_block( Block(height=1, transactions=[election.id], app_hash='')._asdict()) b.store_bulk_transactions([election]) Election.process_block(b, 1, [election]) app.block_transactions = votes resp = app.end_block(RequestEndBlock(height=2)) assert resp.validator_updates[0].power == new_validator['election'][ 'power'] expected = bytes.fromhex(new_validator['election']['public_key']['value']) assert expected == resp.validator_updates[0].pub_key.data
def test_deliver_tx__valid_create_updates_db_and_emits_event( b, init_chain_request): import multiprocessing as mp from bigchaindb import App from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair alice = generate_key_pair() bob = generate_key_pair() events = mp.Queue() tx = Transaction.create([alice.public_key], [([bob.public_key], 1)])\ .sign([alice.private_key]) app = App(b, events) app.init_chain(init_chain_request) begin_block = RequestBeginBlock() app.begin_block(begin_block) result = app.deliver_tx(encode_tx_to_bytes(tx)) assert result.code == CodeTypeOk app.end_block(RequestEndBlock(height=99)) app.commit() assert b.get_transaction(tx.id).id == tx.id block_event = events.get() assert block_event.data['transactions'] == [tx]
def test_deliver_transfer_tx__double_spend_fails(b, init_chain_request): from bigchaindb import App from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair app = App(b) app.init_chain(init_chain_request) begin_block = RequestBeginBlock() app.begin_block(begin_block) alice = generate_key_pair() bob = generate_key_pair() carly = generate_key_pair() asset = { 'msg': 'live long and prosper' } tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset=asset)\ .sign([alice.private_key]) result = app.deliver_tx(encode_tx_to_bytes(tx)) assert result.code == CodeTypeOk tx_transfer = Transaction.transfer(tx.to_inputs(), [([bob.public_key], 1)], asset_id=tx.id)\ .sign([alice.private_key]) result = app.deliver_tx(encode_tx_to_bytes(tx_transfer)) assert result.code == CodeTypeOk double_spend = Transaction.transfer(tx.to_inputs(), [([carly.public_key], 1)], asset_id=tx.id)\ .sign([alice.private_key]) result = app.deliver_tx(encode_tx_to_bytes(double_spend)) assert result.code == CodeTypeError
def test_store_pre_commit_state_in_end_block(b, alice, init_chain_request): from bigchaindb import App from bigchaindb.backend import query from bigchaindb.models import Transaction tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'msg': 'live long and prosper'})\ .sign([alice.private_key]) app = App(b) app.init_chain(init_chain_request) begin_block = RequestBeginBlock() app.begin_block(begin_block) app.deliver_tx(encode_tx_to_bytes(tx)) app.end_block(RequestEndBlock(height=99)) resp = query.get_pre_commit_state(b.connection) assert resp['height'] == 99 assert resp['transactions'] == [tx.id] app.begin_block(begin_block) app.deliver_tx(encode_tx_to_bytes(tx)) app.end_block(RequestEndBlock(height=100)) resp = query.get_pre_commit_state(b.connection) assert resp['height'] == 100 assert resp['transactions'] == [tx.id] # simulate a chain migration and assert the height is shifted b.store_abci_chain(100, 'new-chain') app = App(b) app.begin_block(begin_block) app.deliver_tx(encode_tx_to_bytes(tx)) app.end_block(RequestEndBlock(height=1)) resp = query.get_pre_commit_state(b.connection) assert resp['height'] == 101 assert resp['transactions'] == [tx.id]
def test_deliver_tx__valid_create_updates_db(b): from bigchaindb.tendermint import App from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair alice = generate_key_pair() bob = generate_key_pair() tx = Transaction.create([alice.public_key], [([bob.public_key], 1)])\ .sign([alice.private_key]) app = App(b) begin_block = RequestBeginBlock() app.init_chain(['ignore']) app.begin_block(begin_block) result = app.deliver_tx(encode_tx_to_bytes(tx)) assert result.is_ok() app.end_block(99) app.commit() assert b.get_transaction(tx.id).id == tx.id
def test_handler(): app = ExampleApp() p = ProtocolHandler(app) # Echo req = Request(echo=RequestEcho(message='hello')) raw = p.process('echo', req) resp = __deserialze(raw) assert resp.echo.message == 'hello' # Flush req = Request(flush=RequestFlush()) raw = p.process('flush', req) resp = __deserialze(raw) assert isinstance(resp.flush, ResponseFlush) # Info req = Request(info=RequestInfo(version='16')) raw = p.process('info', req) resp = __deserialze(raw) assert resp.info.version == '16' assert resp.info.data == 'hello' assert resp.info.last_block_height == 0 assert resp.info.last_block_app_hash == b'0x12' # init_chain val_a = ValidatorUpdate(power=10, pub_key=PubKey(type='amino_encoded', data=b'a_pub_key')) val_b = ValidatorUpdate(power=10, pub_key=PubKey(type='amino_encoded', data=b'b_pub_key')) v = [val_a, val_b] req = Request(init_chain=RequestInitChain(validators=v)) raw = p.process('init_chain', req) resp = __deserialze(raw) assert isinstance(resp.init_chain, ResponseInitChain) # check_tx req = Request(check_tx=RequestCheckTx(tx=b'helloworld')) raw = p.process('check_tx', req) resp = __deserialze(raw) assert resp.check_tx.code == CodeTypeOk assert resp.check_tx.data == b'helloworld' assert resp.check_tx.log == 'bueno' # deliver_tx req = Request(deliver_tx=RequestDeliverTx(tx=b'helloworld')) raw = p.process('deliver_tx', req) resp = __deserialze(raw) assert resp.deliver_tx.code == CodeTypeOk assert resp.deliver_tx.data == b'helloworld' assert resp.deliver_tx.log == 'bueno' # query req = Request(query=RequestQuery(path='/dave', data=b'0x12')) raw = p.process('query', req) resp = __deserialze(raw) assert resp.query.code == CodeTypeOk assert resp.query.value == b'0x12' # begin_block req = Request(begin_block=RequestBeginBlock(hash=b'0x12')) raw = p.process('begin_block', req) resp = __deserialze(raw) assert isinstance(resp.begin_block, ResponseBeginBlock) # end_block req = Request(end_block=RequestEndBlock(height=10)) raw = p.process('end_block', req) resp = __deserialze(raw) assert resp.end_block.validator_updates assert len(resp.end_block.validator_updates) == 2 assert resp.end_block.validator_updates[0].pub_key.data == b'a_pub_key' assert resp.end_block.validator_updates[1].pub_key.data == b'b_pub_key' # Commit req = Request(commit=RequestCommit()) raw = p.process('commit', req) resp = __deserialze(raw) assert resp.commit.data == b'0x1234' # No match raw = p.process('whatever', None) resp = __deserialze(raw) assert resp.exception.error == "ABCI request not found" # set_option req = Request(set_option=RequestSetOption(key='name', value='dave')) raw = p.process('set_option', req) resp = __deserialze(raw) assert resp.set_option.code == CodeTypeOk assert resp.set_option.log == 'name=dave'
def test_begin_aborts_if_chain_is_not_synced(b): b.store_abci_chain(0, 'chain-XYZ', False) with pytest.raises(SystemExit): App(b).info(RequestBeginBlock())