Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Contains all the PRs that improved the code without changing the behaviours.

- [#267](https://github.com/archway-network/archway/pull/267) - update `querySrvr.EstimateTxFees` to also consider contract flat fee when returning the estimated fees.
- [#271](https://github.com/archway-network/archway/pull/271) - update the x/rewards/min_cons_fee antehandler to check for contract flat fees
- [#275](https://github.com/archway-network/archway/pull/275) - update the x/rewards/genesis to import/export for contract flat fees

## [v0.1.0]

Expand Down
4 changes: 4 additions & 0 deletions proto/archway/rewards/v1beta1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ message GenesisState {
repeated RewardsRecord rewards_records = 7 [
(gogoproto.nullable) = false
];
// flat_fees defines a list of contract flat fee.
repeated FlatFee flat_fees = 8 [
(gogoproto.nullable) = false
];
}
10 changes: 10 additions & 0 deletions proto/archway/rewards/v1beta1/rewards.proto
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,13 @@ message RewardsRecord {
(gogoproto.stdtime) = true
];
}

// FlatFee defines the flat fee for a particular contract.
message FlatFee {
option (gogoproto.goproto_stringer) = false;

// contract_address defines the contract address (bech32 encoded).
string contract_address = 1;
// flat_fee defines the minimum flat fee set by the contract_owner
cosmos.base.v1beta1.Coin flat_fee = 2 [ (gogoproto.nullable) = false ];
}
2 changes: 2 additions & 0 deletions x/rewards/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
minConsFee,
rewardsRecordLastID,
rewardsRecords,
k.state.FlatFee(ctx).Export(),
)
}

