Skip to content

Commit

Permalink
add nonce-send mutex
Browse files Browse the repository at this point in the history
  • Loading branch information
buck54321 committed Nov 28, 2021
1 parent caba170 commit 19d93a0
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 13 deletions.
2 changes: 2 additions & 0 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,8 @@ func (eth *ExchangeWallet) checkForNewBlocks() {
go eth.tipChange(nil)
}

// Balance is the current balance, including information about the pending
// balance.
type Balance struct {
Current, Pending, PendingIn, PendingOut *big.Int
}
2 changes: 0 additions & 2 deletions client/asset/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ type testNode struct {
syncProg ethereum.SyncProgress
bal *Balance
balErr error
pendingTxs []*types.Transaction
pendingTxsErr error
initGas uint64
initGasErr error
signDataErr error
Expand Down
29 changes: 18 additions & 11 deletions client/asset/eth/nodeclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"errors"
"fmt"
"math/big"
"sync"

"decred.org/dcrdex/client/asset"
"decred.org/dcrdex/dex"
Expand Down Expand Up @@ -45,15 +46,16 @@ var (
// nodeClient satisfies the ethFetcher interface. Do not use until Connect is
// called.
type nodeClient struct {
net dex.Network
log dex.Logger
creds *accountCredentials
p2pSrv *p2p.Server
ec *ethclient.Client
node *node.Node
leth *les.LightEthereum
chainID *big.Int
contractors map[uint32]contractor
net dex.Network
log dex.Logger
creds *accountCredentials
p2pSrv *p2p.Server
ec *ethclient.Client
node *node.Node
leth *les.LightEthereum
chainID *big.Int
contractors map[uint32]contractor
nonceSendMtx sync.Mutex
}

func newNodeClient(dir string, net dex.Network, log dex.Logger) (*nodeClient, error) {
Expand Down Expand Up @@ -184,10 +186,10 @@ func (n *nodeClient) balanceAt(ctx context.Context, addr common.Address, bn rpc.
}

func (n *nodeClient) addressBalance(ctx context.Context, addr common.Address) (*big.Int, error) {
return n.balanceAt(ctx, n.creds.addr, rpc.LatestBlockNumber)
return n.balanceAt(ctx, addr, rpc.LatestBlockNumber)
}

// balance gets the current balance of an address.
// balance gets the current and pending balances.
func (n *nodeClient) balance(ctx context.Context) (*Balance, error) {
pendingBal, err := n.balanceAt(ctx, n.creds.addr, rpc.PendingBlockNumber)
if err != nil {
Expand All @@ -211,6 +213,8 @@ func (n *nodeClient) balance(ctx context.Context) (*Balance, error) {
outgoing.Add(outgoing, tx.Value())
}

// pending = current + incoming - outgoing
// => incoming = pending + outgoing - current
incoming := pendingBal.Add(pendingBal, outgoing)
incoming.Sub(incoming, bal)

Expand Down Expand Up @@ -302,6 +306,9 @@ func (n *nodeClient) listWallets(ctx context.Context) []accounts.Wallet {
func (n *nodeClient) sendTransaction(ctx context.Context, txOpts *bind.TransactOpts,
to common.Address, data []byte) (*types.Transaction, error) {

n.nonceSendMtx.Lock()
defer n.nonceSendMtx.Unlock()

nonce, err := n.leth.ApiBackend.GetPoolNonce(ctx, n.creds.addr)
if err != nil {
return nil, fmt.Errorf("error getting nonce: %v", err)
Expand Down
10 changes: 10 additions & 0 deletions client/asset/eth/nodeclient_harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,16 @@ func testSendTransaction(t *testing.T) {
if err != nil {
t.Fatal(err)
}

bal, _ := ethClient.balance(ctx)
if bal.PendingIn.Cmp(dexeth.GweiToWei(1)) != 0 { // We sent it to ourselves.
t.Fatalf("pending in not showing")
}

if bal.PendingOut.Cmp(dexeth.GweiToWei(1)) != 0 {
t.Fatalf("pending out not showing")
}

spew.Dump(tx)
if err := waitForMined(t, time.Second*10, false); err != nil {
t.Fatal(err)
Expand Down

0 comments on commit 19d93a0

Please sign in to comment.