1 #include <boost/test/unit_test.hpp>
2 #include <qtumtests/test_utils.h>
3 #include <script/standard.h>
4 #include <chainparams.h>
5 
6 namespace ConstantinopleTest{
7 
8 const dev::u256 GASLIMIT = dev::u256(500000);
9 const dev::h256 HASHTX = dev::h256(ParseHex("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
10 
11 // Codes used to check that the newer forks up to constantinople are present
12 const std::vector<valtype> CODE = {
13     /*
14     // Contract for Byzantium check
15     contract Proxy {
16         address public implementation;
17 
18         function upgradeTo(address _address) public {
19             implementation = _address;
20         }
21 
22         function () payable public {
23             address _impl = implementation;
24             require(_impl != address(0));
25 
26             assembly {
27                 let ptr := mload(0x40)
28                 calldatacopy(ptr, 0, calldatasize)
29                 let result := delegatecall(gas, _impl, ptr, calldatasize, 0, 0)
30                 let size := returndatasize
31                 returndatacopy(ptr, 0, size)
32 
33                 switch result
34                 case 0 { revert(ptr, size) }
35                 default { return(ptr, size) }
36             }
37         }
38     }
39     */
40     valtype(ParseHex("608060405234801561001057600080fd5b50610187806100206000396000f30060806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633659cfe681146100955780635c60da1b146100c5575b60005473ffffffffffffffffffffffffffffffffffffffff1680151561007057600080fd5b60405136600082376000803683855af43d806000843e818015610091578184f35b8184fd5b3480156100a157600080fd5b506100c373ffffffffffffffffffffffffffffffffffffffff60043516610103565b005b3480156100d157600080fd5b506100da61013f565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6000805473ffffffffffffffffffffffffffffffffffffffff191673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a723058209f0b14aef0ec22d6019dddc8ad7a0c8f0fbb76c8847e588da0a1559bc958db040029")),
41 
42     /*
43     // Contract for Byzantium check
44     contract TokenVersion1 {
45         mapping (address => uint) balances;
46 
47         event Transfer(address _from, address _to, uint256 _value);
48 
49         function balanceOf(address _address) public view returns (uint) {
50             return balances[_address];
51         }
52 
53         function transfer(address _to, uint256 _value) public {
54             require(balances[msg.sender] >= _value);
55             balances[msg.sender] -= _value;
56             balances[_to] += _value;
57             emit Transfer(msg.sender, _to, _value);
58         }
59 
60         function mint(address _to, uint256 _value) public {
61             balances[_to] += _value * 2;
62             emit Transfer(0x0, _to, _value);
63         }
64     }
65     */
66     valtype(ParseHex("608060405234801561001057600080fd5b506101e3806100206000396000f3006080604052600436106100565763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166340c10f19811461005b57806370a082311461008e578063a9059cbb146100ce575b600080fd5b34801561006757600080fd5b5061008c73ffffffffffffffffffffffffffffffffffffffff600435166024356100ff565b005b34801561009a57600080fd5b506100bc73ffffffffffffffffffffffffffffffffffffffff60043516610134565b60408051918252519081900360200190f35b3480156100da57600080fd5b5061008c73ffffffffffffffffffffffffffffffffffffffff6004351660243561015c565b73ffffffffffffffffffffffffffffffffffffffff909116600090815260208190526040902080546002909202919091019055565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b3360009081526020819052604090205481111561017857600080fd5b336000908152602081905260408082208054849003905573ffffffffffffffffffffffffffffffffffffffff93909316815291909120805490910190555600a165627a7a72305820c517c25d8609e1668bebed32141ed2c2415e8b77ba9f2aef29c6d84e5756b4c20029")),
67 
68     // upgradeTo(address _address)
69     valtype(ParseHex("3659cfe6000000000000000000000000c4c1d7375918557df2ef8f1d1f0b2329cb248a15")),
70 
71     // mint(address _to, uint256 _value)
72     valtype(ParseHex("40c10f1900000000000000000000000001010101010101010101010101010101010101010000000000000000000000000000000000000000000000000000000000000010")),
73 
74     /*
75     // Contract for Constantinople check
76     contract ConstantinopleCheck2 {
77         event Constantinople(bool);
78 
79         // call this function to check if we are on constantinple
80         function IsItConstantinople() public view returns (bool){
81             (bool success) = address(this).call(abi.encodeWithSignature("ConstantinopleCheckFunction()"));
82             emit Constantinople(success);
83             return success;
84         }
85 
86         // reverts if not constantinople
87         // call IsItConstantinople() not this one (is available to be called though)
88         // using shl for low gas use. "now" has to be called to make sure this function doesnt return a constant
89         function ConstantinopleCheckFunction() public view returns (bytes32){
90             bytes32 test = bytes32(now);
91             assembly {
92                 test := shl(test, 1)
93             }
94             return test; // explicitly return test so we are sure that the optimizer doesnt optimize this out
95         }
96     }
97     */
98     valtype(ParseHex("608060405234801561001057600080fd5b506101d5806100206000396000f30060806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416634ac429f28114610050578063f8af251414610077575b600080fd5b34801561005c57600080fd5b506100656100a0565b60408051918252519081900360200190f35b34801561008357600080fd5b5061008c6100a7565b604080519115158252519081900360200190f35b6001421b90565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f4ac429f2000000000000000000000000000000000000000000000000000000001781529151815160009384933093909290918291808383895b8381101561012b578181015183820152602001610113565b50505050905090810190601f1680156101585780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af160408051821515815290519194507f27cb433ab98fc487efab30ed965c7b21cb0c65b05a72ae5bf5a9815af956fe1693508190036020019150a19190505600a165627a7a7230582069c72d05c3b31b65dc0b5de1dc97b02549a66fe816407fc4e98bcee6792074c40029")),
99 
100     // IsItConstantinople()
101     valtype(ParseHex("f8af2514"))
102 };
103 
genesisLoading()104 void genesisLoading(){
105     const CChainParams& chainparams = Params();
106     int forkHeight = Params().GetConsensus().CoinbaseMaturity(0) + 499;
107     dev::eth::ChainParams cp(chainparams.EVMGenesisInfo(forkHeight));
108     globalState->populateFrom(cp.genesisState);
109     globalSealEngine = std::unique_ptr<dev::eth::SealEngineFace>(cp.createSealEngine());
110     globalState->db().commit();
111 }
112 
createNewBlocks(TestChain100Setup * testChain100Setup,size_t n)113 void createNewBlocks(TestChain100Setup* testChain100Setup, size_t n){
114     std::function<void(size_t n)> generateBlocks = [&](size_t n){
115         dev::h256 oldHashStateRoot = globalState->rootHash();
116         dev::h256 oldHashUTXORoot = globalState->rootHashUTXO();
117         for(size_t i = 0; i < n; i++){
118             testChain100Setup->CreateAndProcessBlock({}, GetScriptForRawPubKey(testChain100Setup->coinbaseKey.GetPubKey()));
119         }
120         globalState->setRoot(oldHashStateRoot);
121         globalState->setRootUTXO(oldHashUTXORoot);
122     };
123 
124     generateBlocks(n);
125 }
BOOST_FIXTURE_TEST_SUITE(constantinoplefork_tests,TestChain100Setup)126 BOOST_FIXTURE_TEST_SUITE(constantinoplefork_tests, TestChain100Setup)
127 
128 BOOST_AUTO_TEST_CASE(checking_returndata_opcode_after_fork){
129     // Initialize
130 //    initState();
131     genesisLoading();
132     createNewBlocks(this, 499);
133     dev::h256 hashTx(HASHTX);
134 
135     // Create contracts
136     std::vector<QtumTransaction> txs;
137     txs.push_back(createQtumTransaction(CODE[0], 0, GASLIMIT, dev::u256(1), hashTx, dev::Address()));
138     txs.push_back(createQtumTransaction(CODE[1], 0, GASLIMIT, dev::u256(1), ++hashTx, dev::Address()));
139     executeBC(txs);
140 
141     // Call upgrade to
142     dev::Address proxy = createQtumAddress(txs[0].getHashWith(), txs[0].getNVout());
143     std::vector<QtumTransaction> txsCall;
144     txsCall.push_back(createQtumTransaction(CODE[2], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
145     executeBC(txsCall);
146 
147     // Call mint
148     std::vector<QtumTransaction> txsMint;
149     txsMint.push_back(createQtumTransaction(CODE[3], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
150     auto result = executeBC(txsMint);
151     BOOST_CHECK(result.first[0].execRes.excepted == dev::eth::TransactionException::None);
152 
153     // Call balance of
154     std::vector<QtumTransaction> txsbalance;
155     txsbalance.push_back(createQtumTransaction(ParseHex("70a082310000000000000000000000000101010101010101010101010101010101010101"), 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
156     result = executeBC(txsbalance);
157     BOOST_CHECK(dev::h256(result.first[0].execRes.output) == dev::h256(0x0000000000000000000000000000000000000000000000000000000000000020));
158 }
159 
BOOST_AUTO_TEST_CASE(checking_returndata_opcode_before_fork)160 BOOST_AUTO_TEST_CASE(checking_returndata_opcode_before_fork){
161     // Initialize
162 //    initState();
163     genesisLoading();
164     createNewBlocks(this, 498);
165     dev::h256 hashTx(HASHTX);
166 
167     // Create contracts
168     std::vector<QtumTransaction> txs;
169     txs.push_back(createQtumTransaction(CODE[0], 0, GASLIMIT, dev::u256(1), hashTx, dev::Address()));
170     txs.push_back(createQtumTransaction(CODE[1], 0, GASLIMIT, dev::u256(1), ++hashTx, dev::Address()));
171     executeBC(txs);
172 
173     // Call upgrade to
174     dev::Address proxy = createQtumAddress(txs[0].getHashWith(), txs[0].getNVout());
175     std::vector<QtumTransaction> txsCall;
176     txsCall.push_back(createQtumTransaction(CODE[2], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
177     executeBC(txsCall);
178 
179     // Call mint
180     std::vector<QtumTransaction> txsMint;
181     txsMint.push_back(createQtumTransaction(CODE[3], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
182     auto result = executeBC(txsMint);
183     BOOST_CHECK(result.first[0].execRes.excepted == dev::eth::TransactionException::BadInstruction);
184 }
185 
BOOST_AUTO_TEST_CASE(checking_constantinople_after_fork)186 BOOST_AUTO_TEST_CASE(checking_constantinople_after_fork){
187     // Initialize
188 //    initState();
189     genesisLoading();
190     createNewBlocks(this, 499);
191     dev::h256 hashTx(HASHTX);
192 
193     // Create contract
194     std::vector<QtumTransaction> txs;
195     txs.push_back(createQtumTransaction(CODE[4], 0, GASLIMIT, dev::u256(1), hashTx, dev::Address()));
196     executeBC(txs);
197 
198     // Call is it constantinople
199     dev::Address proxy = createQtumAddress(txs[0].getHashWith(), txs[0].getNVout());
200     std::vector<QtumTransaction> txIsItConstantinople;
201     txIsItConstantinople.push_back(createQtumTransaction(CODE[5], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
202     auto result = executeBC(txIsItConstantinople);
203     BOOST_CHECK(dev::h256(result.first[0].execRes.output) == dev::h256(0x0000000000000000000000000000000000000000000000000000000000000001));
204 }
205 
BOOST_AUTO_TEST_CASE(checking_constantinople_before_fork)206 BOOST_AUTO_TEST_CASE(checking_constantinople_before_fork){
207     // Initialize
208 //    initState();
209     genesisLoading();
210     createNewBlocks(this, 498);
211     dev::h256 hashTx(HASHTX);
212 
213     // Create contract
214     std::vector<QtumTransaction> txs;
215     txs.push_back(createQtumTransaction(CODE[4], 0, GASLIMIT, dev::u256(1), hashTx, dev::Address()));
216     executeBC(txs);
217 
218     // Call is it constantinople
219     dev::Address proxy = createQtumAddress(txs[0].getHashWith(), txs[0].getNVout());
220     std::vector<QtumTransaction> txIsItConstantinople;
221     txIsItConstantinople.push_back(createQtumTransaction(CODE[5], 0, GASLIMIT, dev::u256(1), ++hashTx, proxy));
222     auto result = executeBC(txIsItConstantinople);
223     BOOST_CHECK(dev::h256(result.first[0].execRes.output) == dev::h256(0x0000000000000000000000000000000000000000000000000000000000000000));
224 }
225 
226 BOOST_AUTO_TEST_SUITE_END()
227 
228 }
229