def test_add_vote3(self): vote_tracker = VoteTracker() validator_xmss1 = get_alice_xmss() slave_xmss1 = XMSS(validator_xmss1.height, validator_xmss1.get_seed()) stake_amount1 = 101.5012 headerhash1 = b'ffff' vote1 = Vote.create(addr_from=validator_xmss1.get_address().encode(), blocknumber=0, headerhash=headerhash1, xmss=slave_xmss1) vote1.sign(slave_xmss1) self.assertTrue(vote_tracker.add_vote(vote1, stake_amount1)) validator_xmss2 = get_random_xmss() slave_xmss2 = XMSS(validator_xmss2.height, validator_xmss2.get_seed()) headerhash2 = b'aaaa' stake_amount2 = 10000 vote2 = Vote.create(addr_from=validator_xmss2.get_address().encode(), blocknumber=0, headerhash=headerhash2, xmss=slave_xmss2) vote2.sign(slave_xmss2) self.assertTrue(vote_tracker.add_vote(vote2, stake_amount2)) vote_metadata = vote_tracker.get_consensus() self.assertNotEqual(vote_metadata, None) self.assertEqual(stake_amount2, vote_metadata.total_stake_amount) self.assertNotEqual(vote_tracker.get_consensus_headerhash(), headerhash1) self.assertEqual(vote_tracker.get_consensus_headerhash(), headerhash2)
def test_add_vote2(self): validator_xmss1 = get_alice_xmss() slave_xmss1 = XMSS(validator_xmss1.height, validator_xmss1.get_seed()) stake_amount1 = 101.5012 headerhash1 = b'ffff' vote1 = Vote.create(addr_from=validator_xmss1.get_address().encode(), blocknumber=0, headerhash=headerhash1, xmss=slave_xmss1) vote1.sign(slave_xmss1) vote_metadata = VoteMetadata() vote_metadata.add_vote(vote=vote1, stake_amount=stake_amount1) self.assertIn(vote1.txfrom, vote_metadata.stake_validator_vote) validator_xmss2 = get_random_xmss() slave_xmss2 = XMSS(validator_xmss2.height, validator_xmss2.get_seed()) stake_amount2 = 10000 headerhash2 = b'ffff' vote2 = Vote.create(addr_from=validator_xmss2.get_address().encode(), blocknumber=0, headerhash=headerhash2, xmss=slave_xmss2) vote2.sign(slave_xmss2) vote_metadata.add_vote(vote=vote2, stake_amount=stake_amount2) self.assertIn(vote2.txfrom, vote_metadata.stake_validator_vote) total_stake_amount = stake_amount1 + stake_amount2 self.assertEqual(total_stake_amount, vote_metadata.total_stake_amount)
def test_add_vote1(self): vote_tracker = VoteTracker() alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) headerhash = b'ffff' vote = Vote.create(addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=headerhash, xmss=slave_xmss) vote.sign(slave_xmss) stake_amount = 101.5012 self.assertFalse(vote_tracker.is_already_voted(vote)) self.assertTrue(vote_tracker.add_vote(vote, stake_amount)) self.assertFalse(vote_tracker.add_vote(vote, stake_amount)) self.assertTrue(vote_tracker.is_already_voted(vote)) vote_metadata = vote_tracker.get_consensus() self.assertNotEqual(vote_metadata, None) self.assertIn(vote.addr_from, vote_metadata.stake_validator_vote) self.assertEqual(vote, vote_metadata.stake_validator_vote[vote.addr_from]) self.assertEqual(stake_amount, vote_metadata.total_stake_amount) self.assertEqual(vote_tracker.get_consensus_headerhash(), headerhash)
def pre_pos_1(self, data=None): # triggered after genesis for block 1.. logger.info('pre_pos_1') # are we a staker in the stake list? genesis_block = self.buffered_chain.get_block(0) found = False for genesisBalance in genesis_block.genesis_balance: if genesisBalance.address.encode( ) == self.buffered_chain.staking_address: logger.info('Found in Genesis Address %s %s', genesisBalance.address.encode(), genesisBalance.balance) found = True break if not found: return logger.info('mining address: %s in the genesis.stake_list', self.buffered_chain.staking_address) xmss = self.buffered_chain.wallet.address_bundle[0].xmss tmphc = hashchain(xmss.get_seed_private(), epoch=0) self.buffered_chain.hash_chain[0] = tmphc.hashchain slave_xmss = self.buffered_chain.get_slave_xmss(0) if not slave_xmss: logger.info('Waiting for SLAVE XMSS to be done') reactor.callLater(5, self.pre_pos_1) return signing_xmss = self.buffered_chain.wallet.address_bundle[0].xmss st = StakeTransaction.create(activation_blocknumber=1, xmss=signing_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=tmphc.hc_terminator) st.sign(signing_xmss) self.buffered_chain.tx_pool.add_tx_to_pool(st) # send the stake tx to generate hashchain terminators for the staker addresses.. self.p2p_factory.broadcast_st(st) vote = Vote.create( addr_from=self.buffered_chain.wallet.address_bundle[0].address, blocknumber=0, headerhash=genesis_block.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) self.buffered_chain.add_vote(vote) # send the stake votes for genesis block self.p2p_factory.broadcast_vote(vote) logger.info('await delayed call to build staker list from genesis') reactor.callLater(5, self.pre_pos_2, st)
def test_add_vote1(self): alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) headerhash = b'ffff' vote = Vote.create(addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=headerhash, xmss=slave_xmss) vote.sign(slave_xmss) stake_amount = 101.5012 vote_metadata = VoteMetadata() self.assertNotIn(vote.txfrom, vote_metadata.stake_validator_vote) vote_metadata.add_vote(vote=vote, stake_amount=stake_amount) self.assertIn(vote.txfrom, vote_metadata.stake_validator_vote) self.assertEqual(stake_amount, vote_metadata.total_stake_amount)
def create_vote_tx(self, blocknumber: int): block = self.buffered_chain.get_block(blocknumber) if not block: logger.warning('Block #%s not found, cancelled voting', blocknumber) return signing_xmss = self.buffered_chain.get_slave_xmss(blocknumber) if not signing_xmss: logger.warning( 'Skipped Voting: Slave XMSS none, XMSS POOL might still be generating slave_xmss' ) return vote = Vote.create( addr_from=self.buffered_chain.wallet.address_bundle[0].address, blocknumber=blocknumber, headerhash=block.blockheader.headerhash, xmss=signing_xmss) vote.sign(signing_xmss) # FIXME: Temporary fix, need to add ST txn into Genesis if blocknumber > 1: tx_state = self.buffered_chain.get_stxn_state( blocknumber + 1, vote.addr_from) stake_validators_tracker = self.buffered_chain.get_stake_validators_tracker( blocknumber) if not (vote.validate() and vote.validate_extended( tx_state, stake_validators_tracker.sv_dict)): logger.warning( 'Create Vote Txn failed due to validation failure') return self.buffered_chain.set_voted(blocknumber) self.buffered_chain.add_vote(vote) self.p2p_factory.broadcast_vote(vote)
def test_from_txdict(self): tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash, self.alice) self.assertIsInstance(tx, Vote) # Test that common Transaction components were copied over. self.assertEqual(0, tx.nonce) self.assertEqual( b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2', tx.txfrom) self.assertEqual( '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77' 'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5', bin2hstr(tx.PK)) self.assertEqual(11, tx.ots_key) self.assertEqual(b'', tx.signature) self.assertEqual( '1a1274bedfc53287853c3aea5b8a93d64f2e4dff23ddbf96e52c8033f0107154', bin2hstr(tx.pubhash)) self.assertEqual( 'b77410e48e9d8ee140c8b49d6331152e090fe3acc5dcd7e4cd3b4ea6bf8c3839', bin2hstr(tx.txhash))
def test_add_2(self): destroy_state() with State() as state: with set_wallet_dir("test_wallet"): chain = Chain(state) buffered_chain = BufferedChain(chain) alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) staking_address = bytes(alice_xmss.get_address().encode()) h0 = sha256(b'hashchain_seed') h1 = sha256(h0) with mocked_genesis() as custom_genesis: custom_genesis.genesis_balance.extend([ qrl_pb2.GenesisBalance( address=alice_xmss.get_address(), balance=700000000000000) ]) res = buffered_chain.add_block(block=custom_genesis) self.assertTrue(res) stake_transaction = StakeTransaction.create( activation_blocknumber=1, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h1) vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=custom_genesis.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(0) # FIXME: The test needs private access.. This is an API issue stake_transaction._data.nonce = 1 stake_transaction.sign(alice_xmss) chain.pstate.stake_validators_tracker.add_sv( balance=700000000000000, stake_txn=stake_transaction, blocknumber=1) sv = chain.pstate.stake_validators_tracker.sv_dict[ staking_address] self.assertEqual(0, sv.nonce) tmp_block = Block.create( staking_address=bytes( alice_xmss.get_address().encode()), block_number=1, reveal_hash=h0, prevblock_headerhash=custom_genesis.headerhash, transactions=[stake_transaction], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=alice_xmss, nonce=1) res = buffered_chain.add_block(block=tmp_block) self.assertTrue(res)
def test_add_4(self): destroy_state() with State() as state: with set_wallet_dir("test_wallet"): chain = Chain(state) buffered_chain = BufferedChain(chain) alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) random_xmss1 = get_random_xmss() random_xmss2 = get_random_xmss() staking_address = bytes(alice_xmss.get_address().encode()) # FIXME: Replace this with a call to create a hash_chain h0 = sha256(b'hashchain_seed') h1 = sha256(h0) h2 = sha256(h1) h3 = sha256(h2) h4 = sha256(h3) with mocked_genesis() as custom_genesis: custom_genesis.genesis_balance.extend([ qrl_pb2.GenesisBalance( address=alice_xmss.get_address(), balance=700000000000000) ]) res = buffered_chain.add_block(block=GenesisBlock()) self.assertTrue(res) stake_transaction = StakeTransaction.create( activation_blocknumber=1, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h4) stake_transaction._data.nonce = 1 # FIXME: The test needs private access.. This is an API issue stake_transaction.sign(alice_xmss) vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=GenesisBlock().headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(0) chain.pstate.stake_validators_tracker.add_sv( balance=700000000000000, stake_txn=stake_transaction, blocknumber=1) sv = chain.pstate.stake_validators_tracker.sv_dict[ staking_address] self.assertEqual(0, sv.nonce) # Token Transaction to create a token for test token_transaction = get_token_transaction( random_xmss1, random_xmss2) token_transaction._data.nonce = 1 token_transaction.sign(random_xmss1) # Transfer Token Transaction transfer_token1 = TransferTokenTransaction.create( addr_from=random_xmss1.get_address().encode(), token_txhash=token_transaction.txhash, addr_to=alice_xmss.get_address().encode(), amount=100000000, fee=1, xmss_pk=random_xmss1.pk(), xmss_ots_index=random_xmss1.get_index()) transfer_token1._data.nonce = 2 transfer_token1.sign(random_xmss1) transfer_token2 = TransferTokenTransaction.create( addr_from=random_xmss2.get_address().encode(), token_txhash=token_transaction.txhash, addr_to=alice_xmss.get_address().encode(), amount=200000000, fee=1, xmss_pk=random_xmss2.pk(), xmss_ots_index=random_xmss2.get_index()) transfer_token2._data.nonce = 1 transfer_token2.sign(random_xmss2) # Transfer Coin Transaction transfer_transaction = TransferTransaction.create( addr_from=random_xmss1.get_address().encode(), addr_to=random_xmss2.get_address().encode(), amount=10, fee=1, xmss_pk=random_xmss1.pk(), xmss_ots_index=random_xmss1.get_index()) transfer_transaction._data.nonce = 3 transfer_transaction.sign(random_xmss1) tmp_block1 = Block.create( staking_address=staking_address, block_number=1, reveal_hash=h3, prevblock_headerhash=GenesisBlock().headerhash, transactions=[stake_transaction, token_transaction], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=1) res = buffered_chain.add_block(block=tmp_block1) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=1, headerhash=tmp_block1.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(1) tmp_block2 = Block.create( staking_address=staking_address, block_number=2, reveal_hash=h2, prevblock_headerhash=tmp_block1.headerhash, transactions=[ transfer_token1, transfer_token2, transfer_transaction ], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=2) res = buffered_chain.add_block(block=tmp_block2) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=2, headerhash=tmp_block2.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(2) tmp_block3 = Block.create( staking_address=staking_address, block_number=3, reveal_hash=h1, prevblock_headerhash=tmp_block2.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=3) res = buffered_chain.add_block(block=tmp_block3) self.assertTrue(res) chain = buffered_chain._chain random_xmss1_state = chain.pstate._get_address_state( random_xmss1.get_address().encode()) random_xmss2_state = chain.pstate._get_address_state( random_xmss2.get_address().encode()) self.assertEqual( random_xmss1_state.tokens[bin2hstr( token_transaction.txhash).encode()], 400000000) self.assertEqual( random_xmss2_state.tokens[bin2hstr( token_transaction.txhash).encode()], 200000000) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block3.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=3, headerhash=tmp_block3.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(3) tmp_block4 = Block.create( staking_address=staking_address, block_number=4, reveal_hash=h0, prevblock_headerhash=tmp_block3.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=4) res = buffered_chain.add_block(block=tmp_block4) self.assertTrue(res) token_metadata = buffered_chain.get_token_metadata( token_transaction.txhash) self.assertEqual(token_metadata.token_txhash, token_transaction.txhash) self.assertEqual( len(token_metadata.transfer_token_tx_hashes), 3) self.assertEqual( token_metadata.transfer_token_tx_hashes[0], token_transaction.txhash) random_xmss1_state = chain.pstate._get_address_state( random_xmss1.get_address().encode()) random_xmss2_state = chain.pstate._get_address_state( random_xmss2.get_address().encode()) alice_state = chain.pstate._get_address_state( alice_xmss.get_address().encode()) self.assertEqual( random_xmss1_state.tokens[bin2hstr( token_transaction.txhash).encode()], 300000000) self.assertEqual( random_xmss2_state.tokens[bin2hstr( token_transaction.txhash).encode()], 0) self.assertEqual( alice_state.tokens[bin2hstr( token_transaction.txhash).encode()], 300000000) self.assertEqual(random_xmss1_state.balance, config.dev.default_account_balance - 13) self.assertEqual(random_xmss2_state.balance, config.dev.default_account_balance + 9)
def test_add_3(self): destroy_state() with State() as state: with set_wallet_dir("test_wallet"): chain = Chain(state) buffered_chain = BufferedChain(chain) alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) staking_address = bytes(alice_xmss.get_address().encode()) # FIXME: Replace this with a call to create a hash_chain h0 = sha256(b'hashchain_seed') h1 = sha256(h0) h2 = sha256(h1) h3 = sha256(h2) with mocked_genesis() as custom_genesis: custom_genesis.genesis_balance.extend([ qrl_pb2.GenesisBalance( address=alice_xmss.get_address(), balance=700000000000000) ]) res = buffered_chain.add_block(block=GenesisBlock()) self.assertTrue(res) stake_transaction = StakeTransaction.create( activation_blocknumber=1, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h3) stake_transaction._data.nonce = 1 # FIXME: The test needs private access.. This is an API issue stake_transaction.sign(alice_xmss) vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=GenesisBlock().headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(0) chain.pstate.stake_validators_tracker.add_sv( balance=700000000000000, stake_txn=stake_transaction, blocknumber=1) sv = chain.pstate.stake_validators_tracker.sv_dict[ staking_address] self.assertEqual(0, sv.nonce) tmp_block1 = Block.create( staking_address=staking_address, block_number=1, reveal_hash=h2, prevblock_headerhash=GenesisBlock().headerhash, transactions=[stake_transaction], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=1) res = buffered_chain.add_block(block=tmp_block1) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=1, headerhash=tmp_block1.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(1) tmp_block2 = Block.create( staking_address=staking_address, block_number=2, reveal_hash=h1, prevblock_headerhash=tmp_block1.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=2) res = buffered_chain.add_block(block=tmp_block2) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=2, headerhash=tmp_block2.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(2) tmp_block3 = Block.create( staking_address=staking_address, block_number=3, reveal_hash=h0, prevblock_headerhash=tmp_block2.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=3) res = buffered_chain.add_block(block=tmp_block3) self.assertTrue(res)
def broadcast_vote(self, vote: Vote): logger.info('<<<Transmitting Vote Txn: %s', vote.blocknumber) self.register_and_broadcast('VT', vote.get_message_hash(), vote.to_json())
def test_to_json(self): tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash, self.alice) txjson = tx.to_json() print(txjson) self.assertEqual(json.loads(test_json_Vote), json.loads(txjson))
def test_create(self): tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash, self.alice) self.assertIsInstance(tx, Vote)