class TestNode(TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.t = BlockchainDriver() self.c = MasterStorage() self.ctx = zmq.asyncio.Context() def tearDown(self): self.ctx.destroy() self.t.flush() self.c.drop_collections() self.loop.close() def test_catchup(self): fake_block_1 = {'blockNum': 1, 'subBlocks': []} fake_block_2 = {'blockNum': 2, 'subBlocks': []} self.c.store_block(fake_block_1) self.c.store_block(fake_block_2) mn_wallets = [Wallet() for _ in range(2)] dl_wallets = [Wallet() for _ in range(2)] constitution = { 'masternodes': [mn.verifying_key().hex() for mn in mn_wallets], 'delegates': [dl.verifying_key().hex() for dl in dl_wallets], 'masternode_min_quorum': 2, 'delegate_min_quorum': 2, } n = Node(socket_base='tcp://127.0.0.1', ctx=self.ctx, constitution=constitution, wallet=mn_wallets[0]) w = Wallet() m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500) tasks = asyncio.gather( m.serve(), n.catchup(SocketStruct.from_string('tcp://127.0.0.1:10004')), stop_server(m, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) print(res)
def setUp(self): self.ctx = zmq.asyncio.Context() self.loop = asyncio.get_event_loop() driver = BlockchainDriver() driver.flush()
class TestBlockServer(TestCase): def setUp(self): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.t = BlockchainDriver() self.ctx = zmq.asyncio.Context() def tearDown(self): self.ctx.destroy() self.t.flush() self.loop.close() def test_get_latest_block_height(self): w = Wallet() m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500, driver=self.t) self.t.set_latest_block_num(555) async def get(msg): socket = self.ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:10004') await socket.send(msg) res = await socket.recv() return res message = Message.get_signed_message_packed_2( wallet=w, msg_type=MessageType.LATEST_BLOCK_HEIGHT_REQUEST, timestamp=int(time.time())) tasks = asyncio.gather( m.serve(), get(message), stop_server(m, 0.2), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) msg_type, msg, sender, timestamp, is_verified = Message.unpack_message_2( res[1]) self.assertEqual(msg.blockHeight, 555) def test_get_latest_block_hash(self): w = Wallet() m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500) self.t.set_latest_block_hash(b'\xAA' * 32) async def get(msg): socket = self.ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:10004') await socket.send(msg) res = await socket.recv() return res message = Message.get_signed_message_packed_2( wallet=w, msg_type=MessageType.LATEST_BLOCK_HASH_REQUEST, timestamp=int(time.time())) tasks = asyncio.gather( m.serve(), get(message), stop_server(m, 0.2), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) msg_type, msg, sender, timestamp, is_verified = Message.unpack_message_2( res[1]) self.assertEqual(msg.hash, b'\xAA' * 32) def test_get_block_blob_by_block_data_request(self): block = random_txs.random_block() w = Wallet() c = CilantroStorageDriver(key=w.sk.encode().hex()) c.drop_collections() d = canonical.block_from_subblocks([s for s in block.subBlocks], previous_hash=b'x/00' * 32, block_num=0) d['blockOwners'] = [secrets.token_bytes(32) for _ in range(12)] c.put(d) del d['_id'] del d['blockOwners'] m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500, driver=c) async def get(msg): socket = self.ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:10004') await socket.send(msg) res = await socket.recv() return res message = Message.get_signed_message_packed_2( wallet=w, msg_type=MessageType.BLOCK_DATA_REQUEST, blockNum=0) tasks = asyncio.gather( m.serve(), get(message), stop_server(m, 0.2), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) msg_type, msg, sender, timestamp, is_verified = Message.unpack_message_2( res[1]) dd = canonical.block_from_subblocks([s for s in msg.subBlocks], previous_hash=b'x/00' * 32, block_num=0) self.assertDictEqual(d, dd) def test_get_block_blob_by_block_but_failure_returns_bad_request(self): w = Wallet() c = CilantroStorageDriver(key=w.sk.encode().hex()) c.drop_collections() m = BlockServer(w, 'tcp://127.0.0.1', self.ctx, linger=500, poll_timeout=500, driver=c) async def get(msg): socket = self.ctx.socket(zmq.DEALER) socket.connect('tcp://127.0.0.1:10004') await socket.send(msg) res = await socket.recv() return res message = Message.get_signed_message_packed_2( wallet=w, msg_type=MessageType.BLOCK_DATA_REQUEST, blockNum=0) tasks = asyncio.gather( m.serve(), get(message), stop_server(m, 1), ) loop = asyncio.get_event_loop() res = loop.run_until_complete(tasks) msg_type, msg, sender, timestamp, is_verified = Message.unpack_message_2( res[1]) self.assertEqual(msg_type, MessageType.BAD_REQUEST)
class TestTXValidity(TestCase): def setUp(self): self.nonce_manager = BlockchainDriver() self.nonce_manager.flush() def tearDown(self): self.nonce_manager.flush() def test_processor_incorrect_returns_false(self): w = Wallet() expected_processor = secrets.token_bytes(32) given_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=given_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionProcessorInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_processor_is_expected_but_nonce_is_incorrect_returns_false(self): w = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=1) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionNonceInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_processor_and_nonce_correct_increments_pending_nonce_by_one(self): w = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=10000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) pending_nonce = self.nonce_manager.get_pending_nonce(expected_processor, w.verifying_key()) self.assertEqual(pending_nonce, 1) def test_all_but_wallet_signed_returns_false(self): w = Wallet() x = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=0, processor=expected_processor, nonce=0) tx.sign(x.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionSignatureInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_all_but_proof_valid_returns_false(self): w = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=0, processor=expected_processor, nonce=0) tx.proof = b'\00' * 32 tx.proof_generated = True tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionPOWProofInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_processor_and_nonce_correct_but_not_enough_stamps_returns_false(self): w = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionSenderTooFewStamps): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, tx.payload.sender.hex()) balance = self.nonce_manager.get(balances_key) or 0 self.assertEqual(balance, 0) def test_all_valid_with_stamps_when_balance_is_set(self): w = Wallet() expected_processor = secrets.token_bytes(32) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, tx.payload.sender.hex()) self.nonce_manager.set(balances_key, 500000) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) balance = self.nonce_manager.get(balances_key) or 0 self.assertEqual(balance, 500000) def test_multiple_nonces_in_sequence_all_verify(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=1) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=2) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=3) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_non_sequence_fails_in_strict_mode(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=1) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=2) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=5) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionNonceInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_greater_than_passes_in_no_strict_mode(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=1) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=2) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=5) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager, strict=False) def test_non_strict_fails_if_same_nonce(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager, strict=False) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionNonceInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager, strict=False) def test_strict_fails_if_same_nonce(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionNonceInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_tx_nonce_minus_nonce_less_than_tx_per_block(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) self.nonce_manager.set_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=1) self.nonce_manager.set_pending_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=2) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=2) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_tx_nonce_minus_nonce_greater_than_tx_per_block_fails(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) self.nonce_manager.set_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=1) self.nonce_manager.set_pending_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=10) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=20) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionTooManyPendingException): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_nonce_minus_pending_nonce_equal_tx_per_block_fails(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) self.nonce_manager.set_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=1) self.nonce_manager.set_pending_nonce(processor=expected_processor, sender=w.verifying_key(), nonce=16) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=16) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionTooManyPendingException): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_15_in_row_valid_16th_not_due_to_tx_per_block_failing(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) for i in range(15): tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=i) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 10, 'to': 'jeff'}, stamps=500000, processor=expected_processor, nonce=15) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionTooManyPendingException): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_sending_transfer_of_all_money_fails(self): self.nonce_manager.set_var('stamp_cost', 'S', ['value'], value=3000) stamp_to_tau = self.nonce_manager.get_var('stamp_cost', 'S', ['value']) w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 500000, 'to': 'jeff'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionSenderTooFewStamps): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_sending_transfer_of_most_money_fails_if_only_one_transfer_in_stamps_left(self): self.nonce_manager.set_var('stamp_cost', 'S', ['value'], value=3000) stamp_to_tau = self.nonce_manager.get_var('stamp_cost', 'S', ['value']) w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 499999, 'to': 'jeff'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionSenderTooFewStamps): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_sending_transfer_of_most_money_doesnt_fail_if_enough_stamps(self): self.nonce_manager.set_var('stamp_cost', 'S', ['value'], value=3000) w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='currency', function='transfer', kwargs={'amount': 499990, 'to': 'jeff'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_submission_not_prepended_with_con_throws_error(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='submission', function='submit_contract', kwargs={'name': 'bad_name', 'code': 'blah'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionContractNameInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_submission_not_str_throws_error(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='submission', function='submit_contract', kwargs={'name': 123, 'code': 'blah'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) with self.assertRaises(transaction.TransactionContractNameInvalid): transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager) def test_submission_prepended_with_con_succeeds(self): w = Wallet() expected_processor = secrets.token_bytes(32) balances_key = '{}{}{}{}{}'.format('currency', config.INDEX_SEPARATOR, 'balances', config.DELIMITER, w.verifying_key().hex()) self.nonce_manager.set(balances_key, 500000) tx = TransactionBuilder(w.verifying_key(), contract='submission', function='submit_contract', kwargs={'name': 'con_bad_name', 'code': 'blah'}, stamps=3000, processor=expected_processor, nonce=0) tx.sign(w.signing_key()) tx_bytes = tx.serialize() tx_struct = transaction_capnp.NewTransaction.from_bytes_packed(tx_bytes) transaction_is_valid(tx=tx_struct, expected_processor=expected_processor, driver=self.nonce_manager)