Skip to content

Commit

Permalink
hotfix: avoid unnecessary panic (#1212) (#1220)
Browse files Browse the repository at this point in the history
  • Loading branch information
Yashk767 authored Jul 17, 2024
1 parent aabca34 commit dae96c9
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 55 deletions.
72 changes: 37 additions & 35 deletions cmd/dispute.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
err = cmdUtils.StoreBountyId(client, account)
if err != nil {
log.Error(err)
break
}
continue
}
Expand All @@ -124,6 +123,7 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
idDisputeTxn, err := cmdUtils.CheckDisputeForIds(client, transactionOptions, epoch, uint8(blockIndex), proposedBlock.Ids, revealedCollectionIds)
if err != nil {
log.Error("Error in disputing: ", err)
continue
}
if idDisputeTxn != nil {
idDisputeTxnHash := transactionUtils.Hash(idDisputeTxn)
Expand All @@ -136,7 +136,6 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
err = cmdUtils.StoreBountyId(client, account)
if err != nil {
log.Error(err)
break
}
continue
}
Expand All @@ -153,6 +152,11 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
// ids [1, 2, 3, 4]
// Sorted revealed values would be the vote values for the wrong median, here 230
log.Debug("HandleDispute: Mismatch index while iterating: ", mismatchIndex)
if mismatchIndex < 0 || mismatchIndex >= len(proposedBlock.Ids) {
log.Error("Mismatch index is out of bounds, cannot continue dispute for medians")
continue
}

collectionIdOfWrongMedian := proposedBlock.Ids[mismatchIndex]
log.Debug("HandleDispute: Collection Id of wrong median: ", collectionIdOfWrongMedian)

Expand Down Expand Up @@ -190,65 +194,63 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu

