def test_recover_db_from_zombie_block(b, monkeypatch): from bigchaindb.commands.bigchaindb import run_recover from bigchaindb.models import Transaction from bigchaindb.common.crypto import generate_key_pair from bigchaindb.tendermint.lib import Block from bigchaindb import backend alice = generate_key_pair() tx = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}, metadata={'name': 'hohenheim'}) \ .sign([alice.private_key]) b.store_bulk_transactions([tx]) block9 = Block(app_hash='random_app_hash', height=9, transactions=[])._asdict() b.store_block(block9) block10 = Block(app_hash='random_app_hash', height=10, transactions=[tx.id])._asdict() b.store_block(block10) def mock_get(uri): return MockResponse(9) monkeypatch.setattr('requests.get', mock_get) run_recover(b) assert list(backend.query.get_metadata(b.connection, [tx.id])) == [] assert not backend.query.get_asset(b.connection, tx.id) assert not b.get_transaction(tx.id) block = b.get_latest_block() assert block['height'] == 9
def test_store_block(): from bigchaindb.backend import connect, query from bigchaindb.tendermint.lib import Block conn = connect() block = Block(app_hash='random_utxo', height=3, transactions=[]) query.store_block(conn, block._asdict()) cursor = conn.db.blocks.find({}, projection={'_id': False}) assert cursor.count() == 1
def test_get_block(): from bigchaindb.backend import connect, query from bigchaindb.tendermint.lib import Block conn = connect() block = Block(app_hash='random_utxo', height=3, transactions=[]) conn.db.blocks.insert_one(block._asdict()) block = dict(query.get_block(conn, 3)) assert block['height'] == 3
def commit(self): """Store the new height and along with block hash.""" # register a new block only when new transactions are received if self.block_txn_ids: self.bigchaindb.store_bulk_transactions(self.block_transactions) block = Block(app_hash=self.block_txn_hash, height=self.new_height, transactions=self.block_txn_ids) self.bigchaindb.store_block(block._asdict()) data = self.block_txn_hash.encode('utf-8') return Result.ok(data=data)
def test_get_block_containing_transaction(tb, client): b = tb tx = Transaction.create([b.me], [([b.me], 1)], asset={'cycle': 'hero'}) tx = tx.sign([b.me_private]) b.store_transaction(tx) block = Block(app_hash='random_utxo', height=13, transactions=[tx.id]) b.store_block(block._asdict()) res = client.get('{}?transaction_id={}'.format(BLOCKS_ENDPOINT, tx.id)) expected_response = [block.height] assert res.json == expected_response assert res.status_code == 200
def inputs(user_pk, b, alice): from bigchaindb.models import Transaction # create blocks with transactions for `USER` to spend for block in range(4): transactions = [ Transaction.create( [alice_pubkey(alice)], [([user_pk], 1)], metadata={'msg': random.random()}, ).sign([alice_privkey(alice)]).to_dict() for _ in range(10) ] block = Block(app_hash='', height=_get_height(b), transactions=transactions) b.store_block(block._asdict())
def test_delete_latest_block(signed_create_tx, signed_transfer_tx): from bigchaindb.backend import connect, query from bigchaindb.tendermint.lib import Block conn = connect() conn.db.transactions.insert_one(signed_create_tx.to_dict()) query.store_asset(conn, {'id': signed_create_tx.id}) block = Block(app_hash='random_utxo', height=51, transactions=[signed_create_tx.id]) query.store_block(conn, block._asdict()) query.delete_latest_block(conn) assert query.get_transaction(conn, signed_create_tx.id) is None assert query.get_asset(conn, signed_create_tx.id) is None assert query.get_block(conn, 51) is None
def commit(self): """Store the new height and along with block hash.""" data = self.block_txn_hash.encode('utf-8') # register a new block only when new transactions are received if self.block_txn_ids: self.bigchaindb.store_bulk_transactions(self.block_transactions) block = Block(app_hash=self.block_txn_hash, height=self.new_height, transactions=self.block_txn_ids) # NOTE: storing the block should be the last operation during commit # this effects crash recovery. Refer BEP#8 for details self.bigchaindb.store_block(block._asdict()) return Result.ok(data=data)
def test_get_block_endpoint(tb, client): b = tb tx = Transaction.create([b.me], [([b.me], 1)], asset={'cycle': 'hero'}) tx = tx.sign([b.me_private]) b.store_transaction(tx) block = Block(app_hash='random_utxo', height=31, transactions=[tx.id]) b.store_block(block._asdict()) res = client.get(BLOCKS_ENDPOINT + str(block.height)) expected_response = { 'height': block.height, 'transactions': [tx.to_dict()] } assert res.json == expected_response assert res.status_code == 200
def inputs_shared(user_pk, user2_pk): from bigchaindb.models import Transaction # create blocks with transactions for `USER` to spend for block in range(4): transactions = [ Transaction.create( [b.me], [user_pk, user2_pk], metadata={ 'msg': random.random() }, ).sign([b.me_private]).to_dict() for _ in range(10) ] block = Block(app_hash='', height=_get_height(b), transaction=transactions) b.store_block(block._asdict())
def commit(self): """Store the new height and along with block hash.""" data = self.block_txn_hash.encode('utf-8') # register a new block only when new transactions are received if self.block_txn_ids: self.bigchaindb.store_bulk_transactions(self.block_transactions) block = Block(app_hash=self.block_txn_hash, height=self.new_height, transactions=self.block_txn_ids) # NOTE: storing the block should be the last operation during commit # this effects crash recovery. Refer BEP#8 for details self.bigchaindb.store_block(block._asdict()) logger.debug( 'Commit-ing new block with hash: apphash=%s ,' 'height=%s, txn ids=%s', data, self.new_height, self.block_txn_ids) logger.benchmark('COMMIT_BLOCK, height:%s', self.new_height) return data
def test_run_recover(b, alice, bob): from bigchaindb.commands.bigchaindb import run_recover from bigchaindb.models import Transaction from bigchaindb.tendermint.lib import Block, PreCommitState from bigchaindb.backend.query import PRE_COMMIT_ID from bigchaindb.backend import query tx1 = Transaction.create([alice.public_key], [([alice.public_key], 1)], asset={'cycle': 'hero'}, metadata={'name': 'hohenheim'}) \ .sign([alice.private_key]) tx2 = Transaction.create([bob.public_key], [([bob.public_key], 1)], asset={'cycle': 'hero'}, metadata={'name': 'hohenheim'}) \ .sign([bob.private_key]) # store the transactions b.store_bulk_transactions([tx1, tx2]) # create a random block block8 = Block(app_hash='random_app_hash1', height=8, transactions=['txid_doesnt_matter'])._asdict() b.store_block(block8) # create the next block block9 = Block(app_hash='random_app_hash1', height=9, transactions=[tx1.id])._asdict() b.store_block(block9) # create a pre_commit state which is ahead of the commit state pre_commit_state = PreCommitState(commit_id=PRE_COMMIT_ID, height=10, transactions=[tx2.id])._asdict() b.store_pre_commit_state(pre_commit_state) run_recover(b) assert not query.get_transaction(b.connection, tx2.id)
def test_get_latest_block(tb): from bigchaindb.tendermint.lib import Block b = tb for i in range(10): app_hash = os.urandom(16).hex() txn_id = os.urandom(16).hex() block = Block(app_hash=app_hash, height=i, transactions=[txn_id])._asdict() b.store_block(block) block = b.get_latest_block() assert block['height'] == 9
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())