Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Backport upstream changes #2

Draft
wants to merge 49 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
773438f
Problem: gasWanted is not aligned for process proposal mode (#493)
mmsqe Jun 26, 2024
f9cd15e
Problem: no way to disable nonce checking in benchmark (#495)
yihuang Jun 28, 2024
e5b222f
Problem: no MaxTx set from config for mempool (#496)
mmsqe Jul 2, 2024
45ac081
Problem: insufficient invalid value check in eth transaction (#497)
mmsqe Jul 12, 2024
9c959a2
Problem: incarnation cache not enabled (#498)
yihuang Jul 15, 2024
d874df7
Problem: no overflow check when add gasLimit to gasWanted (#500)
mmsqe Jul 17, 2024
f3e62cb
Problem: invalid chain id for signer (#501)
mmsqe Jul 24, 2024
3509552
Problem: benchmark logic don't increase nonce (#502)
yihuang Jul 29, 2024
c36b266
Problem: cometbft not up to date (#505)
mmsqe Aug 1, 2024
b0022ea
Problem: disable of create vesting account messages are not complete …
mmsqe Aug 1, 2024
ff4caa1
Optimize AnteHandle method to skip checks if disabledMsgs is empty (#…
fx0x55 Aug 2, 2024
0e0baa4
Problem: vote_extensions is not disabled in test (#507)
mmsqe Aug 2, 2024
e3b813e
Problem: no debug files uploaded when timeout in ci (#511)
mmsqe Aug 7, 2024
7ef8af1
Problem: nondeterministic account set occurs with more stm workers (#…
mmsqe Aug 7, 2024
fe3f4fd
Problem: unnecessary GetAccount in ante handlers (#513)
mmsqe Aug 15, 2024
d26adad
Problem: handle for integer overflow is messy (#517)
mmsqe Sep 10, 2024
452b0cf
Problem: method eth_chainId crashed occasionally (#516)
mmsqe Sep 10, 2024
3fabdbe
Problem: hash in subscribe newHeads differs from eth_getBlockByNumber…
mmsqe Sep 11, 2024
79bb39e
Problem: block-stm tx executor bad worst case performance (#522)
yihuang Sep 11, 2024
56f8a5b
Problem: pre-estimation don't run in parallel (#523)
yihuang Sep 12, 2024
dbc7eb4
Problem: tx evm raw doesn't work under offline (#524)
mmsqe Sep 13, 2024
7e30762
Problem: get unnecessary block result when only need header (#526)
mmsqe Sep 23, 2024
bcac9e2
Problem: trace block gas refund change not committed (#527)
yihuang Sep 24, 2024
f2a562b
Problem: db is double closed when shutdown (#530)
yihuang Sep 25, 2024
9755333
Problem: no time in Transaction (#531)
mmsqe Sep 25, 2024
33e3cc6
Problem: multisig account failed on threshold encode after send tx (#…
mmsqe Sep 27, 2024
5acb559
Problem: dependencies are outdated (#533)
mmsqe Sep 30, 2024
b16b489
Problem: get unnecessary block result in header related api call (#535)
mmsqe Oct 4, 2024
c4cef0f
Problem: unsuppored sign mode SIGN_MODE_TEXTUAL in bank transfer (#537)
mmsqe Oct 4, 2024
617eac9
Problem: validation broke after transaction conversion with raw field…
mmsqe Oct 4, 2024
853e1e5
Problem: opBlockhash broke after sdk50 (#534)
mmsqe Oct 4, 2024
580ce6e
Problem: default headerHashNum is too large (#539)
mmsqe Oct 7, 2024
a2ad87c
Problem: no header hash from fallback historicalInfo (#540)
mmsqe Oct 9, 2024
816389c
Problem: node can't quit by signal (#543)
yihuang Oct 17, 2024
4300682
Problem: state overwrite not work in debug trace API (#545)
mmsqe Oct 22, 2024
e786b3f
Problem: dependencies are outdated (#542)
mmsqe Oct 23, 2024
e567c5a
Problem: check tx blocks consensus (#546)
yihuang Oct 28, 2024
ce5773e
graceful shutdown of websocket (#547)
valli0x Oct 30, 2024
885530b
Problem: build fail without cgo (#549)
yihuang Oct 30, 2024
8afdc69
Problem: rpc stream overhead even if not used (#551)
yihuang Nov 1, 2024
e52a555
removed listener closing in gracefully shutdown json-rpc server (#550)
valli0x Nov 1, 2024
e4d00df
Problem: check-tx don't run in parallel (#552)
yihuang Nov 1, 2024
836617d
Problem: no trace detail on insufficient balance (#554)
mmsqe Nov 8, 2024
c9e06fa
Problem: incorrect balance when no tracer in predecessors (#558)
mmsqe Nov 11, 2024
64bd2de
Problem: different maxGasWanted config leads hash mismatch (#560)
mmsqe Nov 12, 2024
4fb45a3
Problem: wrong gas price when using basefee of minus one height when …
mmsqe Nov 12, 2024
6464c22
Problem: nil pointer error with legacy tx format (#562)
yihuang Nov 14, 2024
eac770f
Problem: cometbft is outdated (#555)
mmsqe Nov 14, 2024
acbe290
Problem: nonce management in batch tx (#567)
yihuang Dec 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v26
with:
nix_path: nixpkgs=channel:nixos-23.11
nix_path: nixpkgs=channel:nixos-22.11
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v14
Expand All @@ -84,7 +84,7 @@ jobs:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v26
with:
nix_path: nixpkgs=channel:nixos-23.11
nix_path: nixpkgs=channel:nixos-22.11
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v14
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ jobs:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v26
with:
nix_path: nixpkgs=channel:nixos-23.11
nix_path: nixpkgs=channel:nixos-22.11
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v14
Expand Down Expand Up @@ -138,7 +138,7 @@ jobs:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v26
with:
nix_path: nixpkgs=channel:nixos-23.11
nix_path: nixpkgs=channel:nixos-22.11
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
- uses: cachix/cachix-action@v14
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,15 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features

* (evm) [#414](https://github.com/crypto-org-chain/ethermint/pull/414) Integrate go-block-stm for parallel tx execution.
* (block-stm) [#498](https://github.com/crypto-org-chain/ethermint/pull/498) Enable incarnation cache for block-stm executor.

### State Machine Breaking

* (rpc) [#443](https://github.com/crypto-org-chain/ethermint/pull/443) Keep behavior of random opcode as before.
* (app) [#451](https://github.com/crypto-org-chain/ethermint/pull/451) Disable block gas meter, it's not compatible with parallel tx execution. It's safe to do as long as we checks total gas-wanted against block gas limit in process proposal, which we do in default handler.
* (ante) [#493](https://github.com/crypto-org-chain/ethermint/pull/493) Align gasWanted for process proposal mode, [#500](https://github.com/crypto-org-chain/ethermint/pull/500) Check for overflow before adding gasLimit to gasWanted.
* (ante) [#506](https://github.com/crypto-org-chain/ethermint/pull/506) Disable MsgCreatePermanentLockedAccount and MsgCreatePeriodicVestingAccount messages.
* (ante) [#513](https://github.com/crypto-org-chain/ethermint/pull/513) Avoid unnecessary GetAccount and MakeSigner in ante handlers.

### Bug Fixes

Expand All @@ -59,6 +63,23 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [#474](https://github.com/crypto-org-chain/ethermint/pull/474), [#476](https://github.com/crypto-org-chain/ethermint/pull/441) Align genesis related cmd.
* (rpc) [#480](https://github.com/crypto-org-chain/ethermint/pull/480), [#482](https://github.com/crypto-org-chain/ethermint/pull/482) Fix parsed logs from old events.
* (rpc) [#488](https://github.com/crypto-org-chain/ethermint/pull/488) Fix handling of pending transactions related APIs.
* (rpc) [#501](https://github.com/crypto-org-chain/ethermint/pull/501) Avoid invalid chain id for signer error when rpc call before chain id set in BeginBlock.
* (block-stm) [#510](https://github.com/crypto-org-chain/ethermint/pull/510) Include a fix to avoid nondeterministic account set when stm workers execute in parallel.
* (rpc) [#521](https://github.com/crypto-org-chain/ethermint/pull/521) Align hash and miner in subscribe newHeads with eth_getBlockByNumber.
* (rpc) [#516](https://github.com/crypto-org-chain/ethermint/pull/516) Avoid method eth_chainId crashed due to nil pointer on IsEIP155 check.
* (cli) [#524](https://github.com/crypto-org-chain/ethermint/pull/524) Allow tx evm raw run for generate only when offline with evm-denom flag.
* (rpc) [#527](https://github.com/crypto-org-chain/ethermint/pull/527) Fix balance consistency between trace-block and state machine.
* (rpc) [#534](https://github.com/crypto-org-chain/ethermint/pull/534), [#540](https://github.com/crypto-org-chain/ethermint/pull/540) Fix opBlockhash when no block header in abci request.
* (rpc) [#536](https://github.com/crypto-org-chain/ethermint/pull/536) Fix validate basic after transaction conversion with raw field.
* (cli) [#537](https://github.com/crypto-org-chain/ethermint/pull/537) Fix unsuppored sign mode SIGN_MODE_TEXTUAL for bank transfer.
* (cli) [#543](https://github.com/crypto-org-chain/ethermint/pull/543) Fix graceful shutdown.
* (rpc) [#545](https://github.com/crypto-org-chain/ethermint/pull/545) Fix state overwrite in debug trace APIs.
* (rpc) [#554](https://github.com/crypto-org-chain/ethermint/pull/554) No trace detail on insufficient balance.
* (rpc) [#558](https://github.com/crypto-org-chain/ethermint/pull/558) New tracer in predecessors to trace balance correctly when `debug_traceTransaction`.
* (rpc) [#559](https://github.com/crypto-org-chain/ethermint/pull/559) Use basefee of transaction height instead of minus one height when `debug_traceTransaction`.
* (ante) [#560](https://github.com/crypto-org-chain/ethermint/pull/560) Check gasWanted only in checkTx mode.
* (rpc) [#562](https://github.com/crypto-org-chain/ethermint/pull/562) Fix nil pointer panic with legacy transaction format.
* (evm) [#567](https://github.com/crypto-org-chain/ethermint/pull/567) Fix nonce management in batch transaction.

### Improvements

Expand All @@ -74,6 +95,18 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (app) [#483](https://github.com/crypto-org-chain/ethermint/pull/483) Make keyring-backend client config accessible in app.
* (deps) [#489](https://github.com/crypto-org-chain/ethermint/pull/489) Update cosmos-sdk to `v0.50.7`.
* (rpc) [#491](https://github.com/crypto-org-chain/ethermint/pull/491) Avoid unnecessary tx decode in tx listener.
* [#496](https://github.com/crypto-org-chain/ethermint/pull/496) Set mempool MaxTx from config.
* (ante) [#497](https://github.com/crypto-org-chain/ethermint/pull/497) Enforce positive value check in eth transaction.
* (deps) [#505](https://github.com/crypto-org-chain/ethermint/pull/505) Update cometbft to v0.38.10.
* (ante) [#504](https://github.com/crypto-org-chain/ethermint/pull/504) Optimize AnteHandle method to skip checks if disabledMsgs is empty.
* [#517](https://github.com/crypto-org-chain/ethermint/pull/517) Add check for integer overflow to ensure safe conversion.
* [#522](https://github.com/crypto-org-chain/ethermint/pull/522) block-stm executor support optional pre-estimations.
* [#526](https://github.com/crypto-org-chain/ethermint/pull/526), [#535](https://github.com/crypto-org-chain/ethermint/pull/535) Avoid unnecessary block result in header related api call.
* [#533](https://github.com/crypto-org-chain/ethermint/pull/533) Bump cosmos-sdk to v0.50.10, cometbft to v0.38.13 and ibc-go to v8.5.1.
* [#546](https://github.com/crypto-org-chain/ethermint/pull/546) Introduce `--async-check-tx` flag to run check-tx async with consensus.
* [#549](https://github.com/crypto-org-chain/ethermint/pull/549) Support build without cgo.
* [#551](https://github.com/crypto-org-chain/ethermint/pull/551) Start event stream on demand.
* [#555](https://github.com/crypto-org-chain/ethermint/pull/555) Update cometbft to 0.38.14 and rocksdb to 9.7.4.

## v0.21.x-cronos

Expand Down
6 changes: 5 additions & 1 deletion app/ante/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,12 @@ func NewAuthzLimiterDecorator(disabledMsgTypes []string) AuthzLimiterDecorator {
}

func (ald AuthzLimiterDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
if len(ald.disabledMsgs) == 0 {
return next(ctx, tx, simulate)
}

if err := ald.checkDisabledMsgs(tx.GetMsgs(), false, 0); err != nil {
return ctx, errorsmod.Wrapf(errortypes.ErrUnauthorized, err.Error())
return ctx, errorsmod.Wrap(errortypes.ErrUnauthorized, err.Error())
}
return next(ctx, tx, simulate)
}
Expand Down
20 changes: 20 additions & 0 deletions app/ante/authz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,26 @@ func (suite *AnteTestSuite) TestRejectDeliverMsgsInAuthz() {
},
expectedCode: sdkerrors.ErrUnauthorized.ABCICode(),
},
{
name: "a MsgGrant with MsgCreatePermanentLockedAccount typeURL on the authorization field is blocked",
msgs: []sdk.Msg{
newGenericMsgGrant(
testAddresses,
sdk.MsgTypeURL(&sdkvesting.MsgCreatePermanentLockedAccount{}),
),
},
expectedCode: sdkerrors.ErrUnauthorized.ABCICode(),
},
{
name: "a MsgGrant with MsgCreatePeriodicVestingAccount typeURL on the authorization field is blocked",
msgs: []sdk.Msg{
newGenericMsgGrant(
testAddresses,
sdk.MsgTypeURL(&sdkvesting.MsgCreatePeriodicVestingAccount{}),
),
},
expectedCode: sdkerrors.ErrUnauthorized.ABCICode(),
},
{
name: "a MsgGrant with MsgEthereumTx typeURL on the authorization field included on EIP712 tx is blocked",
msgs: []sdk.Msg{
Expand Down
5 changes: 2 additions & 3 deletions app/ante/eip712.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
ibcante "github.com/cosmos/ibc-go/v8/modules/core/ante"

ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/evmos/ethermint/crypto/ethsecp256k1"
"github.com/evmos/ethermint/ethereum/eip712"
Expand Down Expand Up @@ -301,7 +300,7 @@ func VerifySignature(
feePayerSig[ethcrypto.RecoveryIDOffset] -= 27
}

feePayerPubkey, err := secp256k1.RecoverPubkey(sigHash, feePayerSig)
feePayerPubkey, err := ethcrypto.Ecrecover(sigHash, feePayerSig)
if err != nil {
return errorsmod.Wrap(err, "failed to recover delegated fee payer from sig")
}
Expand All @@ -327,7 +326,7 @@ func VerifySignature(

// VerifySignature of ethsecp256k1 accepts 64 byte signature [R||S]
// WARNING! Under NO CIRCUMSTANCES try to use pubKey.VerifySignature there
if !secp256k1.VerifySignature(pubKey.Bytes(), sigHash, feePayerSig[:len(feePayerSig)-1]) {
if !ethcrypto.VerifySignature(pubKey.Bytes(), sigHash, feePayerSig[:len(feePayerSig)-1]) {
return errorsmod.Wrap(errortypes.ErrorInvalidSigner, "unable to verify signer signature of EIP712 typed data")
}

Expand Down
91 changes: 58 additions & 33 deletions app/ante/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package ante

import (
"fmt"
"math"
"math/big"

Expand All @@ -27,21 +28,46 @@ import (

ethermint "github.com/evmos/ethermint/types"
"github.com/evmos/ethermint/x/evm/keeper"
"github.com/evmos/ethermint/x/evm/statedb"
evmtypes "github.com/evmos/ethermint/x/evm/types"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)

type AccountGetter func(sdk.AccAddress) sdk.AccountI

// NewCachedAccountGetter cache the account objects during the ante handler execution,
// it's safe because there's no store branching in the ante handlers,
// it also creates new account in memory if it doesn't exist in the store.
func NewCachedAccountGetter(ctx sdk.Context, ak evmtypes.AccountKeeper) AccountGetter {
accounts := make(map[string]sdk.AccountI, 1)
return func(addr sdk.AccAddress) sdk.AccountI {
acc := accounts[string(addr)]
if acc == nil {
acc = ak.GetAccount(ctx, addr)
if acc == nil {
// we create a new account in memory if it doesn't exist,
// which is only set to store when updated.
acc = ak.NewAccountWithAddress(ctx, addr)
}
accounts[string(addr)] = acc
}
return acc
}
}

// VerifyEthAccount validates checks that the sender balance is greater than the total transaction cost.
// The account will be set to store if it doesn't exis, i.e cannot be found on store.
// The account will be created in memory if it doesn't exist, i.e cannot be found on store, which will eventually set to
// store when increasing nonce.
// This AnteHandler decorator will fail if:
// - any of the msgs is not a MsgEthereumTx
// - from address is empty
// - account balance is lower than the transaction cost
func VerifyEthAccount(
ctx sdk.Context, tx sdk.Tx,
evmKeeper EVMKeeper, ak evmtypes.AccountKeeper, evmDenom string,
evmKeeper EVMKeeper, evmDenom string,
accountGetter AccountGetter,
) error {
if !ctx.IsCheckTx() {
return nil
Expand All @@ -62,13 +88,9 @@ func VerifyEthAccount(
}

// check whether the sender address is EOA
fromAddr := common.BytesToAddress(from)
acct := evmKeeper.GetAccount(ctx, fromAddr)

if acct == nil {
acc := ak.NewAccountWithAddress(ctx, from)
ak.SetAccount(ctx, acc)
} else if acct.IsContract() {
acct := statedb.NewAccountFromSdkAccount(accountGetter(from))
if acct.IsContract() {
fromAddr := common.BytesToAddress(from)
return errorsmod.Wrapf(errortypes.ErrInvalidType,
"the sender is not EOA: address %s, codeHash <%s>", fromAddr, acct.CodeHash)
}
Expand Down Expand Up @@ -122,18 +144,15 @@ func CheckEthGasConsume(
minPriority = priority
}

// We can't trust the tx gas limit, because we'll refund the unused gas.
gasLimit := msgEthTx.GetGas()
if ctx.IsCheckTx() && maxGasWanted != 0 {
// We can't trust the tx gas limit, because we'll refund the unused gas.
if gasLimit > maxGasWanted {
gasWanted += maxGasWanted
} else {
gasWanted += gasLimit
}
} else {
gasWanted += gasLimit
gasLimit = min(gasLimit, maxGasWanted)
}

if gasWanted > math.MaxInt64-gasLimit {
return ctx, fmt.Errorf("gasWanted(%d) + gasLimit(%d) overflow", gasWanted, gasLimit)
}
gasWanted += gasLimit
// user balance is already checked during CheckTx so there's no need to
// verify it again during ReCheckTx
if ctx.IsReCheckTx() {
Expand Down Expand Up @@ -221,15 +240,18 @@ func CheckEthCanTransfer(
)
}
}

value := tx.Value()
if value == nil || value.Sign() == -1 {
return fmt.Errorf("value (%s) must be positive", value)
}
from := common.BytesToAddress(msgEthTx.From)
// check that caller has enough balance to cover asset transfer for **topmost** call
// NOTE: here the gas consumed is from the context with the infinite gas meter
if tx.Value().Sign() > 0 && !canTransfer(ctx, evmKeeper, evmParams.EvmDenom, from, tx.Value()) {
if value.Sign() > 0 && !canTransfer(ctx, evmKeeper, evmParams.EvmDenom, from, value) {
return errorsmod.Wrapf(
errortypes.ErrInsufficientFunds,
"failed to transfer %s from address %s using the EVM block context transfer function",
tx.Value(),
value,
from,
)
}
Expand All @@ -244,11 +266,11 @@ func canTransfer(ctx sdk.Context, evmKeeper EVMKeeper, denom string, from common
return balance.Cmp(amount) >= 0
}

// CheckEthSenderNonce handles incrementing the sequence of the signer (i.e sender). If the transaction is a
// CheckAndSetEthSenderNonce handles incrementing the sequence of the signer (i.e sender). If the transaction is a
// contract creation, the nonce will be incremented during the transaction execution and not within
// this AnteHandler decorator.
func CheckEthSenderNonce(
ctx sdk.Context, tx sdk.Tx, ak evmtypes.AccountKeeper,
func CheckAndSetEthSenderNonce(
ctx sdk.Context, tx sdk.Tx, ak evmtypes.AccountKeeper, unsafeUnOrderedTx bool, accountGetter AccountGetter,
) error {
for _, msg := range tx.GetMsgs() {
msgEthTx, ok := msg.(*evmtypes.MsgEthereumTx)
Expand All @@ -259,22 +281,25 @@ func CheckEthSenderNonce(
tx := msgEthTx.AsTransaction()

// increase sequence of sender
acc := ak.GetAccount(ctx, msgEthTx.GetFrom())
from := msgEthTx.GetFrom()
acc := accountGetter(from)
if acc == nil {
return errorsmod.Wrapf(
errortypes.ErrUnknownAddress,
"account %s is nil", common.BytesToAddress(msgEthTx.GetFrom().Bytes()),
"account %s is nil", common.BytesToAddress(from.Bytes()),
)
}
nonce := acc.GetSequence()

// we merged the nonce verification to nonce increment, so when tx includes multiple messages
// with same sender, they'll be accepted.
if tx.Nonce() != nonce {
return errorsmod.Wrapf(
errortypes.ErrInvalidSequence,
"invalid nonce; got %d, expected %d", tx.Nonce(), nonce,
)
if !unsafeUnOrderedTx {
// we merged the nonce verification to nonce increment, so when tx includes multiple messages
// with same sender, they'll be accepted.
if tx.Nonce() != nonce {
return errorsmod.Wrapf(
errortypes.ErrInvalidSequence,
"invalid nonce; got %d, expected %d", tx.Nonce(), nonce,
)
}
}

if err := acc.SetSequence(nonce + 1); err != nil {
Expand Down
Loading