//This function returns the local median data
func (*UtilsStruct) GetLocalMediansData(client *ethclient.Client, account types.Account, epoch uint32, blockNumber *big.Int, rogueData types.Rogue) (types.ProposeFileData, error) {
if (globalProposedDataStruct.MediansData == nil && !rogueData.IsRogue) || epoch != globalProposedDataStruct.Epoch {
if rogueData.IsRogue {
// As the staker has proposed with incorrect medians in rogue mode so those values needs to be compared with the correct calculated medians
log.Debug("Staker proposed in rogue mode, now calculating medians correctly...")
return calculateMedian(client, account, epoch, blockNumber)
}

// Fetching the data from file only if the node is not in rogue mode and
// the proposed data in memory is nil or epoch in propose data from memory doesn't match with current epoch
nilProposedData := globalProposedDataStruct.MediansData == nil || globalProposedDataStruct.RevealedDataMaps == nil || globalProposedDataStruct.RevealedCollectionIds == nil
if nilProposedData || epoch != globalProposedDataStruct.Epoch {
log.Debug("Global propose data struct is not updated, getting the proposed data from file...")
fileName, err := pathUtils.GetProposeDataFileName(account.Address)
if err != nil {
log.Error("Error in getting file name to read median data: ", err)
goto CalculateMedian
return calculateMedian(client, account, epoch, blockNumber)
}
log.Debug("GetLocalMediansData: Propose data file path: ", fileName)
proposedData, err := fileUtils.ReadFromProposeJsonFile(fileName)
if err != nil {
log.Errorf("Error in getting propose data from file %s: %v", fileName, err)
goto CalculateMedian
return calculateMedian(client, account, epoch, blockNumber)
}
log.Debugf("GetLocalMediansData: Proposed data from file: %+v", proposedData)
if proposedData.Epoch != epoch {
log.Errorf("File %s doesn't contain latest median data", fileName)
goto CalculateMedian
return calculateMedian(client, account, epoch, blockNumber)
}
log.Debug("Updating global proposed data struct...")
updateGlobalProposedDataStruct(proposedData)
log.Debugf("GetLocalMediansData: Global proposed data struct: %+v", globalProposedDataStruct)
return proposedData, err
}
CalculateMedian:

return globalProposedDataStruct, nil
}

func calculateMedian(client *ethclient.Client, account types.Account, epoch uint32, blockNumber *big.Int) (types.ProposeFileData, error) {
stakerId, err := razorUtils.GetStakerId(client, account.Address)
if err != nil {
log.Error("Error in getting stakerId: ", err)
return types.ProposeFileData{}, err
}
log.Debug("GetLocalMediansData: Staker Id: ", stakerId)
lastProposedEpoch, err := razorUtils.GetEpochLastProposed(client, stakerId)

log.Debug("Calculating the medians data again...")
log.Debugf("GetLocalMediansData: Calling MakeBlock() with arguments blockNumber = %s, epoch = %d, rogueData = %+v", blockNumber, epoch, types.Rogue{IsRogue: false})
medians, revealedCollectionIds, revealedDataMaps, err := cmdUtils.MakeBlock(client, blockNumber, epoch, types.Rogue{IsRogue: false})
if err != nil {
log.Error("Error in getting last proposed epoch: ", err)
log.Error("Error in calculating block medians: ", err)
return types.ProposeFileData{}, err
}
log.Debug("GetLocalMediansData: Last proposed epoch: ", lastProposedEpoch)

nilProposedData := globalProposedDataStruct.MediansData == nil || globalProposedDataStruct.RevealedDataMaps == nil || globalProposedDataStruct.RevealedCollectionIds == nil
epochCheck := epoch != lastProposedEpoch

if nilProposedData || rogueData.IsRogue || epochCheck {
log.Debug("Calculating the medians data again...")
log.Debugf("GetLocalMediansData: Calling MakeBlock() with arguments blockNumber = %s, epoch = %d, rogueData = %+v", blockNumber, epoch, types.Rogue{IsRogue: false})
medians, revealedCollectionIds, revealedDataMaps, err := cmdUtils.MakeBlock(client, blockNumber, epoch, types.Rogue{IsRogue: false})
if err != nil {
log.Error("Error in calculating block medians")
return types.ProposeFileData{}, err
}
log.Debug("Updating global proposed data struct...")
updateGlobalProposedDataStruct(types.ProposeFileData{
MediansData: medians,
RevealedCollectionIds: revealedCollectionIds,
RevealedDataMaps: revealedDataMaps,
Epoch: epoch,
})
log.Debugf("GetLocalMediansData: Global proposed data struct: %+v", globalProposedDataStruct)
calculatedProposedData := types.ProposeFileData{
MediansData: medians,
RevealedCollectionIds: revealedCollectionIds,
RevealedDataMaps: revealedDataMaps,
Epoch: epoch,
}

log.Debugf("Locally calculated data, Medians: %s", globalProposedDataStruct.MediansData)
return globalProposedDataStruct, nil
log.Debugf("Locally calculated data, Medians: %s", calculatedProposedData.MediansData)
return calculatedProposedData, nil
}

//This function check for the dispute in different type of Id's
Expand Down
52 changes: 37 additions & 15 deletions cmd/dispute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,30 @@ func TestHandleDispute(t *testing.T) {
},
want: nil,
},
{
name: "Test 19: When the mismatch id index is out of range",
args: args{
sortedProposedBlockIds: []uint32{45, 65, 23, 64, 12},
biggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
biggestStakeId: 2,
medians: []*big.Int{big.NewInt(6901548), big.NewInt(498307)},
revealedCollectionIds: []uint16{1},
revealedDataMaps: &types.RevealedDataMaps{
SortedRevealedValues: nil,
VoteWeights: nil,
InfluenceSum: nil,
},
proposedBlock: bindings.StructsBlock{
Medians: []*big.Int{big.NewInt(6901548)},
Ids: []uint16{1},
Valid: true,
BiggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
},
idDisputeTxn: nil,
disputeErr: nil,
},
want: nil,
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -659,7 +683,6 @@ func TestGetLocalMediansData(t *testing.T) {
client *ethclient.Client
account types.Account
blockNumber *big.Int
rogueData types.Rogue
)
type args struct {
epoch uint32
Expand All @@ -673,8 +696,7 @@ func TestGetLocalMediansData(t *testing.T) {
mediansErr error
stakerId uint32
stakerIdErr error
lastProposedEpoch uint32
lastProposedEpochErr error
isRogue bool
}
tests := []struct {
name string
Expand Down Expand Up @@ -720,16 +742,18 @@ func TestGetLocalMediansData(t *testing.T) {
{
name: "Test 4: When there is an error in getting medians",
args: args{
mediansErr: errors.New("error in fetching medians"),
fileNameErr: errors.New("error in getting fileName"),
mediansErr: errors.New("error in fetching medians"),
},
want: nil,
want1: nil,
want2: nil,
wantErr: true,
},
{
name: "Test 5: When GetLocalMediansData executes successfully",
name: "Test 5: When GetLocalMediansData executes successfully when there is an error in getting file name",
args: args{
fileNameErr: errors.New("error in getting fileName"),
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
revealedCollectionIds: []uint16{1, 2, 3},
revealedDataMaps: &types.RevealedDataMaps{},
Expand All @@ -742,6 +766,7 @@ func TestGetLocalMediansData(t *testing.T) {
{
name: "Test 6: When there is an error in getting stakerId",
args: args{
fileNameErr: errors.New("error in getting fileName"),
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
revealedCollectionIds: []uint16{1, 2, 3},
revealedDataMaps: &types.RevealedDataMaps{},
Expand All @@ -753,19 +778,17 @@ func TestGetLocalMediansData(t *testing.T) {
wantErr: true,
},
{
name: "Test 7: When there is an error in getting last proposed epoch",
name: "Test 7: When staker votes in rogue mode and needs to calculate median again",
args: args{
isRogue: true,
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
revealedCollectionIds: []uint16{1, 2, 3},
revealedDataMaps: &types.RevealedDataMaps{},
stakerId: 2,
epoch: 5,
lastProposedEpochErr: errors.New("lastProposedEpoch error"),
},
want: nil,
want1: nil,
want2: nil,
wantErr: true,
want: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
want1: []uint16{1, 2, 3},
want2: &types.RevealedDataMaps{},
wantErr: false,
},
}
for _, tt := range tests {
Expand All @@ -776,9 +799,8 @@ func TestGetLocalMediansData(t *testing.T) {
fileUtilsMock.On("ReadFromProposeJsonFile", mock.Anything).Return(tt.args.proposedData, tt.args.proposeDataErr)
cmdUtilsMock.On("MakeBlock", mock.AnythingOfType("*ethclient.Client"), mock.Anything, mock.Anything, mock.Anything).Return(tt.args.medians, tt.args.revealedCollectionIds, tt.args.revealedDataMaps, tt.args.mediansErr)
utilsMock.On("GetStakerId", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.stakerId, tt.args.stakerIdErr)
utilsMock.On("GetEpochLastProposed", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32")).Return(tt.args.lastProposedEpoch, tt.args.lastProposedEpochErr)
ut := &UtilsStruct{}
localProposedData, err := ut.GetLocalMediansData(client, account, tt.args.epoch, blockNumber, rogueData)
localProposedData, err := ut.GetLocalMediansData(client, account, tt.args.epoch, blockNumber, types.Rogue{IsRogue: tt.args.isRogue})
if (err != nil) != tt.wantErr {
t.Errorf("GetLocalMediansData() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down
10 changes: 5 additions & 5 deletions utils/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func getAPIByteArray(index int) []byte {

func TestGetDataFromAPI(t *testing.T) {
//postRequestInput := `{"type": "POST","url": "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar","body": {"jsonrpc": "2.0","method": "eth_chainId","params": [],"id": 0},"header": {"content-type": "application/json"}}`
sampleChainId, _ := hex.DecodeString("7b226964223a302c226a736f6e727063223a22322e30222c22726573756c74223a2230783561373963343465227d")
sampleChainId, _ := hex.DecodeString("7b226a736f6e727063223a22322e30222c22726573756c74223a223078616133376463222c226964223a307d0a")

type args struct {
urlStruct types.DataSourceURL
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestGetDataFromAPI(t *testing.T) {
args: args{
urlStruct: types.DataSourceURL{
Type: "POST",
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
URL: "https://sepolia.optimism.io",
Body: map[string]interface{}{"jsonrpc": "2.0", "method": "eth_chainId", "params": nil, "id": 0},
Header: map[string]string{"content-type": "application/json"},
},
Expand All @@ -120,7 +120,7 @@ func TestGetDataFromAPI(t *testing.T) {
args: args{
urlStruct: types.DataSourceURL{
Type: "POST",
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
URL: "https://sepolia.optimism.io",
Body: map[string]interface{}{"jsonrpc": "2.0", "method": "eth_chainId", "params": nil, "id": 0},
Header: map[string]string{"auth": "${API_KEY}", "content-type": "application/json"},
},
Expand All @@ -132,7 +132,7 @@ func TestGetDataFromAPI(t *testing.T) {
args: args{
urlStruct: types.DataSourceURL{
Type: "POST",
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
URL: "https://sepolia.optimism.io",
Body: map[string]interface{}{"fail": func() {}, "jsonrpc": 1},
},
},
Expand All @@ -144,7 +144,7 @@ func TestGetDataFromAPI(t *testing.T) {
args: args{
urlStruct: types.DataSourceURL{
Type: "",
URL: "https://jsonplaceholder.typicode.com/todos/1",
URL: "https://sepolia.optimism.io",
},
},
want: nil,
Expand Down

0 comments on commit dae96c9

Please sign in to comment.