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