@@ -11,8 +11,8 @@ import (
11
11
"sync"
12
12
"time"
13
13
14
- "github.com/Phala-Network/chainbridge-utils/crypto/secp256k1"
15
14
"github.com/ChainSafe/log15"
15
+ "github.com/Phala-Network/chainbridge-utils/crypto/secp256k1"
16
16
"github.com/ethereum/go-ethereum/accounts/abi/bind"
17
17
ethcommon "github.com/ethereum/go-ethereum/common"
18
18
ethcrypto "github.com/ethereum/go-ethereum/crypto"
@@ -31,12 +31,13 @@ type Connection struct {
31
31
gasMultiplier * big.Float
32
32
conn * ethclient.Client
33
33
// signer ethtypes.Signer
34
- opts * bind.TransactOpts
35
- callOpts * bind.CallOpts
36
- nonce uint64
37
- optsLock sync.Mutex
38
- log log15.Logger
39
- stop chan int // All routines should exit when this channel is closed
34
+ opts * bind.TransactOpts
35
+ callOpts * bind.CallOpts
36
+ nonce uint64
37
+ nonceLock sync.Mutex
38
+ optsLock sync.Mutex
39
+ log log15.Logger
40
+ stop chan int // All routines should exit when this channel is closed
40
41
}
41
42
42
43
// NewConnection returns an uninitialized connection, must call Connection.Connect() before using.
@@ -80,12 +81,34 @@ func (c *Connection) Connect() error {
80
81
return nil
81
82
}
82
83
84
+ func (c * Connection ) unsafeNonce (address ethcommon.Address ) (uint64 , error ) {
85
+ // Sync on-chain nonce
86
+ nonce , err := c .conn .NonceAt (context .Background (), address , nil )
87
+ if err != nil {
88
+ return 0 , err
89
+ }
90
+ if c .nonce >= nonce {
91
+ return c .nonce , nil
92
+ } else {
93
+ c .nonce = nonce
94
+ return nonce , nil
95
+ }
96
+ }
97
+
98
+ // LockAndIncreaseNonce acquires a lock on the opts before increase nonce by 1
99
+ // and gas price.
100
+ func (c * Connection ) IncreaseNonce () {
101
+ c .nonceLock .Lock ()
102
+ c .nonce += 1
103
+ c .nonceLock .Unlock ()
104
+ }
105
+
83
106
// newTransactOpts builds the TransactOpts for the connection's keypair.
84
107
func (c * Connection ) newTransactOpts (value , gasLimit , gasPrice * big.Int ) (* bind.TransactOpts , uint64 , error ) {
85
108
privateKey := c .kp .PrivateKey ()
86
109
address := ethcrypto .PubkeyToAddress (privateKey .PublicKey )
87
110
88
- nonce , err := c .conn . PendingNonceAt ( context . Background (), address )
111
+ nonce , err := c .unsafeNonce ( address )
89
112
if err != nil {
90
113
return nil , 0 , err
91
114
}
@@ -167,12 +190,13 @@ func (c *Connection) LockAndUpdateOpts() error {
167
190
}
168
191
c .opts .GasPrice = gasPrice
169
192
170
- nonce , err := c .conn . PendingNonceAt ( context . Background (), c .opts .From )
193
+ nonce , err := c .unsafeNonce ( c .opts .From )
171
194
if err != nil {
172
195
c .optsLock .Unlock ()
173
196
return err
174
197
}
175
198
c .opts .Nonce .SetUint64 (nonce )
199
+ c .log .Info ("LockAndUpdateOpts: update opts nonce to: " , nonce )
176
200
return nil
177
201
}
178
202
0 commit comments