Skip to content

Commit 8af3679

Browse files
authored
verify ErrCodeStoreOutOfGas fix in e2etest (iotexproject#2364)
1 parent 1af74a0 commit 8af3679

File tree

3 files changed

+179
-35
lines changed

3 files changed

+179
-35
lines changed

api/api.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ func (api *Server) GetTransactionLogByBlockHeight(
850850
}
851851
return nil, status.Error(codes.Internal, err.Error())
852852
}
853-
853+
854854
res := &iotexapi.GetTransactionLogByBlockHeightResponse{
855855
BlockIdentifier: &iotextypes.BlockIdentifier{
856856
Hash: hex.EncodeToString(h[:]),

blockchain/integrity/integrity_test.go

+164-34
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222

2323
"github.com/iotexproject/go-pkgs/hash"
2424
"github.com/iotexproject/iotex-address/address"
25+
"github.com/iotexproject/iotex-proto/golang/iotextypes"
2526

2627
"github.com/iotexproject/iotex-core/action"
2728
"github.com/iotexproject/iotex-core/action/protocol"
@@ -44,37 +45,39 @@ import (
4445
"github.com/iotexproject/iotex-core/db/trie"
4546
"github.com/iotexproject/iotex-core/db/trie/mptrie"
4647
"github.com/iotexproject/iotex-core/pkg/unit"
48+
"github.com/iotexproject/iotex-core/state"
4749
"github.com/iotexproject/iotex-core/state/factory"
4850
"github.com/iotexproject/iotex-core/test/identityset"
4951
"github.com/iotexproject/iotex-core/test/mock/mock_blockcreationsubscriber"
5052
"github.com/iotexproject/iotex-core/testutil"
5153
)
5254

5355
var (
54-
deployHash hash.Hash256 // in block 2
55-
setHash hash.Hash256 // in block 3
56-
shrHash hash.Hash256 // in block 4
57-
shlHash hash.Hash256 // in block 5
58-
sarHash hash.Hash256 // in block 6
59-
extHash hash.Hash256 // in block 7
60-
crt2Hash hash.Hash256 // in block 8
61-
setTopic, _ = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f40") // in block 3
62-
getTopic, _ = hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001") // in block 4
63-
shrTopic, _ = hex.DecodeString("00fe00000000000000000000000000000000000000000000000000000000001f") // in block 4
64-
shlTopic, _ = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f00") // in block 5
65-
sarTopic, _ = hex.DecodeString("fffe00000000000000000000000000000000000000000000000000000000001f") // in block 6
66-
extTopic, _ = hex.DecodeString("4a98ce81a2fd5177f0f42b49cb25b01b720f9ce8019f3937f63b789766c938e2") // in block 7
67-
crt2Topic, _ = hex.DecodeString("0000000000000000000000001895e6033cd1081f18e0bd23a4501d9376028523") // in block 8
56+
deployHash hash.Hash256 // in block 1
57+
setHash hash.Hash256 // in block 2
58+
shrHash hash.Hash256 // in block 3
59+
shlHash hash.Hash256 // in block 4
60+
sarHash hash.Hash256 // in block 5
61+
extHash hash.Hash256 // in block 6
62+
crt2Hash hash.Hash256 // in block 7
63+
storeHash hash.Hash256 // in block 8
64+
store2Hash hash.Hash256 // in block 9
65+
setTopic, _ = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f40") // in block 2
66+
getTopic, _ = hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000001") // in block 2
67+
shrTopic, _ = hex.DecodeString("00fe00000000000000000000000000000000000000000000000000000000001f") // in block 3
68+
shlTopic, _ = hex.DecodeString("fe00000000000000000000000000000000000000000000000000000000001f00") // in block 4
69+
sarTopic, _ = hex.DecodeString("fffe00000000000000000000000000000000000000000000000000000000001f") // in block 5
70+
extTopic, _ = hex.DecodeString("4a98ce81a2fd5177f0f42b49cb25b01b720f9ce8019f3937f63b789766c938e2") // in block 6
71+
crt2Topic, _ = hex.DecodeString("0000000000000000000000001895e6033cd1081f18e0bd23a4501d9376028523") // in block 7
72+
preGrPreStore *big.Int
73+
preGrPostStore *big.Int
74+
postGrPostStore *big.Int
6875
)
6976

70-
func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.BlockDAO, ap actpool.ActPool) error {
77+
func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.BlockDAO, sf factory.Factory, ap actpool.ActPool) error {
7178
// Add block 1
7279
priKey0 := identityset.PrivateKey(27)
73-
data, err := hex.DecodeString("608060405234801561001057600080fd5b506104d5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c806381ea44081161005b57806381ea440814610101578063a91b336214610159578063c2bc2efc14610177578063f5eacece146101cf57610088565b80635bec9e671461008d57806360fe47b1146100975780636bc8ecaa146100c5578063744f5f83146100e3575b600080fd5b6100956101ed565b005b6100c3600480360360208110156100ad57600080fd5b8101908080359060200190929190505050610239565b005b6100cd610270565b6040518082815260200191505060405180910390f35b6100eb6102b3565b6040518082815260200191505060405180910390f35b6101436004803603602081101561011757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506102f6565b6040518082815260200191505060405180910390f35b61016161036a565b6040518082815260200191505060405180910390f35b6101b96004803603602081101561018d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506103ad565b6040518082815260200191505060405180910390f35b6101d761045f565b6040518082815260200191505060405180910390f35b5b60011561020b5760008081548092919060010191905055506101ee565b7f8bfaa460932ccf8751604dd60efa3eafa220ec358fccb32ef703f91c509bc3ea60405160405180910390a1565b80600081905550807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a250565b6000805460081d905080600081905550807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a280905090565b6000805460081c905080600081905550807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a280905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561033157600080fd5b813f9050807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a2809050919050565b6000805460081b905080600081905550807fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a280905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156103e857600080fd5b7fbde7a70c2261170a87678200113c8e12f82f63d0a1d1cfa45681cbac328e87e382600054604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16000549050919050565b60008080602060406000f59150817fdf7a95aebff315db1b7716215d602ab537373cdb769232aae6055c06e798425b60405160405180910390a2819150509056fea265627a7a72305820209a8ef04c4d621759f34878b27b238650e8605c8a71d6efc619a769a64aa9cc64736f6c634300050a0032")
74-
if err != nil {
75-
return err
76-
}
77-
ex1, err := testutil.SignedExecution(action.EmptyAddress, priKey0, 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), data)
80+
ex1, err := testutil.SignedExecution(action.EmptyAddress, priKey0, 1, big.NewInt(0), 500000, big.NewInt(testutil.TestGasPriceInt64), _constantinopleOpCodeContract)
7881
if err != nil {
7982
return err
8083
}
@@ -101,8 +104,8 @@ func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.Block
101104
contract = r.ContractAddress
102105
}
103106

