@@ -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 处理本地区块新增逻辑
1750func (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