diff --git a/x/emissions/keeper/inference_synthesis/network_inferences_test.go b/x/emissions/keeper/inference_synthesis/network_inferences_test.go index 5b2391d72..abb3d72d7 100644 --- a/x/emissions/keeper/inference_synthesis/network_inferences_test.go +++ b/x/emissions/keeper/inference_synthesis/network_inferences_test.go @@ -1274,3 +1274,197 @@ func TestSelectTopNWorkerNonces(t *testing.T) { }) } } + +func (s *InferenceSynthesisTestSuite) TestCalcNetworkInferencesTwoWorkerTwoForecasters() { + k := s.emissionsKeeper + ctx := s.ctx + topicId := uint64(1) + + worker1 := "worker1" + worker2 := "worker2" + worker3 := "worker3" + worker4 := "worker4" + worker1Add := sdk.AccAddress(worker1) + worker2Add := sdk.AccAddress(worker2) + worker3Add := sdk.AccAddress(worker3) + worker4Add := sdk.AccAddress(worker4) + + // Set up input data + inferences := &emissions.Inferences{ + Inferences: []*emissions.Inference{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.5")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.7")}, + }, + } + + forecasts := &emissions.Forecasts{ + Forecasts: []*emissions.Forecast{ + { + Forecaster: worker3, + ForecastElements: []*emissions.ForecastElement{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.6")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.8")}, + }, + }, + { + Forecaster: worker4, + ForecastElements: []*emissions.ForecastElement{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.4")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.9")}, + }, + }, + }, + } + + networkCombinedLoss := alloraMath.MustNewDecFromString("0.2") + epsilon := alloraMath.MustNewDecFromString("0.001") + pInferenceSynthesis := alloraMath.MustNewDecFromString("2") + + // Set inferer network regrets + err := k.SetInfererNetworkRegret(ctx, topicId, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.2")}) + s.Require().NoError(err) + err = k.SetInfererNetworkRegret(ctx, topicId, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.3")}) + s.Require().NoError(err) + + // Set forecaster network regrets + err = k.SetForecasterNetworkRegret(ctx, topicId, worker3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.4")}) + s.Require().NoError(err) + err = k.SetForecasterNetworkRegret(ctx, topicId, worker4Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.5")}) + s.Require().NoError(err) + + // Set one-in forecaster network regrets + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, worker3Add, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.2")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, worker3Add, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.3")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, worker4Add, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.6")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, worker4Add, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.4")}) + s.Require().NoError(err) + + // Call the function + valueBundle, err := inference_synthesis.CalcNetworkInferences(ctx, k, topicId, inferences, forecasts, networkCombinedLoss, epsilon, pInferenceSynthesis) + s.Require().NoError(err) + + // Check the results + s.Require().NotNil(valueBundle) + s.Require().NotNil(valueBundle.CombinedValue) + s.Require().NotNil(valueBundle.NaiveValue) + + s.Require().Len(valueBundle.OneOutInfererValues, 2) + s.Require().Len(valueBundle.OneOutForecasterValues, 2) + s.Require().Len(valueBundle.OneInForecasterValues, 2) +} + +func (s *InferenceSynthesisTestSuite) TestCalcNetworkInferencesThreeWorkerThreeForecasters() { + k := s.emissionsKeeper + ctx := s.ctx + topicId := uint64(1) + + worker1 := "worker1" + worker2 := "worker2" + worker3 := "worker3" + worker1Add := sdk.AccAddress(worker1) + worker2Add := sdk.AccAddress(worker2) + worker3Add := sdk.AccAddress(worker3) + + forecaster1 := "forecaster1" + forecaster2 := "forecaster2" + forecaster3 := "forecaster3" + forecaster1Add := sdk.AccAddress(forecaster1) + forecaster2Add := sdk.AccAddress(forecaster2) + forecaster3Add := sdk.AccAddress(forecaster3) + + // Set up input data + inferences := &emissions.Inferences{ + Inferences: []*emissions.Inference{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.1")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.2")}, + {Inferer: worker3, Value: alloraMath.MustNewDecFromString("0.3")}, + }, + } + + forecasts := &emissions.Forecasts{ + Forecasts: []*emissions.Forecast{ + { + Forecaster: forecaster1, + ForecastElements: []*emissions.ForecastElement{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.4")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.5")}, + {Inferer: worker3, Value: alloraMath.MustNewDecFromString("0.6")}, + }, + }, + { + Forecaster: forecaster2, + ForecastElements: []*emissions.ForecastElement{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.7")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.8")}, + {Inferer: worker3, Value: alloraMath.MustNewDecFromString("0.9")}, + }, + }, + { + Forecaster: forecaster3, + ForecastElements: []*emissions.ForecastElement{ + {Inferer: worker1, Value: alloraMath.MustNewDecFromString("0.1")}, + {Inferer: worker2, Value: alloraMath.MustNewDecFromString("0.2")}, + {Inferer: worker3, Value: alloraMath.MustNewDecFromString("0.3")}, + }, + }, + }, + } + + networkCombinedLoss := alloraMath.MustNewDecFromString("0.3") + epsilon := alloraMath.MustNewDecFromString("0.001") + pInferenceSynthesis := alloraMath.MustNewDecFromString("2") + + // Set inferer network regrets + err := k.SetInfererNetworkRegret(ctx, topicId, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.1")}) + s.Require().NoError(err) + err = k.SetInfererNetworkRegret(ctx, topicId, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.2")}) + s.Require().NoError(err) + err = k.SetInfererNetworkRegret(ctx, topicId, worker3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.3")}) + s.Require().NoError(err) + + // Set forecaster network regrets + err = k.SetForecasterNetworkRegret(ctx, topicId, forecaster1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.4")}) + s.Require().NoError(err) + err = k.SetForecasterNetworkRegret(ctx, topicId, forecaster2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.5")}) + s.Require().NoError(err) + err = k.SetForecasterNetworkRegret(ctx, topicId, forecaster3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.6")}) + s.Require().NoError(err) + + // Set one-in forecaster network regrets + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster1Add, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.7")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster1Add, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.8")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster1Add, worker3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.9")}) + s.Require().NoError(err) + + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster2Add, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.1")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster2Add, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.2")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster2Add, worker3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.3")}) + s.Require().NoError(err) + + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster3Add, worker1Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.4")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster3Add, worker2Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.5")}) + s.Require().NoError(err) + err = k.SetOneInForecasterNetworkRegret(ctx, topicId, forecaster3Add, worker3Add, emissions.TimestampedValue{Value: alloraMath.MustNewDecFromString("0.6")}) + s.Require().NoError(err) + + // Call the function + valueBundle, err := inference_synthesis.CalcNetworkInferences(ctx, k, topicId, inferences, forecasts, networkCombinedLoss, epsilon, pInferenceSynthesis) + s.Require().NoError(err) + + // Check the results + s.Require().NotNil(valueBundle) + s.Require().NotNil(valueBundle.CombinedValue) + s.Require().NotNil(valueBundle.NaiveValue) + + s.Require().Len(valueBundle.OneOutInfererValues, 3) + s.Require().Len(valueBundle.OneOutForecasterValues, 3) + s.Require().Len(valueBundle.OneInForecasterValues, 3) +} diff --git a/x/emissions/keeper/inference_synthesis/network_losses_test.go b/x/emissions/keeper/inference_synthesis/network_losses_test.go index c8a197ba8..4bc746a07 100644 --- a/x/emissions/keeper/inference_synthesis/network_losses_test.go +++ b/x/emissions/keeper/inference_synthesis/network_losses_test.go @@ -192,8 +192,117 @@ func (s *InferenceSynthesisTestSuite) TestCalcCombinedNetworkLoss() { } } -func (s *InferenceSynthesisTestSuite) TestCalcNetworkLosses() { - tests := []struct { +func getTestCasesOneWorker() []struct { + name string + stakesByReputer map[inference_synthesis.Worker]cosmosMath.Uint + reportedLosses emissions.ReputerValueBundles + epsilon alloraMath.Dec + expectedOutput emissions.ValueBundle + expectedError error +} { + return []struct { + name string + stakesByReputer map[inference_synthesis.Worker]cosmosMath.Uint + reportedLosses emissions.ReputerValueBundles + epsilon alloraMath.Dec + expectedOutput emissions.ValueBundle + expectedError error + }{ + { + name: "simple one reputer combined loss", + stakesByReputer: map[inference_synthesis.Worker]cosmosMath.Uint{ + "worker1": inference_synthesis.CosmosUintOneE18(), // 1 token + }, + reportedLosses: emissions.ReputerValueBundles{ + ReputerValueBundles: []*emissions.ReputerValueBundle{ + { + ValueBundle: &emissions.ValueBundle{ + Reputer: "worker1", + CombinedValue: alloraMath.MustNewDecFromString("0.1"), + NaiveValue: alloraMath.MustNewDecFromString("0.1"), + InfererValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1"), + }, + }, + ForecasterValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1"), + }, + }, + OneOutInfererValues: []*emissions.WithheldWorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1"), + }, + }, + OneOutForecasterValues: []*emissions.WithheldWorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1"), + }, + }, + OneInForecasterValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1"), + }, + }, + }, + }, + }, + }, + epsilon: alloraMath.MustNewDecFromString("1e-4"), + expectedOutput: emissions.ValueBundle{ + CombinedValue: alloraMath.MustNewDecFromString("0.1587401051968199"), + NaiveValue: alloraMath.MustNewDecFromString("0.1587401051968199"), + InfererValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1587401051968199"), + }, + }, + ForecasterValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1587401051968199"), + }, + }, + OneOutInfererValues: []*emissions.WithheldWorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1587401051968199"), + }, + }, + OneOutForecasterValues: []*emissions.WithheldWorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1587401051968199"), + }, + }, + OneInForecasterValues: []*emissions.WorkerAttributedValue{ + { + Worker: "worker1", + Value: alloraMath.MustNewDecFromString("0.1587401051968199"), + }, + }, + }, + expectedError: nil, + }, + } +} + +func getTestCasesTwoWorkers() []struct { + name string + stakesByReputer map[inference_synthesis.Worker]cosmosMath.Uint + reportedLosses emissions.ReputerValueBundles + epsilon alloraMath.Dec + expectedOutput emissions.ValueBundle + expectedError error +} { + return []struct { name string stakesByReputer map[inference_synthesis.Worker]cosmosMath.Uint reportedLosses emissions.ReputerValueBundles @@ -383,6 +492,10 @@ func (s *InferenceSynthesisTestSuite) TestCalcNetworkLosses() { expectedError: nil, }, } +} + +func (s *InferenceSynthesisTestSuite) TestCalcNetworkLosses() { + tests := getTestCasesTwoWorkers() require := s.Require() @@ -432,3 +545,28 @@ func (s *InferenceSynthesisTestSuite) TestCalcNetworkLosses() { }) } } + +func (s *InferenceSynthesisTestSuite) TestCalcNetworkLossesCombined() { + tests := append(getTestCasesOneWorker(), getTestCasesTwoWorkers()...) + + require := s.Require() + + for _, tc := range tests { + s.Run(tc.name, func() { + output, err := inference_synthesis.CalcNetworkLosses(tc.stakesByReputer, tc.reportedLosses, tc.epsilon) + if tc.expectedError != nil { + require.Error(err) + require.EqualError(err, tc.expectedError.Error()) + } else { + require.NoError(err) + + // Verify the length of each attribute in the ValueBundle + require.Len(output.InfererValues, len(tc.expectedOutput.InfererValues), "Mismatch in number of InfererValues") + require.Len(output.ForecasterValues, len(tc.expectedOutput.ForecasterValues), "Mismatch in number of ForecasterValues") + require.Len(output.OneInForecasterValues, len(tc.expectedOutput.OneInForecasterValues), "Mismatch in number of OneInForecasterValues") + require.Len(output.OneOutInfererValues, len(tc.expectedOutput.OneOutInfererValues), "Mismatch in number of OneOutInfererValues") + require.Len(output.OneOutForecasterValues, len(tc.expectedOutput.OneOutForecasterValues), "Mismatch in number of OneOutForecasterValues") + } + }) + } +} diff --git a/x/emissions/keeper/inference_synthesis/network_regrets_test.go b/x/emissions/keeper/inference_synthesis/network_regrets_test.go index cfd7409ff..0cfcb92e2 100644 --- a/x/emissions/keeper/inference_synthesis/network_regrets_test.go +++ b/x/emissions/keeper/inference_synthesis/network_regrets_test.go @@ -75,23 +75,32 @@ func (s *InferenceSynthesisTestSuite) TestComputeAndBuildEMRegret() { require.Equal(blockHeight, result.BlockHeight) } -func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegrets() { +func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegretsTwoWorkers() { require := s.Require() k := s.emissionsKeeper + + worker1 := "worker1" + worker2 := "worker2" + worker3 := "worker3" + + worker1Acc := sdk.AccAddress(worker1) + worker2Acc := sdk.AccAddress(worker2) + worker3Acc := sdk.AccAddress(worker3) + valueBundle := types.ValueBundle{ CombinedValue: alloraMath.MustNewDecFromString("500"), NaiveValue: alloraMath.MustNewDecFromString("123"), InfererValues: []*types.WorkerAttributedValue{ - {Worker: "worker1", Value: alloraMath.MustNewDecFromString("200")}, - {Worker: "worker2", Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, }, ForecasterValues: []*types.WorkerAttributedValue{ - {Worker: "worker1", Value: alloraMath.MustNewDecFromString("200")}, - {Worker: "worker2", Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, }, OneInForecasterValues: []*types.WorkerAttributedValue{ - {Worker: "worker1", Value: alloraMath.MustNewDecFromString("200")}, - {Worker: "worker2", Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, }, } blockHeight := int64(42) @@ -104,17 +113,14 @@ func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegrets() { Value: alloraMath.MustNewDecFromString("200"), } - acc1 := sdk.AccAddress("worker1") - acc2 := sdk.AccAddress("worker2") - - k.SetInfererNetworkRegret(s.ctx, topicId, acc1, timestampedValue) - k.SetInfererNetworkRegret(s.ctx, topicId, acc2, timestampedValue) - k.SetForecasterNetworkRegret(s.ctx, topicId, acc1, timestampedValue) - k.SetForecasterNetworkRegret(s.ctx, topicId, acc2, timestampedValue) - k.SetOneInForecasterNetworkRegret(s.ctx, topicId, acc1, acc1, timestampedValue) - k.SetOneInForecasterNetworkRegret(s.ctx, topicId, acc1, acc2, timestampedValue) - k.SetOneInForecasterNetworkRegret(s.ctx, topicId, acc2, acc1, timestampedValue) - k.SetOneInForecasterNetworkRegret(s.ctx, topicId, acc2, acc2, timestampedValue) + k.SetInfererNetworkRegret(s.ctx, topicId, worker1Acc, timestampedValue) + k.SetInfererNetworkRegret(s.ctx, topicId, worker2Acc, timestampedValue) + k.SetForecasterNetworkRegret(s.ctx, topicId, worker1Acc, timestampedValue) + k.SetForecasterNetworkRegret(s.ctx, topicId, worker2Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker1Acc, worker1Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker1Acc, worker2Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker2Acc, worker1Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker2Acc, worker2Acc, timestampedValue) err := inference_synthesis.GetCalcSetNetworkRegrets( s.ctx, @@ -126,10 +132,35 @@ func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegrets() { ) require.NoError(err) - bothAccs := []sdk.AccAddress{acc1, acc2} + bothAccs := []sdk.AccAddress{worker1Acc, worker2Acc} expected := alloraMath.MustNewDecFromString("210") expectedOneIn := alloraMath.MustNewDecFromString("180") + worker3LastRegret, worker3NoPriorRegret, err := k.GetInfererNetworkRegret(s.ctx, topicId, worker3Acc) + require.NoError(err) + require.Equal(worker3LastRegret.Value, alloraMath.ZeroDec()) + require.True(worker3NoPriorRegret) + + worker3LastRegret, worker3NoPriorRegret, err = k.GetForecasterNetworkRegret(s.ctx, topicId, worker3Acc) + require.NoError(err) + require.Equal(worker3LastRegret.Value, alloraMath.ZeroDec()) + require.True(worker3NoPriorRegret) + + worker3LastRegret, worker3NoPriorRegret, err = k.GetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker1Acc) + require.NoError(err) + require.Equal(worker3LastRegret.Value, alloraMath.ZeroDec()) + require.True(worker3NoPriorRegret) + + worker3LastRegret, worker3NoPriorRegret, err = k.GetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker2Acc) + require.NoError(err) + require.Equal(worker3LastRegret.Value, alloraMath.ZeroDec()) + require.True(worker3NoPriorRegret) + + worker3LastRegret, worker3NoPriorRegret, err = k.GetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker3Acc) + require.NoError(err) + require.Equal(worker3LastRegret.Value, alloraMath.ZeroDec()) + require.True(worker3NoPriorRegret) + for _, acc := range bothAccs { lastRegret, noPriorRegret, err := k.GetInfererNetworkRegret(s.ctx, topicId, acc) require.NoError(err) @@ -149,3 +180,96 @@ func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegrets() { } } } + +func (s *InferenceSynthesisTestSuite) TestGetCalcSetNetworkRegretsThreeWorkers() { + require := s.Require() + k := s.emissionsKeeper + + worker1 := "worker1" + worker2 := "worker2" + worker3 := "worker3" + + worker1Acc := sdk.AccAddress(worker1) + worker2Acc := sdk.AccAddress(worker2) + worker3Acc := sdk.AccAddress(worker3) + + valueBundle := types.ValueBundle{ + CombinedValue: alloraMath.MustNewDecFromString("500"), + NaiveValue: alloraMath.MustNewDecFromString("123"), + InfererValues: []*types.WorkerAttributedValue{ + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker3, Value: alloraMath.MustNewDecFromString("200")}, + }, + ForecasterValues: []*types.WorkerAttributedValue{ + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker3, Value: alloraMath.MustNewDecFromString("200")}, + }, + OneInForecasterValues: []*types.WorkerAttributedValue{ + {Worker: worker1, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker2, Value: alloraMath.MustNewDecFromString("200")}, + {Worker: worker3, Value: alloraMath.MustNewDecFromString("200")}, + }, + } + blockHeight := int64(42) + nonce := types.Nonce{BlockHeight: blockHeight} + alpha := alloraMath.MustNewDecFromString("0.1") + topicId := uint64(1) + + timestampedValue := types.TimestampedValue{ + BlockHeight: blockHeight, + Value: alloraMath.MustNewDecFromString("200"), + } + + k.SetInfererNetworkRegret(s.ctx, topicId, worker1Acc, timestampedValue) + k.SetInfererNetworkRegret(s.ctx, topicId, worker2Acc, timestampedValue) + k.SetInfererNetworkRegret(s.ctx, topicId, worker3Acc, timestampedValue) + + k.SetForecasterNetworkRegret(s.ctx, topicId, worker1Acc, timestampedValue) + k.SetForecasterNetworkRegret(s.ctx, topicId, worker2Acc, timestampedValue) + k.SetForecasterNetworkRegret(s.ctx, topicId, worker2Acc, timestampedValue) + + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker1Acc, worker1Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker1Acc, worker2Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker1Acc, worker3Acc, timestampedValue) + + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker2Acc, worker1Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker2Acc, worker2Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker2Acc, worker3Acc, timestampedValue) + + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker1Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker2Acc, timestampedValue) + k.SetOneInForecasterNetworkRegret(s.ctx, topicId, worker3Acc, worker3Acc, timestampedValue) + + err := inference_synthesis.GetCalcSetNetworkRegrets( + s.ctx, + s.emissionsKeeper, + topicId, + valueBundle, + nonce, + alpha, + ) + require.NoError(err) + + allWorkerAccs := []sdk.AccAddress{worker1Acc, worker2Acc, worker3Acc} + expected := alloraMath.MustNewDecFromString("210") + // expectedOneIn := alloraMath.MustNewDecFromString("180") + + for _, workerAcc := range allWorkerAccs { + lastRegret, noPriorRegret, err := k.GetInfererNetworkRegret(s.ctx, topicId, workerAcc) + require.NoError(err) + require.True(alloraMath.InDelta(expected, lastRegret.Value, alloraMath.MustNewDecFromString("0.0001"))) + require.False(noPriorRegret) + + lastRegret, noPriorRegret, err = k.GetForecasterNetworkRegret(s.ctx, topicId, workerAcc) + require.NoError(err) + require.False(noPriorRegret) + + for _, innerWorkerAcc := range allWorkerAccs { + lastRegret, noPriorRegret, err = k.GetOneInForecasterNetworkRegret(s.ctx, topicId, workerAcc, innerWorkerAcc) + require.NoError(err) + require.False(noPriorRegret) + } + } +}