104-
addOneBlock := func(nonce uint64, data []byte) (hash.Hash256, error) {
105-
ex1, err := testutil.SignedExecution(contract, priKey0, nonce, big.NewInt(0), testutil.TestGasLimit*5, big.NewInt(testutil.TestGasPriceInt64), data)
107+
addOneBlock := func(contract string, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) (hash.Hash256, error) {
108+
ex1, err := testutil.SignedExecution(contract, priKey0, nonce, amount, gasLimit, gasPrice, data)
106109
if err != nil {
107110
return hash.ZeroHash256, err
108111
}
@@ -120,35 +123,41 @@ func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.Block
120123
return ex1.Hash(), nil
121124
}
122125

126+
var (
127+
zero = big.NewInt(0)
128+
gasLimit = testutil.TestGasLimit * 5
129+
gasPrice = big.NewInt(testutil.TestGasPriceInt64)
130+
)
131+
123132
// Add block 2
124133
// call set() to set storedData = 0xfe...1f40
125134
funcSig := hash.Hash256b([]byte("set(uint256)"))
126-
data = append(funcSig[:4], setTopic...)
127-
setHash, err = addOneBlock(2, data)
135+
data := append(funcSig[:4], setTopic...)
136+
setHash, err = addOneBlock(contract, 2, zero, gasLimit, gasPrice, data)
128137
if err != nil {
129138
return err
130139
}
131140

132141
// Add block 3
133142
// call shright() to test SHR opcode, storedData => 0x00fe...1f
134143
funcSig = hash.Hash256b([]byte("shright()"))
135-
shrHash, err = addOneBlock(3, funcSig[:4])
144+
shrHash, err = addOneBlock(contract, 3, zero, gasLimit, gasPrice, funcSig[:4])
136145
if err != nil {
137146
return err
138147
}
139148

140149
// Add block 4
141150
// call shleft() to test SHL opcode, storedData => 0xfe...1f00
142151
funcSig = hash.Hash256b([]byte("shleft()"))
143-
shlHash, err = addOneBlock(4, funcSig[:4])
152+
shlHash, err = addOneBlock(contract, 4, zero, gasLimit, gasPrice, funcSig[:4])
144153
if err != nil {
145154
return err
146155
}
147156

148157
// Add block 5
149158
// call saright() to test SAR opcode, storedData => 0xfffe...1f
150159
funcSig = hash.Hash256b([]byte("saright()"))
151-
sarHash, err = addOneBlock(5, funcSig[:4])
160+
sarHash, err = addOneBlock(contract, 5, zero, gasLimit, gasPrice, funcSig[:4])
152161
if err != nil {
153162
return err
154163
}
@@ -159,18 +168,72 @@ func addTestingConstantinopleBlocks(bc blockchain.Blockchain, dao blockdao.Block
159168
addr, _ := address.FromString(contract)
160169
ethaddr := hash.BytesToHash256(addr.Bytes())
161170
data = append(funcSig[:4], ethaddr[:]...)
162-
extHash, err = addOneBlock(6, data)
171+
extHash, err = addOneBlock(contract, 6, zero, gasLimit, gasPrice, data)
163172
if err != nil {
164173
return err
165174
}
166175

167176
// Add block 7
168177
// call create2() to test CREATE2 opcode
169178
funcSig = hash.Hash256b([]byte("create2()"))
170-
crt2Hash, err = addOneBlock(7, funcSig[:4])
179+
crt2Hash, err = addOneBlock(contract, 7, zero, gasLimit, gasPrice, funcSig[:4])
180+
if err != nil {
181+
return err
182+
}
183+
184+
// Add block 8
185+
// test store out of gas
186+
var (
187+
caller state.Account
188+
callerAddr = hash.BytesToHash160(identityset.Address(27).Bytes())
189+
)
190+
_, err = sf.State(&caller, protocol.LegacyKeyOption(callerAddr))
191+
if err != nil {
192+
return err
193+
}
194+
preGrPreStore = new(big.Int).Set(caller.Balance)
195+
storeHash, err = addOneBlock(action.EmptyAddress, 8, unit.ConvertIotxToRau(10000), 3000000, big.NewInt(unit.Qev), _codeStoreOutOfGasContract)
196+
if err != nil {
197+
return err
198+
}
199+
200+
if dao != nil {
201+
r, err := dao.GetReceiptByActionHash(storeHash, 8)
202+
if err != nil {
203+
return err
204+
}
205+
if r.Status != uint64(iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas) {
206+
return blockchain.ErrBalance
207+
}
208+
}
209+
210+
// Add block 9
211+
// test store out of gas
212+
_, err = sf.State(&caller, protocol.LegacyKeyOption(callerAddr))
213+
if err != nil {
214+
return err
215+
}
216+
preGrPostStore = new(big.Int).Set(caller.Balance)
217+
store2Hash, err = addOneBlock(action.EmptyAddress, 9, unit.ConvertIotxToRau(10000), 3000000, big.NewInt(unit.Qev), _codeStoreOutOfGasContract)
171218
if err != nil {
172219
return err
173220
}
221+
222+
if dao != nil {
223+
r, err := dao.GetReceiptByActionHash(store2Hash, 9)
224+
if err != nil {
225+
return err
226+
}
227+
if r.Status != uint64(iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas) {
228+
return blockchain.ErrBalance
229+
}
230+
}
231+
232+
_, err = sf.State(&caller, protocol.LegacyKeyOption(callerAddr))
233+
if err != nil {
234+
return err
235+
}
236+
postGrPostStore = new(big.Int).Set(caller.Balance)
174237
return nil
175238
}
176239

@@ -698,9 +761,12 @@ func TestConstantinople(t *testing.T) {
698761
require.NoError(bc.Stop(ctx))
699762
}()
700763

701-
require.NoError(addTestingConstantinopleBlocks(bc, dao, ap))
764+
require.NoError(addTestingConstantinopleBlocks(bc, dao, sf, ap))
702765

703-
// TODO: don't use hard coded hash
766+
// reason to use hard-coded hash value here:
767+
// this test TestConstantinople() is added when we upgrade our EVM to enable Constantinople
768+
// at that time, the test is run with both EVM version (Byzantium vs. Constantinople), and it generates the
769+
// same exact block hash, so these values stood as gatekeeper for backward-compatibility
704770
hashTopic := []struct {
705771
h hash.Hash256
706772
blkHash string
@@ -776,17 +842,79 @@ func TestConstantinople(t *testing.T) {
776842
}
777843
}
778844

845+
storeOutGasTests := []struct {
846+
height uint64
847+
actHash hash.Hash256
848+
status iotextypes.ReceiptStatus
849+
preBalance *big.Int
850+
postBalance *big.Int
851+
}{
852+
{
853+
8, storeHash, iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas, preGrPreStore, preGrPostStore,
854+
},
855+
{
856+
9, store2Hash, iotextypes.ReceiptStatus_ErrCodeStoreOutOfGas, preGrPostStore, postGrPostStore,
857+
},
858+
}
859+
caller := identityset.Address(27)
860+
for _, v := range storeOutGasTests {
861+
r, err := dao.GetReceiptByActionHash(v.actHash, v.height)
862+
require.NoError(err)
863+
require.EqualValues(v.status, r.Status)
864+
865+
// verify transaction log
866+
bLog, err := dao.TransactionLogs(v.height)
867+
require.NoError(err)
868+
tLog := bLog.Logs[0]
869+
// first transaction log is gas fee
870+
tx := tLog.Transactions[0]
871+
require.Equal(tx.Sender, caller.String())
872+
require.Equal(tx.Recipient, address.RewardingPoolAddr)
873+
require.Equal(iotextypes.TransactionLogType_GAS_FEE, tx.Type)
874+
gasFee, ok := new(big.Int).SetString(tx.Amount, 10)
875+
require.True(ok)
876+
postBalance := new(big.Int).Sub(v.preBalance, gasFee)
877+
878+
hu := config.NewHeightUpgrade(&cfg.Genesis)
879+
if hu.IsPre(config.Greenland, v.height) {
880+
// pre-Greenland contains a tx with status = ReceiptStatus_ErrCodeStoreOutOfGas
881+
// due to a bug the transfer is not reverted
882+
require.Equal(3, len(tLog.Transactions))
883+
// 2nd log is in-contract-transfer
884+
tx = tLog.Transactions[1]
885+
require.Equal(tx.Sender, caller.String())
886+
require.Equal(iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER, tx.Type)
887+
tsfAmount, ok := new(big.Int).SetString(tx.Amount, 10)
888+
require.True(ok)
889+
postBalance.Sub(postBalance, tsfAmount)
890+
// post = pre - gasFee - in_contract_transfer
891+
require.Equal(v.postBalance, postBalance)
892+
// 3rd log is also in-contract-transfer
893+
tx = tLog.Transactions[2]
894+
require.Equal(tx.Recipient, caller.String())
895+
require.Equal(iotextypes.TransactionLogType_IN_CONTRACT_TRANSFER, tx.Type)
896+
} else {
897+
// post-Greenland fixed that bug, the transfer is reverted so it only contains the gas fee
898+
require.Equal(1, len(tLog.Transactions))
899+
// post = pre - gasFee (transfer is reverted)
900+
require.Equal(v.postBalance, postBalance)
901+
}
902+
}
903+
779904
// test getActions
780-
addr27 := hash.BytesToHash160(identityset.Address(27).Bytes())
905+
addr27 := hash.BytesToHash160(caller.Bytes())
781906
total, err := indexer.GetActionCountByAddress(addr27)
782907
require.NoError(err)
783-
require.EqualValues(7, total)
908+
require.EqualValues(len(hashTopic)+len(storeOutGasTests), total)
784909
actions, err := indexer.GetActionsByAddress(addr27, 0, total)
785910
require.NoError(err)
786911
require.EqualValues(total, len(actions))
787-
for i := range actions {
912+
for i := range hashTopic {
788913
require.Equal(hashTopic[i].h[:], actions[i])
789914
}
915+
for i := range storeOutGasTests {
916+
require.Equal(storeOutGasTests[i].actHash[:], actions[i+len(hashTopic)])
917+
}
790918
}
791919

792920
cfg := config.Default
@@ -814,6 +942,8 @@ func TestConstantinople(t *testing.T) {
814942
cfg.Chain.EnableAsyncIndexWrite = false
815943
cfg.ActPool.MinGasPriceStr = "0"
816944
cfg.Genesis.AleutianBlockHeight = 2
945+
cfg.Genesis.BeringBlockHeight = 8
946+
cfg.Genesis.GreenlandBlockHeight = 9
817947
cfg.Genesis.InitBalanceMap[identityset.Address(27).String()] = unit.ConvertIotxToRau(10000000000).String()
818948

819949
t.Run("test Constantinople contract", func(t *testing.T) {

0 commit comments

Comments
 (0)