Skip to content

Commit 3609b74

Browse files
bysomeonevipwzw
authored andcommitted
[[FIX]] fix evm nonce rollback
1 parent faa1a26 commit 3609b74

File tree

2 files changed

+47
-43
lines changed

2 files changed

+47
-43
lines changed

plugin/dapp/evm/executor/exec_del_local.go

+6-20
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package executor
66

77
import (
8-
"github.com/33cn/chain33/system/crypto/secp256k1eth"
98
"github.com/33cn/chain33/types"
109
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
1110
)
@@ -17,29 +16,16 @@ func (evm *EVMExecutor) ExecDelLocal(tx *types.Transaction, receipt *types.Recei
1716
return nil, err
1817
}
1918

20-
defer func(lSet *types.LocalDBSet) {
19+
if receipt.GetTy() != types.ExecOk {
20+
2121
if types.IsEthSignID(tx.GetSignature().GetTy()) {
22-
nonceLocalKey := secp256k1eth.CaculCoinsEvmAccountKey(tx.From())
23-
nonceV, err := evm.GetLocalDB().Get(nonceLocalKey)
24-
if err == nil {
25-
var evmNonce types.EvmAccountNonce
26-
types.Decode(nonceV, &evmNonce)
27-
if evmNonce.GetNonce() == tx.GetNonce()+1 {
28-
evmNonce.Nonce--
29-
if evmNonce.GetNonce() < 0 {
30-
evmNonce.Nonce = 0
31-
}
32-
if lSet != nil {
33-
lSet.KV = append(lSet.KV, &types.KeyValue{Key: nonceLocalKey, Value: types.Encode(&evmNonce)})
34-
}
35-
}
3622

23+
kvs, err := evm.DelRollbackKV(tx, []byte(evmtypes.ExecutorName))
24+
if err != nil {
25+
return nil, err
3726
}
38-
27+
set.KV = kvs
3928
}
40-
}(set)
41-
42-
if receipt.GetTy() != types.ExecOk {
4329
return set, nil
4430
}
4531
cfg := evm.GetAPI().GetConfig()

plugin/dapp/evm/executor/exec_local.go

+41-23
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,61 @@ import (
88
"bytes"
99
"errors"
1010

11+
"github.com/33cn/chain33/common"
12+
log "github.com/33cn/chain33/common/log/log15"
1113
"github.com/33cn/chain33/system/crypto/secp256k1eth"
1214
"github.com/33cn/chain33/types"
1315
evmtypes "github.com/33cn/plugin/plugin/dapp/evm/types"
1416
)
1517

18+
var (
19+
errInvalidEvmNonce = errors.New("errInvalidEvmNonce")
20+
)
21+
22+
func (evm *EVMExecutor) handleEvmNonce(tx *types.Transaction, dbSet *types.LocalDBSet) error {
23+
24+
if types.IsEthSignID(tx.GetSignature().GetTy()) {
25+
fromAddr := tx.From()
26+
nonceLocalKey := secp256k1eth.CaculCoinsEvmAccountKey(fromAddr)
27+
evmNonce := &types.EvmAccountNonce{}
28+
nonceV, nonceErr := evm.GetLocalDB().Get(nonceLocalKey)
29+
if nonceErr == nil {
30+
_ = types.Decode(nonceV, evmNonce)
31+
}
32+
33+
log.Debug("ExecLocal handleEvmNonce", "height", evm.GetHeight(), "txHash", common.ToHex(tx.Hash()),
34+
"from", fromAddr, "expect", evmNonce.GetNonce(), "actual", tx.GetNonce())
35+
36+
if evm.GetAPI().GetConfig().IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEvmExecNonce) &&
37+
evmNonce.GetNonce() != tx.GetNonce() { //nonce 错误 返回异常
38+
return errInvalidEvmNonce
39+
}
40+
evmNonce.Addr = fromAddr
41+
evmNonce.Nonce++
42+
if dbSet != nil {
43+
dbSet.KV = append(dbSet.KV, &types.KeyValue{Key: nonceLocalKey, Value: types.Encode(evmNonce)})
44+
}
45+
}
46+
return nil
47+
}
48+
1649
// ExecLocal 处理本地区块新增逻辑
1750
func (evm *EVMExecutor) ExecLocal(tx *types.Transaction, receipt *types.ReceiptData, index int) (set *types.LocalDBSet, err error) {
1851
set, err = evm.DriverBase.ExecLocal(tx, receipt, index)
1952
if err != nil {
2053
return nil, err
2154
}
2255

23-
defer func(lSet *types.LocalDBSet) {
24-
if types.IsEthSignID(tx.GetSignature().GetTy()) {
25-
nonceLocalKey := secp256k1eth.CaculCoinsEvmAccountKey(tx.From())
26-
var evmNonce types.EvmAccountNonce
27-
nonceV, nonceErr := evm.GetLocalDB().Get(nonceLocalKey)
28-
if nonceErr == nil {
29-
types.Decode(nonceV, &evmNonce)
30-
if evmNonce.GetNonce() == tx.GetNonce() {
31-
evmNonce.Nonce++
32-
} else if evm.GetAPI().GetConfig().IsDappFork(evm.GetHeight(), "evm", evmtypes.ForkEvmExecNonce) { //nonce 错误 返回异常
33-
err = errors.New("invalid nonce")
34-
return
35-
}
36-
37-
} else {
38-
evmNonce.Addr = tx.From()
39-
evmNonce.Nonce = 1
40-
}
41-
if lSet != nil {
42-
lSet.KV = append(lSet.KV, &types.KeyValue{Key: nonceLocalKey, Value: types.Encode(&evmNonce)})
43-
}
44-
}
45-
}(set)
56+
// 校验及设置evm nonce
57+
if err = evm.handleEvmNonce(tx, set); err != nil {
58+
return nil, err
59+
}
4660

4761
if receipt.GetTy() != types.ExecOk {
62+
// 失败交易也需要记录evm nonce, 增加自动回滚处理
63+
if types.IsEthSignID(tx.GetSignature().GetTy()) {
64+
set.KV = evm.AddRollbackKV(tx, []byte(evmtypes.ExecutorName), set.KV)
65+
}
4866
return set, nil
4967
}
5068
cfg := evm.GetAPI().GetConfig()

0 commit comments

Comments
 (0)