Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: store stake security for finalized bundles #108

Merged
merged 2 commits into from
Jul 12, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

- (ibc) [#30](https://github.com/KYVENetwork/chain/pull/30) Integrate [Packet Forward Middleware](https://github.com/strangelove-ventures/packet-forward-middleware).
- (`x/bundles`) [#99](https://github.com/KYVENetwork/chain/pull/99) Use weighted round-robin approach for uploader selection.
- (`x/bundles`) [#108](https://github.com/KYVENetwork/chain/pull/108) Store stake security for finalized bundles.

### Improvements

Expand Down
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ func NewKYVEApp(
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
app.BundlesKeeper,
),
)

Expand Down
16 changes: 16 additions & 0 deletions app/upgrades/v1_3/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package v1_3
import (
"fmt"

bundlesKeeper "github.com/KYVENetwork/chain/x/bundles/keeper"
bundlesTypes "github.com/KYVENetwork/chain/x/bundles/types"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/tendermint/tendermint/libs/log"
Expand All @@ -29,11 +32,13 @@ func CreateUpgradeHandler(
accountKeeper authKeeper.AccountKeeper,
bankKeeper bankKeeper.Keeper,
stakingKeeper stakingKeeper.Keeper,
bundlesKeeper bundlesKeeper.Keeper,
) upgradeTypes.UpgradeHandler {
return func(ctx sdk.Context, _ upgradeTypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
logger := ctx.Logger().With("upgrade", UpgradeName)

CheckPoolAccounts(ctx, logger, poolKeeper)
UpdateBundlesVersionMap(bundlesKeeper, ctx)

if ctx.ChainID() == MainnetChainID {
for _, address := range InvestorAccounts {
Expand Down Expand Up @@ -92,3 +97,14 @@ func CheckPoolAccounts(ctx sdk.Context, logger log.Logger, keeper poolKeeper.Kee
logger.Info("successfully initialised pool account", "name", name)
}
}

func UpdateBundlesVersionMap(keeper bundlesKeeper.Keeper, ctx sdk.Context) {
keeper.SetBundleVersionMap(ctx, bundlesTypes.BundleVersionMap{
Versions: []*bundlesTypes.BundleVersionEntry{
{
Height: uint64(ctx.BlockHeight()),
Version: 2,
},
},
})
}
8 changes: 5 additions & 3 deletions proto/kyve/bundles/v1beta1/bundles.proto
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ message FinalizedBundle {
uint32 storage_provider_id = 12;
// compression_id the id of the compression type with which the data was compressed
uint32 compression_id = 13;
// stake_security
StakeSecurity stake_security = 14;
}

// FinalizedAt ...
Expand All @@ -101,11 +103,11 @@ message FinalizedAt {
uint64 timestamp = 2;
}

// FinalizedAt ...
// StakeSecurity stores information about total stake and valid votes with which the bundle got finalized.
message StakeSecurity {
// valid_vote_power ...
// valid_vote_power is the total amount of stake of all pool stakers which voted valid for the given bundle.
uint64 valid_vote_power = 1;
// total_vote_power ...
// total_vote_power is the total amount of stake that was present during the finalization of the bundle
uint64 total_vote_power = 2;
}

Expand Down
2 changes: 2 additions & 0 deletions testutil/integration/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ func checkFinalizedBundle(queryBundle querytypes.FinalizedBundle, rawBundle bund
Expect(queryBundle.FromKey).To(Equal(rawBundle.FromKey))
Expect(queryBundle.StorageProviderId).To(Equal(uint64(rawBundle.StorageProviderId)))
Expect(queryBundle.CompressionId).To(Equal(uint64(rawBundle.CompressionId)))
Expect(queryBundle.StakeSecurity.ValidVotePower.Uint64()).To(Equal(rawBundle.StakeSecurity.ValidVotePower))
Expect(queryBundle.StakeSecurity.TotalVotePower.Uint64()).To(Equal(rawBundle.StakeSecurity.TotalVotePower))
}

func (suite *KeeperTestSuite) VerifyBundlesQueries() {
Expand Down
7 changes: 6 additions & 1 deletion x/bundles/keeper/getters_bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,12 @@ func RawBundleToQueryBundle(rawFinalizedBundle types.FinalizedBundle, versionMap
}

// Check for version 2
// TODO will be done by separate PR
if rawFinalizedBundle.FinalizedAt.Height >= versionMap[2] {
validPower := cosmossdk_io_math.NewInt(int64(rawFinalizedBundle.StakeSecurity.ValidVotePower))
totalPower := cosmossdk_io_math.NewInt(int64(rawFinalizedBundle.StakeSecurity.TotalVotePower))
finalizedBundle.StakeSecurity.ValidVotePower = &validPower
finalizedBundle.StakeSecurity.TotalVotePower = &totalPower
}

return finalizedBundle
}
Expand Down
16 changes: 14 additions & 2 deletions x/bundles/keeper/keeper_suite_valid_bundles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(100 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(100 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand Down Expand Up @@ -263,6 +265,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(400 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(400 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand Down Expand Up @@ -401,6 +405,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(200 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(200 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand All @@ -409,7 +415,6 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(bundleProposal.PoolId).To(Equal(uint64(0)))
Expect(bundleProposal.StorageId).To(Equal("P9edn0bjEfMU_lecFDIPLvGO2v2ltpFNUMWp5kgPddg"))
Expect(bundleProposal.Uploader).To(Equal(i.STAKER_0))
// TODO(postAudit,@troy): how to get next uploader deterministically?
Expect(bundleProposal.NextUploader).NotTo(BeEmpty())
Expect(bundleProposal.DataSize).To(Equal(uint64(100)))
Expect(bundleProposal.DataHash).To(Equal("test_hash2"))
Expand Down Expand Up @@ -557,6 +562,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(700 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(700 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand All @@ -565,7 +572,6 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(bundleProposal.PoolId).To(Equal(uint64(0)))
Expect(bundleProposal.StorageId).To(Equal("P9edn0bjEfMU_lecFDIPLvGO2v2ltpFNUMWp5kgPddg"))
Expect(bundleProposal.Uploader).To(Equal(i.STAKER_0))
// TODO(postAudit,@troy): how to get next uploader deterministically?
Expect(bundleProposal.NextUploader).NotTo(BeEmpty())
Expect(bundleProposal.DataSize).To(Equal(uint64(100)))
Expect(bundleProposal.DataHash).To(Equal("test_hash2"))
Expand Down Expand Up @@ -720,6 +726,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(400 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(700 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand Down Expand Up @@ -884,6 +892,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(400 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(700 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand Down Expand Up @@ -1048,6 +1058,8 @@ var _ = Describe("valid bundles", Ordered, func() {
Expect(finalizedBundle.BundleSummary).To(Equal("test_value"))
Expect(finalizedBundle.DataHash).To(Equal("test_hash"))
Expect(finalizedBundle.FinalizedAt).NotTo(BeZero())
Expect(finalizedBundle.StakeSecurity.ValidVotePower).To(Equal(400 * i.KYVE))
Expect(finalizedBundle.StakeSecurity.TotalVotePower).To(Equal(700 * i.KYVE))

// check if next bundle proposal got registered
bundleProposal, bundleProposalFound := s.App().BundlesKeeper.GetBundleProposal(s.Ctx(), 0)
Expand Down
4 changes: 4 additions & 0 deletions x/bundles/keeper/logic_bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ func (k Keeper) finalizeCurrentBundleProposal(ctx sdk.Context, poolId uint64, vo
DataHash: bundleProposal.DataHash,
StorageProviderId: bundleProposal.StorageProviderId,
CompressionId: bundleProposal.CompressionId,
StakeSecurity: &types.StakeSecurity{
ValidVotePower: voteDistribution.Valid,
TotalVotePower: voteDistribution.Total,
},
}

k.SetFinalizedBundle(ctx, finalizedBundle)
Expand Down
20 changes: 18 additions & 2 deletions x/bundles/spec/02_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,29 @@ type FinalizedBundle struct {
ToKey string
BundleSummary string
DataHash string
FinalizedAt uint64
FinalizedAt {
Height uint64
Timestamp uint64
}
FromKey string
StorageProviderId uint32
CompressionId uint32
StakeSecurity {
ValidVotePower uint64
TotalVotePower uint64
}
}
```

### BundleVersionMap

The version map keeps track of which protocol version was present at given
block heights. It is only updated during chain upgrades. It helps the query
handler to probably decode a finalized bundle. Later it might also be important
for on chain computations.

- BundleVersionMap `0x03 -> ProtocolBuffer(BundleVersionMap)`


## Round-Robin
For correctly determining the next uploader the current round-robin
Expand All @@ -89,7 +105,7 @@ type RoundRobinSingleValidatorProgress struct {
RoundRobinProgress stores the current state of the round-robin selection for a
given pool.

- RoundRobinProgress `0x03 | PoolId -> ProtocolBuffer(roundRobinProgress)`
- RoundRobinProgress `0x04 | PoolId -> ProtocolBuffer(roundRobinProgress)`

```go
message RoundRobinProgress {
Expand Down
Loading