Skip to content

Commit

Permalink
client/eth: Check provider header times.
Browse files Browse the repository at this point in the history
When fetching a new or cached header with a provider, do a basic check
on the header's time to determine if the header, and so the provider,
are up to date.
  • Loading branch information
JoeGruffins committed Feb 3, 2023
1 parent c4e9ffa commit 8b30026
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 177 deletions.
12 changes: 4 additions & 8 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ type ethFetcher interface {
sendSignedTransaction(ctx context.Context, tx *types.Transaction) error
sendTransaction(ctx context.Context, txOpts *bind.TransactOpts, to common.Address, data []byte) (*types.Transaction, error)
signData(data []byte) (sig, pubKey []byte, err error)
syncProgress(context.Context) (*ethereum.SyncProgress, error)
syncProgress(context.Context) (progress *ethereum.SyncProgress, bestHeaderUNIXTime uint64, err error)
transactionConfirmations(context.Context, common.Hash) (uint32, error)
getTransaction(context.Context, common.Hash) (*types.Transaction, int64, error)
txOpts(ctx context.Context, val, maxGas uint64, maxFeeRate, nonce *big.Int) (*bind.TransactOpts, error)
Expand Down Expand Up @@ -2806,18 +2806,14 @@ func (*baseWallet) ValidateSecret(secret, secretHash []byte) bool {
// more, requesting the best block header starts to fail after a few tries
// during initial sync. Investigate how to get correct sync progress.
func (eth *baseWallet) SyncStatus() (bool, float32, error) {
prog, err := eth.node.syncProgress(eth.ctx)
prog, bestHeaderUNIXTime, err := eth.node.syncProgress(eth.ctx)
if err != nil {
return false, 0, err
}
checkHeaderTime := func() (bool, error) {
bh, err := eth.node.bestHeader(eth.ctx)
if err != nil {
return false, err
}
// Time in the header is in seconds.
timeDiff := time.Now().Unix() - int64(bh.Time)
if timeDiff > dexeth.MaxBlockInterval && eth.net != dex.Simnet {
timeDiff := time.Now().Unix() - int64(bestHeaderUNIXTime)
if timeDiff > dexeth.MaxBlockInterval {
eth.log.Infof("Time since last eth block (%d sec) exceeds %d sec."+
"Assuming not in sync. Ensure your computer's system clock "+
"is correct.", timeDiff, dexeth.MaxBlockInterval)
Expand Down
94 changes: 48 additions & 46 deletions client/asset/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,43 +91,45 @@ type tGetTxRes struct {
}

type testNode struct {
acct *accounts.Account
addr common.Address
connectErr error
bestHdr *types.Header
bestHdrErr error
syncProg ethereum.SyncProgress
bal *big.Int
balErr error
signDataErr error
privKey *ecdsa.PrivateKey
swapVers map[uint32]struct{} // For SwapConfirmations -> swap. TODO for other contractor methods
swapMap map[[32]byte]*dexeth.SwapState
refundable bool
baseFee *big.Int
tip *big.Int
netFeeStateErr error
confNonce uint64
confNonceErr error
getTxRes *types.Transaction
getTxResMap map[common.Hash]*tGetTxRes
getTxHeight int64
getTxErr error
receipt *types.Receipt
receiptTx *types.Transaction
receiptErr error
hdrByHash *types.Header
txReceipt *types.Receipt
lastSignedTx *types.Transaction
sendTxTx *types.Transaction
sendTxErr error
simBackend bind.ContractBackend
maxFeeRate *big.Int
pendingTxs []*types.Transaction
tContractor *tContractor
tokenContractor *tTokenContractor
contractor contractor
tokenParent *assetWallet // only set for tokens
acct *accounts.Account
addr common.Address
connectErr error
bestHdr *types.Header
bestHdrErr error
syncProg ethereum.SyncProgress
syncProgBestHeaderUNIXTime uint64
syncProgErr error
bal *big.Int
balErr error
signDataErr error
privKey *ecdsa.PrivateKey
swapVers map[uint32]struct{} // For SwapConfirmations -> swap. TODO for other contractor methods
swapMap map[[32]byte]*dexeth.SwapState
refundable bool
baseFee *big.Int
tip *big.Int
netFeeStateErr error
confNonce uint64
confNonceErr error
getTxRes *types.Transaction
getTxResMap map[common.Hash]*tGetTxRes
getTxHeight int64
getTxErr error
receipt *types.Receipt
receiptTx *types.Transaction
receiptErr error
hdrByHash *types.Header
txReceipt *types.Receipt
lastSignedTx *types.Transaction
sendTxTx *types.Transaction
sendTxErr error
simBackend bind.ContractBackend
maxFeeRate *big.Int
pendingTxs []*types.Transaction
tContractor *tContractor
tokenContractor *tTokenContractor
contractor contractor
tokenParent *assetWallet // only set for tokens
}

func newBalance(current, in, out uint64) *Balance {
Expand Down Expand Up @@ -206,8 +208,8 @@ func (n *testNode) lock() error {
func (n *testNode) locked() bool {
return false
}
func (n *testNode) syncProgress(context.Context) (*ethereum.SyncProgress, error) {
return &n.syncProg, nil
func (n *testNode) syncProgress(context.Context) (prog *ethereum.SyncProgress, bestBlockUNIXTime uint64, err error) {
return &n.syncProg, n.syncProgBestHeaderUNIXTime, n.syncProgErr
}
func (n *testNode) peerCount() uint32 {
return 1
Expand Down Expand Up @@ -479,8 +481,8 @@ func TestSyncStatus(t *testing.T) {
tests := []struct {
name string
syncProg ethereum.SyncProgress
syncProgErr error
subSecs uint64
bestHdrErr error
wantErr, wantSynced bool
wantRatio float32
}{{
Expand All @@ -506,22 +508,22 @@ func TestSyncStatus(t *testing.T) {
},
subSecs: dexeth.MaxBlockInterval + 1,
}, {
name: "best header error",
bestHdrErr: errors.New(""),
name: "sync progress error",
syncProg: ethereum.SyncProgress{
CurrentBlock: 25,
HighestBlock: 0,
},
wantErr: true,
syncProgErr: errors.New(""),
wantErr: true,
}}

for _, test := range tests {
nowInSecs := uint64(time.Now().Unix())
ctx, cancel := context.WithCancel(context.Background())
node := &testNode{
syncProg: test.syncProg,
bestHdr: &types.Header{Time: nowInSecs - test.subSecs},
bestHdrErr: test.bestHdrErr,
syncProg: test.syncProg,
syncProgBestHeaderUNIXTime: nowInSecs - test.subSecs,
syncProgErr: test.syncProgErr,
}
eth := &baseWallet{
node: node,
Expand Down
Loading

0 comments on commit 8b30026

Please sign in to comment.