def test_get_spent_for_tx_with_multiple_inputs(carol): from bigchaindb.backend import connect, query from bigchaindb.models import Block, Transaction conn = connect() tx_0 = Transaction.create( [carol.public_key], [([carol.public_key], 1), ([carol.public_key], 1), ([carol.public_key], 2)], ).sign([carol.private_key]) block = Block(transactions=[tx_0]) conn.db.bigchain.insert_one(block.to_dict()) spents = list(query.get_spent(conn, tx_0.id, 0)) assert not spents tx_1 = Transaction.transfer( tx_0.to_inputs()[2:3], [([carol.public_key], 1), ([carol.public_key], 1)], asset_id=tx_0.id, ).sign([carol.private_key]) block = Block(transactions=[tx_1]) conn.db.bigchain.insert_one(block.to_dict()) spents = list(query.get_spent(conn, tx_0.id, 0)) assert not spents tx_2 = Transaction.transfer( tx_0.to_inputs()[0:1] + tx_1.to_inputs()[1:2], [([carol.public_key], 2)], asset_id=tx_0.id, ).sign([carol.private_key]) block = Block(transactions=[tx_2]) conn.db.bigchain.insert_one(block.to_dict()) spents = list(query.get_spent(conn, tx_0.id, 1)) assert not spents
def test_get_txids_filtered(signed_create_tx, signed_transfer_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block, Transaction conn = connect() # create and insert two blocks, one for the create and one for the # transfer transaction block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) block = Block(transactions=[signed_transfer_tx]) conn.db.bigchain.insert_one(block.to_dict()) asset_id = Transaction.get_asset_id([signed_create_tx, signed_transfer_tx]) # Test get by just asset id txids = set(query.get_txids_filtered(conn, asset_id)) assert txids == {signed_create_tx.id, signed_transfer_tx.id} # Test get by asset and CREATE txids = set(query.get_txids_filtered(conn, asset_id, Transaction.CREATE)) assert txids == {signed_create_tx.id} # Test get by asset and TRANSFER txids = set(query.get_txids_filtered(conn, asset_id, Transaction.TRANSFER)) assert txids == {signed_transfer_tx.id}
def test_get_block(signed_create_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert block block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) block_db = query.get_block(conn, block.id) assert block_db == block.to_dict()
def test_write_block(signed_create_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and write block block = Block(transactions=[signed_create_tx]) query.write_block(conn, block.to_dict()) block_db = conn.db.bigchain.find_one({'id': block.id}, {'_id': False}) assert block_db == block.to_dict()
def test_get_spent(signed_create_tx, signed_transfer_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert two blocks, one for the create and one for the # transfer transaction block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) block = Block(transactions=[signed_transfer_tx]) conn.db.bigchain.insert_one(block.to_dict()) spents = list(query.get_spent(conn, signed_create_tx.id, 0)) assert len(spents) == 1 assert spents[0] == signed_transfer_tx.to_dict()
def test_block_serialization(self, b, alice): from bigchaindb.common.crypto import hash_data from bigchaindb.common.utils import gen_timestamp, serialize from bigchaindb.models import Block, Transaction transactions = [ Transaction.create([alice.public_key], [([alice.public_key], 1)]) ] timestamp = gen_timestamp() voters = ['Qaaa', 'Qbbb'] expected_block = { 'timestamp': timestamp, 'transactions': [tx.to_dict() for tx in transactions], 'node_pubkey': alice.public_key, 'voters': voters, } expected = { 'id': hash_data(serialize(expected_block)), 'block': expected_block, 'signature': None, } block = Block(transactions, alice.public_key, timestamp, voters) assert block.to_dict() == expected
def test_get_votes_by_block_id(signed_create_tx, structurally_valid_vote): from bigchaindb.common.crypto import generate_key_pair from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert a block block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) # create and insert some votes structurally_valid_vote['vote']['voting_for_block'] = block.id conn.db.votes.insert_one(structurally_valid_vote) # create a second vote under a different key _, pk = generate_key_pair() structurally_valid_vote['vote']['voting_for_block'] = block.id structurally_valid_vote['node_pubkey'] = pk structurally_valid_vote.pop('_id') conn.db.votes.insert_one(structurally_valid_vote) votes = list(query.get_votes_by_block_id(conn, block.id)) assert len(votes) == 2 assert votes[0]['vote']['voting_for_block'] == block.id assert votes[1]['vote']['voting_for_block'] == block.id
def test_get_last_voted_block_id(genesis_block, signed_create_tx, b): from bigchaindb.backend import connect, query from bigchaindb.models import Block from bigchaindb.common.exceptions import CyclicBlockchainError conn = connect() # check that the last voted block is the genesis block assert query.get_last_voted_block_id(conn, b.me) == genesis_block.id # create and insert a new vote and block block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) vote = b.vote(block.id, genesis_block.id, True) conn.db.votes.insert_one(vote) assert query.get_last_voted_block_id(conn, b.me) == block.id # force a bad chain vote.pop('_id') vote['vote']['voting_for_block'] = genesis_block.id vote['vote']['previous_block'] = block.id conn.db.votes.insert_one(vote) with pytest.raises(CyclicBlockchainError): query.get_last_voted_block_id(conn, b.me)
def test_block_dupe_tx(self, b, alice): from bigchaindb.models import Block, Transaction from bigchaindb.common.exceptions import DuplicateTransaction tx = Transaction.create([alice.public_key], [([alice.public_key], 1)]) block = Block([tx, tx], alice.public_key) block.sign(alice.private_key) b.store_block(block.to_dict()) with raises(DuplicateTransaction): block.validate(b)
def test_count_blocks(signed_create_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert some blocks block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) conn.db.bigchain.insert_one(block.to_dict()) assert query.count_blocks(conn) == 2
def blockdata(b, user_pk, user2_pk): txs = [Transaction.create([user_pk], [([user2_pk], 1)]), Transaction.create([user2_pk], [([user_pk], 1)]), Transaction.create([user_pk], [([user_pk], 1), ([user2_pk], 1)])] blocks = [] for i in range(3): block = Block([txs[i]]) b.write_block(block) blocks.append(block.to_dict()) b.write_vote(b.vote(blocks[1]['id'], '', True)) b.write_vote(b.vote(blocks[2]['id'], '', False)) return blocks, [b['id'] for b in blocks]
def test_get_owned_ids(signed_create_tx, user_pk): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert a block block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) [(block_id, tx)] = list(query.get_owned_ids(conn, user_pk)) assert block_id == block.id assert tx == signed_create_tx.to_dict()
def test_get_asset_by_id(create_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create asset and block create_tx.asset = {'msg': 'aaa'} block = Block(transactions=[create_tx]) conn.db.bigchain.insert_one(block.to_dict()) asset = list(query.get_asset_by_id(conn, create_tx.id)) assert len(asset) == 1 assert asset[0]['asset'] == create_tx.asset
def test_get_block_status_from_transaction(create_tx): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create a block block = Block(transactions=[create_tx], voters=['aaa', 'bbb', 'ccc']) # insert block conn.db.bigchain.insert_one(block.to_dict()) block_db = list( query.get_blocks_status_from_transaction(conn, create_tx.id)) assert len(block_db) == 1 block_db = block_db.pop() assert block_db['id'] == block.id assert block_db['block']['voters'] == block.voters
def test_get_transaction_from_block(user_pk): from bigchaindb.backend import connect, query from bigchaindb.models import Transaction, Block conn = connect() # create a block with 2 transactions txs = [ Transaction.create([user_pk], [([user_pk], 1)]), Transaction.create([user_pk], [([user_pk], 1)]), ] block = Block(transactions=txs) conn.db.bigchain.insert_one(block.to_dict()) tx_db = query.get_transaction_from_block(conn, txs[0].id, block.id) assert tx_db == txs[0].to_dict() assert query.get_transaction_from_block(conn, txs[0].id, 'aaa') is None assert query.get_transaction_from_block(conn, 'aaa', block.id) is None
def test_get_spending_transactions(user_pk): from bigchaindb.backend import connect, query from bigchaindb.models import Block, Transaction conn = connect() out = [([user_pk], 1)] tx1 = Transaction.create([user_pk], out * 3) inputs = tx1.to_inputs() tx2 = Transaction.transfer([inputs[0]], out, tx1.id) tx3 = Transaction.transfer([inputs[1]], out, tx1.id) tx4 = Transaction.transfer([inputs[2]], out, tx1.id) block = Block([tx1, tx2, tx3, tx4]) conn.db.bigchain.insert_one(block.to_dict()) links = [inputs[0].fulfills.to_dict(), inputs[2].fulfills.to_dict()] res = list(query.get_spending_transactions(conn, links)) # tx3 not a member because input 1 not asked for assert res == [(block.id, tx2.to_dict()), (block.id, tx4.to_dict())]
def test_get_votes_by_block_id_and_voter(signed_create_tx, structurally_valid_vote): from bigchaindb.backend import connect, query from bigchaindb.models import Block conn = connect() # create and insert a block block = Block(transactions=[signed_create_tx]) conn.db.bigchain.insert_one(block.to_dict()) # create and insert some votes structurally_valid_vote['vote']['voting_for_block'] = block.id structurally_valid_vote['node_pubkey'] = 'aaa' conn.db.votes.insert_one(structurally_valid_vote) structurally_valid_vote['vote']['voting_for_block'] = block.id structurally_valid_vote['node_pubkey'] = 'bbb' structurally_valid_vote.pop('_id') conn.db.votes.insert_one(structurally_valid_vote) votes = list(query.get_votes_by_block_id_and_voter(conn, block.id, 'aaa')) assert len(votes) == 1 assert votes[0]['node_pubkey'] == 'aaa'
def test_block_invalid_serializaton(self): from bigchaindb.models import Block block = Block([]) with raises(ValueError): block.to_dict()
def main(): """ Main function """ ctx = {} def pretty_json(data): return json.dumps(data, indent=2, sort_keys=True) client = server.create_app().test_client() host = 'example.com:9984' # HTTP Index res = client.get('/', environ_overrides={'HTTP_HOST': host}) res_data = json.loads(res.data.decode()) res_data['keyring'] = [ "6qHyZew94NMmUTYyHnkZsB8cxJYuRNEiEpXHe1ih9QX3", "AdDuyrTyjrDt935YnFu4VBCVDhHtY2Y6rcy7x2TFeiRi" ] res_data['public_key'] = 'NC8c8rYcAhyKVpx1PCV65CBmyq4YUbLysy3Rqrg8L8mz' ctx['index'] = pretty_json(res_data) # API index res = client.get('/api/v1/', environ_overrides={'HTTP_HOST': host}) ctx['api_index'] = pretty_json(json.loads(res.data.decode())) # tx create privkey = 'CfdqtD7sS7FgkMoGPXw55MVGGFwQLAoHYTcBhZDtF99Z' pubkey = '4K9sWUMFwTgaDGPfdynrbxWqWS6sWmKbZoTjxLtVUibD' asset = {'msg': 'Hello BigchainDB!'} tx = Transaction.create([pubkey], [([pubkey], 1)], asset=asset, metadata={'sequence': 0}) tx = tx.sign([privkey]) ctx['tx'] = pretty_json(tx.to_dict()) ctx['public_keys'] = tx.outputs[0].public_keys[0] ctx['txid'] = tx.id # tx transfer privkey_transfer = '3AeWpPdhEZzWLYfkfYHBfMFC2r1f8HEaGS9NtbbKssya' pubkey_transfer = '3yfQPHeWAa1MxTX9Zf9176QqcpcnWcanVZZbaHb8B3h9' cid = 0 input_ = Input(fulfillment=tx.outputs[cid].fulfillment, fulfills=TransactionLink(txid=tx.id, output=cid), owners_before=tx.outputs[cid].public_keys) tx_transfer = Transaction.transfer([input_], [([pubkey_transfer], 1)], asset_id=tx.id, metadata={'sequence': 1}) tx_transfer = tx_transfer.sign([privkey]) ctx['tx_transfer'] = pretty_json(tx_transfer.to_dict()) ctx['public_keys_transfer'] = tx_transfer.outputs[0].public_keys[0] ctx['tx_transfer_id'] = tx_transfer.id # privkey_transfer_last = 'sG3jWDtdTXUidBJK53ucSTrosktG616U3tQHBk81eQe' pubkey_transfer_last = '3Af3fhhjU6d9WecEM9Uw5hfom9kNEwE7YuDWdqAUssqm' cid = 0 input_ = Input(fulfillment=tx_transfer.outputs[cid].fulfillment, fulfills=TransactionLink(txid=tx_transfer.id, output=cid), owners_before=tx_transfer.outputs[cid].public_keys) tx_transfer_last = Transaction.transfer([input_], [([pubkey_transfer_last], 1)], asset_id=tx.id, metadata={'sequence': 2}) tx_transfer_last = tx_transfer_last.sign([privkey_transfer]) ctx['tx_transfer_last'] = pretty_json(tx_transfer_last.to_dict()) ctx['tx_transfer_last_id'] = tx_transfer_last.id ctx['public_keys_transfer_last'] = tx_transfer_last.outputs[0].public_keys[ 0] # block node_private = "5G2kE1zJAgTajkVSbPAQWo4c2izvtwqaNHYsaNpbbvxX" node_public = "DngBurxfeNVKZWCEcDnLj1eMPAS7focUZTE5FndFGuHT" signature = "53wxrEQDYk1dXzmvNSytbCfmNVnPqPkDQaTnAe8Jf43s6ssejPxezkCvUnGTnduNUmaLjhaan1iRLi3peu6s5DzA" block = Block(transactions=[tx], node_pubkey=node_public, voters=[node_public], signature=signature) ctx['block'] = pretty_json(block.to_dict()) ctx['blockid'] = block.id block_transfer = Block(transactions=[tx_transfer], node_pubkey=node_public, voters=[node_public], signature=signature) ctx['block_transfer'] = pretty_json(block.to_dict()) # vote DUMMY_SHA3 = '0123456789abcdef' * 4 b = Bigchain(public_key=node_public, private_key=node_private) vote = b.vote(block.id, DUMMY_SHA3, True) ctx['vote'] = pretty_json(vote) # block status block_list = [block_transfer.id, block.id] ctx['block_list'] = pretty_json(block_list) base_path = os.path.join(os.path.dirname(__file__), 'source/http-samples') if not os.path.exists(base_path): os.makedirs(base_path) for name, tpl in TPLS.items(): path = os.path.join(base_path, name + '.http') code = tpl % ctx with open(path, 'w') as handle: handle.write(code)