1#!/usr/bin/env python3
2
3from test_framework.test_framework import BitcoinTestFramework
4from test_framework.util import *
5from test_framework.script import *
6from test_framework.mininode import *
7from test_framework.qtum import *
8from test_framework.address import *
9from test_framework.blocktools import *
10import io
11
12"""
13Note, these tests do not test the functionality of the DGP template contract itself, for tests for the DGP template, see qtum-dgp.py
14"""
15class QtumDGPGasSchedule(BitcoinTestFramework):
16
17    def set_test_params(self):
18        self.setup_clean_chain = True
19        self.num_nodes = 2
20        self.extra_args = [['-dgpevm'], ['-dgpstorage']]
21
22    def skip_test_if_missing_module(self):
23        self.skip_if_no_wallet()
24
25
26    def create_proposal_contract(self):
27        """
28        pragma solidity ^0.4.11;
29        contract gasSchedule{
30            uint32[39] _gasSchedule=[
31                10, //0: tierStepGas0
32                10, //1: tierStepGas1
33                10, //2: tierStepGas2
34                10, //3: tierStepGas3
35                10, //4: tierStepGas4
36                10, //5: tierStepGas5
37                10, //6: tierStepGas6
38                10, //7: tierStepGas7
39                10, //8: expGas
40                50, //9: expByteGas
41                30, //10: sha3Gas
42                6, //11: sha3WordGas
43                200, //12: sloadGas
44                201, //13: sstoreSetGas
45                5000, //14: sstoreResetGas
46                15000, //15: sstoreRefundGas
47                1, //16: jumpdestGas
48                374000, //17: logGas
49                8, //18: logDataGas
50                375, //19: logTopicGas
51                32000, //20: createGas
52                700, //21: callGas
53                2300, //22: callStipend
54                9000, //23: callValueTransferGas
55                25000, //24: callNewAccountGas
56                24000, //25: suicideRefundGas
57                3, //26: memoryGas
58                512, //27: quadCoeffDiv
59                200, //28: createDataGas
60                21000, //29: txGas
61                53000, //30: txCreateGas
62                4, //31: txDataZeroGas
63                68, //32: txDataNonZeroGas
64                3, //33: copyGas
65                700, //34: extcodesizeGas
66                700, //35: extcodecopyGas
67                400, //36: balanceGas
68                5000, //37: suicideGas
69                24576 //38: maxCodeSize
70            ];
71            function getSchedule() constant returns(uint32[39] _schedule){
72                return _gasSchedule;
73            }
74        }
75        """
76
77        contract_data = self.node.createcontract("60806040526104e060405190810160405280600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001600a62ffffff168152602001603262ffffff168152602001601e62ffffff168152602001600662ffffff16815260200160c862ffffff16815260200160c962ffffff16815260200161138862ffffff168152602001613a9862ffffff168152602001600162ffffff1681526020016205b4f062ffffff168152602001600862ffffff16815260200161017762ffffff168152602001617d0062ffffff1681526020016102bc62ffffff1681526020016108fc62ffffff16815260200161232862ffffff1681526020016161a862ffffff168152602001615dc062ffffff168152602001600362ffffff16815260200161020062ffffff16815260200160c862ffffff16815260200161520862ffffff16815260200161cf0862ffffff168152602001600462ffffff168152602001604462ffffff168152602001600362ffffff1681526020016102bc62ffffff1681526020016102bc62ffffff16815260200161019062ffffff16815260200161138862ffffff16815260200161600062ffffff168152506000906027610206929190610219565b5034801561021357600080fd5b506102ee565b8260276007016008900481019282156102aa5791602002820160005b8382111561027857835183826101000a81548163ffffffff021916908362ffffff1602179055509260200192600401602081600301049283019260010302610235565b80156102a85782816101000a81549063ffffffff0219169055600401602081600301049283019260010302610278565b505b5090506102b791906102bb565b5090565b6102eb91905b808211156102e757600081816101000a81549063ffffffff0219169055506001016102c1565b5090565b90565b610160806102fd6000396000f300608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806326fadbe214610046575b600080fd5b34801561005257600080fd5b5061005b610099565b6040518082602760200280838360005b8381101561008657808201518184015260208101905061006b565b5050505090500191505060405180910390f35b6100a1610110565b6000602780602002604051908101604052809291908260278015610106576020028201916000905b82829054906101000a900463ffffffff1663ffffffff16815260200190600401906020826003010492830192600103820291508084116100c95790505b5050505050905090565b6104e0604051908101604052806027906020820280388339808201915050905050905600a165627a7a723058205e249731b14c9492ca6a161a7342bd0796c89a7eea6a30255be7fe5c0ee8995a0029", 10000000)
78        self.proposal_address = contract_data['address']
79
80
81    def run_test(self):
82        # Generate some blocks to make sure we have enough spendable outputs
83        self.node = self.nodes[0]
84        generatesynchronized(self.node, 1+COINBASE_MATURITY, None, self.nodes)
85        self.node.sendtoaddress(self.nodes[1].getnewaddress(), INITIAL_BLOCK_REWARD-1)
86        generatesynchronized(self.node, COINBASE_MATURITY, None, self.nodes)
87        self.BLOCK_SIZE_DGP = DGPState(self.node, "0000000000000000000000000000000000000080")
88        # Start off by setting ourself as admin
89        admin_address = self.node.getnewaddress()
90
91        # Set ourself up as admin
92        self.BLOCK_SIZE_DGP.send_set_initial_admin(admin_address)
93        self.node.generate(1)
94        self.create_proposal_contract()
95        self.BLOCK_SIZE_DGP.send_add_address_proposal(self.proposal_address, 2, admin_address)
96        self.node.generate(2) # We need to generate 2 blocks now for it to activate
97
98        for i in range(1, self.node.getblockcount()+1):
99            block_raw = self.node.getblock(self.node.getblockhash(i), False)
100            self.nodes[1].submitblock(block_raw)
101        """
102        pragma solidity ^0.4.0;
103        contract Test {
104            mapping(uint => uint) store;
105            constructor() public {
106                for(uint i = 1; i < 100; ++i) {
107                    store[i] = i;
108                }
109            }
110        }
111        """
112        bytecode = "6080604052348015600f57600080fd5b506000600190505b606481101560405780600080838152602001908152602001600020819055508060010190506017565b50603580604e6000396000f3006080604052600080fd00a165627a7a72305820322822a2891bf2231763465379f848c02acc8a6b6a468faed8193987b355199a0029"
113
114        for node, opt in zip(self.nodes, ['dgpevm', 'dgpstorage']):
115            contract_address = node.createcontract(bytecode, 1000000)['address']
116            node.generate(1)
117            print('dgp worked with ', opt, contract_address in node.listcontracts())
118            self.sync_all()
119
120if __name__ == '__main__':
121    QtumDGPGasSchedule().main()
122