Skip to content

Commit dae96c9

Browse files
authored
hotfix: avoid unnecessary panic (#1212) (#1220)
1 parent aabca34 commit dae96c9

File tree

3 files changed

+79
-55
lines changed

3 files changed

+79
-55
lines changed

cmd/dispute.go

+37-35
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
110110
err = cmdUtils.StoreBountyId(client, account)
111111
if err != nil {
112112
log.Error(err)
113-
break
114113
}
115114
continue
116115
}
@@ -124,6 +123,7 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
124123
idDisputeTxn, err := cmdUtils.CheckDisputeForIds(client, transactionOptions, epoch, uint8(blockIndex), proposedBlock.Ids, revealedCollectionIds)
125124
if err != nil {
126125
log.Error("Error in disputing: ", err)
126+
continue
127127
}
128128
if idDisputeTxn != nil {
129129
idDisputeTxnHash := transactionUtils.Hash(idDisputeTxn)
@@ -136,7 +136,6 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
136136
err = cmdUtils.StoreBountyId(client, account)
137137
if err != nil {
138138
log.Error(err)
139-
break
140139
}
141140
continue
142141
}
@@ -153,6 +152,11 @@ func (*UtilsStruct) HandleDispute(client *ethclient.Client, config types.Configu
153152
// ids [1, 2, 3, 4]
154153
// Sorted revealed values would be the vote values for the wrong median, here 230
155154
log.Debug("HandleDispute: Mismatch index while iterating: ", mismatchIndex)
155+
if mismatchIndex < 0 || mismatchIndex >= len(proposedBlock.Ids) {
156+
log.Error("Mismatch index is out of bounds, cannot continue dispute for medians")
157+
continue
158+
}
159+
156160
collectionIdOfWrongMedian := proposedBlock.Ids[mismatchIndex]
157161
log.Debug("HandleDispute: Collection Id of wrong median: ", collectionIdOfWrongMedian)
158162

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

191195
//This function returns the local median data
192196
func (*UtilsStruct) GetLocalMediansData(client *ethclient.Client, account types.Account, epoch uint32, blockNumber *big.Int, rogueData types.Rogue) (types.ProposeFileData, error) {
193-
if (globalProposedDataStruct.MediansData == nil && !rogueData.IsRogue) || epoch != globalProposedDataStruct.Epoch {
197+
if rogueData.IsRogue {
198+
// As the staker has proposed with incorrect medians in rogue mode so those values needs to be compared with the correct calculated medians
199+
log.Debug("Staker proposed in rogue mode, now calculating medians correctly...")
200+
return calculateMedian(client, account, epoch, blockNumber)
201+
}
202+
203+
// Fetching the data from file only if the node is not in rogue mode and
204+
// the proposed data in memory is nil or epoch in propose data from memory doesn't match with current epoch
205+
nilProposedData := globalProposedDataStruct.MediansData == nil || globalProposedDataStruct.RevealedDataMaps == nil || globalProposedDataStruct.RevealedCollectionIds == nil
206+
if nilProposedData || epoch != globalProposedDataStruct.Epoch {
194207
log.Debug("Global propose data struct is not updated, getting the proposed data from file...")
195208
fileName, err := pathUtils.GetProposeDataFileName(account.Address)
196209
if err != nil {
197210
log.Error("Error in getting file name to read median data: ", err)
198-
goto CalculateMedian
211+
return calculateMedian(client, account, epoch, blockNumber)
199212
}
200213
log.Debug("GetLocalMediansData: Propose data file path: ", fileName)
201214
proposedData, err := fileUtils.ReadFromProposeJsonFile(fileName)
202215
if err != nil {
203216
log.Errorf("Error in getting propose data from file %s: %v", fileName, err)
204-
goto CalculateMedian
217+
return calculateMedian(client, account, epoch, blockNumber)
205218
}
206219
log.Debugf("GetLocalMediansData: Proposed data from file: %+v", proposedData)
207220
if proposedData.Epoch != epoch {
208221
log.Errorf("File %s doesn't contain latest median data", fileName)
209-
goto CalculateMedian
222+
return calculateMedian(client, account, epoch, blockNumber)
210223
}
211-
log.Debug("Updating global proposed data struct...")
212-
updateGlobalProposedDataStruct(proposedData)
213-
log.Debugf("GetLocalMediansData: Global proposed data struct: %+v", globalProposedDataStruct)
224+
return proposedData, err
214225
}
215-
CalculateMedian:
226+
227+
return globalProposedDataStruct, nil
228+
}
229+
230+
func calculateMedian(client *ethclient.Client, account types.Account, epoch uint32, blockNumber *big.Int) (types.ProposeFileData, error) {
216231
stakerId, err := razorUtils.GetStakerId(client, account.Address)
217232
if err != nil {
218233
log.Error("Error in getting stakerId: ", err)
219234
return types.ProposeFileData{}, err
220235
}
221236
log.Debug("GetLocalMediansData: Staker Id: ", stakerId)
222-
lastProposedEpoch, err := razorUtils.GetEpochLastProposed(client, stakerId)
237+
238+
log.Debug("Calculating the medians data again...")
239+
log.Debugf("GetLocalMediansData: Calling MakeBlock() with arguments blockNumber = %s, epoch = %d, rogueData = %+v", blockNumber, epoch, types.Rogue{IsRogue: false})
240+
medians, revealedCollectionIds, revealedDataMaps, err := cmdUtils.MakeBlock(client, blockNumber, epoch, types.Rogue{IsRogue: false})
223241
if err != nil {
224-
log.Error("Error in getting last proposed epoch: ", err)
242+
log.Error("Error in calculating block medians: ", err)
225243
return types.ProposeFileData{}, err
226244
}
227-
log.Debug("GetLocalMediansData: Last proposed epoch: ", lastProposedEpoch)
228-
229-
nilProposedData := globalProposedDataStruct.MediansData == nil || globalProposedDataStruct.RevealedDataMaps == nil || globalProposedDataStruct.RevealedCollectionIds == nil
230-
epochCheck := epoch != lastProposedEpoch
231-
232-
if nilProposedData || rogueData.IsRogue || epochCheck {
233-
log.Debug("Calculating the medians data again...")
234-
log.Debugf("GetLocalMediansData: Calling MakeBlock() with arguments blockNumber = %s, epoch = %d, rogueData = %+v", blockNumber, epoch, types.Rogue{IsRogue: false})
235-
medians, revealedCollectionIds, revealedDataMaps, err := cmdUtils.MakeBlock(client, blockNumber, epoch, types.Rogue{IsRogue: false})
236-
if err != nil {
237-
log.Error("Error in calculating block medians")
238-
return types.ProposeFileData{}, err
239-
}
240-
log.Debug("Updating global proposed data struct...")
241-
updateGlobalProposedDataStruct(types.ProposeFileData{
242-
MediansData: medians,
243-
RevealedCollectionIds: revealedCollectionIds,
244-
RevealedDataMaps: revealedDataMaps,
245-
Epoch: epoch,
246-
})
247-
log.Debugf("GetLocalMediansData: Global proposed data struct: %+v", globalProposedDataStruct)
245+
calculatedProposedData := types.ProposeFileData{
246+
MediansData: medians,
247+
RevealedCollectionIds: revealedCollectionIds,
248+
RevealedDataMaps: revealedDataMaps,
249+
Epoch: epoch,
248250
}
249251

250-
log.Debugf("Locally calculated data, Medians: %s", globalProposedDataStruct.MediansData)
251-
return globalProposedDataStruct, nil
252+
log.Debugf("Locally calculated data, Medians: %s", calculatedProposedData.MediansData)
253+
return calculatedProposedData, nil
252254
}
253255

254256
//This function check for the dispute in different type of Id's

cmd/dispute_test.go

+37-15
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,30 @@ func TestHandleDispute(t *testing.T) {
497497
},
498498
want: nil,
499499
},
500+
{
501+
name: "Test 19: When the mismatch id index is out of range",
502+
args: args{
503+
sortedProposedBlockIds: []uint32{45, 65, 23, 64, 12},
504+
biggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
505+
biggestStakeId: 2,
506+
medians: []*big.Int{big.NewInt(6901548), big.NewInt(498307)},
507+
revealedCollectionIds: []uint16{1},
508+
revealedDataMaps: &types.RevealedDataMaps{
509+
SortedRevealedValues: nil,
510+
VoteWeights: nil,
511+
InfluenceSum: nil,
512+
},
513+
proposedBlock: bindings.StructsBlock{
514+
Medians: []*big.Int{big.NewInt(6901548)},
515+
Ids: []uint16{1},
516+
Valid: true,
517+
BiggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
518+
},
519+
idDisputeTxn: nil,
520+
disputeErr: nil,
521+
},
522+
want: nil,
523+
},
500524
}
501525

502526
for _, tt := range tests {
@@ -659,7 +683,6 @@ func TestGetLocalMediansData(t *testing.T) {
659683
client *ethclient.Client
660684
account types.Account
661685
blockNumber *big.Int
662-
rogueData types.Rogue
663686
)
664687
type args struct {
665688
epoch uint32
@@ -673,8 +696,7 @@ func TestGetLocalMediansData(t *testing.T) {
673696
mediansErr error
674697
stakerId uint32
675698
stakerIdErr error
676-
lastProposedEpoch uint32
677-
lastProposedEpochErr error
699+
isRogue bool
678700
}
679701
tests := []struct {
680702
name string
@@ -720,16 +742,18 @@ func TestGetLocalMediansData(t *testing.T) {
720742
{
721743
name: "Test 4: When there is an error in getting medians",
722744
args: args{
723-
mediansErr: errors.New("error in fetching medians"),
745+
fileNameErr: errors.New("error in getting fileName"),
746+
mediansErr: errors.New("error in fetching medians"),
724747
},
725748
want: nil,
726749
want1: nil,
727750
want2: nil,
728751
wantErr: true,
729752
},
730753
{
731-
name: "Test 5: When GetLocalMediansData executes successfully",
754+
name: "Test 5: When GetLocalMediansData executes successfully when there is an error in getting file name",
732755
args: args{
756+
fileNameErr: errors.New("error in getting fileName"),
733757
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
734758
revealedCollectionIds: []uint16{1, 2, 3},
735759
revealedDataMaps: &types.RevealedDataMaps{},
@@ -742,6 +766,7 @@ func TestGetLocalMediansData(t *testing.T) {
742766
{
743767
name: "Test 6: When there is an error in getting stakerId",
744768
args: args{
769+
fileNameErr: errors.New("error in getting fileName"),
745770
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
746771
revealedCollectionIds: []uint16{1, 2, 3},
747772
revealedDataMaps: &types.RevealedDataMaps{},
@@ -753,19 +778,17 @@ func TestGetLocalMediansData(t *testing.T) {
753778
wantErr: true,
754779
},
755780
{
756-
name: "Test 7: When there is an error in getting last proposed epoch",
781+
name: "Test 7: When staker votes in rogue mode and needs to calculate median again",
757782
args: args{
783+
isRogue: true,
758784
medians: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
759785
revealedCollectionIds: []uint16{1, 2, 3},
760786
revealedDataMaps: &types.RevealedDataMaps{},
761-
stakerId: 2,
762-
epoch: 5,
763-
lastProposedEpochErr: errors.New("lastProposedEpoch error"),
764787
},
765-
want: nil,
766-
want1: nil,
767-
want2: nil,
768-
wantErr: true,
788+
want: []*big.Int{big.NewInt(100), big.NewInt(200), big.NewInt(300)},
789+
want1: []uint16{1, 2, 3},
790+
want2: &types.RevealedDataMaps{},
791+
wantErr: false,
769792
},
770793
}
771794
for _, tt := range tests {
@@ -776,9 +799,8 @@ func TestGetLocalMediansData(t *testing.T) {
776799
fileUtilsMock.On("ReadFromProposeJsonFile", mock.Anything).Return(tt.args.proposedData, tt.args.proposeDataErr)
777800
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)
778801
utilsMock.On("GetStakerId", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.stakerId, tt.args.stakerIdErr)
779-
utilsMock.On("GetEpochLastProposed", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32")).Return(tt.args.lastProposedEpoch, tt.args.lastProposedEpochErr)
780802
ut := &UtilsStruct{}
781-
localProposedData, err := ut.GetLocalMediansData(client, account, tt.args.epoch, blockNumber, rogueData)
803+
localProposedData, err := ut.GetLocalMediansData(client, account, tt.args.epoch, blockNumber, types.Rogue{IsRogue: tt.args.isRogue})
782804
if (err != nil) != tt.wantErr {
783805
t.Errorf("GetLocalMediansData() error = %v, wantErr %v", err, tt.wantErr)
784806
return

utils/api_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func getAPIByteArray(index int) []byte {
3030

3131
func TestGetDataFromAPI(t *testing.T) {
3232
//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"}}`
33-
sampleChainId, _ := hex.DecodeString("7b226964223a302c226a736f6e727063223a22322e30222c22726573756c74223a2230783561373963343465227d")
33+
sampleChainId, _ := hex.DecodeString("7b226a736f6e727063223a22322e30222c22726573756c74223a223078616133376463222c226964223a307d0a")
3434

3535
type args struct {
3636
urlStruct types.DataSourceURL
@@ -108,7 +108,7 @@ func TestGetDataFromAPI(t *testing.T) {
108108
args: args{
109109
urlStruct: types.DataSourceURL{
110110
Type: "POST",
111-
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
111+
URL: "https://sepolia.optimism.io",
112112
Body: map[string]interface{}{"jsonrpc": "2.0", "method": "eth_chainId", "params": nil, "id": 0},
113113
Header: map[string]string{"content-type": "application/json"},
114114
},
@@ -120,7 +120,7 @@ func TestGetDataFromAPI(t *testing.T) {
120120
args: args{
121121
urlStruct: types.DataSourceURL{
122122
Type: "POST",
123-
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
123+
URL: "https://sepolia.optimism.io",
124124
Body: map[string]interface{}{"jsonrpc": "2.0", "method": "eth_chainId", "params": nil, "id": 0},
125125
Header: map[string]string{"auth": "${API_KEY}", "content-type": "application/json"},
126126
},
@@ -132,7 +132,7 @@ func TestGetDataFromAPI(t *testing.T) {
132132
args: args{
133133
urlStruct: types.DataSourceURL{
134134
Type: "POST",
135-
URL: "https://staging-v3.skalenodes.com/v1/staging-aware-chief-gianfar",
135+
URL: "https://sepolia.optimism.io",
136136
Body: map[string]interface{}{"fail": func() {}, "jsonrpc": 1},
137137
},
138138
},
@@ -144,7 +144,7 @@ func TestGetDataFromAPI(t *testing.T) {
144144
args: args{
145145
urlStruct: types.DataSourceURL{
146146
Type: "",
147-
URL: "https://jsonplaceholder.typicode.com/todos/1",
147+
URL: "https://sepolia.optimism.io",
148148
},
149149
},
150150
want: nil,

0 commit comments

Comments
 (0)