evm-tokenvote

Voting machine using ERC20 tokens as votes.
Info | Log | Files | Refs | README

test_option.py (14254B)


      1 # standard imports
      2 import unittest
      3 import logging
      4 import os
      5 from chainlib.error import JSONRPCException
      6 from chainlib.eth.nonce import RPCNonceOracle
      7 from chainlib.eth.tx import receipt
      8 from chainlib.eth.block import block_latest
      9 from hexathon import same as same_hex
     10 from eth_erc20 import ERC20
     11 from giftable_erc20_token import GiftableToken
     12 
     13 # local imports
     14 from evm_tokenvote.unittest import TestEvmVote
     15 from evm_tokenvote.unittest.base import hash_of_foo
     16 from evm_tokenvote.unittest.base import hash_of_bar
     17 from evm_tokenvote.unittest.base import hash_of_baz
     18 from evm_tokenvote import Voter
     19 from evm_tokenvote import ProposalState
     20 
     21 
     22 logging.basicConfig(level=logging.DEBUG)
     23 logg = logging.getLogger()
     24 
     25 
     26 class TestVoteBase(TestEvmVote):
     27 
     28     def test_propose_multi(self):
     29         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
     30         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     31         (tx_hash, o) = c.propose(self.voter_address, self.accounts[0], hash_of_foo, 100)
     32         self.rpc.do(o)
     33         o = receipt(tx_hash)
     34         r = self.rpc.do(o)
     35         self.assertEqual(r['status'], 1)
     36 
     37         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_bar)
     38         self.rpc.do(o)
     39         o = receipt(tx_hash)
     40         r = self.rpc.do(o)
     41         self.assertEqual(r['status'], 1)
     42 
     43         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_baz)
     44         self.rpc.do(o)
     45         o = receipt(tx_hash)
     46         r = self.rpc.do(o)
     47         self.assertEqual(r['status'], 1)
     48 
     49         o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0])
     50         r = self.rpc.do(o)
     51         proposal = c.parse_proposal(r)
     52 
     53         o = c.get_option(self.voter_address, 0, 0, sender_address=self.accounts[0])
     54         r = self.rpc.do(o)
     55         self.assertTrue(same_hex(r, hash_of_bar))
     56 
     57         o = c.get_option(self.voter_address, 0, 1, sender_address=self.accounts[0])
     58         r = self.rpc.do(o)
     59         self.assertTrue(same_hex(r, hash_of_baz))
     60 
     61         with self.assertRaises(JSONRPCException):
     62             o = c.get_option(self.voter_address, 0, 2, sender_address=self.accounts[0])
     63             r = self.rpc.do(o)
     64 
     65         o = c.option_count(self.voter_address, 0, sender_address=self.accounts[0])
     66         r = self.rpc.do(o)
     67         count = int(r, 16)
     68         self.assertEqual(count, 2)
     69 
     70         # check that vote count is accessible for the full options index
     71         o = c.vote_count(self.voter_address, 0, 1, sender_address=self.accounts[0])
     72         r = self.rpc.do(o)
     73         count = int(r, 16)
     74         self.assertEqual(count, 0)
     75 
     76     
     77     def test_vote_multi(self):
     78         third_of_supply = int(self.initial_supply / 3)
     79         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
     80         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     81         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, third_of_supply)
     82         self.rpc.do(o)
     83 
     84         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     85         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, third_of_supply)
     86         self.rpc.do(o)
     87 
     88         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     89         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.carol, third_of_supply)
     90         self.rpc.do(o)
     91 
     92         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
     93         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     94         (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, third_of_supply)
     95         self.rpc.do(o)
     96         
     97         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
     98         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
     99         (tx_hash, o) = c.approve(self.address, self.bob, self.voter_address, third_of_supply)
    100         self.rpc.do(o)
    101 
    102         nonce_oracle = RPCNonceOracle(self.carol, conn=self.conn)
    103         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    104         (tx_hash, o) = c.approve(self.address, self.carol, self.voter_address, third_of_supply)
    105         self.rpc.do(o)
    106 
    107         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
    108         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    109         (tx_hash, o) = c.propose(self.voter_address, self.accounts[0], hash_of_foo, 100)
    110         self.rpc.do(o)
    111 
    112         o = block_latest()
    113         proposal_block_height = self.rpc.do(o)
    114 
    115         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_bar)
    116         self.rpc.do(o)
    117 
    118         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_baz)
    119         self.rpc.do(o)
    120 
    121         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
    122         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    123         (tx_hash, o) = c.vote(self.voter_address, self.alice, third_of_supply, option=1)
    124         self.rpc.do(o)
    125 
    126         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
    127         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    128         (tx_hash, o) = c.vote(self.voter_address, self.bob, third_of_supply, option=0)
    129         self.rpc.do(o)
    130 
    131         nonce_oracle = RPCNonceOracle(self.carol, conn=self.conn)
    132         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    133         (tx_hash, o) = c.vote(self.voter_address, self.carol, third_of_supply, option=1)
    134         self.rpc.do(o)
    135 
    136         o = block_latest()
    137         now_block_height = self.rpc.do(o)
    138         need_blocks = proposal_block_height + 100 - now_block_height + 1
    139         self.backend.mine_blocks(need_blocks)
    140 
    141         nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn)
    142         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    143         (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 3) # count is 2, let's check 3 to see if the check catches it
    144         self.rpc.do(o)
    145 
    146         (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent)
    147         self.rpc.do(o)
    148 
    149         o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0])
    150         r = self.rpc.do(o)
    151         proposal = c.parse_proposal(r)
    152 
    153         self.assertEqual(proposal.state & ProposalState.SCANNED, ProposalState.SCANNED)
    154         self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL)
    155         self.assertEqual(proposal.state & ProposalState.TIED, 0)
    156         self.assertEqual(proposal.state & ProposalState.INSUFFICIENT, 0)
    157 
    158 
    159     def test_vote_unanimous_fail(self):
    160         third_of_supply = int(self.initial_supply / 3)
    161         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
    162         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    163         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, third_of_supply)
    164         self.rpc.do(o)
    165 
    166         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    167         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, third_of_supply)
    168         self.rpc.do(o)
    169 
    170         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    171         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.carol, third_of_supply)
    172         self.rpc.do(o)
    173 
    174         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
    175         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    176         (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, third_of_supply)
    177         self.rpc.do(o)
    178         
    179         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
    180         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    181         (tx_hash, o) = c.approve(self.address, self.bob, self.voter_address, third_of_supply)
    182         self.rpc.do(o)
    183 
    184         nonce_oracle = RPCNonceOracle(self.carol, conn=self.conn)
    185         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    186         (tx_hash, o) = c.approve(self.address, self.carol, self.voter_address, third_of_supply)
    187         self.rpc.do(o)
    188 
    189         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
    190         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    191         (tx_hash, o) = c.propose(self.voter_address, self.accounts[0], hash_of_foo, 100, target_vote_ppm=1000000)
    192         self.rpc.do(o)
    193 
    194         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_bar)
    195         self.rpc.do(o)
    196 
    197         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_baz)
    198         self.rpc.do(o)
    199 
    200         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
    201         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    202         (tx_hash, o) = c.vote(self.voter_address, self.alice, third_of_supply, option=1)
    203         self.rpc.do(o)
    204 
    205         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
    206         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    207         (tx_hash, o) = c.vote(self.voter_address, self.bob, third_of_supply, option=0)
    208         self.rpc.do(o)
    209 
    210         nonce_oracle = RPCNonceOracle(self.carol, conn=self.conn)
    211         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    212         (tx_hash, o) = c.vote(self.voter_address, self.carol, third_of_supply, option=1)
    213         self.rpc.do(o)
    214 
    215         o = block_latest()
    216         proposal_block_height = self.rpc.do(o)
    217         o = block_latest()
    218         now_block_height = self.rpc.do(o)
    219 
    220         need_blocks = proposal_block_height + 100 - now_block_height + 1
    221         self.backend.mine_blocks(need_blocks)
    222 
    223         nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn)
    224         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    225         (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 3)
    226         self.rpc.do(o)
    227 
    228         (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent)
    229         self.rpc.do(o)
    230 
    231         o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0])
    232         r = self.rpc.do(o)
    233         proposal = c.parse_proposal(r)
    234         self.assertEqual(proposal.state & ProposalState.SCANNED, ProposalState.SCANNED)
    235         self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL)
    236         self.assertEqual(proposal.state & ProposalState.TIED, 0)
    237         self.assertEqual(proposal.state & ProposalState.INSUFFICIENT, ProposalState.INSUFFICIENT)
    238 
    239 
    240     def test_vote_tied(self):
    241         third_of_supply = int(self.initial_supply / 3)
    242         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
    243         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    244         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.alice, third_of_supply)
    245         self.rpc.do(o)
    246 
    247         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    248         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.bob, third_of_supply)
    249         self.rpc.do(o)
    250 
    251         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    252         (tx_hash, o) = c.transfer(self.address, self.accounts[0], self.carol, third_of_supply)
    253         self.rpc.do(o)
    254 
    255         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
    256         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    257         (tx_hash, o) = c.approve(self.address, self.alice, self.voter_address, third_of_supply)
    258         self.rpc.do(o)
    259         
    260         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
    261         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    262         (tx_hash, o) = c.approve(self.address, self.bob, self.voter_address, third_of_supply)
    263         self.rpc.do(o)
    264 
    265         nonce_oracle = RPCNonceOracle(self.carol, conn=self.conn)
    266         c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    267         (tx_hash, o) = c.approve(self.address, self.carol, self.voter_address, third_of_supply)
    268         self.rpc.do(o)
    269 
    270         nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
    271         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    272         (tx_hash, o) = c.propose(self.voter_address, self.accounts[0], hash_of_foo, 100)
    273         self.rpc.do(o)
    274 
    275         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_bar)
    276         self.rpc.do(o)
    277 
    278         (tx_hash, o) = c.add_option(self.voter_address, self.accounts[0], 0, hash_of_baz)
    279         self.rpc.do(o)
    280 
    281         nonce_oracle = RPCNonceOracle(self.alice, conn=self.conn)
    282         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    283         (tx_hash, o) = c.vote(self.voter_address, self.alice, third_of_supply, option=1)
    284         self.rpc.do(o)
    285 
    286         nonce_oracle = RPCNonceOracle(self.bob, conn=self.conn)
    287         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    288         (tx_hash, o) = c.vote(self.voter_address, self.bob, third_of_supply, option=0)
    289         self.rpc.do(o)
    290 
    291         o = block_latest()
    292         proposal_block_height = self.rpc.do(o)
    293         o = block_latest()
    294         now_block_height = self.rpc.do(o)
    295 
    296         need_blocks = proposal_block_height + 100 - now_block_height + 1
    297         self.backend.mine_blocks(need_blocks)
    298 
    299         nonce_oracle = RPCNonceOracle(self.trent, conn=self.conn)
    300         c = Voter(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
    301         (tx_hash, o) = c.scan(self.voter_address, self.trent, 0, 3)
    302         self.rpc.do(o)
    303 
    304         (tx_hash, o) = c.finalize_vote(self.voter_address, self.trent)
    305         self.rpc.do(o)
    306 
    307         o = c.get_proposal(self.voter_address, 0, sender_address=self.accounts[0])
    308         r = self.rpc.do(o)
    309         proposal = c.parse_proposal(r)
    310         self.assertEqual(proposal.state & ProposalState.SCANNED, ProposalState.SCANNED)
    311         self.assertEqual(proposal.state & ProposalState.FINAL, ProposalState.FINAL)
    312         self.assertEqual(proposal.state & ProposalState.TIED, ProposalState.TIED)
    313         self.assertEqual(proposal.state & ProposalState.INSUFFICIENT, 0)
    314 
    315 
    316 if __name__ == '__main__':
    317     unittest.main()