From 2b8304f7568ec271f05a7d286bf25adb3669ff20 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Wed, 6 Sep 2023 18:38:59 +0800 Subject: [PATCH 01/13] update --- cmd/chain33/chain33.toml | 3 +- rpc/ethrpc/eth/eth.go | 28 +++++++++++++------ system/mempool/check.go | 59 ++++++++++++++++++++++++++++++++++++++++ types/cfg.go | 13 +++++---- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/cmd/chain33/chain33.toml b/cmd/chain33/chain33.toml index c0cf1c408..da1159811 100644 --- a/cmd/chain33/chain33.toml +++ b/cmd/chain33/chain33.toml @@ -306,7 +306,8 @@ enableStat=false #是否开启MVCC插件 enableMVCC=false alias=["token1:token","token2:token","token3:token"] - +#代理执行器地址 +proxyExecAddrss=["0x0000000000000000000000000000000000200005"] [exec.sub.token] #是否保存token交易信息 saveTokenTxList=true diff --git a/rpc/ethrpc/eth/eth.go b/rpc/ethrpc/eth/eth.go index fbdd5ceaa..3ccc81997 100644 --- a/rpc/ethrpc/eth/eth.go +++ b/rpc/ethrpc/eth/eth.go @@ -31,13 +31,14 @@ import ( ) type ethHandler struct { - cli rpcclient.ChannelClient - cfg *ctypes.Chain33Config - grpcCli ctypes.Chain33Client - filtersMu sync.Mutex - filters map[rpc.ID]*filter - evmChainID int64 - filterTimeout time.Duration + cli rpcclient.ChannelClient + cfg *ctypes.Chain33Config + grpcCli ctypes.Chain33Client + filtersMu sync.Mutex + filters map[rpc.ID]*filter + evmChainID int64 + filterTimeout time.Duration + proxyExecAddress []string } var ( @@ -51,6 +52,7 @@ func NewEthAPI(cfg *ctypes.Chain33Config, c queue.Client, api client.QueueProtoc e.cfg = cfg e.filters = make(map[rpc.ID]*filter) e.evmChainID = secp256k1eth.GetEvmChainID() + e.proxyExecAddress = e.cfg.GetModuleConfig().Exec.ProxyExecAddress grpcBindAddr := e.cfg.GetModuleConfig().RPC.GrpcBindAddr _, port, _ := net.SplitHostPort(grpcBindAddr) conn, err := grpc.Dial(fmt.Sprintf("localhost:%v", port), grpc.WithInsecure()) @@ -560,6 +562,16 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) }) fee := properFee.GetProperFee() + //GetMinTxFeeRate 默认1e5 + realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) + if callMsg.To == "0x0000000000000000000000000000000000200005" { + rightFee := realFee + if realFee < fee { + rightFee = fee + } + return hexutil.Uint64(rightFee), nil + } + var minimumGas int64 = 21000 if callMsg.Data == nil || len(*callMsg.Data) == 0 { if fee < e.cfg.GetMinTxFeeRate() { @@ -597,8 +609,6 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) } bigGas, _ := new(big.Int).SetString(gas.Gas, 10) - //GetMinTxFeeRate 默认1e5 - realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) var finalFee = realFee if bigGas.Uint64() > uint64(realFee) { diff --git a/system/mempool/check.go b/system/mempool/check.go index 9f2d861ce..7355a0e79 100644 --- a/system/mempool/check.go +++ b/system/mempool/check.go @@ -1,7 +1,11 @@ package mempool import ( + "bytes" "errors" + "fmt" + "math/big" + "sort" "sync/atomic" "time" @@ -198,6 +202,15 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } } + //检查mempool内是否有相同的tx.nonce + if types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { + err = mem.evmTxNonceCheck(tx.Tx()) + if err != nil { + msg.Data = err + return msg + } + } + err = mem.PushTx(tx.Tx()) if err != nil { if err == types.ErrMemFull { @@ -209,3 +222,49 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } return msg } + +//evmTxNonceCheck 检查eth noce 是否有重复值,如果有的话,需要比较txFee大小,用于替换较小的fee的那笔交易 +func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { + if tx.GetNonce() < mem.getCurrentNonce(tx.From()) { + return errors.New("nonce too low") + } + details := mem.GetAccTxs(&types.ReqAddrs{Addrs: []string{tx.From()}}) + txs := details.GetTxs() + txs = append(txs, &types.TransactionDetail{Tx: tx, Index: int64(len(txs))}) + if len(txs) > 1 { + sort.SliceStable(txs, func(i, j int) bool { //nonce asc + return txs[i].Tx.GetNonce() < txs[j].Tx.GetNonce() + }) + //遇到相同的Nonce ,较低的手续费的交易将被删除 + for i, stx := range txs { + if bytes.Equal(stx.Tx.Hash(), tx.Hash()) { + continue + } + if txs[i].GetTx().GetNonce() == tx.GetNonce() { + //step1 先比较交易创建的时间,后创建的交易要求比前面的交易手续费更高,否则直接删除 + if tx.Expire > txs[i].GetTx().Expire { + bnfee := big.NewInt(txs[i].GetTx().Fee) + //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 + bnfee = bnfee.Mul(bnfee, big.NewInt(110)) + bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) + if tx.Fee < bnfee.Int64() { + err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) + mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) + return err + } + + } + //删除Expire 较大的交易或者更低手续费的交易,确保先创建的交易留在mempool 中 + mem.RemoveTxs(&types.TxHashList{ + Hashes: [][]byte{txs[i].GetTx().Hash()}, + }) + + return nil + } + } + + } + + return nil + +} diff --git a/types/cfg.go b/types/cfg.go index 6e6d289f9..347026c44 100644 --- a/types/cfg.go +++ b/types/cfg.go @@ -314,12 +314,13 @@ type Exec struct { DisableAddrIndex bool `json:"disableAddrIndex,omitempty"` Alias []string `json:"alias,omitempty"` // 是否保存token交易信息 - SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` - EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` - DisableTxIndex bool `json:"disableTxIndex,omitempty"` - DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` - DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` - DisableExecLocal bool `json:"disableExecLocal,omitempty"` + SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` + EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` + DisableTxIndex bool `json:"disableTxIndex,omitempty"` + DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` + DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` + DisableExecLocal bool `json:"disableExecLocal,omitempty"` + ProxyExecAddress []string `json:"proxyExecAddress,omitempty"` } // Pprof 配置 From 1ccfb9ac042c0adbf508f460cbf2f13d2aaa56b7 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 14:34:25 +0800 Subject: [PATCH 02/13] add proxyexec --- cmd/chain33/chain33.fork.toml | 1 + cmd/chain33/chain33.toml | 2 +- executor/execenv.go | 51 ++++++++++++++++++++++++++++++-- rpc/ethrpc/eth/eth.go | 19 ++++++------ system/mempool/check.go | 41 +++++++++++++------------- system/mempool/mempool_test.go | 53 ++++++++++++++++++++++++++++++++++ types/cfg.go | 14 ++++----- types/error.go | 1 + types/fork.go | 1 + wallet/common/walletoperate.go | 4 +-- wallet/sendtx.go | 20 ++++++------- wallet/wallet_proc.go | 7 ++++- wallet/wallet_test.go | 7 +++-- 13 files changed, 165 insertions(+), 56 deletions(-) diff --git a/cmd/chain33/chain33.fork.toml b/cmd/chain33/chain33.fork.toml index eff5c318a..921312d6d 100644 --- a/cmd/chain33/chain33.fork.toml +++ b/cmd/chain33/chain33.fork.toml @@ -25,6 +25,7 @@ ForkTicketFundAddrV1=3350000 ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 +ForkProxyExec=0 [fork.sub.none] ForkUseTimeDelay=0 diff --git a/cmd/chain33/chain33.toml b/cmd/chain33/chain33.toml index da1159811..c0f7e99b4 100644 --- a/cmd/chain33/chain33.toml +++ b/cmd/chain33/chain33.toml @@ -307,7 +307,7 @@ enableStat=false enableMVCC=false alias=["token1:token","token2:token","token3:token"] #代理执行器地址 -proxyExecAddrss=["0x0000000000000000000000000000000000200005"] +proxyExecAddrss="0x0000000000000000000000000000000000200005" [exec.sub.token] #是否保存token交易信息 saveTokenTxList=true diff --git a/executor/execenv.go b/executor/execenv.go index bcf0ad746..fd4efffc1 100644 --- a/executor/execenv.go +++ b/executor/execenv.go @@ -6,7 +6,8 @@ package executor import ( "bytes" - + "errors" + "fmt" "github.com/33cn/chain33/account" "github.com/33cn/chain33/client" "github.com/33cn/chain33/client/api" @@ -598,6 +599,42 @@ func (e *executor) rollback() { } } +func (e *executor) proxyGetRealTx(tx *types.Transaction) (*types.Transaction, error) { + if string(types.GetRealExecName(tx.GetExecer())) != "evm" { + return nil, fmt.Errorf("execName %s not allowd", string(types.GetRealExecName(tx.GetExecer()))) + } + var actionData types.EVMContractAction4Chain33 + err := types.Decode(tx.GetPayload(), &actionData) + if err != nil { + return nil, err + } + if len(actionData.GetPara()) == 0 { + return nil, errors.New("empty tx") + } + var realTx types.Transaction + err = types.Decode(actionData.Para, &realTx) + if err != nil { + return nil, err + } + + return &realTx, nil + +} + +func (e *executor) proxyExecTx(tx *types.Transaction) (*types.Transaction, error) { + var realTx *types.Transaction + var err error + if tx.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { + realTx, err = e.proxyGetRealTx(tx) + if err != nil { + return realTx, err + } + realTx.Signature = tx.Signature + + } + return realTx, nil +} + func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*types.Receipt, error) { if e.height == 0 { //genesis block 不检查手续费 receipt, err := e.Exec(tx, index) @@ -609,10 +646,20 @@ func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*ty } return receipt, nil } + + var err error + //代理执行 EVM-->txpayload-->chain33 tx + if e.cfg.IsFork(e.height, "ForkProxyExec") { + tx, err = e.proxyExecTx(tx) + if err != nil { + return nil, err + } + } + //交易检查规则: //1. mempool 检查区块,尽量检查更多的错误 //2. 打包的时候,尽量打包更多的交易,只要基本的签名,以及格式没有问题 - err := e.checkTx(tx, index) + err = e.checkTx(tx, index) if err != nil { elog.Error("execTx.checkTx ", "txhash", common.ToHex(tx.Hash()), "err", err) if e.cfg.IsPara() { diff --git a/rpc/ethrpc/eth/eth.go b/rpc/ethrpc/eth/eth.go index 3ccc81997..0efa9d5b0 100644 --- a/rpc/ethrpc/eth/eth.go +++ b/rpc/ethrpc/eth/eth.go @@ -31,14 +31,13 @@ import ( ) type ethHandler struct { - cli rpcclient.ChannelClient - cfg *ctypes.Chain33Config - grpcCli ctypes.Chain33Client - filtersMu sync.Mutex - filters map[rpc.ID]*filter - evmChainID int64 - filterTimeout time.Duration - proxyExecAddress []string + cli rpcclient.ChannelClient + cfg *ctypes.Chain33Config + grpcCli ctypes.Chain33Client + filtersMu sync.Mutex + filters map[rpc.ID]*filter + evmChainID int64 + filterTimeout time.Duration } var ( @@ -52,7 +51,6 @@ func NewEthAPI(cfg *ctypes.Chain33Config, c queue.Client, api client.QueueProtoc e.cfg = cfg e.filters = make(map[rpc.ID]*filter) e.evmChainID = secp256k1eth.GetEvmChainID() - e.proxyExecAddress = e.cfg.GetModuleConfig().Exec.ProxyExecAddress grpcBindAddr := e.cfg.GetModuleConfig().RPC.GrpcBindAddr _, port, _ := net.SplitHostPort(grpcBindAddr) conn, err := grpc.Dial(fmt.Sprintf("localhost:%v", port), grpc.WithInsecure()) @@ -564,7 +562,8 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) fee := properFee.GetProperFee() //GetMinTxFeeRate 默认1e5 realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) - if callMsg.To == "0x0000000000000000000000000000000000200005" { + //判断是否是代理执行的地址,如果是,则直接返回,不会交给evm执行器去模拟执行计算gas. + if callMsg.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { rightFee := realFee if realFee < fee { rightFee = fee diff --git a/system/mempool/check.go b/system/mempool/check.go index 7355a0e79..a64dced20 100644 --- a/system/mempool/check.go +++ b/system/mempool/check.go @@ -203,12 +203,10 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } //检查mempool内是否有相同的tx.nonce - if types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { - err = mem.evmTxNonceCheck(tx.Tx()) - if err != nil { - msg.Data = err - return msg - } + err = mem.evmTxNonceCheck(tx.Tx()) + if err != nil { + msg.Data = err + return msg } err = mem.PushTx(tx.Tx()) @@ -225,8 +223,13 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { //evmTxNonceCheck 检查eth noce 是否有重复值,如果有的话,需要比较txFee大小,用于替换较小的fee的那笔交易 func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { + if !types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { + return nil + } + + //较小的nonce 则返回错误,不被允许进入mempool if tx.GetNonce() < mem.getCurrentNonce(tx.From()) { - return errors.New("nonce too low") + return types.ErrLowNonce } details := mem.GetAccTxs(&types.ReqAddrs{Addrs: []string{tx.From()}}) txs := details.GetTxs() @@ -240,25 +243,23 @@ func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { if bytes.Equal(stx.Tx.Hash(), tx.Hash()) { continue } - if txs[i].GetTx().GetNonce() == tx.GetNonce() { - //step1 先比较交易创建的时间,后创建的交易要求比前面的交易手续费更高,否则直接删除 - if tx.Expire > txs[i].GetTx().Expire { - bnfee := big.NewInt(txs[i].GetTx().Fee) - //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 - bnfee = bnfee.Mul(bnfee, big.NewInt(110)) - bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) - if tx.Fee < bnfee.Int64() { - err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) - mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) - return err - } + if txs[i].GetTx().GetNonce() == tx.GetNonce() { + bnfee := big.NewInt(txs[i].GetTx().Fee) + //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 + bnfee = bnfee.Mul(bnfee, big.NewInt(110)) + bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) + if tx.Fee < bnfee.Int64() { + err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) + mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) + return err } + //删除Expire 较大的交易或者更低手续费的交易,确保先创建的交易留在mempool 中 mem.RemoveTxs(&types.TxHashList{ Hashes: [][]byte{txs[i].GetTx().Hash()}, }) - + mlog.Info("evmTxNonceCheck", "remote txhash:", common.ToHex(txs[i].GetTx().Hash()), "replace txHash:", common.ToHex(tx.Hash())) return nil } } diff --git a/system/mempool/mempool_test.go b/system/mempool/mempool_test.go index 4efd0fb6c..9d8cc7535 100644 --- a/system/mempool/mempool_test.go +++ b/system/mempool/mempool_test.go @@ -7,6 +7,9 @@ package mempool import ( "errors" "fmt" + "github.com/33cn/chain33/system/address/eth" + "github.com/33cn/chain33/system/crypto/secp256k1eth" + "github.com/stretchr/testify/assert" "math/rand" "testing" @@ -1475,3 +1478,53 @@ func Test_sortEthSignTyTx(t *testing.T) { require.Equal(t, txs[3].GetNonce(), tx4.GetNonce()) } + +func TestCheckTxsNonce(t *testing.T) { + var err error + c, _ = crypto.Load(types.GetSignName("", types.SECP256K1ETH), -1) + key, _ := common.FromHex(hexPirv) + privKey, err = c.PrivKeyFromBytes(key) + assert.Nil(t, err) + tx0 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000000, Expire: 0, To: toAddr, Nonce: 0} + tx0.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx1 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000000, Expire: 0, To: toAddr, Nonce: 1} + tx1.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx2 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000002, Expire: 0, To: toAddr, Nonce: 1} + tx2.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx3 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000002 + 45999998, Expire: 0, To: toAddr, Nonce: 1} + tx3.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + _, mem := initEnv(10) + //测试nonce 较低的情况下进入mempool 检查 + msg := mem.client.NewMessage("mempool", types.EventTx, tx0) + mem.client.Send(msg, true) + msg, _ = mem.client.Wait(msg) + reply := msg.GetData().(*types.Reply) + assert.False(t, reply.GetIsOk()) + assert.Equal(t, "ErrNonceTooLow", string(reply.GetMsg())) + + msg = mem.client.NewMessage("mempool", types.EventTx, tx1) + mem.client.Send(msg, true) + msg, _ = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.True(t, reply.GetIsOk()) + //相同的nonce的交易,在gas 不满足条件下,不允许通过过 + msg = mem.client.NewMessage("mempool", types.EventTx, tx2) + mem.client.Send(msg, true) + msg, err = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.False(t, reply.GetIsOk()) + assert.Equal(t, "requires at least 10 percent increase in handling fee,need more:45999998", string(reply.GetMsg())) + txs := mem.GetLatestTx() + assert.Equal(t, 1, len(txs)) + assert.Equal(t, txs[0].Hash(), tx1.Hash()) + msg = mem.client.NewMessage("mempool", types.EventTx, tx3) + mem.client.Send(msg, true) + msg, err = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.True(t, reply.GetIsOk()) + + //此时mempool 中应该之后tx3 ,tx1 已经被自动删除 + txs = mem.GetLatestTx() + assert.Equal(t, 1, len(txs)) + assert.Equal(t, txs[0].Hash(), tx3.Hash()) +} diff --git a/types/cfg.go b/types/cfg.go index 347026c44..c7d0a9f3e 100644 --- a/types/cfg.go +++ b/types/cfg.go @@ -314,13 +314,13 @@ type Exec struct { DisableAddrIndex bool `json:"disableAddrIndex,omitempty"` Alias []string `json:"alias,omitempty"` // 是否保存token交易信息 - SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` - EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` - DisableTxIndex bool `json:"disableTxIndex,omitempty"` - DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` - DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` - DisableExecLocal bool `json:"disableExecLocal,omitempty"` - ProxyExecAddress []string `json:"proxyExecAddress,omitempty"` + SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` + EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` + DisableTxIndex bool `json:"disableTxIndex,omitempty"` + DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` + DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` + DisableExecLocal bool `json:"disableExecLocal,omitempty"` + ProxyExecAddress string `json:"proxyExecAddress,omitempty"` } // Pprof 配置 diff --git a/types/error.go b/types/error.go index 588c3f25b..382f764c2 100644 --- a/types/error.go +++ b/types/error.go @@ -207,4 +207,5 @@ var ( ErrPushNotSubscribed = errors.New("ErrPushNotSubscribed") ErrTxChainID = errors.New("ErrTxChainID") ErrTimeout = errors.New("ErrTimeout") + ErrLowNonce = errors.New("ErrNonceTooLow") ) diff --git a/types/fork.go b/types/fork.go index eec698341..a2bdf29f4 100644 --- a/types/fork.go +++ b/types/fork.go @@ -143,6 +143,7 @@ func (f *Forks) SetTestNetFork() { f.SetFork("ForkRootHash", 4500000) f.SetFork(address.ForkFormatAddressKey, 0) f.setFork("ForkCheckEthTxSort", 0) + f.setFork("ForkProxyExec", 0) } func (f *Forks) setLocalFork() { diff --git a/wallet/common/walletoperate.go b/wallet/common/walletoperate.go index b981260b6..a04815d5f 100644 --- a/wallet/common/walletoperate.go +++ b/wallet/common/walletoperate.go @@ -71,6 +71,6 @@ type WalletOperate interface { WaitTx(hash []byte) *types.TransactionDetail WaitTxs(hashes [][]byte) (ret []*types.TransactionDetail) - SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) - SendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) + SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) + SendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) } diff --git a/wallet/sendtx.go b/wallet/sendtx.go index a050b79cd..5970a803f 100644 --- a/wallet/sendtx.go +++ b/wallet/sendtx.go @@ -88,8 +88,8 @@ func (wallet *Wallet) GetHeight() int64 { return h } -func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (err error) { - hash, err := wallet.sendTransaction(payload, execer, priv, to) +func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (err error) { + hash, err := wallet.sendTransaction(payload, execer, priv, addressID, to) if err != nil { return err } @@ -101,17 +101,17 @@ func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, } // SendTransaction 发送一笔交易 -func (wallet *Wallet) SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) { +func (wallet *Wallet) SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) { if !wallet.isInited() { return nil, types.ErrNotInited } wallet.mtx.Lock() defer wallet.mtx.Unlock() - return wallet.sendTransaction(payload, execer, priv, to) + return wallet.sendTransaction(payload, execer, priv, addressID, to) } -func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) { +func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) { if to == "" { to = address.ExecAddress(string(execer)) } @@ -129,7 +129,7 @@ func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv } tx.Fee = fee tx.SetExpire(wallet.client.GetConfig(), time.Second*120) - signID := types.EncodeSignID(int32(wallet.SignType), address.GetDefaultAddressID()) + signID := types.EncodeSignID(int32(wallet.SignType), addressID) tx.Sign(signID, priv) reply, err := wallet.sendTx(tx) if err != nil { @@ -203,10 +203,10 @@ func (wallet *Wallet) queryTx(hash []byte) (*types.TransactionDetail, error) { } // SendToAddress 想合约地址转账 -func (wallet *Wallet) SendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { +func (wallet *Wallet) SendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { wallet.mtx.Lock() defer wallet.mtx.Unlock() - return wallet.sendToAddress(priv, addrto, amount, note, Istoken, tokenSymbol) + return wallet.sendToAddress(priv, addressID, addrto, amount, note, Istoken, tokenSymbol) } func (wallet *Wallet) createSendToAddress(addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.Transaction, error) { @@ -270,12 +270,12 @@ func (wallet *Wallet) createSendToAddress(addrto string, amount int64, note stri return tx, nil } -func (wallet *Wallet) sendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { +func (wallet *Wallet) sendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { tx, err := wallet.createSendToAddress(addrto, amount, note, Istoken, tokenSymbol) if err != nil { return nil, err } - signID := types.EncodeSignID(int32(wallet.SignType), address.GetDefaultAddressID()) + signID := types.EncodeSignID(int32(wallet.SignType), addressID) tx.Sign(signID, priv) reply, err := wallet.api.SendTx(tx) diff --git a/wallet/wallet_proc.go b/wallet/wallet_proc.go index da46d2ead..d65d8d0fe 100644 --- a/wallet/wallet_proc.go +++ b/wallet/wallet_proc.go @@ -7,6 +7,7 @@ package wallet import ( "encoding/hex" "fmt" + "github.com/33cn/chain33/system/address/eth" "io/ioutil" "os" "strings" @@ -640,7 +641,11 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr if err != nil { return nil, err } - return wallet.sendToAddress(priv, addrto, amount, note, SendToAddress.IsToken, SendToAddress.TokenSymbol) + addressID := address.GetDefaultAddressID() + if common.IsHex(addrs[0]) { + addressID = eth.ID + } + return wallet.sendToAddress(priv, addressID, addrto, amount, note, SendToAddress.IsToken, SendToAddress.TokenSymbol) } // ProcWalletSetFee 处理设置手续费 diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 8871fd63b..87db971f5 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -878,16 +878,17 @@ func testSendTx(t *testing.T, wallet *Wallet) { _, err = wallet.GetAllPrivKeys() assert.NoError(t, err) - hash, err := wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("coins"), priv, ToAddr1) + + hash, err := wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("coins"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) //wallet.WaitTx(hash) wallet.WaitTxs([][]byte{hash}) - hash, err = wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1) + hash, err = wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("test"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) t.Log(common.ToHex(hash)) - err = wallet.sendTransactionWait(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1) + err = wallet.sendTransactionWait(&types.ReceiptAccountTransfer{}, []byte("test"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) _, err = wallet.getMinerColdAddr(addr) From 16f1ff5139d5176fd10045ab37048bc1db3dd57c Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 15:43:38 +0800 Subject: [PATCH 03/13] fix fmt --- executor/execenv.go | 2 +- system/mempool/mempool_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/executor/execenv.go b/executor/execenv.go index fd4efffc1..704e3bcf4 100644 --- a/executor/execenv.go +++ b/executor/execenv.go @@ -622,7 +622,7 @@ func (e *executor) proxyGetRealTx(tx *types.Transaction) (*types.Transaction, er } func (e *executor) proxyExecTx(tx *types.Transaction) (*types.Transaction, error) { - var realTx *types.Transaction + var realTx = tx var err error if tx.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { realTx, err = e.proxyGetRealTx(tx) diff --git a/system/mempool/mempool_test.go b/system/mempool/mempool_test.go index 9d8cc7535..bd7d8f651 100644 --- a/system/mempool/mempool_test.go +++ b/system/mempool/mempool_test.go @@ -1511,6 +1511,7 @@ func TestCheckTxsNonce(t *testing.T) { msg = mem.client.NewMessage("mempool", types.EventTx, tx2) mem.client.Send(msg, true) msg, err = mem.client.Wait(msg) + assert.Nil(t, err) reply = msg.GetData().(*types.Reply) assert.False(t, reply.GetIsOk()) assert.Equal(t, "requires at least 10 percent increase in handling fee,need more:45999998", string(reply.GetMsg())) @@ -1520,6 +1521,7 @@ func TestCheckTxsNonce(t *testing.T) { msg = mem.client.NewMessage("mempool", types.EventTx, tx3) mem.client.Send(msg, true) msg, err = mem.client.Wait(msg) + assert.Nil(t, err) reply = msg.GetData().(*types.Reply) assert.True(t, reply.GetIsOk()) From 6fe0a6ea00209ef43c92faa69dc75a7c1a2afe88 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 16:56:27 +0800 Subject: [PATCH 04/13] fix testcase --- cmd/chain33/chain33.system.fork.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/chain33/chain33.system.fork.toml b/cmd/chain33/chain33.system.fork.toml index b9210f2c6..74f579ecd 100644 --- a/cmd/chain33/chain33.system.fork.toml +++ b/cmd/chain33/chain33.system.fork.toml @@ -25,3 +25,4 @@ ForkTicketFundAddrV1=3350000 ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 +ForkProxyExec=0 From 93da582cc7bf7949885ea05dd06e00102da804cc Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Wed, 6 Sep 2023 18:38:59 +0800 Subject: [PATCH 05/13] update --- cmd/chain33/chain33.toml | 3 +- rpc/ethrpc/eth/eth.go | 28 +++++++++++++------ system/mempool/check.go | 59 ++++++++++++++++++++++++++++++++++++++++ types/cfg.go | 13 +++++---- 4 files changed, 87 insertions(+), 16 deletions(-) diff --git a/cmd/chain33/chain33.toml b/cmd/chain33/chain33.toml index c0cf1c408..da1159811 100644 --- a/cmd/chain33/chain33.toml +++ b/cmd/chain33/chain33.toml @@ -306,7 +306,8 @@ enableStat=false #是否开启MVCC插件 enableMVCC=false alias=["token1:token","token2:token","token3:token"] - +#代理执行器地址 +proxyExecAddrss=["0x0000000000000000000000000000000000200005"] [exec.sub.token] #是否保存token交易信息 saveTokenTxList=true diff --git a/rpc/ethrpc/eth/eth.go b/rpc/ethrpc/eth/eth.go index fbdd5ceaa..3ccc81997 100644 --- a/rpc/ethrpc/eth/eth.go +++ b/rpc/ethrpc/eth/eth.go @@ -31,13 +31,14 @@ import ( ) type ethHandler struct { - cli rpcclient.ChannelClient - cfg *ctypes.Chain33Config - grpcCli ctypes.Chain33Client - filtersMu sync.Mutex - filters map[rpc.ID]*filter - evmChainID int64 - filterTimeout time.Duration + cli rpcclient.ChannelClient + cfg *ctypes.Chain33Config + grpcCli ctypes.Chain33Client + filtersMu sync.Mutex + filters map[rpc.ID]*filter + evmChainID int64 + filterTimeout time.Duration + proxyExecAddress []string } var ( @@ -51,6 +52,7 @@ func NewEthAPI(cfg *ctypes.Chain33Config, c queue.Client, api client.QueueProtoc e.cfg = cfg e.filters = make(map[rpc.ID]*filter) e.evmChainID = secp256k1eth.GetEvmChainID() + e.proxyExecAddress = e.cfg.GetModuleConfig().Exec.ProxyExecAddress grpcBindAddr := e.cfg.GetModuleConfig().RPC.GrpcBindAddr _, port, _ := net.SplitHostPort(grpcBindAddr) conn, err := grpc.Dial(fmt.Sprintf("localhost:%v", port), grpc.WithInsecure()) @@ -560,6 +562,16 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) }) fee := properFee.GetProperFee() + //GetMinTxFeeRate 默认1e5 + realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) + if callMsg.To == "0x0000000000000000000000000000000000200005" { + rightFee := realFee + if realFee < fee { + rightFee = fee + } + return hexutil.Uint64(rightFee), nil + } + var minimumGas int64 = 21000 if callMsg.Data == nil || len(*callMsg.Data) == 0 { if fee < e.cfg.GetMinTxFeeRate() { @@ -597,8 +609,6 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) } bigGas, _ := new(big.Int).SetString(gas.Gas, 10) - //GetMinTxFeeRate 默认1e5 - realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) var finalFee = realFee if bigGas.Uint64() > uint64(realFee) { diff --git a/system/mempool/check.go b/system/mempool/check.go index 9f2d861ce..7355a0e79 100644 --- a/system/mempool/check.go +++ b/system/mempool/check.go @@ -1,7 +1,11 @@ package mempool import ( + "bytes" "errors" + "fmt" + "math/big" + "sort" "sync/atomic" "time" @@ -198,6 +202,15 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } } + //检查mempool内是否有相同的tx.nonce + if types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { + err = mem.evmTxNonceCheck(tx.Tx()) + if err != nil { + msg.Data = err + return msg + } + } + err = mem.PushTx(tx.Tx()) if err != nil { if err == types.ErrMemFull { @@ -209,3 +222,49 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } return msg } + +//evmTxNonceCheck 检查eth noce 是否有重复值,如果有的话,需要比较txFee大小,用于替换较小的fee的那笔交易 +func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { + if tx.GetNonce() < mem.getCurrentNonce(tx.From()) { + return errors.New("nonce too low") + } + details := mem.GetAccTxs(&types.ReqAddrs{Addrs: []string{tx.From()}}) + txs := details.GetTxs() + txs = append(txs, &types.TransactionDetail{Tx: tx, Index: int64(len(txs))}) + if len(txs) > 1 { + sort.SliceStable(txs, func(i, j int) bool { //nonce asc + return txs[i].Tx.GetNonce() < txs[j].Tx.GetNonce() + }) + //遇到相同的Nonce ,较低的手续费的交易将被删除 + for i, stx := range txs { + if bytes.Equal(stx.Tx.Hash(), tx.Hash()) { + continue + } + if txs[i].GetTx().GetNonce() == tx.GetNonce() { + //step1 先比较交易创建的时间,后创建的交易要求比前面的交易手续费更高,否则直接删除 + if tx.Expire > txs[i].GetTx().Expire { + bnfee := big.NewInt(txs[i].GetTx().Fee) + //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 + bnfee = bnfee.Mul(bnfee, big.NewInt(110)) + bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) + if tx.Fee < bnfee.Int64() { + err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) + mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) + return err + } + + } + //删除Expire 较大的交易或者更低手续费的交易,确保先创建的交易留在mempool 中 + mem.RemoveTxs(&types.TxHashList{ + Hashes: [][]byte{txs[i].GetTx().Hash()}, + }) + + return nil + } + } + + } + + return nil + +} diff --git a/types/cfg.go b/types/cfg.go index 6e6d289f9..347026c44 100644 --- a/types/cfg.go +++ b/types/cfg.go @@ -314,12 +314,13 @@ type Exec struct { DisableAddrIndex bool `json:"disableAddrIndex,omitempty"` Alias []string `json:"alias,omitempty"` // 是否保存token交易信息 - SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` - EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` - DisableTxIndex bool `json:"disableTxIndex,omitempty"` - DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` - DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` - DisableExecLocal bool `json:"disableExecLocal,omitempty"` + SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` + EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` + DisableTxIndex bool `json:"disableTxIndex,omitempty"` + DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` + DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` + DisableExecLocal bool `json:"disableExecLocal,omitempty"` + ProxyExecAddress []string `json:"proxyExecAddress,omitempty"` } // Pprof 配置 From 02b27f5ce15b87d811a5c7b3c7441281aa4676ee Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 14:34:25 +0800 Subject: [PATCH 06/13] add proxyexec --- cmd/chain33/chain33.fork.toml | 1 + cmd/chain33/chain33.toml | 2 +- executor/execenv.go | 51 ++++++++++++++++++++++++++++++-- rpc/ethrpc/eth/eth.go | 19 ++++++------ system/mempool/check.go | 41 +++++++++++++------------- system/mempool/mempool_test.go | 53 ++++++++++++++++++++++++++++++++++ types/cfg.go | 14 ++++----- types/error.go | 1 + types/fork.go | 1 + wallet/common/walletoperate.go | 4 +-- wallet/sendtx.go | 20 ++++++------- wallet/wallet_proc.go | 7 ++++- wallet/wallet_test.go | 7 +++-- 13 files changed, 165 insertions(+), 56 deletions(-) diff --git a/cmd/chain33/chain33.fork.toml b/cmd/chain33/chain33.fork.toml index eff5c318a..921312d6d 100644 --- a/cmd/chain33/chain33.fork.toml +++ b/cmd/chain33/chain33.fork.toml @@ -25,6 +25,7 @@ ForkTicketFundAddrV1=3350000 ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 +ForkProxyExec=0 [fork.sub.none] ForkUseTimeDelay=0 diff --git a/cmd/chain33/chain33.toml b/cmd/chain33/chain33.toml index da1159811..c0f7e99b4 100644 --- a/cmd/chain33/chain33.toml +++ b/cmd/chain33/chain33.toml @@ -307,7 +307,7 @@ enableStat=false enableMVCC=false alias=["token1:token","token2:token","token3:token"] #代理执行器地址 -proxyExecAddrss=["0x0000000000000000000000000000000000200005"] +proxyExecAddrss="0x0000000000000000000000000000000000200005" [exec.sub.token] #是否保存token交易信息 saveTokenTxList=true diff --git a/executor/execenv.go b/executor/execenv.go index bcf0ad746..fd4efffc1 100644 --- a/executor/execenv.go +++ b/executor/execenv.go @@ -6,7 +6,8 @@ package executor import ( "bytes" - + "errors" + "fmt" "github.com/33cn/chain33/account" "github.com/33cn/chain33/client" "github.com/33cn/chain33/client/api" @@ -598,6 +599,42 @@ func (e *executor) rollback() { } } +func (e *executor) proxyGetRealTx(tx *types.Transaction) (*types.Transaction, error) { + if string(types.GetRealExecName(tx.GetExecer())) != "evm" { + return nil, fmt.Errorf("execName %s not allowd", string(types.GetRealExecName(tx.GetExecer()))) + } + var actionData types.EVMContractAction4Chain33 + err := types.Decode(tx.GetPayload(), &actionData) + if err != nil { + return nil, err + } + if len(actionData.GetPara()) == 0 { + return nil, errors.New("empty tx") + } + var realTx types.Transaction + err = types.Decode(actionData.Para, &realTx) + if err != nil { + return nil, err + } + + return &realTx, nil + +} + +func (e *executor) proxyExecTx(tx *types.Transaction) (*types.Transaction, error) { + var realTx *types.Transaction + var err error + if tx.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { + realTx, err = e.proxyGetRealTx(tx) + if err != nil { + return realTx, err + } + realTx.Signature = tx.Signature + + } + return realTx, nil +} + func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*types.Receipt, error) { if e.height == 0 { //genesis block 不检查手续费 receipt, err := e.Exec(tx, index) @@ -609,10 +646,20 @@ func (e *executor) execTx(exec *Executor, tx *types.Transaction, index int) (*ty } return receipt, nil } + + var err error + //代理执行 EVM-->txpayload-->chain33 tx + if e.cfg.IsFork(e.height, "ForkProxyExec") { + tx, err = e.proxyExecTx(tx) + if err != nil { + return nil, err + } + } + //交易检查规则: //1. mempool 检查区块,尽量检查更多的错误 //2. 打包的时候,尽量打包更多的交易,只要基本的签名,以及格式没有问题 - err := e.checkTx(tx, index) + err = e.checkTx(tx, index) if err != nil { elog.Error("execTx.checkTx ", "txhash", common.ToHex(tx.Hash()), "err", err) if e.cfg.IsPara() { diff --git a/rpc/ethrpc/eth/eth.go b/rpc/ethrpc/eth/eth.go index 3ccc81997..0efa9d5b0 100644 --- a/rpc/ethrpc/eth/eth.go +++ b/rpc/ethrpc/eth/eth.go @@ -31,14 +31,13 @@ import ( ) type ethHandler struct { - cli rpcclient.ChannelClient - cfg *ctypes.Chain33Config - grpcCli ctypes.Chain33Client - filtersMu sync.Mutex - filters map[rpc.ID]*filter - evmChainID int64 - filterTimeout time.Duration - proxyExecAddress []string + cli rpcclient.ChannelClient + cfg *ctypes.Chain33Config + grpcCli ctypes.Chain33Client + filtersMu sync.Mutex + filters map[rpc.ID]*filter + evmChainID int64 + filterTimeout time.Duration } var ( @@ -52,7 +51,6 @@ func NewEthAPI(cfg *ctypes.Chain33Config, c queue.Client, api client.QueueProtoc e.cfg = cfg e.filters = make(map[rpc.ID]*filter) e.evmChainID = secp256k1eth.GetEvmChainID() - e.proxyExecAddress = e.cfg.GetModuleConfig().Exec.ProxyExecAddress grpcBindAddr := e.cfg.GetModuleConfig().RPC.GrpcBindAddr _, port, _ := net.SplitHostPort(grpcBindAddr) conn, err := grpc.Dial(fmt.Sprintf("localhost:%v", port), grpc.WithInsecure()) @@ -564,7 +562,8 @@ func (e *ethHandler) EstimateGas(callMsg *types.CallMsg) (hexutil.Uint64, error) fee := properFee.GetProperFee() //GetMinTxFeeRate 默认1e5 realFee, _ := tx.GetRealFee(e.cfg.GetMinTxFeeRate()) - if callMsg.To == "0x0000000000000000000000000000000000200005" { + //判断是否是代理执行的地址,如果是,则直接返回,不会交给evm执行器去模拟执行计算gas. + if callMsg.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { rightFee := realFee if realFee < fee { rightFee = fee diff --git a/system/mempool/check.go b/system/mempool/check.go index 7355a0e79..a64dced20 100644 --- a/system/mempool/check.go +++ b/system/mempool/check.go @@ -203,12 +203,10 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { } //检查mempool内是否有相同的tx.nonce - if types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { - err = mem.evmTxNonceCheck(tx.Tx()) - if err != nil { - msg.Data = err - return msg - } + err = mem.evmTxNonceCheck(tx.Tx()) + if err != nil { + msg.Data = err + return msg } err = mem.PushTx(tx.Tx()) @@ -225,8 +223,13 @@ func (mem *Mempool) checkTxRemote(msg *queue.Message) *queue.Message { //evmTxNonceCheck 检查eth noce 是否有重复值,如果有的话,需要比较txFee大小,用于替换较小的fee的那笔交易 func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { + if !types.IsEthSignID(tx.Tx().GetSignature().GetTy()) { + return nil + } + + //较小的nonce 则返回错误,不被允许进入mempool if tx.GetNonce() < mem.getCurrentNonce(tx.From()) { - return errors.New("nonce too low") + return types.ErrLowNonce } details := mem.GetAccTxs(&types.ReqAddrs{Addrs: []string{tx.From()}}) txs := details.GetTxs() @@ -240,25 +243,23 @@ func (mem *Mempool) evmTxNonceCheck(tx *types.Transaction) error { if bytes.Equal(stx.Tx.Hash(), tx.Hash()) { continue } - if txs[i].GetTx().GetNonce() == tx.GetNonce() { - //step1 先比较交易创建的时间,后创建的交易要求比前面的交易手续费更高,否则直接删除 - if tx.Expire > txs[i].GetTx().Expire { - bnfee := big.NewInt(txs[i].GetTx().Fee) - //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 - bnfee = bnfee.Mul(bnfee, big.NewInt(110)) - bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) - if tx.Fee < bnfee.Int64() { - err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) - mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) - return err - } + if txs[i].GetTx().GetNonce() == tx.GetNonce() { + bnfee := big.NewInt(txs[i].GetTx().Fee) + //相同的nonce,fee 必须提升至1.1 倍 才能有效替换之前的交易 + bnfee = bnfee.Mul(bnfee, big.NewInt(110)) + bnfee = bnfee.Div(bnfee, big.NewInt(1e2)) + if tx.Fee < bnfee.Int64() { + err := fmt.Errorf("requires at least 10 percent increase in handling fee,need more:%d", bnfee.Int64()-tx.Fee) + mlog.Error("checkTxNonce", "fee err", err, "txfee", tx.Fee, "mempooltx", txs[0].GetTx().Fee, "from:", tx.From()) + return err } + //删除Expire 较大的交易或者更低手续费的交易,确保先创建的交易留在mempool 中 mem.RemoveTxs(&types.TxHashList{ Hashes: [][]byte{txs[i].GetTx().Hash()}, }) - + mlog.Info("evmTxNonceCheck", "remote txhash:", common.ToHex(txs[i].GetTx().Hash()), "replace txHash:", common.ToHex(tx.Hash())) return nil } } diff --git a/system/mempool/mempool_test.go b/system/mempool/mempool_test.go index 4efd0fb6c..9d8cc7535 100644 --- a/system/mempool/mempool_test.go +++ b/system/mempool/mempool_test.go @@ -7,6 +7,9 @@ package mempool import ( "errors" "fmt" + "github.com/33cn/chain33/system/address/eth" + "github.com/33cn/chain33/system/crypto/secp256k1eth" + "github.com/stretchr/testify/assert" "math/rand" "testing" @@ -1475,3 +1478,53 @@ func Test_sortEthSignTyTx(t *testing.T) { require.Equal(t, txs[3].GetNonce(), tx4.GetNonce()) } + +func TestCheckTxsNonce(t *testing.T) { + var err error + c, _ = crypto.Load(types.GetSignName("", types.SECP256K1ETH), -1) + key, _ := common.FromHex(hexPirv) + privKey, err = c.PrivKeyFromBytes(key) + assert.Nil(t, err) + tx0 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000000, Expire: 0, To: toAddr, Nonce: 0} + tx0.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx1 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000000, Expire: 0, To: toAddr, Nonce: 1} + tx1.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx2 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000002, Expire: 0, To: toAddr, Nonce: 1} + tx2.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + tx3 := &types.Transaction{ChainID: 0, Execer: []byte("evm"), Payload: types.Encode(transfer), Fee: 460000002 + 45999998, Expire: 0, To: toAddr, Nonce: 1} + tx3.Sign(types.EncodeSignID(secp256k1eth.ID, eth.ID), privKey) + _, mem := initEnv(10) + //测试nonce 较低的情况下进入mempool 检查 + msg := mem.client.NewMessage("mempool", types.EventTx, tx0) + mem.client.Send(msg, true) + msg, _ = mem.client.Wait(msg) + reply := msg.GetData().(*types.Reply) + assert.False(t, reply.GetIsOk()) + assert.Equal(t, "ErrNonceTooLow", string(reply.GetMsg())) + + msg = mem.client.NewMessage("mempool", types.EventTx, tx1) + mem.client.Send(msg, true) + msg, _ = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.True(t, reply.GetIsOk()) + //相同的nonce的交易,在gas 不满足条件下,不允许通过过 + msg = mem.client.NewMessage("mempool", types.EventTx, tx2) + mem.client.Send(msg, true) + msg, err = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.False(t, reply.GetIsOk()) + assert.Equal(t, "requires at least 10 percent increase in handling fee,need more:45999998", string(reply.GetMsg())) + txs := mem.GetLatestTx() + assert.Equal(t, 1, len(txs)) + assert.Equal(t, txs[0].Hash(), tx1.Hash()) + msg = mem.client.NewMessage("mempool", types.EventTx, tx3) + mem.client.Send(msg, true) + msg, err = mem.client.Wait(msg) + reply = msg.GetData().(*types.Reply) + assert.True(t, reply.GetIsOk()) + + //此时mempool 中应该之后tx3 ,tx1 已经被自动删除 + txs = mem.GetLatestTx() + assert.Equal(t, 1, len(txs)) + assert.Equal(t, txs[0].Hash(), tx3.Hash()) +} diff --git a/types/cfg.go b/types/cfg.go index 347026c44..c7d0a9f3e 100644 --- a/types/cfg.go +++ b/types/cfg.go @@ -314,13 +314,13 @@ type Exec struct { DisableAddrIndex bool `json:"disableAddrIndex,omitempty"` Alias []string `json:"alias,omitempty"` // 是否保存token交易信息 - SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` - EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` - DisableTxIndex bool `json:"disableTxIndex,omitempty"` - DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` - DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` - DisableExecLocal bool `json:"disableExecLocal,omitempty"` - ProxyExecAddress []string `json:"proxyExecAddress,omitempty"` + SaveTokenTxList bool `json:"saveTokenTxList,omitempty"` + EnableAddrFeeIndex bool `json:"enableAddrFeeIndex,omitempty"` + DisableTxIndex bool `json:"disableTxIndex,omitempty"` + DisableFeeIndex bool `json:"disableFeeIndex,omitempty"` + DisableTxDupCheck bool `json:"disableTxDupCheck,omitempty"` + DisableExecLocal bool `json:"disableExecLocal,omitempty"` + ProxyExecAddress string `json:"proxyExecAddress,omitempty"` } // Pprof 配置 diff --git a/types/error.go b/types/error.go index 588c3f25b..382f764c2 100644 --- a/types/error.go +++ b/types/error.go @@ -207,4 +207,5 @@ var ( ErrPushNotSubscribed = errors.New("ErrPushNotSubscribed") ErrTxChainID = errors.New("ErrTxChainID") ErrTimeout = errors.New("ErrTimeout") + ErrLowNonce = errors.New("ErrNonceTooLow") ) diff --git a/types/fork.go b/types/fork.go index eec698341..a2bdf29f4 100644 --- a/types/fork.go +++ b/types/fork.go @@ -143,6 +143,7 @@ func (f *Forks) SetTestNetFork() { f.SetFork("ForkRootHash", 4500000) f.SetFork(address.ForkFormatAddressKey, 0) f.setFork("ForkCheckEthTxSort", 0) + f.setFork("ForkProxyExec", 0) } func (f *Forks) setLocalFork() { diff --git a/wallet/common/walletoperate.go b/wallet/common/walletoperate.go index b981260b6..a04815d5f 100644 --- a/wallet/common/walletoperate.go +++ b/wallet/common/walletoperate.go @@ -71,6 +71,6 @@ type WalletOperate interface { WaitTx(hash []byte) *types.TransactionDetail WaitTxs(hashes [][]byte) (ret []*types.TransactionDetail) - SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) - SendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) + SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) + SendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) } diff --git a/wallet/sendtx.go b/wallet/sendtx.go index a050b79cd..5970a803f 100644 --- a/wallet/sendtx.go +++ b/wallet/sendtx.go @@ -88,8 +88,8 @@ func (wallet *Wallet) GetHeight() int64 { return h } -func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (err error) { - hash, err := wallet.sendTransaction(payload, execer, priv, to) +func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (err error) { + hash, err := wallet.sendTransaction(payload, execer, priv, addressID, to) if err != nil { return err } @@ -101,17 +101,17 @@ func (wallet *Wallet) sendTransactionWait(payload types.Message, execer []byte, } // SendTransaction 发送一笔交易 -func (wallet *Wallet) SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) { +func (wallet *Wallet) SendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) { if !wallet.isInited() { return nil, types.ErrNotInited } wallet.mtx.Lock() defer wallet.mtx.Unlock() - return wallet.sendTransaction(payload, execer, priv, to) + return wallet.sendTransaction(payload, execer, priv, addressID, to) } -func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, to string) (hash []byte, err error) { +func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv crypto.PrivKey, addressID int32, to string) (hash []byte, err error) { if to == "" { to = address.ExecAddress(string(execer)) } @@ -129,7 +129,7 @@ func (wallet *Wallet) sendTransaction(payload types.Message, execer []byte, priv } tx.Fee = fee tx.SetExpire(wallet.client.GetConfig(), time.Second*120) - signID := types.EncodeSignID(int32(wallet.SignType), address.GetDefaultAddressID()) + signID := types.EncodeSignID(int32(wallet.SignType), addressID) tx.Sign(signID, priv) reply, err := wallet.sendTx(tx) if err != nil { @@ -203,10 +203,10 @@ func (wallet *Wallet) queryTx(hash []byte) (*types.TransactionDetail, error) { } // SendToAddress 想合约地址转账 -func (wallet *Wallet) SendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { +func (wallet *Wallet) SendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { wallet.mtx.Lock() defer wallet.mtx.Unlock() - return wallet.sendToAddress(priv, addrto, amount, note, Istoken, tokenSymbol) + return wallet.sendToAddress(priv, addressID, addrto, amount, note, Istoken, tokenSymbol) } func (wallet *Wallet) createSendToAddress(addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.Transaction, error) { @@ -270,12 +270,12 @@ func (wallet *Wallet) createSendToAddress(addrto string, amount int64, note stri return tx, nil } -func (wallet *Wallet) sendToAddress(priv crypto.PrivKey, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { +func (wallet *Wallet) sendToAddress(priv crypto.PrivKey, addressID int32, addrto string, amount int64, note string, Istoken bool, tokenSymbol string) (*types.ReplyHash, error) { tx, err := wallet.createSendToAddress(addrto, amount, note, Istoken, tokenSymbol) if err != nil { return nil, err } - signID := types.EncodeSignID(int32(wallet.SignType), address.GetDefaultAddressID()) + signID := types.EncodeSignID(int32(wallet.SignType), addressID) tx.Sign(signID, priv) reply, err := wallet.api.SendTx(tx) diff --git a/wallet/wallet_proc.go b/wallet/wallet_proc.go index da46d2ead..d65d8d0fe 100644 --- a/wallet/wallet_proc.go +++ b/wallet/wallet_proc.go @@ -7,6 +7,7 @@ package wallet import ( "encoding/hex" "fmt" + "github.com/33cn/chain33/system/address/eth" "io/ioutil" "os" "strings" @@ -640,7 +641,11 @@ func (wallet *Wallet) ProcSendToAddress(SendToAddress *types.ReqWalletSendToAddr if err != nil { return nil, err } - return wallet.sendToAddress(priv, addrto, amount, note, SendToAddress.IsToken, SendToAddress.TokenSymbol) + addressID := address.GetDefaultAddressID() + if common.IsHex(addrs[0]) { + addressID = eth.ID + } + return wallet.sendToAddress(priv, addressID, addrto, amount, note, SendToAddress.IsToken, SendToAddress.TokenSymbol) } // ProcWalletSetFee 处理设置手续费 diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 8871fd63b..87db971f5 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -878,16 +878,17 @@ func testSendTx(t *testing.T, wallet *Wallet) { _, err = wallet.GetAllPrivKeys() assert.NoError(t, err) - hash, err := wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("coins"), priv, ToAddr1) + + hash, err := wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("coins"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) //wallet.WaitTx(hash) wallet.WaitTxs([][]byte{hash}) - hash, err = wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1) + hash, err = wallet.SendTransaction(&types.ReceiptAccountTransfer{}, []byte("test"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) t.Log(common.ToHex(hash)) - err = wallet.sendTransactionWait(&types.ReceiptAccountTransfer{}, []byte("test"), priv, ToAddr1) + err = wallet.sendTransactionWait(&types.ReceiptAccountTransfer{}, []byte("test"), priv, address.GetDefaultAddressID(), ToAddr1) assert.NoError(t, err) _, err = wallet.getMinerColdAddr(addr) From 8e00017df4c43889188cfd0798910c12f763c508 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 15:43:38 +0800 Subject: [PATCH 07/13] fix fmt --- executor/execenv.go | 2 +- system/mempool/mempool_test.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/executor/execenv.go b/executor/execenv.go index fd4efffc1..704e3bcf4 100644 --- a/executor/execenv.go +++ b/executor/execenv.go @@ -622,7 +622,7 @@ func (e *executor) proxyGetRealTx(tx *types.Transaction) (*types.Transaction, er } func (e *executor) proxyExecTx(tx *types.Transaction) (*types.Transaction, error) { - var realTx *types.Transaction + var realTx = tx var err error if tx.To == e.cfg.GetModuleConfig().Exec.ProxyExecAddress { realTx, err = e.proxyGetRealTx(tx) diff --git a/system/mempool/mempool_test.go b/system/mempool/mempool_test.go index 9d8cc7535..bd7d8f651 100644 --- a/system/mempool/mempool_test.go +++ b/system/mempool/mempool_test.go @@ -1511,6 +1511,7 @@ func TestCheckTxsNonce(t *testing.T) { msg = mem.client.NewMessage("mempool", types.EventTx, tx2) mem.client.Send(msg, true) msg, err = mem.client.Wait(msg) + assert.Nil(t, err) reply = msg.GetData().(*types.Reply) assert.False(t, reply.GetIsOk()) assert.Equal(t, "requires at least 10 percent increase in handling fee,need more:45999998", string(reply.GetMsg())) @@ -1520,6 +1521,7 @@ func TestCheckTxsNonce(t *testing.T) { msg = mem.client.NewMessage("mempool", types.EventTx, tx3) mem.client.Send(msg, true) msg, err = mem.client.Wait(msg) + assert.Nil(t, err) reply = msg.GetData().(*types.Reply) assert.True(t, reply.GetIsOk()) From 375f2b80d9a10129a9029ec6bfe9b88e5dd85704 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Mon, 11 Sep 2023 16:56:27 +0800 Subject: [PATCH 08/13] fix testcase --- cmd/chain33/chain33.system.fork.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/chain33/chain33.system.fork.toml b/cmd/chain33/chain33.system.fork.toml index b9210f2c6..74f579ecd 100644 --- a/cmd/chain33/chain33.system.fork.toml +++ b/cmd/chain33/chain33.system.fork.toml @@ -25,3 +25,4 @@ ForkTicketFundAddrV1=3350000 ForkRootHash=4500000 ForkFormatAddressKey=0 ForkCheckEthTxSort=0 +ForkProxyExec=0 From c6155db4871796cc1507a50001aa11ff1f455f8f Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Fri, 15 Sep 2023 15:22:43 +0800 Subject: [PATCH 09/13] add testcase --- cmd/chain33/chain33.test.toml | 6 +++ executor/execenv_test.go | 67 +++++++++++++++++++++++++++++++++- executor/executor_real_test.go | 10 ++--- queue/queue_test.go | 1 + system/p2p/dht/p2p_test.go | 2 +- types/defaultcfg.go | 8 +++- 6 files changed, 84 insertions(+), 10 deletions(-) diff --git a/cmd/chain33/chain33.test.toml b/cmd/chain33/chain33.test.toml index 4741a3922..1ee425815 100644 --- a/cmd/chain33/chain33.test.toml +++ b/cmd/chain33/chain33.test.toml @@ -207,8 +207,14 @@ coinType="bty" minerwhitelist=["*"] [exec] +#交易费相关统一在mempool中配置 +#是否开启stat插件 enableStat=false +#是否开启MVCC插件 enableMVCC=false +alias=["token1:token","token2:token","token3:token"] +#代理执行器地址 +proxyExecAddress="0x0000000000000000000000000000000000200005" [exec.sub.token] saveTokenTxList=true diff --git a/executor/execenv_test.go b/executor/execenv_test.go index fb6cace58..13edc180c 100644 --- a/executor/execenv_test.go +++ b/executor/execenv_test.go @@ -5,11 +5,16 @@ package executor import ( + "github.com/33cn/chain33/common/crypto" + erpctypes "github.com/33cn/chain33/rpc/ethrpc/types" + drivers "github.com/33cn/chain33/system/dapp" + ecommon "github.com/ethereum/go-ethereum/common" + ethtypes "github.com/ethereum/go-ethereum/core/types" + ethcrypto "github.com/ethereum/go-ethereum/crypto" + "math/big" "testing" "time" - drivers "github.com/33cn/chain33/system/dapp" - "strings" _ "github.com/33cn/chain33/system" @@ -19,6 +24,7 @@ import ( ) func TestLoadDriverFork(t *testing.T) { + str := types.GetDefaultCfgstring() new := strings.Replace(str, "Title=\"local\"", "Title=\"chain33\"", 1) exec, _ := initEnv(types.MergeCfg(types.ReadFile("../cmd/chain33/chain33.fork.toml"), new)) @@ -97,3 +103,60 @@ func (app *notAllowApp) Allow(tx *types.Transaction, index int) error { } return types.ErrActionNotSupport } + +func TestProxyExec(t *testing.T) { + exec, _ := initEnv(types.GetDefaultCfgstring()) + cfg := exec.client.GetConfig() + ctx := &executorCtx{ + stateHash: nil, + height: 0, + blocktime: time.Now().Unix(), + difficulty: 1, + mainHash: nil, + parentHash: nil, + } + + execute := newExecutor(ctx, exec, nil, nil, nil) + //测试解析代理地址 + proxyAddr := ecommon.HexToAddress("0x0000000000000000000000000000000000200005") + var hexKey = "7939624566468cfa3cb2c9f39d5ad83bdc7cf4356bfd1a7b8094abda6b0699d1" + sk, err := ethcrypto.ToECDSA(ecommon.FromHex(hexKey)) + assert.Nil(t, err) + + signer := ethtypes.NewEIP155Signer(big.NewInt(3999)) + //构建eth交易 + to, _ := util.Genaddress() + //coins 转账,没有签名的裸交易 + coinsTx := util.CreateCoinsTx(cfg, nil, to, 1000) + etx := ethtypes.NewTransaction(uint64(0), proxyAddr, big.NewInt(0), 3000000, big.NewInt(10e9), types.Encode(coinsTx)) + signtx, err := ethtypes.SignTx(etx, signer, sk) + assert.Nil(t, err) + v, r, s := signtx.RawSignatureValues() + cv, err := erpctypes.CaculateRealV(v, signtx.ChainId().Uint64(), signtx.Type()) + assert.Nil(t, err) + sig := make([]byte, 65) + copy(sig[32-len(r.Bytes()):32], r.Bytes()) + copy(sig[64-len(s.Bytes()):64], s.Bytes()) + sig[64] = cv + txSha3 := signer.Hash(signtx) + pubkey, err := ethcrypto.Ecrecover(txSha3.Bytes(), sig) + assembleTx := erpctypes.AssembleChain33Tx(signtx, sig, pubkey, cfg) + //checkSign + err = execute.checkTx(assembleTx, 0) + assert.Errorf(t, err, "ErrExecNameNotAllow") + types.AllowUserExec = append(types.AllowUserExec, []byte("evm")) + err = execute.checkTx(assembleTx, 0) + assert.Nil(t, err) + + crypto.Init(cfg.GetModuleConfig().Crypto, cfg.GetSubConfig().Crypto) + assert.True(t, assembleTx.CheckSign(0)) + //解析交易 + realTx, err := execute.proxyExecTx(assembleTx) + assert.Nil(t, err) + assert.Equal(t, "0xa42431da868c58877a627cc71dc95f01bf40c196", realTx.From()) + testTx := realTx.Clone() + testTx.Signature = nil + + //与原始交易对比 + assert.Equal(t, coinsTx.Hash(), testTx.Hash()) +} diff --git a/executor/executor_real_test.go b/executor/executor_real_test.go index 587df9f85..989f0947b 100644 --- a/executor/executor_real_test.go +++ b/executor/executor_real_test.go @@ -7,12 +7,6 @@ package executor_test import ( "errors" "fmt" - "net/http" - _ "net/http/pprof" - "testing" - - "sync" - "github.com/33cn/chain33/common" "github.com/33cn/chain33/common/address" "github.com/33cn/chain33/common/merkle" @@ -22,6 +16,10 @@ import ( "github.com/33cn/chain33/util" "github.com/33cn/chain33/util/testnode" "github.com/stretchr/testify/assert" + "net/http" + _ "net/http/pprof" + "sync" + "testing" ) var runonce sync.Once diff --git a/queue/queue_test.go b/queue/queue_test.go index f07437e12..4d96bf905 100644 --- a/queue/queue_test.go +++ b/queue/queue_test.go @@ -512,6 +512,7 @@ func TestChannelClose(t *testing.T) { go q.Start() //rpc 模块 会向其他模块发送消息,自己本身不需要订阅消息 go func() { + time.Sleep(time.Millisecond * 100) done <- struct{}{} }() for i := 0; i < 10000; i++ { diff --git a/system/p2p/dht/p2p_test.go b/system/p2p/dht/p2p_test.go index 05ff882e3..dac3b8388 100644 --- a/system/p2p/dht/p2p_test.go +++ b/system/p2p/dht/p2p_test.go @@ -469,5 +469,5 @@ func Test_p2p(t *testing.T) { tcfg.DbCache = 4 tcfg.DbPath = filepath.Join(datadir, "addrbook") testAddrbook(t, &tcfg) - p2p.CloseP2P() + //p2p.CloseP2P() } diff --git a/types/defaultcfg.go b/types/defaultcfg.go index e922bf458..7581333bb 100644 --- a/types/defaultcfg.go +++ b/types/defaultcfg.go @@ -23,7 +23,9 @@ enableTypes=[] #设置启用的加密插件名称,不配置启用所有 [crypto.enableHeight] #配置已启用插件的启用高度,不配置采用默认高度0, 负数表示不启用 secp256k1=0 [crypto.sub.secp256k1] #支持插件子配置 -[crypto.sub.secp256k1eth] #支持插件子配置 + +[crypto.sub.secp256k1eth] +#兼容EVM链的链ID evmChainID=3999 [log] # 日志级别,支持debug(dbug)/info/warn/error(eror)/crit @@ -202,8 +204,12 @@ minerwhitelist=["*"] [exec] enableStat=false enableMVCC=false +#代理执行器地址 +proxyExecAddress="0x0000000000000000000000000000000000200005" alias=["token1:token","token2:token","token3:token"] [exec.sub.coins] +#允许evm执行器操作coins +friendExecer=["evm"] [exec.sub.token] saveTokenTxList=true From 5cb5b6c27241f41963c27e798993999e92e2fab4 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Fri, 15 Sep 2023 15:25:15 +0800 Subject: [PATCH 10/13] fix #1311 --- types/defaultcfg.go | 1 + 1 file changed, 1 insertion(+) diff --git a/types/defaultcfg.go b/types/defaultcfg.go index 7581333bb..5e15cf57e 100644 --- a/types/defaultcfg.go +++ b/types/defaultcfg.go @@ -204,6 +204,7 @@ minerwhitelist=["*"] [exec] enableStat=false enableMVCC=false + #代理执行器地址 proxyExecAddress="0x0000000000000000000000000000000000200005" alias=["token1:token","token2:token","token3:token"] From 9d21b1090610f8f3b2efb7bf8f134c67ed2401da Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Fri, 15 Sep 2023 15:40:23 +0800 Subject: [PATCH 11/13] merge master --- system/p2p/dht/p2p_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/p2p/dht/p2p_test.go b/system/p2p/dht/p2p_test.go index a7c3fb271..5560e1d9a 100644 --- a/system/p2p/dht/p2p_test.go +++ b/system/p2p/dht/p2p_test.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/stretchr/testify/mock" clientMocks "github.com/33cn/chain33/client/mocks" @@ -469,5 +468,4 @@ func Test_p2p(t *testing.T) { tcfg.DbPath = filepath.Join(datadir, "addrbook") testAddrbook(t, &tcfg) dhtp2p.reStart() - } From c9756c5ecff4a235f406389276719ad6ec1ed2a6 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Fri, 15 Sep 2023 16:15:48 +0800 Subject: [PATCH 12/13] update p2ptest --- system/p2p/dht/p2p_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/p2p/dht/p2p_test.go b/system/p2p/dht/p2p_test.go index 5560e1d9a..e4e879c15 100644 --- a/system/p2p/dht/p2p_test.go +++ b/system/p2p/dht/p2p_test.go @@ -6,6 +6,8 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/libp2p/go-libp2p" + "github.com/multiformats/go-multiaddr" "github.com/stretchr/testify/mock" clientMocks "github.com/33cn/chain33/client/mocks" From 0e855c8f5887bf96f5a02197e2cfa2221827a3e3 Mon Sep 17 00:00:00 2001 From: libangzhu <601276804@qq.com> Date: Fri, 15 Sep 2023 16:31:54 +0800 Subject: [PATCH 13/13] fix fmt err --- executor/execenv_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/executor/execenv_test.go b/executor/execenv_test.go index 13edc180c..f8c9ce35c 100644 --- a/executor/execenv_test.go +++ b/executor/execenv_test.go @@ -140,6 +140,7 @@ func TestProxyExec(t *testing.T) { sig[64] = cv txSha3 := signer.Hash(signtx) pubkey, err := ethcrypto.Ecrecover(txSha3.Bytes(), sig) + assert.Nil(t, err) assembleTx := erpctypes.AssembleChain33Tx(signtx, sig, pubkey, cfg) //checkSign err = execute.checkTx(assembleTx, 0)