Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ func NewArchwayApp(
authtypes.ModuleName,
banktypes.ModuleName,
govtypes.ModuleName,
crisistypes.ModuleName,
crisistypes.ModuleName, // doesn't have BeginBlocker, so order is not important
genutiltypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
Expand Down Expand Up @@ -658,7 +658,6 @@ func NewArchwayApp(
slashingtypes.ModuleName,
govtypes.ModuleName,
minttypes.ModuleName,
crisistypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
authz.ModuleName,
Expand All @@ -674,6 +673,8 @@ func NewArchwayApp(
// wasm gas tracking
trackingTypes.ModuleName,
rewardsTypes.ModuleName,
// invariants checks are always the last to run
crisistypes.ModuleName,
)

// Uncomment if you want to set a custom migration order here.
Expand Down
5 changes: 4 additions & 1 deletion docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ GenesisState defines the initial state of the tracking module.
| `block_rewards` | [BlockRewards](#archway.rewards.v1beta1.BlockRewards) | repeated | block_rewards defines a list of all block rewards objects. |
| `tx_rewards` | [TxRewards](#archway.rewards.v1beta1.TxRewards) | repeated | tx_rewards defines a list of all tx rewards objects. |
| `min_consensus_fee` | [cosmos.base.v1beta1.DecCoin](#cosmos.base.v1beta1.DecCoin) | | min_consensus_fee defines the minimum gas unit price. |
| `rewards_record_last_id` | [uint64](#uint64) | | rewards_record_last_id defines the last unique ID for a RewardsRecord objs. |
| `rewards_records` | [RewardsRecord](#archway.rewards.v1beta1.RewardsRecord) | repeated | rewards_records defines a list of all active (undistributed) rewards records. |


Expand Down Expand Up @@ -586,7 +587,7 @@ MsgWithdrawRewards is the request for Msg.WithdrawRewards.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `rewards_address` | [string](#string) | | rewards_address is the address to distribute rewards to (bech32 encoded). |
| `records_limit` | [MsgWithdrawRewards.RecordsLimit](#archway.rewards.v1beta1.MsgWithdrawRewards.RecordsLimit) | | records_limit defines the maximum number of RewardsRecord objects to process. If provided limit is 0, the default limit is used (the max_withdraw_records module parameter value). |
| `records_limit` | [MsgWithdrawRewards.RecordsLimit](#archway.rewards.v1beta1.MsgWithdrawRewards.RecordsLimit) | | records_limit defines the maximum number of RewardsRecord objects to process. If provided limit is 0, the default limit is used. |
| `record_ids` | [MsgWithdrawRewards.RecordIDs](#archway.rewards.v1beta1.MsgWithdrawRewards.RecordIDs) | | record_ids defines specific RewardsRecord object IDs to process. |


Expand Down Expand Up @@ -779,7 +780,9 @@ GenesisState defines the initial state of the tracking module.

| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `tx_info_last_id` | [uint64](#uint64) | | tx_info_last_id defines the last unique ID for a TxInfo objs. |
| `tx_infos` | [TxInfo](#archway.tracking.v1beta1.TxInfo) | repeated | tx_infos defines a list of all the tracked transactions. |
| `contract_op_info_last_id` | [uint64](#uint64) | | contract_op_info_last_id defines the last unique ID for ContractOperationInfo objs. |
| `contract_op_infos` | [ContractOperationInfo](#archway.tracking.v1beta1.ContractOperationInfo) | repeated | contract_op_infos defines a list of all the tracked contract operations. |


Expand Down
4 changes: 3 additions & 1 deletion proto/archway/rewards/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ message GenesisState {
cosmos.base.v1beta1.DecCoin min_consensus_fee = 5 [
(gogoproto.nullable) = false
];
// rewards_record_last_id defines the last unique ID for a RewardsRecord objs.
uint64 rewards_record_last_id = 6;
// rewards_records defines a list of all active (undistributed) rewards records.
repeated RewardsRecord rewards_records = 6 [
repeated RewardsRecord rewards_records = 7 [
(gogoproto.nullable) = false
];
}
6 changes: 5 additions & 1 deletion proto/archway/tracking/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import "archway/tracking/v1beta1/tracking.proto";

// GenesisState defines the initial state of the tracking module.
message GenesisState {
// tx_info_last_id defines the last unique ID for a TxInfo objs.
uint64 tx_info_last_id = 1;
// tx_infos defines a list of all the tracked transactions.
repeated TxInfo tx_infos = 2 [
(gogoproto.nullable) = false
];
// contract_op_info_last_id defines the last unique ID for ContractOperationInfo objs.
uint64 contract_op_info_last_id = 3;
// contract_op_infos defines a list of all the tracked contract operations.
repeated ContractOperationInfo contract_op_infos = 3 [
repeated ContractOperationInfo contract_op_infos = 4 [
(gogoproto.nullable) = false
];
}
6 changes: 4 additions & 2 deletions x/rewards/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ import (
// ExportGenesis exports the module genesis for the current block.
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
minConsFee, _ := k.state.MinConsensusFee(ctx).GetFee() // default sdk.Coin value is ok
rewardsRecordLastID, rewardsRecords := k.state.RewardsRecord(ctx).Export()

return types.NewGenesisState(
k.GetParams(ctx),
k.state.ContractMetadataState(ctx).Export(),
k.state.BlockRewardsState(ctx).Export(),
k.state.TxRewardsState(ctx).Export(),
minConsFee,
k.state.RewardsRecord(ctx).Export(),
rewardsRecordLastID,
rewardsRecords,
)
}

Expand All @@ -27,7 +29,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) {
k.state.ContractMetadataState(ctx).Import(state.ContractsMetadata)
k.state.BlockRewardsState(ctx).Import(state.BlockRewards)
k.state.TxRewardsState(ctx).Import(state.TxRewards)
k.state.RewardsRecord(ctx).Import(state.RewardsRecords)
k.state.RewardsRecord(ctx).Import(state.RewardsRecordLastId, state.RewardsRecords)

if !pkg.DecCoinIsZero(state.MinConsensusFee) {
k.state.MinConsensusFee(ctx).SetFee(state.MinConsensusFee)
Expand Down
27 changes: 19 additions & 8 deletions x/rewards/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

// TestGenesisImportExport check genesis import/export.
// Test updates the initial state with new records and checks that they were merged.
func (s KeeperTestSuite) TestGenesisImportExport() {
func (s *KeeperTestSuite) TestGenesisImportExport() {
ctx, keeper := s.chain.GetContext(), s.chain.GetApp().RewardsKeeper

contractAddrs := e2eTesting.GenContractAddresses(2)
Expand All @@ -26,6 +26,7 @@ func (s KeeperTestSuite) TestGenesisImportExport() {
s.Assert().Empty(genesisState.ContractsMetadata)
s.Assert().NotEmpty(genesisState.BlockRewards) // height is 2 so we have some inflation rewards already
s.Assert().Empty(genesisState.TxRewards)
s.Assert().Empty(genesisState.RewardsRecordLastId)
s.Assert().Empty(genesisState.RewardsRecords)

genesisStateInitial = *genesisState
Expand Down Expand Up @@ -98,17 +99,26 @@ func (s KeeperTestSuite) TestGenesisImportExport() {
},
}

genesisStateImported := types.NewGenesisState(newParams, newMetadata, newBlockRewards, newTxRewards, newMinConsFee, newRewardsRecords)
genesisStateImported := types.NewGenesisState(
newParams,
newMetadata,
newBlockRewards,
newTxRewards,
newMinConsFee,
newRewardsRecords[len(newRewardsRecords)-1].Id,
newRewardsRecords,
)
s.Run("Check import of an updated genesis", func() {
keeper.InitGenesis(ctx, genesisStateImported)

genesisStateExpected := types.GenesisState{
Params: newParams,
ContractsMetadata: append(genesisStateInitial.ContractsMetadata, newMetadata...),
BlockRewards: append(genesisStateInitial.BlockRewards, newBlockRewards...),
TxRewards: append(genesisStateInitial.TxRewards, newTxRewards...),
MinConsensusFee: newMinConsFee,
RewardsRecords: append(genesisStateInitial.RewardsRecords, newRewardsRecords...),
Params: newParams,
ContractsMetadata: append(genesisStateInitial.ContractsMetadata, newMetadata...),
BlockRewards: append(genesisStateInitial.BlockRewards, newBlockRewards...),
TxRewards: append(genesisStateInitial.TxRewards, newTxRewards...),
MinConsensusFee: newMinConsFee,
RewardsRecordLastId: newRewardsRecords[len(newRewardsRecords)-1].Id,
RewardsRecords: append(genesisStateInitial.RewardsRecords, newRewardsRecords...),
}

genesisStateReceived := keeper.ExportGenesis(ctx)
Expand All @@ -118,6 +128,7 @@ func (s KeeperTestSuite) TestGenesisImportExport() {
s.Assert().ElementsMatch(genesisStateExpected.BlockRewards, genesisStateReceived.BlockRewards)
s.Assert().ElementsMatch(genesisStateExpected.TxRewards, genesisStateReceived.TxRewards)
s.Assert().Equal(genesisStateExpected.MinConsensusFee.String(), genesisStateReceived.MinConsensusFee.String())
s.Assert().Equal(genesisStateExpected.RewardsRecordLastId, genesisStateReceived.RewardsRecordLastId)
s.Assert().ElementsMatch(genesisStateExpected.RewardsRecords, genesisStateReceived.RewardsRecords)
})
}
3 changes: 2 additions & 1 deletion x/rewards/keeper/invariants.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ func ModuleAccountBalanceInvariant(k Keeper) sdk.Invariant {
poolCurrent := k.UndistributedRewardsPool(ctx)

poolExpected := sdk.NewCoins()
for _, record := range k.state.RewardsRecord(ctx).Export() {
_, records := k.state.RewardsRecord(ctx).Export()
for _, record := range records {
poolExpected = poolExpected.Add(record.Rewards...)
}

Expand Down
9 changes: 8 additions & 1 deletion x/rewards/keeper/invariants_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,14 @@ func TestRewardsModuleAccountInvariant(t *testing.T) {
}

// Store rewards records
chain.GetApp().RewardsKeeper.GetState().RewardsRecord(ctx).Import(tc.rewardsRecords)
recordLastID := uint64(0)
for _, record := range tc.rewardsRecords {
if record.Id > recordLastID {
recordLastID = record.Id
}
}

chain.GetApp().RewardsKeeper.GetState().RewardsRecord(ctx).Import(recordLastID, tc.rewardsRecords)

// Check invariant
_, brokenReceived := keeper.ModuleAccountBalanceInvariant(chain.GetApp().RewardsKeeper)(ctx)
Expand Down
9 changes: 3 additions & 6 deletions x/rewards/keeper/state_rewards_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,16 @@ func (s RewardsRecordState) DeleteRewardsRecords(objs ...types.RewardsRecord) {
}

// Import initializes state from the module genesis data.
func (s RewardsRecordState) Import(objs []types.RewardsRecord) {
lastID := uint64(0)
func (s RewardsRecordState) Import(lastID uint64, objs []types.RewardsRecord) {
for _, obj := range objs {
s.setRewardsRecord(&obj)
s.setAddressIndex(obj.Id, obj.MustGetRewardsAddress())
if obj.Id > lastID {
lastID = obj.Id
}
}
s.setLastID(lastID)
}

// Export returns the module genesis data for the state.
func (s RewardsRecordState) Export() (objs []types.RewardsRecord) {
func (s RewardsRecordState) Export() (lastID uint64, objs []types.RewardsRecord) {
store := prefix.NewStore(s.stateStore, types.RewardsRecordPrefix)

iterator := store.Iterator(nil, nil)
Expand All @@ -132,6 +128,7 @@ func (s RewardsRecordState) Export() (objs []types.RewardsRecord) {
s.cdc.MustUnmarshal(iterator.Value(), &obj)
objs = append(objs, obj)
}
lastID = s.getNextID() - 1

return
}
Expand Down
5 changes: 4 additions & 1 deletion x/rewards/keeper/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,10 @@ func (s *KeeperTestSuite) TestStates() {
txState.CreateTxRewards(txRewards.TxId, txRewards.Height, txRewards.FeeRewards)
}
}
rewardsRecordState.Import(testDataExpected.RewardsRecords)
rewardsRecordState.Import(
testDataExpected.RewardsRecords[len(testDataExpected.RewardsRecords)-1].Id,
testDataExpected.RewardsRecords,
)

// Check non-existing records
s.Run("Check non-existing metadata record", func() {
Expand Down
36 changes: 24 additions & 12 deletions x/rewards/types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,31 @@ func NewGenesisState(
contractsMetadata []ContractMetadata,
blockRewards []BlockRewards, txRewards []TxRewards,
minConsFee sdk.DecCoin,
rewardsRecordLastID uint64,
rewardsRecords []RewardsRecord,
) *GenesisState {

return &GenesisState{
Params: params,
ContractsMetadata: contractsMetadata,
BlockRewards: blockRewards,
TxRewards: txRewards,
MinConsensusFee: minConsFee,
RewardsRecords: rewardsRecords,
Params: params,
ContractsMetadata: contractsMetadata,
BlockRewards: blockRewards,
TxRewards: txRewards,
MinConsensusFee: minConsFee,
RewardsRecordLastId: rewardsRecordLastID,
RewardsRecords: rewardsRecords,
}
}

// DefaultGenesisState returns a default genesis state.
func DefaultGenesisState() *GenesisState {
return &GenesisState{
Params: DefaultParams(),
ContractsMetadata: []ContractMetadata{},
BlockRewards: []BlockRewards{},
TxRewards: []TxRewards{},
MinConsensusFee: sdk.DecCoin{},
RewardsRecords: []RewardsRecord{},
Params: DefaultParams(),
ContractsMetadata: []ContractMetadata{},
BlockRewards: []BlockRewards{},
TxRewards: []TxRewards{},
MinConsensusFee: sdk.DecCoin{},
RewardsRecordLastId: 0,
RewardsRecords: []RewardsRecord{},
}
}

Expand Down Expand Up @@ -88,6 +91,7 @@ func (m GenesisState) Validate() error {
}
}

rewardsRecordIDMax := uint64(0)
rewardsRecordsIdSet := make(map[uint64]struct{})
for i, rewardsRecord := range m.RewardsRecords {
if err := rewardsRecord.Validate(); err != nil {
Expand All @@ -96,8 +100,16 @@ func (m GenesisState) Validate() error {
if _, ok := rewardsRecordsIdSet[rewardsRecord.Id]; ok {
return fmt.Errorf("rewardsRecords [%d]: duplicated id: %d", i, rewardsRecord.Id)
}

if rewardsRecord.Id > rewardsRecordIDMax {
rewardsRecordIDMax = rewardsRecord.Id
}
rewardsRecordsIdSet[rewardsRecord.Id] = struct{}{}
}

if m.RewardsRecordLastId < rewardsRecordIDMax {
return fmt.Errorf("rewardsRecordLastId: %d < max RewardsRecord ID (%d)", m.RewardsRecordLastId, rewardsRecordIDMax)
}

return nil
}
Loading