fix: unlock local nonce when an error occurs and increment only when the tx is sent for real
This commit is contained in:
parent
05baec8bec
commit
ce121710d9
|
@ -96,5 +96,5 @@ type Bridge interface {
|
||||||
CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error)
|
CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error)
|
||||||
Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (types.Hash, error)
|
Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (types.Hash, error)
|
||||||
GetContractAddress(network *params.Network, token *token.Token) *common.Address
|
GetContractAddress(network *params.Network, token *token.Token) *common.Address
|
||||||
BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error)
|
BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, transactions.UnlockNonceFunc, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,8 +312,8 @@ func (s *CBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerF
|
||||||
if fromNetwork == nil {
|
if fromNetwork == nil {
|
||||||
return nil, errors.New("network not found")
|
return nil, errors.New("network not found")
|
||||||
}
|
}
|
||||||
tk := s.tokenManager.FindToken(fromNetwork, sendArgs.CbridgeTx.Symbol)
|
token := s.tokenManager.FindToken(fromNetwork, sendArgs.CbridgeTx.Symbol)
|
||||||
if tk == nil {
|
if token == nil {
|
||||||
return nil, errors.New("token not found")
|
return nil, errors.New("token not found")
|
||||||
}
|
}
|
||||||
addrs := s.GetContractAddress(fromNetwork, nil)
|
addrs := s.GetContractAddress(fromNetwork, nil)
|
||||||
|
@ -331,7 +331,7 @@ func (s *CBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerF
|
||||||
}
|
}
|
||||||
|
|
||||||
txOpts := sendArgs.CbridgeTx.ToTransactOpts(signerFn)
|
txOpts := sendArgs.CbridgeTx.ToTransactOpts(signerFn)
|
||||||
if tk.IsNative() {
|
if token.IsNative() {
|
||||||
return contract.SendNative(
|
return contract.SendNative(
|
||||||
txOpts,
|
txOpts,
|
||||||
sendArgs.CbridgeTx.Recipient,
|
sendArgs.CbridgeTx.Recipient,
|
||||||
|
@ -345,7 +345,7 @@ func (s *CBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerF
|
||||||
return contract.Send(
|
return contract.Send(
|
||||||
txOpts,
|
txOpts,
|
||||||
sendArgs.CbridgeTx.Recipient,
|
sendArgs.CbridgeTx.Recipient,
|
||||||
tk.Address,
|
token.Address,
|
||||||
(*big.Int)(sendArgs.CbridgeTx.Amount),
|
(*big.Int)(sendArgs.CbridgeTx.Amount),
|
||||||
sendArgs.CbridgeTx.ChainID,
|
sendArgs.CbridgeTx.ChainID,
|
||||||
uint64(time.Now().UnixMilli()),
|
uint64(time.Now().UnixMilli()),
|
||||||
|
@ -362,8 +362,9 @@ func (s *CBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.Sel
|
||||||
return types.Hash(tx.Hash()), nil
|
return types.Hash(tx.Hash()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error) {
|
func (s *CBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, transactions.UnlockNonceFunc, error) {
|
||||||
return s.sendOrBuild(sendArgs, nil)
|
tx, err := s.sendOrBuild(sendArgs, nil)
|
||||||
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *CBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
func (s *CBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||||
|
|
|
@ -95,40 +95,45 @@ func (s *ERC721TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwor
|
||||||
return uint64(increasedEstimation), nil
|
return uint64(increasedEstimation), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ERC721TransferBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
func (s *ERC721TransferBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (tx *ethTypes.Transaction, unlock transactions.UnlockNonceFunc, err error) {
|
||||||
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
|
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
contract, err := collectibles.NewCollectibles(common.Address(*sendArgs.ERC721TransferTx.To), ethClient)
|
contract, err := collectibles.NewCollectibles(common.Address(*sendArgs.ERC721TransferTx.To), ethClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce, unlock, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC721TransferTx.From)
|
nonce, unlock, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC721TransferTx.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
unlock(err == nil, nonce)
|
|
||||||
}()
|
|
||||||
argNonce := hexutil.Uint64(nonce)
|
argNonce := hexutil.Uint64(nonce)
|
||||||
sendArgs.ERC721TransferTx.Nonce = &argNonce
|
sendArgs.ERC721TransferTx.Nonce = &argNonce
|
||||||
txOpts := sendArgs.ERC721TransferTx.ToTransactOpts(signerFn)
|
txOpts := sendArgs.ERC721TransferTx.ToTransactOpts(signerFn)
|
||||||
return contract.SafeTransferFrom(txOpts, common.Address(sendArgs.ERC721TransferTx.From), sendArgs.ERC721TransferTx.Recipient,
|
tx, err = contract.SafeTransferFrom(txOpts, common.Address(sendArgs.ERC721TransferTx.From),
|
||||||
|
sendArgs.ERC721TransferTx.Recipient,
|
||||||
sendArgs.ERC721TransferTx.TokenID.ToInt())
|
sendArgs.ERC721TransferTx.TokenID.ToInt())
|
||||||
|
return tx, unlock, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ERC721TransferBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
func (s *ERC721TransferBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||||
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC721TransferTx.From, verifiedAccount))
|
tx, unlock, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC721TransferTx.From, verifiedAccount))
|
||||||
|
defer func() {
|
||||||
|
if unlock != nil {
|
||||||
|
unlock(err == nil, tx.Nonce())
|
||||||
|
}
|
||||||
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hash, err
|
return hash, err
|
||||||
}
|
}
|
||||||
return types.Hash(tx.Hash()), nil
|
return types.Hash(tx.Hash()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ERC721TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error) {
|
func (s *ERC721TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, transactions.UnlockNonceFunc, error) {
|
||||||
return s.sendOrBuild(sendArgs, nil)
|
return s.sendOrBuild(sendArgs, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,40 +226,43 @@ func (h *HopBridge) GetContractAddress(network *params.Network, token *token.Tok
|
||||||
return &address
|
return &address
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HopBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
func (h *HopBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (tx *ethTypes.Transaction, unlock transactions.UnlockNonceFunc, err error) {
|
||||||
fromNetwork := h.contractMaker.RPCClient.NetworkManager.Find(sendArgs.ChainID)
|
fromNetwork := h.contractMaker.RPCClient.NetworkManager.Find(sendArgs.ChainID)
|
||||||
if fromNetwork == nil {
|
if fromNetwork == nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce, unlock, err := h.transactor.NextNonce(h.contractMaker.RPCClient, sendArgs.ChainID, sendArgs.HopTx.From)
|
nonce, unlock, err := h.transactor.NextNonce(h.contractMaker.RPCClient, sendArgs.ChainID, sendArgs.HopTx.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
unlock(err == nil, nonce)
|
|
||||||
}()
|
|
||||||
argNonce := hexutil.Uint64(nonce)
|
argNonce := hexutil.Uint64(nonce)
|
||||||
sendArgs.HopTx.Nonce = &argNonce
|
sendArgs.HopTx.Nonce = &argNonce
|
||||||
|
|
||||||
token := h.tokenManager.FindToken(fromNetwork, sendArgs.HopTx.Symbol)
|
token := h.tokenManager.FindToken(fromNetwork, sendArgs.HopTx.Symbol)
|
||||||
if fromNetwork.Layer == 1 {
|
if fromNetwork.Layer == 1 {
|
||||||
tx, err = h.sendToL2(sendArgs.ChainID, sendArgs.HopTx, signerFn, token)
|
tx, err = h.sendToL2(sendArgs.ChainID, sendArgs.HopTx, signerFn, token)
|
||||||
return tx, err
|
return tx, unlock, err
|
||||||
}
|
}
|
||||||
tx, err = h.swapAndSend(sendArgs.ChainID, sendArgs.HopTx, signerFn, token)
|
tx, err = h.swapAndSend(sendArgs.ChainID, sendArgs.HopTx, signerFn, token)
|
||||||
return tx, err
|
return tx, unlock, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HopBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
func (h *HopBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||||
tx, err := h.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.HopTx.From, verifiedAccount))
|
tx, unlock, err := h.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.HopTx.From, verifiedAccount))
|
||||||
|
defer func() {
|
||||||
|
if unlock != nil {
|
||||||
|
unlock(err == nil, tx.Nonce())
|
||||||
|
}
|
||||||
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.Hash{}, err
|
return types.Hash{}, err
|
||||||
}
|
}
|
||||||
return types.Hash(tx.Hash()), nil
|
return types.Hash(tx.Hash()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *HopBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error) {
|
func (h *HopBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, transactions.UnlockNonceFunc, error) {
|
||||||
return h.sendOrBuild(sendArgs, nil)
|
return h.sendOrBuild(sendArgs, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ func (s *TransferBridge) Send(sendArgs *TransactionBridge, verifiedAccount *acco
|
||||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error) {
|
func (s *TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, transactions.UnlockNonceFunc, error) {
|
||||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ type TransactionDescription struct {
|
||||||
chainID uint64
|
chainID uint64
|
||||||
builtTx *ethTypes.Transaction
|
builtTx *ethTypes.Transaction
|
||||||
signature []byte
|
signature []byte
|
||||||
|
unlock transactions.UnlockNonceFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
type TransactionManager struct {
|
type TransactionManager struct {
|
||||||
|
@ -385,7 +386,7 @@ func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Cont
|
||||||
rBytes, _ := hex.DecodeString(sigDetails.R)
|
rBytes, _ := hex.DecodeString(sigDetails.R)
|
||||||
sBytes, _ := hex.DecodeString(sigDetails.S)
|
sBytes, _ := hex.DecodeString(sigDetails.S)
|
||||||
vByte := byte(0)
|
vByte := byte(0)
|
||||||
if sigDetails.V == "1" {
|
if sigDetails.V == "01" {
|
||||||
vByte = 1
|
vByte = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +400,9 @@ func (tm *TransactionManager) ProceedWithTransactionsSignatures(ctx context.Cont
|
||||||
hashes := make(map[uint64][]types.Hash)
|
hashes := make(map[uint64][]types.Hash)
|
||||||
for _, desc := range tm.transactionsForKeycardSingning {
|
for _, desc := range tm.transactionsForKeycardSingning {
|
||||||
hash, err := tm.transactor.SendBuiltTransactionWithSignature(desc.chainID, desc.builtTx, desc.signature)
|
hash, err := tm.transactor.SendBuiltTransactionWithSignature(desc.chainID, desc.builtTx, desc.signature)
|
||||||
|
defer func() {
|
||||||
|
desc.unlock(err == nil, desc.builtTx.Nonce())
|
||||||
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -477,8 +481,11 @@ func (tm *TransactionManager) buildTransactions(bridges map[string]bridge.Bridge
|
||||||
tm.transactionsForKeycardSingning = make(map[common.Hash]*TransactionDescription)
|
tm.transactionsForKeycardSingning = make(map[common.Hash]*TransactionDescription)
|
||||||
var hashes []string
|
var hashes []string
|
||||||
for _, bridgeTx := range tm.transactionsBridgeData {
|
for _, bridgeTx := range tm.transactionsBridgeData {
|
||||||
builtTx, err := bridges[bridgeTx.BridgeName].BuildTransaction(bridgeTx)
|
builtTx, unlock, err := bridges[bridgeTx.BridgeName].BuildTransaction(bridgeTx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if unlock != nil {
|
||||||
|
unlock(false, 0) // unlock nonce in case of an error, otherwise keep it locked, until the transaction is sent
|
||||||
|
}
|
||||||
return hashes, err
|
return hashes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,6 +495,7 @@ func (tm *TransactionManager) buildTransactions(bridges map[string]bridge.Bridge
|
||||||
tm.transactionsForKeycardSingning[txHash] = &TransactionDescription{
|
tm.transactionsForKeycardSingning[txHash] = &TransactionDescription{
|
||||||
chainID: bridgeTx.ChainID,
|
chainID: bridgeTx.ChainID,
|
||||||
builtTx: builtTx,
|
builtTx: builtTx,
|
||||||
|
unlock: unlock,
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes = append(hashes, txHash.String())
|
hashes = append(hashes, txHash.String())
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type UnlockNonceFunc func(inc bool, n uint64)
|
||||||
|
|
||||||
type Nonce struct {
|
type Nonce struct {
|
||||||
addrLock *AddrLocker
|
addrLock *AddrLocker
|
||||||
localNonce map[uint64]*sync.Map
|
localNonce map[uint64]*sync.Map
|
||||||
|
@ -20,7 +22,7 @@ func NewNonce() *Nonce {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Nonce) Next(rpcWrapper *rpcWrapper, from types.Address) (uint64, func(inc bool, nonce uint64), error) {
|
func (n *Nonce) Next(rpcWrapper *rpcWrapper, from types.Address) (uint64, UnlockNonceFunc, error) {
|
||||||
n.addrLock.LockAddr(from)
|
n.addrLock.LockAddr(from)
|
||||||
current, err := n.GetCurrent(rpcWrapper, from)
|
current, err := n.GetCurrent(rpcWrapper, from)
|
||||||
unlock := func(inc bool, nonce uint64) {
|
unlock := func(inc bool, nonce uint64) {
|
||||||
|
|
|
@ -77,10 +77,11 @@ func (t *Transactor) SetRPC(rpcClient *rpc.Client, timeout time.Duration) {
|
||||||
t.rpcCallTimeout = timeout
|
t.rpcCallTimeout = timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) NextNonce(rpcClient *rpc.Client, chainID uint64, from types.Address) (uint64, func(inc bool, n uint64), error) {
|
func (t *Transactor) NextNonce(rpcClient *rpc.Client, chainID uint64, from types.Address) (uint64, UnlockNonceFunc, error) {
|
||||||
wrapper := newRPCWrapper(rpcClient, chainID)
|
wrapper := newRPCWrapper(rpcClient, chainID)
|
||||||
return t.nonce.Next(wrapper, from)
|
return t.nonce.Next(wrapper, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) EstimateGas(network *params.Network, from common.Address, to common.Address, value *big.Int, input []byte) (uint64, error) {
|
func (t *Transactor) EstimateGas(network *params.Network, from common.Address, to common.Address, value *big.Int, input []byte) (uint64, error) {
|
||||||
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, network.ChainID)
|
rpcWrapper := newRPCWrapper(t.rpcWrapper.RPCClient, network.ChainID)
|
||||||
|
|
||||||
|
@ -109,9 +110,9 @@ func (t *Transactor) SendTransactionWithChainID(chainID uint64, sendArgs SendTxA
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs) (tx *gethtypes.Transaction, err error) {
|
func (t *Transactor) ValidateAndBuildTransaction(chainID uint64, sendArgs SendTxArgs) (tx *gethtypes.Transaction, unlock UnlockNonceFunc, err error) {
|
||||||
wrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
wrapper := newRPCWrapper(t.rpcWrapper.RPCClient, chainID)
|
||||||
tx, err = t.validateAndBuildTransaction(wrapper, sendArgs)
|
tx, unlock, err = t.validateAndBuildTransaction(wrapper, sendArgs)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,21 +268,18 @@ func (t *Transactor) validateAccount(args SendTxArgs, selectedAccount *account.S
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args SendTxArgs) (tx *gethtypes.Transaction, err error) {
|
func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args SendTxArgs) (tx *gethtypes.Transaction, unlock UnlockNonceFunc, err error) {
|
||||||
if !args.Valid() {
|
if !args.Valid() {
|
||||||
return tx, ErrInvalidSendTxArgs
|
return tx, nil, ErrInvalidSendTxArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce, unlock, err := t.nonce.Next(rpcWrapper, args.From)
|
nonce, unlock, err := t.nonce.Next(rpcWrapper, args.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, nil, err
|
||||||
}
|
}
|
||||||
if args.Nonce != nil {
|
if args.Nonce != nil {
|
||||||
nonce = uint64(*args.Nonce)
|
nonce = uint64(*args.Nonce)
|
||||||
}
|
}
|
||||||
defer func() {
|
|
||||||
unlock(err == nil, nonce)
|
|
||||||
}()
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), t.rpcCallTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), t.rpcCallTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
@ -289,7 +287,7 @@ func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args Se
|
||||||
if !args.IsDynamicFeeTx() && args.GasPrice == nil {
|
if !args.IsDynamicFeeTx() && args.GasPrice == nil {
|
||||||
gasPrice, err = rpcWrapper.SuggestGasPrice(ctx)
|
gasPrice, err = rpcWrapper.SuggestGasPrice(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, unlock, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +315,7 @@ func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args Se
|
||||||
Data: args.GetInput(),
|
Data: args.GetInput(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tx, err
|
return tx, unlock, err
|
||||||
}
|
}
|
||||||
if gas < defaultGas {
|
if gas < defaultGas {
|
||||||
t.log.Info("default gas will be used because estimated is lower", "estimated", gas, "default", defaultGas)
|
t.log.Info("default gas will be used because estimated is lower", "estimated", gas, "default", defaultGas)
|
||||||
|
@ -325,7 +323,7 @@ func (t *Transactor) validateAndBuildTransaction(rpcWrapper *rpcWrapper, args Se
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tx = t.buildTransactionWithOverrides(nonce, value, gas, gasPrice, args)
|
tx = t.buildTransactionWithOverrides(nonce, value, gas, gasPrice, args)
|
||||||
return tx, nil
|
return tx, unlock, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transactor) validateAndPropagate(rpcWrapper *rpcWrapper, selectedAccount *account.SelectedExtKey, args SendTxArgs) (hash types.Hash, err error) {
|
func (t *Transactor) validateAndPropagate(rpcWrapper *rpcWrapper, selectedAccount *account.SelectedExtKey, args SendTxArgs) (hash types.Hash, err error) {
|
||||||
|
@ -333,7 +331,12 @@ func (t *Transactor) validateAndPropagate(rpcWrapper *rpcWrapper, selectedAccoun
|
||||||
return hash, err
|
return hash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := t.validateAndBuildTransaction(rpcWrapper, args)
|
tx, unlock, err := t.validateAndBuildTransaction(rpcWrapper, args)
|
||||||
|
defer func() {
|
||||||
|
if unlock != nil {
|
||||||
|
unlock(err == nil, tx.Nonce())
|
||||||
|
}
|
||||||
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hash, err
|
return hash, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue