From 5e5ec9330f82a64330f28d5f354f400cd8d00258 Mon Sep 17 00:00:00 2001 From: rbajollari Date: Thu, 12 Dec 2024 12:48:43 -0500 Subject: [PATCH] abci logic --- app/app.go | 15 +- app/preblocker.go | 8 + proto/ojo/oracle/v1/abci.proto | 10 + x/oracle/abci/proposal.go | 87 +++++ x/oracle/abci/voteextension.go | 12 + x/oracle/keeper/keeper.go | 3 + x/oracle/types/abci.pb.go | 374 +++++++++++++++++++-- x/oracle/types/block_hash_vote.go | 1 + x/oracle/types/errors.go | 59 ++-- x/oracle/types/expected_keeper.go | 8 + x/symbiotic/abci.go | 2 +- x/symbiotic/keeper/keeper.go | 34 ++ x/symbiotic/keeper/network_state_change.go | 8 +- x/symbiotic/types/expected_keeper.go | 2 + 14 files changed, 558 insertions(+), 65 deletions(-) create mode 100644 x/oracle/types/block_hash_vote.go diff --git a/app/app.go b/app/app.go index c69e14b3..2dd00782 100644 --- a/app/app.go +++ b/app/app.go @@ -121,6 +121,9 @@ import ( gasestimatekeeper "github.com/ojo-network/ojo/x/gasestimate/keeper" gasestimatetypes "github.com/ojo-network/ojo/x/gasestimate/types" + symbiotickeeper "github.com/ojo-network/ojo/x/symbiotic/keeper" + symbiotictypes "github.com/ojo-network/ojo/x/symbiotic/types" + "github.com/ojo-network/ojo/x/airdrop" airdropkeeper "github.com/ojo-network/ojo/x/airdrop/keeper" airdroptypes "github.com/ojo-network/ojo/x/airdrop/types" @@ -150,6 +153,7 @@ var ( oracletypes.ModuleName: {authtypes.Minter}, gmptypes.ModuleName: {authtypes.Minter}, gasestimatetypes.ModuleName: {authtypes.Burner}, + symbiotictypes.ModuleName: {authtypes.Minter}, airdroptypes.ModuleName: {authtypes.Minter}, } ) @@ -208,6 +212,7 @@ type App struct { GmpKeeper gmpkeeper.Keeper GasEstimateKeeper gasestimatekeeper.Keeper AirdropKeeper airdropkeeper.Keeper + SymbioticKeeper symbiotickeeper.Keeper ConsensusParamsKeeper consensusparamkeeper.Keeper // make scoped keepers public for test purposes @@ -270,7 +275,7 @@ func New( govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, consensusparamtypes.StoreKey, group.StoreKey, oracletypes.StoreKey, gmptypes.StoreKey, - gasestimatetypes.ModuleName, airdroptypes.StoreKey, + gasestimatetypes.ModuleName, airdroptypes.StoreKey, symbiotictypes.StoreKey, ) tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -421,6 +426,13 @@ func New( authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + app.SymbioticKeeper = symbiotickeeper.NewKeeper( + appCodec, + keys[symbiotictypes.ModuleName], + app.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + app.OracleKeeper = oraclekeeper.NewKeeper( appCodec, keys[oracletypes.ModuleName], @@ -430,6 +442,7 @@ func New( app.DistrKeeper, app.StakingKeeper, app.GasEstimateKeeper, + app.SymbioticKeeper, distrtypes.ModuleName, cast.ToBool(appOpts.Get("telemetry.enabled")), authtypes.NewModuleAddress(govtypes.ModuleName).String(), diff --git a/app/preblocker.go b/app/preblocker.go index 0df1c144..479e0d74 100644 --- a/app/preblocker.go +++ b/app/preblocker.go @@ -10,6 +10,7 @@ import ( "github.com/ojo-network/ojo/x/oracle/types" gasestimatetypes "github.com/ojo-network/ojo/x/gasestimate/types" + symbiotictypes "github.com/ojo-network/ojo/x/symbiotic/types" ) // PreBlocker is run before finalize block to update the aggregrate exchange rate votes on the oracle module @@ -67,6 +68,13 @@ func (app *App) PreBlocker(ctx sdk.Context, req *cometabci.RequestFinalizeBlock) }) } app.Logger().Info("gas estimates updated", "gasestimates", injectedVoteExtTx.GasEstimateMedians) + + currentBlockHash := app.OracleKeeper.SymbioticKeeper.TallyBlockHashVotes(ctx, injectedVoteExtTx.BlockHashVotes) + cachedBlockHash := symbiotictypes.CachedBlockHash{ + BlockHash: currentBlockHash, + Height: req.Height, + } + app.OracleKeeper.SymbioticKeeper.SetCachedBlockHash(ctx, cachedBlockHash) } app.Logger().Info( diff --git a/proto/ojo/oracle/v1/abci.proto b/proto/ojo/oracle/v1/abci.proto index 88605425..bde0cb22 100644 --- a/proto/ojo/oracle/v1/abci.proto +++ b/proto/ojo/oracle/v1/abci.proto @@ -18,6 +18,7 @@ message OracleVoteExtension { (gogoproto.nullable) = false ]; repeated GasEstimate gas_estimates = 3 [(gogoproto.nullable) = false]; + string block_hash = 4; } // InjectedVoteExtensionTx defines the vote extension tx injected by the prepare @@ -28,6 +29,7 @@ message InjectedVoteExtensionTx { ]; bytes extended_commit_info = 2; repeated GasEstimate gas_estimate_medians = 3 [(gogoproto.nullable) = false]; + repeated BlockHashVote block_hash_votes = 4 [(gogoproto.nullable) = false]; } // GasEstimate defines a gas estimate for a given network. @@ -35,3 +37,11 @@ message GasEstimate { int64 gas_estimation = 1; string network = 2; } + +// Struct for voting on the block hash to store. +message BlockHashVote { + // Block hash of cached block on chain. + string block_hash = 1; + // Validator address proposing block hash. + string voter = 2; +} diff --git a/x/oracle/abci/proposal.go b/x/oracle/abci/proposal.go index 5bc1db7c..a1c0e06f 100644 --- a/x/oracle/abci/proposal.go +++ b/x/oracle/abci/proposal.go @@ -77,10 +77,15 @@ func (h *ProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHandler { if err != nil { return &cometabci.ResponsePrepareProposal{Txs: make([][]byte, 0)}, err } + blockHashVotes, err := h.generateBlockHashVotes(ctx, req.LocalLastCommit) + if err != nil { + return &cometabci.ResponsePrepareProposal{Txs: make([][]byte, 0)}, err + } injectedVoteExtTx := oracletypes.InjectedVoteExtensionTx{ ExchangeRateVotes: exchangeRateVotes, ExtendedCommitInfo: extendedCommitInfoBz, GasEstimateMedians: medianGasEstimates, + BlockHashVotes: blockHashVotes, } bz, err := injectedVoteExtTx.Marshal() @@ -184,6 +189,14 @@ func (h *ProposalHandler) ProcessProposalHandler() sdk.ProcessProposalHandler { if err := h.verifyMedianGasEstimations(injectedVoteExtTx.GasEstimateMedians, gasEstimateMedians); err != nil { return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err } + // Verify proposer's block hash votes by computing the same ballot. + blockHashVotes, err := h.generateBlockHashVotes(ctx, extendedCommitInfo) + if err != nil { + return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err + } + if err := h.verifyBlockHashVotes(injectedVoteExtTx.BlockHashVotes, blockHashVotes); err != nil { + return &cometabci.ResponseProcessProposal{Status: cometabci.ResponseProcessProposal_REJECT}, err + } } h.logger.Info( @@ -360,3 +373,77 @@ func (h *ProposalHandler) verifyMedianGasEstimations( return nil } + +func (h *ProposalHandler) generateBlockHashVotes( + ctx sdk.Context, + ci cometabci.ExtendedCommitInfo, +) (blockHashVotes []oracletypes.BlockHashVote, err error) { + for _, vote := range ci.Votes { + if vote.BlockIdFlag != cmtproto.BlockIDFlagCommit { + continue + } + + var voteExt oracletypes.OracleVoteExtension + if err := voteExt.Unmarshal(vote.VoteExtension); err != nil { + h.logger.Error( + "failed to decode vote extension", + "err", err, + ) + return nil, err + } + + var valConsAddr sdk.ConsAddress + if err := valConsAddr.Unmarshal(vote.Validator.Address); err != nil { + h.logger.Error( + "failed to unmarshal validator consensus address", + "err", err, + ) + return nil, err + } + val, err := h.stakingKeeper.GetValidatorByConsAddr(ctx, valConsAddr) + if err != nil { + h.logger.Error( + "failed to get consensus validator from staking keeper", + "err", err, + ) + return nil, err + } + valAddr, err := sdk.ValAddressFromBech32(val.OperatorAddress) + if err != nil { + return nil, err + } + + blockHashVote := oracletypes.BlockHashVote{ + BlockHash: voteExt.BlockHash, + Voter: valAddr.String(), + } + blockHashVotes = append(blockHashVotes, blockHashVote) + } + + // sort votes so they are verified in the same order in ProcessProposalHandler + sort.Slice(blockHashVotes, func(i, j int) bool { + return blockHashVotes[i].Voter < blockHashVotes[j].Voter + }) + + return blockHashVotes, nil +} + +func (h *ProposalHandler) verifyBlockHashVotes( + injectedVotes []oracletypes.BlockHashVote, + generatedVotes []oracletypes.BlockHashVote, +) error { + if len(injectedVotes) != len(generatedVotes) { + return oracletypes.ErrNonEqualInjVotesLen + } + + for i := range injectedVotes { + injectedVote := injectedVotes[i] + generatedVote := generatedVotes[i] + + if injectedVote.Voter != generatedVote.Voter || injectedVote.BlockHash != generatedVote.BlockHash { + return oracletypes.ErrNonEqualInjVotesBlockHash + } + } + + return nil +} diff --git a/x/oracle/abci/voteextension.go b/x/oracle/abci/voteextension.go index e4da6a30..4b8ce3ed 100644 --- a/x/oracle/abci/voteextension.go +++ b/x/oracle/abci/voteextension.go @@ -101,10 +101,22 @@ func (h *VoteExtensionHandler) ExtendVoteHandler() sdk.ExtendVoteHandler { }) } + var blockHash string + symbioticParams := h.oracleKeeper.SymbioticKeeper.GetParams(ctx) + if req.Height%symbioticParams.SymbioticSyncPeriod == 0 { + blockHash, err = h.oracleKeeper.SymbioticKeeper.GetFinalizedBlockHash(ctx) + h.logger.Error( + "height", req.Height, + err.Error(), + ) + return &cometabci.ResponseExtendVote{VoteExtension: []byte{}}, err + } + voteExt := types.OracleVoteExtension{ Height: req.Height, ExchangeRates: filteredDecCoins, GasEstimates: gasEstimates, + BlockHash: blockHash, } bz, err := voteExt.Marshal() diff --git a/x/oracle/keeper/keeper.go b/x/oracle/keeper/keeper.go index 05a9fbc8..4ab6a5d9 100644 --- a/x/oracle/keeper/keeper.go +++ b/x/oracle/keeper/keeper.go @@ -30,6 +30,7 @@ type Keeper struct { distrKeeper types.DistributionKeeper StakingKeeper types.StakingKeeper GasEstimateKeeper types.GasEstimateKeeper + SymbioticKeeper types.SymbioticKeeper PriceFeeder *pricefeeder.PriceFeeder @@ -50,6 +51,7 @@ func NewKeeper( distrKeeper types.DistributionKeeper, stakingKeeper types.StakingKeeper, gasEstimateKeeper types.GasEstimateKeeper, + symbioticKeeper types.SymbioticKeeper, distrName string, telemetryEnabled bool, authority string, @@ -73,6 +75,7 @@ func NewKeeper( distrKeeper: distrKeeper, StakingKeeper: stakingKeeper, GasEstimateKeeper: gasEstimateKeeper, + SymbioticKeeper: symbioticKeeper, PriceFeeder: &pricefeeder.PriceFeeder{}, distrName: distrName, telemetryEnabled: telemetryEnabled, diff --git a/x/oracle/types/abci.pb.go b/x/oracle/types/abci.pb.go index e74a793c..d2a0976e 100644 --- a/x/oracle/types/abci.pb.go +++ b/x/oracle/types/abci.pb.go @@ -31,6 +31,7 @@ type OracleVoteExtension struct { Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` ExchangeRates github_com_cosmos_cosmos_sdk_types.DecCoins `protobuf:"bytes,2,rep,name=exchange_rates,json=exchangeRates,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.DecCoins" json:"exchange_rates"` GasEstimates []GasEstimate `protobuf:"bytes,3,rep,name=gas_estimates,json=gasEstimates,proto3" json:"gas_estimates"` + BlockHash string `protobuf:"bytes,4,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` } func (m *OracleVoteExtension) Reset() { *m = OracleVoteExtension{} } @@ -72,6 +73,7 @@ type InjectedVoteExtensionTx struct { ExchangeRateVotes []AggregateExchangeRateVote `protobuf:"bytes,1,rep,name=exchange_rate_votes,json=exchangeRateVotes,proto3" json:"exchange_rate_votes"` ExtendedCommitInfo []byte `protobuf:"bytes,2,opt,name=extended_commit_info,json=extendedCommitInfo,proto3" json:"extended_commit_info,omitempty"` GasEstimateMedians []GasEstimate `protobuf:"bytes,3,rep,name=gas_estimate_medians,json=gasEstimateMedians,proto3" json:"gas_estimate_medians"` + BlockHashVotes []BlockHashVote `protobuf:"bytes,4,rep,name=block_hash_votes,json=blockHashVotes,proto3" json:"block_hash_votes"` } func (m *InjectedVoteExtensionTx) Reset() { *m = InjectedVoteExtensionTx{} } @@ -146,45 +148,92 @@ func (m *GasEstimate) XXX_DiscardUnknown() { var xxx_messageInfo_GasEstimate proto.InternalMessageInfo +// Struct for voting on the block hash to store. +type BlockHashVote struct { + // Block hash of cached block on chain. + BlockHash string `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` + // Validator address proposing block hash. + Voter string `protobuf:"bytes,2,opt,name=voter,proto3" json:"voter,omitempty"` +} + +func (m *BlockHashVote) Reset() { *m = BlockHashVote{} } +func (m *BlockHashVote) String() string { return proto.CompactTextString(m) } +func (*BlockHashVote) ProtoMessage() {} +func (*BlockHashVote) Descriptor() ([]byte, []int) { + return fileDescriptor_a17fd58ec0319b85, []int{3} +} +func (m *BlockHashVote) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlockHashVote) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlockHashVote.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BlockHashVote) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockHashVote.Merge(m, src) +} +func (m *BlockHashVote) XXX_Size() int { + return m.Size() +} +func (m *BlockHashVote) XXX_DiscardUnknown() { + xxx_messageInfo_BlockHashVote.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockHashVote proto.InternalMessageInfo + func init() { proto.RegisterType((*OracleVoteExtension)(nil), "ojo.oracle.v1.OracleVoteExtension") proto.RegisterType((*InjectedVoteExtensionTx)(nil), "ojo.oracle.v1.InjectedVoteExtensionTx") proto.RegisterType((*GasEstimate)(nil), "ojo.oracle.v1.GasEstimate") + proto.RegisterType((*BlockHashVote)(nil), "ojo.oracle.v1.BlockHashVote") } func init() { proto.RegisterFile("ojo/oracle/v1/abci.proto", fileDescriptor_a17fd58ec0319b85) } var fileDescriptor_a17fd58ec0319b85 = []byte{ - // 463 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x6e, 0xd3, 0x40, - 0x10, 0xc6, 0xe3, 0x16, 0x15, 0xb1, 0x6d, 0x2a, 0xb1, 0x8d, 0xc0, 0x8a, 0x90, 0x1b, 0x45, 0x42, - 0x0a, 0x42, 0x5d, 0x13, 0xfa, 0x04, 0xa4, 0x44, 0x55, 0x0f, 0x80, 0x64, 0x21, 0x0e, 0x1c, 0xb0, - 0xd6, 0xf6, 0x74, 0xb3, 0x29, 0xde, 0xa9, 0xbc, 0x4b, 0x30, 0x6f, 0xc1, 0x73, 0xf0, 0x24, 0x39, - 0xf6, 0xc8, 0x89, 0x3f, 0xc9, 0x9d, 0x57, 0x00, 0xed, 0xda, 0x56, 0x9c, 0x9e, 0x38, 0x79, 0x77, - 0xbf, 0x99, 0xf9, 0x7d, 0xe3, 0x19, 0xe2, 0xe3, 0x1c, 0x43, 0x2c, 0x78, 0xfa, 0x11, 0xc2, 0xc5, - 0x38, 0xe4, 0x49, 0x2a, 0xd9, 0x75, 0x81, 0x06, 0x69, 0x17, 0xe7, 0xc8, 0x2a, 0x85, 0x2d, 0xc6, - 0xfd, 0x9e, 0x40, 0x81, 0x4e, 0x09, 0xed, 0xa9, 0x0a, 0xea, 0x07, 0x29, 0xea, 0x1c, 0x75, 0x98, - 0x70, 0x6d, 0xf3, 0x13, 0x30, 0x7c, 0x1c, 0xa6, 0x28, 0x55, 0xad, 0xf7, 0xb7, 0xcb, 0xd7, 0xe5, - 0x9c, 0x36, 0xfc, 0xe3, 0x91, 0xa3, 0x37, 0xee, 0xe1, 0x1d, 0x1a, 0x98, 0x96, 0x06, 0x94, 0x96, - 0xa8, 0xe8, 0x03, 0xb2, 0x37, 0x03, 0x29, 0x66, 0xc6, 0xf7, 0x06, 0xde, 0x68, 0x37, 0xaa, 0x6f, - 0xb4, 0x24, 0x87, 0x50, 0xa6, 0x33, 0xae, 0x04, 0xc4, 0x05, 0x37, 0xa0, 0xfd, 0x9d, 0xc1, 0xee, - 0x68, 0xff, 0xf9, 0x23, 0x56, 0x99, 0x60, 0xd6, 0x04, 0xab, 0x4d, 0xb0, 0x97, 0x90, 0x9e, 0xa1, - 0x54, 0x93, 0xd3, 0xe5, 0x8f, 0xe3, 0xce, 0xb7, 0x9f, 0xc7, 0x4f, 0x85, 0x34, 0xb3, 0x4f, 0x09, - 0x4b, 0x31, 0x0f, 0x6b, 0xd3, 0xd5, 0xe7, 0x44, 0x67, 0x57, 0xa1, 0xf9, 0x72, 0x0d, 0xba, 0xc9, - 0xd1, 0x51, 0xb7, 0x01, 0x45, 0x96, 0x43, 0xa7, 0xa4, 0x2b, 0xb8, 0x8e, 0x41, 0x1b, 0x99, 0x3b, - 0xf0, 0xae, 0x03, 0xf7, 0xd9, 0xd6, 0x2f, 0x62, 0xe7, 0x5c, 0x4f, 0xeb, 0x90, 0xc9, 0x1d, 0x8b, - 0x8d, 0x0e, 0xc4, 0xe6, 0x49, 0x0f, 0xff, 0x7a, 0xe4, 0xe1, 0x85, 0x9a, 0x43, 0x6a, 0x20, 0xdb, - 0x6a, 0xf9, 0x6d, 0x49, 0x3f, 0x90, 0xa3, 0xad, 0xe6, 0xe2, 0x05, 0x5a, 0x90, 0xe7, 0x40, 0xa3, - 0x5b, 0xa0, 0x17, 0x42, 0x14, 0x20, 0xb8, 0xad, 0xb0, 0xb1, 0x69, 0x2b, 0xd6, 0xd8, 0xfb, 0x70, - 0xeb, 0x5d, 0xd3, 0x67, 0xa4, 0x07, 0x16, 0x97, 0x41, 0x16, 0xa7, 0x98, 0xe7, 0xd2, 0xc4, 0x52, - 0x5d, 0xa2, 0xbf, 0x33, 0xf0, 0x46, 0x07, 0x11, 0x6d, 0xb4, 0x33, 0x27, 0x5d, 0xa8, 0x4b, 0xa4, - 0x11, 0xe9, 0xb5, 0x9b, 0x8e, 0x73, 0xc8, 0x24, 0x57, 0xff, 0xdf, 0x3b, 0x6d, 0xf5, 0xfe, 0xaa, - 0xca, 0x1d, 0xbe, 0x26, 0xfb, 0xad, 0x40, 0xfa, 0x98, 0x1c, 0xb6, 0x10, 0x12, 0x55, 0x3d, 0xf1, - 0xee, 0x26, 0xd5, 0x2e, 0x84, 0x4f, 0xee, 0x2a, 0x30, 0x9f, 0xb1, 0xb8, 0x72, 0x76, 0xef, 0x45, - 0xcd, 0x75, 0x72, 0xbe, 0xfc, 0x1d, 0x74, 0x96, 0xab, 0xc0, 0xbb, 0x59, 0x05, 0xde, 0xaf, 0x55, - 0xe0, 0x7d, 0x5d, 0x07, 0x9d, 0x9b, 0x75, 0xd0, 0xf9, 0xbe, 0x0e, 0x3a, 0xef, 0x9f, 0xb4, 0x46, - 0x8e, 0x73, 0x3c, 0xa9, 0xb3, 0xec, 0x39, 0x2c, 0x9b, 0xad, 0x74, 0x93, 0x4f, 0xf6, 0xdc, 0x4a, - 0x9e, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0x98, 0x69, 0xf4, 0x0f, 0x03, 0x00, 0x00, + // 529 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xdd, 0x6e, 0xd3, 0x30, + 0x14, 0x6e, 0xda, 0x32, 0x54, 0x6f, 0xad, 0xc0, 0xab, 0x20, 0xaa, 0x20, 0xab, 0x2a, 0x21, 0x15, + 0xa1, 0x25, 0x94, 0x3d, 0x01, 0xdd, 0xaa, 0x31, 0x89, 0x1f, 0x29, 0x42, 0x5c, 0x70, 0x41, 0xe4, + 0xa4, 0x5e, 0xe2, 0x76, 0xf1, 0x99, 0x62, 0x53, 0xca, 0x43, 0x20, 0xf1, 0x1c, 0x3c, 0x49, 0x6f, + 0x90, 0x76, 0xc9, 0x15, 0x3f, 0xed, 0x8b, 0x20, 0x3b, 0x8e, 0x9a, 0xf4, 0x6a, 0x57, 0x89, 0xcf, + 0xb1, 0xbf, 0x3f, 0x1f, 0x23, 0x1b, 0x66, 0xe0, 0x41, 0x46, 0xa2, 0x2b, 0xea, 0x2d, 0x46, 0x1e, + 0x09, 0x23, 0xe6, 0x5e, 0x67, 0x20, 0x01, 0xb7, 0x61, 0x06, 0x6e, 0xde, 0x71, 0x17, 0xa3, 0x5e, + 0x37, 0x86, 0x18, 0x74, 0xc7, 0x53, 0x7f, 0xf9, 0xa6, 0x9e, 0x13, 0x81, 0x48, 0x41, 0x78, 0x21, + 0x11, 0xea, 0x7c, 0x48, 0x25, 0x19, 0x79, 0x11, 0x30, 0x6e, 0xfa, 0xbd, 0x2a, 0xbc, 0x81, 0xd3, + 0xbd, 0xc1, 0xb7, 0x3a, 0x3a, 0x7c, 0xa7, 0x0b, 0x1f, 0x40, 0xd2, 0xc9, 0x52, 0x52, 0x2e, 0x18, + 0x70, 0xfc, 0x00, 0xed, 0x25, 0x94, 0xc5, 0x89, 0xb4, 0xad, 0xbe, 0x35, 0x6c, 0xf8, 0x66, 0x85, + 0x97, 0xa8, 0x43, 0x97, 0x51, 0x42, 0x78, 0x4c, 0x83, 0x8c, 0x48, 0x2a, 0xec, 0x7a, 0xbf, 0x31, + 0xdc, 0x7f, 0xf1, 0xc8, 0xcd, 0x45, 0xb8, 0x4a, 0x84, 0x6b, 0x44, 0xb8, 0x67, 0x34, 0x3a, 0x05, + 0xc6, 0xc7, 0x27, 0xab, 0xdf, 0x47, 0xb5, 0x1f, 0x7f, 0x8e, 0x9e, 0xc5, 0x4c, 0x26, 0x9f, 0x43, + 0x37, 0x82, 0xd4, 0x33, 0xa2, 0xf3, 0xcf, 0xb1, 0x98, 0xce, 0x3d, 0xf9, 0xf5, 0x9a, 0x8a, 0xe2, + 0x8c, 0xf0, 0xdb, 0x05, 0x91, 0xaf, 0x78, 0xf0, 0x04, 0xb5, 0x63, 0x22, 0x02, 0x2a, 0x24, 0x4b, + 0x35, 0x71, 0x43, 0x13, 0xf7, 0xdc, 0x4a, 0x44, 0xee, 0x39, 0x11, 0x13, 0xb3, 0x65, 0xdc, 0x54, + 0xb4, 0xfe, 0x41, 0xbc, 0x2d, 0x09, 0xfc, 0x18, 0xa1, 0xf0, 0x0a, 0xa2, 0x79, 0x90, 0x10, 0x91, + 0xd8, 0xcd, 0xbe, 0x35, 0x6c, 0xf9, 0x2d, 0x5d, 0x79, 0x45, 0x44, 0x32, 0xf8, 0x59, 0x47, 0x0f, + 0x2f, 0xf8, 0x8c, 0x46, 0x92, 0x4e, 0x2b, 0x89, 0xbc, 0x5f, 0xe2, 0x4f, 0xe8, 0xb0, 0xe2, 0x3d, + 0x58, 0x80, 0xd2, 0x61, 0x69, 0x1d, 0xc3, 0x1d, 0x1d, 0x2f, 0xe3, 0x38, 0xa3, 0x31, 0x51, 0x08, + 0x5b, 0x17, 0x0a, 0xd1, 0xa8, 0xba, 0x4f, 0x77, 0xea, 0x02, 0x3f, 0x47, 0x5d, 0xaa, 0xe8, 0xa6, + 0x74, 0x1a, 0x44, 0x90, 0xa6, 0x4c, 0x06, 0x8c, 0x5f, 0x82, 0x5d, 0xef, 0x5b, 0xc3, 0x03, 0x1f, + 0x17, 0xbd, 0x53, 0xdd, 0xba, 0xe0, 0x97, 0x80, 0x7d, 0xd4, 0x2d, 0x67, 0x12, 0xa4, 0x74, 0xca, + 0x08, 0xbf, 0x7d, 0x34, 0xb8, 0x14, 0xcd, 0x9b, 0xfc, 0x2c, 0x7e, 0x8d, 0xee, 0x6d, 0x03, 0x32, + 0x16, 0x9b, 0xe6, 0x8e, 0xab, 0x78, 0xe3, 0x22, 0xb5, 0x92, 0xad, 0x4e, 0x58, 0x2e, 0x8a, 0xc1, + 0x5b, 0xb4, 0x5f, 0xa2, 0xc5, 0x4f, 0x50, 0xa7, 0x24, 0x98, 0x01, 0x37, 0xe3, 0xd5, 0xde, 0x0a, + 0x51, 0xd3, 0x67, 0xa3, 0xbb, 0x9c, 0xca, 0x2f, 0x90, 0xcd, 0xb5, 0xf9, 0x96, 0x5f, 0x2c, 0x07, + 0x67, 0xa8, 0x5d, 0xa1, 0xdd, 0xb9, 0x4f, 0x6b, 0xe7, 0x3e, 0x71, 0x17, 0xdd, 0x51, 0x16, 0x32, + 0x83, 0x93, 0x2f, 0xc6, 0xe7, 0xab, 0x7f, 0x4e, 0x6d, 0xb5, 0x76, 0xac, 0x9b, 0xb5, 0x63, 0xfd, + 0x5d, 0x3b, 0xd6, 0xf7, 0x8d, 0x53, 0xbb, 0xd9, 0x38, 0xb5, 0x5f, 0x1b, 0xa7, 0xf6, 0xf1, 0x69, + 0x69, 0x4a, 0x61, 0x06, 0xc7, 0x86, 0x5b, 0xfd, 0x7b, 0xcb, 0xe2, 0x21, 0xe9, 0x61, 0x0d, 0xf7, + 0xf4, 0x2b, 0x3a, 0xf9, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x77, 0xe1, 0x6e, 0xc2, 0x03, 0x00, + 0x00, } func (m *OracleVoteExtension) Marshal() (dAtA []byte, err error) { @@ -207,6 +256,13 @@ func (m *OracleVoteExtension) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintAbci(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0x22 + } if len(m.GasEstimates) > 0 { for iNdEx := len(m.GasEstimates) - 1; iNdEx >= 0; iNdEx-- { { @@ -263,6 +319,20 @@ func (m *InjectedVoteExtensionTx) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if len(m.BlockHashVotes) > 0 { + for iNdEx := len(m.BlockHashVotes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BlockHashVotes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAbci(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } if len(m.GasEstimateMedians) > 0 { for iNdEx := len(m.GasEstimateMedians) - 1; iNdEx >= 0; iNdEx-- { { @@ -336,6 +406,43 @@ func (m *GasEstimate) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *BlockHashVote) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockHashVote) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlockHashVote) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Voter) > 0 { + i -= len(m.Voter) + copy(dAtA[i:], m.Voter) + i = encodeVarintAbci(dAtA, i, uint64(len(m.Voter))) + i-- + dAtA[i] = 0x12 + } + if len(m.BlockHash) > 0 { + i -= len(m.BlockHash) + copy(dAtA[i:], m.BlockHash) + i = encodeVarintAbci(dAtA, i, uint64(len(m.BlockHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintAbci(dAtA []byte, offset int, v uint64) int { offset -= sovAbci(v) base := offset @@ -368,6 +475,10 @@ func (m *OracleVoteExtension) Size() (n int) { n += 1 + l + sovAbci(uint64(l)) } } + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovAbci(uint64(l)) + } return n } @@ -393,6 +504,12 @@ func (m *InjectedVoteExtensionTx) Size() (n int) { n += 1 + l + sovAbci(uint64(l)) } } + if len(m.BlockHashVotes) > 0 { + for _, e := range m.BlockHashVotes { + l = e.Size() + n += 1 + l + sovAbci(uint64(l)) + } + } return n } @@ -412,6 +529,23 @@ func (m *GasEstimate) Size() (n int) { return n } +func (m *BlockHashVote) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.BlockHash) + if l > 0 { + n += 1 + l + sovAbci(uint64(l)) + } + l = len(m.Voter) + if l > 0 { + n += 1 + l + sovAbci(uint64(l)) + } + return n +} + func sovAbci(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -534,6 +668,38 @@ func (m *OracleVoteExtension) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAbci + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAbci + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAbci + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAbci(dAtA[iNdEx:]) @@ -686,6 +852,40 @@ func (m *InjectedVoteExtensionTx) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHashVotes", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAbci + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAbci + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAbci + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHashVotes = append(m.BlockHashVotes, BlockHashVote{}) + if err := m.BlockHashVotes[len(m.BlockHashVotes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipAbci(dAtA[iNdEx:]) @@ -808,6 +1008,120 @@ func (m *GasEstimate) Unmarshal(dAtA []byte) error { } return nil } +func (m *BlockHashVote) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAbci + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlockHashVote: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockHashVote: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAbci + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAbci + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAbci + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Voter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAbci + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAbci + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAbci + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Voter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAbci(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAbci + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipAbci(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/oracle/types/block_hash_vote.go b/x/oracle/types/block_hash_vote.go new file mode 100644 index 00000000..ab1254f4 --- /dev/null +++ b/x/oracle/types/block_hash_vote.go @@ -0,0 +1 @@ +package types diff --git a/x/oracle/types/errors.go b/x/oracle/types/errors.go index 9a7d0062..9732f258 100644 --- a/x/oracle/types/errors.go +++ b/x/oracle/types/errors.go @@ -9,33 +9,34 @@ import ( // Oracle sentinel errors var ( - ErrInvalidExchangeRate = errors.Register(ModuleName, 2, "invalid exchange rate") - ErrNoPrevote = errors.Register(ModuleName, 3, "no prevote") - ErrNoVote = errors.Register(ModuleName, 4, "no vote") - ErrNoVotingPermission = errors.Register(ModuleName, 5, "unauthorized voter") - ErrInvalidHash = errors.Register(ModuleName, 6, "invalid hash") - ErrInvalidHashLength = errors.Register(ModuleName, 7, fmt.Sprintf("invalid hash length; should equal %d", tmhash.TruncatedSize)) //nolint: lll - ErrVerificationFailed = errors.Register(ModuleName, 8, "hash verification failed") - ErrRevealPeriodMissMatch = errors.Register(ModuleName, 9, "reveal period of submitted vote does not match with registered prevote") //nolint: lll - ErrInvalidSaltLength = errors.Register(ModuleName, 10, "invalid salt length; must be 64") - ErrInvalidSaltFormat = errors.Register(ModuleName, 11, "invalid salt format") - ErrNoAggregatePrevote = errors.Register(ModuleName, 12, "no aggregate prevote") - ErrNoAggregateVote = errors.Register(ModuleName, 13, "no aggregate vote") - ErrUnknownDenom = errors.Register(ModuleName, 14, "unknown denom") - ErrNegativeOrZeroRate = errors.Register(ModuleName, 15, "invalid exchange rate; should be positive") - ErrExistingPrevote = errors.Register(ModuleName, 16, "prevote already submitted for this voting period") - ErrBallotNotSorted = errors.Register(ModuleName, 17, "ballot must be sorted before this operation") - ErrInvalidOraclePrice = errors.Register(ModuleName, 18, "invalid or unavailable oracle price") - ErrNoHistoricPrice = errors.Register(ModuleName, 19, "no historic price for this denom at this block") - ErrNoMedian = errors.Register(ModuleName, 20, "no median for this denom at this block") - ErrNoMedianDeviation = errors.Register(ModuleName, 21, "no median deviation for this denom at this block") - ErrNoRewardBand = errors.Register(ModuleName, 22, "unable to find the reward band the given asset") - ErrNoValidatorRewardSet = errors.Register(ModuleName, 23, "unable to find the latest validator reward set") - ErrNoGovAuthority = errors.Register(ModuleName, 24, "invalid gov authority to perform these changes") - ErrInvalidRequest = errors.Register(ModuleName, 25, "invalid request") - ErrInvalidParamValue = errors.Register(ModuleName, 26, "invalid oracle param value") - ErrEncodeInjVoteExt = errors.Register(ModuleName, 27, "failed to encode injected vote extension tx") - ErrNonEqualInjVotesLen = errors.Register(ModuleName, 28, "number of exchange rate votes in vote extension and extended commit info are not equal") //nolint: lll - ErrNonEqualInjVotesRates = errors.Register(ModuleName, 29, "injected exchange rate votes and generated exchange votes are not equal") //nolint: lll - ErrNoCommitInfo = errors.Register(ModuleName, 30, "no commit info in process proposal request") + ErrInvalidExchangeRate = errors.Register(ModuleName, 2, "invalid exchange rate") + ErrNoPrevote = errors.Register(ModuleName, 3, "no prevote") + ErrNoVote = errors.Register(ModuleName, 4, "no vote") + ErrNoVotingPermission = errors.Register(ModuleName, 5, "unauthorized voter") + ErrInvalidHash = errors.Register(ModuleName, 6, "invalid hash") + ErrInvalidHashLength = errors.Register(ModuleName, 7, fmt.Sprintf("invalid hash length; should equal %d", tmhash.TruncatedSize)) //nolint: lll + ErrVerificationFailed = errors.Register(ModuleName, 8, "hash verification failed") + ErrRevealPeriodMissMatch = errors.Register(ModuleName, 9, "reveal period of submitted vote does not match with registered prevote") //nolint: lll + ErrInvalidSaltLength = errors.Register(ModuleName, 10, "invalid salt length; must be 64") + ErrInvalidSaltFormat = errors.Register(ModuleName, 11, "invalid salt format") + ErrNoAggregatePrevote = errors.Register(ModuleName, 12, "no aggregate prevote") + ErrNoAggregateVote = errors.Register(ModuleName, 13, "no aggregate vote") + ErrUnknownDenom = errors.Register(ModuleName, 14, "unknown denom") + ErrNegativeOrZeroRate = errors.Register(ModuleName, 15, "invalid exchange rate; should be positive") + ErrExistingPrevote = errors.Register(ModuleName, 16, "prevote already submitted for this voting period") + ErrBallotNotSorted = errors.Register(ModuleName, 17, "ballot must be sorted before this operation") + ErrInvalidOraclePrice = errors.Register(ModuleName, 18, "invalid or unavailable oracle price") + ErrNoHistoricPrice = errors.Register(ModuleName, 19, "no historic price for this denom at this block") + ErrNoMedian = errors.Register(ModuleName, 20, "no median for this denom at this block") + ErrNoMedianDeviation = errors.Register(ModuleName, 21, "no median deviation for this denom at this block") + ErrNoRewardBand = errors.Register(ModuleName, 22, "unable to find the reward band the given asset") + ErrNoValidatorRewardSet = errors.Register(ModuleName, 23, "unable to find the latest validator reward set") + ErrNoGovAuthority = errors.Register(ModuleName, 24, "invalid gov authority to perform these changes") + ErrInvalidRequest = errors.Register(ModuleName, 25, "invalid request") + ErrInvalidParamValue = errors.Register(ModuleName, 26, "invalid oracle param value") + ErrEncodeInjVoteExt = errors.Register(ModuleName, 27, "failed to encode injected vote extension tx") + ErrNonEqualInjVotesLen = errors.Register(ModuleName, 28, "number of exchange rate votes in vote extension and extended commit info are not equal") //nolint: lll + ErrNonEqualInjVotesRates = errors.Register(ModuleName, 29, "injected exchange rate votes and generated exchange votes are not equal") //nolint: lll + ErrNonEqualInjVotesBlockHash = errors.Register(ModuleName, 29, "injected block hash votes and generated block hash votes are not equal") //nolint: lll + ErrNoCommitInfo = errors.Register(ModuleName, 30, "no commit info in process proposal request") ) diff --git a/x/oracle/types/expected_keeper.go b/x/oracle/types/expected_keeper.go index 9e3879ad..d1125b7e 100644 --- a/x/oracle/types/expected_keeper.go +++ b/x/oracle/types/expected_keeper.go @@ -9,6 +9,7 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" gasestimatetypes "github.com/ojo-network/ojo/x/gasestimate/types" + symbiotictypes "github.com/ojo-network/ojo/x/symbiotic/types" ) // StakingKeeper defines the expected interface contract defined by the x/staking @@ -54,3 +55,10 @@ type BankKeeper interface { type GasEstimateKeeper interface { GetParams(ctx sdk.Context) (params gasestimatetypes.Params) } + +type SymbioticKeeper interface { + SetCachedBlockHash(ctx sdk.Context, cachedBlockHash symbiotictypes.CachedBlockHash) + GetParams(ctx sdk.Context) (params symbiotictypes.Params) + GetFinalizedBlockHash(ctx context.Context) (string, error) + TallyBlockHashVotes(ctx sdk.Context, blockHashVotes []BlockHashVote) string +} diff --git a/x/symbiotic/abci.go b/x/symbiotic/abci.go index 3a739ca2..0f82183e 100644 --- a/x/symbiotic/abci.go +++ b/x/symbiotic/abci.go @@ -23,5 +23,5 @@ func EndBlocker(ctx context.Context, k keeper.Keeper) error { } } - return nil + return k.SymbioticUpdateValidatorsPower(ctx) } diff --git a/x/symbiotic/keeper/keeper.go b/x/symbiotic/keeper/keeper.go index 538106ed..5d5b5e2d 100644 --- a/x/symbiotic/keeper/keeper.go +++ b/x/symbiotic/keeper/keeper.go @@ -9,6 +9,7 @@ import ( storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" + oracletypes "github.com/ojo-network/ojo/x/oracle/types" "github.com/ojo-network/ojo/x/symbiotic/types" ) @@ -28,6 +29,7 @@ type Keeper struct { func NewKeeper( cdc codec.BinaryCodec, storeKey storetypes.StoreKey, + stakingKeeper types.StakingKeeper, authority string, ) Keeper { return Keeper{ @@ -112,3 +114,35 @@ func (k Keeper) PruneBlockHashesBeforeBlock( return false }) } + +func (k Keeper) TallyBlockHashVotes( + ctx sdk.Context, + blockHashVotes []oracletypes.BlockHashVote, +) string { + votePower := make(map[string]int64) + powerReduction := k.StakingKeeper.PowerReduction(ctx) + + for _, vote := range blockHashVotes { + voterAddr := sdk.ValAddress(vote.Voter) + + validator, err := k.StakingKeeper.GetValidator(ctx, voterAddr) + if err != nil { + continue + } + + power := validator.GetConsensusPower(powerReduction) + votePower[vote.BlockHash] += power + } + + var maxHash string + var maxPower int64 + + for hash, power := range votePower { + if power > maxPower { + maxPower = power + maxHash = hash + } + } + + return maxHash +} diff --git a/x/symbiotic/keeper/network_state_change.go b/x/symbiotic/keeper/network_state_change.go index 678cc7d8..70ddcaa2 100644 --- a/x/symbiotic/keeper/network_state_change.go +++ b/x/symbiotic/keeper/network_state_change.go @@ -119,7 +119,7 @@ const ( ]` ) -func (k *Keeper) SymbioticUpdateValidatorsPower(ctx context.Context) error { +func (k Keeper) SymbioticUpdateValidatorsPower(ctx context.Context) error { sdkCtx := sdk.UnwrapSDKContext(ctx) params := k.GetParams(sdkCtx) @@ -184,7 +184,7 @@ func (k *Keeper) SymbioticUpdateValidatorsPower(ctx context.Context) error { return nil } -func (k *Keeper) GetFinalizedBlockHash(ctx context.Context) (string, error) { +func (k Keeper) GetFinalizedBlockHash(ctx context.Context) (string, error) { var err error var block Block @@ -223,7 +223,7 @@ func (k *Keeper) GetFinalizedBlockHash(ctx context.Context) (string, error) { return block.Data.Message.Body.ExecutionPayload.BlockHash, nil } -func (k *Keeper) GetBlockByHash(ctx context.Context, blockHash string) (*types.Block, error) { +func (k Keeper) GetBlockByHash(ctx context.Context, blockHash string) (*types.Block, error) { var block *types.Block client, err := ethclient.Dial(k.apiUrls.GetEthApiUrl()) if err != nil { @@ -248,7 +248,7 @@ func (k *Keeper) GetBlockByHash(ctx context.Context, blockHash string) (*types.B return block, nil } -func (k *Keeper) GetBlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { +func (k Keeper) GetBlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { var block *types.Block client, err := ethclient.Dial(k.apiUrls.GetEthApiUrl()) if err != nil { diff --git a/x/symbiotic/types/expected_keeper.go b/x/symbiotic/types/expected_keeper.go index 57b2742b..6dfef8e0 100644 --- a/x/symbiotic/types/expected_keeper.go +++ b/x/symbiotic/types/expected_keeper.go @@ -11,6 +11,7 @@ import ( // StakingKeeper defines the expected interface contract defined by the x/staking // module. type StakingKeeper interface { + GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error) GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (validator stakingtypes.Validator, err error) AddValidatorTokensAndShares(ctx context.Context, validator stakingtypes.Validator, tokensToAdd sdkmath.Int, @@ -18,4 +19,5 @@ type StakingKeeper interface { RemoveValidatorTokens(ctx context.Context, validator stakingtypes.Validator, tokensToRemove sdkmath.Int, ) (stakingtypes.Validator, error) + PowerReduction(ctx context.Context) (res sdkmath.Int) }