def test_negative_balance(self): alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) stake_transaction = StakeTransaction.create(activation_blocknumber=0, xmss=alice_xmss, slavePK=slave_xmss.pk()) with self.assertRaises(ValueError): StakeValidator.create(-1, stake_transaction)
def test_empty_terminator(self): alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) stake_transaction = StakeTransaction.create(activation_blocknumber=0, xmss=alice_xmss, slavePK=slave_xmss.pk()) stake_transaction._data.stake.hash = bytes([]) with self.assertRaises(ValueError): StakeValidator.create(0, stake_transaction)
def test_invalid_balance(self): alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) stake_transaction = StakeTransaction.create(activation_blocknumber=0, xmss=alice_xmss, slavePK=slave_xmss.pk()) with self.assertRaises(ValueError): StakeValidator.create( config.dev.minimum_staking_balance_required - 1, stake_transaction)
def validate_hash(self, reveal_hash: bytes, block_idx: int, stake_address: bytes = None) -> bool: if stake_address not in self._data.sv_dict: return False sv = StakeValidator(self._data.sv_dict[stake_address]) result = sv.validate_hash(reveal_hash, block_idx) self._data.sv_dict[stake_address].CopyFrom(sv.pbdata) return result
def to_object(json_svl): dict_svl = json.loads(json_svl) svl = StakeValidatorsList() svl.sv_list = dict_svl['sv_list'] for sv in svl.sv_list: svl.sv_list[sv] = StakeValidator.to_object(sv) svl.next_sv_list = dict_svl['next_sv_list'] for sv in svl.next_sv_list: svl.sv_list[sv] = StakeValidator.to_object(sv) return svl
def _add_future_sv(self, balance, stake_txn): if stake_txn.txfrom in self._future_sv_dict: logger.info('Stake Validator already in Future Staker, future_sv_dict') return sv = StakeValidator(balance, stake_txn) self.future_stake_addresses[stake_txn.txfrom] = sv self._future_sv_dict[stake_txn.activation_blocknumber].add(sv)
def test_create(self): 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) h2 = sha256(h1) stake_transaction = StakeTransaction.create(activation_blocknumber=0, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h2) sv = StakeValidator(100, stake_transaction) self.assertEqual(staking_address, sv.address) self.assertEqual(slave_xmss.pk(), sv.slave_public_key) self.assertEqual(h2, sv.terminator_hash) self.assertEqual(100, sv.balance) self.assertEqual(0, sv.nonce) self.assertFalse(sv.is_banned) self.assertTrue(sv.is_active)
def validate_hash(self, hash, blocknum, target_chain=config.dev.hashchain_nums - 1, stake_address=None): epoch_blocknum = StakeValidator.get_epoch_blocknum(blocknum) if hash in self.hash_staker: if stake_address and stake_address != self.hash_staker[hash]: return False return True if stake_address: if stake_address not in self.sv_list: return False sv = self.sv_list[stake_address] return sv.validate_hash(hash, blocknum, self.hash_staker, target_chain) tmp = hash count = epoch_blocknum while count >= -1: tmp = sha256(tmp) if tmp in self.hash_staker: stake_address = self.hash_staker[tmp] sv = self.sv_list[stake_address] sv.update(epoch_blocknum, hash, target_chain, self.hash_staker) return True count -= 1 return False
def _activate_sv(self, balance, stake_txn): if stake_txn.txfrom in self.sv_dict: logger.info('Stake Validator already in Current Staker, sv_dict') return sv = StakeValidator(balance, stake_txn) self.sv_dict[stake_txn.txfrom] = sv self._total_stake_amount += sv.balance self._expiry[stake_txn.activation_blocknumber + config.dev.blocks_per_epoch].add(stake_txn.txfrom)
def test_getStakers(self): db_state = Mock(spec=State) db_state.stake_validators_tracker = Mock(spec=StakeValidatorsTracker) db_state.stake_validators_tracker.sv_dict = dict() p2p_factory = Mock(spec=P2PFactory) buffered_chain = Mock(spec=BufferedChain) buffered_chain.tx_pool = Mock() buffered_chain.get_block = Mock() buffered_chain._chain = Mock() qrlnode = QRLNode(db_state) qrlnode.set_p2pfactory(p2p_factory) qrlnode.set_chain(buffered_chain) service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) request = qrl_pb2.GetStakersReq(filter=qrl_pb2.GetStakersReq.CURRENT, offset=0, quantity=3) response = service.GetStakers(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertEqual(0, len(response.stakers)) # Add a few validators stake_tx = StakeTransaction.create(1, get_alice_xmss(), get_bob_xmss().pk(), sha256(b'terminator')) expected_address = bytes(get_alice_xmss().get_address().encode()) db_state.get_address = MagicMock( return_value=AddressState.create(address=expected_address, nonce=1, balance=100, pubhashes=[], tokens=dict())) db_state.get_address_tx_hashes = MagicMock(return_value=[]) validator1 = StakeValidator.create(100, stake_tx) db_state.stake_validators_tracker.sv_dict[ validator1.address] = validator1 request = qrl_pb2.GetStakersReq(filter=qrl_pb2.GetStakersReq.CURRENT, offset=0, quantity=3) response = service.GetStakers(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertEqual(1, len(response.stakers)) self.assertEqual(expected_address, response.stakers[0].address_state.address)
def _activate_sv(self, balance, stake_txn): if stake_txn.txfrom in self.sv_dict: logger.info('Stake Validator already in Current Staker, sv_dict') return sv = StakeValidator.create(balance, stake_txn) self._data.sv_dict[stake_txn.txfrom].MergeFrom(sv.pbdata) self._data.total_stake_amount += sv.balance self._data.expiry[stake_txn.activation_blocknumber + config.dev.blocks_per_epoch].addresses.extend( [stake_txn.txfrom])
def _add_future_sv(self, balance, stake_txn): if stake_txn.txfrom in self._data.future_stake_addresses: logger.info( 'Stake Validator already in Future Staker, future_sv_dict') return sv = StakeValidator.create(balance, stake_txn) self._data.future_stake_addresses[stake_txn.txfrom].MergeFrom( sv.pbdata) self._data.future_sv_dict[ stake_txn.activation_blocknumber].stake_validators.extend( [sv.pbdata])
def test_create2(self): alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) h0 = sha256(b'hashchain_seed') h1 = sha256(h0) h2 = sha256(h1) h3 = sha256(h2) stake_transaction = StakeTransaction.create(activation_blocknumber=0, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h3) sv = StakeValidator(100, stake_transaction) self.assertTrue(sv.validate_hash(h0, 2)) self.assertTrue(sv.validate_hash(h2, 0)) self.assertTrue(sv.validate_hash(h2, 0)) self.assertTrue(sv.validate_hash(h1, 1)) self.assertTrue(sv.validate_hash(h0, 2))
def __add__(self, sv_list, txfrom, slave_public_key, hash, first_hash, balance): sv = StakeValidator(txfrom, slave_public_key, hash, first_hash, balance) sv_list[txfrom] = sv return sv