diff --git a/api/layer/dispute/tx.pulsar.go b/api/layer/dispute/tx.pulsar.go index 6280747f2..c8ba39745 100644 --- a/api/layer/dispute/tx.pulsar.go +++ b/api/layer/dispute/tx.pulsar.go @@ -3244,7 +3244,7 @@ var file_layer_dispute_tx_proto_rawDesc = []byte{ 0x70, 0x61, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x42, 0x6f, 0x6e, 0x64, 0x3a, 0x0c, 0x82, 0xe7, 0xb0, 0x2a, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x22, 0x1c, 0x0a, 0x1a, 0x4d, 0x73, 0x67, 0x41, 0x64, 0x64, 0x46, 0x65, 0x65, 0x54, 0x6f, 0x44, 0x69, 0x73, 0x70, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x68, 0x0a, 0x07, 0x4d, 0x73, 0x67, 0x56, 0x6f, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, 0x0a, 0x07, 0x4d, 0x73, 0x67, 0x56, 0x6f, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x6f, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x04, 0x76, 0x6f, 0x74, 0x65, diff --git a/proto/layer/dispute/tx.proto b/proto/layer/dispute/tx.proto index 3756a557e..08eee7cfb 100644 --- a/proto/layer/dispute/tx.proto +++ b/proto/layer/dispute/tx.proto @@ -52,3 +52,4 @@ enum VoteEnum { VOTE_SUPPORT = 1; VOTE_AGAINST = 2; } + diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go new file mode 100644 index 000000000..8daaa4011 --- /dev/null +++ b/tests/e2e/e2e_test.go @@ -0,0 +1,778 @@ +package e2e_test + +import ( + "math/big" + "math/rand" + "strconv" + "time" + + "cosmossdk.io/math" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/tellor-io/layer/utils" + minttypes "github.com/tellor-io/layer/x/mint/types" + oraclekeeper "github.com/tellor-io/layer/x/oracle/keeper" + oracletypes "github.com/tellor-io/layer/x/oracle/types" + oracleutils "github.com/tellor-io/layer/x/oracle/utils" + reporterkeeper "github.com/tellor-io/layer/x/reporter/keeper" + reportertypes "github.com/tellor-io/layer/x/reporter/types" +) + +func (s *E2ETestSuite) TestInitialMint() { + require := s.Require() + + mintToTeamAcc := s.accountKeeper.GetModuleAddress(minttypes.MintToTeam) + require.NotNil(mintToTeamAcc) + balance := s.bankKeeper.GetBalance(s.ctx, mintToTeamAcc, s.denom) + require.Equal(balance.Amount, math.NewInt(300*1e6)) +} + +func (s *E2ETestSuite) TestTransferAfterMint() { + require := s.Require() + + mintToTeamAcc := s.accountKeeper.GetModuleAddress(minttypes.MintToTeam) + require.NotNil(mintToTeamAcc) + balance := s.bankKeeper.GetBalance(s.ctx, mintToTeamAcc, s.denom) + require.Equal(balance.Amount, math.NewInt(300*1e6)) + + // create 5 accounts + type Accounts struct { + PrivateKey secp256k1.PrivKey + Account sdk.AccAddress + } + accounts := make([]Accounts, 0, 5) + for i := 0; i < 5; i++ { + privKey := secp256k1.GenPrivKey() + accountAddress := sdk.AccAddress(privKey.PubKey().Address()) + account := authtypes.BaseAccount{ + Address: accountAddress.String(), + PubKey: codectypes.UnsafePackAny(privKey.PubKey()), + AccountNumber: uint64(i + 1), + } + existingAccount := s.accountKeeper.GetAccount(s.ctx, accountAddress) + if existingAccount == nil { + s.accountKeeper.SetAccount(s.ctx, &account) + accounts = append(accounts, Accounts{ + PrivateKey: *privKey, + Account: accountAddress, + }) + } + } + + // transfer 1000 tokens from team to all 5 accounts + for _, acc := range accounts { + startBalance := s.bankKeeper.GetBalance(s.ctx, acc.Account, s.denom).Amount + err := s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, minttypes.MintToTeam, acc.Account, sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(1000)))) + require.NoError(err) + require.Equal(startBalance.Add(math.NewInt(1000)), s.bankKeeper.GetBalance(s.ctx, acc.Account, s.denom).Amount) + } + expectedTeamBalance := math.NewInt(300*1e6 - 1000*5) + require.Equal(expectedTeamBalance, s.bankKeeper.GetBalance(s.ctx, mintToTeamAcc, s.denom).Amount) + + // transfer from account 0 to account 1 + s.bankKeeper.SendCoins(s.ctx, accounts[0].Account, accounts[1].Account, sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(1000)))) + require.Equal(math.NewInt(0), s.bankKeeper.GetBalance(s.ctx, accounts[0].Account, s.denom).Amount) + require.Equal(math.NewInt(2000), s.bankKeeper.GetBalance(s.ctx, accounts[1].Account, s.denom).Amount) + + // transfer from account 2 to team + s.bankKeeper.SendCoinsFromAccountToModule(s.ctx, accounts[2].Account, minttypes.MintToTeam, sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(1000)))) + require.Equal(math.NewInt(0), s.bankKeeper.GetBalance(s.ctx, accounts[2].Account, s.denom).Amount) + require.Equal(expectedTeamBalance.Add(math.NewInt(1000)), s.bankKeeper.GetBalance(s.ctx, mintToTeamAcc, s.denom).Amount) + + // try to transfer more than balance from account 3 to 4 + err := s.bankKeeper.SendCoins(s.ctx, accounts[3].Account, accounts[4].Account, sdk.NewCoins(sdk.NewCoin(s.denom, math.NewInt(1001)))) + require.Error(err) + require.Equal(s.bankKeeper.GetBalance(s.ctx, accounts[3].Account, s.denom).Amount, math.NewInt(1000)) + require.Equal(s.bankKeeper.GetBalance(s.ctx, accounts[4].Account, s.denom).Amount, math.NewInt(1000)) +} + +func (s *E2ETestSuite) TestValidateCycleList() { + require := s.Require() + + // height 0 + _, err := s.app.BeginBlocker(s.ctx) + require.NoError(err) + firstInCycle, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + queryDataBytes, err := utils.QueryBytesFromString(ethQueryData[2:]) + require.NoError(err) + require.Equal(queryDataBytes, firstInCycle) + require.Equal(s.ctx.BlockHeight(), int64(0)) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + // height 1 + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + require.Equal(s.ctx.BlockHeight(), int64(1)) + secondInCycle, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + queryDataBytes, err = utils.QueryBytesFromString(btcQueryData[2:]) + require.NoError(err) + require.Equal(queryDataBytes, secondInCycle) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + // height 2 + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + require.Equal(s.ctx.BlockHeight(), int64(2)) + thirdInCycle, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + queryDataBytes, err = utils.QueryBytesFromString(trbQueryData[2:]) + require.NoError(err) + require.Equal(queryDataBytes, thirdInCycle) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + // loop through more times + list, err := s.oraclekeeper.GetCyclelist(s.ctx) + require.NoError(err) + for i := 0; i < 20; i++ { + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + query, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + require.Contains(list, query) + + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + } +} + +func (s *E2ETestSuite) TestSetUpValidatorAndReporter() { + require := s.Require() + + // Create Validator Accounts + numValidators := 10 + base := new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil) + _ = new(big.Int).Mul(big.NewInt(1000), base) + + // make addresses + testAddresses := simtestutil.CreateIncrementalAccounts(numValidators) + // mint 50k tokens to minter account and send to each address + initCoins := sdk.NewCoin(s.denom, math.NewInt(5000*1e6)) + for _, addr := range testAddresses { + s.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + s.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, addr, sdk.NewCoins(initCoins))) + } + // get val address for each test address + valAddresses := simtestutil.ConvertAddrsToValAddrs(testAddresses) + // create pub keys for each address + pubKeys := simtestutil.CreateTestPubKeys(numValidators) + + // set each account with proper keepers + for i, pubKey := range pubKeys { + s.accountKeeper.NewAccountWithAddress(s.ctx, testAddresses[i]) + validator, err := stakingtypes.NewValidator(valAddresses[i].String(), pubKey, stakingtypes.Description{Moniker: strconv.Itoa(i)}) + require.NoError(err) + s.stakingKeeper.SetValidator(s.ctx, validator) + s.stakingKeeper.SetValidatorByConsAddr(s.ctx, validator) + s.stakingKeeper.SetNewValidatorByPowerIndex(s.ctx, validator) + + randomStakeAmount := rand.Intn(5000-1000+1) + 1000 + require.True(randomStakeAmount >= 1000 && randomStakeAmount <= 5000, "randomStakeAmount is not within the expected range") + _, err = s.stakingKeeper.Delegate(s.ctx, testAddresses[i], math.NewInt(int64(randomStakeAmount)*1e6), stakingtypes.Unbonded, validator, true) + require.NoError(err) + // call hooks for distribution init + valBz, err := s.stakingKeeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + if err != nil { + panic(err) + } + err = s.distrKeeper.Hooks().AfterValidatorCreated(s.ctx, valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().BeforeDelegationCreated(s.ctx, testAddresses[i], valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().AfterDelegationModified(s.ctx, testAddresses[i], valBz) + require.NoError(err) + } + + _, err := s.stakingKeeper.EndBlocker(s.ctx) + s.NoError(err) + + // check that everyone is a bonded validator + validatorSet, err := s.stakingKeeper.GetAllValidators(s.ctx) + require.NoError(err) + for _, val := range validatorSet { + status := val.GetStatus() + require.Equal(stakingtypes.Bonded.String(), status.String()) + } + + // create 3 delegators + const ( + reporter = "reporter" + delegatorI = "delegator1" + delegatorII = "delegator2" + delegatorIII = "delegator3" + ) + + type Delegator struct { + delegatorAddress sdk.AccAddress + validator stakingtypes.Validator + tokenAmount math.Int + } + + numDelegators := 4 + // create random private keys for each delegator + delegatorPrivateKeys := make([]secp256k1.PrivKey, numDelegators) + for i := 0; i < numDelegators; i++ { + pk := secp256k1.GenPrivKey() + delegatorPrivateKeys[i] = *pk + } + // turn private keys into accounts + delegatorAccounts := make([]sdk.AccAddress, numDelegators) + for i, pk := range delegatorPrivateKeys { + delegatorAccounts[i] = sdk.AccAddress(pk.PubKey().Address()) + // give each account tokens + s.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + s.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, delegatorAccounts[i], sdk.NewCoins(initCoins))) + } + // define each delegator + delegators := map[string]Delegator{ + reporter: {delegatorAddress: delegatorAccounts[0], validator: validatorSet[1], tokenAmount: math.NewInt(100 * 1e6)}, + delegatorI: {delegatorAddress: delegatorAccounts[1], validator: validatorSet[1], tokenAmount: math.NewInt(100 * 1e6)}, + delegatorII: {delegatorAddress: delegatorAccounts[2], validator: validatorSet[1], tokenAmount: math.NewInt(100 * 1e6)}, + delegatorIII: {delegatorAddress: delegatorAccounts[3], validator: validatorSet[2], tokenAmount: math.NewInt(100 * 1e6)}, + } + // delegate to validators + for _, del := range delegators { + _, err := s.stakingKeeper.Delegate(s.ctx, del.delegatorAddress, del.tokenAmount, stakingtypes.Unbonded, del.validator, true) + require.NoError(err) + } + + // set up reporter module msgServer + msgServerReporter := reporterkeeper.NewMsgServerImpl(s.reporterkeeper) + require.NotNil(msgServerReporter) + // define reporter params + var createReporterMsg reportertypes.MsgCreateReporter + reporterAddress := delegators[reporter].delegatorAddress.String() + amount := math.NewInt(100 * 1e6) + source := reportertypes.TokenOrigin{ValidatorAddress: validatorSet[1].GetOperator(), Amount: math.NewInt(100 * 1e6)} + commission := stakingtypes.NewCommissionWithTime(math.LegacyNewDecWithPrec(1, 1), math.LegacyNewDecWithPrec(3, 1), + math.LegacyNewDecWithPrec(1, 1), s.ctx.BlockTime()) + // fill in createReporterMsg + createReporterMsg.Reporter = reporterAddress + createReporterMsg.Amount = amount + createReporterMsg.TokenOrigins = []*reportertypes.TokenOrigin{&source} + createReporterMsg.Commission = &commission + // create reporter through msg server + _, err = msgServerReporter.CreateReporter(s.ctx, &createReporterMsg) + require.NoError(err) + // check that reporter was created correctly + oracleReporter, err := s.reporterkeeper.Reporters.Get(s.ctx, delegators[reporter].delegatorAddress) + require.NoError(err) + require.Equal(oracleReporter.Reporter, delegators[reporter].delegatorAddress.String()) + require.Equal(oracleReporter.TotalTokens, math.NewInt(100*1e6)) + require.Equal(oracleReporter.Jailed, false) + + // define delegation source + source = reportertypes.TokenOrigin{ValidatorAddress: validatorSet[1].GetOperator(), Amount: math.NewInt(25 * 1e6)} + delegationMsg := reportertypes.NewMsgDelegateReporter( + delegators[delegatorI].delegatorAddress.String(), + delegators[reporter].delegatorAddress.String(), + math.NewInt(25*1e6), + []*reportertypes.TokenOrigin{&source}, + ) + // self delegate as reporter + _, err = msgServerReporter.DelegateReporter(s.ctx, delegationMsg) + require.NoError(err) + delegationReporter, err := s.reporterkeeper.Delegators.Get(s.ctx, delegators[delegatorI].delegatorAddress) + require.NoError(err) + require.Equal(delegationReporter.Reporter, delegators[reporter].delegatorAddress.String()) +} + +// todo: claim tbr/tips for these reports +func (s *E2ETestSuite) TestBasicReporting() { + require := s.Require() + + //--------------------------------------------------------------------------- + // Height 0 + //--------------------------------------------------------------------------- + _, err := s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // create a validator + valAccount := simtestutil.CreateIncrementalAccounts(1) + // mint 5000*1e8 tokens for validator + initCoins := sdk.NewCoin(s.denom, math.NewInt(5000*1e8)) + require.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + require.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, valAccount[0], sdk.NewCoins(initCoins))) + // get val address + valAccountValAddrs := simtestutil.ConvertAddrsToValAddrs(valAccount) + // create pub key for validator + pubKey := simtestutil.CreateTestPubKeys(1) + // tell keepers about the new validator + s.accountKeeper.NewAccountWithAddress(s.ctx, valAccount[0]) + validator, err := stakingtypes.NewValidator(valAccountValAddrs[0].String(), pubKey[0], stakingtypes.Description{Moniker: "created validator"}) + require.NoError(err) + s.stakingKeeper.SetValidator(s.ctx, validator) + s.stakingKeeper.SetValidatorByConsAddr(s.ctx, validator) + s.stakingKeeper.SetNewValidatorByPowerIndex(s.ctx, validator) + // self delegate from validator account to itself + _, err = s.stakingKeeper.Delegate(s.ctx, valAccount[0], math.NewInt(int64(4000)*1e8), stakingtypes.Unbonded, validator, true) + require.NoError(err) + // call hooks for distribution init + valBz, err := s.stakingKeeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + if err != nil { + panic(err) + } + err = s.distrKeeper.Hooks().AfterValidatorCreated(s.ctx, valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().BeforeDelegationCreated(s.ctx, valAccount[0], valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().AfterDelegationModified(s.ctx, valAccount[0], valBz) + require.NoError(err) + _, err = s.stakingKeeper.EndBlocker(s.ctx) + s.NoError(err) + + //create a self delegated reporter from a different account + type Delegator struct { + delegatorAddress sdk.AccAddress + validator stakingtypes.Validator + tokenAmount math.Int + } + pk := secp256k1.GenPrivKey() + reporterAccount := sdk.AccAddress(pk.PubKey().Address()) + // mint 5000*1e6 tokens for reporter + s.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + s.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, reporterAccount, sdk.NewCoins(initCoins))) + // delegate to validator so reporter can delegate to themselves + reporterDelToVal := Delegator{delegatorAddress: reporterAccount, validator: validator, tokenAmount: math.NewInt(5000 * 1e6)} + _, err = s.stakingKeeper.Delegate(s.ctx, reporterDelToVal.delegatorAddress, reporterDelToVal.tokenAmount, stakingtypes.Unbonded, reporterDelToVal.validator, true) + require.NoError(err) + // call dist module hooks + err = s.distrKeeper.Hooks().AfterValidatorCreated(s.ctx, valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().BeforeDelegationCreated(s.ctx, reporterAccount, valAccountValAddrs[0]) + require.NoError(err) + err = s.distrKeeper.Hooks().AfterDelegationModified(s.ctx, reporterAccount, valAccountValAddrs[0]) + require.NoError(err) + // set up reporter module msgServer + msgServerReporter := reporterkeeper.NewMsgServerImpl(s.reporterkeeper) + require.NotNil(msgServerReporter) + // define createReporterMsg params + var createReporterMsg reportertypes.MsgCreateReporter + reporterAddress := reporterDelToVal.delegatorAddress.String() + amount := math.NewInt(4000 * 1e6) + source := reportertypes.TokenOrigin{ValidatorAddress: validator.OperatorAddress, Amount: math.NewInt(4000 * 1e6)} + // 0% commission for reporter staking to validator + commission := stakingtypes.NewCommissionWithTime(math.LegacyNewDecWithPrec(0, 0), math.LegacyNewDecWithPrec(3, 1), + math.LegacyNewDecWithPrec(1, 1), s.ctx.BlockTime()) + // fill in createReporterMsg + createReporterMsg.Reporter = reporterAddress + createReporterMsg.Amount = amount + createReporterMsg.TokenOrigins = []*reportertypes.TokenOrigin{&source} + createReporterMsg.Commission = &commission + // send createreporter msg + _, err = msgServerReporter.CreateReporter(s.ctx, &createReporterMsg) + require.NoError(err) + // check that reporter was created in Reporters collections + reporter, err := s.reporterkeeper.Reporters.Get(s.ctx, reporterAccount) + require.NoError(err) + require.Equal(reporter.Reporter, reporterAccount.String()) + require.Equal(reporter.TotalTokens, math.NewInt(4000*1e6)) + require.Equal(reporter.Jailed, false) + // check on reporter in Delegators collections + rkDelegation, err := s.reporterkeeper.Delegators.Get(s.ctx, reporterAccount) + require.NoError(err) + require.Equal(rkDelegation.Reporter, reporterAccount.String()) + require.Equal(rkDelegation.Amount, math.NewInt(4000*1e6)) + // check on reporter/validator delegation + skDelegation, err := s.stakingKeeper.Delegation(s.ctx, reporterAccount, valBz) + require.NoError(err) + require.Equal(skDelegation.GetDelegatorAddr(), reporterAccount.String()) + require.Equal(skDelegation.GetValidatorAddr(), validator.GetOperator()) + + // setup oracle msgServer + msgServerOracle := oraclekeeper.NewMsgServerImpl(s.oraclekeeper) + require.NotNil(msgServerOracle) + + // case 1: commit/reveal for cycle list + //--------------------------------------------------------------------------- + // Height 1 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // check that no time based rewards have been minted yet + tbrModuleAccount := s.accountKeeper.GetModuleAddress(minttypes.TimeBasedRewards) + tbrModuleAccountBalance := s.bankKeeper.GetBalance(s.ctx, tbrModuleAccount, sdk.DefaultBondDenom) + require.Equal(int64(0), tbrModuleAccountBalance.Amount.Int64()) + + // begin report + cycleListEth, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + // create hash for commit + salt1, err := oracleutils.Salt(32) + require.NoError(err) + value1 := encodeValue(4500) + hash1 := oracleutils.CalculateCommitment(value1, salt1) + // create commit1 msg + commit1 := oracletypes.MsgCommitReport{ + Creator: reporter.Reporter, + QueryData: cycleListEth, + Hash: hash1, + } + // send commit tx + commitResponse1, err := msgServerOracle.CommitReport(s.ctx, &commit1) + require.NoError(err) + require.NotNil(commitResponse1) + commitHeight := s.ctx.BlockHeight() + require.Equal(int64(1), commitHeight) + + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + //--------------------------------------------------------------------------- + // Height 2 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(commitHeight + 1) + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(time.Duration(1 * time.Second))) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // check that 1 second worth of tbr has been minted + // expected tbr = (daily mint rate * time elapsed) / (# of ms in a day) + expectedBlockProvision := int64(146940000 * (1 * time.Second) / (24 * 60 * 60 * 1000)) + expectedTbr := sdk.NewCoin(s.denom, math.NewInt((expectedBlockProvision)).Quo(sdk.DefaultPowerReduction)) + tbrModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, tbrModuleAccount, sdk.DefaultBondDenom) + require.Equal(expectedTbr, tbrModuleAccountBalance) + // check that the cycle list has rotated + cycleListBtc, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NotEqual(cycleListEth, cycleListBtc) + require.NoError(err) + + // create reveal msg + require.NoError(err) + reveal1 := oracletypes.MsgSubmitValue{ + Creator: reporter.Reporter, + QueryData: cycleListEth, + Value: value1, + Salt: salt1, + } + // send reveal tx + revealResponse1, err := msgServerOracle.SubmitValue(s.ctx, &reveal1) + require.NoError(err) + require.NotNil(revealResponse1) + // advance time and block height to expire the query and aggregate report + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(7 * time.Second)) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + // get queryId for GetAggregatedReportRequest + queryIdEth := utils.QueryIDFromData(cycleListEth) + s.NoError(err) + // check that aggregated report is stored + getAggReportRequest1 := oracletypes.QueryGetCurrentAggregatedReportRequest{ + QueryId: queryIdEth, + } + result1, err := s.oraclekeeper.GetAggregatedReport(s.ctx, &getAggReportRequest1) + require.NoError(err) + require.Equal(result1.Report.Height, int64(2)) + require.Equal(result1.Report.AggregateReportIndex, int64(0)) + require.Equal(result1.Report.AggregateValue, encodeValue(4500)) + require.Equal(result1.Report.AggregateReporter, reporter.Reporter) + require.Equal(result1.Report.QueryId, queryIdEth) + require.Equal(int64(4000), result1.Report.ReporterPower) + // check that tbr is no longer in timeBasedRewards module acct + tbrModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, tbrModuleAccount, sdk.DefaultBondDenom) + require.Equal(int64(0), tbrModuleAccountBalance.Amount.Int64()) + // check that tbr was sent to reporter module account + reporterModuleAccount := s.accountKeeper.GetModuleAddress(reportertypes.ModuleName) + reporterModuleAccountBalance := s.bankKeeper.GetBalance(s.ctx, reporterModuleAccount, sdk.DefaultBondDenom) + require.Equal(expectedTbr, reporterModuleAccountBalance) + // check reporters outstaning rewards + outstandingRewards, err := s.reporterkeeper.GetReporterOutstandingRewardsCoins(s.ctx, sdk.ValAddress(reporterAccount)) + require.NoError(err) + require.Equal(outstandingRewards.AmountOf(s.denom).TruncateInt(), expectedTbr.Amount) + // withdraw tbr + rewards, err := s.reporterkeeper.WithdrawDelegationRewards(s.ctx, sdk.ValAddress(reporterAccount), reporterAccount) + require.NoError(err) + // check that there is only one reward to claim + require.Equal(len(rewards), 1) + // check that the reward is the correct amount and denom + require.Equal(rewards[0].Denom, s.denom) + require.Equal(rewards.AmountOf(s.denom), expectedTbr.Amount) + // check that reporter module account balance is now empty + reporterModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, reporterModuleAccount, sdk.DefaultBondDenom) + require.Equal(int64(0), reporterModuleAccountBalance.Amount.Int64()) + // check that reporter now has more bonded tokens + + // case 2: direct reveal for cycle list + //--------------------------------------------------------------------------- + // Height 3 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(time.Duration(1 * time.Second))) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // check that 8 sec of tbr has been minted + tbrModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, tbrModuleAccount, sdk.DefaultBondDenom) + expectedBlockProvision = int64(146940000 * (8 * time.Second) / (24 * 60 * 60 * 1000)) + expectedTbr = sdk.NewCoin(s.denom, math.NewInt((expectedBlockProvision)).Quo(sdk.DefaultPowerReduction)) + require.Equal(expectedTbr, tbrModuleAccountBalance) + + // get new cycle list query data + cycleListTrb, err := s.oraclekeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + require.NotEqual(cycleListEth, cycleListTrb) + require.NotEqual(cycleListBtc, cycleListTrb) + // create reveal message + value2 := encodeValue(100_000) + require.NoError(err) + reveal2 := oracletypes.MsgSubmitValue{ + Creator: reporter.Reporter, + QueryData: cycleListTrb, + Value: value2, + } + // send reveal message + revealResponse2, err := msgServerOracle.SubmitValue(s.ctx, &reveal2) + require.NoError(err) + require.NotNil(revealResponse2) + // advance time and block height to expire the query and aggregate report + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(7 * time.Second)) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + // get queryId for GetAggregatedReportRequest + queryIdTrb := utils.QueryIDFromData(cycleListTrb) + s.NoError(err) + // create get aggregated report query + getAggReportRequest2 := oracletypes.QueryGetCurrentAggregatedReportRequest{ + QueryId: queryIdTrb, + } + // check that aggregated report is stored correctly + result2, err := s.oraclekeeper.GetAggregatedReport(s.ctx, &getAggReportRequest2) + require.NoError(err) + require.Equal(int64(0), result2.Report.AggregateReportIndex) + require.Equal(encodeValue(100_000), result2.Report.AggregateValue) + require.Equal(reporter.Reporter, result2.Report.AggregateReporter) + require.Equal(queryIdTrb, result2.Report.QueryId) + require.Equal(int64(4000), result2.Report.ReporterPower) + require.Equal(int64(3), result2.Report.Height) + // check that tbr is no longer in timeBasedRewards module acct + tbrModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, tbrModuleAccount, sdk.DefaultBondDenom) + require.Equal(int64(0), tbrModuleAccountBalance.Amount.Int64()) + // check that tbr was sent to reporter module account + reporterModuleAccount = s.accountKeeper.GetModuleAddress(reportertypes.ModuleName) + reporterModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, reporterModuleAccount, sdk.DefaultBondDenom) + require.Equal(expectedTbr, reporterModuleAccountBalance) + // check reporters outstaning rewards + outstandingRewards, err = s.reporterkeeper.GetReporterOutstandingRewardsCoins(s.ctx, sdk.ValAddress(reporterAccount)) + require.NoError(err) + require.Equal(outstandingRewards.AmountOf(s.denom).TruncateInt(), expectedTbr.Amount) + // withdraw tbr + rewards, err = s.reporterkeeper.WithdrawDelegationRewards(s.ctx, sdk.ValAddress(reporterAccount), reporterAccount) + require.NoError(err) + // check that there is only one reward to claim + require.Equal(len(rewards), 1) + // check that the reward is the correct amount and denom + require.Equal(rewards[0].Denom, s.denom) + require.Equal(rewards.AmountOf(s.denom), expectedTbr.Amount) + // check that reporter module account balance is now empty + reporterModuleAccountBalance = s.bankKeeper.GetBalance(s.ctx, reporterModuleAccount, sdk.DefaultBondDenom) + require.Equal(int64(0), reporterModuleAccountBalance.Amount.Int64()) + // check that reporter now has more bonded tokens + + // case 3: commit/reveal for tipped query + //--------------------------------------------------------------------------- + // Height 4 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // get reporters shares + deleBeforeReport, err := s.stakingKeeper.Delegation(s.ctx, reporterAccount.Bytes(), valBz) + require.NoError(err) + require.Equal(deleBeforeReport.GetShares(), math.LegacyNewDecFromInt(math.NewInt(5000*1e6))) + + // create tip msg + tipAmount := sdk.NewCoin(sdk.DefaultBondDenom, math.NewInt(100)) + msgTip := oracletypes.MsgTip{ + Tipper: reporter.Reporter, + QueryData: cycleListEth, + Amount: tipAmount, + } + // send tip tx + tipRes, err := msgServerOracle.Tip(s.ctx, &msgTip) + require.NoError(err) + require.NotNil(tipRes) + // check that tip is in oracle module account + twoPercent := sdk.NewCoin(s.denom, tipAmount.Amount.Mul(math.NewInt(2)).Quo(math.NewInt(100))) + tipModuleAcct := s.accountKeeper.GetModuleAddress(oracletypes.ModuleName) + tipAcctBalance := s.bankKeeper.GetBalance(s.ctx, tipModuleAcct, sdk.DefaultBondDenom) + require.Equal(tipAcctBalance, tipAmount.Sub(twoPercent)) + // create commit for tipped eth query + salt1, err = oracleutils.Salt(32) + require.NoError(err) + value1 = encodeValue(5000) + hash1 = oracleutils.CalculateCommitment(value1, salt1) + commit1 = oracletypes.MsgCommitReport{ + Creator: reporter.Reporter, + QueryData: cycleListEth, + Hash: hash1, + } + // send commit tx + commitResponse1, err = msgServerOracle.CommitReport(s.ctx, &commit1) + require.NoError(err) + require.NotNil(commitResponse1) + commitHeight = s.ctx.BlockHeight() + require.Equal(int64(4), commitHeight) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + //--------------------------------------------------------------------------- + // Height 5 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(commitHeight + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // create reveal msg + value1 = encodeValue(5000) + reveal1 = oracletypes.MsgSubmitValue{ + Creator: reporter.Reporter, + QueryData: cycleListEth, + Value: value1, + Salt: salt1, + } + // send reveal tx + revealResponse1, err = msgServerOracle.SubmitValue(s.ctx, &reveal1) + require.NoError(err) + require.NotNil(revealResponse1) + // advance time and block height to expire the query and aggregate report + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(7 * time.Second)) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + // create get aggreagted report query + getAggReportRequest1 = oracletypes.QueryGetCurrentAggregatedReportRequest{ + QueryId: queryIdEth, + } + // check that the aggregated report is stored correctly + result1, err = s.oraclekeeper.GetAggregatedReport(s.ctx, &getAggReportRequest1) + require.NoError(err) + require.Equal(result1.Report.AggregateReportIndex, int64(0)) + require.Equal(result1.Report.AggregateValue, encodeValue(5000)) + require.Equal(result1.Report.AggregateReporter, reporter.Reporter) + require.Equal(queryIdEth, result1.Report.QueryId) + require.Equal(int64(4000), result1.Report.ReporterPower) + require.Equal(int64(5), result1.Report.Height) + // check that the tip is in tip escrow + tipEscrowAcct := s.accountKeeper.GetModuleAddress(reportertypes.TipsEscrowPool) + tipEscrowBalance := s.bankKeeper.GetBalance(s.ctx, tipEscrowAcct, sdk.DefaultBondDenom) // 98 loya + require.Equal(tipAmount.Amount.Sub(twoPercent.Amount), tipEscrowBalance.Amount) + // withdraw tip + msgWithdrawTip := reportertypes.MsgWithdrawTip{ + DelegatorAddress: reporterAddress, + ValidatorAddress: validator.OperatorAddress, + } + _, err = msgServerReporter.WithdrawTip(s.ctx, &msgWithdrawTip) + require.NoError(err) + // check that tip is no longer in escrow pool + tipEscrowBalance = s.bankKeeper.GetBalance(s.ctx, tipEscrowAcct, sdk.DefaultBondDenom) + require.Equal(int64(0), tipEscrowBalance.Amount.Int64()) + // check that reporter now has more bonded tokens + deleAfter, err := s.stakingKeeper.Delegation(s.ctx, reporterAccount.Bytes(), valBz) + require.NoError(err) + require.Equal(deleBeforeReport.GetShares().Add(math.LegacyNewDec(98)), deleAfter.GetShares()) + + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + + // case 4: submit without committing for tipped query + //--------------------------------------------------------------------------- + // Height 6 + //--------------------------------------------------------------------------- + s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) + _, err = s.app.BeginBlocker(s.ctx) + require.NoError(err) + + // check reporter starting shares + deleBeforeReport2, err := s.stakingKeeper.Delegation(s.ctx, reporterAccount.Bytes(), valBz) + require.NoError(err) + expectedShares := math.LegacyNewDecFromInt(math.NewInt(5000 * 1e6).Add(math.NewInt(98))) + require.Equal(deleBeforeReport2.GetShares(), expectedShares) + + // create tip msg + msgTip = oracletypes.MsgTip{ + Tipper: reporter.Reporter, + QueryData: cycleListTrb, + Amount: tipAmount, + } + // send tip tx + tipRes, err = msgServerOracle.Tip(s.ctx, &msgTip) + require.NoError(err) + require.NotNil(tipRes) + // check that tip is in oracle module account + tipModuleAcct = s.accountKeeper.GetModuleAddress(oracletypes.ModuleName) + tipAcctBalance = s.bankKeeper.GetBalance(s.ctx, tipModuleAcct, sdk.DefaultBondDenom) + require.Equal(tipAcctBalance, tipAmount.Sub(twoPercent)) + // create submit msg + revealMsgTrb := oracletypes.MsgSubmitValue{ + Creator: reporter.Reporter, + QueryData: cycleListTrb, + Value: encodeValue(1_000_000), + } + // send submit msg + revealTrb, err := msgServerOracle.SubmitValue(s.ctx, &revealMsgTrb) + require.NoError(err) + require.NotNil(revealTrb) + // advance time and block height to expire the query and aggregate report + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(7 * time.Second)) + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) + // create get aggregated report query + getAggReportRequestTrb := oracletypes.QueryGetCurrentAggregatedReportRequest{ + QueryId: queryIdTrb, + } + // query aggregated report + resultTrb, err := s.oraclekeeper.GetAggregatedReport(s.ctx, &getAggReportRequestTrb) + require.NoError(err) + require.Equal(resultTrb.Report.AggregateReportIndex, int64(0)) + require.Equal(resultTrb.Report.AggregateValue, encodeValue(1_000_000)) + require.Equal(resultTrb.Report.AggregateReporter, reporter.Reporter) + require.Equal(queryIdTrb, resultTrb.Report.QueryId) + require.Equal(int64(4000), resultTrb.Report.ReporterPower) + require.Equal(int64(6), resultTrb.Report.Height) + // check that the tip is in tip escrow + tipEscrowBalance = s.bankKeeper.GetBalance(s.ctx, tipEscrowAcct, sdk.DefaultBondDenom) // 98 loya + require.Equal(tipAmount.Amount.Sub(twoPercent.Amount), tipEscrowBalance.Amount) + // withdraw tip + _, err = msgServerReporter.WithdrawTip(s.ctx, &msgWithdrawTip) + require.NoError(err) + // check that tip is no longer in escrow pool + tipEscrowBalance = s.bankKeeper.GetBalance(s.ctx, tipEscrowAcct, sdk.DefaultBondDenom) + require.Equal(int64(0), tipEscrowBalance.Amount.Int64()) + // check that reporter now has more bonded tokens + deleAfter, err = s.stakingKeeper.Delegation(s.ctx, reporterAccount.Bytes(), valBz) + require.NoError(err) + require.Equal(deleBeforeReport2.GetShares().Add(math.LegacyNewDec(98)), deleAfter.GetShares()) + + _, err = s.app.EndBlocker(s.ctx) + require.NoError(err) +} + +// todo: dispute test + +func (s *E2ETestSuite) TestDisputes() { + require := s.Require() + _, msgServerDispute := s.disputeKeeper() + require.NotNil(msgServerDispute) + + // create 5 validators with all of their TRB staked + accountsAddrs, valsAddrs := s.CreateValidators(5, 5000) + _, err := s.stakingKeeper.EndBlocker(s.ctx) + s.NoError(err) + _ = accountsAddrs + _ = valsAddrs + +} diff --git a/tests/e2e/keeper_test.go b/tests/e2e/keeper_test.go new file mode 100644 index 000000000..ad2f0a837 --- /dev/null +++ b/tests/e2e/keeper_test.go @@ -0,0 +1,524 @@ +package e2e_test + +import ( + "encoding/hex" + "fmt" + "math/big" + "strconv" + "strings" + "time" + + "cosmossdk.io/depinject" + "cosmossdk.io/math" + + authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" + + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil/configurator" + simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/stretchr/testify/suite" + + "cosmossdk.io/log" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + + "github.com/cosmos/cosmos-sdk/baseapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/bank" + distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" + distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + "github.com/cosmos/cosmos-sdk/x/staking" + + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/tellor-io/layer/app/config" + disputekeeper "github.com/tellor-io/layer/x/dispute/keeper" + mintkeeper "github.com/tellor-io/layer/x/mint/keeper" + minttypes "github.com/tellor-io/layer/x/mint/types" + oraclekeeper "github.com/tellor-io/layer/x/oracle/keeper" + registrykeeper "github.com/tellor-io/layer/x/registry/keeper" + reporterkeeper "github.com/tellor-io/layer/x/reporter/keeper" + + // _ "github.com/cosmos/cosmos-sdk/x/auth" + _ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" + // _ "github.com/cosmos/cosmos-sdk/x/bank" + _ "github.com/cosmos/cosmos-sdk/x/consensus" + _ "github.com/cosmos/cosmos-sdk/x/distribution" + _ "github.com/cosmos/cosmos-sdk/x/genutil" + _ "github.com/cosmos/cosmos-sdk/x/gov" + _ "github.com/cosmos/cosmos-sdk/x/mint" + _ "github.com/cosmos/cosmos-sdk/x/params" + _ "github.com/cosmos/cosmos-sdk/x/slashing" + _ "github.com/tellor-io/layer/x/dispute" + _ "github.com/tellor-io/layer/x/mint" + _ "github.com/tellor-io/layer/x/oracle" + _ "github.com/tellor-io/layer/x/reporter/module" + + // _ "github.com/cosmos/cosmos-sdk/x/staking" + + testutils "github.com/tellor-io/layer/tests" + disputetypes "github.com/tellor-io/layer/x/dispute/types" + oracletypes "github.com/tellor-io/layer/x/oracle/types" + _ "github.com/tellor-io/layer/x/registry/module" + registrytypes "github.com/tellor-io/layer/x/registry/types" + + "testing" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/ethereum/go-ethereum/accounts/abi" +) + +const ( + ethQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + btcQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003627463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + trbQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003747262000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" +) + +type E2ETestSuite struct { + suite.Suite + + oraclekeeper oraclekeeper.Keeper + disputekeeper disputekeeper.Keeper + registrykeeper registrykeeper.Keeper + mintkeeper mintkeeper.Keeper + reporterkeeper reporterkeeper.Keeper + + accountKeeper authkeeper.AccountKeeper + bankKeeper bankkeeper.BaseKeeper + distrKeeper distrkeeper.Keeper + slashingKeeper slashingkeeper.Keeper + stakingKeeper *stakingkeeper.Keeper + govKeeper *govkeeper.Keeper + ctx sdk.Context + appCodec codec.Codec + authConfig *authmodulev1.Module + + queryHelper *baseapp.QueryServiceTestHelper + interfaceRegistry codectypes.InterfaceRegistry + fetchStoreKey func(string) storetypes.StoreKey + + denom string + app *runtime.App +} + +func (suite *E2ETestSuite) initKeepersWithmAccPerms(blockedAddrs map[string]bool) { + maccPerms := map[string][]string{} + for _, permission := range suite.authConfig.ModuleAccountPermissions { + maccPerms[permission.Account] = permission.Permissions + } + + appCodec := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{}, staking.AppModuleBasic{}).Codec + cdc := moduletestutil.MakeTestEncodingConfig(auth.AppModuleBasic{}, bank.AppModuleBasic{}, staking.AppModuleBasic{}).Amino + + maccPerms[authtypes.Burner] = []string{authtypes.Burner} + maccPerms[authtypes.Minter] = []string{authtypes.Minter} + + suite.accountKeeper = authkeeper.NewAccountKeeper( + appCodec, + runtime.NewKVStoreService(suite.fetchStoreKey(banktypes.StoreKey).(*storetypes.KVStoreKey)), + authtypes.ProtoBaseAccount, + maccPerms, + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), + sdk.GetConfig().GetBech32AccountAddrPrefix(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + suite.bankKeeper = bankkeeper.NewBaseKeeper( + appCodec, + runtime.NewKVStoreService(suite.fetchStoreKey(banktypes.StoreKey).(*storetypes.KVStoreKey)), + suite.accountKeeper, + blockedAddrs, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + log.NewNopLogger(), + ) + + suite.stakingKeeper = stakingkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(suite.fetchStoreKey(stakingtypes.StoreKey).(*storetypes.KVStoreKey)), + suite.accountKeeper, + suite.bankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ValidatorAddrPrefix()), + authcodec.NewBech32Codec(sdk.GetConfig().GetBech32ConsensusAddrPrefix()), + ) + + suite.slashingKeeper = slashingkeeper.NewKeeper( + appCodec, + cdc, + runtime.NewKVStoreService(suite.fetchStoreKey(banktypes.StoreKey).(*storetypes.KVStoreKey)), + suite.stakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + suite.registrykeeper = registrykeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(suite.fetchStoreKey(registrytypes.StoreKey).(*storetypes.KVStoreKey)), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + suite.distrKeeper = distrkeeper.NewKeeper( + appCodec, runtime.NewKVStoreService(suite.fetchStoreKey(distrtypes.StoreKey).(*storetypes.KVStoreKey)), suite.accountKeeper, suite.bankKeeper, suite.stakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + suite.oraclekeeper = oraclekeeper.NewKeeper( + appCodec, runtime.NewKVStoreService(suite.fetchStoreKey(oracletypes.StoreKey).(*storetypes.KVStoreKey)), suite.accountKeeper, suite.bankKeeper, suite.registrykeeper, suite.reporterkeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + suite.disputekeeper = disputekeeper.NewKeeper( + appCodec, suite.fetchStoreKey(disputetypes.StoreKey), suite.fetchStoreKey(disputetypes.StoreKey), paramtypes.Subspace{}, suite.accountKeeper, suite.bankKeeper, suite.oraclekeeper, suite.reporterkeeper, + ) + suite.mintkeeper = mintkeeper.NewKeeper( + appCodec, suite.fetchStoreKey(minttypes.StoreKey), suite.accountKeeper, suite.bankKeeper, + ) + // suite.stakingKeeper.SetHooks(stakingtypes.NewMultiStakingHooks( + // suite.distrKeeper.Hooks(), + // )) + // suite.reporterkeeper = reporterkeeper.NewKeeper( + // appCodec, suite.fetchStoreKey(reportertypes.StoreKey), +} + +func (s *E2ETestSuite) SetupTest() { + + sdk.DefaultBondDenom = "loya" + config.SetupConfig() + + app, err := simtestutil.SetupWithConfiguration( + depinject.Configs( + configurator.NewAppConfig( + testutils.AuthModule(), + configurator.BankModule(), + configurator.StakingModule(), + configurator.SlashingModule(), + configurator.ParamsModule(), + configurator.ConsensusModule(), + configurator.DistributionModule(), + testutils.OracleModule(), + testutils.DisputeModule(), + testutils.RegistryModule(), + testutils.MintModule(), + testutils.ReporterModule(), + configurator.GovModule(), + ), + depinject.Supply(log.NewNopLogger()), + ), + testutils.DefaultStartUpConfig(), + &s.accountKeeper, &s.bankKeeper, &s.stakingKeeper, &s.slashingKeeper, + &s.interfaceRegistry, &s.appCodec, &s.authConfig, &s.oraclekeeper, + &s.disputekeeper, &s.registrykeeper, &s.govKeeper, &s.distrKeeper, &s.mintkeeper, &s.reporterkeeper) + + s.NoError(err) + s.ctx = sdk.UnwrapSDKContext(app.BaseApp.NewContextLegacy(false, tmproto.Header{Time: time.Now()})) + s.fetchStoreKey = app.UnsafeFindStoreKey + + s.queryHelper = baseapp.NewQueryServerTestHelper(s.ctx, s.interfaceRegistry) + s.denom = sdk.DefaultBondDenom + s.initKeepersWithmAccPerms(make(map[string]bool)) + s.app = app +} + +func (s *E2ETestSuite) CreateValidators(numValidators int, numTrb int64) ([]sdk.AccAddress, []sdk.ValAddress) { + require := s.Require() + // create account that will become a validator + accountsAddrs := simtestutil.CreateIncrementalAccounts(numValidators) + // mint numTrb for each validator + initCoins := sdk.NewCoin(s.denom, math.NewInt(numTrb*1e6)) + for _, acc := range accountsAddrs { + // mint to module + require.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + // send from module to account + require.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, acc, sdk.NewCoins(initCoins))) + } + // get val address for each account + validatorsAddrs := simtestutil.ConvertAddrsToValAddrs(accountsAddrs) + // create pub keys for validators + pubKeys := simtestutil.CreateTestPubKeys(numValidators) + // set each account with proper keepers + for i, pubKey := range pubKeys { + s.accountKeeper.NewAccountWithAddress(s.ctx, accountsAddrs[i]) + validator, err := stakingtypes.NewValidator(validatorsAddrs[i].String(), pubKey, stakingtypes.Description{Moniker: strconv.Itoa(i)}) + require.NoError(err) + s.stakingKeeper.SetValidator(s.ctx, validator) + s.stakingKeeper.SetValidatorByConsAddr(s.ctx, validator) + s.stakingKeeper.SetNewValidatorByPowerIndex(s.ctx, validator) + + _, err = s.stakingKeeper.Delegate(s.ctx, accountsAddrs[i], math.NewInt(numTrb*1e6), stakingtypes.Unbonded, validator, true) + require.NoError(err) + // call hooks for distribution init + valBz, err := s.stakingKeeper.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) + if err != nil { + panic(err) + } + err = s.distrKeeper.Hooks().AfterValidatorCreated(s.ctx, valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().BeforeDelegationCreated(s.ctx, accountsAddrs[i], valBz) + require.NoError(err) + err = s.distrKeeper.Hooks().AfterDelegationModified(s.ctx, accountsAddrs[i], valBz) + require.NoError(err) + } + + return accountsAddrs, validatorsAddrs +} + +func (s *E2ETestSuite) mintTokens(addr sdk.AccAddress, amount sdk.Coin) { + ctx := s.ctx + s.accountKeeper.SetAccount(ctx, authtypes.NewBaseAccountWithAddress(addr)) + s.NoError(s.bankKeeper.MintCoins(ctx, authtypes.Minter, sdk.NewCoins(amount))) + s.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(ctx, authtypes.Minter, addr, sdk.NewCoins(amount))) +} + +func (s *E2ETestSuite) newKeysWithTokens() (sdk.AccAddress, cryptotypes.PrivKey, cryptotypes.PubKey) { + PrivKey := secp256k1.GenPrivKey() + PubKey := PrivKey.PubKey() + Addr := sdk.AccAddress(PubKey.Address()) + s.mintTokens(Addr, sdk.NewCoin(s.denom, math.NewInt(1000000))) + return Addr, PrivKey, PubKey +} + +// func (s *E2ETestSuite) microReport() (disputetypes.MicroReport, sdk.ValAddress) { +// vals, err := s.stakingKeeper.GetAllValidators(s.ctx) +// s.Require().NoError(err) +// valAddr, err := sdk.ValAddressFromBech32(vals[0].OperatorAddress) +// s.Require().NoError(err) +// return disputetypes.MicroReport{ +// Reporter: sdk.AccAddress(valAddr).String(), +// Power: vals[0].GetConsensusPower(vals[0].GetBondedTokens()), +// QueryId: "83a7f3d48786ac2667503a61e8c415438ed2922eb86a2906e4ee66d9a2ce4992", +// Value: "000000000000000000000000000000000000000000000058528649cf80ee0000", +// Timestamp: 1696516597, +// }, valAddr + +// } + +func (s *E2ETestSuite) CreateAccountsWithTokens(numofAccs int, amountOfTokens int64) []sdk.AccAddress { + privKeys := CreateRandomPrivateKeys(numofAccs) + accs := make([]sdk.AccAddress, numofAccs) + for i, pk := range privKeys { + accs[i] = sdk.AccAddress(pk.PubKey().Address()) + s.mintTokens(accs[i], sdk.NewCoin(s.denom, math.NewInt(amountOfTokens))) + } + return accs +} + +// func (s *E2ETestSuite) createValidators(powers []int64) ([]sdk.AccAddress, []sdk.ValAddress) { +// ctx := s.ctx +// acctNum := len(powers) +// base := new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil) +// amount := new(big.Int).Mul(big.NewInt(1000), base) +// testAddrs := simtestutil.CreateIncrementalAccounts(acctNum) +// addrs := s.addTestAddrs(acctNum, math.NewIntFromBigInt(amount), testAddrs) +// valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs) +// pks := simtestutil.CreateTestPubKeys(acctNum) + +// for i, pk := range pks { +// // account := authtypes.BaseAccount{ +// // Address: testAddrs[i].String(), +// // PubKey: codectypes.UnsafePackAny(pk), +// // AccountNumber: s.accountKeeper.NextAccountNumber(ctx), +// // } +// // s.accountKeeper.NewAccount(s.ctx, &account) + +// s.accountKeeper.NewAccountWithAddress(ctx, testAddrs[i]) + +// val, err := stakingtypes.NewValidator(valAddrs[i].String(), pk, stakingtypes.Description{}) +// s.NoError(err) +// s.stakingKeeper.SetValidator(ctx, val) +// s.stakingKeeper.SetValidatorByConsAddr(ctx, val) +// s.stakingKeeper.SetNewValidatorByPowerIndex(ctx, val) +// s.stakingKeeper.Delegate(ctx, addrs[i], s.stakingKeeper.TokensFromConsensusPower(ctx, powers[i]), stakingtypes.Unbonded, val, true) +// } + +// _, err := s.stakingKeeper.EndBlocker(ctx) +// s.NoError(err) + +// return addrs, valAddrs +// } + +func (s *E2ETestSuite) addTestAddrs(accNum int, accAmt math.Int, testAddrs []sdk.AccAddress) []sdk.AccAddress { + initCoins := sdk.NewCoin(s.denom, accAmt) + for _, addr := range testAddrs { + s.NoError(s.bankKeeper.MintCoins(s.ctx, authtypes.Minter, sdk.NewCoins(initCoins))) + s.NoError(s.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, authtypes.Minter, addr, sdk.NewCoins(initCoins))) + } + + return testAddrs +} + +type ModuleAccs struct { + staking authtypes.AccountI + dispute authtypes.AccountI +} + +func (s *E2ETestSuite) ModuleAccs() ModuleAccs { + return ModuleAccs{ + staking: s.accountKeeper.GetModuleAccount(s.ctx, "bonded_tokens_pool"), + dispute: s.accountKeeper.GetModuleAccount(s.ctx, "dispute"), + } +} + +func CreateRandomPrivateKeys(accNum int) []secp256k1.PrivKey { + testAddrs := make([]secp256k1.PrivKey, accNum) + for i := 0; i < accNum; i++ { + pk := secp256k1.GenPrivKey() + testAddrs[i] = *pk + } + return testAddrs +} + +func (s *E2ETestSuite) convertToAccAddress(priv []secp256k1.PrivKey) []sdk.AccAddress { + testAddrs := make([]sdk.AccAddress, len(priv)) + for i, pk := range priv { + testAddrs[i] = sdk.AccAddress(pk.PubKey().Address()) + } + return testAddrs +} + +func JailValidator(ctx sdk.Context, consensusAddress sdk.ConsAddress, validatorAddress sdk.ValAddress, k stakingkeeper.Keeper) error { + validator, err := k.GetValidator(ctx, validatorAddress) + if err != nil { + return fmt.Errorf("validator %s not found", validatorAddress) + } + + if validator.Jailed { + return fmt.Errorf("validator %s is already jailed", validatorAddress) + } + + k.Jail(ctx, consensusAddress) + + return nil +} + +// func CommitReport(ctx context.Context, accountAddr string, []queryData bytes, msgServerOracle oracletypes.MsgServer) error { +// // commit +// value := "000000000000000000000000000000000000000000000058528649cf80ee0000" +// valueDecoded, err := hex.DecodeString(value) // convert hex value to bytes +// if err != nil { +// return err +// } +// salt, err := utils.Salt(32) +// if err != nil { +// return err +// } +// hash := utils.CalculateCommitment(string(valueDecoded), salt) +// if err != nil { +// return err +// } +// // commit report with query data in cycle list +// commitreq := &oracletypes.MsgCommitReport{ +// Creator: accountAddr, +// QueryData: queryData, +// Hash: hash, +// } +// _, err = msgServerOracle.CommitReport(ctx, commitreq) +// if err != nil { +// return err +// } + +// return nil +// } + +func (s *E2ETestSuite) createValidatorAccs(powers []int64) []sdk.AccAddress { + ctx := s.ctx + acctNum := len(powers) + base := new(big.Int).Exp(big.NewInt(10), big.NewInt(6), nil) + amount := new(big.Int).Mul(big.NewInt(1000), base) + privKeys := CreateRandomPrivateKeys(acctNum) + testAddrs := s.convertToAccAddress(privKeys) + addrs := s.addTestAddrs(acctNum, math.NewIntFromBigInt(amount), testAddrs) + valAddrs := simtestutil.ConvertAddrsToValAddrs(addrs) + + for i, pk := range privKeys { + account := authtypes.BaseAccount{ + Address: testAddrs[i].String(), + PubKey: codectypes.UnsafePackAny(pk.PubKey()), + AccountNumber: uint64(i + 1), + } + s.accountKeeper.SetAccount(s.ctx, &account) + val, err := stakingtypes.NewValidator(valAddrs[i].String(), pk.PubKey(), stakingtypes.Description{}) + s.NoError(err) + s.stakingKeeper.SetValidator(ctx, val) + s.stakingKeeper.SetValidatorByConsAddr(ctx, val) + s.stakingKeeper.SetNewValidatorByPowerIndex(ctx, val) + s.stakingKeeper.Delegate(ctx, addrs[i], s.stakingKeeper.TokensFromConsensusPower(ctx, powers[i]), stakingtypes.Unbonded, val, true) + // call hooks for distribution init + valBz, err := s.stakingKeeper.ValidatorAddressCodec().StringToBytes(val.GetOperator()) + if err != nil { + panic(err) + } + err = s.distrKeeper.Hooks().AfterValidatorCreated(ctx, valBz) + err = s.distrKeeper.Hooks().BeforeDelegationCreated(ctx, addrs[i], valBz) + err = s.distrKeeper.Hooks().AfterDelegationModified(ctx, addrs[i], valBz) + } + + _, err := s.stakingKeeper.EndBlocker(ctx) + s.NoError(err) + + return addrs +} + +// inspired by telliot python code +func encodeValue(number float64) string { + strNumber := fmt.Sprintf("%.18f", number) + + parts := strings.Split(strNumber, ".") + if len(parts[1]) > 18 { + parts[1] = parts[1][:18] + } + truncatedStr := parts[0] + parts[1] + + bigIntNumber := new(big.Int) + bigIntNumber.SetString(truncatedStr, 10) + + uint256ABIType, _ := abi.NewType("uint256", "", nil) + + arguments := abi.Arguments{{Type: uint256ABIType}} + encodedBytes, _ := arguments.Pack(bigIntNumber) + + encodedString := hex.EncodeToString(encodedBytes) + return encodedString +} + +func (s *E2ETestSuite) oracleKeeper() (queryClient oracletypes.QueryClient, msgServer oracletypes.MsgServer) { + oracletypes.RegisterQueryServer(s.queryHelper, &oracletypes.UnimplementedQueryServer{}) + oracletypes.RegisterInterfaces(s.interfaceRegistry) + queryClient = oracletypes.NewQueryClient(s.queryHelper) + msgServer = oraclekeeper.NewMsgServerImpl(s.oraclekeeper) + return +} + +func (s *E2ETestSuite) disputeKeeper() (queryClient disputetypes.QueryClient, msgServer disputetypes.MsgServer) { + disputetypes.RegisterQueryServer(s.queryHelper, s.disputekeeper) + disputetypes.RegisterInterfaces(s.interfaceRegistry) + queryClient = disputetypes.NewQueryClient(s.queryHelper) + msgServer = disputekeeper.NewMsgServerImpl(s.disputekeeper) + return +} + +func (s *E2ETestSuite) registryKeeper() (queryClient registrytypes.QueryClient, msgServer registrytypes.MsgServer) { + registrytypes.RegisterQueryServer(s.queryHelper, registrykeeper.NewQuerier(s.registrykeeper)) + registrytypes.RegisterInterfaces(s.interfaceRegistry) + queryClient = registrytypes.NewQueryClient(s.queryHelper) + msgServer = registrykeeper.NewMsgServerImpl(s.registrykeeper) + return +} + +// func (s *E2ETestSuite) mintKeeper() (queryClient minttypes.QueryClient) { +// // minttypes.RegisterQueryServer(s.queryHelper, mintkeeper.NewQuerier(s.mintkeeper)) +// // minttypes.RegisterInterfaces(s.interfaceRegistry) +// queryClient = minttypes.NewQueryClient(s.queryHelper) +// // msgServer = mintkeeper.NewMsgServerImpl(s.mintkeeper) +// return +// } + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(E2ETestSuite)) +} diff --git a/tests/integration/oracle_keeper_test.go b/tests/integration/oracle_keeper_test.go index 56cf11e0e..678c39cae 100644 --- a/tests/integration/oracle_keeper_test.go +++ b/tests/integration/oracle_keeper_test.go @@ -608,13 +608,13 @@ func (s *IntegrationTestSuite) TestTipQueryNotInCycleListSingleDelegator() { twoPercent := sdk.NewCoin(s.denom, tipAmount.Mul(math.NewInt(2)).Quo(math.NewInt(100))) require.Equal(tipAmount.Sub(twoPercent.Amount), escrowBalance.Amount) - // withdraw tip // create reporterMsgServer reporterMsgServer := reporterkeeper.NewMsgServerImpl(s.reporterkeeper) + // withdraw tip _, err = reporterMsgServer.WithdrawTip(s.ctx, &reportertypes.MsgWithdrawTip{DelegatorAddress: repAcc.String(), ValidatorAddress: valAddr.String()}) require.NoError(err) - // delegation shares should increase after reporting and escrow balance should go nback to 0 + // delegation shares should increase after reporting and escrow balance should go back to 0 delAfter, err := s.stakingKeeper.Delegation(s.ctx, repAcc.Bytes(), valAddr) s.Nil(err) s.True(delAfter.GetShares().Equal(delBefore.GetShares().Add(math.LegacyNewDec(980))), "delegation shares plus the tip added") // 1000 - 2% tip diff --git a/tests/setup.go b/tests/setup.go index bd5d626fd..503586d2c 100644 --- a/tests/setup.go +++ b/tests/setup.go @@ -12,8 +12,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" disputemodulev1 "github.com/tellor-io/layer/api/layer/dispute/module" + mintmodulev1 "github.com/tellor-io/layer/api/layer/mint/module" oraclemodulev1 "github.com/tellor-io/layer/api/layer/oracle/module" - mintmodulev1 "github.com/tellor-io/layer/api/layer/registry/module" registrymodulev1 "github.com/tellor-io/layer/api/layer/registry/module" reportermodulev1 "github.com/tellor-io/layer/api/layer/reporter/module" ) @@ -83,6 +83,9 @@ func RegistryModule() configurator.ModuleOption { func MintModule() configurator.ModuleOption { return func(config *configurator.Config) { + // config.BeginBlockersOrder = append(config.BeginBlockersOrder, "mint") + // config.EndBlockersOrder = append(config.EndBlockersOrder, "mint") + // config.InitGenesisOrder = append(config.InitGenesisOrder, "mint") config.ModuleConfigs["mint"] = &appv1alpha1.ModuleConfig{ Name: "mint", Config: appconfig.WrapAny(&mintmodulev1.Module{}), diff --git a/x/dispute/keeper/execute_test.go b/x/dispute/keeper/execute_test.go new file mode 100644 index 000000000..2d747cbe9 --- /dev/null +++ b/x/dispute/keeper/execute_test.go @@ -0,0 +1,7 @@ +package keeper_test + +func (s *KeeperTestSuite) TestRewardVoters() { + // require := s.Require() + + // s.disputeKeeper.RewardVoters(s.ctx, ) +} diff --git a/x/mint/abci.go b/x/mint/abci.go index 26cb9016e..17207ed25 100644 --- a/x/mint/abci.go +++ b/x/mint/abci.go @@ -4,7 +4,7 @@ import ( "context" "time" - cosmosmath "cosmossdk.io/math" + "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/tellor-io/layer/x/mint/keeper" @@ -18,6 +18,10 @@ func BeginBlocker(ctx context.Context, k keeper.Keeper) error { sdkCtx := sdk.UnwrapSDKContext(ctx) currentTime := sdkCtx.BlockTime() + if currentTime.IsZero() { + // return on invalid block time + return nil + } if err := mintBlockProvision(sdkCtx, k, currentTime); err != nil { return err } @@ -31,14 +35,13 @@ func mintBlockProvision(ctx sdk.Context, k keeper.Keeper, currentTime time.Time) if minter.PreviousBlockTime == nil { return nil } - toMintCoin, err := minter.CalculateBlockProvision(currentTime, *minter.PreviousBlockTime) if err != nil { return err } toMintCoins := sdk.NewCoins(toMintCoin) // mint coins double half going to team and half to oracle - err = k.MintCoins(ctx, toMintCoins.MulInt(cosmosmath.NewInt(2))) + err = k.MintCoins(ctx, toMintCoins.MulInt(math.NewInt(2))) if err != nil { return err } diff --git a/x/mint/module.go b/x/mint/module.go index fbb79a816..2d94bd3a0 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -19,7 +19,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - // mintmodulev1 "github.com/tellor-io/layer/api/layer/mint/module" + mintmodulev1 "github.com/tellor-io/layer/api/layer/mint/module" "github.com/tellor-io/layer/x/mint/keeper" "github.com/tellor-io/layer/x/mint/types" ) @@ -148,13 +148,23 @@ func (am AppModule) BeginBlock(ctx context.Context) error { return BeginBlocker(sdkCtx, am.keeper) } +// ---------------------------------------------------------------------------- +// App Wiring Setup +// ---------------------------------------------------------------------------- + +func init() { + appmodule.Register(&mintmodulev1.Module{}, + appmodule.Provide(ProvideModule)) + +} + type MintInputs struct { depinject.In KvStoreKey *storetypes.KVStoreKey MemStoreKey *storetypes.MemoryStoreKey Cdc codec.Codec - // Config *mintmodulev1.Module + Config *mintmodulev1.Module AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper diff --git a/x/oracle/keeper/cycle_list_test.go b/x/oracle/keeper/cycle_list_test.go new file mode 100644 index 000000000..354bdcf3b --- /dev/null +++ b/x/oracle/keeper/cycle_list_test.go @@ -0,0 +1,88 @@ +package keeper_test + +import ( + oracletypes "github.com/tellor-io/layer/x/oracle/types" +) + +// TODO: fix all of these to match bytes + +func (s *KeeperTestSuite) TestGetCycleList() { + // require := s.Require() + + // list, err := s.oracleKeeper.GetCyclelist(s.ctx) + // require.NoError(err) + // require.Contains(list, ethQueryData[2:]) + // require.Contains(list, btcQueryData[2:]) + // require.Contains(list, trbQueryData[2:]) +} + +func (s *KeeperTestSuite) TestRotateQueries() { + require := s.Require() + + // todo: match the bytes + list, err := s.oracleKeeper.GetCyclelist(s.ctx) + require.NoError(err) + + // first query from cycle list (trb) + firstQuery, err := s.oracleKeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + require.Contains(list, firstQuery) + // require.Equal(firstQuery, trbQueryData[2:]) + + // second query from cycle list (eth) + err = s.oracleKeeper.RotateQueries(s.ctx) + require.NoError(err) + secondQuery, err := s.oracleKeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + require.Contains(list, secondQuery) + // require.Equal(secondQuery, ethQueryData[2:]) + + // third query from cycle list (btc) + err = s.oracleKeeper.RotateQueries(s.ctx) + require.NoError(err) + thirdQuery, err := s.oracleKeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + require.Contains(list, thirdQuery) + // require.Equal(thirdQuery, btcQueryData[2:]) + + // Rotate through a couple times + for i := 0; i < 10; i++ { + query, err := s.oracleKeeper.GetCurrentQueryInCycleList(s.ctx) + require.NoError(err) + err = s.oracleKeeper.RotateQueries(s.ctx) + require.NoError(err) + require.Contains(list, query) + } +} + +func (s *KeeperTestSuite) TestInitCycleListQuery() { + // require := s.Require() + + // startingList, err := s.oracleKeeper.GetCyclelist(s.ctx) + // require.NoError(err) + // require.Contains(startingList, ethQueryData) + // require.Contains(startingList, btcQueryData) + // require.Contains(startingList, trbQueryData) + // newQueryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706f745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657469000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + + // s.oracleKeeper.InitCycleListQuery(s.ctx, []string{newQueryData}) + // newList, err := s.oracleKeeper.GetCyclelist(s.ctx) + // fmt.Println(newList) + // require.NoError(err) + // require.Contains(newList, newQueryData) +} + +func (s *KeeperTestSuite) TestGenesisCycleList() { + require := s.Require() + + err := s.oracleKeeper.GenesisCycleList(s.ctx, oracletypes.InitialCycleList()) + require.NoError(err) + + cycleList, err := s.oracleKeeper.GetCyclelist(s.ctx) + require.NoError(err) + _ = cycleList + // require.Contains(cycleList, ethQueryData[2:]) + // require.Contains(cycleList, btcQueryData[2:]) + // require.Contains(cycleList, trbQueryData[2:]) + +} diff --git a/x/oracle/keeper/keeper_test.go b/x/oracle/keeper/keeper_test.go index 7be724ed7..1a4346993 100644 --- a/x/oracle/keeper/keeper_test.go +++ b/x/oracle/keeper/keeper_test.go @@ -14,6 +14,12 @@ import ( keepertest "github.com/tellor-io/layer/testutil/keeper" ) +const ( + trbQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706f745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003747262000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + ethQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706f745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + btcQueryData = "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706f745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003627463000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" +) + type KeeperTestSuite struct { suite.Suite diff --git a/x/oracle/keeper/msg_server_submit_value_test.go b/x/oracle/keeper/msg_server_submit_value_test.go index 689942486..d7883d64f 100644 --- a/x/oracle/keeper/msg_server_submit_value_test.go +++ b/x/oracle/keeper/msg_server_submit_value_test.go @@ -13,8 +13,9 @@ import ( ) func (s *KeeperTestSuite) TestSubmitValue() (reportertypes.OracleReporter, []byte) { + require := s.Require() value := "000000000000000000000000000000000000000000000058528649cf80ee0000" - // Commit value transaction first + // Commit stakedReporter, salt, queryData := s.TestCommitValue() // forward block by 1 and reveal value s.ctx = s.ctx.WithBlockHeight(s.ctx.BlockHeight() + 1) @@ -29,8 +30,8 @@ func (s *KeeperTestSuite) TestSubmitValue() (reportertypes.OracleReporter, []byt Salt: salt, } res, err := s.msgServer.SubmitValue(s.ctx, &submitreq) - s.Nil(err) - s.Equal(&types.MsgSubmitValueResponse{}, res) + require.NoError(err) + require.Equal(&types.MsgSubmitValueResponse{}, res) queryId := utils.QueryIDFromData(queryData) report, err := s.queryClient.GetReportsbyQid(s.ctx, &types.QueryGetReportsbyQidRequest{QueryId: queryId}) @@ -52,7 +53,7 @@ func (s *KeeperTestSuite) TestSubmitValue() (reportertypes.OracleReporter, []byt MicroReports: []*types.MicroReport{µReport}, }, } - s.Equal(&expectedReport, report) + require.Equal(&expectedReport, report) return stakedReporter, queryId } diff --git a/x/oracle/keeper/msg_server_tip_test.go b/x/oracle/keeper/msg_server_tip_test.go new file mode 100644 index 000000000..e14c6b3b3 --- /dev/null +++ b/x/oracle/keeper/msg_server_tip_test.go @@ -0,0 +1,74 @@ +package keeper_test + +func (s *KeeperTestSuite) TestTip() { + // require := s.Require() + + // queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // tip := sdk.NewCoin("loya", math.NewInt(1000)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: queryData, + // Amount: tip, + // } + // _, err := s.msgServer.Tip(s.ctx, &msg) + // require.NoError(err) + +} + +func (s *KeeperTestSuite) TestTipWithInvalidDenom() { + // require := s.Require() + + // queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // tip := sdk.NewCoin("invalidDenom", math.NewInt(1000)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: queryData, + // Amount: tip, + // } + // _, err := s.msgServer.Tip(s.ctx, &msg) + // require.ErrorContains(err, "invalid request") +} + +func (s *KeeperTestSuite) TestTipWithZeroAmount() { + // require := s.Require() + + // queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // tip := sdk.NewCoin("loya", math.NewInt(0)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: queryData, + // Amount: tip, + // } + // _, err := s.msgServer.Tip(s.ctx, &msg) + // require.ErrorContains(err, "invalid request") +} + +func (s *KeeperTestSuite) TestTipWithNegativeAmount() { + // require := s.Require() + + // queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // require.Panics(func() { + // tip := sdk.NewCoin("loya", math.NewInt(-1000)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: queryData, + // Amount: tip, + // } + // _, _ = s.msgServer.Tip(s.ctx, &msg) + // }, "negative coin amount should panic") +} + +func (s *KeeperTestSuite) TestTipWithInvalidQueryData() { + // require := s.Require() + + // queryData := "badQueryData" + // tip := sdk.NewCoin("loya", math.NewInt(1000)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: queryData, + // Amount: tip, + // } + // _, err := s.msgServer.Tip(s.ctx, &msg) + // require.Error(err) + // require.Panics(func() { _, _ = s.msgServer.Tip(s.ctx, &msg) }, "invalid query data should panic") +} diff --git a/x/oracle/keeper/query_get_aggregated_report_test.go b/x/oracle/keeper/query_get_aggregated_report_test.go new file mode 100644 index 000000000..5fe9d7ee6 --- /dev/null +++ b/x/oracle/keeper/query_get_aggregated_report_test.go @@ -0,0 +1,110 @@ +package keeper_test + +import ( + "encoding/hex" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/tellor-io/layer/x/oracle/types" +) + +func (s *KeeperTestSuite) TestQueryGetAggregatedReport() { + // require := s.Require() + + // queryId, err := utils.QueryIDFromDataString(ethQueryData) + // s.NoError(err) + // aggregate, err := s.oracleKeeper.GetCurrentValueForQueryId(s.ctx, queryId) + // require.NoError(err) + // fmt.Println(aggregate) + + // s.TestSubmitValue() + // aggregate, err = s.oracleKeeper.GetCurrentValueForQueryId(s.ctx, queryId) + // require.NoError(err) + // fmt.Println(aggregate) + + // aggReportRequest := &types.QueryGetCurrentAggregatedReportRequest{ + // QueryId: hex.EncodeToString(queryId), + // } + + // response, err := s.oracleKeeper.GetAggregatedReport(s.ctx, aggReportRequest) + // require.NoError(err) + // require.NotNil(response) + // // get validator info for expectedAggregate + // validatorData, err := s.stakingKeeper.Validator(s.ctx, sdk.ValAddress(Addr.String())) + // require.Nil(err) + // valTokens := validatorData.GetBondedTokens() + // // get queryID + // queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // queryDataBytes, err := hex.DecodeString(queryData[2:]) + // require.Nil(err) + // queryIdBytes := crypto.Keccak256(queryDataBytes) + // queryId := hex.EncodeToString(queryIdBytes) + // // submit and set aggregated report + // s.TestSubmitValue() + // // todo: use proper variables instead of mock.Anything + // s.accountKeeper.On("GetAccount", mock.Anything, mock.Anything).Return(Addr) + // s.accountKeeper.On("GetModuleAccount", mock.Anything, mock.Anything).Return(authtypes.NewEmptyModuleAccount("oracle")) + // s.bankKeeper.On("GetBalance", mock.Anything, mock.Anything, mock.Anything).Return(sdk.Coin{Denom: "loya", Amount: valTokens}) + // s.distrKeeper.On("AllocateTokensToValidator", mock.Anything, mock.Anything, mock.Anything).Return(nil) + // s.bankKeeper.On("SendCoinsFromModuleToModule", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) + // s.oracleKeeper.SetAggregatedReport(s.ctx) + + // expectedAggregate := types.Aggregate{ + // QueryId: queryId, + // AggregateValue: "000000000000000000000000000000000000000000000058528649cf80ee0000", + // AggregateReporter: Addr.String(), + // ReporterPower: validatorData.GetConsensusPower(sdk.DefaultPowerReduction), + // StandardDeviation: 0, + // Reporters: []*types.AggregateReporter{ + // { + // Reporter: Addr.String(), + // Power: validatorData.GetConsensusPower(sdk.DefaultPowerReduction), + // }, + // }, + // Flagged: false, + // Nonce: 1, + // AggregateReportIndex: 0, + // } + + // aggregate, err := s.oracleKeeper.GetAggregatedReport(s.ctx, &types.QueryGetCurrentAggregatedReportRequest{QueryId: queryId}) + // require.Nil(err) + // require.Equal(expectedAggregate.AggregateReporter, aggregate.Report.AggregateReporter) + // require.Equal(expectedAggregate.AggregateValue, aggregate.Report.AggregateValue) + // require.Equal(expectedAggregate.QueryId, aggregate.Report.QueryId) + // require.Equal(expectedAggregate.Reporters, aggregate.Report.Reporters) + // require.Equal(expectedAggregate.StandardDeviation, aggregate.Report.StandardDeviation) + // require.Equal(expectedAggregate.Flagged, aggregate.Report.Flagged) + // require.Equal(expectedAggregate.Nonce, aggregate.Report.Nonce) + // require.Equal(expectedAggregate.AggregateReportIndex, aggregate.Report.AggregateReportIndex) + +} + +func (s *KeeperTestSuite) TestQueryGetAggregatedReportNilRequest() { + require := s.Require() + + _, err := s.oracleKeeper.GetAggregatedReport(s.ctx, nil) + require.ErrorContains(err, "invalid request") +} + +// func (s *KeeperTestSuite) TestQueryGetAggregatedReportInvalidQueryId() { +// require := s.Require() +// require.Panics(func() { +// s.oracleKeeper.GetAggregatedReport(s.ctx, &types.QueryGetCurrentAggregatedReportRequest{QueryId: "invalidQueryID"}) +// }, "invalid queryID") +// } + +func (s *KeeperTestSuite) TestQueryGetAggregatedReportNoAvailableTimestamps() { + require := s.Require() + + // get queryID + queryData := "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + queryDataBytes, err := hex.DecodeString(queryData[2:]) + require.Nil(err) + queryIdBytes := crypto.Keccak256(queryDataBytes) + // queryId := hex.EncodeToString(queryIdBytes) + // submit without setting aggregate report + s.TestSubmitValue() + + _, err = s.oracleKeeper.GetAggregatedReport(s.ctx, &types.QueryGetCurrentAggregatedReportRequest{QueryId: queryIdBytes}) + require.ErrorContains(err, "no available reports") + +} diff --git a/x/oracle/keeper/query_get_current_tip_test.go b/x/oracle/keeper/query_get_current_tip_test.go new file mode 100644 index 000000000..c741e8052 --- /dev/null +++ b/x/oracle/keeper/query_get_current_tip_test.go @@ -0,0 +1,55 @@ +package keeper_test + +func (s *KeeperTestSuite) TestGetCurrentTip() { + // require := s.Require() + + // // tip trb + // amount := sdk.NewCoin("loya", math.NewInt(1000)) + // msg := types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: trbQueryData, + // Amount: amount, + // } + // _, err := s.msgServer.Tip(s.ctx, &msg) + // require.Nil(err) + + // // get trb tips + // tipRequest := &types.QueryGetCurrentTipRequest{ + // QueryData: trbQueryData, + // } + // trbTips, err := s.oracleKeeper.GetCurrentTip(s.ctx, tipRequest) + // require.Nil(err) + // require.Equal(trbQueryData, trbTips.Tips.QueryData) + // twoPercent := sdk.NewCoin("loya", amount.Amount.Mul(math.NewInt(2)).Quo(math.NewInt(100))) + // require.Equal(amount.Sub(twoPercent), trbTips.Tips.Amount) + + // // get btc tips (none) + // btcTips, err := s.oracleKeeper.GetCurrentTip(s.ctx, &types.QueryGetCurrentTipRequest{QueryData: btcQueryData}) + // require.Nil(err) + // require.Equal(btcQueryData, btcTips.Tips.QueryData) + // zeroAmount := sdk.NewCoin("loya", math.NewInt(0)) + // require.Equal(zeroAmount, btcTips.Tips.Amount) + // require.Equal(btcTips.Tips.Amount.Denom, "loya") + + // //tip trb again + // amount = sdk.NewCoin("loya", math.NewInt(10000)) + // msg = types.MsgTip{ + // Tipper: Addr.String(), + // QueryData: trbQueryData, + // Amount: amount, + // } + // _, err = s.msgServer.Tip(s.ctx, &msg) + // require.Nil(err) + // trbTips2, err := s.oracleKeeper.GetCurrentTip(s.ctx, tipRequest) + // require.Nil(err) + // trbTipTotal := sdk.NewCoin("loya", (math.NewInt(10780))) + // require.Equal(trbTipTotal, trbTips2.Tips.Amount) + // require.Equal(trbQueryData, trbTips2.Tips.QueryData) + // require.Equal(trbTips2.Tips.Amount.Denom, "loya") + +} + +func (s *KeeperTestSuite) TestGetCurrentTipInvalidRequest() { + _, err := s.oracleKeeper.GetCurrentTip(s.ctx, nil) + s.ErrorContains(err, "invalid request") +} diff --git a/x/oracle/keeper/query_get_data_before_test.go b/x/oracle/keeper/query_get_data_before_test.go new file mode 100644 index 000000000..ffbaa3b84 --- /dev/null +++ b/x/oracle/keeper/query_get_data_before_test.go @@ -0,0 +1,26 @@ +package keeper_test + +func (s *KeeperTestSuite) TestGetDataBefore() { + // require := s.Require() + + // s.TestSubmitValue() + // queryData := "00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000953706F745072696365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000003657468000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000037573640000000000000000000000000000000000000000000000000000000000" + // queryDataBytes, err := hex.DecodeString(queryData) + // fmt.Println("queryDataBytes: ", queryDataBytes) + // require.Nil(err) + // queryIdBytes := crypto.Keccak256(queryDataBytes) + // fmt.Println("queryIdBytes: ", queryIdBytes) + // queryId := hex.EncodeToString(queryIdBytes) + // fmt.Println("queryId: ", queryId) + // test := crypto.Keccak256([]byte(queryData)) + // fmt.Println("test: ", test) + // queryGetDataBeforeRequest := &types.QueryGetDataBeforeRequest{ + // QueryId: queryId, + // Timestamp: s.ctx.BlockTime().Unix() + 100, + // } + // s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(101)) + // data, err := s.oracleKeeper.GetDataBefore(s.ctx, queryGetDataBeforeRequest) + // require.Nil(err) + // fmt.Println(data) + +} diff --git a/x/oracle/module.go b/x/oracle/module.go index b8f8ff36e..49fb3ff21 100644 --- a/x/oracle/module.go +++ b/x/oracle/module.go @@ -28,8 +28,10 @@ import ( ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ appmodule.HasBeginBlocker = AppModule{} + _ appmodule.HasEndBlocker = AppModule{} ) // ---------------------------------------------------------------------------- diff --git a/x/registry/types/decoding.go b/x/registry/types/decoding.go index 46ff657be..ad989d376 100644 --- a/x/registry/types/decoding.go +++ b/x/registry/types/decoding.go @@ -9,11 +9,11 @@ import ( ) func IsValueDecodable(value, datatype string) error { - result, err := DecodeValue(value, datatype) + _, err := DecodeValue(value, datatype) if err != nil { return fmt.Errorf("failed to unpack value: %v", err) } - fmt.Println("Decoded value: ", result[0]) + // fmt.Println("Decoded value: ", result[0]) todo: do we still need this ? return nil } diff --git a/x/reporter/keeper/distribution.go b/x/reporter/keeper/distribution.go index 053e77dc9..9625d9e05 100644 --- a/x/reporter/keeper/distribution.go +++ b/x/reporter/keeper/distribution.go @@ -740,6 +740,7 @@ func (k Keeper) AfterDelegationModified(ctx context.Context, delAddr sdk.AccAddr if err != nil { return err } + return k.initializeDelegation(ctx, reporterVal, delAddr, stake) } diff --git a/x/reporter/keeper/reporter.go b/x/reporter/keeper/reporter.go index 81c44a7f5..a1c33b8c1 100644 --- a/x/reporter/keeper/reporter.go +++ b/x/reporter/keeper/reporter.go @@ -43,10 +43,13 @@ func (k Keeper) ValidateAndSetAmount(ctx context.Context, delegator sdk.AccAddre if err != nil { return err } - // check if the validator has enough tokens bonded with validator, this would be the sum + // check if the delegator has enough tokens bonded with validator, this would be the sum // of what is currently delegated to reporter plus the amount being added in this transaction + // todo: further documentation + // LTE doesnt work ? sum := tokenSource.Add(origin.Amount) - if validator.TokensFromShares(delegation.GetShares()).TruncateInt().LT(sum) { + tokensFromShares := validator.TokensFromShares(delegation.GetShares()).TruncateInt() + if tokensFromShares.LT(sum) { return errorsmod.Wrapf(types.ErrInsufficientTokens, "insufficient tokens bonded with validator %v", valAddr) } tokenSource = sum diff --git a/x/reporter/keeper/withdraw.go b/x/reporter/keeper/withdraw.go index 8a501812b..9a30110ba 100644 --- a/x/reporter/keeper/withdraw.go +++ b/x/reporter/keeper/withdraw.go @@ -9,7 +9,6 @@ import ( "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - layer "github.com/tellor-io/layer/types" layertypes "github.com/tellor-io/layer/types" disputetypes "github.com/tellor-io/layer/x/dispute/types" "github.com/tellor-io/layer/x/reporter/types" @@ -237,5 +236,5 @@ func (k Keeper) EscrowReporterStake(ctx context.Context, reporterAddr sdk.AccAdd } func (k Keeper) tokensToDispute(ctx context.Context, fromPool string, amount math.Int) error { - return k.bankKeeper.SendCoinsFromModuleToModule(ctx, fromPool, disputetypes.ModuleName, sdk.NewCoins(sdk.NewCoin(layer.BondDenom, amount))) + return k.bankKeeper.SendCoinsFromModuleToModule(ctx, fromPool, disputetypes.ModuleName, sdk.NewCoins(sdk.NewCoin(layertypes.BondDenom, amount))) }