Expand All @@ -30,6 +31,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state *types.GenesisState) {
k.state.BlockRewardsState(ctx).Import(state.BlockRewards)
k.state.TxRewardsState(ctx).Import(state.TxRewards)
k.state.RewardsRecord(ctx).Import(state.RewardsRecordLastId, state.RewardsRecords)
k.state.FlatFee(ctx).Import(state.FlatFees)

if !pkg.DecCoinIsZero(state.MinConsensusFee) && !pkg.DecCoinIsNegative(state.MinConsensusFee) {
k.state.MinConsensusFee(ctx).SetFee(state.MinConsensusFee)
Expand Down
15 changes: 15 additions & 0 deletions x/rewards/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func (s *KeeperTestSuite) TestGenesisImportExport() {
s.Assert().Empty(genesisState.TxRewards)
s.Assert().Empty(genesisState.RewardsRecordLastId)
s.Assert().Empty(genesisState.RewardsRecords)
s.Assert().Empty(genesisState.FlatFees)

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

newFlatFees := []types.FlatFee{
{
ContractAddress: contractAddrs[0].String(),
FlatFee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)),
},
{
ContractAddress: contractAddrs[1].String(),
FlatFee: sdk.NewCoin("uarch", sdk.NewInt(1)),
},
}

genesisStateImported := types.NewGenesisState(
newParams,
newMetadata,
Expand All @@ -107,6 +119,7 @@ func (s *KeeperTestSuite) TestGenesisImportExport() {
newMinConsFee,
newRewardsRecords[len(newRewardsRecords)-1].Id,
newRewardsRecords,
newFlatFees,
)
s.Run("Check import of an updated genesis", func() {
keeper.InitGenesis(ctx, genesisStateImported)
Expand All @@ -119,6 +132,7 @@ func (s *KeeperTestSuite) TestGenesisImportExport() {
MinConsensusFee: newMinConsFee,
RewardsRecordLastId: newRewardsRecords[len(newRewardsRecords)-1].Id,
RewardsRecords: append(genesisStateInitial.RewardsRecords, newRewardsRecords...),
FlatFees: append(genesisStateInitial.FlatFees, newFlatFees...),
}

genesisStateReceived := keeper.ExportGenesis(ctx)
Expand All @@ -130,5 +144,6 @@ func (s *KeeperTestSuite) TestGenesisImportExport() {
s.Assert().Equal(genesisStateExpected.MinConsensusFee.String(), genesisStateReceived.MinConsensusFee.String())
s.Assert().Equal(genesisStateExpected.RewardsRecordLastId, genesisStateReceived.RewardsRecordLastId)
s.Assert().ElementsMatch(genesisStateExpected.RewardsRecords, genesisStateReceived.RewardsRecords)
s.Assert().ElementsMatch(genesisStateExpected.FlatFees, genesisStateReceived.FlatFees)
})
}
39 changes: 39 additions & 0 deletions x/rewards/keeper/state_flatfee.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package keeper

import (
"fmt"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storeTypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkErrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/archway-network/archway/x/rewards/types"
)
Expand Down Expand Up @@ -44,3 +47,39 @@ func (s FlatFeeState) RemoveFee(contractAddr sdk.AccAddress) {
store := prefix.NewStore(s.stateStore, types.FlatFeePrefix)
store.Delete(contractAddr.Bytes())
}

// Import initializes state from the genesis flat fees data.
func (s FlatFeeState) Import(flatFees []types.FlatFee) {
for _, flatFee := range flatFees {
contractAddr := flatFee.MustGetContractAddress()
fee := flatFee.GetFlatFee()

if !fee.Amount.IsPositive() {
panic(fmt.Sprintf("flat fee: %+v is invalid, err: %s", flatFee, sdkErrors.ErrInvalidCoins))
Comment thread
fdymylja marked this conversation as resolved.
Outdated
}

s.SetFee(contractAddr, fee)
}
}

// Export returns the flat fees genesis data for the state.
func (s FlatFeeState) Export() []types.FlatFee {
store := prefix.NewStore(s.stateStore, types.FlatFeePrefix)

iterator := store.Iterator(nil, nil)
defer iterator.Close()

var fees = make([]types.FlatFee, 0)
for ; iterator.Valid(); iterator.Next() {
var coin sdk.Coin
contractAddr := sdk.AccAddress(iterator.Key())
s.cdc.MustUnmarshal(iterator.Value(), &coin)

fees = append(fees, types.FlatFee{
ContractAddress: contractAddr.String(),
FlatFee: coin,
})
}

return fees
}
33 changes: 33 additions & 0 deletions x/rewards/keeper/state_flatfee_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package keeper_test

import (
sdk "github.com/cosmos/cosmos-sdk/types"

e2eTesting "github.com/archway-network/archway/e2e/testing"
rewardsTypes "github.com/archway-network/archway/x/rewards/types"
)

// TestFlatFeeImportExport check flat fees import/export.
// Test updates the initial state with new records and checks that they were merged.
func (s *KeeperTestSuite) TestFlatFeeImportExport() {
ctx, keeper := s.chain.GetContext(), s.chain.GetApp().RewardsKeeper
contractAddrs := e2eTesting.GenContractAddresses(2)

newFlatFees := []rewardsTypes.FlatFee{
{
ContractAddress: contractAddrs[0].String(),
FlatFee: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100)),
},
{
ContractAddress: contractAddrs[1].String(),
FlatFee: sdk.NewCoin("uarch", sdk.NewInt(1)),
},
}

s.Run("Check import export of flat fees", func() {
keeper.GetState().FlatFee(ctx).Import(newFlatFees)
exportedFlatFees := keeper.GetState().FlatFee(ctx).Export()
s.Require().NotNil(exportedFlatFees)
s.Assert().ElementsMatch(newFlatFees, exportedFlatFees)
})
}
19 changes: 19 additions & 0 deletions x/rewards/types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ func NewGenesisState(
minConsFee sdk.DecCoin,
rewardsRecordLastID uint64,
rewardsRecords []RewardsRecord,
flatFees []FlatFee,
) *GenesisState {
return &GenesisState{
Params: params,
Expand All @@ -25,6 +26,7 @@ func NewGenesisState(
MinConsensusFee: minConsFee,
RewardsRecordLastId: rewardsRecordLastID,
RewardsRecords: rewardsRecords,
FlatFees: flatFees,
}
}

Expand All @@ -38,6 +40,7 @@ func DefaultGenesisState() *GenesisState {
MinConsensusFee: sdk.DecCoin{},
RewardsRecordLastId: 0,
RewardsRecords: []RewardsRecord{},
FlatFees: []FlatFee{},
}
}

Expand Down Expand Up @@ -110,5 +113,21 @@ func (m GenesisState) Validate() error {
return fmt.Errorf("rewardsRecordLastId: %d < max RewardsRecord ID (%d)", m.RewardsRecordLastId, rewardsRecordIDMax)
}

flatFeeSet := make(map[string]struct{})
for i, fee := range m.FlatFees {
if _, ok := contractAddrSet[fee.ContractAddress]; !ok {
return fmt.Errorf("flat fee: %+v is invalid, err: contract metadata not found", fee)
}

if err := fee.Validate(); err != nil {
return fmt.Errorf("flatFee [%d]: %w", i, err)
}

if _, ok := flatFeeSet[fee.ContractAddress]; ok {
return fmt.Errorf("flatFee [%d]: duplicated contract address: %s", i, fee.ContractAddress)
}
flatFeeSet[fee.ContractAddress] = struct{}{}
}

return nil
}
122 changes: 94 additions & 28 deletions x/rewards/types/genesis.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading