test_base.py (11668B)
1 # standard imports 2 import unittest 3 import logging 4 import os 5 from chainlib.eth.nonce import RPCNonceOracle 6 from chainlib.eth.tx import receipt 7 from chainlib.eth.block import block_latest 8 from hexathon import same as same_hex 9 from eth_erc20 import ERC20 10 from giftable_erc20_token import GiftableToken 11 12 # local imports 13 from evm_tokenvote.unittest import TestEvmVoteProposal 14 from evm_tokenvote.unittest.base import hash_of_foo 15 from evm_tokenvote import Voter 16 from evm_tokenvote import ProposalState 17 18 19 logging.basicConfig(level=logging.DEBUG) 20 logg = logging.getLogger() 21 22 class TestVoteBase(TestEvmVoteProposal): 23 24 def test_propose(self): 25 c = Voter(self.chain_spec) 26 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 27 r = self.rpc.do(o) 28 proposal = c.parse_proposal(r) 29 self.assertTrue(same_hex(proposal.description_digest, hash_of_foo)) 30 self.assertEqual(proposal.supply, self.supply) 31 self.assertEqual(proposal.total, 0) 32 self.assertEqual(proposal.block_deadline, self.proposal_block_height + 100) 33 self.assertEqual(proposal.target_vote_ppm, 500000) 34 self.assertTrue(same_hex(proposal.proposer, self.ivan)) 35 self.assertEqual(proposal.state, ProposalState.INIT) 36 37 o = c.current_proposal(self.voter_address, sender_address=self.accounts[0]) 38 r = self.rpc.do(o) 39 proposal = c.parse_proposal(r) 40 self.assertTrue(same_hex(proposal.description_digest, hash_of_foo)) 41 self.assertEqual(proposal.supply, self.supply) 42 self.assertEqual(proposal.total, 0) 43 self.assertEqual(proposal.block_deadline, self.proposal_block_height + 100) 44 self.assertEqual(proposal.target_vote_ppm, 500000) 45 self.assertTrue(same_hex(proposal.proposer, self.ivan)) 46 self.assertEqual(proposal.state, ProposalState.INIT) 47 48 49 50 def test_vote(self): 51 nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) 52 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 53 (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) 54 self.rpc.do(o) 55 o = receipt(tx_hash) 56 r = self.rpc.do(o) 57 self.assertEqual(r['status'], 0) 58 59 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 60 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 61 (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, 100) 62 self.rpc.do(o) 63 64 nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) 65 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 66 o = c.get_proposal(self.voter_address, 0, sender_address=self.alice) 67 r = self.rpc.do(o) 68 proposal = c.parse_proposal(r) 69 self.assertEqual(proposal.total, 0) 70 71 # vote does not work without approval 72 (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) 73 self.rpc.do(o) 74 o = receipt(tx_hash) 75 r = self.rpc.do(o) 76 self.assertEqual(r['status'], 0) 77 78 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 79 (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, 100) 80 self.rpc.do(o) 81 82 # vote can be called multiple times (up to balance) 83 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 84 (tx_hash, o) = c.vote(self.voter_address, self.alice, 10) 85 self.rpc.do(o) 86 o = receipt(tx_hash) 87 r = self.rpc.do(o) 88 self.assertEqual(r['status'], 1) 89 90 (tx_hash, o) = c.vote(self.voter_address, self.alice, 90) 91 self.rpc.do(o) 92 o = receipt(tx_hash) 93 r = self.rpc.do(o) 94 self.assertEqual(r['status'], 1) 95 96 # vote total is updated 97 o = c.get_proposal(self.voter_address, 0, sender_address=self.alice) 98 r = self.rpc.do(o) 99 proposal = c.parse_proposal(r) 100 self.assertEqual(proposal.total, 100) 101 102 # fail because all votes used 103 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 104 (tx_hash, o) = c.vote(self.voter_address, self.alice, 1) 105 self.rpc.do(o) 106 o = receipt(tx_hash) 107 r = self.rpc.do(o) 108 self.assertEqual(r['status'], 0) 109 110 111 def test_vote_win(self): 112 half_supply = self.initial_supply / 2 113 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 114 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 115 (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, half_supply) 116 self.rpc.do(o) 117 118 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 119 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 120 (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, half_supply) 121 self.rpc.do(o) 122 123 nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) 124 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 125 (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, half_supply) 126 self.rpc.do(o) 127 128 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 129 (tx_hash, o) = c.vote(self.voter_address, self.alice, half_supply - 1) 130 self.rpc.do(o) 131 132 # no majority and deadline not reached 133 nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn) 134 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 135 (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) 136 self.rpc.do(o) 137 o = receipt(tx_hash) 138 r = self.rpc.do(o) 139 self.assertEqual(r['status'], 0) 140 141 nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) 142 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 143 (tx_hash, o) = c.vote(self.voter_address, self.alice, 1) 144 self.rpc.do(o) 145 146 self.backend.mine_blocks(100) 147 148 # majority, but not cancel, we care about deadline 149 nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn) 150 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 151 (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) 152 self.rpc.do(o) 153 o = receipt(tx_hash) 154 r = self.rpc.do(o) 155 self.assertEqual(r['status'], 1) 156 157 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 158 r = self.rpc.do(o) 159 proposal = c.parse_proposal(r) 160 self.assertEqual(proposal.state & ProposalState.INIT, ProposalState.INIT) 161 162 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 163 (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) 164 self.rpc.do(o) 165 o = receipt(tx_hash) 166 r = self.rpc.do(o) 167 self.assertEqual(r['status'], 1) 168 169 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 170 r = self.rpc.do(o) 171 proposal = c.parse_proposal(r) 172 self.assertEqual(proposal.state & ProposalState.SCANNED, ProposalState.SCANNED) 173 174 (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent) 175 self.rpc.do(o) 176 o = receipt(tx_hash) 177 r = self.rpc.do(o) 178 self.assertEqual(r['status'], 1) 179 180 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 181 r = self.rpc.do(o) 182 proposal = c.parse_proposal(r) 183 self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL) 184 self.assertEqual(proposal.state & ProposalState.INSUFFICIENT, 0) 185 self.assertEqual(proposal.state & ProposalState.TIED, 0) 186 self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, 0) 187 188 189 def test_vote_insufficient(self): 190 half_supply = self.initial_supply / 2 191 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 192 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 193 (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, half_supply) 194 self.rpc.do(o) 195 196 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 197 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 198 (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, half_supply) 199 self.rpc.do(o) 200 201 nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn) 202 c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 203 (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, half_supply) 204 self.rpc.do(o) 205 206 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 207 (tx_hash, o) = c.vote(self.voter_address, self.alice, half_supply - 1) 208 self.rpc.do(o) 209 210 o = block_latest() 211 now_block_height = self.rpc.do(o) 212 need_blocks = self.proposal_block_height + 100 - now_block_height + 1 213 self.backend.mine_blocks(need_blocks) 214 215 nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn) 216 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 217 (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) 218 self.rpc.do(o) 219 o = receipt(tx_hash) 220 r = self.rpc.do(o) 221 self.assertEqual(r['status'], 1) 222 223 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 224 r = self.rpc.do(o) 225 proposal = c.parse_proposal(r) 226 self.assertEqual(proposal.state & ProposalState.SCANNED, ProposalState.SCANNED) 227 228 (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent) 229 self.rpc.do(o) 230 o = receipt(tx_hash) 231 r = self.rpc.do(o) 232 self.assertEqual(r['status'], 1) 233 234 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 235 r = self.rpc.do(o) 236 proposal = c.parse_proposal(r) 237 self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL) 238 self.assertEqual(proposal.state & ProposalState.INSUFFICIENT, ProposalState.INSUFFICIENT) 239 self.assertEqual(proposal.state & ProposalState.TIED, 0) 240 self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, 0) 241 242 243 def test_proposal_ok_supplychange(self): 244 nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn) 245 c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 246 (tx_hash, o) = c.mint_to(self.address, self.accounts[0], self.alice, 1) 247 self.rpc.do(o) 248 249 o = block_latest() 250 now_block_height = self.rpc.do(o) 251 need_blocks = self.proposal_block_height + 100 - now_block_height + 1 252 self.backend.mine_blocks(need_blocks) 253 254 nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn) 255 c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle) 256 (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 0) 257 self.rpc.do(o) 258 259 (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent) 260 self.rpc.do(o) 261 o = receipt(tx_hash) 262 r = self.rpc.do(o) 263 self.assertEqual(r['status'], 1) 264 265 o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0]) 266 r = self.rpc.do(o) 267 proposal = c.parse_proposal(r) 268 self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL) 269 self.assertEqual(proposal.state & ProposalState.SUPPLYCHANGE, ProposalState.SUPPLYCHANGE) 270 self.assertEqual(proposal.state & ProposalState.CANCELLED, 0) 271 272 273 if __name__ == '__main__': 274 unittest.main()