Skip to content

Commit 2e111b3

Browse files
authored
Rogue mode on biggestStakerId (#819)
* Changed rogue implemenattion for biggestStakerId * Added a nil error check * Fixed tests
1 parent 2c05d12 commit 2e111b3

File tree

5 files changed

+207
-25
lines changed

5 files changed

+207
-25
lines changed

cmd/dispute.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,9 @@ func (*UtilsStruct) ResetDispute(client *ethclient.Client, blockManager *binding
432432
log.Info("Transaction hash: ", transactionUtils.Hash(txn))
433433
log.Info("Dispute has been reset")
434434
err = razorUtils.WaitForBlockCompletion(client, transactionUtils.Hash(txn).String())
435-
log.Error("Error in WaitForBlockCompletion for resetDispute: ", err)
436-
435+
if err != nil {
436+
log.Error("Error in WaitForBlockCompletion for resetDispute: ", err)
437+
}
437438
}
438439

439440
//This function returns the bountyId from events

cmd/interface.go

+1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ type UtilsCmdInterface interface {
307307
ExecuteUpdateCommission(flagSet *pflag.FlagSet)
308308
UpdateCommission(config types.Configurations, client *ethclient.Client, updateCommissionInput types.UpdateCommissionInput) error
309309
GetBiggestStakeAndId(client *ethclient.Client, address string, epoch uint32) (*big.Int, uint32, error)
310+
GetSmallestStakeAndId(client *ethclient.Client, epoch uint32) (*big.Int, uint32, error)
310311
StakeCoins(txnArgs types.TransactionOptions) (common.Hash, error)
311312
CalculateSecret(account types.Account, epoch uint32, keystorePath string, chainId *big.Int) ([]byte, []byte, error)
312313
GetLastProposedEpoch(client *ethclient.Client, blockNumber *big.Int, stakerId uint32) (uint32, error)

cmd/mocks/utils_cmd_interface.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/propose.go

+35-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
package cmd
33

44
import (
5-
"crypto/rand"
65
"encoding/hex"
76
"errors"
87
"github.com/ethereum/go-ethereum/common"
@@ -52,9 +51,14 @@ func (*UtilsStruct) Propose(client *ethclient.Client, config types.Configuration
5251
)
5352

5453
if rogueData.IsRogue && utils.Contains(rogueData.RogueMode, "biggestStakerId") {
55-
biggestStake = utils.GetRogueRandomValue(1000000)
56-
biggestStakerIdInBigInt, _ := rand.Int(rand.Reader, big.NewInt(int64(numStakers)))
57-
biggestStakerId = uint32(biggestStakerIdInBigInt.Int64())
54+
// If staker is going rogue with biggestStakerId than we do biggestStakerId = smallestStakerId
55+
smallestStake, smallestStakerId, smallestStakerErr := cmdUtils.GetSmallestStakeAndId(client, epoch)
56+
if smallestStakerErr != nil {
57+
log.Error("Error in calculating smallest staker: ", smallestStakerErr)
58+
return core.NilHash, smallestStakerErr
59+
}
60+
biggestStake = smallestStake
61+
biggestStakerId = smallestStakerId
5862
} else {
5963
biggestStake, biggestStakerId, biggestStakerErr = cmdUtils.GetBiggestStakeAndId(client, account.Address, epoch)
6064
if biggestStakerErr != nil {
@@ -174,6 +178,9 @@ func (*UtilsStruct) GetBiggestStakeAndId(client *ethclient.Client, address strin
174178
if err != nil {
175179
return nil, 0, err
176180
}
181+
if numberOfStakers == 0 {
182+
return nil, 0, errors.New("numberOfStakers is 0")
183+
}
177184
var biggestStakerId uint32
178185
biggestStake := big.NewInt(0)
179186

@@ -376,3 +383,27 @@ func (*UtilsStruct) InfluencedMedian(sortedVotes []*big.Int, totalInfluenceRevea
376383
}
377384
return accProd.Div(accProd, totalInfluenceRevealed)
378385
}
386+
387+
func (*UtilsStruct) GetSmallestStakeAndId(client *ethclient.Client, epoch uint32) (*big.Int, uint32, error) {
388+
numberOfStakers, err := razorUtils.GetNumberOfStakers(client)
389+
if err != nil {
390+
return nil, 0, err
391+
}
392+
if numberOfStakers == 0 {
393+
return nil, 0, errors.New("numberOfStakers is 0")
394+
}
395+
var smallestStakerId uint32
396+
smallestStake := big.NewInt(1).Mul(big.NewInt(1e18), big.NewInt(1e18))
397+
398+
for i := 1; i <= int(numberOfStakers); i++ {
399+
stake, err := razorUtils.GetStakeSnapshot(client, uint32(i), epoch)
400+
if err != nil {
401+
return nil, 0, err
402+
}
403+
if stake.Cmp(smallestStake) < 0 {
404+
smallestStake = stake
405+
smallestStakerId = uint32(i)
406+
}
407+
}
408+
return smallestStake, smallestStakerId, nil
409+
}

cmd/propose_test.go

+138-19
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ func TestPropose(t *testing.T) {
5151
biggestStake *big.Int
5252
biggestStakerId uint32
5353
biggestStakerIdErr error
54+
smallestStake *big.Int
55+
smallestStakerId uint32
56+
smallestStakerIdErr error
5457
randaoHash [32]byte
5558
randaoHashErr error
5659
bufferPercent int32
@@ -431,7 +434,7 @@ func TestPropose(t *testing.T) {
431434
wantErr: errors.New("buffer error"),
432435
},
433436
{
434-
name: "Test 18: When rogue mode is on for biggestStakerId Propose function executes successfully",
437+
name: "Test 18: When rogue mode is on for biggestStakerId and propose exceutes successfully",
435438
args: args{
436439
rogueData: types.Rogue{
437440
IsRogue: true,
@@ -442,6 +445,8 @@ func TestPropose(t *testing.T) {
442445
numStakers: 5,
443446
biggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
444447
biggestStakerId: 2,
448+
smallestStake: big.NewInt(1000),
449+
smallestStakerId: 1,
445450
salt: saltBytes32,
446451
iteration: 1,
447452
numOfProposedBlocks: 3,
@@ -456,6 +461,33 @@ func TestPropose(t *testing.T) {
456461
want: common.BigToHash(big.NewInt(1)),
457462
wantErr: nil,
458463
},
464+
{
465+
name: "Test 19: When rogue mode is on for biggestStakerId and there is an error in getting smallestStakerId",
466+
args: args{
467+
rogueData: types.Rogue{
468+
IsRogue: true,
469+
RogueMode: []string{"biggestStakerId"},
470+
},
471+
state: 2,
472+
staker: bindings.StructsStaker{},
473+
numStakers: 5,
474+
biggestStake: big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18)),
475+
biggestStakerId: 2,
476+
smallestStakerIdErr: errors.New("smallestStakerId error"),
477+
salt: saltBytes32,
478+
iteration: 1,
479+
numOfProposedBlocks: 3,
480+
maxAltBlocks: 4,
481+
lastIteration: big.NewInt(5),
482+
lastProposedBlockStruct: bindings.StructsBlock{},
483+
medians: []*big.Int{big.NewInt(6701548), big.NewInt(478307)},
484+
txnOpts: txnOpts,
485+
proposeTxn: &Types.Transaction{},
486+
hash: common.BigToHash(big.NewInt(1)),
487+
},
488+
want: core.NilHash,
489+
wantErr: errors.New("smallestStakerId error"),
490+
},
459491
}
460492
for _, tt := range tests {
461493

@@ -472,6 +504,7 @@ func TestPropose(t *testing.T) {
472504
utilsMock.On("GetDelayedState", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("int32")).Return(tt.args.state, tt.args.stateErr)
473505
utilsMock.On("GetNumberOfStakers", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.numStakers, tt.args.numStakerErr)
474506
cmdUtilsMock.On("GetBiggestStakeAndId", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string"), mock.AnythingOfType("uint32")).Return(tt.args.biggestStake, tt.args.biggestStakerId, tt.args.biggestStakerIdErr)
507+
cmdUtilsMock.On("GetSmallestStakeAndId", mock.Anything, mock.Anything).Return(tt.args.smallestStake, tt.args.smallestStakerId, tt.args.smallestStakerIdErr)
475508
utilsMock.On("GetRandaoHash", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.randaoHash, tt.args.randaoHashErr)
476509
cmdUtilsMock.On("GetIteration", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.iteration)
477510
utilsMock.On("GetMaxAltBlocks", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.maxAltBlocks, tt.args.maxAltBlocksErr)
@@ -520,7 +553,7 @@ func TestGetBiggestStakeAndId(t *testing.T) {
520553
bufferPercentErr error
521554
remainingTime int64
522555
remainingTimeErr error
523-
stake []*big.Int
556+
stake *big.Int
524557
stakeErr error
525558
}
526559
tests := []struct {
@@ -535,29 +568,26 @@ func TestGetBiggestStakeAndId(t *testing.T) {
535568
args: args{
536569
numOfStakers: 2,
537570
remainingTime: 10,
538-
stake: []*big.Int{big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)), big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18))},
571+
stake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
539572
},
540573
wantStake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
541574
wantId: 1,
542575
wantErr: nil,
543576
},
544577
{
545-
name: "Test 2: When getBiggestStakeAndId function executes successfully with more number of stakers",
578+
name: "Test 2: When numOfStakers is 0",
546579
args: args{
547-
numOfStakers: 5,
548-
remainingTime: 10,
549-
stake: []*big.Int{big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)), big.NewInt(1).Mul(big.NewInt(32432), big.NewInt(1e18)), big.NewInt(1).Mul(big.NewInt(32), big.NewInt(1e18)), big.NewInt(1e18), big.NewInt(1e10)},
580+
numOfStakers: 0,
550581
},
551-
wantStake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
552-
wantId: 1,
553-
wantErr: nil,
582+
wantStake: nil,
583+
wantId: 0,
584+
wantErr: errors.New("numberOfStakers is 0"),
554585
},
555586
{
556587
name: "Test 3: When there is an error in getting numOfStakers",
557588
args: args{
558589
numOfStakersErr: errors.New("numOfStakers error"),
559590
remainingTime: 10,
560-
stake: []*big.Int{big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18))},
561591
},
562592
wantStake: nil,
563593
wantId: 0,
@@ -589,8 +619,9 @@ func TestGetBiggestStakeAndId(t *testing.T) {
589619
name: "Test 6: When there is a timeout case",
590620
args: args{
591621
numOfStakers: 100000,
592-
remainingTime: 1,
593-
stake: []*big.Int{big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)), big.NewInt(1).Mul(big.NewInt(5356), big.NewInt(1e18))},
622+
bufferPercent: 10,
623+
remainingTime: 0,
624+
stake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
594625
},
595626
wantStake: nil,
596627
wantId: 0,
@@ -619,12 +650,6 @@ func TestGetBiggestStakeAndId(t *testing.T) {
619650
cmdUtils = cmdUtilsMock
620651

621652
utilsMock.On("GetNumberOfStakers", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.numOfStakers, tt.args.numOfStakersErr)
622-
if tt.args.stake != nil {
623-
utilsMock.On("GetStakeSnapshot", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32"), mock.AnythingOfType("uint32")).Return(tt.args.stake[uint32(0)], tt.args.stakeErr)
624-
} else {
625-
utilsMock.On("GetStakeSnapshot", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32"), mock.AnythingOfType("uint32")).Return(nil, tt.args.stakeErr)
626-
627-
}
628653
utilsMock.On("GetStakeSnapshot", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32"), mock.AnythingOfType("uint32")).Return(tt.args.stake, tt.args.stakeErr)
629654
utilsPkgMock.On("GetRemainingTimeOfCurrentState", mock.Anything, mock.Anything).Return(tt.args.remainingTime, tt.args.remainingTimeErr)
630655
cmdUtilsMock.On("GetBufferPercent").Return(tt.args.bufferPercent, tt.args.bufferPercentErr)
@@ -1153,6 +1178,100 @@ func TestGetSortedRevealedValues(t *testing.T) {
11531178
}
11541179
}
11551180

1181+
func TestGetSmallestStakeAndId(t *testing.T) {
1182+
var client *ethclient.Client
1183+
var epoch uint32
1184+
1185+
type args struct {
1186+
numOfStakers uint32
1187+
numOfStakersErr error
1188+
stake *big.Int
1189+
stakeErr error
1190+
}
1191+
tests := []struct {
1192+
name string
1193+
args args
1194+
wantStake *big.Int
1195+
wantId uint32
1196+
wantErr error
1197+
}{
1198+
{
1199+
name: "Test 1: When GetSmallestStakeAndId function executes successfully",
1200+
args: args{
1201+
numOfStakers: 4,
1202+
stake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
1203+
},
1204+
wantStake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
1205+
wantId: 1,
1206+
wantErr: nil,
1207+
},
1208+
{
1209+
name: "Test 2: When the numberOfStakers is 0",
1210+
args: args{
1211+
numOfStakers: 0,
1212+
stake: big.NewInt(1).Mul(big.NewInt(5326), big.NewInt(1e18)),
1213+
},
1214+
wantStake: nil,
1215+
wantId: 0,
1216+
wantErr: errors.New("numberOfStakers is 0"),
1217+
},
1218+
{
1219+
name: "Test 3: When there is an error in getting numOfStakers",
1220+
args: args{
1221+
numOfStakersErr: errors.New("numOfStakers error"),
1222+
},
1223+
wantStake: nil,
1224+
wantId: 0,
1225+
wantErr: errors.New("numOfStakers error"),
1226+
},
1227+
{
1228+
name: "Test 4: When there is an error in getting stake",
1229+
args: args{
1230+
numOfStakers: 5,
1231+
stakeErr: errors.New("stake error"),
1232+
},
1233+
wantStake: nil,
1234+
wantId: 0,
1235+
wantErr: errors.New("stake error"),
1236+
},
1237+
}
1238+
for _, tt := range tests {
1239+
t.Run(tt.name, func(t *testing.T) {
1240+
1241+
utilsMock := new(mocks.UtilsInterface)
1242+
cmdUtilsMock := new(mocks.UtilsCmdInterface)
1243+
utilsPkgMock := new(Mocks.Utils)
1244+
1245+
razorUtils = utilsMock
1246+
utilsInterface = utilsPkgMock
1247+
cmdUtils = cmdUtilsMock
1248+
1249+
utilsMock.On("GetNumberOfStakers", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("string")).Return(tt.args.numOfStakers, tt.args.numOfStakersErr)
1250+
utilsMock.On("GetStakeSnapshot", mock.AnythingOfType("*ethclient.Client"), mock.AnythingOfType("uint32"), mock.AnythingOfType("uint32")).Return(tt.args.stake, tt.args.stakeErr)
1251+
1252+
utils := &UtilsStruct{}
1253+
1254+
gotStake, gotId, err := utils.GetSmallestStakeAndId(client, epoch)
1255+
if gotStake.Cmp(tt.wantStake) != 0 {
1256+
t.Errorf("Smallest Stake from GetSmallestStakeAndId function, got = %v, want %v", gotStake, tt.wantStake)
1257+
}
1258+
if gotId != tt.wantId {
1259+
t.Errorf("Staker Id of staker having smallest Influence from GetSmallestStakeAndId function, got = %v, want %v", gotId, tt.wantId)
1260+
}
1261+
if err == nil || tt.wantErr == nil {
1262+
if err != tt.wantErr {
1263+
t.Errorf("Error for GetSmallestStakeAndId function, got = %v, want %v", err, tt.wantErr)
1264+
}
1265+
} else {
1266+
if err.Error() != tt.wantErr.Error() {
1267+
t.Errorf("Error for GetSmallestStakeAndId function, got = %v, want %v", err, tt.wantErr)
1268+
}
1269+
}
1270+
1271+
})
1272+
}
1273+
}
1274+
11561275
func BenchmarkGetIteration(b *testing.B) {
11571276
var client *ethclient.Client
11581277
var bufferPercent int32

0 commit comments

Comments
 (0)