Skip to content

Commit

Permalink
refactor: added context with timeout to retry mechanism (#1235)
Browse files Browse the repository at this point in the history
* chore: updated config variable default and limits for 5 min epoch (#1232)

* feat: added timeout to retry mechanism using context

* refactor: called stateBuffer once and used in other functions

* refactor: added context to RPC calls used in vote function

* refactor: added context instance to all the dependent functions

* refactor: fixed tests for cmd package

* refactor: fixed tests for utils package

* refactor: fixed additional tests in cmd package

* refactor: fixed benchmarks in cmd package

* refactor: reduced number of retry attempts

* refactor: added tests for context deadline exceeded for retry case

* refactor: rebased retry params with current main branch v2.0.0 release
  • Loading branch information
Yashk767 authored Oct 9, 2024
1 parent 500f8bf commit bb75173
Show file tree
Hide file tree
Showing 78 changed files with 1,669 additions and 1,526 deletions.
13 changes: 7 additions & 6 deletions cmd/addStake.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package cmd

import (
"context"
"razor/accounts"
"razor/core"
"razor/core/types"
Expand Down Expand Up @@ -69,13 +70,13 @@ func (*UtilsStruct) ExecuteStake(flagSet *pflag.FlagSet) {
razorUtils.CheckAmountAndBalance(valueInWei, balance)

log.Debug("Checking whether sFuel balance is not 0...")
razorUtils.CheckEthBalanceIsZero(client, address)
razorUtils.CheckEthBalanceIsZero(context.Background(), client, address)

minSafeRazor, err := razorUtils.GetMinSafeRazor(client)
minSafeRazor, err := razorUtils.GetMinSafeRazor(context.Background(), client)
utils.CheckError("Error in getting minimum safe razor amount: ", err)
log.Debug("ExecuteStake: Minimum razor that you can stake for first time: ", minSafeRazor)

stakerId, err := razorUtils.GetStakerId(client, address)
stakerId, err := razorUtils.GetStakerId(context.Background(), client, address)
utils.CheckError("Error in getting stakerId: ", err)
log.Debug("ExecuteStake: Staker Id: ", stakerId)

Expand All @@ -84,7 +85,7 @@ func (*UtilsStruct) ExecuteStake(flagSet *pflag.FlagSet) {
}

if stakerId != 0 {
staker, err := razorUtils.GetStaker(client, stakerId)
staker, err := razorUtils.GetStaker(context.Background(), client, stakerId)
utils.CheckError("Error in getting staker: ", err)

if staker.IsSlashed {
Expand Down Expand Up @@ -119,7 +120,7 @@ func (*UtilsStruct) ExecuteStake(flagSet *pflag.FlagSet) {

//This function allows the user to stake razors in the razor network and returns the hash
func (*UtilsStruct) StakeCoins(txnArgs types.TransactionOptions) (common.Hash, error) {
epoch, err := razorUtils.GetEpoch(txnArgs.Client)
epoch, err := razorUtils.GetEpoch(context.Background(), txnArgs.Client)
if err != nil {
return core.NilHash, err
}
Expand All @@ -129,7 +130,7 @@ func (*UtilsStruct) StakeCoins(txnArgs types.TransactionOptions) (common.Hash, e
txnArgs.MethodName = "stake"
txnArgs.Parameters = []interface{}{epoch, txnArgs.Amount}
txnArgs.ABI = bindings.StakeManagerMetaData.ABI
txnOpts := razorUtils.GetTxnOpts(txnArgs)
txnOpts := razorUtils.GetTxnOpts(context.Background(), txnArgs)
log.Debugf("Executing Stake transaction with epoch = %d, amount = %d", epoch, txnArgs.Amount)
txn, err := stakeManagerUtils.Stake(txnArgs.Client, txnOpts, epoch, txnArgs.Amount)
if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions cmd/addStake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ func TestStakeCoins(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetUpMockInterfaces()
utilsMock.On("GetEpoch", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.epoch, tt.args.getEpochErr)
utilsMock.On("GetTxnOpts", mock.AnythingOfType("types.TransactionOptions")).Return(TxnOpts)
utilsMock.On("GetEpoch", mock.Anything, mock.Anything).Return(tt.args.epoch, tt.args.getEpochErr)
utilsMock.On("GetTxnOpts", mock.Anything, mock.Anything).Return(TxnOpts)
transactionMock.On("Hash", mock.Anything).Return(tt.args.hash)
stakeManagerMock.On("Stake", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tt.args.stakeTxn, tt.args.stakeErr)

Expand Down Expand Up @@ -327,10 +327,10 @@ func TestExecuteStake(t *testing.T) {
utilsMock.On("FetchBalance", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.balance, tt.args.balanceErr)
cmdUtilsMock.On("AssignAmountInWei", flagSet).Return(tt.args.amount, tt.args.amountErr)
utilsMock.On("CheckAmountAndBalance", mock.AnythingOfType("*big.Int"), mock.AnythingOfType("*big.Int")).Return(tt.args.amount)
utilsMock.On("CheckEthBalanceIsZero", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return()
utilsMock.On("GetMinSafeRazor", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.minSafeRazor, tt.args.minSafeRazorErr)
utilsMock.On("GetStakerId", mock.Anything, mock.Anything).Return(tt.args.stakerId, tt.args.stakerIdErr)
utilsMock.On("GetStaker", mock.Anything, mock.Anything).Return(tt.args.staker, tt.args.stakerErr)
utilsMock.On("CheckEthBalanceIsZero", mock.Anything, mock.Anything, mock.Anything).Return()
utilsMock.On("GetMinSafeRazor", mock.Anything, mock.Anything).Return(tt.args.minSafeRazor, tt.args.minSafeRazorErr)
utilsMock.On("GetStakerId", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.stakerId, tt.args.stakerIdErr)
utilsMock.On("GetStaker", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.staker, tt.args.stakerErr)
cmdUtilsMock.On("Approve", mock.Anything).Return(tt.args.approveTxn, tt.args.approveErr)
cmdUtilsMock.On("StakeCoins", mock.Anything).Return(tt.args.stakeTxn, tt.args.stakeErr)

Expand Down
3 changes: 2 additions & 1 deletion cmd/approve.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package cmd

import (
"context"
"github.com/ethereum/go-ethereum/common"
"razor/core"
"razor/core/types"
Expand All @@ -25,7 +26,7 @@ func (*UtilsStruct) Approve(txnArgs types.TransactionOptions) (common.Hash, erro
txnArgs.MethodName = "approve"
txnArgs.ABI = bindings.RAZORMetaData.ABI
txnArgs.Parameters = []interface{}{common.HexToAddress(core.StakeManagerAddress), txnArgs.Amount}
txnOpts := razorUtils.GetTxnOpts(txnArgs)
txnOpts := razorUtils.GetTxnOpts(context.Background(), txnArgs)
log.Debug("Executing Approve transaction with amount: ", txnArgs.Amount)
txn, err := tokenManagerUtils.Approve(txnArgs.Client, txnOpts, common.HexToAddress(core.StakeManagerAddress), txnArgs.Amount)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/approve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TestApprove(t *testing.T) {
SetUpMockInterfaces()

utilsMock.On("GetOptions").Return(tt.args.callOpts)
utilsMock.On("GetTxnOpts", mock.AnythingOfType("types.TransactionOptions")).Return(TxnOpts)
utilsMock.On("GetTxnOpts", mock.Anything, mock.Anything).Return(TxnOpts)
transactionMock.On("Hash", mock.Anything).Return(tt.args.hash)
tokenManagerMock.On("Allowance", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tt.args.allowanceAmount, tt.args.allowanceError)
tokenManagerMock.On("Approve", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tt.args.approveTxn, tt.args.approveError)
Expand Down
5 changes: 3 additions & 2 deletions cmd/claimBounty.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package cmd

import (
"context"
"errors"
"math/big"
"os"
Expand Down Expand Up @@ -155,7 +156,7 @@ func (*UtilsStruct) ClaimBounty(config types.Configurations, client *ethclient.C
MethodName: "redeemBounty",
Parameters: []interface{}{redeemBountyInput.BountyId},
}
epoch, err := razorUtils.GetEpoch(txnArgs.Client)
epoch, err := razorUtils.GetEpoch(context.Background(), txnArgs.Client)
if err != nil {
log.Error("Error in getting epoch: ", err)
return core.NilHash, err
Expand Down Expand Up @@ -190,7 +191,7 @@ func (*UtilsStruct) ClaimBounty(config types.Configurations, client *ethclient.C
return core.NilHash, nil
}

txnOpts := razorUtils.GetTxnOpts(txnArgs)
txnOpts := razorUtils.GetTxnOpts(context.Background(), txnArgs)

log.Debug("Executing RedeemBounty transaction with bountyId: ", redeemBountyInput.BountyId)
tx, err := stakeManagerUtils.RedeemBounty(txnArgs.Client, txnOpts, redeemBountyInput.BountyId)
Expand Down
4 changes: 2 additions & 2 deletions cmd/claimBounty_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,12 @@ func TestClaimBounty(t *testing.T) {
transactionUtils = transactionUtilsMock
timeUtils = timeMock

utilsMock.On("GetEpoch", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.epoch, tt.args.epochErr)
utilsMock.On("GetEpoch", mock.Anything, mock.Anything).Return(tt.args.epoch, tt.args.epochErr)
utilsMock.On("GetOptions").Return(callOpts)
stakeManagerMock.On("GetBountyLock", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("*bind.CallOpts"), mock.AnythingOfType("uint32")).Return(tt.args.bountyLock, tt.args.bountyLockErr)
timeMock.On("Sleep", mock.AnythingOfType("time.Duration")).Return()
utilsMock.On("CalculateBlockTime", mock.AnythingOfType("*ethclient.Client")).Return(blockTime)
utilsMock.On("GetTxnOpts", mock.AnythingOfType("types.TransactionOptions")).Return(TxnOpts)
utilsMock.On("GetTxnOpts", mock.Anything, mock.Anything).Return(TxnOpts)
stakeManagerMock.On("RedeemBounty", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("*bind.TransactOpts"), mock.AnythingOfType("uint32")).Return(tt.args.redeemBountyTxn, tt.args.redeemBountyErr)
utilsMock.On("SecondsToReadableTime", mock.AnythingOfType("int")).Return(tt.args.time)
transactionUtilsMock.On("Hash", mock.Anything).Return(tt.args.hash)
Expand Down
5 changes: 3 additions & 2 deletions cmd/claimCommission.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package cmd

import (
"context"
"math/big"
"razor/accounts"
"razor/core"
Expand Down Expand Up @@ -54,7 +55,7 @@ func (*UtilsStruct) ClaimCommission(flagSet *pflag.FlagSet) {
err = razorUtils.CheckPassword(account)
utils.CheckError("Error in fetching private key from given password: ", err)

stakerId, err := razorUtils.GetStakerId(client, address)
stakerId, err := razorUtils.GetStakerId(context.Background(), client, address)
utils.CheckError("Error in getting stakerId: ", err)
log.Debug("ClaimCommission: Staker Id: ", stakerId)
callOpts := razorUtils.GetOptions()
Expand All @@ -64,7 +65,7 @@ func (*UtilsStruct) ClaimCommission(flagSet *pflag.FlagSet) {
log.Debugf("ClaimCommission: Staker Info: %+v", stakerInfo)

if stakerInfo.StakerReward.Cmp(big.NewInt(0)) > 0 {
txnOpts := razorUtils.GetTxnOpts(types.TransactionOptions{
txnOpts := razorUtils.GetTxnOpts(context.Background(), types.TransactionOptions{
Client: client,
ChainId: core.ChainId,
Config: config,
Expand Down
4 changes: 2 additions & 2 deletions cmd/claimCommission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,13 @@ func TestClaimCommission(t *testing.T) {
fatal = false

fileUtilsMock.On("AssignLogFile", mock.AnythingOfType("*pflag.FlagSet"), mock.Anything)
utilsMock.On("GetStakerId", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.stakerId, tt.args.stakerIdErr)
utilsMock.On("GetStakerId", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.stakerId, tt.args.stakerIdErr)
utilsMock.On("GetOptions").Return(callOpts)
utilsMock.On("AssignPassword", mock.AnythingOfType("*pflag.FlagSet")).Return(tt.args.password)
utilsMock.On("CheckPassword", mock.Anything).Return(nil)
utilsMock.On("AccountManagerForKeystore").Return(&accounts.AccountManager{}, nil)
utilsMock.On("ConnectToClient", mock.AnythingOfType("string")).Return(client)
utilsMock.On("GetTxnOpts", mock.AnythingOfType("types.TransactionOptions")).Return(TxnOpts)
utilsMock.On("GetTxnOpts", mock.Anything, mock.Anything).Return(TxnOpts)
utilsMock.On("WaitForBlockCompletion", mock.AnythingOfType("*ethclient.Client"), mock.Anything).Return(nil)

stakeManagerMock.On("StakerInfo", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("*bind.CallOpts"), mock.AnythingOfType("uint32")).Return(tt.args.stakerInfo, tt.args.stakerInfoErr)
Expand Down
24 changes: 15 additions & 9 deletions cmd/cmd-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
package cmd

import (
"context"
"errors"
"math/big"
"razor/utils"
Expand All @@ -14,25 +15,30 @@ import (
)

//This function takes client as a parameter and returns the epoch and state
func (*UtilsStruct) GetEpochAndState(client *ethclient.Client) (uint32, int64, error) {
epoch, err := razorUtils.GetEpoch(client)
func (*UtilsStruct) GetEpochAndState(ctx context.Context, client *ethclient.Client) (uint32, int64, error) {
epoch, err := razorUtils.GetEpoch(ctx, client)
if err != nil {
return 0, 0, err
}
bufferPercent, err := cmdUtils.GetBufferPercent()
if err != nil {
return 0, 0, err
}
err = ValidateBufferPercentLimit(client, bufferPercent)
err = ValidateBufferPercentLimit(ctx, client, bufferPercent)
if err != nil {
return 0, 0, err
}
latestHeader, err := clientUtils.GetLatestBlockWithRetry(client)
latestHeader, err := clientUtils.GetLatestBlockWithRetry(ctx, client)
if err != nil {
log.Error("Error in fetching block: ", err)
return 0, 0, err
}
state, err := razorUtils.GetBufferedState(client, latestHeader, bufferPercent)
stateBuffer, err := razorUtils.GetStateBuffer(ctx, client)
if err != nil {
log.Error("Error in getting state buffer: ", err)
return 0, 0, err
}
state, err := razorUtils.GetBufferedState(latestHeader, stateBuffer, bufferPercent)
if err != nil {
return 0, 0, err
}
Expand All @@ -42,10 +48,10 @@ func (*UtilsStruct) GetEpochAndState(client *ethclient.Client) (uint32, int64, e
}

//This function waits for the appropriate states which are required
func (*UtilsStruct) WaitForAppropriateState(client *ethclient.Client, action string, states ...int) (uint32, error) {
func (*UtilsStruct) WaitForAppropriateState(ctx context.Context, client *ethclient.Client, action string, states ...int) (uint32, error) {
statesAllowed := GetFormattedStateNames(states)
for {
epoch, state, err := cmdUtils.GetEpochAndState(client)
epoch, state, err := cmdUtils.GetEpochAndState(ctx, client)
if err != nil {
log.Error("Error in fetching epoch and state: ", err)
return epoch, err
Expand All @@ -60,9 +66,9 @@ func (*UtilsStruct) WaitForAppropriateState(client *ethclient.Client, action str
}

//This function wait if the state is commit state
func (*UtilsStruct) WaitIfCommitState(client *ethclient.Client, action string) (uint32, error) {
func (*UtilsStruct) WaitIfCommitState(ctx context.Context, client *ethclient.Client, action string) (uint32, error) {
for {
epoch, state, err := cmdUtils.GetEpochAndState(client)
epoch, state, err := cmdUtils.GetEpochAndState(ctx, client)
if err != nil {
log.Error("Error in fetching epoch and state: ", err)
return epoch, err
Expand Down
17 changes: 9 additions & 8 deletions cmd/cmd-utils_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"context"
"errors"
Types "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -130,14 +131,14 @@ func TestGetEpochAndState(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
SetUpMockInterfaces()

utilsMock.On("GetEpoch", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.epoch, tt.args.epochErr)
utilsMock.On("GetEpoch", mock.Anything, mock.Anything).Return(tt.args.epoch, tt.args.epochErr)
cmdUtilsMock.On("GetBufferPercent").Return(tt.args.bufferPercent, tt.args.bufferPercentErr)
utilsMock.On("GetStateBuffer", mock.Anything).Return(tt.args.stateBuffer, tt.args.stateBufferErr)
clientUtilsMock.On("GetLatestBlockWithRetry", mock.Anything).Return(tt.args.latestHeader, tt.args.latestHeaderErr)
utilsMock.On("GetStateBuffer", mock.Anything, mock.Anything).Return(tt.args.stateBuffer, tt.args.stateBufferErr)
clientUtilsMock.On("GetLatestBlockWithRetry", mock.Anything, mock.Anything).Return(tt.args.latestHeader, tt.args.latestHeaderErr)
utilsMock.On("GetBufferedState", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.state, tt.args.stateErr)

utils := &UtilsStruct{}
gotEpoch, gotState, err := utils.GetEpochAndState(client)
gotEpoch, gotState, err := utils.GetEpochAndState(context.Background(), client)
if gotEpoch != tt.wantEpoch {
t.Errorf("GetEpochAndState() got epoch = %v, want %v", gotEpoch, tt.wantEpoch)
}
Expand Down Expand Up @@ -221,10 +222,10 @@ func TestWaitForAppropriateState(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
SetUpMockInterfaces()

cmdUtilsMock.On("GetEpochAndState", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.epoch, tt.args.state, tt.args.epochOrStateErr)
cmdUtilsMock.On("GetEpochAndState", mock.Anything, mock.Anything).Return(tt.args.epoch, tt.args.state, tt.args.epochOrStateErr)
timeMock.On("Sleep", mock.Anything).Return()
utils := &UtilsStruct{}
got, err := utils.WaitForAppropriateState(client, tt.args.action, tt.args.states)
got, err := utils.WaitForAppropriateState(context.Background(), client, tt.args.action, tt.args.states)
if got != tt.want {
t.Errorf("WaitForAppropriateState() function, got = %v, want = %v", got, tt.want)
}
Expand Down Expand Up @@ -278,12 +279,12 @@ func TestWaitIfCommitState(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
SetUpMockInterfaces()

cmdUtilsMock.On("GetEpochAndState", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.epoch, tt.args.state, tt.args.epochOrStateErr)
cmdUtilsMock.On("GetEpochAndState", mock.Anything, mock.Anything).Return(tt.args.epoch, tt.args.state, tt.args.epochOrStateErr)
timeMock.On("Sleep", mock.Anything).Return()

utils := &UtilsStruct{}

got, err := utils.WaitIfCommitState(client, action)
got, err := utils.WaitIfCommitState(context.Background(), client, action)
if got != tt.want {
t.Errorf("WaitIfCommitState() function, got = %v, want = %v", got, tt.want)
}
Expand Down
Loading

0 comments on commit bb75173

Please sign in to comment.