From 6724629a87ba821997c8c1d90d0a0e129b94eb7f Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Thu, 8 Feb 2024 09:00:12 +0100 Subject: [PATCH 001/119] Add CHANGELOG (#458) * Add update changelog script * Add CHANGELOG.md --- CHANGELOG.md | 529 ++++++++++++++++++++++++++++++++++++ Makefile | 13 + scripts/update_changelog.sh | 89 ++++++ 3 files changed, 631 insertions(+) create mode 100755 scripts/update_changelog.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 825c32f0d..1793be5f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1 +1,530 @@ # Changelog + +## [v0.8.0](https://github.com/babylonchain/babylon/tree/v0.8.0) (2024-02-08) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.8.0-rc.0...v0.8.0) + +## [v0.8.0-rc.0](https://github.com/babylonchain/babylon/tree/v0.8.0-rc.0) (2024-01-22) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.2...v0.8.0-rc.0) + +**Closed issues:** + +- Dead Link in the Git "Joining the testnet" [\#406](https://github.com/babylonchain/babylon/issues/406) +- Broken link for testnet in the main README.md [\#403](https://github.com/babylonchain/babylon/issues/403) +- Random failure when running integration test [\#319](https://github.com/babylonchain/babylon/issues/319) +- Refactor BLS signer to load gas settings during initiation [\#311](https://github.com/babylonchain/babylon/issues/311) +- Random CI failure on QueryFinalizedChainInfo [\#288](https://github.com/babylonchain/babylon/issues/288) + +**Merged pull requests:** + +- chore: add parameter sections for module docs [\#418](https://github.com/babylonchain/babylon/pull/418) ([SebastianElvis](https://github.com/SebastianElvis)) +- doc: documentation for the epoching module [\#416](https://github.com/babylonchain/babylon/pull/416) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: making zoneconcierge resilient against long BTC reorg \(again\) [\#413](https://github.com/babylonchain/babylon/pull/413) ([SebastianElvis](https://github.com/SebastianElvis)) +- BTC Staking [\#409](https://github.com/babylonchain/babylon/pull/409) ([vitsalis](https://github.com/vitsalis)) +- Fix typos [\#405](https://github.com/babylonchain/babylon/pull/405) ([AtomicInnovation321](https://github.com/AtomicInnovation321)) +- Updated testnet link [\#404](https://github.com/babylonchain/babylon/pull/404) ([kunallimaye](https://github.com/kunallimaye)) +- README: updating discord link [\#402](https://github.com/babylonchain/babylon/pull/402) ([GakiBash](https://github.com/GakiBash)) +- README: Add medium link [\#400](https://github.com/babylonchain/babylon/pull/400) ([EdwardFanfan](https://github.com/EdwardFanfan)) +- Bump comet bft [\#399](https://github.com/babylonchain/babylon/pull/399) ([KonradStaniec](https://github.com/KonradStaniec)) +- hotfix: Barberry upgrade [\#398](https://github.com/babylonchain/babylon/pull/398) ([vitsalis](https://github.com/vitsalis)) +- Bump wasmd to stable [\#396](https://github.com/babylonchain/babylon/pull/396) ([KonradStaniec](https://github.com/KonradStaniec)) +- hotfix: fixing marshaling of MsgWrappedCreateValidator [\#394](https://github.com/babylonchain/babylon/pull/394) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: adding a flag for retrieving proofs of a FinalizedChainInfo [\#391](https://github.com/babylonchain/babylon/pull/391) ([SebastianElvis](https://github.com/SebastianElvis)) +- e2e: merge integration tests with e2e tests [\#390](https://github.com/babylonchain/babylon/pull/390) ([SebastianElvis](https://github.com/SebastianElvis)) + +## [v0.7.2](https://github.com/babylonchain/babylon/tree/v0.7.2) (2023-06-10) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.1...v0.7.2) + +## [v0.7.1](https://github.com/babylonchain/babylon/tree/v0.7.1) (2023-05-30) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.0...v0.7.1) + +**Closed issues:** + +- zoneconcierge: parameterise timeout for IBC packets [\#207](https://github.com/babylonchain/babylon/issues/207) + +**Merged pull requests:** + +- hotfix: fixing marshaling of `MsgWrappedCreateValidator` [\#393](https://github.com/babylonchain/babylon/pull/393) ([SebastianElvis](https://github.com/SebastianElvis)) + +## [v0.7.0](https://github.com/babylonchain/babylon/tree/v0.7.0) (2023-05-26) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0...v0.7.0) + +**Closed issues:** + +- Nil hooks [\#214](https://github.com/babylonchain/babylon/issues/214) + +**Merged pull requests:** + +- Release v0.7.0 [\#388](https://github.com/babylonchain/babylon/pull/388) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: adding header timestamp to IndexedHeader [\#387](https://github.com/babylonchain/babylon/pull/387) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: parameterise timeout for IBC packets [\#386](https://github.com/babylonchain/babylon/pull/386) ([SebastianElvis](https://github.com/SebastianElvis)) +- CI: Push images for dev branch commits [\#385](https://github.com/babylonchain/babylon/pull/385) ([filippos47](https://github.com/filippos47)) +- dockerfile: opt out version when building [\#384](https://github.com/babylonchain/babylon/pull/384) ([SebastianElvis](https://github.com/SebastianElvis)) +- Use fee module [\#383](https://github.com/babylonchain/babylon/pull/383) ([KonradStaniec](https://github.com/KonradStaniec)) +- Bump vulnerable docker/distribution [\#382](https://github.com/babylonchain/babylon/pull/382) ([vitsalis](https://github.com/vitsalis)) +- Bump wasmd to rc2 [\#381](https://github.com/babylonchain/babylon/pull/381) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add wasm e2e test [\#380](https://github.com/babylonchain/babylon/pull/380) ([KonradStaniec](https://github.com/KonradStaniec)) +- phase2: IBC packet and logic [\#368](https://github.com/babylonchain/babylon/pull/368) ([SebastianElvis](https://github.com/SebastianElvis)) + +## [v0.6.0](https://github.com/babylonchain/babylon/tree/v0.6.0) (2023-05-10) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0rc0...v0.6.0) + +**Merged pull requests:** + +- Release v0.6.0 [\#379](https://github.com/babylonchain/babylon/pull/379) ([vitsalis](https://github.com/vitsalis)) +- Fix non-determinism in integration test [\#377](https://github.com/babylonchain/babylon/pull/377) ([KonradStaniec](https://github.com/KonradStaniec)) +- Fix consensus version in our custom modules [\#376](https://github.com/babylonchain/babylon/pull/376) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add fuzz test for epoch finalization/confirmation [\#375](https://github.com/babylonchain/babylon/pull/375) ([KonradStaniec](https://github.com/KonradStaniec)) + +## [v0.6.0rc0](https://github.com/babylonchain/babylon/tree/v0.6.0rc0) (2023-05-04) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0-rc0...v0.6.0rc0) + +## [v0.6.0-rc0](https://github.com/babylonchain/babylon/tree/v0.6.0-rc0) (2023-05-04) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/devnet...v0.6.0-rc0) + +**Merged pull requests:** + +- use tagged branch in test contract [\#374](https://github.com/babylonchain/babylon/pull/374) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Reduce default number of tests from 100 to 10 [\#373](https://github.com/babylonchain/babylon/pull/373) ([vitsalis](https://github.com/vitsalis)) +- feat: new rpc RawCheckpoints [\#372](https://github.com/babylonchain/babylon/pull/372) ([gusin13](https://github.com/gusin13)) +- chore: circleci: Use image with go 1.20.3 installed [\#371](https://github.com/babylonchain/babylon/pull/371) ([vitsalis](https://github.com/vitsalis)) +- Improve btccheckpointinfo rpc [\#370](https://github.com/babylonchain/babylon/pull/370) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add support for multiple chain ids in EpochChainsInfo API [\#369](https://github.com/babylonchain/babylon/pull/369) ([gusin13](https://github.com/gusin13)) +- Fix bug in submission btc info [\#367](https://github.com/babylonchain/babylon/pull/367) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Bump Cosmos SDK to v0.47.2 and minor bug fix [\#366](https://github.com/babylonchain/babylon/pull/366) ([vitsalis](https://github.com/vitsalis)) +- feat: support multiple chain ids in FinalizedChainsInfo [\#365](https://github.com/babylonchain/babylon/pull/365) ([gusin13](https://github.com/gusin13)) +- chore: Update runc and docker dependencies due to security alerts [\#364](https://github.com/babylonchain/babylon/pull/364) ([vitsalis](https://github.com/vitsalis)) +- chore: Replace deprecated `rand.Seed` with dedicated datagen random generators [\#363](https://github.com/babylonchain/babylon/pull/363) ([vitsalis](https://github.com/vitsalis)) +- feat: support multiple chain ids in zoneconcierge chains info api [\#362](https://github.com/babylonchain/babylon/pull/362) ([gusin13](https://github.com/gusin13)) +- Add last block height to finalized epoch info [\#361](https://github.com/babylonchain/babylon/pull/361) ([KonradStaniec](https://github.com/KonradStaniec)) +- Version bumps [\#358](https://github.com/babylonchain/babylon/pull/358) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Make testnet command produce addresses bound to the host IP [\#357](https://github.com/babylonchain/babylon/pull/357) ([vitsalis](https://github.com/vitsalis)) +- Move checkpoint tag to params [\#356](https://github.com/babylonchain/babylon/pull/356) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Use more descriptive error message for using wrapped transactions [\#355](https://github.com/babylonchain/babylon/pull/355) ([vitsalis](https://github.com/vitsalis)) +- chore: Enable building docker image with unpushed changes [\#354](https://github.com/babylonchain/babylon/pull/354) ([vitsalis](https://github.com/vitsalis)) +- Handle btc related wasm queries [\#353](https://github.com/babylonchain/babylon/pull/353) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: fix query height in `ProveEpochSealed` [\#352](https://github.com/babylonchain/babylon/pull/352) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: fixing the bug in generating proof of sealed epoch [\#351](https://github.com/babylonchain/babylon/pull/351) ([SebastianElvis](https://github.com/SebastianElvis)) +- testnet: Add flag for time between blocks [\#134](https://github.com/babylonchain/babylon/pull/134) ([vitsalis](https://github.com/vitsalis)) + +## [devnet](https://github.com/babylonchain/babylon/tree/devnet) (2023-04-17) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/test...devnet) + +**Breaking changes:** + +- fix gas cost of insert header [\#309](https://github.com/babylonchain/babylon/pull/309) ([KonradStaniec](https://github.com/KonradStaniec)) + +**Closed issues:** + +- Remove `handler.go` from modules [\#336](https://github.com/babylonchain/babylon/issues/336) + +**Merged pull requests:** + +- Add support for querying for latest finalized epoch [\#350](https://github.com/babylonchain/babylon/pull/350) ([KonradStaniec](https://github.com/KonradStaniec)) +- Use block gas limit when defining genesis [\#349](https://github.com/babylonchain/babylon/pull/349) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Use the account specified in app.toml to sign BLS transactions [\#348](https://github.com/babylonchain/babylon/pull/348) ([vitsalis](https://github.com/vitsalis)) +- Custom bindings for smart contracts [\#347](https://github.com/babylonchain/babylon/pull/347) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Make e2e tests work with new docker image [\#345](https://github.com/babylonchain/babylon/pull/345) ([vitsalis](https://github.com/vitsalis)) +- Migrate epoching and btccheckpointing module to new way of handling params [\#344](https://github.com/babylonchain/babylon/pull/344) ([KonradStaniec](https://github.com/KonradStaniec)) +- Feature/lint proto ci [\#343](https://github.com/babylonchain/babylon/pull/343) ([KonradStaniec](https://github.com/KonradStaniec)) +- Re-enable e2e tests [\#342](https://github.com/babylonchain/babylon/pull/342) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Parallelize CircleCI lint build [\#341](https://github.com/babylonchain/babylon/pull/341) ([vitsalis](https://github.com/vitsalis)) +- docker: Refactor to a lightweight unified image [\#340](https://github.com/babylonchain/babylon/pull/340) ([danbryan](https://github.com/danbryan)) +- chore: set up OpenAPI [\#339](https://github.com/babylonchain/babylon/pull/339) ([fadeev](https://github.com/fadeev)) +- refactor: remove `handler.go` files from modules [\#337](https://github.com/babylonchain/babylon/pull/337) ([fadeev](https://github.com/fadeev)) +- Cleanup params in Babylon custom modules. [\#334](https://github.com/babylonchain/babylon/pull/334) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: moving extended client keeper to Babylon repo [\#333](https://github.com/babylonchain/babylon/pull/333) ([SebastianElvis](https://github.com/SebastianElvis)) +- Use new version for our fork of ibc go [\#332](https://github.com/babylonchain/babylon/pull/332) ([KonradStaniec](https://github.com/KonradStaniec)) +- proto: fix proto-linter comments for epoching/zoneconcierge [\#331](https://github.com/babylonchain/babylon/pull/331) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix proto linter comments in btccheckpoint and monitor [\#330](https://github.com/babylonchain/babylon/pull/330) ([KonradStaniec](https://github.com/KonradStaniec)) +- proto-lint: Add comments to btclightclient and checkpointing proto files [\#329](https://github.com/babylonchain/babylon/pull/329) ([vitsalis](https://github.com/vitsalis)) +- CI: Build and push Docker image to ECR [\#328](https://github.com/babylonchain/babylon/pull/328) ([filippos47](https://github.com/filippos47)) +- Bump cosmos-sdk to stable version [\#327](https://github.com/babylonchain/babylon/pull/327) ([KonradStaniec](https://github.com/KonradStaniec)) +- Integrate wasmd [\#324](https://github.com/babylonchain/babylon/pull/324) ([KonradStaniec](https://github.com/KonradStaniec)) +- Migrate to comet bft [\#323](https://github.com/babylonchain/babylon/pull/323) ([KonradStaniec](https://github.com/KonradStaniec)) +- Update protobuf generation [\#322](https://github.com/babylonchain/babylon/pull/322) ([KonradStaniec](https://github.com/KonradStaniec)) +- Use cosmos v47 [\#320](https://github.com/babylonchain/babylon/pull/320) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Add balance check before inserting MsgWrappedCreateValidator into the epoch message queue [\#318](https://github.com/babylonchain/babylon/pull/318) ([gitferry](https://github.com/gitferry)) +- checkpointing: stateless checks on `MsgCreateValidator` [\#316](https://github.com/babylonchain/babylon/pull/316) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Add fuzz test of addBlsSig [\#313](https://github.com/babylonchain/babylon/pull/313) ([gitferry](https://github.com/gitferry)) +- btccheckpoint: Add information about transactions to BTCCheckpointInfo [\#312](https://github.com/babylonchain/babylon/pull/312) ([vitsalis](https://github.com/vitsalis)) +- chore: Keep a single encoding config in the application [\#308](https://github.com/babylonchain/babylon/pull/308) ([gitferry](https://github.com/gitferry)) +- feat: Checkpointing/Add fee estimation in sending BLS-sig tx [\#307](https://github.com/babylonchain/babylon/pull/307) ([gitferry](https://github.com/gitferry)) +- prepare-genesis cmd: Add flags related to inflation [\#306](https://github.com/babylonchain/babylon/pull/306) ([vitsalis](https://github.com/vitsalis)) +- fix: remove `start_epoch` and `end_epoch` parameters in APIs [\#305](https://github.com/babylonchain/babylon/pull/305) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix whitespace for Make 4.3 [\#303](https://github.com/babylonchain/babylon/pull/303) ([freshe4qa](https://github.com/freshe4qa)) + +## [test](https://github.com/babylonchain/babylon/tree/test) (2023-03-17) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.5.0...test) + +**Implemented enhancements:** + +- Fees as a parameter for the BlsSig transaction [\#168](https://github.com/babylonchain/babylon/issues/168) + +**Fixed bugs:** + +- flaky Test: `TestRawCheckpointWithMeta_Accumulate4` [\#124](https://github.com/babylonchain/babylon/issues/124) + +**Closed issues:** + +- Use proto linter and formatter [\#321](https://github.com/babylonchain/babylon/issues/321) +- Lack of balance check before inserting MsgWrappedCreateValidator into the message queue [\#317](https://github.com/babylonchain/babylon/issues/317) +- Duplicate txs queued in the same epoch show inconsistent execution result [\#314](https://github.com/babylonchain/babylon/issues/314) +- Redundant pagination parameters in API [\#304](https://github.com/babylonchain/babylon/issues/304) +- Chain died on block 621 [\#302](https://github.com/babylonchain/babylon/issues/302) +- Add test for adding a BLS-sig transaction [\#279](https://github.com/babylonchain/babylon/issues/279) +- Add logs to show the submitter of each BLS-sig transaction [\#278](https://github.com/babylonchain/babylon/issues/278) +- zoneconcierge: API for querying submitted/confirmed chain info [\#212](https://github.com/babylonchain/babylon/issues/212) +- Validators should stop submitting BLS-sigs when they are syncing [\#182](https://github.com/babylonchain/babylon/issues/182) +- Accept encoding config in `InitPrivSigner` function instead of creating it. [\#174](https://github.com/babylonchain/babylon/issues/174) +- Improving Undelegating Requests and Lifecycle [\#159](https://github.com/babylonchain/babylon/issues/159) + +## [v0.5.0](https://github.com/babylonchain/babylon/tree/v0.5.0) (2023-02-03) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.4.0...v0.5.0) + +**Breaking changes:** + +- Improve btc checkpoint data model [\#284](https://github.com/babylonchain/babylon/pull/284) ([KonradStaniec](https://github.com/KonradStaniec)) + +**Fixed bugs:** + +- Fix vulnerability when processing bls sig transactions [\#287](https://github.com/babylonchain/babylon/pull/287) ([KonradStaniec](https://github.com/KonradStaniec)) + +**Closed issues:** + +- Error results in RawCheckpointList [\#280](https://github.com/babylonchain/babylon/issues/280) +- Creating a validator after the chain has been running for a while leads to the validator never becoming bonded. [\#275](https://github.com/babylonchain/babylon/issues/275) +- Flaky zoneconcierge test [\#251](https://github.com/babylonchain/babylon/issues/251) +- go 1.19 [\#227](https://github.com/babylonchain/babylon/issues/227) + +**Merged pull requests:** + +- Release v0.5.0 [\#301](https://github.com/babylonchain/babylon/pull/301) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge API: pagtinating chain IDs API [\#300](https://github.com/babylonchain/babylon/pull/300) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix: Monitor/fix reported checkpoint BTC height query bugs [\#299](https://github.com/babylonchain/babylon/pull/299) ([gitferry](https://github.com/gitferry)) +- Add Apache 2.0 licence [\#298](https://github.com/babylonchain/babylon/pull/298) ([vitsalis](https://github.com/vitsalis)) +- Clean and split up README [\#297](https://github.com/babylonchain/babylon/pull/297) ([vitsalis](https://github.com/vitsalis)) +- fix: add BLST\_PORTABLE flag before build instruction [\#295](https://github.com/babylonchain/babylon/pull/295) ([vitsalis](https://github.com/vitsalis)) +- btccheckpoint API: enriching existing APIs with `BTCCheckpointInfo` [\#294](https://github.com/babylonchain/babylon/pull/294) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Remove checkpointing spec [\#293](https://github.com/babylonchain/babylon/pull/293) ([gitferry](https://github.com/gitferry)) +- API: add parameters to range queries and improve outputs [\#292](https://github.com/babylonchain/babylon/pull/292) ([SebastianElvis](https://github.com/SebastianElvis)) +- btccheckpoint API: range query for BTC checkpoints [\#291](https://github.com/babylonchain/babylon/pull/291) ([SebastianElvis](https://github.com/SebastianElvis)) +- btccheckpoint API: add hash to `BtcCheckpointHeightAndHash` API [\#290](https://github.com/babylonchain/babylon/pull/290) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: range query for epochs [\#289](https://github.com/babylonchain/babylon/pull/289) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Monitor/Add new KV and query for checkpoint reported btc height [\#286](https://github.com/babylonchain/babylon/pull/286) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proper initialisation for chain info [\#285](https://github.com/babylonchain/babylon/pull/285) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: API/Fix checkpoint list total error [\#283](https://github.com/babylonchain/babylon/pull/283) ([gitferry](https://github.com/gitferry)) +- fix: Fix pagination error of RawCheckpointList [\#282](https://github.com/babylonchain/babylon/pull/282) ([gitferry](https://github.com/gitferry)) +- Bump btcd versions to fix 2 consensus issues [\#281](https://github.com/babylonchain/babylon/pull/281) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: add HTTP URL for LastCheckpointWithStatusRequest [\#277](https://github.com/babylonchain/babylon/pull/277) ([gitferry](https://github.com/gitferry)) +- epoching/checkpointing: fuzz test for validators with zero voting power [\#276](https://github.com/babylonchain/babylon/pull/276) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add simple monitor module [\#274](https://github.com/babylonchain/babylon/pull/274) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: checkpointing: Do not make the `home` flag a required one and unmarshall PubKey \(\#271\) [\#271](https://github.com/babylonchain/babylon/pull/271) ([vitsalis](https://github.com/vitsalis)) +- Fix: Increase gas in e2e test [\#270](https://github.com/babylonchain/babylon/pull/270) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add integration test for zoneconcierge checkpointing [\#269](https://github.com/babylonchain/babylon/pull/269) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: refactor `FinalizedChainInfo` API [\#268](https://github.com/babylonchain/babylon/pull/268) ([SebastianElvis](https://github.com/SebastianElvis)) +- checkpointing API: add checkpoint lifecycle in `RawCheckpointWithMeta` [\#267](https://github.com/babylonchain/babylon/pull/267) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: find header and fork headers at a given height [\#266](https://github.com/babylonchain/babylon/pull/266) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: find the BTC-finalised chain info before specific CZ height [\#264](https://github.com/babylonchain/babylon/pull/264) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: adding total number of timestamped headers to chainInfo [\#263](https://github.com/babylonchain/babylon/pull/263) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for querying headers in a given epoch [\#261](https://github.com/babylonchain/babylon/pull/261) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for querying the chain info of a given epoch [\#260](https://github.com/babylonchain/babylon/pull/260) ([SebastianElvis](https://github.com/SebastianElvis)) +- add e2e test to CI [\#259](https://github.com/babylonchain/babylon/pull/259) ([KonradStaniec](https://github.com/KonradStaniec)) +- Bump golang to 1.19 [\#257](https://github.com/babylonchain/babylon/pull/257) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: fix flaky test `FuzzProofEpochSealed_BLSSig` [\#256](https://github.com/babylonchain/babylon/pull/256) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: ignore out-of-order headers in ZoneConcierge [\#255](https://github.com/babylonchain/babylon/pull/255) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for listing the last checkpointed headers [\#254](https://github.com/babylonchain/babylon/pull/254) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add new query for the last checkpoint with a given status [\#253](https://github.com/babylonchain/babylon/pull/253) ([gitferry](https://github.com/gitferry)) + +## [v0.4.0](https://github.com/babylonchain/babylon/tree/v0.4.0) (2022-12-20) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.3.0...v0.4.0) + +**Closed issues:** + +- epoching: excessive `absent validator` logs during simulation [\#75](https://github.com/babylonchain/babylon/issues/75) + +**Merged pull requests:** + +- Release v0.4.0 [\#252](https://github.com/babylonchain/babylon/pull/252) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: typos and rename filenames [\#250](https://github.com/babylonchain/babylon/pull/250) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Introduce more control over home directory name for localnet [\#249](https://github.com/babylonchain/babylon/pull/249) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge/epoching: proof that a header is in an epoch [\#248](https://github.com/babylonchain/babylon/pull/248) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add e2e testing framework based on Osmosis [\#247](https://github.com/babylonchain/babylon/pull/247) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: verifier for `ProofEpochSubmitted` [\#246](https://github.com/babylonchain/babylon/pull/246) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add versioning based on Git names for the executable [\#245](https://github.com/babylonchain/babylon/pull/245) ([vitsalis](https://github.com/vitsalis)) +- Fix: Resolve linting errors [\#244](https://github.com/babylonchain/babylon/pull/244) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: query inclusion proofs and add them to `ProofEpochSealed` [\#243](https://github.com/babylonchain/babylon/pull/243) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add kv for validator BLS key set [\#242](https://github.com/babylonchain/babylon/pull/242) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: verifying BLS multisig in `ProofEpochSealed` [\#241](https://github.com/babylonchain/babylon/pull/241) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Unify bitmap length [\#240](https://github.com/babylonchain/babylon/pull/240) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: enriching `SubmissionData` to store BTCSpvProof [\#239](https://github.com/babylonchain/babylon/pull/239) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Move functionalities from the verifier [\#238](https://github.com/babylonchain/babylon/pull/238) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proof of a sealed epoch and make proof generation optional [\#237](https://github.com/babylonchain/babylon/pull/237) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: API for querying the validator set of a given epoch [\#236](https://github.com/babylonchain/babylon/pull/236) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add voting power to BLS key set API [\#235](https://github.com/babylonchain/babylon/pull/235) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proof that a tx is in a block [\#234](https://github.com/babylonchain/babylon/pull/234) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: repurpose heartbeat mechanism to a generic function [\#233](https://github.com/babylonchain/babylon/pull/233) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add bls pubkey set api [\#232](https://github.com/babylonchain/babylon/pull/232) ([gitferry](https://github.com/gitferry)) +- golangci-lint [\#222](https://github.com/babylonchain/babylon/pull/222) ([faddat](https://github.com/faddat)) + +## [v0.3.0](https://github.com/babylonchain/babylon/tree/v0.3.0) (2022-11-30) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.2.0...v0.3.0) + +**Breaking changes:** + +- Submission pruning improvements [\#204](https://github.com/babylonchain/babylon/pull/204) ([KonradStaniec](https://github.com/KonradStaniec)) + +**Closed issues:** + +- zoneconcierge: Chain info indexer snapshots the latest chain info for each epoch even without any relayer [\#220](https://github.com/babylonchain/babylon/issues/220) + +**Merged pull requests:** + +- Release v0.3.0 [\#231](https://github.com/babylonchain/babylon/pull/231) ([vitsalis](https://github.com/vitsalis)) +- doc: update swagger yml file [\#230](https://github.com/babylonchain/babylon/pull/230) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Update verification rule for btc raw checkpoints [\#229](https://github.com/babylonchain/babylon/pull/229) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: API route [\#228](https://github.com/babylonchain/babylon/pull/228) ([SebastianElvis](https://github.com/SebastianElvis)) +- Bump protogen cosmos [\#226](https://github.com/babylonchain/babylon/pull/226) ([vitsalis](https://github.com/vitsalis)) +- chore: Remove starport references [\#225](https://github.com/babylonchain/babylon/pull/225) ([faddat](https://github.com/faddat)) +- bump ledger and cosmos-proto [\#223](https://github.com/babylonchain/babylon/pull/223) ([faddat](https://github.com/faddat)) +- zoneconcierge: find the earliest epoch that finalised a chain info for the API [\#221](https://github.com/babylonchain/babylon/pull/221) ([SebastianElvis](https://github.com/SebastianElvis)) +- bump deps [\#218](https://github.com/babylonchain/babylon/pull/218) ([faddat](https://github.com/faddat)) +- fix: fixed marshaling issue when enqueueing CreateValidator message and added tests [\#215](https://github.com/babylonchain/babylon/pull/215) ([gitferry](https://github.com/gitferry)) + +## [v0.2.0](https://github.com/babylonchain/babylon/tree/v0.2.0) (2022-11-23) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.1.0...v0.2.0) + +**Fixed bugs:** + +- Concurrent issue when sending BLS-sig tx in a gorouting [\#197](https://github.com/babylonchain/babylon/issues/197) + +**Closed issues:** + +- Make FromName an attribute in app.toml [\#188](https://github.com/babylonchain/babylon/issues/188) +- Add correspondence check for genesis BLS keys and genesis txs [\#180](https://github.com/babylonchain/babylon/issues/180) + +**Merged pull requests:** + +- Release v0.2.0 [\#217](https://github.com/babylonchain/babylon/pull/217) ([vitsalis](https://github.com/vitsalis)) +- hotfix: fixing the hook issue in `app.go` [\#213](https://github.com/babylonchain/babylon/pull/213) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: debugging API `ChainInfo` [\#211](https://github.com/babylonchain/babylon/pull/211) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: add checkpoint info and epoch info to `FinalizedChainInfo` API [\#210](https://github.com/babylonchain/babylon/pull/210) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: restrict the used port for IBC [\#209](https://github.com/babylonchain/babylon/pull/209) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Use better short description for the babylond executable [\#208](https://github.com/babylonchain/babylon/pull/208) ([vitsalis](https://github.com/vitsalis)) +- IBC: bug fixes for creating IBC channels [\#206](https://github.com/babylonchain/babylon/pull/206) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for listing all chain IDs [\#205](https://github.com/babylonchain/babylon/pull/205) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: fuzz tests for various indexers [\#203](https://github.com/babylonchain/babylon/pull/203) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Resolved concurrency issue when sending BLS-sig txs [\#202](https://github.com/babylonchain/babylon/pull/202) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: track latest BTC-finalised header and add the query [\#201](https://github.com/babylonchain/babylon/pull/201) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: subscribe to checkpointing/epoching's hooks, and add a new hooks [\#200](https://github.com/babylonchain/babylon/pull/200) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Add signer key name into app custom config [\#199](https://github.com/babylonchain/babylon/pull/199) ([gitferry](https://github.com/gitferry)) +- feat: Introduce swagger docs for RPC queries [\#198](https://github.com/babylonchain/babylon/pull/198) ([vitsalis](https://github.com/vitsalis)) +- feat: Add genesis time on genesis parameters [\#196](https://github.com/babylonchain/babylon/pull/196) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: heartbeat IBC packet to keep relayer awake [\#195](https://github.com/babylonchain/babylon/pull/195) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: test infra for IBC and vanilla tests [\#193](https://github.com/babylonchain/babylon/pull/193) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add changelog [\#192](https://github.com/babylonchain/babylon/pull/192) ([KonradStaniec](https://github.com/KonradStaniec)) +- datagen: add datagen functions for testing reporter [\#190](https://github.com/babylonchain/babylon/pull/190) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: hook onto the light client and index headers/forks [\#189](https://github.com/babylonchain/babylon/pull/189) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: replace IBC-Go with Babylon's fork, and implement DB schemas [\#184](https://github.com/babylonchain/babylon/pull/184) ([SebastianElvis](https://github.com/SebastianElvis)) + +## [v0.1.0](https://github.com/babylonchain/babylon/tree/v0.1.0) (2022-11-05) + +[Full Changelog](https://github.com/babylonchain/babylon/compare/b1645c9eea6511069c0b2ad0328d794018450eac...v0.1.0) + +**Implemented enhancements:** + +- Checkpointing: remove hardcoded FlagFee [\#160](https://github.com/babylonchain/babylon/issues/160) +- Proper coin denomination for testnet [\#139](https://github.com/babylonchain/babylon/issues/139) +- chore: bump Cosmos SDK dependency to `v0.46.0` [\#93](https://github.com/babylonchain/babylon/issues/93) +- btclightclient: Store BTCHeaderInfo objects instead of BTCHeaderBytes objects [\#57](https://github.com/babylonchain/babylon/issues/57) + +**Fixed bugs:** + +- bug: Transaction submission panics due to unavailability of BTC config [\#117](https://github.com/babylonchain/babylon/issues/117) +- epoching: simulation panicked with error message `panic: no delegation distribution info` [\#74](https://github.com/babylonchain/babylon/issues/74) +- Epoching AnteHandler rejects genesis staking transactions [\#36](https://github.com/babylonchain/babylon/issues/36) +- Fix handling duplicated submissions [\#163](https://github.com/babylonchain/babylon/pull/163) ([KonradStaniec](https://github.com/KonradStaniec)) + +**Closed issues:** + +- Improve sending of bls transaction by checkpointing module. [\#155](https://github.com/babylonchain/babylon/issues/155) +- Checkpointing: random BLS-sig transactions are not executed successfully [\#141](https://github.com/babylonchain/babylon/issues/141) +- Fix integration test and blssigner denominations [\#137](https://github.com/babylonchain/babylon/issues/137) +- Errors prompted by the static analyser in `x/btclightclient` [\#9](https://github.com/babylonchain/babylon/issues/9) + +**Merged pull requests:** + +- Release v0.1.0 [\#191](https://github.com/babylonchain/babylon/pull/191) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add validate-genesis cmd [\#187](https://github.com/babylonchain/babylon/pull/187) ([gitferry](https://github.com/gitferry)) +- chore: add correspondence check against gentx when adding genesis BLS keys [\#186](https://github.com/babylonchain/babylon/pull/186) ([gitferry](https://github.com/gitferry)) +- chore: regtest support [\#185](https://github.com/babylonchain/babylon/pull/185) ([SebastianElvis](https://github.com/SebastianElvis)) +- Implement ADR-01 [\#183](https://github.com/babylonchain/babylon/pull/183) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Upgrade proto generation Docker image and script [\#181](https://github.com/babylonchain/babylon/pull/181) ([vitsalis](https://github.com/vitsalis)) +- Fix accepting submission [\#179](https://github.com/babylonchain/babylon/pull/179) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add add-genesis-bls cmd [\#178](https://github.com/babylonchain/babylon/pull/178) ([gitferry](https://github.com/gitferry)) +- fix: CI failed after merging \#175 [\#177](https://github.com/babylonchain/babylon/pull/177) ([gitferry](https://github.com/gitferry)) +- ibc: vanilla IBC module [\#176](https://github.com/babylonchain/babylon/pull/176) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: add create-genesis-bls cmd [\#175](https://github.com/babylonchain/babylon/pull/175) ([gitferry](https://github.com/gitferry)) +- Bump cosmos sdk [\#173](https://github.com/babylonchain/babylon/pull/173) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add prepare-genesis command [\#172](https://github.com/babylonchain/babylon/pull/172) ([vitsalis](https://github.com/vitsalis)) +- Refactor submission bitcoin status [\#170](https://github.com/babylonchain/babylon/pull/170) ([KonradStaniec](https://github.com/KonradStaniec)) +- Validate btc objects in ante-handler [\#169](https://github.com/babylonchain/babylon/pull/169) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Use \(u\)bbn bond denominations [\#167](https://github.com/babylonchain/babylon/pull/167) ([vitsalis](https://github.com/vitsalis)) +- feat: checkpointing/improve the sending of BLS-sig tx [\#166](https://github.com/babylonchain/babylon/pull/166) ([gitferry](https://github.com/gitferry)) +- feat: checkpointing/implement WrappedCreateValidator cli [\#165](https://github.com/babylonchain/babylon/pull/165) ([gitferry](https://github.com/gitferry)) +- Move retry module from Vigilante to BBN [\#164](https://github.com/babylonchain/babylon/pull/164) ([gusin13](https://github.com/gusin13)) +- feat: checkpointing/add create-bls-key cli [\#162](https://github.com/babylonchain/babylon/pull/162) ([gitferry](https://github.com/gitferry)) +- chore: checkpointing/refactor validate basic [\#161](https://github.com/babylonchain/babylon/pull/161) ([gitferry](https://github.com/gitferry)) +- Query to get submissions for given epoch [\#158](https://github.com/babylonchain/babylon/pull/158) ([KonradStaniec](https://github.com/KonradStaniec)) +- Functionality for building custom mainnet tags [\#157](https://github.com/babylonchain/babylon/pull/157) ([vitsalis](https://github.com/vitsalis)) +- Improve integration tests [\#156](https://github.com/babylonchain/babylon/pull/156) ([KonradStaniec](https://github.com/KonradStaniec)) +- epoching: fix error of `unexpected validator in unbonding queue` [\#154](https://github.com/babylonchain/babylon/pull/154) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix ancestry error [\#153](https://github.com/babylonchain/babylon/pull/153) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: fix error msg typo of btccheckpoint [\#151](https://github.com/babylonchain/babylon/pull/151) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching/checkpointing: checkpoint-assisted unbonding [\#150](https://github.com/babylonchain/babylon/pull/150) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Allow minimum work headers for a testnet/simnet [\#148](https://github.com/babylonchain/babylon/pull/148) ([vitsalis](https://github.com/vitsalis)) +- Add test for checkpoint submissions and state change [\#147](https://github.com/babylonchain/babylon/pull/147) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: fixed decoder for checkpoint [\#146](https://github.com/babylonchain/babylon/pull/146) ([gitferry](https://github.com/gitferry)) +- epoching: add delegator address to events [\#145](https://github.com/babylonchain/babylon/pull/145) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: checkpointing/add logs for checkpoint status change [\#144](https://github.com/babylonchain/babylon/pull/144) ([gitferry](https://github.com/gitferry)) +- epoching: delegation lifecycle [\#143](https://github.com/babylonchain/babylon/pull/143) ([SebastianElvis](https://github.com/SebastianElvis)) +- Relax tx formatter rules [\#142](https://github.com/babylonchain/babylon/pull/142) ([KonradStaniec](https://github.com/KonradStaniec)) +- epoching: bugfix of `LatestEpochMsgs` API [\#140](https://github.com/babylonchain/babylon/pull/140) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: CLI for delegating/undelegating/redelegating requests [\#138](https://github.com/babylonchain/babylon/pull/138) ([SebastianElvis](https://github.com/SebastianElvis)) +- Revert: testnet: denom of gas price \#133 [\#136](https://github.com/babylonchain/babylon/pull/136) ([vitsalis](https://github.com/vitsalis)) +- bitcoinsim: Remove it from the repository [\#135](https://github.com/babylonchain/babylon/pull/135) ([vitsalis](https://github.com/vitsalis)) +- testnet: denom of gas price [\#133](https://github.com/babylonchain/babylon/pull/133) ([SebastianElvis](https://github.com/SebastianElvis)) +- btclightclient: create temporary method for Contains request with bytes parameter [\#132](https://github.com/babylonchain/babylon/pull/132) ([SebastianElvis](https://github.com/SebastianElvis)) +- btclightclient: Add BaseHeader query [\#130](https://github.com/babylonchain/babylon/pull/130) ([vitsalis](https://github.com/vitsalis)) +- Remove full stack deployment and irrelevant files [\#129](https://github.com/babylonchain/babylon/pull/129) ([vitsalis](https://github.com/vitsalis)) +- testnet: Add CLI args for specifying btccheckpoint and staking genesis params [\#128](https://github.com/babylonchain/babylon/pull/128) ([vitsalis](https://github.com/vitsalis)) +- Add extending btc light client chain in tests [\#127](https://github.com/babylonchain/babylon/pull/127) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: checkpointing/refactor bls-signer [\#126](https://github.com/babylonchain/babylon/pull/126) ([gitferry](https://github.com/gitferry)) +- fix: Re-introduce localnet start to enable integration tests [\#125](https://github.com/babylonchain/babylon/pull/125) ([vitsalis](https://github.com/vitsalis)) +- docker: Include vigilantes and explorer in the localnet deployment [\#123](https://github.com/babylonchain/babylon/pull/123) ([vitsalis](https://github.com/vitsalis)) +- fix: checkpointing/query epoch status count bug [\#122](https://github.com/babylonchain/babylon/pull/122) ([gitferry](https://github.com/gitferry)) +- Fixes initialisation bug [\#121](https://github.com/babylonchain/babylon/pull/121) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/integrate bls-sig tx into the message flow [\#120](https://github.com/babylonchain/babylon/pull/120) ([gitferry](https://github.com/gitferry)) +- epoching API: add epoch msg range queries and add timestamp to validator lifecycle [\#119](https://github.com/babylonchain/babylon/pull/119) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: bls-sig accumulating bug and added tests [\#118](https://github.com/babylonchain/babylon/pull/118) ([gitferry](https://github.com/gitferry)) +- epoching API: add timestamp to queued messages [\#116](https://github.com/babylonchain/babylon/pull/116) ([SebastianElvis](https://github.com/SebastianElvis)) +- Parameterize genesis and config through testnet command flags [\#115](https://github.com/babylonchain/babylon/pull/115) ([vitsalis](https://github.com/vitsalis)) +- Add custom query [\#114](https://github.com/babylonchain/babylon/pull/114) ([KonradStaniec](https://github.com/KonradStaniec)) +- btccheckpoint: make kDeep/wDeep as system parameters [\#113](https://github.com/babylonchain/babylon/pull/113) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: checkpointing/add typed events [\#112](https://github.com/babylonchain/babylon/pull/112) ([gitferry](https://github.com/gitferry)) +- feat: checkpointing/ add queries about epoch status [\#111](https://github.com/babylonchain/babylon/pull/111) ([gitferry](https://github.com/gitferry)) +- chore: BLS signer refactor [\#110](https://github.com/babylonchain/babylon/pull/110) ([gitferry](https://github.com/gitferry)) +- epoching API: validator lifecycle [\#109](https://github.com/babylonchain/babylon/pull/109) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: API: epoch\_msgs/{epoch\_num} -\> all events during this epoch [\#108](https://github.com/babylonchain/babylon/pull/108) ([SebastianElvis](https://github.com/SebastianElvis)) +- btcutils: refactor for vigilante [\#107](https://github.com/babylonchain/babylon/pull/107) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Replace all instances of bbl with bbn [\#106](https://github.com/babylonchain/babylon/pull/106) ([vitsalis](https://github.com/vitsalis)) +- Add babylon app config [\#105](https://github.com/babylonchain/babylon/pull/105) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/implement BLS signer [\#104](https://github.com/babylonchain/babylon/pull/104) ([gitferry](https://github.com/gitferry)) +- Add parsing correct format in btccheckpoint [\#102](https://github.com/babylonchain/babylon/pull/102) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add genesis state for checkpointing [\#101](https://github.com/babylonchain/babylon/pull/101) ([gitferry](https://github.com/gitferry)) +- Add fuzz tests to formatter [\#100](https://github.com/babylonchain/babylon/pull/100) ([KonradStaniec](https://github.com/KonradStaniec)) +- Fix: checkpointing/epoch growth bug [\#99](https://github.com/babylonchain/babylon/pull/99) ([gitferry](https://github.com/gitferry)) +- chore: replace bbl with bbn and gitignore [\#98](https://github.com/babylonchain/babylon/pull/98) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: checkpointing/changed PoP by signing BLS public key [\#97](https://github.com/babylonchain/babylon/pull/97) ([gitferry](https://github.com/gitferry)) +- Add initial implementation of tx formatter [\#96](https://github.com/babylonchain/babylon/pull/96) ([KonradStaniec](https://github.com/KonradStaniec)) +- BM-102: Single BTC node in docker producing blocks [\#95](https://github.com/babylonchain/babylon/pull/95) ([aakoshh](https://github.com/aakoshh)) +- Add initial test checking progress [\#94](https://github.com/babylonchain/babylon/pull/94) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add tests to ci [\#90](https://github.com/babylonchain/babylon/pull/90) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Add checkpoint query with status [\#89](https://github.com/babylonchain/babylon/pull/89) ([gitferry](https://github.com/gitferry)) +- enable gRPC gateway routes for rest queries [\#88](https://github.com/babylonchain/babylon/pull/88) ([toliujiayi](https://github.com/toliujiayi)) +- Wire app without mocks [\#87](https://github.com/babylonchain/babylon/pull/87) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: implement bls key generation [\#86](https://github.com/babylonchain/babylon/pull/86) ([gitferry](https://github.com/gitferry)) +- Add integration tests [\#85](https://github.com/babylonchain/babylon/pull/85) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/implement checkpoint verification and keeper tests [\#84](https://github.com/babylonchain/babylon/pull/84) ([gitferry](https://github.com/gitferry)) +- Add btccheckpoit unit tests [\#83](https://github.com/babylonchain/babylon/pull/83) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: btclightclient: Add BTCHeaderInserted event [\#82](https://github.com/babylonchain/babylon/pull/82) ([vitsalis](https://github.com/vitsalis)) +- fix: Remove WASM config from application configuration [\#81](https://github.com/babylonchain/babylon/pull/81) ([vitsalis](https://github.com/vitsalis)) +- epoching: smaller epoch interval in simulation [\#80](https://github.com/babylonchain/babylon/pull/80) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: Use a caching multistore in delayed staking message handler [\#79](https://github.com/babylonchain/babylon/pull/79) ([aakoshh](https://github.com/aakoshh)) +- feat: checkpointing/implement cli [\#78](https://github.com/babylonchain/babylon/pull/78) ([gitferry](https://github.com/gitferry)) +- fix: Add installation instructions and executable reference [\#77](https://github.com/babylonchain/babylon/pull/77) ([vitsalis](https://github.com/vitsalis)) +- chore: issue templates [\#76](https://github.com/babylonchain/babylon/pull/76) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Register msg server for all modules & instructions for tx submission [\#73](https://github.com/babylonchain/babylon/pull/73) ([vitsalis](https://github.com/vitsalis)) +- feat: btclightclient: Refactor keepers based on needs of btcheckpoint module [\#72](https://github.com/babylonchain/babylon/pull/72) ([vitsalis](https://github.com/vitsalis)) +- simulation: vanilla simulation tests [\#71](https://github.com/babylonchain/babylon/pull/71) ([SebastianElvis](https://github.com/SebastianElvis)) +- Implement core btc handling logic [\#70](https://github.com/babylonchain/babylon/pull/70) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: btclightclient: gRPC query fuzz tests [\#69](https://github.com/babylonchain/babylon/pull/69) ([vitsalis](https://github.com/vitsalis)) +- epoching: simulation infra for integration testing [\#68](https://github.com/babylonchain/babylon/pull/68) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: btclightclient: Add keeper fuzz tests [\#67](https://github.com/babylonchain/babylon/pull/67) ([vitsalis](https://github.com/vitsalis)) +- epoching: fuzz tests on epoched undelegations and redelegations [\#66](https://github.com/babylonchain/babylon/pull/66) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: refactor test infra, mock messages and sample fuzz tests [\#65](https://github.com/babylonchain/babylon/pull/65) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: fuzz tests for slashed validator set [\#64](https://github.com/babylonchain/babylon/pull/64) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: replace deprecated `EmitEvent` APIs with `EmitTypedEvent` ones [\#63](https://github.com/babylonchain/babylon/pull/63) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: btclightclient HeadersState keeper fuzz tests [\#61](https://github.com/babylonchain/babylon/pull/61) ([vitsalis](https://github.com/vitsalis)) +- epoching: more test infra and some fuzz tests on keeper functionalities [\#60](https://github.com/babylonchain/babylon/pull/60) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: checkpointing/aggregate BLS signatures [\#59](https://github.com/babylonchain/babylon/pull/59) ([gitferry](https://github.com/gitferry)) +- feat: btclightclient: Abstract the usage of btcd types and store BTCHeaderInfo objects [\#58](https://github.com/babylonchain/babylon/pull/58) ([vitsalis](https://github.com/vitsalis)) +- feat: Replace BTC types unit tests with fuzz tests [\#56](https://github.com/babylonchain/babylon/pull/56) ([vitsalis](https://github.com/vitsalis)) +- feat: Create datagen testutil for common random generation functions [\#55](https://github.com/babylonchain/babylon/pull/55) ([vitsalis](https://github.com/vitsalis)) +- epoching: wrapper type `Epoch` and simplify code using this type [\#54](https://github.com/babylonchain/babylon/pull/54) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add btclightclient events and hooks [\#53](https://github.com/babylonchain/babylon/pull/53) ([vitsalis](https://github.com/vitsalis)) +- feat: add raw checkpoint creation [\#52](https://github.com/babylonchain/babylon/pull/52) ([gitferry](https://github.com/gitferry)) +- feat: Add accumulattive PoW functionality to btclightclient [\#51](https://github.com/babylonchain/babylon/pull/51) ([vitsalis](https://github.com/vitsalis)) +- btclightclient: Cleanup codebase and add descriptive comments [\#50](https://github.com/babylonchain/babylon/pull/50) ([vitsalis](https://github.com/vitsalis)) +- Update go to 1.18 in README [\#49](https://github.com/babylonchain/babylon/pull/49) ([vitsalis](https://github.com/vitsalis)) +- Upgrade to go 1.18 [\#48](https://github.com/babylonchain/babylon/pull/48) ([vitsalis](https://github.com/vitsalis)) +- feat: define checkpointing registration proto and state [\#46](https://github.com/babylonchain/babylon/pull/46) ([gitferry](https://github.com/gitferry)) +- BM-60: Database schema ER diagram [\#45](https://github.com/babylonchain/babylon/pull/45) ([aakoshh](https://github.com/aakoshh)) +- Revert "feat: CI: Generate a single block in build check " [\#44](https://github.com/babylonchain/babylon/pull/44) ([vitsalis](https://github.com/vitsalis)) +- Btccheckpoint oracle schema and processing [\#43](https://github.com/babylonchain/babylon/pull/43) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Fuzz and unit tests for btclightclient types [\#42](https://github.com/babylonchain/babylon/pull/42) ([vitsalis](https://github.com/vitsalis)) +- epoching: fix genesis, param and bootstrapping [\#41](https://github.com/babylonchain/babylon/pull/41) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add unit tests for ValidateHeader of btcutils [\#40](https://github.com/babylonchain/babylon/pull/40) ([vitsalis](https://github.com/vitsalis)) +- feat: Add unit tests for BTCHeaderHashBytes and BTCHeaderBytes types [\#39](https://github.com/babylonchain/babylon/pull/39) ([vitsalis](https://github.com/vitsalis)) +- Add building, testing, and testnet instructions on README [\#38](https://github.com/babylonchain/babylon/pull/38) ([vitsalis](https://github.com/vitsalis)) +- feat: CI: Generate a single block in build check [\#37](https://github.com/babylonchain/babylon/pull/37) ([vitsalis](https://github.com/vitsalis)) +- epoching: event and hook upon a certain threshold amount of slashed voting power [\#35](https://github.com/babylonchain/babylon/pull/35) ([SebastianElvis](https://github.com/SebastianElvis)) +- doc: add BLS key registration spec [\#34](https://github.com/babylonchain/babylon/pull/34) ([gitferry](https://github.com/gitferry)) +- feat: add hooks, events, and error types to the checkpointing module [\#33](https://github.com/babylonchain/babylon/pull/33) ([gitferry](https://github.com/gitferry)) +- epoching: state transition upon `BeginBlock` and `EndBlock` [\#32](https://github.com/babylonchain/babylon/pull/32) ([SebastianElvis](https://github.com/SebastianElvis)) +- Handle insert checkpoint [\#31](https://github.com/babylonchain/babylon/pull/31) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add btclightclient chain query [\#30](https://github.com/babylonchain/babylon/pull/30) ([vitsalis](https://github.com/vitsalis)) +- feat: Implement BTCHeaderBytes and BTCHeaderHashBytes types [\#29](https://github.com/babylonchain/babylon/pull/29) ([vitsalis](https://github.com/vitsalis)) +- epoching: copy/paste necessary code from staking/evidence/slashing and make modifications [\#28](https://github.com/babylonchain/babylon/pull/28) ([SebastianElvis](https://github.com/SebastianElvis)) +- checkpointing: add keeper and core state [\#27](https://github.com/babylonchain/babylon/pull/27) ([gitferry](https://github.com/gitferry)) +- FIX: btclightclient: Properly convert the input of contains to bytes [\#26](https://github.com/babylonchain/babylon/pull/26) ([vitsalis](https://github.com/vitsalis)) +- BM-32: Update diagrams for out-of-sequence checkpoint handling [\#25](https://github.com/babylonchain/babylon/pull/25) ([aakoshh](https://github.com/aakoshh)) +- FIX\(localnet\): Redirect babylond stderr to stdout [\#24](https://github.com/babylonchain/babylon/pull/24) ([vitsalis](https://github.com/vitsalis)) +- BM-31: Add CircleCI pipeline for building and testing [\#23](https://github.com/babylonchain/babylon/pull/23) ([vitsalis](https://github.com/vitsalis)) +- FIX: Failing btclightclient tests, remove unneeded ones, clean up [\#22](https://github.com/babylonchain/babylon/pull/22) ([vitsalis](https://github.com/vitsalis)) +- FIX: Replace 'unimplemented' AnteHandler panic with comment [\#21](https://github.com/babylonchain/babylon/pull/21) ([vitsalis](https://github.com/vitsalis)) +- FIX: Implement Msg interface for MsgInsertBTCSpvProof [\#20](https://github.com/babylonchain/babylon/pull/20) ([vitsalis](https://github.com/vitsalis)) +- epoching: keeper functions, queries, and testing infra [\#19](https://github.com/babylonchain/babylon/pull/19) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: Wrapped messages and AnteHandler implementation [\#18](https://github.com/babylonchain/babylon/pull/18) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: Stringer in RawCheckpoint and correct checkpointing module ModuleName [\#17](https://github.com/babylonchain/babylon/pull/17) ([vitsalis](https://github.com/vitsalis)) +- BM-16: feat\(epoching\): add AnteHandler `DropValidatorMsgDecorator` [\#15](https://github.com/babylonchain/babylon/pull/15) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-13: feat\(epoching\): add hooks, events and keeper functions [\#14](https://github.com/babylonchain/babylon/pull/14) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-10: Basic btcheaderoracle module [\#13](https://github.com/babylonchain/babylon/pull/13) ([vitsalis](https://github.com/vitsalis)) +- BM-17: Add basic functianalities of bls crypto [\#12](https://github.com/babylonchain/babylon/pull/12) ([gitferry](https://github.com/gitferry)) +- FIX: Resolve inconsistent BTCLightClientKeeper name [\#11](https://github.com/babylonchain/babylon/pull/11) ([vitsalis](https://github.com/vitsalis)) +- BM-15: feat\(epoching\): add protobuf messages [\#10](https://github.com/babylonchain/babylon/pull/10) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-6: Initial proposal for btc checkpoint message [\#8](https://github.com/babylonchain/babylon/pull/8) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Do not modify go.mod when generating proto files [\#7](https://github.com/babylonchain/babylon/pull/7) ([vitsalis](https://github.com/vitsalis)) +- BM-5: feat\(btc light client\): BTC Light Client module setup [\#6](https://github.com/babylonchain/babylon/pull/6) ([vitsalis](https://github.com/vitsalis)) +- BM-2: feat\(checkpointing\): init checkpointing module and define proto types [\#5](https://github.com/babylonchain/babylon/pull/5) ([gitferry](https://github.com/gitferry)) +- BM-6: Add initial scaffold for rawcheckpoint module [\#4](https://github.com/babylonchain/babylon/pull/4) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Add script that downloads third party proto dependencies [\#3](https://github.com/babylonchain/babylon/pull/3) ([vitsalis](https://github.com/vitsalis)) +- BM-3: feat\(epoching\): Epoching module setup [\#2](https://github.com/babylonchain/babylon/pull/2) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-4: Add docs/diagrams with a Makefile and a test. [\#1](https://github.com/babylonchain/babylon/pull/1) ([aakoshh](https://github.com/aakoshh)) + + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* diff --git a/Makefile b/Makefile index bd525c73e..718e7da00 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,14 @@ ifeq (,$(findstring nostrip,$(BABYLON_BUILD_OPTIONS))) BUILD_FLAGS += -trimpath endif +# Update changelog vars +ifneq (,$(SINCE_TAG)) + since_tag := --since-tag $(SINCE_TAG) +endif +ifneq (,$(UPCOMING_TAG)) + upcoming_tag := --upcoming-tag $(UPCOMING_TAG) +endif + all: tools build lint test # The below include contains the tools and runsim targets. @@ -441,3 +449,8 @@ localnet-stop .PHONY: diagrams diagrams: $(MAKE) -C client/docs/diagrams + +.PHONY: update-changelog +update-changelog: + @echo ./scripts/update_changelog.sh $(since_tag) $(upcoming_tag) + ./scripts/update_changelog.sh $(since_tag) $(upcoming_tag) diff --git a/scripts/update_changelog.sh b/scripts/update_changelog.sh new file mode 100755 index 000000000..cb3e3674a --- /dev/null +++ b/scripts/update_changelog.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# This is a wrapper around `github_changelog_generator` (https://github.com/github-changelog-generator) +# to simplify / automate updating of the CHANGELOG.md file. +# +# Originally developed for CosmWasm cw_plus (https://github.com/CosmWasm/cw-plus) repository. +set -o errexit -o pipefail + +ORIGINAL_OPTS=$* +# Requires getopt from util-linux 2.37.4 (brew install gnu-getopt on Mac) +OPTS=$(getopt -l "help,release-branch:,since-tag:,upcoming-tag:,full,token:" -o "hu:ft" -- "$@") || exit 1 + +function print_usage() { + echo -e "Usage: $0 [-h|--help] [-f|--full] [--release-branch ] [--since-tag ] [-u|--upcoming-tag] [-t|--token ] + +-h, --help Display help +-f, --full Process changes since the beginning (by default: since latest git version tag) +--release-branch Limit pull requests to the release branch . +--since-tag Process changes since git version tag (by default: since latest git version tag) +-u, --upcoming-tag Add a title in CHANGELOG for the new changes +--token Pass changelog github token " +} + +function remove_opt() { + ORIGINAL_OPTS=$(echo "$ORIGINAL_OPTS" | sed "s/\\B$1\\b//") +} + +eval set -- "$OPTS" +while true +do +case $1 in + -h|--help) + print_usage + exit 0 + ;; + --since-tag) + shift + TAG="$1" + ;; + -f|--full) + TAG="" + remove_opt $1 + ;; + -u|--upcoming-tag) + remove_opt $1 + shift + UPCOMING_TAG="$1" + remove_opt $1 + ;; + --) + shift + break + ;; +esac +shift +done + +# Get user and repo from ./.git/config +ORIGIN_URL=$(git config --local remote.origin.url) +GITHUB_USER=$(echo $ORIGIN_URL | sed -n 's#.*:\([^\/]*\)\/.*#\1#p') +echo "Github user: $GITHUB_USER" +GITHUB_REPO=$(echo $ORIGIN_URL | sed -n 's#.*/\(.*\)\.git#\1#p') +echo "Github repo: $GITHUB_REPO" + +if [ -z "$TAG" ] +then + # Use latest git version tag + TAG=$(git tag --sort=creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | tail -1) + ORIGINAL_OPTS="$ORIGINAL_OPTS --since-tag $TAG" +fi + +echo "Git version tag: $TAG" + +cp CHANGELOG.md /tmp/CHANGELOG.md.$$ +# Consolidate tag for matching changelog entries +TAG=$(echo "$TAG" | sed -e 's/-\([A-Za-z]*\)[^A-Za-z]*/-\1/' -e 's/-$//') +echo "Consolidated tag: $TAG" +sed -i -n "/^## \\[${TAG}[^]]*\\]/,\$p" CHANGELOG.md + +echo github_changelog_generator -u $GITHUB_USER -p $GITHUB_REPO --base CHANGELOG.md $ORIGINAL_OPTS || cp /tmp/CHANGELOG.md.$$ CHANGELOG.md +github_changelog_generator -u $GITHUB_USER -p $GITHUB_REPO --base CHANGELOG.md $ORIGINAL_OPTS || cp /tmp/CHANGELOG.md.$$ CHANGELOG.md + +if [ -n "$UPCOMING_TAG" ] +then + # Add "upcoming" version tag + TODAY=$(date "+%Y-%m-%d") + sed -i "s+\[Full Changelog\](https://github.com/$GITHUB_USER/$GITHUB_REPO/compare/\(.*\)\.\.\.HEAD)+[Full Changelog](https://github.com/$GITHUB_USER/$GITHUB_REPO/compare/$UPCOMING_TAG...HEAD)\n\n## [$UPCOMING_TAG](https://github.com/$GITHUB_USER/$GITHUB_REPO/tree/$UPCOMING_TAG) ($TODAY)\n\n[Full Changelog](https://github.com/$GITHUB_USER/$GITHUB_REPO/compare/\1...$UPCOMING_TAG)+" CHANGELOG.md +fi + +rm -f /tmp/CHANGELOG.md.$$ From b77528498351beeceaccfae28b6243da78e4463c Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 12 Feb 2024 11:04:15 +1100 Subject: [PATCH 002/119] metrics: add performance and application metrics for BTC staking (#440) --- x/btcstaking/keeper/finality_providers.go | 1 + x/btcstaking/keeper/keeper.go | 45 +++++++++-- x/btcstaking/keeper/msg_server.go | 12 +++ x/btcstaking/types/metrics.go | 91 +++++++++++++++++++++++ x/finality/keeper/indexed_blocks.go | 3 + x/finality/keeper/msg_server.go | 6 ++ x/finality/keeper/tallying.go | 2 + x/finality/types/metrics.go | 45 +++++++++++ 8 files changed, 199 insertions(+), 6 deletions(-) create mode 100644 x/btcstaking/types/metrics.go create mode 100644 x/finality/types/metrics.go diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index 01b7e0c77..8084df572 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -53,6 +53,7 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error } fp.SlashedBtcHeight = btcTip.Height k.SetFinalityProvider(ctx, fp) + return nil } diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 64197cc54..1fc63966e 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -13,6 +13,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +const ( + SatoshisPerBTC = 100_000_000 +) + type ( Keeper struct { cdc codec.BinaryCodec @@ -63,7 +67,7 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { // index BTC height at the current height k.IndexBTCHeight(ctx) - covenantQuorum := k.GetParams(ctx).CovenantQuorum + params := k.GetParams(ctx) btcTipHeight, err := k.GetCurrentBTCHeight(ctx) if err != nil { panic(err) // only possible upon programming error @@ -74,7 +78,21 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { activeFps := []*types.FinalityProviderWithMeta{} // prepare for recording finality providers and their BTC delegations // for rewards - rdc := types.NewRewardDistCache() + dc := types.NewRewardDistCache() + + // prepare metrics for {active, inactive} finality providers, + // {pending, active, unbonded BTC delegations}, and total staked Bitcoins + // NOTE: slashed finality providers and BTC delegations are recorded upon + // slashing events rather than here + var ( + numFPs int = 0 + numStakedSats uint64 = 0 + numDelsMap = map[types.BTCDelegationStatus]int{ + types.BTCDelegationStatus_PENDING: 0, + types.BTCDelegationStatus_ACTIVE: 0, + types.BTCDelegationStatus_UNBONDED: 0, + } + ) // iterate over all finality providers to find out non-slashed ones that have // positive voting power @@ -87,7 +105,12 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { // in order to accumulate voting power and reward dist info for it k.IterateBTCDelegations(ctx, fp.BtcPk, func(btcDel *types.BTCDelegation) bool { // accumulate voting power and reward distribution cache - fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, covenantQuorum) + fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, params.CovenantQuorum) + + // record metrics + numStakedSats += btcDel.VotingPower(btcTipHeight, wValue, params.CovenantQuorum) + numDelsMap[btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum)]++ + return true }) @@ -97,15 +120,25 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { VotingPower: fpDistInfo.TotalVotingPower, } activeFps = append(activeFps, activeFP) - rdc.AddFinalityProviderDistInfo(fpDistInfo) + dc.AddFinalityProviderDistInfo(fpDistInfo) } return true }, ) + // record metrics for finality providers and total staked BTCs + numActiveFPs := min(numFPs, int(params.MaxActiveFinalityProviders)) + types.RecordActiveFinalityProviders(numActiveFPs) + types.RecordInactiveFinalityProviders(numFPs - numActiveFPs) + numStakedBTCs := float32(numStakedSats / SatoshisPerBTC) + types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) + // record metrics for BTC delegations + for status, num := range numDelsMap { + types.RecordBTCDelegations(num, status) + } // filter out top `MaxActiveFinalityProviders` active finality providers in terms of voting power - activeFps = types.FilterTopNFinalityProviders(activeFps, k.GetParams(ctx).MaxActiveFinalityProviders) + activeFps = types.FilterTopNFinalityProviders(activeFps, params.MaxActiveFinalityProviders) // set voting power table babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) for _, fp := range activeFps { @@ -114,7 +147,7 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { // set the reward distribution cache of the current height // TODO: only give rewards to top N finality providers and their BTC delegations - k.setRewardDistCache(ctx, uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height), rdc) + k.setRewardDistCache(ctx, babylonTipHeight, dc) return nil } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 9384e997f..f42d2ca5a 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "time" errorsmod "cosmossdk.io/errors" @@ -12,6 +13,7 @@ import ( "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "google.golang.org/grpc/codes" @@ -49,6 +51,8 @@ func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdatePara // CreateFinalityProvider creates a finality provider func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.MsgCreateFinalityProvider) (*types.MsgCreateFinalityProviderResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCreateFinalityProvider) + // ensure the finality provider address does not already exist ctx := sdk.UnwrapSDKContext(goCtx) // basic stateless checks @@ -96,6 +100,8 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg // CreateBTCDelegation creates a BTC delegation // TODO: refactor this handler. It's now too convoluted func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCreateBTCDelegation) (*types.MsgCreateBTCDelegationResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCreateBTCDelegation) + ctx := sdk.UnwrapSDKContext(goCtx) // basic stateless checks if err := req.ValidateBasic(); err != nil { @@ -382,6 +388,8 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre // AddCovenantSig adds signatures from covenants to a BTC delegation // TODO: refactor this handler. Now it's too convoluted func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCovenantSigs) (*types.MsgAddCovenantSigsResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyAddCovenantSigs) + ctx := sdk.UnwrapSDKContext(goCtx) // basic stateless checks if err := req.ValidateBasic(); err != nil { @@ -528,6 +536,8 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove // this effectively proves that the BTC delegator wants to unbond and Babylon // will consider its BTC delegation unbonded func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndelegate) (*types.MsgBTCUndelegateResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyBTCUndelegate) + ctx := sdk.UnwrapSDKContext(goCtx) // basic stateless checks if err := req.ValidateBasic(); err != nil { @@ -598,6 +608,8 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele // SelectiveSlashingEvidence handles the evidence that a finality provider has // selectively slashed a BTC delegation func (ms msgServer) SelectiveSlashingEvidence(goCtx context.Context, req *types.MsgSelectiveSlashingEvidence) (*types.MsgSelectiveSlashingEvidenceResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeySelectiveSlashingEvidence) + ctx := sdk.UnwrapSDKContext(goCtx) bsParams := ms.GetParams(ctx) diff --git a/x/btcstaking/types/metrics.go b/x/btcstaking/types/metrics.go new file mode 100644 index 000000000..ab0cc699a --- /dev/null +++ b/x/btcstaking/types/metrics.go @@ -0,0 +1,91 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/telemetry" + "github.com/hashicorp/go-metrics" +) + +// performance oriented metrics measuring the execution time of each message +const ( + MetricsKeyCreateFinalityProvider = "create_finality_provider" + MetricsKeyCreateBTCDelegation = "create_btc_delegation" + MetricsKeyAddCovenantSigs = "add_covenant_sigs" + MetricsKeyBTCUndelegate = "btc_undelegate" + MetricsKeySelectiveSlashingEvidence = "selective_slashing_evidence" +) + +// Metrics for monitoring finality providers and BTC delegations +const ( + // MetricsKeyFinalityProviders is the key of the gauge recording the number + // of {active, inactive} finality providers, and the key of the counter + // recording the number of slashed finality providers + MetricsKeyFinalityProviders = "finality_providers" + // MetricsKeyBTCDelegations is the key of the gauge recording the number of + // {pending, active, unbonded} BTC delegations, and the key of the counter + // recording the number of slashed BTC delegations + MetricsKeyBTCDelegations = "btc_delegations" + // MetricsKeyStakedBitcoins is the key of the gauge recording the total + // amount of Bitcoins staked under active finality providers + MetricsKeyStakedBitcoins = "staked_bitcoins" +) + +// RecordActiveFinalityProviders records the number of active finality providers. +// It is triggered upon recording voting power table. +func RecordActiveFinalityProviders(num int) { + keys := []string{MetricsKeyFinalityProviders, "ACTIVE"} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + float32(num), + labels, + ) +} + +// RecordInactiveFinalityProviders records the number of inactive finality providers. +// It is triggered upon recording voting power table. +func RecordInactiveFinalityProviders(num int) { + keys := []string{MetricsKeyFinalityProviders, "INACTIVE"} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + float32(num), + labels, + ) +} + +// RecordNewSlashedFinalityProvider increments the number of slashed finality providers. +// It is triggered upon a finality provider becomes slashed. +func RecordNewSlashedFinalityProvider() { + keys := []string{MetricsKeyFinalityProviders, "SLASHED"} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.IncrCounterWithLabels( + keys, + 1, + labels, + ) +} + +// RecordBTCDelegations records the number of BTC delegations under the given status. +// It is triggered upon recording voting power table. +func RecordBTCDelegations(num int, status BTCDelegationStatus) { + keys := []string{MetricsKeyBTCDelegations, status.String()} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + float32(num), + labels, + ) +} + +// RecordMetricsKeyStakedBitcoins records the amount of Bitcoins staked under +// all active finality providers. +// It is triggered upon recording voting power table. +func RecordMetricsKeyStakedBitcoins(amount float32) { + keys := []string{MetricsKeyStakedBitcoins} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + amount, + labels, + ) +} diff --git a/x/finality/keeper/indexed_blocks.go b/x/finality/keeper/indexed_blocks.go index fd7fc0771..07455ffb1 100644 --- a/x/finality/keeper/indexed_blocks.go +++ b/x/finality/keeper/indexed_blocks.go @@ -19,6 +19,9 @@ func (k Keeper) IndexBlock(ctx context.Context) { Finalized: false, } k.SetBlock(ctx, ib) + + // record the block height + types.RecordLastHeight(uint64(headerInfo.Height)) } func (k Keeper) SetBlock(ctx context.Context, block *types.IndexedBlock) { diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index 6b3ced4a7..f5b910389 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -4,12 +4,14 @@ import ( "bytes" "context" "fmt" + "time" errorsmod "cosmossdk.io/errors" "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/babylonchain/babylon/x/finality/types" + "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) @@ -45,6 +47,8 @@ func (ms msgServer) UpdateParams(goCtx context.Context, req *types.MsgUpdatePara // AddFinalitySig adds a new vote to a given block func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinalitySig) (*types.MsgAddFinalitySigResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyAddFinalitySig) + ctx := sdk.UnwrapSDKContext(goCtx) // ensure the finality provider exists @@ -174,6 +178,8 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal // CommitPubRandList commits a list of EOTS public randomness func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommitPubRandList) (*types.MsgCommitPubRandListResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCommitPubRandList) + ctx := sdk.UnwrapSDKContext(goCtx) // ensure the request contains enough number of public randomness diff --git a/x/finality/keeper/tallying.go b/x/finality/keeper/tallying.go index 68c1a4f0d..2b986b1a1 100644 --- a/x/finality/keeper/tallying.go +++ b/x/finality/keeper/tallying.go @@ -94,6 +94,8 @@ func (k Keeper) finalizeBlock(ctx context.Context, block *types.IndexedBlock, vo k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, rdc) // remove reward distribution cache afterwards k.BTCStakingKeeper.RemoveRewardDistCache(ctx, block.Height) + // record the last finalized height metric + types.RecordLastFinalizedHeight(block.Height) } // tally checks whether a block with the given finality provider set and votes reaches a quorum or not diff --git a/x/finality/types/metrics.go b/x/finality/types/metrics.go new file mode 100644 index 000000000..84c131add --- /dev/null +++ b/x/finality/types/metrics.go @@ -0,0 +1,45 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/telemetry" + "github.com/hashicorp/go-metrics" +) + +// performance oriented metrics measuring the execution time of each message +const ( + MetricsKeyCommitPubRandList = "commit_pub_rand_list" + MetricsKeyAddFinalitySig = "add_finality_sig" +) + +// Metrics for monitoring block finalization status +const ( + // MetricsKeyLastHeight is the key of the gauge recording the last height + // of the ledger + MetricsKeyLastHeight = "last_height" + // MetricsKeyLastFinalizedHeight is the key of the gauge recording the + // last height finalized by finality providers + MetricsKeyLastFinalizedHeight = "last_finalized_height" +) + +// RecordLastHeight records the last height. It is triggered upon `IndexBlock` +func RecordLastHeight(height uint64) { + keys := []string{MetricsKeyLastHeight} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + float32(height), + labels, + ) +} + +// RecordLastHeight records the last finalized height. It is triggered upon +// finalizing a block becomes finalized +func RecordLastFinalizedHeight(height uint64) { + keys := []string{MetricsKeyLastFinalizedHeight} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.SetGaugeWithLabels( + keys, + float32(height), + labels, + ) +} From 105216ae6413bf295c85d8bad9b35a2bc7cc1e39 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 12 Feb 2024 16:05:30 +1100 Subject: [PATCH 003/119] doc: hardware requirement (#467) --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3c9ccfbb1..9eb4ad11a 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,19 @@ litepaper](https://badgen.net/badge/icon/BTC%20staking%20litepaper?label=)](http [![BTC timestamping whitepaper](https://badgen.net/badge/icon/BTC%20timestamping%20whitepaper?label=)](https://arxiv.org/abs/2207.08392) -## Build and install +## System requirements + +This system spec has been tested by validators and found to be comfortable: -This repository contains the Golang implementation of the Babylon node. It is -based on the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk). +- Quad Core or larger AMD or Intel (amd64) CPU +- 32GB RAM +- 1TB NVMe Storage +- 100MBps bidirectional internet connection -### Requirements +You can run Babylon on lower-spec hardware for each component, but you may find +that it is not highly performant or prone to crashing. + +## Build and install To build and install, you need to have Go 1.21 available. Follow the instructions on the [Golang page](https://go.dev/doc/install) to do that. From e30545a7b00e14c0ee0067c11a75f84592363a62 Mon Sep 17 00:00:00 2001 From: HarveyV <34950940+HarveyV@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:30:09 +0100 Subject: [PATCH 004/119] Update README.md (#472) Link to a broken user guide document is fixed. it was https://docs.babylonchain.io/docs/user-guides and now is https://docs.babylonchain.io/docs/user-guides/overview --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9eb4ad11a..3ed4699e6 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ document about its design and implementation. ## Joining the testnet Please follow the instructions on the [User -Guides](https://docs.babylonchain.io/docs/user-guides/). +Guides](https://docs.babylonchain.io/docs/user-guides/overview). ## Contributing From 09ce4986072f0598812b63c54aceac32709f03c3 Mon Sep 17 00:00:00 2001 From: HarveyV <34950940+HarveyV@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:30:35 +0100 Subject: [PATCH 005/119] Update staking-script.md (#473) a small spelling error has been fixed --- docs/staking-script.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/staking-script.md b/docs/staking-script.md index 41003e6b0..53ed7d48d 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -43,7 +43,7 @@ that were introduced through the Taproot upgrade. ## Staking Flow -Following diagram show how different transactions described in following +Following diagram shows how different transactions described in following paragraphs create and spend different bitcoin outputs: ```mermaid From a94cbc3b71a49a17289799f50e6dcee9bddd24d9 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 15 Feb 2024 10:45:43 +1100 Subject: [PATCH 006/119] btcstaking: editing finality provider (#469) --- proto/babylon/btcstaking/v1/tx.proto | 26 +- testutil/datagen/btcstaking.go | 14 +- testutil/helper/helper.go | 4 + x/btcstaking/README.md | 62 +++ x/btcstaking/client/cli/tx.go | 67 +++ x/btcstaking/keeper/msg_server.go | 44 +- x/btcstaking/keeper/msg_server_test.go | 57 +++ x/btcstaking/types/codec.go | 4 + x/btcstaking/types/msg.go | 24 + x/btcstaking/types/tx.pb.go | 683 +++++++++++++++++++++---- 10 files changed, 887 insertions(+), 98 deletions(-) diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index 05bc22218..8d2d5a642 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -19,6 +19,8 @@ service Msg { // CreateFinalityProvider creates a new finality provider rpc CreateFinalityProvider(MsgCreateFinalityProvider) returns (MsgCreateFinalityProviderResponse); + // EditFinalityProvider edits an existing finality provider + rpc EditFinalityProvider(MsgEditFinalityProvider) returns (MsgEditFinalityProviderResponse); // CreateBTCDelegation creates a new BTC delegation rpc CreateBTCDelegation(MsgCreateBTCDelegation) returns (MsgCreateBTCDelegationResponse); // AddCovenantSigs handles signatures from a covenant member @@ -38,9 +40,9 @@ message MsgCreateFinalityProvider { string signer = 1; - // description defines the description terms for the finality provider. + // description defines the description terms for the finality provider cosmos.staking.v1beta1.Description description = 2; - // commission defines the commission rate of finality provider. + // commission defines the commission rate of the finality provider string commission = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" @@ -56,6 +58,26 @@ message MsgCreateFinalityProvider { // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider message MsgCreateFinalityProviderResponse {} +// MsgEditFinalityProvider is the message for editing an existing finality provider +message MsgEditFinalityProvider { + option (cosmos.msg.v1.signer) = "signer"; + + // NOTE: this signer needs to correspond to babylon_pk of the finality provider + string signer = 1; + // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited + bytes btc_pk = 2; + + // description defines the updated description terms for the finality provider + cosmos.staking.v1beta1.Description description = 3; + // commission defines the updated commission rate of the finality provider + string commission = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" + ]; +} +// MsgEditFinalityProviderResponse is the response for MsgEditFinalityProvider +message MsgEditFinalityProviderResponse {} + // MsgCreateBTCDelegation is the message for creating a BTC delegation message MsgCreateBTCDelegation { option (cosmos.msg.v1.signer) = "signer"; diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 9bcdcba52..8c5323aab 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -54,11 +54,19 @@ func GenRandomFinalityProviderWithBTCSK(r *rand.Rand, btcSK *btcec.PrivateKey) ( return GenRandomFinalityProviderWithBTCBabylonSKs(r, btcSK, bbnSK) } +func GenRandomCommission(r *rand.Rand) sdkmath.LegacyDec { + return sdkmath.LegacyNewDecWithPrec(int64(RandomInt(r, 49)+1), 2) // [1/100, 50/100] +} + +func GenRandomDescription(r *rand.Rand) *stakingtypes.Description { + return &stakingtypes.Description{Moniker: GenRandomHexStr(r, 10)} +} + func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey) (*bstypes.FinalityProvider, error) { // commission - commission := sdkmath.LegacyNewDecWithPrec(int64(RandomInt(r, 49)+1), 2) // [1/100, 50/100] + commission := GenRandomCommission(r) // description - description := stakingtypes.Description{Moniker: GenRandomHexStr(r, 10)} + description := GenRandomDescription(r) // key pairs btcPK := btcSK.PubKey() bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) @@ -73,7 +81,7 @@ func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.Priva return nil, err } return &bstypes.FinalityProvider{ - Description: &description, + Description: description, Commission: &commission, BabylonPk: secp256k1PK, BtcPk: bip340PK, diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index a59093b5d..c91077e16 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -94,6 +94,10 @@ func (h *Helper) NoError(err error) { require.NoError(h.t, err) } +func (h *Helper) Error(err error) { + require.Error(h.t, err) +} + func (h *Helper) getExtendedVotesFromValSet(epochNum, height uint64, blockHash checkpointingtypes.BlockHash, valSet *datagen.GenesisValidators) ([]abci.ExtendedVoteInfo, error) { valPrivKey := valSet.GetValPrivKeys() blsPrivKeys := valSet.GetBLSPrivKeys() diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index 473a7eee5..c934521c3 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -23,6 +23,7 @@ providers and BTC delegations under them. This includes: - [Params](#params) - [Messages](#messages) - [MsgCreateFinalityProvider](#msgcreatefinalityprovider) + - [MsgEditFinalityProvider](#msgeditfinalityprovider) - [MsgCreateBTCDelegation](#msgcreatebtcdelegation) - [MsgAddCovenantSigs](#msgaddcovenantsigs) - [MsgBTCUndelegate](#msgbtcundelegate) @@ -362,6 +363,27 @@ message MsgCreateFinalityProvider { } ``` +where `Description` is adapted from Cosmos SDK's staking module and is defined +as follows: + +```protobuf +// Description defines a validator description. +message Description { + option (gogoproto.equal) = true; + + // moniker defines a human-readable name for the validator. + string moniker = 1; + // identity defines an optional identity signature (ex. UPort or Keybase). + string identity = 2; + // website defines an optional website link. + string website = 3; + // security_contact defines an optional email for security contact. + string security_contact = 4; + // details define other optional details. + string details = 5; +} +``` + Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: 1. Verify a [proof of @@ -372,6 +394,46 @@ Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: 3. Ensure the finality provider does not exist already. 4. Create a `FinalityProvider` object and save it to finality provider storage. +### MsgEditFinalityProvider + +The `MsgEditFinalityProvider` message is used for editing the information of an +existing finality provider, including the commission and the description. It +needs to be submitted by using the Babylon account registered in the finality +provider. + +```protobuf +// MsgEditFinalityProvider is the message for editing an existing finality provider +message MsgEditFinalityProvider { + option (cosmos.msg.v1.signer) = "signer"; + + // NOTE: this signer needs to correspond to babylon_pk of the finality provider + string signer = 1; + // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited + bytes btc_pk = 2; + + // description defines the updated description terms for the finality provider + cosmos.staking.v1beta1.Description description = 3; + // commission defines the updated commission rate of the finality provider + string commission = 4 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" + ]; +} +``` + +Upon `MsgEditFinalityProvider`, a Babylon node will execute as follows: + +1. Validate the formats of the description. +2. Ensure the given commission rate is at least the `MinCommissionRate` in the + parameters and at most 100%. +3. Get the finality provider with the given `btc_pk` from the finality provider + storage. +4. Ensure the address `signer` corresponds to the Babylon public key + `babylon_pk` in the finality provider. +5. Change the `description` and `commission` in the finality provider to the + values supplied in the message, and write back the finlaity provider to the + finality provider storage. + ### MsgCreateBTCDelegation The `MsgCreateBTCDelegation` message is used for delegating some bitcoins to a diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 8dc5e51f9..134f42f86 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -40,6 +40,7 @@ func GetTxCmd() *cobra.Command { cmd.AddCommand( NewCreateFinalityProvicerCmd(), + NewEditFinalityProvicerCmd(), NewCreateBTCDelegationCmd(), NewAddCovenantSigsCmd(), NewBTCUndelegateCmd(), @@ -133,6 +134,72 @@ func NewCreateFinalityProvicerCmd() *cobra.Command { return cmd } +func NewEditFinalityProvicerCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "edit-finality-provider [btc_pk]", + Args: cobra.ExactArgs(3), + Short: "Edit an existing finality provider", + Long: strings.TrimSpace( + `Edit an existing finality provider.`, // TODO: example + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + fs := cmd.Flags() + + // get description + moniker, _ := fs.GetString(FlagMoniker) + identity, _ := fs.GetString(FlagIdentity) + website, _ := fs.GetString(FlagWebsite) + security, _ := fs.GetString(FlagSecurityContact) + details, _ := fs.GetString(FlagDetails) + description := stakingtypes.NewDescription( + moniker, + identity, + website, + security, + details, + ) + // get commission + rateStr, _ := fs.GetString(FlagCommissionRate) + rate, err := sdkmath.LegacyNewDecFromStr(rateStr) + if err != nil { + return err + } + + // get BTC PK + btcPK, err := hex.DecodeString(args[1]) + if err != nil { + return err + } + + msg := types.MsgEditFinalityProvider{ + Signer: clientCtx.FromAddress.String(), + BtcPk: btcPK, + Description: &description, + Commission: &rate, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + fs := cmd.Flags() + fs.String(FlagMoniker, "", "The finality provider's (optional) moniker") + fs.String(FlagWebsite, "", "The finality provider's (optional) website") + fs.String(FlagSecurityContact, "", "The finality provider's (optional) security contact email") + fs.String(FlagDetails, "", "The finality provider's (optional) details") + fs.String(FlagIdentity, "", "The (optional) identity signature (ex. UPort or Keybase)") + fs.String(FlagCommissionRate, "0", "The initial commission rate percentage") + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + func NewCreateBTCDelegationCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-btc-delegation [babylon_pk] [btc_pk] [pop] [staking_tx_info] [fp_pk] [staking_time] [staking_value] [slashing_tx] [delegator_slashing_sig] [unbonding_tx] [unbonding_slashing_tx] [unbonding_time] [unbonding_value] [delegator_unbonding_slashing_sig]", diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index f42d2ca5a..e2eca02c2 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -6,7 +6,6 @@ import ( "time" errorsmod "cosmossdk.io/errors" - sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/btcstaking" bbn "github.com/babylonchain/babylon/types" @@ -65,11 +64,12 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return nil, status.Errorf(codes.InvalidArgument, "invalid proof of possession: %v", err) } - // ensure commission rate is at least the minimum commission rate in parameters + // ensure commission rate is + // - at least the minimum commission rate in parameters, and + // - at most 1 if req.Commission.LT(ms.MinCommissionRate(ctx)) { return nil, types.ErrCommissionLTMinRate.Wrapf("cannot set finality provider commission to less than minimum rate of %s", ms.MinCommissionRate(ctx)) } - if req.Commission.GT(sdkmath.LegacyOneDec()) { return nil, types.ErrCommissionGTMaxRate } @@ -97,6 +97,44 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return &types.MsgCreateFinalityProviderResponse{}, nil } +// EditFinalityProvider edits an existing finality provider +func (ms msgServer) EditFinalityProvider(ctx context.Context, req *types.MsgEditFinalityProvider) (*types.MsgEditFinalityProviderResponse, error) { + // basic stateless checks + // NOTE: after this, description is guaranteed to be valid + if err := req.ValidateBasic(); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%v", err) + } + + // ensure commission rate is + // - at least the minimum commission rate in parameters, and + // - at most 1 + if req.Commission.LT(ms.MinCommissionRate(ctx)) { + return nil, types.ErrCommissionLTMinRate.Wrapf("cannot set finality provider commission to less than minimum rate of %s", ms.MinCommissionRate(ctx)) + } + if req.Commission.GT(sdkmath.LegacyOneDec()) { + return nil, types.ErrCommissionGTMaxRate + } + + // find the finality provider with the given BTC PK + fp, err := ms.GetFinalityProvider(ctx, req.BtcPk) + if err != nil { + return nil, err + } + + // ensure the signer corresponds to the finality provider's Babylon address + fpBabylonAddr := sdk.AccAddress(fp.BabylonPk.Address()) + if req.Signer != fpBabylonAddr.String() { + return nil, status.Errorf(codes.PermissionDenied, "the signer does not correspond to the finality provider's Babylon address") + } + + // all good, update the finality provider and set back + fp.Description = req.Description + fp.Commission = req.Commission + ms.SetFinalityProvider(ctx, fp) + + return &types.MsgEditFinalityProviderResponse{}, nil +} + // CreateBTCDelegation creates a BTC delegation // TODO: refactor this handler. It's now too convoluted func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCreateBTCDelegation) (*types.MsgCreateBTCDelegationResponse, error) { diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 58b6536dc..decc29be6 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -11,16 +11,21 @@ import ( sdkmath "cosmossdk.io/math" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" testhelper "github.com/babylonchain/babylon/testutil/helper" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) func FuzzMsgCreateFinalityProvider(f *testing.F) { @@ -70,6 +75,58 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { }) } +func FuzzMsgEditFinalityProvider(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + h := helper.NewHelper(t) + bsKeeper := h.App.BTCStakingKeeper + msgSrvr := keeper.NewMsgServerImpl(bsKeeper) + + // generate new finality provider + fp, err := datagen.GenRandomFinalityProvider(r) + fpAddr := sdk.AccAddress(fp.BabylonPk.Address()) + require.NoError(t, err) + // insert the finality provider + h.AddFinalityProvider(fp) + // assert the finality providers exist in KVStore + require.True(t, bsKeeper.HasFinalityProvider(h.Ctx, *fp.BtcPk)) + + // updated commission and description + newCommission := datagen.GenRandomCommission(r) + newDescription := datagen.GenRandomDescription(r) + + // scenario 1: editing finality provider should succeed + msg := &types.MsgEditFinalityProvider{ + Signer: fpAddr.String(), + BtcPk: *fp.BtcPk, + Description: newDescription, + Commission: &newCommission, + } + _, err = msgSrvr.EditFinalityProvider(h.Ctx, msg) + h.NoError(err) + editedFp, err := bsKeeper.GetFinalityProvider(h.Ctx, *fp.BtcPk) + h.NoError(err) + require.Equal(t, newCommission, *editedFp.Commission) + require.Equal(t, newDescription, editedFp.Description) + + // scenario 2: message from an unauthorised signer should fail + newCommission = datagen.GenRandomCommission(r) + newDescription = datagen.GenRandomDescription(r) + msg = &types.MsgEditFinalityProvider{ + Signer: datagen.GenRandomAccount().Address, + BtcPk: *fp.BtcPk, + Description: newDescription, + Commission: &newCommission, + } + _, err = msgSrvr.EditFinalityProvider(h.Ctx, msg) + h.Error(err) + errStatus := status.Convert(err) + require.Equal(t, codes.PermissionDenied, errStatus.Code()) + }) +} + func FuzzCreateBTCDelegation(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) diff --git a/x/btcstaking/types/codec.go b/x/btcstaking/types/codec.go index 256b38291..e859ded71 100644 --- a/x/btcstaking/types/codec.go +++ b/x/btcstaking/types/codec.go @@ -9,8 +9,10 @@ import ( func RegisterCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(&MsgCreateFinalityProvider{}, "btcstaking/MsgCreateFinalityProvider", nil) + cdc.RegisterConcrete(&MsgEditFinalityProvider{}, "btcstaking/MsgEditFinalityProvider", nil) cdc.RegisterConcrete(&MsgCreateBTCDelegation{}, "btcstaking/MsgCreateBTCDelegation", nil) cdc.RegisterConcrete(&MsgAddCovenantSigs{}, "btcstaking/MsgAddCovenantSigs", nil) + cdc.RegisterConcrete(&MsgBTCUndelegate{}, "btcstaking/MsgBTCUndelegate", nil) cdc.RegisterConcrete(&MsgUpdateParams{}, "btcstaking/MsgUpdateParams", nil) } @@ -19,8 +21,10 @@ func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { registry.RegisterImplementations( (*sdk.Msg)(nil), &MsgCreateFinalityProvider{}, + &MsgEditFinalityProvider{}, &MsgCreateBTCDelegation{}, &MsgAddCovenantSigs{}, + &MsgBTCUndelegate{}, &MsgUpdateParams{}, ) diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index 73247bc0c..4669288f0 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -14,6 +14,7 @@ import ( var ( _ sdk.Msg = &MsgUpdateParams{} _ sdk.Msg = &MsgCreateFinalityProvider{} + _ sdk.Msg = &MsgEditFinalityProvider{} _ sdk.Msg = &MsgCreateBTCDelegation{} _ sdk.Msg = &MsgAddCovenantSigs{} _ sdk.Msg = &MsgBTCUndelegate{} @@ -54,6 +55,29 @@ func (m *MsgCreateFinalityProvider) ValidateBasic() error { return nil } +func (m *MsgEditFinalityProvider) ValidateBasic() error { + if m.Commission == nil { + return fmt.Errorf("empty commission") + } + if m.Description == nil { + return fmt.Errorf("empty description") + } + if len(m.Description.Moniker) == 0 { + return fmt.Errorf("empty moniker") + } + if _, err := m.Description.EnsureLength(); err != nil { + return err + } + if len(m.BtcPk) != bbn.BIP340PubKeyLen { + return fmt.Errorf("malformed BTC PK") + } + if _, err := bbn.NewBIP340PubKey(m.BtcPk); err != nil { + return err + } + + return nil +} + func (m *MsgCreateBTCDelegation) ValidateBasic() error { if m.BabylonPk == nil { return fmt.Errorf("empty Babylon public key") diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index be9cf29ba..e1c979153 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -38,9 +38,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgCreateFinalityProvider is the message for creating a finality provider type MsgCreateFinalityProvider struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` - // description defines the description terms for the finality provider. + // description defines the description terms for the finality provider Description *types.Description `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` - // commission defines the commission rate of finality provider. + // commission defines the commission rate of the finality provider Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` // babylon_pk is the Babylon secp256k1 PK of this finality provider BabylonPk *secp256k1.PubKey `protobuf:"bytes,4,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` @@ -149,6 +149,109 @@ func (m *MsgCreateFinalityProviderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateFinalityProviderResponse proto.InternalMessageInfo +// MsgEditFinalityProvider is the message for editing an existing finality provider +type MsgEditFinalityProvider struct { + // NOTE: this signer needs to correspond to babylon_pk of the finality provider + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited + BtcPk []byte `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3" json:"btc_pk,omitempty"` + // description defines the updated description terms for the finality provider + Description *types.Description `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + // commission defines the updated commission rate of the finality provider + Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,4,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` +} + +func (m *MsgEditFinalityProvider) Reset() { *m = MsgEditFinalityProvider{} } +func (m *MsgEditFinalityProvider) String() string { return proto.CompactTextString(m) } +func (*MsgEditFinalityProvider) ProtoMessage() {} +func (*MsgEditFinalityProvider) Descriptor() ([]byte, []int) { + return fileDescriptor_4baddb53e97f38f2, []int{2} +} +func (m *MsgEditFinalityProvider) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditFinalityProvider) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditFinalityProvider.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 *MsgEditFinalityProvider) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditFinalityProvider.Merge(m, src) +} +func (m *MsgEditFinalityProvider) XXX_Size() int { + return m.Size() +} +func (m *MsgEditFinalityProvider) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditFinalityProvider.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditFinalityProvider proto.InternalMessageInfo + +func (m *MsgEditFinalityProvider) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +func (m *MsgEditFinalityProvider) GetBtcPk() []byte { + if m != nil { + return m.BtcPk + } + return nil +} + +func (m *MsgEditFinalityProvider) GetDescription() *types.Description { + if m != nil { + return m.Description + } + return nil +} + +// MsgEditFinalityProviderResponse is the response for MsgEditFinalityProvider +type MsgEditFinalityProviderResponse struct { +} + +func (m *MsgEditFinalityProviderResponse) Reset() { *m = MsgEditFinalityProviderResponse{} } +func (m *MsgEditFinalityProviderResponse) String() string { return proto.CompactTextString(m) } +func (*MsgEditFinalityProviderResponse) ProtoMessage() {} +func (*MsgEditFinalityProviderResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_4baddb53e97f38f2, []int{3} +} +func (m *MsgEditFinalityProviderResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditFinalityProviderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditFinalityProviderResponse.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 *MsgEditFinalityProviderResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditFinalityProviderResponse.Merge(m, src) +} +func (m *MsgEditFinalityProviderResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgEditFinalityProviderResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditFinalityProviderResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditFinalityProviderResponse proto.InternalMessageInfo + // MsgCreateBTCDelegation is the message for creating a BTC delegation type MsgCreateBTCDelegation struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` @@ -199,7 +302,7 @@ func (m *MsgCreateBTCDelegation) Reset() { *m = MsgCreateBTCDelegation{} func (m *MsgCreateBTCDelegation) String() string { return proto.CompactTextString(m) } func (*MsgCreateBTCDelegation) ProtoMessage() {} func (*MsgCreateBTCDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{2} + return fileDescriptor_4baddb53e97f38f2, []int{4} } func (m *MsgCreateBTCDelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -299,7 +402,7 @@ func (m *MsgCreateBTCDelegationResponse) Reset() { *m = MsgCreateBTCDele func (m *MsgCreateBTCDelegationResponse) String() string { return proto.CompactTextString(m) } func (*MsgCreateBTCDelegationResponse) ProtoMessage() {} func (*MsgCreateBTCDelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{3} + return fileDescriptor_4baddb53e97f38f2, []int{5} } func (m *MsgCreateBTCDelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -354,7 +457,7 @@ func (m *MsgAddCovenantSigs) Reset() { *m = MsgAddCovenantSigs{} } func (m *MsgAddCovenantSigs) String() string { return proto.CompactTextString(m) } func (*MsgAddCovenantSigs) ProtoMessage() {} func (*MsgAddCovenantSigs) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{4} + return fileDescriptor_4baddb53e97f38f2, []int{6} } func (m *MsgAddCovenantSigs) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -419,7 +522,7 @@ func (m *MsgAddCovenantSigsResponse) Reset() { *m = MsgAddCovenantSigsRe func (m *MsgAddCovenantSigsResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddCovenantSigsResponse) ProtoMessage() {} func (*MsgAddCovenantSigsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{5} + return fileDescriptor_4baddb53e97f38f2, []int{7} } func (m *MsgAddCovenantSigsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -465,7 +568,7 @@ func (m *MsgBTCUndelegate) Reset() { *m = MsgBTCUndelegate{} } func (m *MsgBTCUndelegate) String() string { return proto.CompactTextString(m) } func (*MsgBTCUndelegate) ProtoMessage() {} func (*MsgBTCUndelegate) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{6} + return fileDescriptor_4baddb53e97f38f2, []int{8} } func (m *MsgBTCUndelegate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -516,7 +619,7 @@ func (m *MsgBTCUndelegateResponse) Reset() { *m = MsgBTCUndelegateRespon func (m *MsgBTCUndelegateResponse) String() string { return proto.CompactTextString(m) } func (*MsgBTCUndelegateResponse) ProtoMessage() {} func (*MsgBTCUndelegateResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{7} + return fileDescriptor_4baddb53e97f38f2, []int{9} } func (m *MsgBTCUndelegateResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -563,7 +666,7 @@ func (m *MsgSelectiveSlashingEvidence) Reset() { *m = MsgSelectiveSlashi func (m *MsgSelectiveSlashingEvidence) String() string { return proto.CompactTextString(m) } func (*MsgSelectiveSlashingEvidence) ProtoMessage() {} func (*MsgSelectiveSlashingEvidence) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{8} + return fileDescriptor_4baddb53e97f38f2, []int{10} } func (m *MsgSelectiveSlashingEvidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -621,7 +724,7 @@ func (m *MsgSelectiveSlashingEvidenceResponse) Reset() { *m = MsgSelecti func (m *MsgSelectiveSlashingEvidenceResponse) String() string { return proto.CompactTextString(m) } func (*MsgSelectiveSlashingEvidenceResponse) ProtoMessage() {} func (*MsgSelectiveSlashingEvidenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{9} + return fileDescriptor_4baddb53e97f38f2, []int{11} } func (m *MsgSelectiveSlashingEvidenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -667,7 +770,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{10} + return fileDescriptor_4baddb53e97f38f2, []int{12} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -718,7 +821,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_4baddb53e97f38f2, []int{11} + return fileDescriptor_4baddb53e97f38f2, []int{13} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -750,6 +853,8 @@ var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo func init() { proto.RegisterType((*MsgCreateFinalityProvider)(nil), "babylon.btcstaking.v1.MsgCreateFinalityProvider") proto.RegisterType((*MsgCreateFinalityProviderResponse)(nil), "babylon.btcstaking.v1.MsgCreateFinalityProviderResponse") + proto.RegisterType((*MsgEditFinalityProvider)(nil), "babylon.btcstaking.v1.MsgEditFinalityProvider") + proto.RegisterType((*MsgEditFinalityProviderResponse)(nil), "babylon.btcstaking.v1.MsgEditFinalityProviderResponse") proto.RegisterType((*MsgCreateBTCDelegation)(nil), "babylon.btcstaking.v1.MsgCreateBTCDelegation") proto.RegisterType((*MsgCreateBTCDelegationResponse)(nil), "babylon.btcstaking.v1.MsgCreateBTCDelegationResponse") proto.RegisterType((*MsgAddCovenantSigs)(nil), "babylon.btcstaking.v1.MsgAddCovenantSigs") @@ -765,84 +870,88 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1224 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x8f, 0xd3, 0xc6, - 0x17, 0x5f, 0x27, 0x9b, 0xf0, 0xdd, 0x97, 0x4d, 0x76, 0xbf, 0x06, 0x16, 0xaf, 0x0b, 0x49, 0x08, - 0x14, 0x02, 0xea, 0x3a, 0x64, 0x29, 0xa8, 0x05, 0xa9, 0x12, 0xd9, 0x05, 0x81, 0x4a, 0xd4, 0xc8, - 0xc9, 0xf6, 0xd0, 0x1e, 0x22, 0xc7, 0x99, 0x38, 0xa3, 0x24, 0x1e, 0xcb, 0x33, 0x89, 0x12, 0xf5, - 0x52, 0xa1, 0x5e, 0x2b, 0xf5, 0xd4, 0x43, 0x6f, 0xfd, 0x0f, 0x38, 0xf0, 0x27, 0xf4, 0xc0, 0x11, - 0x71, 0xaa, 0xb6, 0xd2, 0xaa, 0x82, 0x4a, 0xfc, 0x05, 0xbd, 0x57, 0xb6, 0xc7, 0x3f, 0x92, 0xc6, - 0x85, 0x65, 0xb9, 0xc5, 0x33, 0x9f, 0xf7, 0x79, 0xef, 0x7d, 0xde, 0x7b, 0x33, 0x13, 0xc8, 0x77, - 0xb4, 0xce, 0x6c, 0x48, 0xcc, 0x4a, 0x87, 0xe9, 0x94, 0x69, 0x03, 0x6c, 0x1a, 0x95, 0x49, 0xb5, - 0xc2, 0xa6, 0x8a, 0x65, 0x13, 0x46, 0xc4, 0xb3, 0x7c, 0x5f, 0x09, 0xf7, 0x95, 0x49, 0x55, 0x3e, - 0x63, 0x10, 0x83, 0xb8, 0x88, 0x8a, 0xf3, 0xcb, 0x03, 0xcb, 0xdb, 0x3a, 0xa1, 0x23, 0x42, 0xdb, - 0xde, 0x86, 0xf7, 0xc1, 0xb7, 0xce, 0x79, 0x5f, 0x95, 0x11, 0x75, 0xf9, 0x47, 0xd4, 0xe0, 0x1b, - 0x25, 0xbe, 0xa1, 0xdb, 0x33, 0x8b, 0x91, 0x0a, 0x45, 0xba, 0xb5, 0x7b, 0xeb, 0xf6, 0xa0, 0x5a, - 0x19, 0xa0, 0x99, 0x6f, 0x5c, 0x5a, 0x1e, 0xa4, 0xa5, 0xd9, 0xda, 0xc8, 0xc7, 0x7c, 0x12, 0xc1, - 0xe8, 0x7d, 0xa4, 0x0f, 0x2c, 0x82, 0x4d, 0xe6, 0xc0, 0xe6, 0x16, 0x38, 0xfa, 0x32, 0xf7, 0x1a, - 0xb2, 0x75, 0x10, 0xd3, 0xaa, 0xfe, 0x37, 0x47, 0x15, 0x62, 0xfc, 0x12, 0xcb, 0x03, 0x94, 0x7e, - 0x4d, 0xc2, 0x76, 0x9d, 0x1a, 0x7b, 0x36, 0xd2, 0x18, 0x7a, 0x80, 0x4d, 0x6d, 0x88, 0xd9, 0xac, - 0x61, 0x93, 0x09, 0xee, 0x22, 0x5b, 0xdc, 0x82, 0x34, 0xc5, 0x86, 0x89, 0x6c, 0x49, 0x28, 0x0a, - 0xe5, 0x35, 0x95, 0x7f, 0x89, 0xf7, 0x21, 0xd3, 0x45, 0x54, 0xb7, 0xb1, 0xc5, 0x30, 0x31, 0xa5, - 0x44, 0x51, 0x28, 0x67, 0x76, 0x2f, 0x29, 0x5c, 0xaf, 0x50, 0x65, 0x37, 0x24, 0x65, 0x3f, 0x84, - 0xaa, 0x51, 0x3b, 0xb1, 0x0e, 0xa0, 0x93, 0xd1, 0x08, 0x53, 0xea, 0xb0, 0x24, 0x1d, 0x17, 0xb5, - 0x9d, 0xc3, 0xa3, 0xc2, 0x47, 0x1e, 0x11, 0xed, 0x0e, 0x14, 0x4c, 0x2a, 0x23, 0x8d, 0xf5, 0x95, - 0xc7, 0xc8, 0xd0, 0xf4, 0xd9, 0x3e, 0xd2, 0x5f, 0x3e, 0xdb, 0x01, 0xee, 0x67, 0x1f, 0xe9, 0x6a, - 0x84, 0x40, 0xfc, 0x02, 0x80, 0xa7, 0xdb, 0xb6, 0x06, 0xd2, 0xaa, 0x1b, 0x54, 0xc1, 0x0f, 0xca, - 0xab, 0x8e, 0x12, 0x54, 0x47, 0x69, 0x8c, 0x3b, 0x5f, 0xa2, 0x99, 0xba, 0xc6, 0x4d, 0x1a, 0x03, - 0xb1, 0x0e, 0xe9, 0x0e, 0xd3, 0x1d, 0xdb, 0x54, 0x51, 0x28, 0xaf, 0xd7, 0x6e, 0x1f, 0x1e, 0x15, - 0x76, 0x0d, 0xcc, 0xfa, 0xe3, 0x8e, 0xa2, 0x93, 0x51, 0x85, 0x23, 0xf5, 0xbe, 0x86, 0x4d, 0xff, - 0xa3, 0xc2, 0x66, 0x16, 0xa2, 0x4a, 0xed, 0x51, 0xe3, 0xe6, 0xa7, 0x37, 0x38, 0x65, 0xaa, 0xc3, - 0xf4, 0xc6, 0x40, 0xbc, 0x03, 0x49, 0x8b, 0x58, 0x52, 0xda, 0x8d, 0xa3, 0xac, 0x2c, 0x6d, 0x43, - 0xa5, 0x61, 0x13, 0xd2, 0xfb, 0xaa, 0xd7, 0x20, 0x94, 0x22, 0x37, 0x0b, 0xd5, 0x31, 0xba, 0x93, - 0x79, 0xf2, 0xe6, 0xe9, 0x75, 0xae, 0x76, 0xe9, 0x12, 0x5c, 0x8c, 0x2d, 0x91, 0x8a, 0xa8, 0x45, - 0x4c, 0x8a, 0x4a, 0x7f, 0x9c, 0x82, 0xad, 0x00, 0x55, 0x6b, 0xed, 0xed, 0xa3, 0x21, 0x32, 0x34, - 0x57, 0xe6, 0xb8, 0x2a, 0xce, 0xeb, 0x95, 0x38, 0xb6, 0x5e, 0x3c, 0xc1, 0xe4, 0x7b, 0x24, 0x18, - 0xd1, 0x7a, 0xf5, 0x43, 0x68, 0xfd, 0x2d, 0xe4, 0x7a, 0x56, 0xdb, 0x63, 0x6c, 0x0f, 0x31, 0x65, - 0x52, 0xaa, 0x98, 0x3c, 0x01, 0x6d, 0xa6, 0x67, 0xd5, 0x1c, 0xe2, 0xc7, 0x98, 0x32, 0xf1, 0x22, - 0xac, 0xf3, 0x84, 0xda, 0x0c, 0x8f, 0x90, 0x5b, 0xd1, 0xac, 0x9a, 0xe1, 0x6b, 0x2d, 0x3c, 0x42, - 0xe2, 0x25, 0xc8, 0xfa, 0x90, 0x89, 0x36, 0x1c, 0x23, 0xe9, 0x54, 0x51, 0x28, 0x27, 0x55, 0xdf, - 0xee, 0x6b, 0x67, 0x4d, 0x7c, 0x08, 0x10, 0xf0, 0x4c, 0xa5, 0xff, 0xb9, 0xb2, 0x5d, 0x8b, 0xca, - 0x16, 0x19, 0xf2, 0x49, 0x55, 0x69, 0xd9, 0x9a, 0x49, 0x35, 0xdd, 0x29, 0xe1, 0x23, 0xb3, 0x47, - 0xd4, 0x35, 0xdf, 0xe1, 0x54, 0xdc, 0x85, 0x0c, 0x1d, 0x6a, 0xb4, 0xcf, 0xa9, 0xd6, 0x5c, 0x09, - 0xff, 0x7f, 0x78, 0x54, 0xc8, 0xd6, 0x5a, 0x7b, 0x4d, 0xbe, 0xd3, 0x9a, 0xaa, 0x40, 0x83, 0xdf, - 0x22, 0x81, 0xad, 0xae, 0xd7, 0x13, 0xc4, 0x6e, 0x07, 0xd6, 0x14, 0x1b, 0x12, 0xb8, 0xe6, 0x9f, - 0x1f, 0x1e, 0x15, 0x6e, 0x1d, 0x47, 0xaa, 0x26, 0x36, 0x4c, 0x8d, 0x8d, 0x6d, 0xa4, 0x9e, 0x09, - 0x88, 0x7d, 0xdf, 0x4d, 0x6c, 0x88, 0x1f, 0x43, 0x6e, 0x6c, 0x76, 0x88, 0xd9, 0x0d, 0x84, 0xcb, - 0xb8, 0xc2, 0x65, 0x83, 0x55, 0x57, 0xba, 0x8b, 0xb0, 0x1e, 0x81, 0x4d, 0xa5, 0x75, 0x27, 0x1a, - 0x35, 0x13, 0x82, 0xa6, 0xe2, 0x55, 0xd8, 0x08, 0x21, 0x9e, 0xbe, 0x59, 0x57, 0xdf, 0xd0, 0x81, - 0xa7, 0xf0, 0x7d, 0x38, 0x1b, 0x02, 0xa3, 0x0a, 0xe5, 0xe2, 0x14, 0x3a, 0x1d, 0xe0, 0xc3, 0x45, - 0xf1, 0x89, 0x00, 0xc5, 0x50, 0xab, 0x25, 0x8c, 0x8e, 0x6a, 0x1b, 0x27, 0x55, 0xed, 0x42, 0xe0, - 0xe2, 0x60, 0x31, 0x86, 0x26, 0x36, 0xe6, 0x8f, 0x80, 0x22, 0xe4, 0x97, 0x0f, 0x77, 0x30, 0xff, - 0x7f, 0x27, 0x40, 0xac, 0x53, 0xe3, 0x5e, 0xb7, 0xbb, 0x47, 0x26, 0xc8, 0xd4, 0x4c, 0xd6, 0xc4, - 0x06, 0x8d, 0x9d, 0xfd, 0x07, 0x90, 0xe0, 0x33, 0xff, 0xfe, 0x43, 0x92, 0xb0, 0x06, 0xe2, 0x15, - 0xd8, 0x08, 0x7b, 0xba, 0xdd, 0xd7, 0x68, 0xdf, 0x3b, 0xc7, 0xd5, 0x6c, 0xd0, 0xad, 0x0f, 0x35, - 0xda, 0x17, 0xcb, 0xb0, 0x19, 0xa9, 0x87, 0x23, 0x20, 0x95, 0x56, 0x9d, 0x11, 0x55, 0x73, 0x61, - 0x8f, 0xba, 0x11, 0xeb, 0xb0, 0x19, 0xed, 0x07, 0x57, 0xeb, 0xd4, 0x49, 0xb5, 0xce, 0x45, 0xda, - 0xc9, 0xe9, 0xcd, 0xbb, 0x20, 0x07, 0xe1, 0x2c, 0x7a, 0xa3, 0x52, 0xda, 0x0d, 0xec, 0x9c, 0x8f, - 0x38, 0x98, 0xb3, 0xa5, 0xf3, 0x95, 0x39, 0x0f, 0xf2, 0xbf, 0x65, 0x0f, 0xaa, 0xf2, 0x9b, 0x00, - 0x9b, 0x75, 0x6a, 0xd4, 0x5a, 0x7b, 0x07, 0x26, 0x2f, 0x37, 0x8a, 0xad, 0xc9, 0x12, 0x2d, 0x13, - 0xcb, 0xb4, 0x5c, 0xa6, 0x50, 0xf2, 0x03, 0x2b, 0x34, 0x9f, 0xa4, 0x0c, 0xd2, 0x62, 0x16, 0x41, - 0x8a, 0xbf, 0x08, 0x70, 0xbe, 0x4e, 0x8d, 0x26, 0x1a, 0x22, 0x9d, 0xe1, 0x09, 0xf2, 0x7b, 0xf8, - 0xbe, 0x73, 0x3f, 0x99, 0xfa, 0xc9, 0xd3, 0xdd, 0x81, 0xd3, 0x36, 0xd2, 0xc9, 0x04, 0xd9, 0xa8, - 0xdb, 0xe6, 0xa7, 0x3c, 0x1d, 0x78, 0x19, 0xab, 0x9b, 0xc1, 0xd6, 0x03, 0xe7, 0xc4, 0x6e, 0x0e, - 0xe6, 0x03, 0xbf, 0x02, 0x97, 0xff, 0x2b, 0xb6, 0x20, 0x89, 0x9f, 0x05, 0xd8, 0xa8, 0x53, 0xe3, - 0xc0, 0xea, 0x6a, 0x0c, 0x35, 0xdc, 0x57, 0x99, 0x78, 0x1b, 0xd6, 0xb4, 0x31, 0xeb, 0x13, 0x1b, - 0xb3, 0x99, 0x17, 0x7a, 0x4d, 0x7a, 0xf9, 0x6c, 0xe7, 0x0c, 0xbf, 0x20, 0xef, 0x75, 0xbb, 0x36, - 0xa2, 0xb4, 0xc9, 0x6c, 0x6c, 0x1a, 0x6a, 0x08, 0x15, 0xef, 0x42, 0xda, 0x7b, 0xd7, 0xf1, 0x2b, - 0xf5, 0x42, 0xdc, 0xcd, 0xe8, 0x82, 0x6a, 0xab, 0xcf, 0x8f, 0x0a, 0x2b, 0x2a, 0x37, 0xb9, 0x93, - 0x73, 0xa2, 0x0f, 0xc9, 0x4a, 0xdb, 0x70, 0x6e, 0x21, 0x2e, 0x3f, 0xe6, 0xdd, 0xbf, 0x52, 0x90, - 0xac, 0x53, 0x43, 0xfc, 0x41, 0x80, 0xad, 0x98, 0xf7, 0xdb, 0x8d, 0x18, 0xd7, 0xb1, 0xcf, 0x09, - 0xf9, 0xb3, 0xe3, 0x5a, 0xf8, 0xe1, 0x88, 0xdf, 0xc1, 0xe9, 0x65, 0x8f, 0x8f, 0x9d, 0xb7, 0x11, - 0xce, 0xc1, 0xe5, 0x5b, 0xc7, 0x82, 0x07, 0xce, 0x09, 0x6c, 0x2c, 0x9e, 0x7c, 0xd7, 0xe2, 0x99, - 0x16, 0xa0, 0x72, 0xf5, 0x9d, 0xa1, 0x81, 0x43, 0x0c, 0xd9, 0xf9, 0xa1, 0xbe, 0x1a, 0xcf, 0x31, - 0x07, 0x94, 0x2b, 0xef, 0x08, 0x0c, 0x5c, 0xfd, 0x28, 0xc0, 0x76, 0xfc, 0x74, 0xdd, 0x8c, 0xa7, - 0x8b, 0x35, 0x92, 0xef, 0xbe, 0x87, 0x51, 0x10, 0x4f, 0x0f, 0xd6, 0xe7, 0xe6, 0xe4, 0x4a, 0x3c, - 0x59, 0x14, 0x27, 0x2b, 0xef, 0x86, 0xf3, 0xfd, 0xc8, 0xa9, 0xef, 0xdf, 0x3c, 0xbd, 0x2e, 0xd4, - 0x1e, 0x3f, 0x7f, 0x95, 0x17, 0x5e, 0xbc, 0xca, 0x0b, 0x7f, 0xbe, 0xca, 0x0b, 0x3f, 0xbd, 0xce, - 0xaf, 0xbc, 0x78, 0x9d, 0x5f, 0xf9, 0xfd, 0x75, 0x7e, 0xe5, 0x9b, 0xb7, 0xde, 0x59, 0xd3, 0xe8, - 0xdf, 0x1e, 0xf7, 0xd8, 0xeb, 0xa4, 0xdd, 0xbf, 0x3d, 0x37, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, - 0x14, 0xbd, 0x7a, 0x11, 0x36, 0x0e, 0x00, 0x00, + // 1284 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0xdb, 0xc6, + 0x13, 0x35, 0x2d, 0x5b, 0xf9, 0x79, 0x64, 0xd9, 0xfe, 0x31, 0x8e, 0x43, 0xb3, 0x89, 0x24, 0x3b, + 0x69, 0xe2, 0x04, 0x35, 0x15, 0x3b, 0x8d, 0xd1, 0x26, 0x40, 0x81, 0xc8, 0x76, 0x90, 0xa0, 0x11, + 0x2a, 0x50, 0x76, 0x0f, 0xed, 0x41, 0xa0, 0xa8, 0x35, 0xb5, 0x90, 0xc4, 0x25, 0xb8, 0x6b, 0x41, + 0x42, 0x81, 0xa2, 0x08, 0x7a, 0x2d, 0xd0, 0x53, 0x0f, 0xbd, 0xf5, 0x1b, 0xe4, 0x90, 0x8f, 0xd0, + 0x43, 0x8e, 0x41, 0x4e, 0x85, 0x0b, 0x18, 0x45, 0x52, 0x20, 0x87, 0x9e, 0x7b, 0x2f, 0x48, 0x2e, + 0x97, 0xa4, 0x2a, 0x36, 0x76, 0x9c, 0x1b, 0x77, 0xf7, 0xcd, 0xcc, 0x9b, 0x37, 0xb3, 0x7f, 0x08, + 0x85, 0xa6, 0xd1, 0x1c, 0x76, 0x89, 0x5d, 0x6e, 0x32, 0x93, 0x32, 0xa3, 0x83, 0x6d, 0xab, 0xdc, + 0xdf, 0x28, 0xb3, 0x81, 0xe6, 0xb8, 0x84, 0x11, 0xf9, 0x02, 0x5f, 0xd7, 0xa2, 0x75, 0xad, 0xbf, + 0xa1, 0x2e, 0x5a, 0xc4, 0x22, 0x3e, 0xa2, 0xec, 0x7d, 0x05, 0x60, 0x75, 0xd9, 0x24, 0xb4, 0x47, + 0x68, 0x23, 0x58, 0x08, 0x06, 0x7c, 0xe9, 0x62, 0x30, 0x2a, 0xf7, 0xa8, 0xef, 0xbf, 0x47, 0x2d, + 0xbe, 0xb0, 0xca, 0x17, 0x4c, 0x77, 0xe8, 0x30, 0x52, 0xa6, 0xc8, 0x74, 0x36, 0xef, 0x6c, 0x75, + 0x36, 0xca, 0x1d, 0x34, 0x0c, 0x8d, 0x57, 0xc7, 0x93, 0x74, 0x0c, 0xd7, 0xe8, 0x85, 0x98, 0x8f, + 0x62, 0x18, 0xb3, 0x8d, 0xcc, 0x8e, 0x43, 0xb0, 0xcd, 0x3c, 0x58, 0x62, 0x82, 0xa3, 0xaf, 0xf2, + 0xa8, 0x91, 0xb7, 0x26, 0x62, 0xc6, 0x46, 0x38, 0xe6, 0xa8, 0x62, 0x4a, 0x5c, 0xe2, 0x04, 0x80, + 0xd5, 0x5f, 0x32, 0xb0, 0x5c, 0xa5, 0xd6, 0xb6, 0x8b, 0x0c, 0x86, 0x1e, 0x60, 0xdb, 0xe8, 0x62, + 0x36, 0xac, 0xb9, 0xa4, 0x8f, 0x5b, 0xc8, 0x95, 0x97, 0x20, 0x4b, 0xb1, 0x65, 0x23, 0x57, 0x91, + 0x4a, 0xd2, 0xda, 0x8c, 0xce, 0x47, 0xf2, 0x2e, 0xe4, 0x5a, 0x88, 0x9a, 0x2e, 0x76, 0x18, 0x26, + 0xb6, 0x32, 0x59, 0x92, 0xd6, 0x72, 0x9b, 0x57, 0x34, 0xae, 0x57, 0xa4, 0xb2, 0x4f, 0x49, 0xdb, + 0x89, 0xa0, 0x7a, 0xdc, 0x4e, 0xae, 0x02, 0x98, 0xa4, 0xd7, 0xc3, 0x94, 0x7a, 0x5e, 0x32, 0x5e, + 0x88, 0xca, 0xfa, 0xd1, 0x71, 0xf1, 0x83, 0xc0, 0x11, 0x6d, 0x75, 0x34, 0x4c, 0xca, 0x3d, 0x83, + 0xb5, 0xb5, 0xc7, 0xc8, 0x32, 0xcc, 0xe1, 0x0e, 0x32, 0x5f, 0x3e, 0x5b, 0x07, 0x1e, 0x67, 0x07, + 0x99, 0x7a, 0xcc, 0x81, 0xfc, 0x19, 0x00, 0x4f, 0xb7, 0xe1, 0x74, 0x94, 0x29, 0x9f, 0x54, 0x31, + 0x24, 0x15, 0x54, 0x47, 0x13, 0xd5, 0xd1, 0x6a, 0x87, 0xcd, 0xcf, 0xd1, 0x50, 0x9f, 0xe1, 0x26, + 0xb5, 0x8e, 0x5c, 0x85, 0x6c, 0x93, 0x99, 0x9e, 0xed, 0x74, 0x49, 0x5a, 0x9b, 0xad, 0x6c, 0x1d, + 0x1d, 0x17, 0x37, 0x2d, 0xcc, 0xda, 0x87, 0x4d, 0xcd, 0x24, 0xbd, 0x32, 0x47, 0x9a, 0x6d, 0x03, + 0xdb, 0xe1, 0xa0, 0xcc, 0x86, 0x0e, 0xa2, 0x5a, 0xe5, 0x51, 0xed, 0xf6, 0xc7, 0xb7, 0xb8, 0xcb, + 0xe9, 0x26, 0x33, 0x6b, 0x1d, 0xf9, 0x2e, 0x64, 0x1c, 0xe2, 0x28, 0x59, 0x9f, 0xc7, 0x9a, 0x36, + 0xb6, 0x0d, 0xb5, 0x9a, 0x4b, 0xc8, 0xc1, 0x17, 0x07, 0x35, 0x42, 0x29, 0xf2, 0xb3, 0xd0, 0x3d, + 0xa3, 0xbb, 0xb9, 0x27, 0x6f, 0x9e, 0xde, 0xe4, 0x6a, 0xaf, 0x5e, 0x81, 0x95, 0xd4, 0x12, 0xe9, + 0x88, 0x3a, 0xc4, 0xa6, 0x68, 0xf5, 0x2f, 0x09, 0x2e, 0x56, 0xa9, 0xb5, 0xdb, 0xc2, 0xec, 0xc4, + 0x65, 0xbc, 0x20, 0x12, 0xf6, 0x2a, 0x38, 0x1b, 0x12, 0x1f, 0xa9, 0x6e, 0xe6, 0xbd, 0x54, 0x77, + 0xea, 0x8c, 0xd5, 0x4d, 0x4a, 0xb2, 0x02, 0xc5, 0x94, 0x64, 0x85, 0x20, 0xbf, 0x9f, 0x83, 0x25, + 0x21, 0x5b, 0x65, 0x6f, 0x7b, 0x07, 0x75, 0x91, 0x65, 0xf8, 0xcc, 0xd2, 0xf4, 0x48, 0x36, 0xd0, + 0xe4, 0xa9, 0x1b, 0x88, 0x57, 0x3c, 0xf3, 0x0e, 0x15, 0x8f, 0x35, 0xdf, 0xd4, 0xfb, 0x68, 0xbe, + 0xaf, 0x61, 0xee, 0xc0, 0x69, 0x04, 0x1e, 0x1b, 0x5d, 0x4c, 0x99, 0x32, 0x5d, 0xca, 0x9c, 0xc1, + 0x6d, 0xee, 0xc0, 0xa9, 0x78, 0x8e, 0x1f, 0x63, 0xca, 0xe4, 0x15, 0x98, 0xe5, 0x09, 0x35, 0x18, + 0xee, 0x21, 0xbf, 0xc5, 0xf3, 0x7a, 0x8e, 0xcf, 0xed, 0xe1, 0x1e, 0x92, 0xaf, 0x40, 0x3e, 0x84, + 0xf4, 0x8d, 0xee, 0x21, 0x52, 0xce, 0x95, 0xa4, 0xb5, 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xcd, 0xc9, + 0x0f, 0x01, 0x84, 0x9f, 0x81, 0xf2, 0x3f, 0x5f, 0xb6, 0x1b, 0x71, 0xd9, 0x62, 0xa7, 0x5e, 0x7f, + 0x43, 0xdb, 0x73, 0x0d, 0x9b, 0x1a, 0xa6, 0x57, 0xc2, 0x47, 0xf6, 0x01, 0xd1, 0x67, 0xc2, 0x80, + 0x03, 0x79, 0x13, 0x72, 0xb4, 0x6b, 0xd0, 0x36, 0x77, 0x35, 0xe3, 0x4b, 0xf8, 0xff, 0xa3, 0xe3, + 0x62, 0xbe, 0xb2, 0xb7, 0x5d, 0xe7, 0x2b, 0x7b, 0x03, 0x1d, 0xa8, 0xf8, 0x96, 0x09, 0x2c, 0xb5, + 0x82, 0x9e, 0x20, 0x6e, 0x43, 0x58, 0x53, 0x6c, 0x29, 0xe0, 0x9b, 0x7f, 0x7a, 0x74, 0x5c, 0xbc, + 0x73, 0x1a, 0xa9, 0xea, 0xd8, 0xb2, 0x0d, 0x76, 0xe8, 0x22, 0x7d, 0x51, 0x38, 0x0e, 0x63, 0xd7, + 0xb1, 0x25, 0x7f, 0x08, 0x73, 0x87, 0x76, 0x93, 0xd8, 0x2d, 0x21, 0x5c, 0xce, 0x17, 0x2e, 0x2f, + 0x66, 0x7d, 0xe9, 0x56, 0x60, 0x36, 0x06, 0x1b, 0x28, 0xb3, 0xfe, 0xde, 0xcc, 0x45, 0xa0, 0x81, + 0x7c, 0x1d, 0xe6, 0x23, 0x48, 0xa0, 0x6f, 0xde, 0xd7, 0x37, 0x0a, 0x10, 0x28, 0xbc, 0x0b, 0x17, + 0x22, 0x60, 0x5c, 0xa1, 0xb9, 0x34, 0x85, 0xce, 0x0b, 0x7c, 0x34, 0x29, 0x3f, 0x91, 0xa0, 0x14, + 0x69, 0x35, 0xc6, 0xa3, 0xa7, 0xda, 0xfc, 0x59, 0x55, 0xbb, 0x2c, 0x42, 0xec, 0x8f, 0x72, 0xa8, + 0x63, 0x2b, 0x79, 0x00, 0x94, 0xa0, 0x30, 0x7e, 0x73, 0x8b, 0xfd, 0xff, 0xf7, 0x24, 0xc8, 0x55, + 0x6a, 0xdd, 0x6f, 0xb5, 0xb6, 0x49, 0x1f, 0xd9, 0x86, 0xcd, 0xea, 0xd8, 0xa2, 0xa9, 0x7b, 0xff, + 0x01, 0x4c, 0x86, 0xe7, 0xe0, 0x3b, 0x6f, 0x92, 0x49, 0xa7, 0x23, 0x5f, 0x83, 0xf9, 0xa8, 0xa7, + 0x1b, 0x6d, 0x83, 0xb6, 0x83, 0x8b, 0x4d, 0xcf, 0x8b, 0x6e, 0x7d, 0x68, 0xd0, 0xb6, 0xbc, 0x06, + 0x0b, 0xb1, 0x7a, 0x78, 0x02, 0x52, 0x65, 0xca, 0xdb, 0xa2, 0xfa, 0x5c, 0xd4, 0xa3, 0x3e, 0x63, + 0x13, 0x16, 0xe2, 0xfd, 0xe0, 0x6b, 0x3d, 0x7d, 0x56, 0xad, 0xe7, 0x62, 0xed, 0xe4, 0xf5, 0xe6, + 0x3d, 0x50, 0x05, 0x9d, 0xd1, 0x68, 0x54, 0xc9, 0xfa, 0xc4, 0x2e, 0x86, 0x88, 0xfd, 0x84, 0x2d, + 0x4d, 0x56, 0xe6, 0x12, 0xa8, 0xff, 0x96, 0x5d, 0x54, 0xe5, 0x57, 0x09, 0x16, 0xaa, 0xd4, 0xaa, + 0xec, 0x6d, 0xef, 0xdb, 0xbc, 0xdc, 0x28, 0xb5, 0x26, 0x63, 0xb4, 0x9c, 0x1c, 0xa7, 0xe5, 0x38, + 0x85, 0x32, 0xef, 0x59, 0xa1, 0x64, 0x92, 0x2a, 0x28, 0xa3, 0x59, 0x88, 0x14, 0x7f, 0x96, 0xe0, + 0x52, 0x95, 0x5a, 0x75, 0xd4, 0x45, 0x26, 0xc3, 0x7d, 0x14, 0xf6, 0xf0, 0xae, 0x77, 0x3f, 0xd9, + 0xe6, 0xd9, 0xd3, 0x5d, 0x87, 0xf3, 0x2e, 0x32, 0x49, 0x1f, 0xb9, 0xa8, 0xd5, 0xe0, 0xa7, 0x3c, + 0xed, 0x04, 0x19, 0xeb, 0x0b, 0x62, 0xe9, 0x81, 0x77, 0x62, 0xd7, 0x3b, 0x49, 0xe2, 0xd7, 0xe0, + 0xea, 0x7f, 0x71, 0x13, 0x49, 0xfc, 0x24, 0xc1, 0x7c, 0x95, 0x5a, 0xfb, 0x4e, 0xcb, 0x60, 0xa8, + 0xe6, 0x3f, 0x53, 0xe5, 0x2d, 0x98, 0x31, 0x0e, 0x59, 0x9b, 0xb8, 0x98, 0x0d, 0x03, 0xea, 0x15, + 0xe5, 0xe5, 0xb3, 0xf5, 0x45, 0x7e, 0x41, 0xde, 0x6f, 0xb5, 0x5c, 0x44, 0x69, 0x9d, 0xb9, 0xd8, + 0xb6, 0xf4, 0x08, 0x2a, 0xdf, 0x83, 0x6c, 0xf0, 0xd0, 0xe5, 0x57, 0xea, 0xe5, 0xb4, 0x9b, 0xd1, + 0x07, 0x55, 0xa6, 0x9e, 0x1f, 0x17, 0x27, 0x74, 0x6e, 0x72, 0x77, 0xce, 0x63, 0x1f, 0x39, 0x5b, + 0x5d, 0xf6, 0x9f, 0x39, 0x71, 0x5e, 0x21, 0xe7, 0xcd, 0x3f, 0xb3, 0x90, 0xa9, 0x52, 0x4b, 0xfe, + 0x5e, 0x82, 0xa5, 0x94, 0x07, 0xed, 0xad, 0x94, 0xd0, 0xa9, 0xef, 0x2b, 0xf5, 0x93, 0xd3, 0x5a, + 0x84, 0x74, 0xe4, 0x6f, 0x61, 0x71, 0xec, 0x6b, 0x4c, 0x4b, 0xf7, 0x38, 0x0e, 0xaf, 0x6e, 0x9d, + 0x0e, 0x2f, 0xe2, 0x7f, 0x03, 0xe7, 0xc7, 0x3d, 0x7e, 0xd6, 0xdf, 0x96, 0x50, 0x02, 0xae, 0xde, + 0x39, 0x15, 0x5c, 0x04, 0x27, 0x30, 0x3f, 0x7a, 0xf2, 0xde, 0x48, 0xf7, 0x34, 0x02, 0x55, 0x37, + 0x4e, 0x0c, 0x15, 0x01, 0x31, 0xe4, 0x93, 0x87, 0xca, 0xf5, 0x74, 0x1f, 0x09, 0xa0, 0x5a, 0x3e, + 0x21, 0x50, 0x84, 0xfa, 0x41, 0x82, 0xe5, 0xf4, 0xdd, 0x7d, 0x3b, 0xdd, 0x5d, 0xaa, 0x91, 0x7a, + 0xef, 0x1d, 0x8c, 0x04, 0x9f, 0x03, 0x98, 0x4d, 0xec, 0xd3, 0x6b, 0xe9, 0xce, 0xe2, 0x38, 0x55, + 0x3b, 0x19, 0x2e, 0x8c, 0xa3, 0x4e, 0x7f, 0xf7, 0xe6, 0xe9, 0x4d, 0xa9, 0xf2, 0xf8, 0xf9, 0xab, + 0x82, 0xf4, 0xe2, 0x55, 0x41, 0xfa, 0xe3, 0x55, 0x41, 0xfa, 0xf1, 0x75, 0x61, 0xe2, 0xc5, 0xeb, + 0xc2, 0xc4, 0x6f, 0xaf, 0x0b, 0x13, 0x5f, 0xbd, 0xf5, 0xce, 0x1c, 0xc4, 0xff, 0x43, 0xfd, 0x63, + 0xb7, 0x99, 0xf5, 0xff, 0x43, 0x6f, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xd3, 0xc8, 0xf6, + 0xc7, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -859,6 +968,8 @@ const _ = grpc.SupportPackageIsVersion4 type MsgClient interface { // CreateFinalityProvider creates a new finality provider CreateFinalityProvider(ctx context.Context, in *MsgCreateFinalityProvider, opts ...grpc.CallOption) (*MsgCreateFinalityProviderResponse, error) + // EditFinalityProvider edits an existing finality provider + EditFinalityProvider(ctx context.Context, in *MsgEditFinalityProvider, opts ...grpc.CallOption) (*MsgEditFinalityProviderResponse, error) // CreateBTCDelegation creates a new BTC delegation CreateBTCDelegation(ctx context.Context, in *MsgCreateBTCDelegation, opts ...grpc.CallOption) (*MsgCreateBTCDelegationResponse, error) // AddCovenantSigs handles signatures from a covenant member @@ -889,6 +1000,15 @@ func (c *msgClient) CreateFinalityProvider(ctx context.Context, in *MsgCreateFin return out, nil } +func (c *msgClient) EditFinalityProvider(ctx context.Context, in *MsgEditFinalityProvider, opts ...grpc.CallOption) (*MsgEditFinalityProviderResponse, error) { + out := new(MsgEditFinalityProviderResponse) + err := c.cc.Invoke(ctx, "/babylon.btcstaking.v1.Msg/EditFinalityProvider", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) CreateBTCDelegation(ctx context.Context, in *MsgCreateBTCDelegation, opts ...grpc.CallOption) (*MsgCreateBTCDelegationResponse, error) { out := new(MsgCreateBTCDelegationResponse) err := c.cc.Invoke(ctx, "/babylon.btcstaking.v1.Msg/CreateBTCDelegation", in, out, opts...) @@ -938,6 +1058,8 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts type MsgServer interface { // CreateFinalityProvider creates a new finality provider CreateFinalityProvider(context.Context, *MsgCreateFinalityProvider) (*MsgCreateFinalityProviderResponse, error) + // EditFinalityProvider edits an existing finality provider + EditFinalityProvider(context.Context, *MsgEditFinalityProvider) (*MsgEditFinalityProviderResponse, error) // CreateBTCDelegation creates a new BTC delegation CreateBTCDelegation(context.Context, *MsgCreateBTCDelegation) (*MsgCreateBTCDelegationResponse, error) // AddCovenantSigs handles signatures from a covenant member @@ -958,6 +1080,9 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) CreateFinalityProvider(ctx context.Context, req *MsgCreateFinalityProvider) (*MsgCreateFinalityProviderResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateFinalityProvider not implemented") } +func (*UnimplementedMsgServer) EditFinalityProvider(ctx context.Context, req *MsgEditFinalityProvider) (*MsgEditFinalityProviderResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EditFinalityProvider not implemented") +} func (*UnimplementedMsgServer) CreateBTCDelegation(ctx context.Context, req *MsgCreateBTCDelegation) (*MsgCreateBTCDelegationResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateBTCDelegation not implemented") } @@ -996,6 +1121,24 @@ func _Msg_CreateFinalityProvider_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Msg_EditFinalityProvider_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgEditFinalityProvider) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).EditFinalityProvider(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.btcstaking.v1.Msg/EditFinalityProvider", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).EditFinalityProvider(ctx, req.(*MsgEditFinalityProvider)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_CreateBTCDelegation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgCreateBTCDelegation) if err := dec(in); err != nil { @@ -1094,6 +1237,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "CreateFinalityProvider", Handler: _Msg_CreateFinalityProvider_Handler, }, + { + MethodName: "EditFinalityProvider", + Handler: _Msg_EditFinalityProvider_Handler, + }, { MethodName: "CreateBTCDelegation", Handler: _Msg_CreateBTCDelegation_Handler, @@ -1232,6 +1379,90 @@ func (m *MsgCreateFinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } +func (m *MsgEditFinalityProvider) 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 *MsgEditFinalityProvider) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgEditFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Commission != nil { + { + size := m.Commission.Size() + i -= size + if _, err := m.Commission.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Description != nil { + { + size, err := m.Description.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.BtcPk) > 0 { + i -= len(m.BtcPk) + copy(dAtA[i:], m.BtcPk) + i = encodeVarintTx(dAtA, i, uint64(len(m.BtcPk))) + i-- + dAtA[i] = 0x12 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgEditFinalityProviderResponse) 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 *MsgEditFinalityProviderResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgEditFinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *MsgCreateBTCDelegation) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1779,6 +2010,40 @@ func (m *MsgCreateFinalityProviderResponse) Size() (n int) { return n } +func (m *MsgEditFinalityProvider) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.BtcPk) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Description != nil { + l = m.Description.Size() + n += 1 + l + sovTx(uint64(l)) + } + if m.Commission != nil { + l = m.Commission.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgEditFinalityProviderResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgCreateBTCDelegation) Size() (n int) { if m == nil { return 0 @@ -2302,6 +2567,244 @@ func (m *MsgCreateFinalityProviderResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgEditFinalityProvider) 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 ErrIntOverflowTx + } + 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: MsgEditFinalityProvider: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgEditFinalityProvider: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BtcPk = append(m.BtcPk[:0], dAtA[iNdEx:postIndex]...) + if m.BtcPk == nil { + m.BtcPk = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Description == nil { + m.Description = &types.Description{} + } + if err := m.Description.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commission", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v cosmossdk_io_math.LegacyDec + m.Commission = &v + if err := m.Commission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgEditFinalityProviderResponse) 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 ErrIntOverflowTx + } + 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: MsgEditFinalityProviderResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgEditFinalityProviderResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From d2ae0ae8a6926b9157180cccb2416fd85e61aa93 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 15 Feb 2024 14:15:10 +1100 Subject: [PATCH 007/119] btcstaking: query finality provider (#474) --- x/btcstaking/client/cli/query.go | 28 ++++++++++++++++++++++++++++ x/btcstaking/client/cli/tx.go | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/x/btcstaking/client/cli/query.go b/x/btcstaking/client/cli/query.go index 9d70db427..a587b19e9 100644 --- a/x/btcstaking/client/cli/query.go +++ b/x/btcstaking/client/cli/query.go @@ -23,6 +23,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { } cmd.AddCommand(CmdQueryParams()) + cmd.AddCommand(CmdFinalityProvider()) cmd.AddCommand(CmdFinalityProviders()) cmd.AddCommand(CmdBTCDelegations()) cmd.AddCommand(CmdFinalityProvidersAtHeight()) @@ -33,6 +34,33 @@ func GetQueryCmd(queryRoute string) *cobra.Command { return cmd } +func CmdFinalityProvider() *cobra.Command { + cmd := &cobra.Command{ + Use: "finality-provider [fp_btc_pk_hex]", + Short: "retrieve a finality provider", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.FinalityProvider( + cmd.Context(), + &types.QueryFinalityProviderRequest{ + FpBtcPkHex: args[0], + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + func CmdFinalityProviders() *cobra.Command { cmd := &cobra.Command{ Use: "finality-providers", diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 134f42f86..0557bebcf 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -137,7 +137,7 @@ func NewCreateFinalityProvicerCmd() *cobra.Command { func NewEditFinalityProvicerCmd() *cobra.Command { cmd := &cobra.Command{ Use: "edit-finality-provider [btc_pk]", - Args: cobra.ExactArgs(3), + Args: cobra.ExactArgs(1), Short: "Edit an existing finality provider", Long: strings.TrimSpace( `Edit an existing finality provider.`, // TODO: example From ddc16cb702d4d5f801757a90851e6d7d051f42a0 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 20 Feb 2024 10:54:08 +1100 Subject: [PATCH 008/119] doc: add doc for selective slashing (#484) --- x/btcstaking/README.md | 52 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index c934521c3..9f7ed6884 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -28,6 +28,7 @@ providers and BTC delegations under them. This includes: - [MsgAddCovenantSigs](#msgaddcovenantsigs) - [MsgBTCUndelegate](#msgbtcundelegate) - [MsgUpdateParams](#msgupdateparams) + - [MsgSelectiveSlashingEvidence](#msgselectiveslashingevidence) - [BeginBlocker](#beginblocker) - [Events](#events) - [Queries](#queries) @@ -580,7 +581,7 @@ Upon `AddCovenantSigs`, a Babylon node will execute as follows: The `MsgBTCUndelegate` message is used for unbonding bitcoins from a given finality provider. It is typically reported by the [BTC staking -tracker](https://github.com/babylonchain/vigilante-private/tree/dev/btcstaking-tracker) +tracker](https://github.com/babylonchain/vigilante/tree/dev/btcstaking-tracker) program which proactively monitors unbonding transactions on Bitcoin. ```protobuf @@ -633,6 +634,55 @@ message MsgUpdateParams { } ``` +### MsgSelectiveSlashingEvidence + +The `MsgSelectiveSlashingEvidence` message is used for submitting evidences for +selective slashing offences. In a selective slashing offence, the adversarial +finality provider chooses a victim BTC delegation, signs its slashing +transaction, and decrypts covenant adaptor signatures to the Schnorr signatures +using its secret key, before submitting this slashing transaction to Bitcoin. By +observing a pair of a [Schnorr +signature](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) and +an [adaptor signature](https://bitcoinops.org/en/topics/adaptor-signatures/) +from the covenant committee, anyone can extract the finality provider's secret +key due to the [adaptor signature +properties](../../crypto/schnorr-adaptor-signature/README.md). + +```proto +// MsgSelectiveSlashingEvidence is the message for handling evidence of selective slashing +// launched by a finality provider +message MsgSelectiveSlashingEvidence { + option (cosmos.msg.v1.signer) = "signer"; + + string signer = 1; + // staking_tx_hash is the hash of the staking tx. + // It uniquely identifies a BTC delegation + string staking_tx_hash = 2; + // recovered_fp_btc_sk is the BTC SK of the finality provider who + // launches the selective slashing offence. The SK is recovered by + // using a covenant adaptor signature and the corresponding Schnorr + // signature + bytes recovered_fp_btc_sk = 3; +} +``` + +Upon `MsgSelectiveSlashingEvidence`, a Babylon node will execute as follows: + +1. Find the BTC delegation with the given staking transaction hash. +2. Ensure the BTC delegation is active or unbonding. +3. Ensure the given secret key corresponds to the finality provider's public + key. +4. At this point, the finality provider must have done selective slashing. Thus, + slash the finality provider and emit an event `EventSelectiveSlashing` about + this. + +The `MsgSelectiveSlashingEvidence` is typically reported by the [BTC staking +tracker](https://github.com/babylonchain/vigilante/tree/dev/btcstaking-tracker) +program. It keeps monitoring for slashing transactions on Bitcoin. Upon each +slashing transaction, it will try to extract the finality provider's secret key. +If successful, it will construct a `MsgSelectiveSlashingEvidence` message and +submit it to Babylon. + ## BeginBlocker Upon `BeginBlock`, the BTC Staking module will execute the following: From 41737b8eb751cc8dcee88d4682ab3d1b5c3543a3 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 20 Feb 2024 07:41:57 -0300 Subject: [PATCH 009/119] chore: create client friendly response for BtcCheckpointInfo query --- client/docs/swagger-ui/swagger.yaml | 261 +++- proto/babylon/btccheckpoint/v1/query.proto | 58 +- x/btccheckpoint/keeper/grpc_query.go | 10 +- x/btccheckpoint/types/query.go | 52 + x/btccheckpoint/types/query.pb.go | 1364 ++++++++++++++++++-- 5 files changed, 1563 insertions(+), 182 deletions(-) create mode 100644 x/btccheckpoint/types/query.go diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index cccf807c2..843c8b9fa 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -339,19 +339,18 @@ paths: epoch_number: type: string format: uint64 - title: epoch number of this checkpoint + description: EpochNumber of this checkpoint. best_submission_btc_block_height: type: string format: uint64 title: btc height of the best submission of the epoch best_submission_btc_block_hash: type: string - format: byte title: >- hash of the btc block which determines checkpoint btc block height i.e. - youngest block of best submission + youngest block of best submission Hexadecimal best_submission_transactions: type: array items: @@ -379,32 +378,26 @@ paths: index: type: integer format: int64 + description: Index Bitcoin Transaction index in block. hash: type: string - format: byte + description: Hash BTC Header hash as hex. title: >- - Each provided OP_RETURN transaction can be - idendtified by hash of block in + TransactionKeyResponse Each provided OP_RETURN + transaction can be idendtified by - which transaction was included and transaction index - in the block + hash of block in which transaction was included and + transaction index in the block transaction: type: string - format: byte - title: transaction is the full transaction in bytes + description: transaction is the full transaction data as str hex. proof: type: string - format: byte title: >- proof is the Merkle proof that this tx is included in the position in `key` - - TODO: maybe it could use here better format as we - already processed and - - valideated the proof? title: |- - TransactionInfo is the info of a tx on Bitcoin, + TransactionInfoResponse is the info of a tx on Bitcoin, including - the position of the tx on BTC blockchain - the full tx content @@ -417,17 +410,13 @@ paths: properties: submitter: type: string - format: byte description: >- - TODO: this could probably be better typed - submitter is the address of the checkpoint submitter to BTC, extracted from the checkpoint itself. reporter: type: string - format: byte title: >- reporter is the address of the reporter who reported the submissions, @@ -435,17 +424,17 @@ paths: calculated from submission message MsgInsertBTCSpvProof itself title: >- - CheckpointAddresses contains the addresses of the - submitter and reporter of a + CheckpointAddressesResponse contains the addresses of + the submitter and reporter of a given checkpoint title: list of vigilantes' addresses of the best submission - title: >- - BTCCheckpointInfo contains all data about best submission of - checkpoint for + description: >- + BTCCheckpointInfoResponse contains all data about best + submission of checkpoint for given epoch. Best submission is the submission which is deeper - in btc ledger + in btc ledger. title: |- QueryBtcCheckpointInfoResponse is response type for the Query/BtcCheckpointInfo RPC method @@ -9680,6 +9669,107 @@ definitions: given epoch. Best submission is the submission which is deeper in btc ledger + babylon.btccheckpoint.v1.BTCCheckpointInfoResponse: + type: object + properties: + epoch_number: + type: string + format: uint64 + description: EpochNumber of this checkpoint. + best_submission_btc_block_height: + type: string + format: uint64 + title: btc height of the best submission of the epoch + best_submission_btc_block_hash: + type: string + title: >- + hash of the btc block which determines checkpoint btc block height + i.e. + + youngest block of best submission Hexadecimal + best_submission_transactions: + type: array + items: + type: object + properties: + key: + description: >- + key is the position (txIdx, blockHash) of this tx on BTC + blockchain + + Although it is already a part of SubmissionKey, we store it here + again + + to make TransactionInfo self-contained. + + For example, storing the key allows TransactionInfo to not relay + on + + the fact that TransactionInfo will be ordered in the same order + as + + TransactionKeys in SubmissionKey. + type: object + properties: + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. + title: >- + TransactionKeyResponse Each provided OP_RETURN transaction can + be idendtified by + + hash of block in which transaction was included and transaction + index in the block + transaction: + type: string + description: transaction is the full transaction data as str hex. + proof: + type: string + title: >- + proof is the Merkle proof that this tx is included in the + position in `key` + title: |- + TransactionInfoResponse is the info of a tx on Bitcoin, + including + - the position of the tx on BTC blockchain + - the full tx content + - the Merkle proof that this tx is on the above position + title: the BTC checkpoint transactions of the best submission + best_submission_vigilante_address_list: + type: array + items: + type: object + properties: + submitter: + type: string + description: >- + submitter is the address of the checkpoint submitter to BTC, + extracted from + + the checkpoint itself. + reporter: + type: string + title: >- + reporter is the address of the reporter who reported the + submissions, + + calculated from submission message MsgInsertBTCSpvProof itself + title: >- + CheckpointAddressesResponse contains the addresses of the submitter + and reporter of a + + given checkpoint + title: list of vigilantes' addresses of the best submission + description: >- + BTCCheckpointInfoResponse contains all data about best submission of + checkpoint for + + given epoch. Best submission is the submission which is deeper in btc + ledger. babylon.btccheckpoint.v1.CheckpointAddresses: type: object properties: @@ -9703,6 +9793,26 @@ definitions: CheckpointAddresses contains the addresses of the submitter and reporter of a + given checkpoint + babylon.btccheckpoint.v1.CheckpointAddressesResponse: + type: object + properties: + submitter: + type: string + description: >- + submitter is the address of the checkpoint submitter to BTC, extracted + from + + the checkpoint itself. + reporter: + type: string + title: |- + reporter is the address of the reporter who reported the submissions, + calculated from submission message MsgInsertBTCSpvProof itself + title: >- + CheckpointAddressesResponse contains the addresses of the submitter and + reporter of a + given checkpoint babylon.btccheckpoint.v1.Params: type: object @@ -9752,19 +9862,18 @@ definitions: epoch_number: type: string format: uint64 - title: epoch number of this checkpoint + description: EpochNumber of this checkpoint. best_submission_btc_block_height: type: string format: uint64 title: btc height of the best submission of the epoch best_submission_btc_block_hash: type: string - format: byte title: >- hash of the btc block which determines checkpoint btc block height i.e. - youngest block of best submission + youngest block of best submission Hexadecimal best_submission_transactions: type: array items: @@ -9792,32 +9901,26 @@ definitions: index: type: integer format: int64 + description: Index Bitcoin Transaction index in block. hash: type: string - format: byte + description: Hash BTC Header hash as hex. title: >- - Each provided OP_RETURN transaction can be idendtified by - hash of block in + TransactionKeyResponse Each provided OP_RETURN transaction + can be idendtified by - which transaction was included and transaction index in the - block + hash of block in which transaction was included and + transaction index in the block transaction: type: string - format: byte - title: transaction is the full transaction in bytes + description: transaction is the full transaction data as str hex. proof: type: string - format: byte title: >- proof is the Merkle proof that this tx is included in the position in `key` - - TODO: maybe it could use here better format as we already - processed and - - valideated the proof? title: |- - TransactionInfo is the info of a tx on Bitcoin, + TransactionInfoResponse is the info of a tx on Bitcoin, including - the position of the tx on BTC blockchain - the full tx content @@ -9830,17 +9933,13 @@ definitions: properties: submitter: type: string - format: byte description: >- - TODO: this could probably be better typed - submitter is the address of the checkpoint submitter to BTC, extracted from the checkpoint itself. reporter: type: string - format: byte title: >- reporter is the address of the reporter who reported the submissions, @@ -9848,17 +9947,17 @@ definitions: calculated from submission message MsgInsertBTCSpvProof itself title: >- - CheckpointAddresses contains the addresses of the submitter and - reporter of a + CheckpointAddressesResponse contains the addresses of the + submitter and reporter of a given checkpoint title: list of vigilantes' addresses of the best submission - title: >- - BTCCheckpointInfo contains all data about best submission of + description: >- + BTCCheckpointInfoResponse contains all data about best submission of checkpoint for given epoch. Best submission is the submission which is deeper in btc - ledger + ledger. title: |- QueryBtcCheckpointInfoResponse is response type for the Query/BtcCheckpointInfo RPC method @@ -10208,6 +10307,46 @@ definitions: - the position of the tx on BTC blockchain - the full tx content - the Merkle proof that this tx is on the above position + babylon.btccheckpoint.v1.TransactionInfoResponse: + type: object + properties: + key: + description: |- + key is the position (txIdx, blockHash) of this tx on BTC blockchain + Although it is already a part of SubmissionKey, we store it here again + to make TransactionInfo self-contained. + For example, storing the key allows TransactionInfo to not relay on + the fact that TransactionInfo will be ordered in the same order as + TransactionKeys in SubmissionKey. + type: object + properties: + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. + title: >- + TransactionKeyResponse Each provided OP_RETURN transaction can be + idendtified by + + hash of block in which transaction was included and transaction index + in the block + transaction: + type: string + description: transaction is the full transaction data as str hex. + proof: + type: string + title: >- + proof is the Merkle proof that this tx is included in the position in + `key` + title: |- + TransactionInfoResponse is the info of a tx on Bitcoin, + including + - the position of the tx on BTC blockchain + - the full tx content + - the Merkle proof that this tx is on the above position babylon.btccheckpoint.v1.TransactionKey: type: object properties: @@ -10220,6 +10359,22 @@ definitions: title: |- Each provided OP_RETURN transaction can be idendtified by hash of block in which transaction was included and transaction index in the block + babylon.btccheckpoint.v1.TransactionKeyResponse: + type: object + properties: + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. + title: >- + TransactionKeyResponse Each provided OP_RETURN transaction can be + idendtified by + + hash of block in which transaction was included and transaction index in + the block cosmos.base.query.v1beta1.PageRequest: type: object properties: diff --git a/proto/babylon/btccheckpoint/v1/query.proto b/proto/babylon/btccheckpoint/v1/query.proto index 2c88f8905..6b8a9eb0c 100644 --- a/proto/babylon/btccheckpoint/v1/query.proto +++ b/proto/babylon/btccheckpoint/v1/query.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package babylon.btccheckpoint.v1; import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btccheckpoint/v1/params.proto"; @@ -55,7 +56,7 @@ message QueryBtcCheckpointInfoRequest { // QueryBtcCheckpointInfoResponse is response type for the // Query/BtcCheckpointInfo RPC method -message QueryBtcCheckpointInfoResponse { BTCCheckpointInfo info = 1; } +message QueryBtcCheckpointInfoResponse { BTCCheckpointInfoResponse info = 1; } // QueryBtcCheckpointsInfoRequest is request type for the // Query/BtcCheckpointsInfo RPC method @@ -89,3 +90,58 @@ message QueryEpochSubmissionsResponse { cosmos.base.query.v1beta1.PageResponse pagination = 2; } + +// BTCCheckpointInfoResponse contains all data about best submission of checkpoint for +// given epoch. Best submission is the submission which is deeper in btc ledger. +message BTCCheckpointInfoResponse { + // EpochNumber of this checkpoint. + uint64 epoch_number = 1; + // btc height of the best submission of the epoch + uint64 best_submission_btc_block_height = 2; + // hash of the btc block which determines checkpoint btc block height i.e. + // youngest block of best submission Hexadecimal + string best_submission_btc_block_hash = 3; + // the BTC checkpoint transactions of the best submission + repeated TransactionInfoResponse best_submission_transactions = 4; + // list of vigilantes' addresses of the best submission + repeated CheckpointAddressesResponse best_submission_vigilante_address_list = 5; +} + +// TransactionInfoResponse is the info of a tx on Bitcoin, +// including +// - the position of the tx on BTC blockchain +// - the full tx content +// - the Merkle proof that this tx is on the above position +message TransactionInfoResponse { + // key is the position (txIdx, blockHash) of this tx on BTC blockchain + // Although it is already a part of SubmissionKey, we store it here again + // to make TransactionInfo self-contained. + // For example, storing the key allows TransactionInfo to not relay on + // the fact that TransactionInfo will be ordered in the same order as + // TransactionKeys in SubmissionKey. + TransactionKeyResponse key = 1; + // transaction is the full transaction data as str hex. + string transaction = 2; + // proof is the Merkle proof that this tx is included in the position in `key` + string proof = 3; +} + +// TransactionKeyResponse Each provided OP_RETURN transaction can be idendtified by +// hash of block in which transaction was included and transaction index in the block +message TransactionKeyResponse { + // Index Bitcoin Transaction index in block. + uint32 index = 1; + // Hash BTC Header hash as hex. + string hash = 2; +} + +// CheckpointAddressesResponse contains the addresses of the submitter and reporter of a +// given checkpoint +message CheckpointAddressesResponse { + // submitter is the address of the checkpoint submitter to BTC, extracted from + // the checkpoint itself. + string submitter = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // reporter is the address of the reporter who reported the submissions, + // calculated from submission message MsgInsertBTCSpvProof itself + string reporter = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} diff --git a/x/btccheckpoint/keeper/grpc_query.go b/x/btccheckpoint/keeper/grpc_query.go index d5e155029..bb9e2f723 100644 --- a/x/btccheckpoint/keeper/grpc_query.go +++ b/x/btccheckpoint/keeper/grpc_query.go @@ -44,21 +44,17 @@ func (k Keeper) BtcCheckpointInfo(c context.Context, req *types.QueryBtcCheckpoi } ctx := sdk.UnwrapSDKContext(c) - checkpointEpoch := req.GetEpochNum() ed := k.GetEpochData(ctx, checkpointEpoch) - ckptInfo, err := k.getCheckpointInfo(ctx, checkpointEpoch, ed) - if err != nil { return nil, fmt.Errorf("failed to get lowest BTC height and hash in keys of epoch %d: %w", req.EpochNum, err) } - resp := &types.QueryBtcCheckpointInfoResponse{ - Info: ckptInfo, - } - return resp, nil + return &types.QueryBtcCheckpointInfoResponse{ + Info: ckptInfo.ToResponse(), + }, nil } func (k Keeper) BtcCheckpointsInfo(ctx context.Context, req *types.QueryBtcCheckpointsInfoRequest) (*types.QueryBtcCheckpointsInfoResponse, error) { diff --git a/x/btccheckpoint/types/query.go b/x/btccheckpoint/types/query.go new file mode 100644 index 000000000..fb2276c8d --- /dev/null +++ b/x/btccheckpoint/types/query.go @@ -0,0 +1,52 @@ +package types + +import ( + "encoding/hex" + + "github.com/cosmos/cosmos-sdk/types" +) + +// ToResponse parses a TransactionInfo into a query response tx info struct. +func (ti *TransactionInfo) ToResponse() *TransactionInfoResponse { + return &TransactionInfoResponse{ + Key: ti.Key.ToResponse(), + Transaction: hex.EncodeToString(ti.Transaction), + Proof: hex.EncodeToString(ti.Proof), + } +} + +// ToResponse parses a TransactionKeyResponse into a query response tx key struct. +func (tk *TransactionKey) ToResponse() *TransactionKeyResponse { + return &TransactionKeyResponse{ + Index: tk.Index, + Hash: hex.EncodeToString(*tk.Hash), + } +} + +// ToResponse parses a CheckpointAddresses into a query response checkpoint addresses struct. +func (ca *CheckpointAddresses) ToResponse() *CheckpointAddressesResponse { + return &CheckpointAddressesResponse{ + Submitter: types.AccAddress(ca.Submitter).String(), + Reporter: types.AccAddress(ca.Reporter).String(), + } +} + +// ToResponse parses a BTCCheckpointInfo into a query response for btc checkpoint info struct. +func (b BTCCheckpointInfo) ToResponse() *BTCCheckpointInfoResponse { + bestSubTxs := make([]*TransactionInfoResponse, len(b.BestSubmissionTransactions)) + for i, tx := range b.BestSubmissionTransactions { + bestSubTxs[i] = tx.ToResponse() + } + bestSubVigAddrs := make([]*CheckpointAddressesResponse, len(b.BestSubmissionVigilanteAddressList)) + for i, addrs := range b.BestSubmissionVigilanteAddressList { + bestSubVigAddrs[i] = addrs.ToResponse() + } + + return &BTCCheckpointInfoResponse{ + EpochNumber: b.EpochNumber, + BestSubmissionBtcBlockHeight: b.BestSubmissionBtcBlockHeight, + BestSubmissionBtcBlockHash: hex.EncodeToString(*b.BestSubmissionBtcBlockHash), + BestSubmissionTransactions: bestSubTxs, + BestSubmissionVigilanteAddressList: bestSubVigAddrs, + } +} diff --git a/x/btccheckpoint/types/query.pb.go b/x/btccheckpoint/types/query.pb.go index 65b155490..81cde87e4 100644 --- a/x/btccheckpoint/types/query.pb.go +++ b/x/btccheckpoint/types/query.pb.go @@ -6,6 +6,7 @@ package types import ( context "context" fmt "fmt" + _ "github.com/cosmos/cosmos-proto" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -164,7 +165,7 @@ func (m *QueryBtcCheckpointInfoRequest) GetEpochNum() uint64 { // QueryBtcCheckpointInfoResponse is response type for the // Query/BtcCheckpointInfo RPC method type QueryBtcCheckpointInfoResponse struct { - Info *BTCCheckpointInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` + Info *BTCCheckpointInfoResponse `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` } func (m *QueryBtcCheckpointInfoResponse) Reset() { *m = QueryBtcCheckpointInfoResponse{} } @@ -200,7 +201,7 @@ func (m *QueryBtcCheckpointInfoResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryBtcCheckpointInfoResponse proto.InternalMessageInfo -func (m *QueryBtcCheckpointInfoResponse) GetInfo() *BTCCheckpointInfo { +func (m *QueryBtcCheckpointInfoResponse) GetInfo() *BTCCheckpointInfoResponse { if m != nil { return m.Info } @@ -419,6 +420,277 @@ func (m *QueryEpochSubmissionsResponse) GetPagination() *query.PageResponse { return nil } +// BTCCheckpointInfoResponse contains all data about best submission of checkpoint for +// given epoch. Best submission is the submission which is deeper in btc ledger. +type BTCCheckpointInfoResponse struct { + // EpochNumber of this checkpoint. + EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` + // btc height of the best submission of the epoch + BestSubmissionBtcBlockHeight uint64 `protobuf:"varint,2,opt,name=best_submission_btc_block_height,json=bestSubmissionBtcBlockHeight,proto3" json:"best_submission_btc_block_height,omitempty"` + // hash of the btc block which determines checkpoint btc block height i.e. + // youngest block of best submission Hexadecimal + BestSubmissionBtcBlockHash string `protobuf:"bytes,3,opt,name=best_submission_btc_block_hash,json=bestSubmissionBtcBlockHash,proto3" json:"best_submission_btc_block_hash,omitempty"` + // the BTC checkpoint transactions of the best submission + BestSubmissionTransactions []*TransactionInfoResponse `protobuf:"bytes,4,rep,name=best_submission_transactions,json=bestSubmissionTransactions,proto3" json:"best_submission_transactions,omitempty"` + // list of vigilantes' addresses of the best submission + BestSubmissionVigilanteAddressList []*CheckpointAddressesResponse `protobuf:"bytes,5,rep,name=best_submission_vigilante_address_list,json=bestSubmissionVigilanteAddressList,proto3" json:"best_submission_vigilante_address_list,omitempty"` +} + +func (m *BTCCheckpointInfoResponse) Reset() { *m = BTCCheckpointInfoResponse{} } +func (m *BTCCheckpointInfoResponse) String() string { return proto.CompactTextString(m) } +func (*BTCCheckpointInfoResponse) ProtoMessage() {} +func (*BTCCheckpointInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6b9a2f46ada7d854, []int{8} +} +func (m *BTCCheckpointInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BTCCheckpointInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BTCCheckpointInfoResponse.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 *BTCCheckpointInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCCheckpointInfoResponse.Merge(m, src) +} +func (m *BTCCheckpointInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *BTCCheckpointInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BTCCheckpointInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BTCCheckpointInfoResponse proto.InternalMessageInfo + +func (m *BTCCheckpointInfoResponse) GetEpochNumber() uint64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +func (m *BTCCheckpointInfoResponse) GetBestSubmissionBtcBlockHeight() uint64 { + if m != nil { + return m.BestSubmissionBtcBlockHeight + } + return 0 +} + +func (m *BTCCheckpointInfoResponse) GetBestSubmissionBtcBlockHash() string { + if m != nil { + return m.BestSubmissionBtcBlockHash + } + return "" +} + +func (m *BTCCheckpointInfoResponse) GetBestSubmissionTransactions() []*TransactionInfoResponse { + if m != nil { + return m.BestSubmissionTransactions + } + return nil +} + +func (m *BTCCheckpointInfoResponse) GetBestSubmissionVigilanteAddressList() []*CheckpointAddressesResponse { + if m != nil { + return m.BestSubmissionVigilanteAddressList + } + return nil +} + +// TransactionInfoResponse is the info of a tx on Bitcoin, +// including +// - the position of the tx on BTC blockchain +// - the full tx content +// - the Merkle proof that this tx is on the above position +type TransactionInfoResponse struct { + // key is the position (txIdx, blockHash) of this tx on BTC blockchain + // Although it is already a part of SubmissionKey, we store it here again + // to make TransactionInfo self-contained. + // For example, storing the key allows TransactionInfo to not relay on + // the fact that TransactionInfo will be ordered in the same order as + // TransactionKeys in SubmissionKey. + Key *TransactionKeyResponse `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // transaction is the full transaction data as str hex. + Transaction string `protobuf:"bytes,2,opt,name=transaction,proto3" json:"transaction,omitempty"` + // proof is the Merkle proof that this tx is included in the position in `key` + Proof string `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"` +} + +func (m *TransactionInfoResponse) Reset() { *m = TransactionInfoResponse{} } +func (m *TransactionInfoResponse) String() string { return proto.CompactTextString(m) } +func (*TransactionInfoResponse) ProtoMessage() {} +func (*TransactionInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6b9a2f46ada7d854, []int{9} +} +func (m *TransactionInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TransactionInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TransactionInfoResponse.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 *TransactionInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransactionInfoResponse.Merge(m, src) +} +func (m *TransactionInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *TransactionInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TransactionInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TransactionInfoResponse proto.InternalMessageInfo + +func (m *TransactionInfoResponse) GetKey() *TransactionKeyResponse { + if m != nil { + return m.Key + } + return nil +} + +func (m *TransactionInfoResponse) GetTransaction() string { + if m != nil { + return m.Transaction + } + return "" +} + +func (m *TransactionInfoResponse) GetProof() string { + if m != nil { + return m.Proof + } + return "" +} + +// TransactionKeyResponse Each provided OP_RETURN transaction can be idendtified by +// hash of block in which transaction was included and transaction index in the block +type TransactionKeyResponse struct { + // Index Bitcoin Transaction index in block. + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // Hash BTC Header hash as hex. + Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (m *TransactionKeyResponse) Reset() { *m = TransactionKeyResponse{} } +func (m *TransactionKeyResponse) String() string { return proto.CompactTextString(m) } +func (*TransactionKeyResponse) ProtoMessage() {} +func (*TransactionKeyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6b9a2f46ada7d854, []int{10} +} +func (m *TransactionKeyResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TransactionKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TransactionKeyResponse.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 *TransactionKeyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_TransactionKeyResponse.Merge(m, src) +} +func (m *TransactionKeyResponse) XXX_Size() int { + return m.Size() +} +func (m *TransactionKeyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_TransactionKeyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_TransactionKeyResponse proto.InternalMessageInfo + +func (m *TransactionKeyResponse) GetIndex() uint32 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *TransactionKeyResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +// CheckpointAddressesResponse contains the addresses of the submitter and reporter of a +// given checkpoint +type CheckpointAddressesResponse struct { + // submitter is the address of the checkpoint submitter to BTC, extracted from + // the checkpoint itself. + Submitter string `protobuf:"bytes,1,opt,name=submitter,proto3" json:"submitter,omitempty"` + // reporter is the address of the reporter who reported the submissions, + // calculated from submission message MsgInsertBTCSpvProof itself + Reporter string `protobuf:"bytes,2,opt,name=reporter,proto3" json:"reporter,omitempty"` +} + +func (m *CheckpointAddressesResponse) Reset() { *m = CheckpointAddressesResponse{} } +func (m *CheckpointAddressesResponse) String() string { return proto.CompactTextString(m) } +func (*CheckpointAddressesResponse) ProtoMessage() {} +func (*CheckpointAddressesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6b9a2f46ada7d854, []int{11} +} +func (m *CheckpointAddressesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CheckpointAddressesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CheckpointAddressesResponse.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 *CheckpointAddressesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckpointAddressesResponse.Merge(m, src) +} +func (m *CheckpointAddressesResponse) XXX_Size() int { + return m.Size() +} +func (m *CheckpointAddressesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CheckpointAddressesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckpointAddressesResponse proto.InternalMessageInfo + +func (m *CheckpointAddressesResponse) GetSubmitter() string { + if m != nil { + return m.Submitter + } + return "" +} + +func (m *CheckpointAddressesResponse) GetReporter() string { + if m != nil { + return m.Reporter + } + return "" +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btccheckpoint.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btccheckpoint.v1.QueryParamsResponse") @@ -428,6 +700,10 @@ func init() { proto.RegisterType((*QueryBtcCheckpointsInfoResponse)(nil), "babylon.btccheckpoint.v1.QueryBtcCheckpointsInfoResponse") proto.RegisterType((*QueryEpochSubmissionsRequest)(nil), "babylon.btccheckpoint.v1.QueryEpochSubmissionsRequest") proto.RegisterType((*QueryEpochSubmissionsResponse)(nil), "babylon.btccheckpoint.v1.QueryEpochSubmissionsResponse") + proto.RegisterType((*BTCCheckpointInfoResponse)(nil), "babylon.btccheckpoint.v1.BTCCheckpointInfoResponse") + proto.RegisterType((*TransactionInfoResponse)(nil), "babylon.btccheckpoint.v1.TransactionInfoResponse") + proto.RegisterType((*TransactionKeyResponse)(nil), "babylon.btccheckpoint.v1.TransactionKeyResponse") + proto.RegisterType((*CheckpointAddressesResponse)(nil), "babylon.btccheckpoint.v1.CheckpointAddressesResponse") } func init() { @@ -435,46 +711,65 @@ func init() { } var fileDescriptor_6b9a2f46ada7d854 = []byte{ - // 621 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0x4d, 0x6b, 0x13, 0x4f, - 0x1c, 0xc7, 0x33, 0xf9, 0xa7, 0xa1, 0x9d, 0xff, 0x45, 0xc7, 0x1e, 0xe2, 0xb6, 0x6e, 0xe3, 0x62, - 0x4d, 0xd1, 0x76, 0x97, 0xb4, 0x68, 0x2d, 0x8a, 0x42, 0x8a, 0x4f, 0x28, 0x5a, 0xa3, 0x5e, 0xbc, - 0x94, 0xd9, 0x65, 0xba, 0x59, 0x9a, 0x9d, 0xd9, 0x66, 0x66, 0x83, 0x41, 0xbc, 0xe8, 0x0b, 0x50, - 0xf0, 0x35, 0x78, 0xf3, 0xa8, 0x57, 0xc1, 0x5b, 0x8f, 0x05, 0x2f, 0x9e, 0x44, 0x12, 0x5f, 0x88, - 0xec, 0xec, 0x34, 0x8f, 0x0e, 0x49, 0x8a, 0xb7, 0xb0, 0xf9, 0x7e, 0x7f, 0xdf, 0xcf, 0xfe, 0x1e, - 0x12, 0x78, 0xc1, 0xc5, 0x6e, 0xab, 0xce, 0xa8, 0xe3, 0x0a, 0xcf, 0xab, 0x11, 0x6f, 0x3f, 0x62, - 0x01, 0x15, 0x4e, 0xb3, 0xec, 0x1c, 0xc4, 0xa4, 0xd1, 0xb2, 0xa3, 0x06, 0x13, 0x0c, 0x15, 0x94, - 0xca, 0x1e, 0x50, 0xd9, 0xcd, 0xb2, 0x31, 0xef, 0x33, 0x9f, 0x49, 0x91, 0x93, 0x7c, 0x4a, 0xf5, - 0xc6, 0xa2, 0xcf, 0x98, 0x5f, 0x27, 0x0e, 0x8e, 0x02, 0x07, 0x53, 0xca, 0x04, 0x16, 0x01, 0xa3, - 0x5c, 0x7d, 0x7b, 0xc9, 0x63, 0x3c, 0x64, 0xdc, 0x71, 0x31, 0x27, 0x69, 0x8c, 0xd3, 0x2c, 0xbb, - 0x44, 0xe0, 0xb2, 0x13, 0x61, 0x3f, 0xa0, 0x52, 0xac, 0xb4, 0xcb, 0x5a, 0xbe, 0x08, 0x37, 0x70, - 0x78, 0x5c, 0x72, 0x55, 0x2b, 0x1b, 0x24, 0x96, 0x6a, 0x6b, 0x1e, 0xa2, 0x27, 0x49, 0xec, 0x8e, - 0x2c, 0x51, 0x25, 0x07, 0x31, 0xe1, 0xc2, 0x7a, 0x0e, 0xcf, 0x0c, 0x3c, 0xe5, 0x11, 0xa3, 0x9c, - 0xa0, 0x9b, 0x30, 0x9f, 0x46, 0x15, 0x40, 0x11, 0xac, 0xfc, 0xbf, 0x5e, 0xb4, 0x75, 0xcd, 0xb0, - 0x53, 0x67, 0x25, 0x77, 0xf8, 0x73, 0x29, 0x53, 0x55, 0x2e, 0xeb, 0x06, 0x3c, 0x27, 0xcb, 0x56, - 0x84, 0xb7, 0xdd, 0x55, 0xdf, 0xa7, 0x7b, 0x4c, 0xe5, 0xa2, 0x05, 0x38, 0x47, 0x22, 0xe6, 0xd5, - 0x76, 0x69, 0x1c, 0xca, 0x8c, 0x5c, 0x75, 0x56, 0x3e, 0x78, 0x14, 0x87, 0x16, 0x86, 0xa6, 0xce, - 0xad, 0xf8, 0x6e, 0xc1, 0x5c, 0x40, 0xf7, 0x98, 0xa2, 0xbb, 0xac, 0xa7, 0xab, 0x3c, 0xdb, 0x1e, - 0x2a, 0x21, 0x8d, 0x56, 0xed, 0x6f, 0x11, 0xbc, 0x9f, 0xf0, 0x0e, 0x84, 0xbd, 0xc1, 0xa8, 0xa0, - 0x8b, 0x76, 0x3a, 0x45, 0x3b, 0x99, 0xa2, 0x9d, 0x2e, 0x8b, 0x9a, 0xa2, 0xbd, 0x83, 0x7d, 0xa2, - 0xbc, 0xd5, 0x3e, 0xa7, 0xf5, 0x19, 0xc0, 0x25, 0x6d, 0x94, 0x7a, 0x9d, 0x7b, 0x70, 0x2e, 0xa1, - 0xda, 0xad, 0x07, 0x5c, 0x14, 0x40, 0xf1, 0xbf, 0x69, 0xdf, 0x69, 0x36, 0x71, 0x3f, 0x0c, 0xb8, - 0x40, 0x77, 0x07, 0xa8, 0xb3, 0x92, 0xba, 0x34, 0x96, 0x3a, 0xc5, 0x18, 0xc0, 0x7e, 0x0b, 0xe0, - 0xa2, 0xc4, 0xbe, 0x9d, 0x4c, 0xe5, 0x69, 0xec, 0x86, 0x01, 0xe7, 0xc9, 0x3e, 0x4f, 0x32, 0xc1, - 0xa1, 0xe6, 0x65, 0x4f, 0xdc, 0xbc, 0x8f, 0x40, 0x2d, 0xd2, 0x28, 0x85, 0x6a, 0xdd, 0x75, 0x98, - 0xdb, 0x27, 0x2d, 0xae, 0xba, 0x56, 0xd2, 0x77, 0xad, 0x67, 0x7e, 0x40, 0x5a, 0x55, 0x69, 0xfa, - 0x67, 0xdd, 0x5a, 0xff, 0x36, 0x03, 0x67, 0x24, 0x27, 0x7a, 0x07, 0x60, 0x3e, 0x3d, 0x09, 0xb4, - 0xaa, 0x87, 0x19, 0xbd, 0x44, 0x63, 0x6d, 0x42, 0x75, 0x9a, 0x6e, 0xad, 0xbc, 0xf9, 0xfe, 0xfb, - 0x43, 0xd6, 0x42, 0x45, 0x67, 0xcc, 0x8f, 0x05, 0xfa, 0x02, 0xe0, 0xe9, 0x91, 0x4b, 0x42, 0x9b, - 0x63, 0xe2, 0x74, 0x97, 0x6b, 0x5c, 0x9b, 0xde, 0xa8, 0x90, 0xd7, 0x24, 0x72, 0x09, 0x2d, 0xeb, - 0x91, 0x5f, 0x75, 0x57, 0xea, 0x35, 0xfa, 0x04, 0x20, 0x1a, 0xbd, 0x19, 0x34, 0x55, 0x7e, 0xff, - 0x45, 0x1b, 0x5b, 0x27, 0x70, 0x2a, 0xf4, 0xf3, 0x12, 0x7d, 0x01, 0x9d, 0xd5, 0xa2, 0xa3, 0xaf, - 0x00, 0x9e, 0x1a, 0xde, 0x52, 0x74, 0x75, 0x4c, 0xa4, 0xe6, 0xb8, 0x8c, 0xcd, 0xa9, 0x7d, 0x0a, - 0x74, 0x4b, 0x82, 0x6e, 0xa0, 0xf2, 0x44, 0x3d, 0x76, 0x78, 0xaf, 0x44, 0xe5, 0xf1, 0x61, 0xdb, - 0x04, 0x47, 0x6d, 0x13, 0xfc, 0x6a, 0x9b, 0xe0, 0x7d, 0xc7, 0xcc, 0x1c, 0x75, 0xcc, 0xcc, 0x8f, - 0x8e, 0x99, 0x79, 0x71, 0xc5, 0x0f, 0x44, 0x2d, 0x76, 0x6d, 0x8f, 0x85, 0xc7, 0x65, 0xbd, 0x1a, - 0x0e, 0x68, 0x37, 0xe3, 0xe5, 0x50, 0x8a, 0x68, 0x45, 0x84, 0xbb, 0x79, 0xf9, 0xc7, 0xb3, 0xf1, - 0x27, 0x00, 0x00, 0xff, 0xff, 0x19, 0x16, 0x59, 0xdc, 0x6f, 0x07, 0x00, 0x00, + // 920 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xdc, 0x44, + 0x18, 0xcd, 0x24, 0x9b, 0x28, 0xfb, 0x05, 0x24, 0x18, 0x22, 0xd8, 0x6c, 0x82, 0xbb, 0xb5, 0x68, + 0x13, 0x41, 0x63, 0xb3, 0x09, 0x6d, 0xa9, 0x40, 0x48, 0xb8, 0xa2, 0x2d, 0x02, 0x41, 0x71, 0x0b, + 0x07, 0x2e, 0xd6, 0xd8, 0x99, 0xd8, 0xa3, 0xec, 0x7a, 0x5c, 0xcf, 0x6c, 0xd4, 0x15, 0xe2, 0x02, + 0x27, 0xc4, 0x01, 0x24, 0xc4, 0x9f, 0xc0, 0x8d, 0x63, 0xb9, 0x22, 0x71, 0xab, 0xc4, 0xa5, 0x82, + 0x0b, 0x27, 0x84, 0x12, 0xfe, 0x10, 0xe4, 0xf1, 0xec, 0xef, 0x4c, 0x77, 0x37, 0xe2, 0xb6, 0xb6, + 0xdf, 0xfb, 0xde, 0x9b, 0xf7, 0xcd, 0xcc, 0xb7, 0xf0, 0x4a, 0x48, 0xc2, 0x6e, 0x8b, 0xa7, 0x6e, + 0x28, 0xa3, 0x28, 0xa1, 0xd1, 0x51, 0xc6, 0x59, 0x2a, 0xdd, 0xe3, 0xa6, 0xfb, 0xa0, 0x43, 0xf3, + 0xae, 0x93, 0xe5, 0x5c, 0x72, 0x5c, 0xd3, 0x28, 0x67, 0x04, 0xe5, 0x1c, 0x37, 0xeb, 0xeb, 0x31, + 0x8f, 0xb9, 0x02, 0xb9, 0xc5, 0xaf, 0x12, 0x5f, 0xdf, 0x88, 0xb8, 0x68, 0x73, 0x11, 0x94, 0x1f, + 0xca, 0x07, 0xfd, 0x69, 0x2b, 0xe6, 0x3c, 0x6e, 0x51, 0x97, 0x64, 0xcc, 0x25, 0x69, 0xca, 0x25, + 0x91, 0x8c, 0xa7, 0xbd, 0xaf, 0xaf, 0x96, 0x58, 0x37, 0x24, 0x82, 0x96, 0x0e, 0xdc, 0xe3, 0x66, + 0x48, 0x25, 0x69, 0xba, 0x19, 0x89, 0x59, 0xaa, 0xc0, 0x1a, 0x7b, 0xc9, 0x68, 0x3d, 0x23, 0x39, + 0x69, 0xf7, 0x4a, 0x5e, 0x31, 0xc2, 0x46, 0x17, 0xa3, 0xd0, 0xf6, 0x3a, 0xe0, 0x4f, 0x0a, 0xd9, + 0xbb, 0xaa, 0x84, 0x4f, 0x1f, 0x74, 0xa8, 0x90, 0xf6, 0xa7, 0xf0, 0xc2, 0xc8, 0x5b, 0x91, 0xf1, + 0x54, 0x50, 0xfc, 0x0e, 0xac, 0x94, 0x52, 0x35, 0xd4, 0x40, 0x3b, 0x6b, 0x7b, 0x0d, 0xc7, 0x94, + 0x93, 0x53, 0x32, 0xbd, 0xca, 0xe3, 0xbf, 0x2f, 0x2c, 0xf8, 0x9a, 0x65, 0xbf, 0x0d, 0x2f, 0xab, + 0xb2, 0x9e, 0x8c, 0x6e, 0xf6, 0xd1, 0xef, 0xa7, 0x87, 0x5c, 0xeb, 0xe2, 0x4d, 0xa8, 0xd2, 0x8c, + 0x47, 0x49, 0x90, 0x76, 0xda, 0x4a, 0xa3, 0xe2, 0xaf, 0xaa, 0x17, 0x1f, 0x75, 0xda, 0x36, 0x03, + 0xcb, 0xc4, 0xd6, 0xfe, 0x6e, 0x43, 0x85, 0xa5, 0x87, 0x5c, 0xbb, 0xdb, 0x37, 0xbb, 0xf3, 0xee, + 0xdf, 0x3c, 0xbb, 0x84, 0xaf, 0x0a, 0xd8, 0xc9, 0x59, 0x52, 0x62, 0xd8, 0xe9, 0x2d, 0x80, 0x41, + 0x83, 0xb4, 0xe0, 0x65, 0x47, 0x77, 0xbe, 0xe8, 0xa6, 0x53, 0xee, 0x27, 0xdd, 0x4d, 0xe7, 0x2e, + 0x89, 0xa9, 0xe6, 0xfa, 0x43, 0x4c, 0xfb, 0x11, 0x82, 0x0b, 0x46, 0x29, 0xbd, 0xac, 0x3b, 0x50, + 0x2d, 0x5c, 0x05, 0x2d, 0x26, 0x64, 0x0d, 0x35, 0x96, 0x76, 0xd6, 0xf6, 0x5e, 0x9b, 0x67, 0x6d, + 0xab, 0x05, 0xfb, 0x43, 0x26, 0x24, 0xbe, 0x3d, 0xe2, 0x7a, 0x51, 0xb9, 0xde, 0x9e, 0xea, 0x5a, + 0x47, 0x33, 0x6c, 0xfb, 0x6b, 0x04, 0x5b, 0xca, 0xf6, 0x7b, 0x45, 0x77, 0xee, 0x75, 0xc2, 0x36, + 0x13, 0xa2, 0xd8, 0xd7, 0xb3, 0x74, 0x72, 0x2c, 0xbc, 0xc5, 0x73, 0x87, 0xf7, 0x13, 0xd2, 0x1b, + 0x6a, 0xd2, 0x85, 0x8e, 0xee, 0x2d, 0xa8, 0x1c, 0xd1, 0xae, 0xd0, 0xa9, 0x6d, 0x9b, 0x53, 0x1b, + 0x90, 0x3f, 0xa0, 0x5d, 0x5f, 0x91, 0xfe, 0xbf, 0xb4, 0x7e, 0x5f, 0x82, 0x0d, 0xe3, 0x96, 0xc3, + 0x17, 0xe1, 0x99, 0x7e, 0x54, 0x21, 0xcd, 0x75, 0x5a, 0x6b, 0xbd, 0xb4, 0x42, 0x9a, 0xe3, 0x5b, + 0xd0, 0x08, 0xa9, 0x90, 0x81, 0xe8, 0xbb, 0x0c, 0x42, 0x19, 0x05, 0x61, 0x8b, 0x47, 0x47, 0x41, + 0x42, 0x59, 0x9c, 0x48, 0xe5, 0xaf, 0xe2, 0x6f, 0x15, 0xb8, 0xc1, 0x62, 0x3c, 0x19, 0x79, 0x05, + 0xe8, 0x8e, 0xc2, 0x60, 0x0f, 0xac, 0xa7, 0xd4, 0x21, 0x22, 0xa9, 0x2d, 0x35, 0xd0, 0x4e, 0xd5, + 0xaf, 0x1b, 0xaa, 0x10, 0x91, 0x60, 0x01, 0x5b, 0xe3, 0x35, 0x64, 0x4e, 0x52, 0x41, 0x22, 0x75, + 0xb1, 0xd5, 0x2a, 0x2a, 0xea, 0xa6, 0x39, 0xea, 0xfb, 0x03, 0xf4, 0xc8, 0xd1, 0x1b, 0x13, 0x1d, + 0x82, 0x09, 0xfc, 0x0d, 0x82, 0xcb, 0xe3, 0xaa, 0xc7, 0x2c, 0x66, 0x2d, 0x92, 0x4a, 0x1a, 0x90, + 0x83, 0x83, 0x9c, 0x0a, 0x51, 0x1e, 0x90, 0x65, 0xa5, 0x7f, 0xd5, 0xac, 0x3f, 0x68, 0xc3, 0xbb, + 0x25, 0x8f, 0xf6, 0xf7, 0x8b, 0x6f, 0x8f, 0x7a, 0xf8, 0xac, 0x27, 0xa1, 0x91, 0xc5, 0x21, 0xb2, + 0x7f, 0x44, 0xf0, 0x92, 0x61, 0x0d, 0xd8, 0x83, 0xa5, 0x23, 0xda, 0xd5, 0xf7, 0xc1, 0xeb, 0x33, + 0x65, 0x50, 0xec, 0xb7, 0x9e, 0x7c, 0x41, 0xc6, 0x0d, 0x58, 0x1b, 0x0a, 0x54, 0xf5, 0xb5, 0xea, + 0x0f, 0xbf, 0xc2, 0xeb, 0xb0, 0x9c, 0xe5, 0x9c, 0x1f, 0xea, 0x6e, 0x95, 0x0f, 0xb6, 0x07, 0x2f, + 0x9e, 0x5d, 0xb6, 0xc0, 0xb3, 0xf4, 0x80, 0x3e, 0x54, 0xbe, 0x9e, 0xf5, 0xcb, 0x07, 0x8c, 0xa1, + 0xa2, 0x5a, 0x5e, 0x0a, 0xa8, 0xdf, 0xf6, 0xb7, 0x08, 0x36, 0x9f, 0x92, 0x0f, 0xbe, 0x06, 0x55, + 0xd5, 0x01, 0x29, 0xf5, 0x46, 0xad, 0x7a, 0xb5, 0x3f, 0x1e, 0xed, 0xae, 0xeb, 0x43, 0xa1, 0x09, + 0xf7, 0x64, 0xce, 0xd2, 0xd8, 0x1f, 0x40, 0xf1, 0x1b, 0xb0, 0x9a, 0xd3, 0x8c, 0xe7, 0x05, 0x6d, + 0x71, 0x0a, 0xad, 0x8f, 0xdc, 0xfb, 0x6d, 0x19, 0x96, 0xd5, 0xf9, 0xc6, 0xdf, 0x21, 0x58, 0x29, + 0x47, 0x0a, 0xbe, 0x62, 0x4e, 0x75, 0x72, 0x92, 0xd5, 0x77, 0x67, 0x44, 0x97, 0xeb, 0xb3, 0x77, + 0xbe, 0xfa, 0xf3, 0xdf, 0x1f, 0x16, 0x6d, 0xdc, 0x70, 0xa7, 0x0c, 0x5b, 0xfc, 0x0b, 0x82, 0xe7, + 0x27, 0x26, 0x11, 0xbe, 0x3e, 0x45, 0xce, 0x34, 0xf9, 0xea, 0x6f, 0xce, 0x4f, 0xd4, 0x96, 0x77, + 0x95, 0xe5, 0x6d, 0x7c, 0xc9, 0x6c, 0xf9, 0x8b, 0xfe, 0xfd, 0xf2, 0x25, 0xfe, 0x19, 0x01, 0x9e, + 0x9c, 0x35, 0x78, 0x2e, 0xfd, 0xe1, 0x49, 0x58, 0xbf, 0x71, 0x0e, 0xa6, 0xb6, 0x7e, 0x51, 0x59, + 0xdf, 0xc4, 0x1b, 0x46, 0xeb, 0xf8, 0x57, 0x04, 0xcf, 0x8d, 0xdf, 0xee, 0xf8, 0xda, 0x14, 0x49, + 0xc3, 0x50, 0xaa, 0x5f, 0x9f, 0x9b, 0xa7, 0x8d, 0xde, 0x50, 0x46, 0xf7, 0x71, 0x73, 0xa6, 0x8c, + 0xdd, 0xc1, 0x25, 0x25, 0xbc, 0x8f, 0x1f, 0x9f, 0x58, 0xe8, 0xc9, 0x89, 0x85, 0xfe, 0x39, 0xb1, + 0xd0, 0xf7, 0xa7, 0xd6, 0xc2, 0x93, 0x53, 0x6b, 0xe1, 0xaf, 0x53, 0x6b, 0xe1, 0xf3, 0xab, 0x31, + 0x93, 0x49, 0x27, 0x74, 0x22, 0xde, 0xee, 0x95, 0x8d, 0x12, 0xc2, 0xd2, 0xbe, 0xc6, 0xc3, 0x31, + 0x15, 0xd9, 0xcd, 0xa8, 0x08, 0x57, 0xd4, 0x1f, 0xb7, 0xfd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, + 0x2e, 0xd4, 0x53, 0xae, 0xca, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -965,104 +1260,293 @@ func (m *QueryEpochSubmissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *BTCCheckpointInfoResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n +func (m *BTCCheckpointInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryBtcCheckpointInfoRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *BTCCheckpointInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.EpochNum != 0 { - n += 1 + sovQuery(uint64(m.EpochNum)) + if len(m.BestSubmissionVigilanteAddressList) > 0 { + for iNdEx := len(m.BestSubmissionVigilanteAddressList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BestSubmissionVigilanteAddressList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } } - return n -} - -func (m *QueryBtcCheckpointInfoResponse) Size() (n int) { - if m == nil { - return 0 + if len(m.BestSubmissionTransactions) > 0 { + for iNdEx := len(m.BestSubmissionTransactions) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BestSubmissionTransactions[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } } - var l int - _ = l - if m.Info != nil { - l = m.Info.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.BestSubmissionBtcBlockHash) > 0 { + i -= len(m.BestSubmissionBtcBlockHash) + copy(dAtA[i:], m.BestSubmissionBtcBlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BestSubmissionBtcBlockHash))) + i-- + dAtA[i] = 0x1a } - return n -} - -func (m *QueryBtcCheckpointsInfoRequest) Size() (n int) { - if m == nil { - return 0 + if m.BestSubmissionBtcBlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BestSubmissionBtcBlockHeight)) + i-- + dAtA[i] = 0x10 } - var l int - _ = l - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + if m.EpochNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x8 } - return n + return len(dAtA) - i, nil } -func (m *QueryBtcCheckpointsInfoResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.InfoList) > 0 { - for _, e := range m.InfoList { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) - } - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) +func (m *TransactionInfoResponse) 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 n + return dAtA[:n], nil } -func (m *QueryEpochSubmissionsRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *TransactionInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TransactionInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.EpochNum != 0 { - n += 1 + sovQuery(uint64(m.EpochNum)) + if len(m.Proof) > 0 { + i -= len(m.Proof) + copy(dAtA[i:], m.Proof) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Proof))) + i-- + dAtA[i] = 0x1a } - if m.Pagination != nil { + if len(m.Transaction) > 0 { + i -= len(m.Transaction) + copy(dAtA[i:], m.Transaction) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Transaction))) + i-- + dAtA[i] = 0x12 + } + if m.Key != nil { + { + size, err := m.Key.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *TransactionKeyResponse) 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 *TransactionKeyResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TransactionKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0x12 + } + if m.Index != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *CheckpointAddressesResponse) 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 *CheckpointAddressesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CheckpointAddressesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Reporter) > 0 { + i -= len(m.Reporter) + copy(dAtA[i:], m.Reporter) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Reporter))) + i-- + dAtA[i] = 0x12 + } + if len(m.Submitter) > 0 { + i -= len(m.Submitter) + copy(dAtA[i:], m.Submitter) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Submitter))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryBtcCheckpointInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNum != 0 { + n += 1 + sovQuery(uint64(m.EpochNum)) + } + return n +} + +func (m *QueryBtcCheckpointInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Info != nil { + l = m.Info.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryBtcCheckpointsInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryBtcCheckpointsInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.InfoList) > 0 { + for _, e := range m.InfoList { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryEpochSubmissionsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNum != 0 { + n += 1 + sovQuery(uint64(m.EpochNum)) + } + if m.Pagination != nil { l = m.Pagination.Size() n += 1 + l + sovQuery(uint64(l)) } @@ -1088,6 +1572,91 @@ func (m *QueryEpochSubmissionsResponse) Size() (n int) { return n } +func (m *BTCCheckpointInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNumber != 0 { + n += 1 + sovQuery(uint64(m.EpochNumber)) + } + if m.BestSubmissionBtcBlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BestSubmissionBtcBlockHeight)) + } + l = len(m.BestSubmissionBtcBlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.BestSubmissionTransactions) > 0 { + for _, e := range m.BestSubmissionTransactions { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if len(m.BestSubmissionVigilanteAddressList) > 0 { + for _, e := range m.BestSubmissionVigilanteAddressList { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *TransactionInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Key != nil { + l = m.Key.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Transaction) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Proof) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *TransactionKeyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != 0 { + n += 1 + sovQuery(uint64(m.Index)) + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *CheckpointAddressesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Submitter) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Reporter) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1355,7 +1924,7 @@ func (m *QueryBtcCheckpointInfoResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Info == nil { - m.Info = &BTCCheckpointInfo{} + m.Info = &BTCCheckpointInfoResponse{} } if err := m.Info.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1813,6 +2382,559 @@ func (m *QueryEpochSubmissionsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *BTCCheckpointInfoResponse) 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 ErrIntOverflowQuery + } + 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: BTCCheckpointInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCCheckpointInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BestSubmissionBtcBlockHeight", wireType) + } + m.BestSubmissionBtcBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BestSubmissionBtcBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BestSubmissionBtcBlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BestSubmissionBtcBlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BestSubmissionTransactions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BestSubmissionTransactions = append(m.BestSubmissionTransactions, &TransactionInfoResponse{}) + if err := m.BestSubmissionTransactions[len(m.BestSubmissionTransactions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BestSubmissionVigilanteAddressList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BestSubmissionVigilanteAddressList = append(m.BestSubmissionVigilanteAddressList, &CheckpointAddressesResponse{}) + if err := m.BestSubmissionVigilanteAddressList[len(m.BestSubmissionVigilanteAddressList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TransactionInfoResponse) 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 ErrIntOverflowQuery + } + 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: TransactionInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TransactionInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Key == nil { + m.Key = &TransactionKeyResponse{} + } + if err := m.Key.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Transaction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Transaction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Proof = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TransactionKeyResponse) 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 ErrIntOverflowQuery + } + 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: TransactionKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TransactionKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CheckpointAddressesResponse) 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 ErrIntOverflowQuery + } + 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: CheckpointAddressesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CheckpointAddressesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Submitter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Submitter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reporter", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reporter = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From cb758fb54bbf4fd730845138e6a7bb10a66c85ed Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 20 Feb 2024 09:08:38 -0300 Subject: [PATCH 010/119] fix: reduce TransactionKeyResponse struct and marshalHex when converting BTCHeaderHashBytes into hex --- client/docs/swagger-ui/swagger.yaml | 163 ++------- proto/babylon/btccheckpoint/v1/query.proto | 20 +- x/btccheckpoint/types/query.go | 13 +- x/btccheckpoint/types/query.pb.go | 370 +++++---------------- 4 files changed, 126 insertions(+), 440 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 843c8b9fa..4882e3b0b 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -356,38 +356,13 @@ paths: items: type: object properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx on - BTC blockchain - - Although it is already a part of SubmissionKey, we - store it here again - - to make TransactionInfo self-contained. - - For example, storing the key allows TransactionInfo - to not relay on - - the fact that TransactionInfo will be ordered in the - same order as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - description: Index Bitcoin Transaction index in block. - hash: - type: string - description: Hash BTC Header hash as hex. - title: >- - TransactionKeyResponse Each provided OP_RETURN - transaction can be idendtified by - - hash of block in which transaction was included and - transaction index in the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string description: transaction is the full transaction data as str hex. @@ -9692,38 +9667,13 @@ definitions: items: type: object properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx on BTC - blockchain - - Although it is already a part of SubmissionKey, we store it here - again - - to make TransactionInfo self-contained. - - For example, storing the key allows TransactionInfo to not relay - on - - the fact that TransactionInfo will be ordered in the same order - as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - description: Index Bitcoin Transaction index in block. - hash: - type: string - description: Hash BTC Header hash as hex. - title: >- - TransactionKeyResponse Each provided OP_RETURN transaction can - be idendtified by - - hash of block in which transaction was included and transaction - index in the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string description: transaction is the full transaction data as str hex. @@ -9879,38 +9829,13 @@ definitions: items: type: object properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx on BTC - blockchain - - Although it is already a part of SubmissionKey, we store it - here again - - to make TransactionInfo self-contained. - - For example, storing the key allows TransactionInfo to not - relay on - - the fact that TransactionInfo will be ordered in the same - order as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - description: Index Bitcoin Transaction index in block. - hash: - type: string - description: Hash BTC Header hash as hex. - title: >- - TransactionKeyResponse Each provided OP_RETURN transaction - can be idendtified by - - hash of block in which transaction was included and - transaction index in the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string description: transaction is the full transaction data as str hex. @@ -10310,29 +10235,13 @@ definitions: babylon.btccheckpoint.v1.TransactionInfoResponse: type: object properties: - key: - description: |- - key is the position (txIdx, blockHash) of this tx on BTC blockchain - Although it is already a part of SubmissionKey, we store it here again - to make TransactionInfo self-contained. - For example, storing the key allows TransactionInfo to not relay on - the fact that TransactionInfo will be ordered in the same order as - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - description: Index Bitcoin Transaction index in block. - hash: - type: string - description: Hash BTC Header hash as hex. - title: >- - TransactionKeyResponse Each provided OP_RETURN transaction can be - idendtified by - - hash of block in which transaction was included and transaction index - in the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string description: transaction is the full transaction data as str hex. @@ -10359,22 +10268,6 @@ definitions: title: |- Each provided OP_RETURN transaction can be idendtified by hash of block in which transaction was included and transaction index in the block - babylon.btccheckpoint.v1.TransactionKeyResponse: - type: object - properties: - index: - type: integer - format: int64 - description: Index Bitcoin Transaction index in block. - hash: - type: string - description: Hash BTC Header hash as hex. - title: >- - TransactionKeyResponse Each provided OP_RETURN transaction can be - idendtified by - - hash of block in which transaction was included and transaction index in - the block cosmos.base.query.v1beta1.PageRequest: type: object properties: diff --git a/proto/babylon/btccheckpoint/v1/query.proto b/proto/babylon/btccheckpoint/v1/query.proto index 6b8a9eb0c..f16974f00 100644 --- a/proto/babylon/btccheckpoint/v1/query.proto +++ b/proto/babylon/btccheckpoint/v1/query.proto @@ -113,26 +113,14 @@ message BTCCheckpointInfoResponse { // - the full tx content // - the Merkle proof that this tx is on the above position message TransactionInfoResponse { - // key is the position (txIdx, blockHash) of this tx on BTC blockchain - // Although it is already a part of SubmissionKey, we store it here again - // to make TransactionInfo self-contained. - // For example, storing the key allows TransactionInfo to not relay on - // the fact that TransactionInfo will be ordered in the same order as - // TransactionKeys in SubmissionKey. - TransactionKeyResponse key = 1; - // transaction is the full transaction data as str hex. - string transaction = 2; - // proof is the Merkle proof that this tx is included in the position in `key` - string proof = 3; -} - -// TransactionKeyResponse Each provided OP_RETURN transaction can be idendtified by -// hash of block in which transaction was included and transaction index in the block -message TransactionKeyResponse { // Index Bitcoin Transaction index in block. uint32 index = 1; // Hash BTC Header hash as hex. string hash = 2; + // transaction is the full transaction data as str hex. + string transaction = 3; + // proof is the Merkle proof that this tx is included in the position in `key` + string proof = 4; } // CheckpointAddressesResponse contains the addresses of the submitter and reporter of a diff --git a/x/btccheckpoint/types/query.go b/x/btccheckpoint/types/query.go index fb2276c8d..98263e8c5 100644 --- a/x/btccheckpoint/types/query.go +++ b/x/btccheckpoint/types/query.go @@ -9,20 +9,13 @@ import ( // ToResponse parses a TransactionInfo into a query response tx info struct. func (ti *TransactionInfo) ToResponse() *TransactionInfoResponse { return &TransactionInfoResponse{ - Key: ti.Key.ToResponse(), + Index: ti.Key.Index, + Hash: ti.Key.Hash.MarshalHex(), Transaction: hex.EncodeToString(ti.Transaction), Proof: hex.EncodeToString(ti.Proof), } } -// ToResponse parses a TransactionKeyResponse into a query response tx key struct. -func (tk *TransactionKey) ToResponse() *TransactionKeyResponse { - return &TransactionKeyResponse{ - Index: tk.Index, - Hash: hex.EncodeToString(*tk.Hash), - } -} - // ToResponse parses a CheckpointAddresses into a query response checkpoint addresses struct. func (ca *CheckpointAddresses) ToResponse() *CheckpointAddressesResponse { return &CheckpointAddressesResponse{ @@ -45,7 +38,7 @@ func (b BTCCheckpointInfo) ToResponse() *BTCCheckpointInfoResponse { return &BTCCheckpointInfoResponse{ EpochNumber: b.EpochNumber, BestSubmissionBtcBlockHeight: b.BestSubmissionBtcBlockHeight, - BestSubmissionBtcBlockHash: hex.EncodeToString(*b.BestSubmissionBtcBlockHash), + BestSubmissionBtcBlockHash: b.BestSubmissionBtcBlockHash.MarshalHex(), BestSubmissionTransactions: bestSubTxs, BestSubmissionVigilanteAddressList: bestSubVigAddrs, } diff --git a/x/btccheckpoint/types/query.pb.go b/x/btccheckpoint/types/query.pb.go index 81cde87e4..ad2e65a8a 100644 --- a/x/btccheckpoint/types/query.pb.go +++ b/x/btccheckpoint/types/query.pb.go @@ -510,17 +510,14 @@ func (m *BTCCheckpointInfoResponse) GetBestSubmissionVigilanteAddressList() []*C // - the full tx content // - the Merkle proof that this tx is on the above position type TransactionInfoResponse struct { - // key is the position (txIdx, blockHash) of this tx on BTC blockchain - // Although it is already a part of SubmissionKey, we store it here again - // to make TransactionInfo self-contained. - // For example, storing the key allows TransactionInfo to not relay on - // the fact that TransactionInfo will be ordered in the same order as - // TransactionKeys in SubmissionKey. - Key *TransactionKeyResponse `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // Index Bitcoin Transaction index in block. + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // Hash BTC Header hash as hex. + Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` // transaction is the full transaction data as str hex. - Transaction string `protobuf:"bytes,2,opt,name=transaction,proto3" json:"transaction,omitempty"` + Transaction string `protobuf:"bytes,3,opt,name=transaction,proto3" json:"transaction,omitempty"` // proof is the Merkle proof that this tx is included in the position in `key` - Proof string `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"` + Proof string `protobuf:"bytes,4,opt,name=proof,proto3" json:"proof,omitempty"` } func (m *TransactionInfoResponse) Reset() { *m = TransactionInfoResponse{} } @@ -556,79 +553,30 @@ func (m *TransactionInfoResponse) XXX_DiscardUnknown() { var xxx_messageInfo_TransactionInfoResponse proto.InternalMessageInfo -func (m *TransactionInfoResponse) GetKey() *TransactionKeyResponse { +func (m *TransactionInfoResponse) GetIndex() uint32 { if m != nil { - return m.Key + return m.Index } - return nil + return 0 } -func (m *TransactionInfoResponse) GetTransaction() string { +func (m *TransactionInfoResponse) GetHash() string { if m != nil { - return m.Transaction + return m.Hash } return "" } -func (m *TransactionInfoResponse) GetProof() string { +func (m *TransactionInfoResponse) GetTransaction() string { if m != nil { - return m.Proof + return m.Transaction } return "" } -// TransactionKeyResponse Each provided OP_RETURN transaction can be idendtified by -// hash of block in which transaction was included and transaction index in the block -type TransactionKeyResponse struct { - // Index Bitcoin Transaction index in block. - Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - // Hash BTC Header hash as hex. - Hash string `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` -} - -func (m *TransactionKeyResponse) Reset() { *m = TransactionKeyResponse{} } -func (m *TransactionKeyResponse) String() string { return proto.CompactTextString(m) } -func (*TransactionKeyResponse) ProtoMessage() {} -func (*TransactionKeyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_6b9a2f46ada7d854, []int{10} -} -func (m *TransactionKeyResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *TransactionKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_TransactionKeyResponse.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 *TransactionKeyResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_TransactionKeyResponse.Merge(m, src) -} -func (m *TransactionKeyResponse) XXX_Size() int { - return m.Size() -} -func (m *TransactionKeyResponse) XXX_DiscardUnknown() { - xxx_messageInfo_TransactionKeyResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_TransactionKeyResponse proto.InternalMessageInfo - -func (m *TransactionKeyResponse) GetIndex() uint32 { - if m != nil { - return m.Index - } - return 0 -} - -func (m *TransactionKeyResponse) GetHash() string { +func (m *TransactionInfoResponse) GetProof() string { if m != nil { - return m.Hash + return m.Proof } return "" } @@ -648,7 +596,7 @@ func (m *CheckpointAddressesResponse) Reset() { *m = CheckpointAddresses func (m *CheckpointAddressesResponse) String() string { return proto.CompactTextString(m) } func (*CheckpointAddressesResponse) ProtoMessage() {} func (*CheckpointAddressesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_6b9a2f46ada7d854, []int{11} + return fileDescriptor_6b9a2f46ada7d854, []int{10} } func (m *CheckpointAddressesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -702,7 +650,6 @@ func init() { proto.RegisterType((*QueryEpochSubmissionsResponse)(nil), "babylon.btccheckpoint.v1.QueryEpochSubmissionsResponse") proto.RegisterType((*BTCCheckpointInfoResponse)(nil), "babylon.btccheckpoint.v1.BTCCheckpointInfoResponse") proto.RegisterType((*TransactionInfoResponse)(nil), "babylon.btccheckpoint.v1.TransactionInfoResponse") - proto.RegisterType((*TransactionKeyResponse)(nil), "babylon.btccheckpoint.v1.TransactionKeyResponse") proto.RegisterType((*CheckpointAddressesResponse)(nil), "babylon.btccheckpoint.v1.CheckpointAddressesResponse") } @@ -711,65 +658,64 @@ func init() { } var fileDescriptor_6b9a2f46ada7d854 = []byte{ - // 920 bytes of a gzipped FileDescriptorProto + // 897 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xdc, 0x44, - 0x18, 0xcd, 0x24, 0x9b, 0x28, 0xfb, 0x05, 0x24, 0x18, 0x22, 0xd8, 0x6c, 0x82, 0xbb, 0xb5, 0x68, - 0x13, 0x41, 0x63, 0xb3, 0x09, 0x6d, 0xa9, 0x40, 0x48, 0xb8, 0xa2, 0x2d, 0x02, 0x41, 0x71, 0x0b, - 0x07, 0x2e, 0xd6, 0xd8, 0x99, 0xd8, 0xa3, 0xec, 0x7a, 0x5c, 0xcf, 0x6c, 0xd4, 0x15, 0xe2, 0x02, - 0x27, 0xc4, 0x01, 0x24, 0xc4, 0x9f, 0xc0, 0x8d, 0x63, 0xb9, 0x22, 0x71, 0xab, 0xc4, 0xa5, 0x82, - 0x0b, 0x27, 0x84, 0x12, 0xfe, 0x10, 0xe4, 0xf1, 0xec, 0xef, 0x4c, 0x77, 0x37, 0xe2, 0xb6, 0xb6, - 0xdf, 0xfb, 0xde, 0x9b, 0xf7, 0xcd, 0xcc, 0xb7, 0xf0, 0x4a, 0x48, 0xc2, 0x6e, 0x8b, 0xa7, 0x6e, - 0x28, 0xa3, 0x28, 0xa1, 0xd1, 0x51, 0xc6, 0x59, 0x2a, 0xdd, 0xe3, 0xa6, 0xfb, 0xa0, 0x43, 0xf3, - 0xae, 0x93, 0xe5, 0x5c, 0x72, 0x5c, 0xd3, 0x28, 0x67, 0x04, 0xe5, 0x1c, 0x37, 0xeb, 0xeb, 0x31, - 0x8f, 0xb9, 0x02, 0xb9, 0xc5, 0xaf, 0x12, 0x5f, 0xdf, 0x88, 0xb8, 0x68, 0x73, 0x11, 0x94, 0x1f, - 0xca, 0x07, 0xfd, 0x69, 0x2b, 0xe6, 0x3c, 0x6e, 0x51, 0x97, 0x64, 0xcc, 0x25, 0x69, 0xca, 0x25, - 0x91, 0x8c, 0xa7, 0xbd, 0xaf, 0xaf, 0x96, 0x58, 0x37, 0x24, 0x82, 0x96, 0x0e, 0xdc, 0xe3, 0x66, - 0x48, 0x25, 0x69, 0xba, 0x19, 0x89, 0x59, 0xaa, 0xc0, 0x1a, 0x7b, 0xc9, 0x68, 0x3d, 0x23, 0x39, - 0x69, 0xf7, 0x4a, 0x5e, 0x31, 0xc2, 0x46, 0x17, 0xa3, 0xd0, 0xf6, 0x3a, 0xe0, 0x4f, 0x0a, 0xd9, - 0xbb, 0xaa, 0x84, 0x4f, 0x1f, 0x74, 0xa8, 0x90, 0xf6, 0xa7, 0xf0, 0xc2, 0xc8, 0x5b, 0x91, 0xf1, - 0x54, 0x50, 0xfc, 0x0e, 0xac, 0x94, 0x52, 0x35, 0xd4, 0x40, 0x3b, 0x6b, 0x7b, 0x0d, 0xc7, 0x94, - 0x93, 0x53, 0x32, 0xbd, 0xca, 0xe3, 0xbf, 0x2f, 0x2c, 0xf8, 0x9a, 0x65, 0xbf, 0x0d, 0x2f, 0xab, - 0xb2, 0x9e, 0x8c, 0x6e, 0xf6, 0xd1, 0xef, 0xa7, 0x87, 0x5c, 0xeb, 0xe2, 0x4d, 0xa8, 0xd2, 0x8c, - 0x47, 0x49, 0x90, 0x76, 0xda, 0x4a, 0xa3, 0xe2, 0xaf, 0xaa, 0x17, 0x1f, 0x75, 0xda, 0x36, 0x03, - 0xcb, 0xc4, 0xd6, 0xfe, 0x6e, 0x43, 0x85, 0xa5, 0x87, 0x5c, 0xbb, 0xdb, 0x37, 0xbb, 0xf3, 0xee, - 0xdf, 0x3c, 0xbb, 0x84, 0xaf, 0x0a, 0xd8, 0xc9, 0x59, 0x52, 0x62, 0xd8, 0xe9, 0x2d, 0x80, 0x41, - 0x83, 0xb4, 0xe0, 0x65, 0x47, 0x77, 0xbe, 0xe8, 0xa6, 0x53, 0xee, 0x27, 0xdd, 0x4d, 0xe7, 0x2e, - 0x89, 0xa9, 0xe6, 0xfa, 0x43, 0x4c, 0xfb, 0x11, 0x82, 0x0b, 0x46, 0x29, 0xbd, 0xac, 0x3b, 0x50, - 0x2d, 0x5c, 0x05, 0x2d, 0x26, 0x64, 0x0d, 0x35, 0x96, 0x76, 0xd6, 0xf6, 0x5e, 0x9b, 0x67, 0x6d, - 0xab, 0x05, 0xfb, 0x43, 0x26, 0x24, 0xbe, 0x3d, 0xe2, 0x7a, 0x51, 0xb9, 0xde, 0x9e, 0xea, 0x5a, - 0x47, 0x33, 0x6c, 0xfb, 0x6b, 0x04, 0x5b, 0xca, 0xf6, 0x7b, 0x45, 0x77, 0xee, 0x75, 0xc2, 0x36, - 0x13, 0xa2, 0xd8, 0xd7, 0xb3, 0x74, 0x72, 0x2c, 0xbc, 0xc5, 0x73, 0x87, 0xf7, 0x13, 0xd2, 0x1b, - 0x6a, 0xd2, 0x85, 0x8e, 0xee, 0x2d, 0xa8, 0x1c, 0xd1, 0xae, 0xd0, 0xa9, 0x6d, 0x9b, 0x53, 0x1b, - 0x90, 0x3f, 0xa0, 0x5d, 0x5f, 0x91, 0xfe, 0xbf, 0xb4, 0x7e, 0x5f, 0x82, 0x0d, 0xe3, 0x96, 0xc3, - 0x17, 0xe1, 0x99, 0x7e, 0x54, 0x21, 0xcd, 0x75, 0x5a, 0x6b, 0xbd, 0xb4, 0x42, 0x9a, 0xe3, 0x5b, - 0xd0, 0x08, 0xa9, 0x90, 0x81, 0xe8, 0xbb, 0x0c, 0x42, 0x19, 0x05, 0x61, 0x8b, 0x47, 0x47, 0x41, - 0x42, 0x59, 0x9c, 0x48, 0xe5, 0xaf, 0xe2, 0x6f, 0x15, 0xb8, 0xc1, 0x62, 0x3c, 0x19, 0x79, 0x05, - 0xe8, 0x8e, 0xc2, 0x60, 0x0f, 0xac, 0xa7, 0xd4, 0x21, 0x22, 0xa9, 0x2d, 0x35, 0xd0, 0x4e, 0xd5, - 0xaf, 0x1b, 0xaa, 0x10, 0x91, 0x60, 0x01, 0x5b, 0xe3, 0x35, 0x64, 0x4e, 0x52, 0x41, 0x22, 0x75, - 0xb1, 0xd5, 0x2a, 0x2a, 0xea, 0xa6, 0x39, 0xea, 0xfb, 0x03, 0xf4, 0xc8, 0xd1, 0x1b, 0x13, 0x1d, - 0x82, 0x09, 0xfc, 0x0d, 0x82, 0xcb, 0xe3, 0xaa, 0xc7, 0x2c, 0x66, 0x2d, 0x92, 0x4a, 0x1a, 0x90, - 0x83, 0x83, 0x9c, 0x0a, 0x51, 0x1e, 0x90, 0x65, 0xa5, 0x7f, 0xd5, 0xac, 0x3f, 0x68, 0xc3, 0xbb, - 0x25, 0x8f, 0xf6, 0xf7, 0x8b, 0x6f, 0x8f, 0x7a, 0xf8, 0xac, 0x27, 0xa1, 0x91, 0xc5, 0x21, 0xb2, - 0x7f, 0x44, 0xf0, 0x92, 0x61, 0x0d, 0xd8, 0x83, 0xa5, 0x23, 0xda, 0xd5, 0xf7, 0xc1, 0xeb, 0x33, - 0x65, 0x50, 0xec, 0xb7, 0x9e, 0x7c, 0x41, 0xc6, 0x0d, 0x58, 0x1b, 0x0a, 0x54, 0xf5, 0xb5, 0xea, - 0x0f, 0xbf, 0xc2, 0xeb, 0xb0, 0x9c, 0xe5, 0x9c, 0x1f, 0xea, 0x6e, 0x95, 0x0f, 0xb6, 0x07, 0x2f, - 0x9e, 0x5d, 0xb6, 0xc0, 0xb3, 0xf4, 0x80, 0x3e, 0x54, 0xbe, 0x9e, 0xf5, 0xcb, 0x07, 0x8c, 0xa1, - 0xa2, 0x5a, 0x5e, 0x0a, 0xa8, 0xdf, 0xf6, 0xb7, 0x08, 0x36, 0x9f, 0x92, 0x0f, 0xbe, 0x06, 0x55, - 0xd5, 0x01, 0x29, 0xf5, 0x46, 0xad, 0x7a, 0xb5, 0x3f, 0x1e, 0xed, 0xae, 0xeb, 0x43, 0xa1, 0x09, - 0xf7, 0x64, 0xce, 0xd2, 0xd8, 0x1f, 0x40, 0xf1, 0x1b, 0xb0, 0x9a, 0xd3, 0x8c, 0xe7, 0x05, 0x6d, - 0x71, 0x0a, 0xad, 0x8f, 0xdc, 0xfb, 0x6d, 0x19, 0x96, 0xd5, 0xf9, 0xc6, 0xdf, 0x21, 0x58, 0x29, - 0x47, 0x0a, 0xbe, 0x62, 0x4e, 0x75, 0x72, 0x92, 0xd5, 0x77, 0x67, 0x44, 0x97, 0xeb, 0xb3, 0x77, - 0xbe, 0xfa, 0xf3, 0xdf, 0x1f, 0x16, 0x6d, 0xdc, 0x70, 0xa7, 0x0c, 0x5b, 0xfc, 0x0b, 0x82, 0xe7, - 0x27, 0x26, 0x11, 0xbe, 0x3e, 0x45, 0xce, 0x34, 0xf9, 0xea, 0x6f, 0xce, 0x4f, 0xd4, 0x96, 0x77, - 0x95, 0xe5, 0x6d, 0x7c, 0xc9, 0x6c, 0xf9, 0x8b, 0xfe, 0xfd, 0xf2, 0x25, 0xfe, 0x19, 0x01, 0x9e, - 0x9c, 0x35, 0x78, 0x2e, 0xfd, 0xe1, 0x49, 0x58, 0xbf, 0x71, 0x0e, 0xa6, 0xb6, 0x7e, 0x51, 0x59, - 0xdf, 0xc4, 0x1b, 0x46, 0xeb, 0xf8, 0x57, 0x04, 0xcf, 0x8d, 0xdf, 0xee, 0xf8, 0xda, 0x14, 0x49, - 0xc3, 0x50, 0xaa, 0x5f, 0x9f, 0x9b, 0xa7, 0x8d, 0xde, 0x50, 0x46, 0xf7, 0x71, 0x73, 0xa6, 0x8c, - 0xdd, 0xc1, 0x25, 0x25, 0xbc, 0x8f, 0x1f, 0x9f, 0x58, 0xe8, 0xc9, 0x89, 0x85, 0xfe, 0x39, 0xb1, - 0xd0, 0xf7, 0xa7, 0xd6, 0xc2, 0x93, 0x53, 0x6b, 0xe1, 0xaf, 0x53, 0x6b, 0xe1, 0xf3, 0xab, 0x31, - 0x93, 0x49, 0x27, 0x74, 0x22, 0xde, 0xee, 0x95, 0x8d, 0x12, 0xc2, 0xd2, 0xbe, 0xc6, 0xc3, 0x31, - 0x15, 0xd9, 0xcd, 0xa8, 0x08, 0x57, 0xd4, 0x1f, 0xb7, 0xfd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, - 0x2e, 0xd4, 0x53, 0xae, 0xca, 0x0a, 0x00, 0x00, + 0x18, 0xcd, 0x6c, 0x9c, 0x28, 0xfb, 0x05, 0x24, 0x18, 0x22, 0xb1, 0xd9, 0x04, 0x77, 0x6b, 0xd1, + 0x26, 0x82, 0xc6, 0xd6, 0x26, 0xb4, 0xa5, 0x02, 0x21, 0xe1, 0x8a, 0xb6, 0x08, 0x04, 0xc5, 0x2d, + 0x1c, 0xb8, 0x58, 0x63, 0x67, 0x62, 0x8f, 0xb2, 0xeb, 0x71, 0x3d, 0xb3, 0x51, 0x57, 0x15, 0x17, + 0x38, 0x21, 0x0e, 0x20, 0xf1, 0x37, 0x70, 0xe3, 0x58, 0xae, 0x48, 0xdc, 0x2a, 0x71, 0xa9, 0xe0, + 0xc2, 0x09, 0xa1, 0x84, 0x3f, 0x04, 0x79, 0x3c, 0xfb, 0x33, 0x9d, 0x6e, 0x36, 0xe2, 0xb6, 0xb6, + 0xdf, 0xfb, 0xde, 0x9b, 0xf7, 0xcd, 0xcc, 0xb7, 0xf0, 0x7a, 0x44, 0xa2, 0x7e, 0x87, 0x67, 0x5e, + 0x24, 0xe3, 0x38, 0xa5, 0xf1, 0x61, 0xce, 0x59, 0x26, 0xbd, 0xa3, 0xb6, 0xf7, 0xa0, 0x47, 0x8b, + 0xbe, 0x9b, 0x17, 0x5c, 0x72, 0xdc, 0xd0, 0x28, 0x77, 0x02, 0xe5, 0x1e, 0xb5, 0x9b, 0x6b, 0x09, + 0x4f, 0xb8, 0x02, 0x79, 0xe5, 0xaf, 0x0a, 0xdf, 0x5c, 0x8f, 0xb9, 0xe8, 0x72, 0x11, 0x56, 0x1f, + 0xaa, 0x07, 0xfd, 0x69, 0x33, 0xe1, 0x3c, 0xe9, 0x50, 0x8f, 0xe4, 0xcc, 0x23, 0x59, 0xc6, 0x25, + 0x91, 0x8c, 0x67, 0x83, 0xaf, 0x6f, 0x54, 0x58, 0x2f, 0x22, 0x82, 0x56, 0x0e, 0xbc, 0xa3, 0x76, + 0x44, 0x25, 0x69, 0x7b, 0x39, 0x49, 0x58, 0xa6, 0xc0, 0x1a, 0x7b, 0xc9, 0x68, 0x3d, 0x27, 0x05, + 0xe9, 0x0e, 0x4a, 0x5e, 0x31, 0xc2, 0x26, 0x17, 0xa3, 0xd0, 0xce, 0x1a, 0xe0, 0xcf, 0x4a, 0xd9, + 0xbb, 0xaa, 0x44, 0x40, 0x1f, 0xf4, 0xa8, 0x90, 0xce, 0xe7, 0xf0, 0xca, 0xc4, 0x5b, 0x91, 0xf3, + 0x4c, 0x50, 0xfc, 0x1e, 0x2c, 0x57, 0x52, 0x0d, 0xd4, 0x42, 0xdb, 0xab, 0xbb, 0x2d, 0xd7, 0x94, + 0x93, 0x5b, 0x31, 0x7d, 0xeb, 0xc9, 0xdf, 0x17, 0x16, 0x02, 0xcd, 0x72, 0xde, 0x85, 0xd7, 0x54, + 0x59, 0x5f, 0xc6, 0x37, 0x87, 0xe8, 0x0f, 0xb3, 0x03, 0xae, 0x75, 0xf1, 0x06, 0xd4, 0x69, 0xce, + 0xe3, 0x34, 0xcc, 0x7a, 0x5d, 0xa5, 0x61, 0x05, 0x2b, 0xea, 0xc5, 0x27, 0xbd, 0xae, 0xc3, 0xc0, + 0x36, 0xb1, 0xb5, 0xbf, 0xdb, 0x60, 0xb1, 0xec, 0x80, 0x6b, 0x77, 0x7b, 0x66, 0x77, 0xfe, 0xfd, + 0x9b, 0xcf, 0x2e, 0x11, 0xa8, 0x02, 0x4e, 0xfa, 0x2c, 0x29, 0x31, 0xee, 0xf4, 0x16, 0xc0, 0xa8, + 0x41, 0x5a, 0xf0, 0xb2, 0xab, 0x3b, 0x5f, 0x76, 0xd3, 0xad, 0xf6, 0x93, 0xee, 0xa6, 0x7b, 0x97, + 0x24, 0x54, 0x73, 0x83, 0x31, 0xa6, 0xf3, 0x18, 0xc1, 0x05, 0xa3, 0x94, 0x5e, 0xd6, 0x1d, 0xa8, + 0x97, 0xae, 0xc2, 0x0e, 0x13, 0xb2, 0x81, 0x5a, 0x8b, 0xdb, 0xab, 0xbb, 0x6f, 0xce, 0xb3, 0xb6, + 0x95, 0x92, 0xfd, 0x31, 0x13, 0x12, 0xdf, 0x9e, 0x70, 0x5d, 0x53, 0xae, 0xb7, 0x66, 0xba, 0xd6, + 0xd1, 0x8c, 0xdb, 0xfe, 0x06, 0xc1, 0xa6, 0xb2, 0xfd, 0x41, 0xd9, 0x9d, 0x7b, 0xbd, 0xa8, 0xcb, + 0x84, 0x28, 0xf7, 0xf5, 0x59, 0x3a, 0x39, 0x15, 0x5e, 0xed, 0xdc, 0xe1, 0xfd, 0x84, 0xf4, 0x86, + 0x3a, 0xed, 0x42, 0x47, 0xf7, 0x0e, 0x58, 0x87, 0xb4, 0x2f, 0x74, 0x6a, 0x5b, 0xe6, 0xd4, 0x46, + 0xe4, 0x8f, 0x68, 0x3f, 0x50, 0xa4, 0xff, 0x2f, 0xad, 0xdf, 0x17, 0x61, 0xdd, 0xb8, 0xe5, 0xf0, + 0x45, 0x78, 0x61, 0x18, 0x55, 0x44, 0x0b, 0x9d, 0xd6, 0xea, 0x20, 0xad, 0x88, 0x16, 0xf8, 0x16, + 0xb4, 0x22, 0x2a, 0x64, 0x28, 0x86, 0x2e, 0xc3, 0x48, 0xc6, 0x61, 0xd4, 0xe1, 0xf1, 0x61, 0x98, + 0x52, 0x96, 0xa4, 0x52, 0xf9, 0xb3, 0x82, 0xcd, 0x12, 0x37, 0x5a, 0x8c, 0x2f, 0x63, 0xbf, 0x04, + 0xdd, 0x51, 0x18, 0xec, 0x83, 0xfd, 0x9c, 0x3a, 0x44, 0xa4, 0x8d, 0xc5, 0x16, 0xda, 0xae, 0x07, + 0x4d, 0x43, 0x15, 0x22, 0x52, 0x2c, 0x60, 0x73, 0xba, 0x86, 0x2c, 0x48, 0x26, 0x48, 0xac, 0x2e, + 0xb6, 0x86, 0xa5, 0xa2, 0x6e, 0x9b, 0xa3, 0xbe, 0x3f, 0x42, 0x4f, 0x1c, 0xbd, 0x29, 0xd1, 0x31, + 0x98, 0xc0, 0xdf, 0x22, 0xb8, 0x3c, 0xad, 0x7a, 0xc4, 0x12, 0xd6, 0x21, 0x99, 0xa4, 0x21, 0xd9, + 0xdf, 0x2f, 0xa8, 0x10, 0xd5, 0x01, 0x59, 0x52, 0xfa, 0x57, 0xcd, 0xfa, 0xa3, 0x36, 0xbc, 0x5f, + 0xf1, 0xe8, 0x70, 0xbf, 0x04, 0xce, 0xa4, 0x87, 0x2f, 0x06, 0x12, 0x1a, 0x59, 0x1e, 0x22, 0xe7, + 0x11, 0xbc, 0x6a, 0x58, 0x02, 0x5e, 0x83, 0x25, 0x96, 0xed, 0xd3, 0x87, 0xaa, 0x87, 0x2f, 0x06, + 0xd5, 0x03, 0xc6, 0x60, 0xa9, 0x6c, 0x6b, 0x2a, 0x5b, 0xf5, 0x1b, 0xb7, 0x60, 0x75, 0x2c, 0x35, + 0x1d, 0xfb, 0xf8, 0xab, 0xb2, 0x56, 0x5e, 0x70, 0x7e, 0xd0, 0xb0, 0xd4, 0xb7, 0xea, 0xc1, 0xf9, + 0x0e, 0xc1, 0xc6, 0x73, 0x16, 0x80, 0xaf, 0x41, 0x5d, 0x45, 0x24, 0xa5, 0xde, 0x49, 0x75, 0xbf, + 0xf1, 0xc7, 0xe3, 0x9d, 0x35, 0xbd, 0x6b, 0x35, 0xe1, 0x9e, 0x2c, 0x58, 0x96, 0x04, 0x23, 0x28, + 0x7e, 0x0b, 0x56, 0x0a, 0x9a, 0xf3, 0xa2, 0xa4, 0xd5, 0x66, 0xd0, 0x86, 0xc8, 0xdd, 0xdf, 0x96, + 0x60, 0x49, 0x1d, 0x40, 0xfc, 0x3d, 0x82, 0xe5, 0xea, 0xce, 0xc7, 0x57, 0xcc, 0xd1, 0x9f, 0x1e, + 0x35, 0xcd, 0x9d, 0x33, 0xa2, 0xab, 0xf5, 0x39, 0xdb, 0x5f, 0xff, 0xf9, 0xef, 0x8f, 0x35, 0x07, + 0xb7, 0xbc, 0x19, 0xd3, 0x10, 0xff, 0x82, 0xe0, 0xe5, 0x53, 0xa3, 0x02, 0x5f, 0x9f, 0x21, 0x67, + 0x1a, 0x4d, 0xcd, 0xb7, 0xe7, 0x27, 0x6a, 0xcb, 0x3b, 0xca, 0xf2, 0x16, 0xbe, 0x64, 0xb6, 0xfc, + 0x68, 0x78, 0x01, 0x7c, 0x85, 0x7f, 0x46, 0x80, 0x4f, 0x0f, 0x03, 0x3c, 0x97, 0xfe, 0xf8, 0xa8, + 0x6a, 0xde, 0x38, 0x07, 0x53, 0x5b, 0xbf, 0xa8, 0xac, 0x6f, 0xe0, 0x75, 0xa3, 0x75, 0xfc, 0x2b, + 0x82, 0x97, 0xa6, 0xaf, 0x5f, 0x7c, 0x6d, 0x86, 0xa4, 0x61, 0x6a, 0x34, 0xaf, 0xcf, 0xcd, 0xd3, + 0x46, 0x6f, 0x28, 0xa3, 0x7b, 0xb8, 0x7d, 0xa6, 0x8c, 0xbd, 0xd1, 0x2d, 0x22, 0xfc, 0x4f, 0x9f, + 0x1c, 0xdb, 0xe8, 0xe9, 0xb1, 0x8d, 0xfe, 0x39, 0xb6, 0xd1, 0x0f, 0x27, 0xf6, 0xc2, 0xd3, 0x13, + 0x7b, 0xe1, 0xaf, 0x13, 0x7b, 0xe1, 0xcb, 0xab, 0x09, 0x93, 0x69, 0x2f, 0x72, 0x63, 0xde, 0x1d, + 0x94, 0x8d, 0x53, 0xc2, 0xb2, 0xa1, 0xc6, 0xc3, 0x29, 0x15, 0xd9, 0xcf, 0xa9, 0x88, 0x96, 0xd5, + 0x3f, 0xab, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x77, 0xc9, 0xbe, 0x6b, 0x0a, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1353,50 +1299,15 @@ func (m *TransactionInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) copy(dAtA[i:], m.Proof) i = encodeVarintQuery(dAtA, i, uint64(len(m.Proof))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } if len(m.Transaction) > 0 { i -= len(m.Transaction) copy(dAtA[i:], m.Transaction) i = encodeVarintQuery(dAtA, i, uint64(len(m.Transaction))) i-- - dAtA[i] = 0x12 - } - if m.Key != nil { - { - size, err := m.Key.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *TransactionKeyResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err + dAtA[i] = 0x1a } - return dAtA[:n], nil -} - -func (m *TransactionKeyResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *TransactionKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l if len(m.Hash) > 0 { i -= len(m.Hash) copy(dAtA[i:], m.Hash) @@ -1609,31 +1520,18 @@ func (m *TransactionInfoResponse) Size() (n int) { } var l int _ = l - if m.Key != nil { - l = m.Key.Size() - n += 1 + l + sovQuery(uint64(l)) + if m.Index != 0 { + n += 1 + sovQuery(uint64(m.Index)) } - l = len(m.Transaction) + l = len(m.Hash) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - l = len(m.Proof) + l = len(m.Transaction) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - return n -} - -func (m *TransactionKeyResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Index != 0 { - n += 1 + sovQuery(uint64(m.Index)) - } - l = len(m.Hash) + l = len(m.Proof) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } @@ -2600,10 +2498,10 @@ func (m *TransactionInfoResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) } - var msglen int + m.Index = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2613,31 +2511,14 @@ func (m *TransactionInfoResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.Index |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Key == nil { - m.Key = &TransactionKeyResponse{} - } - if err := m.Key.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Transaction", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2665,11 +2546,11 @@ func (m *TransactionInfoResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Transaction = string(dAtA[iNdEx:postIndex]) + m.Hash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Transaction", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2697,80 +2578,11 @@ func (m *TransactionInfoResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Proof = string(dAtA[iNdEx:postIndex]) + m.Transaction = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *TransactionKeyResponse) 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 ErrIntOverflowQuery - } - 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: TransactionKeyResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TransactionKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) - } - m.Index = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Index |= uint32(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2798,7 +2610,7 @@ func (m *TransactionKeyResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Hash = string(dAtA[iNdEx:postIndex]) + m.Proof = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex From 2c4bdbb1d7c969c1780b0c6919e46c241300727c Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Tue, 20 Feb 2024 18:05:29 -0300 Subject: [PATCH 011/119] feat: add test for BtcCheckpointInfo grpc query --- x/btccheckpoint/keeper/grpc_query_test.go | 72 +++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 x/btccheckpoint/keeper/grpc_query_test.go diff --git a/x/btccheckpoint/keeper/grpc_query_test.go b/x/btccheckpoint/keeper/grpc_query_test.go new file mode 100644 index 000000000..36c390db4 --- /dev/null +++ b/x/btccheckpoint/keeper/grpc_query_test.go @@ -0,0 +1,72 @@ +package keeper_test + +import ( + "encoding/hex" + "math/rand" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + dg "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/x/btccheckpoint/types" +) + +func TestBtcCheckpointInfo(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + epoch := uint64(1) + raw, btcRaw := dg.RandomRawCheckpointDataForEpoch(r, epoch) + + blck1BabylonOpReturnIdx, blck2BabylonOpReturnIdx := uint32(7), uint32(3) + blck1 := dg.CreateBlock(r, 1, 7, blck1BabylonOpReturnIdx, raw.FirstPart) + blck2 := dg.CreateBlock(r, 2, 14, blck2BabylonOpReturnIdx, raw.SecondPart) + + tk := InitTestKeepers(t) + + blockResults := []*dg.BlockCreationResult{blck1, blck2} + proofs := dg.BlockCreationResultToProofs(blockResults) + msg := dg.GenerateMessageWithRandomSubmitter(blockResults) + + // Now we will return depth enough for moving submission to be submitted + tk.BTCLightClient.SetDepth(blck1.HeaderBytes.Hash(), uint64(1)) + tk.BTCLightClient.SetDepth(blck2.HeaderBytes.Hash(), uint64(1)) + + _, err := tk.insertProofMsg(msg) + require.NoErrorf(t, err, "Unexpected message processing error: %v", err) + + // test the GRPC client call. + resp, err := tk.BTCCheckpoint.BtcCheckpointInfo(tk.SdkCtx, &types.QueryBtcCheckpointInfoRequest{EpochNum: epoch}) + require.NoErrorf(t, err, "Unexpected message processing error: %v", err) + + // gather info for verifying with response. + btcInfo := resp.Info + blkHeight, err := tk.BTCLightClient.BlockHeight(tk.Ctx, nil) + require.NoErrorf(t, err, "Unexpected message processing error: %v", err) + + rawSubmission, err := types.ParseSubmission(msg, tk.BTCCheckpoint.GetPowLimit(), tk.BTCCheckpoint.GetExpectedTag(tk.SdkCtx)) + require.NoErrorf(t, err, "Unexpected message processing error: %v", err) + blk1 := rawSubmission.GetFirstBlockHash() + blk2 := rawSubmission.GetSecondBlockHash() + + require.Equal(t, btcInfo.EpochNumber, epoch) + require.Equal(t, btcInfo.BestSubmissionBtcBlockHeight, blkHeight) + require.Equal(t, btcInfo.BestSubmissionBtcBlockHash, blk1.MarshalHex()) + + require.Equal(t, len(btcInfo.BestSubmissionTransactions), 2) + tx0 := btcInfo.BestSubmissionTransactions[0] + require.Equal(t, tx0.Index, blck1BabylonOpReturnIdx) + require.Equal(t, tx0.Hash, blk1.MarshalHex()) + require.Equal(t, tx0.Transaction, blck1.Transactions[blck1BabylonOpReturnIdx]) + require.Equal(t, tx0.Proof, hex.EncodeToString(proofs[0].MerkleNodes)) + + tx1 := btcInfo.BestSubmissionTransactions[1] + require.Equal(t, tx1.Index, blck2BabylonOpReturnIdx) + require.Equal(t, tx1.Hash, blk2.MarshalHex()) + require.Equal(t, tx1.Transaction, blck2.Transactions[blck2BabylonOpReturnIdx]) + require.Equal(t, tx1.Proof, hex.EncodeToString(proofs[1].MerkleNodes)) + + require.Equal(t, len(btcInfo.BestSubmissionVigilanteAddressList), 1) + require.Equal(t, btcInfo.BestSubmissionVigilanteAddressList[0].Reporter, rawSubmission.Reporter.String()) + require.Equal(t, btcInfo.BestSubmissionVigilanteAddressList[0].Submitter, sdk.AccAddress(btcRaw.SubmitterAddress).String()) +} From 7a8552a4ed618e0762a794771f9df95f54db28f1 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 16 Feb 2024 13:39:37 +0100 Subject: [PATCH 012/119] Setup a test suite for testing proposals --- testutil/mocks/proposal_keeper.go | 140 ++++++ x/checkpointing/proposal.go | 16 +- x/checkpointing/proposal_expected_keeper.go | 21 + x/checkpointing/proposal_test.go | 479 ++++++++++++++++++++ 4 files changed, 649 insertions(+), 7 deletions(-) create mode 100644 testutil/mocks/proposal_keeper.go create mode 100644 x/checkpointing/proposal_expected_keeper.go create mode 100644 x/checkpointing/proposal_test.go diff --git a/testutil/mocks/proposal_keeper.go b/testutil/mocks/proposal_keeper.go new file mode 100644 index 000000000..89becc9ea --- /dev/null +++ b/testutil/mocks/proposal_keeper.go @@ -0,0 +1,140 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/checkpointing/proposal_expected_keeper.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + reflect "reflect" + + bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + types "github.com/babylonchain/babylon/x/checkpointing/types" + types0 "github.com/babylonchain/babylon/x/epoching/types" + crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + types1 "github.com/cosmos/cosmos-sdk/types" + gomock "github.com/golang/mock/gomock" +) + +// MockCheckpointingKeeper is a mock of CheckpointingKeeper interface. +type MockCheckpointingKeeper struct { + ctrl *gomock.Controller + recorder *MockCheckpointingKeeperMockRecorder +} + +// MockCheckpointingKeeperMockRecorder is the mock recorder for MockCheckpointingKeeper. +type MockCheckpointingKeeperMockRecorder struct { + mock *MockCheckpointingKeeper +} + +// NewMockCheckpointingKeeper creates a new mock instance. +func NewMockCheckpointingKeeper(ctrl *gomock.Controller) *MockCheckpointingKeeper { + mock := &MockCheckpointingKeeper{ctrl: ctrl} + mock.recorder = &MockCheckpointingKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCheckpointingKeeper) EXPECT() *MockCheckpointingKeeperMockRecorder { + return m.recorder +} + +// GetBlsPubKey mocks base method. +func (m *MockCheckpointingKeeper) GetBlsPubKey(ctx context.Context, address types1.ValAddress) (bls12381.PublicKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlsPubKey", ctx, address) + ret0, _ := ret[0].(bls12381.PublicKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetBlsPubKey indicates an expected call of GetBlsPubKey. +func (mr *MockCheckpointingKeeperMockRecorder) GetBlsPubKey(ctx, address interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlsPubKey", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetBlsPubKey), ctx, address) +} + +// GetEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetEpoch(ctx context.Context) *types0.Epoch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEpoch", ctx) + ret0, _ := ret[0].(*types0.Epoch) + return ret0 +} + +// GetEpoch indicates an expected call of GetEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetEpoch), ctx) +} + +// GetPubKeyByConsAddr mocks base method. +func (m *MockCheckpointingKeeper) GetPubKeyByConsAddr(arg0 context.Context, arg1 types1.ConsAddress) (crypto.PublicKey, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPubKeyByConsAddr", arg0, arg1) + ret0, _ := ret[0].(crypto.PublicKey) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetPubKeyByConsAddr indicates an expected call of GetPubKeyByConsAddr. +func (mr *MockCheckpointingKeeperMockRecorder) GetPubKeyByConsAddr(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPubKeyByConsAddr", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetPubKeyByConsAddr), arg0, arg1) +} + +// GetTotalVotingPower mocks base method. +func (m *MockCheckpointingKeeper) GetTotalVotingPower(ctx context.Context, epochNumber uint64) int64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTotalVotingPower", ctx, epochNumber) + ret0, _ := ret[0].(int64) + return ret0 +} + +// GetTotalVotingPower indicates an expected call of GetTotalVotingPower. +func (mr *MockCheckpointingKeeperMockRecorder) GetTotalVotingPower(ctx, epochNumber interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTotalVotingPower", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetTotalVotingPower), ctx, epochNumber) +} + +// GetValidatorSet mocks base method. +func (m *MockCheckpointingKeeper) GetValidatorSet(ctx context.Context, epochNumber uint64) types0.ValidatorSet { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetValidatorSet", ctx, epochNumber) + ret0, _ := ret[0].(types0.ValidatorSet) + return ret0 +} + +// GetValidatorSet indicates an expected call of GetValidatorSet. +func (mr *MockCheckpointingKeeperMockRecorder) GetValidatorSet(ctx, epochNumber interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValidatorSet", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetValidatorSet), ctx, epochNumber) +} + +// SealCheckpoint mocks base method. +func (m *MockCheckpointingKeeper) SealCheckpoint(ctx context.Context, ckptWithMeta *types.RawCheckpointWithMeta) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SealCheckpoint", ctx, ckptWithMeta) + ret0, _ := ret[0].(error) + return ret0 +} + +// SealCheckpoint indicates an expected call of SealCheckpoint. +func (mr *MockCheckpointingKeeperMockRecorder) SealCheckpoint(ctx, ckptWithMeta interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SealCheckpoint", reflect.TypeOf((*MockCheckpointingKeeper)(nil).SealCheckpoint), ctx, ckptWithMeta) +} + +// VerifyBLSSig mocks base method. +func (m *MockCheckpointingKeeper) VerifyBLSSig(ctx context.Context, sig *types.BlsSig) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "VerifyBLSSig", ctx, sig) + ret0, _ := ret[0].(error) + return ret0 +} + +// VerifyBLSSig indicates an expected call of VerifyBLSSig. +func (mr *MockCheckpointingKeeperMockRecorder) VerifyBLSSig(ctx, sig interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VerifyBLSSig", reflect.TypeOf((*MockCheckpointingKeeper)(nil).VerifyBLSSig), ctx, sig) +} diff --git a/x/checkpointing/proposal.go b/x/checkpointing/proposal.go index 9812099b8..6947098a1 100644 --- a/x/checkpointing/proposal.go +++ b/x/checkpointing/proposal.go @@ -12,7 +12,6 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/checkpointing/keeper" ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" ) @@ -20,19 +19,22 @@ const defaultInjectedTxIndex = 0 type ProposalHandler struct { logger log.Logger - ckptKeeper *keeper.Keeper - valStore baseapp.ValidatorStore + ckptKeeper CheckpointingKeeper txVerifier baseapp.ProposalTxVerifier defaultPrepareProposalHandler sdk.PrepareProposalHandler defaultProcessProposalHandler sdk.ProcessProposalHandler } -func NewProposalHandler(logger log.Logger, ckptKeeper *keeper.Keeper, mp mempool.Mempool, txVerifier baseapp.ProposalTxVerifier) *ProposalHandler { +func NewProposalHandler( + logger log.Logger, + ckptKeeper CheckpointingKeeper, + mp mempool.Mempool, + txVerifier baseapp.ProposalTxVerifier, +) *ProposalHandler { defaultHandler := baseapp.NewDefaultProposalHandler(mp, txVerifier) return &ProposalHandler{ logger: logger, ckptKeeper: ckptKeeper, - valStore: ckptKeeper, txVerifier: txVerifier, defaultPrepareProposalHandler: defaultHandler.PrepareProposalHandler(), defaultProcessProposalHandler: defaultHandler.ProcessProposalHandler(), @@ -75,7 +77,7 @@ func (h *ProposalHandler) PrepareProposal() sdk.PrepareProposalHandler { } // 1. verify the validity of vote extensions (2/3 majority is achieved) - err = baseapp.ValidateVoteExtensions(ctx, h.valStore, req.Height, ctx.ChainID(), req.LocalLastCommit) + err = baseapp.ValidateVoteExtensions(ctx, h.ckptKeeper, req.Height, ctx.ChainID(), req.LocalLastCommit) if err != nil { return proposalRes, fmt.Errorf("invalid vote extensions: %w", err) } @@ -276,7 +278,7 @@ func (h *ProposalHandler) ProcessProposal() sdk.ProcessProposalHandler { } // 3. verify the validity of the vote extension (2/3 majority is achieved) - err = baseapp.ValidateVoteExtensions(ctx, h.valStore, req.Height, ctx.ChainID(), *injectedCkpt.ExtendedCommitInfo) + err = baseapp.ValidateVoteExtensions(ctx, h.ckptKeeper, req.Height, ctx.ChainID(), *injectedCkpt.ExtendedCommitInfo) if err != nil { // the returned err will lead to panic as something very wrong happened during consensus return resReject, err diff --git a/x/checkpointing/proposal_expected_keeper.go b/x/checkpointing/proposal_expected_keeper.go new file mode 100644 index 000000000..920c2eeb2 --- /dev/null +++ b/x/checkpointing/proposal_expected_keeper.go @@ -0,0 +1,21 @@ +package checkpointing + +import ( + "context" + + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type CheckpointingKeeper interface { + GetPubKeyByConsAddr(context.Context, sdk.ConsAddress) (cmtprotocrypto.PublicKey, error) + GetEpoch(ctx context.Context) *epochingtypes.Epoch + GetValidatorSet(ctx context.Context, epochNumber uint64) epochingtypes.ValidatorSet + GetTotalVotingPower(ctx context.Context, epochNumber uint64) int64 + GetBlsPubKey(ctx context.Context, address sdk.ValAddress) (bls12381.PublicKey, error) + VerifyBLSSig(ctx context.Context, sig *types.BlsSig) error + SealCheckpoint(ctx context.Context, ckptWithMeta *types.RawCheckpointWithMeta) error +} diff --git a/x/checkpointing/proposal_test.go b/x/checkpointing/proposal_test.go new file mode 100644 index 000000000..2d0627917 --- /dev/null +++ b/x/checkpointing/proposal_test.go @@ -0,0 +1,479 @@ +package checkpointing_test + +import ( + "bytes" + "fmt" + "math/rand" + "sort" + + "time" + + "testing" + + "cosmossdk.io/core/header" + "cosmossdk.io/log" + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/mocks" + "github.com/babylonchain/babylon/x/checkpointing" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + et "github.com/babylonchain/babylon/x/epoching/types" + cbftt "github.com/cometbft/cometbft/abci/types" + cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" + tendermintTypes "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/mempool" + protoio "github.com/cosmos/gogoproto/io" + "github.com/cosmos/gogoproto/proto" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +type TestValidator struct { + Keys *datagen.GenesisKeyWithBLS + Power int64 +} + +func (v *TestValidator) CometValidator() *cbftt.Validator { + return &cbftt.Validator{ + Address: v.Keys.GenesisKey.ValPubkey.Address(), + Power: v.Power, + } +} + +func (v *TestValidator) EpochingValidator() et.Validator { + return et.Validator{ + Addr: v.Keys.GenesisKey.ValPubkey.Address(), + Power: v.Power, + } +} + +func (v *TestValidator) ProtoPubkey() cmtprotocrypto.PublicKey { + validatorPubKey := cmtprotocrypto.PublicKey{ + Sum: &cmtprotocrypto.PublicKey_Ed25519{ + Ed25519: v.Keys.PrivKey.PubKey().Bytes(), + }, + } + return validatorPubKey +} + +func (v *TestValidator) VoteExtension( + bh *checkpointingtypes.BlockHash, + epochNum uint64, +) checkpointingtypes.VoteExtension { + signBytes := checkpointingtypes.GetSignBytes(epochNum, *bh) + // Need valid bls signature for aggregation + bls := bls12381.Sign(v.Keys.PrivateKey, signBytes) + + return checkpointingtypes.VoteExtension{ + Signer: v.Keys.ValidatorAddress, + BlockHash: bh, + EpochNum: epochNum, + Height: 0, + BlsSig: &bls, + } +} + +func (v *TestValidator) SignVoteExtension( + t *testing.T, + bytes []byte, + height int64, + chainId string, +) cbftt.ExtendedVoteInfo { + votExt := genVoteExt(t, + bytes, height, 0, chainId) + signature, err := v.Keys.PrivKey.Sign(votExt) + require.NoError(t, err) + + evi := cbftt.ExtendedVoteInfo{ + Validator: *v.CometValidator(), + VoteExtension: bytes, + ExtensionSignature: signature, + BlockIdFlag: tendermintTypes.BlockIDFlagCommit, + } + + return evi +} + +func (v *TestValidator) ValidatorAddress(t *testing.T) sdk.ValAddress { + valAddress, err := sdk.ValAddressFromBech32(v.Keys.ValidatorAddress) + require.NoError(t, err) + return valAddress +} + +func (v *TestValidator) BlsPubKey() bls12381.PublicKey { + return *v.Keys.BlsKey.Pubkey +} + +func genNTestValidators(t *testing.T, n int) []TestValidator { + if n == 0 { + return []TestValidator{} + } + + keys, err := datagen.GenesisValidatorSet(n) + require.NoError(t, err) + + var vals []TestValidator + for _, key := range keys.Keys { + k := key + vals = append(vals, TestValidator{ + Keys: k, + Power: 100, + }) + } + + return vals +} + +func setupSdkCtx(height int64) sdk.Context { + return sdk.Context{}.WithHeaderInfo(header.Info{ + Height: height, + Time: time.Now(), + }).WithConsensusParams(tendermintTypes.ConsensusParams{ + Abci: &tendermintTypes.ABCIParams{ + VoteExtensionsEnableHeight: 1, + }, + }).WithChainID("test") +} + +func firstEpoch() *et.Epoch { + return &et.Epoch{ + EpochNumber: 1, + CurrentEpochInterval: 10, + FirstBlockHeight: 1, + } +} + +func epochAndVoteExtensionCtx() (sdk.Context, *et.Epoch) { + epoch := firstEpoch() + ctx := setupSdkCtx(int64(epoch.FirstBlockHeight) + int64(epoch.GetCurrentEpochInterval())) + return ctx, epoch +} + +func genVoteExt( + t *testing.T, + ext []byte, + height int64, + round int64, + chainID string, +) []byte { + cve := tendermintTypes.CanonicalVoteExtension{ + Extension: ext, + Height: height, // the vote extension was signed in the previous height + Round: round, + ChainId: chainID, + } + + marshalDelimitedFn := func(msg proto.Message) ([]byte, error) { + var buf bytes.Buffer + if err := protoio.NewDelimitedWriter(&buf).WriteMsg(msg); err != nil { + return nil, err + } + + return buf.Bytes(), nil + } + + extSignBytes, err := marshalDelimitedFn(&cve) + require.NoError(t, err) + return extSignBytes +} + +func requestPrepareProposal(height int64, votes []cbftt.ExtendedVoteInfo) *cbftt.RequestPrepareProposal { + return &cbftt.RequestPrepareProposal{ + MaxTxBytes: 10000, + Txs: [][]byte{}, + LocalLastCommit: cbftt.ExtendedCommitInfo{ + Round: 0, + Votes: votes, + }, + Height: height, + } +} + +func randomBlockHash() checkpointingtypes.BlockHash { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + return checkpointingtypes.BlockHash(datagen.GenRandomByteArray(r, 32)) +} + +// TODO There should be one function to verify the checkpoint against the validator set +// but currently there are different implementations in the codebase in checpointing module +// and zonecocierge module +func verifyCheckpoint(validators []TestValidator, rawCkpt *checkpointingtypes.RawCheckpoint) error { + valsCopy := validators + + sort.Slice(valsCopy, func(i, j int) bool { + return sdk.BigEndianToUint64(valsCopy[i].EpochingValidator().Addr) < sdk.BigEndianToUint64(valsCopy[j].EpochingValidator().Addr) + }) + + var validatorWithBls []*checkpointingtypes.ValidatorWithBlsKey + + for _, val := range valsCopy { + validatorWithBls = append(validatorWithBls, &checkpointingtypes.ValidatorWithBlsKey{ + ValidatorAddress: val.Keys.ValidatorAddress, + BlsPubKey: val.BlsPubKey(), + VotingPower: uint64(val.Power), + }) + } + + valSet := &checkpointingtypes.ValidatorWithBlsKeySet{ValSet: validatorWithBls} + // filter validator set that contributes to the signature + signerSet, signerSetPower, err := valSet.FindSubsetWithPowerSum(rawCkpt.Bitmap) + if err != nil { + return err + } + // ensure the signerSet has > 2/3 voting power + if signerSetPower*3 <= valSet.GetTotalPower()*2 { + return fmt.Errorf("failed") + } + // verify BLS multisig + signedMsgBytes := rawCkpt.SignedMsg() + ok, err := bls12381.VerifyMultiSig(*rawCkpt.BlsMultiSig, signerSet.GetBLSKeySet(), signedMsgBytes) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("BLS signature does not match the public key") + } + return nil +} + +type Scenario struct { + Ctx sdk.Context + Epoch *et.Epoch + TotalPower int64 + ValidatorSet []TestValidator + Extensions []cbftt.ExtendedVoteInfo +} + +type ValidatorVithVoteExtension struct { + Validator et.Validator + ValAddress sdk.ValAddress + VoteExtension checkpointingtypes.VoteExtension +} + +type ValidatorsAndExtensions struct { + Vals []TestValidator + Extensions []checkpointingtypes.VoteExtension +} + +func generateNValidatorAndVoteExtensions(t *testing.T, n int, bh *checkpointingtypes.BlockHash, epochNumber uint64) (*ValidatorsAndExtensions, int64) { + validators := genNTestValidators(t, n) + var extensions []checkpointingtypes.VoteExtension + var power int64 + for _, val := range validators { + validator := val + ve := validator.VoteExtension(bh, epochNumber) + extensions = append(extensions, ve) + power += validator.Power + } + return &ValidatorsAndExtensions{ + Vals: validators, + Extensions: extensions, + }, power +} + +func ToValidatorSet(v []TestValidator) et.ValidatorSet { + var cv []et.Validator + for _, val := range v { + cv = append(cv, val.EpochingValidator()) + } + return et.NewSortedValidatorSet(cv) +} + +func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { + tests := []struct { + name string + scenarioSetup func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario + expectError bool + }{ + { + name: "Empty vote extension list ", + scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { + ctx, epoch := epochAndVoteExtensionCtx() + r := rand.New(rand.NewSource(time.Now().UnixNano())) + bh := checkpointingtypes.BlockHash(datagen.GenRandomByteArray(r, 32)) + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) + return &Scenario{ + Ctx: ctx, + Epoch: epoch, + TotalPower: totalPower, + ValidatorSet: validatorAndExtensions.Vals, + Extensions: []cbftt.ExtendedVoteInfo{}, + } + }, + expectError: true, + }, + { + name: "List with only empty vote extensions", + scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { + ctx, epoch := epochAndVoteExtensionCtx() + bh := randomBlockHash() + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) + + var signedVoteExtensions []cbftt.ExtendedVoteInfo + for i, val := range validatorAndExtensions.Vals { + validator := val + ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() + ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() + // empty vote extension + signedExtension := validator.SignVoteExtension(t, []byte{}, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedVoteExtensions = append(signedVoteExtensions, signedExtension) + } + + return &Scenario{ + Ctx: ctx, + Epoch: epoch, + TotalPower: totalPower, + ValidatorSet: validatorAndExtensions.Vals, + Extensions: signedVoteExtensions, + } + }, + expectError: true, + }, + { + name: "1/3 of validators provided invalid bls signature", + scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { + ctx, epoch := epochAndVoteExtensionCtx() + bh := randomBlockHash() + // each validator has the same voting power + numValidators := 9 + invalidValidBlsSig := numValidators / 3 + + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, numValidators, &bh, epoch.EpochNumber) + + var signedVoteExtensions []cbftt.ExtendedVoteInfo + for i, val := range validatorAndExtensions.Vals { + validator := val + ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() + + if i < invalidValidBlsSig { + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(checkpointingtypes.ErrInvalidBlsSignature).AnyTimes() + } else { + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() + } + ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() + // empty vote extension + marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() + require.NoError(t, err) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedVoteExtensions = append(signedVoteExtensions, signedExtension) + } + + return &Scenario{ + Ctx: ctx, + Epoch: epoch, + TotalPower: totalPower, + ValidatorSet: validatorAndExtensions.Vals, + Extensions: signedVoteExtensions, + } + }, + expectError: true, + }, + { + name: "2/3 + 1 of validators voted for valid block hash, the rest voted for invalid block hash", + scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { + ctx, epoch := epochAndVoteExtensionCtx() + bh := randomBlockHash() + bh1 := randomBlockHash() + + validatorAndExtensionsValid, totalPowerValid := generateNValidatorAndVoteExtensions(t, 7, &bh, epoch.EpochNumber) + validatorAndExtensionsInvalid, totalPowerInvalid := generateNValidatorAndVoteExtensions(t, 2, &bh1, epoch.EpochNumber) + + var allvalidators []TestValidator + allvalidators = append(allvalidators, validatorAndExtensionsValid.Vals...) + allvalidators = append(allvalidators, validatorAndExtensionsInvalid.Vals...) + + var allExtensions []checkpointingtypes.VoteExtension + allExtensions = append(allExtensions, validatorAndExtensionsValid.Extensions...) + allExtensions = append(allExtensions, validatorAndExtensionsInvalid.Extensions...) + + var signedVoteExtensions []cbftt.ExtendedVoteInfo + for i, val := range allvalidators { + validator := val + ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() + ek.EXPECT().VerifyBLSSig(gomock.Any(), allExtensions[i].ToBLSSig()).Return(nil).AnyTimes() + ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() + marshaledExtension, err := allExtensions[i].Marshal() + require.NoError(t, err) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedVoteExtensions = append(signedVoteExtensions, signedExtension) + } + + return &Scenario{ + Ctx: ctx, + Epoch: epoch, + TotalPower: totalPowerValid + totalPowerInvalid, + ValidatorSet: allvalidators, + Extensions: signedVoteExtensions, + } + }, + expectError: false, + }, + { + name: "All valid vote extensions", + scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { + ctx, epoch := epochAndVoteExtensionCtx() + bh := randomBlockHash() + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) + + var signedVoteExtensions []cbftt.ExtendedVoteInfo + for i, val := range validatorAndExtensions.Vals { + validator := val + ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() + ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() + marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() + require.NoError(t, err) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedVoteExtensions = append(signedVoteExtensions, signedExtension) + } + + return &Scenario{ + Ctx: ctx, + Epoch: epoch, + TotalPower: totalPower, + ValidatorSet: validatorAndExtensions.Vals, + Extensions: signedVoteExtensions, + } + }, + expectError: false, + }, + + // TODO: Add scenarios testing compatibility of prepareProposal, processProposal and preBlocker + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := gomock.NewController(t) + ek := mocks.NewMockCheckpointingKeeper(c) + mem := mempool.NoOpMempool{} + scenario := tt.scenarioSetup(t, ek) + // Those are true for every scenario + ek.EXPECT().GetEpoch(gomock.Any()).Return(scenario.Epoch).AnyTimes() + ek.EXPECT().GetTotalVotingPower(gomock.Any(), scenario.Epoch.EpochNumber).Return(scenario.TotalPower).AnyTimes() + ek.EXPECT().GetValidatorSet(gomock.Any(), scenario.Epoch.EpochNumber).Return(et.NewSortedValidatorSet(ToValidatorSet(scenario.ValidatorSet))).AnyTimes() + + h := checkpointing.NewProposalHandler( + log.NewNopLogger(), + ek, + mem, + nil, + ) + prepareProposalFn := h.PrepareProposal() + + prop, err := prepareProposalFn(scenario.Ctx, requestPrepareProposal(scenario.Ctx.HeaderInfo().Height, scenario.Extensions)) + if tt.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Len(t, prop.Txs, 1) + var checkpoint checkpointingtypes.InjectedCheckpoint + err := checkpoint.Unmarshal(prop.Txs[0]) + require.NoError(t, err) + err = verifyCheckpoint(scenario.ValidatorSet, checkpoint.Ckpt.Ckpt) + require.NoError(t, err) + } + }) + } +} From 68c898b5004bbe66d68a6e134746aa9db0286177 Mon Sep 17 00:00:00 2001 From: RafilxTenfen Date: Thu, 22 Feb 2024 11:27:01 -0300 Subject: [PATCH 013/119] chore: removed unused comment --- x/btccheckpoint/keeper/grpc_query_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/btccheckpoint/keeper/grpc_query_test.go b/x/btccheckpoint/keeper/grpc_query_test.go index 36c390db4..b9917de18 100644 --- a/x/btccheckpoint/keeper/grpc_query_test.go +++ b/x/btccheckpoint/keeper/grpc_query_test.go @@ -28,7 +28,6 @@ func TestBtcCheckpointInfo(t *testing.T) { proofs := dg.BlockCreationResultToProofs(blockResults) msg := dg.GenerateMessageWithRandomSubmitter(blockResults) - // Now we will return depth enough for moving submission to be submitted tk.BTCLightClient.SetDepth(blck1.HeaderBytes.Hash(), uint64(1)) tk.BTCLightClient.SetDepth(blck2.HeaderBytes.Hash(), uint64(1)) From 8fc1efb97da3567674b4e5f2959b6f6270bc7b71 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 23 Feb 2024 09:43:30 +0100 Subject: [PATCH 014/119] Pr comments --- x/btcstaking/client/cli/query.go | 30 ++++++++++++ x/checkpointing/proposal_test.go | 78 ++++++++++++++------------------ 2 files changed, 64 insertions(+), 44 deletions(-) diff --git a/x/btcstaking/client/cli/query.go b/x/btcstaking/client/cli/query.go index a587b19e9..2008b987d 100644 --- a/x/btcstaking/client/cli/query.go +++ b/x/btcstaking/client/cli/query.go @@ -30,6 +30,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdFinalityProviderPowerAtHeight()) cmd.AddCommand(CmdActivatedHeight()) cmd.AddCommand(CmdFinalityProviderDelegations()) + cmd.AddCommand(CmdDelegation()) return cmd } @@ -61,6 +62,35 @@ func CmdFinalityProvider() *cobra.Command { return cmd } +func CmdDelegation() *cobra.Command { + cmd := &cobra.Command{ + Use: "delegatopn [staking_tx_hash_hex]", + Short: "retrieve a BTC delegation", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.BTCDelegation( + cmd.Context(), + &types.QueryBTCDelegationRequest{ + StakingTxHashHex: args[0], + }, + ) + + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + func CmdFinalityProviders() *cobra.Command { cmd := &cobra.Command{ Use: "finality-providers", diff --git a/x/checkpointing/proposal_test.go b/x/checkpointing/proposal_test.go index 2d0627917..71c05b405 100644 --- a/x/checkpointing/proposal_test.go +++ b/x/checkpointing/proposal_test.go @@ -144,10 +144,18 @@ func firstEpoch() *et.Epoch { } } -func epochAndVoteExtensionCtx() (sdk.Context, *et.Epoch) { +type EpochAndCtx struct { + Epoch *et.Epoch + Ctx sdk.Context +} + +func epochAndVoteExtensionCtx() *EpochAndCtx { epoch := firstEpoch() ctx := setupSdkCtx(int64(epoch.FirstBlockHeight) + int64(epoch.GetCurrentEpochInterval())) - return ctx, epoch + return &EpochAndCtx{ + Epoch: epoch, + Ctx: ctx, + } } func genVoteExt( @@ -192,7 +200,7 @@ func requestPrepareProposal(height int64, votes []cbftt.ExtendedVoteInfo) *cbftt func randomBlockHash() checkpointingtypes.BlockHash { r := rand.New(rand.NewSource(time.Now().UnixNano())) - return checkpointingtypes.BlockHash(datagen.GenRandomByteArray(r, 32)) + return datagen.GenRandomBlockHash(r) } // TODO There should be one function to verify the checkpoint against the validator set @@ -238,8 +246,6 @@ func verifyCheckpoint(validators []TestValidator, rawCkpt *checkpointingtypes.Ra } type Scenario struct { - Ctx sdk.Context - Epoch *et.Epoch TotalPower int64 ValidatorSet []TestValidator Extensions []cbftt.ExtendedVoteInfo @@ -283,19 +289,15 @@ func ToValidatorSet(v []TestValidator) et.ValidatorSet { func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { tests := []struct { name string - scenarioSetup func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario + scenarioSetup func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario expectError bool }{ { name: "Empty vote extension list ", - scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { - ctx, epoch := epochAndVoteExtensionCtx() - r := rand.New(rand.NewSource(time.Now().UnixNano())) - bh := checkpointingtypes.BlockHash(datagen.GenRandomByteArray(r, 32)) - validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { + bh := randomBlockHash() + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, ec.Epoch.EpochNumber) return &Scenario{ - Ctx: ctx, - Epoch: epoch, TotalPower: totalPower, ValidatorSet: validatorAndExtensions.Vals, Extensions: []cbftt.ExtendedVoteInfo{}, @@ -305,11 +307,9 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { }, { name: "List with only empty vote extensions", - scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { - ctx, epoch := epochAndVoteExtensionCtx() + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { bh := randomBlockHash() - validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) - + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, ec.Epoch.EpochNumber) var signedVoteExtensions []cbftt.ExtendedVoteInfo for i, val := range validatorAndExtensions.Vals { validator := val @@ -317,13 +317,11 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() // empty vote extension - signedExtension := validator.SignVoteExtension(t, []byte{}, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedExtension := validator.SignVoteExtension(t, []byte{}, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) signedVoteExtensions = append(signedVoteExtensions, signedExtension) } return &Scenario{ - Ctx: ctx, - Epoch: epoch, TotalPower: totalPower, ValidatorSet: validatorAndExtensions.Vals, Extensions: signedVoteExtensions, @@ -333,14 +331,13 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { }, { name: "1/3 of validators provided invalid bls signature", - scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { - ctx, epoch := epochAndVoteExtensionCtx() + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { bh := randomBlockHash() // each validator has the same voting power numValidators := 9 invalidValidBlsSig := numValidators / 3 - validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, numValidators, &bh, epoch.EpochNumber) + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, numValidators, &bh, ec.Epoch.EpochNumber) var signedVoteExtensions []cbftt.ExtendedVoteInfo for i, val := range validatorAndExtensions.Vals { @@ -356,13 +353,11 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { // empty vote extension marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() require.NoError(t, err) - signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) signedVoteExtensions = append(signedVoteExtensions, signedExtension) } return &Scenario{ - Ctx: ctx, - Epoch: epoch, TotalPower: totalPower, ValidatorSet: validatorAndExtensions.Vals, Extensions: signedVoteExtensions, @@ -372,13 +367,12 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { }, { name: "2/3 + 1 of validators voted for valid block hash, the rest voted for invalid block hash", - scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { - ctx, epoch := epochAndVoteExtensionCtx() + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { bh := randomBlockHash() bh1 := randomBlockHash() - validatorAndExtensionsValid, totalPowerValid := generateNValidatorAndVoteExtensions(t, 7, &bh, epoch.EpochNumber) - validatorAndExtensionsInvalid, totalPowerInvalid := generateNValidatorAndVoteExtensions(t, 2, &bh1, epoch.EpochNumber) + validatorAndExtensionsValid, totalPowerValid := generateNValidatorAndVoteExtensions(t, 7, &bh, ec.Epoch.EpochNumber) + validatorAndExtensionsInvalid, totalPowerInvalid := generateNValidatorAndVoteExtensions(t, 2, &bh1, ec.Epoch.EpochNumber) var allvalidators []TestValidator allvalidators = append(allvalidators, validatorAndExtensionsValid.Vals...) @@ -396,13 +390,11 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() marshaledExtension, err := allExtensions[i].Marshal() require.NoError(t, err) - signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) signedVoteExtensions = append(signedVoteExtensions, signedExtension) } return &Scenario{ - Ctx: ctx, - Epoch: epoch, TotalPower: totalPowerValid + totalPowerInvalid, ValidatorSet: allvalidators, Extensions: signedVoteExtensions, @@ -412,10 +404,9 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { }, { name: "All valid vote extensions", - scenarioSetup: func(t *testing.T, ek *mocks.MockCheckpointingKeeper) *Scenario { - ctx, epoch := epochAndVoteExtensionCtx() + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { bh := randomBlockHash() - validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, epoch.EpochNumber) + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, 4, &bh, ec.Epoch.EpochNumber) var signedVoteExtensions []cbftt.ExtendedVoteInfo for i, val := range validatorAndExtensions.Vals { @@ -425,13 +416,11 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() require.NoError(t, err) - signedExtension := validator.SignVoteExtension(t, marshaledExtension, ctx.HeaderInfo().Height-1, ctx.ChainID()) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) signedVoteExtensions = append(signedVoteExtensions, signedExtension) } return &Scenario{ - Ctx: ctx, - Epoch: epoch, TotalPower: totalPower, ValidatorSet: validatorAndExtensions.Vals, Extensions: signedVoteExtensions, @@ -448,11 +437,12 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { c := gomock.NewController(t) ek := mocks.NewMockCheckpointingKeeper(c) mem := mempool.NoOpMempool{} - scenario := tt.scenarioSetup(t, ek) + ec := epochAndVoteExtensionCtx() + scenario := tt.scenarioSetup(ec, ek) // Those are true for every scenario - ek.EXPECT().GetEpoch(gomock.Any()).Return(scenario.Epoch).AnyTimes() - ek.EXPECT().GetTotalVotingPower(gomock.Any(), scenario.Epoch.EpochNumber).Return(scenario.TotalPower).AnyTimes() - ek.EXPECT().GetValidatorSet(gomock.Any(), scenario.Epoch.EpochNumber).Return(et.NewSortedValidatorSet(ToValidatorSet(scenario.ValidatorSet))).AnyTimes() + ek.EXPECT().GetEpoch(gomock.Any()).Return(ec.Epoch).AnyTimes() + ek.EXPECT().GetTotalVotingPower(gomock.Any(), ec.Epoch.EpochNumber).Return(scenario.TotalPower).AnyTimes() + ek.EXPECT().GetValidatorSet(gomock.Any(), ec.Epoch.EpochNumber).Return(et.NewSortedValidatorSet(ToValidatorSet(scenario.ValidatorSet))).AnyTimes() h := checkpointing.NewProposalHandler( log.NewNopLogger(), @@ -462,7 +452,7 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { ) prepareProposalFn := h.PrepareProposal() - prop, err := prepareProposalFn(scenario.Ctx, requestPrepareProposal(scenario.Ctx.HeaderInfo().Height, scenario.Extensions)) + prop, err := prepareProposalFn(ec.Ctx, requestPrepareProposal(ec.Ctx.HeaderInfo().Height, scenario.Extensions)) if tt.expectError { require.Error(t, err) } else { From 04bdcc6851e0f329e9d3c64a84b598be7b07350f Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 23 Feb 2024 11:02:51 +0100 Subject: [PATCH 015/119] Fix spelling --- x/btcstaking/client/cli/query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/btcstaking/client/cli/query.go b/x/btcstaking/client/cli/query.go index 2008b987d..3f5ba70a9 100644 --- a/x/btcstaking/client/cli/query.go +++ b/x/btcstaking/client/cli/query.go @@ -64,7 +64,7 @@ func CmdFinalityProvider() *cobra.Command { func CmdDelegation() *cobra.Command { cmd := &cobra.Command{ - Use: "delegatopn [staking_tx_hash_hex]", + Use: "delegation [staking_tx_hash_hex]", Short: "retrieve a BTC delegation", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { From 8458387d94bea0cda691b0a90bde73fc151712d4 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 23 Feb 2024 12:44:13 +0100 Subject: [PATCH 016/119] Clean up and additional test case --- x/checkpointing/proposal_test.go | 42 ++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/x/checkpointing/proposal_test.go b/x/checkpointing/proposal_test.go index 71c05b405..1eafcf229 100644 --- a/x/checkpointing/proposal_test.go +++ b/x/checkpointing/proposal_test.go @@ -251,12 +251,6 @@ type Scenario struct { Extensions []cbftt.ExtendedVoteInfo } -type ValidatorVithVoteExtension struct { - Validator et.Validator - ValAddress sdk.ValAddress - VoteExtension checkpointingtypes.VoteExtension -} - type ValidatorsAndExtensions struct { Vals []TestValidator Extensions []checkpointingtypes.VoteExtension @@ -350,7 +344,6 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() } ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() - // empty vote extension marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() require.NoError(t, err) signedExtension := validator.SignVoteExtension(t, marshaledExtension, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) @@ -365,6 +358,41 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { }, expectError: true, }, + { + name: "less than 1/3 of validators provided invalid bls signature", + scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { + bh := randomBlockHash() + // each validator has the same voting power + numValidators := 9 + invalidValidBlsSig := numValidators/3 - 1 + + validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, numValidators, &bh, ec.Epoch.EpochNumber) + + var signedVoteExtensions []cbftt.ExtendedVoteInfo + for i, val := range validatorAndExtensions.Vals { + validator := val + ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() + + if i < invalidValidBlsSig { + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(checkpointingtypes.ErrInvalidBlsSignature).AnyTimes() + } else { + ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() + } + ek.EXPECT().GetBlsPubKey(gomock.Any(), validator.ValidatorAddress(t)).Return(validator.BlsPubKey(), nil).AnyTimes() + marshaledExtension, err := validatorAndExtensions.Extensions[i].Marshal() + require.NoError(t, err) + signedExtension := validator.SignVoteExtension(t, marshaledExtension, ec.Ctx.HeaderInfo().Height-1, ec.Ctx.ChainID()) + signedVoteExtensions = append(signedVoteExtensions, signedExtension) + } + + return &Scenario{ + TotalPower: totalPower, + ValidatorSet: validatorAndExtensions.Vals, + Extensions: signedVoteExtensions, + } + }, + expectError: false, + }, { name: "2/3 + 1 of validators voted for valid block hash, the rest voted for invalid block hash", scenarioSetup: func(ec *EpochAndCtx, ek *mocks.MockCheckpointingKeeper) *Scenario { From bc4b05688999e26914a214d913a410661046790f Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 26 Feb 2024 07:47:38 -0300 Subject: [PATCH 017/119] chore: update proto of `QueryBtcCheckpointsInfoResponse` to return `BTCCheckpointInfoResponse` (#493) chore: update proto of BtcCheckpointsInfo to return response --- client/docs/swagger-ui/swagger.yaml | 367 +++++---------------- proto/babylon/btccheckpoint/v1/query.proto | 2 +- x/btccheckpoint/keeper/grpc_query.go | 19 +- x/btccheckpoint/types/query.pb.go | 113 ++++--- 4 files changed, 147 insertions(+), 354 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 4882e3b0b..eb3e79a28 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -22,72 +22,43 @@ paths: epoch_number: type: string format: uint64 - title: epoch number of this checkpoint + description: EpochNumber of this checkpoint. best_submission_btc_block_height: type: string format: uint64 title: btc height of the best submission of the epoch best_submission_btc_block_hash: type: string - format: byte title: >- hash of the btc block which determines checkpoint btc block height i.e. - youngest block of best submission + youngest block of best submission Hexadecimal best_submission_transactions: type: array items: type: object properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx - on BTC blockchain - - Although it is already a part of SubmissionKey, we - store it here again - - to make TransactionInfo self-contained. - - For example, storing the key allows - TransactionInfo to not relay on - - the fact that TransactionInfo will be ordered in - the same order as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be - idendtified by hash of block in - - which transaction was included and transaction - index in the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string - format: byte - title: transaction is the full transaction in bytes + description: >- + transaction is the full transaction data as str + hex. proof: type: string - format: byte title: >- proof is the Merkle proof that this tx is included in the position in `key` - - TODO: maybe it could use here better format as we - already processed and - - valideated the proof? title: >- - TransactionInfo is the info of a tx on Bitcoin, + TransactionInfoResponse is the info of a tx on + Bitcoin, including @@ -105,17 +76,13 @@ paths: properties: submitter: type: string - format: byte description: >- - TODO: this could probably be better typed - submitter is the address of the checkpoint submitter to BTC, extracted from the checkpoint itself. reporter: type: string - format: byte title: >- reporter is the address of the reporter who reported the submissions, @@ -123,17 +90,17 @@ paths: calculated from submission message MsgInsertBTCSpvProof itself title: >- - CheckpointAddresses contains the addresses of the - submitter and reporter of a + CheckpointAddressesResponse contains the addresses of + the submitter and reporter of a given checkpoint title: list of vigilantes' addresses of the best submission - title: >- - BTCCheckpointInfo contains all data about best submission of - checkpoint for + description: >- + BTCCheckpointInfoResponse contains all data about best + submission of checkpoint for given epoch. Best submission is the submission which is - deeper in btc ledger + deeper in btc ledger. pagination: title: pagination defines the pagination in the response type: object @@ -9532,118 +9499,6 @@ paths: tags: - Query definitions: - babylon.btccheckpoint.v1.BTCCheckpointInfo: - type: object - properties: - epoch_number: - type: string - format: uint64 - title: epoch number of this checkpoint - best_submission_btc_block_height: - type: string - format: uint64 - title: btc height of the best submission of the epoch - best_submission_btc_block_hash: - type: string - format: byte - title: >- - hash of the btc block which determines checkpoint btc block height - i.e. - - youngest block of best submission - best_submission_transactions: - type: array - items: - type: object - properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx on BTC - blockchain - - Although it is already a part of SubmissionKey, we store it here - again - - to make TransactionInfo self-contained. - - For example, storing the key allows TransactionInfo to not relay - on - - the fact that TransactionInfo will be ordered in the same order - as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified by hash - of block in - - which transaction was included and transaction index in the - block - transaction: - type: string - format: byte - title: transaction is the full transaction in bytes - proof: - type: string - format: byte - title: >- - proof is the Merkle proof that this tx is included in the - position in `key` - - TODO: maybe it could use here better format as we already - processed and - - valideated the proof? - title: |- - TransactionInfo is the info of a tx on Bitcoin, - including - - the position of the tx on BTC blockchain - - the full tx content - - the Merkle proof that this tx is on the above position - title: the BTC checkpoint transactions of the best submission - best_submission_vigilante_address_list: - type: array - items: - type: object - properties: - submitter: - type: string - format: byte - description: >- - TODO: this could probably be better typed - - submitter is the address of the checkpoint submitter to BTC, - extracted from - - the checkpoint itself. - reporter: - type: string - format: byte - title: >- - reporter is the address of the reporter who reported the - submissions, - - calculated from submission message MsgInsertBTCSpvProof itself - title: >- - CheckpointAddresses contains the addresses of the submitter and - reporter of a - - given checkpoint - title: list of vigilantes' addresses of the best submission - title: >- - BTCCheckpointInfo contains all data about best submission of checkpoint - for - - given epoch. Best submission is the submission which is deeper in btc - ledger babylon.btccheckpoint.v1.BTCCheckpointInfoResponse: type: object properties: @@ -9720,30 +9575,6 @@ definitions: given epoch. Best submission is the submission which is deeper in btc ledger. - babylon.btccheckpoint.v1.CheckpointAddresses: - type: object - properties: - submitter: - type: string - format: byte - description: >- - TODO: this could probably be better typed - - submitter is the address of the checkpoint submitter to BTC, extracted - from - - the checkpoint itself. - reporter: - type: string - format: byte - title: |- - reporter is the address of the reporter who reported the submissions, - calculated from submission message MsgInsertBTCSpvProof itself - title: >- - CheckpointAddresses contains the addresses of the submitter and reporter - of a - - given checkpoint babylon.btccheckpoint.v1.CheckpointAddressesResponse: type: object properties: @@ -9897,72 +9728,40 @@ definitions: epoch_number: type: string format: uint64 - title: epoch number of this checkpoint + description: EpochNumber of this checkpoint. best_submission_btc_block_height: type: string format: uint64 title: btc height of the best submission of the epoch best_submission_btc_block_hash: type: string - format: byte title: >- hash of the btc block which determines checkpoint btc block height i.e. - youngest block of best submission + youngest block of best submission Hexadecimal best_submission_transactions: type: array items: type: object properties: - key: - description: >- - key is the position (txIdx, blockHash) of this tx on BTC - blockchain - - Although it is already a part of SubmissionKey, we store - it here again - - to make TransactionInfo self-contained. - - For example, storing the key allows TransactionInfo to not - relay on - - the fact that TransactionInfo will be ordered in the same - order as - - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified by - hash of block in - - which transaction was included and transaction index in - the block + index: + type: integer + format: int64 + description: Index Bitcoin Transaction index in block. + hash: + type: string + description: Hash BTC Header hash as hex. transaction: type: string - format: byte - title: transaction is the full transaction in bytes + description: transaction is the full transaction data as str hex. proof: type: string - format: byte title: >- proof is the Merkle proof that this tx is included in the position in `key` - - TODO: maybe it could use here better format as we already - processed and - - valideated the proof? title: |- - TransactionInfo is the info of a tx on Bitcoin, + TransactionInfoResponse is the info of a tx on Bitcoin, including - the position of the tx on BTC blockchain - the full tx content @@ -9975,17 +9774,13 @@ definitions: properties: submitter: type: string - format: byte description: >- - TODO: this could probably be better typed - submitter is the address of the checkpoint submitter to BTC, extracted from the checkpoint itself. reporter: type: string - format: byte title: >- reporter is the address of the reporter who reported the submissions, @@ -9993,17 +9788,17 @@ definitions: calculated from submission message MsgInsertBTCSpvProof itself title: >- - CheckpointAddresses contains the addresses of the submitter - and reporter of a + CheckpointAddressesResponse contains the addresses of the + submitter and reporter of a given checkpoint title: list of vigilantes' addresses of the best submission - title: >- - BTCCheckpointInfo contains all data about best submission of + description: >- + BTCCheckpointInfoResponse contains all data about best submission of checkpoint for given epoch. Best submission is the submission which is deeper in - btc ledger + btc ledger. pagination: title: pagination defines the pagination in the response type: object @@ -10187,51 +9982,6 @@ definitions: hash), so there should be other strong arguments for this optimization - babylon.btccheckpoint.v1.TransactionInfo: - type: object - properties: - key: - description: |- - key is the position (txIdx, blockHash) of this tx on BTC blockchain - Although it is already a part of SubmissionKey, we store it here again - to make TransactionInfo self-contained. - For example, storing the key allows TransactionInfo to not relay on - the fact that TransactionInfo will be ordered in the same order as - TransactionKeys in SubmissionKey. - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified by hash of - block in - - which transaction was included and transaction index in the block - transaction: - type: string - format: byte - title: transaction is the full transaction in bytes - proof: - type: string - format: byte - title: >- - proof is the Merkle proof that this tx is included in the position in - `key` - - TODO: maybe it could use here better format as we already processed - and - - valideated the proof? - title: |- - TransactionInfo is the info of a tx on Bitcoin, - including - - the position of the tx on BTC blockchain - - the full tx content - - the Merkle proof that this tx is on the above position babylon.btccheckpoint.v1.TransactionInfoResponse: type: object properties: @@ -14348,6 +14098,51 @@ definitions: title: |- ValidatorWithBlsKey couples validator address, voting power, and its bls public key + babylon.btccheckpoint.v1.TransactionInfo: + type: object + properties: + key: + type: object + properties: + index: + type: integer + format: int64 + hash: + type: string + format: byte + title: >- + Each provided OP_RETURN transaction can be idendtified by hash of + block in + + which transaction was included and transaction index in the block + description: |- + key is the position (txIdx, blockHash) of this tx on BTC blockchain + Although it is already a part of SubmissionKey, we store it here again + to make TransactionInfo self-contained. + For example, storing the key allows TransactionInfo to not relay on + the fact that TransactionInfo will be ordered in the same order as + TransactionKeys in SubmissionKey. + transaction: + type: string + format: byte + title: transaction is the full transaction in bytes + proof: + type: string + format: byte + title: >- + proof is the Merkle proof that this tx is included in the position in + `key` + + TODO: maybe it could use here better format as we already processed + and + + valideated the proof? + title: |- + TransactionInfo is the info of a tx on Bitcoin, + including + - the position of the tx on BTC blockchain + - the full tx content + - the Merkle proof that this tx is on the above position babylon.zoneconcierge.v1.ChainInfo: type: object properties: diff --git a/proto/babylon/btccheckpoint/v1/query.proto b/proto/babylon/btccheckpoint/v1/query.proto index f16974f00..216fafb1c 100644 --- a/proto/babylon/btccheckpoint/v1/query.proto +++ b/proto/babylon/btccheckpoint/v1/query.proto @@ -68,7 +68,7 @@ message QueryBtcCheckpointsInfoRequest { // QueryBtcCheckpointsInfoResponse is response type for the // Query/BtcCheckpointsInfo RPC method message QueryBtcCheckpointsInfoResponse { - repeated BTCCheckpointInfo info_list = 1; + repeated BTCCheckpointInfoResponse info_list = 1; // pagination defines the pagination in the response cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/x/btccheckpoint/keeper/grpc_query.go b/x/btccheckpoint/keeper/grpc_query.go index bb9e2f723..833bb7a9c 100644 --- a/x/btccheckpoint/keeper/grpc_query.go +++ b/x/btccheckpoint/keeper/grpc_query.go @@ -62,34 +62,33 @@ func (k Keeper) BtcCheckpointsInfo(ctx context.Context, req *types.QueryBtcCheck return nil, status.Error(codes.InvalidArgument, "invalid request") } + ckptInfoList := []*types.BTCCheckpointInfoResponse{} epochDataStore := k.epochDataStore(ctx) - - ckptInfoList := []*types.BTCCheckpointInfo{} // iterate over epochDataStore, where key is the epoch number and value is the epoch data pageRes, err := query.Paginate(epochDataStore, req.Pagination, func(key, value []byte) error { - epochNum := sdk.BigEndianToUint64(key) var epochData types.EpochData - k.cdc.MustUnmarshal(value, &epochData) + if err := k.cdc.Unmarshal(value, &epochData); err != nil { + return fmt.Errorf("failed to decode epoch data %+v: %w", value, err) + } + epochNum := sdk.BigEndianToUint64(key) ckptInfo, err := k.getCheckpointInfo(ctx, epochNum, &epochData) - if err != nil { return fmt.Errorf("failed to get lowest BTC height and hash in keys of epoch %d: %w", epochNum, err) } - // append ckpt info - ckptInfoList = append(ckptInfoList, ckptInfo) + // append ckpt info + ckptInfoList = append(ckptInfoList, ckptInfo.ToResponse()) return nil }) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - resp := &types.QueryBtcCheckpointsInfoResponse{ + return &types.QueryBtcCheckpointsInfoResponse{ InfoList: ckptInfoList, Pagination: pageRes, - } - return resp, nil + }, nil } func getOffset(pageReq *query.PageRequest) uint64 { diff --git a/x/btccheckpoint/types/query.pb.go b/x/btccheckpoint/types/query.pb.go index ad2e65a8a..e03f9655b 100644 --- a/x/btccheckpoint/types/query.pb.go +++ b/x/btccheckpoint/types/query.pb.go @@ -258,7 +258,7 @@ func (m *QueryBtcCheckpointsInfoRequest) GetPagination() *query.PageRequest { // QueryBtcCheckpointsInfoResponse is response type for the // Query/BtcCheckpointsInfo RPC method type QueryBtcCheckpointsInfoResponse struct { - InfoList []*BTCCheckpointInfo `protobuf:"bytes,1,rep,name=info_list,json=infoList,proto3" json:"info_list,omitempty"` + InfoList []*BTCCheckpointInfoResponse `protobuf:"bytes,1,rep,name=info_list,json=infoList,proto3" json:"info_list,omitempty"` // pagination defines the pagination in the response Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -296,7 +296,7 @@ func (m *QueryBtcCheckpointsInfoResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryBtcCheckpointsInfoResponse proto.InternalMessageInfo -func (m *QueryBtcCheckpointsInfoResponse) GetInfoList() []*BTCCheckpointInfo { +func (m *QueryBtcCheckpointsInfoResponse) GetInfoList() []*BTCCheckpointInfoResponse { if m != nil { return m.InfoList } @@ -658,64 +658,63 @@ func init() { } var fileDescriptor_6b9a2f46ada7d854 = []byte{ - // 897 bytes of a gzipped FileDescriptorProto + // 892 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xdc, 0x44, 0x18, 0xcd, 0x6c, 0x9c, 0x28, 0xfb, 0x05, 0x24, 0x18, 0x22, 0xb1, 0xd9, 0x04, 0x77, 0x6b, 0xd1, - 0x26, 0x82, 0xc6, 0xd6, 0x26, 0xb4, 0xa5, 0x02, 0x21, 0xe1, 0x8a, 0xb6, 0x08, 0x04, 0xc5, 0x2d, + 0x26, 0x42, 0x8d, 0xad, 0x6d, 0x68, 0x4b, 0x05, 0x42, 0xc2, 0x15, 0x2d, 0x08, 0x04, 0xc1, 0x2d, 0x1c, 0xb8, 0x58, 0x63, 0x67, 0x62, 0x8f, 0xb2, 0xeb, 0x71, 0x3d, 0xb3, 0x51, 0x57, 0x15, 0x17, - 0x38, 0x21, 0x0e, 0x20, 0xf1, 0x37, 0x70, 0xe3, 0x58, 0xae, 0x48, 0xdc, 0x2a, 0x71, 0xa9, 0xe0, - 0xc2, 0x09, 0xa1, 0x84, 0x3f, 0x04, 0x79, 0x3c, 0xfb, 0x33, 0x9d, 0x6e, 0x36, 0xe2, 0xb6, 0xb6, - 0xdf, 0xfb, 0xde, 0x9b, 0xf7, 0xcd, 0xcc, 0xb7, 0xf0, 0x7a, 0x44, 0xa2, 0x7e, 0x87, 0x67, 0x5e, - 0x24, 0xe3, 0x38, 0xa5, 0xf1, 0x61, 0xce, 0x59, 0x26, 0xbd, 0xa3, 0xb6, 0xf7, 0xa0, 0x47, 0x8b, + 0x38, 0x21, 0x0e, 0x20, 0xf1, 0x37, 0x70, 0xe3, 0x08, 0x37, 0x84, 0xc4, 0xad, 0x12, 0x97, 0x0a, + 0x2e, 0x9c, 0x10, 0x4a, 0xf8, 0x43, 0x90, 0xc7, 0xb3, 0xbf, 0x3b, 0xd9, 0x24, 0xe2, 0xb6, 0xf6, + 0xbc, 0xf7, 0xbd, 0x37, 0xef, 0x1b, 0xcf, 0xb7, 0xf0, 0x6a, 0x44, 0xa2, 0x7e, 0x87, 0x67, 0x5e, + 0x24, 0xe3, 0x38, 0xa5, 0xf1, 0x61, 0xce, 0x59, 0x26, 0xbd, 0xa3, 0xb6, 0xf7, 0xb0, 0x47, 0x8b, 0xbe, 0x9b, 0x17, 0x5c, 0x72, 0xdc, 0xd0, 0x28, 0x77, 0x02, 0xe5, 0x1e, 0xb5, 0x9b, 0x6b, 0x09, - 0x4f, 0xb8, 0x02, 0x79, 0xe5, 0xaf, 0x0a, 0xdf, 0x5c, 0x8f, 0xb9, 0xe8, 0x72, 0x11, 0x56, 0x1f, - 0xaa, 0x07, 0xfd, 0x69, 0x33, 0xe1, 0x3c, 0xe9, 0x50, 0x8f, 0xe4, 0xcc, 0x23, 0x59, 0xc6, 0x25, - 0x91, 0x8c, 0x67, 0x83, 0xaf, 0x6f, 0x54, 0x58, 0x2f, 0x22, 0x82, 0x56, 0x0e, 0xbc, 0xa3, 0x76, - 0x44, 0x25, 0x69, 0x7b, 0x39, 0x49, 0x58, 0xa6, 0xc0, 0x1a, 0x7b, 0xc9, 0x68, 0x3d, 0x27, 0x05, - 0xe9, 0x0e, 0x4a, 0x5e, 0x31, 0xc2, 0x26, 0x17, 0xa3, 0xd0, 0xce, 0x1a, 0xe0, 0xcf, 0x4a, 0xd9, - 0xbb, 0xaa, 0x44, 0x40, 0x1f, 0xf4, 0xa8, 0x90, 0xce, 0xe7, 0xf0, 0xca, 0xc4, 0x5b, 0x91, 0xf3, - 0x4c, 0x50, 0xfc, 0x1e, 0x2c, 0x57, 0x52, 0x0d, 0xd4, 0x42, 0xdb, 0xab, 0xbb, 0x2d, 0xd7, 0x94, - 0x93, 0x5b, 0x31, 0x7d, 0xeb, 0xc9, 0xdf, 0x17, 0x16, 0x02, 0xcd, 0x72, 0xde, 0x85, 0xd7, 0x54, - 0x59, 0x5f, 0xc6, 0x37, 0x87, 0xe8, 0x0f, 0xb3, 0x03, 0xae, 0x75, 0xf1, 0x06, 0xd4, 0x69, 0xce, - 0xe3, 0x34, 0xcc, 0x7a, 0x5d, 0xa5, 0x61, 0x05, 0x2b, 0xea, 0xc5, 0x27, 0xbd, 0xae, 0xc3, 0xc0, - 0x36, 0xb1, 0xb5, 0xbf, 0xdb, 0x60, 0xb1, 0xec, 0x80, 0x6b, 0x77, 0x7b, 0x66, 0x77, 0xfe, 0xfd, - 0x9b, 0xcf, 0x2e, 0x11, 0xa8, 0x02, 0x4e, 0xfa, 0x2c, 0x29, 0x31, 0xee, 0xf4, 0x16, 0xc0, 0xa8, - 0x41, 0x5a, 0xf0, 0xb2, 0xab, 0x3b, 0x5f, 0x76, 0xd3, 0xad, 0xf6, 0x93, 0xee, 0xa6, 0x7b, 0x97, - 0x24, 0x54, 0x73, 0x83, 0x31, 0xa6, 0xf3, 0x18, 0xc1, 0x05, 0xa3, 0x94, 0x5e, 0xd6, 0x1d, 0xa8, - 0x97, 0xae, 0xc2, 0x0e, 0x13, 0xb2, 0x81, 0x5a, 0x8b, 0xdb, 0xab, 0xbb, 0x6f, 0xce, 0xb3, 0xb6, - 0x95, 0x92, 0xfd, 0x31, 0x13, 0x12, 0xdf, 0x9e, 0x70, 0x5d, 0x53, 0xae, 0xb7, 0x66, 0xba, 0xd6, - 0xd1, 0x8c, 0xdb, 0xfe, 0x06, 0xc1, 0xa6, 0xb2, 0xfd, 0x41, 0xd9, 0x9d, 0x7b, 0xbd, 0xa8, 0xcb, - 0x84, 0x28, 0xf7, 0xf5, 0x59, 0x3a, 0x39, 0x15, 0x5e, 0xed, 0xdc, 0xe1, 0xfd, 0x84, 0xf4, 0x86, - 0x3a, 0xed, 0x42, 0x47, 0xf7, 0x0e, 0x58, 0x87, 0xb4, 0x2f, 0x74, 0x6a, 0x5b, 0xe6, 0xd4, 0x46, - 0xe4, 0x8f, 0x68, 0x3f, 0x50, 0xa4, 0xff, 0x2f, 0xad, 0xdf, 0x17, 0x61, 0xdd, 0xb8, 0xe5, 0xf0, - 0x45, 0x78, 0x61, 0x18, 0x55, 0x44, 0x0b, 0x9d, 0xd6, 0xea, 0x20, 0xad, 0x88, 0x16, 0xf8, 0x16, - 0xb4, 0x22, 0x2a, 0x64, 0x28, 0x86, 0x2e, 0xc3, 0x48, 0xc6, 0x61, 0xd4, 0xe1, 0xf1, 0x61, 0x98, - 0x52, 0x96, 0xa4, 0x52, 0xf9, 0xb3, 0x82, 0xcd, 0x12, 0x37, 0x5a, 0x8c, 0x2f, 0x63, 0xbf, 0x04, - 0xdd, 0x51, 0x18, 0xec, 0x83, 0xfd, 0x9c, 0x3a, 0x44, 0xa4, 0x8d, 0xc5, 0x16, 0xda, 0xae, 0x07, - 0x4d, 0x43, 0x15, 0x22, 0x52, 0x2c, 0x60, 0x73, 0xba, 0x86, 0x2c, 0x48, 0x26, 0x48, 0xac, 0x2e, - 0xb6, 0x86, 0xa5, 0xa2, 0x6e, 0x9b, 0xa3, 0xbe, 0x3f, 0x42, 0x4f, 0x1c, 0xbd, 0x29, 0xd1, 0x31, - 0x98, 0xc0, 0xdf, 0x22, 0xb8, 0x3c, 0xad, 0x7a, 0xc4, 0x12, 0xd6, 0x21, 0x99, 0xa4, 0x21, 0xd9, - 0xdf, 0x2f, 0xa8, 0x10, 0xd5, 0x01, 0x59, 0x52, 0xfa, 0x57, 0xcd, 0xfa, 0xa3, 0x36, 0xbc, 0x5f, - 0xf1, 0xe8, 0x70, 0xbf, 0x04, 0xce, 0xa4, 0x87, 0x2f, 0x06, 0x12, 0x1a, 0x59, 0x1e, 0x22, 0xe7, - 0x11, 0xbc, 0x6a, 0x58, 0x02, 0x5e, 0x83, 0x25, 0x96, 0xed, 0xd3, 0x87, 0xaa, 0x87, 0x2f, 0x06, - 0xd5, 0x03, 0xc6, 0x60, 0xa9, 0x6c, 0x6b, 0x2a, 0x5b, 0xf5, 0x1b, 0xb7, 0x60, 0x75, 0x2c, 0x35, - 0x1d, 0xfb, 0xf8, 0xab, 0xb2, 0x56, 0x5e, 0x70, 0x7e, 0xd0, 0xb0, 0xd4, 0xb7, 0xea, 0xc1, 0xf9, - 0x0e, 0xc1, 0xc6, 0x73, 0x16, 0x80, 0xaf, 0x41, 0x5d, 0x45, 0x24, 0xa5, 0xde, 0x49, 0x75, 0xbf, - 0xf1, 0xc7, 0xe3, 0x9d, 0x35, 0xbd, 0x6b, 0x35, 0xe1, 0x9e, 0x2c, 0x58, 0x96, 0x04, 0x23, 0x28, - 0x7e, 0x0b, 0x56, 0x0a, 0x9a, 0xf3, 0xa2, 0xa4, 0xd5, 0x66, 0xd0, 0x86, 0xc8, 0xdd, 0xdf, 0x96, - 0x60, 0x49, 0x1d, 0x40, 0xfc, 0x3d, 0x82, 0xe5, 0xea, 0xce, 0xc7, 0x57, 0xcc, 0xd1, 0x9f, 0x1e, - 0x35, 0xcd, 0x9d, 0x33, 0xa2, 0xab, 0xf5, 0x39, 0xdb, 0x5f, 0xff, 0xf9, 0xef, 0x8f, 0x35, 0x07, - 0xb7, 0xbc, 0x19, 0xd3, 0x10, 0xff, 0x82, 0xe0, 0xe5, 0x53, 0xa3, 0x02, 0x5f, 0x9f, 0x21, 0x67, - 0x1a, 0x4d, 0xcd, 0xb7, 0xe7, 0x27, 0x6a, 0xcb, 0x3b, 0xca, 0xf2, 0x16, 0xbe, 0x64, 0xb6, 0xfc, - 0x68, 0x78, 0x01, 0x7c, 0x85, 0x7f, 0x46, 0x80, 0x4f, 0x0f, 0x03, 0x3c, 0x97, 0xfe, 0xf8, 0xa8, - 0x6a, 0xde, 0x38, 0x07, 0x53, 0x5b, 0xbf, 0xa8, 0xac, 0x6f, 0xe0, 0x75, 0xa3, 0x75, 0xfc, 0x2b, - 0x82, 0x97, 0xa6, 0xaf, 0x5f, 0x7c, 0x6d, 0x86, 0xa4, 0x61, 0x6a, 0x34, 0xaf, 0xcf, 0xcd, 0xd3, - 0x46, 0x6f, 0x28, 0xa3, 0x7b, 0xb8, 0x7d, 0xa6, 0x8c, 0xbd, 0xd1, 0x2d, 0x22, 0xfc, 0x4f, 0x9f, - 0x1c, 0xdb, 0xe8, 0xe9, 0xb1, 0x8d, 0xfe, 0x39, 0xb6, 0xd1, 0x0f, 0x27, 0xf6, 0xc2, 0xd3, 0x13, - 0x7b, 0xe1, 0xaf, 0x13, 0x7b, 0xe1, 0xcb, 0xab, 0x09, 0x93, 0x69, 0x2f, 0x72, 0x63, 0xde, 0x1d, - 0x94, 0x8d, 0x53, 0xc2, 0xb2, 0xa1, 0xc6, 0xc3, 0x29, 0x15, 0xd9, 0xcf, 0xa9, 0x88, 0x96, 0xd5, - 0x3f, 0xab, 0xbd, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x77, 0xc9, 0xbe, 0x6b, 0x0a, 0x00, - 0x00, + 0x4f, 0xb8, 0x02, 0x79, 0xe5, 0xaf, 0x0a, 0xdf, 0x5c, 0x8f, 0xb9, 0xe8, 0x72, 0x11, 0x56, 0x0b, + 0xd5, 0x83, 0x5e, 0xda, 0x4c, 0x38, 0x4f, 0x3a, 0xd4, 0x23, 0x39, 0xf3, 0x48, 0x96, 0x71, 0x49, + 0x24, 0xe3, 0xd9, 0x60, 0xf5, 0xb5, 0x0a, 0xeb, 0x45, 0x44, 0xd0, 0xca, 0x81, 0x77, 0xd4, 0x8e, + 0xa8, 0x24, 0x6d, 0x2f, 0x27, 0x09, 0xcb, 0x14, 0x58, 0x63, 0xaf, 0x18, 0xad, 0xe7, 0xa4, 0x20, + 0xdd, 0x41, 0xc9, 0x6b, 0x46, 0xd8, 0xe4, 0x66, 0x14, 0xda, 0x59, 0x03, 0xfc, 0x49, 0x29, 0xbb, + 0xa7, 0x4a, 0x04, 0xf4, 0x61, 0x8f, 0x0a, 0xe9, 0x7c, 0x0a, 0x2f, 0x4d, 0xbc, 0x15, 0x39, 0xcf, + 0x04, 0xc5, 0x6f, 0xc3, 0x72, 0x25, 0xd5, 0x40, 0x2d, 0xb4, 0xbd, 0x7a, 0xbd, 0xe5, 0x9a, 0x72, + 0x72, 0x2b, 0xa6, 0x6f, 0x3d, 0xf9, 0xfb, 0xd2, 0x42, 0xa0, 0x59, 0xce, 0x5b, 0xf0, 0x8a, 0x2a, + 0xeb, 0xcb, 0xf8, 0xce, 0x10, 0xfd, 0x7e, 0x76, 0xc0, 0xb5, 0x2e, 0xde, 0x80, 0x3a, 0xcd, 0x79, + 0x9c, 0x86, 0x59, 0xaf, 0xab, 0x34, 0xac, 0x60, 0x45, 0xbd, 0xf8, 0xa8, 0xd7, 0x75, 0x18, 0xd8, + 0x26, 0xb6, 0xf6, 0x77, 0x0f, 0x2c, 0x96, 0x1d, 0x70, 0xed, 0x6e, 0xd7, 0xec, 0xce, 0x7f, 0x70, + 0xe7, 0xd9, 0x25, 0x02, 0x55, 0xc0, 0x49, 0x9f, 0x25, 0x25, 0xc6, 0x9d, 0xde, 0x05, 0x18, 0x35, + 0x48, 0x0b, 0x5e, 0x75, 0x75, 0xe7, 0xcb, 0x6e, 0xba, 0xd5, 0x79, 0xd2, 0xdd, 0x74, 0xf7, 0x48, + 0x42, 0x35, 0x37, 0x18, 0x63, 0x3a, 0xbf, 0x20, 0xb8, 0x64, 0x94, 0xd2, 0xdb, 0xda, 0x83, 0x7a, + 0xe9, 0x2a, 0xec, 0x30, 0x21, 0x1b, 0xa8, 0xb5, 0x78, 0xd1, 0xbd, 0xad, 0x94, 0x55, 0x3e, 0x64, + 0x42, 0xe2, 0x7b, 0x13, 0xee, 0x6b, 0xca, 0xfd, 0xd6, 0x5c, 0xf7, 0xba, 0xcc, 0xb8, 0xfd, 0xaf, + 0x10, 0x6c, 0x2a, 0xfb, 0xef, 0x96, 0x5d, 0xba, 0xdf, 0x8b, 0xba, 0x4c, 0x88, 0xf2, 0x7c, 0x9f, + 0xa5, 0xa3, 0x53, 0x21, 0xd6, 0x2e, 0x1c, 0xe2, 0x0f, 0x48, 0x1f, 0xac, 0x59, 0x17, 0x3a, 0xc2, + 0x37, 0xc1, 0x3a, 0xa4, 0x7d, 0xa1, 0xd3, 0xdb, 0x32, 0xa7, 0x37, 0x22, 0x7f, 0x40, 0xfb, 0x81, + 0x22, 0xfd, 0x7f, 0x69, 0xfd, 0xbe, 0x08, 0xeb, 0xc6, 0xf6, 0xe0, 0xcb, 0xf0, 0xdc, 0x30, 0xaa, + 0x88, 0x16, 0x3a, 0xad, 0xd5, 0x41, 0x5a, 0x11, 0x2d, 0xf0, 0x5d, 0x68, 0x45, 0x54, 0xc8, 0x50, + 0x0c, 0x5d, 0x86, 0x91, 0x8c, 0xc3, 0xa8, 0xc3, 0xe3, 0xc3, 0x30, 0xa5, 0x2c, 0x49, 0xa5, 0xf2, + 0x67, 0x05, 0x9b, 0x25, 0x6e, 0xb4, 0x19, 0x5f, 0xc6, 0x7e, 0x09, 0x7a, 0x4f, 0x61, 0xb0, 0x0f, + 0xf6, 0x29, 0x75, 0x88, 0x48, 0x1b, 0x8b, 0x2d, 0xb4, 0x5d, 0x0f, 0x9a, 0x86, 0x2a, 0x44, 0xa4, + 0x58, 0xc0, 0xe6, 0x74, 0x0d, 0x59, 0x90, 0x4c, 0x90, 0x58, 0x5d, 0x70, 0x0d, 0x4b, 0x45, 0xdd, + 0x36, 0x47, 0xfd, 0x60, 0x84, 0x9e, 0x38, 0xa6, 0x53, 0xa2, 0x63, 0x30, 0x81, 0xbf, 0x46, 0x70, + 0x75, 0x5a, 0xf5, 0x88, 0x25, 0xac, 0x43, 0x32, 0x49, 0x43, 0xb2, 0xbf, 0x5f, 0x50, 0x21, 0xaa, + 0x0f, 0x65, 0x49, 0xe9, 0xdf, 0x30, 0xeb, 0x8f, 0xda, 0xf0, 0x4e, 0xc5, 0xa3, 0xc3, 0xf3, 0x12, + 0x38, 0x93, 0x1e, 0x3e, 0x1b, 0x48, 0x68, 0x64, 0xf9, 0x11, 0x39, 0x8f, 0xe1, 0x65, 0xc3, 0x16, + 0xf0, 0x1a, 0x2c, 0xb1, 0x6c, 0x9f, 0x3e, 0x52, 0x3d, 0x7c, 0x3e, 0xa8, 0x1e, 0x30, 0x06, 0x4b, + 0x65, 0x5b, 0x53, 0xd9, 0xaa, 0xdf, 0xb8, 0x05, 0xab, 0x63, 0xa9, 0xe9, 0xd8, 0xc7, 0x5f, 0x95, + 0xb5, 0xf2, 0x82, 0xf3, 0x83, 0x86, 0xa5, 0xd6, 0xaa, 0x07, 0xe7, 0x1b, 0x04, 0x1b, 0xa7, 0x6c, + 0x00, 0xdf, 0x84, 0xba, 0x8a, 0x48, 0x4a, 0x7d, 0x92, 0xea, 0x7e, 0xe3, 0x8f, 0x9f, 0x76, 0xd6, + 0xf4, 0xa9, 0xd5, 0x84, 0xfb, 0xb2, 0x60, 0x59, 0x12, 0x8c, 0xa0, 0xf8, 0x75, 0x58, 0x29, 0x68, + 0xce, 0x8b, 0x92, 0x56, 0x9b, 0x43, 0x1b, 0x22, 0xaf, 0xff, 0xb6, 0x04, 0x4b, 0xea, 0x03, 0xc4, + 0xdf, 0x22, 0x58, 0xae, 0xee, 0x7e, 0x7c, 0xcd, 0x1c, 0xfd, 0xec, 0xc8, 0x69, 0xee, 0x9c, 0x11, + 0x5d, 0xed, 0xcf, 0xd9, 0xfe, 0xf2, 0xcf, 0x7f, 0xbf, 0xaf, 0x39, 0xb8, 0xe5, 0xcd, 0x99, 0x8a, + 0xf8, 0x67, 0x04, 0x2f, 0xce, 0x8c, 0x0c, 0x7c, 0x6b, 0x8e, 0x9c, 0x69, 0x44, 0x35, 0xdf, 0x38, + 0x3f, 0x51, 0x5b, 0xde, 0x51, 0x96, 0xb7, 0xf0, 0x15, 0xb3, 0xe5, 0xc7, 0xc3, 0x0b, 0xe0, 0x0b, + 0xfc, 0x23, 0x02, 0x3c, 0x3b, 0x14, 0xf0, 0xb9, 0xf4, 0xc7, 0x47, 0x56, 0xf3, 0xf6, 0x05, 0x98, + 0xda, 0xfa, 0x65, 0x65, 0x7d, 0x03, 0xaf, 0x1b, 0xad, 0xe3, 0x5f, 0x11, 0xbc, 0x30, 0x7d, 0xfd, + 0xe2, 0x9b, 0x73, 0x24, 0x0d, 0x53, 0xa3, 0x79, 0xeb, 0xdc, 0x3c, 0x6d, 0xf4, 0xb6, 0x32, 0xba, + 0x8b, 0xdb, 0x67, 0xca, 0xd8, 0x1b, 0xdd, 0x22, 0xc2, 0xff, 0xf8, 0xc9, 0xb1, 0x8d, 0x9e, 0x1e, + 0xdb, 0xe8, 0x9f, 0x63, 0x1b, 0x7d, 0x77, 0x62, 0x2f, 0x3c, 0x3d, 0xb1, 0x17, 0xfe, 0x3a, 0xb1, + 0x17, 0x3e, 0xbf, 0x91, 0x30, 0x99, 0xf6, 0x22, 0x37, 0xe6, 0xdd, 0x41, 0xd9, 0x38, 0x25, 0x2c, + 0x1b, 0x6a, 0x3c, 0x9a, 0x52, 0x91, 0xfd, 0x9c, 0x8a, 0x68, 0x59, 0xfd, 0xc3, 0xda, 0xfd, 0x2f, + 0x00, 0x00, 0xff, 0xff, 0xe7, 0x65, 0x4e, 0xb6, 0x73, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1993,7 +1992,7 @@ func (m *QueryBtcCheckpointsInfoResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.InfoList = append(m.InfoList, &BTCCheckpointInfo{}) + m.InfoList = append(m.InfoList, &BTCCheckpointInfoResponse{}) if err := m.InfoList[len(m.InfoList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } From 72d2a8ecc9f632402f1e73841aeb301e559917a9 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 26 Feb 2024 09:53:43 -0300 Subject: [PATCH 018/119] chore: update query `EpochSubmissions` to return directly slice of tx keys (#494) * chore: modified EpochSubmissions query to return client friendly response * chore: removed unused pagination * chore: moved to structure that combines txs keys from same submission * fix: removed unused pagination tag * chore: moved from toResponse to NewSubsmissionKey * chore: update error msg * fix: lint removed unused import * chore: add log err msg --- client/docs/swagger-ui/swagger.yaml | 282 ++++------- proto/babylon/btccheckpoint/v1/query.proto | 26 +- x/btccheckpoint/client/cli/query.go | 14 +- x/btccheckpoint/keeper/grpc_query.go | 66 +-- x/btccheckpoint/types/query.go | 17 + x/btccheckpoint/types/query.pb.go | 548 ++++++++++++++------- x/btccheckpoint/types/query.pb.gw.go | 18 - 7 files changed, 514 insertions(+), 457 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index eb3e79a28..b71b5dc92 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -428,28 +428,24 @@ paths: items: type: object properties: - key: - type: array - items: - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified - by hash of block in - - which transaction was included and transaction index - in the block + first_tx_block_hash: + type: string + description: FirstTxBlockHash is the BTCHeaderHashBytes in hex. + first_tx_index: + type: integer + format: int64 + second_tx_block_hash: + type: string + description: SecondBlockHash is the BTCHeaderHashBytes in hex. + second_tx_index: + type: integer + format: int64 title: >- - Checkpoint can be composed from multiple transactions, so to - identify whole + SubmissionKeyResponse Checkpoint can be composed from + multiple transactions, - submission we need list of transaction keys. + so to identify whole submission we need list of transaction + keys. Each submission can generally be identified by this list of (txIdx, @@ -465,35 +461,7 @@ paths: so there should be other strong arguments for this optimization - description: All submissions saved during an epoch. - pagination: - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: >- - PageResponse is to be embedded in gRPC response messages where - the - - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } + description: Keys All submissions transactions key saved during an epoch. title: >- QueryEpochSubmissionsResponse defines a response to get all submissions in @@ -528,62 +496,6 @@ paths: required: true type: string format: uint64 - - name: pagination.key - description: |- - key is a value returned in PageResponse.next_key to begin - querying the next page most efficiently. Only one of offset or key - should be set. - in: query - required: false - type: string - format: byte - - name: pagination.offset - description: >- - offset is a numeric offset that can be used when key is unavailable. - - It is less efficient than using key. Only one of offset or key - should - - be set. - in: query - required: false - type: string - format: uint64 - - name: pagination.limit - description: >- - limit is the total number of results to be returned in the result - page. - - If left empty it will default to a value to be set by each app. - in: query - required: false - type: string - format: uint64 - - name: pagination.count_total - description: >- - count_total is set to true to indicate that the result set should - include - - a count of the total number of items available for pagination in - UIs. - - count_total is only respected when offset is used. It is ignored - when key - - is set. - in: query - required: false - type: boolean - - name: pagination.reverse - description: >- - reverse is set to true if results are to be returned in the - descending order. - - - Since: cosmos-sdk 0.43 - in: query - required: false - type: boolean tags: - Query /babylon/btclightclient/v1/baseheader: @@ -9837,28 +9749,23 @@ definitions: items: type: object properties: - key: - type: array - items: - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified by hash - of block in - - which transaction was included and transaction index in the - block + first_tx_block_hash: + type: string + description: FirstTxBlockHash is the BTCHeaderHashBytes in hex. + first_tx_index: + type: integer + format: int64 + second_tx_block_hash: + type: string + description: SecondBlockHash is the BTCHeaderHashBytes in hex. + second_tx_index: + type: integer + format: int64 title: >- - Checkpoint can be composed from multiple transactions, so to - identify whole + SubmissionKeyResponse Checkpoint can be composed from multiple + transactions, - submission we need list of transaction keys. + so to identify whole submission we need list of transaction keys. Each submission can generally be identified by this list of (txIdx, @@ -9872,33 +9779,7 @@ definitions: byte hash), so there should be other strong arguments for this optimization - description: All submissions saved during an epoch. - pagination: - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } + description: Keys All submissions transactions key saved during an epoch. title: |- QueryEpochSubmissionsResponse defines a response to get all submissions in given epoch (QueryEpochSubmissionsRequest) @@ -9945,30 +9826,26 @@ definitions: related to babylon description: QueryParamsResponse is response type for the Query/Params RPC method. - babylon.btccheckpoint.v1.SubmissionKey: + babylon.btccheckpoint.v1.SubmissionKeyResponse: type: object properties: - key: - type: array - items: - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: >- - Each provided OP_RETURN transaction can be idendtified by hash of - block in - - which transaction was included and transaction index in the block + first_tx_block_hash: + type: string + description: FirstTxBlockHash is the BTCHeaderHashBytes in hex. + first_tx_index: + type: integer + format: int64 + second_tx_block_hash: + type: string + description: SecondBlockHash is the BTCHeaderHashBytes in hex. + second_tx_index: + type: integer + format: int64 title: >- - Checkpoint can be composed from multiple transactions, so to identify - whole + SubmissionKeyResponse Checkpoint can be composed from multiple + transactions, - submission we need list of transaction keys. + so to identify whole submission we need list of transaction keys. Each submission can generally be identified by this list of (txIdx, @@ -10006,18 +9883,6 @@ definitions: - the position of the tx on BTC blockchain - the full tx content - the Merkle proof that this tx is on the above position - babylon.btccheckpoint.v1.TransactionKey: - type: object - properties: - index: - type: integer - format: int64 - hash: - type: string - format: byte - title: |- - Each provided OP_RETURN transaction can be idendtified by hash of block in - which transaction was included and transaction index in the block cosmos.base.query.v1beta1.PageRequest: type: object properties: @@ -14098,6 +13963,43 @@ definitions: title: |- ValidatorWithBlsKey couples validator address, voting power, and its bls public key + babylon.btccheckpoint.v1.SubmissionKey: + type: object + properties: + key: + type: array + items: + type: object + properties: + index: + type: integer + format: int64 + hash: + type: string + format: byte + title: >- + Each provided OP_RETURN transaction can be idendtified by hash of + block in + + which transaction was included and transaction index in the block + title: >- + Checkpoint can be composed from multiple transactions, so to identify + whole + + submission we need list of transaction keys. + + Each submission can generally be identified by this list of (txIdx, + + blockHash) tuples. Note: this could possibly be optimized as if + transactions + + were in one block they would have the same block hash and different + indexes, + + but each blockhash is only 33 (1 byte for prefix encoding and 32 byte + hash), + + so there should be other strong arguments for this optimization babylon.btccheckpoint.v1.TransactionInfo: type: object properties: @@ -14143,6 +14045,18 @@ definitions: - the position of the tx on BTC blockchain - the full tx content - the Merkle proof that this tx is on the above position + babylon.btccheckpoint.v1.TransactionKey: + type: object + properties: + index: + type: integer + format: int64 + hash: + type: string + format: byte + title: |- + Each provided OP_RETURN transaction can be idendtified by hash of block in + which transaction was included and transaction index in the block babylon.zoneconcierge.v1.ChainInfo: type: object properties: diff --git a/proto/babylon/btccheckpoint/v1/query.proto b/proto/babylon/btccheckpoint/v1/query.proto index 216fafb1c..9fc55b2c8 100644 --- a/proto/babylon/btccheckpoint/v1/query.proto +++ b/proto/babylon/btccheckpoint/v1/query.proto @@ -6,7 +6,6 @@ import "cosmos_proto/cosmos.proto"; import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btccheckpoint/v1/params.proto"; -import "babylon/btccheckpoint/v1/btccheckpoint.proto"; option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; @@ -78,17 +77,13 @@ message QueryBtcCheckpointsInfoResponse { message QueryEpochSubmissionsRequest { // Number of epoch for which submissions are requested uint64 epoch_num = 1; - - cosmos.base.query.v1beta1.PageRequest pagination = 2; } // QueryEpochSubmissionsResponse defines a response to get all submissions in // given epoch (QueryEpochSubmissionsRequest) message QueryEpochSubmissionsResponse { - // All submissions saved during an epoch. - repeated SubmissionKey keys = 1; - - cosmos.base.query.v1beta1.PageResponse pagination = 2; + // Keys All submissions transactions key saved during an epoch. + repeated SubmissionKeyResponse keys = 1; } // BTCCheckpointInfoResponse contains all data about best submission of checkpoint for @@ -133,3 +128,20 @@ message CheckpointAddressesResponse { // calculated from submission message MsgInsertBTCSpvProof itself string reporter = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; } + +// SubmissionKeyResponse Checkpoint can be composed from multiple transactions, +// so to identify whole submission we need list of transaction keys. +// Each submission can generally be identified by this list of (txIdx, +// blockHash) tuples. Note: this could possibly be optimized as if transactions +// were in one block they would have the same block hash and different indexes, +// but each blockhash is only 33 (1 byte for prefix encoding and 32 byte hash), +// so there should be other strong arguments for this optimization +message SubmissionKeyResponse { + // FirstTxBlockHash is the BTCHeaderHashBytes in hex. + string first_tx_block_hash = 1; + uint32 first_tx_index = 2; + + // SecondBlockHash is the BTCHeaderHashBytes in hex. + string second_tx_block_hash = 3; + uint32 second_tx_index = 4; +} \ No newline at end of file diff --git a/x/btccheckpoint/client/cli/query.go b/x/btccheckpoint/client/cli/query.go index 49a2376cd..07d645da6 100644 --- a/x/btccheckpoint/client/cli/query.go +++ b/x/btccheckpoint/client/cli/query.go @@ -70,24 +70,15 @@ func CmdEpochSubmissions() *cobra.Command { Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx := client.GetClientContextFromCmd(cmd) - queryClient := types.NewQueryClient(clientCtx) epochNum, err := strconv.ParseUint(args[0], 10, 64) - - if err != nil { - return err - } - - pageReq, err := client.ReadPageRequest(cmd.Flags()) if err != nil { return err } - params := types.QueryEpochSubmissionsRequest{EpochNum: epochNum, Pagination: pageReq} - - res, err := queryClient.EpochSubmissions(context.Background(), ¶ms) - + req := types.QueryEpochSubmissionsRequest{EpochNum: epochNum} + res, err := queryClient.EpochSubmissions(context.Background(), &req) if err != nil { return err } @@ -97,7 +88,6 @@ func CmdEpochSubmissions() *cobra.Command { } flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "epoch-submissions") return cmd } diff --git a/x/btccheckpoint/keeper/grpc_query.go b/x/btccheckpoint/keeper/grpc_query.go index 833bb7a9c..81986aea5 100644 --- a/x/btccheckpoint/keeper/grpc_query.go +++ b/x/btccheckpoint/keeper/grpc_query.go @@ -91,75 +91,33 @@ func (k Keeper) BtcCheckpointsInfo(ctx context.Context, req *types.QueryBtcCheck }, nil } -func getOffset(pageReq *query.PageRequest) uint64 { - if pageReq == nil { - return 0 - } else { - return pageReq.Offset - } -} - -func buildPageResponse(numOfKeys uint64, pageReq *query.PageRequest) *query.PageResponse { - if pageReq == nil { - return &query.PageResponse{} - } - - if !pageReq.CountTotal { - return &query.PageResponse{} - } - - return &query.PageResponse{Total: numOfKeys} -} - func (k Keeper) EpochSubmissions(c context.Context, req *types.QueryEpochSubmissionsRequest) (*types.QueryEpochSubmissionsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - ctx := sdk.UnwrapSDKContext(c) - checkpointEpoch := req.GetEpochNum() - - _, limit, err := query.ParsePagination(req.Pagination) - - offset := getOffset(req.Pagination) - - if err != nil { - return nil, err - } - - epochData := k.GetEpochData(ctx, checkpointEpoch) - + epoch := req.GetEpochNum() + epochData := k.GetEpochData(ctx, epoch) if epochData == nil || len(epochData.Keys) == 0 { - return &types.QueryEpochSubmissionsResponse{ - Keys: []*types.SubmissionKey{}, - Pagination: buildPageResponse(0, req.Pagination), + Keys: []*types.SubmissionKeyResponse{}, }, nil } - numberOfKeys := uint64(len((epochData.Keys))) - - if offset >= numberOfKeys { - // offset larger than number of keys return empty response - return &types.QueryEpochSubmissionsResponse{ - Keys: []*types.SubmissionKey{}, - Pagination: buildPageResponse(numberOfKeys, req.Pagination), - }, nil - } - - var responseKeys []*types.SubmissionKey - - for i := offset; i < numberOfKeys; i++ { - if len(responseKeys) == limit { - break + submKeysResp := make([]*types.SubmissionKeyResponse, len(epochData.Keys)) + for i, submKey := range epochData.Keys { + skr, err := types.NewSubmissionKeyResponse(*submKey) + if err != nil { + errMsgf := "epoch submission: this error should not happen, check DB corruption and proto files: %v" + k.Logger(ctx).Error(errMsgf, err) + return nil, status.Errorf(codes.Internal, errMsgf, err) } - responseKeys = append(responseKeys, epochData.Keys[i]) + submKeysResp[i] = skr } return &types.QueryEpochSubmissionsResponse{ - Keys: responseKeys, - Pagination: buildPageResponse(numberOfKeys, req.Pagination), + Keys: submKeysResp, }, nil } diff --git a/x/btccheckpoint/types/query.go b/x/btccheckpoint/types/query.go index 98263e8c5..e2d51a647 100644 --- a/x/btccheckpoint/types/query.go +++ b/x/btccheckpoint/types/query.go @@ -4,6 +4,8 @@ import ( "encoding/hex" "github.com/cosmos/cosmos-sdk/types" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" ) // ToResponse parses a TransactionInfo into a query response tx info struct. @@ -24,6 +26,21 @@ func (ca *CheckpointAddresses) ToResponse() *CheckpointAddressesResponse { } } +// NewSubmissionKeyResponse parses a SubmissionKey into a query response submission key struct. +func NewSubmissionKeyResponse(sk SubmissionKey) (skr *SubmissionKeyResponse, err error) { + if len(sk.Key) != 2 { + return nil, status.Errorf(codes.Internal, "bad submission key %+v, does not have 2 keys", sk) + } + + k1, k2 := sk.Key[0], sk.Key[1] + return &SubmissionKeyResponse{ + FirstTxBlockHash: k1.Hash.MarshalHex(), + FirstTxIndex: k1.Index, + SecondTxBlockHash: k2.Hash.MarshalHex(), + SecondTxIndex: k2.Index, + }, nil +} + // ToResponse parses a BTCCheckpointInfo into a query response for btc checkpoint info struct. func (b BTCCheckpointInfo) ToResponse() *BTCCheckpointInfoResponse { bestSubTxs := make([]*TransactionInfoResponse, len(b.BestSubmissionTransactions)) diff --git a/x/btccheckpoint/types/query.pb.go b/x/btccheckpoint/types/query.pb.go index e03f9655b..05ce91205 100644 --- a/x/btccheckpoint/types/query.pb.go +++ b/x/btccheckpoint/types/query.pb.go @@ -314,8 +314,7 @@ func (m *QueryBtcCheckpointsInfoResponse) GetPagination() *query.PageResponse { // given epoch type QueryEpochSubmissionsRequest struct { // Number of epoch for which submissions are requested - EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` } func (m *QueryEpochSubmissionsRequest) Reset() { *m = QueryEpochSubmissionsRequest{} } @@ -358,19 +357,11 @@ func (m *QueryEpochSubmissionsRequest) GetEpochNum() uint64 { return 0 } -func (m *QueryEpochSubmissionsRequest) GetPagination() *query.PageRequest { - if m != nil { - return m.Pagination - } - return nil -} - // QueryEpochSubmissionsResponse defines a response to get all submissions in // given epoch (QueryEpochSubmissionsRequest) type QueryEpochSubmissionsResponse struct { - // All submissions saved during an epoch. - Keys []*SubmissionKey `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + // Keys All submissions transactions key saved during an epoch. + Keys []*SubmissionKeyResponse `protobuf:"bytes,1,rep,name=keys,proto3" json:"keys,omitempty"` } func (m *QueryEpochSubmissionsResponse) Reset() { *m = QueryEpochSubmissionsResponse{} } @@ -406,20 +397,13 @@ func (m *QueryEpochSubmissionsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryEpochSubmissionsResponse proto.InternalMessageInfo -func (m *QueryEpochSubmissionsResponse) GetKeys() []*SubmissionKey { +func (m *QueryEpochSubmissionsResponse) GetKeys() []*SubmissionKeyResponse { if m != nil { return m.Keys } return nil } -func (m *QueryEpochSubmissionsResponse) GetPagination() *query.PageResponse { - if m != nil { - return m.Pagination - } - return nil -} - // BTCCheckpointInfoResponse contains all data about best submission of checkpoint for // given epoch. Best submission is the submission which is deeper in btc ledger. type BTCCheckpointInfoResponse struct { @@ -639,6 +623,83 @@ func (m *CheckpointAddressesResponse) GetReporter() string { return "" } +// SubmissionKeyResponse Checkpoint can be composed from multiple transactions, +// so to identify whole submission we need list of transaction keys. +// Each submission can generally be identified by this list of (txIdx, +// blockHash) tuples. Note: this could possibly be optimized as if transactions +// were in one block they would have the same block hash and different indexes, +// but each blockhash is only 33 (1 byte for prefix encoding and 32 byte hash), +// so there should be other strong arguments for this optimization +type SubmissionKeyResponse struct { + // FirstTxBlockHash is the BTCHeaderHashBytes in hex. + FirstTxBlockHash string `protobuf:"bytes,1,opt,name=first_tx_block_hash,json=firstTxBlockHash,proto3" json:"first_tx_block_hash,omitempty"` + FirstTxIndex uint32 `protobuf:"varint,2,opt,name=first_tx_index,json=firstTxIndex,proto3" json:"first_tx_index,omitempty"` + // SecondBlockHash is the BTCHeaderHashBytes in hex. + SecondTxBlockHash string `protobuf:"bytes,3,opt,name=second_tx_block_hash,json=secondTxBlockHash,proto3" json:"second_tx_block_hash,omitempty"` + SecondTxIndex uint32 `protobuf:"varint,4,opt,name=second_tx_index,json=secondTxIndex,proto3" json:"second_tx_index,omitempty"` +} + +func (m *SubmissionKeyResponse) Reset() { *m = SubmissionKeyResponse{} } +func (m *SubmissionKeyResponse) String() string { return proto.CompactTextString(m) } +func (*SubmissionKeyResponse) ProtoMessage() {} +func (*SubmissionKeyResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_6b9a2f46ada7d854, []int{11} +} +func (m *SubmissionKeyResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SubmissionKeyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SubmissionKeyResponse.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 *SubmissionKeyResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubmissionKeyResponse.Merge(m, src) +} +func (m *SubmissionKeyResponse) XXX_Size() int { + return m.Size() +} +func (m *SubmissionKeyResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SubmissionKeyResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SubmissionKeyResponse proto.InternalMessageInfo + +func (m *SubmissionKeyResponse) GetFirstTxBlockHash() string { + if m != nil { + return m.FirstTxBlockHash + } + return "" +} + +func (m *SubmissionKeyResponse) GetFirstTxIndex() uint32 { + if m != nil { + return m.FirstTxIndex + } + return 0 +} + +func (m *SubmissionKeyResponse) GetSecondTxBlockHash() string { + if m != nil { + return m.SecondTxBlockHash + } + return "" +} + +func (m *SubmissionKeyResponse) GetSecondTxIndex() uint32 { + if m != nil { + return m.SecondTxIndex + } + return 0 +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btccheckpoint.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btccheckpoint.v1.QueryParamsResponse") @@ -651,6 +712,7 @@ func init() { proto.RegisterType((*BTCCheckpointInfoResponse)(nil), "babylon.btccheckpoint.v1.BTCCheckpointInfoResponse") proto.RegisterType((*TransactionInfoResponse)(nil), "babylon.btccheckpoint.v1.TransactionInfoResponse") proto.RegisterType((*CheckpointAddressesResponse)(nil), "babylon.btccheckpoint.v1.CheckpointAddressesResponse") + proto.RegisterType((*SubmissionKeyResponse)(nil), "babylon.btccheckpoint.v1.SubmissionKeyResponse") } func init() { @@ -658,63 +720,67 @@ func init() { } var fileDescriptor_6b9a2f46ada7d854 = []byte{ - // 892 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0xdc, 0x44, - 0x18, 0xcd, 0x6c, 0x9c, 0x28, 0xfb, 0x05, 0x24, 0x18, 0x22, 0xb1, 0xd9, 0x04, 0x77, 0x6b, 0xd1, - 0x26, 0x42, 0x8d, 0xad, 0x6d, 0x68, 0x4b, 0x05, 0x42, 0xc2, 0x15, 0x2d, 0x08, 0x04, 0xc1, 0x2d, - 0x1c, 0xb8, 0x58, 0x63, 0x67, 0x62, 0x8f, 0xb2, 0xeb, 0x71, 0x3d, 0xb3, 0x51, 0x57, 0x15, 0x17, - 0x38, 0x21, 0x0e, 0x20, 0xf1, 0x37, 0x70, 0xe3, 0x08, 0x37, 0x84, 0xc4, 0xad, 0x12, 0x97, 0x0a, - 0x2e, 0x9c, 0x10, 0x4a, 0xf8, 0x43, 0x90, 0xc7, 0xb3, 0xbf, 0x3b, 0xd9, 0x24, 0xe2, 0xb6, 0xf6, - 0xbc, 0xf7, 0xbd, 0x37, 0xef, 0x1b, 0xcf, 0xb7, 0xf0, 0x6a, 0x44, 0xa2, 0x7e, 0x87, 0x67, 0x5e, - 0x24, 0xe3, 0x38, 0xa5, 0xf1, 0x61, 0xce, 0x59, 0x26, 0xbd, 0xa3, 0xb6, 0xf7, 0xb0, 0x47, 0x8b, - 0xbe, 0x9b, 0x17, 0x5c, 0x72, 0xdc, 0xd0, 0x28, 0x77, 0x02, 0xe5, 0x1e, 0xb5, 0x9b, 0x6b, 0x09, - 0x4f, 0xb8, 0x02, 0x79, 0xe5, 0xaf, 0x0a, 0xdf, 0x5c, 0x8f, 0xb9, 0xe8, 0x72, 0x11, 0x56, 0x0b, - 0xd5, 0x83, 0x5e, 0xda, 0x4c, 0x38, 0x4f, 0x3a, 0xd4, 0x23, 0x39, 0xf3, 0x48, 0x96, 0x71, 0x49, - 0x24, 0xe3, 0xd9, 0x60, 0xf5, 0xb5, 0x0a, 0xeb, 0x45, 0x44, 0xd0, 0xca, 0x81, 0x77, 0xd4, 0x8e, - 0xa8, 0x24, 0x6d, 0x2f, 0x27, 0x09, 0xcb, 0x14, 0x58, 0x63, 0xaf, 0x18, 0xad, 0xe7, 0xa4, 0x20, - 0xdd, 0x41, 0xc9, 0x6b, 0x46, 0xd8, 0xe4, 0x66, 0x14, 0xda, 0x59, 0x03, 0xfc, 0x49, 0x29, 0xbb, - 0xa7, 0x4a, 0x04, 0xf4, 0x61, 0x8f, 0x0a, 0xe9, 0x7c, 0x0a, 0x2f, 0x4d, 0xbc, 0x15, 0x39, 0xcf, - 0x04, 0xc5, 0x6f, 0xc3, 0x72, 0x25, 0xd5, 0x40, 0x2d, 0xb4, 0xbd, 0x7a, 0xbd, 0xe5, 0x9a, 0x72, - 0x72, 0x2b, 0xa6, 0x6f, 0x3d, 0xf9, 0xfb, 0xd2, 0x42, 0xa0, 0x59, 0xce, 0x5b, 0xf0, 0x8a, 0x2a, - 0xeb, 0xcb, 0xf8, 0xce, 0x10, 0xfd, 0x7e, 0x76, 0xc0, 0xb5, 0x2e, 0xde, 0x80, 0x3a, 0xcd, 0x79, - 0x9c, 0x86, 0x59, 0xaf, 0xab, 0x34, 0xac, 0x60, 0x45, 0xbd, 0xf8, 0xa8, 0xd7, 0x75, 0x18, 0xd8, - 0x26, 0xb6, 0xf6, 0x77, 0x0f, 0x2c, 0x96, 0x1d, 0x70, 0xed, 0x6e, 0xd7, 0xec, 0xce, 0x7f, 0x70, - 0xe7, 0xd9, 0x25, 0x02, 0x55, 0xc0, 0x49, 0x9f, 0x25, 0x25, 0xc6, 0x9d, 0xde, 0x05, 0x18, 0x35, - 0x48, 0x0b, 0x5e, 0x75, 0x75, 0xe7, 0xcb, 0x6e, 0xba, 0xd5, 0x79, 0xd2, 0xdd, 0x74, 0xf7, 0x48, - 0x42, 0x35, 0x37, 0x18, 0x63, 0x3a, 0xbf, 0x20, 0xb8, 0x64, 0x94, 0xd2, 0xdb, 0xda, 0x83, 0x7a, - 0xe9, 0x2a, 0xec, 0x30, 0x21, 0x1b, 0xa8, 0xb5, 0x78, 0xd1, 0xbd, 0xad, 0x94, 0x55, 0x3e, 0x64, - 0x42, 0xe2, 0x7b, 0x13, 0xee, 0x6b, 0xca, 0xfd, 0xd6, 0x5c, 0xf7, 0xba, 0xcc, 0xb8, 0xfd, 0xaf, - 0x10, 0x6c, 0x2a, 0xfb, 0xef, 0x96, 0x5d, 0xba, 0xdf, 0x8b, 0xba, 0x4c, 0x88, 0xf2, 0x7c, 0x9f, - 0xa5, 0xa3, 0x53, 0x21, 0xd6, 0x2e, 0x1c, 0xe2, 0x0f, 0x48, 0x1f, 0xac, 0x59, 0x17, 0x3a, 0xc2, - 0x37, 0xc1, 0x3a, 0xa4, 0x7d, 0xa1, 0xd3, 0xdb, 0x32, 0xa7, 0x37, 0x22, 0x7f, 0x40, 0xfb, 0x81, - 0x22, 0xfd, 0x7f, 0x69, 0xfd, 0xbe, 0x08, 0xeb, 0xc6, 0xf6, 0xe0, 0xcb, 0xf0, 0xdc, 0x30, 0xaa, - 0x88, 0x16, 0x3a, 0xad, 0xd5, 0x41, 0x5a, 0x11, 0x2d, 0xf0, 0x5d, 0x68, 0x45, 0x54, 0xc8, 0x50, - 0x0c, 0x5d, 0x86, 0x91, 0x8c, 0xc3, 0xa8, 0xc3, 0xe3, 0xc3, 0x30, 0xa5, 0x2c, 0x49, 0xa5, 0xf2, - 0x67, 0x05, 0x9b, 0x25, 0x6e, 0xb4, 0x19, 0x5f, 0xc6, 0x7e, 0x09, 0x7a, 0x4f, 0x61, 0xb0, 0x0f, - 0xf6, 0x29, 0x75, 0x88, 0x48, 0x1b, 0x8b, 0x2d, 0xb4, 0x5d, 0x0f, 0x9a, 0x86, 0x2a, 0x44, 0xa4, - 0x58, 0xc0, 0xe6, 0x74, 0x0d, 0x59, 0x90, 0x4c, 0x90, 0x58, 0x5d, 0x70, 0x0d, 0x4b, 0x45, 0xdd, - 0x36, 0x47, 0xfd, 0x60, 0x84, 0x9e, 0x38, 0xa6, 0x53, 0xa2, 0x63, 0x30, 0x81, 0xbf, 0x46, 0x70, - 0x75, 0x5a, 0xf5, 0x88, 0x25, 0xac, 0x43, 0x32, 0x49, 0x43, 0xb2, 0xbf, 0x5f, 0x50, 0x21, 0xaa, - 0x0f, 0x65, 0x49, 0xe9, 0xdf, 0x30, 0xeb, 0x8f, 0xda, 0xf0, 0x4e, 0xc5, 0xa3, 0xc3, 0xf3, 0x12, - 0x38, 0x93, 0x1e, 0x3e, 0x1b, 0x48, 0x68, 0x64, 0xf9, 0x11, 0x39, 0x8f, 0xe1, 0x65, 0xc3, 0x16, - 0xf0, 0x1a, 0x2c, 0xb1, 0x6c, 0x9f, 0x3e, 0x52, 0x3d, 0x7c, 0x3e, 0xa8, 0x1e, 0x30, 0x06, 0x4b, - 0x65, 0x5b, 0x53, 0xd9, 0xaa, 0xdf, 0xb8, 0x05, 0xab, 0x63, 0xa9, 0xe9, 0xd8, 0xc7, 0x5f, 0x95, - 0xb5, 0xf2, 0x82, 0xf3, 0x83, 0x86, 0xa5, 0xd6, 0xaa, 0x07, 0xe7, 0x1b, 0x04, 0x1b, 0xa7, 0x6c, - 0x00, 0xdf, 0x84, 0xba, 0x8a, 0x48, 0x4a, 0x7d, 0x92, 0xea, 0x7e, 0xe3, 0x8f, 0x9f, 0x76, 0xd6, - 0xf4, 0xa9, 0xd5, 0x84, 0xfb, 0xb2, 0x60, 0x59, 0x12, 0x8c, 0xa0, 0xf8, 0x75, 0x58, 0x29, 0x68, - 0xce, 0x8b, 0x92, 0x56, 0x9b, 0x43, 0x1b, 0x22, 0xaf, 0xff, 0xb6, 0x04, 0x4b, 0xea, 0x03, 0xc4, - 0xdf, 0x22, 0x58, 0xae, 0xee, 0x7e, 0x7c, 0xcd, 0x1c, 0xfd, 0xec, 0xc8, 0x69, 0xee, 0x9c, 0x11, - 0x5d, 0xed, 0xcf, 0xd9, 0xfe, 0xf2, 0xcf, 0x7f, 0xbf, 0xaf, 0x39, 0xb8, 0xe5, 0xcd, 0x99, 0x8a, - 0xf8, 0x67, 0x04, 0x2f, 0xce, 0x8c, 0x0c, 0x7c, 0x6b, 0x8e, 0x9c, 0x69, 0x44, 0x35, 0xdf, 0x38, - 0x3f, 0x51, 0x5b, 0xde, 0x51, 0x96, 0xb7, 0xf0, 0x15, 0xb3, 0xe5, 0xc7, 0xc3, 0x0b, 0xe0, 0x0b, - 0xfc, 0x23, 0x02, 0x3c, 0x3b, 0x14, 0xf0, 0xb9, 0xf4, 0xc7, 0x47, 0x56, 0xf3, 0xf6, 0x05, 0x98, - 0xda, 0xfa, 0x65, 0x65, 0x7d, 0x03, 0xaf, 0x1b, 0xad, 0xe3, 0x5f, 0x11, 0xbc, 0x30, 0x7d, 0xfd, - 0xe2, 0x9b, 0x73, 0x24, 0x0d, 0x53, 0xa3, 0x79, 0xeb, 0xdc, 0x3c, 0x6d, 0xf4, 0xb6, 0x32, 0xba, - 0x8b, 0xdb, 0x67, 0xca, 0xd8, 0x1b, 0xdd, 0x22, 0xc2, 0xff, 0xf8, 0xc9, 0xb1, 0x8d, 0x9e, 0x1e, - 0xdb, 0xe8, 0x9f, 0x63, 0x1b, 0x7d, 0x77, 0x62, 0x2f, 0x3c, 0x3d, 0xb1, 0x17, 0xfe, 0x3a, 0xb1, - 0x17, 0x3e, 0xbf, 0x91, 0x30, 0x99, 0xf6, 0x22, 0x37, 0xe6, 0xdd, 0x41, 0xd9, 0x38, 0x25, 0x2c, - 0x1b, 0x6a, 0x3c, 0x9a, 0x52, 0x91, 0xfd, 0x9c, 0x8a, 0x68, 0x59, 0xfd, 0xc3, 0xda, 0xfd, 0x2f, - 0x00, 0x00, 0xff, 0xff, 0xe7, 0x65, 0x4e, 0xb6, 0x73, 0x0a, 0x00, 0x00, + // 949 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x41, 0x6f, 0xdc, 0x44, + 0x14, 0x8e, 0x37, 0x4e, 0x94, 0x7d, 0x69, 0xa1, 0x9d, 0x2e, 0x62, 0xb3, 0x09, 0xdb, 0xad, 0xd5, + 0xa6, 0x11, 0x22, 0xb6, 0xb6, 0xa1, 0x2d, 0x15, 0x08, 0x89, 0x8d, 0x68, 0xa9, 0x40, 0x10, 0xdc, + 0xc0, 0x81, 0x8b, 0x35, 0xf6, 0x4e, 0xec, 0x51, 0x76, 0x3d, 0xae, 0x67, 0x36, 0xca, 0xaa, 0xe2, + 0xc2, 0x0d, 0x71, 0x00, 0x89, 0xbf, 0xc1, 0x11, 0x6e, 0x08, 0x89, 0x03, 0x52, 0x25, 0x2e, 0x15, + 0x5c, 0x38, 0x21, 0x94, 0xf0, 0x43, 0x2a, 0xcf, 0xcc, 0xae, 0xbd, 0x9b, 0xb8, 0x9b, 0xf4, 0xb6, + 0xf6, 0x7c, 0xdf, 0xf7, 0xbe, 0xf9, 0xde, 0x8b, 0x5f, 0xe0, 0xba, 0x8f, 0xfd, 0x61, 0x8f, 0xc5, + 0x8e, 0x2f, 0x82, 0x20, 0x22, 0xc1, 0x7e, 0xc2, 0x68, 0x2c, 0x9c, 0x83, 0xb6, 0xf3, 0x78, 0x40, + 0xd2, 0xa1, 0x9d, 0xa4, 0x4c, 0x30, 0x54, 0xd7, 0x28, 0x7b, 0x02, 0x65, 0x1f, 0xb4, 0x1b, 0xb5, + 0x90, 0x85, 0x4c, 0x82, 0x9c, 0xec, 0x97, 0xc2, 0x37, 0x56, 0x02, 0xc6, 0xfb, 0x8c, 0x7b, 0xea, + 0x40, 0x3d, 0xe8, 0xa3, 0xb5, 0x90, 0xb1, 0xb0, 0x47, 0x1c, 0x9c, 0x50, 0x07, 0xc7, 0x31, 0x13, + 0x58, 0x50, 0x16, 0x8f, 0x4e, 0xdf, 0x54, 0x58, 0xc7, 0xc7, 0x9c, 0x28, 0x07, 0xce, 0x41, 0xdb, + 0x27, 0x02, 0xb7, 0x9d, 0x04, 0x87, 0x34, 0x96, 0x60, 0x8d, 0xbd, 0x51, 0x6a, 0x3d, 0xc1, 0x29, + 0xee, 0x6b, 0x49, 0xab, 0x06, 0xe8, 0xf3, 0x4c, 0x68, 0x47, 0xbe, 0x74, 0xc9, 0xe3, 0x01, 0xe1, + 0xc2, 0xfa, 0x02, 0xae, 0x4c, 0xbc, 0xe5, 0x09, 0x8b, 0x39, 0x41, 0xef, 0xc3, 0xa2, 0x22, 0xd7, + 0x8d, 0x96, 0xb1, 0xb1, 0x7c, 0xab, 0x65, 0x97, 0xdd, 0xdc, 0x56, 0xcc, 0x8e, 0xf9, 0xf4, 0xdf, + 0xab, 0x73, 0xae, 0x66, 0x59, 0xef, 0xc1, 0x1b, 0x52, 0xb6, 0x23, 0x82, 0xed, 0x31, 0xfa, 0x61, + 0xbc, 0xc7, 0x74, 0x5d, 0xb4, 0x0a, 0x55, 0x92, 0xb0, 0x20, 0xf2, 0xe2, 0x41, 0x5f, 0xd6, 0x30, + 0xdd, 0x25, 0xf9, 0xe2, 0xd3, 0x41, 0xdf, 0xa2, 0xd0, 0x2c, 0x63, 0x6b, 0x7f, 0x0f, 0xc0, 0xa4, + 0xf1, 0x1e, 0xd3, 0xee, 0xb6, 0xca, 0xdd, 0x75, 0x76, 0xb7, 0x4f, 0x97, 0x70, 0xa5, 0x80, 0x15, + 0x9d, 0x56, 0x8a, 0x17, 0x9d, 0xde, 0x07, 0xc8, 0x23, 0xd7, 0x05, 0xd7, 0x6d, 0xdd, 0xcb, 0xac, + 0x3f, 0xb6, 0x9a, 0x10, 0xdd, 0x1f, 0x7b, 0x07, 0x87, 0x44, 0x73, 0xdd, 0x02, 0xd3, 0xfa, 0xd5, + 0x80, 0xab, 0xa5, 0xa5, 0xf4, 0xb5, 0x76, 0xa0, 0x9a, 0xb9, 0xf2, 0x7a, 0x94, 0x8b, 0xba, 0xd1, + 0x9a, 0x7f, 0xd9, 0xbb, 0x2d, 0x65, 0x2a, 0x9f, 0x50, 0x2e, 0xd0, 0x83, 0x09, 0xf7, 0x15, 0xe9, + 0xfe, 0xe6, 0x4c, 0xf7, 0x5a, 0xa6, 0x68, 0xff, 0x5d, 0x58, 0x93, 0xee, 0x3f, 0xcc, 0x9a, 0xf4, + 0x68, 0xe0, 0xf7, 0x29, 0xe7, 0xd9, 0xc0, 0x9e, 0xa9, 0xa1, 0x5d, 0x3d, 0x0e, 0x27, 0xc9, 0xfa, + 0xe2, 0xdb, 0x60, 0xee, 0x93, 0x21, 0xd7, 0x77, 0x76, 0xca, 0xef, 0x9c, 0x93, 0x3f, 0x26, 0xc3, + 0xbc, 0x97, 0x19, 0xd9, 0xfa, 0x73, 0x1e, 0x56, 0x4a, 0x33, 0x41, 0xd7, 0xe0, 0xc2, 0xd8, 0xa0, + 0x4f, 0x52, 0xed, 0x71, 0x79, 0xe4, 0xd1, 0x27, 0x29, 0xba, 0x0f, 0x2d, 0x9f, 0x70, 0xe1, 0xf1, + 0x71, 0x11, 0xcf, 0x17, 0x81, 0xe7, 0xf7, 0x58, 0xb0, 0xef, 0x45, 0x84, 0x86, 0x91, 0x90, 0x11, + 0x9a, 0xee, 0x5a, 0x86, 0xcb, 0xbd, 0x74, 0x44, 0xd0, 0xc9, 0x40, 0x1f, 0x49, 0x0c, 0xea, 0x40, + 0xf3, 0x05, 0x3a, 0x98, 0x47, 0xf5, 0xf9, 0x96, 0xb1, 0x51, 0x75, 0x1b, 0x25, 0x2a, 0x98, 0x47, + 0x88, 0xc3, 0xda, 0xb4, 0x86, 0x48, 0x71, 0xcc, 0x71, 0x20, 0xbf, 0x13, 0x75, 0x53, 0x26, 0xd5, + 0x2e, 0x4f, 0x6a, 0x37, 0x47, 0x4f, 0xcc, 0xc6, 0x54, 0xd1, 0x02, 0x8c, 0xa3, 0x6f, 0x0d, 0x58, + 0x9f, 0xae, 0x7a, 0x40, 0x43, 0xda, 0xc3, 0xb1, 0x20, 0x1e, 0xee, 0x76, 0x53, 0xc2, 0xb9, 0x9a, + 0xce, 0x05, 0x59, 0xff, 0x76, 0x79, 0xfd, 0xbc, 0x0d, 0x1f, 0x28, 0x1e, 0x19, 0xb7, 0xdb, 0xb5, + 0x26, 0x3d, 0x7c, 0x39, 0x2a, 0xa1, 0x91, 0xd9, 0xe4, 0x5a, 0x4f, 0xe0, 0xf5, 0x92, 0x2b, 0xa0, + 0x1a, 0x2c, 0xd0, 0xb8, 0x4b, 0x0e, 0x65, 0x0f, 0x2f, 0xba, 0xea, 0x01, 0x21, 0x30, 0x65, 0xb6, + 0x15, 0x99, 0xad, 0xfc, 0x8d, 0x5a, 0xb0, 0x5c, 0x48, 0x4d, 0xc7, 0x5e, 0x7c, 0x95, 0x69, 0x25, + 0x29, 0x63, 0x7b, 0x75, 0x53, 0x9e, 0xa9, 0x07, 0xeb, 0x3b, 0x03, 0x56, 0x5f, 0x70, 0x01, 0x74, + 0x07, 0xaa, 0x32, 0x22, 0x21, 0xf4, 0x24, 0x55, 0x3b, 0xf5, 0xbf, 0x7e, 0xde, 0xac, 0xe9, 0x3f, + 0x2c, 0x4d, 0x78, 0x24, 0x52, 0x1a, 0x87, 0x6e, 0x0e, 0x45, 0x6f, 0xc3, 0x52, 0x4a, 0x12, 0x96, + 0x66, 0xb4, 0xca, 0x0c, 0xda, 0x18, 0x69, 0xfd, 0x61, 0xc0, 0x6b, 0xa7, 0x0e, 0x3e, 0xda, 0x84, + 0x2b, 0x7b, 0x34, 0xe5, 0xc2, 0x13, 0x87, 0xc5, 0xf1, 0x92, 0x8e, 0xdc, 0x4b, 0xf2, 0x68, 0xf7, + 0x30, 0x1f, 0xaa, 0xeb, 0xf0, 0xca, 0x18, 0xae, 0x12, 0xac, 0xc8, 0x04, 0x2f, 0x68, 0xe4, 0x43, + 0x19, 0xa4, 0x03, 0x35, 0x4e, 0x02, 0x16, 0x77, 0xa7, 0x54, 0x55, 0x7a, 0x97, 0xd5, 0x59, 0x51, + 0x76, 0x1d, 0x5e, 0xcd, 0x09, 0x4a, 0xd7, 0x94, 0xba, 0x17, 0x47, 0x58, 0x29, 0x7c, 0xeb, 0xf7, + 0x05, 0x58, 0x90, 0xdf, 0x01, 0xf4, 0xbd, 0x01, 0x8b, 0x6a, 0x71, 0xa0, 0xb7, 0xca, 0x47, 0xe8, + 0xe4, 0xbe, 0x6a, 0x6c, 0x9e, 0x11, 0xad, 0xf2, 0xb1, 0x36, 0xbe, 0xf9, 0xfb, 0xff, 0x1f, 0x2b, + 0x16, 0x6a, 0x39, 0x33, 0x96, 0x24, 0xfa, 0xc5, 0x80, 0xcb, 0x27, 0xf6, 0x0d, 0xba, 0x3b, 0xa3, + 0x5c, 0xd9, 0x7e, 0x6b, 0xbc, 0x73, 0x7e, 0xa2, 0xb6, 0xbc, 0x29, 0x2d, 0xdf, 0x44, 0x37, 0xca, + 0x2d, 0x3f, 0x19, 0x7f, 0xc8, 0xbe, 0x46, 0x3f, 0x19, 0x80, 0x4e, 0x6e, 0x14, 0x74, 0xae, 0xfa, + 0xc5, 0x7d, 0xd7, 0xb8, 0xf7, 0x12, 0x4c, 0x6d, 0xfd, 0x9a, 0xb4, 0xbe, 0x8a, 0x56, 0x4a, 0xad, + 0xa3, 0xdf, 0x0c, 0xb8, 0x34, 0xbd, 0x05, 0xd0, 0x9d, 0x19, 0x25, 0x4b, 0x76, 0x4e, 0xe3, 0xee, + 0xb9, 0x79, 0xda, 0xe8, 0x3d, 0x69, 0x74, 0x0b, 0xb5, 0xcf, 0x94, 0xb1, 0x93, 0x7f, 0x0d, 0x79, + 0xe7, 0xb3, 0xa7, 0x47, 0x4d, 0xe3, 0xd9, 0x51, 0xd3, 0xf8, 0xef, 0xa8, 0x69, 0xfc, 0x70, 0xdc, + 0x9c, 0x7b, 0x76, 0xdc, 0x9c, 0xfb, 0xe7, 0xb8, 0x39, 0xf7, 0xd5, 0xed, 0x90, 0x8a, 0x68, 0xe0, + 0xdb, 0x01, 0xeb, 0x8f, 0x64, 0x83, 0x08, 0xd3, 0x78, 0x5c, 0xe3, 0x70, 0xaa, 0x8a, 0x18, 0x26, + 0x84, 0xfb, 0x8b, 0xf2, 0xdf, 0xb3, 0xad, 0xe7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x9f, 0x31, + 0x97, 0x82, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1136,18 +1202,6 @@ func (m *QueryEpochSubmissionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } if m.EpochNum != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.EpochNum)) i-- @@ -1176,18 +1230,6 @@ func (m *QueryEpochSubmissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } if len(m.Keys) > 0 { for iNdEx := len(m.Keys) - 1; iNdEx >= 0; iNdEx-- { { @@ -1359,6 +1401,53 @@ func (m *CheckpointAddressesResponse) MarshalToSizedBuffer(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *SubmissionKeyResponse) 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 *SubmissionKeyResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SubmissionKeyResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SecondTxIndex != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SecondTxIndex)) + i-- + dAtA[i] = 0x20 + } + if len(m.SecondTxBlockHash) > 0 { + i -= len(m.SecondTxBlockHash) + copy(dAtA[i:], m.SecondTxBlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.SecondTxBlockHash))) + i-- + dAtA[i] = 0x1a + } + if m.FirstTxIndex != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.FirstTxIndex)) + i-- + dAtA[i] = 0x10 + } + if len(m.FirstTxBlockHash) > 0 { + i -= len(m.FirstTxBlockHash) + copy(dAtA[i:], m.FirstTxBlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.FirstTxBlockHash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1456,10 +1545,6 @@ func (m *QueryEpochSubmissionsRequest) Size() (n int) { if m.EpochNum != 0 { n += 1 + sovQuery(uint64(m.EpochNum)) } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } return n } @@ -1475,10 +1560,6 @@ func (m *QueryEpochSubmissionsResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } return n } @@ -1554,6 +1635,29 @@ func (m *CheckpointAddressesResponse) Size() (n int) { return n } +func (m *SubmissionKeyResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FirstTxBlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.FirstTxIndex != 0 { + n += 1 + sovQuery(uint64(m.FirstTxIndex)) + } + l = len(m.SecondTxBlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.SecondTxIndex != 0 { + n += 1 + sovQuery(uint64(m.SecondTxIndex)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2102,42 +2206,6 @@ func (m *QueryEpochSubmissionsRequest) Unmarshal(dAtA []byte) error { break } } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2217,47 +2285,11 @@ func (m *QueryEpochSubmissionsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Keys = append(m.Keys, &SubmissionKey{}) + m.Keys = append(m.Keys, &SubmissionKeyResponse{}) if err := m.Keys[len(m.Keys)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -2746,6 +2778,158 @@ func (m *CheckpointAddressesResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *SubmissionKeyResponse) 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 ErrIntOverflowQuery + } + 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: SubmissionKeyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubmissionKeyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FirstTxBlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FirstTxBlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FirstTxIndex", wireType) + } + m.FirstTxIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FirstTxIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SecondTxBlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SecondTxBlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SecondTxIndex", wireType) + } + m.SecondTxIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SecondTxIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/btccheckpoint/types/query.pb.gw.go b/x/btccheckpoint/types/query.pb.gw.go index 87a078f9e..c2092a04a 100644 --- a/x/btccheckpoint/types/query.pb.gw.go +++ b/x/btccheckpoint/types/query.pb.gw.go @@ -141,10 +141,6 @@ func local_request_Query_BtcCheckpointsInfo_0(ctx context.Context, marshaler run } -var ( - filter_Query_EpochSubmissions_0 = &utilities.DoubleArray{Encoding: map[string]int{"epoch_num": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - func request_Query_EpochSubmissions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryEpochSubmissionsRequest var metadata runtime.ServerMetadata @@ -167,13 +163,6 @@ func request_Query_EpochSubmissions_0(ctx context.Context, marshaler runtime.Mar return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "epoch_num", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_EpochSubmissions_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - msg, err := client.EpochSubmissions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -201,13 +190,6 @@ func local_request_Query_EpochSubmissions_0(ctx context.Context, marshaler runti return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "epoch_num", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_EpochSubmissions_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - msg, err := server.EpochSubmissions(ctx, &protoReq) return msg, metadata, err From da0ed1071992c5c22e3aaaabbdeb14000a4a73cc Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Mon, 26 Feb 2024 21:42:47 +0800 Subject: [PATCH 019/119] fix: Disable sending of empty vote extension (#492) --- testutil/helper/helper.go | 39 +++++++++++ x/checkpointing/vote_ext.go | 29 +++++--- x/checkpointing/vote_ext_test.go | 115 +++++++++++++++++++++++++++++++ 3 files changed, 175 insertions(+), 8 deletions(-) diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index 495280adc..b4fba4972 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -90,6 +90,45 @@ func NewHelperWithValSet(t *testing.T, valSet *datagen.GenesisValidators, privSi } } +// NewHelperWithValSetNoSigner is same as NewHelperWithValSet, except that the privSigner is not +// included in the validator set +func NewHelperWithValSetNoSigner(t *testing.T, valSet *datagen.GenesisValidators, privSigner *app.PrivSigner) *Helper { + // generate the genesis account + signerPubKey := privSigner.WrappedPV.Key.PubKey + acc := authtypes.NewBaseAccount(signerPubKey.Address().Bytes(), &cosmosed.PubKey{Key: signerPubKey.Bytes()}, 0, 0) + privSigner.WrappedPV.Key.DelegatorAddress = acc.Address + // set a random validator address instead of the privSigner's + valSet.Keys[0].ValidatorAddress = datagen.GenRandomValidatorAddress().String() + // ensure the genesis account has a sufficient amount of tokens + balance := banktypes.Balance{ + Address: acc.GetAddress().String(), + Coins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.DefaultPowerReduction.MulRaw(10000000))), + } + GenAccs := []authtypes.GenesisAccount{acc} + + // setup the app and ctx + app := app.SetupWithGenesisValSet(t, valSet.GetGenesisKeys(), privSigner, GenAccs, balance) + ctx := app.BaseApp.NewContext(false).WithBlockHeight(1).WithHeaderInfo(header.Info{Height: 1}) // NOTE: height is 1 + + // get necessary subsets of the app/keeper + epochingKeeper := app.EpochingKeeper + querier := keeper.Querier{Keeper: epochingKeeper} + queryHelper := baseapp.NewQueryServerTestHelper(ctx, app.InterfaceRegistry()) + types.RegisterQueryServer(queryHelper, querier) + queryClient := types.NewQueryClient(queryHelper) + msgSrvr := keeper.NewMsgServerImpl(epochingKeeper) + + return &Helper{ + t, + ctx, + app, + msgSrvr, + queryClient, + GenAccs, + valSet, + } +} + func (h *Helper) NoError(err error) { require.NoError(h.t, err) } diff --git a/x/checkpointing/vote_ext.go b/x/checkpointing/vote_ext.go index a0a157e9e..ea4239de3 100644 --- a/x/checkpointing/vote_ext.go +++ b/x/checkpointing/vote_ext.go @@ -31,6 +31,14 @@ func (h *VoteExtensionHandler) SetHandlers(bApp *baseapp.BaseApp) { // ExtendVote sends a BLS signature as a vote extension // the signature is signed over the hash of the last // block of the current epoch +// NOTE: we should not allow empty vote extension to be +// sent as we cannot ensure all the vote extensions will +// be checked by VerifyVoteExtension due to the issue +// https://github.com/cometbft/cometbft/issues/2361 +// therefore, we panic upon any error, otherwise, empty +// vote extension will still be sent, according to +// https://github.com/cosmos/cosmos-sdk/blob/7dbed2fc0c3ed7c285645e21cb1037d8810372ae/baseapp/abci.go#L612 +// TODO: revisit panicking if the CometBFT issue is resolved func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { return func(ctx sdk.Context, req *abci.RequestExtendVote) (*abci.ResponseExtendVote, error) { k := h.ckptKeeper @@ -49,22 +57,25 @@ func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { curValSet := k.GetValidatorSet(ctx, epoch.EpochNumber) _, _, err := curValSet.FindValidatorWithIndex(signer) if err != nil { - // not being a validator is not an error - h.logger.Info("the BLS signer is not in the validator set", "signer_address", signer.String()) - return emptyRes, nil + // NOTE: this indicates programmatic error because ExtendVote + // should not be invoked if the validator is not in the + // active set according to: + // https://github.com/cometbft/cometbft/blob/a17290f6905ef714761f12c1f82409b0731e3838/consensus/state.go#L2434 + panic(fmt.Errorf("the BLS signer %s is not in the validator set", signer.String())) } // 2. sign BLS signature blsSig, err := k.SignBLS(epoch.EpochNumber, req.Hash) if err != nil { - // the returned error will lead to panic - return emptyRes, fmt.Errorf("failed to sign BLS signature at epoch %v, height %v", - epoch.EpochNumber, req.Height) + // NOTE: this indicates misconfiguration of the BLS key + panic(fmt.Errorf("failed to sign BLS signature at epoch %v, height %v", + epoch.EpochNumber, req.Height)) } var bhash ckpttypes.BlockHash if err := bhash.Unmarshal(req.Hash); err != nil { - return emptyRes, fmt.Errorf("invalid CometBFT hash") + // NOTE: this indicates programmatic error in CometBFT + panic(fmt.Errorf("invalid CometBFT hash")) } // 3. build vote extension @@ -78,7 +89,9 @@ func (h *VoteExtensionHandler) ExtendVote() sdk.ExtendVoteHandler { } bz, err := ve.Marshal() if err != nil { - return emptyRes, fmt.Errorf("failed to encode vote extension: %w", err) + // NOTE: the returned error will lead to panic + // this indicates programmatic error in building vote extension + panic(fmt.Errorf("failed to encode vote extension: %w", err)) } h.logger.Info("successfully sent BLS signature in vote extension", diff --git a/x/checkpointing/vote_ext_test.go b/x/checkpointing/vote_ext_test.go index 5921447b5..e370ece8b 100644 --- a/x/checkpointing/vote_ext_test.go +++ b/x/checkpointing/vote_ext_test.go @@ -4,6 +4,7 @@ import ( "math/rand" "testing" + abci "github.com/cometbft/cometbft/abci/types" "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/testutil/datagen" @@ -135,3 +136,117 @@ func FuzzAddBLSSigVoteExtension_EmptyVoteExtensions(f *testing.F) { require.Equal(t, types.Sealed, ckpt.Status) }) } + +// FuzzExtendVote_InvalidBlockHash tests the case where the +// block hash for signing is invalid in terms of format +func FuzzExtendVote_InvalidBlockHash(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + // generate the validator set with 10 validators as genesis + genesisValSet, privSigner, err := datagen.GenesisValidatorSetWithPrivSigner(10) + require.NoError(t, err) + helper := testhelper.NewHelperWithValSet(t, genesisValSet, privSigner) + ek := helper.App.EpochingKeeper + + epoch := ek.GetEpoch(helper.Ctx) + require.Equal(t, uint64(1), epoch.EpochNumber) + + // go to block 10, reaching epoch boundary + interval := ek.GetParams(helper.Ctx).EpochInterval + for i := uint64(0); i < interval-2; i++ { + _, err := helper.ApplyEmptyBlockWithVoteExtension(r) + require.NoError(t, err) + } + + req1 := &abci.RequestExtendVote{ + Hash: datagen.GenRandomByteArray(r, datagen.RandomIntOtherThan(r, types.HashSize, 100)), + Height: 10, + } + _, err = helper.App.ExtendVote(helper.Ctx, req1) + require.Error(t, err) + + req2 := &abci.RequestExtendVote{ + Hash: datagen.GenRandomByteArray(r, types.HashSize), + Height: 10, + } + _, err = helper.App.ExtendVote(helper.Ctx, req2) + require.NoError(t, err) + }) +} + +// FuzzExtendVote_EmptyBLSPrivKey tests the case where the +// BLS private key of the private signer is missing +func FuzzExtendVote_EmptyBLSPrivKey(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + // generate the validator set with 10 validators as genesis + genesisValSet, ps, err := datagen.GenesisValidatorSetWithPrivSigner(10) + require.NoError(t, err) + + // set the BLS private key to be nil to trigger panic + ps.WrappedPV.Key.BlsPrivKey = nil + helper := testhelper.NewHelperWithValSet(t, genesisValSet, ps) + ek := helper.App.EpochingKeeper + + epoch := ek.GetEpoch(helper.Ctx) + require.Equal(t, uint64(1), epoch.EpochNumber) + + // go to block 10, reaching epoch boundary + interval := ek.GetParams(helper.Ctx).EpochInterval + for i := uint64(0); i < interval-2; i++ { + _, err := helper.ApplyEmptyBlockWithVoteExtension(r) + require.NoError(t, err) + } + + req := &abci.RequestExtendVote{ + Hash: datagen.GenRandomByteArray(r, types.HashSize), + Height: 10, + } + + // error is expected due to nil BLS private key + _, err = helper.App.ExtendVote(helper.Ctx, req) + require.Error(t, err) + }) +} + +// FuzzExtendVote_NotInValidatorSet tests the case where the +// private signer is not in the validator set +func FuzzExtendVote_NotInValidatorSet(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + // generate the validator set with 10 validators as genesis + genesisValSet, ps, err := datagen.GenesisValidatorSetWithPrivSigner(10) + require.NoError(t, err) + + // the private signer is not included in the validator set + helper := testhelper.NewHelperWithValSetNoSigner(t, genesisValSet, ps) + + ek := helper.App.EpochingKeeper + + epoch := ek.GetEpoch(helper.Ctx) + require.Equal(t, uint64(1), epoch.EpochNumber) + + // go to block 10, reaching epoch boundary + interval := ek.GetParams(helper.Ctx).EpochInterval + for i := uint64(0); i < interval-2; i++ { + _, err := helper.ApplyEmptyBlockWithSomeEmptyVoteExtensions(r) + require.NoError(t, err) + } + + req := &abci.RequestExtendVote{ + Hash: datagen.GenRandomByteArray(r, types.HashSize), + Height: 10, + } + + // error is expected because the BLS signer in not + // in the validator set + _, err = helper.App.ExtendVote(helper.Ctx, req) + require.Error(t, err) + }) +} From 48d6ba91a1d5099923803b87900055abf846dc5a Mon Sep 17 00:00:00 2001 From: miles <66052478+miles-six@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:58:37 +0800 Subject: [PATCH 020/119] fix some typo (#513) --- proto/babylon/btccheckpoint/v1/btccheckpoint.proto | 12 ++++++------ x/btccheckpoint/types/btccheckpoint.pb.go | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/proto/babylon/btccheckpoint/v1/btccheckpoint.proto b/proto/babylon/btccheckpoint/v1/btccheckpoint.proto index 9dae49c47..8bfef61d6 100644 --- a/proto/babylon/btccheckpoint/v1/btccheckpoint.proto +++ b/proto/babylon/btccheckpoint/v1/btccheckpoint.proto @@ -39,7 +39,7 @@ message BTCSpvProof { "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; } -// Each provided OP_RETURN transaction can be idendtified by hash of block in +// Each provided OP_RETURN transaction can be identified by hash of block in // which transaction was included and transaction index in the block message TransactionKey { uint32 index = 1; @@ -88,20 +88,20 @@ message TransactionInfo { bytes transaction = 2; // proof is the Merkle proof that this tx is included in the position in `key` // TODO: maybe it could use here better format as we already processed and - // valideated the proof? + // validated the proof? bytes proof = 3; } // TODO: Determine if we should keep any block number or depth info. -// On one hand it may be usefull to determine if block is stable or not, on +// On one hand it may be useful to determine if block is stable or not, on // other depth/block number info, without context (i.e info about chain) is -// pretty useless and blockshash in enough to retrieve is from lightclient +// pretty useless and blockhash in enough to retrieve is from lightclient message SubmissionData { // address of the submitter and reporter CheckpointAddresses vigilante_addresses = 1; // txs_info is the two `TransactionInfo`s corresponding to the submission // It is used for - // - recovering address of sender of btc transction to payup the reward. + // - recovering address of sender of btc transaction to payup the reward. // - allowing the ZoneConcierge module to prove the checkpoint is submitted to // BTC repeated TransactionInfo txs_info = 2; @@ -109,7 +109,7 @@ message SubmissionData { } // Data stored in db and indexed by epoch number -// TODO: Add btc blockheight at epooch end, when adding hadnling of epoching +// TODO: Add btc blockheight at epoch end, when adding handling of epoching // callbacks message EpochData { // keys is the list of all received checkpoints during this epoch, sorted by diff --git a/x/btccheckpoint/types/btccheckpoint.pb.go b/x/btccheckpoint/types/btccheckpoint.pb.go index 23f50d154..1f1882d7a 100644 --- a/x/btccheckpoint/types/btccheckpoint.pb.go +++ b/x/btccheckpoint/types/btccheckpoint.pb.go @@ -147,7 +147,7 @@ func (m *BTCSpvProof) GetMerkleNodes() []byte { return nil } -// Each provided OP_RETURN transaction can be idendtified by hash of block in +// Each provided OP_RETURN transaction can be identified by hash of block in // which transaction was included and transaction index in the block type TransactionKey struct { Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` @@ -262,7 +262,7 @@ type TransactionInfo struct { Transaction []byte `protobuf:"bytes,2,opt,name=transaction,proto3" json:"transaction,omitempty"` // proof is the Merkle proof that this tx is included in the position in `key` // TODO: maybe it could use here better format as we already processed and - // valideated the proof? + // validated the proof? Proof []byte `protobuf:"bytes,3,opt,name=proof,proto3" json:"proof,omitempty"` } @@ -321,15 +321,15 @@ func (m *TransactionInfo) GetProof() []byte { } // TODO: Determine if we should keep any block number or depth info. -// On one hand it may be usefull to determine if block is stable or not, on +// On one hand it may be useful to determine if block is stable or not, on // other depth/block number info, without context (i.e info about chain) is -// pretty useless and blockshash in enough to retrieve is from lightclient +// pretty useless and blockhash in enough to retrieve is from lightclient type SubmissionData struct { // address of the submitter and reporter VigilanteAddresses *CheckpointAddresses `protobuf:"bytes,1,opt,name=vigilante_addresses,json=vigilanteAddresses,proto3" json:"vigilante_addresses,omitempty"` // txs_info is the two `TransactionInfo`s corresponding to the submission // It is used for - // - recovering address of sender of btc transction to payup the reward. + // - recovering address of sender of btc transaction to payup the reward. // - allowing the ZoneConcierge module to prove the checkpoint is submitted to // BTC TxsInfo []*TransactionInfo `protobuf:"bytes,2,rep,name=txs_info,json=txsInfo,proto3" json:"txs_info,omitempty"` @@ -391,7 +391,7 @@ func (m *SubmissionData) GetEpoch() uint64 { } // Data stored in db and indexed by epoch number -// TODO: Add btc blockheight at epooch end, when adding hadnling of epoching +// TODO: Add btc blockheight at epoch end, when adding handling of epoching // callbacks type EpochData struct { // keys is the list of all received checkpoints during this epoch, sorted by From c3f772ae65e60fe6125d83fd9014028b970d6cf7 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 29 Feb 2024 23:55:10 +1100 Subject: [PATCH 021/119] fix pubkey format in EOTS (#512) Co-authored-by: KonradStaniec --- crypto/eots/eots.go | 16 ++++++++-- crypto/eots/eots_test.go | 65 ++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/crypto/eots/eots.go b/crypto/eots/eots.go index f94e66786..932051b46 100644 --- a/crypto/eots/eots.go +++ b/crypto/eots/eots.go @@ -6,6 +6,7 @@ import ( "io" "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/decred/dcrd/dcrec/secp256k1/v4" ecdsa_schnorr "github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr" @@ -118,12 +119,23 @@ func signHash(sk *PrivateKey, privateRand *PrivateRand, hash [32]byte) (*Signatu // Verify verifies that the signature is valid for this message, public key and random value. func Verify(pubKey *PublicKey, r *PublicRand, message []byte, sig *Signature) error { h := hash(message) - return verifyHash(pubKey, r, h, sig) + pubkeyBytes := schnorr.SerializePubKey(pubKey) + return verifyHash(pubkeyBytes, r, h, sig) } // Verify verifies that the signature is valid for this hashed message, public key and random value. // Based on unexported schnorrVerify of btcd. -func verifyHash(pubKey *PublicKey, r *PublicRand, hash [32]byte, sig *Signature) error { +func verifyHash(pubKeyBytes []byte, r *PublicRand, hash [32]byte, sig *Signature) error { + // Step 2. + // + // P = lift_x(int(pk)) + // + // Fail if P is not a point on the curve + pubKey, err := schnorr.ParsePubKey(pubKeyBytes) + if err != nil { + return err + } + // Fail if P is not a point on the curve if !pubKey.IsOnCurve() { str := "pubkey point is not on curve" diff --git a/crypto/eots/eots_test.go b/crypto/eots/eots_test.go index 9adc8df8f..91865b4d0 100644 --- a/crypto/eots/eots_test.go +++ b/crypto/eots/eots_test.go @@ -1,11 +1,15 @@ -package eots +package eots_test import ( "bytes" "crypto/rand" + mathrand "math/rand" "testing" + "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonchain/babylon/testutil/datagen" "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/stretchr/testify/require" "github.com/vulpine-io/io-test/v1/pkg/iotest" ) @@ -14,64 +18,59 @@ import ( // test compare signatures against btcec func FuzzSignAndVerify(f *testing.F) { - randSource := new(iotest.ReadCloser) + datagen.AddRandomSeedsToFuzzer(f, 10) - sk, err := KeyGen(randSource) - if err != nil { - f.Fatal(err) - } - k, publicK, err := RandGen(rand.Reader) - if err != nil { - f.Fatal(err) - } + f.Fuzz(func(t *testing.T, seed int64) { + r := mathrand.New(mathrand.NewSource(seed)) - for _, seed := range [][]byte{[]byte("hello"), []byte("1234567890!@#$%^&*()")} { - f.Add(seed) - } - f.Fuzz(func(t *testing.T, message []byte) { - sig, err := Sign(sk, k, message) - if err != nil { - t.Fatal(err) - } - err = Verify(PubGen(sk), publicK, message, sig) - if err != nil { - t.Fatal(err) - } + sk, err := eots.KeyGen(r) + require.NoError(t, err) + pk := eots.PubGen(sk) + + sr, pr, err := eots.RandGen(rand.Reader) + require.NoError(t, err) + + msg := datagen.GenRandomByteArray(r, 100) + sig, err := eots.Sign(sk, sr, msg) + require.NoError(t, err) + + err = eots.Verify(pk, pr, msg, sig) + require.NoError(t, err) }) } func TestSignAndInvalidVerify(t *testing.T) { randSource := new(iotest.ReadCloser) - sk, err := KeyGen(randSource) + sk, err := eots.KeyGen(randSource) if err != nil { t.Fatal(err) } - k, publicK, err := RandGen(randSource) + k, publicK, err := eots.RandGen(randSource) if err != nil { t.Fatal(err) } message := []byte("hello") - sig, err := Sign(sk, k, message) + sig, err := eots.Sign(sk, k, message) if err != nil { t.Fatal(err) } invalidK := new(secp256k1.FieldVal).Set(publicK).AddInt(1) - err = Verify(PubGen(sk), invalidK, message, sig) + err = eots.Verify(eots.PubGen(sk), invalidK, message, sig) if err == nil { t.Fatal("Expected verify to fail with wrong k value") } - err = Verify(PubGen(sk), publicK, message, new(Signature)) + err = eots.Verify(eots.PubGen(sk), publicK, message, new(eots.Signature)) if err == nil { t.Fatal("Expected verify to fail with wrong signature for the hash") } messageInvalid := []byte("bye") - err = Verify(PubGen(sk), publicK, messageInvalid, sig) + err = eots.Verify(eots.PubGen(sk), publicK, messageInvalid, sig) if err == nil { t.Fatal("Expected verify to fail with wrong signature for the hash") } @@ -79,11 +78,11 @@ func TestSignAndInvalidVerify(t *testing.T) { func FuzzExtract(f *testing.F) { randSource := new(iotest.ReadCloser) - sk, err := KeyGen(randSource) + sk, err := eots.KeyGen(randSource) if err != nil { f.Fatal(err) } - k, publicK, err := RandGen(rand.Reader) + k, publicK, err := eots.RandGen(rand.Reader) if err != nil { f.Fatal(err) } @@ -102,17 +101,17 @@ func FuzzExtract(f *testing.F) { t.Skip() } - sig1, err := Sign(sk, k, message1) + sig1, err := eots.Sign(sk, k, message1) if err != nil { t.Fatal(err) } - sig2, err := Sign(sk, k, message2) + sig2, err := eots.Sign(sk, k, message2) if err != nil { t.Fatal(err) } - sk2, err := Extract(sk.PubKey(), publicK, message1, sig1, message2, sig2) + sk2, err := eots.Extract(eots.PubGen(sk), publicK, message1, sig1, message2, sig2) if err != nil { t.Fatal(err) } From fac964770aeb1b1f7b7ffea691ca40984f6906d0 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 29 Feb 2024 11:43:56 -0300 Subject: [PATCH 022/119] chore: split btc delegation response structure from query return (#508) * chore: split btc delegation response structure from query return * chore: add slashing properties to BTCDelegationResponse * fix: add verification for nil properties * chore: btc del resp finality provider (#511) * chore: update FinalityProviderDelegations to return BTCDelegatorDelegationsResponse which has delegation status * chore: reduce code diff * chore: add StakingOutputIdx to BTC del response and fix e2e ParseRespsBTCDelToBTCDel --- proto/babylon/btcstaking/v1/btcstaking.proto | 16 - proto/babylon/btcstaking/v1/query.proto | 63 +- test/e2e/btc_staking_e2e_test.go | 105 +- .../configurer/chain/queries_btcstaking.go | 2 +- x/btcstaking/keeper/grpc_query.go | 47 +- x/btcstaking/keeper/grpc_query_test.go | 12 +- x/btcstaking/types/btcstaking.pb.go | 467 +----- x/btcstaking/types/query.go | 55 + x/btcstaking/types/query.pb.go | 1403 ++++++++++++++--- 9 files changed, 1545 insertions(+), 625 deletions(-) create mode 100644 x/btcstaking/types/query.go diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 89b284156..b9902e597 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -130,22 +130,6 @@ message BTCUndelegation { repeated SignatureInfo covenant_unbonding_sig_list = 6; } - -// BTCUndelegationInfo provides all necessary info about the undeleagation -message BTCUndelegationInfo { - // unbonding_tx is the transaction which will transfer the funds from staking - // output to unbonding output. Unbonding output will usually have lower timelock - // than staking output. - bytes unbonding_tx = 1; - // covenant_unbonding_sig_list is the list of signatures on the unbonding tx - // by covenant members - repeated SignatureInfo covenant_unbonding_sig_list = 2; - // covenant_slashing_sigs is a list of adaptor signatures on the - // unbonding slashing tx by each covenant member - // It will be a part of the witness for the staking tx output. - repeated CovenantAdaptorSignatures covenant_slashing_sigs = 3; -} - // BTCDelegatorDelegations is a collection of BTC delegations from the same delegator. message BTCDelegatorDelegations { repeated BTCDelegation dels = 1; diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 640258bea..fcbb9ee98 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -203,7 +203,7 @@ message QueryFinalityProviderDelegationsRequest { // Query/FinalityProviderDelegations RPC method. message QueryFinalityProviderDelegationsResponse { // btc_delegator_delegations contains all the queried BTC delegations. - repeated BTCDelegatorDelegations btc_delegator_delegations = 1; + repeated BTCDelegatorDelegationsResponse btc_delegator_delegations = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -219,7 +219,13 @@ message QueryBTCDelegationRequest { // QueryBTCDelegationResponse is response type matching QueryBTCDelegationRequest // and containing BTC delegation information message QueryBTCDelegationResponse { - // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation + // BTCDelegation represents the client needed information of an BTCDelegation. + BTCDelegationResponse btc_delegation = 1; +} + +// BTCDelegationResponse is the client needed information from a BTCDelegation with the current status based on parameters. +message BTCDelegationResponse { + // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that @@ -236,15 +242,58 @@ message QueryBTCDelegationResponse { uint64 total_sat = 5; // staking_tx_hex is the hex string of staking tx string staking_tx_hex = 6; + // slashing_tx_hex is the hex string of slashing tx + string slashing_tx_hex = 7; + // delegator_slash_sig_hex is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk) as string hex. + // It will be a part of the witness for the staking tx output. + string delegator_slash_sig_hex = 8; // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. - repeated CovenantAdaptorSignatures covenant_sigs = 7; + repeated CovenantAdaptorSignatures covenant_sigs = 9; + // staking_output_idx is the index of the staking output in the staking tx + uint32 staking_output_idx = 10; // whether this delegation is active - bool active = 8; + bool active = 11; + // descriptive status of current delegation. + string status_desc = 12; // unbonding_time used in unbonding output timelock path and in slashing transactions // change outputs - uint32 unbonding_time = 9; - // undelegation_info is the undelegation info of this delegation. - BTCUndelegationInfo undelegation_info = 10; + uint32 unbonding_time = 13; + // undelegation_response is the undelegation info of this delegation. + BTCUndelegationResponse undelegation_response = 14; } + +// BTCUndelegationResponse provides all necessary info about the undeleagation +message BTCUndelegationResponse { + // unbonding_tx is the transaction which will transfer the funds from staking + // output to unbonding output. Unbonding output will usually have lower timelock + // than staking output. The unbonding tx as string hex. + string unbonding_tx_hex = 1; + // delegator_unbonding_sig is the signature on the unbonding tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It effectively proves that the delegator wants to unbond and thus + // Babylon will consider this BTC delegation unbonded. Delegator's BTC + // on Bitcoin will be unbonded after timelock. The unbonding delegator sig as string hex. + string delegator_unbonding_sig_hex = 2; + // covenant_unbonding_sig_list is the list of signatures on the unbonding tx + // by covenant members + repeated SignatureInfo covenant_unbonding_sig_list = 3; + // slashingTxHex is the hex string of slashing tx + string slashing_tx_hex = 4; + // delegator_slashing_sig is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It will be a part of the witness for the unbonding tx output. + // The delegator slashing sig as string hex. + string delegator_slashing_sig_hex = 5; + // covenant_slashing_sigs is a list of adaptor signatures on the + // unbonding slashing tx by each covenant member + // It will be a part of the witness for the staking tx output. + repeated CovenantAdaptorSignatures covenant_slashing_sigs = 6; +} + +// BTCDelegatorDelegationsResponse is a collection of BTC delegations responses from the same delegator. +message BTCDelegatorDelegationsResponse { + repeated BTCDelegationResponse dels = 1; +} \ No newline at end of file diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index ffd19b59e..019aea1ce 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -1,6 +1,7 @@ package e2e import ( + "encoding/hex" "math" "math/rand" "time" @@ -218,11 +219,14 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { s.Len(pendingDelsSet, 1) pendingDels := pendingDelsSet[0] s.Len(pendingDels.Dels, 1) - pendingDel := pendingDels.Dels[0] + pendingDelResp := pendingDels.Dels[0] + pendingDel, err := ParseRespBTCDelToBTCDel(pendingDelResp) + s.NoError(err) s.Len(pendingDel.CovenantSigs, 0) slashingTx := pendingDel.SlashingTx stakingTx := pendingDel.StakingTx + stakingMsgTx, err := bbn.NewBTCTxFromBytes(stakingTx) s.NoError(err) stakingTxHash := stakingMsgTx.TxHash().String() @@ -298,8 +302,12 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { // ensure the BTC delegation has covenant sigs now activeDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(fp.BtcPk.MarshalHex()) s.Len(activeDelsSet, 1) - activeDels := activeDelsSet[0] + + activeDels, err := ParseRespsBTCDelToBTCDel(activeDelsSet[0]) + s.NoError(err) + s.NotNil(activeDels) s.Len(activeDels.Dels, 1) + activeDel := activeDels.Dels[0] s.True(activeDel.HasCovenantQuorums(covenantQuorum)) @@ -482,7 +490,9 @@ func (s *BTCStakingTestSuite) Test5SubmitStakerUnbonding() { s.Len(activeDelsSet, 1) activeDels := activeDelsSet[0] s.Len(activeDels.Dels, 1) - activeDel := activeDels.Dels[0] + activeDelResp := activeDels.Dels[0] + activeDel, err := ParseRespBTCDelToBTCDel(activeDelResp) + s.NoError(err) s.NotNil(activeDel.CovenantSigs) // staking tx hash @@ -509,3 +519,92 @@ func (s *BTCStakingTestSuite) Test5SubmitStakerUnbonding() { s.Len(unbondedDels, 1) s.Equal(stakingTxHash, unbondedDels[0].MustGetStakingTxHash()) } + +// ParseRespsBTCDelToBTCDel parses an BTC delegation response to BTC Delegation +func ParseRespsBTCDelToBTCDel(resp *bstypes.BTCDelegatorDelegationsResponse) (btcDels *bstypes.BTCDelegatorDelegations, err error) { + if resp == nil { + return nil, nil + } + btcDels = &bstypes.BTCDelegatorDelegations{ + Dels: make([]*bstypes.BTCDelegation, len(resp.Dels)), + } + + for i, delResp := range resp.Dels { + del, err := ParseRespBTCDelToBTCDel(delResp) + if err != nil { + return nil, err + } + btcDels.Dels[i] = del + } + return btcDels, nil +} + +// ParseRespBTCDelToBTCDel parses an BTC delegation response to BTC Delegation +func ParseRespBTCDelToBTCDel(resp *bstypes.BTCDelegationResponse) (btcDel *bstypes.BTCDelegation, err error) { + stakingTx, err := hex.DecodeString(resp.StakingTxHex) + if err != nil { + return nil, err + } + + delSig, err := bbn.NewBIP340SignatureFromHex(resp.DelegatorSlashSigHex) + if err != nil { + return nil, err + } + + slashingTx, err := bstypes.NewBTCSlashingTxFromHex(resp.SlashingTxHex) + if err != nil { + return nil, err + } + + btcDel = &bstypes.BTCDelegation{ + // missing BabylonPk, Pop + // these fields are not sent out to the client on BTCDelegationResponse + BtcPk: resp.BtcPk, + FpBtcPkList: resp.FpBtcPkList, + StartHeight: resp.StartHeight, + EndHeight: resp.EndHeight, + TotalSat: resp.TotalSat, + StakingTx: stakingTx, + DelegatorSig: delSig, + StakingOutputIdx: resp.StakingOutputIdx, + CovenantSigs: resp.CovenantSigs, + UnbondingTime: resp.UnbondingTime, + SlashingTx: slashingTx, + } + + if resp.UndelegationResponse != nil { + ud := resp.UndelegationResponse + unbondTx, err := hex.DecodeString(ud.UnbondingTxHex) + if err != nil { + return nil, err + } + + slashTx, err := bstypes.NewBTCSlashingTxFromHex(ud.SlashingTxHex) + if err != nil { + return nil, err + } + + delSlashingSig, err := bbn.NewBIP340SignatureFromHex(ud.DelegatorSlashingSigHex) + if err != nil { + return nil, err + } + + btcDel.BtcUndelegation = &bstypes.BTCUndelegation{ + UnbondingTx: unbondTx, + CovenantUnbondingSigList: ud.CovenantUnbondingSigList, + CovenantSlashingSigs: ud.CovenantSlashingSigs, + SlashingTx: slashTx, + DelegatorSlashingSig: delSlashingSig, + } + + if len(ud.DelegatorUnbondingSigHex) > 0 { + delUnbondingSig, err := bbn.NewBIP340SignatureFromHex(ud.DelegatorUnbondingSigHex) + if err != nil { + return nil, err + } + btcDel.BtcUndelegation.DelegatorUnbondingSig = delUnbondingSig + } + } + + return btcDel, nil +} diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index cb55b0ab3..7669200aa 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -45,7 +45,7 @@ func (n *NodeConfig) QueryActiveFinalityProvidersAtHeight(height uint64) []*bsty return resp.FinalityProviders } -func (n *NodeConfig) QueryFinalityProviderDelegations(fpBTCPK string) []*bstypes.BTCDelegatorDelegations { +func (n *NodeConfig) QueryFinalityProviderDelegations(fpBTCPK string) []*bstypes.BTCDelegatorDelegationsResponse { path := fmt.Sprintf("/babylon/btcstaking/v1/finality_providers/%s/delegations", fpBTCPK) bz, err := n.QueryGRPCGateway(path, url.Values{}) require.NoError(n.t, err) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index d7455786c..72d22772e 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "encoding/hex" errorsmod "cosmossdk.io/errors" bbn "github.com/babylonchain/babylon/types" @@ -212,7 +211,11 @@ func (k Keeper) FinalityProviderDelegations(ctx context.Context, req *types.Quer sdkCtx := sdk.UnwrapSDKContext(ctx) btcDelStore := k.btcDelegatorStore(sdkCtx, fpPK) - btcDels := []*types.BTCDelegatorDelegations{} + currentWValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout + btcHeight := k.btclcKeeper.GetTipInfo(ctx).Height + covenantQuorum := k.GetParams(ctx).CovenantQuorum + + btcDels := []*types.BTCDelegatorDelegationsResponse{} pageRes, err := query.Paginate(btcDelStore, req.Pagination, func(key, value []byte) error { delBTCPK, err := bbn.NewBIP340PubKey(key) if err != nil { @@ -224,7 +227,19 @@ func (k Keeper) FinalityProviderDelegations(ctx context.Context, req *types.Quer return err } - btcDels = append(btcDels, curBTCDels) + btcDelsResp := make([]*types.BTCDelegationResponse, len(curBTCDels.Dels)) + for i, btcDel := range curBTCDels.Dels { + status := btcDel.GetStatus( + btcHeight, + currentWValue, + covenantQuorum, + ) + btcDelsResp[i] = types.NewBTCDelegationResponse(btcDel, status) + } + + btcDels = append(btcDels, &types.BTCDelegatorDelegationsResponse{ + Dels: btcDelsResp, + }) return nil }) if err != nil { @@ -252,32 +267,14 @@ func (k Keeper) BTCDelegation(ctx context.Context, req *types.QueryBTCDelegation return nil, types.ErrBTCDelegationNotFound } - // check whether it's active - currentTip := k.btclcKeeper.GetTipInfo(ctx) currentWValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout - isActive := btcDel.GetStatus( - currentTip.Height, + status := btcDel.GetStatus( + k.btclcKeeper.GetTipInfo(ctx).Height, currentWValue, k.GetParams(ctx).CovenantQuorum, - ) == types.BTCDelegationStatus_ACTIVE - - // get its undelegation info - undelegationInfo := &types.BTCUndelegationInfo{ - UnbondingTx: btcDel.BtcUndelegation.UnbondingTx, - CovenantUnbondingSigList: btcDel.BtcUndelegation.CovenantUnbondingSigList, - CovenantSlashingSigs: btcDel.BtcUndelegation.CovenantSlashingSigs, - } + ) return &types.QueryBTCDelegationResponse{ - BtcPk: btcDel.BtcPk, - FpBtcPkList: btcDel.FpBtcPkList, - StartHeight: btcDel.StartHeight, - EndHeight: btcDel.EndHeight, - TotalSat: btcDel.TotalSat, - StakingTxHex: hex.EncodeToString(btcDel.StakingTx), - CovenantSigs: btcDel.CovenantSigs, - Active: isActive, - UnbondingTime: btcDel.UnbondingTime, - UndelegationInfo: undelegationInfo, + BtcDelegation: types.NewBTCDelegationResponse(btcDel, status), }, nil } diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index 353a1a910..b3f1d5e40 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "errors" + "math" "math/rand" "testing" @@ -517,12 +518,17 @@ func FuzzFinalityProviderDelegations(f *testing.F) { babylonHeight := datagen.RandomInt(r, 10) + 1 ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: startHeight}).Times(1) - keeper.IndexBTCHeight(ctx) - // Generate a page request with a limit and a nil key // query a page of BTC delegations and assert consistency limit := datagen.RandomInt(r, len(expectedBtcDelsMap)) + 1 + + // FinalityProviderDelegations loads status, which calls GetTipInfo + finalityProviderDelegationCalls := math.Ceil(float64(numBTCDels) / float64(limit)) + tipInfoTimesCalled := int(finalityProviderDelegationCalls + 1) // + call at IndexBTCHeight + btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: startHeight}).Times(tipInfoTimesCalled) + + keeper.IndexBTCHeight(ctx) + pagination := constructRequestWithLimit(r, limit) // Generate the initial query req := types.QueryFinalityProviderDelegationsRequest{ diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index c377002ae..dfd283b1c 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -473,75 +473,6 @@ func (m *BTCUndelegation) GetCovenantUnbondingSigList() []*SignatureInfo { return nil } -// BTCUndelegationInfo provides all necessary info about the undeleagation -type BTCUndelegationInfo struct { - // unbonding_tx is the transaction which will transfer the funds from staking - // output to unbonding output. Unbonding output will usually have lower timelock - // than staking output. - UnbondingTx []byte `protobuf:"bytes,1,opt,name=unbonding_tx,json=unbondingTx,proto3" json:"unbonding_tx,omitempty"` - // covenant_unbonding_sig_list is the list of signatures on the unbonding tx - // by covenant members - CovenantUnbondingSigList []*SignatureInfo `protobuf:"bytes,2,rep,name=covenant_unbonding_sig_list,json=covenantUnbondingSigList,proto3" json:"covenant_unbonding_sig_list,omitempty"` - // covenant_slashing_sigs is a list of adaptor signatures on the - // unbonding slashing tx by each covenant member - // It will be a part of the witness for the staking tx output. - CovenantSlashingSigs []*CovenantAdaptorSignatures `protobuf:"bytes,3,rep,name=covenant_slashing_sigs,json=covenantSlashingSigs,proto3" json:"covenant_slashing_sigs,omitempty"` -} - -func (m *BTCUndelegationInfo) Reset() { *m = BTCUndelegationInfo{} } -func (m *BTCUndelegationInfo) String() string { return proto.CompactTextString(m) } -func (*BTCUndelegationInfo) ProtoMessage() {} -func (*BTCUndelegationInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{4} -} -func (m *BTCUndelegationInfo) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *BTCUndelegationInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_BTCUndelegationInfo.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 *BTCUndelegationInfo) XXX_Merge(src proto.Message) { - xxx_messageInfo_BTCUndelegationInfo.Merge(m, src) -} -func (m *BTCUndelegationInfo) XXX_Size() int { - return m.Size() -} -func (m *BTCUndelegationInfo) XXX_DiscardUnknown() { - xxx_messageInfo_BTCUndelegationInfo.DiscardUnknown(m) -} - -var xxx_messageInfo_BTCUndelegationInfo proto.InternalMessageInfo - -func (m *BTCUndelegationInfo) GetUnbondingTx() []byte { - if m != nil { - return m.UnbondingTx - } - return nil -} - -func (m *BTCUndelegationInfo) GetCovenantUnbondingSigList() []*SignatureInfo { - if m != nil { - return m.CovenantUnbondingSigList - } - return nil -} - -func (m *BTCUndelegationInfo) GetCovenantSlashingSigs() []*CovenantAdaptorSignatures { - if m != nil { - return m.CovenantSlashingSigs - } - return nil -} - // BTCDelegatorDelegations is a collection of BTC delegations from the same delegator. type BTCDelegatorDelegations struct { Dels []*BTCDelegation `protobuf:"bytes,1,rep,name=dels,proto3" json:"dels,omitempty"` @@ -551,7 +482,7 @@ func (m *BTCDelegatorDelegations) Reset() { *m = BTCDelegatorDelegations func (m *BTCDelegatorDelegations) String() string { return proto.CompactTextString(m) } func (*BTCDelegatorDelegations) ProtoMessage() {} func (*BTCDelegatorDelegations) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{5} + return fileDescriptor_3851ae95ccfaf7db, []int{4} } func (m *BTCDelegatorDelegations) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -596,7 +527,7 @@ func (m *BTCDelegatorDelegationIndex) Reset() { *m = BTCDelegatorDelegat func (m *BTCDelegatorDelegationIndex) String() string { return proto.CompactTextString(m) } func (*BTCDelegatorDelegationIndex) ProtoMessage() {} func (*BTCDelegatorDelegationIndex) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{6} + return fileDescriptor_3851ae95ccfaf7db, []int{5} } func (m *BTCDelegatorDelegationIndex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -642,7 +573,7 @@ func (m *SignatureInfo) Reset() { *m = SignatureInfo{} } func (m *SignatureInfo) String() string { return proto.CompactTextString(m) } func (*SignatureInfo) ProtoMessage() {} func (*SignatureInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{7} + return fileDescriptor_3851ae95ccfaf7db, []int{6} } func (m *SignatureInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -684,7 +615,7 @@ func (m *CovenantAdaptorSignatures) Reset() { *m = CovenantAdaptorSignat func (m *CovenantAdaptorSignatures) String() string { return proto.CompactTextString(m) } func (*CovenantAdaptorSignatures) ProtoMessage() {} func (*CovenantAdaptorSignatures) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{8} + return fileDescriptor_3851ae95ccfaf7db, []int{7} } func (m *CovenantAdaptorSignatures) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -743,7 +674,7 @@ func (m *SelectiveSlashingEvidence) Reset() { *m = SelectiveSlashingEvid func (m *SelectiveSlashingEvidence) String() string { return proto.CompactTextString(m) } func (*SelectiveSlashingEvidence) ProtoMessage() {} func (*SelectiveSlashingEvidence) Descriptor() ([]byte, []int) { - return fileDescriptor_3851ae95ccfaf7db, []int{9} + return fileDescriptor_3851ae95ccfaf7db, []int{8} } func (m *SelectiveSlashingEvidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -792,7 +723,6 @@ func init() { proto.RegisterType((*FinalityProviderWithMeta)(nil), "babylon.btcstaking.v1.FinalityProviderWithMeta") proto.RegisterType((*BTCDelegation)(nil), "babylon.btcstaking.v1.BTCDelegation") proto.RegisterType((*BTCUndelegation)(nil), "babylon.btcstaking.v1.BTCUndelegation") - proto.RegisterType((*BTCUndelegationInfo)(nil), "babylon.btcstaking.v1.BTCUndelegationInfo") proto.RegisterType((*BTCDelegatorDelegations)(nil), "babylon.btcstaking.v1.BTCDelegatorDelegations") proto.RegisterType((*BTCDelegatorDelegationIndex)(nil), "babylon.btcstaking.v1.BTCDelegatorDelegationIndex") proto.RegisterType((*SignatureInfo)(nil), "babylon.btcstaking.v1.SignatureInfo") @@ -805,83 +735,81 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1203 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcb, 0x6e, 0xdb, 0x46, - 0x1b, 0x35, 0x25, 0x59, 0x8e, 0x3e, 0x49, 0x89, 0x32, 0x71, 0x1c, 0x26, 0xc6, 0x6f, 0xfb, 0x57, - 0xd3, 0x40, 0x28, 0x1a, 0x2a, 0x76, 0x2e, 0x68, 0xbb, 0x28, 0x10, 0x59, 0x4e, 0x63, 0x24, 0x71, - 0x54, 0xca, 0x6e, 0xd1, 0x16, 0x28, 0x41, 0x91, 0x23, 0x8a, 0x90, 0xc4, 0x61, 0x39, 0x23, 0x55, - 0x7a, 0x80, 0x02, 0xdd, 0x14, 0xe8, 0xb6, 0xfb, 0x3e, 0x42, 0x9f, 0xa1, 0xc8, 0x32, 0xe8, 0xa6, - 0x85, 0x17, 0x46, 0x91, 0xbc, 0x48, 0x31, 0xc3, 0xe1, 0x45, 0x4e, 0xec, 0x5c, 0xe4, 0x9d, 0x38, - 0xdf, 0xed, 0xcc, 0x39, 0x87, 0x9c, 0x11, 0xdc, 0xe8, 0x98, 0x9d, 0xe9, 0x80, 0x78, 0xf5, 0x0e, - 0xb3, 0x28, 0x33, 0xfb, 0xae, 0xe7, 0xd4, 0xc7, 0x9b, 0xa9, 0x27, 0xcd, 0x0f, 0x08, 0x23, 0xe8, - 0xb2, 0xcc, 0xd3, 0x52, 0x91, 0xf1, 0xe6, 0xb5, 0x65, 0x87, 0x38, 0x44, 0x64, 0xd4, 0xf9, 0xaf, - 0x30, 0xf9, 0xda, 0x55, 0x8b, 0xd0, 0x21, 0xa1, 0x46, 0x18, 0x08, 0x1f, 0x64, 0xa8, 0x1a, 0x3e, - 0xd5, 0xad, 0x60, 0xea, 0x33, 0x52, 0xa7, 0xd8, 0xf2, 0xb7, 0xee, 0xde, 0xeb, 0x6f, 0xd6, 0xfb, - 0x78, 0x1a, 0xe5, 0x5c, 0x97, 0x39, 0x09, 0x9e, 0x0e, 0x66, 0xe6, 0x66, 0x7d, 0x06, 0xd1, 0xb5, - 0xf5, 0xd7, 0x23, 0xf7, 0x89, 0x1f, 0x26, 0x54, 0xff, 0xce, 0x42, 0xe5, 0x81, 0xeb, 0x99, 0x03, - 0x97, 0x4d, 0x5b, 0x01, 0x19, 0xbb, 0x36, 0x0e, 0xd0, 0x0e, 0x14, 0x6d, 0x4c, 0xad, 0xc0, 0xf5, - 0x99, 0x4b, 0x3c, 0x55, 0xd9, 0x50, 0x6a, 0xc5, 0xad, 0x0f, 0x34, 0x89, 0x31, 0xd9, 0x99, 0x98, - 0xa8, 0x35, 0x93, 0x54, 0x3d, 0x5d, 0x87, 0x9e, 0x00, 0x58, 0x64, 0x38, 0x74, 0x29, 0xe5, 0x5d, - 0x32, 0x1b, 0x4a, 0xad, 0xd0, 0xb8, 0x79, 0x78, 0xb4, 0xbe, 0x1a, 0x36, 0xa2, 0x76, 0x5f, 0x73, - 0x49, 0x7d, 0x68, 0xb2, 0x9e, 0xf6, 0x18, 0x3b, 0xa6, 0x35, 0x6d, 0x62, 0xeb, 0xaf, 0x3f, 0x6e, - 0x82, 0x9c, 0xd3, 0xc4, 0x96, 0x9e, 0x6a, 0x80, 0x3e, 0x07, 0x90, 0xbb, 0x31, 0xfc, 0xbe, 0x9a, - 0x15, 0xa0, 0xd6, 0x23, 0x50, 0x21, 0x55, 0x5a, 0x4c, 0x95, 0xd6, 0x1a, 0x75, 0x1e, 0xe1, 0xa9, - 0x5e, 0x90, 0x25, 0xad, 0x3e, 0x7a, 0x02, 0xf9, 0x0e, 0xb3, 0x78, 0x6d, 0x6e, 0x43, 0xa9, 0x95, - 0x1a, 0xf7, 0x0e, 0x8f, 0xd6, 0xb7, 0x1c, 0x97, 0xf5, 0x46, 0x1d, 0xcd, 0x22, 0xc3, 0xba, 0xcc, - 0xb4, 0x7a, 0xa6, 0xeb, 0x45, 0x0f, 0x75, 0x36, 0xf5, 0x31, 0xd5, 0x1a, 0xbb, 0xad, 0xdb, 0x77, - 0x6e, 0xc9, 0x96, 0x8b, 0x1d, 0x66, 0xb5, 0xfa, 0xe8, 0x33, 0xc8, 0xfa, 0xc4, 0x57, 0x17, 0x05, - 0x8e, 0x9a, 0xf6, 0x5a, 0xe9, 0xb5, 0x56, 0x40, 0x48, 0xf7, 0x69, 0xb7, 0x45, 0x28, 0xc5, 0x62, - 0x17, 0x3a, 0x2f, 0x42, 0x77, 0x60, 0x85, 0x0e, 0x4c, 0xda, 0xc3, 0xb6, 0x11, 0x6d, 0xa9, 0x87, - 0x5d, 0xa7, 0xc7, 0xd4, 0xfc, 0x86, 0x52, 0xcb, 0xe9, 0xcb, 0x32, 0xda, 0x08, 0x83, 0x0f, 0x45, - 0x0c, 0x7d, 0x0c, 0x28, 0xae, 0x62, 0x56, 0x54, 0xb1, 0x24, 0x2a, 0x2a, 0x51, 0x05, 0xb3, 0xc2, - 0xec, 0xea, 0xcf, 0x19, 0x50, 0x8f, 0x2b, 0xfb, 0xb5, 0xcb, 0x7a, 0x4f, 0x30, 0x33, 0x53, 0x5c, - 0x28, 0x67, 0xc1, 0xc5, 0x0a, 0xe4, 0x25, 0x9a, 0x8c, 0x40, 0x23, 0x9f, 0xd0, 0xff, 0xa1, 0x34, - 0x26, 0xcc, 0xf5, 0x1c, 0xc3, 0x27, 0x3f, 0xe2, 0x40, 0x88, 0x96, 0xd3, 0x8b, 0xe1, 0x5a, 0x8b, - 0x2f, 0x9d, 0x42, 0x45, 0xee, 0x9d, 0xa9, 0x58, 0x3c, 0x81, 0x8a, 0x67, 0x79, 0x28, 0x37, 0xf6, - 0xb7, 0x9b, 0x78, 0x80, 0x1d, 0x93, 0xbd, 0xea, 0x25, 0x65, 0x0e, 0x2f, 0x65, 0xce, 0xd0, 0x4b, - 0xd9, 0xf7, 0xf1, 0xd2, 0x77, 0x70, 0xbe, 0xeb, 0x1b, 0x21, 0x1a, 0x63, 0xe0, 0x52, 0x4e, 0x5c, - 0x76, 0x0e, 0x48, 0xc5, 0xae, 0xdf, 0xe0, 0xa0, 0x1e, 0xbb, 0x54, 0x08, 0x48, 0x99, 0x19, 0xb0, - 0x59, 0x86, 0x8b, 0x62, 0x4d, 0x4a, 0xf1, 0x3f, 0x00, 0xec, 0xd9, 0xb3, 0xfe, 0x2d, 0x60, 0xcf, - 0x96, 0xe1, 0x55, 0x28, 0x30, 0xc2, 0xcc, 0x81, 0x41, 0xcd, 0xc8, 0xab, 0xe7, 0xc4, 0x42, 0xdb, - 0x14, 0xb5, 0x72, 0x83, 0x06, 0x9b, 0xa8, 0xe7, 0x38, 0x95, 0x7a, 0x41, 0xae, 0xec, 0x4f, 0x84, - 0xca, 0x32, 0x4c, 0x46, 0xcc, 0x1f, 0x31, 0xc3, 0xb5, 0x27, 0x6a, 0x61, 0x43, 0xa9, 0x95, 0xf5, - 0x8a, 0x8c, 0x3c, 0x15, 0x81, 0x5d, 0x7b, 0x82, 0xb6, 0xa0, 0x28, 0x94, 0x97, 0xdd, 0x40, 0x08, - 0x73, 0xf1, 0xf0, 0x68, 0x9d, 0x6b, 0xdf, 0x96, 0x91, 0xfd, 0x89, 0x0e, 0x34, 0xfe, 0x8d, 0xbe, - 0x87, 0xb2, 0x1d, 0xba, 0x82, 0x04, 0x06, 0x75, 0x1d, 0xb5, 0x28, 0xaa, 0x3e, 0x3d, 0x3c, 0x5a, - 0xbf, 0xfb, 0x2e, 0xdc, 0xb5, 0x5d, 0xc7, 0x33, 0xd9, 0x28, 0xc0, 0x7a, 0x29, 0xee, 0xd7, 0x76, - 0x1d, 0x74, 0x00, 0x65, 0x8b, 0x8c, 0xb1, 0x67, 0x7a, 0x8c, 0xb7, 0xa7, 0x6a, 0x69, 0x23, 0x5b, - 0x2b, 0x6e, 0xdd, 0x3a, 0x41, 0xe2, 0x6d, 0x99, 0x7b, 0xdf, 0x36, 0xfd, 0xb0, 0x43, 0xd8, 0x95, - 0xea, 0xa5, 0xa8, 0x4d, 0xdb, 0x75, 0x28, 0xfa, 0x10, 0xce, 0x8f, 0xbc, 0x0e, 0xf1, 0x6c, 0xb1, - 0x57, 0x77, 0x88, 0xd5, 0xb2, 0x20, 0xa5, 0x1c, 0xaf, 0xee, 0xbb, 0x43, 0x8c, 0xbe, 0x84, 0x0a, - 0xf7, 0xc5, 0xc8, 0xb3, 0x63, 0xe7, 0xab, 0xe7, 0x85, 0xc7, 0x6e, 0x9c, 0x00, 0xa0, 0xb1, 0xbf, - 0x7d, 0x90, 0xca, 0xd6, 0x2f, 0x74, 0x98, 0x95, 0x5e, 0xa8, 0xfe, 0x96, 0x83, 0x0b, 0xc7, 0x92, - 0xb8, 0x49, 0x52, 0x68, 0x26, 0xe1, 0x27, 0x45, 0x2f, 0x26, 0x58, 0x5e, 0xd1, 0x26, 0xf3, 0x36, - 0xda, 0xfc, 0x00, 0x57, 0x12, 0x6d, 0x92, 0x01, 0x5c, 0xa5, 0xec, 0xbc, 0x2a, 0x5d, 0x8e, 0x3b, - 0x1f, 0x44, 0x8d, 0xb9, 0x5c, 0x04, 0x56, 0x52, 0x76, 0x88, 0x00, 0xf3, 0x89, 0xb9, 0x79, 0x27, - 0x2e, 0x27, 0xbe, 0x90, 0x7d, 0xf9, 0xc0, 0x2e, 0xac, 0x24, 0xfe, 0x48, 0xcd, 0xa3, 0xea, 0xe2, - 0x7b, 0x1a, 0x65, 0x39, 0x36, 0x4a, 0x32, 0x86, 0x22, 0x0b, 0x56, 0xe3, 0x39, 0x33, 0x54, 0x86, - 0x5f, 0x8c, 0xbc, 0x18, 0x76, 0xfd, 0x84, 0x61, 0x71, 0xf7, 0x5d, 0xaf, 0x4b, 0x74, 0x35, 0x6a, - 0x94, 0x66, 0x8e, 0x7f, 0x2c, 0xaa, 0x3f, 0x65, 0xe0, 0xd2, 0x31, 0x6f, 0xf0, 0x8a, 0xb7, 0xf1, - 0xc7, 0x1b, 0xf0, 0x65, 0xce, 0x02, 0xdf, 0x29, 0x64, 0x67, 0xcf, 0x92, 0xec, 0x6a, 0x1b, 0xae, - 0x24, 0xa7, 0x0d, 0x09, 0x92, 0x63, 0x87, 0xa2, 0x4f, 0x20, 0x67, 0xe3, 0x01, 0x55, 0x95, 0x53, - 0x37, 0x34, 0x73, 0x56, 0xe9, 0xa2, 0xa2, 0xba, 0x07, 0xab, 0xaf, 0x6f, 0xba, 0xeb, 0xd9, 0x78, - 0x82, 0xea, 0xb0, 0x9c, 0x7c, 0x49, 0x8d, 0x9e, 0x49, 0x7b, 0x21, 0x73, 0x7c, 0x50, 0x49, 0xbf, - 0x18, 0x7f, 0x53, 0x1f, 0x9a, 0xb4, 0x27, 0xc4, 0xfa, 0x5d, 0x81, 0xf2, 0x0c, 0x71, 0xe8, 0x01, - 0x64, 0xe6, 0xbe, 0x0f, 0x64, 0xfc, 0x3e, 0x7a, 0x04, 0x59, 0xfe, 0xc6, 0x64, 0xe6, 0x7d, 0x63, - 0x78, 0x97, 0xea, 0x2f, 0x0a, 0x5c, 0x3d, 0x91, 0x7f, 0x7e, 0x0c, 0x5b, 0x64, 0x7c, 0x06, 0xd7, - 0x18, 0x8b, 0x8c, 0x5b, 0x7d, 0x6e, 0x54, 0x33, 0x9c, 0x11, 0xda, 0x22, 0x23, 0xc8, 0x2b, 0x9a, - 0xf1, 0x5c, 0x5a, 0xfd, 0x53, 0x81, 0xab, 0x6d, 0x3c, 0xc0, 0x16, 0x73, 0xc7, 0x38, 0x52, 0x7d, - 0x87, 0x5f, 0xae, 0x3c, 0x0b, 0xa3, 0x1b, 0x70, 0xe1, 0x98, 0x0a, 0x02, 0x58, 0x41, 0x2f, 0xcf, - 0x08, 0x80, 0x74, 0x28, 0xc4, 0x67, 0xf6, 0x9c, 0x37, 0x88, 0x25, 0x79, 0x5c, 0xa3, 0x9b, 0x70, - 0x29, 0xc0, 0xdc, 0x8f, 0x01, 0xb6, 0x0d, 0xd9, 0x9d, 0x86, 0xf7, 0xe4, 0x92, 0x5e, 0x89, 0x43, - 0x0f, 0x78, 0x7a, 0xbb, 0xff, 0xd1, 0x8e, 0x78, 0x57, 0x13, 0x1b, 0xb5, 0x99, 0xc9, 0x46, 0x14, - 0x15, 0x61, 0xa9, 0xb5, 0xb3, 0xd7, 0xdc, 0xdd, 0xfb, 0xa2, 0xb2, 0x80, 0x00, 0xf2, 0xf7, 0xb7, - 0xf7, 0x77, 0xbf, 0xda, 0xa9, 0x28, 0xa8, 0x04, 0xe7, 0x0e, 0xf6, 0x1a, 0x4f, 0xf7, 0x9a, 0x3b, - 0xcd, 0x4a, 0x06, 0x2d, 0x41, 0xf6, 0xfe, 0xde, 0x37, 0x95, 0x6c, 0xe3, 0xf1, 0xb3, 0x17, 0x6b, - 0xca, 0xf3, 0x17, 0x6b, 0xca, 0xbf, 0x2f, 0xd6, 0x94, 0x5f, 0x5f, 0xae, 0x2d, 0x3c, 0x7f, 0xb9, - 0xb6, 0xf0, 0xcf, 0xcb, 0xb5, 0x85, 0x6f, 0xdf, 0xb8, 0x99, 0x49, 0xfa, 0x4f, 0x89, 0xd8, 0x59, - 0x27, 0x2f, 0xfe, 0x94, 0xdc, 0xfe, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x72, 0x85, 0x4f, 0x14, 0x71, - 0x0d, 0x00, 0x00, + // 1175 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xce, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0xad, 0x3b, 0x4d, 0xd3, 0x6d, 0x23, 0x92, 0x60, 0x4a, + 0x65, 0x21, 0xba, 0x6e, 0xd2, 0x1f, 0x01, 0x17, 0x48, 0x75, 0x9c, 0xd2, 0xa8, 0xad, 0x6b, 0xd6, + 0x0e, 0x08, 0x90, 0x58, 0xad, 0x77, 0xc7, 0xeb, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, 0x37, + 0xe0, 0x06, 0x89, 0x5b, 0xee, 0x79, 0x04, 0x9e, 0x01, 0xf5, 0xb2, 0xe2, 0x06, 0x94, 0x8b, 0x08, + 0xb5, 0x2f, 0x82, 0x66, 0x76, 0xf6, 0xc7, 0x6d, 0x53, 0x68, 0xdd, 0x3b, 0xcf, 0x9c, 0x73, 0xbe, + 0xf3, 0xcd, 0xf9, 0x3e, 0xcf, 0x2c, 0x5c, 0xeb, 0x99, 0xbd, 0xf9, 0x88, 0x78, 0xf5, 0x1e, 0xb3, + 0x28, 0x33, 0x87, 0xae, 0xe7, 0xd4, 0xa7, 0xbb, 0xa9, 0x95, 0xe6, 0x07, 0x84, 0x11, 0x74, 0x51, + 0xe6, 0x69, 0xa9, 0xc8, 0x74, 0xf7, 0xca, 0xba, 0x43, 0x1c, 0x22, 0x32, 0xea, 0xfc, 0x57, 0x98, + 0x7c, 0xe5, 0xb2, 0x45, 0xe8, 0x98, 0x50, 0x23, 0x0c, 0x84, 0x0b, 0x19, 0xaa, 0x86, 0xab, 0xba, + 0x15, 0xcc, 0x7d, 0x46, 0xea, 0x14, 0x5b, 0xfe, 0xde, 0xed, 0x3b, 0xc3, 0xdd, 0xfa, 0x10, 0xcf, + 0xa3, 0x9c, 0xab, 0x32, 0x27, 0xe1, 0xd3, 0xc3, 0xcc, 0xdc, 0xad, 0x2f, 0x30, 0xba, 0xb2, 0xfd, + 0x6a, 0xe6, 0x3e, 0xf1, 0xc3, 0x84, 0xea, 0x5f, 0x59, 0xa8, 0xdc, 0x73, 0x3d, 0x73, 0xe4, 0xb2, + 0x79, 0x3b, 0x20, 0x53, 0xd7, 0xc6, 0x01, 0x3a, 0x80, 0xa2, 0x8d, 0xa9, 0x15, 0xb8, 0x3e, 0x73, + 0x89, 0xa7, 0x2a, 0x3b, 0x4a, 0xad, 0xb8, 0xf7, 0x81, 0x26, 0x39, 0x26, 0x27, 0x13, 0x1d, 0xb5, + 0x66, 0x92, 0xaa, 0xa7, 0xeb, 0xd0, 0x23, 0x00, 0x8b, 0x8c, 0xc7, 0x2e, 0xa5, 0x1c, 0x25, 0xb3, + 0xa3, 0xd4, 0x0a, 0x8d, 0xeb, 0xc7, 0x27, 0xdb, 0x9b, 0x21, 0x10, 0xb5, 0x87, 0x9a, 0x4b, 0xea, + 0x63, 0x93, 0x0d, 0xb4, 0x87, 0xd8, 0x31, 0xad, 0x79, 0x13, 0x5b, 0x7f, 0xfe, 0x7e, 0x1d, 0x64, + 0x9f, 0x26, 0xb6, 0xf4, 0x14, 0x00, 0xfa, 0x1c, 0x40, 0x9e, 0xc6, 0xf0, 0x87, 0x6a, 0x56, 0x90, + 0xda, 0x8e, 0x48, 0x85, 0xa3, 0xd2, 0xe2, 0x51, 0x69, 0xed, 0x49, 0xef, 0x01, 0x9e, 0xeb, 0x05, + 0x59, 0xd2, 0x1e, 0xa2, 0x47, 0x90, 0xef, 0x31, 0x8b, 0xd7, 0xe6, 0x76, 0x94, 0x5a, 0xa9, 0x71, + 0xe7, 0xf8, 0x64, 0x7b, 0xcf, 0x71, 0xd9, 0x60, 0xd2, 0xd3, 0x2c, 0x32, 0xae, 0xcb, 0x4c, 0x6b, + 0x60, 0xba, 0x5e, 0xb4, 0xa8, 0xb3, 0xb9, 0x8f, 0xa9, 0xd6, 0x38, 0x6c, 0xdf, 0xbc, 0x75, 0x43, + 0x42, 0xae, 0xf6, 0x98, 0xd5, 0x1e, 0xa2, 0xcf, 0x20, 0xeb, 0x13, 0x5f, 0x5d, 0x15, 0x3c, 0x6a, + 0xda, 0x2b, 0xa5, 0xd7, 0xda, 0x01, 0x21, 0xfd, 0xc7, 0xfd, 0x36, 0xa1, 0x14, 0x8b, 0x53, 0xe8, + 0xbc, 0x08, 0xdd, 0x82, 0x0d, 0x3a, 0x32, 0xe9, 0x00, 0xdb, 0x46, 0x74, 0xa4, 0x01, 0x76, 0x9d, + 0x01, 0x53, 0xf3, 0x3b, 0x4a, 0x2d, 0xa7, 0xaf, 0xcb, 0x68, 0x23, 0x0c, 0xde, 0x17, 0x31, 0xf4, + 0x31, 0xa0, 0xb8, 0x8a, 0x59, 0x51, 0xc5, 0x9a, 0xa8, 0xa8, 0x44, 0x15, 0xcc, 0x0a, 0xb3, 0xab, + 0x3f, 0x65, 0x40, 0x7d, 0x51, 0xd9, 0xaf, 0x5d, 0x36, 0x78, 0x84, 0x99, 0x99, 0x9a, 0x85, 0xf2, + 0x2e, 0x66, 0xb1, 0x01, 0x79, 0xc9, 0x26, 0x23, 0xd8, 0xc8, 0x15, 0x7a, 0x1f, 0x4a, 0x53, 0xc2, + 0x5c, 0xcf, 0x31, 0x7c, 0xf2, 0x23, 0x0e, 0x84, 0x68, 0x39, 0xbd, 0x18, 0xee, 0xb5, 0xf9, 0xd6, + 0x6b, 0x46, 0x91, 0x7b, 0xe3, 0x51, 0xac, 0x9e, 0x32, 0x8a, 0x27, 0x79, 0x28, 0x37, 0xba, 0xfb, + 0x4d, 0x3c, 0xc2, 0x8e, 0xc9, 0x5e, 0xf6, 0x92, 0xb2, 0x84, 0x97, 0x32, 0xef, 0xd0, 0x4b, 0xd9, + 0xb7, 0xf1, 0xd2, 0x77, 0x70, 0xb6, 0xef, 0x1b, 0x21, 0x1b, 0x63, 0xe4, 0x52, 0x3e, 0xb8, 0xec, + 0x12, 0x94, 0x8a, 0x7d, 0xbf, 0xc1, 0x49, 0x3d, 0x74, 0xa9, 0x10, 0x90, 0x32, 0x33, 0x60, 0x8b, + 0x13, 0x2e, 0x8a, 0x3d, 0x29, 0xc5, 0x7b, 0x00, 0xd8, 0xb3, 0x17, 0xfd, 0x5b, 0xc0, 0x9e, 0x2d, + 0xc3, 0x9b, 0x50, 0x60, 0x84, 0x99, 0x23, 0x83, 0x9a, 0x91, 0x57, 0xcf, 0x88, 0x8d, 0x8e, 0x29, + 0x6a, 0xe5, 0x01, 0x0d, 0x36, 0x53, 0xcf, 0xf0, 0x51, 0xea, 0x05, 0xb9, 0xd3, 0x9d, 0x09, 0x95, + 0x65, 0x98, 0x4c, 0x98, 0x3f, 0x61, 0x86, 0x6b, 0xcf, 0xd4, 0xc2, 0x8e, 0x52, 0x2b, 0xeb, 0x15, + 0x19, 0x79, 0x2c, 0x02, 0x87, 0xf6, 0x0c, 0xed, 0x41, 0x51, 0x28, 0x2f, 0xd1, 0x40, 0x08, 0x73, + 0xfe, 0xf8, 0x64, 0x9b, 0x6b, 0xdf, 0x91, 0x91, 0xee, 0x4c, 0x07, 0x1a, 0xff, 0x46, 0xdf, 0x43, + 0xd9, 0x0e, 0x5d, 0x41, 0x02, 0x83, 0xba, 0x8e, 0x5a, 0x14, 0x55, 0x9f, 0x1e, 0x9f, 0x6c, 0xdf, + 0x7e, 0x93, 0xd9, 0x75, 0x5c, 0xc7, 0x33, 0xd9, 0x24, 0xc0, 0x7a, 0x29, 0xc6, 0xeb, 0xb8, 0x0e, + 0x3a, 0x82, 0xb2, 0x45, 0xa6, 0xd8, 0x33, 0x3d, 0xc6, 0xe1, 0xa9, 0x5a, 0xda, 0xc9, 0xd6, 0x8a, + 0x7b, 0x37, 0x4e, 0x91, 0x78, 0x5f, 0xe6, 0xde, 0xb5, 0x4d, 0x3f, 0x44, 0x08, 0x51, 0xa9, 0x5e, + 0x8a, 0x60, 0x3a, 0xae, 0x43, 0xd1, 0x87, 0x70, 0x76, 0xe2, 0xf5, 0x88, 0x67, 0x8b, 0xb3, 0xba, + 0x63, 0xac, 0x96, 0xc5, 0x50, 0xca, 0xf1, 0x6e, 0xd7, 0x1d, 0x63, 0xf4, 0x25, 0x54, 0xb8, 0x2f, + 0x26, 0x9e, 0x1d, 0x3b, 0x5f, 0x3d, 0x2b, 0x3c, 0x76, 0xed, 0x14, 0x02, 0x8d, 0xee, 0xfe, 0x51, + 0x2a, 0x5b, 0x3f, 0xd7, 0x63, 0x56, 0x7a, 0xa3, 0xfa, 0x6b, 0x0e, 0xce, 0xbd, 0x90, 0xc4, 0x4d, + 0x92, 0x62, 0x33, 0x0b, 0xaf, 0x14, 0xbd, 0x98, 0x70, 0x79, 0x49, 0x9b, 0xcc, 0xff, 0xd1, 0xe6, + 0x07, 0xb8, 0x94, 0x68, 0x93, 0x34, 0xe0, 0x2a, 0x65, 0x97, 0x55, 0xe9, 0x62, 0x8c, 0x7c, 0x14, + 0x01, 0x73, 0xb9, 0x08, 0x6c, 0xa4, 0xec, 0x10, 0x11, 0xe6, 0x1d, 0x73, 0xcb, 0x76, 0x5c, 0x4f, + 0x7c, 0x21, 0x71, 0x79, 0xc3, 0x3e, 0x6c, 0x24, 0xfe, 0x48, 0xf5, 0xa3, 0xea, 0xea, 0x5b, 0x1a, + 0x65, 0x3d, 0x36, 0x4a, 0xd2, 0x86, 0x22, 0x0b, 0x36, 0xe3, 0x3e, 0x0b, 0xa3, 0x0c, 0x6f, 0x8c, + 0xbc, 0x68, 0x76, 0xf5, 0x94, 0x66, 0x31, 0xfa, 0xa1, 0xd7, 0x27, 0xba, 0x1a, 0x01, 0xa5, 0x27, + 0xc7, 0x2f, 0x8b, 0x6a, 0x07, 0x2e, 0x25, 0xb7, 0x2c, 0x09, 0x92, 0xeb, 0x96, 0xa2, 0x4f, 0x20, + 0x67, 0xe3, 0x11, 0x55, 0x95, 0xd7, 0x36, 0x5a, 0xb8, 0xa3, 0x75, 0x51, 0x51, 0x6d, 0xc1, 0xe6, + 0xab, 0x41, 0x0f, 0x3d, 0x1b, 0xcf, 0x50, 0x1d, 0xd6, 0x93, 0x1b, 0xc4, 0x18, 0x98, 0x74, 0x10, + 0x9e, 0x88, 0x37, 0x2a, 0xe9, 0xe7, 0xe3, 0xbb, 0xe4, 0xbe, 0x49, 0x07, 0x82, 0xe4, 0x6f, 0x0a, + 0x94, 0x17, 0x0e, 0x84, 0xee, 0x41, 0x66, 0xe9, 0x77, 0x30, 0xe3, 0x0f, 0xd1, 0x03, 0xc8, 0x72, + 0xa7, 0x64, 0x96, 0x75, 0x0a, 0x47, 0xa9, 0xfe, 0xac, 0xc0, 0xe5, 0x53, 0x45, 0xe6, 0xcf, 0x8f, + 0x45, 0xa6, 0xef, 0xe0, 0xf9, 0xb6, 0xc8, 0xb4, 0x3d, 0xe4, 0x7f, 0x60, 0x33, 0xec, 0x11, 0x7a, + 0x2f, 0x23, 0x86, 0x57, 0x34, 0xe3, 0xbe, 0xb4, 0xfa, 0x87, 0x02, 0x97, 0x3b, 0x78, 0x84, 0x2d, + 0xe6, 0x4e, 0x71, 0x64, 0xad, 0x03, 0xfe, 0x51, 0xe1, 0x59, 0x18, 0x5d, 0x83, 0x73, 0x2f, 0xa8, + 0x20, 0x88, 0x15, 0xf4, 0xf2, 0x82, 0x00, 0x48, 0x87, 0x42, 0xfc, 0x56, 0x2d, 0xf9, 0x72, 0xae, + 0xc9, 0x67, 0x0a, 0x5d, 0x87, 0x0b, 0x01, 0xe6, 0x9e, 0x0c, 0xb0, 0x6d, 0x48, 0x74, 0x1a, 0x7e, + 0x1f, 0x96, 0xf4, 0x4a, 0x1c, 0xba, 0xc7, 0xd3, 0x3b, 0xc3, 0x8f, 0x0e, 0xe0, 0xc2, 0x82, 0xcd, + 0x3a, 0xcc, 0x64, 0x13, 0x8a, 0x8a, 0xb0, 0xd6, 0x3e, 0x68, 0x35, 0x0f, 0x5b, 0x5f, 0x54, 0x56, + 0x10, 0x40, 0xfe, 0xee, 0x7e, 0xf7, 0xf0, 0xab, 0x83, 0x8a, 0x82, 0x4a, 0x70, 0xe6, 0xa8, 0xd5, + 0x78, 0xdc, 0x6a, 0x1e, 0x34, 0x2b, 0x19, 0xb4, 0x06, 0xd9, 0xbb, 0xad, 0x6f, 0x2a, 0xd9, 0xc6, + 0xc3, 0x27, 0xcf, 0xb6, 0x94, 0xa7, 0xcf, 0xb6, 0x94, 0x7f, 0x9e, 0x6d, 0x29, 0xbf, 0x3c, 0xdf, + 0x5a, 0x79, 0xfa, 0x7c, 0x6b, 0xe5, 0xef, 0xe7, 0x5b, 0x2b, 0xdf, 0xfe, 0xe7, 0x61, 0x66, 0xe9, + 0x8f, 0x71, 0x71, 0xb2, 0x5e, 0x5e, 0x7c, 0x8c, 0xdf, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc4, + 0x5e, 0xb6, 0xaa, 0x69, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -1281,64 +1209,6 @@ func (m *BTCUndelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *BTCUndelegationInfo) 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 *BTCUndelegationInfo) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *BTCUndelegationInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.CovenantSlashingSigs) > 0 { - for iNdEx := len(m.CovenantSlashingSigs) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.CovenantSlashingSigs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintBtcstaking(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - } - if len(m.CovenantUnbondingSigList) > 0 { - for iNdEx := len(m.CovenantUnbondingSigList) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.CovenantUnbondingSigList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintBtcstaking(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if len(m.UnbondingTx) > 0 { - i -= len(m.UnbondingTx) - copy(dAtA[i:], m.UnbondingTx) - i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.UnbondingTx))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - func (m *BTCDelegatorDelegations) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1720,31 +1590,6 @@ func (m *BTCUndelegation) Size() (n int) { return n } -func (m *BTCUndelegationInfo) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.UnbondingTx) - if l > 0 { - n += 1 + l + sovBtcstaking(uint64(l)) - } - if len(m.CovenantUnbondingSigList) > 0 { - for _, e := range m.CovenantUnbondingSigList { - l = e.Size() - n += 1 + l + sovBtcstaking(uint64(l)) - } - } - if len(m.CovenantSlashingSigs) > 0 { - for _, e := range m.CovenantSlashingSigs { - l = e.Size() - n += 1 + l + sovBtcstaking(uint64(l)) - } - } - return n -} - func (m *BTCDelegatorDelegations) Size() (n int) { if m == nil { return 0 @@ -2984,158 +2829,6 @@ func (m *BTCUndelegation) Unmarshal(dAtA []byte) error { } return nil } -func (m *BTCUndelegationInfo) 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 ErrIntOverflowBtcstaking - } - 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: BTCUndelegationInfo: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: BTCUndelegationInfo: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTx", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthBtcstaking - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthBtcstaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UnbondingTx = append(m.UnbondingTx[:0], dAtA[iNdEx:postIndex]...) - if m.UnbondingTx == nil { - m.UnbondingTx = []byte{} - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CovenantUnbondingSigList", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthBtcstaking - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthBtcstaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CovenantUnbondingSigList = append(m.CovenantUnbondingSigList, &SignatureInfo{}) - if err := m.CovenantUnbondingSigList[len(m.CovenantUnbondingSigList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CovenantSlashingSigs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthBtcstaking - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthBtcstaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.CovenantSlashingSigs = append(m.CovenantSlashingSigs, &CovenantAdaptorSignatures{}) - if err := m.CovenantSlashingSigs[len(m.CovenantSlashingSigs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipBtcstaking(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthBtcstaking - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *BTCDelegatorDelegations) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go new file mode 100644 index 000000000..df669cbb5 --- /dev/null +++ b/x/btcstaking/types/query.go @@ -0,0 +1,55 @@ +package types + +import ( + "encoding/hex" +) + +// NewBTCDelegationResponse returns a new delegation response structure. +func NewBTCDelegationResponse(btcDel *BTCDelegation, status BTCDelegationStatus) (resp *BTCDelegationResponse) { + resp = &BTCDelegationResponse{ + BtcPk: btcDel.BtcPk, + FpBtcPkList: btcDel.FpBtcPkList, + StartHeight: btcDel.StartHeight, + EndHeight: btcDel.EndHeight, + TotalSat: btcDel.TotalSat, + StakingTxHex: hex.EncodeToString(btcDel.StakingTx), + DelegatorSlashSigHex: btcDel.DelegatorSig.ToHexStr(), + CovenantSigs: btcDel.CovenantSigs, + StakingOutputIdx: btcDel.StakingOutputIdx, + Active: status == BTCDelegationStatus_ACTIVE, + StatusDesc: status.String(), + UnbondingTime: btcDel.UnbondingTime, + UndelegationResponse: nil, + } + + if btcDel.SlashingTx != nil { + resp.SlashingTxHex = hex.EncodeToString(*btcDel.SlashingTx) + } + + if btcDel.BtcUndelegation != nil { + resp.UndelegationResponse = btcDel.BtcUndelegation.ToResponse() + } + + return resp +} + +// ToResponse parses an BTCUndelegation into BTCUndelegationResponse. +func (ud *BTCUndelegation) ToResponse() (resp *BTCUndelegationResponse) { + resp = &BTCUndelegationResponse{ + UnbondingTxHex: hex.EncodeToString(ud.UnbondingTx), + CovenantUnbondingSigList: ud.CovenantUnbondingSigList, + CovenantSlashingSigs: ud.CovenantSlashingSigs, + } + + if ud.DelegatorUnbondingSig != nil { + resp.DelegatorUnbondingSigHex = ud.DelegatorUnbondingSig.ToHexStr() + } + if ud.SlashingTx != nil { + resp.SlashingTxHex = ud.SlashingTx.ToHexStr() + } + if ud.DelegatorSlashingSig != nil { + resp.DelegatorSlashingSigHex = ud.DelegatorSlashingSig.ToHexStr() + } + + return resp +} diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index fb4f4e200..8ef5396b5 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -911,7 +911,7 @@ func (m *QueryFinalityProviderDelegationsRequest) GetPagination() *query.PageReq // Query/FinalityProviderDelegations RPC method. type QueryFinalityProviderDelegationsResponse struct { // btc_delegator_delegations contains all the queried BTC delegations. - BtcDelegatorDelegations []*BTCDelegatorDelegations `protobuf:"bytes,1,rep,name=btc_delegator_delegations,json=btcDelegatorDelegations,proto3" json:"btc_delegator_delegations,omitempty"` + BtcDelegatorDelegations []*BTCDelegatorDelegationsResponse `protobuf:"bytes,1,rep,name=btc_delegator_delegations,json=btcDelegatorDelegations,proto3" json:"btc_delegator_delegations,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -951,7 +951,7 @@ func (m *QueryFinalityProviderDelegationsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryFinalityProviderDelegationsResponse proto.InternalMessageInfo -func (m *QueryFinalityProviderDelegationsResponse) GetBtcDelegatorDelegations() []*BTCDelegatorDelegations { +func (m *QueryFinalityProviderDelegationsResponse) GetBtcDelegatorDelegations() []*BTCDelegatorDelegationsResponse { if m != nil { return m.BtcDelegatorDelegations } @@ -1015,6 +1015,52 @@ func (m *QueryBTCDelegationRequest) GetStakingTxHashHex() string { // QueryBTCDelegationResponse is response type matching QueryBTCDelegationRequest // and containing BTC delegation information type QueryBTCDelegationResponse struct { + // BTCDelegation represents the client needed information of an BTCDelegation. + BtcDelegation *BTCDelegationResponse `protobuf:"bytes,1,opt,name=btc_delegation,json=btcDelegation,proto3" json:"btc_delegation,omitempty"` +} + +func (m *QueryBTCDelegationResponse) Reset() { *m = QueryBTCDelegationResponse{} } +func (m *QueryBTCDelegationResponse) String() string { return proto.CompactTextString(m) } +func (*QueryBTCDelegationResponse) ProtoMessage() {} +func (*QueryBTCDelegationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{19} +} +func (m *QueryBTCDelegationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryBTCDelegationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryBTCDelegationResponse.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 *QueryBTCDelegationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryBTCDelegationResponse.Merge(m, src) +} +func (m *QueryBTCDelegationResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryBTCDelegationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryBTCDelegationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryBTCDelegationResponse proto.InternalMessageInfo + +func (m *QueryBTCDelegationResponse) GetBtcDelegation() *BTCDelegationResponse { + if m != nil { + return m.BtcDelegation + } + return nil +} + +// BTCDelegationResponse is the client needed information from a BTCDelegation with the current status based on parameters. +type BTCDelegationResponse struct { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` @@ -1032,31 +1078,41 @@ type QueryBTCDelegationResponse struct { TotalSat uint64 `protobuf:"varint,5,opt,name=total_sat,json=totalSat,proto3" json:"total_sat,omitempty"` // staking_tx_hex is the hex string of staking tx StakingTxHex string `protobuf:"bytes,6,opt,name=staking_tx_hex,json=stakingTxHex,proto3" json:"staking_tx_hex,omitempty"` + // slashing_tx_hex is the hex string of slashing tx + SlashingTxHex string `protobuf:"bytes,7,opt,name=slashing_tx_hex,json=slashingTxHex,proto3" json:"slashing_tx_hex,omitempty"` + // delegator_slash_sig_hex is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk) as string hex. + // It will be a part of the witness for the staking tx output. + DelegatorSlashSigHex string `protobuf:"bytes,8,opt,name=delegator_slash_sig_hex,json=delegatorSlashSigHex,proto3" json:"delegator_slash_sig_hex,omitempty"` // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. - CovenantSigs []*CovenantAdaptorSignatures `protobuf:"bytes,7,rep,name=covenant_sigs,json=covenantSigs,proto3" json:"covenant_sigs,omitempty"` + CovenantSigs []*CovenantAdaptorSignatures `protobuf:"bytes,9,rep,name=covenant_sigs,json=covenantSigs,proto3" json:"covenant_sigs,omitempty"` + // staking_output_idx is the index of the staking output in the staking tx + StakingOutputIdx uint32 `protobuf:"varint,10,opt,name=staking_output_idx,json=stakingOutputIdx,proto3" json:"staking_output_idx,omitempty"` // whether this delegation is active - Active bool `protobuf:"varint,8,opt,name=active,proto3" json:"active,omitempty"` + Active bool `protobuf:"varint,11,opt,name=active,proto3" json:"active,omitempty"` + // descriptive status of current delegation. + StatusDesc string `protobuf:"bytes,12,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` // unbonding_time used in unbonding output timelock path and in slashing transactions // change outputs - UnbondingTime uint32 `protobuf:"varint,9,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` - // undelegation_info is the undelegation info of this delegation. - UndelegationInfo *BTCUndelegationInfo `protobuf:"bytes,10,opt,name=undelegation_info,json=undelegationInfo,proto3" json:"undelegation_info,omitempty"` + UnbondingTime uint32 `protobuf:"varint,13,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` + // undelegation_response is the undelegation info of this delegation. + UndelegationResponse *BTCUndelegationResponse `protobuf:"bytes,14,opt,name=undelegation_response,json=undelegationResponse,proto3" json:"undelegation_response,omitempty"` } -func (m *QueryBTCDelegationResponse) Reset() { *m = QueryBTCDelegationResponse{} } -func (m *QueryBTCDelegationResponse) String() string { return proto.CompactTextString(m) } -func (*QueryBTCDelegationResponse) ProtoMessage() {} -func (*QueryBTCDelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{19} +func (m *BTCDelegationResponse) Reset() { *m = BTCDelegationResponse{} } +func (m *BTCDelegationResponse) String() string { return proto.CompactTextString(m) } +func (*BTCDelegationResponse) ProtoMessage() {} +func (*BTCDelegationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{20} } -func (m *QueryBTCDelegationResponse) XXX_Unmarshal(b []byte) error { +func (m *BTCDelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryBTCDelegationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *BTCDelegationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryBTCDelegationResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_BTCDelegationResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -1066,70 +1122,246 @@ func (m *QueryBTCDelegationResponse) XXX_Marshal(b []byte, deterministic bool) ( return b[:n], nil } } -func (m *QueryBTCDelegationResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryBTCDelegationResponse.Merge(m, src) +func (m *BTCDelegationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCDelegationResponse.Merge(m, src) } -func (m *QueryBTCDelegationResponse) XXX_Size() int { +func (m *BTCDelegationResponse) XXX_Size() int { return m.Size() } -func (m *QueryBTCDelegationResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryBTCDelegationResponse.DiscardUnknown(m) +func (m *BTCDelegationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BTCDelegationResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryBTCDelegationResponse proto.InternalMessageInfo +var xxx_messageInfo_BTCDelegationResponse proto.InternalMessageInfo -func (m *QueryBTCDelegationResponse) GetStartHeight() uint64 { +func (m *BTCDelegationResponse) GetStartHeight() uint64 { if m != nil { return m.StartHeight } return 0 } -func (m *QueryBTCDelegationResponse) GetEndHeight() uint64 { +func (m *BTCDelegationResponse) GetEndHeight() uint64 { if m != nil { return m.EndHeight } return 0 } -func (m *QueryBTCDelegationResponse) GetTotalSat() uint64 { +func (m *BTCDelegationResponse) GetTotalSat() uint64 { if m != nil { return m.TotalSat } return 0 } -func (m *QueryBTCDelegationResponse) GetStakingTxHex() string { +func (m *BTCDelegationResponse) GetStakingTxHex() string { if m != nil { return m.StakingTxHex } return "" } -func (m *QueryBTCDelegationResponse) GetCovenantSigs() []*CovenantAdaptorSignatures { +func (m *BTCDelegationResponse) GetSlashingTxHex() string { + if m != nil { + return m.SlashingTxHex + } + return "" +} + +func (m *BTCDelegationResponse) GetDelegatorSlashSigHex() string { + if m != nil { + return m.DelegatorSlashSigHex + } + return "" +} + +func (m *BTCDelegationResponse) GetCovenantSigs() []*CovenantAdaptorSignatures { if m != nil { return m.CovenantSigs } return nil } -func (m *QueryBTCDelegationResponse) GetActive() bool { +func (m *BTCDelegationResponse) GetStakingOutputIdx() uint32 { + if m != nil { + return m.StakingOutputIdx + } + return 0 +} + +func (m *BTCDelegationResponse) GetActive() bool { if m != nil { return m.Active } return false } -func (m *QueryBTCDelegationResponse) GetUnbondingTime() uint32 { +func (m *BTCDelegationResponse) GetStatusDesc() string { + if m != nil { + return m.StatusDesc + } + return "" +} + +func (m *BTCDelegationResponse) GetUnbondingTime() uint32 { if m != nil { return m.UnbondingTime } return 0 } -func (m *QueryBTCDelegationResponse) GetUndelegationInfo() *BTCUndelegationInfo { +func (m *BTCDelegationResponse) GetUndelegationResponse() *BTCUndelegationResponse { + if m != nil { + return m.UndelegationResponse + } + return nil +} + +// BTCUndelegationResponse provides all necessary info about the undeleagation +type BTCUndelegationResponse struct { + // unbonding_tx is the transaction which will transfer the funds from staking + // output to unbonding output. Unbonding output will usually have lower timelock + // than staking output. The unbonding tx as string hex. + UnbondingTxHex string `protobuf:"bytes,1,opt,name=unbonding_tx_hex,json=unbondingTxHex,proto3" json:"unbonding_tx_hex,omitempty"` + // delegator_unbonding_sig is the signature on the unbonding tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It effectively proves that the delegator wants to unbond and thus + // Babylon will consider this BTC delegation unbonded. Delegator's BTC + // on Bitcoin will be unbonded after timelock. The unbonding delegator sig as string hex. + DelegatorUnbondingSigHex string `protobuf:"bytes,2,opt,name=delegator_unbonding_sig_hex,json=delegatorUnbondingSigHex,proto3" json:"delegator_unbonding_sig_hex,omitempty"` + // covenant_unbonding_sig_list is the list of signatures on the unbonding tx + // by covenant members + CovenantUnbondingSigList []*SignatureInfo `protobuf:"bytes,3,rep,name=covenant_unbonding_sig_list,json=covenantUnbondingSigList,proto3" json:"covenant_unbonding_sig_list,omitempty"` + // slashingTxHex is the hex string of slashing tx + SlashingTxHex string `protobuf:"bytes,4,opt,name=slashing_tx_hex,json=slashingTxHex,proto3" json:"slashing_tx_hex,omitempty"` + // delegator_slashing_sig is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It will be a part of the witness for the unbonding tx output. + // The delegator slashing sig as string hex. + DelegatorSlashingSigHex string `protobuf:"bytes,5,opt,name=delegator_slashing_sig_hex,json=delegatorSlashingSigHex,proto3" json:"delegator_slashing_sig_hex,omitempty"` + // covenant_slashing_sigs is a list of adaptor signatures on the + // unbonding slashing tx by each covenant member + // It will be a part of the witness for the staking tx output. + CovenantSlashingSigs []*CovenantAdaptorSignatures `protobuf:"bytes,6,rep,name=covenant_slashing_sigs,json=covenantSlashingSigs,proto3" json:"covenant_slashing_sigs,omitempty"` +} + +func (m *BTCUndelegationResponse) Reset() { *m = BTCUndelegationResponse{} } +func (m *BTCUndelegationResponse) String() string { return proto.CompactTextString(m) } +func (*BTCUndelegationResponse) ProtoMessage() {} +func (*BTCUndelegationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{21} +} +func (m *BTCUndelegationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BTCUndelegationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BTCUndelegationResponse.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 *BTCUndelegationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCUndelegationResponse.Merge(m, src) +} +func (m *BTCUndelegationResponse) XXX_Size() int { + return m.Size() +} +func (m *BTCUndelegationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BTCUndelegationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BTCUndelegationResponse proto.InternalMessageInfo + +func (m *BTCUndelegationResponse) GetUnbondingTxHex() string { + if m != nil { + return m.UnbondingTxHex + } + return "" +} + +func (m *BTCUndelegationResponse) GetDelegatorUnbondingSigHex() string { + if m != nil { + return m.DelegatorUnbondingSigHex + } + return "" +} + +func (m *BTCUndelegationResponse) GetCovenantUnbondingSigList() []*SignatureInfo { + if m != nil { + return m.CovenantUnbondingSigList + } + return nil +} + +func (m *BTCUndelegationResponse) GetSlashingTxHex() string { + if m != nil { + return m.SlashingTxHex + } + return "" +} + +func (m *BTCUndelegationResponse) GetDelegatorSlashingSigHex() string { + if m != nil { + return m.DelegatorSlashingSigHex + } + return "" +} + +func (m *BTCUndelegationResponse) GetCovenantSlashingSigs() []*CovenantAdaptorSignatures { + if m != nil { + return m.CovenantSlashingSigs + } + return nil +} + +// BTCDelegatorDelegationsResponse is a collection of BTC delegations responses from the same delegator. +type BTCDelegatorDelegationsResponse struct { + Dels []*BTCDelegationResponse `protobuf:"bytes,1,rep,name=dels,proto3" json:"dels,omitempty"` +} + +func (m *BTCDelegatorDelegationsResponse) Reset() { *m = BTCDelegatorDelegationsResponse{} } +func (m *BTCDelegatorDelegationsResponse) String() string { return proto.CompactTextString(m) } +func (*BTCDelegatorDelegationsResponse) ProtoMessage() {} +func (*BTCDelegatorDelegationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{22} +} +func (m *BTCDelegatorDelegationsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BTCDelegatorDelegationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BTCDelegatorDelegationsResponse.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 *BTCDelegatorDelegationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCDelegatorDelegationsResponse.Merge(m, src) +} +func (m *BTCDelegatorDelegationsResponse) XXX_Size() int { + return m.Size() +} +func (m *BTCDelegatorDelegationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BTCDelegatorDelegationsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BTCDelegatorDelegationsResponse proto.InternalMessageInfo + +func (m *BTCDelegatorDelegationsResponse) GetDels() []*BTCDelegationResponse { if m != nil { - return m.UndelegationInfo + return m.Dels } return nil } @@ -1155,96 +1387,113 @@ func init() { proto.RegisterType((*QueryFinalityProviderDelegationsResponse)(nil), "babylon.btcstaking.v1.QueryFinalityProviderDelegationsResponse") proto.RegisterType((*QueryBTCDelegationRequest)(nil), "babylon.btcstaking.v1.QueryBTCDelegationRequest") proto.RegisterType((*QueryBTCDelegationResponse)(nil), "babylon.btcstaking.v1.QueryBTCDelegationResponse") + proto.RegisterType((*BTCDelegationResponse)(nil), "babylon.btcstaking.v1.BTCDelegationResponse") + proto.RegisterType((*BTCUndelegationResponse)(nil), "babylon.btcstaking.v1.BTCUndelegationResponse") + proto.RegisterType((*BTCDelegatorDelegationsResponse)(nil), "babylon.btcstaking.v1.BTCDelegatorDelegationsResponse") } func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1333 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcb, 0x6f, 0x1b, 0x45, - 0x1c, 0xce, 0xa4, 0xa9, 0x69, 0x7e, 0x79, 0x34, 0x99, 0x16, 0x70, 0xdd, 0xc6, 0x49, 0x57, 0x6d, - 0xf3, 0x28, 0xec, 0xd6, 0x4e, 0xe8, 0x01, 0x50, 0xdb, 0x38, 0xa5, 0x4d, 0x1f, 0x11, 0x66, 0x93, - 0x52, 0x09, 0x24, 0xac, 0x59, 0x67, 0xbc, 0x5e, 0x9a, 0xec, 0x6c, 0x77, 0xc7, 0xc6, 0x51, 0xd5, - 0x0b, 0x07, 0x6e, 0x48, 0x48, 0xf0, 0x3f, 0x80, 0xc4, 0x11, 0x71, 0x41, 0x5c, 0xb8, 0xf5, 0x58, - 0xc1, 0x01, 0xc4, 0xa1, 0xa0, 0x16, 0x71, 0x40, 0x42, 0xdc, 0x38, 0x23, 0xcf, 0xce, 0xd6, 0x6b, - 0x7b, 0xd7, 0x59, 0x27, 0xe1, 0x56, 0xef, 0xfc, 0x5e, 0xdf, 0x37, 0xdf, 0x7e, 0xfb, 0x6b, 0xe0, - 0xb4, 0x41, 0x8c, 0x9d, 0x2d, 0x66, 0x6b, 0x06, 0x2f, 0x7b, 0x9c, 0xdc, 0xb3, 0x6c, 0x53, 0xab, - 0xe7, 0xb4, 0xfb, 0x35, 0xea, 0xee, 0xa8, 0x8e, 0xcb, 0x38, 0xc3, 0x2f, 0xca, 0x10, 0xb5, 0x15, - 0xa2, 0xd6, 0x73, 0x99, 0xe3, 0x26, 0x33, 0x99, 0x88, 0xd0, 0x9a, 0xff, 0xf2, 0x83, 0x33, 0xa7, - 0x4c, 0xc6, 0xcc, 0x2d, 0xaa, 0x11, 0xc7, 0xd2, 0x88, 0x6d, 0x33, 0x4e, 0xb8, 0xc5, 0x6c, 0x4f, - 0x9e, 0x2e, 0x94, 0x99, 0xb7, 0xcd, 0x3c, 0xcd, 0x20, 0x1e, 0xf5, 0x7b, 0x68, 0xf5, 0x9c, 0x41, - 0x39, 0xc9, 0x69, 0x0e, 0x31, 0x2d, 0x5b, 0x04, 0xcb, 0x58, 0x25, 0x7a, 0x32, 0x87, 0xb8, 0x64, - 0x3b, 0xa8, 0x77, 0x2e, 0x3a, 0x26, 0x34, 0xa8, 0x88, 0x53, 0x8e, 0x03, 0x7e, 0xa7, 0xd9, 0xad, - 0x28, 0x92, 0x75, 0x7a, 0xbf, 0x46, 0x3d, 0xae, 0xe8, 0x70, 0xac, 0xed, 0xa9, 0xe7, 0x30, 0xdb, - 0xa3, 0xf8, 0x0d, 0x48, 0xf9, 0x4d, 0xd2, 0x68, 0x06, 0xcd, 0x8d, 0xe4, 0xa7, 0xd4, 0x48, 0x02, - 0x54, 0x3f, 0xad, 0x30, 0xf4, 0xe8, 0xc9, 0xf4, 0x80, 0x2e, 0x53, 0x14, 0x13, 0xa6, 0x44, 0xcd, - 0x6b, 0x96, 0x4d, 0xb6, 0x2c, 0xbe, 0x53, 0x74, 0x59, 0xdd, 0xda, 0xa4, 0x6e, 0xd0, 0x14, 0x5f, - 0x03, 0x68, 0x41, 0x95, 0x1d, 0xce, 0xa9, 0x3e, 0x2f, 0x6a, 0x93, 0x17, 0xd5, 0xe7, 0x5e, 0xf2, - 0xa2, 0x16, 0x89, 0x49, 0x65, 0xae, 0x1e, 0xca, 0x54, 0x7e, 0x40, 0x90, 0x8d, 0xeb, 0x24, 0x81, - 0xbc, 0x0b, 0xb8, 0x22, 0x0f, 0x4b, 0x4e, 0x70, 0x9a, 0x46, 0x33, 0x87, 0xe6, 0x46, 0xf2, 0xb3, - 0x31, 0xa0, 0x3a, 0xab, 0xe9, 0x93, 0x95, 0xce, 0xfa, 0xf8, 0x7a, 0x1b, 0x84, 0x41, 0x01, 0x61, - 0x76, 0x57, 0x08, 0xfe, 0x50, 0x6d, 0x18, 0x96, 0xe1, 0x54, 0x24, 0x84, 0x80, 0xab, 0xd3, 0x30, - 0x56, 0x71, 0x4a, 0x06, 0x2f, 0x97, 0x9c, 0x7b, 0xa5, 0x2a, 0x6d, 0x08, 0xba, 0x86, 0x75, 0xa8, - 0x38, 0x05, 0x5e, 0x2e, 0xde, 0x5b, 0xa5, 0x0d, 0xa5, 0x16, 0xc3, 0xf7, 0x73, 0x12, 0x36, 0x60, - 0xb2, 0x8b, 0x04, 0x49, 0x7b, 0x62, 0x0e, 0x26, 0x3a, 0x39, 0x50, 0xbe, 0x42, 0x90, 0x11, 0x7d, - 0x0b, 0x1b, 0x2b, 0x57, 0xe9, 0x16, 0x35, 0x7d, 0x99, 0x07, 0x83, 0x17, 0x20, 0xe5, 0x71, 0xc2, - 0x6b, 0xbe, 0x84, 0xc6, 0xf3, 0x0b, 0x31, 0x9d, 0xda, 0xb2, 0xd7, 0x45, 0x86, 0x2e, 0x33, 0x3b, - 0x84, 0x32, 0xb8, 0x67, 0xa1, 0x7c, 0x8b, 0xe0, 0x64, 0xe4, 0xa8, 0x92, 0xa0, 0x35, 0x38, 0xda, - 0x64, 0x78, 0xb3, 0x75, 0x24, 0x25, 0x72, 0x26, 0xc9, 0xd0, 0xfa, 0xb8, 0xc1, 0xcb, 0xa1, 0xb2, - 0x07, 0x27, 0x8e, 0x0a, 0xcc, 0x47, 0xde, 0x6c, 0x91, 0x7d, 0x44, 0xdd, 0x65, 0xbe, 0x4a, 0x2d, - 0xb3, 0xca, 0x93, 0x2b, 0x05, 0xbf, 0x04, 0xa9, 0xaa, 0xc8, 0x11, 0x43, 0x0d, 0xe9, 0xf2, 0x97, - 0xf2, 0x36, 0x2c, 0x24, 0xe9, 0x23, 0xd9, 0x3a, 0x0d, 0xa3, 0x75, 0xc6, 0x2d, 0xdb, 0x2c, 0x39, - 0xcd, 0x73, 0xd1, 0x67, 0x48, 0x1f, 0xf1, 0x9f, 0x89, 0x14, 0x65, 0x0d, 0xe6, 0x22, 0x0b, 0xae, - 0xd4, 0x5c, 0x97, 0xda, 0x5c, 0x04, 0xf5, 0xa1, 0xf0, 0x38, 0x1e, 0xda, 0xcb, 0xc9, 0xf1, 0x5a, - 0x20, 0x51, 0x18, 0x64, 0xd7, 0xd8, 0x83, 0xdd, 0x63, 0x7f, 0x8a, 0xe0, 0xbc, 0x68, 0xb4, 0x5c, - 0xe6, 0x56, 0x9d, 0x76, 0xd9, 0x4a, 0x27, 0xe5, 0x71, 0xad, 0x0e, 0x4a, 0xb7, 0x3f, 0x23, 0x78, - 0x25, 0xd9, 0x3c, 0x12, 0xfb, 0x07, 0x3d, 0xec, 0x4e, 0x4b, 0xf8, 0xaa, 0xdf, 0xb5, 0x78, 0x75, - 0x8d, 0x72, 0xf2, 0xbf, 0xda, 0xde, 0x94, 0x7c, 0x21, 0x05, 0x30, 0xc2, 0xe9, 0x66, 0x1b, 0xb1, - 0xca, 0x45, 0xe9, 0x8a, 0x5d, 0xc7, 0xbd, 0xef, 0x58, 0xf9, 0x02, 0xc1, 0x6c, 0xa4, 0x52, 0x22, - 0x0c, 0x2a, 0xc1, 0xfb, 0x72, 0x50, 0xf7, 0xf8, 0x1b, 0x8a, 0x79, 0x1f, 0xa2, 0xcc, 0xe8, 0x43, - 0x38, 0x11, 0x32, 0x23, 0xe6, 0x46, 0xd8, 0x92, 0xba, 0xab, 0x2d, 0xb1, 0xb6, 0xd2, 0x2f, 0xb7, - 0x0c, 0xaa, 0xed, 0xe0, 0xe0, 0xee, 0xf3, 0x26, 0x9c, 0xe8, 0x36, 0xd8, 0x80, 0xe9, 0x57, 0xe1, - 0x98, 0x1c, 0xb2, 0xc4, 0x1b, 0xa5, 0x2a, 0xf1, 0xaa, 0x21, 0xbe, 0x27, 0xe4, 0xd1, 0x46, 0x63, - 0x95, 0x78, 0xd5, 0xe6, 0xdb, 0xfe, 0xfd, 0x50, 0xd4, 0x87, 0x25, 0x64, 0xd6, 0x29, 0xff, 0xd2, - 0x44, 0x81, 0xd1, 0xc2, 0xc5, 0x5f, 0x9f, 0x4c, 0xe7, 0x4d, 0x8b, 0x57, 0x6b, 0x86, 0x5a, 0x66, - 0xdb, 0x9a, 0xa4, 0xa6, 0x5c, 0x25, 0x96, 0x1d, 0xfc, 0xd0, 0xf8, 0x8e, 0x43, 0x3d, 0xb5, 0x70, - 0xa3, 0xb8, 0xb8, 0x74, 0xa1, 0x58, 0x33, 0x6e, 0xd1, 0x1d, 0xfd, 0xb0, 0xd1, 0xbc, 0x66, 0xfc, - 0x3e, 0x8c, 0xb7, 0x64, 0xb0, 0x65, 0x79, 0x4d, 0x6f, 0x3c, 0xb4, 0x8f, 0xb2, 0x23, 0x52, 0x3f, - 0xb7, 0x2d, 0xa1, 0xb1, 0x51, 0x8f, 0x13, 0x97, 0x97, 0xa4, 0x5a, 0x0f, 0xf9, 0x9e, 0x23, 0x9e, - 0xf9, 0x92, 0xc6, 0x53, 0x00, 0xd4, 0xde, 0x0c, 0x02, 0x86, 0x44, 0xc0, 0x30, 0xb5, 0xa5, 0xe2, - 0xf1, 0x49, 0x18, 0xe6, 0x8c, 0x93, 0xad, 0x92, 0x47, 0x78, 0xfa, 0xb0, 0x38, 0x3d, 0x22, 0x1e, - 0xac, 0x13, 0x8e, 0xcf, 0xc0, 0x78, 0x98, 0x58, 0xda, 0x48, 0xa7, 0x04, 0xa7, 0xa3, 0x2d, 0x4e, - 0x69, 0x03, 0xdf, 0x81, 0xb1, 0x32, 0xab, 0x53, 0x9b, 0xd8, 0xbc, 0xe4, 0x59, 0xa6, 0x97, 0x7e, - 0x41, 0x88, 0xe8, 0x42, 0x8c, 0x88, 0x56, 0x64, 0xec, 0xf2, 0x26, 0x71, 0x38, 0x73, 0xd7, 0x2d, - 0xd3, 0x26, 0xbc, 0xe6, 0x52, 0x4f, 0x1f, 0x0d, 0xca, 0xac, 0x5b, 0xa6, 0xd7, 0x7c, 0x07, 0x89, - 0xb0, 0xa5, 0xf4, 0x91, 0x19, 0x34, 0x77, 0x44, 0x97, 0xbf, 0xf0, 0x59, 0x18, 0xaf, 0xd9, 0x06, - 0xb3, 0x37, 0xc5, 0x58, 0xd6, 0x36, 0x4d, 0x0f, 0xcf, 0xa0, 0xb9, 0x31, 0x7d, 0xec, 0xf9, 0xd3, - 0x0d, 0x6b, 0x9b, 0xe2, 0xbb, 0x30, 0x59, 0xb3, 0x5b, 0xd2, 0x2e, 0x59, 0x76, 0x85, 0xa5, 0x41, - 0x28, 0xb0, 0xc7, 0xaa, 0x70, 0x27, 0x94, 0x72, 0xc3, 0xae, 0x30, 0x7d, 0xa2, 0xd6, 0xf1, 0x24, - 0xff, 0xcf, 0x51, 0x38, 0x2c, 0xe4, 0x83, 0x3f, 0x41, 0x90, 0xf2, 0x37, 0x54, 0x3c, 0x1f, 0x53, - 0xb2, 0x7b, 0x25, 0xce, 0x2c, 0x24, 0x09, 0xf5, 0xb5, 0xa8, 0x9c, 0xfd, 0xf8, 0xa7, 0x3f, 0x3e, - 0x1f, 0x9c, 0xc6, 0x53, 0x5a, 0xaf, 0x4d, 0x1d, 0x7f, 0x83, 0x60, 0xb2, 0xcb, 0xbc, 0xf1, 0x52, - 0xaf, 0x46, 0x71, 0xcb, 0x73, 0xe6, 0xb5, 0x3e, 0xb3, 0xe4, 0xa4, 0x39, 0x31, 0xe9, 0x79, 0x3c, - 0x1f, 0x33, 0x69, 0xf7, 0x67, 0x03, 0xff, 0x88, 0x60, 0xa2, 0xb3, 0x20, 0x5e, 0xec, 0xa7, 0x7d, - 0x30, 0xf3, 0x52, 0x7f, 0x49, 0x72, 0xe4, 0x75, 0x31, 0xf2, 0x1a, 0xbe, 0x95, 0x78, 0x64, 0xed, - 0x41, 0x9b, 0xa3, 0x3f, 0xec, 0x0e, 0xc1, 0x5f, 0x22, 0x18, 0x6f, 0xdf, 0x02, 0x71, 0xae, 0xd7, - 0x74, 0x91, 0xcb, 0x6d, 0x26, 0xdf, 0x4f, 0x8a, 0x84, 0xa3, 0x0a, 0x38, 0x73, 0xf8, 0x9c, 0x16, - 0xfb, 0x3f, 0xb6, 0xb0, 0xd5, 0xe3, 0x3f, 0x11, 0x4c, 0xef, 0xf2, 0xdd, 0xc7, 0x85, 0x5e, 0x73, - 0x24, 0x5b, 0x62, 0x32, 0x2b, 0xfb, 0xaa, 0x21, 0xc1, 0xbd, 0x2e, 0xc0, 0x2d, 0xe1, 0x7c, 0x1f, - 0x77, 0xe5, 0x5b, 0xde, 0x43, 0xfc, 0x2f, 0x82, 0xa9, 0x9e, 0x9b, 0x27, 0xbe, 0xd2, 0x8f, 0x7e, - 0xa2, 0x96, 0xe3, 0xcc, 0xf2, 0x3e, 0x2a, 0x48, 0x88, 0x45, 0x01, 0xf1, 0x26, 0x5e, 0xdd, 0xbb, - 0x1c, 0xc5, 0xe2, 0xd9, 0x02, 0xfe, 0x17, 0x82, 0x53, 0xbd, 0x56, 0x5a, 0x7c, 0xb9, 0x9f, 0xa9, - 0x23, 0x76, 0xeb, 0xcc, 0x95, 0xbd, 0x17, 0x90, 0xa8, 0xaf, 0x0b, 0xd4, 0xcb, 0xf8, 0xf2, 0x3e, - 0x51, 0xe3, 0xaf, 0x11, 0x1c, 0xed, 0x58, 0xe7, 0x70, 0x7e, 0x57, 0xe9, 0x75, 0xad, 0x86, 0x99, - 0xc5, 0xbe, 0x72, 0x24, 0x0a, 0x4d, 0xa0, 0x98, 0xc7, 0xb3, 0x31, 0x28, 0x48, 0x90, 0x27, 0xbf, - 0xc3, 0xf8, 0x6f, 0x04, 0x27, 0x7b, 0x2c, 0x6b, 0xf8, 0x52, 0x3f, 0xc4, 0x46, 0x18, 0xc8, 0xe5, - 0x3d, 0xe7, 0x4b, 0x44, 0x6b, 0x02, 0xd1, 0x75, 0xfc, 0xd6, 0xde, 0xef, 0x25, 0x6c, 0x36, 0xdf, - 0x21, 0x18, 0x6b, 0xf3, 0x2d, 0x7c, 0x21, 0xb1, 0xc5, 0x05, 0x98, 0x72, 0x7d, 0x64, 0x48, 0x14, - 0x57, 0x05, 0x8a, 0x4b, 0xf8, 0xcd, 0x64, 0x9e, 0xa8, 0x3d, 0x88, 0xd8, 0x23, 0x1f, 0x16, 0x6e, - 0x3f, 0x7a, 0x9a, 0x45, 0x8f, 0x9f, 0x66, 0xd1, 0xef, 0x4f, 0xb3, 0xe8, 0xb3, 0x67, 0xd9, 0x81, - 0xc7, 0xcf, 0xb2, 0x03, 0xbf, 0x3c, 0xcb, 0x0e, 0xbc, 0xb7, 0xeb, 0x02, 0xd7, 0x08, 0x37, 0x14, - 0xdb, 0x9c, 0x91, 0x12, 0x7f, 0x2f, 0x5b, 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x11, 0x52, - 0x4c, 0x17, 0x14, 0x00, 0x00, + // 1563 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xcf, 0xe6, 0x87, 0xbf, 0xcd, 0x4b, 0xec, 0xa4, 0xd3, 0xb4, 0x71, 0x9d, 0xc6, 0x49, 0x57, + 0x6d, 0xe2, 0xa4, 0xfd, 0x7a, 0x6b, 0x27, 0xed, 0x81, 0x42, 0xdb, 0x38, 0xa5, 0x4d, 0x7f, 0x44, + 0x35, 0xeb, 0x14, 0x24, 0x90, 0xb0, 0xc6, 0xeb, 0xf1, 0x7a, 0x55, 0x67, 0xd7, 0xf5, 0x8e, 0x8d, + 0xa3, 0xaa, 0x17, 0x0e, 0xdc, 0x90, 0x90, 0xe0, 0x7f, 0x00, 0x89, 0x23, 0x70, 0xe1, 0xc6, 0xad, + 0xc7, 0x0a, 0x0e, 0x20, 0x0e, 0x15, 0x6a, 0x11, 0x48, 0x48, 0x08, 0x71, 0xe1, 0x8c, 0x3c, 0x3b, + 0xeb, 0xdd, 0xb5, 0x77, 0x1d, 0x3b, 0x09, 0xb7, 0x78, 0xe6, 0xfd, 0xfa, 0xbc, 0xf7, 0x79, 0x6f, + 0xe7, 0x05, 0xce, 0x16, 0x70, 0x61, 0xaf, 0x62, 0xe8, 0x52, 0x81, 0x2a, 0x26, 0xc5, 0x8f, 0x34, + 0x5d, 0x95, 0x1a, 0x29, 0xe9, 0x71, 0x9d, 0xd4, 0xf6, 0x92, 0xd5, 0x9a, 0x41, 0x0d, 0x74, 0x92, + 0x8b, 0x24, 0x1d, 0x91, 0x64, 0x23, 0x15, 0x9b, 0x51, 0x0d, 0xd5, 0x60, 0x12, 0x52, 0xeb, 0x2f, + 0x4b, 0x38, 0x76, 0x46, 0x35, 0x0c, 0xb5, 0x42, 0x24, 0x5c, 0xd5, 0x24, 0xac, 0xeb, 0x06, 0xc5, + 0x54, 0x33, 0x74, 0x93, 0xdf, 0xae, 0x2a, 0x86, 0xb9, 0x6b, 0x98, 0x52, 0x01, 0x9b, 0xc4, 0xf2, + 0x21, 0x35, 0x52, 0x05, 0x42, 0x71, 0x4a, 0xaa, 0x62, 0x55, 0xd3, 0x99, 0x30, 0x97, 0x15, 0xfd, + 0x23, 0xab, 0xe2, 0x1a, 0xde, 0xb5, 0xed, 0x2d, 0xf9, 0xcb, 0xb8, 0x02, 0x65, 0x72, 0xe2, 0x0c, + 0xa0, 0xb7, 0x5a, 0xde, 0xb2, 0x4c, 0x59, 0x26, 0x8f, 0xeb, 0xc4, 0xa4, 0xa2, 0x0c, 0x27, 0x3c, + 0xa7, 0x66, 0xd5, 0xd0, 0x4d, 0x82, 0xae, 0x42, 0xc8, 0x72, 0x12, 0x15, 0x16, 0x85, 0xc4, 0x44, + 0x7a, 0x3e, 0xe9, 0x9b, 0x80, 0xa4, 0xa5, 0x96, 0x19, 0x7d, 0xf6, 0x62, 0x61, 0x48, 0xe6, 0x2a, + 0xa2, 0x0a, 0xf3, 0xcc, 0xe6, 0x2d, 0x4d, 0xc7, 0x15, 0x8d, 0xee, 0x65, 0x6b, 0x46, 0x43, 0x2b, + 0x92, 0x9a, 0xed, 0x14, 0xdd, 0x02, 0x70, 0xa0, 0x72, 0x0f, 0x4b, 0x49, 0x2b, 0x2f, 0xc9, 0x56, + 0x5e, 0x92, 0x56, 0xee, 0x79, 0x5e, 0x92, 0x59, 0xac, 0x12, 0xae, 0x2b, 0xbb, 0x34, 0xc5, 0xef, + 0x04, 0x88, 0x07, 0x79, 0xe2, 0x40, 0xde, 0x06, 0x54, 0xe2, 0x97, 0xf9, 0xaa, 0x7d, 0x1b, 0x15, + 0x16, 0x47, 0x12, 0x13, 0xe9, 0xe5, 0x00, 0x50, 0x9d, 0xd6, 0xe4, 0xe3, 0xa5, 0x4e, 0xfb, 0xe8, + 0xb6, 0x07, 0xc2, 0x30, 0x83, 0xb0, 0xbc, 0x2f, 0x04, 0x2b, 0x28, 0x0f, 0x86, 0x0d, 0x38, 0xe3, + 0x0b, 0xc1, 0xce, 0xd5, 0x59, 0x08, 0x97, 0xaa, 0xf9, 0x02, 0x55, 0xf2, 0xd5, 0x47, 0xf9, 0x32, + 0x69, 0xb2, 0x74, 0x8d, 0xcb, 0x50, 0xaa, 0x66, 0xa8, 0x92, 0x7d, 0xb4, 0x45, 0x9a, 0x62, 0x3d, + 0x20, 0xdf, 0xed, 0x24, 0xec, 0xc0, 0xf1, 0xae, 0x24, 0xf0, 0xb4, 0xf7, 0x9d, 0x83, 0xe9, 0xce, + 0x1c, 0x88, 0x5f, 0x08, 0x10, 0x63, 0x7e, 0x33, 0x3b, 0x9b, 0x37, 0x49, 0x85, 0xa8, 0x16, 0xcd, + 0xed, 0xc0, 0x33, 0x10, 0x32, 0x29, 0xa6, 0x75, 0x8b, 0x42, 0x91, 0xf4, 0x6a, 0x80, 0x27, 0x8f, + 0x76, 0x8e, 0x69, 0xc8, 0x5c, 0xb3, 0x83, 0x28, 0xc3, 0x07, 0x26, 0xca, 0x37, 0x02, 0xcc, 0xf9, + 0x86, 0xca, 0x13, 0xb4, 0x0d, 0x53, 0xad, 0x0c, 0x17, 0x9d, 0x2b, 0x4e, 0x91, 0x73, 0xfd, 0x04, + 0x2d, 0x47, 0x0a, 0x54, 0x71, 0x99, 0x3d, 0x3a, 0x72, 0x94, 0x60, 0xc5, 0xb7, 0xb2, 0x59, 0xe3, + 0x03, 0x52, 0xdb, 0xa0, 0x5b, 0x44, 0x53, 0xcb, 0xb4, 0x7f, 0xa6, 0xa0, 0x53, 0x10, 0x2a, 0x33, + 0x1d, 0x16, 0xd4, 0xa8, 0xcc, 0x7f, 0x89, 0x0f, 0x60, 0xb5, 0x1f, 0x3f, 0x3c, 0x5b, 0x67, 0x61, + 0xb2, 0x61, 0x50, 0x4d, 0x57, 0xf3, 0xd5, 0xd6, 0x3d, 0xf3, 0x33, 0x2a, 0x4f, 0x58, 0x67, 0x4c, + 0x45, 0xdc, 0x86, 0x84, 0xaf, 0xc1, 0xcd, 0x7a, 0xad, 0x46, 0x74, 0xca, 0x84, 0x06, 0x60, 0x78, + 0x50, 0x1e, 0xbc, 0xe6, 0x78, 0x78, 0x0e, 0x48, 0xc1, 0x0d, 0xb2, 0x2b, 0xec, 0xe1, 0xee, 0xb0, + 0x3f, 0x16, 0xe0, 0x02, 0x73, 0xb4, 0xa1, 0x50, 0xad, 0x41, 0xba, 0xc6, 0x4a, 0x67, 0xca, 0x83, + 0x5c, 0x1d, 0x15, 0x6f, 0x7f, 0x14, 0xe0, 0x62, 0x7f, 0xf1, 0x70, 0xec, 0xef, 0xf7, 0x18, 0x77, + 0x52, 0x9f, 0xad, 0xfe, 0x8e, 0x46, 0xcb, 0xdb, 0x84, 0xe2, 0xff, 0x74, 0xec, 0xcd, 0xf3, 0x86, + 0x64, 0xc0, 0x30, 0x25, 0x45, 0x4f, 0x62, 0xc5, 0x2b, 0x7c, 0x2a, 0x76, 0x5d, 0xf7, 0xae, 0xb1, + 0xf8, 0x99, 0x00, 0xcb, 0xbe, 0x4c, 0xf1, 0x19, 0x50, 0x7d, 0xf4, 0xcb, 0x51, 0xd5, 0xf1, 0x77, + 0x21, 0xa0, 0x1f, 0xfc, 0x86, 0x51, 0x0d, 0x4e, 0xbb, 0x86, 0x91, 0x51, 0xf3, 0x19, 0x4b, 0x57, + 0xf6, 0x1d, 0x4b, 0x86, 0x9f, 0x69, 0x79, 0xd6, 0x19, 0x54, 0x1e, 0x81, 0xa3, 0xab, 0xeb, 0x5d, + 0x38, 0xdd, 0x3d, 0x68, 0xed, 0x8c, 0xff, 0x1f, 0x4e, 0xf0, 0x60, 0xf3, 0xb4, 0x99, 0x2f, 0x63, + 0xb3, 0xec, 0xca, 0xfb, 0x34, 0xbf, 0xda, 0x69, 0x6e, 0x61, 0xb3, 0xdc, 0xea, 0xfa, 0xc7, 0x7e, + 0xdf, 0x97, 0x76, 0x9a, 0x72, 0x10, 0xf1, 0xce, 0x6c, 0xfe, 0x45, 0xbb, 0xd8, 0xd7, 0xc8, 0xb6, + 0x63, 0x0f, 0x7b, 0x46, 0xb7, 0xf8, 0xf7, 0x18, 0x9c, 0xf4, 0x77, 0xb7, 0x0d, 0x21, 0x8b, 0x2a, + 0xcc, 0xcd, 0x64, 0xe6, 0xca, 0xcf, 0x2f, 0x16, 0xd2, 0xaa, 0x46, 0xcb, 0xf5, 0x42, 0x52, 0x31, + 0x76, 0x25, 0xee, 0x54, 0x29, 0x63, 0x4d, 0xb7, 0x7f, 0x48, 0x74, 0xaf, 0x4a, 0xcc, 0x64, 0xe6, + 0x4e, 0x76, 0x6d, 0xfd, 0x52, 0xb6, 0x5e, 0xb8, 0x47, 0xf6, 0xe4, 0xb1, 0x42, 0x8b, 0x5c, 0xe8, + 0x3d, 0x88, 0x38, 0xe4, 0xab, 0x68, 0x66, 0x6b, 0x22, 0x8f, 0x1c, 0xc2, 0xec, 0x04, 0x67, 0xed, + 0x7d, 0x8d, 0x31, 0x7b, 0xd2, 0xa4, 0xb8, 0x46, 0xf3, 0xbc, 0x47, 0x46, 0xac, 0x49, 0xc7, 0xce, + 0xac, 0x46, 0x42, 0xf3, 0x00, 0x44, 0x2f, 0xda, 0x02, 0xa3, 0x4c, 0x60, 0x9c, 0xe8, 0xbc, 0xcf, + 0xd0, 0x1c, 0x8c, 0x53, 0x83, 0xe2, 0x4a, 0xde, 0xc4, 0x34, 0x3a, 0xc6, 0x6e, 0x8f, 0xb1, 0x83, + 0x1c, 0xa6, 0xe8, 0x1c, 0x44, 0xdc, 0x65, 0x24, 0xcd, 0x68, 0x88, 0x55, 0x70, 0xd2, 0xa9, 0x20, + 0x69, 0xa2, 0x25, 0x98, 0x32, 0x2b, 0xd8, 0x2c, 0xbb, 0xc4, 0xfe, 0xc7, 0xc4, 0xc2, 0xf6, 0xb1, + 0x25, 0x77, 0x19, 0x66, 0x1d, 0xaa, 0xb3, 0xab, 0xbc, 0xa9, 0xa9, 0x4c, 0xfe, 0x18, 0x93, 0x9f, + 0x69, 0x5f, 0xe7, 0x5a, 0xb7, 0x39, 0x4d, 0x6d, 0xa9, 0x3d, 0x84, 0xb0, 0x62, 0x34, 0x88, 0x8e, + 0x75, 0xda, 0x92, 0x37, 0xa3, 0xe3, 0xac, 0x33, 0x2e, 0x05, 0x54, 0x7f, 0x93, 0xcb, 0x6e, 0x14, + 0x71, 0xb5, 0x65, 0x49, 0x53, 0x75, 0x4c, 0xeb, 0x35, 0x62, 0xca, 0x93, 0xb6, 0x99, 0x9c, 0xa6, + 0x9a, 0xe8, 0x22, 0x20, 0x1b, 0x9b, 0x51, 0xa7, 0xd5, 0x3a, 0xcd, 0x6b, 0xc5, 0x66, 0x14, 0x16, + 0x85, 0x44, 0xb8, 0xcd, 0xd0, 0x07, 0xec, 0xe2, 0x4e, 0x91, 0x7d, 0x4f, 0x31, 0x9b, 0xcc, 0xd1, + 0x89, 0x45, 0x21, 0x71, 0x4c, 0xe6, 0xbf, 0xd0, 0x02, 0x4c, 0x58, 0x2f, 0x98, 0x7c, 0x91, 0x98, + 0x4a, 0x74, 0xd2, 0x1a, 0x2c, 0xd6, 0xd1, 0x4d, 0x62, 0x2a, 0xe8, 0x3c, 0x44, 0xea, 0x7a, 0xc1, + 0xd0, 0x8b, 0x2c, 0x3b, 0xda, 0x2e, 0x89, 0x86, 0x99, 0x8b, 0x70, 0xfb, 0x74, 0x47, 0xdb, 0x25, + 0x48, 0x81, 0x93, 0x75, 0xdd, 0x61, 0x78, 0xbe, 0xc6, 0xd9, 0x18, 0x8d, 0x30, 0xaa, 0x27, 0x83, + 0xa9, 0xfe, 0xd0, 0xa5, 0xd6, 0x26, 0xfb, 0x4c, 0xdd, 0xe7, 0x54, 0xfc, 0x7a, 0x04, 0x66, 0x03, + 0x34, 0x50, 0x02, 0xa6, 0x5d, 0x71, 0x36, 0x5d, 0xed, 0xea, 0xc4, 0x6f, 0x95, 0xf1, 0x0d, 0x98, + 0x73, 0xca, 0xe8, 0xe8, 0xd8, 0xa5, 0x1c, 0x66, 0x4a, 0xd1, 0xb6, 0xc8, 0x43, 0x5b, 0x82, 0x97, + 0x53, 0x81, 0xb9, 0x76, 0x39, 0xbd, 0xda, 0xac, 0x39, 0x46, 0x7a, 0xbe, 0xc6, 0xda, 0xd5, 0xbc, + 0xa3, 0x97, 0x0c, 0x39, 0x6a, 0x1b, 0x72, 0xfb, 0x60, 0x7d, 0xe1, 0x43, 0xc9, 0x51, 0x3f, 0x4a, + 0x5e, 0x85, 0x58, 0x07, 0x25, 0xdd, 0x50, 0xc6, 0x98, 0xca, 0xac, 0x97, 0x95, 0x0e, 0x92, 0x12, + 0x9c, 0x72, 0x88, 0xe9, 0xd2, 0x35, 0xa3, 0xa1, 0x03, 0x32, 0x74, 0xa6, 0xcd, 0x50, 0xc7, 0x93, + 0x29, 0x2a, 0xb0, 0xb0, 0xcf, 0xb8, 0x47, 0x37, 0x60, 0xb4, 0x48, 0x2a, 0xf6, 0x47, 0x63, 0xb0, + 0xc1, 0xc8, 0x34, 0xd3, 0x7f, 0x4d, 0xc1, 0x18, 0x9b, 0xc1, 0xe8, 0x23, 0x01, 0x42, 0xd6, 0xb6, + 0x87, 0x56, 0x02, 0x0c, 0x75, 0xaf, 0x97, 0xb1, 0xd5, 0x7e, 0x44, 0x39, 0x0f, 0xcf, 0x7f, 0xf8, + 0xc3, 0xaf, 0x9f, 0x0e, 0x2f, 0xa0, 0x79, 0xa9, 0xd7, 0xd6, 0x8b, 0xbe, 0x12, 0xe0, 0x78, 0xd7, + 0x43, 0x08, 0xad, 0xf7, 0x72, 0x14, 0xb4, 0x88, 0xc6, 0x2e, 0x0f, 0xa8, 0xc5, 0x23, 0x4d, 0xb1, + 0x48, 0x2f, 0xa0, 0x95, 0x80, 0x48, 0xbb, 0x9f, 0x60, 0xe8, 0x7b, 0x01, 0xa6, 0x3b, 0x0d, 0xa2, + 0xb5, 0x41, 0xdc, 0xdb, 0x31, 0xaf, 0x0f, 0xa6, 0xc4, 0x43, 0xce, 0xb1, 0x90, 0xb7, 0xd1, 0xbd, + 0xbe, 0x43, 0x96, 0x9e, 0x78, 0x5e, 0x47, 0x4f, 0xbb, 0x45, 0xd0, 0xe7, 0x02, 0x44, 0xbc, 0x1b, + 0x15, 0x4a, 0xf5, 0x8a, 0xce, 0x77, 0x51, 0x8c, 0xa5, 0x07, 0x51, 0xe1, 0x70, 0x92, 0x0c, 0x4e, + 0x02, 0x2d, 0x49, 0x81, 0xff, 0xfd, 0x70, 0x3f, 0x9b, 0xd0, 0x6f, 0x02, 0x2c, 0xec, 0xf3, 0x86, + 0x46, 0x99, 0x5e, 0x71, 0xf4, 0xb7, 0x10, 0xc4, 0x36, 0x0f, 0x65, 0x83, 0x83, 0x7b, 0x8d, 0x81, + 0x5b, 0x47, 0xe9, 0x01, 0x6a, 0x65, 0x7d, 0xc8, 0x9f, 0xa2, 0x7f, 0x04, 0x98, 0xef, 0xb9, 0xc5, + 0xa1, 0x1b, 0x83, 0xf0, 0xc7, 0x6f, 0xd1, 0x8c, 0x6d, 0x1c, 0xc2, 0x02, 0x87, 0x98, 0x65, 0x10, + 0xef, 0xa2, 0xad, 0x83, 0xd3, 0x91, 0x2d, 0x71, 0x0e, 0xf0, 0x3f, 0x04, 0x38, 0xd3, 0x6b, 0x3d, + 0x44, 0xd7, 0x07, 0x89, 0xda, 0x67, 0x4f, 0x8d, 0xdd, 0x38, 0xb8, 0x01, 0x8e, 0xfa, 0x36, 0x43, + 0xbd, 0x81, 0xae, 0x1f, 0x12, 0x35, 0xfa, 0x52, 0x80, 0xa9, 0x8e, 0xd5, 0x08, 0xa5, 0xf7, 0xa5, + 0x5e, 0xd7, 0x9a, 0x15, 0x5b, 0x1b, 0x48, 0x87, 0xa3, 0x90, 0x18, 0x8a, 0x15, 0xb4, 0x1c, 0x80, + 0x02, 0xdb, 0x7a, 0xfc, 0x75, 0x89, 0xfe, 0x14, 0x60, 0xae, 0xc7, 0xe2, 0x83, 0xae, 0x0d, 0x92, + 0x58, 0x9f, 0x01, 0x72, 0xfd, 0xc0, 0xfa, 0x1c, 0xd1, 0x36, 0x43, 0x74, 0x1b, 0xbd, 0x79, 0xf0, + 0xba, 0xb8, 0x87, 0xcd, 0xb7, 0x02, 0x84, 0x3d, 0x73, 0x0b, 0x5d, 0xea, 0x7b, 0xc4, 0xd9, 0x98, + 0x52, 0x03, 0x68, 0x70, 0x14, 0x37, 0x19, 0x8a, 0x6b, 0xe8, 0xf5, 0xfe, 0x66, 0xa2, 0xf4, 0xc4, + 0x67, 0x17, 0x7b, 0x9a, 0xb9, 0xff, 0xec, 0x65, 0x5c, 0x78, 0xfe, 0x32, 0x2e, 0xfc, 0xf2, 0x32, + 0x2e, 0x7c, 0xf2, 0x2a, 0x3e, 0xf4, 0xfc, 0x55, 0x7c, 0xe8, 0xa7, 0x57, 0xf1, 0xa1, 0x77, 0xf7, + 0x5d, 0x4b, 0x9a, 0x6e, 0x87, 0x6c, 0x47, 0x29, 0x84, 0xd8, 0xff, 0x9e, 0xd7, 0xfe, 0x0d, 0x00, + 0x00, 0xff, 0xff, 0x94, 0xfc, 0x62, 0x5d, 0x63, 0x17, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2374,9 +2623,44 @@ func (m *QueryBTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l - if m.UndelegationInfo != nil { + if m.BtcDelegation != nil { + { + size, err := m.BtcDelegation.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *BTCDelegationResponse) 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 *BTCDelegationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UndelegationResponse != nil { { - size, err := m.UndelegationInfo.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.UndelegationResponse.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -2384,12 +2668,19 @@ func (m *QueryBTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, err i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x52 + dAtA[i] = 0x72 } if m.UnbondingTime != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.UnbondingTime)) i-- - dAtA[i] = 0x48 + dAtA[i] = 0x68 + } + if len(m.StatusDesc) > 0 { + i -= len(m.StatusDesc) + copy(dAtA[i:], m.StatusDesc) + i = encodeVarintQuery(dAtA, i, uint64(len(m.StatusDesc))) + i-- + dAtA[i] = 0x62 } if m.Active { i-- @@ -2399,7 +2690,12 @@ func (m *QueryBTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, err dAtA[i] = 0 } i-- - dAtA[i] = 0x40 + dAtA[i] = 0x58 + } + if m.StakingOutputIdx != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.StakingOutputIdx)) + i-- + dAtA[i] = 0x50 } if len(m.CovenantSigs) > 0 { for iNdEx := len(m.CovenantSigs) - 1; iNdEx >= 0; iNdEx-- { @@ -2412,9 +2708,23 @@ func (m *QueryBTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, err i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x3a + dAtA[i] = 0x4a } } + if len(m.DelegatorSlashSigHex) > 0 { + i -= len(m.DelegatorSlashSigHex) + copy(dAtA[i:], m.DelegatorSlashSigHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.DelegatorSlashSigHex))) + i-- + dAtA[i] = 0x42 + } + if len(m.SlashingTxHex) > 0 { + i -= len(m.SlashingTxHex) + copy(dAtA[i:], m.SlashingTxHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.SlashingTxHex))) + i-- + dAtA[i] = 0x3a + } if len(m.StakingTxHex) > 0 { i -= len(m.StakingTxHex) copy(dAtA[i:], m.StakingTxHex) @@ -2466,60 +2776,176 @@ func (m *QueryBTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 +func (m *BTCUndelegationResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n + return dAtA[:n], nil } -func (m *QueryFinalityProvidersRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n +func (m *BTCUndelegationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryFinalityProvidersResponse) Size() (n int) { - if m == nil { - return 0 - } +func (m *BTCUndelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.FinalityProviders) > 0 { - for _, e := range m.FinalityProviders { - l = e.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.CovenantSlashingSigs) > 0 { + for iNdEx := len(m.CovenantSlashingSigs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.CovenantSlashingSigs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.DelegatorSlashingSigHex) > 0 { + i -= len(m.DelegatorSlashingSigHex) + copy(dAtA[i:], m.DelegatorSlashingSigHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.DelegatorSlashingSigHex))) + i-- + dAtA[i] = 0x2a + } + if len(m.SlashingTxHex) > 0 { + i -= len(m.SlashingTxHex) + copy(dAtA[i:], m.SlashingTxHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.SlashingTxHex))) + i-- + dAtA[i] = 0x22 + } + if len(m.CovenantUnbondingSigList) > 0 { + for iNdEx := len(m.CovenantUnbondingSigList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.CovenantUnbondingSigList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.DelegatorUnbondingSigHex) > 0 { + i -= len(m.DelegatorUnbondingSigHex) + copy(dAtA[i:], m.DelegatorUnbondingSigHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.DelegatorUnbondingSigHex))) + i-- + dAtA[i] = 0x12 + } + if len(m.UnbondingTxHex) > 0 { + i -= len(m.UnbondingTxHex) + copy(dAtA[i:], m.UnbondingTxHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.UnbondingTxHex))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *BTCDelegatorDelegationsResponse) 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 *BTCDelegatorDelegationsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BTCDelegatorDelegationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Dels) > 0 { + for iNdEx := len(m.Dels) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Dels[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryFinalityProvidersRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryFinalityProvidersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.FinalityProviders) > 0 { + for _, e := range m.FinalityProviders { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) } } if m.Pagination != nil { @@ -2752,6 +3178,19 @@ func (m *QueryBTCDelegationRequest) Size() (n int) { } func (m *QueryBTCDelegationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BtcDelegation != nil { + l = m.BtcDelegation.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *BTCDelegationResponse) Size() (n int) { if m == nil { return 0 } @@ -2780,22 +3219,89 @@ func (m *QueryBTCDelegationResponse) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + l = len(m.SlashingTxHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.DelegatorSlashSigHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } if len(m.CovenantSigs) > 0 { for _, e := range m.CovenantSigs { l = e.Size() n += 1 + l + sovQuery(uint64(l)) } } + if m.StakingOutputIdx != 0 { + n += 1 + sovQuery(uint64(m.StakingOutputIdx)) + } if m.Active { n += 2 } + l = len(m.StatusDesc) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } if m.UnbondingTime != 0 { n += 1 + sovQuery(uint64(m.UnbondingTime)) } - if m.UndelegationInfo != nil { - l = m.UndelegationInfo.Size() + if m.UndelegationResponse != nil { + l = m.UndelegationResponse.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *BTCUndelegationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.UnbondingTxHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.DelegatorUnbondingSigHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if len(m.CovenantUnbondingSigList) > 0 { + for _, e := range m.CovenantUnbondingSigList { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + l = len(m.SlashingTxHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.DelegatorSlashingSigHex) + if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if len(m.CovenantSlashingSigs) > 0 { + for _, e := range m.CovenantSlashingSigs { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *BTCDelegatorDelegationsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Dels) > 0 { + for _, e := range m.Dels { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -4397,7 +4903,7 @@ func (m *QueryFinalityProviderDelegationsResponse) Unmarshal(dAtA []byte) error if postIndex > l { return io.ErrUnexpectedEOF } - m.BtcDelegatorDelegations = append(m.BtcDelegatorDelegations, &BTCDelegatorDelegations{}) + m.BtcDelegatorDelegations = append(m.BtcDelegatorDelegations, &BTCDelegatorDelegationsResponse{}) if err := m.BtcDelegatorDelegations[len(m.BtcDelegatorDelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -4570,6 +5076,92 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: QueryBTCDelegationResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcDelegation", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BtcDelegation == nil { + m.BtcDelegation = &BTCDelegationResponse{} + } + if err := m.BtcDelegation.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BTCDelegationResponse) 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 ErrIntOverflowQuery + } + 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: BTCDelegationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCDelegationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { case 1: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) @@ -4731,9 +5323,9 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CovenantSigs", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SlashingTxHex", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -4743,13 +5335,77 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthQuery + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SlashingTxHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorSlashSigHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorSlashSigHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CovenantSigs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery } postIndex := iNdEx + msglen if postIndex < 0 { @@ -4763,7 +5419,26 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 8: + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StakingOutputIdx", wireType) + } + m.StakingOutputIdx = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StakingOutputIdx |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Active", wireType) } @@ -4783,7 +5458,39 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { } } m.Active = bool(v != 0) - case 9: + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusDesc", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StatusDesc = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTime", wireType) } @@ -4802,9 +5509,159 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 10: + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UndelegationResponse", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UndelegationResponse == nil { + m.UndelegationResponse = &BTCUndelegationResponse{} + } + if err := m.UndelegationResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BTCUndelegationResponse) 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 ErrIntOverflowQuery + } + 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: BTCUndelegationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCUndelegationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTxHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnbondingTxHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UndelegationInfo", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorUnbondingSigHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorUnbondingSigHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CovenantUnbondingSigList", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -4831,10 +5688,190 @@ func (m *QueryBTCDelegationResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.UndelegationInfo == nil { - m.UndelegationInfo = &BTCUndelegationInfo{} + m.CovenantUnbondingSigList = append(m.CovenantUnbondingSigList, &SignatureInfo{}) + if err := m.CovenantUnbondingSigList[len(m.CovenantUnbondingSigList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashingTxHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SlashingTxHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorSlashingSigHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorSlashingSigHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CovenantSlashingSigs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CovenantSlashingSigs = append(m.CovenantSlashingSigs, &CovenantAdaptorSignatures{}) + if err := m.CovenantSlashingSigs[len(m.CovenantSlashingSigs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BTCDelegatorDelegationsResponse) 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 ErrIntOverflowQuery + } + 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: BTCDelegatorDelegationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCDelegatorDelegationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dels", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF } - if err := m.UndelegationInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Dels = append(m.Dels, &BTCDelegationResponse{}) + if err := m.Dels[len(m.Dels)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex From e5e01195ef470e5b9b577539ae9bcef217d2a2c7 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 29 Feb 2024 22:03:47 -0300 Subject: [PATCH 023/119] chore: add voting power to finality provider (#516) * chore: add voting power to finality provider * fix: check of equal between finality provider and query response --- client/docs/swagger-ui/swagger.yaml | 52 +- proto/babylon/btcstaking/v1/query.proto | 36 +- test/e2e/btc_staking_e2e_test.go | 13 +- .../configurer/chain/queries_btcstaking.go | 2 +- x/btcstaking/keeper/grpc_query.go | 28 +- x/btcstaking/types/query.go | 15 + x/btcstaking/types/query.pb.go | 782 +++++++++++++++--- 7 files changed, 784 insertions(+), 144 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index b71b5dc92..2497a2a35 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -7356,8 +7356,8 @@ paths: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified - by hash of block in + Each provided OP_RETURN transaction can be identified by + hash of block in which transaction was included and transaction index in the block @@ -7506,7 +7506,7 @@ paths: format: byte title: >- Each provided OP_RETURN transaction can be - idendtified by hash of block in + identified by hash of block in which transaction was included and transaction index in the block @@ -7540,7 +7540,7 @@ paths: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including @@ -8109,7 +8109,7 @@ paths: format: byte title: >- Each provided OP_RETURN transaction can be - idendtified by hash of block in + identified by hash of block in which transaction was included and transaction index in the block @@ -8261,7 +8261,7 @@ paths: format: byte title: >- Each provided OP_RETURN transaction can be - idendtified by hash of block in + identified by hash of block in which transaction was included and transaction index in the block @@ -8295,7 +8295,7 @@ paths: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: >- TransactionInfo is the info of a tx on Bitcoin, @@ -13978,7 +13978,7 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by hash of + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in the block @@ -14013,8 +14013,8 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by hash of - block in + Each provided OP_RETURN transaction can be identified by hash of block + in which transaction was included and transaction index in the block description: |- @@ -14038,7 +14038,7 @@ definitions: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including @@ -14055,7 +14055,7 @@ definitions: type: string format: byte title: |- - Each provided OP_RETURN transaction can be idendtified by hash of block in + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in the block babylon.zoneconcierge.v1.ChainInfo: type: object @@ -14513,8 +14513,8 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by hash - of block in + Each provided OP_RETURN transaction can be identified by hash of + block in which transaction was included and transaction index in the block @@ -14657,7 +14657,7 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in the @@ -14692,7 +14692,7 @@ definitions: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including @@ -15093,8 +15093,8 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by hash - of block in + Each provided OP_RETURN transaction can be identified by hash of + block in which transaction was included and transaction index in the block @@ -15128,7 +15128,7 @@ definitions: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including @@ -15849,8 +15849,8 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by hash - of block in + Each provided OP_RETURN transaction can be identified by hash of + block in which transaction was included and transaction index in the block @@ -15993,7 +15993,7 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in the @@ -16028,7 +16028,7 @@ definitions: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including @@ -16350,7 +16350,7 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified by + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in @@ -16495,7 +16495,7 @@ definitions: type: string format: byte title: >- - Each provided OP_RETURN transaction can be idendtified + Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index @@ -16530,7 +16530,7 @@ definitions: TODO: maybe it could use here better format as we already processed and - valideated the proof? + validated the proof? title: |- TransactionInfo is the info of a tx on Bitcoin, including diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index fcbb9ee98..f7e34b305 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -3,9 +3,13 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; +import "cosmos_proto/cosmos.proto"; +import "cosmos/crypto/secp256k1/keys.proto"; +import "cosmos/staking/v1beta1/staking.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btcstaking/v1/params.proto"; import "babylon/btcstaking/v1/btcstaking.proto"; +import "babylon/btcstaking/v1/pop.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; @@ -83,7 +87,7 @@ message QueryFinalityProvidersRequest { // Query/FinalityProviders RPC method. message QueryFinalityProvidersResponse { // finality_providers contains all the finality providers - repeated FinalityProvider finality_providers = 1; + repeated FinalityProviderResponse finality_providers = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -296,4 +300,34 @@ message BTCUndelegationResponse { // BTCDelegatorDelegationsResponse is a collection of BTC delegations responses from the same delegator. message BTCDelegatorDelegationsResponse { repeated BTCDelegationResponse dels = 1; +} + +// FinalityProviderResponse defines a finality provider with voting power information. +message FinalityProviderResponse { + // description defines the description terms for the finality provider. + cosmos.staking.v1beta1.Description description = 1; + // commission defines the commission rate of the finality provider. + string commission = 2 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" + ]; + // babylon_pk is the Babylon secp256k1 PK of this finality provider + cosmos.crypto.secp256k1.PubKey babylon_pk = 3; + // btc_pk is the Bitcoin secp256k1 PK of this finality provider + // the PK follows encoding in BIP-340 spec + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of babylon_pk and btc_pk + ProofOfPossession pop = 5; + // slashed_babylon_height indicates the Babylon height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_babylon_height = 6; + // slashed_btc_height indicates the BTC height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_btc_height = 7; + // height is the queried Babylon height + uint64 height = 8; + // voting_power is the voting power of this finality provider at the given height + uint64 voting_power = 9; } \ No newline at end of file diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 019aea1ce..05ef85f20 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -17,7 +17,6 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/test/e2e/configurer" "github.com/babylonchain/babylon/test/e2e/initialization" - "github.com/babylonchain/babylon/test/e2e/util" "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -89,7 +88,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { // query the existence of finality provider and assert equivalence actualFps := nonValidatorNode.QueryFinalityProviders() s.Len(actualFps, 1) - s.Equal(util.Cdc.MustMarshal(fp), util.Cdc.MustMarshal(actualFps[0])) + s.equalFinalityProviderResp(fp, actualFps[0]) /* create a random BTC delegation under this finality provider @@ -608,3 +607,13 @@ func ParseRespBTCDelToBTCDel(resp *bstypes.BTCDelegationResponse) (btcDel *bstyp return btcDel, nil } + +func (s *BTCStakingTestSuite) equalFinalityProviderResp(fp *bstypes.FinalityProvider, fpResp *bstypes.FinalityProviderResponse) { + s.Equal(fp.Description, fpResp.Description) + s.Equal(fp.Commission, fpResp.Commission) + s.Equal(fp.BabylonPk, fpResp.BabylonPk) + s.Equal(fp.BtcPk, fpResp.BtcPk) + s.Equal(fp.Pop, fpResp.Pop) + s.Equal(fp.SlashedBabylonHeight, fpResp.SlashedBabylonHeight) + s.Equal(fp.SlashedBtcHeight, fpResp.SlashedBtcHeight) +} diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index 7669200aa..66642b1ff 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -22,7 +22,7 @@ func (n *NodeConfig) QueryBTCStakingParams() *bstypes.Params { return &resp.Params } -func (n *NodeConfig) QueryFinalityProviders() []*bstypes.FinalityProvider { +func (n *NodeConfig) QueryFinalityProviders() []*bstypes.FinalityProviderResponse { bz, err := n.QueryGRPCGateway("/babylon/btcstaking/v1/finality_providers", url.Values{}) require.NoError(n.t, err) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index 72d22772e..94e198fda 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -17,30 +17,36 @@ import ( var _ types.QueryServer = Keeper{} // FinalityProviders returns a paginated list of all Babylon maintained finality providers -func (k Keeper) FinalityProviders(ctx context.Context, req *types.QueryFinalityProvidersRequest) (*types.QueryFinalityProvidersResponse, error) { +func (k Keeper) FinalityProviders(c context.Context, req *types.QueryFinalityProvidersRequest) (*types.QueryFinalityProvidersResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - store := k.finalityProviderStore(sdkCtx) + ctx := sdk.UnwrapSDKContext(c) + store := k.finalityProviderStore(ctx) + currBlockHeight := uint64(ctx.BlockHeight()) - var finalityProviders []*types.FinalityProvider + var finalityProvidersResp []*types.FinalityProviderResponse pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { var finalityProvider types.FinalityProvider - k.cdc.MustUnmarshal(value, &finalityProvider) - finalityProviders = append(finalityProviders, &finalityProvider) + if err := finalityProvider.Unmarshal(value); err != nil { + return err + } + + votingPower := k.GetVotingPower(ctx, key, currBlockHeight) + resp := types.NewFinalityProviderResponse(&finalityProvider, currBlockHeight, votingPower) + finalityProvidersResp = append(finalityProvidersResp, resp) return nil }) if err != nil { return nil, err } - return &types.QueryFinalityProvidersResponse{FinalityProviders: finalityProviders, Pagination: pageRes}, nil + return &types.QueryFinalityProvidersResponse{FinalityProviders: finalityProvidersResp, Pagination: pageRes}, nil } // FinalityProvider returns the finality provider with the specified finality provider BTC PK -func (k Keeper) FinalityProvider(ctx context.Context, req *types.QueryFinalityProviderRequest) (*types.QueryFinalityProviderResponse, error) { +func (k Keeper) FinalityProvider(c context.Context, req *types.QueryFinalityProviderRequest) (*types.QueryFinalityProviderResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } @@ -55,10 +61,8 @@ func (k Keeper) FinalityProvider(ctx context.Context, req *types.QueryFinalityPr return nil, err } - sdkCtx := sdk.UnwrapSDKContext(ctx) - - fp, err := k.GetFinalityProvider(sdkCtx, fpPK.MustMarshal()) - + ctx := sdk.UnwrapSDKContext(c) + fp, err := k.GetFinalityProvider(ctx, fpPK.MustMarshal()) if err != nil { return nil, err } diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index df669cbb5..0016e4adb 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -53,3 +53,18 @@ func (ud *BTCUndelegation) ToResponse() (resp *BTCUndelegationResponse) { return resp } + +// NewFinalityProviderResponse creates a new finality provider response based on the finaliny provider and his voting power. +func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPower uint64) *FinalityProviderResponse { + return &FinalityProviderResponse{ + Description: f.Description, + Commission: f.Commission, + BabylonPk: f.BabylonPk, + BtcPk: f.BtcPk, + Pop: f.Pop, + SlashedBabylonHeight: f.SlashedBabylonHeight, + SlashedBtcHeight: f.SlashedBtcHeight, + Height: bbnBlockHeight, + VotingPower: votingPower, + } +} diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 8ef5396b5..f9d16c4d0 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -5,9 +5,13 @@ package types import ( context "context" + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + _ "github.com/cosmos/cosmos-proto" + secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" query "github.com/cosmos/cosmos-sdk/types/query" + types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" @@ -165,7 +169,7 @@ func (m *QueryFinalityProvidersRequest) GetPagination() *query.PageRequest { // Query/FinalityProviders RPC method. type QueryFinalityProvidersResponse struct { // finality_providers contains all the finality providers - FinalityProviders []*FinalityProvider `protobuf:"bytes,1,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` + FinalityProviders []*FinalityProviderResponse `protobuf:"bytes,1,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -203,7 +207,7 @@ func (m *QueryFinalityProvidersResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryFinalityProvidersResponse proto.InternalMessageInfo -func (m *QueryFinalityProvidersResponse) GetFinalityProviders() []*FinalityProvider { +func (m *QueryFinalityProvidersResponse) GetFinalityProviders() []*FinalityProviderResponse { if m != nil { return m.FinalityProviders } @@ -1366,6 +1370,115 @@ func (m *BTCDelegatorDelegationsResponse) GetDels() []*BTCDelegationResponse { return nil } +// FinalityProviderResponse defines a finality provider with voting power information. +type FinalityProviderResponse struct { + // description defines the description terms for the finality provider. + Description *types.Description `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + // commission defines the commission rate of the finality provider. + Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` + // babylon_pk is the Babylon secp256k1 PK of this finality provider + BabylonPk *secp256k1.PubKey `protobuf:"bytes,3,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // btc_pk is the Bitcoin secp256k1 PK of this finality provider + // the PK follows encoding in BIP-340 spec + BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + // pop is the proof of possession of babylon_pk and btc_pk + Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` + // slashed_babylon_height indicates the Babylon height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + // slashed_btc_height indicates the BTC height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + // height is the queried Babylon height + Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"` + // voting_power is the voting power of this finality provider at the given height + VotingPower uint64 `protobuf:"varint,9,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` +} + +func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } +func (m *FinalityProviderResponse) String() string { return proto.CompactTextString(m) } +func (*FinalityProviderResponse) ProtoMessage() {} +func (*FinalityProviderResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{23} +} +func (m *FinalityProviderResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FinalityProviderResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FinalityProviderResponse.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 *FinalityProviderResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinalityProviderResponse.Merge(m, src) +} +func (m *FinalityProviderResponse) XXX_Size() int { + return m.Size() +} +func (m *FinalityProviderResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FinalityProviderResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_FinalityProviderResponse proto.InternalMessageInfo + +func (m *FinalityProviderResponse) GetDescription() *types.Description { + if m != nil { + return m.Description + } + return nil +} + +func (m *FinalityProviderResponse) GetBabylonPk() *secp256k1.PubKey { + if m != nil { + return m.BabylonPk + } + return nil +} + +func (m *FinalityProviderResponse) GetPop() *ProofOfPossession { + if m != nil { + return m.Pop + } + return nil +} + +func (m *FinalityProviderResponse) GetSlashedBabylonHeight() uint64 { + if m != nil { + return m.SlashedBabylonHeight + } + return 0 +} + +func (m *FinalityProviderResponse) GetSlashedBtcHeight() uint64 { + if m != nil { + return m.SlashedBtcHeight + } + return 0 +} + +func (m *FinalityProviderResponse) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *FinalityProviderResponse) GetVotingPower() uint64 { + if m != nil { + return m.VotingPower + } + return 0 +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btcstaking.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btcstaking.v1.QueryParamsResponse") @@ -1390,110 +1503,126 @@ func init() { proto.RegisterType((*BTCDelegationResponse)(nil), "babylon.btcstaking.v1.BTCDelegationResponse") proto.RegisterType((*BTCUndelegationResponse)(nil), "babylon.btcstaking.v1.BTCUndelegationResponse") proto.RegisterType((*BTCDelegatorDelegationsResponse)(nil), "babylon.btcstaking.v1.BTCDelegatorDelegationsResponse") + proto.RegisterType((*FinalityProviderResponse)(nil), "babylon.btcstaking.v1.FinalityProviderResponse") } func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1563 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0xe6, 0x87, 0xbf, 0xcd, 0x4b, 0xec, 0xa4, 0xd3, 0xb4, 0x71, 0x9d, 0xc6, 0x49, 0x57, - 0x6d, 0xe2, 0xa4, 0xfd, 0x7a, 0x6b, 0x27, 0xed, 0x81, 0x42, 0xdb, 0x38, 0xa5, 0x4d, 0x7f, 0x44, - 0x35, 0xeb, 0x14, 0x24, 0x90, 0xb0, 0xc6, 0xeb, 0xf1, 0x7a, 0x55, 0x67, 0xd7, 0xf5, 0x8e, 0x8d, - 0xa3, 0xaa, 0x17, 0x0e, 0xdc, 0x90, 0x90, 0xe0, 0x7f, 0x00, 0x89, 0x23, 0x70, 0xe1, 0xc6, 0xad, - 0xc7, 0x0a, 0x0e, 0x20, 0x0e, 0x15, 0x6a, 0x11, 0x48, 0x48, 0x08, 0x71, 0xe1, 0x8c, 0x3c, 0x3b, - 0xeb, 0xdd, 0xb5, 0x77, 0x1d, 0x3b, 0x09, 0xb7, 0x78, 0xe6, 0xfd, 0xfa, 0xbc, 0xf7, 0x79, 0x6f, - 0xe7, 0x05, 0xce, 0x16, 0x70, 0x61, 0xaf, 0x62, 0xe8, 0x52, 0x81, 0x2a, 0x26, 0xc5, 0x8f, 0x34, - 0x5d, 0x95, 0x1a, 0x29, 0xe9, 0x71, 0x9d, 0xd4, 0xf6, 0x92, 0xd5, 0x9a, 0x41, 0x0d, 0x74, 0x92, - 0x8b, 0x24, 0x1d, 0x91, 0x64, 0x23, 0x15, 0x9b, 0x51, 0x0d, 0xd5, 0x60, 0x12, 0x52, 0xeb, 0x2f, - 0x4b, 0x38, 0x76, 0x46, 0x35, 0x0c, 0xb5, 0x42, 0x24, 0x5c, 0xd5, 0x24, 0xac, 0xeb, 0x06, 0xc5, - 0x54, 0x33, 0x74, 0x93, 0xdf, 0xae, 0x2a, 0x86, 0xb9, 0x6b, 0x98, 0x52, 0x01, 0x9b, 0xc4, 0xf2, - 0x21, 0x35, 0x52, 0x05, 0x42, 0x71, 0x4a, 0xaa, 0x62, 0x55, 0xd3, 0x99, 0x30, 0x97, 0x15, 0xfd, - 0x23, 0xab, 0xe2, 0x1a, 0xde, 0xb5, 0xed, 0x2d, 0xf9, 0xcb, 0xb8, 0x02, 0x65, 0x72, 0xe2, 0x0c, - 0xa0, 0xb7, 0x5a, 0xde, 0xb2, 0x4c, 0x59, 0x26, 0x8f, 0xeb, 0xc4, 0xa4, 0xa2, 0x0c, 0x27, 0x3c, - 0xa7, 0x66, 0xd5, 0xd0, 0x4d, 0x82, 0xae, 0x42, 0xc8, 0x72, 0x12, 0x15, 0x16, 0x85, 0xc4, 0x44, - 0x7a, 0x3e, 0xe9, 0x9b, 0x80, 0xa4, 0xa5, 0x96, 0x19, 0x7d, 0xf6, 0x62, 0x61, 0x48, 0xe6, 0x2a, - 0xa2, 0x0a, 0xf3, 0xcc, 0xe6, 0x2d, 0x4d, 0xc7, 0x15, 0x8d, 0xee, 0x65, 0x6b, 0x46, 0x43, 0x2b, - 0x92, 0x9a, 0xed, 0x14, 0xdd, 0x02, 0x70, 0xa0, 0x72, 0x0f, 0x4b, 0x49, 0x2b, 0x2f, 0xc9, 0x56, - 0x5e, 0x92, 0x56, 0xee, 0x79, 0x5e, 0x92, 0x59, 0xac, 0x12, 0xae, 0x2b, 0xbb, 0x34, 0xc5, 0xef, - 0x04, 0x88, 0x07, 0x79, 0xe2, 0x40, 0xde, 0x06, 0x54, 0xe2, 0x97, 0xf9, 0xaa, 0x7d, 0x1b, 0x15, - 0x16, 0x47, 0x12, 0x13, 0xe9, 0xe5, 0x00, 0x50, 0x9d, 0xd6, 0xe4, 0xe3, 0xa5, 0x4e, 0xfb, 0xe8, - 0xb6, 0x07, 0xc2, 0x30, 0x83, 0xb0, 0xbc, 0x2f, 0x04, 0x2b, 0x28, 0x0f, 0x86, 0x0d, 0x38, 0xe3, - 0x0b, 0xc1, 0xce, 0xd5, 0x59, 0x08, 0x97, 0xaa, 0xf9, 0x02, 0x55, 0xf2, 0xd5, 0x47, 0xf9, 0x32, - 0x69, 0xb2, 0x74, 0x8d, 0xcb, 0x50, 0xaa, 0x66, 0xa8, 0x92, 0x7d, 0xb4, 0x45, 0x9a, 0x62, 0x3d, - 0x20, 0xdf, 0xed, 0x24, 0xec, 0xc0, 0xf1, 0xae, 0x24, 0xf0, 0xb4, 0xf7, 0x9d, 0x83, 0xe9, 0xce, - 0x1c, 0x88, 0x5f, 0x08, 0x10, 0x63, 0x7e, 0x33, 0x3b, 0x9b, 0x37, 0x49, 0x85, 0xa8, 0x16, 0xcd, - 0xed, 0xc0, 0x33, 0x10, 0x32, 0x29, 0xa6, 0x75, 0x8b, 0x42, 0x91, 0xf4, 0x6a, 0x80, 0x27, 0x8f, - 0x76, 0x8e, 0x69, 0xc8, 0x5c, 0xb3, 0x83, 0x28, 0xc3, 0x07, 0x26, 0xca, 0x37, 0x02, 0xcc, 0xf9, - 0x86, 0xca, 0x13, 0xb4, 0x0d, 0x53, 0xad, 0x0c, 0x17, 0x9d, 0x2b, 0x4e, 0x91, 0x73, 0xfd, 0x04, - 0x2d, 0x47, 0x0a, 0x54, 0x71, 0x99, 0x3d, 0x3a, 0x72, 0x94, 0x60, 0xc5, 0xb7, 0xb2, 0x59, 0xe3, - 0x03, 0x52, 0xdb, 0xa0, 0x5b, 0x44, 0x53, 0xcb, 0xb4, 0x7f, 0xa6, 0xa0, 0x53, 0x10, 0x2a, 0x33, - 0x1d, 0x16, 0xd4, 0xa8, 0xcc, 0x7f, 0x89, 0x0f, 0x60, 0xb5, 0x1f, 0x3f, 0x3c, 0x5b, 0x67, 0x61, - 0xb2, 0x61, 0x50, 0x4d, 0x57, 0xf3, 0xd5, 0xd6, 0x3d, 0xf3, 0x33, 0x2a, 0x4f, 0x58, 0x67, 0x4c, - 0x45, 0xdc, 0x86, 0x84, 0xaf, 0xc1, 0xcd, 0x7a, 0xad, 0x46, 0x74, 0xca, 0x84, 0x06, 0x60, 0x78, - 0x50, 0x1e, 0xbc, 0xe6, 0x78, 0x78, 0x0e, 0x48, 0xc1, 0x0d, 0xb2, 0x2b, 0xec, 0xe1, 0xee, 0xb0, - 0x3f, 0x16, 0xe0, 0x02, 0x73, 0xb4, 0xa1, 0x50, 0xad, 0x41, 0xba, 0xc6, 0x4a, 0x67, 0xca, 0x83, - 0x5c, 0x1d, 0x15, 0x6f, 0x7f, 0x14, 0xe0, 0x62, 0x7f, 0xf1, 0x70, 0xec, 0xef, 0xf7, 0x18, 0x77, - 0x52, 0x9f, 0xad, 0xfe, 0x8e, 0x46, 0xcb, 0xdb, 0x84, 0xe2, 0xff, 0x74, 0xec, 0xcd, 0xf3, 0x86, - 0x64, 0xc0, 0x30, 0x25, 0x45, 0x4f, 0x62, 0xc5, 0x2b, 0x7c, 0x2a, 0x76, 0x5d, 0xf7, 0xae, 0xb1, - 0xf8, 0x99, 0x00, 0xcb, 0xbe, 0x4c, 0xf1, 0x19, 0x50, 0x7d, 0xf4, 0xcb, 0x51, 0xd5, 0xf1, 0x77, - 0x21, 0xa0, 0x1f, 0xfc, 0x86, 0x51, 0x0d, 0x4e, 0xbb, 0x86, 0x91, 0x51, 0xf3, 0x19, 0x4b, 0x57, - 0xf6, 0x1d, 0x4b, 0x86, 0x9f, 0x69, 0x79, 0xd6, 0x19, 0x54, 0x1e, 0x81, 0xa3, 0xab, 0xeb, 0x5d, - 0x38, 0xdd, 0x3d, 0x68, 0xed, 0x8c, 0xff, 0x1f, 0x4e, 0xf0, 0x60, 0xf3, 0xb4, 0x99, 0x2f, 0x63, - 0xb3, 0xec, 0xca, 0xfb, 0x34, 0xbf, 0xda, 0x69, 0x6e, 0x61, 0xb3, 0xdc, 0xea, 0xfa, 0xc7, 0x7e, - 0xdf, 0x97, 0x76, 0x9a, 0x72, 0x10, 0xf1, 0xce, 0x6c, 0xfe, 0x45, 0xbb, 0xd8, 0xd7, 0xc8, 0xb6, - 0x63, 0x0f, 0x7b, 0x46, 0xb7, 0xf8, 0xf7, 0x18, 0x9c, 0xf4, 0x77, 0xb7, 0x0d, 0x21, 0x8b, 0x2a, - 0xcc, 0xcd, 0x64, 0xe6, 0xca, 0xcf, 0x2f, 0x16, 0xd2, 0xaa, 0x46, 0xcb, 0xf5, 0x42, 0x52, 0x31, - 0x76, 0x25, 0xee, 0x54, 0x29, 0x63, 0x4d, 0xb7, 0x7f, 0x48, 0x74, 0xaf, 0x4a, 0xcc, 0x64, 0xe6, - 0x4e, 0x76, 0x6d, 0xfd, 0x52, 0xb6, 0x5e, 0xb8, 0x47, 0xf6, 0xe4, 0xb1, 0x42, 0x8b, 0x5c, 0xe8, - 0x3d, 0x88, 0x38, 0xe4, 0xab, 0x68, 0x66, 0x6b, 0x22, 0x8f, 0x1c, 0xc2, 0xec, 0x04, 0x67, 0xed, - 0x7d, 0x8d, 0x31, 0x7b, 0xd2, 0xa4, 0xb8, 0x46, 0xf3, 0xbc, 0x47, 0x46, 0xac, 0x49, 0xc7, 0xce, - 0xac, 0x46, 0x42, 0xf3, 0x00, 0x44, 0x2f, 0xda, 0x02, 0xa3, 0x4c, 0x60, 0x9c, 0xe8, 0xbc, 0xcf, - 0xd0, 0x1c, 0x8c, 0x53, 0x83, 0xe2, 0x4a, 0xde, 0xc4, 0x34, 0x3a, 0xc6, 0x6e, 0x8f, 0xb1, 0x83, - 0x1c, 0xa6, 0xe8, 0x1c, 0x44, 0xdc, 0x65, 0x24, 0xcd, 0x68, 0x88, 0x55, 0x70, 0xd2, 0xa9, 0x20, - 0x69, 0xa2, 0x25, 0x98, 0x32, 0x2b, 0xd8, 0x2c, 0xbb, 0xc4, 0xfe, 0xc7, 0xc4, 0xc2, 0xf6, 0xb1, - 0x25, 0x77, 0x19, 0x66, 0x1d, 0xaa, 0xb3, 0xab, 0xbc, 0xa9, 0xa9, 0x4c, 0xfe, 0x18, 0x93, 0x9f, - 0x69, 0x5f, 0xe7, 0x5a, 0xb7, 0x39, 0x4d, 0x6d, 0xa9, 0x3d, 0x84, 0xb0, 0x62, 0x34, 0x88, 0x8e, - 0x75, 0xda, 0x92, 0x37, 0xa3, 0xe3, 0xac, 0x33, 0x2e, 0x05, 0x54, 0x7f, 0x93, 0xcb, 0x6e, 0x14, - 0x71, 0xb5, 0x65, 0x49, 0x53, 0x75, 0x4c, 0xeb, 0x35, 0x62, 0xca, 0x93, 0xb6, 0x99, 0x9c, 0xa6, - 0x9a, 0xe8, 0x22, 0x20, 0x1b, 0x9b, 0x51, 0xa7, 0xd5, 0x3a, 0xcd, 0x6b, 0xc5, 0x66, 0x14, 0x16, - 0x85, 0x44, 0xb8, 0xcd, 0xd0, 0x07, 0xec, 0xe2, 0x4e, 0x91, 0x7d, 0x4f, 0x31, 0x9b, 0xcc, 0xd1, - 0x89, 0x45, 0x21, 0x71, 0x4c, 0xe6, 0xbf, 0xd0, 0x02, 0x4c, 0x58, 0x2f, 0x98, 0x7c, 0x91, 0x98, - 0x4a, 0x74, 0xd2, 0x1a, 0x2c, 0xd6, 0xd1, 0x4d, 0x62, 0x2a, 0xe8, 0x3c, 0x44, 0xea, 0x7a, 0xc1, - 0xd0, 0x8b, 0x2c, 0x3b, 0xda, 0x2e, 0x89, 0x86, 0x99, 0x8b, 0x70, 0xfb, 0x74, 0x47, 0xdb, 0x25, - 0x48, 0x81, 0x93, 0x75, 0xdd, 0x61, 0x78, 0xbe, 0xc6, 0xd9, 0x18, 0x8d, 0x30, 0xaa, 0x27, 0x83, - 0xa9, 0xfe, 0xd0, 0xa5, 0xd6, 0x26, 0xfb, 0x4c, 0xdd, 0xe7, 0x54, 0xfc, 0x7a, 0x04, 0x66, 0x03, - 0x34, 0x50, 0x02, 0xa6, 0x5d, 0x71, 0x36, 0x5d, 0xed, 0xea, 0xc4, 0x6f, 0x95, 0xf1, 0x0d, 0x98, - 0x73, 0xca, 0xe8, 0xe8, 0xd8, 0xa5, 0x1c, 0x66, 0x4a, 0xd1, 0xb6, 0xc8, 0x43, 0x5b, 0x82, 0x97, - 0x53, 0x81, 0xb9, 0x76, 0x39, 0xbd, 0xda, 0xac, 0x39, 0x46, 0x7a, 0xbe, 0xc6, 0xda, 0xd5, 0xbc, - 0xa3, 0x97, 0x0c, 0x39, 0x6a, 0x1b, 0x72, 0xfb, 0x60, 0x7d, 0xe1, 0x43, 0xc9, 0x51, 0x3f, 0x4a, - 0x5e, 0x85, 0x58, 0x07, 0x25, 0xdd, 0x50, 0xc6, 0x98, 0xca, 0xac, 0x97, 0x95, 0x0e, 0x92, 0x12, - 0x9c, 0x72, 0x88, 0xe9, 0xd2, 0x35, 0xa3, 0xa1, 0x03, 0x32, 0x74, 0xa6, 0xcd, 0x50, 0xc7, 0x93, - 0x29, 0x2a, 0xb0, 0xb0, 0xcf, 0xb8, 0x47, 0x37, 0x60, 0xb4, 0x48, 0x2a, 0xf6, 0x47, 0x63, 0xb0, - 0xc1, 0xc8, 0x34, 0xd3, 0x7f, 0x4d, 0xc1, 0x18, 0x9b, 0xc1, 0xe8, 0x23, 0x01, 0x42, 0xd6, 0xb6, - 0x87, 0x56, 0x02, 0x0c, 0x75, 0xaf, 0x97, 0xb1, 0xd5, 0x7e, 0x44, 0x39, 0x0f, 0xcf, 0x7f, 0xf8, - 0xc3, 0xaf, 0x9f, 0x0e, 0x2f, 0xa0, 0x79, 0xa9, 0xd7, 0xd6, 0x8b, 0xbe, 0x12, 0xe0, 0x78, 0xd7, - 0x43, 0x08, 0xad, 0xf7, 0x72, 0x14, 0xb4, 0x88, 0xc6, 0x2e, 0x0f, 0xa8, 0xc5, 0x23, 0x4d, 0xb1, - 0x48, 0x2f, 0xa0, 0x95, 0x80, 0x48, 0xbb, 0x9f, 0x60, 0xe8, 0x7b, 0x01, 0xa6, 0x3b, 0x0d, 0xa2, - 0xb5, 0x41, 0xdc, 0xdb, 0x31, 0xaf, 0x0f, 0xa6, 0xc4, 0x43, 0xce, 0xb1, 0x90, 0xb7, 0xd1, 0xbd, - 0xbe, 0x43, 0x96, 0x9e, 0x78, 0x5e, 0x47, 0x4f, 0xbb, 0x45, 0xd0, 0xe7, 0x02, 0x44, 0xbc, 0x1b, - 0x15, 0x4a, 0xf5, 0x8a, 0xce, 0x77, 0x51, 0x8c, 0xa5, 0x07, 0x51, 0xe1, 0x70, 0x92, 0x0c, 0x4e, - 0x02, 0x2d, 0x49, 0x81, 0xff, 0xfd, 0x70, 0x3f, 0x9b, 0xd0, 0x6f, 0x02, 0x2c, 0xec, 0xf3, 0x86, - 0x46, 0x99, 0x5e, 0x71, 0xf4, 0xb7, 0x10, 0xc4, 0x36, 0x0f, 0x65, 0x83, 0x83, 0x7b, 0x8d, 0x81, - 0x5b, 0x47, 0xe9, 0x01, 0x6a, 0x65, 0x7d, 0xc8, 0x9f, 0xa2, 0x7f, 0x04, 0x98, 0xef, 0xb9, 0xc5, - 0xa1, 0x1b, 0x83, 0xf0, 0xc7, 0x6f, 0xd1, 0x8c, 0x6d, 0x1c, 0xc2, 0x02, 0x87, 0x98, 0x65, 0x10, - 0xef, 0xa2, 0xad, 0x83, 0xd3, 0x91, 0x2d, 0x71, 0x0e, 0xf0, 0x3f, 0x04, 0x38, 0xd3, 0x6b, 0x3d, - 0x44, 0xd7, 0x07, 0x89, 0xda, 0x67, 0x4f, 0x8d, 0xdd, 0x38, 0xb8, 0x01, 0x8e, 0xfa, 0x36, 0x43, - 0xbd, 0x81, 0xae, 0x1f, 0x12, 0x35, 0xfa, 0x52, 0x80, 0xa9, 0x8e, 0xd5, 0x08, 0xa5, 0xf7, 0xa5, - 0x5e, 0xd7, 0x9a, 0x15, 0x5b, 0x1b, 0x48, 0x87, 0xa3, 0x90, 0x18, 0x8a, 0x15, 0xb4, 0x1c, 0x80, - 0x02, 0xdb, 0x7a, 0xfc, 0x75, 0x89, 0xfe, 0x14, 0x60, 0xae, 0xc7, 0xe2, 0x83, 0xae, 0x0d, 0x92, - 0x58, 0x9f, 0x01, 0x72, 0xfd, 0xc0, 0xfa, 0x1c, 0xd1, 0x36, 0x43, 0x74, 0x1b, 0xbd, 0x79, 0xf0, - 0xba, 0xb8, 0x87, 0xcd, 0xb7, 0x02, 0x84, 0x3d, 0x73, 0x0b, 0x5d, 0xea, 0x7b, 0xc4, 0xd9, 0x98, - 0x52, 0x03, 0x68, 0x70, 0x14, 0x37, 0x19, 0x8a, 0x6b, 0xe8, 0xf5, 0xfe, 0x66, 0xa2, 0xf4, 0xc4, - 0x67, 0x17, 0x7b, 0x9a, 0xb9, 0xff, 0xec, 0x65, 0x5c, 0x78, 0xfe, 0x32, 0x2e, 0xfc, 0xf2, 0x32, - 0x2e, 0x7c, 0xf2, 0x2a, 0x3e, 0xf4, 0xfc, 0x55, 0x7c, 0xe8, 0xa7, 0x57, 0xf1, 0xa1, 0x77, 0xf7, - 0x5d, 0x4b, 0x9a, 0x6e, 0x87, 0x6c, 0x47, 0x29, 0x84, 0xd8, 0xff, 0x9e, 0xd7, 0xfe, 0x0d, 0x00, - 0x00, 0xff, 0xff, 0x94, 0xfc, 0x62, 0x5d, 0x63, 0x17, 0x00, 0x00, + // 1795 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdf, 0x4f, 0xdb, 0xdc, + 0x19, 0xc6, 0x10, 0xf2, 0xc1, 0x1b, 0x12, 0xe8, 0xf9, 0x68, 0x49, 0x43, 0x21, 0x34, 0xeb, 0x07, + 0x81, 0xb6, 0x76, 0x09, 0x94, 0x8b, 0x76, 0x6b, 0x4b, 0xa0, 0x2d, 0xfd, 0x81, 0x9a, 0x19, 0xaa, + 0x49, 0x9b, 0xb4, 0xc8, 0x71, 0x4e, 0x1c, 0x8b, 0xc4, 0x76, 0xed, 0x13, 0x96, 0xa8, 0xea, 0xcd, + 0x2e, 0x76, 0x37, 0x69, 0xd2, 0x76, 0xb5, 0x7f, 0x60, 0x93, 0x76, 0xb9, 0xee, 0x66, 0x7f, 0x41, + 0x77, 0x57, 0x75, 0x17, 0x9b, 0x7a, 0x51, 0x4d, 0xed, 0xb4, 0x49, 0x93, 0xa6, 0x69, 0x37, 0xbb, + 0x9e, 0x7c, 0x7c, 0x1c, 0x3b, 0x89, 0x1d, 0x12, 0xe0, 0xbb, 0x23, 0x3e, 0xef, 0xaf, 0xe7, 0x7d, + 0x9f, 0xf3, 0xf8, 0x1c, 0x03, 0x57, 0x4b, 0x52, 0xa9, 0x55, 0xd3, 0x35, 0xa1, 0x44, 0x64, 0x8b, + 0x48, 0x47, 0xaa, 0xa6, 0x08, 0xc7, 0xeb, 0xc2, 0xab, 0x06, 0x36, 0x5b, 0xbc, 0x61, 0xea, 0x44, + 0x47, 0x17, 0x99, 0x09, 0xef, 0x99, 0xf0, 0xc7, 0xeb, 0xa9, 0x59, 0x45, 0x57, 0x74, 0x6a, 0x21, + 0xd8, 0x7f, 0x39, 0xc6, 0xa9, 0x2b, 0x8a, 0xae, 0x2b, 0x35, 0x2c, 0x48, 0x86, 0x2a, 0x48, 0x9a, + 0xa6, 0x13, 0x89, 0xa8, 0xba, 0x66, 0xb1, 0xd5, 0xcb, 0xb2, 0x6e, 0xd5, 0x75, 0xab, 0xe8, 0xb8, + 0x39, 0x3f, 0xd8, 0x52, 0xc6, 0xf9, 0x25, 0xc8, 0x66, 0xcb, 0x20, 0xba, 0x60, 0x61, 0xd9, 0xc8, + 0xdd, 0xde, 0x3a, 0x5a, 0x17, 0x8e, 0x70, 0xcb, 0xb5, 0xb9, 0xc6, 0x6c, 0xbc, 0x42, 0x4b, 0x98, + 0x48, 0xeb, 0xee, 0x6f, 0x66, 0xb5, 0xc6, 0xac, 0x4a, 0x92, 0x85, 0x1d, 0x20, 0x6d, 0x43, 0x43, + 0x52, 0x54, 0x8d, 0x56, 0xe4, 0x66, 0x0d, 0x86, 0x6f, 0x48, 0xa6, 0x54, 0x77, 0xb3, 0x2e, 0x07, + 0xdb, 0xf8, 0xba, 0xe1, 0xd8, 0xa5, 0x43, 0x62, 0xe9, 0x86, 0x63, 0x90, 0x99, 0x05, 0xf4, 0x7d, + 0xbb, 0x9c, 0x02, 0x8d, 0x2e, 0xe2, 0x57, 0x0d, 0x6c, 0x91, 0x8c, 0x08, 0x5f, 0x77, 0x3c, 0xb5, + 0x0c, 0x5d, 0xb3, 0x30, 0xba, 0x0b, 0x51, 0xa7, 0x8a, 0x24, 0xb7, 0xc4, 0x65, 0x63, 0xb9, 0x05, + 0x3e, 0x70, 0x0c, 0xbc, 0xe3, 0x96, 0x8f, 0xbc, 0xfb, 0x94, 0x1e, 0x11, 0x99, 0x4b, 0x46, 0x81, + 0x05, 0x1a, 0xf3, 0x91, 0xaa, 0x49, 0x35, 0x95, 0xb4, 0x0a, 0xa6, 0x7e, 0xac, 0x96, 0xb1, 0xe9, + 0x26, 0x45, 0x8f, 0x00, 0xbc, 0x5e, 0xb0, 0x0c, 0xcb, 0x3c, 0x1b, 0x88, 0xdd, 0x38, 0xde, 0x61, + 0x00, 0x6b, 0x1c, 0x5f, 0x90, 0x14, 0xcc, 0x7c, 0x45, 0x9f, 0x67, 0xe6, 0x4f, 0x1c, 0x2c, 0x86, + 0x65, 0x62, 0x40, 0x7e, 0x0c, 0xa8, 0xc2, 0x16, 0xed, 0xb9, 0x3b, 0xab, 0x49, 0x6e, 0x69, 0x2c, + 0x1b, 0xcb, 0x09, 0x21, 0xa0, 0xba, 0xa3, 0xb9, 0xc1, 0xc4, 0x0b, 0x95, 0xee, 0x3c, 0xe8, 0x71, + 0x07, 0x94, 0x51, 0x0a, 0x65, 0xe5, 0x44, 0x28, 0x2c, 0x9e, 0x1f, 0xcb, 0x36, 0x5c, 0x09, 0x84, + 0xe2, 0xf6, 0xec, 0x2a, 0xc4, 0x2b, 0x46, 0xb1, 0x44, 0xe4, 0xa2, 0x71, 0x54, 0xac, 0xe2, 0x26, + 0x6d, 0xdb, 0xa4, 0x08, 0x15, 0x23, 0x4f, 0xe4, 0xc2, 0xd1, 0x1e, 0x6e, 0x66, 0x1a, 0x21, 0x7d, + 0x6f, 0x37, 0xe3, 0x10, 0x2e, 0xf4, 0x34, 0x83, 0xb5, 0x7f, 0x65, 0xd0, 0x5e, 0xcc, 0x74, 0xf7, + 0x20, 0xf3, 0x5b, 0x0e, 0x52, 0x34, 0x6f, 0xfe, 0x70, 0x67, 0x17, 0xd7, 0xb0, 0xe2, 0x6c, 0x3a, + 0xb7, 0xf0, 0x3c, 0x44, 0x2d, 0x22, 0x91, 0x86, 0x43, 0xa5, 0x44, 0x6e, 0x2d, 0x24, 0x53, 0x87, + 0xf7, 0x01, 0xf5, 0x10, 0x99, 0x67, 0x17, 0x61, 0x46, 0x4f, 0x4d, 0x98, 0x3f, 0x70, 0x30, 0x1f, + 0x58, 0x2a, 0x6b, 0xd0, 0x3e, 0x4c, 0xdb, 0x1d, 0x2e, 0x7b, 0x4b, 0x8c, 0x2a, 0xd7, 0x06, 0x29, + 0x5a, 0x4c, 0x94, 0x88, 0xec, 0x0b, 0x7b, 0x7e, 0xe4, 0xa8, 0xc0, 0x6a, 0xe0, 0x64, 0x0b, 0xfa, + 0x4f, 0xb0, 0xb9, 0x4d, 0xf6, 0xb0, 0xaa, 0x54, 0xc9, 0xe0, 0x4c, 0x41, 0x97, 0x20, 0x5a, 0xa5, + 0x3e, 0xb4, 0xa8, 0x88, 0xc8, 0x7e, 0x65, 0x5e, 0xc0, 0xda, 0x20, 0x79, 0x58, 0xb7, 0xae, 0xc2, + 0xd4, 0xb1, 0x4e, 0x54, 0x4d, 0x29, 0x1a, 0xf6, 0x3a, 0xcd, 0x13, 0x11, 0x63, 0xce, 0x33, 0xea, + 0x92, 0xd9, 0x87, 0x6c, 0x60, 0xc0, 0x9d, 0x86, 0x69, 0x62, 0x8d, 0x50, 0xa3, 0x21, 0x18, 0x1e, + 0xd6, 0x87, 0xce, 0x70, 0xac, 0x3c, 0x0f, 0x24, 0xe7, 0x07, 0xd9, 0x53, 0xf6, 0x68, 0x6f, 0xd9, + 0x3f, 0xe7, 0xe0, 0x3a, 0x4d, 0xb4, 0x2d, 0x13, 0xf5, 0x18, 0xf7, 0xc8, 0x4b, 0x77, 0xcb, 0xc3, + 0x52, 0x9d, 0x17, 0x6f, 0xff, 0xc2, 0xc1, 0x8d, 0xc1, 0xea, 0x39, 0x47, 0xd9, 0xfb, 0x81, 0x4a, + 0xaa, 0xfb, 0x98, 0x48, 0xdf, 0xaa, 0xec, 0x2d, 0xb0, 0x0d, 0x49, 0x81, 0x49, 0x04, 0x97, 0x3b, + 0x1a, 0x9b, 0xd9, 0x62, 0xaa, 0xd8, 0xb3, 0xdc, 0x7f, 0xc6, 0x99, 0x5f, 0x71, 0xb0, 0x12, 0xc8, + 0x94, 0x00, 0x81, 0x1a, 0x60, 0xbf, 0x9c, 0xd7, 0x1c, 0xff, 0xc9, 0x85, 0xec, 0x87, 0x20, 0x31, + 0x32, 0xe1, 0xb2, 0x4f, 0x8c, 0x74, 0x33, 0x40, 0x96, 0xb6, 0x4e, 0x94, 0x25, 0x3d, 0x28, 0xb4, + 0x38, 0xe7, 0x09, 0x55, 0x87, 0xc1, 0xf9, 0xcd, 0xf5, 0x29, 0x5c, 0xee, 0x15, 0x5a, 0xb7, 0xe3, + 0x37, 0xe1, 0x6b, 0x56, 0x6c, 0x91, 0x34, 0x8b, 0x55, 0xc9, 0xaa, 0xfa, 0xfa, 0x3e, 0xc3, 0x96, + 0x0e, 0x9b, 0x7b, 0x92, 0x55, 0xb5, 0x77, 0xfd, 0xab, 0xa0, 0xf7, 0x4b, 0xbb, 0x4d, 0x07, 0x90, + 0xe8, 0xd4, 0x6c, 0xf6, 0x46, 0xbb, 0x31, 0x90, 0x64, 0xbb, 0xb5, 0xc7, 0x3b, 0xa4, 0x3b, 0xf3, + 0xdf, 0x71, 0xb8, 0x18, 0x9c, 0x6e, 0x1f, 0xa2, 0x0e, 0x55, 0x68, 0x9a, 0xa9, 0xfc, 0xd6, 0xc7, + 0x4f, 0xe9, 0x9c, 0xa2, 0x92, 0x6a, 0xa3, 0xc4, 0xcb, 0x7a, 0x5d, 0x60, 0x49, 0xe5, 0xaa, 0xa4, + 0x6a, 0xee, 0x0f, 0x81, 0xb4, 0x0c, 0x6c, 0xf1, 0xf9, 0x27, 0x85, 0x8d, 0xcd, 0x5b, 0x85, 0x46, + 0xe9, 0x19, 0x6e, 0x89, 0xe3, 0x25, 0x9b, 0x5c, 0xe8, 0x47, 0x90, 0xf0, 0xc8, 0x57, 0x53, 0x2d, + 0x5b, 0x91, 0xc7, 0xce, 0x10, 0x36, 0xc6, 0x58, 0xfb, 0x5c, 0xa5, 0xcc, 0x9e, 0xb2, 0x88, 0x64, + 0x92, 0x22, 0xdb, 0x23, 0x63, 0x8e, 0xd2, 0xd1, 0x67, 0xce, 0x46, 0x42, 0x0b, 0x00, 0x58, 0x2b, + 0xbb, 0x06, 0x11, 0x6a, 0x30, 0x89, 0x35, 0xb6, 0xcf, 0xd0, 0x3c, 0x4c, 0x12, 0x9d, 0x48, 0xb5, + 0xa2, 0x25, 0x91, 0xe4, 0x38, 0x5d, 0x9d, 0xa0, 0x0f, 0x0e, 0x24, 0x82, 0xae, 0x41, 0xc2, 0x3f, + 0x46, 0xdc, 0x4c, 0x46, 0xe9, 0x04, 0xa7, 0xbc, 0x09, 0xe2, 0x26, 0x5a, 0x86, 0x69, 0xab, 0x26, + 0x59, 0x55, 0x9f, 0xd9, 0x57, 0xd4, 0x2c, 0xee, 0x3e, 0x76, 0xec, 0x6e, 0xc3, 0x9c, 0x47, 0x75, + 0xba, 0x54, 0xb4, 0x54, 0x85, 0xda, 0x4f, 0x50, 0xfb, 0xd9, 0xf6, 0xf2, 0x81, 0xbd, 0x7a, 0xa0, + 0x2a, 0xb6, 0xdb, 0x4b, 0x88, 0xcb, 0xfa, 0x31, 0xd6, 0x24, 0x8d, 0xd8, 0xf6, 0x56, 0x72, 0x92, + 0xee, 0x8c, 0x5b, 0x21, 0xd3, 0xdf, 0x61, 0xb6, 0xdb, 0x65, 0xc9, 0xb0, 0x23, 0xa9, 0x8a, 0x26, + 0x91, 0x86, 0x89, 0x2d, 0x71, 0xca, 0x0d, 0x73, 0xa0, 0x2a, 0x16, 0xba, 0x01, 0xc8, 0xc5, 0xa6, + 0x37, 0x88, 0xd1, 0x20, 0x45, 0xb5, 0xdc, 0x4c, 0xc2, 0x12, 0x97, 0x8d, 0xb7, 0x19, 0xfa, 0x82, + 0x2e, 0x3c, 0x29, 0xd3, 0xf7, 0xa9, 0x44, 0x95, 0x39, 0x19, 0x5b, 0xe2, 0xb2, 0x13, 0x22, 0xfb, + 0x85, 0xd2, 0x10, 0x73, 0x4e, 0x30, 0xc5, 0x32, 0xb6, 0xe4, 0xe4, 0x94, 0x23, 0x2c, 0xce, 0xa3, + 0x5d, 0x6c, 0xc9, 0xe8, 0x1b, 0x48, 0x34, 0xb4, 0x92, 0xae, 0x95, 0x69, 0x77, 0xd4, 0x3a, 0x4e, + 0xc6, 0x69, 0x8a, 0x78, 0xfb, 0xe9, 0xa1, 0x5a, 0xc7, 0x48, 0x86, 0x8b, 0x0d, 0xcd, 0x63, 0x78, + 0xd1, 0x64, 0x6c, 0x4c, 0x26, 0x28, 0xd5, 0xf9, 0x70, 0xaa, 0xbf, 0xf4, 0xb9, 0xb5, 0xc9, 0x3e, + 0xdb, 0x08, 0x78, 0x9a, 0x79, 0x3b, 0x06, 0x73, 0x21, 0x1e, 0x28, 0x0b, 0x33, 0xbe, 0x3a, 0x9b, + 0xbe, 0xed, 0xea, 0xd5, 0xef, 0x8c, 0xf1, 0x7b, 0x30, 0xef, 0x8d, 0xd1, 0xf3, 0x71, 0x47, 0x39, + 0x4a, 0x9d, 0x92, 0x6d, 0x93, 0x97, 0xae, 0x05, 0x1b, 0xa7, 0x0c, 0xf3, 0xed, 0x71, 0x76, 0x7a, + 0xd3, 0xcd, 0x31, 0xd6, 0xf7, 0x34, 0xd6, 0x9e, 0xe6, 0x13, 0xad, 0xa2, 0x8b, 0x49, 0x37, 0x90, + 0x3f, 0x07, 0xdd, 0x17, 0x01, 0x94, 0x8c, 0x04, 0x51, 0xf2, 0x2e, 0xa4, 0xba, 0x28, 0xe9, 0x87, + 0x32, 0x4e, 0x5d, 0xe6, 0x3a, 0x59, 0xe9, 0x21, 0xa9, 0xc0, 0x25, 0x8f, 0x98, 0x3e, 0x5f, 0x2b, + 0x19, 0x3d, 0x25, 0x43, 0x67, 0xdb, 0x0c, 0xf5, 0x32, 0x59, 0x19, 0x19, 0xd2, 0x27, 0xc8, 0x3d, + 0x7a, 0x00, 0x91, 0x32, 0xae, 0xb9, 0x2f, 0x8d, 0xe1, 0x84, 0x91, 0x7a, 0x66, 0x7e, 0x1d, 0x81, + 0x64, 0xe8, 0xb5, 0xe2, 0x21, 0xc4, 0x6c, 0x7a, 0x9b, 0xaa, 0xe1, 0x93, 0xdf, 0xef, 0xb8, 0x6f, + 0x0d, 0x2f, 0x83, 0xf3, 0xca, 0xd8, 0xf5, 0x4c, 0x45, 0xbf, 0x1f, 0xda, 0x07, 0x90, 0xf5, 0x7a, + 0x5d, 0xb5, 0x2c, 0xf7, 0xdd, 0x33, 0x99, 0xbf, 0xf9, 0xf1, 0x53, 0x7a, 0xde, 0x09, 0x64, 0x95, + 0x8f, 0x78, 0x55, 0x17, 0xea, 0x12, 0xa9, 0xf2, 0xcf, 0xb1, 0x22, 0xc9, 0xad, 0x5d, 0x2c, 0x7f, + 0x78, 0x7b, 0x13, 0x58, 0x9e, 0x5d, 0x2c, 0x8b, 0xbe, 0x00, 0xe8, 0x1e, 0x00, 0xc3, 0x69, 0x8b, + 0xf5, 0x18, 0x2d, 0x2a, 0xed, 0x16, 0xe5, 0xdc, 0xf3, 0xf9, 0xf6, 0x3d, 0x9f, 0x67, 0xf2, 0x39, + 0xc9, 0x5c, 0x0a, 0x47, 0x3e, 0xa1, 0x8f, 0x9c, 0x87, 0xd0, 0xdf, 0x81, 0x31, 0x43, 0x37, 0x28, + 0x69, 0x62, 0xb9, 0x6c, 0xd8, 0x75, 0xda, 0xd4, 0xf5, 0xca, 0x8b, 0x4a, 0x41, 0xb7, 0x2c, 0x4c, + 0x51, 0x88, 0xb6, 0x13, 0xda, 0x84, 0x4b, 0x94, 0x41, 0xb8, 0x5c, 0x74, 0x21, 0x31, 0xc1, 0x8e, + 0x52, 0x49, 0x9e, 0x65, 0xab, 0x79, 0x67, 0x91, 0x69, 0xb7, 0x2d, 0x61, 0xae, 0x17, 0x91, 0x5d, + 0x8f, 0xaf, 0xa8, 0xc7, 0x8c, 0xeb, 0x41, 0x64, 0x66, 0xed, 0x9d, 0xa4, 0x26, 0xfa, 0x9e, 0x96, + 0x27, 0x7b, 0x4e, 0xcb, 0xb9, 0xff, 0x4c, 0xc3, 0x38, 0x7d, 0x41, 0xa3, 0x9f, 0x71, 0x10, 0x75, + 0x3e, 0x09, 0xa0, 0xd5, 0x10, 0x88, 0xbd, 0xdf, 0x20, 0x52, 0x6b, 0x83, 0x98, 0x32, 0x91, 0xfa, + 0xe6, 0xa7, 0x7f, 0xfe, 0xfb, 0x2f, 0x47, 0xd3, 0x68, 0x41, 0xe8, 0xf7, 0xed, 0x04, 0xfd, 0x9e, + 0x83, 0x0b, 0x3d, 0xa7, 0x64, 0xb4, 0xd9, 0x2f, 0x51, 0xd8, 0xd7, 0x8a, 0xd4, 0xed, 0x21, 0xbd, + 0x58, 0xa5, 0xeb, 0xb4, 0xd2, 0xeb, 0x68, 0x35, 0xa4, 0xd2, 0xde, 0xf3, 0x39, 0xfa, 0xc0, 0xc1, + 0x4c, 0x77, 0x40, 0xb4, 0x31, 0x4c, 0x7a, 0xb7, 0xe6, 0xcd, 0xe1, 0x9c, 0x58, 0xc9, 0x07, 0xb4, + 0xe4, 0x7d, 0xf4, 0x6c, 0xe0, 0x92, 0x85, 0xd7, 0x1d, 0x47, 0xe7, 0x37, 0xbd, 0x26, 0xe8, 0x37, + 0x1c, 0x24, 0x3a, 0xaf, 0xdb, 0x68, 0xbd, 0x5f, 0x75, 0x81, 0x5f, 0x11, 0x52, 0xb9, 0x61, 0x5c, + 0x18, 0x1c, 0x9e, 0xc2, 0xc9, 0xa2, 0x65, 0x21, 0xf4, 0x1b, 0x9a, 0xff, 0x4c, 0x8d, 0xfe, 0xc1, + 0x41, 0xfa, 0x84, 0x0b, 0x16, 0xca, 0xf7, 0xab, 0x63, 0xb0, 0xdb, 0x62, 0x6a, 0xe7, 0x4c, 0x31, + 0x18, 0xb8, 0x3b, 0x14, 0xdc, 0x26, 0xca, 0x0d, 0x31, 0x2b, 0x67, 0x4b, 0xbf, 0x41, 0xff, 0xe3, + 0x60, 0xa1, 0xef, 0x15, 0x1f, 0x3d, 0x18, 0x86, 0x3f, 0x41, 0x5f, 0x21, 0x52, 0xdb, 0x67, 0x88, + 0xc0, 0x20, 0x16, 0x28, 0xc4, 0xa7, 0x68, 0xef, 0xf4, 0x74, 0xa4, 0x9a, 0xe5, 0x01, 0xff, 0x17, + 0x07, 0x57, 0xfa, 0x7d, 0x3b, 0x40, 0xf7, 0x87, 0xa9, 0x3a, 0xe0, 0x23, 0x46, 0xea, 0xc1, 0xe9, + 0x03, 0x30, 0xd4, 0x8f, 0x29, 0xea, 0x6d, 0x74, 0xff, 0x8c, 0xa8, 0xd1, 0xef, 0x38, 0x98, 0xee, + 0xba, 0x37, 0xa3, 0xdc, 0x89, 0xd4, 0xeb, 0xb9, 0x83, 0xa7, 0x36, 0x86, 0xf2, 0x61, 0x28, 0x04, + 0x8a, 0x62, 0x15, 0xad, 0x84, 0xa0, 0x90, 0x5c, 0x3f, 0xf6, 0x5e, 0x42, 0xff, 0xe6, 0x60, 0xbe, + 0xcf, 0xad, 0x18, 0xdd, 0x1b, 0xa6, 0xb1, 0x01, 0x02, 0x72, 0xff, 0xd4, 0xfe, 0x0c, 0xd1, 0x3e, + 0x45, 0xf4, 0x18, 0x3d, 0x3c, 0xfd, 0x5c, 0xfc, 0x62, 0xf3, 0x47, 0x0e, 0xe2, 0x1d, 0xba, 0x85, + 0x6e, 0x0d, 0x2c, 0x71, 0x2e, 0xa6, 0xf5, 0x21, 0x3c, 0x18, 0x8a, 0x5d, 0x8a, 0xe2, 0x1e, 0xfa, + 0xee, 0x60, 0x9a, 0x28, 0xbc, 0x0e, 0xb8, 0xa8, 0xbf, 0xc9, 0x3f, 0x7f, 0xf7, 0x79, 0x91, 0x7b, + 0xff, 0x79, 0x91, 0xfb, 0xdb, 0xe7, 0x45, 0xee, 0x17, 0x5f, 0x16, 0x47, 0xde, 0x7f, 0x59, 0x1c, + 0xf9, 0xeb, 0x97, 0xc5, 0x91, 0x1f, 0x9e, 0x78, 0x42, 0x6a, 0xfa, 0x13, 0xd2, 0xe3, 0x52, 0x29, + 0x4a, 0xff, 0x41, 0xb1, 0xf1, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0x64, 0x69, 0xce, 0x0e, + 0x1a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2892,6 +3021,109 @@ func (m *BTCDelegatorDelegationsResponse) MarshalToSizedBuffer(dAtA []byte) (int return len(dAtA) - i, nil } +func (m *FinalityProviderResponse) 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 *FinalityProviderResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.VotingPower != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) + i-- + dAtA[i] = 0x48 + } + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x40 + } + if m.SlashedBtcHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBtcHeight)) + i-- + dAtA[i] = 0x38 + } + if m.SlashedBabylonHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBabylonHeight)) + i-- + dAtA[i] = 0x30 + } + if m.Pop != nil { + { + size, err := m.Pop.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.BtcPk != nil { + { + size := m.BtcPk.Size() + i -= size + if _, err := m.BtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.BabylonPk != nil { + { + size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Commission != nil { + { + size := m.Commission.Size() + i -= size + if _, err := m.Commission.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Description != nil { + { + size, err := m.Description.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -3305,6 +3537,47 @@ func (m *BTCDelegatorDelegationsResponse) Size() (n int) { return n } +func (m *FinalityProviderResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Description != nil { + l = m.Description.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Commission != nil { + l = m.Commission.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.BabylonPk != nil { + l = m.BabylonPk.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.BtcPk != nil { + l = m.BtcPk.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pop != nil { + l = m.Pop.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.SlashedBabylonHeight != 0 { + n += 1 + sovQuery(uint64(m.SlashedBabylonHeight)) + } + if m.SlashedBtcHeight != 0 { + n += 1 + sovQuery(uint64(m.SlashedBtcHeight)) + } + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + if m.VotingPower != 0 { + n += 1 + sovQuery(uint64(m.VotingPower)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3588,7 +3861,7 @@ func (m *QueryFinalityProvidersResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.FinalityProviders = append(m.FinalityProviders, &FinalityProvider{}) + m.FinalityProviders = append(m.FinalityProviders, &FinalityProviderResponse{}) if err := m.FinalityProviders[len(m.FinalityProviders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -5896,6 +6169,311 @@ func (m *BTCDelegatorDelegationsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *FinalityProviderResponse) 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 ErrIntOverflowQuery + } + 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: FinalityProviderResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FinalityProviderResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Description == nil { + m.Description = &types.Description{} + } + if err := m.Description.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commission", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v cosmossdk_io_math.LegacyDec + m.Commission = &v + if err := m.Commission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BabylonPk == nil { + m.BabylonPk = &secp256k1.PubKey{} + } + if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.BtcPk = &v + if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pop", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pop == nil { + m.Pop = &ProofOfPossession{} + } + if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) + } + m.SlashedBabylonHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SlashedBabylonHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) + } + m.SlashedBtcHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SlashedBtcHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) + } + m.VotingPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotingPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 6009d4640167db977b8d8c8c91372edbf81130da Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 29 Feb 2024 23:23:11 -0300 Subject: [PATCH 024/119] chore: btcstaking query finality provider (#517) * chore: add voting power to finality provider * chore: modified query FinalityProvider to return FinalityProviderResponse * fix: check of equal between finality provider and query response --- proto/babylon/btcstaking/v1/query.proto | 2 +- x/btcstaking/keeper/grpc_query.go | 24 ++- x/btcstaking/types/query.pb.go | 234 ++++++++++++------------ 3 files changed, 134 insertions(+), 126 deletions(-) diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index f7e34b305..61e67226f 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -103,7 +103,7 @@ message QueryFinalityProviderRequest { // QueryFinalityProviderResponse contains information about a finality provider message QueryFinalityProviderResponse { // finality_provider contains the FinalityProvider - FinalityProvider finality_provider = 1; + FinalityProviderResponse finality_provider = 1; } // QueryBTCDelegationsRequest is the request type for the diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index 94e198fda..f94d233e8 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -26,23 +26,23 @@ func (k Keeper) FinalityProviders(c context.Context, req *types.QueryFinalityPro store := k.finalityProviderStore(ctx) currBlockHeight := uint64(ctx.BlockHeight()) - var finalityProvidersResp []*types.FinalityProviderResponse + var fpResp []*types.FinalityProviderResponse pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { - var finalityProvider types.FinalityProvider - if err := finalityProvider.Unmarshal(value); err != nil { + var fp types.FinalityProvider + if err := fp.Unmarshal(value); err != nil { return err } votingPower := k.GetVotingPower(ctx, key, currBlockHeight) - resp := types.NewFinalityProviderResponse(&finalityProvider, currBlockHeight, votingPower) - finalityProvidersResp = append(finalityProvidersResp, resp) + resp := types.NewFinalityProviderResponse(&fp, currBlockHeight, votingPower) + fpResp = append(fpResp, resp) return nil }) if err != nil { return nil, err } - return &types.QueryFinalityProvidersResponse{FinalityProviders: finalityProvidersResp, Pagination: pageRes}, nil + return &types.QueryFinalityProvidersResponse{FinalityProviders: fpResp, Pagination: pageRes}, nil } // FinalityProvider returns the finality provider with the specified finality provider BTC PK @@ -61,13 +61,21 @@ func (k Keeper) FinalityProvider(c context.Context, req *types.QueryFinalityProv return nil, err } + key, err := fpPK.Marshal() + if err != nil { + return nil, err + } + ctx := sdk.UnwrapSDKContext(c) - fp, err := k.GetFinalityProvider(ctx, fpPK.MustMarshal()) + fp, err := k.GetFinalityProvider(ctx, key) if err != nil { return nil, err } - return &types.QueryFinalityProviderResponse{FinalityProvider: fp}, nil + currBlockHeight := uint64(ctx.BlockHeight()) + votingPower := k.GetVotingPower(ctx, key, currBlockHeight) + fpResp := types.NewFinalityProviderResponse(fp, currBlockHeight, votingPower) + return &types.QueryFinalityProviderResponse{FinalityProvider: fpResp}, nil } // BTCDelegations returns all BTC delegations under a given status diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index f9d16c4d0..1c1e9dc10 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -270,7 +270,7 @@ func (m *QueryFinalityProviderRequest) GetFpBtcPkHex() string { // QueryFinalityProviderResponse contains information about a finality provider type QueryFinalityProviderResponse struct { // finality_provider contains the FinalityProvider - FinalityProvider *FinalityProvider `protobuf:"bytes,1,opt,name=finality_provider,json=finalityProvider,proto3" json:"finality_provider,omitempty"` + FinalityProvider *FinalityProviderResponse `protobuf:"bytes,1,opt,name=finality_provider,json=finalityProvider,proto3" json:"finality_provider,omitempty"` } func (m *QueryFinalityProviderResponse) Reset() { *m = QueryFinalityProviderResponse{} } @@ -306,7 +306,7 @@ func (m *QueryFinalityProviderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryFinalityProviderResponse proto.InternalMessageInfo -func (m *QueryFinalityProviderResponse) GetFinalityProvider() *FinalityProvider { +func (m *QueryFinalityProviderResponse) GetFinalityProvider() *FinalityProviderResponse { if m != nil { return m.FinalityProvider } @@ -1509,120 +1509,120 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1795 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdf, 0x4f, 0xdb, 0xdc, - 0x19, 0xc6, 0x10, 0xf2, 0xc1, 0x1b, 0x12, 0xe8, 0xf9, 0x68, 0x49, 0x43, 0x21, 0x34, 0xeb, 0x07, - 0x81, 0xb6, 0x76, 0x09, 0x94, 0x8b, 0x76, 0x6b, 0x4b, 0xa0, 0x2d, 0xfd, 0x81, 0x9a, 0x19, 0xaa, - 0x49, 0x9b, 0xb4, 0xc8, 0x71, 0x4e, 0x1c, 0x8b, 0xc4, 0x76, 0xed, 0x13, 0x96, 0xa8, 0xea, 0xcd, - 0x2e, 0x76, 0x37, 0x69, 0xd2, 0x76, 0xb5, 0x7f, 0x60, 0x93, 0x76, 0xb9, 0xee, 0x66, 0x7f, 0x41, - 0x77, 0x57, 0x75, 0x17, 0x9b, 0x7a, 0x51, 0x4d, 0xed, 0xb4, 0x49, 0x93, 0xa6, 0x69, 0x37, 0xbb, - 0x9e, 0x7c, 0x7c, 0x1c, 0x3b, 0x89, 0x1d, 0x12, 0xe0, 0xbb, 0x23, 0x3e, 0xef, 0xaf, 0xe7, 0x7d, - 0x9f, 0xf3, 0xf8, 0x1c, 0x03, 0x57, 0x4b, 0x52, 0xa9, 0x55, 0xd3, 0x35, 0xa1, 0x44, 0x64, 0x8b, - 0x48, 0x47, 0xaa, 0xa6, 0x08, 0xc7, 0xeb, 0xc2, 0xab, 0x06, 0x36, 0x5b, 0xbc, 0x61, 0xea, 0x44, - 0x47, 0x17, 0x99, 0x09, 0xef, 0x99, 0xf0, 0xc7, 0xeb, 0xa9, 0x59, 0x45, 0x57, 0x74, 0x6a, 0x21, - 0xd8, 0x7f, 0x39, 0xc6, 0xa9, 0x2b, 0x8a, 0xae, 0x2b, 0x35, 0x2c, 0x48, 0x86, 0x2a, 0x48, 0x9a, - 0xa6, 0x13, 0x89, 0xa8, 0xba, 0x66, 0xb1, 0xd5, 0xcb, 0xb2, 0x6e, 0xd5, 0x75, 0xab, 0xe8, 0xb8, - 0x39, 0x3f, 0xd8, 0x52, 0xc6, 0xf9, 0x25, 0xc8, 0x66, 0xcb, 0x20, 0xba, 0x60, 0x61, 0xd9, 0xc8, - 0xdd, 0xde, 0x3a, 0x5a, 0x17, 0x8e, 0x70, 0xcb, 0xb5, 0xb9, 0xc6, 0x6c, 0xbc, 0x42, 0x4b, 0x98, - 0x48, 0xeb, 0xee, 0x6f, 0x66, 0xb5, 0xc6, 0xac, 0x4a, 0x92, 0x85, 0x1d, 0x20, 0x6d, 0x43, 0x43, - 0x52, 0x54, 0x8d, 0x56, 0xe4, 0x66, 0x0d, 0x86, 0x6f, 0x48, 0xa6, 0x54, 0x77, 0xb3, 0x2e, 0x07, - 0xdb, 0xf8, 0xba, 0xe1, 0xd8, 0xa5, 0x43, 0x62, 0xe9, 0x86, 0x63, 0x90, 0x99, 0x05, 0xf4, 0x7d, - 0xbb, 0x9c, 0x02, 0x8d, 0x2e, 0xe2, 0x57, 0x0d, 0x6c, 0x91, 0x8c, 0x08, 0x5f, 0x77, 0x3c, 0xb5, - 0x0c, 0x5d, 0xb3, 0x30, 0xba, 0x0b, 0x51, 0xa7, 0x8a, 0x24, 0xb7, 0xc4, 0x65, 0x63, 0xb9, 0x05, - 0x3e, 0x70, 0x0c, 0xbc, 0xe3, 0x96, 0x8f, 0xbc, 0xfb, 0x94, 0x1e, 0x11, 0x99, 0x4b, 0x46, 0x81, - 0x05, 0x1a, 0xf3, 0x91, 0xaa, 0x49, 0x35, 0x95, 0xb4, 0x0a, 0xa6, 0x7e, 0xac, 0x96, 0xb1, 0xe9, - 0x26, 0x45, 0x8f, 0x00, 0xbc, 0x5e, 0xb0, 0x0c, 0xcb, 0x3c, 0x1b, 0x88, 0xdd, 0x38, 0xde, 0x61, - 0x00, 0x6b, 0x1c, 0x5f, 0x90, 0x14, 0xcc, 0x7c, 0x45, 0x9f, 0x67, 0xe6, 0x4f, 0x1c, 0x2c, 0x86, - 0x65, 0x62, 0x40, 0x7e, 0x0c, 0xa8, 0xc2, 0x16, 0xed, 0xb9, 0x3b, 0xab, 0x49, 0x6e, 0x69, 0x2c, - 0x1b, 0xcb, 0x09, 0x21, 0xa0, 0xba, 0xa3, 0xb9, 0xc1, 0xc4, 0x0b, 0x95, 0xee, 0x3c, 0xe8, 0x71, - 0x07, 0x94, 0x51, 0x0a, 0x65, 0xe5, 0x44, 0x28, 0x2c, 0x9e, 0x1f, 0xcb, 0x36, 0x5c, 0x09, 0x84, - 0xe2, 0xf6, 0xec, 0x2a, 0xc4, 0x2b, 0x46, 0xb1, 0x44, 0xe4, 0xa2, 0x71, 0x54, 0xac, 0xe2, 0x26, - 0x6d, 0xdb, 0xa4, 0x08, 0x15, 0x23, 0x4f, 0xe4, 0xc2, 0xd1, 0x1e, 0x6e, 0x66, 0x1a, 0x21, 0x7d, - 0x6f, 0x37, 0xe3, 0x10, 0x2e, 0xf4, 0x34, 0x83, 0xb5, 0x7f, 0x65, 0xd0, 0x5e, 0xcc, 0x74, 0xf7, - 0x20, 0xf3, 0x5b, 0x0e, 0x52, 0x34, 0x6f, 0xfe, 0x70, 0x67, 0x17, 0xd7, 0xb0, 0xe2, 0x6c, 0x3a, - 0xb7, 0xf0, 0x3c, 0x44, 0x2d, 0x22, 0x91, 0x86, 0x43, 0xa5, 0x44, 0x6e, 0x2d, 0x24, 0x53, 0x87, - 0xf7, 0x01, 0xf5, 0x10, 0x99, 0x67, 0x17, 0x61, 0x46, 0x4f, 0x4d, 0x98, 0x3f, 0x70, 0x30, 0x1f, - 0x58, 0x2a, 0x6b, 0xd0, 0x3e, 0x4c, 0xdb, 0x1d, 0x2e, 0x7b, 0x4b, 0x8c, 0x2a, 0xd7, 0x06, 0x29, - 0x5a, 0x4c, 0x94, 0x88, 0xec, 0x0b, 0x7b, 0x7e, 0xe4, 0xa8, 0xc0, 0x6a, 0xe0, 0x64, 0x0b, 0xfa, - 0x4f, 0xb0, 0xb9, 0x4d, 0xf6, 0xb0, 0xaa, 0x54, 0xc9, 0xe0, 0x4c, 0x41, 0x97, 0x20, 0x5a, 0xa5, - 0x3e, 0xb4, 0xa8, 0x88, 0xc8, 0x7e, 0x65, 0x5e, 0xc0, 0xda, 0x20, 0x79, 0x58, 0xb7, 0xae, 0xc2, - 0xd4, 0xb1, 0x4e, 0x54, 0x4d, 0x29, 0x1a, 0xf6, 0x3a, 0xcd, 0x13, 0x11, 0x63, 0xce, 0x33, 0xea, - 0x92, 0xd9, 0x87, 0x6c, 0x60, 0xc0, 0x9d, 0x86, 0x69, 0x62, 0x8d, 0x50, 0xa3, 0x21, 0x18, 0x1e, - 0xd6, 0x87, 0xce, 0x70, 0xac, 0x3c, 0x0f, 0x24, 0xe7, 0x07, 0xd9, 0x53, 0xf6, 0x68, 0x6f, 0xd9, - 0x3f, 0xe7, 0xe0, 0x3a, 0x4d, 0xb4, 0x2d, 0x13, 0xf5, 0x18, 0xf7, 0xc8, 0x4b, 0x77, 0xcb, 0xc3, - 0x52, 0x9d, 0x17, 0x6f, 0xff, 0xc2, 0xc1, 0x8d, 0xc1, 0xea, 0x39, 0x47, 0xd9, 0xfb, 0x81, 0x4a, - 0xaa, 0xfb, 0x98, 0x48, 0xdf, 0xaa, 0xec, 0x2d, 0xb0, 0x0d, 0x49, 0x81, 0x49, 0x04, 0x97, 0x3b, - 0x1a, 0x9b, 0xd9, 0x62, 0xaa, 0xd8, 0xb3, 0xdc, 0x7f, 0xc6, 0x99, 0x5f, 0x71, 0xb0, 0x12, 0xc8, - 0x94, 0x00, 0x81, 0x1a, 0x60, 0xbf, 0x9c, 0xd7, 0x1c, 0xff, 0xc9, 0x85, 0xec, 0x87, 0x20, 0x31, - 0x32, 0xe1, 0xb2, 0x4f, 0x8c, 0x74, 0x33, 0x40, 0x96, 0xb6, 0x4e, 0x94, 0x25, 0x3d, 0x28, 0xb4, - 0x38, 0xe7, 0x09, 0x55, 0x87, 0xc1, 0xf9, 0xcd, 0xf5, 0x29, 0x5c, 0xee, 0x15, 0x5a, 0xb7, 0xe3, - 0x37, 0xe1, 0x6b, 0x56, 0x6c, 0x91, 0x34, 0x8b, 0x55, 0xc9, 0xaa, 0xfa, 0xfa, 0x3e, 0xc3, 0x96, - 0x0e, 0x9b, 0x7b, 0x92, 0x55, 0xb5, 0x77, 0xfd, 0xab, 0xa0, 0xf7, 0x4b, 0xbb, 0x4d, 0x07, 0x90, - 0xe8, 0xd4, 0x6c, 0xf6, 0x46, 0xbb, 0x31, 0x90, 0x64, 0xbb, 0xb5, 0xc7, 0x3b, 0xa4, 0x3b, 0xf3, - 0xdf, 0x71, 0xb8, 0x18, 0x9c, 0x6e, 0x1f, 0xa2, 0x0e, 0x55, 0x68, 0x9a, 0xa9, 0xfc, 0xd6, 0xc7, - 0x4f, 0xe9, 0x9c, 0xa2, 0x92, 0x6a, 0xa3, 0xc4, 0xcb, 0x7a, 0x5d, 0x60, 0x49, 0xe5, 0xaa, 0xa4, - 0x6a, 0xee, 0x0f, 0x81, 0xb4, 0x0c, 0x6c, 0xf1, 0xf9, 0x27, 0x85, 0x8d, 0xcd, 0x5b, 0x85, 0x46, - 0xe9, 0x19, 0x6e, 0x89, 0xe3, 0x25, 0x9b, 0x5c, 0xe8, 0x47, 0x90, 0xf0, 0xc8, 0x57, 0x53, 0x2d, - 0x5b, 0x91, 0xc7, 0xce, 0x10, 0x36, 0xc6, 0x58, 0xfb, 0x5c, 0xa5, 0xcc, 0x9e, 0xb2, 0x88, 0x64, - 0x92, 0x22, 0xdb, 0x23, 0x63, 0x8e, 0xd2, 0xd1, 0x67, 0xce, 0x46, 0x42, 0x0b, 0x00, 0x58, 0x2b, - 0xbb, 0x06, 0x11, 0x6a, 0x30, 0x89, 0x35, 0xb6, 0xcf, 0xd0, 0x3c, 0x4c, 0x12, 0x9d, 0x48, 0xb5, - 0xa2, 0x25, 0x91, 0xe4, 0x38, 0x5d, 0x9d, 0xa0, 0x0f, 0x0e, 0x24, 0x82, 0xae, 0x41, 0xc2, 0x3f, - 0x46, 0xdc, 0x4c, 0x46, 0xe9, 0x04, 0xa7, 0xbc, 0x09, 0xe2, 0x26, 0x5a, 0x86, 0x69, 0xab, 0x26, - 0x59, 0x55, 0x9f, 0xd9, 0x57, 0xd4, 0x2c, 0xee, 0x3e, 0x76, 0xec, 0x6e, 0xc3, 0x9c, 0x47, 0x75, - 0xba, 0x54, 0xb4, 0x54, 0x85, 0xda, 0x4f, 0x50, 0xfb, 0xd9, 0xf6, 0xf2, 0x81, 0xbd, 0x7a, 0xa0, - 0x2a, 0xb6, 0xdb, 0x4b, 0x88, 0xcb, 0xfa, 0x31, 0xd6, 0x24, 0x8d, 0xd8, 0xf6, 0x56, 0x72, 0x92, - 0xee, 0x8c, 0x5b, 0x21, 0xd3, 0xdf, 0x61, 0xb6, 0xdb, 0x65, 0xc9, 0xb0, 0x23, 0xa9, 0x8a, 0x26, - 0x91, 0x86, 0x89, 0x2d, 0x71, 0xca, 0x0d, 0x73, 0xa0, 0x2a, 0x16, 0xba, 0x01, 0xc8, 0xc5, 0xa6, - 0x37, 0x88, 0xd1, 0x20, 0x45, 0xb5, 0xdc, 0x4c, 0xc2, 0x12, 0x97, 0x8d, 0xb7, 0x19, 0xfa, 0x82, - 0x2e, 0x3c, 0x29, 0xd3, 0xf7, 0xa9, 0x44, 0x95, 0x39, 0x19, 0x5b, 0xe2, 0xb2, 0x13, 0x22, 0xfb, - 0x85, 0xd2, 0x10, 0x73, 0x4e, 0x30, 0xc5, 0x32, 0xb6, 0xe4, 0xe4, 0x94, 0x23, 0x2c, 0xce, 0xa3, - 0x5d, 0x6c, 0xc9, 0xe8, 0x1b, 0x48, 0x34, 0xb4, 0x92, 0xae, 0x95, 0x69, 0x77, 0xd4, 0x3a, 0x4e, - 0xc6, 0x69, 0x8a, 0x78, 0xfb, 0xe9, 0xa1, 0x5a, 0xc7, 0x48, 0x86, 0x8b, 0x0d, 0xcd, 0x63, 0x78, - 0xd1, 0x64, 0x6c, 0x4c, 0x26, 0x28, 0xd5, 0xf9, 0x70, 0xaa, 0xbf, 0xf4, 0xb9, 0xb5, 0xc9, 0x3e, - 0xdb, 0x08, 0x78, 0x9a, 0x79, 0x3b, 0x06, 0x73, 0x21, 0x1e, 0x28, 0x0b, 0x33, 0xbe, 0x3a, 0x9b, - 0xbe, 0xed, 0xea, 0xd5, 0xef, 0x8c, 0xf1, 0x7b, 0x30, 0xef, 0x8d, 0xd1, 0xf3, 0x71, 0x47, 0x39, - 0x4a, 0x9d, 0x92, 0x6d, 0x93, 0x97, 0xae, 0x05, 0x1b, 0xa7, 0x0c, 0xf3, 0xed, 0x71, 0x76, 0x7a, - 0xd3, 0xcd, 0x31, 0xd6, 0xf7, 0x34, 0xd6, 0x9e, 0xe6, 0x13, 0xad, 0xa2, 0x8b, 0x49, 0x37, 0x90, - 0x3f, 0x07, 0xdd, 0x17, 0x01, 0x94, 0x8c, 0x04, 0x51, 0xf2, 0x2e, 0xa4, 0xba, 0x28, 0xe9, 0x87, - 0x32, 0x4e, 0x5d, 0xe6, 0x3a, 0x59, 0xe9, 0x21, 0xa9, 0xc0, 0x25, 0x8f, 0x98, 0x3e, 0x5f, 0x2b, - 0x19, 0x3d, 0x25, 0x43, 0x67, 0xdb, 0x0c, 0xf5, 0x32, 0x59, 0x19, 0x19, 0xd2, 0x27, 0xc8, 0x3d, - 0x7a, 0x00, 0x91, 0x32, 0xae, 0xb9, 0x2f, 0x8d, 0xe1, 0x84, 0x91, 0x7a, 0x66, 0x7e, 0x1d, 0x81, - 0x64, 0xe8, 0xb5, 0xe2, 0x21, 0xc4, 0x6c, 0x7a, 0x9b, 0xaa, 0xe1, 0x93, 0xdf, 0xef, 0xb8, 0x6f, - 0x0d, 0x2f, 0x83, 0xf3, 0xca, 0xd8, 0xf5, 0x4c, 0x45, 0xbf, 0x1f, 0xda, 0x07, 0x90, 0xf5, 0x7a, - 0x5d, 0xb5, 0x2c, 0xf7, 0xdd, 0x33, 0x99, 0xbf, 0xf9, 0xf1, 0x53, 0x7a, 0xde, 0x09, 0x64, 0x95, - 0x8f, 0x78, 0x55, 0x17, 0xea, 0x12, 0xa9, 0xf2, 0xcf, 0xb1, 0x22, 0xc9, 0xad, 0x5d, 0x2c, 0x7f, - 0x78, 0x7b, 0x13, 0x58, 0x9e, 0x5d, 0x2c, 0x8b, 0xbe, 0x00, 0xe8, 0x1e, 0x00, 0xc3, 0x69, 0x8b, - 0xf5, 0x18, 0x2d, 0x2a, 0xed, 0x16, 0xe5, 0xdc, 0xf3, 0xf9, 0xf6, 0x3d, 0x9f, 0x67, 0xf2, 0x39, - 0xc9, 0x5c, 0x0a, 0x47, 0x3e, 0xa1, 0x8f, 0x9c, 0x87, 0xd0, 0xdf, 0x81, 0x31, 0x43, 0x37, 0x28, - 0x69, 0x62, 0xb9, 0x6c, 0xd8, 0x75, 0xda, 0xd4, 0xf5, 0xca, 0x8b, 0x4a, 0x41, 0xb7, 0x2c, 0x4c, - 0x51, 0x88, 0xb6, 0x13, 0xda, 0x84, 0x4b, 0x94, 0x41, 0xb8, 0x5c, 0x74, 0x21, 0x31, 0xc1, 0x8e, - 0x52, 0x49, 0x9e, 0x65, 0xab, 0x79, 0x67, 0x91, 0x69, 0xb7, 0x2d, 0x61, 0xae, 0x17, 0x91, 0x5d, - 0x8f, 0xaf, 0xa8, 0xc7, 0x8c, 0xeb, 0x41, 0x64, 0x66, 0xed, 0x9d, 0xa4, 0x26, 0xfa, 0x9e, 0x96, - 0x27, 0x7b, 0x4e, 0xcb, 0xb9, 0xff, 0x4c, 0xc3, 0x38, 0x7d, 0x41, 0xa3, 0x9f, 0x71, 0x10, 0x75, - 0x3e, 0x09, 0xa0, 0xd5, 0x10, 0x88, 0xbd, 0xdf, 0x20, 0x52, 0x6b, 0x83, 0x98, 0x32, 0x91, 0xfa, - 0xe6, 0xa7, 0x7f, 0xfe, 0xfb, 0x2f, 0x47, 0xd3, 0x68, 0x41, 0xe8, 0xf7, 0xed, 0x04, 0xfd, 0x9e, - 0x83, 0x0b, 0x3d, 0xa7, 0x64, 0xb4, 0xd9, 0x2f, 0x51, 0xd8, 0xd7, 0x8a, 0xd4, 0xed, 0x21, 0xbd, - 0x58, 0xa5, 0xeb, 0xb4, 0xd2, 0xeb, 0x68, 0x35, 0xa4, 0xd2, 0xde, 0xf3, 0x39, 0xfa, 0xc0, 0xc1, - 0x4c, 0x77, 0x40, 0xb4, 0x31, 0x4c, 0x7a, 0xb7, 0xe6, 0xcd, 0xe1, 0x9c, 0x58, 0xc9, 0x07, 0xb4, - 0xe4, 0x7d, 0xf4, 0x6c, 0xe0, 0x92, 0x85, 0xd7, 0x1d, 0x47, 0xe7, 0x37, 0xbd, 0x26, 0xe8, 0x37, - 0x1c, 0x24, 0x3a, 0xaf, 0xdb, 0x68, 0xbd, 0x5f, 0x75, 0x81, 0x5f, 0x11, 0x52, 0xb9, 0x61, 0x5c, - 0x18, 0x1c, 0x9e, 0xc2, 0xc9, 0xa2, 0x65, 0x21, 0xf4, 0x1b, 0x9a, 0xff, 0x4c, 0x8d, 0xfe, 0xc1, - 0x41, 0xfa, 0x84, 0x0b, 0x16, 0xca, 0xf7, 0xab, 0x63, 0xb0, 0xdb, 0x62, 0x6a, 0xe7, 0x4c, 0x31, - 0x18, 0xb8, 0x3b, 0x14, 0xdc, 0x26, 0xca, 0x0d, 0x31, 0x2b, 0x67, 0x4b, 0xbf, 0x41, 0xff, 0xe3, - 0x60, 0xa1, 0xef, 0x15, 0x1f, 0x3d, 0x18, 0x86, 0x3f, 0x41, 0x5f, 0x21, 0x52, 0xdb, 0x67, 0x88, - 0xc0, 0x20, 0x16, 0x28, 0xc4, 0xa7, 0x68, 0xef, 0xf4, 0x74, 0xa4, 0x9a, 0xe5, 0x01, 0xff, 0x17, - 0x07, 0x57, 0xfa, 0x7d, 0x3b, 0x40, 0xf7, 0x87, 0xa9, 0x3a, 0xe0, 0x23, 0x46, 0xea, 0xc1, 0xe9, - 0x03, 0x30, 0xd4, 0x8f, 0x29, 0xea, 0x6d, 0x74, 0xff, 0x8c, 0xa8, 0xd1, 0xef, 0x38, 0x98, 0xee, - 0xba, 0x37, 0xa3, 0xdc, 0x89, 0xd4, 0xeb, 0xb9, 0x83, 0xa7, 0x36, 0x86, 0xf2, 0x61, 0x28, 0x04, - 0x8a, 0x62, 0x15, 0xad, 0x84, 0xa0, 0x90, 0x5c, 0x3f, 0xf6, 0x5e, 0x42, 0xff, 0xe6, 0x60, 0xbe, - 0xcf, 0xad, 0x18, 0xdd, 0x1b, 0xa6, 0xb1, 0x01, 0x02, 0x72, 0xff, 0xd4, 0xfe, 0x0c, 0xd1, 0x3e, - 0x45, 0xf4, 0x18, 0x3d, 0x3c, 0xfd, 0x5c, 0xfc, 0x62, 0xf3, 0x47, 0x0e, 0xe2, 0x1d, 0xba, 0x85, - 0x6e, 0x0d, 0x2c, 0x71, 0x2e, 0xa6, 0xf5, 0x21, 0x3c, 0x18, 0x8a, 0x5d, 0x8a, 0xe2, 0x1e, 0xfa, - 0xee, 0x60, 0x9a, 0x28, 0xbc, 0x0e, 0xb8, 0xa8, 0xbf, 0xc9, 0x3f, 0x7f, 0xf7, 0x79, 0x91, 0x7b, - 0xff, 0x79, 0x91, 0xfb, 0xdb, 0xe7, 0x45, 0xee, 0x17, 0x5f, 0x16, 0x47, 0xde, 0x7f, 0x59, 0x1c, - 0xf9, 0xeb, 0x97, 0xc5, 0x91, 0x1f, 0x9e, 0x78, 0x42, 0x6a, 0xfa, 0x13, 0xd2, 0xe3, 0x52, 0x29, - 0x4a, 0xff, 0x41, 0xb1, 0xf1, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x77, 0x64, 0x69, 0xce, 0x0e, - 0x1a, 0x00, 0x00, + // 1793 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x5f, 0x6f, 0xdb, 0x5e, + 0x19, 0xae, 0xdb, 0x34, 0xbf, 0xf6, 0x4d, 0x93, 0x76, 0x67, 0xdd, 0x9a, 0xa5, 0x6b, 0xd3, 0x85, + 0xad, 0x4b, 0xbb, 0xcd, 0x5e, 0xd3, 0xae, 0x17, 0x1b, 0x6c, 0x6b, 0xda, 0x6d, 0xdd, 0x9f, 0x6a, + 0xc1, 0xdd, 0x84, 0x04, 0x88, 0xc8, 0x71, 0x4e, 0x1c, 0xab, 0x89, 0xed, 0xd9, 0x27, 0x25, 0xd1, + 0xd4, 0x1b, 0x2e, 0xb8, 0x43, 0x42, 0x82, 0x2b, 0xbe, 0x00, 0x48, 0x5c, 0x32, 0x6e, 0xf8, 0x04, + 0xe3, 0x6e, 0x1a, 0x17, 0xa0, 0x5d, 0x4c, 0x68, 0x43, 0x20, 0x21, 0x21, 0xc4, 0x0d, 0xd7, 0xc8, + 0xc7, 0xc7, 0xb1, 0x93, 0xd8, 0x69, 0xd2, 0x96, 0xbb, 0xc6, 0xe7, 0xfd, 0xf7, 0xbc, 0xef, 0x73, + 0x1e, 0x9f, 0xe3, 0xc2, 0x95, 0x92, 0x54, 0x6a, 0xd5, 0x74, 0x4d, 0x28, 0x11, 0xd9, 0x22, 0xd2, + 0x81, 0xaa, 0x29, 0xc2, 0xe1, 0x9a, 0xf0, 0xa6, 0x81, 0xcd, 0x16, 0x6f, 0x98, 0x3a, 0xd1, 0xd1, + 0x05, 0x66, 0xc2, 0x7b, 0x26, 0xfc, 0xe1, 0x5a, 0x6a, 0x56, 0xd1, 0x15, 0x9d, 0x5a, 0x08, 0xf6, + 0x5f, 0x8e, 0x71, 0xea, 0xb2, 0xa2, 0xeb, 0x4a, 0x0d, 0x0b, 0x92, 0xa1, 0x0a, 0x92, 0xa6, 0xe9, + 0x44, 0x22, 0xaa, 0xae, 0x59, 0x6c, 0xf5, 0x92, 0xac, 0x5b, 0x75, 0xdd, 0x2a, 0x3a, 0x6e, 0xce, + 0x0f, 0xb6, 0x94, 0x71, 0x7e, 0x09, 0xb2, 0xd9, 0x32, 0x88, 0x2e, 0x58, 0x58, 0x36, 0x72, 0x77, + 0x36, 0x0f, 0xd6, 0x84, 0x03, 0xdc, 0x72, 0x6d, 0xae, 0x32, 0x1b, 0xaf, 0xd0, 0x12, 0x26, 0xd2, + 0x9a, 0xfb, 0x9b, 0x59, 0xad, 0x32, 0xab, 0x92, 0x64, 0x61, 0x07, 0x48, 0xdb, 0xd0, 0x90, 0x14, + 0x55, 0xa3, 0x15, 0xb9, 0x59, 0x83, 0xe1, 0x1b, 0x92, 0x29, 0xd5, 0xdd, 0xac, 0xcb, 0xc1, 0x36, + 0xbe, 0x6e, 0x38, 0x76, 0xe9, 0x90, 0x58, 0xba, 0xe1, 0x18, 0x64, 0x66, 0x01, 0x7d, 0xd7, 0x2e, + 0xa7, 0x40, 0xa3, 0x8b, 0xf8, 0x4d, 0x03, 0x5b, 0x24, 0x23, 0xc2, 0xf9, 0x8e, 0xa7, 0x96, 0xa1, + 0x6b, 0x16, 0x46, 0xf7, 0x20, 0xea, 0x54, 0x91, 0xe4, 0x96, 0xb8, 0x6c, 0x2c, 0xb7, 0xc0, 0x07, + 0x8e, 0x81, 0x77, 0xdc, 0xf2, 0x91, 0xf7, 0x9f, 0xd3, 0x23, 0x22, 0x73, 0xc9, 0x28, 0xb0, 0x40, + 0x63, 0x3e, 0x56, 0x35, 0xa9, 0xa6, 0x92, 0x56, 0xc1, 0xd4, 0x0f, 0xd5, 0x32, 0x36, 0xdd, 0xa4, + 0xe8, 0x31, 0x80, 0xd7, 0x0b, 0x96, 0x61, 0x99, 0x67, 0x03, 0xb1, 0x1b, 0xc7, 0x3b, 0x0c, 0x60, + 0x8d, 0xe3, 0x0b, 0x92, 0x82, 0x99, 0xaf, 0xe8, 0xf3, 0xcc, 0xfc, 0x91, 0x83, 0xc5, 0xb0, 0x4c, + 0x0c, 0xc8, 0x8f, 0x00, 0x55, 0xd8, 0xa2, 0x3d, 0x77, 0x67, 0x35, 0xc9, 0x2d, 0x8d, 0x65, 0x63, + 0x39, 0x21, 0x04, 0x54, 0x77, 0x34, 0x37, 0x98, 0x78, 0xae, 0xd2, 0x9d, 0x07, 0x3d, 0xe9, 0x80, + 0x32, 0x4a, 0xa1, 0x5c, 0x3f, 0x16, 0x0a, 0x8b, 0xe7, 0xc7, 0xb2, 0x05, 0x97, 0x03, 0xa1, 0xb8, + 0x3d, 0xbb, 0x02, 0xf1, 0x8a, 0x51, 0x2c, 0x11, 0xb9, 0x68, 0x1c, 0x14, 0xab, 0xb8, 0x49, 0xdb, + 0x36, 0x29, 0x42, 0xc5, 0xc8, 0x13, 0xb9, 0x70, 0xb0, 0x8b, 0x9b, 0x99, 0xa3, 0x90, 0xbe, 0xb7, + 0x9b, 0xf1, 0x43, 0x38, 0xd7, 0xd3, 0x0c, 0xd6, 0xfe, 0xa1, 0x7b, 0x31, 0xd3, 0xdd, 0x8b, 0xcc, + 0x6f, 0x38, 0x48, 0xd1, 0xfc, 0xf9, 0x57, 0xdb, 0x3b, 0xb8, 0x86, 0x15, 0x67, 0xf3, 0xb9, 0x00, + 0xf2, 0x10, 0xb5, 0x88, 0x44, 0x1a, 0x0e, 0xa5, 0x12, 0xb9, 0xd5, 0x90, 0x8c, 0x1d, 0xde, 0xfb, + 0xd4, 0x43, 0x64, 0x9e, 0x5d, 0xc4, 0x19, 0x3d, 0x31, 0x71, 0x7e, 0xcf, 0xc1, 0x7c, 0x60, 0xa9, + 0xac, 0x51, 0x7b, 0x30, 0x6d, 0x77, 0xba, 0xec, 0x2d, 0x31, 0xca, 0x5c, 0x1d, 0xa4, 0x68, 0x31, + 0x51, 0x22, 0xb2, 0x2f, 0xec, 0xd9, 0x91, 0xa4, 0x02, 0x2b, 0x81, 0x13, 0x2e, 0xe8, 0x3f, 0xc6, + 0xe6, 0x16, 0xd9, 0xc5, 0xaa, 0x52, 0x25, 0x83, 0x33, 0x06, 0x5d, 0x84, 0x68, 0x95, 0xfa, 0xd0, + 0xa2, 0x22, 0x22, 0xfb, 0x95, 0x79, 0x09, 0xab, 0x83, 0xe4, 0x61, 0xdd, 0xba, 0x02, 0x53, 0x87, + 0x3a, 0x51, 0x35, 0xa5, 0x68, 0xd8, 0xeb, 0x34, 0x4f, 0x44, 0x8c, 0x39, 0xcf, 0xa8, 0x4b, 0x66, + 0x0f, 0xb2, 0x81, 0x01, 0xb7, 0x1b, 0xa6, 0x89, 0x35, 0x42, 0x8d, 0x86, 0x60, 0x7a, 0x58, 0x1f, + 0x3a, 0xc3, 0xb1, 0xf2, 0x3c, 0x90, 0x9c, 0x1f, 0x64, 0x4f, 0xd9, 0xa3, 0xbd, 0x65, 0xff, 0x8c, + 0x83, 0x1b, 0x34, 0xd1, 0x96, 0x4c, 0xd4, 0x43, 0xdc, 0x23, 0x33, 0xdd, 0x2d, 0x0f, 0x4b, 0x75, + 0x56, 0xbc, 0xfd, 0x33, 0x07, 0x37, 0x07, 0xab, 0xe7, 0x0c, 0xe5, 0xef, 0x7b, 0x2a, 0xa9, 0xee, + 0x61, 0x22, 0xfd, 0x5f, 0xe5, 0x6f, 0x81, 0x6d, 0x48, 0x0a, 0x4c, 0x22, 0xb8, 0xdc, 0xd1, 0xd8, + 0xcc, 0x26, 0x53, 0xc7, 0x9e, 0xe5, 0xfe, 0x33, 0xce, 0xfc, 0x92, 0x83, 0xeb, 0x81, 0x4c, 0x09, + 0x10, 0xa8, 0x01, 0xf6, 0xcb, 0x59, 0xcd, 0xf1, 0x1f, 0x5c, 0xc8, 0x7e, 0x08, 0x12, 0x23, 0x13, + 0x2e, 0xf9, 0xc4, 0x48, 0x37, 0x03, 0x64, 0x69, 0xf3, 0x58, 0x59, 0xd2, 0x83, 0x42, 0x8b, 0x73, + 0x9e, 0x50, 0x75, 0x18, 0x9c, 0xdd, 0x5c, 0x9f, 0xc1, 0xa5, 0x5e, 0xa1, 0x75, 0x3b, 0x7e, 0x0b, + 0xce, 0xb3, 0x62, 0x8b, 0xa4, 0x59, 0xac, 0x4a, 0x56, 0xd5, 0xd7, 0xf7, 0x19, 0xb6, 0xf4, 0xaa, + 0xb9, 0x2b, 0x59, 0x55, 0x7b, 0xd7, 0xbf, 0x09, 0x7a, 0xbf, 0xb4, 0xdb, 0xb4, 0x0f, 0x89, 0x4e, + 0xcd, 0x66, 0x6f, 0xb6, 0x9b, 0x03, 0x49, 0xb6, 0x5b, 0x7b, 0xbc, 0x43, 0xba, 0x33, 0xff, 0x19, + 0x87, 0x0b, 0xc1, 0xe9, 0xf6, 0x20, 0xea, 0x50, 0x85, 0xa6, 0x99, 0xca, 0x6f, 0x7e, 0xfa, 0x9c, + 0xce, 0x29, 0x2a, 0xa9, 0x36, 0x4a, 0xbc, 0xac, 0xd7, 0x05, 0x96, 0x54, 0xae, 0x4a, 0xaa, 0xe6, + 0xfe, 0x10, 0x48, 0xcb, 0xc0, 0x16, 0x9f, 0x7f, 0x5a, 0x58, 0xdf, 0xb8, 0x5d, 0x68, 0x94, 0x9e, + 0xe3, 0x96, 0x38, 0x5e, 0xb2, 0xc9, 0x85, 0x7e, 0x00, 0x09, 0x8f, 0x7c, 0x35, 0xd5, 0xb2, 0x15, + 0x79, 0xec, 0x14, 0x61, 0x63, 0x8c, 0xb5, 0x2f, 0x54, 0xca, 0xec, 0x29, 0x8b, 0x48, 0x26, 0x29, + 0xb2, 0x3d, 0x32, 0xe6, 0x28, 0x1d, 0x7d, 0xe6, 0x6c, 0x24, 0xb4, 0x00, 0x80, 0xb5, 0xb2, 0x6b, + 0x10, 0xa1, 0x06, 0x93, 0x58, 0x63, 0xfb, 0x0c, 0xcd, 0xc3, 0x24, 0xd1, 0x89, 0x54, 0x2b, 0x5a, + 0x12, 0x49, 0x8e, 0xd3, 0xd5, 0x09, 0xfa, 0x60, 0x5f, 0x22, 0xe8, 0x2a, 0x24, 0xfc, 0x63, 0xc4, + 0xcd, 0x64, 0x94, 0x4e, 0x70, 0xca, 0x9b, 0x20, 0x6e, 0xa2, 0x65, 0x98, 0xb6, 0x6a, 0x92, 0x55, + 0xf5, 0x99, 0x7d, 0x43, 0xcd, 0xe2, 0xee, 0x63, 0xc7, 0xee, 0x0e, 0xcc, 0x79, 0x54, 0xa7, 0x4b, + 0x45, 0x4b, 0x55, 0xa8, 0xfd, 0x04, 0xb5, 0x9f, 0x6d, 0x2f, 0xef, 0xdb, 0xab, 0xfb, 0xaa, 0x62, + 0xbb, 0xbd, 0x86, 0xb8, 0xac, 0x1f, 0x62, 0x4d, 0xd2, 0x88, 0x6d, 0x6f, 0x25, 0x27, 0xe9, 0xce, + 0xb8, 0x1d, 0x32, 0xfd, 0x6d, 0x66, 0xbb, 0x55, 0x96, 0x0c, 0x3b, 0x92, 0xaa, 0x68, 0x12, 0x69, + 0x98, 0xd8, 0x12, 0xa7, 0xdc, 0x30, 0xfb, 0xaa, 0x62, 0xa1, 0x9b, 0x80, 0x5c, 0x6c, 0x7a, 0x83, + 0x18, 0x0d, 0x52, 0x54, 0xcb, 0xcd, 0x24, 0x2c, 0x71, 0xd9, 0x78, 0x9b, 0xa1, 0x2f, 0xe9, 0xc2, + 0xd3, 0x32, 0x7d, 0x9f, 0x4a, 0x54, 0x99, 0x93, 0xb1, 0x25, 0x2e, 0x3b, 0x21, 0xb2, 0x5f, 0x28, + 0x0d, 0x31, 0xe7, 0x04, 0x53, 0x2c, 0x63, 0x4b, 0x4e, 0x4e, 0x39, 0xc2, 0xe2, 0x3c, 0xda, 0xc1, + 0x96, 0x8c, 0xae, 0x41, 0xa2, 0xa1, 0x95, 0x74, 0xad, 0x4c, 0xbb, 0xa3, 0xd6, 0x71, 0x32, 0x4e, + 0x53, 0xc4, 0xdb, 0x4f, 0x5f, 0xa9, 0x75, 0x8c, 0x64, 0xb8, 0xd0, 0xd0, 0x3c, 0x86, 0x17, 0x4d, + 0xc6, 0xc6, 0x64, 0x82, 0x52, 0x9d, 0x0f, 0xa7, 0xfa, 0x6b, 0x9f, 0x5b, 0x9b, 0xec, 0xb3, 0x8d, + 0x80, 0xa7, 0x99, 0x77, 0x63, 0x30, 0x17, 0xe2, 0x81, 0xb2, 0x30, 0xe3, 0xab, 0xb3, 0xe9, 0xdb, + 0xae, 0x5e, 0xfd, 0xce, 0x18, 0xbf, 0x03, 0xf3, 0xde, 0x18, 0x3d, 0x1f, 0x77, 0x94, 0xa3, 0xd4, + 0x29, 0xd9, 0x36, 0x79, 0xed, 0x5a, 0xb0, 0x71, 0xca, 0x30, 0xdf, 0x1e, 0x67, 0xa7, 0x37, 0xdd, + 0x1c, 0x63, 0x7d, 0x4f, 0x63, 0xed, 0x69, 0x3e, 0xd5, 0x2a, 0xba, 0x98, 0x74, 0x03, 0xf9, 0x73, + 0xd0, 0x7d, 0x11, 0x40, 0xc9, 0x48, 0x10, 0x25, 0xef, 0x41, 0xaa, 0x8b, 0x92, 0x7e, 0x28, 0xe3, + 0xd4, 0x65, 0xae, 0x93, 0x95, 0x1e, 0x92, 0x0a, 0x5c, 0xf4, 0x88, 0xe9, 0xf3, 0xb5, 0x92, 0xd1, + 0x13, 0x32, 0x74, 0xb6, 0xcd, 0x50, 0x2f, 0x93, 0x95, 0x91, 0x21, 0x7d, 0x8c, 0xdc, 0xa3, 0x87, + 0x10, 0x29, 0xe3, 0x9a, 0xfb, 0xd2, 0x18, 0x4e, 0x18, 0xa9, 0x67, 0xe6, 0x57, 0x11, 0x48, 0x86, + 0x5e, 0x2f, 0x1e, 0x41, 0xcc, 0xa6, 0xb7, 0xa9, 0x1a, 0x3e, 0xf9, 0xfd, 0x96, 0xfb, 0xd6, 0xf0, + 0x32, 0x38, 0xaf, 0x8c, 0x1d, 0xcf, 0x54, 0xf4, 0xfb, 0xa1, 0x3d, 0x00, 0x59, 0xaf, 0xd7, 0x55, + 0xcb, 0x72, 0xdf, 0x3d, 0x93, 0xf9, 0x5b, 0x9f, 0x3e, 0xa7, 0xe7, 0x9d, 0x40, 0x56, 0xf9, 0x80, + 0x57, 0x75, 0xa1, 0x2e, 0x91, 0x2a, 0xff, 0x02, 0x2b, 0x92, 0xdc, 0xda, 0xc1, 0xf2, 0xc7, 0x77, + 0xb7, 0x80, 0xe5, 0xd9, 0xc1, 0xb2, 0xe8, 0x0b, 0x80, 0xee, 0x03, 0x30, 0x9c, 0xb6, 0x58, 0x8f, + 0xd1, 0xa2, 0xd2, 0x6e, 0x51, 0xce, 0x7d, 0x9f, 0x6f, 0xdf, 0xf7, 0x79, 0x26, 0x9f, 0x93, 0xcc, + 0xa5, 0x70, 0xe0, 0x13, 0xfa, 0xc8, 0x59, 0x08, 0xfd, 0x5d, 0x18, 0x33, 0x74, 0x83, 0x92, 0x26, + 0x96, 0xcb, 0x86, 0x5d, 0xab, 0x4d, 0x5d, 0xaf, 0xbc, 0xac, 0x14, 0x74, 0xcb, 0xc2, 0x14, 0x85, + 0x68, 0x3b, 0xa1, 0x0d, 0xb8, 0x48, 0x19, 0x84, 0xcb, 0x45, 0x17, 0x12, 0x13, 0xec, 0x28, 0x95, + 0xe4, 0x59, 0xb6, 0x9a, 0x77, 0x16, 0x99, 0x76, 0xdb, 0x12, 0xe6, 0x7a, 0x11, 0xd9, 0xf5, 0xf8, + 0x86, 0x7a, 0xcc, 0xb8, 0x1e, 0x44, 0x66, 0xd6, 0xde, 0x49, 0x6a, 0xa2, 0xef, 0x69, 0x79, 0xb2, + 0xe7, 0xb4, 0x9c, 0xfb, 0xf7, 0x34, 0x8c, 0xd3, 0x17, 0x34, 0xfa, 0x29, 0x07, 0x51, 0xe7, 0xd3, + 0x00, 0x5a, 0x09, 0x81, 0xd8, 0xfb, 0x2d, 0x22, 0xb5, 0x3a, 0x88, 0x29, 0x13, 0xa9, 0x6b, 0x3f, + 0xf9, 0xd3, 0xdf, 0x7e, 0x31, 0x9a, 0x46, 0x0b, 0x42, 0xbf, 0x6f, 0x28, 0xe8, 0x77, 0x1c, 0x9c, + 0xeb, 0x39, 0x25, 0xa3, 0x8d, 0x7e, 0x89, 0xc2, 0xbe, 0x5a, 0xa4, 0xee, 0x0c, 0xe9, 0xc5, 0x2a, + 0x5d, 0xa3, 0x95, 0xde, 0x40, 0x2b, 0x21, 0x95, 0xf6, 0x9e, 0xcf, 0xd1, 0x47, 0x0e, 0x66, 0xba, + 0x03, 0xa2, 0xf5, 0x61, 0xd2, 0xbb, 0x35, 0x6f, 0x0c, 0xe7, 0xc4, 0x4a, 0xde, 0xa7, 0x25, 0xef, + 0xa1, 0xe7, 0x03, 0x97, 0x2c, 0xbc, 0xed, 0x38, 0x3a, 0x1f, 0xf5, 0x9a, 0xa0, 0x5f, 0x73, 0x90, + 0xe8, 0xbc, 0x6e, 0xa3, 0xb5, 0x7e, 0xd5, 0x05, 0x7e, 0x45, 0x48, 0xe5, 0x86, 0x71, 0x61, 0x70, + 0x78, 0x0a, 0x27, 0x8b, 0x96, 0x85, 0xd0, 0x6f, 0x69, 0xfe, 0x33, 0x35, 0xfa, 0x3b, 0x07, 0xe9, + 0x63, 0x2e, 0x58, 0x28, 0xdf, 0xaf, 0x8e, 0xc1, 0x6e, 0x8b, 0xa9, 0xed, 0x53, 0xc5, 0x60, 0xe0, + 0xee, 0x52, 0x70, 0x1b, 0x28, 0x37, 0xc4, 0xac, 0x9c, 0x2d, 0x7d, 0x84, 0xfe, 0xcb, 0xc1, 0x42, + 0xdf, 0x2b, 0x3e, 0x7a, 0x38, 0x0c, 0x7f, 0x82, 0xbe, 0x42, 0xa4, 0xb6, 0x4e, 0x11, 0x81, 0x41, + 0x2c, 0x50, 0x88, 0xcf, 0xd0, 0xee, 0xc9, 0xe9, 0x48, 0x35, 0xcb, 0x03, 0xfe, 0x4f, 0x0e, 0x2e, + 0xf7, 0xfb, 0x76, 0x80, 0x1e, 0x0c, 0x53, 0x75, 0xc0, 0x47, 0x8c, 0xd4, 0xc3, 0x93, 0x07, 0x60, + 0xa8, 0x9f, 0x50, 0xd4, 0x5b, 0xe8, 0xc1, 0x29, 0x51, 0xa3, 0xdf, 0x72, 0x30, 0xdd, 0x75, 0x6f, + 0x46, 0xb9, 0x63, 0xa9, 0xd7, 0x73, 0x07, 0x4f, 0xad, 0x0f, 0xe5, 0xc3, 0x50, 0x08, 0x14, 0xc5, + 0x0a, 0xba, 0x1e, 0x82, 0x42, 0x72, 0xfd, 0xd8, 0x7b, 0x09, 0xfd, 0x8b, 0x83, 0xf9, 0x3e, 0xb7, + 0x62, 0x74, 0x7f, 0x98, 0xc6, 0x06, 0x08, 0xc8, 0x83, 0x13, 0xfb, 0x33, 0x44, 0x7b, 0x14, 0xd1, + 0x13, 0xf4, 0xe8, 0xe4, 0x73, 0xf1, 0x8b, 0xcd, 0x1f, 0x38, 0x88, 0x77, 0xe8, 0x16, 0xba, 0x3d, + 0xb0, 0xc4, 0xb9, 0x98, 0xd6, 0x86, 0xf0, 0x60, 0x28, 0x76, 0x28, 0x8a, 0xfb, 0xe8, 0xdb, 0x83, + 0x69, 0xa2, 0xf0, 0x36, 0xe0, 0xa2, 0x7e, 0x94, 0x7f, 0xf1, 0xfe, 0xcb, 0x22, 0xf7, 0xe1, 0xcb, + 0x22, 0xf7, 0xd7, 0x2f, 0x8b, 0xdc, 0xcf, 0xbf, 0x2e, 0x8e, 0x7c, 0xf8, 0xba, 0x38, 0xf2, 0x97, + 0xaf, 0x8b, 0x23, 0xdf, 0x3f, 0xf6, 0x84, 0xd4, 0xf4, 0x27, 0xa4, 0xc7, 0xa5, 0x52, 0x94, 0xfe, + 0xa3, 0x62, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb0, 0xc6, 0x38, 0x28, 0x16, 0x1a, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4064,7 +4064,7 @@ func (m *QueryFinalityProviderResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.FinalityProvider == nil { - m.FinalityProvider = &FinalityProvider{} + m.FinalityProvider = &FinalityProviderResponse{} } if err := m.FinalityProvider.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err From 50a8d00535f5e1b645941d99f1b511a5c71725c9 Mon Sep 17 00:00:00 2001 From: pennyyes <161677556+pennyyes@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:38:01 +0800 Subject: [PATCH 025/119] fixes some mistakes (#515) --- app/test_helpers.go | 4 ++-- btcstaking/types.go | 4 ++-- proto/babylon/zoneconcierge/v1/zoneconcierge.proto | 2 +- x/btccheckpoint/keeper/submissions.go | 12 ++++++------ x/btccheckpoint/types/types.go | 4 ++-- x/zoneconcierge/types/zoneconcierge.pb.go | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/test_helpers.go b/app/test_helpers.go index 3a31fa6a4..5319b8129 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -81,7 +81,7 @@ func setup(t *testing.T, ps *PrivSigner, withGenesis bool, invCheckPeriod uint) } // NewBabylonAppWithCustomOptions initializes a new BabylonApp with custom options. -// Created Babylon application will have one validator with hardcoed amout of tokens. +// Created Babylon application will have one validator with hardcoed amount of tokens. // This is necessary as from cosmos-sdk 0.46 it is required that there is at least // one validator in validator set during InitGenesis abci call - https://github.com/cosmos/cosmos-sdk/pull/9697 func NewBabylonAppWithCustomOptions(t *testing.T, isCheckTx bool, privSigner *PrivSigner, options SetupOptions) *BabylonApp { @@ -222,7 +222,7 @@ func genesisStateWithValSet(t *testing.T, } // Setup initializes a new BabylonApp. A Nop logger is set in BabylonApp. -// Created Babylon application will have one validator with hardoced amout of tokens. +// Created Babylon application will have one validator with hardoced amount of tokens. // This is necessary as from cosmos-sdk 0.46 it is required that there is at least // one validator in validator set during InitGenesis abci call - https://github.com/cosmos/cosmos-sdk/pull/9697 func Setup(t *testing.T, isCheckTx bool) *BabylonApp { diff --git a/btcstaking/types.go b/btcstaking/types.go index 9ef508069..3de6a2bf3 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -16,7 +16,7 @@ import ( const ( // Point with unknown discrete logarithm defined in: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs - // using it as internal public key efectively disables taproot key spends + // using it as internal public key effectively disables taproot key spends unspendableKeyPath = "0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0" ) @@ -498,7 +498,7 @@ type RelativeTimeLockTapScriptInfo struct { LockTime uint16 // taproot address of the script TapAddress btcutil.Address - // pkscript in output wchich commits to the given script/leaf + // pkscript in output which commits to the given script/leaf PkScript []byte } diff --git a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto index 7d37d7b30..992662484 100644 --- a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto +++ b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto @@ -99,7 +99,7 @@ message FinalizedChainInfo { // - The raw checkpoint's `app_hash` is same as in the sealer header // - More than 2/3 (in voting power) validators in the validator set of this // epoch have signed `app_hash` of the sealer header -// - The epoch medatata is committed to the `app_hash` of the sealer header +// - The epoch metadata is committed to the `app_hash` of the sealer header // - The validator set is committed to the `app_hash` of the sealer header message ProofEpochSealed { // validator_set is the validator set of the sealed epoch diff --git a/x/btccheckpoint/keeper/submissions.go b/x/btccheckpoint/keeper/submissions.go index 9bf5d400c..bcdb3e8c9 100644 --- a/x/btccheckpoint/keeper/submissions.go +++ b/x/btccheckpoint/keeper/submissions.go @@ -53,7 +53,7 @@ func (k Keeper) addEpochSubmission( ed := k.GetEpochData(ctx, epochNum) // TODO: SaveEpochData and SaveSubmission should be done in one transaction. - // Not sure cosmos-sdk has facialities to do it. + // Not sure cosmos-sdk has facilities to do it. // Otherwise it is possible to end up with node which updated submission list // but did not save submission itself. @@ -65,8 +65,8 @@ func (k Keeper) addEpochSubmission( } if ed.Status == types.Finalized { - // we already finlized given epoch so we do not need any more submissions - // TODO We should probably compare new submmission with the exisiting submission + // we already finalized given epoch so we do not need any more submissions + // TODO We should probably compare new submission with the existing submission // which finalized the epoch. As it means we finalized epoch with not the best // submission possible return types.ErrEpochAlreadyFinalized @@ -159,8 +159,8 @@ func (k Keeper) GetSubmissionBtcInfo(ctx context.Context, sk types.SubmissionKey // Currently if two submissions of one checkpoint are in the same block, // we pick tx with lower index as the point at which checkpoint happened. // This is in line with the logic that if two submission are in the same block, - // they are esentially happening at the same time, so it does not really matter - // which index pick, and for possibble tie breaks it is better to pick lower one. + // they are essentially happening at the same time, so it does not really matter + // which index pick, and for possible tie breaks it is better to pick lower one. // This means in case when we have: // Checkpoint submission `x` for epoch 5, both tx in same block at height 100, with indexes 1 and 10 // and @@ -190,7 +190,7 @@ func (k Keeper) GetSubmissionBtcInfo(ctx context.Context, sk types.SubmissionKey } func (k Keeper) GetEpochBestSubmissionBtcInfo(ctx context.Context, ed *types.EpochData) *types.SubmissionBtcInfo { - // there are no submissions for this epoch, so transitivly there is no best submission + // there are no submissions for this epoch, so transitively there is no best submission if ed == nil || len(ed.Keys) == 0 { return nil } diff --git a/x/btccheckpoint/types/types.go b/x/btccheckpoint/types/types.go index e825908de..fa7423a56 100644 --- a/x/btccheckpoint/types/types.go +++ b/x/btccheckpoint/types/types.go @@ -23,7 +23,7 @@ type RawCheckpointSubmission struct { CheckpointData btctxformatter.RawBtcCheckpoint } -// SubmissionBtcInfo encapsualte important information about submission posistion +// SubmissionBtcInfo encapsulate important information about submission position // on btc ledger type SubmissionBtcInfo struct { SubmissionKey SubmissionKey @@ -133,7 +133,7 @@ func (submission *SubmissionBtcInfo) HappenedAfter(parentEpochSubmission *Submis } // SubmissionDepth return depth of the submission. Due to the fact that submissions -// are splitted between several btc blocks, in Babylon subbmission depth is the depth +// are split between several btc blocks, in Babylon submission depth is the depth // of the youngest btc block func (submission *SubmissionBtcInfo) SubmissionDepth() uint64 { return submission.YoungestBlockDepth diff --git a/x/zoneconcierge/types/zoneconcierge.pb.go b/x/zoneconcierge/types/zoneconcierge.pb.go index a6b9473e3..00489cc79 100644 --- a/x/zoneconcierge/types/zoneconcierge.pb.go +++ b/x/zoneconcierge/types/zoneconcierge.pb.go @@ -384,7 +384,7 @@ func (m *FinalizedChainInfo) GetProof() *ProofFinalizedChainInfo { // - The raw checkpoint's `app_hash` is same as in the sealer header // - More than 2/3 (in voting power) validators in the validator set of this // epoch have signed `app_hash` of the sealer header -// - The epoch medatata is committed to the `app_hash` of the sealer header +// - The epoch metadata is committed to the `app_hash` of the sealer header // - The validator set is committed to the `app_hash` of the sealer header type ProofEpochSealed struct { // validator_set is the validator set of the sealed epoch From 107ab1b457f7b4caef846239990fc93a23efe96a Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Fri, 1 Mar 2024 08:49:14 -0300 Subject: [PATCH 026/119] chore: update query BTCDelegations to return BTCDelegationResponse (#518) * chore: update query BTCDelegations to return BTCDelegationResponse * chore: removed unnecessary line --- proto/babylon/btcstaking/v1/query.proto | 2 +- test/e2e/btc_staking_e2e_test.go | 12 +- .../configurer/chain/queries_btcstaking.go | 2 +- x/btcstaking/keeper/grpc_query.go | 8 +- x/btcstaking/types/query.pb.go | 233 +++++++++--------- 5 files changed, 130 insertions(+), 127 deletions(-) diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 61e67226f..492de61d4 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -120,7 +120,7 @@ message QueryBTCDelegationsRequest { // Query/BTCDelegations RPC method. message QueryBTCDelegationsResponse { // btc_delegations contains all the queried BTC delegations under the given status - repeated BTCDelegation btc_delegations = 1; + repeated BTCDelegationResponse btc_delegations = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 05ef85f20..e72f88682 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -510,13 +510,15 @@ func (s *BTCStakingTestSuite) Test5SubmitStakerUnbonding() { nonValidatorNode.WaitForNextBlock() // Wait for unbonded delegations to be created - var unbondedDels []*bstypes.BTCDelegation + var unbondedDelsResp []*bstypes.BTCDelegationResponse s.Eventually(func() bool { - unbondedDels = nonValidatorNode.QueryUnbondedDelegations() - return len(unbondedDels) > 0 + unbondedDelsResp = nonValidatorNode.QueryUnbondedDelegations() + return len(unbondedDelsResp) > 0 }, time.Minute, time.Second*2) - s.Len(unbondedDels, 1) - s.Equal(stakingTxHash, unbondedDels[0].MustGetStakingTxHash()) + + unbondDel, err := ParseRespBTCDelToBTCDel(unbondedDelsResp[0]) + s.NoError(err) + s.Equal(stakingTxHash, unbondDel.MustGetStakingTxHash()) } // ParseRespsBTCDelToBTCDel parses an BTC delegation response to BTC Delegation diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index 66642b1ff..a4153050d 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -69,7 +69,7 @@ func (n *NodeConfig) QueryBtcDelegation(stakingTxHash string) *bstypes.QueryBTCD return &resp } -func (n *NodeConfig) QueryUnbondedDelegations() []*bstypes.BTCDelegation { +func (n *NodeConfig) QueryUnbondedDelegations() []*bstypes.BTCDelegationResponse { queryParams := url.Values{} queryParams.Add("status", fmt.Sprintf("%d", bstypes.BTCDelegationStatus_UNBONDED)) bz, err := n.QueryGRPCGateway("/babylon/btcstaking/v1/btc_delegations", queryParams) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index f94d233e8..f52d17532 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -92,15 +92,17 @@ func (k Keeper) BTCDelegations(ctx context.Context, req *types.QueryBTCDelegatio wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout store := k.btcDelegationStore(ctx) - var btcDels []*types.BTCDelegation + var btcDels []*types.BTCDelegationResponse pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { var btcDel types.BTCDelegation k.cdc.MustUnmarshal(value, &btcDel) // hit if the queried status is ANY or matches the BTC delegation status - if req.Status == types.BTCDelegationStatus_ANY || btcDel.GetStatus(btcTipHeight, wValue, covenantQuorum) == req.Status { + status := btcDel.GetStatus(btcTipHeight, wValue, covenantQuorum) + if req.Status == types.BTCDelegationStatus_ANY || status == req.Status { if accumulate { - btcDels = append(btcDels, &btcDel) + resp := types.NewBTCDelegationResponse(&btcDel, status) + btcDels = append(btcDels, resp) } return true, nil } diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 1c1e9dc10..8fcbb4924 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -373,7 +373,7 @@ func (m *QueryBTCDelegationsRequest) GetPagination() *query.PageRequest { // Query/BTCDelegations RPC method. type QueryBTCDelegationsResponse struct { // btc_delegations contains all the queried BTC delegations under the given status - BtcDelegations []*BTCDelegation `protobuf:"bytes,1,rep,name=btc_delegations,json=btcDelegations,proto3" json:"btc_delegations,omitempty"` + BtcDelegations []*BTCDelegationResponse `protobuf:"bytes,1,rep,name=btc_delegations,json=btcDelegations,proto3" json:"btc_delegations,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -411,7 +411,7 @@ func (m *QueryBTCDelegationsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryBTCDelegationsResponse proto.InternalMessageInfo -func (m *QueryBTCDelegationsResponse) GetBtcDelegations() []*BTCDelegation { +func (m *QueryBTCDelegationsResponse) GetBtcDelegations() []*BTCDelegationResponse { if m != nil { return m.BtcDelegations } @@ -1509,120 +1509,119 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1793 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x5f, 0x6f, 0xdb, 0x5e, - 0x19, 0xae, 0xdb, 0x34, 0xbf, 0xf6, 0x4d, 0x93, 0x76, 0x67, 0xdd, 0x9a, 0xa5, 0x6b, 0xd3, 0x85, - 0xad, 0x4b, 0xbb, 0xcd, 0x5e, 0xd3, 0xae, 0x17, 0x1b, 0x6c, 0x6b, 0xda, 0x6d, 0xdd, 0x9f, 0x6a, - 0xc1, 0xdd, 0x84, 0x04, 0x88, 0xc8, 0x71, 0x4e, 0x1c, 0xab, 0x89, 0xed, 0xd9, 0x27, 0x25, 0xd1, - 0xd4, 0x1b, 0x2e, 0xb8, 0x43, 0x42, 0x82, 0x2b, 0xbe, 0x00, 0x48, 0x5c, 0x32, 0x6e, 0xf8, 0x04, - 0xe3, 0x6e, 0x1a, 0x17, 0xa0, 0x5d, 0x4c, 0x68, 0x43, 0x20, 0x21, 0x21, 0xc4, 0x0d, 0xd7, 0xc8, - 0xc7, 0xc7, 0xb1, 0x93, 0xd8, 0x69, 0xd2, 0x96, 0xbb, 0xc6, 0xe7, 0xfd, 0xf7, 0xbc, 0xef, 0x73, - 0x1e, 0x9f, 0xe3, 0xc2, 0x95, 0x92, 0x54, 0x6a, 0xd5, 0x74, 0x4d, 0x28, 0x11, 0xd9, 0x22, 0xd2, - 0x81, 0xaa, 0x29, 0xc2, 0xe1, 0x9a, 0xf0, 0xa6, 0x81, 0xcd, 0x16, 0x6f, 0x98, 0x3a, 0xd1, 0xd1, - 0x05, 0x66, 0xc2, 0x7b, 0x26, 0xfc, 0xe1, 0x5a, 0x6a, 0x56, 0xd1, 0x15, 0x9d, 0x5a, 0x08, 0xf6, - 0x5f, 0x8e, 0x71, 0xea, 0xb2, 0xa2, 0xeb, 0x4a, 0x0d, 0x0b, 0x92, 0xa1, 0x0a, 0x92, 0xa6, 0xe9, - 0x44, 0x22, 0xaa, 0xae, 0x59, 0x6c, 0xf5, 0x92, 0xac, 0x5b, 0x75, 0xdd, 0x2a, 0x3a, 0x6e, 0xce, - 0x0f, 0xb6, 0x94, 0x71, 0x7e, 0x09, 0xb2, 0xd9, 0x32, 0x88, 0x2e, 0x58, 0x58, 0x36, 0x72, 0x77, - 0x36, 0x0f, 0xd6, 0x84, 0x03, 0xdc, 0x72, 0x6d, 0xae, 0x32, 0x1b, 0xaf, 0xd0, 0x12, 0x26, 0xd2, - 0x9a, 0xfb, 0x9b, 0x59, 0xad, 0x32, 0xab, 0x92, 0x64, 0x61, 0x07, 0x48, 0xdb, 0xd0, 0x90, 0x14, - 0x55, 0xa3, 0x15, 0xb9, 0x59, 0x83, 0xe1, 0x1b, 0x92, 0x29, 0xd5, 0xdd, 0xac, 0xcb, 0xc1, 0x36, - 0xbe, 0x6e, 0x38, 0x76, 0xe9, 0x90, 0x58, 0xba, 0xe1, 0x18, 0x64, 0x66, 0x01, 0x7d, 0xd7, 0x2e, - 0xa7, 0x40, 0xa3, 0x8b, 0xf8, 0x4d, 0x03, 0x5b, 0x24, 0x23, 0xc2, 0xf9, 0x8e, 0xa7, 0x96, 0xa1, - 0x6b, 0x16, 0x46, 0xf7, 0x20, 0xea, 0x54, 0x91, 0xe4, 0x96, 0xb8, 0x6c, 0x2c, 0xb7, 0xc0, 0x07, - 0x8e, 0x81, 0x77, 0xdc, 0xf2, 0x91, 0xf7, 0x9f, 0xd3, 0x23, 0x22, 0x73, 0xc9, 0x28, 0xb0, 0x40, - 0x63, 0x3e, 0x56, 0x35, 0xa9, 0xa6, 0x92, 0x56, 0xc1, 0xd4, 0x0f, 0xd5, 0x32, 0x36, 0xdd, 0xa4, - 0xe8, 0x31, 0x80, 0xd7, 0x0b, 0x96, 0x61, 0x99, 0x67, 0x03, 0xb1, 0x1b, 0xc7, 0x3b, 0x0c, 0x60, - 0x8d, 0xe3, 0x0b, 0x92, 0x82, 0x99, 0xaf, 0xe8, 0xf3, 0xcc, 0xfc, 0x91, 0x83, 0xc5, 0xb0, 0x4c, - 0x0c, 0xc8, 0x8f, 0x00, 0x55, 0xd8, 0xa2, 0x3d, 0x77, 0x67, 0x35, 0xc9, 0x2d, 0x8d, 0x65, 0x63, - 0x39, 0x21, 0x04, 0x54, 0x77, 0x34, 0x37, 0x98, 0x78, 0xae, 0xd2, 0x9d, 0x07, 0x3d, 0xe9, 0x80, - 0x32, 0x4a, 0xa1, 0x5c, 0x3f, 0x16, 0x0a, 0x8b, 0xe7, 0xc7, 0xb2, 0x05, 0x97, 0x03, 0xa1, 0xb8, - 0x3d, 0xbb, 0x02, 0xf1, 0x8a, 0x51, 0x2c, 0x11, 0xb9, 0x68, 0x1c, 0x14, 0xab, 0xb8, 0x49, 0xdb, - 0x36, 0x29, 0x42, 0xc5, 0xc8, 0x13, 0xb9, 0x70, 0xb0, 0x8b, 0x9b, 0x99, 0xa3, 0x90, 0xbe, 0xb7, - 0x9b, 0xf1, 0x43, 0x38, 0xd7, 0xd3, 0x0c, 0xd6, 0xfe, 0xa1, 0x7b, 0x31, 0xd3, 0xdd, 0x8b, 0xcc, - 0x6f, 0x38, 0x48, 0xd1, 0xfc, 0xf9, 0x57, 0xdb, 0x3b, 0xb8, 0x86, 0x15, 0x67, 0xf3, 0xb9, 0x00, - 0xf2, 0x10, 0xb5, 0x88, 0x44, 0x1a, 0x0e, 0xa5, 0x12, 0xb9, 0xd5, 0x90, 0x8c, 0x1d, 0xde, 0xfb, - 0xd4, 0x43, 0x64, 0x9e, 0x5d, 0xc4, 0x19, 0x3d, 0x31, 0x71, 0x7e, 0xcf, 0xc1, 0x7c, 0x60, 0xa9, - 0xac, 0x51, 0x7b, 0x30, 0x6d, 0x77, 0xba, 0xec, 0x2d, 0x31, 0xca, 0x5c, 0x1d, 0xa4, 0x68, 0x31, - 0x51, 0x22, 0xb2, 0x2f, 0xec, 0xd9, 0x91, 0xa4, 0x02, 0x2b, 0x81, 0x13, 0x2e, 0xe8, 0x3f, 0xc6, - 0xe6, 0x16, 0xd9, 0xc5, 0xaa, 0x52, 0x25, 0x83, 0x33, 0x06, 0x5d, 0x84, 0x68, 0x95, 0xfa, 0xd0, - 0xa2, 0x22, 0x22, 0xfb, 0x95, 0x79, 0x09, 0xab, 0x83, 0xe4, 0x61, 0xdd, 0xba, 0x02, 0x53, 0x87, - 0x3a, 0x51, 0x35, 0xa5, 0x68, 0xd8, 0xeb, 0x34, 0x4f, 0x44, 0x8c, 0x39, 0xcf, 0xa8, 0x4b, 0x66, - 0x0f, 0xb2, 0x81, 0x01, 0xb7, 0x1b, 0xa6, 0x89, 0x35, 0x42, 0x8d, 0x86, 0x60, 0x7a, 0x58, 0x1f, - 0x3a, 0xc3, 0xb1, 0xf2, 0x3c, 0x90, 0x9c, 0x1f, 0x64, 0x4f, 0xd9, 0xa3, 0xbd, 0x65, 0xff, 0x8c, - 0x83, 0x1b, 0x34, 0xd1, 0x96, 0x4c, 0xd4, 0x43, 0xdc, 0x23, 0x33, 0xdd, 0x2d, 0x0f, 0x4b, 0x75, - 0x56, 0xbc, 0xfd, 0x33, 0x07, 0x37, 0x07, 0xab, 0xe7, 0x0c, 0xe5, 0xef, 0x7b, 0x2a, 0xa9, 0xee, - 0x61, 0x22, 0xfd, 0x5f, 0xe5, 0x6f, 0x81, 0x6d, 0x48, 0x0a, 0x4c, 0x22, 0xb8, 0xdc, 0xd1, 0xd8, - 0xcc, 0x26, 0x53, 0xc7, 0x9e, 0xe5, 0xfe, 0x33, 0xce, 0xfc, 0x92, 0x83, 0xeb, 0x81, 0x4c, 0x09, - 0x10, 0xa8, 0x01, 0xf6, 0xcb, 0x59, 0xcd, 0xf1, 0x1f, 0x5c, 0xc8, 0x7e, 0x08, 0x12, 0x23, 0x13, - 0x2e, 0xf9, 0xc4, 0x48, 0x37, 0x03, 0x64, 0x69, 0xf3, 0x58, 0x59, 0xd2, 0x83, 0x42, 0x8b, 0x73, - 0x9e, 0x50, 0x75, 0x18, 0x9c, 0xdd, 0x5c, 0x9f, 0xc1, 0xa5, 0x5e, 0xa1, 0x75, 0x3b, 0x7e, 0x0b, - 0xce, 0xb3, 0x62, 0x8b, 0xa4, 0x59, 0xac, 0x4a, 0x56, 0xd5, 0xd7, 0xf7, 0x19, 0xb6, 0xf4, 0xaa, - 0xb9, 0x2b, 0x59, 0x55, 0x7b, 0xd7, 0xbf, 0x09, 0x7a, 0xbf, 0xb4, 0xdb, 0xb4, 0x0f, 0x89, 0x4e, - 0xcd, 0x66, 0x6f, 0xb6, 0x9b, 0x03, 0x49, 0xb6, 0x5b, 0x7b, 0xbc, 0x43, 0xba, 0x33, 0xff, 0x19, - 0x87, 0x0b, 0xc1, 0xe9, 0xf6, 0x20, 0xea, 0x50, 0x85, 0xa6, 0x99, 0xca, 0x6f, 0x7e, 0xfa, 0x9c, - 0xce, 0x29, 0x2a, 0xa9, 0x36, 0x4a, 0xbc, 0xac, 0xd7, 0x05, 0x96, 0x54, 0xae, 0x4a, 0xaa, 0xe6, - 0xfe, 0x10, 0x48, 0xcb, 0xc0, 0x16, 0x9f, 0x7f, 0x5a, 0x58, 0xdf, 0xb8, 0x5d, 0x68, 0x94, 0x9e, - 0xe3, 0x96, 0x38, 0x5e, 0xb2, 0xc9, 0x85, 0x7e, 0x00, 0x09, 0x8f, 0x7c, 0x35, 0xd5, 0xb2, 0x15, - 0x79, 0xec, 0x14, 0x61, 0x63, 0x8c, 0xb5, 0x2f, 0x54, 0xca, 0xec, 0x29, 0x8b, 0x48, 0x26, 0x29, - 0xb2, 0x3d, 0x32, 0xe6, 0x28, 0x1d, 0x7d, 0xe6, 0x6c, 0x24, 0xb4, 0x00, 0x80, 0xb5, 0xb2, 0x6b, - 0x10, 0xa1, 0x06, 0x93, 0x58, 0x63, 0xfb, 0x0c, 0xcd, 0xc3, 0x24, 0xd1, 0x89, 0x54, 0x2b, 0x5a, - 0x12, 0x49, 0x8e, 0xd3, 0xd5, 0x09, 0xfa, 0x60, 0x5f, 0x22, 0xe8, 0x2a, 0x24, 0xfc, 0x63, 0xc4, - 0xcd, 0x64, 0x94, 0x4e, 0x70, 0xca, 0x9b, 0x20, 0x6e, 0xa2, 0x65, 0x98, 0xb6, 0x6a, 0x92, 0x55, - 0xf5, 0x99, 0x7d, 0x43, 0xcd, 0xe2, 0xee, 0x63, 0xc7, 0xee, 0x0e, 0xcc, 0x79, 0x54, 0xa7, 0x4b, - 0x45, 0x4b, 0x55, 0xa8, 0xfd, 0x04, 0xb5, 0x9f, 0x6d, 0x2f, 0xef, 0xdb, 0xab, 0xfb, 0xaa, 0x62, - 0xbb, 0xbd, 0x86, 0xb8, 0xac, 0x1f, 0x62, 0x4d, 0xd2, 0x88, 0x6d, 0x6f, 0x25, 0x27, 0xe9, 0xce, - 0xb8, 0x1d, 0x32, 0xfd, 0x6d, 0x66, 0xbb, 0x55, 0x96, 0x0c, 0x3b, 0x92, 0xaa, 0x68, 0x12, 0x69, - 0x98, 0xd8, 0x12, 0xa7, 0xdc, 0x30, 0xfb, 0xaa, 0x62, 0xa1, 0x9b, 0x80, 0x5c, 0x6c, 0x7a, 0x83, - 0x18, 0x0d, 0x52, 0x54, 0xcb, 0xcd, 0x24, 0x2c, 0x71, 0xd9, 0x78, 0x9b, 0xa1, 0x2f, 0xe9, 0xc2, - 0xd3, 0x32, 0x7d, 0x9f, 0x4a, 0x54, 0x99, 0x93, 0xb1, 0x25, 0x2e, 0x3b, 0x21, 0xb2, 0x5f, 0x28, - 0x0d, 0x31, 0xe7, 0x04, 0x53, 0x2c, 0x63, 0x4b, 0x4e, 0x4e, 0x39, 0xc2, 0xe2, 0x3c, 0xda, 0xc1, - 0x96, 0x8c, 0xae, 0x41, 0xa2, 0xa1, 0x95, 0x74, 0xad, 0x4c, 0xbb, 0xa3, 0xd6, 0x71, 0x32, 0x4e, - 0x53, 0xc4, 0xdb, 0x4f, 0x5f, 0xa9, 0x75, 0x8c, 0x64, 0xb8, 0xd0, 0xd0, 0x3c, 0x86, 0x17, 0x4d, - 0xc6, 0xc6, 0x64, 0x82, 0x52, 0x9d, 0x0f, 0xa7, 0xfa, 0x6b, 0x9f, 0x5b, 0x9b, 0xec, 0xb3, 0x8d, - 0x80, 0xa7, 0x99, 0x77, 0x63, 0x30, 0x17, 0xe2, 0x81, 0xb2, 0x30, 0xe3, 0xab, 0xb3, 0xe9, 0xdb, - 0xae, 0x5e, 0xfd, 0xce, 0x18, 0xbf, 0x03, 0xf3, 0xde, 0x18, 0x3d, 0x1f, 0x77, 0x94, 0xa3, 0xd4, - 0x29, 0xd9, 0x36, 0x79, 0xed, 0x5a, 0xb0, 0x71, 0xca, 0x30, 0xdf, 0x1e, 0x67, 0xa7, 0x37, 0xdd, - 0x1c, 0x63, 0x7d, 0x4f, 0x63, 0xed, 0x69, 0x3e, 0xd5, 0x2a, 0xba, 0x98, 0x74, 0x03, 0xf9, 0x73, - 0xd0, 0x7d, 0x11, 0x40, 0xc9, 0x48, 0x10, 0x25, 0xef, 0x41, 0xaa, 0x8b, 0x92, 0x7e, 0x28, 0xe3, - 0xd4, 0x65, 0xae, 0x93, 0x95, 0x1e, 0x92, 0x0a, 0x5c, 0xf4, 0x88, 0xe9, 0xf3, 0xb5, 0x92, 0xd1, - 0x13, 0x32, 0x74, 0xb6, 0xcd, 0x50, 0x2f, 0x93, 0x95, 0x91, 0x21, 0x7d, 0x8c, 0xdc, 0xa3, 0x87, - 0x10, 0x29, 0xe3, 0x9a, 0xfb, 0xd2, 0x18, 0x4e, 0x18, 0xa9, 0x67, 0xe6, 0x57, 0x11, 0x48, 0x86, - 0x5e, 0x2f, 0x1e, 0x41, 0xcc, 0xa6, 0xb7, 0xa9, 0x1a, 0x3e, 0xf9, 0xfd, 0x96, 0xfb, 0xd6, 0xf0, - 0x32, 0x38, 0xaf, 0x8c, 0x1d, 0xcf, 0x54, 0xf4, 0xfb, 0xa1, 0x3d, 0x00, 0x59, 0xaf, 0xd7, 0x55, - 0xcb, 0x72, 0xdf, 0x3d, 0x93, 0xf9, 0x5b, 0x9f, 0x3e, 0xa7, 0xe7, 0x9d, 0x40, 0x56, 0xf9, 0x80, - 0x57, 0x75, 0xa1, 0x2e, 0x91, 0x2a, 0xff, 0x02, 0x2b, 0x92, 0xdc, 0xda, 0xc1, 0xf2, 0xc7, 0x77, - 0xb7, 0x80, 0xe5, 0xd9, 0xc1, 0xb2, 0xe8, 0x0b, 0x80, 0xee, 0x03, 0x30, 0x9c, 0xb6, 0x58, 0x8f, - 0xd1, 0xa2, 0xd2, 0x6e, 0x51, 0xce, 0x7d, 0x9f, 0x6f, 0xdf, 0xf7, 0x79, 0x26, 0x9f, 0x93, 0xcc, - 0xa5, 0x70, 0xe0, 0x13, 0xfa, 0xc8, 0x59, 0x08, 0xfd, 0x5d, 0x18, 0x33, 0x74, 0x83, 0x92, 0x26, - 0x96, 0xcb, 0x86, 0x5d, 0xab, 0x4d, 0x5d, 0xaf, 0xbc, 0xac, 0x14, 0x74, 0xcb, 0xc2, 0x14, 0x85, - 0x68, 0x3b, 0xa1, 0x0d, 0xb8, 0x48, 0x19, 0x84, 0xcb, 0x45, 0x17, 0x12, 0x13, 0xec, 0x28, 0x95, - 0xe4, 0x59, 0xb6, 0x9a, 0x77, 0x16, 0x99, 0x76, 0xdb, 0x12, 0xe6, 0x7a, 0x11, 0xd9, 0xf5, 0xf8, - 0x86, 0x7a, 0xcc, 0xb8, 0x1e, 0x44, 0x66, 0xd6, 0xde, 0x49, 0x6a, 0xa2, 0xef, 0x69, 0x79, 0xb2, - 0xe7, 0xb4, 0x9c, 0xfb, 0xf7, 0x34, 0x8c, 0xd3, 0x17, 0x34, 0xfa, 0x29, 0x07, 0x51, 0xe7, 0xd3, - 0x00, 0x5a, 0x09, 0x81, 0xd8, 0xfb, 0x2d, 0x22, 0xb5, 0x3a, 0x88, 0x29, 0x13, 0xa9, 0x6b, 0x3f, - 0xf9, 0xd3, 0xdf, 0x7e, 0x31, 0x9a, 0x46, 0x0b, 0x42, 0xbf, 0x6f, 0x28, 0xe8, 0x77, 0x1c, 0x9c, - 0xeb, 0x39, 0x25, 0xa3, 0x8d, 0x7e, 0x89, 0xc2, 0xbe, 0x5a, 0xa4, 0xee, 0x0c, 0xe9, 0xc5, 0x2a, - 0x5d, 0xa3, 0x95, 0xde, 0x40, 0x2b, 0x21, 0x95, 0xf6, 0x9e, 0xcf, 0xd1, 0x47, 0x0e, 0x66, 0xba, - 0x03, 0xa2, 0xf5, 0x61, 0xd2, 0xbb, 0x35, 0x6f, 0x0c, 0xe7, 0xc4, 0x4a, 0xde, 0xa7, 0x25, 0xef, - 0xa1, 0xe7, 0x03, 0x97, 0x2c, 0xbc, 0xed, 0x38, 0x3a, 0x1f, 0xf5, 0x9a, 0xa0, 0x5f, 0x73, 0x90, - 0xe8, 0xbc, 0x6e, 0xa3, 0xb5, 0x7e, 0xd5, 0x05, 0x7e, 0x45, 0x48, 0xe5, 0x86, 0x71, 0x61, 0x70, - 0x78, 0x0a, 0x27, 0x8b, 0x96, 0x85, 0xd0, 0x6f, 0x69, 0xfe, 0x33, 0x35, 0xfa, 0x3b, 0x07, 0xe9, - 0x63, 0x2e, 0x58, 0x28, 0xdf, 0xaf, 0x8e, 0xc1, 0x6e, 0x8b, 0xa9, 0xed, 0x53, 0xc5, 0x60, 0xe0, - 0xee, 0x52, 0x70, 0x1b, 0x28, 0x37, 0xc4, 0xac, 0x9c, 0x2d, 0x7d, 0x84, 0xfe, 0xcb, 0xc1, 0x42, - 0xdf, 0x2b, 0x3e, 0x7a, 0x38, 0x0c, 0x7f, 0x82, 0xbe, 0x42, 0xa4, 0xb6, 0x4e, 0x11, 0x81, 0x41, - 0x2c, 0x50, 0x88, 0xcf, 0xd0, 0xee, 0xc9, 0xe9, 0x48, 0x35, 0xcb, 0x03, 0xfe, 0x4f, 0x0e, 0x2e, - 0xf7, 0xfb, 0x76, 0x80, 0x1e, 0x0c, 0x53, 0x75, 0xc0, 0x47, 0x8c, 0xd4, 0xc3, 0x93, 0x07, 0x60, - 0xa8, 0x9f, 0x50, 0xd4, 0x5b, 0xe8, 0xc1, 0x29, 0x51, 0xa3, 0xdf, 0x72, 0x30, 0xdd, 0x75, 0x6f, - 0x46, 0xb9, 0x63, 0xa9, 0xd7, 0x73, 0x07, 0x4f, 0xad, 0x0f, 0xe5, 0xc3, 0x50, 0x08, 0x14, 0xc5, - 0x0a, 0xba, 0x1e, 0x82, 0x42, 0x72, 0xfd, 0xd8, 0x7b, 0x09, 0xfd, 0x8b, 0x83, 0xf9, 0x3e, 0xb7, - 0x62, 0x74, 0x7f, 0x98, 0xc6, 0x06, 0x08, 0xc8, 0x83, 0x13, 0xfb, 0x33, 0x44, 0x7b, 0x14, 0xd1, - 0x13, 0xf4, 0xe8, 0xe4, 0x73, 0xf1, 0x8b, 0xcd, 0x1f, 0x38, 0x88, 0x77, 0xe8, 0x16, 0xba, 0x3d, - 0xb0, 0xc4, 0xb9, 0x98, 0xd6, 0x86, 0xf0, 0x60, 0x28, 0x76, 0x28, 0x8a, 0xfb, 0xe8, 0xdb, 0x83, - 0x69, 0xa2, 0xf0, 0x36, 0xe0, 0xa2, 0x7e, 0x94, 0x7f, 0xf1, 0xfe, 0xcb, 0x22, 0xf7, 0xe1, 0xcb, - 0x22, 0xf7, 0xd7, 0x2f, 0x8b, 0xdc, 0xcf, 0xbf, 0x2e, 0x8e, 0x7c, 0xf8, 0xba, 0x38, 0xf2, 0x97, - 0xaf, 0x8b, 0x23, 0xdf, 0x3f, 0xf6, 0x84, 0xd4, 0xf4, 0x27, 0xa4, 0xc7, 0xa5, 0x52, 0x94, 0xfe, - 0xa3, 0x62, 0xfd, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb0, 0xc6, 0x38, 0x28, 0x16, 0x1a, 0x00, - 0x00, + // 1792 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdf, 0x6f, 0xdb, 0x5c, + 0x19, 0xae, 0xdb, 0x34, 0x5f, 0xfb, 0xa6, 0x49, 0xbb, 0xf3, 0x75, 0x6b, 0x96, 0xae, 0x4d, 0x17, + 0xf6, 0x75, 0x69, 0xb7, 0xd9, 0x6b, 0xda, 0xf5, 0x62, 0x83, 0x6d, 0x4d, 0xbb, 0xad, 0xfb, 0x51, + 0x2d, 0xb8, 0xab, 0x90, 0x00, 0x11, 0x39, 0xce, 0x89, 0x63, 0x35, 0xb1, 0x3d, 0xfb, 0xa4, 0x24, + 0x9a, 0x7a, 0xc3, 0x05, 0x77, 0x48, 0x48, 0x70, 0xc5, 0x3f, 0x00, 0x12, 0x97, 0xec, 0x0a, 0x89, + 0xfb, 0x71, 0x37, 0x8d, 0x0b, 0xd0, 0x2e, 0x26, 0xb4, 0x21, 0x90, 0x90, 0x10, 0xe2, 0x86, 0x6b, + 0xe4, 0xe3, 0xe3, 0xd8, 0x49, 0xec, 0x34, 0x69, 0xcb, 0x5d, 0xe3, 0xf3, 0xfe, 0x7a, 0xde, 0xf7, + 0x39, 0x8f, 0xcf, 0x71, 0xe1, 0x6a, 0x49, 0x2a, 0xb5, 0x6a, 0xba, 0x26, 0x94, 0x88, 0x6c, 0x11, + 0xe9, 0x50, 0xd5, 0x14, 0xe1, 0x68, 0x4d, 0x78, 0xdd, 0xc0, 0x66, 0x8b, 0x37, 0x4c, 0x9d, 0xe8, + 0xe8, 0x22, 0x33, 0xe1, 0x3d, 0x13, 0xfe, 0x68, 0x2d, 0x35, 0xab, 0xe8, 0x8a, 0x4e, 0x2d, 0x04, + 0xfb, 0x2f, 0xc7, 0x38, 0x75, 0x45, 0xd1, 0x75, 0xa5, 0x86, 0x05, 0xc9, 0x50, 0x05, 0x49, 0xd3, + 0x74, 0x22, 0x11, 0x55, 0xd7, 0x2c, 0xb6, 0x7a, 0x59, 0xd6, 0xad, 0xba, 0x6e, 0x15, 0x1d, 0x37, + 0xe7, 0x07, 0x5b, 0xca, 0x38, 0xbf, 0x04, 0xd9, 0x6c, 0x19, 0x44, 0x17, 0x2c, 0x2c, 0x1b, 0xb9, + 0x3b, 0x9b, 0x87, 0x6b, 0xc2, 0x21, 0x6e, 0xb9, 0x36, 0xd7, 0x98, 0x8d, 0x57, 0x68, 0x09, 0x13, + 0x69, 0xcd, 0xfd, 0xcd, 0xac, 0x56, 0x99, 0x55, 0x49, 0xb2, 0xb0, 0x03, 0xa4, 0x6d, 0x68, 0x48, + 0x8a, 0xaa, 0xd1, 0x8a, 0xdc, 0xac, 0xc1, 0xf0, 0x0d, 0xc9, 0x94, 0xea, 0x6e, 0xd6, 0xe5, 0x60, + 0x1b, 0x5f, 0x37, 0x1c, 0xbb, 0x74, 0x48, 0x2c, 0xdd, 0x70, 0x0c, 0x32, 0xb3, 0x80, 0xbe, 0x6b, + 0x97, 0x53, 0xa0, 0xd1, 0x45, 0xfc, 0xba, 0x81, 0x2d, 0x92, 0x11, 0xe1, 0xeb, 0x8e, 0xa7, 0x96, + 0xa1, 0x6b, 0x16, 0x46, 0xf7, 0x20, 0xea, 0x54, 0x91, 0xe4, 0x96, 0xb8, 0x6c, 0x2c, 0xb7, 0xc0, + 0x07, 0x8e, 0x81, 0x77, 0xdc, 0xf2, 0x91, 0x77, 0x9f, 0xd2, 0x23, 0x22, 0x73, 0xc9, 0x28, 0xb0, + 0x40, 0x63, 0x3e, 0x56, 0x35, 0xa9, 0xa6, 0x92, 0x56, 0xc1, 0xd4, 0x8f, 0xd4, 0x32, 0x36, 0xdd, + 0xa4, 0xe8, 0x31, 0x80, 0xd7, 0x0b, 0x96, 0x61, 0x99, 0x67, 0x03, 0xb1, 0x1b, 0xc7, 0x3b, 0x0c, + 0x60, 0x8d, 0xe3, 0x0b, 0x92, 0x82, 0x99, 0xaf, 0xe8, 0xf3, 0xcc, 0xfc, 0x91, 0x83, 0xc5, 0xb0, + 0x4c, 0x0c, 0xc8, 0x8f, 0x00, 0x55, 0xd8, 0xa2, 0x3d, 0x77, 0x67, 0x35, 0xc9, 0x2d, 0x8d, 0x65, + 0x63, 0x39, 0x21, 0x04, 0x54, 0x77, 0x34, 0x37, 0x98, 0x78, 0xa1, 0xd2, 0x9d, 0x07, 0x3d, 0xe9, + 0x80, 0x32, 0x4a, 0xa1, 0x5c, 0x3f, 0x11, 0x0a, 0x8b, 0xe7, 0xc7, 0xb2, 0x05, 0x57, 0x02, 0xa1, + 0xb8, 0x3d, 0xbb, 0x0a, 0xf1, 0x8a, 0x51, 0x2c, 0x11, 0xb9, 0x68, 0x1c, 0x16, 0xab, 0xb8, 0x49, + 0xdb, 0x36, 0x29, 0x42, 0xc5, 0xc8, 0x13, 0xb9, 0x70, 0xb8, 0x8b, 0x9b, 0x99, 0xe3, 0x90, 0xbe, + 0xb7, 0x9b, 0xf1, 0x43, 0xb8, 0xd0, 0xd3, 0x0c, 0xd6, 0xfe, 0xa1, 0x7b, 0x31, 0xd3, 0xdd, 0x8b, + 0xcc, 0x6f, 0x38, 0x48, 0xd1, 0xfc, 0xf9, 0x57, 0xdb, 0x3b, 0xb8, 0x86, 0x15, 0x67, 0xf3, 0xb9, + 0x00, 0xf2, 0x10, 0xb5, 0x88, 0x44, 0x1a, 0x0e, 0xa5, 0x12, 0xb9, 0xd5, 0x90, 0x8c, 0x1d, 0xde, + 0xfb, 0xd4, 0x43, 0x64, 0x9e, 0x5d, 0xc4, 0x19, 0x3d, 0x35, 0x71, 0xfe, 0xc0, 0xc1, 0x7c, 0x60, + 0xa9, 0xac, 0x51, 0x07, 0x30, 0x6d, 0x77, 0xba, 0xec, 0x2d, 0x31, 0xca, 0xdc, 0x1c, 0xa4, 0xe8, + 0x76, 0x8f, 0x12, 0x25, 0x22, 0xfb, 0xc2, 0x9f, 0x1f, 0x59, 0x2a, 0xb0, 0x12, 0x38, 0xe9, 0x82, + 0xfe, 0x63, 0x6c, 0x6e, 0x91, 0x5d, 0xac, 0x2a, 0x55, 0x32, 0x38, 0x73, 0xd0, 0x25, 0x88, 0x56, + 0xa9, 0x0f, 0x2d, 0x2a, 0x22, 0xb2, 0x5f, 0x99, 0x97, 0xb0, 0x3a, 0x48, 0x1e, 0xd6, 0xb5, 0xab, + 0x30, 0x75, 0xa4, 0x13, 0x55, 0x53, 0x8a, 0x86, 0xbd, 0x4e, 0xf3, 0x44, 0xc4, 0x98, 0xf3, 0x8c, + 0xba, 0x64, 0xf6, 0x20, 0x1b, 0x18, 0x70, 0xbb, 0x61, 0x9a, 0x58, 0x23, 0xd4, 0x68, 0x08, 0xc6, + 0x87, 0xf5, 0xa1, 0x33, 0x1c, 0x2b, 0xcf, 0x03, 0xc9, 0xf9, 0x41, 0xf6, 0x94, 0x3d, 0xda, 0x5b, + 0xf6, 0xcf, 0x38, 0xb8, 0x41, 0x13, 0x6d, 0xc9, 0x44, 0x3d, 0xc2, 0x3d, 0x72, 0xd3, 0xdd, 0xf2, + 0xb0, 0x54, 0xe7, 0xc5, 0xdf, 0x3f, 0x73, 0x70, 0x73, 0xb0, 0x7a, 0xce, 0x51, 0x06, 0xbf, 0xa7, + 0x92, 0xea, 0x1e, 0x26, 0xd2, 0xff, 0x55, 0x06, 0x17, 0xd8, 0xc6, 0xa4, 0xc0, 0x24, 0x82, 0xcb, + 0x1d, 0x8d, 0xcd, 0x6c, 0x32, 0x95, 0xec, 0x59, 0xee, 0x3f, 0xe3, 0xcc, 0x2f, 0x39, 0xb8, 0x1e, + 0xc8, 0x94, 0x00, 0xa1, 0x1a, 0x60, 0xbf, 0x9c, 0xd7, 0x1c, 0xff, 0xc1, 0x85, 0xec, 0x87, 0x20, + 0x51, 0x32, 0xe1, 0xb2, 0x4f, 0x94, 0x74, 0x33, 0x40, 0x9e, 0x36, 0x4f, 0x94, 0x27, 0x3d, 0x28, + 0xb4, 0x38, 0xe7, 0x09, 0x55, 0x87, 0xc1, 0xf9, 0xcd, 0xf5, 0x19, 0x5c, 0xee, 0x15, 0x5c, 0xb7, + 0xe3, 0xb7, 0xe0, 0x6b, 0x56, 0x6c, 0x91, 0x34, 0x8b, 0x55, 0xc9, 0xaa, 0xfa, 0xfa, 0x3e, 0xc3, + 0x96, 0x5e, 0x35, 0x77, 0x25, 0xab, 0x6a, 0xef, 0xfa, 0xd7, 0x41, 0xef, 0x99, 0x76, 0x9b, 0xf6, + 0x21, 0xd1, 0xa9, 0xdd, 0xec, 0x0d, 0x37, 0x9c, 0x74, 0xc7, 0x3b, 0xa4, 0x3b, 0xf3, 0x9f, 0x71, + 0xb8, 0x18, 0x9c, 0x6e, 0x0f, 0xa2, 0x0e, 0x55, 0x68, 0x9a, 0xa9, 0xfc, 0xe6, 0xc7, 0x4f, 0xe9, + 0x9c, 0xa2, 0x92, 0x6a, 0xa3, 0xc4, 0xcb, 0x7a, 0x5d, 0x60, 0x49, 0xe5, 0xaa, 0xa4, 0x6a, 0xee, + 0x0f, 0x81, 0xb4, 0x0c, 0x6c, 0xf1, 0xf9, 0xa7, 0x85, 0xf5, 0x8d, 0xdb, 0x85, 0x46, 0xe9, 0x39, + 0x6e, 0x89, 0xe3, 0x25, 0x9b, 0x5c, 0xe8, 0x07, 0x90, 0xf0, 0xc8, 0x57, 0x53, 0x2d, 0x5b, 0x91, + 0xc7, 0xce, 0x10, 0x36, 0xc6, 0x58, 0xfb, 0x42, 0xa5, 0xcc, 0x9e, 0xb2, 0x88, 0x64, 0x92, 0x22, + 0xdb, 0x23, 0x63, 0x8e, 0xd2, 0xd1, 0x67, 0xce, 0x46, 0x42, 0x0b, 0x00, 0x58, 0x2b, 0xbb, 0x06, + 0x11, 0x6a, 0x30, 0x89, 0x35, 0xb6, 0xcf, 0xd0, 0x3c, 0x4c, 0x12, 0x9d, 0x48, 0xb5, 0xa2, 0x25, + 0x91, 0xe4, 0x38, 0x5d, 0x9d, 0xa0, 0x0f, 0xf6, 0x25, 0x82, 0xae, 0x41, 0xc2, 0x3f, 0x46, 0xdc, + 0x4c, 0x46, 0xe9, 0x04, 0xa7, 0xbc, 0x09, 0xe2, 0x26, 0x5a, 0x86, 0x69, 0xab, 0x26, 0x59, 0x55, + 0x9f, 0xd9, 0x57, 0xd4, 0x2c, 0xee, 0x3e, 0x76, 0xec, 0xee, 0xc0, 0x9c, 0x47, 0x75, 0xba, 0x54, + 0xb4, 0x54, 0x85, 0xda, 0x4f, 0x50, 0xfb, 0xd9, 0xf6, 0xf2, 0xbe, 0xbd, 0xba, 0xaf, 0x2a, 0xb6, + 0xdb, 0x01, 0xc4, 0x65, 0xfd, 0x08, 0x6b, 0x92, 0x46, 0x6c, 0x7b, 0x2b, 0x39, 0x49, 0x77, 0xc6, + 0xed, 0x90, 0xe9, 0x6f, 0x33, 0xdb, 0xad, 0xb2, 0x64, 0xd8, 0x91, 0x54, 0x45, 0x93, 0x48, 0xc3, + 0xc4, 0x96, 0x38, 0xe5, 0x86, 0xd9, 0x57, 0x15, 0x0b, 0xdd, 0x04, 0xe4, 0x62, 0xd3, 0x1b, 0xc4, + 0x68, 0x90, 0xa2, 0x5a, 0x6e, 0x26, 0x61, 0x89, 0xcb, 0xc6, 0xdb, 0x0c, 0x7d, 0x49, 0x17, 0x9e, + 0x96, 0xe9, 0xfb, 0x54, 0xa2, 0xca, 0x9c, 0x8c, 0x2d, 0x71, 0xd9, 0x09, 0x91, 0xfd, 0x42, 0x69, + 0x88, 0x39, 0x27, 0x99, 0x62, 0x19, 0x5b, 0x72, 0x72, 0xca, 0x11, 0x16, 0xe7, 0xd1, 0x0e, 0xb6, + 0x64, 0xf4, 0x0d, 0x24, 0x1a, 0x5a, 0x49, 0xd7, 0xca, 0xb4, 0x3b, 0x6a, 0x1d, 0x27, 0xe3, 0x34, + 0x45, 0xbc, 0xfd, 0xf4, 0x95, 0x5a, 0xc7, 0x48, 0x86, 0x8b, 0x0d, 0xcd, 0x63, 0x78, 0xd1, 0x64, + 0x6c, 0x4c, 0x26, 0x28, 0xd5, 0xf9, 0x70, 0xaa, 0x1f, 0xf8, 0xdc, 0xda, 0x64, 0x9f, 0x6d, 0x04, + 0x3c, 0xcd, 0xbc, 0x1d, 0x83, 0xb9, 0x10, 0x0f, 0x94, 0x85, 0x19, 0x5f, 0x9d, 0x4d, 0xdf, 0x76, + 0xf5, 0xea, 0x77, 0xc6, 0xf8, 0x1d, 0x98, 0xf7, 0xc6, 0xe8, 0xf9, 0xb8, 0xa3, 0x1c, 0xa5, 0x4e, + 0xc9, 0xb6, 0xc9, 0x81, 0x6b, 0xc1, 0xc6, 0x29, 0xc3, 0x7c, 0x7b, 0x9c, 0x9d, 0xde, 0x74, 0x73, + 0x8c, 0xd1, 0xe1, 0x5e, 0x0b, 0xc1, 0xdb, 0x9e, 0xe6, 0x53, 0xad, 0xa2, 0x8b, 0x49, 0x37, 0x90, + 0x3f, 0x07, 0xdd, 0x17, 0x01, 0x94, 0x8c, 0x04, 0x51, 0xf2, 0x1e, 0xa4, 0xba, 0x28, 0xe9, 0x87, + 0x32, 0x4e, 0x5d, 0xe6, 0x3a, 0x59, 0xe9, 0x21, 0xa9, 0xc0, 0x25, 0x8f, 0x98, 0x3e, 0x5f, 0x2b, + 0x19, 0x3d, 0x25, 0x43, 0x67, 0xdb, 0x0c, 0xf5, 0x32, 0x59, 0x19, 0x19, 0xd2, 0x27, 0xc8, 0x3d, + 0x7a, 0x08, 0x91, 0x32, 0xae, 0x9d, 0xee, 0x4c, 0x4b, 0x3d, 0x33, 0xbf, 0x8a, 0x40, 0x32, 0xf4, + 0x9a, 0xf1, 0x08, 0x62, 0x36, 0xbd, 0x4d, 0xd5, 0xf0, 0xc9, 0xef, 0xb7, 0xdc, 0xb7, 0x86, 0x97, + 0xc1, 0x79, 0x65, 0xec, 0x78, 0xa6, 0xa2, 0xdf, 0x0f, 0xed, 0x01, 0xc8, 0x7a, 0xbd, 0xae, 0x5a, + 0x96, 0xfb, 0xee, 0x99, 0xcc, 0xdf, 0xfa, 0xf8, 0x29, 0x3d, 0xef, 0x04, 0xb2, 0xca, 0x87, 0xbc, + 0xaa, 0x0b, 0x75, 0x89, 0x54, 0xf9, 0x17, 0x58, 0x91, 0xe4, 0xd6, 0x0e, 0x96, 0x3f, 0xbc, 0xbd, + 0x05, 0x2c, 0xcf, 0x0e, 0x96, 0x45, 0x5f, 0x00, 0x74, 0x1f, 0x80, 0xe1, 0xb4, 0xc5, 0x7a, 0x8c, + 0x16, 0x95, 0x76, 0x8b, 0x72, 0xee, 0xfd, 0x7c, 0xfb, 0xde, 0xcf, 0x33, 0xf9, 0x9c, 0x64, 0x2e, + 0x85, 0x43, 0x9f, 0xd0, 0x47, 0xce, 0x43, 0xe8, 0xef, 0xc2, 0x98, 0xa1, 0x1b, 0x94, 0x34, 0xb1, + 0x5c, 0x36, 0xec, 0x7a, 0x6d, 0xea, 0x7a, 0xe5, 0x65, 0xa5, 0xa0, 0x5b, 0x16, 0xa6, 0x28, 0x44, + 0xdb, 0x09, 0x6d, 0xc0, 0x25, 0xca, 0x20, 0x5c, 0x2e, 0xba, 0x90, 0x98, 0x60, 0x47, 0xa9, 0x24, + 0xcf, 0xb2, 0xd5, 0xbc, 0xb3, 0xc8, 0xb4, 0xdb, 0x96, 0x30, 0xd7, 0x8b, 0xc8, 0xae, 0xc7, 0x57, + 0xd4, 0x63, 0xc6, 0xf5, 0x20, 0x32, 0xb3, 0xf6, 0x4e, 0x52, 0x13, 0x7d, 0x4f, 0xcb, 0x93, 0x3d, + 0xa7, 0xe5, 0xdc, 0xbf, 0xa7, 0x61, 0x9c, 0xbe, 0xa0, 0xd1, 0x4f, 0x39, 0x88, 0x3a, 0x9f, 0x08, + 0xd0, 0x4a, 0x08, 0xc4, 0xde, 0x6f, 0x12, 0xa9, 0xd5, 0x41, 0x4c, 0x99, 0x48, 0x7d, 0xf3, 0x93, + 0x3f, 0xfd, 0xed, 0x17, 0xa3, 0x69, 0xb4, 0x20, 0xf4, 0xfb, 0x96, 0x82, 0x7e, 0xc7, 0xc1, 0x85, + 0x9e, 0x53, 0x32, 0xda, 0xe8, 0x97, 0x28, 0xec, 0xeb, 0x45, 0xea, 0xce, 0x90, 0x5e, 0xac, 0xd2, + 0x35, 0x5a, 0xe9, 0x0d, 0xb4, 0x12, 0x52, 0x69, 0xef, 0xf9, 0x1c, 0x7d, 0xe0, 0x60, 0xa6, 0x3b, + 0x20, 0x5a, 0x1f, 0x26, 0xbd, 0x5b, 0xf3, 0xc6, 0x70, 0x4e, 0xac, 0xe4, 0x7d, 0x5a, 0xf2, 0x1e, + 0x7a, 0x3e, 0x70, 0xc9, 0xc2, 0x9b, 0x8e, 0xa3, 0xf3, 0x71, 0xaf, 0x09, 0xfa, 0x35, 0x07, 0x89, + 0xce, 0x6b, 0x37, 0x5a, 0xeb, 0x57, 0x5d, 0xe0, 0xd7, 0x84, 0x54, 0x6e, 0x18, 0x17, 0x06, 0x87, + 0xa7, 0x70, 0xb2, 0x68, 0x59, 0x08, 0xfd, 0xa6, 0xe6, 0x3f, 0x53, 0xa3, 0xbf, 0x73, 0x90, 0x3e, + 0xe1, 0x82, 0x85, 0xf2, 0xfd, 0xea, 0x18, 0xec, 0xb6, 0x98, 0xda, 0x3e, 0x53, 0x0c, 0x06, 0xee, + 0x2e, 0x05, 0xb7, 0x81, 0x72, 0x43, 0xcc, 0xca, 0xd9, 0xd2, 0xc7, 0xe8, 0xbf, 0x1c, 0x2c, 0xf4, + 0xbd, 0xe2, 0xa3, 0x87, 0xc3, 0xf0, 0x27, 0xe8, 0x2b, 0x44, 0x6a, 0xeb, 0x0c, 0x11, 0x18, 0xc4, + 0x02, 0x85, 0xf8, 0x0c, 0xed, 0x9e, 0x9e, 0x8e, 0x54, 0xb3, 0x3c, 0xe0, 0xff, 0xe4, 0xe0, 0x4a, + 0xbf, 0x6f, 0x07, 0xe8, 0xc1, 0x30, 0x55, 0x07, 0x7c, 0xc4, 0x48, 0x3d, 0x3c, 0x7d, 0x00, 0x86, + 0xfa, 0x09, 0x45, 0xbd, 0x85, 0x1e, 0x9c, 0x11, 0x35, 0xfa, 0x2d, 0x07, 0xd3, 0x5d, 0xf7, 0x66, + 0x94, 0x3b, 0x91, 0x7a, 0x3d, 0x77, 0xf0, 0xd4, 0xfa, 0x50, 0x3e, 0x0c, 0x85, 0x40, 0x51, 0xac, + 0xa0, 0xeb, 0x21, 0x28, 0x24, 0xd7, 0x8f, 0xbd, 0x97, 0xd0, 0xbf, 0x38, 0x98, 0xef, 0x73, 0x2b, + 0x46, 0xf7, 0x87, 0x69, 0x6c, 0x80, 0x80, 0x3c, 0x38, 0xb5, 0x3f, 0x43, 0xb4, 0x47, 0x11, 0x3d, + 0x41, 0x8f, 0x4e, 0x3f, 0x17, 0xbf, 0xd8, 0xfc, 0x9e, 0x83, 0x78, 0x87, 0x6e, 0xa1, 0xdb, 0x03, + 0x4b, 0x9c, 0x8b, 0x69, 0x6d, 0x08, 0x0f, 0x86, 0x62, 0x87, 0xa2, 0xb8, 0x8f, 0xbe, 0x3d, 0x98, + 0x26, 0x0a, 0x6f, 0x02, 0x2e, 0xea, 0xc7, 0xf9, 0x17, 0xef, 0x3e, 0x2f, 0x72, 0xef, 0x3f, 0x2f, + 0x72, 0x7f, 0xfd, 0xbc, 0xc8, 0xfd, 0xfc, 0xcb, 0xe2, 0xc8, 0xfb, 0x2f, 0x8b, 0x23, 0x7f, 0xf9, + 0xb2, 0x38, 0xf2, 0xfd, 0x13, 0x4f, 0x48, 0x4d, 0x7f, 0x42, 0x7a, 0x5c, 0x2a, 0x45, 0xe9, 0x3f, + 0x2c, 0xd6, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x4b, 0x83, 0xf4, 0x1e, 0x1a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4254,7 +4253,7 @@ func (m *QueryBTCDelegationsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.BtcDelegations = append(m.BtcDelegations, &BTCDelegation{}) + m.BtcDelegations = append(m.BtcDelegations, &BTCDelegationResponse{}) if err := m.BtcDelegations[len(m.BtcDelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } From 2a47d65cafa422c2b0ff8a9ef1861b014df51228 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 8 Feb 2024 15:53:21 +1100 Subject: [PATCH 027/119] btcstaking: unify BTC delegation state update events and distribution cache (#457) --- proto/babylon/btcstaking/v1/events.proto | 37 +- proto/babylon/btcstaking/v1/incentive.proto | 12 +- testutil/datagen/incentive.go | 22 +- x/btcstaking/keeper/incentive.go | 32 +- x/btcstaking/keeper/incentive_test.go | 12 +- x/btcstaking/keeper/keeper.go | 33 +- x/btcstaking/keeper/msg_server.go | 35 +- .../keeper/voting_power_table_test.go | 10 +- x/btcstaking/types/btcstaking.go | 4 +- x/btcstaking/types/errors.go | 42 +- x/btcstaking/types/events.pb.go | 671 ++---------------- x/btcstaking/types/incentive.go | 23 +- x/btcstaking/types/incentive.pb.go | 181 +++-- x/btcstaking/types/keys.go | 14 +- x/finality/keeper/tallying.go | 12 +- x/finality/keeper/tallying_bench_test.go | 4 +- x/finality/keeper/tallying_test.go | 4 +- x/finality/types/expected_keepers.go | 6 +- x/finality/types/mocked_keepers.go | 50 +- x/incentive/keeper/btc_staking_gauge.go | 6 +- x/incentive/keeper/btc_staking_gauge_test.go | 10 +- 21 files changed, 370 insertions(+), 850 deletions(-) diff --git a/proto/babylon/btcstaking/v1/events.proto b/proto/babylon/btcstaking/v1/events.proto index 1d9845b4f..20f48fb75 100644 --- a/proto/babylon/btcstaking/v1/events.proto +++ b/proto/babylon/btcstaking/v1/events.proto @@ -1,7 +1,6 @@ syntax = "proto3"; package babylon.btcstaking.v1; -import "gogoproto/gogo.proto"; import "babylon/btcstaking/v1/btcstaking.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; @@ -9,33 +8,17 @@ option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; // EventNewFinalityProvider is the event emitted when a finality provider is created message EventNewFinalityProvider { FinalityProvider fp = 1; } -// EventNewBTCDelegation is the event emitted when a BTC delegation is created -// NOTE: the BTC delegation is not active thus does not have voting power yet -// only after it receives a covenant signature it becomes activated and has voting power -message EventNewBTCDelegation { BTCDelegation btc_del = 1; } - -// EventActivateBTCDelegation is the event emitted when covenant activates a BTC delegation -// such that the BTC delegation starts to have voting power in its timelock period -message EventActivateBTCDelegation { BTCDelegation btc_del = 1; } - -// EventUnbondingBTCDelegation is the event emitted when an unbonding BTC delegation -// receives all signatures needed for becoming unbonded -message EventUnbondedBTCDelegation { - // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation - // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that - // this BTC delegation delegates to - // If there is more than 1 PKs, then this means the delegation is restaked - // to multiple finality providers - repeated bytes fp_btc_pk_list = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; +// EventBTCDelegationStateUpdate is the event emitted when a BTC delegation's state is +// updated. There are the following possible state transitions: +// - non-existing -> pending, which happens upon `MsgCreateBTCDelegation` +// - pending -> active, which happens upon `MsgAddCovenantSigs` +// - active -> unbonded, which happens upon `MsgBTCUndelegate` or upon staking tx timelock expires +message EventBTCDelegationStateUpdate { // staking_tx_hash is the hash of the staking tx. - // (fp_pks..., del_pk, staking_tx_hash) uniquely identifies a BTC delegation - string staking_tx_hash = 3; - // unbonding_tx_hash is the hash of the unbonding tx. - string unbonding_tx_hash = 4; - // from_state is the last state the BTC delegation was at - BTCDelegationStatus from_state = 5; + // It uniquely identifies a BTC delegation + string staking_tx_hash = 1; + // new_state is the new state of this BTC delegation + BTCDelegationStatus new_state = 2; } // EventSelectiveSlashing is the event emitted when an adversarial diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index 659b54d98..84160caaf 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -7,8 +7,9 @@ import "cosmos/crypto/secp256k1/keys.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; -// RewardDistCache is the cache for reward distribution of finality providers at a height -message RewardDistCache { +// VotingPowerDistCache is the cache for voting power distribution of finality providers +// and their BTC delegations at a height +message VotingPowerDistCache { uint64 total_voting_power = 1; // finality_providers is a list of finality providers' voting power information repeated FinalityProviderDistInfo finality_providers = 2; @@ -34,8 +35,11 @@ message FinalityProviderDistInfo { // BTCDelDistInfo contains the information related to reward distribution for a BTC delegations message BTCDelDistInfo { + // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation + // the PK follows encoding in BIP-340 spec + bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // babylon_pk is the Babylon public key of the BTC delegations - cosmos.crypto.secp256k1.PubKey babylon_pk = 1; + cosmos.crypto.secp256k1.PubKey babylon_pk = 2; // voting_power is the voting power of the BTC delegation - uint64 voting_power = 2; + uint64 voting_power = 3; } diff --git a/testutil/datagen/incentive.go b/testutil/datagen/incentive.go index 327a746e0..fd5888d95 100644 --- a/testutil/datagen/incentive.go +++ b/testutil/datagen/incentive.go @@ -77,11 +77,16 @@ func GenRandomGauge(r *rand.Rand) *itypes.Gauge { return itypes.NewGauge(coins...) } -func GenRandomBTCDelDistInfo(r *rand.Rand) *bstypes.BTCDelDistInfo { +func GenRandomBTCDelDistInfo(r *rand.Rand) (*bstypes.BTCDelDistInfo, error) { + btcPK, err := GenRandomBIP340PubKey(r) + if err != nil { + return nil, err + } return &bstypes.BTCDelDistInfo{ + BtcPk: btcPK, BabylonPk: GenRandomAccount().GetPubKey().(*secp256k1.PubKey), VotingPower: RandomInt(r, 1000) + 1, - } + }, nil } func GenRandomFinalityProviderDistInfo(r *rand.Rand) (*bstypes.FinalityProviderDistInfo, error) { @@ -95,15 +100,18 @@ func GenRandomFinalityProviderDistInfo(r *rand.Rand) (*bstypes.FinalityProviderD // add a random number of BTC delegation distribution info numBTCDels := RandomInt(r, 100) + 1 for i := uint64(0); i < numBTCDels; i++ { - btcDelDistInfo := GenRandomBTCDelDistInfo(r) + btcDelDistInfo, err := GenRandomBTCDelDistInfo(r) + if err != nil { + return nil, err + } fpDistInfo.BtcDels = append(fpDistInfo.BtcDels, btcDelDistInfo) fpDistInfo.TotalVotingPower += btcDelDistInfo.VotingPower } return fpDistInfo, nil } -func GenRandomBTCStakingRewardDistCache(r *rand.Rand) (*bstypes.RewardDistCache, error) { - rdc := bstypes.NewRewardDistCache() +func GenRandomVotingPowerDistCache(r *rand.Rand) (*bstypes.VotingPowerDistCache, error) { + dc := bstypes.NewVotingPowerDistCache() // a random number of finality providers numFps := RandomInt(r, 10) + 1 for i := uint64(0); i < numFps; i++ { @@ -111,9 +119,9 @@ func GenRandomBTCStakingRewardDistCache(r *rand.Rand) (*bstypes.RewardDistCache, if err != nil { return nil, err } - rdc.AddFinalityProviderDistInfo(v) + dc.AddFinalityProviderDistInfo(v) } - return rdc, nil + return dc, nil } func GenRandomCheckpointAddressPair(r *rand.Rand) *btcctypes.CheckpointAddressPair { diff --git a/x/btcstaking/keeper/incentive.go b/x/btcstaking/keeper/incentive.go index 7c62d2428..fe64ce440 100644 --- a/x/btcstaking/keeper/incentive.go +++ b/x/btcstaking/keeper/incentive.go @@ -9,32 +9,32 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func (k Keeper) setRewardDistCache(ctx context.Context, height uint64, rdc *types.RewardDistCache) { - store := k.rewardDistCacheStore(ctx) - store.Set(sdk.Uint64ToBigEndian(height), k.cdc.MustMarshal(rdc)) +func (k Keeper) setVotingPowerDistCache(ctx context.Context, height uint64, dc *types.VotingPowerDistCache) { + store := k.votingPowerDistCacheStore(ctx) + store.Set(sdk.Uint64ToBigEndian(height), k.cdc.MustMarshal(dc)) } -func (k Keeper) GetRewardDistCache(ctx context.Context, height uint64) (*types.RewardDistCache, error) { - store := k.rewardDistCacheStore(ctx) +func (k Keeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types.VotingPowerDistCache, error) { + store := k.votingPowerDistCacheStore(ctx) rdcBytes := store.Get(sdk.Uint64ToBigEndian(height)) if len(rdcBytes) == 0 { - return nil, types.ErrRewardDistCacheNotFound + return nil, types.ErrVotingPowerDistCacheNotFound } - var rdc types.RewardDistCache - k.cdc.MustUnmarshal(rdcBytes, &rdc) - return &rdc, nil + var dc types.VotingPowerDistCache + k.cdc.MustUnmarshal(rdcBytes, &dc) + return &dc, nil } -func (k Keeper) RemoveRewardDistCache(ctx context.Context, height uint64) { - store := k.rewardDistCacheStore(ctx) +func (k Keeper) RemoveVotingPowerDistCache(ctx context.Context, height uint64) { + store := k.votingPowerDistCacheStore(ctx) store.Delete(sdk.Uint64ToBigEndian(height)) } -// rewardDistCacheStore returns the KVStore of the reward distribution cache -// prefix: RewardDistCacheKey +// votingPowerDistCacheStore returns the KVStore of the voting power distribution cache +// prefix: VotingPowerDistCacheKey // key: Babylon block height -// value: RewardDistCache -func (k Keeper) rewardDistCacheStore(ctx context.Context) prefix.Store { +// value: VotingPowerDistCache +func (k Keeper) votingPowerDistCacheStore(ctx context.Context) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - return prefix.NewStore(storeAdapter, types.RewardDistCacheKey) + return prefix.NewStore(storeAdapter, types.VotingPowerDistCacheKey) } diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 057461e44..0adb764f1 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -17,7 +17,7 @@ import ( "github.com/stretchr/testify/require" ) -func FuzzRecordRewardDistCache(f *testing.F) { +func FuzzRecordVotingPowerDistCache(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { @@ -83,18 +83,18 @@ func FuzzRecordRewardDistCache(f *testing.F) { } } - // record reward distribution cache + // record voting power distribution cache babylonHeight := datagen.RandomInt(r, 10) + 1 ctx = datagen.WithCtxHeight(ctx, babylonHeight) btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) err = keeper.BeginBlocker(ctx) require.NoError(t, err) - // assert reward distribution cache is correct - rdc, err := keeper.GetRewardDistCache(ctx, babylonHeight) + // assert voting power distribution cache is correct + dc, err := keeper.GetVotingPowerDistCache(ctx, babylonHeight) require.NoError(t, err) - require.Equal(t, rdc.TotalVotingPower, numFpsWithVotingPower*numBTCDels*stakingValue) - for _, fpDistInfo := range rdc.FinalityProviders { + require.Equal(t, dc.TotalVotingPower, numFpsWithVotingPower*numBTCDels*stakingValue) + for _, fpDistInfo := range dc.FinalityProviders { require.Equal(t, fpDistInfo.TotalVotingPower, numBTCDels*stakingValue) fp, ok := fpsWithVotingPowerMap[fpDistInfo.BabylonPk.String()] require.True(t, ok) diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 1fc63966e..c5e24e62d 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -61,8 +61,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // BeginBlocker is invoked upon `BeginBlock` of the system. The function // iterates over all BTC delegations under non-slashed finality providers // to 1) record the voting power table for the current height, and 2) record -// the reward distribution cache used for distributing rewards once the block -// is finalised by finality providers. +// the voting power distribution cache used for distributing rewards once +// the block is finalised by finality providers. func (k Keeper) BeginBlocker(ctx context.Context) error { // index BTC height at the current height k.IndexBTCHeight(ctx) @@ -74,12 +74,6 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { } wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout - // prepare for recording finality providers with positive voting power - activeFps := []*types.FinalityProviderWithMeta{} - // prepare for recording finality providers and their BTC delegations - // for rewards - dc := types.NewRewardDistCache() - // prepare metrics for {active, inactive} finality providers, // {pending, active, unbonded BTC delegations}, and total staked Bitcoins // NOTE: slashed finality providers and BTC delegations are recorded upon @@ -93,6 +87,8 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { types.BTCDelegationStatus_UNBONDED: 0, } ) + // for voting power and rewards + dc := types.NewVotingPowerDistCache() // iterate over all finality providers to find out non-slashed ones that have // positive voting power @@ -102,7 +98,7 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { fpDistInfo := types.NewFinalityProviderDistInfo(fp) // iterate over all BTC delegations under the finality provider - // in order to accumulate voting power and reward dist info for it + // in order to accumulate voting power dist info for it k.IterateBTCDelegations(ctx, fp.BtcPk, func(btcDel *types.BTCDelegation) bool { // accumulate voting power and reward distribution cache fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, params.CovenantQuorum) @@ -115,11 +111,6 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { }) if fpDistInfo.TotalVotingPower > 0 { - activeFP := &types.FinalityProviderWithMeta{ - BtcPk: fp.BtcPk, - VotingPower: fpDistInfo.TotalVotingPower, - } - activeFps = append(activeFps, activeFP) dc.AddFinalityProviderDistInfo(fpDistInfo) } @@ -138,16 +129,18 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { } // filter out top `MaxActiveFinalityProviders` active finality providers in terms of voting power - activeFps = types.FilterTopNFinalityProviders(activeFps, params.MaxActiveFinalityProviders) - // set voting power table + maxNumActiveFPs := k.GetParams(ctx).MaxActiveFinalityProviders + activeFps := types.FilterTopNFinalityProviders(dc.FinalityProviders, maxNumActiveFPs) + // set voting power table and re-calculate total voting power of top N finality providers + dc.TotalVotingPower = uint64(0) babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) for _, fp := range activeFps { - k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.VotingPower) + k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.TotalVotingPower) + dc.TotalVotingPower += fp.TotalVotingPower } - // set the reward distribution cache of the current height - // TODO: only give rewards to top N finality providers and their BTC delegations - k.setRewardDistCache(ctx, babylonTipHeight, dc) + // set the voting power distribution cache of the current height + k.setVotingPowerDistCache(ctx, uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height), dc) return nil } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index e2eca02c2..5c6c06b19 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -416,8 +416,12 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } // notify subscriber - if err := ctx.EventManager().EmitTypedEvent(&types.EventNewBTCDelegation{BtcDel: newBTCDel}); err != nil { - panic(fmt.Errorf("failed to emit EventNewBTCDelegation: %w", err)) + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: stakingTxHash.String(), + NewState: types.BTCDelegationStatus_PENDING, + } + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new pending BTC delegation: %w", err)) } return &types.MsgCreateBTCDelegationResponse{}, nil @@ -457,6 +461,14 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove return &types.MsgAddCovenantSigsResponse{}, nil } + // ensure BTC delegation is still pending, i.e., not expired + btcTipHeight := ms.btclcKeeper.GetTipInfo(ctx).Height + wValue := ms.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout + status := btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum) + if status != types.BTCDelegationStatus_PENDING { + return nil, types.ErrInvalidDelegationState.Wrapf("expected: %s, got: %s", types.BTCDelegationStatus_PENDING.String(), status.String()) + } + // Note: we assume the order of adaptor sigs is matched to the // order of finality providers in the delegation // TODO: ensure the order for restaking, currently, we only have one finality provider @@ -563,8 +575,12 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove ms.setBTCDelegation(ctx, btcDel) // notify subscriber - if err := ctx.EventManager().EmitTypedEvent(&types.EventActivateBTCDelegation{BtcDel: btcDel}); err != nil { - panic(fmt.Errorf("failed to emit EventActivateBTCDelegation: %w", err)) + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: req.StakingTxHash, + NewState: types.BTCDelegationStatus_ACTIVE, + } + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new active BTC delegation: %w", err)) } return &types.MsgAddCovenantSigsResponse{}, nil @@ -629,15 +645,12 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele ms.setBTCDelegation(ctx, btcDel) // notify subscriber about this unbonded BTC delegation - event := &types.EventUnbondedBTCDelegation{ - BtcPk: btcDel.BtcPk, - FpBtcPkList: btcDel.FpBtcPkList, - StakingTxHash: req.StakingTxHash, - UnbondingTxHash: unbondingMsgTx.TxHash().String(), - FromState: types.BTCDelegationStatus_ACTIVE, + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: req.StakingTxHash, + NewState: types.BTCDelegationStatus_UNBONDED, } if err := ctx.EventManager().EmitTypedEvent(event); err != nil { - panic(fmt.Errorf("failed to emit EventUnbondedBTCDelegation: %w", err)) + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new unbonded BTC delegation: %w", err)) } return &types.MsgBTCUndelegateResponse{}, nil diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index 6f6ae99ec..d486b13d0 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -217,7 +217,7 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) // generate a random batch of finality providers, each with a BTC delegation with random power - fpsWithMeta := []*types.FinalityProviderWithMeta{} + fpsWithMeta := []*types.FinalityProviderDistInfo{} numFps := datagen.RandomInt(r, 300) + 1 for i := uint64(0); i < numFps; i++ { // generate finality provider @@ -247,9 +247,9 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { require.NoError(t, err) // record voting power - fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderWithMeta{ - BtcPk: fp.BtcPk, - VotingPower: stakingValue, + fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderDistInfo{ + BtcPk: fp.BtcPk, + TotalVotingPower: stakingValue, }) } @@ -258,7 +258,7 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { expectedActiveFps := types.FilterTopNFinalityProviders(fpsWithMeta, maxActiveFpsParam) expectedActiveFpsMap := map[string]uint64{} for _, fp := range expectedActiveFps { - expectedActiveFpsMap[fp.BtcPk.MarshalHex()] = fp.VotingPower + expectedActiveFpsMap[fp.BtcPk.MarshalHex()] = fp.TotalVotingPower } // record voting power table diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 880755870..386161da3 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -37,7 +37,7 @@ func (fp *FinalityProvider) ValidateBasic() error { } // FilterTopNFinalityProviders returns the top n finality providers based on VotingPower. -func FilterTopNFinalityProviders(fps []*FinalityProviderWithMeta, n uint32) []*FinalityProviderWithMeta { +func FilterTopNFinalityProviders(fps []*FinalityProviderDistInfo, n uint32) []*FinalityProviderDistInfo { numFps := uint32(len(fps)) // if the given finality provider set is no bigger than n, no need to do anything @@ -47,7 +47,7 @@ func FilterTopNFinalityProviders(fps []*FinalityProviderWithMeta, n uint32) []*F // Sort the finality providers slice, from higher to lower voting power sort.SliceStable(fps, func(i, j int) bool { - return fps[i].VotingPower > fps[j].VotingPower + return fps[i].TotalVotingPower > fps[j].TotalVotingPower }) // Return the top n elements diff --git a/x/btcstaking/types/errors.go b/x/btcstaking/types/errors.go index 8f65379e5..364d7672e 100644 --- a/x/btcstaking/types/errors.go +++ b/x/btcstaking/types/errors.go @@ -6,25 +6,25 @@ import ( // x/btcstaking module sentinel errors var ( - ErrFpNotFound = errorsmod.Register(ModuleName, 1100, "the finality provider is not found") - ErrBTCDelegatorNotFound = errorsmod.Register(ModuleName, 1101, "the BTC delegator is not found") - ErrBTCDelegationNotFound = errorsmod.Register(ModuleName, 1102, "the BTC delegation is not found") - ErrFpRegistered = errorsmod.Register(ModuleName, 1103, "the finality provider has already been registered") - ErrFpAlreadySlashed = errorsmod.Register(ModuleName, 1104, "the finality provider has already been slashed") - ErrBTCStakingNotActivated = errorsmod.Register(ModuleName, 1105, "the BTC staking protocol is not activated yet") - ErrBTCHeightNotFound = errorsmod.Register(ModuleName, 1106, "the BTC height is not found") - ErrReusedStakingTx = errorsmod.Register(ModuleName, 1107, "the BTC staking tx is already used") - ErrInvalidCovenantPK = errorsmod.Register(ModuleName, 1108, "the BTC staking tx specifies a wrong covenant PK") - ErrInvalidStakingTx = errorsmod.Register(ModuleName, 1109, "the BTC staking tx is not valid") - ErrInvalidSlashingTx = errorsmod.Register(ModuleName, 1110, "the BTC slashing tx is not valid") - ErrInvalidCovenantSig = errorsmod.Register(ModuleName, 1111, "the covenant signature is not valid") - ErrCommissionLTMinRate = errorsmod.Register(ModuleName, 1112, "commission cannot be less than min rate") - ErrCommissionGTMaxRate = errorsmod.Register(ModuleName, 1113, "commission cannot be more than one") - ErrInvalidDelegationState = errorsmod.Register(ModuleName, 1114, "Unexpected delegation state") - ErrInvalidUnbondingTx = errorsmod.Register(ModuleName, 1115, "the BTC unbonding tx is not valid") - ErrRewardDistCacheNotFound = errorsmod.Register(ModuleName, 1116, "the reward distribution cache is not found") - ErrEmptyFpList = errorsmod.Register(ModuleName, 1117, "the finality provider list is empty") - ErrInvalidProofOfPossession = errorsmod.Register(ModuleName, 1118, "the proof of possession is not valid") - ErrDuplicatedFp = errorsmod.Register(ModuleName, 1119, "the staking request contains duplicated finality provider public key") - ErrInvalidBTCUndelegateReq = errorsmod.Register(ModuleName, 1120, "invalid undelegation request") + ErrFpNotFound = errorsmod.Register(ModuleName, 1100, "the finality provider is not found") + ErrBTCDelegatorNotFound = errorsmod.Register(ModuleName, 1101, "the BTC delegator is not found") + ErrBTCDelegationNotFound = errorsmod.Register(ModuleName, 1102, "the BTC delegation is not found") + ErrFpRegistered = errorsmod.Register(ModuleName, 1103, "the finality provider has already been registered") + ErrFpAlreadySlashed = errorsmod.Register(ModuleName, 1104, "the finality provider has already been slashed") + ErrBTCStakingNotActivated = errorsmod.Register(ModuleName, 1105, "the BTC staking protocol is not activated yet") + ErrBTCHeightNotFound = errorsmod.Register(ModuleName, 1106, "the BTC height is not found") + ErrReusedStakingTx = errorsmod.Register(ModuleName, 1107, "the BTC staking tx is already used") + ErrInvalidCovenantPK = errorsmod.Register(ModuleName, 1108, "the BTC staking tx specifies a wrong covenant PK") + ErrInvalidStakingTx = errorsmod.Register(ModuleName, 1109, "the BTC staking tx is not valid") + ErrInvalidSlashingTx = errorsmod.Register(ModuleName, 1110, "the BTC slashing tx is not valid") + ErrInvalidCovenantSig = errorsmod.Register(ModuleName, 1111, "the covenant signature is not valid") + ErrCommissionLTMinRate = errorsmod.Register(ModuleName, 1112, "commission cannot be less than min rate") + ErrCommissionGTMaxRate = errorsmod.Register(ModuleName, 1113, "commission cannot be more than one") + ErrInvalidDelegationState = errorsmod.Register(ModuleName, 1114, "Unexpected delegation state") + ErrInvalidUnbondingTx = errorsmod.Register(ModuleName, 1115, "the BTC unbonding tx is not valid") + ErrVotingPowerDistCacheNotFound = errorsmod.Register(ModuleName, 1116, "the voting power distribution cache is not found") + ErrEmptyFpList = errorsmod.Register(ModuleName, 1117, "the finality provider list is empty") + ErrInvalidProofOfPossession = errorsmod.Register(ModuleName, 1118, "the proof of possession is not valid") + ErrDuplicatedFp = errorsmod.Register(ModuleName, 1119, "the staking request contains duplicated finality provider public key") + ErrInvalidBTCUndelegateReq = errorsmod.Register(ModuleName, 1120, "invalid undelegation request") ) diff --git a/x/btcstaking/types/events.pb.go b/x/btcstaking/types/events.pb.go index d4c7a690d..af40abf48 100644 --- a/x/btcstaking/types/events.pb.go +++ b/x/btcstaking/types/events.pb.go @@ -5,8 +5,6 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" - _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" math "math" @@ -69,131 +67,31 @@ func (m *EventNewFinalityProvider) GetFp() *FinalityProvider { return nil } -// EventNewBTCDelegation is the event emitted when a BTC delegation is created -// NOTE: the BTC delegation is not active thus does not have voting power yet -// only after it receives a covenant signature it becomes activated and has voting power -type EventNewBTCDelegation struct { - BtcDel *BTCDelegation `protobuf:"bytes,1,opt,name=btc_del,json=btcDel,proto3" json:"btc_del,omitempty"` -} - -func (m *EventNewBTCDelegation) Reset() { *m = EventNewBTCDelegation{} } -func (m *EventNewBTCDelegation) String() string { return proto.CompactTextString(m) } -func (*EventNewBTCDelegation) ProtoMessage() {} -func (*EventNewBTCDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_74118427820fff75, []int{1} -} -func (m *EventNewBTCDelegation) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *EventNewBTCDelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_EventNewBTCDelegation.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 *EventNewBTCDelegation) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventNewBTCDelegation.Merge(m, src) -} -func (m *EventNewBTCDelegation) XXX_Size() int { - return m.Size() -} -func (m *EventNewBTCDelegation) XXX_DiscardUnknown() { - xxx_messageInfo_EventNewBTCDelegation.DiscardUnknown(m) -} - -var xxx_messageInfo_EventNewBTCDelegation proto.InternalMessageInfo - -func (m *EventNewBTCDelegation) GetBtcDel() *BTCDelegation { - if m != nil { - return m.BtcDel - } - return nil -} - -// EventActivateBTCDelegation is the event emitted when covenant activates a BTC delegation -// such that the BTC delegation starts to have voting power in its timelock period -type EventActivateBTCDelegation struct { - BtcDel *BTCDelegation `protobuf:"bytes,1,opt,name=btc_del,json=btcDel,proto3" json:"btc_del,omitempty"` -} - -func (m *EventActivateBTCDelegation) Reset() { *m = EventActivateBTCDelegation{} } -func (m *EventActivateBTCDelegation) String() string { return proto.CompactTextString(m) } -func (*EventActivateBTCDelegation) ProtoMessage() {} -func (*EventActivateBTCDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_74118427820fff75, []int{2} -} -func (m *EventActivateBTCDelegation) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *EventActivateBTCDelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_EventActivateBTCDelegation.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 *EventActivateBTCDelegation) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventActivateBTCDelegation.Merge(m, src) -} -func (m *EventActivateBTCDelegation) XXX_Size() int { - return m.Size() -} -func (m *EventActivateBTCDelegation) XXX_DiscardUnknown() { - xxx_messageInfo_EventActivateBTCDelegation.DiscardUnknown(m) -} - -var xxx_messageInfo_EventActivateBTCDelegation proto.InternalMessageInfo - -func (m *EventActivateBTCDelegation) GetBtcDel() *BTCDelegation { - if m != nil { - return m.BtcDel - } - return nil -} - -// EventUnbondingBTCDelegation is the event emitted when an unbonding BTC delegation -// receives all signatures needed for becoming unbonded -type EventUnbondedBTCDelegation struct { - // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation - // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that - // this BTC delegation delegates to - // If there is more than 1 PKs, then this means the delegation is restaked - // to multiple finality providers - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` +// EventBTCDelegationStateUpdate is the event emitted when a BTC delegation's state is +// updated. There are the following possible state transitions: +// - non-existing -> pending, which happens upon `MsgCreateBTCDelegation` +// - pending -> active, which happens upon `MsgAddCovenantSigs` +// - active -> unbonded, which happens upon `MsgBTCUndelegate` or upon staking tx timelock expires +type EventBTCDelegationStateUpdate struct { // staking_tx_hash is the hash of the staking tx. - // (fp_pks..., del_pk, staking_tx_hash) uniquely identifies a BTC delegation - StakingTxHash string `protobuf:"bytes,3,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` - // unbonding_tx_hash is the hash of the unbonding tx. - UnbondingTxHash string `protobuf:"bytes,4,opt,name=unbonding_tx_hash,json=unbondingTxHash,proto3" json:"unbonding_tx_hash,omitempty"` - // from_state is the last state the BTC delegation was at - FromState BTCDelegationStatus `protobuf:"varint,5,opt,name=from_state,json=fromState,proto3,enum=babylon.btcstaking.v1.BTCDelegationStatus" json:"from_state,omitempty"` + // It uniquely identifies a BTC delegation + StakingTxHash string `protobuf:"bytes,1,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` + // new_state is the new state of this BTC delegation + NewState BTCDelegationStatus `protobuf:"varint,2,opt,name=new_state,json=newState,proto3,enum=babylon.btcstaking.v1.BTCDelegationStatus" json:"new_state,omitempty"` } -func (m *EventUnbondedBTCDelegation) Reset() { *m = EventUnbondedBTCDelegation{} } -func (m *EventUnbondedBTCDelegation) String() string { return proto.CompactTextString(m) } -func (*EventUnbondedBTCDelegation) ProtoMessage() {} -func (*EventUnbondedBTCDelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_74118427820fff75, []int{3} +func (m *EventBTCDelegationStateUpdate) Reset() { *m = EventBTCDelegationStateUpdate{} } +func (m *EventBTCDelegationStateUpdate) String() string { return proto.CompactTextString(m) } +func (*EventBTCDelegationStateUpdate) ProtoMessage() {} +func (*EventBTCDelegationStateUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_74118427820fff75, []int{1} } -func (m *EventUnbondedBTCDelegation) XXX_Unmarshal(b []byte) error { +func (m *EventBTCDelegationStateUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *EventUnbondedBTCDelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *EventBTCDelegationStateUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_EventUnbondedBTCDelegation.Marshal(b, m, deterministic) + return xxx_messageInfo_EventBTCDelegationStateUpdate.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -203,35 +101,28 @@ func (m *EventUnbondedBTCDelegation) XXX_Marshal(b []byte, deterministic bool) ( return b[:n], nil } } -func (m *EventUnbondedBTCDelegation) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventUnbondedBTCDelegation.Merge(m, src) +func (m *EventBTCDelegationStateUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventBTCDelegationStateUpdate.Merge(m, src) } -func (m *EventUnbondedBTCDelegation) XXX_Size() int { +func (m *EventBTCDelegationStateUpdate) XXX_Size() int { return m.Size() } -func (m *EventUnbondedBTCDelegation) XXX_DiscardUnknown() { - xxx_messageInfo_EventUnbondedBTCDelegation.DiscardUnknown(m) +func (m *EventBTCDelegationStateUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_EventBTCDelegationStateUpdate.DiscardUnknown(m) } -var xxx_messageInfo_EventUnbondedBTCDelegation proto.InternalMessageInfo +var xxx_messageInfo_EventBTCDelegationStateUpdate proto.InternalMessageInfo -func (m *EventUnbondedBTCDelegation) GetStakingTxHash() string { +func (m *EventBTCDelegationStateUpdate) GetStakingTxHash() string { if m != nil { return m.StakingTxHash } return "" } -func (m *EventUnbondedBTCDelegation) GetUnbondingTxHash() string { +func (m *EventBTCDelegationStateUpdate) GetNewState() BTCDelegationStatus { if m != nil { - return m.UnbondingTxHash - } - return "" -} - -func (m *EventUnbondedBTCDelegation) GetFromState() BTCDelegationStatus { - if m != nil { - return m.FromState + return m.NewState } return BTCDelegationStatus_PENDING } @@ -248,7 +139,7 @@ func (m *EventSelectiveSlashing) Reset() { *m = EventSelectiveSlashing{} func (m *EventSelectiveSlashing) String() string { return proto.CompactTextString(m) } func (*EventSelectiveSlashing) ProtoMessage() {} func (*EventSelectiveSlashing) Descriptor() ([]byte, []int) { - return fileDescriptor_74118427820fff75, []int{4} + return fileDescriptor_74118427820fff75, []int{2} } func (m *EventSelectiveSlashing) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -286,9 +177,7 @@ func (m *EventSelectiveSlashing) GetEvidence() *SelectiveSlashingEvidence { func init() { proto.RegisterType((*EventNewFinalityProvider)(nil), "babylon.btcstaking.v1.EventNewFinalityProvider") - proto.RegisterType((*EventNewBTCDelegation)(nil), "babylon.btcstaking.v1.EventNewBTCDelegation") - proto.RegisterType((*EventActivateBTCDelegation)(nil), "babylon.btcstaking.v1.EventActivateBTCDelegation") - proto.RegisterType((*EventUnbondedBTCDelegation)(nil), "babylon.btcstaking.v1.EventUnbondedBTCDelegation") + proto.RegisterType((*EventBTCDelegationStateUpdate)(nil), "babylon.btcstaking.v1.EventBTCDelegationStateUpdate") proto.RegisterType((*EventSelectiveSlashing)(nil), "babylon.btcstaking.v1.EventSelectiveSlashing") } @@ -297,37 +186,28 @@ func init() { } var fileDescriptor_74118427820fff75 = []byte{ - // 469 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x41, 0x6f, 0xd3, 0x30, - 0x18, 0x86, 0x9b, 0x8e, 0x0d, 0xe6, 0xc1, 0x26, 0x22, 0x86, 0xa2, 0x1e, 0x42, 0x15, 0xa1, 0x51, - 0xed, 0x90, 0x6c, 0x1d, 0x82, 0x13, 0x07, 0xc2, 0x86, 0x98, 0x28, 0xa8, 0x4a, 0x07, 0x07, 0x76, - 0x88, 0xec, 0xf4, 0x4b, 0x62, 0x35, 0xb3, 0xa3, 0xfa, 0x6b, 0x68, 0xff, 0x05, 0x3f, 0x8b, 0xe3, - 0x8e, 0x88, 0x03, 0x42, 0xed, 0x81, 0xbf, 0x81, 0x92, 0x79, 0xa3, 0x83, 0x55, 0x20, 0xb1, 0x9b, - 0x93, 0x3c, 0xef, 0xf3, 0xc9, 0xaf, 0x63, 0xe2, 0x30, 0xca, 0x26, 0x99, 0x14, 0x1e, 0xc3, 0x48, - 0x21, 0x1d, 0x70, 0x91, 0x78, 0xc5, 0xae, 0x07, 0x05, 0x08, 0x54, 0x6e, 0x3e, 0x94, 0x28, 0xcd, - 0x4d, 0xcd, 0xb8, 0xbf, 0x18, 0xb7, 0xd8, 0x6d, 0xdc, 0x4b, 0x64, 0x22, 0x2b, 0xc2, 0x2b, 0x57, - 0x67, 0x70, 0x63, 0xeb, 0x6a, 0xe1, 0x5c, 0xb4, 0xe2, 0x9c, 0x1e, 0xb1, 0x0e, 0xca, 0x21, 0x6f, - 0xe1, 0xe3, 0x4b, 0x2e, 0x68, 0xc6, 0x71, 0xd2, 0x1d, 0xca, 0x82, 0xf7, 0x61, 0x68, 0x3e, 0x25, - 0xf5, 0x38, 0xb7, 0x8c, 0xa6, 0xd1, 0x5a, 0x6b, 0x3f, 0x72, 0xaf, 0x9c, 0xee, 0xfe, 0x1e, 0x0a, - 0xea, 0x71, 0xee, 0xbc, 0x27, 0x9b, 0xe7, 0x52, 0xff, 0xe8, 0xc5, 0x3e, 0x64, 0x90, 0x50, 0xe4, - 0x52, 0x98, 0xcf, 0xc8, 0x4d, 0x86, 0x51, 0xd8, 0x87, 0x4c, 0x6b, 0x1f, 0x2e, 0xd0, 0x5e, 0x8a, - 0x05, 0x2b, 0x0c, 0xa3, 0x7d, 0xc8, 0x9c, 0x63, 0xd2, 0xa8, 0xbc, 0xcf, 0x23, 0xe4, 0x05, 0x45, - 0xb8, 0x56, 0xf9, 0x8f, 0xba, 0xb6, 0xbf, 0x13, 0x4c, 0x8a, 0x3e, 0xf4, 0x2f, 0xdb, 0xdf, 0x90, - 0x12, 0x0c, 0xf3, 0x41, 0x25, 0xbf, 0xed, 0x3f, 0xf9, 0xfa, 0xed, 0x41, 0x3b, 0xe1, 0x98, 0x8e, - 0x98, 0x1b, 0xc9, 0x13, 0x4f, 0x8f, 0x8a, 0x52, 0xca, 0xc5, 0xf9, 0x83, 0x87, 0x93, 0x1c, 0x94, - 0xeb, 0x1f, 0x76, 0xf7, 0x1e, 0xef, 0x74, 0x47, 0xec, 0x35, 0x4c, 0x82, 0x65, 0x86, 0x51, 0x77, - 0x60, 0x1e, 0x93, 0xf5, 0x38, 0x0f, 0xcf, 0x8c, 0x61, 0xc6, 0x15, 0x5a, 0xf5, 0xe6, 0xd2, 0x7f, - 0x68, 0xd7, 0xe2, 0xdc, 0x2f, 0xc5, 0x1d, 0xae, 0xd0, 0xdc, 0x22, 0x1b, 0x7a, 0xbb, 0x21, 0x8e, - 0xc3, 0x94, 0xaa, 0xd4, 0x5a, 0x6a, 0x1a, 0xad, 0xd5, 0xe0, 0x8e, 0x7e, 0x7d, 0x34, 0x7e, 0x45, - 0x55, 0x6a, 0x6e, 0x93, 0xbb, 0xa3, 0x6a, 0xb3, 0xf3, 0xe4, 0x8d, 0x8a, 0xdc, 0xb8, 0xf8, 0xa0, - 0xd9, 0x43, 0x42, 0xe2, 0xa1, 0x3c, 0x09, 0x15, 0x52, 0x04, 0x6b, 0xb9, 0x69, 0xb4, 0xd6, 0xdb, - 0xdb, 0xff, 0x52, 0x70, 0x0f, 0x29, 0x8e, 0x54, 0xb0, 0x5a, 0xa6, 0xcb, 0x35, 0x38, 0x31, 0xb9, - 0x5f, 0x15, 0xdd, 0x83, 0x0c, 0xca, 0x93, 0x84, 0x5e, 0x46, 0x55, 0xca, 0x45, 0x62, 0x76, 0xc8, - 0x2d, 0x28, 0x7f, 0x23, 0x11, 0x81, 0x3e, 0xc3, 0x9d, 0x05, 0x23, 0xfe, 0xc8, 0x1e, 0xe8, 0x5c, - 0x70, 0x61, 0xf0, 0x3b, 0x9f, 0xa7, 0xb6, 0x71, 0x3a, 0xb5, 0x8d, 0xef, 0x53, 0xdb, 0xf8, 0x34, - 0xb3, 0x6b, 0xa7, 0x33, 0xbb, 0xf6, 0x65, 0x66, 0xd7, 0x3e, 0xfc, 0xb5, 0xe1, 0xf1, 0xfc, 0xbd, - 0xa9, 0xea, 0x66, 0x2b, 0xd5, 0x85, 0xd9, 0xfb, 0x19, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x88, 0x9f, - 0xc0, 0xab, 0x03, 0x00, 0x00, + // 325 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4e, 0xf2, 0x40, + 0x14, 0x85, 0x19, 0x16, 0x7f, 0x60, 0xfe, 0xa8, 0x49, 0x13, 0x0d, 0x31, 0xb1, 0x21, 0x5d, 0x20, + 0x71, 0xd1, 0x0a, 0x2e, 0xdc, 0xa3, 0xa8, 0x0b, 0x62, 0x4c, 0x8b, 0x1b, 0x37, 0x64, 0x5a, 0x2e, + 0xed, 0xc4, 0x3a, 0xd3, 0x30, 0x97, 0x02, 0x6f, 0xc1, 0x63, 0xb9, 0x64, 0xe9, 0xd2, 0xc0, 0x8b, + 0x98, 0x4e, 0x46, 0x25, 0x02, 0xcb, 0x36, 0xe7, 0x3b, 0xdf, 0x99, 0x5c, 0xea, 0x84, 0x2c, 0x9c, + 0xa7, 0x52, 0x78, 0x21, 0x46, 0x0a, 0xd9, 0x2b, 0x17, 0xb1, 0x97, 0xb7, 0x3c, 0xc8, 0x41, 0xa0, + 0x72, 0xb3, 0xb1, 0x44, 0x69, 0x1d, 0x9b, 0x8c, 0xfb, 0x9b, 0x71, 0xf3, 0xd6, 0x69, 0x63, 0x37, + 0xba, 0x11, 0xd2, 0xb8, 0x13, 0xd0, 0x5a, 0xb7, 0xa8, 0x7b, 0x84, 0xe9, 0x1d, 0x17, 0x2c, 0xe5, + 0x38, 0x7f, 0x1a, 0xcb, 0x9c, 0x0f, 0x61, 0x6c, 0x5d, 0xd3, 0xf2, 0x28, 0xab, 0x91, 0x3a, 0x69, + 0xfe, 0x6f, 0x9f, 0xbb, 0x3b, 0x3d, 0xee, 0x5f, 0xc8, 0x2f, 0x8f, 0x32, 0x67, 0x41, 0xe8, 0x99, + 0x6e, 0xed, 0xf4, 0x6f, 0x6e, 0x21, 0x85, 0x98, 0x21, 0x97, 0x22, 0x40, 0x86, 0xf0, 0x9c, 0x0d, + 0x19, 0x82, 0xd5, 0xa0, 0x47, 0xa6, 0x64, 0x80, 0xb3, 0x41, 0xc2, 0x54, 0xa2, 0x3d, 0x55, 0xff, + 0xc0, 0xfc, 0xee, 0xcf, 0x1e, 0x98, 0x4a, 0xac, 0x7b, 0x5a, 0x15, 0x30, 0x1d, 0xa8, 0x02, 0xad, + 0x95, 0xeb, 0xa4, 0x79, 0xd8, 0xbe, 0xd8, 0xb3, 0x64, 0xcb, 0x35, 0x51, 0x7e, 0x45, 0xc0, 0x54, + 0x6b, 0x9d, 0x11, 0x3d, 0xd1, 0x8b, 0x02, 0x48, 0x21, 0x42, 0x9e, 0x43, 0x90, 0x32, 0x95, 0x70, + 0x11, 0x5b, 0x3d, 0x5a, 0x81, 0x62, 0xba, 0x88, 0xc0, 0xbc, 0xf5, 0x72, 0x8f, 0x61, 0x8b, 0xed, + 0x1a, 0xce, 0xff, 0x69, 0xe8, 0xf4, 0xde, 0x57, 0x36, 0x59, 0xae, 0x6c, 0xf2, 0xb9, 0xb2, 0xc9, + 0x62, 0x6d, 0x97, 0x96, 0x6b, 0xbb, 0xf4, 0xb1, 0xb6, 0x4b, 0x2f, 0xed, 0x98, 0x63, 0x32, 0x09, + 0xdd, 0x48, 0xbe, 0x79, 0xa6, 0x3f, 0x4a, 0x18, 0x17, 0xdf, 0x1f, 0xde, 0x6c, 0xf3, 0x56, 0x38, + 0xcf, 0x40, 0x85, 0xff, 0xf4, 0x91, 0xae, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xa5, 0x51, + 0x18, 0x09, 0x02, 0x00, 0x00, } func (m *EventNewFinalityProvider) Marshal() (dAtA []byte, err error) { @@ -365,7 +245,7 @@ func (m *EventNewFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } -func (m *EventNewBTCDelegation) Marshal() (dAtA []byte, err error) { +func (m *EventBTCDelegationStateUpdate) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -375,129 +255,26 @@ func (m *EventNewBTCDelegation) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *EventNewBTCDelegation) MarshalTo(dAtA []byte) (int, error) { +func (m *EventBTCDelegationStateUpdate) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *EventNewBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *EventBTCDelegationStateUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.BtcDel != nil { - { - size, err := m.BtcDel.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } + if m.NewState != 0 { + i = encodeVarintEvents(dAtA, i, uint64(m.NewState)) i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *EventActivateBTCDelegation) 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 *EventActivateBTCDelegation) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *EventActivateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.BtcDel != nil { - { - size, err := m.BtcDel.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *EventUnbondedBTCDelegation) 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 *EventUnbondedBTCDelegation) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *EventUnbondedBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.FromState != 0 { - i = encodeVarintEvents(dAtA, i, uint64(m.FromState)) - i-- - dAtA[i] = 0x28 - } - if len(m.UnbondingTxHash) > 0 { - i -= len(m.UnbondingTxHash) - copy(dAtA[i:], m.UnbondingTxHash) - i = encodeVarintEvents(dAtA, i, uint64(len(m.UnbondingTxHash))) - i-- - dAtA[i] = 0x22 + dAtA[i] = 0x10 } if len(m.StakingTxHash) > 0 { i -= len(m.StakingTxHash) copy(dAtA[i:], m.StakingTxHash) i = encodeVarintEvents(dAtA, i, uint64(len(m.StakingTxHash))) i-- - dAtA[i] = 0x1a - } - if len(m.FpBtcPkList) > 0 { - for iNdEx := len(m.FpBtcPkList) - 1; iNdEx >= 0; iNdEx-- { - { - size := m.FpBtcPkList[iNdEx].Size() - i -= size - if _, err := m.FpBtcPkList[iNdEx].MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.BtcPk != nil { - { - size := m.BtcPk.Size() - i -= size - if _, err := m.BtcPk.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintEvents(dAtA, i, uint64(size)) - } - i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -562,58 +339,18 @@ func (m *EventNewFinalityProvider) Size() (n int) { return n } -func (m *EventNewBTCDelegation) Size() (n int) { +func (m *EventBTCDelegationStateUpdate) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.BtcDel != nil { - l = m.BtcDel.Size() - n += 1 + l + sovEvents(uint64(l)) - } - return n -} - -func (m *EventActivateBTCDelegation) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BtcDel != nil { - l = m.BtcDel.Size() - n += 1 + l + sovEvents(uint64(l)) - } - return n -} - -func (m *EventUnbondedBTCDelegation) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BtcPk != nil { - l = m.BtcPk.Size() - n += 1 + l + sovEvents(uint64(l)) - } - if len(m.FpBtcPkList) > 0 { - for _, e := range m.FpBtcPkList { - l = e.Size() - n += 1 + l + sovEvents(uint64(l)) - } - } l = len(m.StakingTxHash) if l > 0 { n += 1 + l + sovEvents(uint64(l)) } - l = len(m.UnbondingTxHash) - if l > 0 { - n += 1 + l + sovEvents(uint64(l)) - } - if m.FromState != 0 { - n += 1 + sovEvents(uint64(m.FromState)) + if m.NewState != 0 { + n += 1 + sovEvents(uint64(m.NewState)) } return n } @@ -723,93 +460,7 @@ func (m *EventNewFinalityProvider) Unmarshal(dAtA []byte) error { } return nil } -func (m *EventNewBTCDelegation) 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 ErrIntOverflowEvents - } - 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: EventNewBTCDelegation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: EventNewBTCDelegation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BtcDel", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.BtcDel == nil { - m.BtcDel = &BTCDelegation{} - } - if err := m.BtcDel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *EventActivateBTCDelegation) Unmarshal(dAtA []byte) error { +func (m *EventBTCDelegationStateUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -832,169 +483,13 @@ func (m *EventActivateBTCDelegation) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: EventActivateBTCDelegation: wiretype end group for non-group") + return fmt.Errorf("proto: EventBTCDelegationStateUpdate: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: EventActivateBTCDelegation: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventBTCDelegationStateUpdate: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BtcDel", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.BtcDel == nil { - m.BtcDel = &BTCDelegation{} - } - if err := m.BtcDel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEvents(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEvents - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *EventUnbondedBTCDelegation) 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 ErrIntOverflowEvents - } - 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: EventUnbondedBTCDelegation: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: EventUnbondedBTCDelegation: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.BIP340PubKey - m.BtcPk = &v - if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkList", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthEvents - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.BIP340PubKey - m.FpBtcPkList = append(m.FpBtcPkList, v) - if err := m.FpBtcPkList[len(m.FpBtcPkList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StakingTxHash", wireType) } @@ -1026,43 +521,11 @@ func (m *EventUnbondedBTCDelegation) Unmarshal(dAtA []byte) error { } m.StakingTxHash = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTxHash", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEvents - } - 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 ErrInvalidLengthEvents - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthEvents - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UnbondingTxHash = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: + case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field FromState", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NewState", wireType) } - m.FromState = 0 + m.NewState = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowEvents @@ -1072,7 +535,7 @@ func (m *EventUnbondedBTCDelegation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.FromState |= BTCDelegationStatus(b&0x7F) << shift + m.NewState |= BTCDelegationStatus(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 6b2d9dd9f..3989659a8 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -5,39 +5,39 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func NewRewardDistCache() *RewardDistCache { - return &RewardDistCache{ +func NewVotingPowerDistCache() *VotingPowerDistCache { + return &VotingPowerDistCache{ TotalVotingPower: 0, FinalityProviders: []*FinalityProviderDistInfo{}, } } -func (rdc *RewardDistCache) AddFinalityProviderDistInfo(v *FinalityProviderDistInfo) { +func (dc *VotingPowerDistCache) AddFinalityProviderDistInfo(v *FinalityProviderDistInfo) { if v.TotalVotingPower > 0 { // append finality provider dist info and accumulate voting power - rdc.FinalityProviders = append(rdc.FinalityProviders, v) - rdc.TotalVotingPower += v.TotalVotingPower + dc.FinalityProviders = append(dc.FinalityProviders, v) + dc.TotalVotingPower += v.TotalVotingPower } } // FilterVotedFinalityProviders filters out finality providers that have voted according to a map of given voters // and update total voted power accordingly -func (rdc *RewardDistCache) FilterVotedFinalityProviders(voterBTCPKs map[string]struct{}) { +func (dc *VotingPowerDistCache) FilterVotedFinalityProviders(voterBTCPKs map[string]struct{}) { filteredFps := []*FinalityProviderDistInfo{} totalVotingPower := uint64(0) - for _, v := range rdc.FinalityProviders { + for _, v := range dc.FinalityProviders { if _, ok := voterBTCPKs[v.BtcPk.MarshalHex()]; ok { filteredFps = append(filteredFps, v) totalVotingPower += v.TotalVotingPower } } - rdc.FinalityProviders = filteredFps - rdc.TotalVotingPower = totalVotingPower + dc.FinalityProviders = filteredFps + dc.TotalVotingPower = totalVotingPower } // GetFinalityProviderPortion returns the portion of a finality provider's voting power out of the total voting power -func (rdc *RewardDistCache) GetFinalityProviderPortion(v *FinalityProviderDistInfo) sdkmath.LegacyDec { - return sdkmath.LegacyNewDec(int64(v.TotalVotingPower)).QuoTruncate(sdkmath.LegacyNewDec(int64(rdc.TotalVotingPower))) +func (dc *VotingPowerDistCache) GetFinalityProviderPortion(v *FinalityProviderDistInfo) sdkmath.LegacyDec { + return sdkmath.LegacyNewDec(int64(v.TotalVotingPower)).QuoTruncate(sdkmath.LegacyNewDec(int64(dc.TotalVotingPower))) } func NewFinalityProviderDistInfo(fp *FinalityProvider) *FinalityProviderDistInfo { @@ -56,6 +56,7 @@ func (v *FinalityProviderDistInfo) GetAddress() sdk.AccAddress { func (v *FinalityProviderDistInfo) AddBTCDel(btcDel *BTCDelegation, btcHeight uint64, wValue uint64, covenantQuorum uint32) { btcDelDistInfo := &BTCDelDistInfo{ + BtcPk: btcDel.BtcPk, BabylonPk: btcDel.BabylonPk, VotingPower: btcDel.VotingPower(btcHeight, wValue, covenantQuorum), } diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index 2ecf02d12..48719ac37 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -27,25 +27,26 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// RewardDistCache is the cache for reward distribution of finality providers at a height -type RewardDistCache struct { +// VotingPowerDistCache is the cache for voting power distribution of finality providers +// and their BTC delegations at a height +type VotingPowerDistCache struct { TotalVotingPower uint64 `protobuf:"varint,1,opt,name=total_voting_power,json=totalVotingPower,proto3" json:"total_voting_power,omitempty"` // finality_providers is a list of finality providers' voting power information FinalityProviders []*FinalityProviderDistInfo `protobuf:"bytes,2,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` } -func (m *RewardDistCache) Reset() { *m = RewardDistCache{} } -func (m *RewardDistCache) String() string { return proto.CompactTextString(m) } -func (*RewardDistCache) ProtoMessage() {} -func (*RewardDistCache) Descriptor() ([]byte, []int) { +func (m *VotingPowerDistCache) Reset() { *m = VotingPowerDistCache{} } +func (m *VotingPowerDistCache) String() string { return proto.CompactTextString(m) } +func (*VotingPowerDistCache) ProtoMessage() {} +func (*VotingPowerDistCache) Descriptor() ([]byte, []int) { return fileDescriptor_ac354c3bd6d7a66b, []int{0} } -func (m *RewardDistCache) XXX_Unmarshal(b []byte) error { +func (m *VotingPowerDistCache) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *RewardDistCache) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *VotingPowerDistCache) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_RewardDistCache.Marshal(b, m, deterministic) + return xxx_messageInfo_VotingPowerDistCache.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -55,26 +56,26 @@ func (m *RewardDistCache) XXX_Marshal(b []byte, deterministic bool) ([]byte, err return b[:n], nil } } -func (m *RewardDistCache) XXX_Merge(src proto.Message) { - xxx_messageInfo_RewardDistCache.Merge(m, src) +func (m *VotingPowerDistCache) XXX_Merge(src proto.Message) { + xxx_messageInfo_VotingPowerDistCache.Merge(m, src) } -func (m *RewardDistCache) XXX_Size() int { +func (m *VotingPowerDistCache) XXX_Size() int { return m.Size() } -func (m *RewardDistCache) XXX_DiscardUnknown() { - xxx_messageInfo_RewardDistCache.DiscardUnknown(m) +func (m *VotingPowerDistCache) XXX_DiscardUnknown() { + xxx_messageInfo_VotingPowerDistCache.DiscardUnknown(m) } -var xxx_messageInfo_RewardDistCache proto.InternalMessageInfo +var xxx_messageInfo_VotingPowerDistCache proto.InternalMessageInfo -func (m *RewardDistCache) GetTotalVotingPower() uint64 { +func (m *VotingPowerDistCache) GetTotalVotingPower() uint64 { if m != nil { return m.TotalVotingPower } return 0 } -func (m *RewardDistCache) GetFinalityProviders() []*FinalityProviderDistInfo { +func (m *VotingPowerDistCache) GetFinalityProviders() []*FinalityProviderDistInfo { if m != nil { return m.FinalityProviders } @@ -152,10 +153,13 @@ func (m *FinalityProviderDistInfo) GetBtcDels() []*BTCDelDistInfo { // BTCDelDistInfo contains the information related to reward distribution for a BTC delegations type BTCDelDistInfo struct { + // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation + // the PK follows encoding in BIP-340 spec + BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // babylon_pk is the Babylon public key of the BTC delegations - BabylonPk *secp256k1.PubKey `protobuf:"bytes,1,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + BabylonPk *secp256k1.PubKey `protobuf:"bytes,2,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` // voting_power is the voting power of the BTC delegation - VotingPower uint64 `protobuf:"varint,2,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } func (m *BTCDelDistInfo) Reset() { *m = BTCDelDistInfo{} } @@ -206,7 +210,7 @@ func (m *BTCDelDistInfo) GetVotingPower() uint64 { } func init() { - proto.RegisterType((*RewardDistCache)(nil), "babylon.btcstaking.v1.RewardDistCache") + proto.RegisterType((*VotingPowerDistCache)(nil), "babylon.btcstaking.v1.VotingPowerDistCache") proto.RegisterType((*FinalityProviderDistInfo)(nil), "babylon.btcstaking.v1.FinalityProviderDistInfo") proto.RegisterType((*BTCDelDistInfo)(nil), "babylon.btcstaking.v1.BTCDelDistInfo") } @@ -216,41 +220,41 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 491 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xcb, 0x6e, 0xd3, 0x40, - 0x14, 0x86, 0xe3, 0xf4, 0x02, 0x9d, 0x54, 0x5c, 0x2c, 0x90, 0x4c, 0x91, 0x9c, 0x10, 0xa9, 0x52, - 0x16, 0x74, 0x86, 0xa4, 0xd0, 0x25, 0x42, 0xae, 0x85, 0x54, 0xd1, 0x4a, 0x96, 0x85, 0x58, 0xb0, - 0x20, 0x9a, 0x99, 0x4c, 0x9c, 0x91, 0xed, 0x19, 0xcb, 0x33, 0x75, 0xf1, 0x5b, 0xf0, 0x06, 0xbc, - 0x04, 0x0f, 0xc1, 0xb2, 0x62, 0x85, 0xba, 0xa8, 0x50, 0xb2, 0xe1, 0x31, 0x90, 0xed, 0xa1, 0x37, - 0x11, 0xa1, 0xee, 0x72, 0xf2, 0xff, 0xe7, 0x9c, 0xdf, 0xdf, 0xb1, 0xc1, 0x36, 0xc1, 0xa4, 0x4c, - 0xa4, 0x40, 0x44, 0x53, 0xa5, 0x71, 0xcc, 0x45, 0x84, 0x8a, 0x21, 0xe2, 0x82, 0x32, 0xa1, 0x79, - 0xc1, 0x60, 0x96, 0x4b, 0x2d, 0xed, 0xc7, 0xc6, 0x06, 0x2f, 0x6d, 0xb0, 0x18, 0x6e, 0x3d, 0x8a, - 0x64, 0x24, 0x6b, 0x07, 0xaa, 0x7e, 0x35, 0xe6, 0xad, 0x27, 0x54, 0xaa, 0x54, 0xaa, 0x71, 0x23, - 0x34, 0x85, 0x91, 0xfa, 0x4d, 0x85, 0x68, 0x5e, 0x66, 0x5a, 0x22, 0xc5, 0x68, 0x36, 0x7a, 0xb5, - 0x17, 0x0f, 0x51, 0xcc, 0x4a, 0xe3, 0xe9, 0x7f, 0xb5, 0xc0, 0xfd, 0x90, 0x9d, 0xe0, 0x7c, 0xe2, - 0x73, 0xa5, 0xf7, 0x31, 0x9d, 0x31, 0xfb, 0x39, 0xb0, 0xb5, 0xd4, 0x38, 0x19, 0x17, 0x52, 0x73, - 0x11, 0x8d, 0x33, 0x79, 0xc2, 0x72, 0xc7, 0xea, 0x59, 0x83, 0xd5, 0xf0, 0x41, 0xad, 0x7c, 0xa8, - 0x85, 0xa0, 0xfa, 0xdf, 0xfe, 0x04, 0xec, 0x29, 0x17, 0x38, 0xe1, 0xba, 0xac, 0x42, 0x14, 0x7c, - 0xc2, 0x72, 0xe5, 0xb4, 0x7b, 0x2b, 0x83, 0xce, 0x08, 0xc1, 0x7f, 0x3e, 0x0a, 0x7c, 0x6b, 0x1a, - 0x02, 0xe3, 0xaf, 0x76, 0x1f, 0x88, 0xa9, 0x0c, 0x1f, 0x4e, 0x6f, 0x28, 0xaa, 0xff, 0xbb, 0x0d, - 0x9c, 0x65, 0x7e, 0xfb, 0x08, 0xac, 0x13, 0x4d, 0xc7, 0x59, 0x5c, 0xc7, 0xdb, 0xf4, 0xf6, 0xce, - 0xce, 0xbb, 0xa3, 0x88, 0xeb, 0xd9, 0x31, 0x81, 0x54, 0xa6, 0xc8, 0xac, 0xa7, 0x33, 0xcc, 0xc5, - 0xdf, 0x02, 0xe9, 0x32, 0x63, 0x0a, 0x7a, 0x07, 0xc1, 0xee, 0xcb, 0x17, 0xc1, 0x31, 0x79, 0xc7, - 0xca, 0x70, 0x8d, 0x68, 0x1a, 0xc4, 0xf6, 0x6b, 0x00, 0x8c, 0xa9, 0x1a, 0xd9, 0xee, 0x59, 0x83, - 0xce, 0xa8, 0x0b, 0x0d, 0xd4, 0x06, 0x23, 0xbc, 0xc0, 0x08, 0x4d, 0xef, 0x86, 0x69, 0x09, 0x62, - 0xfb, 0x08, 0x00, 0x2a, 0xd3, 0x94, 0x2b, 0xc5, 0xa5, 0x70, 0x56, 0x7a, 0xd6, 0x60, 0xc3, 0xdb, - 0x39, 0x3b, 0xef, 0x3e, 0x6d, 0x46, 0xa8, 0x49, 0x0c, 0xb9, 0x44, 0x29, 0xd6, 0x33, 0x78, 0xc8, - 0x22, 0x4c, 0x4b, 0x9f, 0xd1, 0x1f, 0xdf, 0x76, 0x80, 0xd9, 0xe0, 0x33, 0x1a, 0x5e, 0x19, 0xb0, - 0xe4, 0x10, 0xab, 0x4b, 0x0e, 0xf1, 0x06, 0xdc, 0xad, 0x58, 0x4c, 0x58, 0xa2, 0x9c, 0xb5, 0x1a, - 0xff, 0xf6, 0x12, 0xfc, 0xde, 0xfb, 0x7d, 0x9f, 0x25, 0x17, 0xd0, 0xef, 0x10, 0x4d, 0x7d, 0x96, - 0xa8, 0xbe, 0x02, 0xf7, 0xae, 0x4b, 0x37, 0x80, 0x58, 0xb7, 0x06, 0xf2, 0x0c, 0x6c, 0x5e, 0xcb, - 0xde, 0xae, 0xb3, 0x77, 0x8a, 0xcb, 0xd8, 0xde, 0xe1, 0xf7, 0xb9, 0x6b, 0x9d, 0xce, 0x5d, 0xeb, - 0xd7, 0xdc, 0xb5, 0xbe, 0x2c, 0xdc, 0xd6, 0xe9, 0xc2, 0x6d, 0xfd, 0x5c, 0xb8, 0xad, 0x8f, 0xff, - 0x3d, 0xe4, 0xe7, 0xab, 0x1f, 0x52, 0x7d, 0x55, 0xb2, 0x5e, 0xbf, 0xd6, 0xbb, 0x7f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0xef, 0xcd, 0x33, 0x90, 0x6b, 0x03, 0x00, 0x00, -} - -func (m *RewardDistCache) Marshal() (dAtA []byte, err error) { + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0xc1, 0x6e, 0xd3, 0x30, + 0x18, 0xc7, 0xeb, 0x76, 0x1b, 0xcc, 0x9d, 0x10, 0x44, 0x43, 0x0a, 0x43, 0x4a, 0x4b, 0xa5, 0x49, + 0x3d, 0x30, 0x9b, 0x76, 0xb0, 0x23, 0x42, 0x59, 0x84, 0x34, 0xb1, 0x49, 0x51, 0x85, 0x38, 0x70, + 0xa0, 0x8a, 0x5d, 0x37, 0xb5, 0x92, 0xd8, 0x51, 0xed, 0x05, 0xf2, 0x16, 0x3c, 0x04, 0x8f, 0xc0, + 0x13, 0x70, 0xe2, 0x38, 0x71, 0x42, 0x3b, 0x4c, 0xa8, 0xbd, 0xf0, 0x18, 0x28, 0x89, 0xd9, 0x5a, + 0x44, 0xc4, 0x95, 0x9b, 0x3f, 0xfd, 0xff, 0xff, 0xef, 0xfb, 0xfc, 0xb3, 0x0c, 0xf7, 0x49, 0x40, + 0xf2, 0x58, 0x0a, 0x4c, 0x34, 0x55, 0x3a, 0x88, 0xb8, 0x08, 0x71, 0x36, 0xc0, 0x5c, 0x50, 0x26, + 0x34, 0xcf, 0x18, 0x4a, 0xe7, 0x52, 0x4b, 0xeb, 0xbe, 0xb1, 0xa1, 0x1b, 0x1b, 0xca, 0x06, 0x7b, + 0xbb, 0xa1, 0x0c, 0x65, 0xe9, 0xc0, 0xc5, 0xa9, 0x32, 0xef, 0x3d, 0xa0, 0x52, 0x25, 0x52, 0x8d, + 0x2b, 0xa1, 0x2a, 0x8c, 0xd4, 0xab, 0x2a, 0x4c, 0xe7, 0x79, 0xaa, 0x25, 0x56, 0x8c, 0xa6, 0xc3, + 0x67, 0x47, 0xd1, 0x00, 0x47, 0x2c, 0x37, 0x9e, 0xde, 0x27, 0x00, 0x77, 0xdf, 0x48, 0xcd, 0x45, + 0xe8, 0xcb, 0xf7, 0x6c, 0xee, 0x71, 0xa5, 0x8f, 0x03, 0x3a, 0x63, 0xd6, 0x63, 0x68, 0x69, 0xa9, + 0x83, 0x78, 0x9c, 0x95, 0xea, 0x38, 0x2d, 0x64, 0x1b, 0x74, 0x41, 0x7f, 0x63, 0x74, 0xb7, 0x54, + 0x56, 0x62, 0xd6, 0x3b, 0x68, 0x4d, 0xb9, 0x08, 0x62, 0xae, 0xf3, 0x62, 0x93, 0x8c, 0x4f, 0xd8, + 0x5c, 0xd9, 0xcd, 0x6e, 0xab, 0xdf, 0x1e, 0x62, 0xf4, 0xd7, 0xfb, 0xa0, 0x97, 0x26, 0xe0, 0x1b, + 0x7f, 0x31, 0xfb, 0x44, 0x4c, 0xe5, 0xe8, 0xde, 0xf4, 0x0f, 0x45, 0xf5, 0x7e, 0x36, 0xa1, 0x5d, + 0xe7, 0xb7, 0xce, 0xe0, 0x16, 0xd1, 0x74, 0x9c, 0x46, 0xe5, 0x7a, 0x3b, 0xee, 0xd1, 0xe5, 0x55, + 0x67, 0x18, 0x72, 0x3d, 0x3b, 0x27, 0x88, 0xca, 0x04, 0x9b, 0xf1, 0x74, 0x16, 0x70, 0xf1, 0xbb, + 0xc0, 0x3a, 0x4f, 0x99, 0x42, 0xee, 0x89, 0x7f, 0xf8, 0xf4, 0x89, 0x7f, 0x4e, 0x5e, 0xb1, 0x7c, + 0xb4, 0x49, 0x34, 0xf5, 0x23, 0xeb, 0x39, 0x84, 0xc6, 0x54, 0xb4, 0x6c, 0x76, 0x41, 0xbf, 0x3d, + 0xec, 0x20, 0x43, 0xb6, 0x62, 0x89, 0xae, 0x59, 0x22, 0x93, 0xdd, 0x36, 0x11, 0x3f, 0xb2, 0xce, + 0x20, 0xa4, 0x32, 0x49, 0xb8, 0x52, 0x5c, 0x0a, 0xbb, 0xd5, 0x05, 0xfd, 0x6d, 0xf7, 0xe0, 0xf2, + 0xaa, 0xf3, 0xb0, 0x6a, 0xa1, 0x26, 0x11, 0xe2, 0x12, 0x27, 0x81, 0x9e, 0xa1, 0x53, 0x16, 0x06, + 0x34, 0xf7, 0x18, 0xfd, 0xf6, 0xf9, 0x00, 0x9a, 0x09, 0x1e, 0xa3, 0xa3, 0x95, 0x06, 0x35, 0x0f, + 0xb1, 0x51, 0xf3, 0x10, 0x2f, 0xe0, 0xed, 0x82, 0xc5, 0x84, 0xc5, 0xca, 0xde, 0x2c, 0xf1, 0xef, + 0xd7, 0xe0, 0x77, 0x5f, 0x1f, 0x7b, 0x2c, 0xbe, 0x86, 0x7e, 0x8b, 0x68, 0xea, 0xb1, 0x58, 0xf5, + 0xbe, 0x00, 0x78, 0x67, 0x5d, 0xfb, 0xdf, 0x00, 0x3f, 0x82, 0x3b, 0x6b, 0x2c, 0x5a, 0x25, 0x8b, + 0x76, 0x76, 0x83, 0xc1, 0x3d, 0xfd, 0xba, 0x70, 0xc0, 0xc5, 0xc2, 0x01, 0x3f, 0x16, 0x0e, 0xf8, + 0xb8, 0x74, 0x1a, 0x17, 0x4b, 0xa7, 0xf1, 0x7d, 0xe9, 0x34, 0xde, 0xfe, 0x73, 0xef, 0x0f, 0xab, + 0xbf, 0xb3, 0xbc, 0x04, 0xd9, 0x2a, 0xff, 0xca, 0xe1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, + 0x5e, 0x2e, 0x45, 0xc0, 0x03, 0x00, 0x00, +} + +func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -260,12 +264,12 @@ func (m *RewardDistCache) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *RewardDistCache) MarshalTo(dAtA []byte) (int, error) { +func (m *VotingPowerDistCache) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *RewardDistCache) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *VotingPowerDistCache) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -393,7 +397,7 @@ func (m *BTCDelDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.VotingPower != 0 { i = encodeVarintIncentive(dAtA, i, uint64(m.VotingPower)) i-- - dAtA[i] = 0x10 + dAtA[i] = 0x18 } if m.BabylonPk != nil { { @@ -405,6 +409,18 @@ func (m *BTCDelDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintIncentive(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x12 + } + if m.BtcPk != nil { + { + size := m.BtcPk.Size() + i -= size + if _, err := m.BtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintIncentive(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -421,7 +437,7 @@ func encodeVarintIncentive(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *RewardDistCache) Size() (n int) { +func (m *VotingPowerDistCache) Size() (n int) { if m == nil { return 0 } @@ -475,6 +491,10 @@ func (m *BTCDelDistInfo) Size() (n int) { } var l int _ = l + if m.BtcPk != nil { + l = m.BtcPk.Size() + n += 1 + l + sovIncentive(uint64(l)) + } if m.BabylonPk != nil { l = m.BabylonPk.Size() n += 1 + l + sovIncentive(uint64(l)) @@ -491,7 +511,7 @@ func sovIncentive(x uint64) (n int) { func sozIncentive(x uint64) (n int) { return sovIncentive(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *RewardDistCache) Unmarshal(dAtA []byte) error { +func (m *VotingPowerDistCache) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -514,10 +534,10 @@ func (m *RewardDistCache) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RewardDistCache: wiretype end group for non-group") + return fmt.Errorf("proto: VotingPowerDistCache: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RewardDistCache: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: VotingPowerDistCache: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -834,6 +854,41 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIncentive + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthIncentive + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthIncentive + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.BtcPk = &v + if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) } @@ -869,7 +924,7 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) } diff --git a/x/btcstaking/types/keys.go b/x/btcstaking/types/keys.go index 4f291ad14..49d1e7185 100644 --- a/x/btcstaking/types/keys.go +++ b/x/btcstaking/types/keys.go @@ -15,13 +15,13 @@ const ( ) var ( - ParamsKey = []byte{0x01} // key prefix for the parameters - FinalityProviderKey = []byte{0x02} // key prefix for the finality providers - BTCDelegatorKey = []byte{0x03} // key prefix for the BTC delegators - BTCDelegationKey = []byte{0x04} // key prefix for the BTC delegations - VotingPowerKey = []byte{0x05} // key prefix for the voting power - BTCHeightKey = []byte{0x06} // key prefix for the BTC heights - RewardDistCacheKey = []byte{0x07} // key prefix for reward distribution cache + ParamsKey = []byte{0x01} // key prefix for the parameters + FinalityProviderKey = []byte{0x02} // key prefix for the finality providers + BTCDelegatorKey = []byte{0x03} // key prefix for the BTC delegators + BTCDelegationKey = []byte{0x04} // key prefix for the BTC delegations + VotingPowerKey = []byte{0x05} // key prefix for the voting power + BTCHeightKey = []byte{0x06} // key prefix for the BTC heights + VotingPowerDistCacheKey = []byte{0x07} // key prefix for voting power distribution cache ) func KeyPrefix(p string) []byte { diff --git a/x/finality/keeper/tallying.go b/x/finality/keeper/tallying.go index 2b986b1a1..3bbe1cc0d 100644 --- a/x/finality/keeper/tallying.go +++ b/x/finality/keeper/tallying.go @@ -82,18 +82,18 @@ func (k Keeper) finalizeBlock(ctx context.Context, block *types.IndexedBlock, vo k.SetBlock(ctx, block) // set next height to finalise as height+1 k.setNextHeightToFinalize(ctx, block.Height+1) - // distribute rewards to BTC staking stakeholders w.r.t. the reward distribution cache - rdc, err := k.BTCStakingKeeper.GetRewardDistCache(ctx, block.Height) + // distribute rewards to BTC staking stakeholders w.r.t. the voting power distribution cache + dc, err := k.BTCStakingKeeper.GetVotingPowerDistCache(ctx, block.Height) if err != nil { - // failing to get a reward distribution cache before distributing reward is a programming error + // failing to get a voting power distribution cache before distributing reward is a programming error panic(err) } // filter out voted finality providers - rdc.FilterVotedFinalityProviders(voterBTCPKs) + dc.FilterVotedFinalityProviders(voterBTCPKs) // reward voted finality providers - k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, rdc) + k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, dc) // remove reward distribution cache afterwards - k.BTCStakingKeeper.RemoveRewardDistCache(ctx, block.Height) + k.BTCStakingKeeper.RemoveVotingPowerDistCache(ctx, block.Height) // record the last finalized height metric types.RecordLastFinalizedHeight(block.Height) } diff --git a/x/finality/keeper/tallying_bench_test.go b/x/finality/keeper/tallying_bench_test.go index 6155d58a8..1e93139d9 100644 --- a/x/finality/keeper/tallying_bench_test.go +++ b/x/finality/keeper/tallying_bench_test.go @@ -42,9 +42,9 @@ func benchmarkTallyBlocks(b *testing.B, numFPs int) { bsKeeper.EXPECT().GetVotingPowerTable(gomock.Any(), gomock.Any()).Return(fpSet).AnyTimes() // TODO: test incentive - bsKeeper.EXPECT().GetRewardDistCache(gomock.Any(), gomock.Any()).Return(bstypes.NewRewardDistCache(), nil).AnyTimes() + bsKeeper.EXPECT().GetVotingPowerDistCache(gomock.Any(), gomock.Any()).Return(bstypes.NewVotingPowerDistCache(), nil).AnyTimes() iKeeper.EXPECT().RewardBTCStaking(gomock.Any(), gomock.Any(), gomock.Any()).Return().AnyTimes() - bsKeeper.EXPECT().RemoveRewardDistCache(gomock.Any(), gomock.Any()).Return().AnyTimes() + bsKeeper.EXPECT().RemoveVotingPowerDistCache(gomock.Any(), gomock.Any()).Return().AnyTimes() // Start the CPU profiler cpuProfileFile := fmt.Sprintf("/tmp/finality-tally-blocks-%d-cpu.pprof", numFPs) f, err := os.Create(cpuProfileFile) diff --git a/x/finality/keeper/tallying_test.go b/x/finality/keeper/tallying_test.go index aa4af547a..448fcc58d 100644 --- a/x/finality/keeper/tallying_test.go +++ b/x/finality/keeper/tallying_test.go @@ -124,9 +124,9 @@ func FuzzTallying_FinalizingSomeBlocks(f *testing.F) { } } // we don't test incentive in this function - bsKeeper.EXPECT().GetRewardDistCache(gomock.Any(), gomock.Any()).Return(bstypes.NewRewardDistCache(), nil).Times(int(numWithQCs)) + bsKeeper.EXPECT().GetVotingPowerDistCache(gomock.Any(), gomock.Any()).Return(bstypes.NewVotingPowerDistCache(), nil).Times(int(numWithQCs)) iKeeper.EXPECT().RewardBTCStaking(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(int(numWithQCs)) - bsKeeper.EXPECT().RemoveRewardDistCache(gomock.Any(), gomock.Any()).Return().Times(int(numWithQCs)) + bsKeeper.EXPECT().RemoveVotingPowerDistCache(gomock.Any(), gomock.Any()).Return().Times(int(numWithQCs)) // add mock queries to GetBTCStakingActivatedHeight ctx = datagen.WithCtxHeight(ctx, activatedHeight+10-1) bsKeeper.EXPECT().GetBTCStakingActivatedHeight(gomock.Any()).Return(activatedHeight, nil).Times(1) diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index d13913622..ae4795b8f 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -13,11 +13,11 @@ type BTCStakingKeeper interface { GetVotingPower(ctx context.Context, fpBTCPK []byte, height uint64) uint64 GetVotingPowerTable(ctx context.Context, height uint64) map[string]uint64 GetBTCStakingActivatedHeight(ctx context.Context) (uint64, error) - GetRewardDistCache(ctx context.Context, height uint64) (*bstypes.RewardDistCache, error) - RemoveRewardDistCache(ctx context.Context, height uint64) + GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) + RemoveVotingPowerDistCache(ctx context.Context, height uint64) } // IncentiveKeeper defines the expected interface needed to distribute rewards. type IncentiveKeeper interface { - RewardBTCStaking(ctx context.Context, height uint64, rdc *bstypes.RewardDistCache) + RewardBTCStaking(ctx context.Context, height uint64, dc *bstypes.VotingPowerDistCache) } diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index fc73bf710..1f2e09366 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -65,21 +65,6 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetFinalityProvider(ctx, fpBTCPK int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetFinalityProvider), ctx, fpBTCPK) } -// GetRewardDistCache mocks base method. -func (m *MockBTCStakingKeeper) GetRewardDistCache(ctx context.Context, height uint64) (*types.RewardDistCache, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRewardDistCache", ctx, height) - ret0, _ := ret[0].(*types.RewardDistCache) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRewardDistCache indicates an expected call of GetRewardDistCache. -func (mr *MockBTCStakingKeeperMockRecorder) GetRewardDistCache(ctx, height interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRewardDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetRewardDistCache), ctx, height) -} - // GetVotingPower mocks base method. func (m *MockBTCStakingKeeper) GetVotingPower(ctx context.Context, fpBTCPK []byte, height uint64) uint64 { m.ctrl.T.Helper() @@ -94,6 +79,21 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetVotingPower(ctx, fpBTCPK, height return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVotingPower", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetVotingPower), ctx, fpBTCPK, height) } +// GetVotingPowerDistCache mocks base method. +func (m *MockBTCStakingKeeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types.VotingPowerDistCache, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetVotingPowerDistCache", ctx, height) + ret0, _ := ret[0].(*types.VotingPowerDistCache) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetVotingPowerDistCache indicates an expected call of GetVotingPowerDistCache. +func (mr *MockBTCStakingKeeperMockRecorder) GetVotingPowerDistCache(ctx, height interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVotingPowerDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetVotingPowerDistCache), ctx, height) +} + // GetVotingPowerTable mocks base method. func (m *MockBTCStakingKeeper) GetVotingPowerTable(ctx context.Context, height uint64) map[string]uint64 { m.ctrl.T.Helper() @@ -122,16 +122,16 @@ func (mr *MockBTCStakingKeeperMockRecorder) HasFinalityProvider(ctx, fpBTCPK int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).HasFinalityProvider), ctx, fpBTCPK) } -// RemoveRewardDistCache mocks base method. -func (m *MockBTCStakingKeeper) RemoveRewardDistCache(ctx context.Context, height uint64) { +// RemoveVotingPowerDistCache mocks base method. +func (m *MockBTCStakingKeeper) RemoveVotingPowerDistCache(ctx context.Context, height uint64) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RemoveRewardDistCache", ctx, height) + m.ctrl.Call(m, "RemoveVotingPowerDistCache", ctx, height) } -// RemoveRewardDistCache indicates an expected call of RemoveRewardDistCache. -func (mr *MockBTCStakingKeeperMockRecorder) RemoveRewardDistCache(ctx, height interface{}) *gomock.Call { +// RemoveVotingPowerDistCache indicates an expected call of RemoveVotingPowerDistCache. +func (mr *MockBTCStakingKeeperMockRecorder) RemoveVotingPowerDistCache(ctx, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveRewardDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RemoveRewardDistCache), ctx, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveVotingPowerDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RemoveVotingPowerDistCache), ctx, height) } // SlashFinalityProvider mocks base method. @@ -172,13 +172,13 @@ func (m *MockIncentiveKeeper) EXPECT() *MockIncentiveKeeperMockRecorder { } // RewardBTCStaking mocks base method. -func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, rdc *types.RewardDistCache) { +func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, dc *types.VotingPowerDistCache) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RewardBTCStaking", ctx, height, rdc) + m.ctrl.Call(m, "RewardBTCStaking", ctx, height, dc) } // RewardBTCStaking indicates an expected call of RewardBTCStaking. -func (mr *MockIncentiveKeeperMockRecorder) RewardBTCStaking(ctx, height, rdc interface{}) *gomock.Call { +func (mr *MockIncentiveKeeperMockRecorder) RewardBTCStaking(ctx, height, dc interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RewardBTCStaking", reflect.TypeOf((*MockIncentiveKeeper)(nil).RewardBTCStaking), ctx, height, rdc) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RewardBTCStaking", reflect.TypeOf((*MockIncentiveKeeper)(nil).RewardBTCStaking), ctx, height, dc) } diff --git a/x/incentive/keeper/btc_staking_gauge.go b/x/incentive/keeper/btc_staking_gauge.go index b3067ab65..bf83d32ee 100644 --- a/x/incentive/keeper/btc_staking_gauge.go +++ b/x/incentive/keeper/btc_staking_gauge.go @@ -13,16 +13,16 @@ import ( // RewardBTCStaking distributes rewards to finality providers/delegations at a given height according // to the reward distribution cache // (adapted from https://github.com/cosmos/cosmos-sdk/blob/release/v0.47.x/x/distribution/keeper/allocation.go#L12-L64) -func (k Keeper) RewardBTCStaking(ctx context.Context, height uint64, rdc *bstypes.RewardDistCache) { +func (k Keeper) RewardBTCStaking(ctx context.Context, height uint64, dc *bstypes.VotingPowerDistCache) { gauge := k.GetBTCStakingGauge(ctx, height) if gauge == nil { // failing to get a reward gauge at previous height is a programming error panic("failed to get a reward gauge at previous height") } // reward each of the finality provider and its BTC delegations in proportion - for _, fp := range rdc.FinalityProviders { + for _, fp := range dc.FinalityProviders { // get coins that will be allocated to the finality provider and its BTC delegations - fpPortion := rdc.GetFinalityProviderPortion(fp) + fpPortion := dc.GetFinalityProviderPortion(fp) coinsForFpsAndDels := gauge.GetCoinsPortion(fpPortion) // reward the finality provider with commission coinsForCommission := types.GetCoinsPortion(coinsForFpsAndDels, *fp.Commission) diff --git a/x/incentive/keeper/btc_staking_gauge_test.go b/x/incentive/keeper/btc_staking_gauge_test.go index e467829c1..711964b98 100644 --- a/x/incentive/keeper/btc_staking_gauge_test.go +++ b/x/incentive/keeper/btc_staking_gauge_test.go @@ -32,8 +32,8 @@ func FuzzRewardBTCStaking(f *testing.F) { gauge := datagen.GenRandomGauge(r) keeper.SetBTCStakingGauge(ctx, height, gauge) - // generate a random reward distribution cache - rdc, err := datagen.GenRandomBTCStakingRewardDistCache(r) + // generate a random voting power distribution cache + dc, err := datagen.GenRandomVotingPowerDistCache(r) require.NoError(t, err) // expected values @@ -41,8 +41,8 @@ func FuzzRewardBTCStaking(f *testing.F) { fpRewardMap := map[string]sdk.Coins{} // key: address, value: reward btcDelRewardMap := map[string]sdk.Coins{} // key: address, value: reward - for _, fp := range rdc.FinalityProviders { - fpPortion := rdc.GetFinalityProviderPortion(fp) + for _, fp := range dc.FinalityProviders { + fpPortion := dc.GetFinalityProviderPortion(fp) coinsForFpsAndDels := gauge.GetCoinsPortion(fpPortion) coinsForCommission := types.GetCoinsPortion(coinsForFpsAndDels, *fp.Commission) if coinsForCommission.IsAllPositive() { @@ -61,7 +61,7 @@ func FuzzRewardBTCStaking(f *testing.F) { } // distribute rewards in the gauge to finality providers/delegations - keeper.RewardBTCStaking(ctx, height, rdc) + keeper.RewardBTCStaking(ctx, height, dc) // assert consistency between reward map and reward gauge for addrStr, reward := range fpRewardMap { From 6da6dc3ec4bdf5397d5aab058820e7245d3519b8 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 15 Feb 2024 11:15:47 +1100 Subject: [PATCH 028/119] btcstaking: KV stores recording finality provider / BTC delegation state updates (#463) --- proto/babylon/btcstaking/v1/events.proto | 20 + x/btcstaking/keeper/btc_delegations.go | 1 + x/btcstaking/keeper/btc_delegators.go | 2 - x/btcstaking/keeper/finality_providers.go | 15 +- x/btcstaking/keeper/keeper.go | 77 +-- x/btcstaking/keeper/msg_server.go | 36 +- x/btcstaking/keeper/power_dist_change.go | 171 ++++++ x/btcstaking/keeper/power_dist_change_test.go | 138 +++++ x/btcstaking/types/btcstaking.go | 1 - x/btcstaking/types/events.go | 23 + x/btcstaking/types/events.pb.go | 552 +++++++++++++++++- x/btcstaking/types/keys.go | 1 + 12 files changed, 927 insertions(+), 110 deletions(-) create mode 100644 x/btcstaking/keeper/power_dist_change.go create mode 100644 x/btcstaking/keeper/power_dist_change_test.go create mode 100644 x/btcstaking/types/events.go diff --git a/proto/babylon/btcstaking/v1/events.proto b/proto/babylon/btcstaking/v1/events.proto index 20f48fb75..6bf54f882 100644 --- a/proto/babylon/btcstaking/v1/events.proto +++ b/proto/babylon/btcstaking/v1/events.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package babylon.btcstaking.v1; +import "gogoproto/gogo.proto"; import "babylon/btcstaking/v1/btcstaking.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; @@ -28,3 +29,22 @@ message EventSelectiveSlashing { // evidence is the evidence of selective slashing SelectiveSlashingEvidence evidence = 1; } + +// EventPowerDistUpdate is an event that affects voting power distirbution +// of BTC staking protocol +message EventPowerDistUpdate { + // EventSlashedFinalityProvider defines an event that a finality provider + // is slashed + // TODO: unify with existing slashing events + message EventSlashedFinalityProvider { + bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + } + + // ev is the event that affects voting power distribution + oneof ev { + // slashed_fp means a finality provider is slashed + EventSlashedFinalityProvider slashed_fp = 1; + // btc_del_state_update means a BTC delegation's state is updated + EventBTCDelegationStateUpdate btc_del_state_update = 2; + } +} diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index 74a67fa98..548ffdf43 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "cosmossdk.io/store/prefix" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/x/btcstaking/keeper/btc_delegators.go b/x/btcstaking/keeper/btc_delegators.go index f9d89dcca..bc1724a7d 100644 --- a/x/btcstaking/keeper/btc_delegators.go +++ b/x/btcstaking/keeper/btc_delegators.go @@ -138,8 +138,6 @@ func (k Keeper) GetBTCDelegation(ctx context.Context, stakingTxHashStr string) ( if err != nil { return nil, err } - - // find BTC delegation from KV store btcDel := k.getBTCDelegation(ctx, *stakingTxHash) if btcDel == nil { return nil, types.ErrBTCDelegationNotFound diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index 8084df572..abb68f556 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -4,11 +4,10 @@ import ( "context" "fmt" - "github.com/cosmos/cosmos-sdk/runtime" - sdk "github.com/cosmos/cosmos-sdk/types" - "cosmossdk.io/store/prefix" "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" ) // SetFinalityProvider adds the given finality provider to KVStore @@ -39,13 +38,18 @@ func (k Keeper) GetFinalityProvider(ctx context.Context, fpBTCPK []byte) (*types // SlashFinalityProvider slashes a finality provider with the given PK // A slashed finality provider will not have voting power func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error { + // ensure finality provider exists fp, err := k.GetFinalityProvider(ctx, fpBTCPK) if err != nil { return err } + + // ensure finality provider is not slashed yet if fp.IsSlashed() { return types.ErrFpAlreadySlashed } + + // set finality provider to be slashed fp.SlashedBabylonHeight = uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) btcTip := k.btclcKeeper.GetTipInfo(ctx) if btcTip == nil { @@ -54,6 +58,11 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error fp.SlashedBtcHeight = btcTip.Height k.SetFinalityProvider(ctx, fp) + // record slashed event. The next `BeginBlock` will consume this + // event for updating the finality provider set + powerUpdateEvent := types.NewEventPowerDistUpdateWithSlashedFP(fp.BtcPk) + k.addPowerDistUpdateEvent(ctx, btcTip.Height, powerUpdateEvent) + return nil } diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index c5e24e62d..55b9f8ed4 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -66,81 +66,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { func (k Keeper) BeginBlocker(ctx context.Context) error { // index BTC height at the current height k.IndexBTCHeight(ctx) - - params := k.GetParams(ctx) - btcTipHeight, err := k.GetCurrentBTCHeight(ctx) - if err != nil { - panic(err) // only possible upon programming error - } - wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout - - // prepare metrics for {active, inactive} finality providers, - // {pending, active, unbonded BTC delegations}, and total staked Bitcoins - // NOTE: slashed finality providers and BTC delegations are recorded upon - // slashing events rather than here - var ( - numFPs int = 0 - numStakedSats uint64 = 0 - numDelsMap = map[types.BTCDelegationStatus]int{ - types.BTCDelegationStatus_PENDING: 0, - types.BTCDelegationStatus_ACTIVE: 0, - types.BTCDelegationStatus_UNBONDED: 0, - } - ) - // for voting power and rewards - dc := types.NewVotingPowerDistCache() - - // iterate over all finality providers to find out non-slashed ones that have - // positive voting power - k.IterateActiveFPs( - ctx, - func(fp *types.FinalityProvider) bool { - fpDistInfo := types.NewFinalityProviderDistInfo(fp) - - // iterate over all BTC delegations under the finality provider - // in order to accumulate voting power dist info for it - k.IterateBTCDelegations(ctx, fp.BtcPk, func(btcDel *types.BTCDelegation) bool { - // accumulate voting power and reward distribution cache - fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, params.CovenantQuorum) - - // record metrics - numStakedSats += btcDel.VotingPower(btcTipHeight, wValue, params.CovenantQuorum) - numDelsMap[btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum)]++ - - return true - }) - - if fpDistInfo.TotalVotingPower > 0 { - dc.AddFinalityProviderDistInfo(fpDistInfo) - } - - return true - }, - ) - // record metrics for finality providers and total staked BTCs - numActiveFPs := min(numFPs, int(params.MaxActiveFinalityProviders)) - types.RecordActiveFinalityProviders(numActiveFPs) - types.RecordInactiveFinalityProviders(numFPs - numActiveFPs) - numStakedBTCs := float32(numStakedSats / SatoshisPerBTC) - types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) - // record metrics for BTC delegations - for status, num := range numDelsMap { - types.RecordBTCDelegations(num, status) - } - - // filter out top `MaxActiveFinalityProviders` active finality providers in terms of voting power - maxNumActiveFPs := k.GetParams(ctx).MaxActiveFinalityProviders - activeFps := types.FilterTopNFinalityProviders(dc.FinalityProviders, maxNumActiveFPs) - // set voting power table and re-calculate total voting power of top N finality providers - dc.TotalVotingPower = uint64(0) - babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) - for _, fp := range activeFps { - k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.TotalVotingPower) - dc.TotalVotingPower += fp.TotalVotingPower - } - - // set the voting power distribution cache of the current height - k.setVotingPowerDistCache(ctx, uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height), dc) + // update voting power distribution + k.UpdatePowerDist(ctx) return nil } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 5c6c06b19..dba2116bd 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -424,6 +424,16 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new pending BTC delegation: %w", err)) } + // record event that the BTC delegation becomes pending at this height + pendingEvent := types.NewEventPowerDistUpdateWithBTCDel(event) + ms.addPowerDistUpdateEvent(ctx, btcTip.Height, pendingEvent) + // record event that the BTC delegation will become unbonded at endHeight-w + unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(&types.EventBTCDelegationStateUpdate{ + StakingTxHash: stakingTxHash.String(), + NewState: types.BTCDelegationStatus_UNBONDED, + }) + ms.addPowerDistUpdateEvent(ctx, endHeight-wValue, unbondedEvent) + return &types.MsgCreateBTCDelegationResponse{}, nil } @@ -574,13 +584,21 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove ms.setBTCDelegation(ctx, btcDel) - // notify subscriber - event := &types.EventBTCDelegationStateUpdate{ - StakingTxHash: req.StakingTxHash, - NewState: types.BTCDelegationStatus_ACTIVE, - } - if err := ctx.EventManager().EmitTypedEvent(event); err != nil { - panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new active BTC delegation: %w", err)) + // If reaching the covenant quorum after this msg, the BTC delegation becomes + // active. Then, record and emit this event + if len(btcDel.CovenantSigs) == int(params.CovenantQuorum) { + // notify subscriber + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: req.StakingTxHash, + NewState: types.BTCDelegationStatus_ACTIVE, + } + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new active BTC delegation: %w", err)) + } + + // record event that the BTC delegation becomes active at this height + activeEvent := types.NewEventPowerDistUpdateWithBTCDel(event) + ms.addPowerDistUpdateEvent(ctx, btcTipHeight, activeEvent) } return &types.MsgAddCovenantSigsResponse{}, nil @@ -653,6 +671,10 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new unbonded BTC delegation: %w", err)) } + // record event that the BTC delegation becomes unbonded at this height + unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(event) + ms.addPowerDistUpdateEvent(ctx, btcTip.Height, unbondedEvent) + return &types.MsgBTCUndelegateResponse{}, nil } diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go new file mode 100644 index 000000000..8771a3f0b --- /dev/null +++ b/x/btcstaking/keeper/power_dist_change.go @@ -0,0 +1,171 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/store/prefix" + "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +/* power distribution update */ + +// UpdatePowerDist updates the voting power distribution of finality providers +// and their BTC delegations +func (k Keeper) UpdatePowerDist(ctx context.Context) { + params := k.GetParams(ctx) + btcTipHeight, err := k.GetCurrentBTCHeight(ctx) + if err != nil { + panic(err) // only possible upon programming error + } + wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout + + // prepare metrics for {active, inactive} finality providers, + // {pending, active, unbonded BTC delegations}, and total staked Bitcoins + // NOTE: slashed finality providers and BTC delegations are recorded upon + // slashing events rather than here + var ( + numFPs int = 0 + numStakedSats uint64 = 0 + numDelsMap = map[types.BTCDelegationStatus]int{ + types.BTCDelegationStatus_PENDING: 0, + types.BTCDelegationStatus_ACTIVE: 0, + types.BTCDelegationStatus_UNBONDED: 0, + } + ) + // for voting power and rewards + dc := types.NewVotingPowerDistCache() + + // iterate over all finality providers to find out non-slashed ones that have + // positive voting power + k.IterateActiveFPs( + ctx, + func(fp *types.FinalityProvider) bool { + fpDistInfo := types.NewFinalityProviderDistInfo(fp) + + // iterate over all BTC delegations under the finality provider + // in order to accumulate voting power dist info for it + k.IterateBTCDelegations(ctx, fp.BtcPk, func(btcDel *types.BTCDelegation) bool { + // accumulate voting power and reward distribution cache + fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, params.CovenantQuorum) + + // record metrics + numStakedSats += btcDel.VotingPower(btcTipHeight, wValue, params.CovenantQuorum) + numDelsMap[btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum)]++ + + return true + }) + + if fpDistInfo.TotalVotingPower > 0 { + dc.AddFinalityProviderDistInfo(fpDistInfo) + } + + return true + }, + ) + // record metrics for finality providers and total staked BTCs + numActiveFPs := min(numFPs, int(params.MaxActiveFinalityProviders)) + types.RecordActiveFinalityProviders(numActiveFPs) + types.RecordInactiveFinalityProviders(numFPs - numActiveFPs) + numStakedBTCs := float32(numStakedSats / SatoshisPerBTC) + types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) + // record metrics for BTC delegations + for status, num := range numDelsMap { + types.RecordBTCDelegations(num, status) + } + + // filter out top `MaxActiveFinalityProviders` active finality providers in terms of voting power + activeFps := types.FilterTopNFinalityProviders(dc.FinalityProviders, params.MaxActiveFinalityProviders) + // set voting power table and re-calculate total voting power of top N finality providers + dc.TotalVotingPower = uint64(0) + babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) + for _, fp := range activeFps { + k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.TotalVotingPower) + dc.TotalVotingPower += fp.TotalVotingPower + } + + // set the voting power distribution cache of the current height + k.setVotingPowerDistCache(ctx, uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height), dc) +} + +/* voting power distribution update event store */ + +// addPowerDistUpdateEvent appends an event that affect voting power distribution +// to the store +func (k Keeper) addPowerDistUpdateEvent( + ctx context.Context, + btcHeight uint64, + event *types.EventPowerDistUpdate, +) { + store := k.powerDistUpdateEventStore(ctx, btcHeight) + + // get event index + eventIdx := uint64(0) // event index starts from 0 + iter := store.ReverseIterator(nil, nil) + defer iter.Close() + if iter.Valid() { + // if there exists events already, event index will be the subsequent one + eventIdx = sdk.BigEndianToUint64(iter.Key()) + 1 + } + + // key is event index, and value is the event bytes + store.Set(sdk.Uint64ToBigEndian(eventIdx), k.cdc.MustMarshal(event)) +} + +// ClearPowerDistUpdateEvents removes all BTC delegation state update events +// at a given BTC height +// This is called after processing all BTC delegation events in `BeginBlocker` +// nolint:unused +func (k Keeper) ClearPowerDistUpdateEvents(ctx context.Context, btcHeight uint64) { + store := k.powerDistUpdateEventStore(ctx, btcHeight) + keys := [][]byte{} + + // get all keys + // using an enclosure to ensure iterator is closed right after + // the function is done + func() { + iter := store.Iterator(nil, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + }() + + // remove all keys + for _, key := range keys { + store.Delete(key) + } +} + +// IteratePowerDistUpdateEvents uses the given handler function to handle each +// voting power distribution update event that happens at the given BTC height. +// This is called in `BeginBlocker` +func (k Keeper) IteratePowerDistUpdateEvents( + ctx context.Context, + btcHeight uint64, + handleFunc func(event *types.EventPowerDistUpdate) bool, +) { + store := k.powerDistUpdateEventStore(ctx, btcHeight) + iter := store.Iterator(nil, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + var event types.EventPowerDistUpdate + k.cdc.MustUnmarshal(iter.Value(), &event) + shouldContinue := handleFunc(&event) + if !shouldContinue { + break + } + } +} + +// powerDistUpdateEventStore returns the KVStore of events that affect +// voting power distribution +// prefix: PowerDistUpdateKey +// key: (BTC height || event index) +// value: BTCDelegationStatus +func (k Keeper) powerDistUpdateEventStore(ctx context.Context, btcHeight uint64) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + store := prefix.NewStore(storeAdapter, types.PowerDistUpdateKey) + return prefix.NewStore(store, sdk.Uint64ToBigEndian(btcHeight)) +} diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go new file mode 100644 index 000000000..c80124f6e --- /dev/null +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -0,0 +1,138 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + "github.com/babylonchain/babylon/testutil/datagen" + btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" +) + +func FuzzFinalityProviderEvents(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters + h.GenAndApplyParams(r) + + // generate and insert new finality provider + _, _, fp := h.CreateFinalityProvider(r) + + // mock BTC tip info + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + + // slash the finality provider + err := h.BTCStakingKeeper.SlashFinalityProvider(h.Ctx, fp.BtcPk.MustMarshal()) + h.NoError(err) + + // at this point, there should be only 1 event that the finality provider is slashed + btcTipHeight := btclcKeeper.GetTipInfo(h.Ctx).Height + h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { + slashedFPEvent := ev.GetSlashedFp() + require.NotNil(t, slashedFPEvent) + require.Equal(t, fp.BtcPk.MustMarshal(), slashedFPEvent.Pk.MustMarshal()) + return true + }) + }) +} + +func FuzzBTCDelegationEvents(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) + + // generate and insert new finality provider + _, fpPK, _ := h.CreateFinalityProvider(r) + + // generate and insert new BTC delegation + stakingValue := int64(2 * 10e8) + expectedStakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + r, + fpPK, + changeAddress.EncodeAddress(), + stakingValue, + 1000, + ) + actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, expectedStakingTxHash) + h.NoError(err) + + /* + at this point, there should be + - 1 event that BTC delegation becomes pending at current BTC tip + - 1 event that BTC delegation will become expired at end height - w + */ + // the BTC delegation is now pending + btcTipHeight := btclcKeeper.GetTipInfo(h.Ctx).Height + h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { + btcDelStateUpdate := ev.GetBtcDelStateUpdate() + require.NotNil(t, btcDelStateUpdate) + require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) + require.Equal(t, types.BTCDelegationStatus_PENDING, btcDelStateUpdate.NewState) + return true + }) + // the BTC delegation will be unbonded at end height - w + unbondedHeight := actualDel.EndHeight - btccKeeper.GetParams(h.Ctx).CheckpointFinalizationTimeout + h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, unbondedHeight, func(ev *types.EventPowerDistUpdate) bool { + btcDelStateUpdate := ev.GetBtcDelStateUpdate() + require.NotNil(t, btcDelStateUpdate) + require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) + require.Equal(t, types.BTCDelegationStatus_UNBONDED, btcDelStateUpdate.NewState) + return true + }) + + // clear the events at tip, as per the behaviour of each `BeginBlock` + h.BTCStakingKeeper.ClearPowerDistUpdateEvents(h.Ctx, btcTipHeight) + // ensure event queue is cleared at BTC tip height + numEvents := 0 + h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { + numEvents++ + return true + }) + require.Zero(t, numEvents) + + // generate a quorum number of covenant signatures + msgs := h.GenerateCovenantSignaturesMessages(r, covenantSKs, msgCreateBTCDel, actualDel) + for i := 0; i < int(h.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum); i++ { + _, err = h.MsgServer.AddCovenantSigs(h.Ctx, msgs[i]) + h.NoError(err) + } + + /* + at this point, there should be an event that the BTC delegation becomes + active at the current height + */ + btcTipHeight = btclcKeeper.GetTipInfo(h.Ctx).Height + h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { + btcDelStateUpdate := ev.GetBtcDelStateUpdate() + require.NotNil(t, btcDelStateUpdate) + require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) + require.Equal(t, types.BTCDelegationStatus_ACTIVE, btcDelStateUpdate.NewState) + return true + }) + }) +} diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 386161da3..a98323faf 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "sort" "cosmossdk.io/math" diff --git a/x/btcstaking/types/events.go b/x/btcstaking/types/events.go new file mode 100644 index 000000000..6b94d3ca2 --- /dev/null +++ b/x/btcstaking/types/events.go @@ -0,0 +1,23 @@ +package types + +import ( + bbn "github.com/babylonchain/babylon/types" +) + +func NewEventPowerDistUpdateWithBTCDel(ev *EventBTCDelegationStateUpdate) *EventPowerDistUpdate { + return &EventPowerDistUpdate{ + Ev: &EventPowerDistUpdate_BtcDelStateUpdate{ + BtcDelStateUpdate: ev, + }, + } +} + +func NewEventPowerDistUpdateWithSlashedFP(fpBTCPK *bbn.BIP340PubKey) *EventPowerDistUpdate { + return &EventPowerDistUpdate{ + Ev: &EventPowerDistUpdate_SlashedFp{ + SlashedFp: &EventPowerDistUpdate_EventSlashedFinalityProvider{ + Pk: fpBTCPK, + }, + }, + } +} diff --git a/x/btcstaking/types/events.pb.go b/x/btcstaking/types/events.pb.go index af40abf48..38b23f396 100644 --- a/x/btcstaking/types/events.pb.go +++ b/x/btcstaking/types/events.pb.go @@ -5,6 +5,8 @@ package types import ( fmt "fmt" + github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" math "math" @@ -175,10 +177,145 @@ func (m *EventSelectiveSlashing) GetEvidence() *SelectiveSlashingEvidence { return nil } +// EventPowerDistUpdate is an event that affects voting power distirbution +// of BTC staking protocol +type EventPowerDistUpdate struct { + // ev is the event that affects voting power distribution + // + // Types that are valid to be assigned to Ev: + // *EventPowerDistUpdate_SlashedFp + // *EventPowerDistUpdate_BtcDelStateUpdate + Ev isEventPowerDistUpdate_Ev `protobuf_oneof:"ev"` +} + +func (m *EventPowerDistUpdate) Reset() { *m = EventPowerDistUpdate{} } +func (m *EventPowerDistUpdate) String() string { return proto.CompactTextString(m) } +func (*EventPowerDistUpdate) ProtoMessage() {} +func (*EventPowerDistUpdate) Descriptor() ([]byte, []int) { + return fileDescriptor_74118427820fff75, []int{3} +} +func (m *EventPowerDistUpdate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventPowerDistUpdate) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventPowerDistUpdate.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 *EventPowerDistUpdate) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventPowerDistUpdate.Merge(m, src) +} +func (m *EventPowerDistUpdate) XXX_Size() int { + return m.Size() +} +func (m *EventPowerDistUpdate) XXX_DiscardUnknown() { + xxx_messageInfo_EventPowerDistUpdate.DiscardUnknown(m) +} + +var xxx_messageInfo_EventPowerDistUpdate proto.InternalMessageInfo + +type isEventPowerDistUpdate_Ev interface { + isEventPowerDistUpdate_Ev() + MarshalTo([]byte) (int, error) + Size() int +} + +type EventPowerDistUpdate_SlashedFp struct { + SlashedFp *EventPowerDistUpdate_EventSlashedFinalityProvider `protobuf:"bytes,1,opt,name=slashed_fp,json=slashedFp,proto3,oneof" json:"slashed_fp,omitempty"` +} +type EventPowerDistUpdate_BtcDelStateUpdate struct { + BtcDelStateUpdate *EventBTCDelegationStateUpdate `protobuf:"bytes,2,opt,name=btc_del_state_update,json=btcDelStateUpdate,proto3,oneof" json:"btc_del_state_update,omitempty"` +} + +func (*EventPowerDistUpdate_SlashedFp) isEventPowerDistUpdate_Ev() {} +func (*EventPowerDistUpdate_BtcDelStateUpdate) isEventPowerDistUpdate_Ev() {} + +func (m *EventPowerDistUpdate) GetEv() isEventPowerDistUpdate_Ev { + if m != nil { + return m.Ev + } + return nil +} + +func (m *EventPowerDistUpdate) GetSlashedFp() *EventPowerDistUpdate_EventSlashedFinalityProvider { + if x, ok := m.GetEv().(*EventPowerDistUpdate_SlashedFp); ok { + return x.SlashedFp + } + return nil +} + +func (m *EventPowerDistUpdate) GetBtcDelStateUpdate() *EventBTCDelegationStateUpdate { + if x, ok := m.GetEv().(*EventPowerDistUpdate_BtcDelStateUpdate); ok { + return x.BtcDelStateUpdate + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*EventPowerDistUpdate) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*EventPowerDistUpdate_SlashedFp)(nil), + (*EventPowerDistUpdate_BtcDelStateUpdate)(nil), + } +} + +// EventSlashedFinalityProvider defines an event that a finality provider +// is slashed +// TODO: unify with existing slashing events +type EventPowerDistUpdate_EventSlashedFinalityProvider struct { + Pk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=pk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"pk,omitempty"` +} + +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) Reset() { + *m = EventPowerDistUpdate_EventSlashedFinalityProvider{} +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) String() string { + return proto.CompactTextString(m) +} +func (*EventPowerDistUpdate_EventSlashedFinalityProvider) ProtoMessage() {} +func (*EventPowerDistUpdate_EventSlashedFinalityProvider) Descriptor() ([]byte, []int) { + return fileDescriptor_74118427820fff75, []int{3, 0} +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventPowerDistUpdate_EventSlashedFinalityProvider.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 *EventPowerDistUpdate_EventSlashedFinalityProvider) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventPowerDistUpdate_EventSlashedFinalityProvider.Merge(m, src) +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) XXX_Size() int { + return m.Size() +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) XXX_DiscardUnknown() { + xxx_messageInfo_EventPowerDistUpdate_EventSlashedFinalityProvider.DiscardUnknown(m) +} + +var xxx_messageInfo_EventPowerDistUpdate_EventSlashedFinalityProvider proto.InternalMessageInfo + func init() { proto.RegisterType((*EventNewFinalityProvider)(nil), "babylon.btcstaking.v1.EventNewFinalityProvider") proto.RegisterType((*EventBTCDelegationStateUpdate)(nil), "babylon.btcstaking.v1.EventBTCDelegationStateUpdate") proto.RegisterType((*EventSelectiveSlashing)(nil), "babylon.btcstaking.v1.EventSelectiveSlashing") + proto.RegisterType((*EventPowerDistUpdate)(nil), "babylon.btcstaking.v1.EventPowerDistUpdate") + proto.RegisterType((*EventPowerDistUpdate_EventSlashedFinalityProvider)(nil), "babylon.btcstaking.v1.EventPowerDistUpdate.EventSlashedFinalityProvider") } func init() { @@ -186,28 +323,36 @@ func init() { } var fileDescriptor_74118427820fff75 = []byte{ - // 325 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4e, 0xf2, 0x40, - 0x14, 0x85, 0x19, 0x16, 0x7f, 0x60, 0xfe, 0xa8, 0x49, 0x13, 0x0d, 0x31, 0xb1, 0x21, 0x5d, 0x20, - 0x71, 0xd1, 0x0a, 0x2e, 0xdc, 0xa3, 0xa8, 0x0b, 0x62, 0x4c, 0x8b, 0x1b, 0x37, 0x64, 0x5a, 0x2e, - 0xed, 0xc4, 0x3a, 0xd3, 0x30, 0x97, 0x02, 0x6f, 0xc1, 0x63, 0xb9, 0x64, 0xe9, 0xd2, 0xc0, 0x8b, - 0x98, 0x4e, 0x46, 0x25, 0x02, 0xcb, 0x36, 0xe7, 0x3b, 0xdf, 0x99, 0x5c, 0xea, 0x84, 0x2c, 0x9c, - 0xa7, 0x52, 0x78, 0x21, 0x46, 0x0a, 0xd9, 0x2b, 0x17, 0xb1, 0x97, 0xb7, 0x3c, 0xc8, 0x41, 0xa0, - 0x72, 0xb3, 0xb1, 0x44, 0x69, 0x1d, 0x9b, 0x8c, 0xfb, 0x9b, 0x71, 0xf3, 0xd6, 0x69, 0x63, 0x37, - 0xba, 0x11, 0xd2, 0xb8, 0x13, 0xd0, 0x5a, 0xb7, 0xa8, 0x7b, 0x84, 0xe9, 0x1d, 0x17, 0x2c, 0xe5, - 0x38, 0x7f, 0x1a, 0xcb, 0x9c, 0x0f, 0x61, 0x6c, 0x5d, 0xd3, 0xf2, 0x28, 0xab, 0x91, 0x3a, 0x69, - 0xfe, 0x6f, 0x9f, 0xbb, 0x3b, 0x3d, 0xee, 0x5f, 0xc8, 0x2f, 0x8f, 0x32, 0x67, 0x41, 0xe8, 0x99, - 0x6e, 0xed, 0xf4, 0x6f, 0x6e, 0x21, 0x85, 0x98, 0x21, 0x97, 0x22, 0x40, 0x86, 0xf0, 0x9c, 0x0d, - 0x19, 0x82, 0xd5, 0xa0, 0x47, 0xa6, 0x64, 0x80, 0xb3, 0x41, 0xc2, 0x54, 0xa2, 0x3d, 0x55, 0xff, - 0xc0, 0xfc, 0xee, 0xcf, 0x1e, 0x98, 0x4a, 0xac, 0x7b, 0x5a, 0x15, 0x30, 0x1d, 0xa8, 0x02, 0xad, - 0x95, 0xeb, 0xa4, 0x79, 0xd8, 0xbe, 0xd8, 0xb3, 0x64, 0xcb, 0x35, 0x51, 0x7e, 0x45, 0xc0, 0x54, - 0x6b, 0x9d, 0x11, 0x3d, 0xd1, 0x8b, 0x02, 0x48, 0x21, 0x42, 0x9e, 0x43, 0x90, 0x32, 0x95, 0x70, - 0x11, 0x5b, 0x3d, 0x5a, 0x81, 0x62, 0xba, 0x88, 0xc0, 0xbc, 0xf5, 0x72, 0x8f, 0x61, 0x8b, 0xed, - 0x1a, 0xce, 0xff, 0x69, 0xe8, 0xf4, 0xde, 0x57, 0x36, 0x59, 0xae, 0x6c, 0xf2, 0xb9, 0xb2, 0xc9, - 0x62, 0x6d, 0x97, 0x96, 0x6b, 0xbb, 0xf4, 0xb1, 0xb6, 0x4b, 0x2f, 0xed, 0x98, 0x63, 0x32, 0x09, - 0xdd, 0x48, 0xbe, 0x79, 0xa6, 0x3f, 0x4a, 0x18, 0x17, 0xdf, 0x1f, 0xde, 0x6c, 0xf3, 0x56, 0x38, - 0xcf, 0x40, 0x85, 0xff, 0xf4, 0x91, 0xae, 0xbe, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xa5, 0x51, - 0x18, 0x09, 0x02, 0x00, 0x00, + // 463 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0x4f, 0x6f, 0xd3, 0x40, + 0x10, 0xc5, 0x6d, 0x0b, 0xa1, 0x66, 0xcb, 0x1f, 0x61, 0x05, 0x14, 0x45, 0x60, 0x2a, 0x1f, 0x4a, + 0xc5, 0xc1, 0x6e, 0xd3, 0x0a, 0xee, 0x26, 0x0d, 0x41, 0x54, 0x28, 0xb2, 0xcb, 0x85, 0x8b, 0xb5, + 0x76, 0x26, 0xf6, 0x2a, 0x66, 0xd7, 0xca, 0x4e, 0x9c, 0xe4, 0x5b, 0xf4, 0x63, 0x71, 0xec, 0xb1, + 0xe2, 0x80, 0x50, 0xf2, 0x45, 0x90, 0x37, 0xa6, 0x44, 0x6d, 0x1c, 0x6e, 0xc9, 0xe8, 0xbd, 0xf7, + 0x7b, 0x33, 0xb6, 0x89, 0x1d, 0xd1, 0x68, 0x91, 0x09, 0xee, 0x46, 0x18, 0x4b, 0xa4, 0x63, 0xc6, + 0x13, 0xb7, 0x38, 0x71, 0xa1, 0x00, 0x8e, 0xd2, 0xc9, 0x27, 0x02, 0x85, 0xf9, 0xbc, 0xd2, 0x38, + 0xff, 0x34, 0x4e, 0x71, 0xd2, 0x6e, 0x26, 0x22, 0x11, 0x4a, 0xe1, 0x96, 0xbf, 0xd6, 0xe2, 0xf6, + 0xe1, 0xf6, 0xc0, 0x0d, 0xab, 0xd2, 0xd9, 0x01, 0x69, 0x9d, 0x97, 0x90, 0x2f, 0x30, 0xeb, 0x31, + 0x4e, 0x33, 0x86, 0x8b, 0xc1, 0x44, 0x14, 0x6c, 0x08, 0x13, 0xf3, 0x3d, 0x31, 0x46, 0x79, 0x4b, + 0x3f, 0xd0, 0x8f, 0xf6, 0x3b, 0x6f, 0x9c, 0xad, 0x74, 0xe7, 0xae, 0xc9, 0x37, 0x46, 0xb9, 0x7d, + 0xa5, 0x93, 0x57, 0x2a, 0xd5, 0xbb, 0xfc, 0xd0, 0x85, 0x0c, 0x12, 0x8a, 0x4c, 0xf0, 0x00, 0x29, + 0xc2, 0xd7, 0x7c, 0x48, 0x11, 0xcc, 0x43, 0xf2, 0xb4, 0x0a, 0x09, 0x71, 0x1e, 0xa6, 0x54, 0xa6, + 0x8a, 0xd3, 0xf0, 0x1f, 0x57, 0xe3, 0xcb, 0x79, 0x9f, 0xca, 0xd4, 0xfc, 0x48, 0x1a, 0x1c, 0x66, + 0xa1, 0x2c, 0xad, 0x2d, 0xe3, 0x40, 0x3f, 0x7a, 0xd2, 0x79, 0x5b, 0xd3, 0xe4, 0x1e, 0x6b, 0x2a, + 0xfd, 0x3d, 0x0e, 0x33, 0x85, 0xb5, 0x47, 0xe4, 0x85, 0x6a, 0x14, 0x40, 0x06, 0x31, 0xb2, 0x02, + 0x82, 0x8c, 0xca, 0x94, 0xf1, 0xc4, 0xbc, 0x20, 0x7b, 0x50, 0x56, 0xe7, 0x31, 0x54, 0xbb, 0x1e, + 0xd7, 0x10, 0xee, 0x79, 0xcf, 0x2b, 0x9f, 0x7f, 0x9b, 0x60, 0xdf, 0x18, 0xa4, 0xa9, 0x40, 0x03, + 0x31, 0x83, 0x49, 0x97, 0x49, 0xac, 0x36, 0x66, 0x84, 0xc8, 0xd2, 0x06, 0xc3, 0xf0, 0xf6, 0xa8, + 0xfd, 0x1a, 0xd0, 0xb6, 0x80, 0xf5, 0x30, 0x58, 0x47, 0xdc, 0xbd, 0x7a, 0x5f, 0xf3, 0x1b, 0x55, + 0x7a, 0x2f, 0x37, 0x13, 0xd2, 0x8c, 0x30, 0x0e, 0x87, 0x90, 0xad, 0x0f, 0x17, 0x4e, 0x55, 0x82, + 0xba, 0xdf, 0x7e, 0xe7, 0x6c, 0x17, 0xb4, 0xee, 0x81, 0xf5, 0x35, 0xff, 0x59, 0x84, 0x71, 0x17, + 0xb2, 0x8d, 0x61, 0x7b, 0x44, 0x5e, 0xee, 0x6a, 0x65, 0xf6, 0x88, 0x91, 0x8f, 0xd5, 0xae, 0x8f, + 0xbc, 0x77, 0x3f, 0x7f, 0xbd, 0xee, 0x24, 0x0c, 0xd3, 0x69, 0xe4, 0xc4, 0xe2, 0xbb, 0x5b, 0x95, + 0x88, 0x53, 0xca, 0xf8, 0xdf, 0x3f, 0x2e, 0x2e, 0x72, 0x90, 0x8e, 0xf7, 0x69, 0x70, 0x7a, 0x76, + 0x3c, 0x98, 0x46, 0x9f, 0x61, 0xe1, 0x1b, 0xf9, 0xd8, 0x7b, 0x40, 0x0c, 0x28, 0xbc, 0x8b, 0x1f, + 0x4b, 0x4b, 0xbf, 0x5e, 0x5a, 0xfa, 0xef, 0xa5, 0xa5, 0x5f, 0xad, 0x2c, 0xed, 0x7a, 0x65, 0x69, + 0x37, 0x2b, 0x4b, 0xfb, 0xf6, 0xdf, 0xdc, 0xf9, 0xe6, 0x67, 0xa0, 0x20, 0xd1, 0x43, 0xf5, 0xfe, + 0x9f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xc4, 0x7d, 0x08, 0x7a, 0x03, 0x00, 0x00, } func (m *EventNewFinalityProvider) Marshal() (dAtA []byte, err error) { @@ -315,6 +460,115 @@ func (m *EventSelectiveSlashing) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *EventPowerDistUpdate) 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 *EventPowerDistUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPowerDistUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Ev != nil { + { + size := m.Ev.Size() + i -= size + if _, err := m.Ev.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } + } + return len(dAtA) - i, nil +} + +func (m *EventPowerDistUpdate_SlashedFp) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPowerDistUpdate_SlashedFp) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.SlashedFp != nil { + { + size, err := m.SlashedFp.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *EventPowerDistUpdate_BtcDelStateUpdate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPowerDistUpdate_BtcDelStateUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.BtcDelStateUpdate != nil { + { + size, err := m.BtcDelStateUpdate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) 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 *EventPowerDistUpdate_EventSlashedFinalityProvider) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pk != nil { + { + size := m.Pk.Size() + i -= size + if _, err := m.Pk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintEvents(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -368,6 +622,55 @@ func (m *EventSelectiveSlashing) Size() (n int) { return n } +func (m *EventPowerDistUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ev != nil { + n += m.Ev.Size() + } + return n +} + +func (m *EventPowerDistUpdate_SlashedFp) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SlashedFp != nil { + l = m.SlashedFp.Size() + n += 1 + l + sovEvents(uint64(l)) + } + return n +} +func (m *EventPowerDistUpdate_BtcDelStateUpdate) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BtcDelStateUpdate != nil { + l = m.BtcDelStateUpdate.Size() + n += 1 + l + sovEvents(uint64(l)) + } + return n +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pk != nil { + l = m.Pk.Size() + n += 1 + l + sovEvents(uint64(l)) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -647,6 +950,211 @@ func (m *EventSelectiveSlashing) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventPowerDistUpdate) 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 ErrIntOverflowEvents + } + 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: EventPowerDistUpdate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventPowerDistUpdate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SlashedFp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &EventPowerDistUpdate_EventSlashedFinalityProvider{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Ev = &EventPowerDistUpdate_SlashedFp{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcDelStateUpdate", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &EventBTCDelegationStateUpdate{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Ev = &EventPowerDistUpdate_BtcDelStateUpdate{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) 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 ErrIntOverflowEvents + } + 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: EventSlashedFinalityProvider: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSlashedFinalityProvider: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthEvents + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.Pk = &v + if err := m.Pk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipEvents(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/btcstaking/types/keys.go b/x/btcstaking/types/keys.go index 49d1e7185..12af82740 100644 --- a/x/btcstaking/types/keys.go +++ b/x/btcstaking/types/keys.go @@ -22,6 +22,7 @@ var ( VotingPowerKey = []byte{0x05} // key prefix for the voting power BTCHeightKey = []byte{0x06} // key prefix for the BTC heights VotingPowerDistCacheKey = []byte{0x07} // key prefix for voting power distribution cache + PowerDistUpdateKey = []byte{0x08} // key prefix for power distribution update events ) func KeyPrefix(p string) []byte { From 009a25c9f378cbc0cae213bdca021a7c212c35ac Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 26 Feb 2024 11:35:24 +1100 Subject: [PATCH 029/119] btcstaking: improved algorithm for voting power update (#486) --- proto/babylon/btcstaking/v1/incentive.proto | 8 +- testutil/datagen/incentive.go | 3 +- x/btcstaking/README.md | 77 ++--- x/btcstaking/keeper/bench_test.go | 8 +- x/btcstaking/keeper/btc_delegations.go | 140 +++++++++ x/btcstaking/keeper/btc_delegators.go | 116 +------- x/btcstaking/keeper/btc_height_index.go | 10 +- x/btcstaking/keeper/btc_height_index_test.go | 6 +- x/btcstaking/keeper/grpc_query.go | 5 +- x/btcstaking/keeper/grpc_query_test.go | 16 +- x/btcstaking/keeper/incentive.go | 14 +- x/btcstaking/keeper/incentive_test.go | 65 ++-- x/btcstaking/keeper/keeper.go | 4 +- x/btcstaking/keeper/keeper_test.go | 25 +- x/btcstaking/keeper/msg_server.go | 62 +--- x/btcstaking/keeper/msg_server_test.go | 16 +- x/btcstaking/keeper/power_dist_change.go | 278 +++++++++++++----- x/btcstaking/keeper/power_dist_change_test.go | 4 +- .../keeper/voting_power_table_test.go | 272 ++++++----------- x/btcstaking/types/btcstaking.go | 16 +- x/btcstaking/types/expected_keepers.go | 1 + x/btcstaking/types/incentive.go | 70 +++-- x/btcstaking/types/incentive.pb.go | 125 +++++--- x/btcstaking/types/mocked_keepers.go | 14 + x/finality/keeper/tallying.go | 5 +- x/finality/keeper/tallying_test.go | 1 + x/finality/types/expected_keepers.go | 3 +- x/finality/types/mocked_keepers.go | 14 + x/incentive/keeper/btc_staking_gauge.go | 8 +- x/incentive/keeper/btc_staking_gauge_test.go | 2 +- 30 files changed, 772 insertions(+), 616 deletions(-) diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index 84160caaf..ad9efaa0b 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -33,13 +33,15 @@ message FinalityProviderDistInfo { repeated BTCDelDistInfo btc_dels = 5; } -// BTCDelDistInfo contains the information related to reward distribution for a BTC delegations +// BTCDelDistInfo contains the information related to reward distribution for a BTC delegation message BTCDelDistInfo { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // babylon_pk is the Babylon public key of the BTC delegations + // babylon_pk is the Babylon public key of the BTC delegation cosmos.crypto.secp256k1.PubKey babylon_pk = 2; + // staking_tx_hash is the staking tx hash of the BTC delegation + string staking_tx_hash = 3; // voting_power is the voting power of the BTC delegation - uint64 voting_power = 3; + uint64 voting_power = 4; } diff --git a/testutil/datagen/incentive.go b/testutil/datagen/incentive.go index fd5888d95..c6320860f 100644 --- a/testutil/datagen/incentive.go +++ b/testutil/datagen/incentive.go @@ -110,7 +110,7 @@ func GenRandomFinalityProviderDistInfo(r *rand.Rand) (*bstypes.FinalityProviderD return fpDistInfo, nil } -func GenRandomVotingPowerDistCache(r *rand.Rand) (*bstypes.VotingPowerDistCache, error) { +func GenRandomVotingPowerDistCache(r *rand.Rand, maxFPs uint32) (*bstypes.VotingPowerDistCache, error) { dc := bstypes.NewVotingPowerDistCache() // a random number of finality providers numFps := RandomInt(r, 10) + 1 @@ -121,6 +121,7 @@ func GenRandomVotingPowerDistCache(r *rand.Rand) (*bstypes.VotingPowerDistCache, } dc.AddFinalityProviderDistInfo(v) } + dc.ApplyActiveFinalityProviders(maxFPs) return dc, nil } diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index 9f7ed6884..5635d6210 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -689,8 +689,10 @@ Upon `BeginBlock`, the BTC Staking module will execute the following: 1. Index the current BTC tip height. This will be used for determining the status of BTC delegations. -2. Record the voting power table at the current height, by iterating all BTC - delegations. +2. Record the voting power table at the current height, by reconciling the + voting power table at the last height with all events that affect voting + power distribution (including newly active BTC delegations, newly unbonded + BTC delegations, and slashed finality providers). 3. If the BTC Staking protocol is activated, i.e., there exists at least 1 active BTC delegation, then record the reward distribution w.r.t. the active finality providers and active BTC delegations. @@ -706,33 +708,17 @@ at `proto/babylon/btcstaking/v1/events.proto`. // EventNewFinalityProvider is the event emitted when a finality provider is created message EventNewFinalityProvider { FinalityProvider fp = 1; } -// EventNewBTCDelegation is the event emitted when a BTC delegation is created -// NOTE: the BTC delegation is not active thus does not have voting power yet -// only after it receives a covenant signature it becomes activated and has voting power -message EventNewBTCDelegation { BTCDelegation btc_del = 1; } - -// EventActivateBTCDelegation is the event emitted when covenant activates a BTC delegation -// such that the BTC delegation starts to have voting power in its timelock period -message EventActivateBTCDelegation { BTCDelegation btc_del = 1; } - -// EventUnbondingBTCDelegation is the event emitted when an unbonding BTC delegation -// receives all signatures needed for becoming unbonded -message EventUnbondedBTCDelegation { - // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation - // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that - // this BTC delegation delegates to - // If there is more than 1 PKs, then this means the delegation is restaked - // to multiple finality providers - repeated bytes fp_btc_pk_list = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; +// EventBTCDelegationStateUpdate is the event emitted when a BTC delegation's state is +// updated. There are the following possible state transitions: +// - non-existing -> pending, which happens upon `MsgCreateBTCDelegation` +// - pending -> active, which happens upon `MsgAddCovenantSigs` +// - active -> unbonded, which happens upon `MsgBTCUndelegate` or upon staking tx timelock expires +message EventBTCDelegationStateUpdate { // staking_tx_hash is the hash of the staking tx. - // (fp_pks..., del_pk, staking_tx_hash) uniquely identifies a BTC delegation - string staking_tx_hash = 3; - // unbonding_tx_hash is the hash of the unbonding tx. - string unbonding_tx_hash = 4; - // from_state is the last state the BTC delegation was at - BTCDelegationStatus from_state = 5; + // It uniquely identifies a BTC delegation + string staking_tx_hash = 1; + // new_state is the new state of this BTC delegation + BTCDelegationStatus new_state = 2; } // EventSelectiveSlashing is the event emitted when an adversarial @@ -742,23 +728,24 @@ message EventSelectiveSlashing { // evidence is the evidence of selective slashing SelectiveSlashingEvidence evidence = 1; } -// SelectiveSlashingEvidence is the evidence that the finality provider -// selectively slashed a BTC delegation -// NOTE: it's possible that a slashed finality provider exploits the -// SelectiveSlashingEvidence endpoint while it is actually slashed due to -// equivocation. But such behaviour does not affect the system's security -// or gives any benefit for the adversary -message SelectiveSlashingEvidence { - // staking_tx_hash is the hash of the staking tx. - // It uniquely identifies a BTC delegation - string staking_tx_hash = 1; - // fp_btc_pk is the BTC PK of the finality provider who - // launches the selective slashing offence - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // recovered_fp_btc_sk is the finality provider's BTC SK recovered from - // the covenant adaptor/Schnorr signature pair. It is the consequence - // of selective slashing. - bytes recovered_fp_btc_sk = 3; + +// EventPowerDistUpdate is an event that affects voting power distirbution +// of BTC staking protocol +message EventPowerDistUpdate { + // EventSlashedFinalityProvider defines an event that a finality provider + // is slashed + // TODO: unify with existing slashing events + message EventSlashedFinalityProvider { + bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + } + + // ev is the event that affects voting power distribution + oneof ev { + // slashed_fp means a finality provider is slashed + EventSlashedFinalityProvider slashed_fp = 1; + // btc_del_state_update means a BTC delegation's state is updated + EventBTCDelegationStateUpdate btc_del_state_update = 2; + } } ``` diff --git a/x/btcstaking/keeper/bench_test.go b/x/btcstaking/keeper/bench_test.go index 1379984bd..0e0333d16 100644 --- a/x/btcstaking/keeper/bench_test.go +++ b/x/btcstaking/keeper/bench_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/babylonchain/babylon/testutil/datagen" + btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" bsmodule "github.com/babylonchain/babylon/x/btcstaking" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/golang/mock/gomock" @@ -52,7 +53,7 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { for i := 0; i < numDelsUnderFP; i++ { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( r, fp.BtcPk.MustToBTCPK(), changeAddress.EncodeAddress(), @@ -60,8 +61,6 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { 1000, ) // retrieve BTC delegation in DB - actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) - h.NoError(err) btcDelMap[stakingTxHash] = append(btcDelMap[stakingTxHash], actualDel) // generate and insert new covenant signatures // after that, all BTC delegations will have voting power @@ -69,6 +68,9 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { } } + // mock stuff + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + // Start the CPU profiler cpuProfileFile := fmt.Sprintf("/tmp/btcstaking-beginblock-%d-%d-cpu.pprof", numFPs, numDelsUnderFP) f, err := os.Create(cpuProfileFile) diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index 548ffdf43..cb4a25a72 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -2,13 +2,138 @@ package keeper import ( "context" + "fmt" "cosmossdk.io/store/prefix" + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" ) +// AddBTCDelegation adds a BTC delegation post verification to the system, including +// - indexing the given BTC delegation in the BTC delegator store, +// - saving it under BTC delegation store, and +// - emit events about this BTC delegation. +func (k Keeper) AddBTCDelegation(ctx sdk.Context, btcDel *types.BTCDelegation) error { + if err := btcDel.ValidateBasic(); err != nil { + return err + } + + // get staking tx hash + stakingTxHash, err := btcDel.GetStakingTxHash() + if err != nil { + return err + } + + // for each finality provider the delegation restakes to, update its index + for _, fpBTCPK := range btcDel.FpBtcPkList { + // get BTC delegation index under this finality provider + btcDelIndex := k.getBTCDelegatorDelegationIndex(ctx, &fpBTCPK, btcDel.BtcPk) + if btcDelIndex == nil { + btcDelIndex = types.NewBTCDelegatorDelegationIndex() + } + // index staking tx hash of this BTC delegation + if err := btcDelIndex.Add(stakingTxHash); err != nil { + return types.ErrInvalidStakingTx.Wrapf(err.Error()) + } + // save the index + k.setBTCDelegatorDelegationIndex(ctx, &fpBTCPK, btcDel.BtcPk, btcDelIndex) + } + + // save this BTC delegation + k.setBTCDelegation(ctx, btcDel) + + // notify subscriber + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: stakingTxHash.String(), + NewState: types.BTCDelegationStatus_PENDING, + } + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new pending BTC delegation: %w", err)) + } + + // NOTE: we don't need to record events for pending BTC delegations since these + // do not affect voting power distribution + + // record event that the BTC delegation will become unbonded at endHeight-w + unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(&types.EventBTCDelegationStateUpdate{ + StakingTxHash: stakingTxHash.String(), + NewState: types.BTCDelegationStatus_UNBONDED, + }) + wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout + k.addPowerDistUpdateEvent(ctx, btcDel.EndHeight-wValue, unbondedEvent) + + return nil +} + +// addCovenantSigsToBTCDelegation adds signatures from a given covenant member +// to the given BTC delegation +func (k Keeper) addCovenantSigsToBTCDelegation( + ctx sdk.Context, + btcDel *types.BTCDelegation, + covPK *bbn.BIP340PubKey, + parsedSlashingAdaptorSignatures []asig.AdaptorSignature, + unbondingTxSig *bbn.BIP340Signature, + parsedUnbondingSlashingAdaptorSignatures []asig.AdaptorSignature, +) { + // All is fine add received signatures to the BTC delegation and BtcUndelegation + btcDel.AddCovenantSigs( + covPK, + parsedSlashingAdaptorSignatures, + unbondingTxSig, + parsedUnbondingSlashingAdaptorSignatures, + ) + + k.setBTCDelegation(ctx, btcDel) + + // If reaching the covenant quorum after this msg, the BTC delegation becomes + // active. Then, record and emit this event + if len(btcDel.CovenantSigs) == int(k.GetParams(ctx).CovenantQuorum) { + // notify subscriber + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: btcDel.MustGetStakingTxHash().String(), + NewState: types.BTCDelegationStatus_ACTIVE, + } + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new active BTC delegation: %w", err)) + } + + // record event that the BTC delegation becomes active at this height + activeEvent := types.NewEventPowerDistUpdateWithBTCDel(event) + btcTip := k.btclcKeeper.GetTipInfo(ctx) + k.addPowerDistUpdateEvent(ctx, btcTip.Height, activeEvent) + } +} + +// btcUndelegate adds the signature of the unbonding tx signed by the staker +// to the given BTC delegation +func (k Keeper) btcUndelegate( + ctx sdk.Context, + btcDel *types.BTCDelegation, + unbondingTxSig *bbn.BIP340Signature, +) { + btcDel.BtcUndelegation.DelegatorUnbondingSig = unbondingTxSig + k.setBTCDelegation(ctx, btcDel) + + // notify subscriber about this unbonded BTC delegation + event := &types.EventBTCDelegationStateUpdate{ + StakingTxHash: btcDel.MustGetStakingTxHash().String(), + NewState: types.BTCDelegationStatus_UNBONDED, + } + + if err := ctx.EventManager().EmitTypedEvent(event); err != nil { + panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new unbonded BTC delegation: %w", err)) + } + + // record event that the BTC delegation becomes unbonded at this height + unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(event) + btcTip := k.btclcKeeper.GetTipInfo(ctx) + k.addPowerDistUpdateEvent(ctx, btcTip.Height, unbondedEvent) +} + func (k Keeper) setBTCDelegation(ctx context.Context, btcDel *types.BTCDelegation) { store := k.btcDelegationStore(ctx) stakingTxHash := btcDel.MustGetStakingTxHash() @@ -16,6 +141,21 @@ func (k Keeper) setBTCDelegation(ctx context.Context, btcDel *types.BTCDelegatio store.Set(stakingTxHash[:], btcDelBytes) } +// GetBTCDelegation gets the BTC delegation with a given staking tx hash +func (k Keeper) GetBTCDelegation(ctx context.Context, stakingTxHashStr string) (*types.BTCDelegation, error) { + // decode staking tx hash string + stakingTxHash, err := chainhash.NewHashFromStr(stakingTxHashStr) + if err != nil { + return nil, err + } + btcDel := k.getBTCDelegation(ctx, *stakingTxHash) + if btcDel == nil { + return nil, types.ErrBTCDelegationNotFound + } + + return btcDel, nil +} + func (k Keeper) getBTCDelegation(ctx context.Context, stakingTxHash chainhash.Hash) *types.BTCDelegation { store := k.btcDelegationStore(ctx) btcDelBytes := store.Get(stakingTxHash[:]) diff --git a/x/btcstaking/keeper/btc_delegators.go b/x/btcstaking/keeper/btc_delegators.go index bc1724a7d..c6684dee7 100644 --- a/x/btcstaking/keeper/btc_delegators.go +++ b/x/btcstaking/keeper/btc_delegators.go @@ -2,7 +2,6 @@ package keeper import ( "context" - "fmt" "github.com/cosmos/cosmos-sdk/runtime" @@ -13,109 +12,39 @@ import ( "github.com/babylonchain/babylon/x/btcstaking/types" ) -// AddBTCDelegation indexes the given BTC delegation in the BTC delegator store, and saves -// it under BTC delegation store -func (k Keeper) AddBTCDelegation(ctx context.Context, btcDel *types.BTCDelegation) error { - if err := btcDel.ValidateBasic(); err != nil { - return err - } - - // get staking tx hash - stakingTxHash, err := btcDel.GetStakingTxHash() - if err != nil { - return err - } - - // for each finality provider the delegation restakes to, update its index - for _, fpBTCPK := range btcDel.FpBtcPkList { - var btcDelIndex = types.NewBTCDelegatorDelegationIndex() - if k.hasBTCDelegatorDelegations(ctx, &fpBTCPK, btcDel.BtcPk) { - btcDelIndex, err = k.getBTCDelegatorDelegationIndex(ctx, &fpBTCPK, btcDel.BtcPk) - if err != nil { - // this can only be a programming error - panic(fmt.Errorf("failed to get BTC delegations while hasBTCDelegatorDelegations returns true")) - } - } - - // index staking tx hash of this BTC delegation - if err := btcDelIndex.Add(stakingTxHash); err != nil { - return types.ErrInvalidStakingTx.Wrapf(err.Error()) - } - // save the index - store := k.btcDelegatorStore(ctx, &fpBTCPK) - delBTCPKBytes := btcDel.BtcPk.MustMarshal() - btcDelIndexBytes := k.cdc.MustMarshal(btcDelIndex) - store.Set(delBTCPKBytes, btcDelIndexBytes) - } - - // save this BTC delegation - k.setBTCDelegation(ctx, btcDel) - - return nil -} - -// IterateBTCDelegations iterates all BTC delegations under a given finality provider -func (k Keeper) IterateBTCDelegations(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, handler func(btcDel *types.BTCDelegation) bool) { - btcDelIter := k.btcDelegatorStore(ctx, fpBTCPK).Iterator(nil, nil) - defer btcDelIter.Close() - for ; btcDelIter.Valid(); btcDelIter.Next() { - // unmarshal delegator's delegation index - var btcDelIndex types.BTCDelegatorDelegationIndex - k.cdc.MustUnmarshal(btcDelIter.Value(), &btcDelIndex) - // retrieve and process each of the BTC delegation - for _, stakingTxHashBytes := range btcDelIndex.StakingTxHashList { - stakingTxHash, err := chainhash.NewHash(stakingTxHashBytes) - if err != nil { - panic(err) // only programming error is possible - } - btcDel := k.getBTCDelegation(ctx, *stakingTxHash) - shouldContinue := handler(btcDel) - if !shouldContinue { - return - } - } - } -} - -// hasBTCDelegatorDelegations checks if the given BTC delegator has any BTC delegations under a given finality provider -func (k Keeper) hasBTCDelegatorDelegations(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) bool { - fpBTCPKBytes := fpBTCPK.MustMarshal() - delBTCPKBytes := delBTCPK.MustMarshal() - - if !k.HasFinalityProvider(ctx, fpBTCPKBytes) { - return false - } - store := k.btcDelegatorStore(ctx, fpBTCPK) - return store.Has(delBTCPKBytes) -} - // getBTCDelegatorDelegationIndex gets the BTC delegation index with a given BTC PK under a given finality provider -func (k Keeper) getBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) (*types.BTCDelegatorDelegationIndex, error) { +func (k Keeper) getBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) *types.BTCDelegatorDelegationIndex { fpBTCPKBytes := fpBTCPK.MustMarshal() delBTCPKBytes := delBTCPK.MustMarshal() store := k.btcDelegatorStore(ctx, fpBTCPK) // ensure the finality provider exists if !k.HasFinalityProvider(ctx, fpBTCPKBytes) { - return nil, types.ErrFpNotFound + return nil } // ensure BTC delegator exists if !store.Has(delBTCPKBytes) { - return nil, types.ErrBTCDelegatorNotFound + return nil } // get and unmarshal var btcDelIndex types.BTCDelegatorDelegationIndex btcDelIndexBytes := store.Get(delBTCPKBytes) k.cdc.MustUnmarshal(btcDelIndexBytes, &btcDelIndex) - return &btcDelIndex, nil + return &btcDelIndex +} + +func (k Keeper) setBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey, btcDelIndex *types.BTCDelegatorDelegationIndex) { + store := k.btcDelegatorStore(ctx, fpBTCPK) + btcDelIndexBytes := k.cdc.MustMarshal(btcDelIndex) + store.Set(*delBTCPK, btcDelIndexBytes) } // getBTCDelegatorDelegations gets the BTC delegations with a given BTC PK under a given finality provider -func (k Keeper) getBTCDelegatorDelegations(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) (*types.BTCDelegatorDelegations, error) { - btcDelIndex, err := k.getBTCDelegatorDelegationIndex(ctx, fpBTCPK, delBTCPK) - if err != nil { - return nil, err +func (k Keeper) getBTCDelegatorDelegations(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) *types.BTCDelegatorDelegations { + btcDelIndex := k.getBTCDelegatorDelegationIndex(ctx, fpBTCPK, delBTCPK) + if btcDelIndex == nil { + return nil } // get BTC delegation from each staking tx hash btcDels := []*types.BTCDelegation{} @@ -128,22 +57,7 @@ func (k Keeper) getBTCDelegatorDelegations(ctx context.Context, fpBTCPK *bbn.BIP btcDel := k.getBTCDelegation(ctx, *stakingTxHash) btcDels = append(btcDels, btcDel) } - return &types.BTCDelegatorDelegations{Dels: btcDels}, nil -} - -// GetBTCDelegation gets the BTC delegation with a given staking tx hash -func (k Keeper) GetBTCDelegation(ctx context.Context, stakingTxHashStr string) (*types.BTCDelegation, error) { - // decode staking tx hash string - stakingTxHash, err := chainhash.NewHashFromStr(stakingTxHashStr) - if err != nil { - return nil, err - } - btcDel := k.getBTCDelegation(ctx, *stakingTxHash) - if btcDel == nil { - return nil, types.ErrBTCDelegationNotFound - } - - return btcDel, nil + return &types.BTCDelegatorDelegations{Dels: btcDels} } // btcDelegatorStore returns the KVStore of the BTC delegators diff --git a/x/btcstaking/keeper/btc_height_index.go b/x/btcstaking/keeper/btc_height_index.go index 9ed5e3961..60b3ce84f 100644 --- a/x/btcstaking/keeper/btc_height_index.go +++ b/x/btcstaking/keeper/btc_height_index.go @@ -21,16 +21,18 @@ func (k Keeper) IndexBTCHeight(ctx context.Context) { store.Set(sdk.Uint64ToBigEndian(babylonHeight), sdk.Uint64ToBigEndian(btcHeight)) } -func (k Keeper) GetBTCHeightAtBabylonHeight(ctx context.Context, babylonHeight uint64) (uint64, error) { +func (k Keeper) GetBTCHeightAtBabylonHeight(ctx context.Context, babylonHeight uint64) uint64 { store := k.btcHeightStore(ctx) btcHeightBytes := store.Get(sdk.Uint64ToBigEndian(babylonHeight)) if len(btcHeightBytes) == 0 { - return 0, types.ErrBTCHeightNotFound + // if the previous height is not indexed (which might happen at genesis), + // use the base header + return k.btclcKeeper.GetBaseBTCHeader(ctx).Height } - return sdk.BigEndianToUint64(btcHeightBytes), nil + return sdk.BigEndianToUint64(btcHeightBytes) } -func (k Keeper) GetCurrentBTCHeight(ctx context.Context) (uint64, error) { +func (k Keeper) GetCurrentBTCHeight(ctx context.Context) uint64 { babylonHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) return k.GetBTCHeightAtBabylonHeight(ctx, babylonHeight) } diff --git a/x/btcstaking/keeper/btc_height_index_test.go b/x/btcstaking/keeper/btc_height_index_test.go index 27fdf2bc9..b874b3750 100644 --- a/x/btcstaking/keeper/btc_height_index_test.go +++ b/x/btcstaking/keeper/btc_height_index_test.go @@ -32,12 +32,10 @@ func FuzzBTCHeightIndex(f *testing.F) { keeper.IndexBTCHeight(ctx) // assert BTC height - actualBtcHeight, err := keeper.GetBTCHeightAtBabylonHeight(ctx, babylonHeight) - require.NoError(t, err) + actualBtcHeight := keeper.GetBTCHeightAtBabylonHeight(ctx, babylonHeight) require.Equal(t, btcHeight, actualBtcHeight) // assert current BTC height - curBtcHeight, err := keeper.GetCurrentBTCHeight(ctx) - require.NoError(t, err) + curBtcHeight := keeper.GetCurrentBTCHeight(ctx) require.Equal(t, btcHeight, curBtcHeight) }) } diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index f52d17532..87c251ee8 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -236,10 +236,7 @@ func (k Keeper) FinalityProviderDelegations(ctx context.Context, req *types.Quer return err } - curBTCDels, err := k.getBTCDelegatorDelegations(sdkCtx, fpPK, delBTCPK) - if err != nil { - return err - } + curBTCDels := k.getBTCDelegatorDelegations(sdkCtx, fpPK, delBTCPK) btcDelsResp := make([]*types.BTCDelegationResponse, len(curBTCDels.Dels)) for i, btcDel := range curBTCDels.Dels { diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index b3f1d5e40..dabbac899 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "errors" - "math" "math/rand" "testing" @@ -346,9 +345,15 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 10}).AnyTimes() + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper) // covenant and slashing addr covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -487,6 +492,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { startHeight := datagen.RandomInt(r, 100) + 1 endHeight := datagen.RandomInt(r, 1000) + startHeight + btcctypes.DefaultParams().CheckpointFinalizationTimeout + 1 + btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: startHeight}).AnyTimes() // Generate a random number of BTC delegations under this finality provider numBTCDels := datagen.RandomInt(r, 10) + 1 expectedBtcDelsMap := make(map[string]*types.BTCDelegation) @@ -518,14 +524,14 @@ func FuzzFinalityProviderDelegations(f *testing.F) { babylonHeight := datagen.RandomInt(r, 10) + 1 ctx = datagen.WithCtxHeight(ctx, babylonHeight) + keeper.IndexBTCHeight(ctx) + // Generate a page request with a limit and a nil key // query a page of BTC delegations and assert consistency limit := datagen.RandomInt(r, len(expectedBtcDelsMap)) + 1 // FinalityProviderDelegations loads status, which calls GetTipInfo - finalityProviderDelegationCalls := math.Ceil(float64(numBTCDels) / float64(limit)) - tipInfoTimesCalled := int(finalityProviderDelegationCalls + 1) // + call at IndexBTCHeight - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: startHeight}).Times(tipInfoTimesCalled) + btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: startHeight}).AnyTimes() keeper.IndexBTCHeight(ctx) diff --git a/x/btcstaking/keeper/incentive.go b/x/btcstaking/keeper/incentive.go index fe64ce440..d55135281 100644 --- a/x/btcstaking/keeper/incentive.go +++ b/x/btcstaking/keeper/incentive.go @@ -14,15 +14,23 @@ func (k Keeper) setVotingPowerDistCache(ctx context.Context, height uint64, dc * store.Set(sdk.Uint64ToBigEndian(height), k.cdc.MustMarshal(dc)) } -func (k Keeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types.VotingPowerDistCache, error) { +func (k Keeper) getVotingPowerDistCache(ctx context.Context, height uint64) *types.VotingPowerDistCache { store := k.votingPowerDistCacheStore(ctx) rdcBytes := store.Get(sdk.Uint64ToBigEndian(height)) if len(rdcBytes) == 0 { - return nil, types.ErrVotingPowerDistCacheNotFound + return nil } var dc types.VotingPowerDistCache k.cdc.MustUnmarshal(rdcBytes, &dc) - return &dc, nil + return &dc +} + +func (k Keeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types.VotingPowerDistCache, error) { + dc := k.getVotingPowerDistCache(ctx, height) + if dc == nil { + return nil, types.ErrVotingPowerDistCacheNotFound + } + return dc, nil } func (k Keeper) RemoveVotingPowerDistCache(ctx context.Context, height uint64) { diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 0adb764f1..09a75efeb 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -4,15 +4,9 @@ import ( "math/rand" "testing" - sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/chaincfg" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -28,73 +22,56 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper) - - // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) - require.NoError(t, err) - slashingChangeLockTime := uint16(101) + h := NewHelper(t, btclcKeeper, btccKeeper) - // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. - // NOTE - if the rate is higher or lower, it may produce slashing or change outputs - // with value below the dust threshold, causing test failure. - // Our goal is not to test failure due to such extreme cases here; - // this is already covered in FuzzGeneratingValidStakingSlashingTx - slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + h.NoError(err) // generate a random batch of finality providers numFpsWithVotingPower := datagen.RandomInt(r, 10) + 2 numFps := numFpsWithVotingPower + datagen.RandomInt(r, 10) fpsWithVotingPowerMap := map[string]*types.FinalityProvider{} for i := uint64(0); i < numFps; i++ { - fp, err := datagen.GenRandomFinalityProvider(r) - require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + _, _, fp := h.CreateFinalityProvider(r) if i < numFpsWithVotingPower { // these finality providers will receive BTC delegations and have voting power fpsWithVotingPowerMap[fp.BabylonPk.String()] = fp } } - // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations + // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations and add covenant signatures to activate them numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 for _, fp := range fpsWithVotingPowerMap { for j := uint64(0); j < numBTCDels; j++ { - delSK, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - btcDel, err := datagen.GenRandomBTCDelegation( + _, _, _, delMsg, del := h.CreateDelegation( r, - t, - []bbn.BIP340PubKey{*fp.BtcPk}, - delSK, - covenantSKs, - covenantQuorum, - slashingAddress.EncodeAddress(), - 1, 1000, stakingValue, - slashingRate, - slashingChangeLockTime, + fp.BtcPk.MustToBTCPK(), + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, ) - require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) - require.NoError(t, err) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) } } // record voting power distribution cache babylonHeight := datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.BeginBlocker(ctx) + h.Ctx = datagen.WithCtxHeight(h.Ctx, babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) // assert voting power distribution cache is correct - dc, err := keeper.GetVotingPowerDistCache(ctx, babylonHeight) + dc, err := h.BTCStakingKeeper.GetVotingPowerDistCache(h.Ctx, babylonHeight) require.NoError(t, err) + require.NotNil(t, dc) require.Equal(t, dc.TotalVotingPower, numFpsWithVotingPower*numBTCDels*stakingValue) - for _, fpDistInfo := range dc.FinalityProviders { + maxNumFps := h.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders + activeFPs := dc.GetActiveFinalityProviders(maxNumFps) + for _, fpDistInfo := range activeFPs { require.Equal(t, fpDistInfo.TotalVotingPower, numBTCDels*stakingValue) fp, ok := fpsWithVotingPowerMap[fpDistInfo.BabylonPk.String()] require.True(t, ok) diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 55b9f8ed4..93d1698c6 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -61,8 +61,8 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // BeginBlocker is invoked upon `BeginBlock` of the system. The function // iterates over all BTC delegations under non-slashed finality providers // to 1) record the voting power table for the current height, and 2) record -// the voting power distribution cache used for distributing rewards once -// the block is finalised by finality providers. +// the voting power distribution cache used for computing voting power table +// and distributing rewards once the block is finalised by finality providers. func (k Keeper) BeginBlocker(ctx context.Context) error { // index BTC height at the current height k.IndexBTCHeight(ctx) diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 6cf8e67cc..5aa7a92c6 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "context" "math/rand" "testing" @@ -18,6 +17,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -25,7 +25,7 @@ import ( type Helper struct { t testing.TB - Ctx context.Context + Ctx sdk.Context BTCStakingKeeper *keeper.Keeper BTCLightClientKeeper *types.MockBTCLightClientKeeper BTCCheckpointKeeper *types.MockBtcCheckpointKeeper @@ -61,11 +61,19 @@ func (h *Helper) GenAndApplyParams(r *rand.Rand) ([]*btcec.PrivateKey, []*btcec. return h.GenAndApplyCustomParams(r, 100, 0) } +func (h *Helper) SetCtxHeight(height uint64) { + h.Ctx = datagen.WithCtxHeight(h.Ctx, height) +} + func (h *Helper) GenAndApplyCustomParams( r *rand.Rand, finalizationTimeout uint64, minUnbondingTime uint32, ) ([]*btcec.PrivateKey, []*btcec.PublicKey) { + // mock base header + baseHeader := btclctypes.SimnetGenesisBlock() + h.BTCLightClientKeeper.EXPECT().GetBaseBTCHeader(gomock.Any()).Return(&baseHeader).AnyTimes() + // mocking stuff for BTC checkpoint keeper h.BTCCheckpointKeeper.EXPECT().GetPowLimit().Return(h.Net.PowLimit).AnyTimes() @@ -176,8 +184,8 @@ func (h *Helper) CreateDelegationCustom( txInfo := btcctypes.NewTransactionInfo(&btcctypes.TransactionKey{Index: 1, Hash: btcHeader.Hash()}, serializedStakingTx, btcHeaderWithProof.SpvProof.MerkleNodes) // mock for testing k-deep stuff - h.BTCLightClientKeeper.EXPECT().GetHeaderByHash(gomock.Any(), gomock.Eq(btcHeader.Hash())).Return(&btclctypes.BTCHeaderInfo{Header: &btcHeader, Height: 10}).AnyTimes() - h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + h.BTCLightClientKeeper.EXPECT().GetHeaderByHash(gomock.Eq(h.Ctx), gomock.Eq(btcHeader.Hash())).Return(&btclctypes.BTCHeaderInfo{Header: &btcHeader, Height: 10}).AnyTimes() + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() slashingSpendInfo, err := testStakingInfo.StakingInfo.SlashingPathSpendInfo() h.NoError(err) @@ -258,7 +266,7 @@ func (h *Helper) CreateDelegation( changeAddress string, stakingValue int64, stakingTime uint16, -) (string, *btcec.PrivateKey, *btcec.PublicKey, *types.MsgCreateBTCDelegation) { +) (string, *btcec.PrivateKey, *btcec.PublicKey, *types.MsgCreateBTCDelegation, *types.BTCDelegation) { bsParams := h.BTCStakingKeeper.GetParams(h.Ctx) bcParams := h.BTCCheckpointKeeper.GetParams(h.Ctx) @@ -278,7 +286,12 @@ func (h *Helper) CreateDelegation( h.NoError(err) - return stakingTxHash, delSK, delPK, msgCreateBTCDel + stakingMsgTx, err := bbn.NewBTCTxFromBytes(msgCreateBTCDel.StakingTx.Transaction) + h.NoError(err) + btcDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingMsgTx.TxHash().String()) + h.NoError(err) + + return stakingTxHash, delSK, delPK, msgCreateBTCDel, btcDel } func (h *Helper) GenerateCovenantSignaturesMessages( diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index dba2116bd..8335ff62d 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -411,29 +411,11 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre CovenantUnbondingSigList: nil, } + // add this BTC delegation, and emit corresponding events if err := ms.AddBTCDelegation(ctx, newBTCDel); err != nil { - panic(fmt.Errorf("failed to set BTC delegation that has passed verification: %w", err)) + panic(fmt.Errorf("failed to add BTC delegation that has passed verification: %w", err)) } - // notify subscriber - event := &types.EventBTCDelegationStateUpdate{ - StakingTxHash: stakingTxHash.String(), - NewState: types.BTCDelegationStatus_PENDING, - } - if err := ctx.EventManager().EmitTypedEvent(event); err != nil { - panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new pending BTC delegation: %w", err)) - } - - // record event that the BTC delegation becomes pending at this height - pendingEvent := types.NewEventPowerDistUpdateWithBTCDel(event) - ms.addPowerDistUpdateEvent(ctx, btcTip.Height, pendingEvent) - // record event that the BTC delegation will become unbonded at endHeight-w - unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(&types.EventBTCDelegationStateUpdate{ - StakingTxHash: stakingTxHash.String(), - NewState: types.BTCDelegationStatus_UNBONDED, - }) - ms.addPowerDistUpdateEvent(ctx, endHeight-wValue, unbondedEvent) - return &types.MsgCreateBTCDelegationResponse{}, nil } @@ -575,32 +557,16 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove } // All is fine add received signatures to the BTC delegation and BtcUndelegation - btcDel.AddCovenantSigs( + // and emit corresponding events + ms.addCovenantSigsToBTCDelegation( + ctx, + btcDel, req.Pk, parsedSlashingAdaptorSignatures, req.UnbondingTxSig, parsedUnbondingSlashingAdaptorSignatures, ) - ms.setBTCDelegation(ctx, btcDel) - - // If reaching the covenant quorum after this msg, the BTC delegation becomes - // active. Then, record and emit this event - if len(btcDel.CovenantSigs) == int(params.CovenantQuorum) { - // notify subscriber - event := &types.EventBTCDelegationStateUpdate{ - StakingTxHash: req.StakingTxHash, - NewState: types.BTCDelegationStatus_ACTIVE, - } - if err := ctx.EventManager().EmitTypedEvent(event); err != nil { - panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new active BTC delegation: %w", err)) - } - - // record event that the BTC delegation becomes active at this height - activeEvent := types.NewEventPowerDistUpdateWithBTCDel(event) - ms.addPowerDistUpdateEvent(ctx, btcTipHeight, activeEvent) - } - return &types.MsgAddCovenantSigsResponse{}, nil } @@ -659,21 +625,7 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele // all good, add the signature to BTC delegation's undelegation // and set back - btcDel.BtcUndelegation.DelegatorUnbondingSig = req.UnbondingTxSig - ms.setBTCDelegation(ctx, btcDel) - - // notify subscriber about this unbonded BTC delegation - event := &types.EventBTCDelegationStateUpdate{ - StakingTxHash: req.StakingTxHash, - NewState: types.BTCDelegationStatus_UNBONDED, - } - if err := ctx.EventManager().EmitTypedEvent(event); err != nil { - panic(fmt.Errorf("failed to emit EventBTCDelegationStateUpdate for the new unbonded BTC delegation: %w", err)) - } - - // record event that the BTC delegation becomes unbonded at this height - unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(event) - ms.addPowerDistUpdateEvent(ctx, btcTip.Height, unbondedEvent) + ms.btcUndelegate(ctx, btcDel, req.UnbondingTxSig) return &types.MsgBTCUndelegateResponse{}, nil } diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index decc29be6..72098155c 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -151,7 +151,7 @@ func FuzzCreateBTCDelegation(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, _, _, msgCreateBTCDel, _ := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), @@ -198,7 +198,7 @@ func FuzzAddCovenantSigs(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, _, _, msgCreateBTCDel, _ := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), @@ -265,7 +265,7 @@ func FuzzBTCUndelegate(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, delSK, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, delSK, _, msgCreateBTCDel, actualDel := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), @@ -274,8 +274,6 @@ func FuzzBTCUndelegate(f *testing.F) { ) // add covenant signatures to this BTC delegation - actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) - h.NoError(err) h.CreateCovenantSigs(r, covenantSKs, msgCreateBTCDel, actualDel) // ensure the BTC delegation is bonded right now @@ -338,7 +336,7 @@ func FuzzSelectiveSlashing(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), @@ -348,8 +346,6 @@ func FuzzSelectiveSlashing(f *testing.F) { // add covenant signatures to this BTC delegation // so that the BTC delegation becomes bonded - actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) - h.NoError(err) h.CreateCovenantSigs(r, covenantSKs, msgCreateBTCDel, actualDel) // now BTC delegation has all covenant signatures actualDel, err = h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) @@ -406,7 +402,7 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - stakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), @@ -416,8 +412,6 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { // add covenant signatures to this BTC delegation // so that the BTC delegation becomes bonded - actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) - h.NoError(err) h.CreateCovenantSigs(r, covenantSKs, msgCreateBTCDel, actualDel) // now BTC delegation has all covenant signatures actualDel, err = h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index 8771a3f0b..eb763f431 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -4,6 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" + bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,82 +12,215 @@ import ( /* power distribution update */ -// UpdatePowerDist updates the voting power distribution of finality providers -// and their BTC delegations +// UpdatePowerDist updates the voting power table and distribution cache. +// This is triggered upon each `BeginBlock` func (k Keeper) UpdatePowerDist(ctx context.Context) { - params := k.GetParams(ctx) - btcTipHeight, err := k.GetCurrentBTCHeight(ctx) - if err != nil { - panic(err) // only possible upon programming error - } - wValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout - - // prepare metrics for {active, inactive} finality providers, - // {pending, active, unbonded BTC delegations}, and total staked Bitcoins - // NOTE: slashed finality providers and BTC delegations are recorded upon - // slashing events rather than here - var ( - numFPs int = 0 - numStakedSats uint64 = 0 - numDelsMap = map[types.BTCDelegationStatus]int{ - types.BTCDelegationStatus_PENDING: 0, - types.BTCDelegationStatus_ACTIVE: 0, - types.BTCDelegationStatus_UNBONDED: 0, + height := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) + btcTipHeight := k.GetCurrentBTCHeight(ctx) + maxActiveFps := k.GetParams(ctx).MaxActiveFinalityProviders + + // get the power dist cache in the last height + dc := k.getVotingPowerDistCache(ctx, height-1) + // get all power distribution update events during the previous tip + // and the current tip + lastBTCTipHeight := k.GetBTCHeightAtBabylonHeight(ctx, height-1) + events := k.GetAllPowerDistUpdateEvents(ctx, lastBTCTipHeight, btcTipHeight) + + // if no event exists, then map previous voting power and + // cache to the current height + if len(events) == 0 { + if dc != nil { + // map everything in prev height to this height + k.recordVotingPowerAndCache(ctx, dc, maxActiveFps) } - ) - // for voting power and rewards - dc := types.NewVotingPowerDistCache() - - // iterate over all finality providers to find out non-slashed ones that have - // positive voting power - k.IterateActiveFPs( - ctx, - func(fp *types.FinalityProvider) bool { - fpDistInfo := types.NewFinalityProviderDistInfo(fp) - - // iterate over all BTC delegations under the finality provider - // in order to accumulate voting power dist info for it - k.IterateBTCDelegations(ctx, fp.BtcPk, func(btcDel *types.BTCDelegation) bool { - // accumulate voting power and reward distribution cache - fpDistInfo.AddBTCDel(btcDel, btcTipHeight, wValue, params.CovenantQuorum) - - // record metrics - numStakedSats += btcDel.VotingPower(btcTipHeight, wValue, params.CovenantQuorum) - numDelsMap[btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum)]++ - - return true - }) - - if fpDistInfo.TotalVotingPower > 0 { - dc.AddFinalityProviderDistInfo(fpDistInfo) - } + return + } - return true - }, - ) - // record metrics for finality providers and total staked BTCs - numActiveFPs := min(numFPs, int(params.MaxActiveFinalityProviders)) - types.RecordActiveFinalityProviders(numActiveFPs) - types.RecordInactiveFinalityProviders(numFPs - numActiveFPs) - numStakedBTCs := float32(numStakedSats / SatoshisPerBTC) - types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) - // record metrics for BTC delegations - for status, num := range numDelsMap { - types.RecordBTCDelegations(num, status) + if dc == nil { + // no BTC staker at the prior height + dc = types.NewVotingPowerDistCache() } - // filter out top `MaxActiveFinalityProviders` active finality providers in terms of voting power - activeFps := types.FilterTopNFinalityProviders(dc.FinalityProviders, params.MaxActiveFinalityProviders) - // set voting power table and re-calculate total voting power of top N finality providers - dc.TotalVotingPower = uint64(0) + // clear all events that have been consumed in this function + defer func() { + for i := lastBTCTipHeight; i <= btcTipHeight; i++ { + k.ClearPowerDistUpdateEvents(ctx, i) + } + }() + + // reconcile old voting power distribution cache and new events + // to construct the new distribution + newDc := k.processAllPowerDistUpdateEvents(ctx, dc, events, maxActiveFps) + + // record voting power and cache for this height + k.recordVotingPowerAndCache(ctx, newDc, maxActiveFps) + // record metrics + k.recordMetrics(ctx, newDc, maxActiveFps) +} + +func (k Keeper) recordVotingPowerAndCache(ctx context.Context, dc *types.VotingPowerDistCache, maxActiveFps uint32) { babylonTipHeight := uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) - for _, fp := range activeFps { + + // set voting power table for this height + for i := uint32(0); i < dc.GetNumActiveFPs(maxActiveFps); i++ { + fp := dc.FinalityProviders[i] k.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonTipHeight, fp.TotalVotingPower) - dc.TotalVotingPower += fp.TotalVotingPower + } // set the voting power distribution cache of the current height - k.setVotingPowerDistCache(ctx, uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height), dc) + k.setVotingPowerDistCache(ctx, babylonTipHeight, dc) +} + +func (k Keeper) recordMetrics(ctx context.Context, dc *types.VotingPowerDistCache, maxActiveFps uint32) { + // number of active FPs + numActiveFPs := int(dc.GetNumActiveFPs(maxActiveFps)) + types.RecordActiveFinalityProviders(numActiveFPs) + // number of inactive FPs + numInactiveFPs := len(dc.FinalityProviders) - numActiveFPs + types.RecordInactiveFinalityProviders(numInactiveFPs) + // staked Satoshi + // TODO: some wrapper functions between Satoshis and voting power + // to make the 1:1 conversion clear + stakedSats := uint64(0) + for _, fp := range dc.FinalityProviders { + stakedSats += fp.TotalVotingPower + } + numStakedBTCs := float32(stakedSats / SatoshisPerBTC) + types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) + // TODO: record number of BTC delegations under different status +} + +// processAllPowerDistUpdateEvents processes all events that affect +// voting power distribution and returns a new distribution cache. +// The following events will affect the voting power distribution: +// - newly active BTC delegations +// - newly unbonded BTC delegations +// - slashed finality providers +func (k Keeper) processAllPowerDistUpdateEvents( + ctx context.Context, + dc *types.VotingPowerDistCache, + events []*types.EventPowerDistUpdate, + maxActiveFps uint32, +) *types.VotingPowerDistCache { + // a map where key is finality provider's BTC PK hex and value is a list + // of BTC delegations that newly become active under this provider + activeBTCDels := map[string][]*types.BTCDelegation{} + // a map where key is unbonded BTC delegation's staking tx hash + unbondedBTCDels := map[string]struct{}{} + // a map where key is slashed finality providers' BTC PK + slashedFPs := map[string]struct{}{} + + /* + filter and classify all events into new/expired BTC delegations and slashed FPs + */ + for _, event := range events { + switch typedEvent := event.Ev.(type) { + case *types.EventPowerDistUpdate_BtcDelStateUpdate: + delEvent := typedEvent.BtcDelStateUpdate + if delEvent.NewState == types.BTCDelegationStatus_ACTIVE { + // newly active BTC delegation + btcDel, err := k.GetBTCDelegation(ctx, delEvent.StakingTxHash) + if err != nil { + panic(err) // only programming error + } + // add the BTC delegation to each restaked finality provider + for _, fpBTCPK := range btcDel.FpBtcPkList { + fpBTCPKHex := fpBTCPK.MarshalHex() + activeBTCDels[fpBTCPKHex] = append(activeBTCDels[fpBTCPKHex], btcDel) + } + } else if delEvent.NewState == types.BTCDelegationStatus_UNBONDED { + // add the expired BTC delegation to the map + unbondedBTCDels[delEvent.StakingTxHash] = struct{}{} + } + case *types.EventPowerDistUpdate_SlashedFp: + // slashed finality providers + slashedFPs[typedEvent.SlashedFp.Pk.MarshalHex()] = struct{}{} + } + } + + /* + At this point, there is voting power update. + Then, construct a voting power dist cache by reconciling the previous + cache and all the new events. + */ + // TODO: the algorithm needs to iterate over all BTC delegations so remains + // sub-optimal. Ideally we only need to iterate over all events above rather + // than the entire cache. This is made difficulty since BTC delegations are + // not keyed in the cache. Need to find a way to optimise this. + newDc := types.NewVotingPowerDistCache() + + // iterate over all finality providers and apply all events + for i := range dc.FinalityProviders { + // create a copy of the finality provider + fp := *dc.FinalityProviders[i] + fp.TotalVotingPower = 0 + fp.BtcDels = []*types.BTCDelDistInfo{} + + fpBTCPKHex := fp.BtcPk.MarshalHex() + + // if this finality provider is slashed, continue to avoid recording it + if _, ok := slashedFPs[fpBTCPKHex]; ok { + continue + } + + // add all BTC delegations that are not unbonded to the new finality provider + for j := range dc.FinalityProviders[i].BtcDels { + btcDel := *dc.FinalityProviders[i].BtcDels[j] + if _, ok := unbondedBTCDels[btcDel.StakingTxHash]; !ok { + fp.AddBTCDelDistInfo(&btcDel) + } + } + + // process all new BTC delegations under this finality provider + if fpActiveBTCDels, ok := activeBTCDels[fpBTCPKHex]; ok { + // handle new BTC delegations for this finality provider + for _, d := range fpActiveBTCDels { + fp.AddBTCDel(d) + } + // remove the finality provider entry in activeBTCDels map, so that + // after the for loop the rest entries in activeBTCDels belongs to new + // finality providers with new BTC delegations + delete(activeBTCDels, fpBTCPKHex) + } + + // add this finality provider to the new cache if it has voting power + if fp.TotalVotingPower > 0 { + newDc.AddFinalityProviderDistInfo(&fp) + } + } + + /* + process new BTC delegations under new finality providers in activeBTCDels + */ + for fpBTCPKHex, fpActiveBTCDels := range activeBTCDels { + // get the finality provider and initialise its dist info + fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(fpBTCPKHex) + if err != nil { + panic(err) // only programming error + } + newFP, err := k.GetFinalityProvider(ctx, *fpBTCPK) + if err != nil { + panic(err) // only programming error + } + fpDistInfo := types.NewFinalityProviderDistInfo(newFP) + + // add each BTC delegation + for _, d := range fpActiveBTCDels { + fpDistInfo.AddBTCDel(d) + } + + // add this finality provider to the new cache if it has voting power + if fpDistInfo.TotalVotingPower > 0 { + newDc.AddFinalityProviderDistInfo(fpDistInfo) + } + } + + // filter out the top N finality providers and their total voting power, and + // record them in the new cache + newDc.ApplyActiveFinalityProviders(maxActiveFps) + + return newDc } /* voting power distribution update event store */ @@ -138,6 +272,18 @@ func (k Keeper) ClearPowerDistUpdateEvents(ctx context.Context, btcHeight uint64 } } +// GetAllPowerDistUpdateEvents gets all voting power update events +func (k Keeper) GetAllPowerDistUpdateEvents(ctx context.Context, lastBTCTip uint64, curBTCTip uint64) []*types.EventPowerDistUpdate { + events := []*types.EventPowerDistUpdate{} + for i := lastBTCTip; i <= curBTCTip; i++ { + k.IteratePowerDistUpdateEvents(ctx, i, func(event *types.EventPowerDistUpdate) bool { + events = append(events, event) + return true + }) + } + return events +} + // IteratePowerDistUpdateEvents uses the given handler function to handle each // voting power distribution update event that happens at the given BTC height. // This is called in `BeginBlocker` diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index c80124f6e..70ee26303 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -71,15 +71,13 @@ func FuzzBTCDelegationEvents(f *testing.F) { // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) - expectedStakingTxHash, _, _, msgCreateBTCDel := h.CreateDelegation( + expectedStakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( r, fpPK, changeAddress.EncodeAddress(), stakingValue, 1000, ) - actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, expectedStakingTxHash) - h.NoError(err) /* at this point, there should be diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index d486b13d0..8a75d55f6 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -4,15 +4,10 @@ import ( "math/rand" "testing" - sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/chaincfg" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) @@ -28,29 +23,19 @@ func FuzzVotingPowerTable(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + h := NewHelper(t, btclcKeeper, btccKeeper) - // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) - require.NoError(t, err) - slashingChangeLockTime := uint16(101) - // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. - // NOTE - if the rate is higher or lower, it may produce slashing or change outputs - // with value below the dust threshold, causing test failure. - // Our goal is not to test failure due to such extreme cases here; - // this is already covered in FuzzGeneratingValidStakingSlashingTx - slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + h.NoError(err) // generate a random batch of finality providers fps := []*types.FinalityProvider{} numFpsWithVotingPower := datagen.RandomInt(r, 10) + 2 numFps := numFpsWithVotingPower + datagen.RandomInt(r, 10) for i := uint64(0); i < numFps; i++ { - fp, err := datagen.GenRandomFinalityProvider(r) - require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + _, _, fp := h.CreateFinalityProvider(r) fps = append(fps, fp) } @@ -59,93 +44,68 @@ func FuzzVotingPowerTable(f *testing.F) { stakingValue := datagen.RandomInt(r, 100000) + 100000 for i := uint64(0); i < numFpsWithVotingPower; i++ { for j := uint64(0); j < numBTCDels; j++ { - delSK, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - btcDel, err := datagen.GenRandomBTCDelegation( + _, _, _, delMsg, del := h.CreateDelegation( r, - t, - []bbn.BIP340PubKey{*fps[i].BtcPk}, - delSK, - covenantSKs, - covenantQuorum, - slashingAddress.EncodeAddress(), - 1, 1000, stakingValue, - slashingRate, - slashingChangeLockTime, + fps[i].BtcPk.MustToBTCPK(), + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, ) - require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) - require.NoError(t, err) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) } } /* - Case 1: BTC height is 0 that is smaller than start height 1. - No finality privater will have voting power + assert the first numFpsWithVotingPower finality providers have voting power */ babylonHeight := datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 0}).Times(1) - err = keeper.BeginBlocker(ctx) - require.NoError(t, err) - - for i := uint64(0); i < numFps; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) - require.Zero(t, power) - } - - /* - Case 2: move to 1st BTC block, then assert the first numFpsWithVotingPower finality providers have voting power - */ - babylonHeight += datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.BeginBlocker(ctx) + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) for i := uint64(0); i < numFpsWithVotingPower; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) require.Equal(t, numBTCDels*stakingValue, power) } for i := numFpsWithVotingPower; i < numFps; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) require.Zero(t, power) } // also, get voting power table and assert consistency - powerTable := keeper.GetVotingPowerTable(ctx, babylonHeight) + powerTable := h.BTCStakingKeeper.GetVotingPowerTable(h.Ctx, babylonHeight) require.NotNil(t, powerTable) for i := uint64(0); i < numFpsWithVotingPower; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) require.Equal(t, powerTable[fps[i].BtcPk.MarshalHex()], power) } // the activation height should be the current Babylon height as well - activatedHeight, err := keeper.GetBTCStakingActivatedHeight(ctx) + activatedHeight, err := h.BTCStakingKeeper.GetBTCStakingActivatedHeight(h.Ctx) require.NoError(t, err) require.Equal(t, babylonHeight, activatedHeight) /* - Case 3: slash a random finality provider and move on + slash a random finality provider and move on then assert the slashed finality provider does not have voting power */ + // move to next Babylon height + h.BTCLightClientKeeper = btclcKeeper + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() // slash a random finality provider slashedIdx := datagen.RandomInt(r, int(numFpsWithVotingPower)) slashedFp := fps[slashedIdx] - // This will be called to get the slashed height - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.SlashFinalityProvider(ctx, slashedFp.BtcPk.MustMarshal()) + err = h.BTCStakingKeeper.SlashFinalityProvider(h.Ctx, slashedFp.BtcPk.MustMarshal()) require.NoError(t, err) - // move to later Babylon height and 2nd BTC height - babylonHeight += datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 2}).Times(1) // index height and record power table - err = keeper.BeginBlocker(ctx) + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) // check if the slashed finality provider's voting power becomes zero for i := uint64(0); i < numFpsWithVotingPower; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) if i == slashedIdx { require.Zero(t, power) } else { @@ -153,15 +113,15 @@ func FuzzVotingPowerTable(f *testing.F) { } } for i := numFpsWithVotingPower; i < numFps; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) require.Zero(t, power) } // also, get voting power table and assert consistency - powerTable = keeper.GetVotingPowerTable(ctx, babylonHeight) + powerTable = h.BTCStakingKeeper.GetVotingPowerTable(h.Ctx, babylonHeight) require.NotNil(t, powerTable) for i := uint64(0); i < numFpsWithVotingPower; i++ { - power := keeper.GetVotingPower(ctx, *fps[i].BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fps[i].BtcPk, babylonHeight) if i == slashedIdx { require.Zero(t, power) } @@ -169,21 +129,22 @@ func FuzzVotingPowerTable(f *testing.F) { } /* - Case 4: move to 999th BTC block, then assert none of finality providers has voting power (since end height - w < BTC height) + move to 999th BTC block, then assert none of finality providers has voting power (since end height - w < BTC height) */ - babylonHeight += datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 999}).Times(1) - err = keeper.BeginBlocker(ctx) + // replace the old mocked keeper + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 999}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) for _, fp := range fps { - power := keeper.GetVotingPower(ctx, *fp.BtcPk, babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight) require.Zero(t, power) } // the activation height should be same as before - activatedHeight2, err := keeper.GetBTCStakingActivatedHeight(ctx) + activatedHeight2, err := h.BTCStakingKeeper.GetBTCStakingActivatedHeight(h.Ctx) require.NoError(t, err) require.Equal(t, activatedHeight, activatedHeight2) }) @@ -200,51 +161,30 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + h := NewHelper(t, btclcKeeper, btccKeeper) - // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) - require.NoError(t, err) - slashingChangeLockTime := uint16(101) - - // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. - // NOTE - if the rate is higher or lower, it may produce slashing or change outputs - // with value below the dust threshold, causing test failure. - // Our goal is not to test failure due to such extreme cases here; - // this is already covered in FuzzGeneratingValidStakingSlashingTx - slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + h.NoError(err) // generate a random batch of finality providers, each with a BTC delegation with random power fpsWithMeta := []*types.FinalityProviderDistInfo{} numFps := datagen.RandomInt(r, 300) + 1 for i := uint64(0); i < numFps; i++ { // generate finality provider - fp, err := datagen.GenRandomFinalityProvider(r) - require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + _, _, fp := h.CreateFinalityProvider(r) // delegate to this finality provider stakingValue := datagen.RandomInt(r, 100000) + 100000 - fpBTCPK := fp.BtcPk - delSK, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - btcDel, err := datagen.GenRandomBTCDelegation( + _, _, _, delMsg, del := h.CreateDelegation( r, - t, - []bbn.BIP340PubKey{*fpBTCPK}, - delSK, - covenantSKs, - covenantQuorum, - slashingAddress.EncodeAddress(), - 1, 1000, stakingValue, // timelock period: 1-1000 - slashingRate, - slashingChangeLockTime, + fp.BtcPk.MustToBTCPK(), + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, ) - require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) - require.NoError(t, err) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) // record voting power fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderDistInfo{ @@ -253,9 +193,10 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { }) } - maxActiveFpsParam := keeper.GetParams(ctx).MaxActiveFinalityProviders + maxActiveFpsParam := h.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders // get a map of expected active finality providers - expectedActiveFps := types.FilterTopNFinalityProviders(fpsWithMeta, maxActiveFpsParam) + types.SortFinalityProviders(fpsWithMeta) + expectedActiveFps := fpsWithMeta[:min(uint32(len(fpsWithMeta)), maxActiveFpsParam)] expectedActiveFpsMap := map[string]uint64{} for _, fp := range expectedActiveFps { expectedActiveFpsMap[fp.BtcPk.MarshalHex()] = fp.TotalVotingPower @@ -263,24 +204,24 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { // record voting power table babylonHeight := datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.BeginBlocker(ctx) + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) require.NoError(t, err) // only finality providers in expectedActiveFpsMap have voting power for _, fp := range fpsWithMeta { - power := keeper.GetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, fp.BtcPk.MustMarshal(), babylonHeight) if expectedPower, ok := expectedActiveFpsMap[fp.BtcPk.MarshalHex()]; ok { require.Equal(t, expectedPower, power) } else { - require.Equal(t, uint64(0), power) + require.Zero(t, power) } } // also, get voting power table and assert there is // min(len(expectedActiveFps), MaxActiveFinalityProviders) active finality providers - powerTable := keeper.GetVotingPowerTable(ctx, babylonHeight) + powerTable := h.BTCStakingKeeper.GetVotingPowerTable(h.Ctx, babylonHeight) expectedNumActiveFps := len(expectedActiveFpsMap) if expectedNumActiveFps > int(maxActiveFpsParam) { expectedNumActiveFps = int(maxActiveFpsParam) @@ -304,51 +245,31 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + h := NewHelper(t, btclcKeeper, btccKeeper) - // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) - require.NoError(t, err) - slashingChangeLockTime := uint16(101) - - // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. - // NOTE - if the rate is higher or lower, it may produce slashing or change outputs - // with value below the dust threshold, causing test failure. - // Our goal is not to test failure due to such extreme cases here; - // this is already covered in FuzzGeneratingValidStakingSlashingTx - slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + // set all parameters + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + h.NoError(err) // generate a random batch of finality providers, each with a BTC delegation with random power fpsWithMeta := []*types.FinalityProviderWithMeta{} numFps := uint64(200) // there has to be more than `maxActiveFinalityProviders` finality providers for i := uint64(0); i < numFps; i++ { // generate finality provider - fp, err := datagen.GenRandomFinalityProvider(r) - require.NoError(t, err) - keeper.SetFinalityProvider(ctx, fp) + // generate and insert new finality provider + _, fpPK, fp := h.CreateFinalityProvider(r) - // delegate to this finality provider + // create BTC delegation and add covenant signatures to activate it stakingValue := datagen.RandomInt(r, 100000) + 100000 - fpBTCPK := fp.BtcPk - delSK, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - btcDel, err := datagen.GenRandomBTCDelegation( + _, _, _, delMsg, del := h.CreateDelegation( r, - t, - []bbn.BIP340PubKey{*fpBTCPK}, - delSK, - covenantSKs, - covenantQuorum, - slashingAddress.EncodeAddress(), - 1, 1000, stakingValue, // timelock period: 1-1000 - slashingRate, - slashingChangeLockTime, + fpPK, + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, ) - require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) - require.NoError(t, err) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) // record voting power fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderWithMeta{ @@ -359,16 +280,16 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { // record voting power table babylonHeight := datagen.RandomInt(r, 10) + 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.BeginBlocker(ctx) - require.NoError(t, err) + h.Ctx = datagen.WithCtxHeight(h.Ctx, babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) // get maps of active/inactive finality providers activeFpsMap := map[string]uint64{} inactiveFpsMap := map[string]uint64{} for _, fp := range fpsWithMeta { - power := keeper.GetVotingPower(ctx, fp.BtcPk.MustMarshal(), babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, fp.BtcPk.MustMarshal(), babylonHeight) if power > 0 { activeFpsMap[fp.BtcPk.MarshalHex()] = power } else { @@ -381,37 +302,28 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { for fpBTCPKHex := range inactiveFpsMap { stakingValue := uint64(10000000) activatedFpBTCPK, _ = bbn.NewBIP340PubKeyFromHex(fpBTCPKHex) - delSK, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - btcDel, err := datagen.GenRandomBTCDelegation( + _, _, _, delMsg, del := h.CreateDelegation( r, - t, - []bbn.BIP340PubKey{*activatedFpBTCPK}, - delSK, - covenantSKs, - covenantQuorum, - slashingAddress.EncodeAddress(), - 1, 1000, stakingValue, // timelock period: 1-1000 - slashingRate, - slashingChangeLockTime, + activatedFpBTCPK.MustToBTCPK(), + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, ) - require.NoError(t, err) - err = keeper.AddBTCDelegation(ctx, btcDel) - require.NoError(t, err) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) break } // record voting power table babylonHeight += 1 - ctx = datagen.WithCtxHeight(ctx, babylonHeight) - btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 1}).Times(1) - err = keeper.BeginBlocker(ctx) - require.NoError(t, err) + h.Ctx = datagen.WithCtxHeight(h.Ctx, babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) // ensure that the activated finality provider now has entered the active finality provider set // i.e., has voting power - power := keeper.GetVotingPower(ctx, activatedFpBTCPK.MustMarshal(), babylonHeight) + power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, activatedFpBTCPK.MustMarshal(), babylonHeight) require.Positive(t, power) }) } diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index a98323faf..971fefeeb 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -35,22 +35,12 @@ func (fp *FinalityProvider) ValidateBasic() error { return nil } -// FilterTopNFinalityProviders returns the top n finality providers based on VotingPower. -func FilterTopNFinalityProviders(fps []*FinalityProviderDistInfo, n uint32) []*FinalityProviderDistInfo { - numFps := uint32(len(fps)) - - // if the given finality provider set is no bigger than n, no need to do anything - if numFps <= n { - return fps - } - - // Sort the finality providers slice, from higher to lower voting power +// SortFinalityProviders sorts the finality providers slice, +// from higher to lower voting power +func SortFinalityProviders(fps []*FinalityProviderDistInfo) { sort.SliceStable(fps, func(i, j int) bool { return fps[i].TotalVotingPower > fps[j].TotalVotingPower }) - - // Return the top n elements - return fps[:n] } func ExistsDup(btcPKs []bbn.BIP340PubKey) bool { diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index 7d5a8a1ed..02df0f74a 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -10,6 +10,7 @@ import ( ) type BTCLightClientKeeper interface { + GetBaseBTCHeader(ctx context.Context) *btclctypes.BTCHeaderInfo GetTipInfo(ctx context.Context) *btclctypes.BTCHeaderInfo GetHeaderByHash(ctx context.Context, hash *bbn.BTCHeaderHashBytes) *btclctypes.BTCHeaderInfo } diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 3989659a8..1f687ab16 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -12,27 +12,57 @@ func NewVotingPowerDistCache() *VotingPowerDistCache { } } +func (dc *VotingPowerDistCache) Empty() bool { + return len(dc.FinalityProviders) == 0 +} + func (dc *VotingPowerDistCache) AddFinalityProviderDistInfo(v *FinalityProviderDistInfo) { - if v.TotalVotingPower > 0 { - // append finality provider dist info and accumulate voting power - dc.FinalityProviders = append(dc.FinalityProviders, v) - dc.TotalVotingPower += v.TotalVotingPower + dc.FinalityProviders = append(dc.FinalityProviders, v) +} + +// ApplyActiveFinalityProviders sorts all finality providers, counts the total voting +// power of top N finality providers, and records them in cache +func (dc *VotingPowerDistCache) ApplyActiveFinalityProviders(maxActiveFPs uint32) { + // reset total voting power + dc.TotalVotingPower = 0 + // sort finality providers + SortFinalityProviders(dc.FinalityProviders) + // calculate voting power of top N finality providers + numActiveFPs := dc.GetNumActiveFPs(maxActiveFPs) + for i := uint32(0); i < numActiveFPs; i++ { + dc.TotalVotingPower += dc.FinalityProviders[i].TotalVotingPower } } -// FilterVotedFinalityProviders filters out finality providers that have voted according to a map of given voters -// and update total voted power accordingly -func (dc *VotingPowerDistCache) FilterVotedFinalityProviders(voterBTCPKs map[string]struct{}) { +func (dc *VotingPowerDistCache) GetNumActiveFPs(maxActiveFPs uint32) uint32 { + return min(maxActiveFPs, uint32(len(dc.FinalityProviders))) +} + +// GetActiveFinalityProviders returns the list of active finality providers +// i.e., top N of them in terms of voting power +func (dc *VotingPowerDistCache) GetActiveFinalityProviders(maxActiveFPs uint32) []*FinalityProviderDistInfo { + numActiveFPs := dc.GetNumActiveFPs(maxActiveFPs) + return dc.FinalityProviders[:numActiveFPs] +} + +// FilterVotedDistCache filters out a voting power distribution cache +// with finality providers that have voted according to a map of given +// voters, and their total voted power. +func (dc *VotingPowerDistCache) FilterVotedDistCache(maxActiveFPs uint32, voterBTCPKs map[string]struct{}) *VotingPowerDistCache { + activeFPs := dc.GetActiveFinalityProviders(maxActiveFPs) filteredFps := []*FinalityProviderDistInfo{} totalVotingPower := uint64(0) - for _, v := range dc.FinalityProviders { + for _, v := range activeFPs { if _, ok := voterBTCPKs[v.BtcPk.MarshalHex()]; ok { filteredFps = append(filteredFps, v) totalVotingPower += v.TotalVotingPower } } - dc.FinalityProviders = filteredFps - dc.TotalVotingPower = totalVotingPower + + return &VotingPowerDistCache{ + FinalityProviders: filteredFps, + TotalVotingPower: totalVotingPower, + } } // GetFinalityProviderPortion returns the portion of a finality provider's voting power out of the total voting power @@ -54,18 +84,20 @@ func (v *FinalityProviderDistInfo) GetAddress() sdk.AccAddress { return sdk.AccAddress(v.BabylonPk.Address()) } -func (v *FinalityProviderDistInfo) AddBTCDel(btcDel *BTCDelegation, btcHeight uint64, wValue uint64, covenantQuorum uint32) { +func (v *FinalityProviderDistInfo) AddBTCDel(btcDel *BTCDelegation) { btcDelDistInfo := &BTCDelDistInfo{ - BtcPk: btcDel.BtcPk, - BabylonPk: btcDel.BabylonPk, - VotingPower: btcDel.VotingPower(btcHeight, wValue, covenantQuorum), + BtcPk: btcDel.BtcPk, + BabylonPk: btcDel.BabylonPk, + StakingTxHash: btcDel.MustGetStakingTxHash().String(), + VotingPower: btcDel.TotalSat, } + v.BtcDels = append(v.BtcDels, btcDelDistInfo) + v.TotalVotingPower += btcDelDistInfo.VotingPower +} - if btcDelDistInfo.VotingPower > 0 { - // if this BTC delegation has voting power, append it and accumulate voting power - v.BtcDels = append(v.BtcDels, btcDelDistInfo) - v.TotalVotingPower += btcDelDistInfo.VotingPower - } +func (v *FinalityProviderDistInfo) AddBTCDelDistInfo(d *BTCDelDistInfo) { + v.BtcDels = append(v.BtcDels, d) + v.TotalVotingPower += d.VotingPower } // GetBTCDelPortion returns the portion of a BTC delegation's voting power out of diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index 48719ac37..601912c7c 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -151,15 +151,17 @@ func (m *FinalityProviderDistInfo) GetBtcDels() []*BTCDelDistInfo { return nil } -// BTCDelDistInfo contains the information related to reward distribution for a BTC delegations +// BTCDelDistInfo contains the information related to reward distribution for a BTC delegation type BTCDelDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // babylon_pk is the Babylon public key of the BTC delegations + // babylon_pk is the Babylon public key of the BTC delegation BabylonPk *secp256k1.PubKey `protobuf:"bytes,2,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // staking_tx_hash is the staking tx hash of the BTC delegation + StakingTxHash string `protobuf:"bytes,3,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` // voting_power is the voting power of the BTC delegation - VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + VotingPower uint64 `protobuf:"varint,4,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } func (m *BTCDelDistInfo) Reset() { *m = BTCDelDistInfo{} } @@ -202,6 +204,13 @@ func (m *BTCDelDistInfo) GetBabylonPk() *secp256k1.PubKey { return nil } +func (m *BTCDelDistInfo) GetStakingTxHash() string { + if m != nil { + return m.StakingTxHash + } + return "" +} + func (m *BTCDelDistInfo) GetVotingPower() uint64 { if m != nil { return m.VotingPower @@ -220,38 +229,39 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0xc1, 0x6e, 0xd3, 0x30, - 0x18, 0xc7, 0xeb, 0x76, 0x1b, 0xcc, 0x9d, 0x10, 0x44, 0x43, 0x0a, 0x43, 0x4a, 0x4b, 0xa5, 0x49, - 0x3d, 0x30, 0x9b, 0x76, 0xb0, 0x23, 0x42, 0x59, 0x84, 0x34, 0xb1, 0x49, 0x51, 0x85, 0x38, 0x70, - 0xa0, 0x8a, 0x5d, 0x37, 0xb5, 0x92, 0xd8, 0x51, 0xed, 0x05, 0xf2, 0x16, 0x3c, 0x04, 0x8f, 0xc0, - 0x13, 0x70, 0xe2, 0x38, 0x71, 0x42, 0x3b, 0x4c, 0xa8, 0xbd, 0xf0, 0x18, 0x28, 0x89, 0xd9, 0x5a, - 0x44, 0xc4, 0x95, 0x9b, 0x3f, 0xfd, 0xff, 0xff, 0xef, 0xfb, 0xfc, 0xb3, 0x0c, 0xf7, 0x49, 0x40, - 0xf2, 0x58, 0x0a, 0x4c, 0x34, 0x55, 0x3a, 0x88, 0xb8, 0x08, 0x71, 0x36, 0xc0, 0x5c, 0x50, 0x26, - 0x34, 0xcf, 0x18, 0x4a, 0xe7, 0x52, 0x4b, 0xeb, 0xbe, 0xb1, 0xa1, 0x1b, 0x1b, 0xca, 0x06, 0x7b, - 0xbb, 0xa1, 0x0c, 0x65, 0xe9, 0xc0, 0xc5, 0xa9, 0x32, 0xef, 0x3d, 0xa0, 0x52, 0x25, 0x52, 0x8d, - 0x2b, 0xa1, 0x2a, 0x8c, 0xd4, 0xab, 0x2a, 0x4c, 0xe7, 0x79, 0xaa, 0x25, 0x56, 0x8c, 0xa6, 0xc3, - 0x67, 0x47, 0xd1, 0x00, 0x47, 0x2c, 0x37, 0x9e, 0xde, 0x27, 0x00, 0x77, 0xdf, 0x48, 0xcd, 0x45, - 0xe8, 0xcb, 0xf7, 0x6c, 0xee, 0x71, 0xa5, 0x8f, 0x03, 0x3a, 0x63, 0xd6, 0x63, 0x68, 0x69, 0xa9, - 0x83, 0x78, 0x9c, 0x95, 0xea, 0x38, 0x2d, 0x64, 0x1b, 0x74, 0x41, 0x7f, 0x63, 0x74, 0xb7, 0x54, - 0x56, 0x62, 0xd6, 0x3b, 0x68, 0x4d, 0xb9, 0x08, 0x62, 0xae, 0xf3, 0x62, 0x93, 0x8c, 0x4f, 0xd8, - 0x5c, 0xd9, 0xcd, 0x6e, 0xab, 0xdf, 0x1e, 0x62, 0xf4, 0xd7, 0xfb, 0xa0, 0x97, 0x26, 0xe0, 0x1b, - 0x7f, 0x31, 0xfb, 0x44, 0x4c, 0xe5, 0xe8, 0xde, 0xf4, 0x0f, 0x45, 0xf5, 0x7e, 0x36, 0xa1, 0x5d, - 0xe7, 0xb7, 0xce, 0xe0, 0x16, 0xd1, 0x74, 0x9c, 0x46, 0xe5, 0x7a, 0x3b, 0xee, 0xd1, 0xe5, 0x55, - 0x67, 0x18, 0x72, 0x3d, 0x3b, 0x27, 0x88, 0xca, 0x04, 0x9b, 0xf1, 0x74, 0x16, 0x70, 0xf1, 0xbb, - 0xc0, 0x3a, 0x4f, 0x99, 0x42, 0xee, 0x89, 0x7f, 0xf8, 0xf4, 0x89, 0x7f, 0x4e, 0x5e, 0xb1, 0x7c, - 0xb4, 0x49, 0x34, 0xf5, 0x23, 0xeb, 0x39, 0x84, 0xc6, 0x54, 0xb4, 0x6c, 0x76, 0x41, 0xbf, 0x3d, - 0xec, 0x20, 0x43, 0xb6, 0x62, 0x89, 0xae, 0x59, 0x22, 0x93, 0xdd, 0x36, 0x11, 0x3f, 0xb2, 0xce, - 0x20, 0xa4, 0x32, 0x49, 0xb8, 0x52, 0x5c, 0x0a, 0xbb, 0xd5, 0x05, 0xfd, 0x6d, 0xf7, 0xe0, 0xf2, - 0xaa, 0xf3, 0xb0, 0x6a, 0xa1, 0x26, 0x11, 0xe2, 0x12, 0x27, 0x81, 0x9e, 0xa1, 0x53, 0x16, 0x06, - 0x34, 0xf7, 0x18, 0xfd, 0xf6, 0xf9, 0x00, 0x9a, 0x09, 0x1e, 0xa3, 0xa3, 0x95, 0x06, 0x35, 0x0f, - 0xb1, 0x51, 0xf3, 0x10, 0x2f, 0xe0, 0xed, 0x82, 0xc5, 0x84, 0xc5, 0xca, 0xde, 0x2c, 0xf1, 0xef, - 0xd7, 0xe0, 0x77, 0x5f, 0x1f, 0x7b, 0x2c, 0xbe, 0x86, 0x7e, 0x8b, 0x68, 0xea, 0xb1, 0x58, 0xf5, - 0xbe, 0x00, 0x78, 0x67, 0x5d, 0xfb, 0xdf, 0x00, 0x3f, 0x82, 0x3b, 0x6b, 0x2c, 0x5a, 0x25, 0x8b, - 0x76, 0x76, 0x83, 0xc1, 0x3d, 0xfd, 0xba, 0x70, 0xc0, 0xc5, 0xc2, 0x01, 0x3f, 0x16, 0x0e, 0xf8, - 0xb8, 0x74, 0x1a, 0x17, 0x4b, 0xa7, 0xf1, 0x7d, 0xe9, 0x34, 0xde, 0xfe, 0x73, 0xef, 0x0f, 0xab, - 0xbf, 0xb3, 0xbc, 0x04, 0xd9, 0x2a, 0xff, 0xca, 0xe1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, - 0x5e, 0x2e, 0x45, 0xc0, 0x03, 0x00, 0x00, + // 507 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0x9b, 0xee, 0x0f, 0xcc, 0x1d, 0xff, 0xa2, 0x21, 0x95, 0x21, 0xa5, 0xa5, 0xd2, 0x50, + 0x0f, 0xcc, 0xa6, 0x1d, 0xec, 0x88, 0x50, 0x16, 0x21, 0x26, 0x36, 0x29, 0x8a, 0x26, 0x0e, 0x1c, + 0x88, 0x1c, 0xd7, 0x4d, 0xac, 0x24, 0x76, 0x54, 0x7b, 0xa1, 0xf9, 0x16, 0x7c, 0x08, 0x3e, 0x02, + 0x1f, 0x82, 0xe3, 0xc4, 0x09, 0xed, 0x30, 0xa1, 0xf6, 0x82, 0xf8, 0x14, 0x28, 0x89, 0xd9, 0x0a, + 0x5a, 0xc5, 0x95, 0x5b, 0xde, 0x3c, 0xcf, 0xfb, 0xbe, 0x7e, 0x7e, 0x96, 0xc1, 0x4e, 0x80, 0x83, + 0x22, 0x11, 0x1c, 0x05, 0x8a, 0x48, 0x85, 0x63, 0xc6, 0x43, 0x94, 0x0f, 0x10, 0xe3, 0x84, 0x72, + 0xc5, 0x72, 0x0a, 0xb3, 0x89, 0x50, 0xc2, 0xbc, 0xaf, 0x6d, 0xf0, 0xca, 0x06, 0xf3, 0xc1, 0xf6, + 0x56, 0x28, 0x42, 0x51, 0x39, 0x50, 0xf9, 0x55, 0x9b, 0xb7, 0x1f, 0x10, 0x21, 0x53, 0x21, 0xfd, + 0x5a, 0xa8, 0x0b, 0x2d, 0xf5, 0xea, 0x0a, 0x91, 0x49, 0x91, 0x29, 0x81, 0x24, 0x25, 0xd9, 0xf0, + 0xf9, 0x7e, 0x3c, 0x40, 0x31, 0x2d, 0xb4, 0xa7, 0xf7, 0xc9, 0x00, 0x5b, 0x6f, 0x85, 0x62, 0x3c, + 0x74, 0xc5, 0x07, 0x3a, 0x71, 0x98, 0x54, 0x07, 0x98, 0x44, 0xd4, 0x7c, 0x02, 0x4c, 0x25, 0x14, + 0x4e, 0xfc, 0xbc, 0x52, 0xfd, 0xac, 0x94, 0xdb, 0x46, 0xd7, 0xe8, 0xaf, 0x7a, 0x77, 0x2b, 0x65, + 0xa1, 0xcd, 0x7c, 0x0f, 0xcc, 0x31, 0xe3, 0x38, 0x61, 0xaa, 0x28, 0x4f, 0x92, 0xb3, 0x11, 0x9d, + 0xc8, 0x76, 0xb3, 0xbb, 0xd2, 0x6f, 0x0d, 0x11, 0xbc, 0x36, 0x0f, 0x7c, 0xa5, 0x1b, 0x5c, 0xed, + 0x2f, 0x77, 0x1f, 0xf2, 0xb1, 0xf0, 0xee, 0x8d, 0xff, 0x52, 0x64, 0xef, 0x47, 0x13, 0xb4, 0x97, + 0xf9, 0xcd, 0x63, 0xb0, 0x1e, 0x28, 0xe2, 0x67, 0x71, 0x75, 0xbc, 0x4d, 0x7b, 0xff, 0xfc, 0xa2, + 0x33, 0x0c, 0x99, 0x8a, 0x4e, 0x03, 0x48, 0x44, 0x8a, 0xf4, 0x7a, 0x12, 0x61, 0xc6, 0x7f, 0x17, + 0x48, 0x15, 0x19, 0x95, 0xd0, 0x3e, 0x74, 0xf7, 0x9e, 0x3d, 0x75, 0x4f, 0x83, 0x37, 0xb4, 0xf0, + 0xd6, 0x02, 0x45, 0xdc, 0xd8, 0x7c, 0x01, 0x80, 0x36, 0x95, 0x23, 0x9b, 0x5d, 0xa3, 0xdf, 0x1a, + 0x76, 0xa0, 0x26, 0x5b, 0xb3, 0x84, 0x97, 0x2c, 0xa1, 0xee, 0xdd, 0xd0, 0x2d, 0x6e, 0x6c, 0x1e, + 0x03, 0x40, 0x44, 0x9a, 0x32, 0x29, 0x99, 0xe0, 0xed, 0x95, 0xae, 0xd1, 0xdf, 0xb0, 0x77, 0xcf, + 0x2f, 0x3a, 0x0f, 0xeb, 0x11, 0x72, 0x14, 0x43, 0x26, 0x50, 0x8a, 0x55, 0x04, 0x8f, 0x68, 0x88, + 0x49, 0xe1, 0x50, 0xf2, 0xf5, 0xf3, 0x2e, 0xd0, 0x1b, 0x1c, 0x4a, 0xbc, 0x85, 0x01, 0x4b, 0x2e, + 0x62, 0x75, 0xc9, 0x45, 0xbc, 0x04, 0x37, 0x4b, 0x16, 0x23, 0x9a, 0xc8, 0xf6, 0x5a, 0x85, 0x7f, + 0x67, 0x09, 0x7e, 0xfb, 0xe4, 0xc0, 0xa1, 0xc9, 0x25, 0xf4, 0x1b, 0x81, 0x22, 0x0e, 0x4d, 0x64, + 0xef, 0xa7, 0x01, 0x6e, 0xff, 0xa9, 0xfd, 0x6f, 0x80, 0x1f, 0x83, 0x3b, 0x3a, 0x87, 0xaf, 0xa6, + 0x7e, 0x84, 0x65, 0x54, 0x53, 0xf6, 0x6e, 0xe9, 0xdf, 0x27, 0xd3, 0xd7, 0x58, 0x46, 0xe6, 0x23, + 0xb0, 0x79, 0x0d, 0xb3, 0x56, 0x7e, 0x85, 0xcb, 0x3e, 0xfa, 0x32, 0xb3, 0x8c, 0xb3, 0x99, 0x65, + 0x7c, 0x9f, 0x59, 0xc6, 0xc7, 0xb9, 0xd5, 0x38, 0x9b, 0x5b, 0x8d, 0x6f, 0x73, 0xab, 0xf1, 0xee, + 0x9f, 0xf9, 0xa6, 0x8b, 0xaf, 0xb8, 0x0a, 0x1b, 0xac, 0x57, 0x6f, 0x6a, 0xef, 0x57, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x0c, 0xa8, 0xb2, 0x95, 0xe8, 0x03, 0x00, 0x00, } func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { @@ -397,7 +407,14 @@ func (m *BTCDelDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.VotingPower != 0 { i = encodeVarintIncentive(dAtA, i, uint64(m.VotingPower)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x20 + } + if len(m.StakingTxHash) > 0 { + i -= len(m.StakingTxHash) + copy(dAtA[i:], m.StakingTxHash) + i = encodeVarintIncentive(dAtA, i, uint64(len(m.StakingTxHash))) + i-- + dAtA[i] = 0x1a } if m.BabylonPk != nil { { @@ -499,6 +516,10 @@ func (m *BTCDelDistInfo) Size() (n int) { l = m.BabylonPk.Size() n += 1 + l + sovIncentive(uint64(l)) } + l = len(m.StakingTxHash) + if l > 0 { + n += 1 + l + sovIncentive(uint64(l)) + } if m.VotingPower != 0 { n += 1 + sovIncentive(uint64(m.VotingPower)) } @@ -925,6 +946,38 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StakingTxHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowIncentive + } + 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 ErrInvalidLengthIncentive + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthIncentive + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StakingTxHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) } diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index 3ab694c07..75fd1c5d4 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -38,6 +38,20 @@ func (m *MockBTCLightClientKeeper) EXPECT() *MockBTCLightClientKeeperMockRecorde return m.recorder } +// GetBaseBTCHeader mocks base method. +func (m *MockBTCLightClientKeeper) GetBaseBTCHeader(ctx context.Context) *types1.BTCHeaderInfo { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBaseBTCHeader", ctx) + ret0, _ := ret[0].(*types1.BTCHeaderInfo) + return ret0 +} + +// GetBaseBTCHeader indicates an expected call of GetBaseBTCHeader. +func (mr *MockBTCLightClientKeeperMockRecorder) GetBaseBTCHeader(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseBTCHeader", reflect.TypeOf((*MockBTCLightClientKeeper)(nil).GetBaseBTCHeader), ctx) +} + // GetHeaderByHash mocks base method. func (m *MockBTCLightClientKeeper) GetHeaderByHash(ctx context.Context, hash *types.BTCHeaderHashBytes) *types1.BTCHeaderInfo { m.ctrl.T.Helper() diff --git a/x/finality/keeper/tallying.go b/x/finality/keeper/tallying.go index 3bbe1cc0d..6a10d4afa 100644 --- a/x/finality/keeper/tallying.go +++ b/x/finality/keeper/tallying.go @@ -89,9 +89,10 @@ func (k Keeper) finalizeBlock(ctx context.Context, block *types.IndexedBlock, vo panic(err) } // filter out voted finality providers - dc.FilterVotedFinalityProviders(voterBTCPKs) + maxActiveFPs := k.BTCStakingKeeper.GetParams(ctx).MaxActiveFinalityProviders + filteredDc := dc.FilterVotedDistCache(maxActiveFPs, voterBTCPKs) // reward voted finality providers - k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, dc) + k.IncentiveKeeper.RewardBTCStaking(ctx, block.Height, filteredDc) // remove reward distribution cache afterwards k.BTCStakingKeeper.RemoveVotingPowerDistCache(ctx, block.Height) // record the last finalized height metric diff --git a/x/finality/keeper/tallying_test.go b/x/finality/keeper/tallying_test.go index 448fcc58d..6605afc50 100644 --- a/x/finality/keeper/tallying_test.go +++ b/x/finality/keeper/tallying_test.go @@ -97,6 +97,7 @@ func FuzzTallying_FinalizingSomeBlocks(f *testing.F) { defer ctrl.Finish() bsKeeper := types.NewMockBTCStakingKeeper(ctrl) + bsKeeper.EXPECT().GetParams(gomock.Any()).Return(bstypes.Params{MaxActiveFinalityProviders: 100}).AnyTimes() iKeeper := types.NewMockIncentiveKeeper(ctrl) fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index ae4795b8f..942646ba4 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -7,6 +7,7 @@ import ( ) type BTCStakingKeeper interface { + GetParams(ctx context.Context) bstypes.Params GetFinalityProvider(ctx context.Context, fpBTCPK []byte) (*bstypes.FinalityProvider, error) HasFinalityProvider(ctx context.Context, fpBTCPK []byte) bool SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error @@ -19,5 +20,5 @@ type BTCStakingKeeper interface { // IncentiveKeeper defines the expected interface needed to distribute rewards. type IncentiveKeeper interface { - RewardBTCStaking(ctx context.Context, height uint64, dc *bstypes.VotingPowerDistCache) + RewardBTCStaking(ctx context.Context, height uint64, filteredDc *bstypes.VotingPowerDistCache) } diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index 1f2e09366..c5ffaa3e7 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -65,6 +65,20 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetFinalityProvider(ctx, fpBTCPK int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetFinalityProvider), ctx, fpBTCPK) } +// GetParams mocks base method. +func (m *MockBTCStakingKeeper) GetParams(ctx context.Context) types.Params { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetParams", ctx) + ret0, _ := ret[0].(types.Params) + return ret0 +} + +// GetParams indicates an expected call of GetParams. +func (mr *MockBTCStakingKeeperMockRecorder) GetParams(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParams", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetParams), ctx) +} + // GetVotingPower mocks base method. func (m *MockBTCStakingKeeper) GetVotingPower(ctx context.Context, fpBTCPK []byte, height uint64) uint64 { m.ctrl.T.Helper() diff --git a/x/incentive/keeper/btc_staking_gauge.go b/x/incentive/keeper/btc_staking_gauge.go index bf83d32ee..481cf9b63 100644 --- a/x/incentive/keeper/btc_staking_gauge.go +++ b/x/incentive/keeper/btc_staking_gauge.go @@ -11,18 +11,18 @@ import ( ) // RewardBTCStaking distributes rewards to finality providers/delegations at a given height according -// to the reward distribution cache +// to the filtered reward distribution cache (that only contains voted finality providers) // (adapted from https://github.com/cosmos/cosmos-sdk/blob/release/v0.47.x/x/distribution/keeper/allocation.go#L12-L64) -func (k Keeper) RewardBTCStaking(ctx context.Context, height uint64, dc *bstypes.VotingPowerDistCache) { +func (k Keeper) RewardBTCStaking(ctx context.Context, height uint64, filteredDc *bstypes.VotingPowerDistCache) { gauge := k.GetBTCStakingGauge(ctx, height) if gauge == nil { // failing to get a reward gauge at previous height is a programming error panic("failed to get a reward gauge at previous height") } // reward each of the finality provider and its BTC delegations in proportion - for _, fp := range dc.FinalityProviders { + for _, fp := range filteredDc.FinalityProviders { // get coins that will be allocated to the finality provider and its BTC delegations - fpPortion := dc.GetFinalityProviderPortion(fp) + fpPortion := filteredDc.GetFinalityProviderPortion(fp) coinsForFpsAndDels := gauge.GetCoinsPortion(fpPortion) // reward the finality provider with commission coinsForCommission := types.GetCoinsPortion(coinsForFpsAndDels, *fp.Commission) diff --git a/x/incentive/keeper/btc_staking_gauge_test.go b/x/incentive/keeper/btc_staking_gauge_test.go index 711964b98..bd7585324 100644 --- a/x/incentive/keeper/btc_staking_gauge_test.go +++ b/x/incentive/keeper/btc_staking_gauge_test.go @@ -33,7 +33,7 @@ func FuzzRewardBTCStaking(f *testing.F) { keeper.SetBTCStakingGauge(ctx, height, gauge) // generate a random voting power distribution cache - dc, err := datagen.GenRandomVotingPowerDistCache(r) + dc, err := datagen.GenRandomVotingPowerDistCache(r, 100) require.NoError(t, err) // expected values From 4ecc5239b08b805c7d24b8bf2af96a7a2f79d1b8 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 29 Feb 2024 10:54:12 +1100 Subject: [PATCH 030/119] btcstaking: more tests on finality provider set rotation (#502) --- x/btcstaking/keeper/power_dist_change_test.go | 150 ++++++++++++------ .../keeper/voting_power_table_test.go | 106 ++++++++++--- 2 files changed, 186 insertions(+), 70 deletions(-) diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index 70ee26303..393693167 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -25,16 +25,47 @@ func FuzzFinalityProviderEvents(f *testing.F) { h := NewHelper(t, btclcKeeper, btccKeeper) // set all parameters - h.GenAndApplyParams(r) + covenantSKs, _ := h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) // generate and insert new finality provider - _, _, fp := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + /* + insert new BTC delegation and give it covenant quorum + ensure that it has voting power + */ + stakingValue := int64(2 * 10e8) + _, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( + r, + fpPK, + changeAddress.EncodeAddress(), + stakingValue, + 1000, + ) + // give it a quorum number of covenant signatures + msgs := h.GenerateCovenantSignaturesMessages(r, covenantSKs, msgCreateBTCDel, actualDel) + for i := 0; i < int(h.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum); i++ { + _, err = h.MsgServer.AddCovenantSigs(h.Ctx, msgs[i]) + h.NoError(err) + } - // mock BTC tip info - h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 30}).AnyTimes() + // execute BeginBlock + btcTip := btclcKeeper.GetTipInfo(h.Ctx) + babylonHeight := datagen.RandomInt(r, 10) + 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + // ensure the finality provider has voting power at this height + require.Equal(t, uint64(stakingValue), h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) - // slash the finality provider - err := h.BTCStakingKeeper.SlashFinalityProvider(h.Ctx, fp.BtcPk.MustMarshal()) + /* + Slash the finality provider and execute BeginBlock + Then, ensure the finality provider does not have voting power anymore + */ + err = h.BTCStakingKeeper.SlashFinalityProvider(h.Ctx, fp.BtcPk.MustMarshal()) h.NoError(err) // at this point, there should be only 1 event that the finality provider is slashed @@ -45,6 +76,15 @@ func FuzzFinalityProviderEvents(f *testing.F) { require.Equal(t, fp.BtcPk.MustMarshal(), slashedFPEvent.Pk.MustMarshal()) return true }) + + // execute BeginBlock + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + // ensure the finality provider does not have voting power anymore + require.Zero(t, h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) }) } @@ -67,7 +107,7 @@ func FuzzBTCDelegationEvents(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -80,57 +120,73 @@ func FuzzBTCDelegationEvents(f *testing.F) { ) /* - at this point, there should be - - 1 event that BTC delegation becomes pending at current BTC tip - - 1 event that BTC delegation will become expired at end height - w + at this point, there should be 1 event that BTC delegation + will become expired at end height - w */ - // the BTC delegation is now pending - btcTipHeight := btclcKeeper.GetTipInfo(h.Ctx).Height - h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { - btcDelStateUpdate := ev.GetBtcDelStateUpdate() - require.NotNil(t, btcDelStateUpdate) - require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) - require.Equal(t, types.BTCDelegationStatus_PENDING, btcDelStateUpdate.NewState) - return true - }) + // there exists no event at the current BTC tip + btcTip := btclcKeeper.GetTipInfo(h.Ctx) + events := h.BTCStakingKeeper.GetAllPowerDistUpdateEvents(h.Ctx, btcTip.Height, btcTip.Height) + require.Len(t, events, 0) // the BTC delegation will be unbonded at end height - w unbondedHeight := actualDel.EndHeight - btccKeeper.GetParams(h.Ctx).CheckpointFinalizationTimeout - h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, unbondedHeight, func(ev *types.EventPowerDistUpdate) bool { - btcDelStateUpdate := ev.GetBtcDelStateUpdate() - require.NotNil(t, btcDelStateUpdate) - require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) - require.Equal(t, types.BTCDelegationStatus_UNBONDED, btcDelStateUpdate.NewState) - return true - }) - - // clear the events at tip, as per the behaviour of each `BeginBlock` - h.BTCStakingKeeper.ClearPowerDistUpdateEvents(h.Ctx, btcTipHeight) - // ensure event queue is cleared at BTC tip height - numEvents := 0 - h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { - numEvents++ - return true - }) - require.Zero(t, numEvents) + events = h.BTCStakingKeeper.GetAllPowerDistUpdateEvents(h.Ctx, unbondedHeight, unbondedHeight) + require.Len(t, events, 1) + btcDelStateUpdate := events[0].GetBtcDelStateUpdate() + require.NotNil(t, btcDelStateUpdate) + require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) + require.Equal(t, types.BTCDelegationStatus_UNBONDED, btcDelStateUpdate.NewState) + + // ensure this finality provider does not have voting power at the current height + babylonHeight := datagen.RandomInt(r, 10) + 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + require.Zero(t, h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) - // generate a quorum number of covenant signatures + /* + Generate a quorum number of covenant signatures + Then, there should be an event that the BTC delegation becomes + active at the current height + */ msgs := h.GenerateCovenantSignaturesMessages(r, covenantSKs, msgCreateBTCDel, actualDel) for i := 0; i < int(h.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum); i++ { _, err = h.MsgServer.AddCovenantSigs(h.Ctx, msgs[i]) h.NoError(err) } + events = h.BTCStakingKeeper.GetAllPowerDistUpdateEvents(h.Ctx, btcTip.Height, btcTip.Height) + require.Len(t, events, 1) + btcDelStateUpdate = events[0].GetBtcDelStateUpdate() + require.NotNil(t, btcDelStateUpdate) + require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) + require.Equal(t, types.BTCDelegationStatus_ACTIVE, btcDelStateUpdate.NewState) + + // ensure this finality provider has voting power at the current height + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(btcTip).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + require.Equal(t, uint64(stakingValue), h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) + + // ensure event queue is cleared at BTC tip height + events = h.BTCStakingKeeper.GetAllPowerDistUpdateEvents(h.Ctx, btcTip.Height, btcTip.Height) + require.Len(t, events, 0) + /* - at this point, there should be an event that the BTC delegation becomes - active at the current height + BTC height reaches end height - w, such that the BTC delegation becomes expired + ensure the finality provider does not have voting power anymore */ - btcTipHeight = btclcKeeper.GetTipInfo(h.Ctx).Height - h.BTCStakingKeeper.IteratePowerDistUpdateEvents(h.Ctx, btcTipHeight, func(ev *types.EventPowerDistUpdate) bool { - btcDelStateUpdate := ev.GetBtcDelStateUpdate() - require.NotNil(t, btcDelStateUpdate) - require.Equal(t, expectedStakingTxHash, btcDelStateUpdate.StakingTxHash) - require.Equal(t, types.BTCDelegationStatus_ACTIVE, btcDelStateUpdate.NewState) - return true - }) + babylonHeight += 1 + h.SetCtxHeight(babylonHeight) + h.BTCLightClientKeeper.EXPECT().GetTipInfo(gomock.Eq(h.Ctx)).Return(&btclctypes.BTCHeaderInfo{Height: unbondedHeight}).AnyTimes() + err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) + h.NoError(err) + require.Zero(t, h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fp.BtcPk, babylonHeight)) + + // ensure the unbonded event is processed and cleared + events = h.BTCStakingKeeper.GetAllPowerDistUpdateEvents(h.Ctx, unbondedHeight, unbondedHeight) + require.Len(t, events, 0) }) } diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index 8a75d55f6..0696d8708 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -2,10 +2,10 @@ package keeper_test import ( "math/rand" + "sort" "testing" "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/golang/mock/gomock" @@ -249,12 +249,26 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) + // set random number of max number of finality providers + // in order to cover cases that number of finality providers is more or + // less than `MaxActiveFinalityProviders` + bsParams := h.BTCStakingKeeper.GetParams(h.Ctx) + bsParams.MaxActiveFinalityProviders = uint32(datagen.RandomInt(r, 20) + 10) + err := h.BTCStakingKeeper.SetParams(h.Ctx, bsParams) + h.NoError(err) + // change address changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) h.NoError(err) - // generate a random batch of finality providers, each with a BTC delegation with random power + numFps := datagen.RandomInt(r, 20) + 10 + numActiveFPs := int(min(numFps, uint64(bsParams.MaxActiveFinalityProviders))) + + /* + Generate a random batch of finality providers, each with a BTC delegation + with random voting power. + Then, assert voting power table + */ fpsWithMeta := []*types.FinalityProviderWithMeta{} - numFps := uint64(200) // there has to be more than `maxActiveFinalityProviders` finality providers for i := uint64(0); i < numFps; i++ { // generate finality provider // generate and insert new finality provider @@ -285,34 +299,72 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) h.NoError(err) - // get maps of active/inactive finality providers - activeFpsMap := map[string]uint64{} - inactiveFpsMap := map[string]uint64{} - for _, fp := range fpsWithMeta { - power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, fp.BtcPk.MustMarshal(), babylonHeight) - if power > 0 { - activeFpsMap[fp.BtcPk.MarshalHex()] = power - } else { - inactiveFpsMap[fp.BtcPk.MarshalHex()] = power - } + // assert that only top `min(MaxActiveFinalityProviders, numFPs)` finality providers have voting power + sort.SliceStable(fpsWithMeta, func(i, j int) bool { + return fpsWithMeta[i].VotingPower > fpsWithMeta[j].VotingPower + }) + for i := 0; i < numActiveFPs; i++ { + votingPower := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fpsWithMeta[i].BtcPk, babylonHeight) + require.Equal(t, fpsWithMeta[i].VotingPower, votingPower) + } + for i := numActiveFPs; i < int(numFps); i++ { + votingPower := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fpsWithMeta[i].BtcPk, babylonHeight) + require.Zero(t, votingPower) } - // delegate a huge amount of tokens to one of the inactive finality provider - var activatedFpBTCPK *bbn.BIP340PubKey - for fpBTCPKHex := range inactiveFpsMap { - stakingValue := uint64(10000000) - activatedFpBTCPK, _ = bbn.NewBIP340PubKeyFromHex(fpBTCPKHex) + /* + Delegate more tokens to some existing finality providers + , and create some new finality providers + Then assert voting power table again + */ + // delegate more tokens to some existing finality providers + for i := uint64(0); i < numFps; i++ { + if !datagen.OneInN(r, 2) { + continue + } + + stakingValue := datagen.RandomInt(r, 100000) + 100000 + fpBTCPK := fpsWithMeta[i].BtcPk _, _, _, delMsg, del := h.CreateDelegation( r, - activatedFpBTCPK.MustToBTCPK(), + fpBTCPK.MustToBTCPK(), changeAddress.EncodeAddress(), int64(stakingValue), 1000, ) h.CreateCovenantSigs(r, covenantSKs, delMsg, del) + // accumulate voting power for this finality provider + fpsWithMeta[i].VotingPower += stakingValue + break } + // create more finality providers + numNewFps := datagen.RandomInt(r, 20) + 10 + numFps += numNewFps + numActiveFPs = int(min(numFps, uint64(bsParams.MaxActiveFinalityProviders))) + for i := uint64(0); i < numNewFps; i++ { + // generate finality provider + // generate and insert new finality provider + _, fpPK, fp := h.CreateFinalityProvider(r) + + // create BTC delegation and add covenant signatures to activate it + stakingValue := datagen.RandomInt(r, 100000) + 100000 + _, _, _, delMsg, del := h.CreateDelegation( + r, + fpPK, + changeAddress.EncodeAddress(), + int64(stakingValue), + 1000, + ) + h.CreateCovenantSigs(r, covenantSKs, delMsg, del) + + // record voting power + fpsWithMeta = append(fpsWithMeta, &types.FinalityProviderWithMeta{ + BtcPk: fp.BtcPk, + VotingPower: stakingValue, + }) + } // record voting power table babylonHeight += 1 @@ -321,9 +373,17 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { err = h.BTCStakingKeeper.BeginBlocker(h.Ctx) h.NoError(err) - // ensure that the activated finality provider now has entered the active finality provider set - // i.e., has voting power - power := h.BTCStakingKeeper.GetVotingPower(h.Ctx, activatedFpBTCPK.MustMarshal(), babylonHeight) - require.Positive(t, power) + // again, assert that only top `min(MaxActiveFinalityProviders, numFPs)` finality providers have voting power + sort.SliceStable(fpsWithMeta, func(i, j int) bool { + return fpsWithMeta[i].VotingPower > fpsWithMeta[j].VotingPower + }) + for i := 0; i < numActiveFPs; i++ { + votingPower := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fpsWithMeta[i].BtcPk, babylonHeight) + require.Equal(t, fpsWithMeta[i].VotingPower, votingPower) + } + for i := numActiveFPs; i < int(numFps); i++ { + votingPower := h.BTCStakingKeeper.GetVotingPower(h.Ctx, *fpsWithMeta[i].BtcPk, babylonHeight) + require.Zero(t, votingPower) + } }) } From 2684c5f3dc683e2410e63a4a4793234c5df3d4f3 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 4 Mar 2024 17:02:01 +1100 Subject: [PATCH 031/119] btcstaking: addressing leftover minor comments (#523) --- x/btcstaking/keeper/finality_providers.go | 2 +- x/btcstaking/keeper/keeper.go | 4 ---- x/btcstaking/keeper/msg_server.go | 3 ++- x/btcstaking/keeper/power_dist_change.go | 15 +++++++-------- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index abb68f556..6b2a4960f 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -53,7 +53,7 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error fp.SlashedBabylonHeight = uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) btcTip := k.btclcKeeper.GetTipInfo(ctx) if btcTip == nil { - panic(fmt.Errorf("failed to get current BTC tip")) + return fmt.Errorf("failed to get current BTC tip") } fp.SlashedBtcHeight = btcTip.Height k.SetFinalityProvider(ctx, fp) diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 93d1698c6..d239b4aff 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -13,10 +13,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -const ( - SatoshisPerBTC = 100_000_000 -) - type ( Keeper struct { cdc codec.BinaryCodec diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 8335ff62d..60af18f3d 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -458,7 +458,8 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove wValue := ms.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout status := btcDel.GetStatus(btcTipHeight, wValue, params.CovenantQuorum) if status != types.BTCDelegationStatus_PENDING { - return nil, types.ErrInvalidDelegationState.Wrapf("expected: %s, got: %s", types.BTCDelegationStatus_PENDING.String(), status.String()) + ms.Logger(ctx).Debug("Received covenant signature after the BTC delegation is already expired", "covenant pk", req.Pk.MarshalHex()) + return &types.MsgAddCovenantSigsResponse{}, nil } // Note: we assume the order of adaptor sigs is matched to the diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index eb763f431..c3617fa9c 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -6,6 +6,7 @@ import ( "cosmossdk.io/store/prefix" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/btcsuite/btcd/btcutil" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -55,7 +56,7 @@ func (k Keeper) UpdatePowerDist(ctx context.Context) { // record voting power and cache for this height k.recordVotingPowerAndCache(ctx, newDc, maxActiveFps) // record metrics - k.recordMetrics(ctx, newDc, maxActiveFps) + k.recordMetrics(newDc, maxActiveFps) } func (k Keeper) recordVotingPowerAndCache(ctx context.Context, dc *types.VotingPowerDistCache, maxActiveFps uint32) { @@ -72,7 +73,7 @@ func (k Keeper) recordVotingPowerAndCache(ctx context.Context, dc *types.VotingP k.setVotingPowerDistCache(ctx, babylonTipHeight, dc) } -func (k Keeper) recordMetrics(ctx context.Context, dc *types.VotingPowerDistCache, maxActiveFps uint32) { +func (k Keeper) recordMetrics(dc *types.VotingPowerDistCache, maxActiveFps uint32) { // number of active FPs numActiveFPs := int(dc.GetNumActiveFPs(maxActiveFps)) types.RecordActiveFinalityProviders(numActiveFPs) @@ -80,14 +81,12 @@ func (k Keeper) recordMetrics(ctx context.Context, dc *types.VotingPowerDistCach numInactiveFPs := len(dc.FinalityProviders) - numActiveFPs types.RecordInactiveFinalityProviders(numInactiveFPs) // staked Satoshi - // TODO: some wrapper functions between Satoshis and voting power - // to make the 1:1 conversion clear - stakedSats := uint64(0) + stakedSats := btcutil.Amount(0) for _, fp := range dc.FinalityProviders { - stakedSats += fp.TotalVotingPower + stakedSats += btcutil.Amount(fp.TotalVotingPower) } - numStakedBTCs := float32(stakedSats / SatoshisPerBTC) - types.RecordMetricsKeyStakedBitcoins(numStakedBTCs) + numStakedBTCs := stakedSats.ToBTC() + types.RecordMetricsKeyStakedBitcoins(float32(numStakedBTCs)) // TODO: record number of BTC delegations under different status } From 31a890ec76d7ba9c6120f38cf246a1ff8fde0280 Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Mon, 4 Mar 2024 11:49:18 +0400 Subject: [PATCH 032/119] fix: Expedited min deposit should have bbn denom (#524) --- .circleci/config.yml | 10 +++++----- cmd/babylond/cmd/genesis.go | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 538d46c07..399f63355 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ orbs: jobs: build-test: machine: - image: ubuntu-2204:2022.10.1 + image: ubuntu-2204:2024.01.1 resource_class: large steps: - go/install: @@ -35,7 +35,7 @@ jobs: make test e2e-test: machine: - image: ubuntu-2204:2022.10.1 + image: ubuntu-2204:2024.01.1 resource_class: large steps: - go/install: @@ -52,7 +52,7 @@ jobs: sudo make test-e2e lint: machine: - image: ubuntu-2204:2022.10.1 + image: ubuntu-2204:2024.01.1 resource_class: large steps: - go/install: @@ -70,7 +70,7 @@ jobs: build_docker: machine: - image: ubuntu-2204:2022.10.1 + image: ubuntu-2204:2024.01.1 resource_class: large steps: - checkout @@ -93,7 +93,7 @@ jobs: push_docker: machine: - image: ubuntu-2204:2022.10.1 + image: ubuntu-2204:2024.01.1 resource_class: large steps: - attach_workspace: diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 27d9d73ac..fba8dbf6f 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -290,6 +290,10 @@ func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint6 genParams.NativeCoinMetadatas[0].Base, sdkmath.NewInt(2_500_000_000), )) + genParams.GovParams.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewCoin( + genParams.NativeCoinMetadatas[0].Base, + sdkmath.NewInt(2_500_000_000), + )) genParams.CrisisConstantFee = sdk.NewCoin( genParams.NativeCoinMetadatas[0].Base, From 1a3c50da64885452c8d669fcea2a2fad78c8a028 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 4 Mar 2024 07:50:41 -0300 Subject: [PATCH 033/119] chore: update response of queries to use BTCHeaderInfoResponse (#521) * chore: update response of queries to use BTCHeaderInfoResponse * chore: compile sdkmath.Uint as string --- client/docs/swagger-ui/swagger.yaml | 144 +++---- proto/babylon/btclightclient/v1/query.proto | 28 +- test/e2e/btc_staking_e2e_test.go | 6 +- test/e2e/btc_timestamping_e2e_test.go | 6 +- test/e2e/configurer/chain/commands.go | 35 +- test/e2e/configurer/chain/queries.go | 4 +- x/btclightclient/keeper/grpc_query.go | 29 +- x/btclightclient/keeper/grpc_query_test.go | 6 +- x/btclightclient/types/query.go | 25 ++ x/btclightclient/types/query.pb.go | 446 +++++++++++++++++--- 10 files changed, 554 insertions(+), 175 deletions(-) create mode 100644 x/btclightclient/types/query.go diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 2497a2a35..306482f31 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -515,26 +515,24 @@ paths: header: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant - information about a + BTCHeaderInfoResponse is a structure that contains all + relevant information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -856,26 +854,24 @@ paths: items: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant - information about a + BTCHeaderInfoResponse is a structure that contains all + relevant information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -1054,26 +1050,24 @@ paths: header: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant - information about a + BTCHeaderInfoResponse is a structure that contains all + relevant information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -10299,29 +10293,27 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - babylon.btclightclient.v1.BTCHeaderInfo: + babylon.btclightclient.v1.BTCHeaderInfoResponse: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant information about - a + BTCHeaderInfoResponse is a structure that contains all relevant + information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -10344,26 +10336,24 @@ definitions: header: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant information - about a + BTCHeaderInfoResponse is a structure that contains all relevant + information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -10440,26 +10430,24 @@ definitions: items: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant information - about a + BTCHeaderInfoResponse is a structure that contains all relevant + information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -10515,26 +10503,24 @@ definitions: header: type: object properties: - header: + header_hex: type: string - format: byte - hash: + hash_hex: type: string - format: byte height: type: string format: uint64 work: type: string - format: byte + description: Work is the sdkmath.Uint as string. description: >- - BTCHeaderInfo is a structure that contains all relevant information - about a + BTCHeaderInfoResponse is a structure that contains all relevant + information about a - BTC header - - Full header bytes - - Header hash for easy retrieval - - Height of the header in the BTC chain + BTC header response + - Full header as string hex. + - Header hash for easy retrieval as string hex. + - Height of the header in the BTC chain. - Total work spent on the header. This is the sum of the work corresponding to the header Bits field and the total work of the header. @@ -14960,7 +14946,7 @@ definitions: epoch have signed `app_hash` of the sealer header - - The epoch medatata is committed to the `app_hash` of the sealer header + - The epoch metadata is committed to the `app_hash` of the sealer header - The validator set is committed to the `app_hash` of the sealer header babylon.zoneconcierge.v1.ProofFinalizedChainInfo: diff --git a/proto/babylon/btclightclient/v1/query.proto b/proto/babylon/btclightclient/v1/query.proto index 146cbf601..60ae07cc2 100644 --- a/proto/babylon/btclightclient/v1/query.proto +++ b/proto/babylon/btclightclient/v1/query.proto @@ -2,9 +2,9 @@ syntax = "proto3"; package babylon.btclightclient.v1; import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; -import "babylon/btclightclient/v1/btclightclient.proto"; import "babylon/btclightclient/v1/params.proto"; option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; @@ -108,7 +108,7 @@ message QueryMainChainRequest { // QueryMainChainResponse is response type for the Query/MainChain RPC method. message QueryMainChainResponse { - repeated BTCHeaderInfo headers = 1; + repeated BTCHeaderInfoResponse headers = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -117,7 +117,7 @@ message QueryMainChainResponse { message QueryTipRequest {} // QueryTipResponse is the response type for the Query/Tip RPC method. -message QueryTipResponse { BTCHeaderInfo header = 1; } +message QueryTipResponse { BTCHeaderInfoResponse header = 1; } // QueryBaseHeaderRequest is the request type for the Query/BaseHeader RPC // method. @@ -125,7 +125,7 @@ message QueryBaseHeaderRequest {} // QueryBaseHeaderResponse is the response type for the Query/BaseHeader RPC // method. -message QueryBaseHeaderResponse { BTCHeaderInfo header = 1; } +message QueryBaseHeaderResponse { BTCHeaderInfoResponse header = 1; } // QueryMainChainDepthRequest is the request type for the Query/MainChainDepth RPC // it contains hex encoded hash of btc block header as parameter @@ -134,3 +134,23 @@ message QueryHeaderDepthRequest { string hash = 1; } // QueryMainChainDepthResponse is the response type for the Query/MainChainDepth RPC // it contains depth of the block in main chain message QueryHeaderDepthResponse { uint64 depth = 1; } + +// BTCHeaderInfoResponse is a structure that contains all relevant information about a +// BTC header response +// - Full header as string hex. +// - Header hash for easy retrieval as string hex. +// - Height of the header in the BTC chain. +// - Total work spent on the header. This is the sum of the work corresponding +// to the header Bits field +// and the total work of the header. +message BTCHeaderInfoResponse { + string header_hex = 1; + string hash_hex = 2; + uint64 height = 3; + // Work is the sdkmath.Uint as string. + string work = 4 [ + (cosmos_proto.scalar) = "cosmos.Uint", + (gogoproto.customtype) = "cosmossdk.io/math.Uint", + (gogoproto.nullable) = false + ]; +} diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index e72f88682..04aa36010 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -16,6 +16,7 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/test/e2e/configurer" + "github.com/babylonchain/babylon/test/e2e/configurer/chain" "github.com/babylonchain/babylon/test/e2e/initialization" "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" @@ -140,8 +141,11 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { s.NoError(err) // submit staking tx to Bitcoin and get inclusion proof - currentBtcTip, err := nonValidatorNode.QueryTip() + currentBtcTipResp, err := nonValidatorNode.QueryTip() + s.NoError(err) + currentBtcTip, err := chain.ParseBTCHeaderInfoResponseToInfo(currentBtcTipResp) s.NoError(err) + blockWithStakingTx := datagen.CreateBlockWithTransaction(r, currentBtcTip.Header.ToBlockHeader(), stakingMsgTx) nonValidatorNode.InsertHeader(&blockWithStakingTx.HeaderBytes) // make block k-deep diff --git a/test/e2e/btc_timestamping_e2e_test.go b/test/e2e/btc_timestamping_e2e_test.go index 0f7fb1804..db447f5d5 100644 --- a/test/e2e/btc_timestamping_e2e_test.go +++ b/test/e2e/btc_timestamping_e2e_test.go @@ -73,7 +73,7 @@ func (s *BTCTimestampingTestSuite) Test2BTCBaseHeader() { s.NoError(err) baseHeader, err := nonValidatorNode.QueryBtcBaseHeader() s.NoError(err) - s.True(baseHeader.Hash.Eq(hardcodedHeader.Hash())) + s.Equal(baseHeader.HeaderHex, hardcodedHeader.MarshalHex()) s.Equal(hardcodedHeaderHeight, baseHeader.Height) } @@ -94,11 +94,11 @@ func (s *BTCTimestampingTestSuite) Test3SendTx() { s.Equal(tip1.Height+1, tip2.Height) // check that light client properly updates its state - tip1Depth, err := nonValidatorNode.QueryHeaderDepth(tip1.Hash.MarshalHex()) + tip1Depth, err := nonValidatorNode.QueryHeaderDepth(tip1.HashHex) s.NoError(err) s.Equal(tip1Depth, uint64(1)) - tip2Depth, err := nonValidatorNode.QueryHeaderDepth(tip2.Hash.MarshalHex()) + tip2Depth, err := nonValidatorNode.QueryHeaderDepth(tip2.HashHex) s.NoError(err) // tip should have 0 depth s.Equal(tip2Depth, uint64(0)) diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 94335bc60..90dae8a8d 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -86,12 +86,16 @@ func (n *NodeConfig) SendHeaderHex(headerHex string) { } func (n *NodeConfig) InsertNewEmptyBtcHeader(r *rand.Rand) *blc.BTCHeaderInfo { - tip, err := n.QueryTip() + tipResp, err := n.QueryTip() require.NoError(n.t, err) - n.t.Logf("Retrieved current tip of btc headerchain. Height: %d", tip.Height) + n.t.Logf("Retrieved current tip of btc headerchain. Height: %d", tipResp.Height) + + tip, err := ParseBTCHeaderInfoResponseToInfo(tipResp) + require.NoError(n.t, err) + child := datagen.GenRandomValidBTCHeaderInfoWithParent(r, *tip) n.SendHeaderHex(child.Header.MarshalHex()) - n.WaitUntilBtcHeight(tip.Height + 1) + n.WaitUntilBtcHeight(tipResp.Height + 1) return child } @@ -140,7 +144,7 @@ func (n *NodeConfig) FinalizeSealedEpochs(startEpoch uint64, lastEpoch uint64) { for _, checkpoint := range resp.RawCheckpoints { require.Equal(n.t, checkpoint.Status, cttypes.Sealed) - currentBtcTip, err := n.QueryTip() + currentBtcTipResp, err := n.QueryTip() require.NoError(n.t, err) _, submitterAddr, err := bech32.DecodeAndConvert(n.PublicAddress) @@ -160,6 +164,9 @@ func (n *NodeConfig) FinalizeSealedEpochs(startEpoch uint64, lastEpoch uint64) { require.NoError(n.t, err) tx1 := datagen.CreatOpReturnTransaction(r, p1) + currentBtcTip, err := ParseBTCHeaderInfoResponseToInfo(currentBtcTipResp) + require.NoError(n.t, err) + opReturn1 := datagen.CreateBlockWithTransaction(r, currentBtcTip.Header.ToBlockHeader(), tx1) tx2 := datagen.CreatOpReturnTransaction(r, p2) opReturn2 := datagen.CreateBlockWithTransaction(r, opReturn1.HeaderBytes.ToBlockHeader(), tx2) @@ -224,3 +231,23 @@ func (n *NodeConfig) WithdrawReward(sType, from string) { require.NoError(n.t, err) n.LogActionF("successfully withdrawn") } + +// ParseBTCHeaderInfoResponseToInfo turns an BTCHeaderInfoResponse back to BTCHeaderInfo. +func ParseBTCHeaderInfoResponseToInfo(r *blc.BTCHeaderInfoResponse) (*blc.BTCHeaderInfo, error) { + header, err := bbn.NewBTCHeaderBytesFromHex(r.HeaderHex) + if err != nil { + return nil, err + } + + hash, err := bbn.NewBTCHeaderHashBytesFromHex(r.HashHex) + if err != nil { + return nil, err + } + + return &blc.BTCHeaderInfo{ + Header: &header, + Hash: &hash, + Height: r.Height, + Work: &r.Work, + }, nil +} diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index 48b5dba6a..26be927aa 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -206,7 +206,7 @@ func (n *NodeConfig) QueryRawCheckpoints(pagination *query.PageRequest) (*ct.Que return &checkpointingResponse, nil } -func (n *NodeConfig) QueryBtcBaseHeader() (*blc.BTCHeaderInfo, error) { +func (n *NodeConfig) QueryBtcBaseHeader() (*blc.BTCHeaderInfoResponse, error) { bz, err := n.QueryGRPCGateway("babylon/btclightclient/v1/baseheader", url.Values{}) require.NoError(n.t, err) @@ -218,7 +218,7 @@ func (n *NodeConfig) QueryBtcBaseHeader() (*blc.BTCHeaderInfo, error) { return blcResponse.Header, nil } -func (n *NodeConfig) QueryTip() (*blc.BTCHeaderInfo, error) { +func (n *NodeConfig) QueryTip() (*blc.BTCHeaderInfoResponse, error) { bz, err := n.QueryGRPCGateway("babylon/btclightclient/v1/tip", url.Values{}) require.NoError(n.t, err) diff --git a/x/btclightclient/keeper/grpc_query.go b/x/btclightclient/keeper/grpc_query.go index c3230435e..567c51b19 100644 --- a/x/btclightclient/keeper/grpc_query.go +++ b/x/btclightclient/keeper/grpc_query.go @@ -77,13 +77,12 @@ func (k Keeper) ContainsBytes(ctx context.Context, req *types.QueryContainsBytes return &types.QueryContainsBytesResponse{Contains: contains}, nil } -func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) (*types.QueryMainChainResponse, error) { +func (k Keeper) MainChain(c context.Context, req *types.QueryMainChainRequest) (*types.QueryMainChainResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - + ctx := sdk.UnwrapSDKContext(c) if req.Pagination == nil { req.Pagination = &query.PageRequest{} } @@ -98,7 +97,7 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) if err != nil { return nil, status.Error(codes.InvalidArgument, "key does not correspond to a header hash") } - keyHeader, err = k.headersState(sdkCtx).GetHeaderByHash(&headerHash) + keyHeader, err = k.headersState(ctx).GetHeaderByHash(&headerHash) if err != nil { return nil, status.Error(codes.InvalidArgument, "header specified by key does not exist") } @@ -108,10 +107,10 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) var nextKey []byte if req.Pagination.Reverse { var start, end uint64 - baseHeader := k.headersState(sdkCtx).BaseHeader() + baseHeader := k.headersState(ctx).BaseHeader() // The base header is located at the end of the mainchain // which requires starting at the end - mainchain := k.GetMainChainFrom(sdkCtx, 0) + mainchain := k.GetMainChainFrom(ctx, 0) if keyHeader == nil { keyHeader = baseHeader @@ -135,7 +134,7 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) nextKey = mainchain[end].Hash.MustMarshal() } } else { - tip := k.headersState(sdkCtx).GetTip() + tip := k.headersState(ctx).GetTip() // If there is no starting key, then the starting header is the tip if keyHeader == nil { keyHeader = tip @@ -146,7 +145,7 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) // -1 because the depth denotes how many headers have been built on top of it depth := startHeaderDepth + req.Pagination.Limit - 1 // Retrieve the mainchain up to the depth - mainchain := k.GetMainChainUpTo(sdkCtx, depth) + mainchain := k.GetMainChainUpTo(ctx, depth) // Check whether the key provided is part of the mainchain if uint64(len(mainchain)) <= startHeaderDepth || !mainchain[startHeaderDepth].Eq(keyHeader) { return nil, status.Error(codes.InvalidArgument, "header specified by key is not a part of the mainchain") @@ -161,19 +160,17 @@ func (k Keeper) MainChain(ctx context.Context, req *types.QueryMainChainRequest) NextKey: nextKey, } // The headers that we should return start from the depth of the start header - return &types.QueryMainChainResponse{Headers: headers, Pagination: pageRes}, nil + return &types.QueryMainChainResponse{Headers: types.ParseBTCHeadersToResponse(headers), Pagination: pageRes}, nil } -func (k Keeper) Tip(ctx context.Context, req *types.QueryTipRequest) (*types.QueryTipResponse, error) { +func (k Keeper) Tip(c context.Context, req *types.QueryTipRequest) (*types.QueryTipResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - - tip := k.headersState(sdkCtx).GetTip() - - return &types.QueryTipResponse{Header: tip}, nil + ctx := sdk.UnwrapSDKContext(c) + tip := k.headersState(ctx).GetTip() + return &types.QueryTipResponse{Header: tip.ToResponse()}, nil } func (k Keeper) BaseHeader(ctx context.Context, req *types.QueryBaseHeaderRequest) (*types.QueryBaseHeaderResponse, error) { @@ -185,7 +182,7 @@ func (k Keeper) BaseHeader(ctx context.Context, req *types.QueryBaseHeaderReques baseHeader := k.headersState(sdkCtx).BaseHeader() - return &types.QueryBaseHeaderResponse{Header: baseHeader}, nil + return &types.QueryBaseHeaderResponse{Header: baseHeader.ToResponse()}, nil } func (k Keeper) HeaderDepth(ctx context.Context, req *types.QueryHeaderDepthRequest) (*types.QueryHeaderDepthResponse, error) { diff --git a/x/btclightclient/keeper/grpc_query_test.go b/x/btclightclient/keeper/grpc_query_test.go index c5ea9e5f4..15289a490 100644 --- a/x/btclightclient/keeper/grpc_query_test.go +++ b/x/btclightclient/keeper/grpc_query_test.go @@ -300,7 +300,7 @@ func FuzzMainChainQuery(f *testing.F) { } if !resp.Headers[i].Eq(mainchain[idx]) { t.Errorf("%t", reverse) - t.Errorf("Response does not match mainchain. Expected %s got %s", mainchain[idx].Hash, resp.Headers[i].Hash) + t.Errorf("Response does not match mainchain. Expected %s got %s", mainchain[idx].Hash, resp.Headers[i].HashHex) } mcIdx += 1 } @@ -356,7 +356,7 @@ func FuzzTipQuery(f *testing.F) { t.Fatalf("Valid input led to nil response") } if !resp.Header.Eq(chain.GetTipInfo()) { - t.Errorf("Invalid header returned. Expected %s, got %s", chain.GetTipInfo().Hash, resp.Header.Hash) + t.Errorf("Invalid header returned. Expected %s, got %s", chain.GetTipInfo().Hash, resp.Header.HeaderHex) } }) } @@ -402,7 +402,7 @@ func FuzzBaseHeaderQuery(f *testing.F) { t.Fatalf("Valid input led to nil response") } if !resp.Header.Eq(base) { - t.Errorf("Invalid header returned. Expected %s, got %s", base.Hash, resp.Header.Hash) + t.Errorf("Invalid header returned. Expected %s, got %s", base.Hash, resp.Header.HashHex) } }) } diff --git a/x/btclightclient/types/query.go b/x/btclightclient/types/query.go new file mode 100644 index 000000000..a0deed675 --- /dev/null +++ b/x/btclightclient/types/query.go @@ -0,0 +1,25 @@ +package types + +// ToResponse parses one BTC Header Info to BTCHeaderInfoResp. +func (b *BTCHeaderInfo) ToResponse() *BTCHeaderInfoResponse { + return &BTCHeaderInfoResponse{ + HeaderHex: b.Header.MarshalHex(), + HashHex: b.Hash.MarshalHex(), + Height: b.Height, + Work: *b.Work, + } +} + +// ParseBTCHeadersToResponse parses the infos into resposes. +func ParseBTCHeadersToResponse(infos []*BTCHeaderInfo) (resp []*BTCHeaderInfoResponse) { + resp = make([]*BTCHeaderInfoResponse, len(infos)) + for i, info := range infos { + resp[i] = info.ToResponse() + } + return resp +} + +// Eq returns true if the hashes are equal. +func (m *BTCHeaderInfoResponse) Eq(other *BTCHeaderInfo) bool { + return m.HashHex == other.Hash.MarshalHex() +} diff --git a/x/btclightclient/types/query.pb.go b/x/btclightclient/types/query.pb.go index 65d640b56..6148e7143 100644 --- a/x/btclightclient/types/query.pb.go +++ b/x/btclightclient/types/query.pb.go @@ -5,8 +5,10 @@ package types import ( context "context" + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + _ "github.com/cosmos/cosmos-proto" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -430,8 +432,8 @@ func (m *QueryMainChainRequest) GetPagination() *query.PageRequest { // QueryMainChainResponse is response type for the Query/MainChain RPC method. type QueryMainChainResponse struct { - Headers []*BTCHeaderInfo `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + Headers []*BTCHeaderInfoResponse `protobuf:"bytes,1,rep,name=headers,proto3" json:"headers,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryMainChainResponse) Reset() { *m = QueryMainChainResponse{} } @@ -467,7 +469,7 @@ func (m *QueryMainChainResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryMainChainResponse proto.InternalMessageInfo -func (m *QueryMainChainResponse) GetHeaders() []*BTCHeaderInfo { +func (m *QueryMainChainResponse) GetHeaders() []*BTCHeaderInfoResponse { if m != nil { return m.Headers } @@ -520,7 +522,7 @@ var xxx_messageInfo_QueryTipRequest proto.InternalMessageInfo // QueryTipResponse is the response type for the Query/Tip RPC method. type QueryTipResponse struct { - Header *BTCHeaderInfo `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Header *BTCHeaderInfoResponse `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` } func (m *QueryTipResponse) Reset() { *m = QueryTipResponse{} } @@ -556,7 +558,7 @@ func (m *QueryTipResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryTipResponse proto.InternalMessageInfo -func (m *QueryTipResponse) GetHeader() *BTCHeaderInfo { +func (m *QueryTipResponse) GetHeader() *BTCHeaderInfoResponse { if m != nil { return m.Header } @@ -604,7 +606,7 @@ var xxx_messageInfo_QueryBaseHeaderRequest proto.InternalMessageInfo // QueryBaseHeaderResponse is the response type for the Query/BaseHeader RPC // method. type QueryBaseHeaderResponse struct { - Header *BTCHeaderInfo `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` + Header *BTCHeaderInfoResponse `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` } func (m *QueryBaseHeaderResponse) Reset() { *m = QueryBaseHeaderResponse{} } @@ -640,7 +642,7 @@ func (m *QueryBaseHeaderResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryBaseHeaderResponse proto.InternalMessageInfo -func (m *QueryBaseHeaderResponse) GetHeader() *BTCHeaderInfo { +func (m *QueryBaseHeaderResponse) GetHeader() *BTCHeaderInfoResponse { if m != nil { return m.Header } @@ -739,6 +741,76 @@ func (m *QueryHeaderDepthResponse) GetDepth() uint64 { return 0 } +// BTCHeaderInfoResponse is a structure that contains all relevant information about a +// BTC header response +// - Full header as string hex. +// - Header hash for easy retrieval as string hex. +// - Height of the header in the BTC chain. +// - Total work spent on the header. This is the sum of the work corresponding +// to the header Bits field +// and the total work of the header. +type BTCHeaderInfoResponse struct { + HeaderHex string `protobuf:"bytes,1,opt,name=header_hex,json=headerHex,proto3" json:"header_hex,omitempty"` + HashHex string `protobuf:"bytes,2,opt,name=hash_hex,json=hashHex,proto3" json:"hash_hex,omitempty"` + Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` + // Work is the sdkmath.Uint as string. + Work cosmossdk_io_math.Uint `protobuf:"bytes,4,opt,name=work,proto3,customtype=cosmossdk.io/math.Uint" json:"work"` +} + +func (m *BTCHeaderInfoResponse) Reset() { *m = BTCHeaderInfoResponse{} } +func (m *BTCHeaderInfoResponse) String() string { return proto.CompactTextString(m) } +func (*BTCHeaderInfoResponse) ProtoMessage() {} +func (*BTCHeaderInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_3961270631e52721, []int{16} +} +func (m *BTCHeaderInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BTCHeaderInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BTCHeaderInfoResponse.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 *BTCHeaderInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCHeaderInfoResponse.Merge(m, src) +} +func (m *BTCHeaderInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *BTCHeaderInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BTCHeaderInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BTCHeaderInfoResponse proto.InternalMessageInfo + +func (m *BTCHeaderInfoResponse) GetHeaderHex() string { + if m != nil { + return m.HeaderHex + } + return "" +} + +func (m *BTCHeaderInfoResponse) GetHashHex() string { + if m != nil { + return m.HashHex + } + return "" +} + +func (m *BTCHeaderInfoResponse) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btclightclient.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btclightclient.v1.QueryParamsResponse") @@ -756,6 +828,7 @@ func init() { proto.RegisterType((*QueryBaseHeaderResponse)(nil), "babylon.btclightclient.v1.QueryBaseHeaderResponse") proto.RegisterType((*QueryHeaderDepthRequest)(nil), "babylon.btclightclient.v1.QueryHeaderDepthRequest") proto.RegisterType((*QueryHeaderDepthResponse)(nil), "babylon.btclightclient.v1.QueryHeaderDepthResponse") + proto.RegisterType((*BTCHeaderInfoResponse)(nil), "babylon.btclightclient.v1.BTCHeaderInfoResponse") } func init() { @@ -763,59 +836,65 @@ func init() { } var fileDescriptor_3961270631e52721 = []byte{ - // 823 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x4f, 0x13, 0x4d, - 0x18, 0xc7, 0xbb, 0xfc, 0xe8, 0x0b, 0xc3, 0xfb, 0xe6, 0xd5, 0xb1, 0x6a, 0xd9, 0x98, 0x02, 0x8b, - 0x94, 0x02, 0xb2, 0x43, 0x8b, 0x1a, 0x0e, 0x26, 0x9a, 0x62, 0x14, 0x0f, 0x26, 0xb5, 0x69, 0x3c, - 0xa8, 0x89, 0x99, 0x96, 0x71, 0x77, 0x13, 0xba, 0xb3, 0x74, 0x17, 0x62, 0x63, 0xbc, 0x78, 0xf0, - 0x6c, 0xf4, 0xe6, 0xc1, 0x83, 0x89, 0xf1, 0xe6, 0xc9, 0x3f, 0x82, 0x23, 0x89, 0x17, 0xe3, 0x81, - 0x18, 0xf0, 0x8f, 0xf0, 0x68, 0x76, 0xe6, 0xd9, 0xb6, 0xdb, 0x42, 0x77, 0x1b, 0xb9, 0x10, 0x76, - 0xe6, 0xf9, 0x3e, 0xdf, 0xcf, 0x3c, 0xcc, 0x7e, 0x59, 0x34, 0x57, 0xa5, 0xd5, 0xe6, 0x16, 0xb7, - 0x49, 0xd5, 0xab, 0x6d, 0x59, 0x86, 0xe9, 0xff, 0x64, 0xb6, 0x47, 0x76, 0xf3, 0x64, 0x7b, 0x87, - 0x35, 0x9a, 0xba, 0xd3, 0xe0, 0x1e, 0xc7, 0x93, 0x50, 0xa6, 0x87, 0xcb, 0xf4, 0xdd, 0xbc, 0x9a, - 0x32, 0xb8, 0xc1, 0x45, 0x15, 0xf1, 0x7f, 0x93, 0x02, 0xf5, 0x92, 0xc1, 0xb9, 0xb1, 0xc5, 0x08, - 0x75, 0x2c, 0x42, 0x6d, 0x9b, 0x7b, 0xd4, 0xb3, 0xb8, 0xed, 0xc2, 0xee, 0x62, 0x8d, 0xbb, 0x75, - 0xee, 0x92, 0x2a, 0x75, 0x99, 0xf4, 0x21, 0xbb, 0xf9, 0x2a, 0xf3, 0x68, 0x9e, 0x38, 0xd4, 0xb0, - 0x6c, 0x51, 0x0c, 0xb5, 0xfa, 0xc9, 0x84, 0x5d, 0x30, 0xb2, 0x3e, 0x7b, 0x72, 0xbd, 0x43, 0x1b, - 0xb4, 0x0e, 0x0c, 0x5a, 0x0a, 0xe1, 0x07, 0xbe, 0x73, 0x49, 0x2c, 0x96, 0xd9, 0xf6, 0x0e, 0x73, - 0x3d, 0xed, 0x21, 0x3a, 0x17, 0x5a, 0x75, 0x1d, 0x6e, 0xbb, 0x0c, 0xdf, 0x44, 0x49, 0x29, 0x4e, - 0x2b, 0xd3, 0x4a, 0x6e, 0xa2, 0x30, 0xa3, 0x9f, 0x38, 0x10, 0x5d, 0x4a, 0x8b, 0x23, 0x7b, 0x07, - 0x53, 0x89, 0x32, 0xc8, 0xb4, 0x27, 0xe0, 0xb6, 0x41, 0x5d, 0x93, 0x05, 0x6e, 0xf8, 0x0e, 0x42, - 0xed, 0xf3, 0x42, 0xeb, 0xac, 0x2e, 0x87, 0xa3, 0xfb, 0xc3, 0xd1, 0xe5, 0x1f, 0x01, 0x86, 0xa3, - 0x97, 0xa8, 0xc1, 0x40, 0x5b, 0xee, 0x50, 0x6a, 0x5f, 0x15, 0xc0, 0x0e, 0xda, 0x03, 0x76, 0x05, - 0x25, 0x4d, 0xb1, 0x92, 0x56, 0xa6, 0x87, 0x73, 0xff, 0x16, 0x6f, 0xfc, 0x38, 0x98, 0x5a, 0x33, - 0x2c, 0xcf, 0xdc, 0xa9, 0xea, 0x35, 0x5e, 0x27, 0x70, 0x88, 0x9a, 0x49, 0x2d, 0x3b, 0x78, 0x20, - 0x5e, 0xd3, 0x61, 0xae, 0x5e, 0xac, 0xac, 0x6f, 0x30, 0xba, 0xc9, 0x1a, 0x7e, 0xcb, 0x62, 0xd3, - 0x63, 0x6e, 0x19, 0x7a, 0xe1, 0xbb, 0x21, 0xea, 0x21, 0x41, 0x3d, 0x1f, 0x49, 0x2d, 0x91, 0x42, - 0xd8, 0x26, 0x4a, 0x09, 0xea, 0x75, 0x6e, 0x7b, 0xd4, 0xb2, 0x5b, 0x63, 0x29, 0xa1, 0x11, 0xdf, - 0x4a, 0x0c, 0xe4, 0x6f, 0xa1, 0x45, 0x27, 0x6d, 0x15, 0x9d, 0xef, 0x72, 0x82, 0x09, 0xa9, 0x68, - 0xac, 0x06, 0x6b, 0xc2, 0x6e, 0xac, 0xdc, 0x7a, 0xd6, 0x08, 0x9a, 0x0c, 0x89, 0x64, 0x43, 0x60, - 0xc4, 0x9d, 0x8c, 0xe0, 0xb2, 0x86, 0xd4, 0xe3, 0x04, 0x31, 0xac, 0x9e, 0x02, 0xdf, 0x7d, 0x6a, - 0xd9, 0xeb, 0xfe, 0xc1, 0x4e, 0xfb, 0x86, 0x7c, 0x52, 0xd0, 0x85, 0x6e, 0x07, 0xe0, 0x2a, 0xa2, - 0x7f, 0x4c, 0x31, 0x34, 0x79, 0x4b, 0x26, 0x0a, 0xb9, 0x3e, 0x97, 0xbb, 0x35, 0xe1, 0x7b, 0xf6, - 0x33, 0x5e, 0x0e, 0x84, 0xa7, 0x77, 0x25, 0xce, 0xa2, 0xff, 0x05, 0x66, 0xc5, 0x72, 0x82, 0x57, - 0xb2, 0x82, 0xce, 0xb4, 0x97, 0x80, 0xf9, 0x16, 0x4a, 0x4a, 0x6b, 0x18, 0x49, 0x7c, 0x64, 0xd0, - 0x69, 0x69, 0x98, 0x47, 0x91, 0xba, 0x4c, 0x6e, 0x07, 0x7e, 0x8f, 0xd1, 0xc5, 0x9e, 0x9d, 0x53, - 0xb3, 0x5d, 0x86, 0xe6, 0x72, 0xeb, 0x36, 0x73, 0x3c, 0xf3, 0xb8, 0x1b, 0x35, 0x0e, 0x37, 0x6a, - 0x05, 0xa5, 0x7b, 0xcb, 0x01, 0x26, 0x85, 0x46, 0x37, 0xfd, 0x05, 0x21, 0x18, 0x29, 0xcb, 0x87, - 0xc2, 0xef, 0x71, 0x34, 0x2a, 0x24, 0xf8, 0xad, 0x82, 0x92, 0x32, 0x8b, 0xf0, 0x72, 0x1f, 0xce, - 0xde, 0x10, 0x54, 0xf5, 0xb8, 0xe5, 0x92, 0x44, 0x5b, 0x78, 0xf5, 0xed, 0xd7, 0xbb, 0xa1, 0x59, - 0x3c, 0x43, 0xa2, 0xb2, 0x57, 0x40, 0xc9, 0x90, 0x8a, 0x86, 0x0a, 0x65, 0x65, 0x34, 0x54, 0x38, - 0xfb, 0x62, 0x41, 0x41, 0xa0, 0xbd, 0x57, 0xd0, 0x58, 0xf0, 0xce, 0x62, 0x12, 0xe5, 0xd3, 0x95, - 0x56, 0xea, 0x4a, 0x7c, 0x01, 0xa0, 0x2d, 0x09, 0xb4, 0x39, 0x3c, 0xdb, 0x07, 0x2d, 0x88, 0x06, - 0xfc, 0x45, 0x41, 0xff, 0x85, 0x02, 0x05, 0x5f, 0x8d, 0x6b, 0xd8, 0x19, 0x58, 0xea, 0xb5, 0x01, - 0x55, 0xc0, 0xba, 0x22, 0x58, 0x17, 0x71, 0x2e, 0x06, 0xab, 0xc4, 0xfb, 0xa0, 0xa0, 0xf1, 0x56, - 0xca, 0xe0, 0xc8, 0xe9, 0x74, 0x47, 0x9e, 0x9a, 0x1f, 0x40, 0x01, 0x90, 0x57, 0x04, 0x64, 0x16, - 0x5f, 0xee, 0x03, 0x59, 0xa7, 0x96, 0xfc, 0x9f, 0x81, 0x5f, 0x2b, 0x68, 0xb8, 0x62, 0x39, 0x78, - 0x31, 0xca, 0xa8, 0x1d, 0x42, 0xea, 0x52, 0xac, 0x5a, 0xc0, 0xc9, 0x0a, 0x9c, 0x69, 0x9c, 0xe9, - 0x83, 0xe3, 0x59, 0x0e, 0xfe, 0xa8, 0x20, 0xd4, 0x4e, 0x19, 0x1c, 0x79, 0xf0, 0x9e, 0xac, 0x52, - 0x0b, 0x83, 0x48, 0x80, 0x6e, 0x59, 0xd0, 0xcd, 0xe3, 0xb9, 0x3e, 0x74, 0x7e, 0x64, 0xcb, 0xc4, - 0xc2, 0x9f, 0x15, 0x34, 0xd1, 0x11, 0x3f, 0x38, 0xd2, 0xb2, 0x37, 0xda, 0xd4, 0xd5, 0x81, 0x34, - 0xc0, 0x49, 0x04, 0xe7, 0x02, 0x9e, 0xef, 0xc3, 0x29, 0x32, 0x8f, 0xbc, 0xf0, 0xdf, 0xe3, 0x97, - 0xc5, 0xd2, 0xde, 0x61, 0x46, 0xd9, 0x3f, 0xcc, 0x28, 0x3f, 0x0f, 0x33, 0xca, 0x9b, 0xa3, 0x4c, - 0x62, 0xff, 0x28, 0x93, 0xf8, 0x7e, 0x94, 0x49, 0x3c, 0xba, 0x1e, 0xf5, 0xf9, 0xf0, 0xbc, 0xbb, - 0xb7, 0xf8, 0x9e, 0xa8, 0x26, 0xc5, 0xa7, 0xe2, 0xea, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x25, - 0x1e, 0x8e, 0x7d, 0x26, 0x0b, 0x00, 0x00, + // 920 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xc7, 0x33, 0x89, 0xeb, 0x26, 0x2f, 0x20, 0x60, 0x48, 0x83, 0xb3, 0x02, 0x27, 0xdd, 0x92, + 0x1f, 0x4d, 0xf1, 0x4e, 0x9c, 0x00, 0xea, 0x01, 0x09, 0xe1, 0x20, 0x30, 0x48, 0x48, 0xc6, 0x32, + 0x1c, 0x50, 0xa5, 0x68, 0xec, 0x0c, 0xbb, 0xab, 0xc6, 0x3b, 0x5b, 0xef, 0x26, 0xc4, 0x42, 0x5c, + 0x38, 0x70, 0x46, 0x70, 0xe3, 0xc0, 0x81, 0x0b, 0x17, 0xe0, 0xd4, 0x3f, 0xa2, 0xc7, 0x0a, 0x2e, + 0xa8, 0x87, 0x08, 0x25, 0xfc, 0x11, 0x1c, 0xd1, 0xcc, 0xbc, 0xb5, 0xbd, 0x76, 0xea, 0xb5, 0xd5, + 0x5c, 0xa2, 0xcc, 0xcc, 0x7b, 0xef, 0xfb, 0x79, 0xcf, 0xb3, 0xdf, 0x5d, 0x58, 0x6f, 0xf2, 0x66, + 0xf7, 0x48, 0x06, 0xac, 0x19, 0xb7, 0x8e, 0x7c, 0xd7, 0x53, 0x7f, 0x45, 0x10, 0xb3, 0x93, 0x32, + 0x7b, 0x70, 0x2c, 0x3a, 0x5d, 0x27, 0xec, 0xc8, 0x58, 0xd2, 0x15, 0x0c, 0x73, 0xd2, 0x61, 0xce, + 0x49, 0xd9, 0x5a, 0x72, 0xa5, 0x2b, 0x75, 0x14, 0x53, 0xff, 0x99, 0x04, 0x6b, 0xa5, 0x25, 0xa3, + 0xb6, 0x8c, 0x0e, 0xcc, 0x81, 0x59, 0xe0, 0xd1, 0xab, 0xae, 0x94, 0xee, 0x91, 0x60, 0x3c, 0xf4, + 0x19, 0x0f, 0x02, 0x19, 0xf3, 0xd8, 0x97, 0x41, 0x72, 0xba, 0x6d, 0x62, 0x59, 0x93, 0x47, 0xc2, + 0x20, 0xb0, 0x93, 0x72, 0x53, 0xc4, 0xbc, 0xcc, 0x42, 0xee, 0xfa, 0x81, 0x0e, 0xc6, 0xd8, 0x8d, + 0xa7, 0xc3, 0x87, 0xbc, 0xc3, 0xdb, 0x58, 0xd3, 0x5e, 0x02, 0xfa, 0xa9, 0xaa, 0x54, 0xd3, 0x9b, + 0x75, 0xf1, 0xe0, 0x58, 0x44, 0xb1, 0xfd, 0x39, 0xbc, 0x9c, 0xda, 0x8d, 0x42, 0x19, 0x44, 0x82, + 0xbe, 0x0b, 0x79, 0x93, 0x5c, 0x20, 0x6b, 0x64, 0x6b, 0x71, 0xf7, 0xa6, 0xf3, 0xd4, 0xde, 0x1d, + 0x93, 0x5a, 0xc9, 0x3d, 0x3a, 0x5b, 0x9d, 0xa9, 0x63, 0x9a, 0x7d, 0x0f, 0xd5, 0xaa, 0x3c, 0xf2, + 0x44, 0xa2, 0x46, 0x3f, 0x00, 0xe8, 0xf3, 0x63, 0xe9, 0x0d, 0x07, 0x07, 0xa3, 0x9a, 0x75, 0xcc, + 0xbc, 0xb1, 0x59, 0xa7, 0xc6, 0x5d, 0x81, 0xb9, 0xf5, 0x81, 0x4c, 0xfb, 0x21, 0x41, 0xec, 0xa4, + 0x3c, 0x62, 0x37, 0x20, 0xef, 0xe9, 0x9d, 0x02, 0x59, 0x9b, 0xdb, 0x7a, 0xae, 0xf2, 0xce, 0x93, + 0xb3, 0xd5, 0xbb, 0xae, 0x1f, 0x7b, 0xc7, 0x4d, 0xa7, 0x25, 0xdb, 0x0c, 0x9b, 0x68, 0x79, 0xdc, + 0x0f, 0x92, 0x05, 0x8b, 0xbb, 0xa1, 0x88, 0x9c, 0x4a, 0x63, 0xbf, 0x2a, 0xf8, 0xa1, 0xe8, 0xa8, + 0x92, 0x95, 0x6e, 0x2c, 0xa2, 0x3a, 0xd6, 0xa2, 0x1f, 0xa6, 0xa8, 0x67, 0x35, 0xf5, 0x66, 0x26, + 0xb5, 0x41, 0x4a, 0x61, 0x7b, 0xb0, 0xa4, 0xa9, 0xf7, 0x65, 0x10, 0x73, 0x3f, 0xe8, 0x8d, 0xa5, + 0x06, 0x39, 0x25, 0xa5, 0x07, 0xf2, 0xac, 0xd0, 0xba, 0x92, 0xbd, 0x07, 0x37, 0x86, 0x94, 0x70, + 0x42, 0x16, 0xcc, 0xb7, 0x70, 0x4f, 0xcb, 0xcd, 0xd7, 0x7b, 0x6b, 0x9b, 0xc1, 0x4a, 0x2a, 0xc9, + 0x14, 0x44, 0x46, 0x3a, 0xc8, 0x88, 0x2a, 0x77, 0xc1, 0xba, 0x2c, 0x61, 0x02, 0xa9, 0x03, 0xe4, + 0xfb, 0x84, 0xfb, 0xc1, 0xbe, 0x6a, 0xec, 0xaa, 0x6f, 0xc8, 0xef, 0x04, 0x96, 0x87, 0x15, 0x90, + 0xeb, 0x63, 0xb8, 0xee, 0xe9, 0xa1, 0x99, 0x5b, 0xb2, 0xb8, 0xbb, 0x33, 0xe6, 0x72, 0xf7, 0x26, + 0xfc, 0x51, 0xf0, 0xa5, 0xec, 0xfd, 0xa8, 0x49, 0x81, 0xab, 0xbb, 0x1a, 0x2f, 0xc1, 0x0b, 0x1a, + 0xb7, 0xe1, 0x87, 0xc9, 0xa3, 0x79, 0x0f, 0x5e, 0xec, 0x6f, 0x21, 0x7b, 0x15, 0xf2, 0x46, 0x1a, + 0x47, 0x33, 0x3d, 0x3a, 0xe6, 0xdb, 0x05, 0x9c, 0x4f, 0x85, 0x47, 0xc2, 0x84, 0x25, 0xba, 0x2d, + 0x78, 0x65, 0xe4, 0xe4, 0xca, 0xe5, 0x4b, 0x28, 0x62, 0x42, 0xde, 0x17, 0x61, 0xec, 0x5d, 0x76, + 0xd3, 0x16, 0xf0, 0xa6, 0xed, 0x40, 0x61, 0x34, 0x1c, 0xa1, 0x96, 0xe0, 0xda, 0xa1, 0xda, 0xd0, + 0x09, 0xb9, 0xba, 0x59, 0xd8, 0xbf, 0x11, 0xb8, 0x71, 0x29, 0x02, 0x7d, 0x0d, 0xc0, 0x40, 0x1c, + 0x78, 0xe2, 0x14, 0x55, 0x16, 0xcc, 0x4e, 0x55, 0x9c, 0xd2, 0x15, 0x98, 0x57, 0x92, 0xfa, 0x70, + 0x56, 0x1f, 0x5e, 0x57, 0x6b, 0x75, 0xb4, 0xac, 0xda, 0x57, 0x5d, 0x16, 0xe6, 0xb4, 0x14, 0xae, + 0xe8, 0x7b, 0x90, 0xfb, 0x4a, 0x76, 0xee, 0x17, 0x72, 0x2a, 0xbc, 0x52, 0x52, 0x46, 0xf8, 0xe4, + 0x6c, 0x75, 0xd9, 0x5c, 0x83, 0xe8, 0xf0, 0xbe, 0xe3, 0x4b, 0xd6, 0xe6, 0xb1, 0xe7, 0x7c, 0xe6, + 0x07, 0xf1, 0x9f, 0x0f, 0x4b, 0x8b, 0x78, 0x41, 0xd4, 0xb2, 0xae, 0x53, 0x77, 0xff, 0x5b, 0x80, + 0x6b, 0xba, 0x43, 0xfa, 0x03, 0x81, 0xbc, 0xb1, 0x54, 0x5a, 0x1a, 0x33, 0xde, 0x51, 0x2f, 0xb7, + 0x9c, 0x49, 0xc3, 0xcd, 0x20, 0xec, 0xdb, 0xdf, 0xfe, 0xf5, 0xef, 0x8f, 0xb3, 0xb7, 0xe8, 0x4d, + 0x96, 0xf5, 0x0a, 0xd1, 0x50, 0xc6, 0x6b, 0xb3, 0xa1, 0x52, 0x96, 0x9f, 0x0d, 0x95, 0xb6, 0xf0, + 0x89, 0xa0, 0xd0, 0x97, 0x7f, 0x22, 0x30, 0x9f, 0x58, 0x0f, 0x65, 0x59, 0x3a, 0x43, 0xa6, 0x6b, + 0xed, 0x4c, 0x9e, 0x80, 0x68, 0x77, 0x34, 0xda, 0x3a, 0xbd, 0x35, 0x06, 0x2d, 0x71, 0x38, 0xfa, + 0x07, 0x81, 0xe7, 0x53, 0xbe, 0x48, 0xdf, 0x9c, 0x54, 0x70, 0xd0, 0x77, 0xad, 0xb7, 0xa6, 0xcc, + 0x42, 0xd6, 0x1d, 0xcd, 0xba, 0x4d, 0xb7, 0x26, 0x60, 0x35, 0x78, 0x3f, 0x13, 0x58, 0xe8, 0x99, + 0x25, 0xcd, 0x9c, 0xce, 0xb0, 0x73, 0x5b, 0xe5, 0x29, 0x32, 0x10, 0xf2, 0x0d, 0x0d, 0xb9, 0x41, + 0x5f, 0x1f, 0x03, 0xd9, 0xe6, 0xbe, 0x79, 0xf5, 0xd1, 0xef, 0x08, 0xcc, 0x35, 0xfc, 0x90, 0x6e, + 0x67, 0x09, 0xf5, 0x3d, 0xd4, 0xba, 0x33, 0x51, 0x2c, 0xe2, 0x6c, 0x68, 0x9c, 0x35, 0x5a, 0x1c, + 0x83, 0x13, 0xfb, 0x21, 0xfd, 0x85, 0x00, 0xf4, 0xcd, 0x91, 0x66, 0x36, 0x3e, 0x62, 0xb1, 0xd6, + 0xee, 0x34, 0x29, 0x48, 0x57, 0xd2, 0x74, 0x9b, 0x74, 0x7d, 0x0c, 0x9d, 0x7a, 0xe3, 0x18, 0x27, + 0xa3, 0xbf, 0x12, 0x58, 0x1c, 0x70, 0x4b, 0x9a, 0x29, 0x39, 0xea, 0xc4, 0xd6, 0xde, 0x54, 0x39, + 0xc8, 0xc9, 0x34, 0xe7, 0x6d, 0xba, 0x39, 0x86, 0x53, 0x5b, 0x34, 0xfb, 0x5a, 0x3d, 0xc7, 0xdf, + 0x54, 0x6a, 0x8f, 0xce, 0x8b, 0xe4, 0xf1, 0x79, 0x91, 0xfc, 0x73, 0x5e, 0x24, 0xdf, 0x5f, 0x14, + 0x67, 0x1e, 0x5f, 0x14, 0x67, 0xfe, 0xbe, 0x28, 0xce, 0x7c, 0xf1, 0x76, 0xd6, 0x57, 0xd0, 0xe9, + 0x70, 0x6d, 0xfd, 0x59, 0xd4, 0xcc, 0xeb, 0x2f, 0xde, 0xbd, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, + 0x93, 0xd5, 0xc3, 0x8e, 0xd8, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1705,6 +1784,58 @@ func (m *QueryHeaderDepthResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *BTCHeaderInfoResponse) 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 *BTCHeaderInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BTCHeaderInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Work.Size() + i -= size + if _, err := m.Work.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x18 + } + if len(m.HashHex) > 0 { + i -= len(m.HashHex) + copy(dAtA[i:], m.HashHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.HashHex))) + i-- + dAtA[i] = 0x12 + } + if len(m.HeaderHex) > 0 { + i -= len(m.HeaderHex) + copy(dAtA[i:], m.HeaderHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.HeaderHex))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1919,6 +2050,28 @@ func (m *QueryHeaderDepthResponse) Size() (n int) { return n } +func (m *BTCHeaderInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.HeaderHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.HashHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + l = m.Work.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2718,7 +2871,7 @@ func (m *QueryMainChainResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Headers = append(m.Headers, &BTCHeaderInfo{}) + m.Headers = append(m.Headers, &BTCHeaderInfoResponse{}) if err := m.Headers[len(m.Headers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -2889,7 +3042,7 @@ func (m *QueryTipResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Header == nil { - m.Header = &BTCHeaderInfo{} + m.Header = &BTCHeaderInfoResponse{} } if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3025,7 +3178,7 @@ func (m *QueryBaseHeaderResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Header == nil { - m.Header = &BTCHeaderInfo{} + m.Header = &BTCHeaderInfoResponse{} } if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3203,6 +3356,173 @@ func (m *QueryHeaderDepthResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *BTCHeaderInfoResponse) 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 ErrIntOverflowQuery + } + 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: BTCHeaderInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCHeaderInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HeaderHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HeaderHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HashHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.HashHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Work", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Work.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 6896f6c8db1430c57ca62eec078ac227e333dcf7 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Tue, 5 Mar 2024 08:42:08 -0300 Subject: [PATCH 034/119] chore: update query LastCheckpointWithStatus to use response structure (#525) --- client/docs/swagger-ui/swagger.yaml | 48 +- proto/babylon/checkpointing/v1/query.proto | 23 +- .../keeper/grpc_query_checkpoint.go | 2 +- .../keeper/grpc_query_checkpoint_test.go | 4 +- x/checkpointing/types/query.go | 11 + x/checkpointing/types/query.pb.go | 452 +++++++++++++++--- 6 files changed, 460 insertions(+), 80 deletions(-) create mode 100644 x/checkpointing/types/query.go diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 306482f31..d6224245f 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4816,14 +4816,14 @@ paths: title: >- epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: >- - block_hash defines the 'BlockID.Hash', which is the hash - of + block_hash_hex defines the 'BlockID.Hash', which is the + hash of - the block that individual BLS sigs are signed on + the block that individual BLS sigs are signed on as hex + string bitmap: type: string format: byte @@ -4838,7 +4838,7 @@ paths: from individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata description: |- QueryLastCheckpointWithStatusResponse is the response type for the Query/LastCheckpointWithStatus RPC method. @@ -13361,12 +13361,11 @@ definitions: type: string format: uint64 title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on + block_hash_hex defines the 'BlockID.Hash', which is the hash of + the block that individual BLS sigs are signed on as hex string bitmap: type: string format: byte @@ -13381,7 +13380,7 @@ definitions: individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata description: |- QueryLastCheckpointWithStatusResponse is the response type for the Query/LastCheckpointWithStatus RPC method. @@ -13830,6 +13829,33 @@ definitions: sigs title: RawCheckpoint wraps the BLS multi sig with metadata + babylon.checkpointing.v1.RawCheckpointResponse: + type: object + properties: + epoch_num: + type: string + format: uint64 + title: epoch_num defines the epoch number the raw checkpoint is for + block_hash_hex: + type: string + title: |- + block_hash_hex defines the 'BlockID.Hash', which is the hash of + the block that individual BLS sigs are signed on as hex string + bitmap: + type: string + format: byte + title: >- + bitmap defines the bitmap that indicates the signers of the BLS multi + sig + bls_multi_sig: + type: string + format: byte + title: >- + bls_multi_sig defines the multi sig that is aggregated from individual + BLS + + sigs + title: RawCheckpointResponse wraps the BLS multi sig with metadata babylon.checkpointing.v1.RawCheckpointWithMeta: type: object properties: diff --git a/proto/babylon/checkpointing/v1/query.proto b/proto/babylon/checkpointing/v1/query.proto index b522c9a7e..e73c7bc23 100644 --- a/proto/babylon/checkpointing/v1/query.proto +++ b/proto/babylon/checkpointing/v1/query.proto @@ -1,10 +1,11 @@ syntax = "proto3"; package babylon.checkpointing.v1; -import "babylon/checkpointing/v1/bls_key.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; +import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; +import "babylon/checkpointing/v1/bls_key.proto"; import "babylon/checkpointing/v1/checkpoint.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; @@ -161,5 +162,21 @@ message QueryLastCheckpointWithStatusRequest { CheckpointStatus status = 1; } // QueryLastCheckpointWithStatusResponse is the response type for the // Query/LastCheckpointWithStatus RPC method. message QueryLastCheckpointWithStatusResponse { - RawCheckpoint raw_checkpoint = 1; + RawCheckpointResponse raw_checkpoint = 1; } + +// RawCheckpointResponse wraps the BLS multi sig with metadata +message RawCheckpointResponse { + // epoch_num defines the epoch number the raw checkpoint is for + uint64 epoch_num = 1; + // block_hash_hex defines the 'BlockID.Hash', which is the hash of + // the block that individual BLS sigs are signed on as hex string + string block_hash_hex = 2; + // bitmap defines the bitmap that indicates the signers of the BLS multi sig + bytes bitmap = 3; + // bls_multi_sig defines the multi sig that is aggregated from individual BLS + // sigs + bytes bls_multi_sig = 4 [ + (gogoproto.customtype) = "github.com/babylonchain/babylon/crypto/bls12381.Signature" + ]; +} \ No newline at end of file diff --git a/x/checkpointing/keeper/grpc_query_checkpoint.go b/x/checkpointing/keeper/grpc_query_checkpoint.go index b0b2c28e8..43121b36d 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint.go @@ -153,7 +153,7 @@ func (k Keeper) LastCheckpointWithStatus(ctx context.Context, req *types.QueryLa return nil, fmt.Errorf("failed to get the raw checkpoint at epoch %v: %w", e, err) } if ckpt.Status == req.Status || ckpt.IsMoreMatureThanStatus(req.Status) { - return &types.QueryLastCheckpointWithStatusResponse{RawCheckpoint: ckpt.Ckpt}, nil + return &types.QueryLastCheckpointWithStatusResponse{RawCheckpoint: ckpt.Ckpt.ToResponse()}, nil } } return nil, fmt.Errorf("cannot find checkpoint with status %v", req.Status) diff --git a/x/checkpointing/keeper/grpc_query_checkpoint_test.go b/x/checkpointing/keeper/grpc_query_checkpoint_test.go index ef01034a4..3a20467ad 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint_test.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint_test.go @@ -144,7 +144,7 @@ func FuzzQueryLastCheckpointWithStatus(f *testing.F) { // request the last finalized checkpoint req := types.NewQueryLastCheckpointWithStatus(types.Finalized) expectedResp := &types.QueryLastCheckpointWithStatusResponse{ - RawCheckpoint: checkpoints[int(finalizedEpoch)].Ckpt, + RawCheckpoint: checkpoints[int(finalizedEpoch)].Ckpt.ToResponse(), } resp, err := ckptKeeper.LastCheckpointWithStatus(ctx, req) require.NoError(t, err) @@ -153,7 +153,7 @@ func FuzzQueryLastCheckpointWithStatus(f *testing.F) { // request the last confirmed checkpoint req = types.NewQueryLastCheckpointWithStatus(types.Confirmed) expectedResp = &types.QueryLastCheckpointWithStatusResponse{ - RawCheckpoint: checkpoints[int(finalizedEpoch)].Ckpt, + RawCheckpoint: checkpoints[int(finalizedEpoch)].Ckpt.ToResponse(), } resp, err = ckptKeeper.LastCheckpointWithStatus(ctx, req) require.NoError(t, err) diff --git a/x/checkpointing/types/query.go b/x/checkpointing/types/query.go new file mode 100644 index 000000000..1632cefa8 --- /dev/null +++ b/x/checkpointing/types/query.go @@ -0,0 +1,11 @@ +package types + +// ToResponse generates a RawCheckpointResponse struct from RawCheckpoint. +func (r *RawCheckpoint) ToResponse() *RawCheckpointResponse { + return &RawCheckpointResponse{ + EpochNum: r.EpochNum, + BlockHashHex: r.BlockHash.String(), + Bitmap: r.Bitmap, + BlsMultiSig: r.BlsMultiSig, + } +} diff --git a/x/checkpointing/types/query.pb.go b/x/checkpointing/types/query.pb.go index 96dcf8fc1..6a4374c0b 100644 --- a/x/checkpointing/types/query.pb.go +++ b/x/checkpointing/types/query.pb.go @@ -6,7 +6,9 @@ package types import ( context "context" fmt "fmt" + github_com_babylonchain_babylon_crypto_bls12381 "github.com/babylonchain/babylon/crypto/bls12381" query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/genproto/googleapis/api/annotations" @@ -699,7 +701,7 @@ func (m *QueryLastCheckpointWithStatusRequest) GetStatus() CheckpointStatus { // QueryLastCheckpointWithStatusResponse is the response type for the // Query/LastCheckpointWithStatus RPC method. type QueryLastCheckpointWithStatusResponse struct { - RawCheckpoint *RawCheckpoint `protobuf:"bytes,1,opt,name=raw_checkpoint,json=rawCheckpoint,proto3" json:"raw_checkpoint,omitempty"` + RawCheckpoint *RawCheckpointResponse `protobuf:"bytes,1,opt,name=raw_checkpoint,json=rawCheckpoint,proto3" json:"raw_checkpoint,omitempty"` } func (m *QueryLastCheckpointWithStatusResponse) Reset() { *m = QueryLastCheckpointWithStatusResponse{} } @@ -735,13 +737,81 @@ func (m *QueryLastCheckpointWithStatusResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryLastCheckpointWithStatusResponse proto.InternalMessageInfo -func (m *QueryLastCheckpointWithStatusResponse) GetRawCheckpoint() *RawCheckpoint { +func (m *QueryLastCheckpointWithStatusResponse) GetRawCheckpoint() *RawCheckpointResponse { if m != nil { return m.RawCheckpoint } return nil } +// RawCheckpointResponse wraps the BLS multi sig with metadata +type RawCheckpointResponse struct { + // epoch_num defines the epoch number the raw checkpoint is for + EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` + // block_hash_hex defines the 'BlockID.Hash', which is the hash of + // the block that individual BLS sigs are signed on as hex string + BlockHashHex string `protobuf:"bytes,2,opt,name=block_hash_hex,json=blockHashHex,proto3" json:"block_hash_hex,omitempty"` + // bitmap defines the bitmap that indicates the signers of the BLS multi sig + Bitmap []byte `protobuf:"bytes,3,opt,name=bitmap,proto3" json:"bitmap,omitempty"` + // bls_multi_sig defines the multi sig that is aggregated from individual BLS + // sigs + BlsMultiSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,4,opt,name=bls_multi_sig,json=blsMultiSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_multi_sig,omitempty"` +} + +func (m *RawCheckpointResponse) Reset() { *m = RawCheckpointResponse{} } +func (m *RawCheckpointResponse) String() string { return proto.CompactTextString(m) } +func (*RawCheckpointResponse) ProtoMessage() {} +func (*RawCheckpointResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_113f1ca5c3c2ca44, []int{14} +} +func (m *RawCheckpointResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawCheckpointResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawCheckpointResponse.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 *RawCheckpointResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawCheckpointResponse.Merge(m, src) +} +func (m *RawCheckpointResponse) XXX_Size() int { + return m.Size() +} +func (m *RawCheckpointResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RawCheckpointResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RawCheckpointResponse proto.InternalMessageInfo + +func (m *RawCheckpointResponse) GetEpochNum() uint64 { + if m != nil { + return m.EpochNum + } + return 0 +} + +func (m *RawCheckpointResponse) GetBlockHashHex() string { + if m != nil { + return m.BlockHashHex + } + return "" +} + +func (m *RawCheckpointResponse) GetBitmap() []byte { + if m != nil { + return m.Bitmap + } + return nil +} + func init() { proto.RegisterType((*QueryRawCheckpointListRequest)(nil), "babylon.checkpointing.v1.QueryRawCheckpointListRequest") proto.RegisterType((*QueryRawCheckpointListResponse)(nil), "babylon.checkpointing.v1.QueryRawCheckpointListResponse") @@ -758,6 +828,7 @@ func init() { proto.RegisterMapType((map[string]uint64)(nil), "babylon.checkpointing.v1.QueryRecentEpochStatusCountResponse.StatusCountEntry") proto.RegisterType((*QueryLastCheckpointWithStatusRequest)(nil), "babylon.checkpointing.v1.QueryLastCheckpointWithStatusRequest") proto.RegisterType((*QueryLastCheckpointWithStatusResponse)(nil), "babylon.checkpointing.v1.QueryLastCheckpointWithStatusResponse") + proto.RegisterType((*RawCheckpointResponse)(nil), "babylon.checkpointing.v1.RawCheckpointResponse") } func init() { @@ -765,66 +836,73 @@ func init() { } var fileDescriptor_113f1ca5c3c2ca44 = []byte{ - // 938 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x97, 0xd1, 0x6f, 0xdb, 0x44, - 0x1c, 0xc7, 0x7b, 0x29, 0x9b, 0xe8, 0x2f, 0xac, 0x94, 0xd3, 0xc4, 0x82, 0x3b, 0xc2, 0x64, 0xc6, - 0xd6, 0x0d, 0xcd, 0x56, 0xd2, 0xa6, 0x8d, 0xca, 0x56, 0xa4, 0x4c, 0x85, 0x87, 0x8d, 0x32, 0x8c, - 0x34, 0x10, 0x0f, 0x44, 0x67, 0xf7, 0x94, 0x98, 0x3a, 0xb6, 0x9b, 0x3b, 0x27, 0x44, 0xd3, 0x5e, - 0xe0, 0x1f, 0x40, 0x42, 0xe2, 0x9f, 0xe0, 0x05, 0xde, 0x78, 0x44, 0xf0, 0xc2, 0x03, 0x42, 0x93, - 0x78, 0x41, 0xe2, 0x65, 0x6a, 0xf9, 0x43, 0x90, 0xcf, 0xe7, 0x26, 0x76, 0xe2, 0x3a, 0x09, 0x79, - 0xe1, 0xad, 0x3d, 0xdf, 0xf7, 0x7e, 0x9f, 0xef, 0xef, 0x7c, 0xdf, 0x73, 0xe0, 0xba, 0x49, 0xcc, - 0x81, 0xe3, 0xb9, 0xba, 0xd5, 0xa6, 0xd6, 0x91, 0xef, 0xd9, 0x2e, 0xb7, 0xdd, 0x96, 0xde, 0xab, - 0xe8, 0xc7, 0x01, 0xed, 0x0e, 0x34, 0xbf, 0xeb, 0x71, 0x0f, 0x97, 0xe4, 0x2c, 0x2d, 0x31, 0x4b, - 0xeb, 0x55, 0x94, 0x1b, 0x99, 0x7a, 0xd3, 0x61, 0xcd, 0x23, 0x2a, 0x57, 0x50, 0x6e, 0x5b, 0x1e, - 0xeb, 0x78, 0x4c, 0x37, 0x09, 0xa3, 0xd1, 0xd2, 0x7a, 0xaf, 0x62, 0x52, 0x4e, 0x2a, 0xba, 0x4f, - 0x5a, 0xb6, 0x4b, 0xb8, 0xed, 0xb9, 0x72, 0xee, 0xd5, 0x96, 0xe7, 0xb5, 0x1c, 0xaa, 0x13, 0xdf, - 0xd6, 0x89, 0xeb, 0x7a, 0x5c, 0x3c, 0x64, 0xf2, 0xe9, 0xad, 0xcc, 0x8a, 0xc3, 0x81, 0x68, 0xaa, - 0xfa, 0x3d, 0x82, 0xd7, 0x3f, 0x0a, 0x6b, 0x19, 0xa4, 0x7f, 0xff, 0xec, 0xe1, 0x43, 0x9b, 0x71, - 0x83, 0x1e, 0x07, 0x94, 0x71, 0xdc, 0x80, 0x8b, 0x8c, 0x13, 0x1e, 0xb0, 0x12, 0xba, 0x86, 0x36, - 0x56, 0xab, 0xb7, 0xb5, 0x2c, 0xa7, 0xda, 0x70, 0x81, 0x8f, 0x85, 0xc2, 0x90, 0x4a, 0xfc, 0x1e, - 0xc0, 0xd0, 0x42, 0xa9, 0x70, 0x0d, 0x6d, 0x14, 0xab, 0x37, 0xb4, 0xc8, 0xaf, 0x16, 0xfa, 0xd5, - 0xa2, 0x56, 0x4a, 0xbf, 0xda, 0x23, 0xd2, 0xa2, 0xb2, 0xbe, 0x31, 0xa2, 0x54, 0x7f, 0x45, 0x50, - 0xce, 0xa2, 0x65, 0xbe, 0xe7, 0x32, 0x8a, 0x3f, 0x85, 0x97, 0xbb, 0xa4, 0xdf, 0x1c, 0xb2, 0x85, - 0xdc, 0xcb, 0x1b, 0xc5, 0xaa, 0x9e, 0xcd, 0x9d, 0x58, 0xed, 0x13, 0x9b, 0xb7, 0x3f, 0xa0, 0x9c, - 0x18, 0xab, 0xdd, 0xd1, 0x61, 0x86, 0xdf, 0x9f, 0x60, 0xe2, 0x66, 0xae, 0x89, 0x08, 0x2b, 0xe1, - 0xa2, 0x0e, 0xaf, 0x8d, 0x9b, 0x88, 0xdb, 0xbd, 0x0e, 0x2b, 0xd4, 0xf7, 0xac, 0x76, 0xd3, 0x0d, - 0x3a, 0xa2, 0xe3, 0x2f, 0x18, 0x2f, 0x8a, 0x81, 0x83, 0xa0, 0xa3, 0x72, 0x50, 0x26, 0x29, 0xa5, - 0xf5, 0xc7, 0xb0, 0x9a, 0xb4, 0x2e, 0xf4, 0x73, 0x38, 0xbf, 0x94, 0x70, 0xae, 0x1e, 0x4e, 0xaa, - 0xca, 0x62, 0xe0, 0xe4, 0xde, 0xa2, 0xb9, 0xf7, 0xf6, 0x67, 0x04, 0xeb, 0x13, 0xcb, 0xfc, 0x7f, - 0x36, 0xf6, 0x6b, 0x04, 0x57, 0x85, 0x85, 0x86, 0xc3, 0x1e, 0x05, 0xa6, 0x63, 0x5b, 0x0f, 0xe8, - 0x60, 0xf4, 0x2c, 0x9d, 0xb7, 0xb9, 0x0b, 0x3b, 0x24, 0x7f, 0xc4, 0x47, 0x7a, 0x9c, 0x42, 0xb6, - 0xf2, 0x10, 0xae, 0xf4, 0x88, 0x63, 0x1f, 0x12, 0xee, 0x75, 0x9b, 0x7d, 0x9b, 0xb7, 0x9b, 0x32, - 0x89, 0xe2, 0x96, 0xde, 0xc9, 0x6e, 0xe9, 0xe3, 0x58, 0x18, 0xb6, 0xb3, 0xe1, 0xb0, 0x07, 0x74, - 0x60, 0x5c, 0xee, 0x8d, 0x0f, 0x2e, 0xb0, 0xad, 0xdb, 0x70, 0x45, 0xf8, 0xd9, 0x0f, 0x3b, 0x25, - 0x93, 0x65, 0x9a, 0xd3, 0xf2, 0x39, 0x94, 0xc6, 0x75, 0xb2, 0x05, 0x0b, 0x48, 0x35, 0x75, 0x1f, - 0xd4, 0xe8, 0x85, 0xa5, 0x16, 0x75, 0xf9, 0x48, 0x95, 0xfb, 0x5e, 0x30, 0x3c, 0xd0, 0x6f, 0x40, - 0x31, 0x42, 0xb4, 0xc2, 0x51, 0x09, 0x09, 0x62, 0x48, 0xcc, 0x53, 0xbf, 0x2b, 0xc0, 0x9b, 0xe7, - 0xae, 0x23, 0x91, 0xd7, 0x61, 0x85, 0xdb, 0x7e, 0x53, 0x28, 0x63, 0xaf, 0xdc, 0xf6, 0xc5, 0xfc, - 0x74, 0x95, 0x42, 0xba, 0x0a, 0x3e, 0x86, 0x97, 0x22, 0x6c, 0x39, 0x63, 0x59, 0x6c, 0xf4, 0x41, - 0xb6, 0xed, 0x29, 0x90, 0xb4, 0x91, 0xb1, 0x7d, 0x97, 0x77, 0x07, 0x46, 0x91, 0x0d, 0x47, 0x94, - 0x3d, 0x58, 0x4b, 0x4f, 0xc0, 0x6b, 0xb0, 0x7c, 0x44, 0x07, 0x02, 0x7f, 0xc5, 0x08, 0xff, 0xc4, - 0x97, 0xe1, 0x42, 0x8f, 0x38, 0x01, 0x95, 0xcc, 0xd1, 0x3f, 0xbb, 0x85, 0x3a, 0x52, 0xbf, 0x80, - 0xeb, 0x02, 0xe2, 0x21, 0x61, 0x3c, 0x79, 0x8c, 0x93, 0x2f, 0xc1, 0x22, 0xf6, 0xb2, 0x0f, 0x6f, - 0xe5, 0xd4, 0x92, 0xbb, 0x70, 0x90, 0x11, 0xb2, 0x37, 0xa7, 0x4c, 0xa1, 0x54, 0xb8, 0x56, 0x9f, - 0x03, 0x5c, 0x10, 0x95, 0xf1, 0x2f, 0x08, 0x5e, 0x19, 0xbb, 0xd7, 0xf0, 0x4e, 0xde, 0x0e, 0x65, - 0xdc, 0xdb, 0x4a, 0x7d, 0x76, 0x61, 0x64, 0x51, 0xdd, 0xfd, 0xea, 0xcf, 0x7f, 0xbe, 0x2d, 0x6c, - 0xe1, 0xaa, 0x9e, 0xf9, 0x1d, 0x91, 0x4a, 0x62, 0xfd, 0x49, 0xd4, 0xc6, 0xa7, 0xf8, 0x27, 0x04, - 0x97, 0x12, 0x2b, 0xe3, 0xcd, 0x59, 0x38, 0x62, 0xf8, 0xad, 0xd9, 0x44, 0x12, 0xfc, 0xae, 0x00, - 0xdf, 0xc6, 0x5b, 0xd3, 0x82, 0xeb, 0x4f, 0xce, 0xd2, 0xe3, 0x29, 0xfe, 0x01, 0xc1, 0x6a, 0xf2, - 0xee, 0xc1, 0x33, 0x61, 0xc4, 0xef, 0xa3, 0x52, 0x9b, 0x51, 0x25, 0xe9, 0x2b, 0x82, 0xfe, 0x6d, - 0x7c, 0x6b, 0xea, 0xb6, 0x87, 0xaf, 0xcc, 0x5a, 0x3a, 0xe5, 0xf1, 0x76, 0x4e, 0xf9, 0x8c, 0xcb, - 0x49, 0xd9, 0x99, 0x59, 0x27, 0xc1, 0xef, 0x09, 0xf0, 0x1d, 0x5c, 0xd3, 0xcf, 0xfd, 0xd2, 0xf5, - 0x85, 0x58, 0x5c, 0x33, 0x89, 0xbe, 0xff, 0x88, 0xa0, 0x38, 0x92, 0x30, 0xb8, 0x92, 0xc3, 0x31, - 0x7e, 0x0d, 0x28, 0xd5, 0x59, 0x24, 0x92, 0xfa, 0x1d, 0x41, 0x5d, 0xc3, 0x9b, 0xd9, 0xd4, 0x02, - 0x32, 0x01, 0xab, 0xcb, 0x0f, 0xda, 0xdf, 0x11, 0xbc, 0x3a, 0x39, 0x1b, 0xf1, 0xdd, 0x39, 0x23, - 0x35, 0x72, 0x72, 0xef, 0x3f, 0x05, 0xb2, 0x5a, 0x13, 0xa6, 0x74, 0x7c, 0x27, 0xcf, 0xd4, 0xee, - 0xe8, 0x65, 0x80, 0xff, 0x46, 0x50, 0xca, 0x4a, 0x3e, 0xbc, 0x97, 0x83, 0x94, 0x13, 0xcf, 0xca, - 0xbb, 0x73, 0xeb, 0xa5, 0xa9, 0x3d, 0x61, 0xaa, 0x8e, 0xb7, 0xb3, 0x4d, 0x39, 0x84, 0xf1, 0x66, - 0xfa, 0x6c, 0xcb, 0x4c, 0x6a, 0x7c, 0xf8, 0xdb, 0x49, 0x19, 0x3d, 0x3b, 0x29, 0xa3, 0xe7, 0x27, - 0x65, 0xf4, 0xcd, 0x69, 0x79, 0xe9, 0xd9, 0x69, 0x79, 0xe9, 0xaf, 0xd3, 0xf2, 0xd2, 0x67, 0xb5, - 0x96, 0xcd, 0xdb, 0x81, 0xa9, 0x59, 0x5e, 0x27, 0x5e, 0xdb, 0x6a, 0x13, 0xdb, 0x3d, 0x2b, 0xf4, - 0x65, 0xaa, 0x14, 0x1f, 0xf8, 0x94, 0x99, 0x17, 0xc5, 0x6f, 0xa7, 0xcd, 0x7f, 0x03, 0x00, 0x00, - 0xff, 0xff, 0x27, 0x4c, 0x94, 0xaf, 0x1a, 0x0e, 0x00, 0x00, + // 1055 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x97, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xc7, 0x3b, 0x49, 0x1b, 0x91, 0xe7, 0x24, 0x84, 0x51, 0x68, 0xcd, 0xa6, 0xb8, 0xd1, 0x12, + 0x4a, 0x5a, 0xd4, 0x5d, 0xd9, 0xf9, 0x49, 0x68, 0x82, 0x94, 0x2a, 0x50, 0xa9, 0x3f, 0x28, 0x1b, + 0xa9, 0x20, 0x0e, 0xac, 0x66, 0x37, 0xa3, 0xdd, 0x25, 0xeb, 0xdd, 0x8d, 0x67, 0xd6, 0x89, 0x55, + 0x55, 0x48, 0xf0, 0x0f, 0x20, 0x21, 0xf1, 0x4f, 0x70, 0x81, 0x1b, 0x47, 0x04, 0x17, 0x0e, 0x08, + 0x55, 0x42, 0x48, 0x08, 0x24, 0x54, 0x25, 0xfc, 0x21, 0x68, 0x67, 0xc7, 0xb1, 0xd7, 0xf6, 0xc6, + 0x71, 0xf0, 0x85, 0x9b, 0x3d, 0x7e, 0x6f, 0xde, 0xe7, 0xfb, 0x66, 0xde, 0x7b, 0x63, 0x98, 0xb7, + 0x88, 0xd5, 0xf0, 0xc3, 0x40, 0xb7, 0x5d, 0x6a, 0xef, 0x45, 0xa1, 0x17, 0x70, 0x2f, 0x70, 0xf4, + 0x7a, 0x59, 0xdf, 0x8f, 0x69, 0xad, 0xa1, 0x45, 0xb5, 0x90, 0x87, 0xb8, 0x28, 0xad, 0xb4, 0x8c, + 0x95, 0x56, 0x2f, 0x2b, 0x33, 0x4e, 0xe8, 0x84, 0xc2, 0x48, 0x4f, 0x3e, 0xa5, 0xf6, 0xca, 0x55, + 0x27, 0x0c, 0x1d, 0x9f, 0xea, 0x24, 0xf2, 0x74, 0x12, 0x04, 0x21, 0x27, 0xdc, 0x0b, 0x03, 0x26, + 0x7f, 0xbd, 0x9e, 0x1b, 0xd3, 0xf2, 0x99, 0xb9, 0x47, 0x65, 0x54, 0xe5, 0x46, 0xae, 0x5d, 0x6b, + 0x41, 0x9a, 0xde, 0xb4, 0x43, 0x56, 0x0d, 0x99, 0x6e, 0x11, 0x46, 0x53, 0x72, 0xbd, 0x5e, 0xb6, + 0x28, 0x27, 0x65, 0x3d, 0x22, 0x8e, 0x17, 0x88, 0xf8, 0xa9, 0xad, 0xfa, 0x0d, 0x82, 0x57, 0x3f, + 0x48, 0x4c, 0x0c, 0x72, 0x70, 0xe7, 0x64, 0xa3, 0xfb, 0x1e, 0xe3, 0x06, 0xdd, 0x8f, 0x29, 0xe3, + 0x78, 0x0b, 0xc6, 0x18, 0x27, 0x3c, 0x66, 0x45, 0x34, 0x87, 0x16, 0xa6, 0x2a, 0x37, 0xb5, 0x3c, + 0xfd, 0x5a, 0x6b, 0x83, 0x1d, 0xe1, 0x61, 0x48, 0x4f, 0xfc, 0x2e, 0x40, 0x2b, 0x72, 0x71, 0x64, + 0x0e, 0x2d, 0x14, 0x2a, 0xd7, 0xb5, 0x14, 0x53, 0x4b, 0x30, 0xb5, 0x34, 0xc1, 0x12, 0x53, 0x7b, + 0x44, 0x1c, 0x2a, 0xe3, 0x1b, 0x6d, 0x9e, 0xea, 0x4f, 0x08, 0x4a, 0x79, 0xb4, 0x2c, 0x0a, 0x03, + 0x46, 0xf1, 0x47, 0xf0, 0x62, 0x8d, 0x1c, 0x98, 0x2d, 0xb6, 0x84, 0x7b, 0x74, 0xa1, 0x50, 0xd1, + 0xf3, 0xb9, 0x33, 0xbb, 0x7d, 0xe8, 0x71, 0xf7, 0x01, 0xe5, 0xc4, 0x98, 0xaa, 0xb5, 0x2f, 0x33, + 0xfc, 0x5e, 0x0f, 0x11, 0x6f, 0xf4, 0x15, 0x91, 0x62, 0x65, 0x54, 0xac, 0xc1, 0x2b, 0xdd, 0x22, + 0x9a, 0xe9, 0x9e, 0x85, 0x71, 0x1a, 0x85, 0xb6, 0x6b, 0x06, 0x71, 0x55, 0x64, 0xfc, 0xa2, 0xf1, + 0x82, 0x58, 0x78, 0x18, 0x57, 0x55, 0x0e, 0x4a, 0x2f, 0x4f, 0x29, 0xfd, 0x31, 0x4c, 0x65, 0xa5, + 0x0b, 0xff, 0x73, 0x28, 0x9f, 0xcc, 0x28, 0x57, 0x77, 0x7b, 0x45, 0x65, 0x4d, 0xe0, 0xec, 0xd9, + 0xa2, 0x73, 0x9f, 0xed, 0x0f, 0x08, 0x66, 0x7b, 0x86, 0xf9, 0xff, 0x1c, 0xec, 0x17, 0x08, 0xae, + 0x0a, 0x09, 0x5b, 0x3e, 0x7b, 0x14, 0x5b, 0xbe, 0x67, 0xdf, 0xa3, 0x8d, 0xf6, 0x5a, 0x3a, 0xed, + 0x70, 0x87, 0x56, 0x24, 0xbf, 0x36, 0x4b, 0xba, 0x9b, 0x42, 0xa6, 0x72, 0x17, 0xae, 0xd4, 0x89, + 0xef, 0xed, 0x12, 0x1e, 0xd6, 0xcc, 0x03, 0x8f, 0xbb, 0xa6, 0xec, 0x35, 0xcd, 0x94, 0xde, 0xca, + 0x4f, 0xe9, 0xe3, 0xa6, 0x63, 0x92, 0xce, 0x2d, 0x9f, 0xdd, 0xa3, 0x0d, 0x63, 0xa6, 0xde, 0xbd, + 0x38, 0xc4, 0xb4, 0xae, 0xc0, 0x15, 0xa1, 0x67, 0x3b, 0xc9, 0x94, 0xec, 0x2c, 0x67, 0xa9, 0x96, + 0x4f, 0xa0, 0xd8, 0xed, 0x27, 0x53, 0x30, 0x84, 0xae, 0xa6, 0x6e, 0x83, 0x9a, 0x5e, 0x58, 0x6a, + 0xd3, 0x80, 0xb7, 0x45, 0xb9, 0x13, 0xc6, 0xad, 0x82, 0xbe, 0x06, 0x85, 0x14, 0xd1, 0x4e, 0x56, + 0x25, 0x24, 0x88, 0x25, 0x61, 0xa7, 0x7e, 0x3d, 0x02, 0xaf, 0x9d, 0xba, 0x8f, 0x44, 0x9e, 0x85, + 0x71, 0xee, 0x45, 0xa6, 0xf0, 0x6c, 0x6a, 0xe5, 0x5e, 0x24, 0xec, 0x3b, 0xa3, 0x8c, 0x74, 0x46, + 0xc1, 0xfb, 0x30, 0x91, 0x62, 0x4b, 0x8b, 0x51, 0x71, 0xd0, 0x0f, 0xf3, 0x65, 0x9f, 0x01, 0x49, + 0x6b, 0x5b, 0xdb, 0x0e, 0x78, 0xad, 0x61, 0x14, 0x58, 0x6b, 0x45, 0xd9, 0x84, 0xe9, 0x4e, 0x03, + 0x3c, 0x0d, 0xa3, 0x7b, 0xb4, 0x21, 0xf0, 0xc7, 0x8d, 0xe4, 0x23, 0x9e, 0x81, 0x4b, 0x75, 0xe2, + 0xc7, 0x54, 0x32, 0xa7, 0x5f, 0xd6, 0x47, 0xd6, 0x90, 0xfa, 0x29, 0xcc, 0x0b, 0x88, 0xfb, 0x84, + 0xf1, 0x6c, 0x19, 0x67, 0x2f, 0xc1, 0x30, 0xce, 0xf2, 0x33, 0x78, 0xbd, 0x4f, 0xac, 0x21, 0x35, + 0xd9, 0x93, 0x1b, 0xde, 0xd1, 0x64, 0x7f, 0x47, 0xf0, 0x72, 0xef, 0xb6, 0x7e, 0x6a, 0xd3, 0x98, + 0x87, 0x29, 0xcb, 0x0f, 0xed, 0x3d, 0xd3, 0x25, 0xcc, 0x35, 0x5d, 0x7a, 0x28, 0xd2, 0x38, 0x6e, + 0x4c, 0x88, 0xd5, 0xbb, 0x84, 0xb9, 0x77, 0xe9, 0x21, 0xbe, 0x0c, 0x63, 0x96, 0xc7, 0xab, 0x24, + 0x2a, 0x8e, 0xce, 0xa1, 0x85, 0x09, 0x43, 0x7e, 0xc3, 0x04, 0x26, 0x93, 0xca, 0xaf, 0xc6, 0x3e, + 0xf7, 0x4c, 0xe6, 0x39, 0xc5, 0x8b, 0xc9, 0xcf, 0x5b, 0x1b, 0x7f, 0xfe, 0x7d, 0xed, 0x2d, 0xc7, + 0xe3, 0x6e, 0x6c, 0x69, 0x76, 0x58, 0xd5, 0xa5, 0x32, 0xdb, 0x25, 0x5e, 0xa0, 0x9f, 0xbc, 0x43, + 0x6a, 0x8d, 0x88, 0x87, 0xc9, 0x2b, 0xa5, 0x5c, 0x59, 0x5c, 0x2b, 0x6b, 0x3b, 0x9e, 0x13, 0x10, + 0x1e, 0xd7, 0xa8, 0x51, 0xb0, 0x7c, 0xf6, 0x20, 0xd9, 0x72, 0xc7, 0x73, 0x2a, 0xcf, 0x01, 0x2e, + 0x89, 0xcc, 0xe2, 0x1f, 0x11, 0xbc, 0xd4, 0x35, 0xb7, 0xf1, 0x6a, 0xbf, 0x1b, 0x98, 0xf3, 0x2e, + 0x51, 0xd6, 0x06, 0x77, 0x4c, 0x13, 0xaa, 0xae, 0x7f, 0xfe, 0xdb, 0x3f, 0x5f, 0x8d, 0x2c, 0xe1, + 0x8a, 0x9e, 0xfb, 0xa6, 0xea, 0x98, 0x34, 0xfa, 0x93, 0xf4, 0x9a, 0x3c, 0xc5, 0xdf, 0x23, 0x98, + 0xcc, 0xec, 0x8c, 0x17, 0x07, 0xe1, 0x68, 0xc2, 0x2f, 0x0d, 0xe6, 0x24, 0xc1, 0x6f, 0x0b, 0xf0, + 0x15, 0xbc, 0x74, 0x56, 0x70, 0xfd, 0xc9, 0xc9, 0xcd, 0x79, 0x8a, 0xbf, 0x45, 0x30, 0x95, 0x9d, + 0xad, 0x78, 0x20, 0x8c, 0x66, 0xbd, 0x29, 0xcb, 0x03, 0x7a, 0x49, 0xfa, 0xb2, 0xa0, 0x7f, 0x13, + 0xdf, 0x38, 0x73, 0xda, 0x93, 0x2b, 0x33, 0xdd, 0x39, 0xc5, 0xf0, 0x4a, 0x9f, 0xf0, 0x39, 0xc3, + 0x57, 0x59, 0x1d, 0xd8, 0x4f, 0x82, 0x6f, 0x08, 0xf0, 0x55, 0xbc, 0xac, 0x9f, 0xfa, 0x56, 0x8f, + 0x84, 0xb3, 0x18, 0xa3, 0x99, 0xbc, 0x7f, 0x87, 0xa0, 0xd0, 0xd6, 0x41, 0x71, 0xb9, 0x0f, 0x47, + 0xf7, 0x98, 0x53, 0x2a, 0x83, 0xb8, 0x48, 0xea, 0xb7, 0x05, 0xf5, 0x32, 0x5e, 0xcc, 0xa7, 0x16, + 0x90, 0x19, 0x58, 0x5d, 0x3e, 0xd8, 0x7f, 0x41, 0x70, 0xb9, 0x77, 0xef, 0xc7, 0xb7, 0xcf, 0x39, + 0x32, 0x52, 0x25, 0x1b, 0xff, 0x69, 0xe0, 0xa8, 0xcb, 0x42, 0x94, 0x8e, 0x6f, 0xf5, 0x13, 0xb5, + 0xde, 0x3e, 0xec, 0xf0, 0x5f, 0x08, 0x8a, 0x79, 0x9d, 0x1d, 0x6f, 0xf6, 0x41, 0xea, 0x33, 0x7e, + 0x94, 0x77, 0xce, 0xed, 0x2f, 0x45, 0x6d, 0x0a, 0x51, 0x6b, 0x78, 0x25, 0x5f, 0x94, 0x4f, 0x18, + 0x37, 0x3b, 0x6b, 0x5b, 0xf6, 0xa4, 0xad, 0xf7, 0x7f, 0x3e, 0x2a, 0xa1, 0x67, 0x47, 0x25, 0xf4, + 0xfc, 0xa8, 0x84, 0xbe, 0x3c, 0x2e, 0x5d, 0x78, 0x76, 0x5c, 0xba, 0xf0, 0xc7, 0x71, 0xe9, 0xc2, + 0xc7, 0xcb, 0xfd, 0x9a, 0xf8, 0x61, 0x47, 0x28, 0xde, 0x88, 0x28, 0xb3, 0xc6, 0xc4, 0x7f, 0xc3, + 0xc5, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xee, 0xdc, 0xe0, 0x14, 0x10, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1665,6 +1743,60 @@ func (m *QueryLastCheckpointWithStatusResponse) MarshalToSizedBuffer(dAtA []byte return len(dAtA) - i, nil } +func (m *RawCheckpointResponse) 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 *RawCheckpointResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawCheckpointResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BlsMultiSig != nil { + { + size := m.BlsMultiSig.Size() + i -= size + if _, err := m.BlsMultiSig.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.Bitmap) > 0 { + i -= len(m.Bitmap) + copy(dAtA[i:], m.Bitmap) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Bitmap))) + i-- + dAtA[i] = 0x1a + } + if len(m.BlockHashHex) > 0 { + i -= len(m.BlockHashHex) + copy(dAtA[i:], m.BlockHashHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.BlockHashHex))) + i-- + dAtA[i] = 0x12 + } + if m.EpochNum != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EpochNum)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -1887,6 +2019,30 @@ func (m *QueryLastCheckpointWithStatusResponse) Size() (n int) { return n } +func (m *RawCheckpointResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNum != 0 { + n += 1 + sovQuery(uint64(m.EpochNum)) + } + l = len(m.BlockHashHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Bitmap) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.BlsMultiSig != nil { + l = m.BlsMultiSig.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3240,7 +3396,7 @@ func (m *QueryLastCheckpointWithStatusResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.RawCheckpoint == nil { - m.RawCheckpoint = &RawCheckpoint{} + m.RawCheckpoint = &RawCheckpointResponse{} } if err := m.RawCheckpoint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3267,6 +3423,176 @@ func (m *QueryLastCheckpointWithStatusResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *RawCheckpointResponse) 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 ErrIntOverflowQuery + } + 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: RawCheckpointResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawCheckpointResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNum", wireType) + } + m.EpochNum = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNum |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHashHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHashHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Bitmap", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Bitmap = append(m.Bitmap[:0], dAtA[iNdEx:postIndex]...) + if m.Bitmap == nil { + m.Bitmap = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsMultiSig", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_crypto_bls12381.Signature + m.BlsMultiSig = &v + if err := m.BlsMultiSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 6dd8184d8f3bfe9683cc899474ec163c83bba51e Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Tue, 5 Mar 2024 21:49:47 -0300 Subject: [PATCH 035/119] chore: raw checkpoint with meta response (#528) * chore: update query LastCheckpointWithStatus to use response structure * chore: update query RawCheckpointList to use RawCheckpointWithMetaResponse * chore: raw checkpoint with meta queries (#529) * chore: update query RawCheckpoint to use RawCheckpointResponse * chore: update query `RawCheckpoints` to use `RawCheckpointWithMetaResponse` --- client/docs/swagger-ui/swagger.yaml | 253 +++-- proto/babylon/checkpointing/v1/query.proto | 43 +- test/e2e/configurer/chain/commands.go | 5 +- test/e2e/configurer/chain/queries.go | 2 +- .../keeper/grpc_query_checkpoint.go | 23 +- .../keeper/grpc_query_checkpoint_test.go | 4 +- x/checkpointing/types/query.go | 49 + x/checkpointing/types/query.pb.go | 897 ++++++++++++++++-- 8 files changed, 1088 insertions(+), 188 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index d6224245f..a2eddc8ec 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4899,14 +4899,14 @@ paths: title: >- epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: >- - block_hash defines the 'BlockID.Hash', which is the - hash of + block_hash_hex defines the 'BlockID.Hash', which is + the hash of - the block that individual BLS sigs are signed on + the block that individual BLS sigs are signed on as + hex string bitmap: type: string format: byte @@ -4921,7 +4921,9 @@ paths: from individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: >- + RawCheckpointResponse wraps the BLS multi sig with + metadata status: type: string enum: @@ -4940,6 +4942,9 @@ paths: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -4975,6 +4980,11 @@ paths: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: >- + status_desc respresents the description of status + enum. block_height: type: string format: uint64 @@ -4992,8 +5002,8 @@ paths: update description: >- - CheckpointStateUpdate defines a state transition on the - checkpoint. + CheckpointStateUpdateResponse defines a state transition + on the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -5002,7 +5012,9 @@ paths: height) of this transition. - description: RawCheckpointWithMeta wraps the raw checkpoint with metadata. + description: >- + RawCheckpointWithMetaResponse wraps the raw checkpoint with + metadata. description: >- QueryRawCheckpointResponse is the response type for the Query/RawCheckpoint @@ -5065,14 +5077,14 @@ paths: title: >- epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: >- - block_hash defines the 'BlockID.Hash', which is the - hash of + block_hash_hex defines the 'BlockID.Hash', which is + the hash of - the block that individual BLS sigs are signed on + the block that individual BLS sigs are signed on as + hex string bitmap: type: string format: byte @@ -5087,7 +5099,9 @@ paths: aggregated from individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: >- + RawCheckpointResponse wraps the BLS multi sig with + metadata status: type: string enum: @@ -5106,6 +5120,9 @@ paths: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -5141,6 +5158,11 @@ paths: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: >- + status_desc respresents the description of status + enum. block_height: type: string format: uint64 @@ -5158,8 +5180,8 @@ paths: update description: >- - CheckpointStateUpdate defines a state transition on - the checkpoint. + CheckpointStateUpdateResponse defines a state + transition on the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -5169,7 +5191,7 @@ paths: transition. description: >- - RawCheckpointWithMeta wraps the raw checkpoint with + RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. title: >- the order is going from the newest to oldest based on the @@ -5303,14 +5325,14 @@ paths: title: >- epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: >- - block_hash defines the 'BlockID.Hash', which is the - hash of + block_hash_hex defines the 'BlockID.Hash', which is + the hash of - the block that individual BLS sigs are signed on + the block that individual BLS sigs are signed on as + hex string bitmap: type: string format: byte @@ -5325,7 +5347,9 @@ paths: aggregated from individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: >- + RawCheckpointResponse wraps the BLS multi sig with + metadata status: type: string enum: @@ -5344,6 +5368,9 @@ paths: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -5379,6 +5406,11 @@ paths: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: >- + status_desc respresents the description of status + enum. block_height: type: string format: uint64 @@ -5396,8 +5428,8 @@ paths: update description: >- - CheckpointStateUpdate defines a state transition on - the checkpoint. + CheckpointStateUpdateResponse defines a state + transition on the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -5407,7 +5439,7 @@ paths: transition. description: >- - RawCheckpointWithMeta wraps the raw checkpoint with + RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. title: >- the order is going from the newest to oldest based on the @@ -13225,7 +13257,7 @@ definitions: description: |- MsgUndelegate defines a SDK message for performing an undelegation from a delegate and a validator. - babylon.checkpointing.v1.CheckpointStateUpdate: + babylon.checkpointing.v1.CheckpointStateUpdateResponse: type: object properties: state: @@ -13246,6 +13278,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: state defines the event of a state transition towards this state + status_desc: + type: string + description: status_desc respresents the description of status enum. block_height: type: string format: uint64 @@ -13262,7 +13297,9 @@ definitions: state update - description: CheckpointStateUpdate defines a state transition on the checkpoint. + description: >- + CheckpointStateUpdateResponse defines a state transition on the + checkpoint. babylon.checkpointing.v1.CheckpointStatus: type: string enum: @@ -13399,12 +13436,14 @@ definitions: type: string format: uint64 title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte - title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on + title: >- + block_hash_hex defines the 'BlockID.Hash', which is the hash + of + + the block that individual BLS sigs are signed on as hex + string bitmap: type: string format: byte @@ -13419,7 +13458,7 @@ definitions: individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata status: type: string enum: @@ -13438,6 +13477,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -13473,6 +13515,9 @@ definitions: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: status_desc respresents the description of status enum. block_height: type: string format: uint64 @@ -13490,8 +13535,8 @@ definitions: update description: >- - CheckpointStateUpdate defines a state transition on the - checkpoint. + CheckpointStateUpdateResponse defines a state transition on + the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -13500,7 +13545,9 @@ definitions: this transition. - description: RawCheckpointWithMeta wraps the raw checkpoint with metadata. + description: >- + RawCheckpointWithMetaResponse wraps the raw checkpoint with + metadata. title: the order is going from the newest to oldest based on the epoch number pagination: description: pagination defines the pagination in the response. @@ -13537,12 +13584,13 @@ definitions: type: string format: uint64 title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte - title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on + title: >- + block_hash_hex defines the 'BlockID.Hash', which is the hash + of + + the block that individual BLS sigs are signed on as hex string bitmap: type: string format: byte @@ -13557,7 +13605,7 @@ definitions: individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata status: type: string enum: @@ -13576,6 +13624,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -13609,6 +13660,9 @@ definitions: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: status_desc respresents the description of status enum. block_height: type: string format: uint64 @@ -13626,7 +13680,7 @@ definitions: update description: >- - CheckpointStateUpdate defines a state transition on the + CheckpointStateUpdateResponse defines a state transition on the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each @@ -13636,7 +13690,7 @@ definitions: this transition. - description: RawCheckpointWithMeta wraps the raw checkpoint with metadata. + description: RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. description: >- QueryRawCheckpointResponse is the response type for the Query/RawCheckpoint @@ -13657,12 +13711,14 @@ definitions: type: string format: uint64 title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte - title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on + title: >- + block_hash_hex defines the 'BlockID.Hash', which is the hash + of + + the block that individual BLS sigs are signed on as hex + string bitmap: type: string format: byte @@ -13677,7 +13733,7 @@ definitions: individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata status: type: string enum: @@ -13696,6 +13752,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -13731,6 +13790,9 @@ definitions: title: >- state defines the event of a state transition towards this state + status_desc: + type: string + description: status_desc respresents the description of status enum. block_height: type: string format: uint64 @@ -13748,8 +13810,8 @@ definitions: update description: >- - CheckpointStateUpdate defines a state transition on the - checkpoint. + CheckpointStateUpdateResponse defines a state transition on + the checkpoint. description: >- lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -13758,7 +13820,9 @@ definitions: this transition. - description: RawCheckpointWithMeta wraps the raw checkpoint with metadata. + description: >- + RawCheckpointWithMetaResponse wraps the raw checkpoint with + metadata. title: the order is going from the newest to oldest based on the epoch number pagination: description: pagination defines the pagination in the response. @@ -13801,34 +13865,6 @@ definitions: description: |- QueryRecentEpochStatusCountResponse is the response type for the Query/EpochStatusCount RPC method. - babylon.checkpointing.v1.RawCheckpoint: - type: object - properties: - epoch_num: - type: string - format: uint64 - title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: - type: string - format: byte - title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on - bitmap: - type: string - format: byte - title: >- - bitmap defines the bitmap that indicates the signers of the BLS multi - sig - bls_multi_sig: - type: string - format: byte - title: >- - bls_multi_sig defines the multi sig that is aggregated from individual - BLS - - sigs - title: RawCheckpoint wraps the BLS multi sig with metadata babylon.checkpointing.v1.RawCheckpointResponse: type: object properties: @@ -13856,7 +13892,7 @@ definitions: sigs title: RawCheckpointResponse wraps the BLS multi sig with metadata - babylon.checkpointing.v1.RawCheckpointWithMeta: + babylon.checkpointing.v1.RawCheckpointWithMetaResponse: type: object properties: ckpt: @@ -13866,12 +13902,11 @@ definitions: type: string format: uint64 title: epoch_num defines the epoch number the raw checkpoint is for - block_hash: + block_hash_hex: type: string - format: byte title: |- - block_hash defines the 'BlockID.Hash', which is the hash of - the block that individual BLS sigs are signed on + block_hash_hex defines the 'BlockID.Hash', which is the hash of + the block that individual BLS sigs are signed on as hex string bitmap: type: string format: byte @@ -13886,7 +13921,7 @@ definitions: individual BLS sigs - title: RawCheckpoint wraps the BLS multi sig with metadata + title: RawCheckpointResponse wraps the BLS multi sig with metadata status: type: string enum: @@ -13905,6 +13940,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: status defines the status of the checkpoint + status_desc: + type: string + description: status_desc respresents the description of status enum. bls_aggr_pk: type: string format: byte @@ -13936,6 +13974,9 @@ definitions: - CKPT_STATUS_CONFIRMED: CONFIRMED defines a checkpoint that is k-deep on BTC. - CKPT_STATUS_FINALIZED: FINALIZED defines a checkpoint that is w-deep on BTC. title: state defines the event of a state transition towards this state + status_desc: + type: string + description: status_desc respresents the description of status enum. block_height: type: string format: uint64 @@ -13952,12 +13993,14 @@ definitions: the state update - description: CheckpointStateUpdate defines a state transition on the checkpoint. + description: >- + CheckpointStateUpdateResponse defines a state transition on the + checkpoint. description: |- lifecycle defines the lifecycle of this checkpoint, i.e., each state transition and the time (in both timestamp and block height) of this transition. - description: RawCheckpointWithMeta wraps the raw checkpoint with metadata. + description: RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. babylon.checkpointing.v1.ValidatorWithBlsKey: type: object properties: @@ -14069,6 +14112,34 @@ definitions: title: |- Each provided OP_RETURN transaction can be identified by hash of block in which transaction was included and transaction index in the block + babylon.checkpointing.v1.RawCheckpoint: + type: object + properties: + epoch_num: + type: string + format: uint64 + title: epoch_num defines the epoch number the raw checkpoint is for + block_hash: + type: string + format: byte + title: |- + block_hash defines the 'BlockID.Hash', which is the hash of + the block that individual BLS sigs are signed on + bitmap: + type: string + format: byte + title: >- + bitmap defines the bitmap that indicates the signers of the BLS multi + sig + bls_multi_sig: + type: string + format: byte + title: >- + bls_multi_sig defines the multi sig that is aggregated from individual + BLS + + sigs + title: RawCheckpoint wraps the BLS multi sig with metadata babylon.zoneconcierge.v1.ChainInfo: type: object properties: diff --git a/proto/babylon/checkpointing/v1/query.proto b/proto/babylon/checkpointing/v1/query.proto index e73c7bc23..a7ee01e16 100644 --- a/proto/babylon/checkpointing/v1/query.proto +++ b/proto/babylon/checkpointing/v1/query.proto @@ -3,6 +3,7 @@ package babylon.checkpointing.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; +import "google/protobuf/timestamp.proto"; import "babylon/checkpointing/v1/bls_key.proto"; import "babylon/checkpointing/v1/checkpoint.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; @@ -77,7 +78,7 @@ message QueryRawCheckpointListRequest { // Query/RawCheckpoints RPC method. message QueryRawCheckpointListResponse { // the order is going from the newest to oldest based on the epoch number - repeated RawCheckpointWithMeta raw_checkpoints = 1; + repeated RawCheckpointWithMetaResponse raw_checkpoints = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -92,8 +93,7 @@ message QueryRawCheckpointRequest { // QueryRawCheckpointResponse is the response type for the Query/RawCheckpoint // RPC method. -message QueryRawCheckpointResponse { RawCheckpointWithMeta raw_checkpoint = 1; } - +message QueryRawCheckpointResponse { RawCheckpointWithMetaResponse raw_checkpoint = 1; } // QueryRawCheckpointsRequest is the request type for the Query/RawCheckpoints // RPC method. @@ -106,7 +106,7 @@ message QueryRawCheckpointsRequest { // RPC method. message QueryRawCheckpointsResponse { // the order is going from the newest to oldest based on the epoch number - repeated RawCheckpointWithMeta raw_checkpoints = 1; + repeated RawCheckpointWithMetaResponse raw_checkpoints = 1; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -179,4 +179,37 @@ message RawCheckpointResponse { bytes bls_multi_sig = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; -} \ No newline at end of file +} + +// CheckpointStateUpdateResponse defines a state transition on the checkpoint. +message CheckpointStateUpdateResponse { + // state defines the event of a state transition towards this state + CheckpointStatus state = 1; + // status_desc respresents the description of status enum. + string status_desc = 2; + // block_height is the height of the Babylon block that triggers the state + // update + uint64 block_height = 3; + // block_time is the timestamp in the Babylon block that triggers the state + // update + google.protobuf.Timestamp block_time = 4 [ (gogoproto.stdtime) = true ]; +} + +// RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. +message RawCheckpointWithMetaResponse { + RawCheckpointResponse ckpt = 1; + // status defines the status of the checkpoint + CheckpointStatus status = 2; + // status_desc respresents the description of status enum. + string status_desc = 3; + // bls_aggr_pk defines the aggregated BLS public key + bytes bls_aggr_pk = 4 + [ (gogoproto.customtype) = + "github.com/babylonchain/babylon/crypto/bls12381.PublicKey" ]; + // power_sum defines the accumulated voting power for the checkpoint + uint64 power_sum = 5; + // lifecycle defines the lifecycle of this checkpoint, i.e., each state + // transition and the time (in both timestamp and block height) of this + // transition. + repeated CheckpointStateUpdateResponse lifecycle = 6; +} diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 90dae8a8d..cc316188f 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -150,7 +150,10 @@ func (n *NodeConfig) FinalizeSealedEpochs(startEpoch uint64, lastEpoch uint64) { _, submitterAddr, err := bech32.DecodeAndConvert(n.PublicAddress) require.NoError(n.t, err) - btcCheckpoint, err := cttypes.FromRawCkptToBTCCkpt(checkpoint.Ckpt, submitterAddr) + rawCheckpoint, err := checkpoint.Ckpt.ToRawCheckpoint() + require.NoError(n.t, err) + + btcCheckpoint, err := cttypes.FromRawCkptToBTCCkpt(rawCheckpoint, submitterAddr) require.NoError(n.t, err) babylonTagBytes, err := hex.DecodeString(initialization.BabylonOpReturnTag) diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index 26be927aa..c0bb049f8 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -175,7 +175,7 @@ func (n *NodeConfig) QueryListSnapshots() ([]*cmtabcitypes.Snapshot, error) { // return contractsResponse.Contracts, nil // } -func (n *NodeConfig) QueryRawCheckpoint(epoch uint64) (*ct.RawCheckpointWithMeta, error) { +func (n *NodeConfig) QueryRawCheckpoint(epoch uint64) (*ct.RawCheckpointWithMetaResponse, error) { path := fmt.Sprintf("babylon/checkpointing/v1/raw_checkpoint/%d", epoch) bz, err := n.QueryGRPCGateway(path, url.Values{}) require.NoError(n.t, err) diff --git a/x/checkpointing/keeper/grpc_query_checkpoint.go b/x/checkpointing/keeper/grpc_query_checkpoint.go index 43121b36d..b4f1810d9 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint.go @@ -15,15 +15,15 @@ import ( var _ types.QueryServer = Keeper{} // RawCheckpointList returns a list of checkpoint by status in the ascending order of epoch -func (k Keeper) RawCheckpointList(ctx context.Context, req *types.QueryRawCheckpointListRequest) (*types.QueryRawCheckpointListResponse, error) { +func (k Keeper) RawCheckpointList(c context.Context, req *types.QueryRawCheckpointListRequest) (*types.QueryRawCheckpointListResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - var checkpointList []*types.RawCheckpointWithMeta + var checkpointList []*types.RawCheckpointWithMetaResponse - sdkCtx := sdk.UnwrapSDKContext(ctx) + ctx := sdk.UnwrapSDKContext(c) - store := k.CheckpointsState(sdkCtx).checkpoints + store := k.CheckpointsState(ctx).checkpoints pageRes, err := query.FilteredPaginate(store, req.Pagination, func(_ []byte, value []byte, accumulate bool) (bool, error) { ckptWithMeta, err := types.BytesToCkptWithMeta(k.cdc, value) if err != nil { @@ -31,7 +31,7 @@ func (k Keeper) RawCheckpointList(ctx context.Context, req *types.QueryRawCheckp } if ckptWithMeta.Status == req.Status { if accumulate { - checkpointList = append(checkpointList, ckptWithMeta) + checkpointList = append(checkpointList, ckptWithMeta.ToResponse()) } return true, nil } @@ -46,19 +46,18 @@ func (k Keeper) RawCheckpointList(ctx context.Context, req *types.QueryRawCheckp } // RawCheckpoint returns a checkpoint by epoch number -func (k Keeper) RawCheckpoint(ctx context.Context, req *types.QueryRawCheckpointRequest) (*types.QueryRawCheckpointResponse, error) { +func (k Keeper) RawCheckpoint(c context.Context, req *types.QueryRawCheckpointRequest) (*types.QueryRawCheckpointResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "invalid request") } - sdkCtx := sdk.UnwrapSDKContext(ctx) - - ckptWithMeta, err := k.CheckpointsState(sdkCtx).GetRawCkptWithMeta(req.EpochNum) + ctx := sdk.UnwrapSDKContext(c) + ckptWithMeta, err := k.CheckpointsState(ctx).GetRawCkptWithMeta(req.EpochNum) if err != nil { return nil, err } - return &types.QueryRawCheckpointResponse{RawCheckpoint: ckptWithMeta}, nil + return &types.QueryRawCheckpointResponse{RawCheckpoint: ckptWithMeta.ToResponse()}, nil } // RawCheckpoints returns checkpoints for given epoch range specified in pagination params @@ -70,11 +69,11 @@ func (k Keeper) RawCheckpoints(ctx context.Context, req *types.QueryRawCheckpoin sdkCtx := sdk.UnwrapSDKContext(ctx) store := k.CheckpointsState(sdkCtx).checkpoints - var checkpointList []*types.RawCheckpointWithMeta + var checkpointList []*types.RawCheckpointWithMetaResponse pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { var ckptWithMeta types.RawCheckpointWithMeta k.cdc.MustUnmarshal(value, &ckptWithMeta) - checkpointList = append(checkpointList, &ckptWithMeta) + checkpointList = append(checkpointList, ckptWithMeta.ToResponse()) return nil }) if err != nil { diff --git a/x/checkpointing/keeper/grpc_query_checkpoint_test.go b/x/checkpointing/keeper/grpc_query_checkpoint_test.go index 3a20467ad..c19342ecc 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint_test.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint_test.go @@ -38,7 +38,7 @@ func FuzzQueryEpoch(f *testing.F) { ckptRequest := types.NewQueryRawCheckpointRequest(mockCkptWithMeta.Ckpt.EpochNum) ckptResp, err := ckptKeeper.RawCheckpoint(ctx, ckptRequest) require.NoError(t, err) - require.True(t, ckptResp.RawCheckpoint.Equal(mockCkptWithMeta)) + require.Equal(t, ckptResp.RawCheckpoint, mockCkptWithMeta.ToResponse()) // test querying the status of a given epoch number statusRequest := types.NewQueryEpochStatusRequest(mockCkptWithMeta.Ckpt.EpochNum) @@ -75,7 +75,7 @@ func FuzzQueryRawCheckpoints(f *testing.F) { require.Equal(t, int(pageLimit), len(ckptResp.RawCheckpoints)) require.Nil(t, ckptResp.Pagination.NextKey) for i, ckpt := range ckptResp.RawCheckpoints { - require.Equal(t, checkpoints[i], ckpt) + require.Equal(t, checkpoints[i].ToResponse(), ckpt) } }) } diff --git a/x/checkpointing/types/query.go b/x/checkpointing/types/query.go index 1632cefa8..b343b9ab5 100644 --- a/x/checkpointing/types/query.go +++ b/x/checkpointing/types/query.go @@ -1,5 +1,7 @@ package types +import "encoding/hex" + // ToResponse generates a RawCheckpointResponse struct from RawCheckpoint. func (r *RawCheckpoint) ToResponse() *RawCheckpointResponse { return &RawCheckpointResponse{ @@ -9,3 +11,50 @@ func (r *RawCheckpoint) ToResponse() *RawCheckpointResponse { BlsMultiSig: r.BlsMultiSig, } } + +// ToRawCheckpoint generates a RawCheckpoint struct from RawCheckpointResponse. +func (r *RawCheckpointResponse) ToRawCheckpoint() (*RawCheckpoint, error) { + blockHashBz, err := hex.DecodeString(r.BlockHashHex) + if err != nil { + return nil, err + } + blockHash := BlockHash(blockHashBz) + + return &RawCheckpoint{ + EpochNum: r.EpochNum, + BlockHash: &blockHash, + Bitmap: r.Bitmap, + BlsMultiSig: r.BlsMultiSig, + }, nil +} + +// ToResponse generates a RawCheckpointWithMetaResponse struct from RawCheckpointWithMeta. +func (r *RawCheckpointWithMeta) ToResponse() *RawCheckpointWithMetaResponse { + return &RawCheckpointWithMetaResponse{ + Ckpt: r.Ckpt.ToResponse(), + Status: r.Status, + StatusDesc: r.Status.String(), + BlsAggrPk: r.BlsAggrPk, + PowerSum: r.PowerSum, + Lifecycle: NewCheckpointStateUpdateResponse(r.Lifecycle), + } +} + +// ToResponse generates a CheckpointStateUpdateResponse struct from CheckpointStateUpdate. +func (c *CheckpointStateUpdate) ToResponse() *CheckpointStateUpdateResponse { + return &CheckpointStateUpdateResponse{ + State: c.State, + StatusDesc: c.State.String(), + BlockHeight: c.BlockHeight, + BlockTime: c.BlockTime, + } +} + +// NewCheckpointStateUpdateResponse creates a new CheckpointStateUpdateResponse slice from []*CheckpointStateUpdate. +func NewCheckpointStateUpdateResponse(cs []*CheckpointStateUpdate) (resp []*CheckpointStateUpdateResponse) { + resp = make([]*CheckpointStateUpdateResponse, len(cs)) + for i, c := range cs { + resp[i] = c.ToResponse() + } + return resp +} diff --git a/x/checkpointing/types/query.pb.go b/x/checkpointing/types/query.pb.go index 6a4374c0b..485d8e0ec 100644 --- a/x/checkpointing/types/query.pb.go +++ b/x/checkpointing/types/query.pb.go @@ -11,19 +11,23 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -91,7 +95,7 @@ func (m *QueryRawCheckpointListRequest) GetPagination() *query.PageRequest { // Query/RawCheckpoints RPC method. type QueryRawCheckpointListResponse struct { // the order is going from the newest to oldest based on the epoch number - RawCheckpoints []*RawCheckpointWithMeta `protobuf:"bytes,1,rep,name=raw_checkpoints,json=rawCheckpoints,proto3" json:"raw_checkpoints,omitempty"` + RawCheckpoints []*RawCheckpointWithMetaResponse `protobuf:"bytes,1,rep,name=raw_checkpoints,json=rawCheckpoints,proto3" json:"raw_checkpoints,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -129,7 +133,7 @@ func (m *QueryRawCheckpointListResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryRawCheckpointListResponse proto.InternalMessageInfo -func (m *QueryRawCheckpointListResponse) GetRawCheckpoints() []*RawCheckpointWithMeta { +func (m *QueryRawCheckpointListResponse) GetRawCheckpoints() []*RawCheckpointWithMetaResponse { if m != nil { return m.RawCheckpoints } @@ -193,7 +197,7 @@ func (m *QueryRawCheckpointRequest) GetEpochNum() uint64 { // QueryRawCheckpointResponse is the response type for the Query/RawCheckpoint // RPC method. type QueryRawCheckpointResponse struct { - RawCheckpoint *RawCheckpointWithMeta `protobuf:"bytes,1,opt,name=raw_checkpoint,json=rawCheckpoint,proto3" json:"raw_checkpoint,omitempty"` + RawCheckpoint *RawCheckpointWithMetaResponse `protobuf:"bytes,1,opt,name=raw_checkpoint,json=rawCheckpoint,proto3" json:"raw_checkpoint,omitempty"` } func (m *QueryRawCheckpointResponse) Reset() { *m = QueryRawCheckpointResponse{} } @@ -229,7 +233,7 @@ func (m *QueryRawCheckpointResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryRawCheckpointResponse proto.InternalMessageInfo -func (m *QueryRawCheckpointResponse) GetRawCheckpoint() *RawCheckpointWithMeta { +func (m *QueryRawCheckpointResponse) GetRawCheckpoint() *RawCheckpointWithMetaResponse { if m != nil { return m.RawCheckpoint } @@ -287,7 +291,7 @@ func (m *QueryRawCheckpointsRequest) GetPagination() *query.PageRequest { // RPC method. type QueryRawCheckpointsResponse struct { // the order is going from the newest to oldest based on the epoch number - RawCheckpoints []*RawCheckpointWithMeta `protobuf:"bytes,1,rep,name=raw_checkpoints,json=rawCheckpoints,proto3" json:"raw_checkpoints,omitempty"` + RawCheckpoints []*RawCheckpointWithMetaResponse `protobuf:"bytes,1,rep,name=raw_checkpoints,json=rawCheckpoints,proto3" json:"raw_checkpoints,omitempty"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -325,7 +329,7 @@ func (m *QueryRawCheckpointsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryRawCheckpointsResponse proto.InternalMessageInfo -func (m *QueryRawCheckpointsResponse) GetRawCheckpoints() []*RawCheckpointWithMeta { +func (m *QueryRawCheckpointsResponse) GetRawCheckpoints() []*RawCheckpointWithMetaResponse { if m != nil { return m.RawCheckpoints } @@ -812,6 +816,166 @@ func (m *RawCheckpointResponse) GetBitmap() []byte { return nil } +// CheckpointStateUpdateResponse defines a state transition on the checkpoint. +type CheckpointStateUpdateResponse struct { + // state defines the event of a state transition towards this state + State CheckpointStatus `protobuf:"varint,1,opt,name=state,proto3,enum=babylon.checkpointing.v1.CheckpointStatus" json:"state,omitempty"` + // status_desc respresents the description of status enum. + StatusDesc string `protobuf:"bytes,2,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` + // block_height is the height of the Babylon block that triggers the state + // update + BlockHeight uint64 `protobuf:"varint,3,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // block_time is the timestamp in the Babylon block that triggers the state + // update + BlockTime *time.Time `protobuf:"bytes,4,opt,name=block_time,json=blockTime,proto3,stdtime" json:"block_time,omitempty"` +} + +func (m *CheckpointStateUpdateResponse) Reset() { *m = CheckpointStateUpdateResponse{} } +func (m *CheckpointStateUpdateResponse) String() string { return proto.CompactTextString(m) } +func (*CheckpointStateUpdateResponse) ProtoMessage() {} +func (*CheckpointStateUpdateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_113f1ca5c3c2ca44, []int{15} +} +func (m *CheckpointStateUpdateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CheckpointStateUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CheckpointStateUpdateResponse.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 *CheckpointStateUpdateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_CheckpointStateUpdateResponse.Merge(m, src) +} +func (m *CheckpointStateUpdateResponse) XXX_Size() int { + return m.Size() +} +func (m *CheckpointStateUpdateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_CheckpointStateUpdateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_CheckpointStateUpdateResponse proto.InternalMessageInfo + +func (m *CheckpointStateUpdateResponse) GetState() CheckpointStatus { + if m != nil { + return m.State + } + return Accumulating +} + +func (m *CheckpointStateUpdateResponse) GetStatusDesc() string { + if m != nil { + return m.StatusDesc + } + return "" +} + +func (m *CheckpointStateUpdateResponse) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *CheckpointStateUpdateResponse) GetBlockTime() *time.Time { + if m != nil { + return m.BlockTime + } + return nil +} + +// RawCheckpointWithMetaResponse wraps the raw checkpoint with metadata. +type RawCheckpointWithMetaResponse struct { + Ckpt *RawCheckpointResponse `protobuf:"bytes,1,opt,name=ckpt,proto3" json:"ckpt,omitempty"` + // status defines the status of the checkpoint + Status CheckpointStatus `protobuf:"varint,2,opt,name=status,proto3,enum=babylon.checkpointing.v1.CheckpointStatus" json:"status,omitempty"` + // status_desc respresents the description of status enum. + StatusDesc string `protobuf:"bytes,3,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` + // bls_aggr_pk defines the aggregated BLS public key + BlsAggrPk *github_com_babylonchain_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,4,opt,name=bls_aggr_pk,json=blsAggrPk,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.PublicKey" json:"bls_aggr_pk,omitempty"` + // power_sum defines the accumulated voting power for the checkpoint + PowerSum uint64 `protobuf:"varint,5,opt,name=power_sum,json=powerSum,proto3" json:"power_sum,omitempty"` + // lifecycle defines the lifecycle of this checkpoint, i.e., each state + // transition and the time (in both timestamp and block height) of this + // transition. + Lifecycle []*CheckpointStateUpdateResponse `protobuf:"bytes,6,rep,name=lifecycle,proto3" json:"lifecycle,omitempty"` +} + +func (m *RawCheckpointWithMetaResponse) Reset() { *m = RawCheckpointWithMetaResponse{} } +func (m *RawCheckpointWithMetaResponse) String() string { return proto.CompactTextString(m) } +func (*RawCheckpointWithMetaResponse) ProtoMessage() {} +func (*RawCheckpointWithMetaResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_113f1ca5c3c2ca44, []int{16} +} +func (m *RawCheckpointWithMetaResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RawCheckpointWithMetaResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RawCheckpointWithMetaResponse.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 *RawCheckpointWithMetaResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_RawCheckpointWithMetaResponse.Merge(m, src) +} +func (m *RawCheckpointWithMetaResponse) XXX_Size() int { + return m.Size() +} +func (m *RawCheckpointWithMetaResponse) XXX_DiscardUnknown() { + xxx_messageInfo_RawCheckpointWithMetaResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_RawCheckpointWithMetaResponse proto.InternalMessageInfo + +func (m *RawCheckpointWithMetaResponse) GetCkpt() *RawCheckpointResponse { + if m != nil { + return m.Ckpt + } + return nil +} + +func (m *RawCheckpointWithMetaResponse) GetStatus() CheckpointStatus { + if m != nil { + return m.Status + } + return Accumulating +} + +func (m *RawCheckpointWithMetaResponse) GetStatusDesc() string { + if m != nil { + return m.StatusDesc + } + return "" +} + +func (m *RawCheckpointWithMetaResponse) GetPowerSum() uint64 { + if m != nil { + return m.PowerSum + } + return 0 +} + +func (m *RawCheckpointWithMetaResponse) GetLifecycle() []*CheckpointStateUpdateResponse { + if m != nil { + return m.Lifecycle + } + return nil +} + func init() { proto.RegisterType((*QueryRawCheckpointListRequest)(nil), "babylon.checkpointing.v1.QueryRawCheckpointListRequest") proto.RegisterType((*QueryRawCheckpointListResponse)(nil), "babylon.checkpointing.v1.QueryRawCheckpointListResponse") @@ -829,6 +993,8 @@ func init() { proto.RegisterType((*QueryLastCheckpointWithStatusRequest)(nil), "babylon.checkpointing.v1.QueryLastCheckpointWithStatusRequest") proto.RegisterType((*QueryLastCheckpointWithStatusResponse)(nil), "babylon.checkpointing.v1.QueryLastCheckpointWithStatusResponse") proto.RegisterType((*RawCheckpointResponse)(nil), "babylon.checkpointing.v1.RawCheckpointResponse") + proto.RegisterType((*CheckpointStateUpdateResponse)(nil), "babylon.checkpointing.v1.CheckpointStateUpdateResponse") + proto.RegisterType((*RawCheckpointWithMetaResponse)(nil), "babylon.checkpointing.v1.RawCheckpointWithMetaResponse") } func init() { @@ -836,73 +1002,87 @@ func init() { } var fileDescriptor_113f1ca5c3c2ca44 = []byte{ - // 1055 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x97, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0x3b, 0x49, 0x1b, 0x91, 0xe7, 0x24, 0x84, 0x51, 0x68, 0xcd, 0xa6, 0xb8, 0xd1, 0x12, - 0x4a, 0x5a, 0xd4, 0x5d, 0xd9, 0xf9, 0x49, 0x68, 0x82, 0x94, 0x2a, 0x50, 0xa9, 0x3f, 0x28, 0x1b, - 0xa9, 0x20, 0x0e, 0xac, 0x66, 0x37, 0xa3, 0xdd, 0x25, 0xeb, 0xdd, 0x8d, 0x67, 0xd6, 0x89, 0x55, - 0x55, 0x48, 0xf0, 0x0f, 0x20, 0x21, 0xf1, 0x4f, 0x70, 0x81, 0x1b, 0x47, 0x04, 0x17, 0x0e, 0x08, - 0x55, 0x42, 0x48, 0x08, 0x24, 0x54, 0x25, 0xfc, 0x21, 0x68, 0x67, 0xc7, 0xb1, 0xd7, 0xf6, 0xc6, - 0x71, 0xf0, 0x85, 0x9b, 0x3d, 0x7e, 0x6f, 0xde, 0xe7, 0xfb, 0x66, 0xde, 0x7b, 0x63, 0x98, 0xb7, - 0x88, 0xd5, 0xf0, 0xc3, 0x40, 0xb7, 0x5d, 0x6a, 0xef, 0x45, 0xa1, 0x17, 0x70, 0x2f, 0x70, 0xf4, - 0x7a, 0x59, 0xdf, 0x8f, 0x69, 0xad, 0xa1, 0x45, 0xb5, 0x90, 0x87, 0xb8, 0x28, 0xad, 0xb4, 0x8c, - 0x95, 0x56, 0x2f, 0x2b, 0x33, 0x4e, 0xe8, 0x84, 0xc2, 0x48, 0x4f, 0x3e, 0xa5, 0xf6, 0xca, 0x55, - 0x27, 0x0c, 0x1d, 0x9f, 0xea, 0x24, 0xf2, 0x74, 0x12, 0x04, 0x21, 0x27, 0xdc, 0x0b, 0x03, 0x26, - 0x7f, 0xbd, 0x9e, 0x1b, 0xd3, 0xf2, 0x99, 0xb9, 0x47, 0x65, 0x54, 0xe5, 0x46, 0xae, 0x5d, 0x6b, - 0x41, 0x9a, 0xde, 0xb4, 0x43, 0x56, 0x0d, 0x99, 0x6e, 0x11, 0x46, 0x53, 0x72, 0xbd, 0x5e, 0xb6, - 0x28, 0x27, 0x65, 0x3d, 0x22, 0x8e, 0x17, 0x88, 0xf8, 0xa9, 0xad, 0xfa, 0x0d, 0x82, 0x57, 0x3f, - 0x48, 0x4c, 0x0c, 0x72, 0x70, 0xe7, 0x64, 0xa3, 0xfb, 0x1e, 0xe3, 0x06, 0xdd, 0x8f, 0x29, 0xe3, - 0x78, 0x0b, 0xc6, 0x18, 0x27, 0x3c, 0x66, 0x45, 0x34, 0x87, 0x16, 0xa6, 0x2a, 0x37, 0xb5, 0x3c, - 0xfd, 0x5a, 0x6b, 0x83, 0x1d, 0xe1, 0x61, 0x48, 0x4f, 0xfc, 0x2e, 0x40, 0x2b, 0x72, 0x71, 0x64, - 0x0e, 0x2d, 0x14, 0x2a, 0xd7, 0xb5, 0x14, 0x53, 0x4b, 0x30, 0xb5, 0x34, 0xc1, 0x12, 0x53, 0x7b, - 0x44, 0x1c, 0x2a, 0xe3, 0x1b, 0x6d, 0x9e, 0xea, 0x4f, 0x08, 0x4a, 0x79, 0xb4, 0x2c, 0x0a, 0x03, - 0x46, 0xf1, 0x47, 0xf0, 0x62, 0x8d, 0x1c, 0x98, 0x2d, 0xb6, 0x84, 0x7b, 0x74, 0xa1, 0x50, 0xd1, - 0xf3, 0xb9, 0x33, 0xbb, 0x7d, 0xe8, 0x71, 0xf7, 0x01, 0xe5, 0xc4, 0x98, 0xaa, 0xb5, 0x2f, 0x33, - 0xfc, 0x5e, 0x0f, 0x11, 0x6f, 0xf4, 0x15, 0x91, 0x62, 0x65, 0x54, 0xac, 0xc1, 0x2b, 0xdd, 0x22, - 0x9a, 0xe9, 0x9e, 0x85, 0x71, 0x1a, 0x85, 0xb6, 0x6b, 0x06, 0x71, 0x55, 0x64, 0xfc, 0xa2, 0xf1, - 0x82, 0x58, 0x78, 0x18, 0x57, 0x55, 0x0e, 0x4a, 0x2f, 0x4f, 0x29, 0xfd, 0x31, 0x4c, 0x65, 0xa5, - 0x0b, 0xff, 0x73, 0x28, 0x9f, 0xcc, 0x28, 0x57, 0x77, 0x7b, 0x45, 0x65, 0x4d, 0xe0, 0xec, 0xd9, - 0xa2, 0x73, 0x9f, 0xed, 0x0f, 0x08, 0x66, 0x7b, 0x86, 0xf9, 0xff, 0x1c, 0xec, 0x17, 0x08, 0xae, - 0x0a, 0x09, 0x5b, 0x3e, 0x7b, 0x14, 0x5b, 0xbe, 0x67, 0xdf, 0xa3, 0x8d, 0xf6, 0x5a, 0x3a, 0xed, - 0x70, 0x87, 0x56, 0x24, 0xbf, 0x36, 0x4b, 0xba, 0x9b, 0x42, 0xa6, 0x72, 0x17, 0xae, 0xd4, 0x89, - 0xef, 0xed, 0x12, 0x1e, 0xd6, 0xcc, 0x03, 0x8f, 0xbb, 0xa6, 0xec, 0x35, 0xcd, 0x94, 0xde, 0xca, - 0x4f, 0xe9, 0xe3, 0xa6, 0x63, 0x92, 0xce, 0x2d, 0x9f, 0xdd, 0xa3, 0x0d, 0x63, 0xa6, 0xde, 0xbd, - 0x38, 0xc4, 0xb4, 0xae, 0xc0, 0x15, 0xa1, 0x67, 0x3b, 0xc9, 0x94, 0xec, 0x2c, 0x67, 0xa9, 0x96, - 0x4f, 0xa0, 0xd8, 0xed, 0x27, 0x53, 0x30, 0x84, 0xae, 0xa6, 0x6e, 0x83, 0x9a, 0x5e, 0x58, 0x6a, - 0xd3, 0x80, 0xb7, 0x45, 0xb9, 0x13, 0xc6, 0xad, 0x82, 0xbe, 0x06, 0x85, 0x14, 0xd1, 0x4e, 0x56, - 0x25, 0x24, 0x88, 0x25, 0x61, 0xa7, 0x7e, 0x3d, 0x02, 0xaf, 0x9d, 0xba, 0x8f, 0x44, 0x9e, 0x85, - 0x71, 0xee, 0x45, 0xa6, 0xf0, 0x6c, 0x6a, 0xe5, 0x5e, 0x24, 0xec, 0x3b, 0xa3, 0x8c, 0x74, 0x46, - 0xc1, 0xfb, 0x30, 0x91, 0x62, 0x4b, 0x8b, 0x51, 0x71, 0xd0, 0x0f, 0xf3, 0x65, 0x9f, 0x01, 0x49, - 0x6b, 0x5b, 0xdb, 0x0e, 0x78, 0xad, 0x61, 0x14, 0x58, 0x6b, 0x45, 0xd9, 0x84, 0xe9, 0x4e, 0x03, - 0x3c, 0x0d, 0xa3, 0x7b, 0xb4, 0x21, 0xf0, 0xc7, 0x8d, 0xe4, 0x23, 0x9e, 0x81, 0x4b, 0x75, 0xe2, - 0xc7, 0x54, 0x32, 0xa7, 0x5f, 0xd6, 0x47, 0xd6, 0x90, 0xfa, 0x29, 0xcc, 0x0b, 0x88, 0xfb, 0x84, - 0xf1, 0x6c, 0x19, 0x67, 0x2f, 0xc1, 0x30, 0xce, 0xf2, 0x33, 0x78, 0xbd, 0x4f, 0xac, 0x21, 0x35, - 0xd9, 0x93, 0x1b, 0xde, 0xd1, 0x64, 0x7f, 0x47, 0xf0, 0x72, 0xef, 0xb6, 0x7e, 0x6a, 0xd3, 0x98, - 0x87, 0x29, 0xcb, 0x0f, 0xed, 0x3d, 0xd3, 0x25, 0xcc, 0x35, 0x5d, 0x7a, 0x28, 0xd2, 0x38, 0x6e, - 0x4c, 0x88, 0xd5, 0xbb, 0x84, 0xb9, 0x77, 0xe9, 0x21, 0xbe, 0x0c, 0x63, 0x96, 0xc7, 0xab, 0x24, - 0x2a, 0x8e, 0xce, 0xa1, 0x85, 0x09, 0x43, 0x7e, 0xc3, 0x04, 0x26, 0x93, 0xca, 0xaf, 0xc6, 0x3e, - 0xf7, 0x4c, 0xe6, 0x39, 0xc5, 0x8b, 0xc9, 0xcf, 0x5b, 0x1b, 0x7f, 0xfe, 0x7d, 0xed, 0x2d, 0xc7, - 0xe3, 0x6e, 0x6c, 0x69, 0x76, 0x58, 0xd5, 0xa5, 0x32, 0xdb, 0x25, 0x5e, 0xa0, 0x9f, 0xbc, 0x43, - 0x6a, 0x8d, 0x88, 0x87, 0xc9, 0x2b, 0xa5, 0x5c, 0x59, 0x5c, 0x2b, 0x6b, 0x3b, 0x9e, 0x13, 0x10, - 0x1e, 0xd7, 0xa8, 0x51, 0xb0, 0x7c, 0xf6, 0x20, 0xd9, 0x72, 0xc7, 0x73, 0x2a, 0xcf, 0x01, 0x2e, - 0x89, 0xcc, 0xe2, 0x1f, 0x11, 0xbc, 0xd4, 0x35, 0xb7, 0xf1, 0x6a, 0xbf, 0x1b, 0x98, 0xf3, 0x2e, - 0x51, 0xd6, 0x06, 0x77, 0x4c, 0x13, 0xaa, 0xae, 0x7f, 0xfe, 0xdb, 0x3f, 0x5f, 0x8d, 0x2c, 0xe1, - 0x8a, 0x9e, 0xfb, 0xa6, 0xea, 0x98, 0x34, 0xfa, 0x93, 0xf4, 0x9a, 0x3c, 0xc5, 0xdf, 0x23, 0x98, - 0xcc, 0xec, 0x8c, 0x17, 0x07, 0xe1, 0x68, 0xc2, 0x2f, 0x0d, 0xe6, 0x24, 0xc1, 0x6f, 0x0b, 0xf0, - 0x15, 0xbc, 0x74, 0x56, 0x70, 0xfd, 0xc9, 0xc9, 0xcd, 0x79, 0x8a, 0xbf, 0x45, 0x30, 0x95, 0x9d, - 0xad, 0x78, 0x20, 0x8c, 0x66, 0xbd, 0x29, 0xcb, 0x03, 0x7a, 0x49, 0xfa, 0xb2, 0xa0, 0x7f, 0x13, - 0xdf, 0x38, 0x73, 0xda, 0x93, 0x2b, 0x33, 0xdd, 0x39, 0xc5, 0xf0, 0x4a, 0x9f, 0xf0, 0x39, 0xc3, - 0x57, 0x59, 0x1d, 0xd8, 0x4f, 0x82, 0x6f, 0x08, 0xf0, 0x55, 0xbc, 0xac, 0x9f, 0xfa, 0x56, 0x8f, - 0x84, 0xb3, 0x18, 0xa3, 0x99, 0xbc, 0x7f, 0x87, 0xa0, 0xd0, 0xd6, 0x41, 0x71, 0xb9, 0x0f, 0x47, - 0xf7, 0x98, 0x53, 0x2a, 0x83, 0xb8, 0x48, 0xea, 0xb7, 0x05, 0xf5, 0x32, 0x5e, 0xcc, 0xa7, 0x16, - 0x90, 0x19, 0x58, 0x5d, 0x3e, 0xd8, 0x7f, 0x41, 0x70, 0xb9, 0x77, 0xef, 0xc7, 0xb7, 0xcf, 0x39, - 0x32, 0x52, 0x25, 0x1b, 0xff, 0x69, 0xe0, 0xa8, 0xcb, 0x42, 0x94, 0x8e, 0x6f, 0xf5, 0x13, 0xb5, - 0xde, 0x3e, 0xec, 0xf0, 0x5f, 0x08, 0x8a, 0x79, 0x9d, 0x1d, 0x6f, 0xf6, 0x41, 0xea, 0x33, 0x7e, - 0x94, 0x77, 0xce, 0xed, 0x2f, 0x45, 0x6d, 0x0a, 0x51, 0x6b, 0x78, 0x25, 0x5f, 0x94, 0x4f, 0x18, - 0x37, 0x3b, 0x6b, 0x5b, 0xf6, 0xa4, 0xad, 0xf7, 0x7f, 0x3e, 0x2a, 0xa1, 0x67, 0x47, 0x25, 0xf4, - 0xfc, 0xa8, 0x84, 0xbe, 0x3c, 0x2e, 0x5d, 0x78, 0x76, 0x5c, 0xba, 0xf0, 0xc7, 0x71, 0xe9, 0xc2, - 0xc7, 0xcb, 0xfd, 0x9a, 0xf8, 0x61, 0x47, 0x28, 0xde, 0x88, 0x28, 0xb3, 0xc6, 0xc4, 0x7f, 0xc3, - 0xc5, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xee, 0xdc, 0xe0, 0x14, 0x10, 0x0f, 0x00, 0x00, + // 1266 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0x5d, 0x6f, 0x1b, 0x45, + 0x17, 0xee, 0xda, 0x49, 0xf4, 0xfa, 0x38, 0xcd, 0x5b, 0x46, 0xa5, 0x35, 0x6e, 0xeb, 0x94, 0xa5, + 0x94, 0xb4, 0xa8, 0xbb, 0xb2, 0xd3, 0x7c, 0x50, 0xfa, 0x01, 0x2e, 0x81, 0x4a, 0xfd, 0x20, 0x6c, + 0x68, 0x91, 0x90, 0xe8, 0x32, 0xbb, 0x99, 0xae, 0x17, 0xaf, 0x77, 0x37, 0x9e, 0x59, 0x27, 0x56, + 0xa9, 0x90, 0xe0, 0x0f, 0x54, 0x42, 0xe2, 0x8a, 0x7f, 0xc0, 0x0d, 0xdc, 0x71, 0xcd, 0x55, 0x25, + 0x10, 0xaa, 0x84, 0x90, 0x10, 0x48, 0x50, 0x25, 0x88, 0xdf, 0x81, 0x76, 0x76, 0x1c, 0x7b, 0x6d, + 0xaf, 0x1d, 0x3b, 0xb9, 0xe1, 0x2e, 0x3e, 0x7b, 0xce, 0xcc, 0x73, 0x9e, 0xf3, 0x31, 0x4f, 0xe0, + 0x8c, 0x81, 0x8d, 0xa6, 0xe3, 0xb9, 0xaa, 0x59, 0x21, 0x66, 0xd5, 0xf7, 0x6c, 0x97, 0xd9, 0xae, + 0xa5, 0x36, 0x8a, 0xea, 0x46, 0x40, 0xea, 0x4d, 0xc5, 0xaf, 0x7b, 0xcc, 0x43, 0x39, 0xe1, 0xa5, + 0xc4, 0xbc, 0x94, 0x46, 0x31, 0x7f, 0xd4, 0xf2, 0x2c, 0x8f, 0x3b, 0xa9, 0xe1, 0x5f, 0x91, 0x7f, + 0xfe, 0xa4, 0xe5, 0x79, 0x96, 0x43, 0x54, 0xec, 0xdb, 0x2a, 0x76, 0x5d, 0x8f, 0x61, 0x66, 0x7b, + 0x2e, 0x15, 0x5f, 0x67, 0xc5, 0x57, 0xfe, 0xcb, 0x08, 0x1e, 0xa8, 0xcc, 0xae, 0x11, 0xca, 0x70, + 0xcd, 0x17, 0x0e, 0x67, 0x13, 0x41, 0x19, 0x0e, 0xd5, 0xab, 0x44, 0xc0, 0xca, 0x9f, 0x4b, 0xf4, + 0x6b, 0x1b, 0x84, 0xeb, 0x79, 0xd3, 0xa3, 0x35, 0x8f, 0xaa, 0x06, 0xa6, 0x24, 0x4a, 0x4d, 0x6d, + 0x14, 0x0d, 0xc2, 0x70, 0x51, 0xf5, 0xb1, 0x65, 0xbb, 0x1c, 0x60, 0xe4, 0x2b, 0x7f, 0x23, 0xc1, + 0xa9, 0xf7, 0x42, 0x17, 0x0d, 0x6f, 0x5e, 0xdf, 0x3d, 0xe8, 0x96, 0x4d, 0x99, 0x46, 0x36, 0x02, + 0x42, 0x19, 0x2a, 0xc3, 0x14, 0x65, 0x98, 0x05, 0x34, 0x27, 0x9d, 0x96, 0xe6, 0x66, 0x4a, 0xe7, + 0x95, 0x24, 0x82, 0x94, 0xf6, 0x01, 0x6b, 0x3c, 0x42, 0x13, 0x91, 0xe8, 0x6d, 0x80, 0xf6, 0xcd, + 0xb9, 0xd4, 0x69, 0x69, 0x2e, 0x5b, 0x3a, 0xab, 0x44, 0x30, 0x95, 0x10, 0xa6, 0x12, 0x55, 0x40, + 0xc0, 0x54, 0x56, 0xb1, 0x45, 0xc4, 0xfd, 0x5a, 0x47, 0xa4, 0xfc, 0xa3, 0x04, 0x85, 0x24, 0xb4, + 0xd4, 0xf7, 0x5c, 0x4a, 0xd0, 0xc7, 0xf0, 0xff, 0x3a, 0xde, 0xd4, 0xdb, 0xd8, 0x42, 0xdc, 0xe9, + 0xb9, 0x6c, 0x69, 0x29, 0x19, 0x77, 0xec, 0xb4, 0x0f, 0x6c, 0x56, 0xb9, 0x4d, 0x18, 0x6e, 0x9d, + 0xa8, 0xcd, 0xd4, 0x3b, 0x3f, 0x53, 0xf4, 0x4e, 0x9f, 0x64, 0x5e, 0x19, 0x9a, 0x8c, 0x38, 0xac, + 0x33, 0x9b, 0x65, 0x78, 0xa1, 0x37, 0x99, 0x16, 0xed, 0x27, 0x20, 0x43, 0x7c, 0xcf, 0xac, 0xe8, + 0x6e, 0x50, 0xe3, 0xcc, 0x4f, 0x68, 0xff, 0xe3, 0x86, 0x3b, 0x41, 0x4d, 0xfe, 0x14, 0xf2, 0xfd, + 0x22, 0x05, 0x05, 0xf7, 0x61, 0x26, 0x4e, 0x01, 0x8f, 0xdf, 0x07, 0x03, 0x87, 0x63, 0x0c, 0xc8, + 0xeb, 0xfd, 0x6e, 0xa7, 0x2d, 0xe0, 0xf1, 0x5a, 0x4b, 0x63, 0xd7, 0xfa, 0x89, 0x04, 0x27, 0xfa, + 0x5e, 0xf3, 0xdf, 0x2b, 0xf4, 0x17, 0x12, 0x9c, 0xe4, 0xa9, 0x94, 0x1d, 0xba, 0x1a, 0x18, 0x8e, + 0x6d, 0xde, 0x24, 0xcd, 0xce, 0x19, 0x1b, 0x54, 0xec, 0x03, 0x1b, 0x9e, 0x9f, 0x5b, 0xa3, 0xde, + 0x8b, 0x42, 0x50, 0xba, 0x0e, 0xc7, 0x1b, 0xd8, 0xb1, 0xd7, 0x31, 0xf3, 0xea, 0xfa, 0xa6, 0xcd, + 0x2a, 0xba, 0xd8, 0x41, 0x2d, 0x6a, 0x2f, 0x24, 0x53, 0x7b, 0xaf, 0x15, 0x18, 0xd2, 0x5a, 0x76, + 0xe8, 0x4d, 0xd2, 0xd4, 0x8e, 0x36, 0x7a, 0x8d, 0x07, 0x48, 0xeb, 0x22, 0x1c, 0xe7, 0xf9, 0xac, + 0x84, 0x4c, 0x89, 0x8d, 0xb3, 0x97, 0xe9, 0xb9, 0x0f, 0xb9, 0xde, 0x38, 0x41, 0xc1, 0x01, 0x6c, + 0x3b, 0x79, 0x05, 0xe4, 0xa8, 0x71, 0x89, 0x49, 0x5c, 0xd6, 0x71, 0xcb, 0x75, 0x2f, 0x68, 0x0f, + 0xf8, 0x2c, 0x64, 0x23, 0x88, 0x66, 0x68, 0x15, 0x20, 0x81, 0x9b, 0xb8, 0x9f, 0xfc, 0x55, 0x0a, + 0x5e, 0x1a, 0x78, 0x8e, 0x80, 0x7c, 0x02, 0x32, 0xcc, 0xf6, 0x75, 0x1e, 0xd9, 0xca, 0x95, 0xd9, + 0x3e, 0xf7, 0xef, 0xbe, 0x25, 0xd5, 0x7d, 0x0b, 0xda, 0x80, 0xe9, 0x08, 0xb6, 0xf0, 0x48, 0xf3, + 0x42, 0xdf, 0x49, 0x4e, 0x7b, 0x0f, 0x90, 0x94, 0x0e, 0xdb, 0x8a, 0xcb, 0xea, 0x4d, 0x2d, 0x4b, + 0xdb, 0x96, 0xfc, 0x55, 0x38, 0xd2, 0xed, 0x80, 0x8e, 0x40, 0xba, 0x4a, 0x9a, 0x1c, 0x7e, 0x46, + 0x0b, 0xff, 0x44, 0x47, 0x61, 0xb2, 0x81, 0x9d, 0x80, 0x08, 0xcc, 0xd1, 0x8f, 0x4b, 0xa9, 0x65, + 0x49, 0xfe, 0x04, 0xce, 0x70, 0x10, 0xb7, 0x30, 0x65, 0xf1, 0x71, 0x8e, 0x37, 0xc1, 0x41, 0xd4, + 0xf2, 0x33, 0x78, 0x79, 0xc8, 0x5d, 0xa2, 0x0a, 0xf7, 0x12, 0x96, 0xae, 0xba, 0xc7, 0x6d, 0x94, + 0xb4, 0x6c, 0x7f, 0x95, 0xe0, 0xf9, 0xfe, 0x6b, 0x7e, 0xe0, 0xd2, 0x38, 0x03, 0x33, 0x86, 0xe3, + 0x99, 0x55, 0xbd, 0x82, 0x69, 0x45, 0xaf, 0x90, 0x2d, 0x4e, 0x63, 0x46, 0x9b, 0xe6, 0xd6, 0x1b, + 0x98, 0x56, 0x6e, 0x90, 0x2d, 0x74, 0x0c, 0xa6, 0x0c, 0x9b, 0xd5, 0xb0, 0x9f, 0x4b, 0x9f, 0x96, + 0xe6, 0xa6, 0x35, 0xf1, 0x0b, 0x61, 0x38, 0x1c, 0x4e, 0x7e, 0x2d, 0x70, 0x98, 0xad, 0x53, 0xdb, + 0xca, 0x4d, 0x84, 0x9f, 0xcb, 0x57, 0x7e, 0xff, 0x73, 0xf6, 0x35, 0xcb, 0x66, 0x95, 0xc0, 0x50, + 0x4c, 0xaf, 0xa6, 0x8a, 0xcc, 0xcc, 0x0a, 0xb6, 0x5d, 0x75, 0x57, 0x9f, 0xd4, 0x9b, 0x3e, 0xf3, + 0x42, 0xf5, 0x52, 0x2c, 0xcd, 0x2f, 0x17, 0x95, 0x35, 0xdb, 0x72, 0x31, 0x0b, 0xea, 0x44, 0xcb, + 0x1a, 0x0e, 0xbd, 0x1d, 0x1e, 0xb9, 0x66, 0x5b, 0xf2, 0x3f, 0x12, 0x9c, 0x8a, 0xb3, 0x4e, 0xee, + 0xfa, 0xeb, 0x98, 0xed, 0x8e, 0x3a, 0x7a, 0x03, 0x26, 0xc3, 0x22, 0x90, 0x31, 0xaa, 0x17, 0x05, + 0x86, 0xcd, 0x2f, 0x7a, 0x7b, 0x9d, 0x50, 0x53, 0x30, 0x00, 0x91, 0xe9, 0x2d, 0x42, 0x4d, 0xf4, + 0x22, 0x4c, 0x0b, 0x96, 0x88, 0x6d, 0x55, 0x18, 0x67, 0x61, 0x22, 0xc4, 0x19, 0x72, 0xc4, 0x4d, + 0xe8, 0x1a, 0x40, 0xe4, 0x12, 0x0a, 0x37, 0xce, 0x43, 0xb6, 0x94, 0x57, 0x22, 0x55, 0xa7, 0xb4, + 0x54, 0x9d, 0xf2, 0x7e, 0x4b, 0xd5, 0x95, 0x27, 0x1e, 0xff, 0x35, 0x2b, 0x69, 0x19, 0x1e, 0x13, + 0x5a, 0xe5, 0xaf, 0xd3, 0x70, 0x6a, 0xe0, 0xbb, 0x83, 0xae, 0xc3, 0x84, 0x59, 0xf5, 0xc7, 0x6e, + 0x18, 0x1e, 0xdc, 0xd1, 0xec, 0xa9, 0xb1, 0x65, 0x5a, 0x17, 0x5f, 0xe9, 0x1e, 0xbe, 0x3e, 0x82, + 0xb0, 0x86, 0x3a, 0xb6, 0xac, 0xba, 0xee, 0x57, 0xf7, 0xd3, 0x15, 0xbb, 0x0f, 0x50, 0x48, 0x15, + 0x7d, 0xd3, 0xb2, 0xea, 0xab, 0xd5, 0xb0, 0xa3, 0x7d, 0x6f, 0x93, 0xd4, 0x75, 0x1a, 0xd4, 0x72, + 0x93, 0x51, 0x47, 0x73, 0xc3, 0x5a, 0x50, 0x43, 0x77, 0x21, 0xe3, 0xd8, 0x0f, 0x88, 0xd9, 0x34, + 0x1d, 0x92, 0x9b, 0x1a, 0xf6, 0xd2, 0x0f, 0x6c, 0x2d, 0xad, 0x7d, 0x52, 0xe9, 0x19, 0xc0, 0x24, + 0x9f, 0x70, 0xf4, 0x83, 0x04, 0xcf, 0xf5, 0xe8, 0x4a, 0xb4, 0x34, 0x6c, 0x13, 0x26, 0xe8, 0xe6, + 0xfc, 0xf2, 0xe8, 0x81, 0x11, 0x3a, 0xf9, 0xd2, 0xe7, 0xbf, 0xfc, 0xfd, 0x65, 0xea, 0x22, 0x2a, + 0xa9, 0x89, 0x9a, 0xbf, 0x4b, 0xf9, 0xa8, 0x0f, 0xa3, 0x22, 0x3d, 0x42, 0xdf, 0x4b, 0x70, 0x38, + 0x76, 0x32, 0x9a, 0x1f, 0x05, 0x47, 0x0b, 0xfc, 0xc5, 0xd1, 0x82, 0x04, 0xf0, 0xcb, 0x1c, 0xf8, + 0x22, 0xba, 0xb8, 0x57, 0xe0, 0xea, 0xc3, 0xdd, 0x0d, 0xf6, 0x08, 0x7d, 0x2b, 0xc1, 0x4c, 0x5c, + 0xeb, 0xa1, 0x91, 0x60, 0xb4, 0xf6, 0x7e, 0x7e, 0x61, 0xc4, 0x28, 0x81, 0xbe, 0xc8, 0xd1, 0xbf, + 0x8a, 0xce, 0xed, 0x99, 0xf6, 0xb0, 0x65, 0x8e, 0x74, 0xab, 0x29, 0xb4, 0x38, 0xe4, 0xfa, 0x04, + 0x11, 0x98, 0x5f, 0x1a, 0x39, 0x4e, 0x00, 0xbf, 0xc2, 0x81, 0x2f, 0xa1, 0x05, 0x75, 0xe0, 0xff, + 0x92, 0x3e, 0x0f, 0xe6, 0x72, 0x2e, 0xc6, 0xfb, 0x77, 0x12, 0x64, 0x3b, 0x5e, 0x72, 0x54, 0x1c, + 0x82, 0xa3, 0x57, 0x6e, 0xe5, 0x4b, 0xa3, 0x84, 0x08, 0xd4, 0xaf, 0x73, 0xd4, 0x0b, 0x68, 0x3e, + 0x19, 0x35, 0x07, 0x19, 0x03, 0xab, 0x8a, 0x4d, 0xf5, 0x93, 0x04, 0xc7, 0xfa, 0x6b, 0x10, 0x74, + 0x79, 0x4c, 0xe9, 0x12, 0x65, 0x72, 0x65, 0x5f, 0xc2, 0x47, 0x5e, 0xe0, 0x49, 0xa9, 0xe8, 0xc2, + 0xb0, 0xa4, 0x2e, 0x75, 0x8a, 0x2e, 0xf4, 0x87, 0x04, 0xb9, 0x24, 0x85, 0x81, 0xae, 0x0e, 0x81, + 0x34, 0x44, 0x06, 0xe5, 0xaf, 0x8d, 0x1d, 0x2f, 0x92, 0xba, 0xca, 0x93, 0x5a, 0x46, 0x8b, 0xc9, + 0x49, 0x39, 0x98, 0x32, 0xbd, 0x7b, 0xb6, 0xc5, 0x4e, 0x2a, 0xbf, 0xfb, 0x64, 0xbb, 0x20, 0x3d, + 0xdd, 0x2e, 0x48, 0xcf, 0xb6, 0x0b, 0xd2, 0xe3, 0x9d, 0xc2, 0xa1, 0xa7, 0x3b, 0x85, 0x43, 0xbf, + 0xed, 0x14, 0x0e, 0x7d, 0xb8, 0x30, 0xec, 0xd9, 0xd8, 0xea, 0xba, 0x8a, 0x35, 0x7d, 0x42, 0x8d, + 0x29, 0xfe, 0xee, 0xce, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xee, 0xf6, 0x49, 0x5b, 0xd1, 0x11, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1797,6 +1977,134 @@ func (m *RawCheckpointResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *CheckpointStateUpdateResponse) 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 *CheckpointStateUpdateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CheckpointStateUpdateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BlockTime != nil { + n9, err9 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.BlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime):]) + if err9 != nil { + return 0, err9 + } + i -= n9 + i = encodeVarintQuery(dAtA, i, uint64(n9)) + i-- + dAtA[i] = 0x22 + } + if m.BlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x18 + } + if len(m.StatusDesc) > 0 { + i -= len(m.StatusDesc) + copy(dAtA[i:], m.StatusDesc) + i = encodeVarintQuery(dAtA, i, uint64(len(m.StatusDesc))) + i-- + dAtA[i] = 0x12 + } + if m.State != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.State)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *RawCheckpointWithMetaResponse) 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 *RawCheckpointWithMetaResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RawCheckpointWithMetaResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Lifecycle) > 0 { + for iNdEx := len(m.Lifecycle) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Lifecycle[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if m.PowerSum != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.PowerSum)) + i-- + dAtA[i] = 0x28 + } + if m.BlsAggrPk != nil { + { + size := m.BlsAggrPk.Size() + i -= size + if _, err := m.BlsAggrPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.StatusDesc) > 0 { + i -= len(m.StatusDesc) + copy(dAtA[i:], m.StatusDesc) + i = encodeVarintQuery(dAtA, i, uint64(len(m.StatusDesc))) + i-- + dAtA[i] = 0x1a + } + if m.Status != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x10 + } + if m.Ckpt != nil { + { + size, err := m.Ckpt.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2043,6 +2351,62 @@ func (m *RawCheckpointResponse) Size() (n int) { return n } +func (m *CheckpointStateUpdateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.State != 0 { + n += 1 + sovQuery(uint64(m.State)) + } + l = len(m.StatusDesc) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.BlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BlockHeight)) + } + if m.BlockTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime) + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *RawCheckpointWithMetaResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Ckpt != nil { + l = m.Ckpt.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Status != 0 { + n += 1 + sovQuery(uint64(m.Status)) + } + l = len(m.StatusDesc) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.BlsAggrPk != nil { + l = m.BlsAggrPk.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.PowerSum != 0 { + n += 1 + sovQuery(uint64(m.PowerSum)) + } + if len(m.Lifecycle) > 0 { + for _, e := range m.Lifecycle { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2212,7 +2576,7 @@ func (m *QueryRawCheckpointListResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RawCheckpoints = append(m.RawCheckpoints, &RawCheckpointWithMeta{}) + m.RawCheckpoints = append(m.RawCheckpoints, &RawCheckpointWithMetaResponse{}) if err := m.RawCheckpoints[len(m.RawCheckpoints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -2402,7 +2766,7 @@ func (m *QueryRawCheckpointResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.RawCheckpoint == nil { - m.RawCheckpoint = &RawCheckpointWithMeta{} + m.RawCheckpoint = &RawCheckpointWithMetaResponse{} } if err := m.RawCheckpoint.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2573,7 +2937,7 @@ func (m *QueryRawCheckpointsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.RawCheckpoints = append(m.RawCheckpoints, &RawCheckpointWithMeta{}) + m.RawCheckpoints = append(m.RawCheckpoints, &RawCheckpointWithMetaResponse{}) if err := m.RawCheckpoints[len(m.RawCheckpoints)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -3593,6 +3957,387 @@ func (m *RawCheckpointResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *CheckpointStateUpdateResponse) 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 ErrIntOverflowQuery + } + 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: CheckpointStateUpdateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CheckpointStateUpdateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + m.State = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.State |= CheckpointStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusDesc", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StatusDesc = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockTime == nil { + m.BlockTime = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.BlockTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RawCheckpointWithMetaResponse) 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 ErrIntOverflowQuery + } + 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: RawCheckpointWithMetaResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RawCheckpointWithMetaResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ckpt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ckpt == nil { + m.Ckpt = &RawCheckpointResponse{} + } + if err := m.Ckpt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= CheckpointStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusDesc", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StatusDesc = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlsAggrPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_crypto_bls12381.PublicKey + m.BlsAggrPk = &v + if err := m.BlsAggrPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PowerSum", wireType) + } + m.PowerSum = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PowerSum |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Lifecycle", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Lifecycle = append(m.Lifecycle, &CheckpointStateUpdateResponse{}) + if err := m.Lifecycle[len(m.Lifecycle)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From b545f6b3df81d9cdb5c3e8ce24652a0020ef9882 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Wed, 6 Mar 2024 08:11:55 -0300 Subject: [PATCH 036/119] chore: update query `EpochInfo` to return `EpochResponse` instead of Epoch (#532) * chore: update query EpochInfo to return EpochResponse instead of Epoch * chore: update query EpochsInfo to return EpochResponse instead of Epoch --- client/docs/swagger-ui/swagger.yaml | 166 ++++--- proto/babylon/epoching/v1/query.proto | 34 +- x/epoching/keeper/grpc_query.go | 18 +- x/epoching/types/query.go | 16 + x/epoching/types/query.pb.go | 617 +++++++++++++++++++++++--- 5 files changed, 703 insertions(+), 148 deletions(-) create mode 100644 x/epoching/types/query.go diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index a2eddc8ec..cdb03b943 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -1648,35 +1648,35 @@ paths: epoch's beginning, and is set upon the end of this epoch. - app_hash_root: + app_hash_root_hex: type: string - format: byte - title: >- + description: >- app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch - sealer_app_hash: + It will be used for proving a block is in an epoch as + hex string. + sealer_app_hash_hex: type: string - format: byte - title: >- + description: >- sealer is the last block of the sealed epoch sealer_app_hash points to the sealer but stored in the 1st header - of the next epoch + of the next epoch as hex string. sealer_block_hash: type: string - format: byte - title: >- + description: >- sealer_block_hash is the hash of the sealer the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch - title: Epoch is a structure that contains the metadata of an epoch + i.e., hash of the last block in the epoch as hex string. + title: >- + EpochResponse is a structure that contains the metadata of + an epoch pagination: title: pagination defines the pagination in the response type: object @@ -2008,35 +2008,35 @@ paths: beginning, and is set upon the end of this epoch. - app_hash_root: + app_hash_root_hex: type: string - format: byte - title: >- + description: >- app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch - sealer_app_hash: + It will be used for proving a block is in an epoch as hex + string. + sealer_app_hash_hex: type: string - format: byte - title: >- + description: >- sealer is the last block of the sealed epoch sealer_app_hash points to the sealer but stored in the 1st header - of the next epoch + of the next epoch as hex string. sealer_block_hash: type: string - format: byte - title: >- + description: >- sealer_block_hash is the hash of the sealer the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch - title: Epoch is a structure that contains the metadata of an epoch + i.e., hash of the last block in the epoch as hex string. + title: >- + EpochResponse is a structure that contains the metadata of an + epoch title: >- QueryEpochInfoRequest is the response type for the Query/EpochInfo method @@ -10673,7 +10673,7 @@ definitions: title: |- DelegationStateUpdate is the message that records a state update of a delegation - babylon.epoching.v1.Epoch: + babylon.epoching.v1.EpochResponse: type: object properties: epoch_number: @@ -10703,27 +10703,24 @@ definitions: and is set upon the end of this epoch. - app_hash_root: + app_hash_root_hex: type: string - format: byte - title: |- + description: |- app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch - sealer_app_hash: + It will be used for proving a block is in an epoch as hex string. + sealer_app_hash_hex: type: string - format: byte - title: |- + description: |- sealer is the last block of the sealed epoch sealer_app_hash points to the sealer but stored in the 1st header - of the next epoch + of the next epoch as hex string. sealer_block_hash: type: string - format: byte - title: |- + description: |- sealer_block_hash is the hash of the sealer the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch - title: Epoch is a structure that contains the metadata of an epoch + i.e., hash of the last block in the epoch as hex string. + title: EpochResponse is a structure that contains the metadata of an epoch babylon.epoching.v1.Params: type: object properties: @@ -10848,27 +10845,24 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root: + app_hash_root_hex: type: string - format: byte - title: |- + description: |- app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch - sealer_app_hash: + It will be used for proving a block is in an epoch as hex string. + sealer_app_hash_hex: type: string - format: byte - title: |- + description: |- sealer is the last block of the sealed epoch sealer_app_hash points to the sealer but stored in the 1st header - of the next epoch + of the next epoch as hex string. sealer_block_hash: type: string - format: byte - title: |- + description: |- sealer_block_hash is the hash of the sealer the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch - title: Epoch is a structure that contains the metadata of an epoch + i.e., hash of the last block in the epoch as hex string. + title: EpochResponse is a structure that contains the metadata of an epoch title: QueryEpochInfoRequest is the response type for the Query/EpochInfo method babylon.epoching.v1.QueryEpochMsgsResponse: type: object @@ -11403,30 +11397,29 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root: + app_hash_root_hex: type: string - format: byte - title: |- + description: >- app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch - sealer_app_hash: + + It will be used for proving a block is in an epoch as hex + string. + sealer_app_hash_hex: type: string - format: byte - title: >- + description: >- sealer is the last block of the sealed epoch sealer_app_hash points to the sealer but stored in the 1st header - of the next epoch + of the next epoch as hex string. sealer_block_hash: type: string - format: byte - title: |- + description: |- sealer_block_hash is the hash of the sealer the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch - title: Epoch is a structure that contains the metadata of an epoch + i.e., hash of the last block in the epoch as hex string. + title: EpochResponse is a structure that contains the metadata of an epoch pagination: title: pagination defines the pagination in the response type: object @@ -14140,6 +14133,57 @@ definitions: sigs title: RawCheckpoint wraps the BLS multi sig with metadata + babylon.epoching.v1.Epoch: + type: object + properties: + epoch_number: + type: string + format: uint64 + title: epoch_number is the number of this epoch + current_epoch_interval: + type: string + format: uint64 + title: current_epoch_interval is the epoch interval at the time of this epoch + first_block_height: + type: string + format: uint64 + title: first_block_height is the height of the first block in this epoch + last_block_time: + type: string + format: date-time + description: >- + last_block_time is the time of the last block in this epoch. + + Babylon needs to remember the last header's time of each epoch to + complete + + unbonding validators/delegations when a previous epoch's checkpoint is + + finalised. The last_block_time field is nil in the epoch's beginning, + and + + is set upon the end of this epoch. + app_hash_root: + type: string + format: byte + title: |- + app_hash_root is the Merkle root of all AppHashs in this epoch + It will be used for proving a block is in an epoch + sealer_app_hash: + type: string + format: byte + title: |- + sealer is the last block of the sealed epoch + sealer_app_hash points to the sealer but stored in the 1st header + of the next epoch + sealer_block_hash: + type: string + format: byte + title: |- + sealer_block_hash is the hash of the sealer + the validator set has generated a BLS multisig on the hash, + i.e., hash of the last block in the epoch + title: Epoch is a structure that contains the metadata of an epoch babylon.zoneconcierge.v1.ChainInfo: type: object properties: diff --git a/proto/babylon/epoching/v1/query.proto b/proto/babylon/epoching/v1/query.proto index f78acae35..a46e36289 100644 --- a/proto/babylon/epoching/v1/query.proto +++ b/proto/babylon/epoching/v1/query.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package babylon.epoching.v1; import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/epoching/v1/params.proto"; @@ -82,7 +83,7 @@ message QueryParamsResponse { message QueryEpochInfoRequest { uint64 epoch_num = 1; } // QueryEpochInfoRequest is the response type for the Query/EpochInfo method -message QueryEpochInfoResponse { babylon.epoching.v1.Epoch epoch = 1; } +message QueryEpochInfoResponse { EpochResponse epoch = 1; } // QueryEpochInfosRequest is the request type for the Query/EpochInfos method message QueryEpochsInfoRequest { @@ -92,7 +93,7 @@ message QueryEpochsInfoRequest { // QueryEpochsInfoResponse is the response type for the Query/EpochInfos method message QueryEpochsInfoResponse { - repeated babylon.epoching.v1.Epoch epochs = 1; + repeated EpochResponse epochs = 1; // pagination defines the pagination in the response cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -180,4 +181,31 @@ message QueryEpochValSetResponse { repeated babylon.epoching.v1.Validator validators = 1; int64 total_voting_power = 2; cosmos.base.query.v1beta1.PageResponse pagination = 3; -} \ No newline at end of file +} + +// EpochResponse is a structure that contains the metadata of an epoch +message EpochResponse { + // epoch_number is the number of this epoch + uint64 epoch_number = 1; + // current_epoch_interval is the epoch interval at the time of this epoch + uint64 current_epoch_interval = 2; + // first_block_height is the height of the first block in this epoch + uint64 first_block_height = 3; + // last_block_time is the time of the last block in this epoch. + // Babylon needs to remember the last header's time of each epoch to complete + // unbonding validators/delegations when a previous epoch's checkpoint is + // finalised. The last_block_time field is nil in the epoch's beginning, and + // is set upon the end of this epoch. + google.protobuf.Timestamp last_block_time = 4 [ (gogoproto.stdtime) = true ]; + // app_hash_root is the Merkle root of all AppHashs in this epoch + // It will be used for proving a block is in an epoch as hex string. + string app_hash_root_hex = 5; + // sealer is the last block of the sealed epoch + // sealer_app_hash points to the sealer but stored in the 1st header + // of the next epoch as hex string. + string sealer_app_hash_hex = 6; + // sealer_block_hash is the hash of the sealer + // the validator set has generated a BLS multisig on the hash, + // i.e., hash of the last block in the epoch as hex string. + string sealer_block_hash = 7; +} diff --git a/x/epoching/keeper/grpc_query.go b/x/epoching/keeper/grpc_query.go index dfd8f8447..80bc62dda 100644 --- a/x/epoching/keeper/grpc_query.go +++ b/x/epoching/keeper/grpc_query.go @@ -49,10 +49,10 @@ func (k Keeper) EpochInfo(c context.Context, req *types.QueryEpochInfoRequest) ( if err != nil { return nil, err } - resp := &types.QueryEpochInfoResponse{ - Epoch: epoch, - } - return resp, nil + + return &types.QueryEpochInfoResponse{ + Epoch: epoch.ToResponse(), + }, nil } // EpochsInfo handles the QueryEpochsInfoRequest query @@ -60,7 +60,7 @@ func (k Keeper) EpochsInfo(c context.Context, req *types.QueryEpochsInfoRequest) ctx := sdk.UnwrapSDKContext(c) epochInfoStore := k.epochInfoStore(ctx) - epochs := []*types.Epoch{} + epochs := []*types.EpochResponse{} pageRes, err := query.Paginate(epochInfoStore, req.Pagination, func(key, value []byte) error { // unmarshal to epoch metadata var epoch types.Epoch @@ -68,19 +68,17 @@ func (k Keeper) EpochsInfo(c context.Context, req *types.QueryEpochsInfoRequest) return err } // append to epochs list - epochs = append(epochs, &epoch) + epochs = append(epochs, epoch.ToResponse()) return nil }) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - resp := &types.QueryEpochsInfoResponse{ + return &types.QueryEpochsInfoResponse{ Epochs: epochs, Pagination: pageRes, - } - - return resp, nil + }, nil } // EpochMsgs handles the QueryEpochMsgsRequest query diff --git a/x/epoching/types/query.go b/x/epoching/types/query.go new file mode 100644 index 000000000..17fb5db34 --- /dev/null +++ b/x/epoching/types/query.go @@ -0,0 +1,16 @@ +package types + +import "encoding/hex" + +// ToResponse parses a Epoch into a query response epoch struct. +func (e *Epoch) ToResponse() *EpochResponse { + return &EpochResponse{ + EpochNumber: e.EpochNumber, + CurrentEpochInterval: e.CurrentEpochInterval, + FirstBlockHeight: e.FirstBlockHeight, + LastBlockTime: e.LastBlockTime, + AppHashRootHex: hex.EncodeToString(e.AppHashRoot), + SealerAppHashHex: hex.EncodeToString(e.SealerAppHash), + SealerBlockHash: hex.EncodeToString(e.SealerBlockHash), + } +} diff --git a/x/epoching/types/query.pb.go b/x/epoching/types/query.pb.go index 59bfc31b9..3f3024660 100644 --- a/x/epoching/types/query.pb.go +++ b/x/epoching/types/query.pb.go @@ -10,19 +10,23 @@ import ( _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -160,7 +164,7 @@ func (m *QueryEpochInfoRequest) GetEpochNum() uint64 { // QueryEpochInfoRequest is the response type for the Query/EpochInfo method type QueryEpochInfoResponse struct { - Epoch *Epoch `protobuf:"bytes,1,opt,name=epoch,proto3" json:"epoch,omitempty"` + Epoch *EpochResponse `protobuf:"bytes,1,opt,name=epoch,proto3" json:"epoch,omitempty"` } func (m *QueryEpochInfoResponse) Reset() { *m = QueryEpochInfoResponse{} } @@ -196,7 +200,7 @@ func (m *QueryEpochInfoResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryEpochInfoResponse proto.InternalMessageInfo -func (m *QueryEpochInfoResponse) GetEpoch() *Epoch { +func (m *QueryEpochInfoResponse) GetEpoch() *EpochResponse { if m != nil { return m.Epoch } @@ -251,7 +255,7 @@ func (m *QueryEpochsInfoRequest) GetPagination() *query.PageRequest { // QueryEpochsInfoResponse is the response type for the Query/EpochInfos method type QueryEpochsInfoResponse struct { - Epochs []*Epoch `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs,omitempty"` + Epochs []*EpochResponse `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs,omitempty"` // pagination defines the pagination in the response Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -289,7 +293,7 @@ func (m *QueryEpochsInfoResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryEpochsInfoResponse proto.InternalMessageInfo -func (m *QueryEpochsInfoResponse) GetEpochs() []*Epoch { +func (m *QueryEpochsInfoResponse) GetEpochs() []*EpochResponse { if m != nil { return m.Epochs } @@ -929,6 +933,115 @@ func (m *QueryEpochValSetResponse) GetPagination() *query.PageResponse { return nil } +// EpochResponse is a structure that contains the metadata of an epoch +type EpochResponse struct { + // epoch_number is the number of this epoch + EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` + // current_epoch_interval is the epoch interval at the time of this epoch + CurrentEpochInterval uint64 `protobuf:"varint,2,opt,name=current_epoch_interval,json=currentEpochInterval,proto3" json:"current_epoch_interval,omitempty"` + // first_block_height is the height of the first block in this epoch + FirstBlockHeight uint64 `protobuf:"varint,3,opt,name=first_block_height,json=firstBlockHeight,proto3" json:"first_block_height,omitempty"` + // last_block_time is the time of the last block in this epoch. + // Babylon needs to remember the last header's time of each epoch to complete + // unbonding validators/delegations when a previous epoch's checkpoint is + // finalised. The last_block_time field is nil in the epoch's beginning, and + // is set upon the end of this epoch. + LastBlockTime *time.Time `protobuf:"bytes,4,opt,name=last_block_time,json=lastBlockTime,proto3,stdtime" json:"last_block_time,omitempty"` + // app_hash_root is the Merkle root of all AppHashs in this epoch + // It will be used for proving a block is in an epoch as hex string. + AppHashRootHex string `protobuf:"bytes,5,opt,name=app_hash_root_hex,json=appHashRootHex,proto3" json:"app_hash_root_hex,omitempty"` + // sealer is the last block of the sealed epoch + // sealer_app_hash points to the sealer but stored in the 1st header + // of the next epoch as hex string. + SealerAppHashHex string `protobuf:"bytes,6,opt,name=sealer_app_hash_hex,json=sealerAppHashHex,proto3" json:"sealer_app_hash_hex,omitempty"` + // sealer_block_hash is the hash of the sealer + // the validator set has generated a BLS multisig on the hash, + // i.e., hash of the last block in the epoch as hex string. + SealerBlockHash string `protobuf:"bytes,7,opt,name=sealer_block_hash,json=sealerBlockHash,proto3" json:"sealer_block_hash,omitempty"` +} + +func (m *EpochResponse) Reset() { *m = EpochResponse{} } +func (m *EpochResponse) String() string { return proto.CompactTextString(m) } +func (*EpochResponse) ProtoMessage() {} +func (*EpochResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1821b530f2ec2711, []int{18} +} +func (m *EpochResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EpochResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EpochResponse.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 *EpochResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_EpochResponse.Merge(m, src) +} +func (m *EpochResponse) XXX_Size() int { + return m.Size() +} +func (m *EpochResponse) XXX_DiscardUnknown() { + xxx_messageInfo_EpochResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_EpochResponse proto.InternalMessageInfo + +func (m *EpochResponse) GetEpochNumber() uint64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +func (m *EpochResponse) GetCurrentEpochInterval() uint64 { + if m != nil { + return m.CurrentEpochInterval + } + return 0 +} + +func (m *EpochResponse) GetFirstBlockHeight() uint64 { + if m != nil { + return m.FirstBlockHeight + } + return 0 +} + +func (m *EpochResponse) GetLastBlockTime() *time.Time { + if m != nil { + return m.LastBlockTime + } + return nil +} + +func (m *EpochResponse) GetAppHashRootHex() string { + if m != nil { + return m.AppHashRootHex + } + return "" +} + +func (m *EpochResponse) GetSealerAppHashHex() string { + if m != nil { + return m.SealerAppHashHex + } + return "" +} + +func (m *EpochResponse) GetSealerBlockHash() string { + if m != nil { + return m.SealerBlockHash + } + return "" +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.epoching.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.epoching.v1.QueryParamsResponse") @@ -948,79 +1061,93 @@ func init() { proto.RegisterType((*QueryDelegationLifecycleResponse)(nil), "babylon.epoching.v1.QueryDelegationLifecycleResponse") proto.RegisterType((*QueryEpochValSetRequest)(nil), "babylon.epoching.v1.QueryEpochValSetRequest") proto.RegisterType((*QueryEpochValSetResponse)(nil), "babylon.epoching.v1.QueryEpochValSetResponse") + proto.RegisterType((*EpochResponse)(nil), "babylon.epoching.v1.EpochResponse") } func init() { proto.RegisterFile("babylon/epoching/v1/query.proto", fileDescriptor_1821b530f2ec2711) } var fileDescriptor_1821b530f2ec2711 = []byte{ - // 1071 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x97, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xc7, 0xb3, 0x89, 0x1b, 0x92, 0x97, 0x96, 0xc2, 0xa4, 0x40, 0xbb, 0x29, 0x4e, 0xb4, 0x85, - 0x26, 0x24, 0xcd, 0x6e, 0x9c, 0xa4, 0x45, 0xfd, 0x01, 0x88, 0x84, 0x1f, 0xa2, 0x4a, 0x51, 0xba, - 0x48, 0x39, 0x70, 0x31, 0x63, 0xef, 0x64, 0xb3, 0xd2, 0x7a, 0xc7, 0xdd, 0x1f, 0x06, 0xab, 0x04, - 0x21, 0xce, 0x1c, 0x90, 0x90, 0x40, 0xbd, 0x21, 0x71, 0xe4, 0x4f, 0x80, 0x03, 0xc7, 0x1e, 0x83, - 0xb8, 0x70, 0x42, 0x28, 0xe1, 0x0f, 0x41, 0xfb, 0x66, 0xd6, 0x5e, 0xbb, 0xb3, 0xb1, 0x13, 0x45, - 0xdc, 0xda, 0x99, 0xf7, 0xe3, 0xf3, 0xde, 0x9b, 0x7d, 0x5f, 0x07, 0x66, 0x6b, 0xb4, 0xd6, 0xf6, - 0x79, 0x60, 0xb1, 0x26, 0xaf, 0xef, 0x79, 0x81, 0x6b, 0xb5, 0x2a, 0xd6, 0xa3, 0x84, 0x85, 0x6d, - 0xb3, 0x19, 0xf2, 0x98, 0x93, 0x69, 0x69, 0x60, 0x66, 0x06, 0x66, 0xab, 0xa2, 0x5f, 0x72, 0xb9, - 0xcb, 0xf1, 0xde, 0x4a, 0xff, 0x25, 0x4c, 0xf5, 0xab, 0x2e, 0xe7, 0xae, 0xcf, 0x2c, 0xda, 0xf4, - 0x2c, 0x1a, 0x04, 0x3c, 0xa6, 0xb1, 0xc7, 0x83, 0x48, 0xde, 0x2e, 0xd6, 0x79, 0xd4, 0xe0, 0x91, - 0x55, 0xa3, 0x11, 0x13, 0x19, 0xac, 0x56, 0xa5, 0xc6, 0x62, 0x5a, 0xb1, 0x9a, 0xd4, 0xf5, 0x02, - 0x34, 0x96, 0xb6, 0x73, 0x2a, 0xaa, 0x26, 0x0d, 0x69, 0x23, 0x8b, 0x66, 0xa8, 0x2c, 0x3a, 0x88, - 0x68, 0x63, 0x5c, 0x02, 0xf2, 0x30, 0xcd, 0xb3, 0x8d, 0x8e, 0x36, 0x7b, 0x94, 0xb0, 0x28, 0x36, - 0xb6, 0x61, 0xba, 0xe7, 0x34, 0x6a, 0xf2, 0x20, 0x62, 0xe4, 0x36, 0x8c, 0x8b, 0x04, 0x97, 0xb5, - 0x39, 0x6d, 0x61, 0x6a, 0x75, 0xc6, 0x54, 0x14, 0x6e, 0x0a, 0xa7, 0x8d, 0xd2, 0xd3, 0xbf, 0x67, - 0x47, 0x6c, 0xe9, 0x60, 0xac, 0xc3, 0x4b, 0x18, 0xf1, 0xfd, 0xd4, 0xf0, 0xa3, 0x60, 0x97, 0xcb, - 0x54, 0x64, 0x06, 0x26, 0xd1, 0xb9, 0x1a, 0x24, 0x0d, 0x0c, 0x5b, 0xb2, 0x27, 0xf0, 0xe0, 0xe3, - 0xa4, 0x61, 0xdc, 0x87, 0x97, 0xfb, 0xbd, 0x24, 0xca, 0x0a, 0x9c, 0x43, 0x2b, 0x49, 0xa2, 0x2b, - 0x49, 0xd0, 0xcd, 0x16, 0x86, 0xc6, 0x67, 0xf9, 0x58, 0x51, 0x1e, 0xe1, 0x03, 0x80, 0x6e, 0x77, - 0x65, 0xc0, 0xeb, 0xa6, 0x18, 0x85, 0x99, 0x8e, 0xc2, 0x14, 0xc3, 0x96, 0xa3, 0x30, 0xb7, 0xa9, - 0xcb, 0xa4, 0xaf, 0x9d, 0xf3, 0x34, 0x7e, 0xd0, 0xe0, 0x95, 0x67, 0x52, 0x48, 0xde, 0x55, 0x18, - 0x47, 0x8c, 0xb4, 0x75, 0x63, 0x03, 0x80, 0xa5, 0x25, 0xf9, 0xb0, 0x87, 0x6b, 0x14, 0xb9, 0xe6, - 0x07, 0x72, 0x89, 0x84, 0x3d, 0x60, 0x3a, 0x5c, 0x46, 0xae, 0xcd, 0x24, 0x0c, 0x59, 0x10, 0x8b, - 0x2c, 0x72, 0xd4, 0x2e, 0x5c, 0x51, 0xdc, 0x49, 0xea, 0x6b, 0x70, 0xa1, 0x2e, 0xce, 0xab, 0xdd, - 0x6e, 0x97, 0xec, 0xf3, 0xf5, 0x9c, 0x31, 0x79, 0x1d, 0x9e, 0x17, 0x13, 0xac, 0xf1, 0x24, 0x70, - 0x68, 0xd8, 0x46, 0xd4, 0x92, 0x7d, 0x01, 0x4f, 0x37, 0xe4, 0xa1, 0xf1, 0x65, 0xfe, 0x05, 0x3c, - 0x88, 0xdc, 0x68, 0x98, 0x17, 0xd0, 0x37, 0x9b, 0xd1, 0x53, 0xcf, 0xe6, 0x89, 0x96, 0x1f, 0xbf, - 0x48, 0x2f, 0x8b, 0xbc, 0x05, 0xa5, 0x46, 0xe4, 0x66, 0x83, 0x31, 0x94, 0x83, 0x79, 0x98, 0xb0, - 0x84, 0x39, 0x0f, 0x58, 0x14, 0xa5, 0xf1, 0xd1, 0xfe, 0xec, 0xc6, 0xf3, 0xb3, 0x06, 0x33, 0xc8, - 0xb6, 0x45, 0x63, 0x16, 0xc5, 0xca, 0x06, 0x05, 0x4e, 0xcf, 0x04, 0x26, 0x58, 0xe0, 0x88, 0xee, - 0xcf, 0xc2, 0x94, 0xe8, 0x5e, 0x9d, 0x27, 0x41, 0x2c, 0x5b, 0x0f, 0x78, 0xb4, 0x99, 0x9e, 0xf4, - 0x75, 0x70, 0xec, 0xd4, 0x1d, 0xfc, 0x55, 0x83, 0xab, 0x6a, 0x4a, 0xd9, 0x47, 0x1b, 0x5e, 0xf4, - 0xf1, 0x4a, 0x90, 0x56, 0x73, 0x4d, 0xbd, 0x3e, 0xb8, 0xa9, 0x5b, 0x5e, 0x14, 0xdb, 0x17, 0xfd, - 0xde, 0xd8, 0x67, 0xd7, 0xe3, 0xbb, 0x50, 0x46, 0xf8, 0x1d, 0xea, 0x7b, 0x0e, 0x8d, 0x79, 0xb8, - 0xe5, 0xed, 0xb2, 0x7a, 0xbb, 0xee, 0x67, 0xb5, 0x92, 0x2b, 0x30, 0xd1, 0xa2, 0x7e, 0x95, 0x3a, - 0x4e, 0x88, 0x4d, 0x9e, 0xb4, 0x9f, 0x6b, 0x51, 0xff, 0x5d, 0xc7, 0x09, 0x0d, 0x06, 0xb3, 0x85, - 0xce, 0xb2, 0xf8, 0x0d, 0xe1, 0xed, 0x7b, 0xbb, 0x4c, 0x6e, 0x90, 0x79, 0x65, 0xcd, 0x8a, 0x10, - 0x69, 0x9a, 0xf4, 0x7f, 0xc6, 0x3d, 0x99, 0xe6, 0x3d, 0xe6, 0x33, 0x17, 0xb1, 0x55, 0x90, 0x0e, - 0xeb, 0x85, 0x74, 0x98, 0x80, 0x74, 0x61, 0xae, 0xd8, 0x5b, 0x52, 0x6e, 0x0a, 0xf7, 0x1c, 0xe5, - 0x82, 0x92, 0x52, 0x15, 0x23, 0x4d, 0x84, 0x98, 0x5f, 0xe5, 0xb7, 0xdc, 0x0e, 0xf5, 0x3f, 0x61, - 0xf1, 0xff, 0xfa, 0x29, 0xff, 0xa1, 0xc9, 0x75, 0xd6, 0x03, 0x20, 0x2b, 0x7c, 0x1b, 0xa0, 0x95, - 0xb5, 0x38, 0x7b, 0x7d, 0xe5, 0xe3, 0x27, 0x61, 0xe7, 0x3c, 0xc8, 0x0d, 0x20, 0x31, 0x8f, 0xa9, - 0x5f, 0x6d, 0xf1, 0xd8, 0x0b, 0xdc, 0x6a, 0x93, 0x7f, 0xce, 0x42, 0x84, 0x1d, 0xb3, 0x5f, 0xc0, - 0x9b, 0x1d, 0xbc, 0xd8, 0x4e, 0xcf, 0xfb, 0x9e, 0xe7, 0xd8, 0xa9, 0x9f, 0xe7, 0xea, 0xc1, 0x14, - 0x9c, 0xc3, 0x9a, 0xc8, 0xd7, 0x1a, 0x8c, 0x0b, 0x05, 0x25, 0xf3, 0x45, 0x5f, 0x4d, 0x9f, 0x5c, - 0xeb, 0x0b, 0x83, 0x0d, 0x45, 0x4e, 0xe3, 0xda, 0x37, 0x7f, 0xfe, 0xfb, 0xfd, 0xe8, 0xab, 0x64, - 0xc6, 0x2a, 0xfe, 0xf5, 0x40, 0x7e, 0xd4, 0x60, 0xb2, 0xa3, 0xb8, 0x64, 0xb1, 0x38, 0x78, 0xbf, - 0x98, 0xeb, 0x4b, 0x43, 0xd9, 0x4a, 0x96, 0x0a, 0xb2, 0x2c, 0x91, 0x37, 0xac, 0xc2, 0xdf, 0x29, - 0x91, 0xf5, 0xb8, 0xf3, 0x9e, 0xde, 0x5a, 0xdc, 0x27, 0xdf, 0x6a, 0x00, 0x5d, 0x71, 0x25, 0x83, - 0xd2, 0xe5, 0x55, 0x5e, 0xbf, 0x31, 0x9c, 0xf1, 0x50, 0x8d, 0x92, 0x02, 0xfd, 0x44, 0x83, 0xf3, - 0x79, 0xdd, 0x24, 0xcb, 0xc5, 0x39, 0x14, 0xda, 0xab, 0x9b, 0xc3, 0x9a, 0x4b, 0xa8, 0x45, 0x84, - 0x7a, 0x8d, 0x18, 0x4a, 0xa8, 0x1e, 0xa5, 0x26, 0x3f, 0x65, 0x43, 0xc4, 0x3d, 0x3a, 0x68, 0x88, - 0x39, 0xb9, 0x19, 0x38, 0xc4, 0xfc, 0xd2, 0x37, 0xee, 0x20, 0xd2, 0x3a, 0x59, 0x1d, 0x7a, 0x88, - 0x56, 0x43, 0x2c, 0xfc, 0x88, 0xfc, 0xa2, 0xc1, 0xc5, 0x3e, 0x31, 0x21, 0x2b, 0xc5, 0xc9, 0xd5, - 0xea, 0xa8, 0x57, 0x4e, 0xe0, 0x21, 0xa1, 0xd7, 0x10, 0x7a, 0x99, 0x2c, 0x1d, 0x03, 0x7d, 0x47, - 0x48, 0x51, 0x97, 0xf6, 0x37, 0x0d, 0xc8, 0xb3, 0xdb, 0x9b, 0xac, 0x15, 0xa7, 0x2f, 0xd4, 0x1a, - 0x7d, 0xfd, 0x64, 0x4e, 0x12, 0xfb, 0x2e, 0x62, 0xdf, 0x24, 0x6b, 0x4a, 0xec, 0xce, 0x12, 0xc3, - 0xf5, 0x8e, 0x9e, 0xd6, 0xe3, 0x4c, 0xd1, 0xf6, 0xc9, 0xef, 0x1a, 0x4c, 0x2b, 0xd6, 0x3a, 0x39, - 0x06, 0xa5, 0x58, 0x87, 0xf4, 0x9b, 0x27, 0xf4, 0x92, 0x15, 0xdc, 0xc3, 0x0a, 0x6e, 0x91, 0x75, - 0x65, 0x05, 0x4e, 0xc7, 0x33, 0x5f, 0x42, 0xa6, 0x77, 0xfb, 0xe9, 0x7b, 0x99, 0xca, 0xed, 0x7c, - 0x32, 0xe8, 0x8b, 0xee, 0xd1, 0x26, 0x7d, 0x79, 0x48, 0x6b, 0x89, 0xfa, 0x0e, 0xa2, 0xde, 0x26, - 0x6f, 0x0e, 0xff, 0xb0, 0xbb, 0x13, 0x88, 0x58, 0xbc, 0x71, 0xff, 0xe9, 0x61, 0x59, 0x3b, 0x38, - 0x2c, 0x6b, 0xff, 0x1c, 0x96, 0xb5, 0xef, 0x8e, 0xca, 0x23, 0x07, 0x47, 0xe5, 0x91, 0xbf, 0x8e, - 0xca, 0x23, 0x9f, 0xae, 0xb8, 0x5e, 0xbc, 0x97, 0xd4, 0xcc, 0x3a, 0x6f, 0x64, 0xc1, 0xeb, 0x7b, - 0xd4, 0x0b, 0x3a, 0x99, 0xbe, 0xe8, 0xe6, 0x8a, 0xdb, 0x4d, 0x16, 0xd5, 0xc6, 0xf1, 0x8f, 0xb5, - 0xb5, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x76, 0x01, 0x0c, 0x73, 0x8a, 0x0e, 0x00, 0x00, + // 1273 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6f, 0x1b, 0xc5, + 0x1b, 0xce, 0x26, 0x6e, 0xda, 0x4e, 0x9a, 0xa6, 0x9d, 0xf4, 0xd7, 0x5f, 0xba, 0x29, 0x76, 0xd9, + 0x42, 0x3f, 0xd2, 0x66, 0xb7, 0x6e, 0xd2, 0x42, 0x3f, 0x00, 0xd5, 0xe1, 0x23, 0x45, 0x29, 0x4a, + 0x17, 0x94, 0x03, 0x97, 0x65, 0xec, 0x9d, 0xac, 0x57, 0xac, 0x77, 0xb6, 0x3b, 0x63, 0x93, 0xa8, + 0x04, 0x21, 0xce, 0x1c, 0x2a, 0x71, 0x40, 0xbd, 0x20, 0x24, 0x8e, 0xfc, 0x09, 0x70, 0xe0, 0xd8, + 0x63, 0x10, 0x17, 0x4e, 0x80, 0x12, 0xc4, 0xdf, 0x81, 0xf6, 0x9d, 0x59, 0x7b, 0xed, 0xae, 0x63, + 0x27, 0xaa, 0xb8, 0xd9, 0x33, 0xcf, 0xf3, 0xbe, 0xcf, 0xfb, 0xb1, 0xf3, 0xbe, 0xa8, 0x54, 0x25, + 0xd5, 0xcd, 0x80, 0x85, 0x16, 0x8d, 0x58, 0xad, 0xee, 0x87, 0x9e, 0xd5, 0x2a, 0x5b, 0x8f, 0x9a, + 0x34, 0xde, 0x34, 0xa3, 0x98, 0x09, 0x86, 0xa7, 0x15, 0xc0, 0x4c, 0x01, 0x66, 0xab, 0xac, 0x9f, + 0xf2, 0x98, 0xc7, 0xe0, 0xde, 0x4a, 0x7e, 0x49, 0xa8, 0x5e, 0xf2, 0x18, 0xf3, 0x02, 0x6a, 0xc1, + 0xbf, 0x6a, 0x73, 0xdd, 0x12, 0x7e, 0x83, 0x72, 0x41, 0x1a, 0x91, 0x02, 0x9c, 0x55, 0x00, 0x12, + 0xf9, 0x16, 0x09, 0x43, 0x26, 0x88, 0xf0, 0x59, 0xc8, 0xd5, 0xed, 0x5c, 0x8d, 0xf1, 0x06, 0xe3, + 0x56, 0x95, 0x70, 0x2a, 0x25, 0x58, 0xad, 0x72, 0x95, 0x0a, 0x52, 0xb6, 0x22, 0xe2, 0xf9, 0x21, + 0x80, 0x15, 0xf6, 0x5c, 0x9e, 0xec, 0x88, 0xc4, 0xa4, 0x91, 0x5a, 0x33, 0xf2, 0x10, 0xed, 0x18, + 0x00, 0x63, 0x9c, 0x42, 0xf8, 0x61, 0xe2, 0x67, 0x15, 0x88, 0x36, 0x7d, 0xd4, 0xa4, 0x5c, 0x18, + 0xab, 0x68, 0xba, 0xeb, 0x94, 0x47, 0x2c, 0xe4, 0x14, 0xdf, 0x42, 0xe3, 0xd2, 0xc1, 0x8c, 0x76, + 0x4e, 0xbb, 0x34, 0x71, 0x7d, 0xd6, 0xcc, 0xc9, 0x8c, 0x29, 0x49, 0x95, 0xc2, 0xb3, 0x3f, 0x4a, + 0x23, 0xb6, 0x22, 0x18, 0x8b, 0xe8, 0x7f, 0x60, 0xf1, 0x9d, 0x04, 0x78, 0x3f, 0x5c, 0x67, 0xca, + 0x15, 0x9e, 0x45, 0x47, 0x81, 0xec, 0x84, 0xcd, 0x06, 0x98, 0x2d, 0xd8, 0x47, 0xe0, 0xe0, 0x83, + 0x66, 0xc3, 0xb0, 0xd1, 0xe9, 0x5e, 0x96, 0x92, 0xf2, 0x3a, 0x3a, 0x04, 0x28, 0xa5, 0xc4, 0xc8, + 0x55, 0x02, 0xb4, 0x94, 0x62, 0x4b, 0x82, 0xf1, 0x49, 0xd6, 0x26, 0xcf, 0x4a, 0x79, 0x17, 0xa1, + 0x4e, 0x96, 0x95, 0xe1, 0x0b, 0xa6, 0x2c, 0x89, 0x99, 0x94, 0xc4, 0x94, 0x5d, 0xa1, 0x4a, 0x62, + 0xae, 0x12, 0x8f, 0x2a, 0xae, 0x9d, 0x61, 0x1a, 0xdf, 0x69, 0xe8, 0xff, 0xcf, 0xb9, 0x50, 0xba, + 0x6f, 0xa3, 0x71, 0x90, 0x91, 0xa4, 0x70, 0x6c, 0x48, 0xe1, 0x8a, 0x81, 0xdf, 0xeb, 0xd2, 0x37, + 0x0a, 0xfa, 0x2e, 0x0e, 0xd4, 0xa7, 0x8c, 0x64, 0x05, 0xea, 0x68, 0x06, 0xf4, 0x2d, 0x35, 0xe3, + 0x98, 0x86, 0x42, 0x79, 0x93, 0xa5, 0xf7, 0xd0, 0x99, 0x9c, 0x3b, 0xa5, 0xfe, 0x3c, 0x9a, 0xac, + 0xc9, 0x73, 0xa7, 0x93, 0xfd, 0x82, 0x7d, 0xac, 0x96, 0x01, 0xe3, 0x57, 0xd1, 0x71, 0x59, 0xd1, + 0x2a, 0x6b, 0x86, 0x2e, 0x89, 0x37, 0x41, 0x6a, 0xc1, 0x9e, 0x84, 0xd3, 0x8a, 0x3a, 0x34, 0x3e, + 0xcf, 0x76, 0xc4, 0x03, 0xee, 0xf1, 0x61, 0x3a, 0xa2, 0xa7, 0x46, 0xa3, 0x07, 0xae, 0xd1, 0x53, + 0x2d, 0xdb, 0x06, 0xd2, 0xbd, 0x0a, 0xf2, 0x26, 0x2a, 0x34, 0xb8, 0xb7, 0x77, 0x81, 0x1e, 0x36, + 0x69, 0x93, 0xba, 0x0f, 0x28, 0xe7, 0x89, 0x7d, 0xc0, 0xbf, 0xb8, 0xf2, 0xfc, 0xa0, 0xa1, 0x59, + 0xd0, 0xb6, 0x42, 0x04, 0xe5, 0x22, 0x37, 0x41, 0xa1, 0xdb, 0x55, 0x81, 0x23, 0x34, 0x74, 0x65, + 0xf6, 0x4b, 0x68, 0x42, 0x66, 0xaf, 0xc6, 0x9a, 0xa1, 0x50, 0xa9, 0x47, 0x70, 0xb4, 0x94, 0x9c, + 0xf4, 0x64, 0x70, 0xec, 0xc0, 0x19, 0xfc, 0x49, 0x43, 0x67, 0xf3, 0x55, 0xaa, 0x3c, 0xda, 0xe8, + 0x64, 0x00, 0x57, 0x52, 0xa9, 0x93, 0x49, 0xea, 0x85, 0xc1, 0x49, 0x5d, 0xf1, 0xb9, 0xb0, 0xa7, + 0x82, 0x6e, 0xdb, 0x2f, 0x2e, 0xc7, 0x77, 0x50, 0x11, 0xc4, 0xaf, 0x91, 0xc0, 0x77, 0x89, 0x60, + 0xf1, 0x8a, 0xbf, 0x4e, 0x6b, 0x9b, 0xb5, 0x20, 0x8d, 0x15, 0x9f, 0x41, 0x47, 0x5a, 0x24, 0x70, + 0x88, 0xeb, 0xc6, 0x90, 0xe4, 0xa3, 0xf6, 0xe1, 0x16, 0x09, 0xee, 0xb9, 0x6e, 0x6c, 0x50, 0x54, + 0xea, 0x4b, 0x56, 0xc1, 0x57, 0x24, 0x3b, 0xf0, 0xd7, 0xa9, 0x7a, 0x49, 0x2e, 0xe6, 0xc6, 0x9c, + 0x63, 0x22, 0x71, 0x93, 0xfc, 0x33, 0xee, 0x2a, 0x37, 0x6f, 0xd3, 0x80, 0x7a, 0x20, 0x3b, 0x4f, + 0xa4, 0x4b, 0xbb, 0x45, 0xba, 0x54, 0x8a, 0xf4, 0xd0, 0xb9, 0xfe, 0x6c, 0xa5, 0x72, 0x49, 0xd2, + 0x33, 0x2a, 0x2f, 0xe5, 0xaa, 0xcc, 0xb3, 0x91, 0x38, 0x02, 0x99, 0x5f, 0x64, 0x5f, 0xbb, 0x35, + 0x12, 0x7c, 0x48, 0xc5, 0x7f, 0xfa, 0x29, 0xff, 0xaa, 0xa9, 0xe7, 0xac, 0x4b, 0x80, 0x8a, 0xf0, + 0x4d, 0x84, 0x5a, 0x69, 0x8a, 0xd3, 0xee, 0x2b, 0xee, 0x5d, 0x09, 0x3b, 0xc3, 0xc0, 0x57, 0x11, + 0x16, 0x4c, 0x90, 0xc0, 0x69, 0x31, 0xe1, 0x87, 0x9e, 0x13, 0xb1, 0xcf, 0x68, 0x0c, 0x62, 0xc7, + 0xec, 0x13, 0x70, 0xb3, 0x06, 0x17, 0xab, 0xc9, 0x79, 0x4f, 0x7b, 0x8e, 0x1d, 0xbc, 0x3d, 0xff, + 0x19, 0x45, 0x93, 0xdd, 0x4f, 0xef, 0xcb, 0xe8, 0x58, 0x3b, 0x95, 0x55, 0x1a, 0xab, 0x6c, 0x4e, + 0xa4, 0xd9, 0xac, 0xd2, 0x18, 0x2f, 0xa2, 0xd3, 0x5d, 0xaf, 0xb3, 0xe3, 0x87, 0x82, 0xc6, 0x2d, + 0x12, 0xa8, 0x57, 0xe0, 0x54, 0xf6, 0x99, 0xbe, 0xaf, 0xee, 0x92, 0x08, 0xd7, 0xfd, 0x98, 0x0b, + 0xa7, 0x1a, 0xb0, 0xda, 0xa7, 0x4e, 0x9d, 0xfa, 0x5e, 0x5d, 0x80, 0xf6, 0x82, 0x7d, 0x02, 0x6e, + 0x2a, 0xc9, 0xc5, 0x32, 0x9c, 0xe3, 0x65, 0x34, 0x15, 0x90, 0x36, 0x38, 0xd9, 0x6e, 0x66, 0x0a, + 0x10, 0xa6, 0x6e, 0xca, 0xcd, 0xc6, 0x4c, 0x57, 0x1f, 0xf3, 0xa3, 0x74, 0xf5, 0xa9, 0x14, 0x9e, + 0xfc, 0x59, 0xd2, 0xec, 0xc9, 0x84, 0x08, 0xb6, 0x92, 0x1b, 0x7c, 0x19, 0x9d, 0x24, 0x51, 0xe4, + 0xd4, 0x09, 0xaf, 0x3b, 0x31, 0x63, 0xc2, 0xa9, 0xd3, 0x8d, 0x99, 0x43, 0xd0, 0xc3, 0xc7, 0x49, + 0x14, 0x2d, 0x13, 0x5e, 0xb7, 0x19, 0x13, 0xcb, 0x74, 0x03, 0xcf, 0xa3, 0x69, 0x4e, 0x49, 0x40, + 0x63, 0xa7, 0xcd, 0x48, 0xc0, 0xe3, 0x00, 0x3e, 0x21, 0xaf, 0xee, 0x49, 0x4a, 0x02, 0x9f, 0x43, + 0x27, 0x15, 0x5c, 0x85, 0x44, 0x78, 0x7d, 0xe6, 0x30, 0x80, 0xa7, 0xe4, 0x85, 0x8c, 0x88, 0xf0, + 0xfa, 0xf5, 0xed, 0x09, 0x74, 0x08, 0x9a, 0x07, 0x7f, 0xa9, 0xa1, 0x71, 0xb9, 0xba, 0xe0, 0x8b, + 0xfd, 0x9e, 0xa7, 0x9e, 0x3d, 0x49, 0xbf, 0x34, 0x18, 0x28, 0xcb, 0x67, 0x9c, 0xff, 0xea, 0xb7, + 0xbf, 0xbf, 0x19, 0x7d, 0x09, 0xcf, 0x5a, 0xfd, 0xd7, 0x36, 0xfc, 0xad, 0x86, 0x8e, 0xb6, 0x57, + 0x1d, 0x3c, 0xd7, 0xdf, 0x78, 0xef, 0x16, 0xa5, 0x5f, 0x19, 0x0a, 0xab, 0xb4, 0x94, 0x41, 0xcb, + 0x15, 0x7c, 0xd9, 0xea, 0xbb, 0x20, 0x72, 0xeb, 0x71, 0xbb, 0xdb, 0xde, 0x98, 0xdb, 0xc2, 0x5f, + 0x6b, 0x08, 0x75, 0xb6, 0x19, 0x3c, 0xc8, 0x5d, 0x76, 0xad, 0xd2, 0xaf, 0x0e, 0x07, 0x1e, 0x2a, + 0x51, 0x6a, 0x13, 0x7a, 0xaa, 0xa1, 0x63, 0xd9, 0x05, 0x05, 0xcf, 0xf7, 0xf7, 0x91, 0xb3, 0xe4, + 0xe8, 0xe6, 0xb0, 0x70, 0x25, 0x6a, 0x0e, 0x44, 0xbd, 0x82, 0x8d, 0x5c, 0x51, 0x5d, 0x1f, 0x1d, + 0xfe, 0x3e, 0x2d, 0x22, 0x0c, 0xac, 0x41, 0x45, 0xcc, 0xcc, 0xf5, 0x81, 0x45, 0xcc, 0x4e, 0x57, + 0xe3, 0x36, 0x48, 0x5a, 0xc4, 0xd7, 0x87, 0x2e, 0xa2, 0xd5, 0x90, 0x93, 0x95, 0xe3, 0x1f, 0x35, + 0x34, 0xd5, 0x33, 0xb5, 0xf1, 0xb5, 0xfe, 0xce, 0xf3, 0xd7, 0x10, 0xbd, 0xbc, 0x0f, 0x86, 0x12, + 0xbd, 0x00, 0xa2, 0xe7, 0xf1, 0x95, 0x3d, 0x44, 0xdf, 0x96, 0x33, 0xbf, 0xa3, 0xf6, 0x67, 0x0d, + 0xe1, 0xe7, 0xc7, 0x24, 0x5e, 0xe8, 0xef, 0xbe, 0xef, 0x50, 0xd7, 0x17, 0xf7, 0x47, 0x52, 0xb2, + 0xef, 0x80, 0xec, 0x1b, 0x78, 0x21, 0x57, 0x76, 0x7b, 0x5a, 0xc0, 0x1c, 0x05, 0xa6, 0xf5, 0x38, + 0x5d, 0x1d, 0xb6, 0xf0, 0x2f, 0x1a, 0x9a, 0xce, 0x99, 0x9f, 0x78, 0x0f, 0x29, 0xfd, 0x07, 0xbe, + 0x7e, 0x63, 0x9f, 0x2c, 0x15, 0xc1, 0x5d, 0x88, 0xe0, 0x26, 0x5e, 0xcc, 0x8d, 0xc0, 0x6d, 0x33, + 0xb3, 0x21, 0xa4, 0x8b, 0xc5, 0x56, 0xd2, 0x2f, 0x13, 0x99, 0xe1, 0x8a, 0x07, 0x7d, 0xd1, 0x5d, + 0x4b, 0x80, 0x3e, 0x3f, 0x24, 0x5a, 0x49, 0x7d, 0x0b, 0xa4, 0xde, 0xc2, 0xaf, 0x0d, 0xdf, 0xd8, + 0x9d, 0x0a, 0x70, 0x2a, 0x2a, 0xef, 0x3f, 0xdb, 0x29, 0x6a, 0xdb, 0x3b, 0x45, 0xed, 0xaf, 0x9d, + 0xa2, 0xf6, 0x64, 0xb7, 0x38, 0xb2, 0xbd, 0x5b, 0x1c, 0xf9, 0x7d, 0xb7, 0x38, 0xf2, 0xf1, 0x35, + 0xcf, 0x17, 0xf5, 0x66, 0xd5, 0xac, 0xb1, 0x46, 0x6a, 0xbc, 0x56, 0x27, 0x7e, 0xd8, 0xf6, 0xb4, + 0xd1, 0xf1, 0x25, 0x36, 0x23, 0xca, 0xab, 0xe3, 0x30, 0xcd, 0x16, 0xfe, 0x0d, 0x00, 0x00, 0xff, + 0xff, 0x4c, 0x28, 0x27, 0x93, 0x24, 0x10, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2081,6 +2208,75 @@ func (m *QueryEpochValSetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error return len(dAtA) - i, nil } +func (m *EpochResponse) 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 *EpochResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SealerBlockHash) > 0 { + i -= len(m.SealerBlockHash) + copy(dAtA[i:], m.SealerBlockHash) + i = encodeVarintQuery(dAtA, i, uint64(len(m.SealerBlockHash))) + i-- + dAtA[i] = 0x3a + } + if len(m.SealerAppHashHex) > 0 { + i -= len(m.SealerAppHashHex) + copy(dAtA[i:], m.SealerAppHashHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.SealerAppHashHex))) + i-- + dAtA[i] = 0x32 + } + if len(m.AppHashRootHex) > 0 { + i -= len(m.AppHashRootHex) + copy(dAtA[i:], m.AppHashRootHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AppHashRootHex))) + i-- + dAtA[i] = 0x2a + } + if m.LastBlockTime != nil { + n13, err13 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime):]) + if err13 != nil { + return 0, err13 + } + i -= n13 + i = encodeVarintQuery(dAtA, i, uint64(n13)) + i-- + dAtA[i] = 0x22 + } + if m.FirstBlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.FirstBlockHeight)) + i-- + dAtA[i] = 0x18 + } + if m.CurrentEpochInterval != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.CurrentEpochInterval)) + i-- + dAtA[i] = 0x10 + } + if m.EpochNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2356,6 +2552,40 @@ func (m *QueryEpochValSetResponse) Size() (n int) { return n } +func (m *EpochResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNumber != 0 { + n += 1 + sovQuery(uint64(m.EpochNumber)) + } + if m.CurrentEpochInterval != 0 { + n += 1 + sovQuery(uint64(m.CurrentEpochInterval)) + } + if m.FirstBlockHeight != 0 { + n += 1 + sovQuery(uint64(m.FirstBlockHeight)) + } + if m.LastBlockTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime) + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AppHashRootHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.SealerAppHashHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.SealerBlockHash) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -2623,7 +2853,7 @@ func (m *QueryEpochInfoResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Epoch == nil { - m.Epoch = &Epoch{} + m.Epoch = &EpochResponse{} } if err := m.Epoch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2794,7 +3024,7 @@ func (m *QueryEpochsInfoResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Epochs = append(m.Epochs, &Epoch{}) + m.Epochs = append(m.Epochs, &EpochResponse{}) if err := m.Epochs[len(m.Epochs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -4043,6 +4273,245 @@ func (m *QueryEpochValSetResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *EpochResponse) 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 ErrIntOverflowQuery + } + 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: EpochResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EpochResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochInterval", wireType) + } + m.CurrentEpochInterval = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentEpochInterval |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FirstBlockHeight", wireType) + } + m.FirstBlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FirstBlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastBlockTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.LastBlockTime == nil { + m.LastBlockTime = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.LastBlockTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AppHashRootHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AppHashRootHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SealerAppHashHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SealerAppHashHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SealerBlockHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SealerBlockHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 0445a7a819cd2ee76618191273d10fb865a102c7 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 6 Mar 2024 16:31:49 +0100 Subject: [PATCH 037/119] Fix conflits --- x/btcstaking/keeper/keeper.go | 2 +- x/btcstaking/types/incentive.go | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index ffb60b7b6..d239b4aff 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -9,7 +9,6 @@ import ( "cosmossdk.io/log" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -61,6 +60,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // the voting power distribution cache used for computing voting power table // and distributing rewards once the block is finalised by finality providers. func (k Keeper) BeginBlocker(ctx context.Context) error { + // index BTC height at the current height k.IndexBTCHeight(ctx) // update voting power distribution k.UpdatePowerDist(ctx) diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 47cce7b68..1f687ab16 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -100,14 +100,6 @@ func (v *FinalityProviderDistInfo) AddBTCDelDistInfo(d *BTCDelDistInfo) { v.TotalVotingPower += d.VotingPower } -func (v *FinalityProviderDistInfo) AddBTCDistInfo(info *BTCDelDistInfo) { - if info.VotingPower > 0 { - // if this BTC delegation has voting power, append it and accumulate voting power - v.BtcDels = append(v.BtcDels, info) - v.TotalVotingPower += info.VotingPower - } -} - // GetBTCDelPortion returns the portion of a BTC delegation's voting power out of // the finality provider's total voting power func (v *FinalityProviderDistInfo) GetBTCDelPortion(d *BTCDelDistInfo) sdkmath.LegacyDec { From 20d0fa1d38b3eee33a598dbf3e3e8315f12f6361 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 7 Mar 2024 08:07:51 -0300 Subject: [PATCH 038/119] chore: update query `EpochMsgs` to return `QueuedMessageResponse` (#533) * chore: update query `EpochMsgs` to return `QueuedMessageResponse` instead of `QueuedMessage` * chore: update query `LatestEpochMsgs` to return `QueuedMessageResponse` (#534) * chore: update query `LatestEpochMsgs` to return `QueuedMessageResponse` instead of `QueuedMessage` * chore: removed returned naming * fix: misspell block --- client/docs/swagger-ui/swagger.yaml | 3455 +++------------------- proto/babylon/epoching/v1/epoching.proto | 7 - proto/babylon/epoching/v1/query.proto | 29 +- x/epoching/keeper/grpc_query.go | 13 +- x/epoching/keeper/grpc_query_test.go | 5 +- x/epoching/types/epoching.pb.go | 345 +-- x/epoching/types/query.go | 24 +- x/epoching/types/query.pb.go | 766 ++++- 8 files changed, 1208 insertions(+), 3436 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index cdb03b943..a72c38c78 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -2259,14 +2259,14 @@ paths: properties: tx_id: type: string - format: byte - title: tx_id is the ID of the tx that contains the message + description: >- + tx_id is the ID of the tx that contains the message as + hex. msg_id: type: string - format: byte - title: >- + description: >- msg_id is the original message ID, i.e., hash of the - marshaled message + marshaled message as hex. block_height: type: string format: uint64 @@ -2279,401 +2279,16 @@ paths: title: >- block_time is the timestamp when this msg is submitted to Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: >- - moniker defines a human-readable name for the - validator. - identity: - type: string - description: >- - identity defines an optional identity signature - (ex. UPort or Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email for - security contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to - delegators, as a fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate - which validator can ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily - increase of the validator commission, as a - fraction. - description: >- - CommissionRates defines the initial commission rates - to be used for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in - MsgCreateValidator is deprecated. - - The validator address bytes and delegator address - bytes refer to the same account while creating - validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the - type of the serialized - - protocol buffer message. This string must - contain at least - - one "/" character. The last segment of the URL's - path must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name - should be in a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the - binary all types that they - - expect it to use in the context of Any. However, - for URLs which use the - - scheme `http`, `https`, or no scheme, one can - optionally set up a type - - server that maps type URLs to message - definitions as follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup - results based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently - available in the official - - protobuf release, and it is not used for type - URLs beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty - scheme) might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of - the above specified type. - description: >- - `Any` contains an arbitrary serialized protocol - buffer message along with a - - URL that describes the type of the serialized - message. - - - Protobuf library provides support to pack/unpack Any - values in the form - - of utility functions or additional generated methods - of the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will - by default use - - 'type.googleapis.com/full.type.name' as the type URL - and the unpack - - methods only use the fully qualified type name after - the last '/' - - in the type URL, for example "foo.bar.com/x/y.z" - will yield type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the - regular - - representation of the deserialized, embedded - message, with an - - additional field `@type` which contains the type - URL. Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a - custom JSON - - representation, that representation will be embedded - adding a field - - `value` which holds the custom JSON in addition to - the `@type` - - field. Example (for message - [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements - the custom method - - signatures required by gogoproto. - description: >- - MsgCreateValidator defines a SDK message for creating a - new validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements - the custom method - - signatures required by gogoproto. - description: >- - MsgDelegate defines a SDK message for performing a - delegation of coins - - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements - the custom method - - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing an - undelegation from a - - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements - the custom method - - signatures required by gogoproto. + msg: + type: string description: >- - MsgBeginRedelegate defines a SDK message for performing - a redelegation - - of coins from a delegator and source validator to a - destination validator. - msg_cancel_unbonding_delegation: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements - the custom method + msg is the actual message that is sent by a user and is + queued by the - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding - delegation entry balance - creation_height: - type: string - format: int64 - description: >- - creation_height is the height which the unbonding - took place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK message for - performing a cancel unbonding delegation for delegator + epoching module as string. title: >- - QueuedMessage is a message that can change the validator set - and is delayed + QueuedMessageResponse is a message that can change the + validator set and is delayed to the end of an epoch title: msgs is the list of messages queued in the current epoch @@ -3317,16 +2932,14 @@ paths: properties: tx_id: type: string - format: byte - title: >- + description: >- tx_id is the ID of the tx that contains the - message + message as hex. msg_id: type: string - format: byte - title: >- + description: >- msg_id is the original message ID, i.e., hash of - the marshaled message + the marshaled message as hex. block_height: type: string format: uint64 @@ -3339,442 +2952,51 @@ paths: title: >- block_time is the timestamp when this msg is submitted to Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: >- - moniker defines a human-readable name for - the validator. - identity: - type: string - description: >- - identity defines an optional identity - signature (ex. UPort or Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email - for security contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to - delegators, as a fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission - rate which validator can ever charge, as a - fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily - increase of the validator commission, as a - fraction. - description: >- - CommissionRates defines the initial commission - rates to be used for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in - MsgCreateValidator is deprecated. - - The validator address bytes and delegator - address bytes refer to the same account while - creating validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely - identifies the type of the serialized - - protocol buffer message. This string must - contain at least - - one "/" character. The last segment of the - URL's path must represent + msg: + type: string + description: >- + msg is the actual message that is sent by a user + and is queued by the - the fully qualified name of the type (as - in + epoching module as string. + title: >- + QueuedMessageResponse is a message that can change the + validator set and is delayed - `path/google.protobuf.Duration`). The name - should be in a canonical form + to the end of an epoch + title: >- + QueuedMessageList is a message that contains a list of + staking-related - (e.g., leading "." is not accepted). + messages queued for an epoch + title: >- + latest_epoch_msgs is a list of QueuedMessageList + each QueuedMessageList has a field identifying the epoch + number + pagination: + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total - In practice, teams usually precompile into - the binary all types that they + was set, its value is undefined otherwise + description: >- + PageResponse is to be embedded in gRPC response messages where + the - expect it to use in the context of Any. - However, for URLs which use the - - scheme `http`, `https`, or no scheme, one - can optionally set up a type - - server that maps type URLs to message - definitions as follows: - - - * If no scheme is provided, `https` is - assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup - results based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently - available in the official - - protobuf release, and it is not used for - type URLs beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the - empty scheme) might be - - used with implementation specific - semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer - of the above specified type. - description: >- - `Any` contains an arbitrary serialized - protocol buffer message along with a - - URL that describes the type of the serialized - message. - - - Protobuf library provides support to - pack/unpack Any values in the form - - of utility functions or additional generated - methods of the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in - Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library - will by default use - - 'type.googleapis.com/full.type.name' as the - type URL and the unpack - - methods only use the fully qualified type name - after the last '/' - - in the type URL, for example - "foo.bar.com/x/y.z" will yield type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses - the regular - - representation of the deserialized, embedded - message, with an - - additional field `@type` which contains the - type URL. Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and - has a custom JSON - - representation, that representation will be - embedded adding a field - - `value` which holds the custom JSON in - addition to the `@type` - - field. Example (for message - [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and - an amount. - - - NOTE: The amount field is an Int which - implements the custom method - - signatures required by gogoproto. - description: >- - MsgCreateValidator defines a SDK message for - creating a new validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and - an amount. - - - NOTE: The amount field is an Int which - implements the custom method - - signatures required by gogoproto. - description: >- - MsgDelegate defines a SDK message for performing a - delegation of coins - - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and - an amount. - - - NOTE: The amount field is an Int which - implements the custom method - - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing - an undelegation from a - - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and - an amount. - - - NOTE: The amount field is an Int which - implements the custom method - - signatures required by gogoproto. - description: >- - MsgBeginRedelegate defines a SDK message for - performing a redelegation - - of coins from a delegator and source validator to - a destination validator. - msg_cancel_unbonding_delegation: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and - an amount. - - - NOTE: The amount field is an Int which - implements the custom method - - signatures required by gogoproto. - title: >- - amount is always less than or equal to - unbonding delegation entry balance - creation_height: - type: string - format: int64 - description: >- - creation_height is the height which the - unbonding took place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK - message for performing a cancel unbonding - delegation for delegator - title: >- - QueuedMessage is a message that can change the - validator set and is delayed - - to the end of an epoch - title: >- - QueuedMessageList is a message that contains a list of - staking-related - - messages queued for an epoch - title: >- - epoch_msg_map is a list of QueuedMessageList - - each QueuedMessageList has a field identifying the epoch - number - pagination: - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: >- - PageResponse is to be embedded in gRPC response messages where - the - - corresponding request message has used PageRequest. + corresponding request message has used PageRequest. message SomeResponse { repeated Bar results = 1; @@ -10874,14 +10096,12 @@ definitions: properties: tx_id: type: string - format: byte - title: tx_id is the ID of the tx that contains the message + description: tx_id is the ID of the tx that contains the message as hex. msg_id: type: string - format: byte - title: >- + description: >- msg_id is the original message ID, i.e., hash of the marshaled - message + message as hex. block_height: type: string format: uint64 @@ -10892,1899 +10112,410 @@ definitions: title: >- block_time is the timestamp when this msg is submitted to Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: moniker defines a human-readable name for the validator. - identity: - type: string - description: >- - identity defines an optional identity signature (ex. - UPort or Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email for security - contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to delegators, as a - fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which - validator can ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase of - the validator commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates to be - used for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in MsgCreateValidator - is deprecated. - - The validator address bytes and delegator address bytes - refer to the same account while creating validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's path - must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in - a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary - all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can optionally - set up a type - - server that maps type URLs to message definitions as - follows: - + msg: + type: string + description: >- + msg is the actual message that is sent by a user and is queued + by the - * If no scheme is provided, `https` is assumed. + epoching module as string. + title: >- + QueuedMessageResponse is a message that can change the validator set + and is delayed - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) + to the end of an epoch + title: msgs is the list of messages queued in the current epoch + pagination: + title: pagination defines the pagination in the response + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total - Note: this functionality is not currently available in - the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) - might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values - in the form - - of utility functions or additional generated methods of the - Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgCreateValidator defines a SDK message for creating a new - validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgDelegate defines a SDK message for performing a delegation of - coins - - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing an - undelegation from a - - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgBeginRedelegate defines a SDK message for performing a - redelegation - - of coins from a delegator and source validator to a destination - validator. - msg_cancel_unbonding_delegation: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding delegation - entry balance - creation_height: - type: string - format: int64 - description: >- - creation_height is the height which the unbonding took - place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK message for - performing a cancel unbonding delegation for delegator - title: >- - QueuedMessage is a message that can change the validator set and is - delayed - - to the end of an epoch - title: msgs is the list of messages queued in the current epoch - pagination: - title: pagination defines the pagination in the response - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - title: |- - QueryEpochMsgsResponse is the response type for the Query/EpochMsgs RPC - method - babylon.epoching.v1.QueryEpochValSetResponse: - type: object - properties: - validators: - type: array - items: - type: object - properties: - addr: - type: string - format: byte - title: addr is the validator's address (in sdk.ValAddress) - power: - type: string - format: int64 - title: power is the validator's voting power - title: Validator is a message that denotes a validator - total_voting_power: - type: string - format: int64 - pagination: - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - title: |- - QueryEpochValSetRequest is the response type for the Query/EpochValSet RPC - method - babylon.epoching.v1.QueryEpochsInfoResponse: - type: object - properties: - epochs: - type: array - items: - type: object - properties: - epoch_number: - type: string - format: uint64 - title: epoch_number is the number of this epoch - current_epoch_interval: - type: string - format: uint64 - title: >- - current_epoch_interval is the epoch interval at the time of this - epoch - first_block_height: - type: string - format: uint64 - title: >- - first_block_height is the height of the first block in this - epoch - last_block_time: - type: string - format: date-time - description: >- - last_block_time is the time of the last block in this epoch. - - Babylon needs to remember the last header's time of each epoch - to complete - - unbonding validators/delegations when a previous epoch's - checkpoint is - - finalised. The last_block_time field is nil in the epoch's - beginning, and - - is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: >- - app_hash_root is the Merkle root of all AppHashs in this epoch - - It will be used for proving a block is in an epoch as hex - string. - sealer_app_hash_hex: - type: string - description: >- - sealer is the last block of the sealed epoch - - sealer_app_hash points to the sealer but stored in the 1st - header - - of the next epoch as hex string. - sealer_block_hash: - type: string - description: |- - sealer_block_hash is the hash of the sealer - the validator set has generated a BLS multisig on the hash, - i.e., hash of the last block in the epoch as hex string. - title: EpochResponse is a structure that contains the metadata of an epoch - pagination: - title: pagination defines the pagination in the response - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - title: >- - QueryEpochsInfoResponse is the response type for the Query/EpochInfos - method - babylon.epoching.v1.QueryLatestEpochMsgsResponse: - type: object - properties: - latest_epoch_msgs: - type: array - items: - type: object - properties: - epoch_number: - type: string - format: uint64 - msgs: - type: array - items: - type: object - properties: - tx_id: - type: string - format: byte - title: tx_id is the ID of the tx that contains the message - msg_id: - type: string - format: byte - title: >- - msg_id is the original message ID, i.e., hash of the - marshaled message - block_height: - type: string - format: uint64 - title: >- - block_height is the height when this msg is submitted to - Babylon - block_time: - type: string - format: date-time - title: >- - block_time is the timestamp when this msg is submitted to - Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: >- - moniker defines a human-readable name for the - validator. - identity: - type: string - description: >- - identity defines an optional identity signature - (ex. UPort or Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email for - security contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to delegators, - as a fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which - validator can ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase - of the validator commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates - to be used for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in - MsgCreateValidator is deprecated. - - The validator address bytes and delegator address - bytes refer to the same account while creating - validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the - type of the serialized - - protocol buffer message. This string must contain - at least - - one "/" character. The last segment of the URL's - path must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should - be in a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the - binary all types that they - - expect it to use in the context of Any. However, - for URLs which use the - - scheme `http`, `https`, or no scheme, one can - optionally set up a type - - server that maps type URLs to message definitions - as follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results - based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently - available in the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty - scheme) might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the - above specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any - values in the form - - of utility functions or additional generated methods - of the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL - and the unpack - - methods only use the fully qualified type name after - the last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will - yield type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the - regular - - representation of the deserialized, embedded message, - with an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a - custom JSON - - representation, that representation will be embedded - adding a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message - [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - MsgCreateValidator defines a SDK message for creating a - new validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - MsgDelegate defines a SDK message for performing a - delegation of coins - - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing an - undelegation from a - - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - MsgBeginRedelegate defines a SDK message for performing a - redelegation - - of coins from a delegator and source validator to a - destination validator. - msg_cancel_unbonding_delegation: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding - delegation entry balance - creation_height: - type: string - format: int64 - description: >- - creation_height is the height which the unbonding took - place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK message for - performing a cancel unbonding delegation for delegator - title: >- - QueuedMessage is a message that can change the validator set - and is delayed - - to the end of an epoch - title: >- - QueuedMessageList is a message that contains a list of - staking-related - - messages queued for an epoch - title: |- - epoch_msg_map is a list of QueuedMessageList - each QueuedMessageList has a field identifying the epoch number - pagination: - type: object - properties: - next_key: - type: string - format: byte - description: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently. It will be empty if - there are no more results. - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. message SomeResponse { repeated Bar results = 1; PageResponse page = 2; } title: |- - QueryLatestEpochMsgsResponse is the response type for the - Query/LatestEpochMsgs RPC method - babylon.epoching.v1.QueryParamsResponse: - type: object - properties: - params: - description: params holds all the parameters of this module. - type: object - properties: - epoch_interval: - type: string - format: uint64 - title: >- - epoch_interval is the number of consecutive blocks to form an - epoch - description: QueryParamsResponse is the response type for the Query/Params RPC method. - babylon.epoching.v1.QueryValidatorLifecycleResponse: - type: object - properties: - val_life: - type: object - properties: - val_addr: - type: string - val_life: - type: array - items: - type: object - properties: - state: - type: string - enum: - - CREATED - - BONDED - - UNBONDING - - UNBONDED - - REMOVED - default: CREATED - description: >- - - CREATED: CREATED is when the validator/delegation has been - created - - BONDED: CREATED is when the validator/delegation has become bonded - - UNBONDING: CREATED is when the validator/delegation has become unbonding - - UNBONDED: CREATED is when the validator/delegation has become unbonded - - REMOVED: CREATED is when the validator/delegation has been removed - title: BondState is the bond state of a validator or delegation - block_height: - type: string - format: uint64 - block_time: - type: string - format: date-time - title: >- - ValStateUpdate is a messages that records a state update of a - validator - title: |- - ValidatorLifecycle is a message that records records the lifecycle of - a validator - title: |- - QueryValidatorLifecycleResponse is the response type for the - Query/ValidatorLifecycle RPC method - babylon.epoching.v1.QueuedMessage: + QueryEpochMsgsResponse is the response type for the Query/EpochMsgs RPC + method + babylon.epoching.v1.QueryEpochValSetResponse: type: object properties: - tx_id: - type: string - format: byte - title: tx_id is the ID of the tx that contains the message - msg_id: - type: string - format: byte - title: msg_id is the original message ID, i.e., hash of the marshaled message - block_height: - type: string - format: uint64 - title: block_height is the height when this msg is submitted to Babylon - block_time: + validators: + type: array + items: + type: object + properties: + addr: + type: string + format: byte + title: addr is the validator's address (in sdk.ValAddress) + power: + type: string + format: int64 + title: power is the validator's voting power + title: Validator is a message that denotes a validator + total_voting_power: type: string - format: date-time - title: block_time is the timestamp when this msg is submitted to Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: moniker defines a human-readable name for the validator. - identity: - type: string - description: >- - identity defines an optional identity signature (ex. UPort or - Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email for security - contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to delegators, as a - fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which validator - can ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase of the - validator commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates to be used - for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in MsgCreateValidator is - deprecated. - - The validator address bytes and delegator address bytes refer to - the same account while creating validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of the - serialized - - protocol buffer message. This string must contain at least - - one "/" character. The last segment of the URL's path must - represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in a - canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary all - types that they - - expect it to use in the context of Any. However, for URLs - which use the - - scheme `http`, `https`, or no scheme, one can optionally set - up a type - - server that maps type URLs to message definitions as follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based on - the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in the - official - - protobuf release, and it is not used for type URLs beginning - with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) might - be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer message - along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values in the - form - - of utility functions or additional generated methods of the Any - type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with an - - additional field `@type` which contains the type URL. Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom JSON - - representation, that representation will be embedded adding a - field - - `value` which holds the custom JSON in addition to the `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: MsgCreateValidator defines a SDK message for creating a new validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: |- - MsgDelegate defines a SDK message for performing a delegation of coins - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing an undelegation - from a - - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - MsgBeginRedelegate defines a SDK message for performing a redelegation - - of coins from a delegator and source validator to a destination - validator. - msg_cancel_unbonding_delegation: + format: int64 + pagination: type: object properties: - delegator_address: - type: string - validator_address: + next_key: type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding delegation entry - balance - creation_height: + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: type: string - format: int64 - description: creation_height is the height which the unbonding took place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK message for performing a - cancel unbonding delegation for delegator - title: >- - QueuedMessage is a message that can change the validator set and is - delayed + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total - to the end of an epoch - babylon.epoching.v1.QueuedMessageList: + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QueryEpochValSetRequest is the response type for the Query/EpochValSet RPC + method + babylon.epoching.v1.QueryEpochsInfoResponse: type: object properties: - epoch_number: - type: string - format: uint64 - msgs: + epochs: type: array items: type: object properties: - tx_id: + epoch_number: type: string - format: byte - title: tx_id is the ID of the tx that contains the message - msg_id: + format: uint64 + title: epoch_number is the number of this epoch + current_epoch_interval: type: string - format: byte + format: uint64 title: >- - msg_id is the original message ID, i.e., hash of the marshaled - message - block_height: + current_epoch_interval is the epoch interval at the time of this + epoch + first_block_height: type: string format: uint64 - title: block_height is the height when this msg is submitted to Babylon - block_time: - type: string - format: date-time title: >- - block_time is the timestamp when this msg is submitted to - Babylon - msg_create_validator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: moniker defines a human-readable name for the validator. - identity: - type: string - description: >- - identity defines an optional identity signature (ex. - UPort or Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: >- - security_contact defines an optional email for security - contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: >- - rate is the commission rate charged to delegators, as a - fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which - validator can ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase of - the validator commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates to be - used for creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in MsgCreateValidator - is deprecated. - - The validator address bytes and delegator address bytes - refer to the same account while creating validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's path - must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in - a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary - all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can optionally - set up a type - - server that maps type URLs to message definitions as - follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in - the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) - might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values - in the form - - of utility functions or additional generated methods of the - Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): + first_block_height is the height of the first block in this + epoch + last_block_time: + type: string + format: date-time + description: >- + last_block_time is the time of the last block in this epoch. - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. + Babylon needs to remember the last header's time of each epoch + to complete + unbonding validators/delegations when a previous epoch's + checkpoint is - NOTE: The amount field is an Int which implements the custom - method + finalised. The last_block_time field is nil in the epoch's + beginning, and - signatures required by gogoproto. + is set upon the end of this epoch. + app_hash_root_hex: + type: string description: >- - MsgCreateValidator defines a SDK message for creating a new - validator. - msg_delegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method + app_hash_root is the Merkle root of all AppHashs in this epoch - signatures required by gogoproto. + It will be used for proving a block is in an epoch as hex + string. + sealer_app_hash_hex: + type: string description: >- - MsgDelegate defines a SDK message for performing a delegation of - coins + sealer is the last block of the sealed epoch - from a delegator to a validator. - msg_undelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. + sealer_app_hash points to the sealer but stored in the 1st + header + of the next epoch as hex string. + sealer_block_hash: + type: string + description: |- + sealer_block_hash is the hash of the sealer + the validator set has generated a BLS multisig on the hash, + i.e., hash of the last block in the epoch as hex string. + title: EpochResponse is a structure that contains the metadata of an epoch + pagination: + title: pagination defines the pagination in the response + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total - NOTE: The amount field is an Int which implements the custom - method + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. - signatures required by gogoproto. - description: >- - MsgUndelegate defines a SDK message for performing an - undelegation from a + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: >- + QueryEpochsInfoResponse is the response type for the Query/EpochInfos + method + babylon.epoching.v1.QueryLatestEpochMsgsResponse: + type: object + properties: + latest_epoch_msgs: + type: array + items: + type: object + properties: + epoch_number: + type: string + format: uint64 + msgs: + type: array + items: + type: object + properties: + tx_id: + type: string + description: >- + tx_id is the ID of the tx that contains the message as + hex. + msg_id: + type: string + description: >- + msg_id is the original message ID, i.e., hash of the + marshaled message as hex. + block_height: + type: string + format: uint64 + title: >- + block_height is the height when this msg is submitted to + Babylon + block_time: + type: string + format: date-time + title: >- + block_time is the timestamp when this msg is submitted to + Babylon + msg: + type: string + description: >- + msg is the actual message that is sent by a user and is + queued by the - delegate and a validator. - msg_begin_redelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. + epoching module as string. + title: >- + QueuedMessageResponse is a message that can change the + validator set and is delayed + to the end of an epoch + title: >- + QueuedMessageList is a message that contains a list of + staking-related - NOTE: The amount field is an Int which implements the custom - method + messages queued for an epoch + title: |- + latest_epoch_msgs is a list of QueuedMessageList + each QueuedMessageList has a field identifying the epoch number + pagination: + type: object + properties: + next_key: + type: string + format: byte + description: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently. It will be empty if + there are no more results. + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total - signatures required by gogoproto. - description: >- - MsgBeginRedelegate defines a SDK message for performing a - redelegation + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. - of coins from a delegator and source validator to a destination - validator. - msg_cancel_unbonding_delegation: + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QueryLatestEpochMsgsResponse is the response type for the + Query/LatestEpochMsgs RPC method + babylon.epoching.v1.QueryParamsResponse: + type: object + properties: + params: + description: params holds all the parameters of this module. + type: object + properties: + epoch_interval: + type: string + format: uint64 + title: >- + epoch_interval is the number of consecutive blocks to form an + epoch + description: QueryParamsResponse is the response type for the Query/Params RPC method. + babylon.epoching.v1.QueryValidatorLifecycleResponse: + type: object + properties: + val_life: + type: object + properties: + val_addr: + type: string + val_life: + type: array + items: type: object properties: - delegator_address: - type: string - validator_address: + state: type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string + enum: + - CREATED + - BONDED + - UNBONDING + - UNBONDED + - REMOVED + default: CREATED description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding delegation - entry balance - creation_height: + - CREATED: CREATED is when the validator/delegation has been + created + - BONDED: CREATED is when the validator/delegation has become bonded + - UNBONDING: CREATED is when the validator/delegation has become unbonding + - UNBONDED: CREATED is when the validator/delegation has become unbonded + - REMOVED: CREATED is when the validator/delegation has been removed + title: BondState is the bond state of a validator or delegation + block_height: type: string - format: int64 - description: >- - creation_height is the height which the unbonding took - place. - description: 'Since: cosmos-sdk 0.46' + format: uint64 + block_time: + type: string + format: date-time + title: >- + ValStateUpdate is a messages that records a state update of a + validator + title: |- + ValidatorLifecycle is a message that records records the lifecycle of + a validator + title: |- + QueryValidatorLifecycleResponse is the response type for the + Query/ValidatorLifecycle RPC method + babylon.epoching.v1.QueuedMessageList: + type: object + properties: + epoch_number: + type: string + format: uint64 + msgs: + type: array + items: + type: object + properties: + tx_id: + type: string + description: tx_id is the ID of the tx that contains the message as hex. + msg_id: + type: string + description: >- + msg_id is the original message ID, i.e., hash of the marshaled + message as hex. + block_height: + type: string + format: uint64 + title: block_height is the height when this msg is submitted to Babylon + block_time: + type: string + format: date-time title: >- - MsgCancelUnbondingDelegation defines the SDK message for - performing a cancel unbonding delegation for delegator + block_time is the timestamp when this msg is submitted to + Babylon + msg: + type: string + description: >- + msg is the actual message that is sent by a user and is queued + by the + + epoching module as string. title: >- - QueuedMessage is a message that can change the validator set and is - delayed + QueuedMessageResponse is a message that can change the validator set + and is delayed to the end of an epoch title: |- QueuedMessageList is a message that contains a list of staking-related messages queued for an epoch + babylon.epoching.v1.QueuedMessageResponse: + type: object + properties: + tx_id: + type: string + description: tx_id is the ID of the tx that contains the message as hex. + msg_id: + type: string + description: >- + msg_id is the original message ID, i.e., hash of the marshaled message + as hex. + block_height: + type: string + format: uint64 + title: block_height is the height when this msg is submitted to Babylon + block_time: + type: string + format: date-time + title: block_time is the timestamp when this msg is submitted to Babylon + msg: + type: string + description: |- + msg is the actual message that is sent by a user and is queued by the + epoching module as string. + title: >- + QueuedMessageResponse is a message that can change the validator set and + is delayed + + to the end of an epoch babylon.epoching.v1.ValStateUpdate: type: object properties: @@ -12874,382 +10605,6 @@ definitions: NOTE: The amount field is an Int which implements the custom method signatures required by gogoproto. - cosmos.staking.v1beta1.CommissionRates: - type: object - properties: - rate: - type: string - description: rate is the commission rate charged to delegators, as a fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which validator can ever - charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase of the validator - commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates to be used for - creating - - a validator. - cosmos.staking.v1beta1.Description: - type: object - properties: - moniker: - type: string - description: moniker defines a human-readable name for the validator. - identity: - type: string - description: >- - identity defines an optional identity signature (ex. UPort or - Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: security_contact defines an optional email for security contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - cosmos.staking.v1beta1.MsgBeginRedelegate: - type: object - properties: - delegator_address: - type: string - validator_src_address: - type: string - validator_dst_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - description: |- - MsgBeginRedelegate defines a SDK message for performing a redelegation - of coins from a delegator and source validator to a destination validator. - cosmos.staking.v1beta1.MsgCancelUnbondingDelegation: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - title: >- - amount is always less than or equal to unbonding delegation entry - balance - creation_height: - type: string - format: int64 - description: creation_height is the height which the unbonding took place. - description: 'Since: cosmos-sdk 0.46' - title: >- - MsgCancelUnbondingDelegation defines the SDK message for performing a - cancel unbonding delegation for delegator - cosmos.staking.v1beta1.MsgCreateValidator: - type: object - properties: - description: - type: object - properties: - moniker: - type: string - description: moniker defines a human-readable name for the validator. - identity: - type: string - description: >- - identity defines an optional identity signature (ex. UPort or - Keybase). - website: - type: string - description: website defines an optional website link. - security_contact: - type: string - description: security_contact defines an optional email for security contact. - details: - type: string - description: details define other optional details. - description: Description defines a validator description. - commission: - type: object - properties: - rate: - type: string - description: rate is the commission rate charged to delegators, as a fraction. - max_rate: - type: string - description: >- - max_rate defines the maximum commission rate which validator can - ever charge, as a fraction. - max_change_rate: - type: string - description: >- - max_change_rate defines the maximum daily increase of the - validator commission, as a fraction. - description: >- - CommissionRates defines the initial commission rates to be used for - creating - - a validator. - min_self_delegation: - type: string - delegator_address: - type: string - description: >- - Deprecated: Use of Delegator Address in MsgCreateValidator is - deprecated. - - The validator address bytes and delegator address bytes refer to the - same account while creating validator (defer - - only in bech32 notation). - validator_address: - type: string - pubkey: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of the - serialized - - protocol buffer message. This string must contain at least - - one "/" character. The last segment of the URL's path must - represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in a - canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary all types - that they - - expect it to use in the context of Any. However, for URLs which - use the - - scheme `http`, `https`, or no scheme, one can optionally set up a - type - - server that maps type URLs to message definitions as follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in the - official - - protobuf release, and it is not used for type URLs beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above specified - type. - description: >- - `Any` contains an arbitrary serialized protocol buffer message along - with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values in the - form - - of utility functions or additional generated methods of the Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - // or ... - if (any.isSameTypeAs(Foo.getDefaultInstance())) { - foo = any.unpack(Foo.getDefaultInstance()); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := anypb.New(foo) - if err != nil { - ... - } - ... - foo := &pb.Foo{} - if err := any.UnmarshalTo(foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by default use - - 'type.googleapis.com/full.type.name' as the type URL and the unpack - - methods only use the fully qualified type name after the last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield type - - name "y.z". - - - JSON - - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with an - - additional field `@type` which contains the type URL. Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom JSON - - representation, that representation will be embedded adding a field - - `value` which holds the custom JSON in addition to the `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - value: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - description: MsgCreateValidator defines a SDK message for creating a new validator. - cosmos.staking.v1beta1.MsgDelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - description: |- - MsgDelegate defines a SDK message for performing a delegation of coins - from a delegator to a validator. - cosmos.staking.v1beta1.MsgUndelegate: - type: object - properties: - delegator_address: - type: string - validator_address: - type: string - amount: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - description: |- - MsgUndelegate defines a SDK message for performing an undelegation from a - delegate and a validator. babylon.checkpointing.v1.CheckpointStateUpdateResponse: type: object properties: diff --git a/proto/babylon/epoching/v1/epoching.proto b/proto/babylon/epoching/v1/epoching.proto index 59382045e..647d8a825 100644 --- a/proto/babylon/epoching/v1/epoching.proto +++ b/proto/babylon/epoching/v1/epoching.proto @@ -57,13 +57,6 @@ message QueuedMessage { } } -// QueuedMessageList is a message that contains a list of staking-related -// messages queued for an epoch -message QueuedMessageList { - uint64 epoch_number = 1; - repeated QueuedMessage msgs = 2; -} - // BondState is the bond state of a validator or delegation enum BondState { // CREATED is when the validator/delegation has been created diff --git a/proto/babylon/epoching/v1/query.proto b/proto/babylon/epoching/v1/query.proto index a46e36289..c7f5eed91 100644 --- a/proto/babylon/epoching/v1/query.proto +++ b/proto/babylon/epoching/v1/query.proto @@ -125,7 +125,7 @@ message QueryEpochMsgsRequest { // method message QueryEpochMsgsResponse { // msgs is the list of messages queued in the current epoch - repeated babylon.epoching.v1.QueuedMessage msgs = 1; + repeated QueuedMessageResponse msgs = 1; // pagination defines the pagination in the response cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -145,9 +145,9 @@ message QueryLatestEpochMsgsRequest { // QueryLatestEpochMsgsResponse is the response type for the // Query/LatestEpochMsgs RPC method message QueryLatestEpochMsgsResponse { - // epoch_msg_map is a list of QueuedMessageList + // latest_epoch_msgs is a list of QueuedMessageList // each QueuedMessageList has a field identifying the epoch number - repeated babylon.epoching.v1.QueuedMessageList latest_epoch_msgs = 1; + repeated QueuedMessageList latest_epoch_msgs = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -209,3 +209,26 @@ message EpochResponse { // i.e., hash of the last block in the epoch as hex string. string sealer_block_hash = 7; } + +// QueuedMessageResponse is a message that can change the validator set and is delayed +// to the end of an epoch +message QueuedMessageResponse { + // tx_id is the ID of the tx that contains the message as hex. + string tx_id = 1; + // msg_id is the original message ID, i.e., hash of the marshaled message as hex. + string msg_id = 2; + // block_height is the height when this msg is submitted to Babylon + uint64 block_height = 3; + // block_time is the timestamp when this msg is submitted to Babylon + google.protobuf.Timestamp block_time = 4 [ (gogoproto.stdtime) = true ]; + // msg is the actual message that is sent by a user and is queued by the + // epoching module as string. + string msg = 5; +} + +// QueuedMessageList is a message that contains a list of staking-related +// messages queued for an epoch +message QueuedMessageList { + uint64 epoch_number = 1; + repeated QueuedMessageResponse msgs = 2; +} diff --git a/x/epoching/keeper/grpc_query.go b/x/epoching/keeper/grpc_query.go index 80bc62dda..bf7c263c1 100644 --- a/x/epoching/keeper/grpc_query.go +++ b/x/epoching/keeper/grpc_query.go @@ -90,7 +90,7 @@ func (k Keeper) EpochMsgs(c context.Context, req *types.QueryEpochMsgsRequest) ( return nil, types.ErrUnknownEpochNumber } - var msgs []*types.QueuedMessage + var msgs []*types.QueuedMessageResponse epochMsgsStore := k.msgQueueStore(ctx, req.EpochNum) // handle pagination @@ -109,17 +109,17 @@ func (k Keeper) EpochMsgs(c context.Context, req *types.QueryEpochMsgsRequest) ( return errors.New("invalid queue message") } // append to msgs - msgs = append(msgs, queuedMsg) + msgs = append(msgs, queuedMsg.ToResponse()) return nil }) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - resp := &types.QueryEpochMsgsResponse{ + + return &types.QueryEpochMsgsResponse{ Msgs: msgs, Pagination: pageRes, - } - return resp, nil + }, nil } // LatestEpochMsgs handles the QueryLatestEpochMsgsRequest query @@ -158,9 +158,10 @@ func (k Keeper) LatestEpochMsgs(c context.Context, req *types.QueryLatestEpochMs } if accumulate { + msgs := k.GetEpochMsgs(ctx, epochNumber) msgList := &types.QueuedMessageList{ EpochNumber: epochNumber, - Msgs: k.GetEpochMsgs(ctx, epochNumber), + Msgs: types.NewQueuedMessagesResponse(msgs), } latestEpochMsgs = append(latestEpochMsgs, msgList) } diff --git a/x/epoching/keeper/grpc_query_test.go b/x/epoching/keeper/grpc_query_test.go index 8e528da99..92fc074fc 100644 --- a/x/epoching/keeper/grpc_query_test.go +++ b/x/epoching/keeper/grpc_query_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "encoding/hex" "math/rand" "testing" @@ -151,7 +152,7 @@ func FuzzEpochMsgsQuery(f *testing.F) { // enque a random number of msgs with random txids for i := uint64(0); i < numMsgs; i++ { txid := datagen.GenRandomByteArray(r, 32) - txidsMap[string(txid)] = true + txidsMap[hex.EncodeToString(txid)] = true queuedMsg := types.QueuedMessage{ TxId: txid, Msg: &types.QueuedMessage_MsgDelegate{MsgDelegate: &stakingtypes.MsgDelegate{}}, @@ -170,7 +171,7 @@ func FuzzEpochMsgsQuery(f *testing.F) { require.Equal(t, min(uint64(len(txidsMap)), limit), uint64(len(resp.Msgs))) for idx := range resp.Msgs { - _, ok := txidsMap[string(resp.Msgs[idx].TxId)] + _, ok := txidsMap[resp.Msgs[idx].TxId] require.True(t, ok) } diff --git a/x/epoching/types/epoching.pb.go b/x/epoching/types/epoching.pb.go index e63ee0f62..8d4f7b18b 100644 --- a/x/epoching/types/epoching.pb.go +++ b/x/epoching/types/epoching.pb.go @@ -343,60 +343,6 @@ func (*QueuedMessage) XXX_OneofWrappers() []interface{} { } } -// QueuedMessageList is a message that contains a list of staking-related -// messages queued for an epoch -type QueuedMessageList struct { - EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` - Msgs []*QueuedMessage `protobuf:"bytes,2,rep,name=msgs,proto3" json:"msgs,omitempty"` -} - -func (m *QueuedMessageList) Reset() { *m = QueuedMessageList{} } -func (m *QueuedMessageList) String() string { return proto.CompactTextString(m) } -func (*QueuedMessageList) ProtoMessage() {} -func (*QueuedMessageList) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{2} -} -func (m *QueuedMessageList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueuedMessageList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueuedMessageList.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 *QueuedMessageList) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueuedMessageList.Merge(m, src) -} -func (m *QueuedMessageList) XXX_Size() int { - return m.Size() -} -func (m *QueuedMessageList) XXX_DiscardUnknown() { - xxx_messageInfo_QueuedMessageList.DiscardUnknown(m) -} - -var xxx_messageInfo_QueuedMessageList proto.InternalMessageInfo - -func (m *QueuedMessageList) GetEpochNumber() uint64 { - if m != nil { - return m.EpochNumber - } - return 0 -} - -func (m *QueuedMessageList) GetMsgs() []*QueuedMessage { - if m != nil { - return m.Msgs - } - return nil -} - // ValStateUpdate is a messages that records a state update of a validator type ValStateUpdate struct { State BondState `protobuf:"varint,1,opt,name=state,proto3,enum=babylon.epoching.v1.BondState" json:"state,omitempty"` @@ -408,7 +354,7 @@ func (m *ValStateUpdate) Reset() { *m = ValStateUpdate{} } func (m *ValStateUpdate) String() string { return proto.CompactTextString(m) } func (*ValStateUpdate) ProtoMessage() {} func (*ValStateUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{3} + return fileDescriptor_2f2f209d5311f84c, []int{2} } func (m *ValStateUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +415,7 @@ func (m *ValidatorLifecycle) Reset() { *m = ValidatorLifecycle{} } func (m *ValidatorLifecycle) String() string { return proto.CompactTextString(m) } func (*ValidatorLifecycle) ProtoMessage() {} func (*ValidatorLifecycle) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{4} + return fileDescriptor_2f2f209d5311f84c, []int{3} } func (m *ValidatorLifecycle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -526,7 +472,7 @@ func (m *DelegationStateUpdate) Reset() { *m = DelegationStateUpdate{} } func (m *DelegationStateUpdate) String() string { return proto.CompactTextString(m) } func (*DelegationStateUpdate) ProtoMessage() {} func (*DelegationStateUpdate) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{5} + return fileDescriptor_2f2f209d5311f84c, []int{4} } func (m *DelegationStateUpdate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -601,7 +547,7 @@ func (m *DelegationLifecycle) Reset() { *m = DelegationLifecycle{} } func (m *DelegationLifecycle) String() string { return proto.CompactTextString(m) } func (*DelegationLifecycle) ProtoMessage() {} func (*DelegationLifecycle) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{6} + return fileDescriptor_2f2f209d5311f84c, []int{5} } func (m *DelegationLifecycle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -656,7 +602,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_2f2f209d5311f84c, []int{7} + return fileDescriptor_2f2f209d5311f84c, []int{6} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -703,7 +649,6 @@ func init() { proto.RegisterEnum("babylon.epoching.v1.BondState", BondState_name, BondState_value) proto.RegisterType((*Epoch)(nil), "babylon.epoching.v1.Epoch") proto.RegisterType((*QueuedMessage)(nil), "babylon.epoching.v1.QueuedMessage") - proto.RegisterType((*QueuedMessageList)(nil), "babylon.epoching.v1.QueuedMessageList") proto.RegisterType((*ValStateUpdate)(nil), "babylon.epoching.v1.ValStateUpdate") proto.RegisterType((*ValidatorLifecycle)(nil), "babylon.epoching.v1.ValidatorLifecycle") proto.RegisterType((*DelegationStateUpdate)(nil), "babylon.epoching.v1.DelegationStateUpdate") @@ -716,65 +661,64 @@ func init() { } var fileDescriptor_2f2f209d5311f84c = []byte{ - // 927 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x96, 0xdf, 0x6e, 0xdb, 0x36, - 0x14, 0xc6, 0x2d, 0xff, 0x49, 0xe2, 0x63, 0x3b, 0x75, 0x99, 0x74, 0x70, 0x83, 0xc1, 0xc9, 0x5c, - 0x6c, 0x08, 0x82, 0x41, 0x5e, 0xbc, 0x6c, 0x97, 0x1b, 0xe2, 0xd8, 0x98, 0x33, 0x34, 0x2e, 0xc6, - 0x35, 0xb9, 0xd8, 0xc5, 0x04, 0x4a, 0x62, 0x64, 0xa1, 0x12, 0x29, 0x88, 0x94, 0x9b, 0x5c, 0xec, - 0x1d, 0xfa, 0x1c, 0x7b, 0x92, 0x5d, 0xe6, 0x72, 0x77, 0x1b, 0x92, 0x07, 0xe9, 0x40, 0x4a, 0x96, - 0xed, 0xc5, 0x48, 0xd6, 0xf5, 0x8e, 0x3c, 0xe7, 0x3b, 0x1f, 0x79, 0x7e, 0x3a, 0x26, 0x0c, 0x1d, - 0x9b, 0xd8, 0xd7, 0x01, 0x67, 0x5d, 0x1a, 0x71, 0x67, 0xe2, 0x33, 0xaf, 0x3b, 0x3d, 0xcc, 0xd7, - 0x66, 0x14, 0x73, 0xc9, 0xd1, 0x56, 0xa6, 0x31, 0xf3, 0xf8, 0xf4, 0x70, 0x67, 0xd7, 0xe3, 0xdc, - 0x0b, 0x68, 0x57, 0x4b, 0xec, 0xe4, 0xb2, 0x2b, 0xfd, 0x90, 0x0a, 0x49, 0xc2, 0x28, 0xad, 0xda, - 0xd9, 0xf6, 0xb8, 0xc7, 0xf5, 0xb2, 0xab, 0x56, 0x59, 0x74, 0xd7, 0xe1, 0x22, 0xe4, 0xa2, 0x2b, - 0x24, 0x79, 0x93, 0x9e, 0x66, 0x53, 0x49, 0x0e, 0xbb, 0xf2, 0x2a, 0x13, 0xb4, 0x33, 0x81, 0x4d, - 0x04, 0xcd, 0xb3, 0x0e, 0xf7, 0x59, 0x9a, 0xef, 0xdc, 0x14, 0xa1, 0x32, 0x54, 0xf7, 0x40, 0x9f, - 0x41, 0x5d, 0x5f, 0xc8, 0x62, 0x49, 0x68, 0xd3, 0xb8, 0x65, 0xec, 0x19, 0xfb, 0x65, 0x5c, 0xd3, - 0xb1, 0xb1, 0x0e, 0xa1, 0x23, 0xf8, 0xc4, 0x49, 0xe2, 0x98, 0x32, 0x69, 0xa5, 0x52, 0x9f, 0x49, - 0x1a, 0x4f, 0x49, 0xd0, 0x2a, 0x6a, 0xf1, 0x76, 0x96, 0xd5, 0x86, 0xa7, 0x59, 0x0e, 0x7d, 0x09, - 0xe8, 0xd2, 0x8f, 0x85, 0xb4, 0xec, 0x80, 0x3b, 0x6f, 0xac, 0x09, 0xf5, 0xbd, 0x89, 0x6c, 0x95, - 0x74, 0x45, 0x53, 0x67, 0xfa, 0x2a, 0x31, 0xd2, 0x71, 0x34, 0x82, 0x27, 0x01, 0xc9, 0xc5, 0x8a, - 0x42, 0xab, 0xbc, 0x67, 0xec, 0xd7, 0x7a, 0x3b, 0x66, 0x8a, 0xc8, 0x9c, 0x21, 0x32, 0x5f, 0xcf, - 0x10, 0xf5, 0xcb, 0xef, 0xfe, 0xda, 0x35, 0x70, 0x43, 0x15, 0x6a, 0x2f, 0x95, 0x41, 0x1d, 0x68, - 0x90, 0x28, 0xb2, 0x26, 0x44, 0x4c, 0xac, 0x98, 0x73, 0xd9, 0xaa, 0xec, 0x19, 0xfb, 0x75, 0x5c, - 0x23, 0x51, 0x34, 0x22, 0x62, 0x82, 0x39, 0x97, 0xe8, 0x0b, 0x78, 0x22, 0x28, 0x09, 0x68, 0x6c, - 0xcd, 0xa4, 0xad, 0x35, 0xad, 0x6a, 0xa4, 0xe1, 0xe3, 0x54, 0x8b, 0x0e, 0xe0, 0x69, 0xa6, 0xcb, - 0x9a, 0x50, 0xca, 0x75, 0xad, 0xcc, 0x0c, 0xd2, 0x1e, 0x88, 0x98, 0x74, 0xde, 0x97, 0xa1, 0xf1, - 0x53, 0x42, 0x13, 0xea, 0x9e, 0x51, 0x21, 0x88, 0x47, 0xd1, 0x16, 0x54, 0xe4, 0x95, 0xe5, 0xbb, - 0x9a, 0x69, 0x1d, 0x97, 0xe5, 0xd5, 0xa9, 0x8b, 0x9e, 0xc1, 0x5a, 0x28, 0x3c, 0x15, 0x2d, 0xea, - 0x68, 0x25, 0x14, 0xde, 0xa9, 0xab, 0x3e, 0xc3, 0x0a, 0x4e, 0x35, 0x7b, 0x01, 0xd1, 0xf7, 0x00, - 0xff, 0x83, 0x4e, 0xd5, 0xce, 0xc9, 0xfc, 0x0a, 0xdb, 0xea, 0x68, 0x27, 0xa6, 0x44, 0x52, 0x6b, - 0x4a, 0x02, 0xdf, 0x25, 0x92, 0xc7, 0x1a, 0x50, 0xad, 0x77, 0x60, 0xa6, 0x33, 0x63, 0x66, 0x43, - 0x65, 0x66, 0x63, 0x63, 0x9e, 0x09, 0xef, 0x44, 0x97, 0x5c, 0xcc, 0x2a, 0x46, 0x05, 0x8c, 0xc2, - 0x7b, 0x51, 0x34, 0x82, 0xba, 0xf2, 0x77, 0x69, 0x40, 0x3d, 0x22, 0xa9, 0x46, 0x5a, 0xeb, 0xbd, - 0x78, 0xc0, 0x77, 0x90, 0x49, 0x47, 0x05, 0x5c, 0x0b, 0xe7, 0x5b, 0x34, 0x86, 0x4d, 0xe5, 0x94, - 0xb0, 0xdc, 0x6b, 0x5d, 0x7b, 0x7d, 0xfe, 0x80, 0xd7, 0x79, 0x2e, 0x1e, 0x15, 0x70, 0x23, 0x5c, - 0x0c, 0xcc, 0x3a, 0xb7, 0xa9, 0xe7, 0x33, 0x2b, 0xa6, 0xb9, 0xeb, 0xc6, 0xa3, 0x9d, 0xf7, 0x55, - 0x09, 0xa6, 0x0b, 0xd6, 0xaa, 0xf3, 0x7f, 0x45, 0xd1, 0x6f, 0xb0, 0xab, 0xc9, 0x12, 0xe6, 0xd0, - 0xc0, 0x4a, 0x98, 0xcd, 0x99, 0xeb, 0xb3, 0x1c, 0x85, 0xcf, 0x59, 0xab, 0xaa, 0x8f, 0x3a, 0x7a, - 0x08, 0xb2, 0xae, 0x3e, 0x9f, 0x15, 0x0f, 0xf2, 0xda, 0x51, 0x01, 0x7f, 0x1a, 0x3e, 0x90, 0xef, - 0x57, 0xa0, 0x14, 0x0a, 0xaf, 0xc3, 0xe0, 0xe9, 0xd2, 0x00, 0xbe, 0xf4, 0x85, 0xfc, 0x2f, 0xbf, - 0xef, 0x6f, 0xa1, 0x1c, 0x0a, 0x4f, 0xb4, 0x8a, 0x7b, 0xa5, 0xfd, 0x5a, 0xaf, 0x63, 0xae, 0x78, - 0xa8, 0xcc, 0x25, 0x63, 0xac, 0xf5, 0x9d, 0xdf, 0x0d, 0xd8, 0xbc, 0x20, 0xc1, 0xcf, 0x92, 0x48, - 0x7a, 0x1e, 0xb9, 0x0a, 0xc4, 0x11, 0x54, 0x84, 0xda, 0xea, 0x63, 0x36, 0x7b, 0xed, 0x95, 0x5e, - 0x7d, 0xce, 0x5c, 0x5d, 0x84, 0x53, 0xf1, 0xbd, 0xe1, 0x2f, 0x3e, 0x36, 0xfc, 0xa5, 0x0f, 0x1e, - 0xfe, 0x0e, 0x07, 0x94, 0x4f, 0xea, 0x4b, 0xff, 0x92, 0x3a, 0xd7, 0x4e, 0x40, 0xd1, 0x73, 0xd8, - 0x98, 0x92, 0xc0, 0x22, 0xae, 0x9b, 0x92, 0xa9, 0xe2, 0xf5, 0x29, 0x09, 0x8e, 0x5d, 0x37, 0x46, - 0xdf, 0xa5, 0xa9, 0xc0, 0xbf, 0xa4, 0x19, 0x99, 0x17, 0x2b, 0xbb, 0x59, 0x26, 0xa0, 0xeb, 0x95, - 0x7f, 0xe7, 0xbd, 0x01, 0xcf, 0xe6, 0xdf, 0xe8, 0xe3, 0x21, 0x2d, 0x5e, 0xb5, 0xb8, 0x7c, 0xd5, - 0x43, 0x58, 0x23, 0x21, 0x4f, 0x98, 0xcc, 0xc0, 0x3c, 0x9f, 0x4d, 0x99, 0x7a, 0xfe, 0xf3, 0x11, - 0x3b, 0xe1, 0x3e, 0xc3, 0x99, 0xf0, 0x1e, 0xf2, 0xf2, 0x63, 0xc8, 0x2b, 0x1f, 0x8e, 0xfc, 0x2d, - 0x6c, 0xcd, 0x01, 0x2c, 0x31, 0x77, 0xe9, 0x32, 0x73, 0x97, 0xa6, 0x8d, 0x0c, 0xd3, 0xd4, 0x02, - 0xf3, 0x83, 0x95, 0x70, 0x56, 0x72, 0xd5, 0x36, 0x1a, 0xfd, 0x37, 0x50, 0x9d, 0xbf, 0x4a, 0x08, - 0xca, 0xf9, 0x51, 0x75, 0xac, 0xd7, 0x68, 0x1b, 0x2a, 0x11, 0x7f, 0x4b, 0x53, 0x90, 0x25, 0x9c, - 0x6e, 0x0e, 0xc6, 0x50, 0xcd, 0xa9, 0xa3, 0x1a, 0xac, 0x9f, 0xe0, 0xe1, 0xf1, 0xeb, 0xe1, 0xa0, - 0x59, 0x40, 0x00, 0x6b, 0xfd, 0x57, 0xe3, 0xc1, 0x70, 0xd0, 0x34, 0x50, 0x03, 0xaa, 0xe7, 0x63, - 0xb5, 0x3b, 0x1d, 0xff, 0xd0, 0x2c, 0xa2, 0x3a, 0x6c, 0xa4, 0xdb, 0xe1, 0xa0, 0x59, 0x52, 0x55, - 0x78, 0x78, 0xf6, 0xea, 0x62, 0x38, 0x68, 0x96, 0xfb, 0x3f, 0xfe, 0x71, 0xdb, 0x36, 0x6e, 0x6e, - 0xdb, 0xc6, 0xdf, 0xb7, 0x6d, 0xe3, 0xdd, 0x5d, 0xbb, 0x70, 0x73, 0xd7, 0x2e, 0xfc, 0x79, 0xd7, - 0x2e, 0xfc, 0xf2, 0x95, 0xe7, 0xcb, 0x49, 0x62, 0x9b, 0x0e, 0x0f, 0xbb, 0x59, 0x7f, 0xce, 0x84, - 0xf8, 0x6c, 0xb6, 0xe9, 0x5e, 0xcd, 0xff, 0x49, 0xc8, 0xeb, 0x88, 0x0a, 0x7b, 0x4d, 0x03, 0xff, - 0xfa, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x41, 0x06, 0xf6, 0x6a, 0x08, 0x00, 0x00, + // 897 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xdf, 0x6e, 0xe3, 0x44, + 0x14, 0xc6, 0xe3, 0xfc, 0x6b, 0x73, 0x92, 0x74, 0xc3, 0xb4, 0x8b, 0xb2, 0x15, 0x4a, 0x4b, 0x10, + 0xa8, 0xaa, 0x90, 0x43, 0x4b, 0xb9, 0x05, 0x35, 0x4d, 0x44, 0x8a, 0x68, 0x56, 0x98, 0x6d, 0x2f, + 0xb8, 0xc0, 0x1a, 0xdb, 0x53, 0xdb, 0x5a, 0x7b, 0xc6, 0xf2, 0x8c, 0xb3, 0xed, 0x05, 0xef, 0xb0, + 0xcf, 0xc1, 0x93, 0x70, 0xd9, 0x4b, 0xee, 0x40, 0xed, 0x83, 0x2c, 0x9a, 0x19, 0xc7, 0x49, 0x69, + 0xd4, 0xaa, 0x70, 0x37, 0x73, 0xce, 0x77, 0xbe, 0x99, 0xf3, 0xf3, 0xd1, 0x18, 0xfa, 0x0e, 0x76, + 0xae, 0x23, 0x46, 0x07, 0x24, 0x61, 0x6e, 0x10, 0x52, 0x7f, 0x30, 0x3b, 0x28, 0xd6, 0x66, 0x92, + 0x32, 0xc1, 0xd0, 0x66, 0xae, 0x31, 0x8b, 0xf8, 0xec, 0x60, 0x7b, 0xc7, 0x67, 0xcc, 0x8f, 0xc8, + 0x40, 0x49, 0x9c, 0xec, 0x72, 0x20, 0xc2, 0x98, 0x70, 0x81, 0xe3, 0x44, 0x57, 0x6d, 0x6f, 0xf9, + 0xcc, 0x67, 0x6a, 0x39, 0x90, 0xab, 0x3c, 0xba, 0xe3, 0x32, 0x1e, 0x33, 0x3e, 0xe0, 0x02, 0xbf, + 0xd5, 0xa7, 0x39, 0x44, 0xe0, 0x83, 0x81, 0xb8, 0xca, 0x05, 0xbd, 0x5c, 0xe0, 0x60, 0x4e, 0x8a, + 0xac, 0xcb, 0x42, 0xaa, 0xf3, 0xfd, 0x9b, 0x32, 0xd4, 0xc6, 0xf2, 0x1e, 0xe8, 0x53, 0x68, 0xa9, + 0x0b, 0xd9, 0x34, 0x8b, 0x1d, 0x92, 0x76, 0x8d, 0x5d, 0x63, 0xaf, 0x6a, 0x35, 0x55, 0x6c, 0xaa, + 0x42, 0xe8, 0x08, 0x3e, 0x76, 0xb3, 0x34, 0x25, 0x54, 0xd8, 0x5a, 0x1a, 0x52, 0x41, 0xd2, 0x19, + 0x8e, 0xba, 0x65, 0x25, 0xde, 0xca, 0xb3, 0xca, 0xf0, 0x34, 0xcf, 0xa1, 0x2f, 0x01, 0x5d, 0x86, + 0x29, 0x17, 0xb6, 0x13, 0x31, 0xf7, 0xad, 0x1d, 0x90, 0xd0, 0x0f, 0x44, 0xb7, 0xa2, 0x2a, 0x3a, + 0x2a, 0x33, 0x94, 0x89, 0x89, 0x8a, 0xa3, 0x09, 0xbc, 0x88, 0x70, 0x21, 0x96, 0x14, 0xba, 0xd5, + 0x5d, 0x63, 0xaf, 0x79, 0xb8, 0x6d, 0x6a, 0x44, 0xe6, 0x1c, 0x91, 0xf9, 0x66, 0x8e, 0x68, 0x58, + 0x7d, 0xff, 0xd7, 0x8e, 0x61, 0xb5, 0x65, 0xa1, 0xf2, 0x92, 0x19, 0xd4, 0x87, 0x36, 0x4e, 0x12, + 0x3b, 0xc0, 0x3c, 0xb0, 0x53, 0xc6, 0x44, 0xb7, 0xb6, 0x6b, 0xec, 0xb5, 0xac, 0x26, 0x4e, 0x92, + 0x09, 0xe6, 0x81, 0xc5, 0x98, 0x40, 0x5f, 0xc0, 0x0b, 0x4e, 0x70, 0x44, 0x52, 0x7b, 0x2e, 0xed, + 0xd6, 0x95, 0xaa, 0xad, 0xc3, 0xc7, 0x5a, 0x8b, 0xf6, 0xe1, 0xa3, 0x5c, 0x97, 0x37, 0x21, 0x95, + 0x6b, 0x4a, 0x99, 0x1b, 0xe8, 0x1e, 0x30, 0x0f, 0xfa, 0x1f, 0xaa, 0xd0, 0xfe, 0x29, 0x23, 0x19, + 0xf1, 0xce, 0x08, 0xe7, 0xd8, 0x27, 0x68, 0x13, 0x6a, 0xe2, 0xca, 0x0e, 0x3d, 0xc5, 0xb4, 0x65, + 0x55, 0xc5, 0xd5, 0xa9, 0x87, 0x5e, 0x42, 0x3d, 0xe6, 0xbe, 0x8c, 0x96, 0x55, 0xb4, 0x16, 0x73, + 0xff, 0xd4, 0x93, 0x9f, 0x61, 0x05, 0xa7, 0xa6, 0xb3, 0x84, 0xe8, 0x3b, 0x80, 0xff, 0x40, 0xa7, + 0xe1, 0x14, 0x64, 0x7e, 0x85, 0x2d, 0x79, 0xb4, 0x9b, 0x12, 0x2c, 0x88, 0x3d, 0xc3, 0x51, 0xe8, + 0x61, 0xc1, 0x52, 0x05, 0xa8, 0x79, 0xb8, 0x6f, 0xea, 0x99, 0x31, 0xf3, 0xa1, 0x32, 0xf3, 0xb1, + 0x31, 0xcf, 0xb8, 0x7f, 0xa2, 0x4a, 0x2e, 0xe6, 0x15, 0x93, 0x92, 0x85, 0xe2, 0x07, 0x51, 0x34, + 0x81, 0x96, 0xf4, 0xf7, 0x48, 0x44, 0x7c, 0x2c, 0x88, 0x42, 0xda, 0x3c, 0xfc, 0xec, 0x11, 0xdf, + 0x51, 0x2e, 0x9d, 0x94, 0xac, 0x66, 0xbc, 0xd8, 0xa2, 0x29, 0x6c, 0x48, 0xa7, 0x8c, 0x16, 0x5e, + 0x6b, 0xca, 0xeb, 0xf3, 0x47, 0xbc, 0xce, 0x0b, 0xf1, 0xa4, 0x64, 0xb5, 0xe3, 0xe5, 0xc0, 0xbc, + 0x73, 0x87, 0xf8, 0x21, 0xb5, 0x53, 0x52, 0xb8, 0xae, 0x3f, 0xd9, 0xf9, 0x50, 0x96, 0x58, 0x64, + 0xc9, 0x5a, 0x76, 0xfe, 0xaf, 0x28, 0xfa, 0x0d, 0x76, 0x14, 0x59, 0x4c, 0x5d, 0x12, 0xd9, 0x19, + 0x75, 0x18, 0xf5, 0x42, 0x5a, 0xa0, 0x08, 0x19, 0xed, 0x36, 0xd4, 0x51, 0x47, 0x8f, 0x41, 0x56, + 0xd5, 0xe7, 0xf3, 0xe2, 0x51, 0x51, 0x3b, 0x29, 0x59, 0x9f, 0xc4, 0x8f, 0xe4, 0x87, 0x35, 0xa8, + 0xc4, 0xdc, 0xef, 0xff, 0x6e, 0xc0, 0xc6, 0x05, 0x8e, 0x7e, 0x16, 0x58, 0x90, 0xf3, 0xc4, 0x93, + 0x17, 0x3b, 0x82, 0x1a, 0x97, 0x5b, 0x35, 0x82, 0x1b, 0x87, 0x3d, 0x73, 0xc5, 0x23, 0x64, 0x0e, + 0x19, 0xf5, 0x54, 0x91, 0xa5, 0xc5, 0x0f, 0x86, 0xb1, 0xfc, 0xd4, 0x30, 0x56, 0x9e, 0x3d, 0x8c, + 0x7d, 0x06, 0xa8, 0x98, 0x9c, 0x1f, 0xc3, 0x4b, 0xe2, 0x5e, 0xbb, 0x11, 0x41, 0xaf, 0x60, 0x7d, + 0x86, 0x23, 0x1b, 0x7b, 0x9e, 0x7e, 0x89, 0x1a, 0xd6, 0xda, 0x0c, 0x47, 0xc7, 0x9e, 0x97, 0xa2, + 0x6f, 0x75, 0x2a, 0x0a, 0x2f, 0x49, 0xb7, 0xbc, 0x5b, 0x51, 0x93, 0xb5, 0xaa, 0x9b, 0xfb, 0x04, + 0x54, 0xbd, 0xf4, 0xef, 0x7f, 0x30, 0xe0, 0xe5, 0x82, 0xd9, 0xff, 0x87, 0xb4, 0x7c, 0xd5, 0xf2, + 0xfd, 0xab, 0x1e, 0x40, 0x1d, 0xc7, 0x2c, 0xa3, 0x22, 0x07, 0xf3, 0x6a, 0xfe, 0xd5, 0xe5, 0x73, + 0x5c, 0x7c, 0xf2, 0x13, 0x16, 0x52, 0x2b, 0x17, 0x3e, 0x40, 0x5e, 0x7d, 0x0a, 0x79, 0xed, 0xf9, + 0xc8, 0xdf, 0xc1, 0xe6, 0x02, 0xc0, 0x3d, 0xe6, 0x1e, 0xb9, 0xcf, 0xdc, 0x23, 0xba, 0x91, 0xb1, + 0x4e, 0x2d, 0x31, 0xdf, 0x5f, 0x09, 0x67, 0x25, 0x57, 0x65, 0xa3, 0xd0, 0x7f, 0x03, 0x8d, 0xc5, + 0x2b, 0x81, 0xa0, 0x5a, 0x1c, 0xd5, 0xb2, 0xd4, 0x1a, 0x6d, 0x41, 0x2d, 0x61, 0xef, 0x88, 0x06, + 0x59, 0xb1, 0xf4, 0x66, 0x7f, 0x0a, 0x8d, 0x82, 0x3a, 0x6a, 0xc2, 0xda, 0x89, 0x35, 0x3e, 0x7e, + 0x33, 0x1e, 0x75, 0x4a, 0x08, 0xa0, 0x3e, 0x7c, 0x3d, 0x1d, 0x8d, 0x47, 0x1d, 0x03, 0xb5, 0xa1, + 0x71, 0x3e, 0x95, 0xbb, 0xd3, 0xe9, 0xf7, 0x9d, 0x32, 0x6a, 0xc1, 0xba, 0xde, 0x8e, 0x47, 0x9d, + 0x8a, 0xac, 0xb2, 0xc6, 0x67, 0xaf, 0x2f, 0xc6, 0xa3, 0x4e, 0x75, 0xf8, 0xc3, 0x1f, 0xb7, 0x3d, + 0xe3, 0xe6, 0xb6, 0x67, 0xfc, 0x7d, 0xdb, 0x33, 0xde, 0xdf, 0xf5, 0x4a, 0x37, 0x77, 0xbd, 0xd2, + 0x9f, 0x77, 0xbd, 0xd2, 0x2f, 0x5f, 0xf9, 0xa1, 0x08, 0x32, 0xc7, 0x74, 0x59, 0x3c, 0xc8, 0xfb, + 0x73, 0x03, 0x1c, 0xd2, 0xf9, 0x66, 0x70, 0xb5, 0xf8, 0xb3, 0x8b, 0xeb, 0x84, 0x70, 0xa7, 0xae, + 0x80, 0x7f, 0xfd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x06, 0x18, 0x1e, 0x99, 0xfa, 0x07, 0x00, + 0x00, } func (m *Epoch) Marshal() (dAtA []byte, err error) { @@ -1012,48 +956,6 @@ func (m *QueuedMessage_MsgCancelUnbondingDelegation) MarshalToSizedBuffer(dAtA [ } return len(dAtA) - i, nil } -func (m *QueuedMessageList) 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 *QueuedMessageList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueuedMessageList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Msgs) > 0 { - for iNdEx := len(m.Msgs) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Msgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintEpoching(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.EpochNumber != 0 { - i = encodeVarintEpoching(dAtA, i, uint64(m.EpochNumber)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func (m *ValStateUpdate) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1414,24 +1316,6 @@ func (m *QueuedMessage_MsgCancelUnbondingDelegation) Size() (n int) { } return n } -func (m *QueuedMessageList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.EpochNumber != 0 { - n += 1 + sovEpoching(uint64(m.EpochNumber)) - } - if len(m.Msgs) > 0 { - for _, e := range m.Msgs { - l = e.Size() - n += 1 + l + sovEpoching(uint64(l)) - } - } - return n -} - func (m *ValStateUpdate) Size() (n int) { if m == nil { return 0 @@ -2131,109 +2015,6 @@ func (m *QueuedMessage) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueuedMessageList) 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 ErrIntOverflowEpoching - } - 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: QueuedMessageList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueuedMessageList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) - } - m.EpochNumber = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEpoching - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.EpochNumber |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Msgs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEpoching - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthEpoching - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthEpoching - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Msgs = append(m.Msgs, &QueuedMessage{}) - if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipEpoching(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthEpoching - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ValStateUpdate) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/epoching/types/query.go b/x/epoching/types/query.go index 17fb5db34..7dbc87b97 100644 --- a/x/epoching/types/query.go +++ b/x/epoching/types/query.go @@ -1,6 +1,8 @@ package types -import "encoding/hex" +import ( + "encoding/hex" +) // ToResponse parses a Epoch into a query response epoch struct. func (e *Epoch) ToResponse() *EpochResponse { @@ -14,3 +16,23 @@ func (e *Epoch) ToResponse() *EpochResponse { SealerBlockHash: hex.EncodeToString(e.SealerBlockHash), } } + +// ToResponse parses a QueuedMessage into a query response queued message struct. +func (q *QueuedMessage) ToResponse() *QueuedMessageResponse { + return &QueuedMessageResponse{ + TxId: hex.EncodeToString(q.TxId), + MsgId: hex.EncodeToString(q.MsgId), + BlockHeight: q.BlockHeight, + BlockTime: q.BlockTime, + Msg: q.UnwrapToSdkMsg().String(), + } +} + +// NewQueuedMessagesResponse parses all the queued messages as response. +func NewQueuedMessagesResponse(msgs []*QueuedMessage) []*QueuedMessageResponse { + resp := make([]*QueuedMessageResponse, len(msgs)) + for i, m := range msgs { + resp[i] = m.ToResponse() + } + return resp +} diff --git a/x/epoching/types/query.pb.go b/x/epoching/types/query.pb.go index 3f3024660..2985d762a 100644 --- a/x/epoching/types/query.pb.go +++ b/x/epoching/types/query.pb.go @@ -460,7 +460,7 @@ func (m *QueryEpochMsgsRequest) GetPagination() *query.PageRequest { // method type QueryEpochMsgsResponse struct { // msgs is the list of messages queued in the current epoch - Msgs []*QueuedMessage `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs,omitempty"` + Msgs []*QueuedMessageResponse `protobuf:"bytes,1,rep,name=msgs,proto3" json:"msgs,omitempty"` // pagination defines the pagination in the response Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -498,7 +498,7 @@ func (m *QueryEpochMsgsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryEpochMsgsResponse proto.InternalMessageInfo -func (m *QueryEpochMsgsResponse) GetMsgs() []*QueuedMessage { +func (m *QueryEpochMsgsResponse) GetMsgs() []*QueuedMessageResponse { if m != nil { return m.Msgs } @@ -580,7 +580,7 @@ func (m *QueryLatestEpochMsgsRequest) GetPagination() *query.PageRequest { // QueryLatestEpochMsgsResponse is the response type for the // Query/LatestEpochMsgs RPC method type QueryLatestEpochMsgsResponse struct { - // epoch_msg_map is a list of QueuedMessageList + // latest_epoch_msgs is a list of QueuedMessageList // each QueuedMessageList has a field identifying the epoch number LatestEpochMsgs []*QueuedMessageList `protobuf:"bytes,1,rep,name=latest_epoch_msgs,json=latestEpochMsgs,proto3" json:"latest_epoch_msgs,omitempty"` Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` @@ -1042,6 +1042,144 @@ func (m *EpochResponse) GetSealerBlockHash() string { return "" } +// QueuedMessageResponse is a message that can change the validator set and is delayed +// to the end of an epoch +type QueuedMessageResponse struct { + // tx_id is the ID of the tx that contains the message as hex. + TxId string `protobuf:"bytes,1,opt,name=tx_id,json=txId,proto3" json:"tx_id,omitempty"` + // msg_id is the original message ID, i.e., hash of the marshaled message as hex. + MsgId string `protobuf:"bytes,2,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"` + // block_height is the height when this msg is submitted to Babylon + BlockHeight uint64 `protobuf:"varint,3,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // block_time is the timestamp when this msg is submitted to Babylon + BlockTime *time.Time `protobuf:"bytes,4,opt,name=block_time,json=blockTime,proto3,stdtime" json:"block_time,omitempty"` + // msg is the actual message that is sent by a user and is queued by the + // epoching module as string. + Msg string `protobuf:"bytes,5,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (m *QueuedMessageResponse) Reset() { *m = QueuedMessageResponse{} } +func (m *QueuedMessageResponse) String() string { return proto.CompactTextString(m) } +func (*QueuedMessageResponse) ProtoMessage() {} +func (*QueuedMessageResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1821b530f2ec2711, []int{19} +} +func (m *QueuedMessageResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuedMessageResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueuedMessageResponse.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 *QueuedMessageResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuedMessageResponse.Merge(m, src) +} +func (m *QueuedMessageResponse) XXX_Size() int { + return m.Size() +} +func (m *QueuedMessageResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueuedMessageResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuedMessageResponse proto.InternalMessageInfo + +func (m *QueuedMessageResponse) GetTxId() string { + if m != nil { + return m.TxId + } + return "" +} + +func (m *QueuedMessageResponse) GetMsgId() string { + if m != nil { + return m.MsgId + } + return "" +} + +func (m *QueuedMessageResponse) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *QueuedMessageResponse) GetBlockTime() *time.Time { + if m != nil { + return m.BlockTime + } + return nil +} + +func (m *QueuedMessageResponse) GetMsg() string { + if m != nil { + return m.Msg + } + return "" +} + +// QueuedMessageList is a message that contains a list of staking-related +// messages queued for an epoch +type QueuedMessageList struct { + EpochNumber uint64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"` + Msgs []*QueuedMessageResponse `protobuf:"bytes,2,rep,name=msgs,proto3" json:"msgs,omitempty"` +} + +func (m *QueuedMessageList) Reset() { *m = QueuedMessageList{} } +func (m *QueuedMessageList) String() string { return proto.CompactTextString(m) } +func (*QueuedMessageList) ProtoMessage() {} +func (*QueuedMessageList) Descriptor() ([]byte, []int) { + return fileDescriptor_1821b530f2ec2711, []int{20} +} +func (m *QueuedMessageList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuedMessageList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueuedMessageList.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 *QueuedMessageList) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuedMessageList.Merge(m, src) +} +func (m *QueuedMessageList) XXX_Size() int { + return m.Size() +} +func (m *QueuedMessageList) XXX_DiscardUnknown() { + xxx_messageInfo_QueuedMessageList.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuedMessageList proto.InternalMessageInfo + +func (m *QueuedMessageList) GetEpochNumber() uint64 { + if m != nil { + return m.EpochNumber + } + return 0 +} + +func (m *QueuedMessageList) GetMsgs() []*QueuedMessageResponse { + if m != nil { + return m.Msgs + } + return nil +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.epoching.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.epoching.v1.QueryParamsResponse") @@ -1062,92 +1200,99 @@ func init() { proto.RegisterType((*QueryEpochValSetRequest)(nil), "babylon.epoching.v1.QueryEpochValSetRequest") proto.RegisterType((*QueryEpochValSetResponse)(nil), "babylon.epoching.v1.QueryEpochValSetResponse") proto.RegisterType((*EpochResponse)(nil), "babylon.epoching.v1.EpochResponse") + proto.RegisterType((*QueuedMessageResponse)(nil), "babylon.epoching.v1.QueuedMessageResponse") + proto.RegisterType((*QueuedMessageList)(nil), "babylon.epoching.v1.QueuedMessageList") } func init() { proto.RegisterFile("babylon/epoching/v1/query.proto", fileDescriptor_1821b530f2ec2711) } var fileDescriptor_1821b530f2ec2711 = []byte{ - // 1273 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6f, 0x1b, 0xc5, - 0x1b, 0xce, 0x26, 0x6e, 0xda, 0x4e, 0x9a, 0xa6, 0x9d, 0xf4, 0xd7, 0x5f, 0xba, 0x29, 0x76, 0xd9, - 0x42, 0x3f, 0xd2, 0x66, 0xb7, 0x6e, 0xd2, 0x42, 0x3f, 0x00, 0xd5, 0xe1, 0x23, 0x45, 0x29, 0x4a, - 0x17, 0x94, 0x03, 0x97, 0x65, 0xec, 0x9d, 0xac, 0x57, 0xac, 0x77, 0xb6, 0x3b, 0x63, 0x93, 0xa8, - 0x04, 0x21, 0xce, 0x1c, 0x2a, 0x71, 0x40, 0xbd, 0x20, 0x24, 0x8e, 0xfc, 0x09, 0x70, 0xe0, 0xd8, - 0x63, 0x10, 0x17, 0x4e, 0x80, 0x12, 0xc4, 0xdf, 0x81, 0xf6, 0x9d, 0x59, 0x7b, 0xed, 0xae, 0x63, - 0x27, 0xaa, 0xb8, 0xd9, 0x33, 0xcf, 0xf3, 0xbe, 0xcf, 0xfb, 0xb1, 0xf3, 0xbe, 0xa8, 0x54, 0x25, - 0xd5, 0xcd, 0x80, 0x85, 0x16, 0x8d, 0x58, 0xad, 0xee, 0x87, 0x9e, 0xd5, 0x2a, 0x5b, 0x8f, 0x9a, - 0x34, 0xde, 0x34, 0xa3, 0x98, 0x09, 0x86, 0xa7, 0x15, 0xc0, 0x4c, 0x01, 0x66, 0xab, 0xac, 0x9f, - 0xf2, 0x98, 0xc7, 0xe0, 0xde, 0x4a, 0x7e, 0x49, 0xa8, 0x5e, 0xf2, 0x18, 0xf3, 0x02, 0x6a, 0xc1, - 0xbf, 0x6a, 0x73, 0xdd, 0x12, 0x7e, 0x83, 0x72, 0x41, 0x1a, 0x91, 0x02, 0x9c, 0x55, 0x00, 0x12, - 0xf9, 0x16, 0x09, 0x43, 0x26, 0x88, 0xf0, 0x59, 0xc8, 0xd5, 0xed, 0x5c, 0x8d, 0xf1, 0x06, 0xe3, - 0x56, 0x95, 0x70, 0x2a, 0x25, 0x58, 0xad, 0x72, 0x95, 0x0a, 0x52, 0xb6, 0x22, 0xe2, 0xf9, 0x21, - 0x80, 0x15, 0xf6, 0x5c, 0x9e, 0xec, 0x88, 0xc4, 0xa4, 0x91, 0x5a, 0x33, 0xf2, 0x10, 0xed, 0x18, - 0x00, 0x63, 0x9c, 0x42, 0xf8, 0x61, 0xe2, 0x67, 0x15, 0x88, 0x36, 0x7d, 0xd4, 0xa4, 0x5c, 0x18, - 0xab, 0x68, 0xba, 0xeb, 0x94, 0x47, 0x2c, 0xe4, 0x14, 0xdf, 0x42, 0xe3, 0xd2, 0xc1, 0x8c, 0x76, - 0x4e, 0xbb, 0x34, 0x71, 0x7d, 0xd6, 0xcc, 0xc9, 0x8c, 0x29, 0x49, 0x95, 0xc2, 0xb3, 0x3f, 0x4a, - 0x23, 0xb6, 0x22, 0x18, 0x8b, 0xe8, 0x7f, 0x60, 0xf1, 0x9d, 0x04, 0x78, 0x3f, 0x5c, 0x67, 0xca, - 0x15, 0x9e, 0x45, 0x47, 0x81, 0xec, 0x84, 0xcd, 0x06, 0x98, 0x2d, 0xd8, 0x47, 0xe0, 0xe0, 0x83, - 0x66, 0xc3, 0xb0, 0xd1, 0xe9, 0x5e, 0x96, 0x92, 0xf2, 0x3a, 0x3a, 0x04, 0x28, 0xa5, 0xc4, 0xc8, - 0x55, 0x02, 0xb4, 0x94, 0x62, 0x4b, 0x82, 0xf1, 0x49, 0xd6, 0x26, 0xcf, 0x4a, 0x79, 0x17, 0xa1, - 0x4e, 0x96, 0x95, 0xe1, 0x0b, 0xa6, 0x2c, 0x89, 0x99, 0x94, 0xc4, 0x94, 0x5d, 0xa1, 0x4a, 0x62, - 0xae, 0x12, 0x8f, 0x2a, 0xae, 0x9d, 0x61, 0x1a, 0xdf, 0x69, 0xe8, 0xff, 0xcf, 0xb9, 0x50, 0xba, - 0x6f, 0xa3, 0x71, 0x90, 0x91, 0xa4, 0x70, 0x6c, 0x48, 0xe1, 0x8a, 0x81, 0xdf, 0xeb, 0xd2, 0x37, - 0x0a, 0xfa, 0x2e, 0x0e, 0xd4, 0xa7, 0x8c, 0x64, 0x05, 0xea, 0x68, 0x06, 0xf4, 0x2d, 0x35, 0xe3, - 0x98, 0x86, 0x42, 0x79, 0x93, 0xa5, 0xf7, 0xd0, 0x99, 0x9c, 0x3b, 0xa5, 0xfe, 0x3c, 0x9a, 0xac, - 0xc9, 0x73, 0xa7, 0x93, 0xfd, 0x82, 0x7d, 0xac, 0x96, 0x01, 0xe3, 0x57, 0xd1, 0x71, 0x59, 0xd1, - 0x2a, 0x6b, 0x86, 0x2e, 0x89, 0x37, 0x41, 0x6a, 0xc1, 0x9e, 0x84, 0xd3, 0x8a, 0x3a, 0x34, 0x3e, - 0xcf, 0x76, 0xc4, 0x03, 0xee, 0xf1, 0x61, 0x3a, 0xa2, 0xa7, 0x46, 0xa3, 0x07, 0xae, 0xd1, 0x53, - 0x2d, 0xdb, 0x06, 0xd2, 0xbd, 0x0a, 0xf2, 0x26, 0x2a, 0x34, 0xb8, 0xb7, 0x77, 0x81, 0x1e, 0x36, - 0x69, 0x93, 0xba, 0x0f, 0x28, 0xe7, 0x89, 0x7d, 0xc0, 0xbf, 0xb8, 0xf2, 0xfc, 0xa0, 0xa1, 0x59, - 0xd0, 0xb6, 0x42, 0x04, 0xe5, 0x22, 0x37, 0x41, 0xa1, 0xdb, 0x55, 0x81, 0x23, 0x34, 0x74, 0x65, - 0xf6, 0x4b, 0x68, 0x42, 0x66, 0xaf, 0xc6, 0x9a, 0xa1, 0x50, 0xa9, 0x47, 0x70, 0xb4, 0x94, 0x9c, - 0xf4, 0x64, 0x70, 0xec, 0xc0, 0x19, 0xfc, 0x49, 0x43, 0x67, 0xf3, 0x55, 0xaa, 0x3c, 0xda, 0xe8, - 0x64, 0x00, 0x57, 0x52, 0xa9, 0x93, 0x49, 0xea, 0x85, 0xc1, 0x49, 0x5d, 0xf1, 0xb9, 0xb0, 0xa7, - 0x82, 0x6e, 0xdb, 0x2f, 0x2e, 0xc7, 0x77, 0x50, 0x11, 0xc4, 0xaf, 0x91, 0xc0, 0x77, 0x89, 0x60, - 0xf1, 0x8a, 0xbf, 0x4e, 0x6b, 0x9b, 0xb5, 0x20, 0x8d, 0x15, 0x9f, 0x41, 0x47, 0x5a, 0x24, 0x70, - 0x88, 0xeb, 0xc6, 0x90, 0xe4, 0xa3, 0xf6, 0xe1, 0x16, 0x09, 0xee, 0xb9, 0x6e, 0x6c, 0x50, 0x54, - 0xea, 0x4b, 0x56, 0xc1, 0x57, 0x24, 0x3b, 0xf0, 0xd7, 0xa9, 0x7a, 0x49, 0x2e, 0xe6, 0xc6, 0x9c, - 0x63, 0x22, 0x71, 0x93, 0xfc, 0x33, 0xee, 0x2a, 0x37, 0x6f, 0xd3, 0x80, 0x7a, 0x20, 0x3b, 0x4f, - 0xa4, 0x4b, 0xbb, 0x45, 0xba, 0x54, 0x8a, 0xf4, 0xd0, 0xb9, 0xfe, 0x6c, 0xa5, 0x72, 0x49, 0xd2, - 0x33, 0x2a, 0x2f, 0xe5, 0xaa, 0xcc, 0xb3, 0x91, 0x38, 0x02, 0x99, 0x5f, 0x64, 0x5f, 0xbb, 0x35, - 0x12, 0x7c, 0x48, 0xc5, 0x7f, 0xfa, 0x29, 0xff, 0xaa, 0xa9, 0xe7, 0xac, 0x4b, 0x80, 0x8a, 0xf0, - 0x4d, 0x84, 0x5a, 0x69, 0x8a, 0xd3, 0xee, 0x2b, 0xee, 0x5d, 0x09, 0x3b, 0xc3, 0xc0, 0x57, 0x11, - 0x16, 0x4c, 0x90, 0xc0, 0x69, 0x31, 0xe1, 0x87, 0x9e, 0x13, 0xb1, 0xcf, 0x68, 0x0c, 0x62, 0xc7, - 0xec, 0x13, 0x70, 0xb3, 0x06, 0x17, 0xab, 0xc9, 0x79, 0x4f, 0x7b, 0x8e, 0x1d, 0xbc, 0x3d, 0xff, - 0x19, 0x45, 0x93, 0xdd, 0x4f, 0xef, 0xcb, 0xe8, 0x58, 0x3b, 0x95, 0x55, 0x1a, 0xab, 0x6c, 0x4e, - 0xa4, 0xd9, 0xac, 0xd2, 0x18, 0x2f, 0xa2, 0xd3, 0x5d, 0xaf, 0xb3, 0xe3, 0x87, 0x82, 0xc6, 0x2d, - 0x12, 0xa8, 0x57, 0xe0, 0x54, 0xf6, 0x99, 0xbe, 0xaf, 0xee, 0x92, 0x08, 0xd7, 0xfd, 0x98, 0x0b, - 0xa7, 0x1a, 0xb0, 0xda, 0xa7, 0x4e, 0x9d, 0xfa, 0x5e, 0x5d, 0x80, 0xf6, 0x82, 0x7d, 0x02, 0x6e, - 0x2a, 0xc9, 0xc5, 0x32, 0x9c, 0xe3, 0x65, 0x34, 0x15, 0x90, 0x36, 0x38, 0xd9, 0x6e, 0x66, 0x0a, - 0x10, 0xa6, 0x6e, 0xca, 0xcd, 0xc6, 0x4c, 0x57, 0x1f, 0xf3, 0xa3, 0x74, 0xf5, 0xa9, 0x14, 0x9e, - 0xfc, 0x59, 0xd2, 0xec, 0xc9, 0x84, 0x08, 0xb6, 0x92, 0x1b, 0x7c, 0x19, 0x9d, 0x24, 0x51, 0xe4, - 0xd4, 0x09, 0xaf, 0x3b, 0x31, 0x63, 0xc2, 0xa9, 0xd3, 0x8d, 0x99, 0x43, 0xd0, 0xc3, 0xc7, 0x49, - 0x14, 0x2d, 0x13, 0x5e, 0xb7, 0x19, 0x13, 0xcb, 0x74, 0x03, 0xcf, 0xa3, 0x69, 0x4e, 0x49, 0x40, - 0x63, 0xa7, 0xcd, 0x48, 0xc0, 0xe3, 0x00, 0x3e, 0x21, 0xaf, 0xee, 0x49, 0x4a, 0x02, 0x9f, 0x43, - 0x27, 0x15, 0x5c, 0x85, 0x44, 0x78, 0x7d, 0xe6, 0x30, 0x80, 0xa7, 0xe4, 0x85, 0x8c, 0x88, 0xf0, - 0xfa, 0xf5, 0xed, 0x09, 0x74, 0x08, 0x9a, 0x07, 0x7f, 0xa9, 0xa1, 0x71, 0xb9, 0xba, 0xe0, 0x8b, - 0xfd, 0x9e, 0xa7, 0x9e, 0x3d, 0x49, 0xbf, 0x34, 0x18, 0x28, 0xcb, 0x67, 0x9c, 0xff, 0xea, 0xb7, - 0xbf, 0xbf, 0x19, 0x7d, 0x09, 0xcf, 0x5a, 0xfd, 0xd7, 0x36, 0xfc, 0xad, 0x86, 0x8e, 0xb6, 0x57, - 0x1d, 0x3c, 0xd7, 0xdf, 0x78, 0xef, 0x16, 0xa5, 0x5f, 0x19, 0x0a, 0xab, 0xb4, 0x94, 0x41, 0xcb, - 0x15, 0x7c, 0xd9, 0xea, 0xbb, 0x20, 0x72, 0xeb, 0x71, 0xbb, 0xdb, 0xde, 0x98, 0xdb, 0xc2, 0x5f, - 0x6b, 0x08, 0x75, 0xb6, 0x19, 0x3c, 0xc8, 0x5d, 0x76, 0xad, 0xd2, 0xaf, 0x0e, 0x07, 0x1e, 0x2a, - 0x51, 0x6a, 0x13, 0x7a, 0xaa, 0xa1, 0x63, 0xd9, 0x05, 0x05, 0xcf, 0xf7, 0xf7, 0x91, 0xb3, 0xe4, - 0xe8, 0xe6, 0xb0, 0x70, 0x25, 0x6a, 0x0e, 0x44, 0xbd, 0x82, 0x8d, 0x5c, 0x51, 0x5d, 0x1f, 0x1d, - 0xfe, 0x3e, 0x2d, 0x22, 0x0c, 0xac, 0x41, 0x45, 0xcc, 0xcc, 0xf5, 0x81, 0x45, 0xcc, 0x4e, 0x57, - 0xe3, 0x36, 0x48, 0x5a, 0xc4, 0xd7, 0x87, 0x2e, 0xa2, 0xd5, 0x90, 0x93, 0x95, 0xe3, 0x1f, 0x35, - 0x34, 0xd5, 0x33, 0xb5, 0xf1, 0xb5, 0xfe, 0xce, 0xf3, 0xd7, 0x10, 0xbd, 0xbc, 0x0f, 0x86, 0x12, - 0xbd, 0x00, 0xa2, 0xe7, 0xf1, 0x95, 0x3d, 0x44, 0xdf, 0x96, 0x33, 0xbf, 0xa3, 0xf6, 0x67, 0x0d, - 0xe1, 0xe7, 0xc7, 0x24, 0x5e, 0xe8, 0xef, 0xbe, 0xef, 0x50, 0xd7, 0x17, 0xf7, 0x47, 0x52, 0xb2, - 0xef, 0x80, 0xec, 0x1b, 0x78, 0x21, 0x57, 0x76, 0x7b, 0x5a, 0xc0, 0x1c, 0x05, 0xa6, 0xf5, 0x38, - 0x5d, 0x1d, 0xb6, 0xf0, 0x2f, 0x1a, 0x9a, 0xce, 0x99, 0x9f, 0x78, 0x0f, 0x29, 0xfd, 0x07, 0xbe, - 0x7e, 0x63, 0x9f, 0x2c, 0x15, 0xc1, 0x5d, 0x88, 0xe0, 0x26, 0x5e, 0xcc, 0x8d, 0xc0, 0x6d, 0x33, - 0xb3, 0x21, 0xa4, 0x8b, 0xc5, 0x56, 0xd2, 0x2f, 0x13, 0x99, 0xe1, 0x8a, 0x07, 0x7d, 0xd1, 0x5d, - 0x4b, 0x80, 0x3e, 0x3f, 0x24, 0x5a, 0x49, 0x7d, 0x0b, 0xa4, 0xde, 0xc2, 0xaf, 0x0d, 0xdf, 0xd8, - 0x9d, 0x0a, 0x70, 0x2a, 0x2a, 0xef, 0x3f, 0xdb, 0x29, 0x6a, 0xdb, 0x3b, 0x45, 0xed, 0xaf, 0x9d, - 0xa2, 0xf6, 0x64, 0xb7, 0x38, 0xb2, 0xbd, 0x5b, 0x1c, 0xf9, 0x7d, 0xb7, 0x38, 0xf2, 0xf1, 0x35, - 0xcf, 0x17, 0xf5, 0x66, 0xd5, 0xac, 0xb1, 0x46, 0x6a, 0xbc, 0x56, 0x27, 0x7e, 0xd8, 0xf6, 0xb4, - 0xd1, 0xf1, 0x25, 0x36, 0x23, 0xca, 0xab, 0xe3, 0x30, 0xcd, 0x16, 0xfe, 0x0d, 0x00, 0x00, 0xff, - 0xff, 0x4c, 0x28, 0x27, 0x93, 0x24, 0x10, 0x00, 0x00, + // 1354 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6f, 0xdc, 0xc4, + 0x1b, 0x8e, 0x93, 0x4d, 0xda, 0xbc, 0x69, 0x9a, 0x64, 0xd2, 0xf6, 0x97, 0x3a, 0xfd, 0x6d, 0x8a, + 0x0b, 0xfd, 0x48, 0x1b, 0xbb, 0x69, 0x52, 0xa0, 0x1f, 0x50, 0x35, 0xe5, 0x23, 0x41, 0x2d, 0x4a, + 0x0d, 0xea, 0x81, 0x8b, 0x19, 0xaf, 0x27, 0x5e, 0x0b, 0xdb, 0xe3, 0x7a, 0x66, 0x97, 0x44, 0xa5, + 0x08, 0x71, 0xe6, 0x50, 0x89, 0x03, 0xe2, 0x82, 0x40, 0x1c, 0xf9, 0x0b, 0x10, 0x1c, 0x38, 0xf6, + 0x58, 0xc4, 0x85, 0x13, 0xa0, 0x16, 0xf1, 0x77, 0x20, 0xcf, 0x8c, 0x77, 0xbd, 0x1b, 0x6f, 0x77, + 0x1b, 0x55, 0xdc, 0x76, 0x67, 0xde, 0xe7, 0x7d, 0x9f, 0xf7, 0x79, 0xc7, 0x33, 0x0f, 0x2c, 0xb8, + 0xd8, 0xdd, 0x09, 0x69, 0x6c, 0x91, 0x84, 0xd6, 0xea, 0x41, 0xec, 0x5b, 0xcd, 0x65, 0xeb, 0x6e, + 0x83, 0xa4, 0x3b, 0x66, 0x92, 0x52, 0x4e, 0xd1, 0xac, 0x0a, 0x30, 0xf3, 0x00, 0xb3, 0xb9, 0xac, + 0x1f, 0xf2, 0xa9, 0x4f, 0xc5, 0xbe, 0x95, 0xfd, 0x92, 0xa1, 0xfa, 0x82, 0x4f, 0xa9, 0x1f, 0x12, + 0x4b, 0xfc, 0x73, 0x1b, 0x5b, 0x16, 0x0f, 0x22, 0xc2, 0x38, 0x8e, 0x12, 0x15, 0x70, 0x4c, 0x05, + 0xe0, 0x24, 0xb0, 0x70, 0x1c, 0x53, 0x8e, 0x79, 0x40, 0x63, 0xa6, 0x76, 0x17, 0x6b, 0x94, 0x45, + 0x94, 0x59, 0x2e, 0x66, 0x44, 0x52, 0xb0, 0x9a, 0xcb, 0x2e, 0xe1, 0x78, 0xd9, 0x4a, 0xb0, 0x1f, + 0xc4, 0x22, 0x58, 0xc5, 0x1e, 0x2f, 0xa3, 0x9d, 0xe0, 0x14, 0x47, 0x79, 0x36, 0xa3, 0x2c, 0xa2, + 0xd5, 0x83, 0x88, 0x31, 0x0e, 0x01, 0xba, 0x9d, 0xd5, 0xd9, 0x14, 0x40, 0x9b, 0xdc, 0x6d, 0x10, + 0xc6, 0x8d, 0x4d, 0x98, 0xed, 0x58, 0x65, 0x09, 0x8d, 0x19, 0x41, 0x97, 0x60, 0x4c, 0x16, 0x98, + 0xd3, 0x8e, 0x6b, 0xa7, 0x27, 0x2e, 0xcc, 0x9b, 0x25, 0xca, 0x98, 0x12, 0xb4, 0x56, 0x79, 0xf8, + 0xc7, 0xc2, 0x90, 0xad, 0x00, 0xc6, 0x2a, 0x1c, 0x16, 0x19, 0xdf, 0xcc, 0x02, 0x37, 0xe2, 0x2d, + 0xaa, 0x4a, 0xa1, 0x79, 0x18, 0x17, 0x60, 0x27, 0x6e, 0x44, 0x22, 0x6d, 0xc5, 0xde, 0x2f, 0x16, + 0xde, 0x6d, 0x44, 0x86, 0x0d, 0x47, 0xba, 0x51, 0x8a, 0xca, 0xab, 0x30, 0x2a, 0xa2, 0x14, 0x13, + 0xa3, 0x94, 0x89, 0x80, 0xe5, 0x10, 0x5b, 0x02, 0x8c, 0x0f, 0x8b, 0x39, 0x59, 0x91, 0xca, 0x5b, + 0x00, 0x6d, 0x95, 0x55, 0xe2, 0x93, 0xa6, 0x1c, 0x89, 0x99, 0x8d, 0xc4, 0x94, 0xa7, 0x42, 0x8d, + 0xc4, 0xdc, 0xc4, 0x3e, 0x51, 0x58, 0xbb, 0x80, 0x34, 0xbe, 0xd1, 0xe0, 0x7f, 0xbb, 0x4a, 0x28, + 0xde, 0x97, 0x61, 0x4c, 0xd0, 0xc8, 0x24, 0x1c, 0x19, 0x90, 0xb8, 0x42, 0xa0, 0xb7, 0x3b, 0xf8, + 0x0d, 0x0b, 0x7e, 0xa7, 0xfa, 0xf2, 0x53, 0x49, 0x8a, 0x04, 0x75, 0x98, 0x13, 0xfc, 0x6e, 0x34, + 0xd2, 0x94, 0xc4, 0x5c, 0x55, 0x93, 0xa3, 0xf7, 0xe1, 0x68, 0xc9, 0x9e, 0x62, 0x7f, 0x02, 0x26, + 0x6b, 0x72, 0xdd, 0x69, 0xab, 0x5f, 0xb1, 0x0f, 0xd4, 0x0a, 0xc1, 0xe8, 0x25, 0x38, 0x28, 0x27, + 0xea, 0xd2, 0x46, 0xec, 0xe1, 0x74, 0x47, 0x50, 0xad, 0xd8, 0x93, 0x62, 0x75, 0x4d, 0x2d, 0x1a, + 0x9f, 0x14, 0x4f, 0xc4, 0x2d, 0xe6, 0xb3, 0x41, 0x4e, 0x44, 0xd7, 0x8c, 0x86, 0xf7, 0x3c, 0xa3, + 0xef, 0xb4, 0xe2, 0x31, 0x90, 0xe5, 0x55, 0x93, 0xaf, 0x43, 0x25, 0x62, 0x7e, 0x3e, 0xa0, 0xc5, + 0xd2, 0x01, 0xdd, 0x6e, 0x90, 0x06, 0xf1, 0x6e, 0x11, 0xc6, 0x8a, 0x1a, 0x0b, 0xdc, 0xf3, 0x1b, + 0xd3, 0xf7, 0x1a, 0xcc, 0x0b, 0x8e, 0x37, 0x31, 0x27, 0x8c, 0x97, 0x0a, 0x15, 0x7b, 0x1d, 0x93, + 0xd8, 0x4f, 0x62, 0x4f, 0x4e, 0x61, 0x01, 0x26, 0xa4, 0x8a, 0x35, 0xda, 0x88, 0xb9, 0x1a, 0x01, + 0x88, 0xa5, 0x1b, 0xd9, 0x4a, 0x97, 0x92, 0x23, 0x7b, 0x56, 0xf2, 0x27, 0x0d, 0x8e, 0x95, 0xb3, + 0x54, 0x7a, 0xda, 0x30, 0x13, 0x8a, 0x2d, 0xc9, 0xd4, 0x29, 0x88, 0x7b, 0xb2, 0xbf, 0xb8, 0x37, + 0x03, 0xc6, 0xed, 0xa9, 0xb0, 0x33, 0xf7, 0xf3, 0xd3, 0xf8, 0x0a, 0x54, 0x05, 0xf9, 0x3b, 0x38, + 0x0c, 0x3c, 0xcc, 0x69, 0x7a, 0x33, 0xd8, 0x22, 0xb5, 0x9d, 0x5a, 0x98, 0xf7, 0x8a, 0x8e, 0xc2, + 0xfe, 0x26, 0x0e, 0x1d, 0xec, 0x79, 0xa9, 0x10, 0x79, 0xdc, 0xde, 0xd7, 0xc4, 0xe1, 0x75, 0xcf, + 0x4b, 0x0d, 0x02, 0x0b, 0x3d, 0xc1, 0xaa, 0xf9, 0x35, 0x89, 0x0e, 0x83, 0x2d, 0xa2, 0x6e, 0x94, + 0x53, 0xa5, 0x3d, 0x97, 0xa4, 0xc8, 0xca, 0x64, 0xff, 0x8c, 0xab, 0xaa, 0xcc, 0x1b, 0x24, 0x24, + 0xbe, 0xa0, 0x5d, 0x46, 0xd2, 0x23, 0x9d, 0x24, 0x3d, 0x22, 0x49, 0xfa, 0x70, 0xbc, 0x37, 0x5a, + 0xb1, 0xbc, 0x21, 0xe1, 0x05, 0x96, 0xa7, 0x4b, 0x59, 0x96, 0xe5, 0xc8, 0x0a, 0x09, 0x9a, 0x9f, + 0x16, 0x6f, 0xbd, 0x3b, 0x38, 0x7c, 0x8f, 0xf0, 0xff, 0xf4, 0x93, 0xfe, 0x55, 0x53, 0xd7, 0x5a, + 0x07, 0x81, 0xd6, 0x47, 0x0d, 0xcd, 0x5c, 0xe2, 0xfc, 0xf4, 0x55, 0x9f, 0x3e, 0x09, 0xbb, 0x80, + 0x40, 0xe7, 0x00, 0x71, 0xca, 0x71, 0xe8, 0x34, 0x29, 0x0f, 0x62, 0xdf, 0x49, 0xe8, 0xc7, 0x24, + 0x15, 0x64, 0x47, 0xec, 0x69, 0xb1, 0x73, 0x47, 0x6c, 0x6c, 0x66, 0xeb, 0x5d, 0xc7, 0x73, 0x64, + 0xef, 0xc7, 0xf3, 0x9f, 0x61, 0x98, 0xec, 0xbc, 0x82, 0x5f, 0x80, 0x03, 0x2d, 0x29, 0x5d, 0x92, + 0x2a, 0x35, 0x27, 0x72, 0x35, 0x5d, 0x92, 0xa2, 0x55, 0x38, 0xd2, 0x71, 0x4b, 0x3b, 0x41, 0xcc, + 0x49, 0xda, 0xc4, 0xa1, 0xba, 0x05, 0x0e, 0x15, 0xaf, 0xeb, 0x0d, 0xb5, 0x97, 0x75, 0xb8, 0x15, + 0xa4, 0x8c, 0x3b, 0x6e, 0x48, 0x6b, 0x1f, 0x39, 0x75, 0x12, 0xf8, 0x75, 0x2e, 0xb8, 0x57, 0xec, + 0x69, 0xb1, 0xb3, 0x96, 0x6d, 0xac, 0x8b, 0x75, 0xb4, 0x0e, 0x53, 0x21, 0x6e, 0x05, 0x67, 0x2e, + 0x67, 0xae, 0x22, 0xda, 0xd4, 0x4d, 0xe9, 0x70, 0xcc, 0xdc, 0x02, 0x99, 0xef, 0xe7, 0x16, 0x68, + 0xad, 0xf2, 0xe0, 0xcf, 0x05, 0xcd, 0x9e, 0xcc, 0x80, 0x22, 0x57, 0xb6, 0x83, 0xce, 0xc0, 0x0c, + 0x4e, 0x12, 0xa7, 0x8e, 0x59, 0xdd, 0x49, 0x29, 0xe5, 0x4e, 0x9d, 0x6c, 0xcf, 0x8d, 0x8a, 0x33, + 0x7c, 0x10, 0x27, 0xc9, 0x3a, 0x66, 0x75, 0x9b, 0x52, 0xbe, 0x4e, 0xb6, 0xd1, 0x12, 0xcc, 0x32, + 0x82, 0x43, 0x92, 0x3a, 0x2d, 0x44, 0x16, 0x3c, 0x26, 0x82, 0xa7, 0xe5, 0xd6, 0x75, 0x09, 0xc9, + 0xc2, 0x17, 0x61, 0x46, 0x85, 0xab, 0x96, 0x30, 0xab, 0xcf, 0xed, 0x13, 0xc1, 0x53, 0x72, 0x43, + 0x76, 0x84, 0x59, 0xdd, 0xf8, 0x51, 0x13, 0xcf, 0xd1, 0xee, 0x4b, 0x1d, 0xcd, 0xc2, 0x28, 0xdf, + 0x76, 0x02, 0x4f, 0x7d, 0x57, 0x15, 0xbe, 0xbd, 0xe1, 0xa1, 0xc3, 0x30, 0x16, 0x31, 0x3f, 0x5b, + 0x1d, 0x16, 0xab, 0xa3, 0x11, 0xf3, 0x37, 0xbc, 0x6c, 0x38, 0x25, 0xea, 0x4d, 0xb8, 0x05, 0xe1, + 0xae, 0x01, 0xec, 0x41, 0xb3, 0x71, 0xb7, 0xa5, 0xd7, 0x34, 0x8c, 0x44, 0xcc, 0x57, 0x0a, 0x65, + 0x3f, 0x8d, 0x26, 0xcc, 0xec, 0xba, 0x32, 0x07, 0x39, 0x27, 0xf9, 0x43, 0x37, 0xbc, 0xb7, 0x87, + 0xee, 0xc2, 0xa3, 0x09, 0x18, 0x15, 0x1f, 0x1c, 0xfa, 0x4c, 0x83, 0x31, 0x69, 0xfb, 0xd0, 0xa9, + 0x5e, 0x69, 0xba, 0x3c, 0xa6, 0x7e, 0xba, 0x7f, 0xa0, 0xac, 0x66, 0x9c, 0xf8, 0xfc, 0xb7, 0xbf, + 0xbf, 0x1c, 0xfe, 0x3f, 0x9a, 0xb7, 0x7a, 0x5b, 0x5e, 0xf4, 0x95, 0x06, 0xe3, 0x2d, 0x9b, 0x88, + 0x16, 0x7b, 0x27, 0xef, 0x76, 0xa0, 0xfa, 0xd9, 0x81, 0x62, 0x15, 0x97, 0x65, 0xc1, 0xe5, 0x2c, + 0x3a, 0x63, 0xf5, 0x34, 0xd7, 0xcc, 0xba, 0xd7, 0x52, 0xfe, 0xb5, 0xc5, 0xfb, 0xe8, 0x0b, 0x0d, + 0xa0, 0xed, 0x04, 0x51, 0xbf, 0x72, 0x45, 0x4b, 0xaa, 0x9f, 0x1b, 0x2c, 0x78, 0x20, 0xa1, 0x94, + 0x8b, 0xfc, 0x5a, 0x83, 0x03, 0x45, 0x73, 0x87, 0x96, 0x7a, 0xd7, 0x28, 0x31, 0x88, 0xba, 0x39, + 0x68, 0xb8, 0x22, 0xb5, 0x28, 0x48, 0xbd, 0x88, 0x8c, 0x52, 0x52, 0x1d, 0x17, 0x15, 0xfa, 0x36, + 0x1f, 0xa2, 0x78, 0xe4, 0xfb, 0x0d, 0xb1, 0xe0, 0x85, 0xfa, 0x0e, 0xb1, 0xe8, 0x48, 0x8c, 0xcb, + 0x82, 0xd2, 0x2a, 0xba, 0x30, 0xf0, 0x10, 0xad, 0x48, 0x7e, 0x01, 0x0c, 0xfd, 0xa0, 0xc1, 0x54, + 0x97, 0xd3, 0x41, 0xe7, 0x7b, 0x17, 0x2f, 0xb7, 0x6e, 0xfa, 0xf2, 0x33, 0x20, 0x14, 0xe9, 0x15, + 0x41, 0x7a, 0x09, 0x9d, 0x7d, 0x0a, 0xe9, 0xcb, 0xd2, 0x27, 0xb5, 0xd9, 0xfe, 0xac, 0x01, 0xda, + 0x6d, 0x2d, 0xd0, 0x4a, 0xef, 0xf2, 0x3d, 0x8d, 0x90, 0xbe, 0xfa, 0x6c, 0x20, 0x45, 0xfb, 0x8a, + 0xa0, 0x7d, 0x11, 0xad, 0x94, 0xd2, 0x6e, 0xbd, 0xb0, 0xc2, 0x7b, 0x08, 0xa4, 0x75, 0x2f, 0xb7, + 0x5b, 0xf7, 0xd1, 0x2f, 0x1a, 0xcc, 0x96, 0x78, 0x0e, 0xf4, 0x14, 0x2a, 0xbd, 0x4d, 0x92, 0x7e, + 0xf1, 0x19, 0x51, 0xaa, 0x83, 0xab, 0xa2, 0x83, 0x97, 0xd1, 0x6a, 0x69, 0x07, 0x5e, 0x0b, 0x59, + 0x6c, 0x21, 0x37, 0x63, 0xf7, 0xb3, 0xf3, 0x32, 0x51, 0x30, 0x24, 0xa8, 0xdf, 0x17, 0xdd, 0x61, + 0x9c, 0xf4, 0xa5, 0x01, 0xa3, 0x15, 0xd5, 0x6b, 0x82, 0xea, 0x25, 0xf4, 0xca, 0xe0, 0x07, 0xbb, + 0x3d, 0x01, 0x46, 0xf8, 0xda, 0x3b, 0x0f, 0x1f, 0x57, 0xb5, 0x47, 0x8f, 0xab, 0xda, 0x5f, 0x8f, + 0xab, 0xda, 0x83, 0x27, 0xd5, 0xa1, 0x47, 0x4f, 0xaa, 0x43, 0xbf, 0x3f, 0xa9, 0x0e, 0x7d, 0x70, + 0xde, 0x0f, 0x78, 0xbd, 0xe1, 0x9a, 0x35, 0x1a, 0xe5, 0xc9, 0x6b, 0x75, 0x1c, 0xc4, 0xad, 0x4a, + 0xdb, 0xed, 0x5a, 0x7c, 0x27, 0x21, 0xcc, 0x1d, 0x13, 0xaf, 0xd9, 0xca, 0xbf, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x82, 0xd7, 0x47, 0xa2, 0x60, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2277,6 +2422,107 @@ func (m *EpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueuedMessageResponse) 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 *QueuedMessageResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueuedMessageResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msg) > 0 { + i -= len(m.Msg) + copy(dAtA[i:], m.Msg) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Msg))) + i-- + dAtA[i] = 0x2a + } + if m.BlockTime != nil { + n14, err14 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.BlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime):]) + if err14 != nil { + return 0, err14 + } + i -= n14 + i = encodeVarintQuery(dAtA, i, uint64(n14)) + i-- + dAtA[i] = 0x22 + } + if m.BlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x18 + } + if len(m.MsgId) > 0 { + i -= len(m.MsgId) + copy(dAtA[i:], m.MsgId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.MsgId))) + i-- + dAtA[i] = 0x12 + } + if len(m.TxId) > 0 { + i -= len(m.TxId) + copy(dAtA[i:], m.TxId) + i = encodeVarintQuery(dAtA, i, uint64(len(m.TxId))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueuedMessageList) 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 *QueuedMessageList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueuedMessageList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Msgs) > 0 { + for iNdEx := len(m.Msgs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Msgs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.EpochNumber != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EpochNumber)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2586,6 +2832,52 @@ func (m *EpochResponse) Size() (n int) { return n } +func (m *QueuedMessageResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.TxId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.MsgId) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.BlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BlockHeight)) + } + if m.BlockTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime) + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Msg) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueuedMessageList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochNumber != 0 { + n += 1 + sovQuery(uint64(m.EpochNumber)) + } + if len(m.Msgs) > 0 { + for _, e := range m.Msgs { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -3387,7 +3679,7 @@ func (m *QueryEpochMsgsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Msgs = append(m.Msgs, &QueuedMessage{}) + m.Msgs = append(m.Msgs, &QueuedMessageResponse{}) if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -4512,6 +4804,310 @@ func (m *EpochResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueuedMessageResponse) 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 ErrIntOverflowQuery + } + 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: QueuedMessageResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueuedMessageResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MsgId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MsgId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockTime == nil { + m.BlockTime = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.BlockTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msg", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msg = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueuedMessageList) 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 ErrIntOverflowQuery + } + 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: QueuedMessageList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueuedMessageList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType) + } + m.EpochNumber = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochNumber |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Msgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Msgs = append(m.Msgs, &QueuedMessageResponse{}) + if err := m.Msgs[len(m.Msgs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From 047e6943d5f8d121730831a28fa874f78451e7f8 Mon Sep 17 00:00:00 2001 From: xfu Date: Fri, 8 Mar 2024 07:37:45 +0800 Subject: [PATCH 039/119] chore: fix typos in Babylon Architecture (#538) --- docs/architecture.md | 4 +-- docs/run-node.md | 15 +++++++++-- docs/staking-script.md | 58 +++++++++++++++++++++--------------------- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 0a98a4938..329e8ec01 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -108,7 +108,7 @@ an alarm will be raised by the monitor program. A standalone program that submits Babylon checkpoints to Bitcoin as Bitcoin transactions embedding data -utilising the `OP_RETURN` Bitcoin script code. +utilizing the `OP_RETURN` Bitcoin script code. ### [Vigilante Reporter](https://github.com/babylonchain/vigilante) @@ -187,7 +187,7 @@ finality provider's private keys. ### [Covenant Emulator](https://github.com/babylonchain/covenant-emulator) -A standalone program utilised by the covenant emulation committee members. +A standalone program utilized by the covenant emulation committee members. It emulates [covenant](https://covenants.info) functionality by monitoring for pending staking requests, verifying their contents, and diff --git a/docs/run-node.md b/docs/run-node.md index 705bb72f1..8e1b1be41 100644 --- a/docs/run-node.md +++ b/docs/run-node.md @@ -5,9 +5,11 @@ installed. If the repository was only built, then `./build/babylond` should be used in its place. ### Generating the node configuration + The configuration for a single node can be created through the `testnet` command. While the `testnet` command can create an arbitrary number of nodes that communicate on a testnet, here we focus on the setup of a single node. + ```console babylond testnet \ --v 1 \ @@ -18,6 +20,7 @@ babylond testnet \ ``` The flags specify the following: + - `--output-dir `: Specifies that the testnet files should reside under this directory. - `--v `: Leads to the creation of `N` nodes, each one residing under the @@ -27,10 +30,11 @@ The flags specify the following: second one on `192.168.10.3:46656` etc. - `--keyring-backend {os,file,test}`: Specifies the backend to use for the keyring. Available choices include `os`, `file`, and `test`. We use `test` for convenience. -- `--chain-id`: An identifier for the chain. Useful when perrforming operations +- `--chain-id`: An identifier for the chain. Useful when performing operations later. In this case, we generated a single node. If we take a look under `.testnet`: + ```console $ ls .testnet gentxs node0 @@ -41,12 +45,14 @@ transactions that assign bbn tokens to a single address that is defined for each node. The `node0` directory contains the the following, + ```console $ ls .testnet/node0/babylond config data key_seed.json keyring-test ``` A brief description of the contents: + - `config`: Contains the configuration files for the node. - `data`: Contains the database storage for the node. - `key_seed.json`: Seed to generate the keys maintained by the keyring. @@ -57,6 +63,7 @@ A brief description of the contents: The keys for this node can be pointed to by the `node{i}` name. ### Running the node + ```console babylond start --home ./.testnet/node0/babylond ``` @@ -69,6 +76,7 @@ The logs for a particular node can be found under ### Performing queries After building a node and starting it, you can perform queries. + ```console babylond --home .testnet/node{i}/babylond/ --chain-id \ query @@ -76,6 +84,7 @@ babylond --home .testnet/node{i}/babylond/ --chain-id \ For example, in order to get the hashes maintained by the `btcligthclient` module: + ```console $ babylond --home .testnet/node0/babylond/ --chain-id chain-test query btclightclient hashes @@ -89,6 +98,7 @@ pagination: ### Submitting transactions After building a node and running it, one can send transactions as follows: + ```console babylond --home .testnet/node{i}/babylond --chain-id \ --keyring-backend {os,file,test} --fees \ @@ -106,6 +116,7 @@ and `block` means after the transaction has been processed by the next block. For example, in the `btclightclient` module, in order to submit a header, one should: + ```console babylond --home .testnet/node0/babylond --chain-id chain-test \ --keyring-backend test --fees 100bbn \ @@ -122,6 +133,7 @@ make localnet-start ``` The corresponding node directories can be found under `.testnets` + ```console $ ls .testnets gentxs node0 node1 node2 node3 @@ -132,4 +144,3 @@ gentxs node0 node1 node2 node3 ```console make test ``` - diff --git a/docs/staking-script.md b/docs/staking-script.md index 53ed7d48d..84984ed3b 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -100,8 +100,8 @@ The requirements for a valid staking transaction are: - it can contain arbitrary number of inputs - it can contain arbitrary number of outputs. One of those outputs must be -a Taproot output committing to the BTC staking scripts recognized by Babylon. -Henceforth known as `Staking Output`. + a Taproot output committing to the BTC staking scripts recognized by Babylon. + Henceforth known as `Staking Output`. ### Unbonding Transaction @@ -111,9 +111,9 @@ their stake before their originally committed timelock has expired. The requirements for a valid unbonding transaction are: - it contains exactly one input which points to staking transaction's `Staking - Output`. +Output`. - it contains exactly one output which must be a Taproot output committing to -the BTC unbonding scripts recognized by Babylon. Henceforth known as `Unbonding + the BTC unbonding scripts recognized by Babylon. Henceforth known as `Unbonding Output`. ### Slashing Transaction @@ -126,8 +126,8 @@ The requirements for a valid slashing transaction are: - it must have exactly one input pointing to either the staking output or the unbonding output - it must have exactly two outputs, the first sending the slashed fraction of -the funds to a burn address specified in the Babylon chain's parameters and the -second sending the remaining funds back to the BTC staker's address. + the funds to a burn address specified in the Babylon chain's parameters and the + second sending the remaining funds back to the BTC staker's address. - the fee for the slashing transactions must be larger than or equal to the minimal fee specified in Babylon's parameters @@ -164,9 +164,9 @@ where: - `` is the BTC staker's public key.. - `` is the lockup period denoted in Bitcoin blocks. The -timelock comes into effect after the Bitcoin transaction has been included in a -mined block. In essence, the script denotes that only the staker can unlock the -funds after the timelock has passed. It must be lower than `65535`. + timelock comes into effect after the Bitcoin transaction has been included in a + mined block. In essence, the script denotes that only the staker can unlock the + funds after the timelock has passed. It must be lower than `65535`. #### 2. Unbonding path @@ -183,9 +183,9 @@ where: - `Staker_PK` is the BTC staker's public key - `CovenantPk1..CovenantPkN` are the lexicographically sorted public keys of the -current covenant committee recognized by the Babylon chain + current covenant committee recognized by the Babylon chain - `CovenantThreshold` is a Babylon parameter specifying the number of how many -covenant committee member signatures are required. + covenant committee member signatures are required. Signatures from a quorum of the covenant committee are required to ensure that this script is not used for on-demand unlocking without the stake going through @@ -193,7 +193,7 @@ an unbonding period. reward all covenant members for their work. #### 3. Slashing path -The slashing path is utilised for punishing finality providers and their +The slashing path is utilized for punishing finality providers and their delegators in the case of double signing. It commits to a script: ``` @@ -209,9 +209,9 @@ where: - `FinalityProviderPk` is the BTC public key of the finality provider to which the staker delegates their stake - `CovenantPk1..CovenantPkN` are the lexicographically sorted public keys of the -current covenant committee members recognized by the Babylon chain + current covenant committee members recognized by the Babylon chain - `CovenantThreshold` is a Babylon parameter denoting how many covenant -committee member signatures are required. + committee member signatures are required. This path can only be executed with the collaboration of the BTC staker, finality provider, and covenant committee. @@ -220,8 +220,8 @@ It is used in following way: - for stake to become active, staker must publish pre signed slashing transaction - covenant committee validates such transaction, and publish its own signatures. - the only signature missing to send slashing transaction is finality provider -signature. If finality provider private key leaks due to infractions, anyone can -sign slashing transaction and send slashing transaction to Bitcoin network. + signature. If finality provider private key leaks due to infractions, anyone can + sign slashing transaction and send slashing transaction to Bitcoin network. #### Difference between Unbonding and Slashing Path @@ -231,16 +231,16 @@ The main difference between the unbonding and slashing paths is the existence of This leads to following system wide repercussions: - for staking request to become active, btc holder needs to provide valid -unbonding transaction in this staking request. This staking request will become -active only when `CovenantThreshold` signatures will be received by Babylon -chain. Lack of `FinalityProviderPk` in unbonding path, means that after -delegation becomes active, staker can send unbodning transaction any time -without asking finality provider for permission. + unbonding transaction in this staking request. This staking request will become + active only when `CovenantThreshold` signatures will be received by Babylon + chain. Lack of `FinalityProviderPk` in unbonding path, means that after + delegation becomes active, staker can send unbodning transaction any time + without asking finality provider for permission. - existence of `FinalityProviderPk` in slashing path, coupled with the fact that -btc holder needs to provide pre-signed slashing transaction which needs to be -signed by covenant committee for delegation request to become active, leads to -situation in which the only signature missing to send slashing transaction to -btc is signature of finality provider. + btc holder needs to provide pre-signed slashing transaction which needs to be + signed by covenant committee for delegation request to become active, leads to + situation in which the only signature missing to send slashing transaction to + btc is signature of finality provider. ### Unbonding output @@ -266,8 +266,8 @@ where: - Staker_PK is btc holder public key - Timelock_Blocks is unbonding time. It must be lower or equal 65535, but larger -than `max(MinUnbondingTime, CheckpointFinalizationTimeout)`. `MinUnbondingTime` -and `CheckpointFinalizationTimeout` are Babylon parameters. + than `max(MinUnbondingTime, CheckpointFinalizationTimeout)`. `MinUnbondingTime` + and `CheckpointFinalizationTimeout` are Babylon parameters. #### 2. Slashing path @@ -287,9 +287,9 @@ where: - `FinalityProviderPk` is the BTC public key of the finality provider to which the staker delegates their stake - `CovenantPk1..CovenantPkN` are the lexicographically sorted public keys of the -current covenant committee members recognized by the Babylon chain + current covenant committee members recognized by the Babylon chain - `CovenantThreshold` is a Babylon parameter denoting how many covenant -committee member signatures are required. + committee member signatures are required. #### Existence of Slashing path in Unbonding output From feef82caf2129aa3b73df707e349729953fc0eeb Mon Sep 17 00:00:00 2001 From: xfu Date: Mon, 11 Mar 2024 10:39:30 +0800 Subject: [PATCH 040/119] chore: fix typos in staking-script.md (#544) --- docs/staking-script.md | 6 ++-- proto/babylon/btcstaking/v1/btcstaking.proto | 2 +- x/btcstaking/README.md | 29 ++++++++++---------- x/btcstaking/types/btcstaking.pb.go | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/docs/staking-script.md b/docs/staking-script.md index 84984ed3b..e49d63873 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -92,7 +92,7 @@ There are three special transaction types recognized by the Babylon chain: A BTC holder gains voting power by creating a staking transaction. This is a Bitcoin transaction that commits a certain amount of to-be-staked bitcoin to -Babylon recognised BTC staking scripts. These scripts lock the stake for a +Babylon recognized BTC staking scripts. These scripts lock the stake for a chosen amount of BTC blocks and enable other features such as unbonding and slashable safety. @@ -105,7 +105,7 @@ The requirements for a valid staking transaction are: ### Unbonding Transaction -The BTC staker utilises the unbonding transaction when they want to unlock +The BTC staker utilizes the unbonding transaction when they want to unlock their stake before their originally committed timelock has expired. The requirements for a valid unbonding transaction are: @@ -271,7 +271,7 @@ where: #### 2. Slashing path -The slashing path is utilised for punishing finality providers and their +The slashing path is utilized for punishing finality providers and their delegators in the case of double signing. It commits to a script: ``` diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index b9902e597..93feda6d3 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -126,7 +126,7 @@ message BTCUndelegation { repeated CovenantAdaptorSignatures covenant_slashing_sigs = 5; // covenant_unbonding_sig_list is the list of signatures on the unbonding tx // by covenant members - // It must be provided after processing undelagate message by Babylon + // It must be provided after processing undelegate message by Babylon repeated SignatureInfo covenant_unbonding_sig_list = 6; } diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index 5635d6210..7ab64e7c0 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -5,7 +5,7 @@ providers and BTC delegations under them. This includes: - handling requests for creating finality providers, - handling requests for creating BTC delegations, -- handlilng requests for submitting signatures of covenant emulators, +- handling requests for submitting signatures of covenant emulators, - handling requests for unbonding BTC delegations, and - proactively refreshing the active set of finality providers and BTC delegations. @@ -35,15 +35,15 @@ providers and BTC delegations under them. This includes: ## Concepts -Babylon's Bitcoin Staking protocol allows bitcoin holders to *trustlessly* stake +Babylon's Bitcoin Staking protocol allows bitcoin holders to _trustlessly_ stake their bitcoins for providing economic security to the Babylon chain and other -Proof-of-Stake (PoS) blockchains, *without bridging their bitcoins elsewhere*. +Proof-of-Stake (PoS) blockchains, _without bridging their bitcoins elsewhere_. The protocol consists of the following participants: - **BTC staker (aka delegator)** who delegates their bitcoins to a finality provider in order to obtain staking reward. - **Finality provider** who receives bitcoin delegations and participates in the - *finality vote round* on top of the CometBFT consensus. + _finality vote round_ on top of the CometBFT consensus. - **Covenant emulation committee** who serves as the [covenants](https://covenants.info) to enforce spending conditions on bitcoins staked on Babylon. @@ -55,16 +55,16 @@ follows: 1. A finality provider registers itself on the BTC Staking module. 2. A BTC staker delegates some bitcoins to the finality provider. This involves the following steps: - 1. The BTC staker submits a *staking transaction* to Bitcoin. The staking + 1. The BTC staker submits a _staking transaction_ to Bitcoin. The staking transaction locks its bitcoins for a long period of time and specifies slashing conditions. 2. The BTC staker constructs the following transactions (whose specifications can be found [here](../../docs/staking-script.md)): - - a *slashing transaction* that can spend the staking transaction once the + - a _slashing transaction_ that can spend the staking transaction once the finality provider is slashed, - - an *unbonding transaction* that spends the staking transaction to start + - an _unbonding transaction_ that spends the staking transaction to start the early unbonding process, and - - an *unbonding slashing transaction* that can spend the unbonding + - an _unbonding slashing transaction_ that can spend the unbonding transaction once the finality provider is slashed. The BTC staker pre-signs the slashing transaction and unbonding slashing transaction. 3. Once the staking transaction is confirmed on Bitcoin, the BTC staker sends @@ -256,7 +256,7 @@ message BTCUndelegation { repeated CovenantAdaptorSignatures covenant_slashing_sigs = 5; // covenant_unbonding_sig_list is the list of signatures on the unbonding tx // by covenant members - // It must be provided after processing undelagate message by Babylon + // It must be provided after processing undelegate message by Babylon repeated SignatureInfo covenant_unbonding_sig_list = 6; } ``` @@ -432,7 +432,7 @@ Upon `MsgEditFinalityProvider`, a Babylon node will execute as follows: 4. Ensure the address `signer` corresponds to the Babylon public key `babylon_pk` in the finality provider. 5. Change the `description` and `commission` in the finality provider to the - values supplied in the message, and write back the finlaity provider to the + values supplied in the message, and write back the finality provider to the finality provider storage. ### MsgCreateBTCDelegation @@ -494,7 +494,7 @@ message MsgCreateBTCDelegation { Upon `MsgCreateBTCDelegation`, a Babylon node will execute as follows: 1. Ensure the given unbonding time is larger than `max(MinUnbondingTime, - CheckpointFinalizationTimeout)`, where `MinUnbondingTime` and +CheckpointFinalizationTimeout)`, where `MinUnbondingTime` and `CheckpointFinalizationTimeout` are module parameters from BTC Staking module and BTC Checkpoint module, respectively. 2. Verify a [proof of @@ -697,7 +697,7 @@ Upon `BeginBlock`, the BTC Staking module will execute the following: active BTC delegation, then record the reward distribution w.r.t. the active finality providers and active BTC delegations. -The logic is defined at [x/btcstaking/abci.go]((./abci.go)). +The logic is defined at [x/btcstaking/abci.go](./abci.go). ## Events @@ -713,7 +713,7 @@ message EventNewFinalityProvider { FinalityProvider fp = 1; } // - non-existing -> pending, which happens upon `MsgCreateBTCDelegation` // - pending -> active, which happens upon `MsgAddCovenantSigs` // - active -> unbonded, which happens upon `MsgBTCUndelegate` or upon staking tx timelock expires -message EventBTCDelegationStateUpdate { +message EventBTCDelegationStateUpdate { // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 1; @@ -721,7 +721,7 @@ message EventBTCDelegationStateUpdate { BTCDelegationStatus new_state = 2; } -// EventSelectiveSlashing is the event emitted when an adversarial +// EventSelectiveSlashing is the event emitted when an adversarial // finality provider selectively slashes a BTC delegation. This will // result in slashing of all BTC delegations under this finality provider. message EventSelectiveSlashing { @@ -754,4 +754,5 @@ message EventPowerDistUpdate { The BTC staking module provides a set of queries about the status of finality providers and BTC delegations, listed at [docs.babylonchain.io](https://docs.babylonchain.io/docs/developer-guides/grpcrestapi#tag/BTCStaking). + diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index dfd283b1c..fe2ec5157 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -415,7 +415,7 @@ type BTCUndelegation struct { CovenantSlashingSigs []*CovenantAdaptorSignatures `protobuf:"bytes,5,rep,name=covenant_slashing_sigs,json=covenantSlashingSigs,proto3" json:"covenant_slashing_sigs,omitempty"` // covenant_unbonding_sig_list is the list of signatures on the unbonding tx // by covenant members - // It must be provided after processing undelagate message by Babylon + // It must be provided after processing undelegate message by Babylon CovenantUnbondingSigList []*SignatureInfo `protobuf:"bytes,6,rep,name=covenant_unbonding_sig_list,json=covenantUnbondingSigList,proto3" json:"covenant_unbonding_sig_list,omitempty"` } From adb2dbc9934eebb9a4ebe5aefdff08b3f376b4fd Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 11 Mar 2024 07:29:37 -0300 Subject: [PATCH 041/119] chore: update query `ValidatorLifecycle` to return `ValidatorLifecycleResponse` (#536) * chore: update query `ValidatorLifecycle` to return `ValidatorLifecycleResponse` instead of `ValidatorLifecycle` * fix: misspell * chore: removed `ValidatorLifecycleResponse` struct * chore: removed `State` property from ValStateUpdateResponse --- client/docs/swagger-ui/swagger.yaml | 188 ++------ proto/babylon/epoching/v1/epoching.proto | 6 +- proto/babylon/epoching/v1/query.proto | 13 +- x/epoching/keeper/grpc_query.go | 3 +- x/epoching/types/epoching.pb.go | 6 +- x/epoching/types/query.go | 18 + x/epoching/types/query.pb.go | 543 ++++++++++++++++++----- 7 files changed, 516 insertions(+), 261 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index a72c38c78..1418e426a 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -1385,10 +1385,8 @@ paths: state update of a delegation - title: >- - ValidatorLifecycle is a message that records records the - lifecycle of - + title: |- + ValidatorLifecycle is a message that records the lifecycle of a delegation title: |- QueryDelegationLifecycleRequest is the response type for the @@ -3499,49 +3497,25 @@ paths: schema: type: object properties: + val_addr: + type: string val_life: - type: object - properties: - val_addr: - type: string - val_life: - type: array - items: - type: object - properties: - state: - type: string - enum: - - CREATED - - BONDED - - UNBONDING - - UNBONDED - - REMOVED - default: CREATED - description: >- - - CREATED: CREATED is when the validator/delegation - has been created - - BONDED: CREATED is when the validator/delegation has become bonded - - UNBONDING: CREATED is when the validator/delegation has become unbonding - - UNBONDED: CREATED is when the validator/delegation has become unbonded - - REMOVED: CREATED is when the validator/delegation has been removed - title: >- - BondState is the bond state of a validator or - delegation - block_height: - type: string - format: uint64 - block_time: - type: string - format: date-time - title: >- - ValStateUpdate is a messages that records a state update - of a validator - title: >- - ValidatorLifecycle is a message that records records the - lifecycle of - - a validator + type: array + items: + type: object + properties: + state_desc: + type: string + description: StateDesc defines the descriptive state. + block_height: + type: string + format: uint64 + block_time: + type: string + format: date-time + description: >- + ValStateUpdateResponse is a message response that records a + state update of a validator. title: |- QueryValidatorLifecycleResponse is the response type for the Query/ValidatorLifecycle RPC method @@ -9851,7 +9825,7 @@ definitions: delegation title: |- - ValidatorLifecycle is a message that records records the lifecycle of + ValidatorLifecycle is a message that records the lifecycle of a delegation babylon.epoching.v1.DelegationStateUpdate: type: object @@ -10026,7 +10000,7 @@ definitions: delegation title: |- - ValidatorLifecycle is a message that records records the lifecycle of + ValidatorLifecycle is a message that records the lifecycle of a delegation title: |- QueryDelegationLifecycleRequest is the response type for the @@ -10401,45 +10375,25 @@ definitions: babylon.epoching.v1.QueryValidatorLifecycleResponse: type: object properties: + val_addr: + type: string val_life: - type: object - properties: - val_addr: - type: string - val_life: - type: array - items: - type: object - properties: - state: - type: string - enum: - - CREATED - - BONDED - - UNBONDING - - UNBONDED - - REMOVED - default: CREATED - description: >- - - CREATED: CREATED is when the validator/delegation has been - created - - BONDED: CREATED is when the validator/delegation has become bonded - - UNBONDING: CREATED is when the validator/delegation has become unbonding - - UNBONDED: CREATED is when the validator/delegation has become unbonded - - REMOVED: CREATED is when the validator/delegation has been removed - title: BondState is the bond state of a validator or delegation - block_height: - type: string - format: uint64 - block_time: - type: string - format: date-time - title: >- - ValStateUpdate is a messages that records a state update of a - validator - title: |- - ValidatorLifecycle is a message that records records the lifecycle of - a validator + type: array + items: + type: object + properties: + state_desc: + type: string + description: StateDesc defines the descriptive state. + block_height: + type: string + format: uint64 + block_time: + type: string + format: date-time + description: >- + ValStateUpdateResponse is a message response that records a state + update of a validator. title: |- QueryValidatorLifecycleResponse is the response type for the Query/ValidatorLifecycle RPC method @@ -10516,32 +10470,21 @@ definitions: is delayed to the end of an epoch - babylon.epoching.v1.ValStateUpdate: + babylon.epoching.v1.ValStateUpdateResponse: type: object properties: - state: + state_desc: type: string - enum: - - CREATED - - BONDED - - UNBONDING - - UNBONDED - - REMOVED - default: CREATED - description: |- - - CREATED: CREATED is when the validator/delegation has been created - - BONDED: CREATED is when the validator/delegation has become bonded - - UNBONDING: CREATED is when the validator/delegation has become unbonding - - UNBONDED: CREATED is when the validator/delegation has become unbonded - - REMOVED: CREATED is when the validator/delegation has been removed - title: BondState is the bond state of a validator or delegation + description: StateDesc defines the descriptive state. block_height: type: string format: uint64 block_time: type: string format: date-time - title: ValStateUpdate is a messages that records a state update of a validator + description: >- + ValStateUpdateResponse is a message response that records a state update + of a validator. babylon.epoching.v1.Validator: type: object properties: @@ -10554,45 +10497,6 @@ definitions: format: int64 title: power is the validator's voting power title: Validator is a message that denotes a validator - babylon.epoching.v1.ValidatorLifecycle: - type: object - properties: - val_addr: - type: string - val_life: - type: array - items: - type: object - properties: - state: - type: string - enum: - - CREATED - - BONDED - - UNBONDING - - UNBONDED - - REMOVED - default: CREATED - description: >- - - CREATED: CREATED is when the validator/delegation has been - created - - BONDED: CREATED is when the validator/delegation has become bonded - - UNBONDING: CREATED is when the validator/delegation has become unbonding - - UNBONDED: CREATED is when the validator/delegation has become unbonded - - REMOVED: CREATED is when the validator/delegation has been removed - title: BondState is the bond state of a validator or delegation - block_height: - type: string - format: uint64 - block_time: - type: string - format: date-time - title: >- - ValStateUpdate is a messages that records a state update of a - validator - title: |- - ValidatorLifecycle is a message that records records the lifecycle of - a validator cosmos.base.v1beta1.Coin: type: object properties: diff --git a/proto/babylon/epoching/v1/epoching.proto b/proto/babylon/epoching/v1/epoching.proto index 647d8a825..6ea0ddce6 100644 --- a/proto/babylon/epoching/v1/epoching.proto +++ b/proto/babylon/epoching/v1/epoching.proto @@ -71,14 +71,14 @@ enum BondState { REMOVED = 4; } -// ValStateUpdate is a messages that records a state update of a validator +// ValStateUpdate is a message that records a state update of a validator message ValStateUpdate { BondState state = 1; uint64 block_height = 2; google.protobuf.Timestamp block_time = 3 [ (gogoproto.stdtime) = true ]; } -// ValidatorLifecycle is a message that records records the lifecycle of +// ValidatorLifecycle is a message that records the lifecycle of // a validator message ValidatorLifecycle { string val_addr = 1; @@ -95,7 +95,7 @@ message DelegationStateUpdate { google.protobuf.Timestamp block_time = 5 [ (gogoproto.stdtime) = true ]; } -// ValidatorLifecycle is a message that records records the lifecycle of +// ValidatorLifecycle is a message that records the lifecycle of // a delegation message DelegationLifecycle { string del_addr = 1; diff --git a/proto/babylon/epoching/v1/query.proto b/proto/babylon/epoching/v1/query.proto index c7f5eed91..29f925778 100644 --- a/proto/babylon/epoching/v1/query.proto +++ b/proto/babylon/epoching/v1/query.proto @@ -158,7 +158,10 @@ message QueryValidatorLifecycleRequest { string val_addr = 1; } // QueryValidatorLifecycleResponse is the response type for the // Query/ValidatorLifecycle RPC method -message QueryValidatorLifecycleResponse { ValidatorLifecycle val_life = 1; } +message QueryValidatorLifecycleResponse { + string val_addr = 1; + repeated ValStateUpdateResponse val_life = 2; +} // QueryDelegationLifecycleRequest is the request type for the // Query/DelegationLifecycle RPC method @@ -232,3 +235,11 @@ message QueuedMessageList { uint64 epoch_number = 1; repeated QueuedMessageResponse msgs = 2; } + +// ValStateUpdateResponse is a message response that records a state update of a validator. +message ValStateUpdateResponse { + // StateDesc defines the descriptive state. + string state_desc = 1; + uint64 block_height = 2; + google.protobuf.Timestamp block_time = 3 [ (gogoproto.stdtime) = true ]; +} diff --git a/x/epoching/keeper/grpc_query.go b/x/epoching/keeper/grpc_query.go index bf7c263c1..9d88cc565 100644 --- a/x/epoching/keeper/grpc_query.go +++ b/x/epoching/keeper/grpc_query.go @@ -188,7 +188,8 @@ func (k Keeper) ValidatorLifecycle(c context.Context, req *types.QueryValidatorL } lc := k.GetValLifecycle(ctx, valAddr) return &types.QueryValidatorLifecycleResponse{ - ValLife: lc, + ValAddr: lc.ValAddr, + ValLife: types.NewValsetUpdateResponses(lc.ValLife), }, nil } diff --git a/x/epoching/types/epoching.pb.go b/x/epoching/types/epoching.pb.go index 8d4f7b18b..e382650b7 100644 --- a/x/epoching/types/epoching.pb.go +++ b/x/epoching/types/epoching.pb.go @@ -343,7 +343,7 @@ func (*QueuedMessage) XXX_OneofWrappers() []interface{} { } } -// ValStateUpdate is a messages that records a state update of a validator +// ValStateUpdate is a message that records a state update of a validator type ValStateUpdate struct { State BondState `protobuf:"varint,1,opt,name=state,proto3,enum=babylon.epoching.v1.BondState" json:"state,omitempty"` BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` @@ -404,7 +404,7 @@ func (m *ValStateUpdate) GetBlockTime() *time.Time { return nil } -// ValidatorLifecycle is a message that records records the lifecycle of +// ValidatorLifecycle is a message that records the lifecycle of // a validator type ValidatorLifecycle struct { ValAddr string `protobuf:"bytes,1,opt,name=val_addr,json=valAddr,proto3" json:"val_addr,omitempty"` @@ -536,7 +536,7 @@ func (m *DelegationStateUpdate) GetBlockTime() *time.Time { return nil } -// ValidatorLifecycle is a message that records records the lifecycle of +// ValidatorLifecycle is a message that records the lifecycle of // a delegation type DelegationLifecycle struct { DelAddr string `protobuf:"bytes,1,opt,name=del_addr,json=delAddr,proto3" json:"del_addr,omitempty"` diff --git a/x/epoching/types/query.go b/x/epoching/types/query.go index 7dbc87b97..9dbbe889a 100644 --- a/x/epoching/types/query.go +++ b/x/epoching/types/query.go @@ -28,6 +28,24 @@ func (q *QueuedMessage) ToResponse() *QueuedMessageResponse { } } +// ToResponse parses a ValStateUpdate into a query response valset update struct. +func (v *ValStateUpdate) ToResponse() *ValStateUpdateResponse { + return &ValStateUpdateResponse{ + StateDesc: v.State.String(), + BlockHeight: v.BlockHeight, + BlockTime: v.BlockTime, + } +} + +// NewValsetUpdateResponses parses all the valset updates as response. +func NewValsetUpdateResponses(vs []*ValStateUpdate) []*ValStateUpdateResponse { + resp := make([]*ValStateUpdateResponse, len(vs)) + for i, v := range vs { + resp[i] = v.ToResponse() + } + return resp +} + // NewQueuedMessagesResponse parses all the queued messages as response. func NewQueuedMessagesResponse(msgs []*QueuedMessage) []*QueuedMessageResponse { resp := make([]*QueuedMessageResponse, len(msgs)) diff --git a/x/epoching/types/query.pb.go b/x/epoching/types/query.pb.go index 2985d762a..41d754ff2 100644 --- a/x/epoching/types/query.pb.go +++ b/x/epoching/types/query.pb.go @@ -682,7 +682,8 @@ func (m *QueryValidatorLifecycleRequest) GetValAddr() string { // QueryValidatorLifecycleResponse is the response type for the // Query/ValidatorLifecycle RPC method type QueryValidatorLifecycleResponse struct { - ValLife *ValidatorLifecycle `protobuf:"bytes,1,opt,name=val_life,json=valLife,proto3" json:"val_life,omitempty"` + ValAddr string `protobuf:"bytes,1,opt,name=val_addr,json=valAddr,proto3" json:"val_addr,omitempty"` + ValLife []*ValStateUpdateResponse `protobuf:"bytes,2,rep,name=val_life,json=valLife,proto3" json:"val_life,omitempty"` } func (m *QueryValidatorLifecycleResponse) Reset() { *m = QueryValidatorLifecycleResponse{} } @@ -718,7 +719,14 @@ func (m *QueryValidatorLifecycleResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryValidatorLifecycleResponse proto.InternalMessageInfo -func (m *QueryValidatorLifecycleResponse) GetValLife() *ValidatorLifecycle { +func (m *QueryValidatorLifecycleResponse) GetValAddr() string { + if m != nil { + return m.ValAddr + } + return "" +} + +func (m *QueryValidatorLifecycleResponse) GetValLife() []*ValStateUpdateResponse { if m != nil { return m.ValLife } @@ -1180,6 +1188,68 @@ func (m *QueuedMessageList) GetMsgs() []*QueuedMessageResponse { return nil } +// ValStateUpdateResponse is a message response that records a state update of a validator. +type ValStateUpdateResponse struct { + // StateDesc defines the descriptive state. + StateDesc string `protobuf:"bytes,1,opt,name=state_desc,json=stateDesc,proto3" json:"state_desc,omitempty"` + BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + BlockTime *time.Time `protobuf:"bytes,3,opt,name=block_time,json=blockTime,proto3,stdtime" json:"block_time,omitempty"` +} + +func (m *ValStateUpdateResponse) Reset() { *m = ValStateUpdateResponse{} } +func (m *ValStateUpdateResponse) String() string { return proto.CompactTextString(m) } +func (*ValStateUpdateResponse) ProtoMessage() {} +func (*ValStateUpdateResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_1821b530f2ec2711, []int{21} +} +func (m *ValStateUpdateResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValStateUpdateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ValStateUpdateResponse.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 *ValStateUpdateResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValStateUpdateResponse.Merge(m, src) +} +func (m *ValStateUpdateResponse) XXX_Size() int { + return m.Size() +} +func (m *ValStateUpdateResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ValStateUpdateResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ValStateUpdateResponse proto.InternalMessageInfo + +func (m *ValStateUpdateResponse) GetStateDesc() string { + if m != nil { + return m.StateDesc + } + return "" +} + +func (m *ValStateUpdateResponse) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *ValStateUpdateResponse) GetBlockTime() *time.Time { + if m != nil { + return m.BlockTime + } + return nil +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.epoching.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.epoching.v1.QueryParamsResponse") @@ -1202,97 +1272,101 @@ func init() { proto.RegisterType((*EpochResponse)(nil), "babylon.epoching.v1.EpochResponse") proto.RegisterType((*QueuedMessageResponse)(nil), "babylon.epoching.v1.QueuedMessageResponse") proto.RegisterType((*QueuedMessageList)(nil), "babylon.epoching.v1.QueuedMessageList") + proto.RegisterType((*ValStateUpdateResponse)(nil), "babylon.epoching.v1.ValStateUpdateResponse") } func init() { proto.RegisterFile("babylon/epoching/v1/query.proto", fileDescriptor_1821b530f2ec2711) } var fileDescriptor_1821b530f2ec2711 = []byte{ - // 1354 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcd, 0x6f, 0xdc, 0xc4, - 0x1b, 0x8e, 0x93, 0x4d, 0xda, 0xbc, 0x69, 0x9a, 0x64, 0xd2, 0xf6, 0x97, 0x3a, 0xfd, 0x6d, 0x8a, - 0x0b, 0xfd, 0x48, 0x1b, 0xbb, 0x69, 0x52, 0xa0, 0x1f, 0x50, 0x35, 0xe5, 0x23, 0x41, 0x2d, 0x4a, - 0x0d, 0xea, 0x81, 0x8b, 0x19, 0xaf, 0x27, 0x5e, 0x0b, 0xdb, 0xe3, 0x7a, 0x66, 0x97, 0x44, 0xa5, - 0x08, 0x71, 0xe6, 0x50, 0x89, 0x03, 0xe2, 0x82, 0x40, 0x1c, 0xf9, 0x0b, 0x10, 0x1c, 0x38, 0xf6, - 0x58, 0xc4, 0x85, 0x13, 0xa0, 0x16, 0xf1, 0x77, 0x20, 0xcf, 0x8c, 0x77, 0xbd, 0x1b, 0x6f, 0x77, - 0x1b, 0x55, 0xdc, 0x76, 0x67, 0xde, 0xe7, 0x7d, 0x9f, 0xf7, 0x79, 0xc7, 0x33, 0x0f, 0x2c, 0xb8, - 0xd8, 0xdd, 0x09, 0x69, 0x6c, 0x91, 0x84, 0xd6, 0xea, 0x41, 0xec, 0x5b, 0xcd, 0x65, 0xeb, 0x6e, - 0x83, 0xa4, 0x3b, 0x66, 0x92, 0x52, 0x4e, 0xd1, 0xac, 0x0a, 0x30, 0xf3, 0x00, 0xb3, 0xb9, 0xac, - 0x1f, 0xf2, 0xa9, 0x4f, 0xc5, 0xbe, 0x95, 0xfd, 0x92, 0xa1, 0xfa, 0x82, 0x4f, 0xa9, 0x1f, 0x12, - 0x4b, 0xfc, 0x73, 0x1b, 0x5b, 0x16, 0x0f, 0x22, 0xc2, 0x38, 0x8e, 0x12, 0x15, 0x70, 0x4c, 0x05, - 0xe0, 0x24, 0xb0, 0x70, 0x1c, 0x53, 0x8e, 0x79, 0x40, 0x63, 0xa6, 0x76, 0x17, 0x6b, 0x94, 0x45, - 0x94, 0x59, 0x2e, 0x66, 0x44, 0x52, 0xb0, 0x9a, 0xcb, 0x2e, 0xe1, 0x78, 0xd9, 0x4a, 0xb0, 0x1f, - 0xc4, 0x22, 0x58, 0xc5, 0x1e, 0x2f, 0xa3, 0x9d, 0xe0, 0x14, 0x47, 0x79, 0x36, 0xa3, 0x2c, 0xa2, - 0xd5, 0x83, 0x88, 0x31, 0x0e, 0x01, 0xba, 0x9d, 0xd5, 0xd9, 0x14, 0x40, 0x9b, 0xdc, 0x6d, 0x10, - 0xc6, 0x8d, 0x4d, 0x98, 0xed, 0x58, 0x65, 0x09, 0x8d, 0x19, 0x41, 0x97, 0x60, 0x4c, 0x16, 0x98, - 0xd3, 0x8e, 0x6b, 0xa7, 0x27, 0x2e, 0xcc, 0x9b, 0x25, 0xca, 0x98, 0x12, 0xb4, 0x56, 0x79, 0xf8, - 0xc7, 0xc2, 0x90, 0xad, 0x00, 0xc6, 0x2a, 0x1c, 0x16, 0x19, 0xdf, 0xcc, 0x02, 0x37, 0xe2, 0x2d, - 0xaa, 0x4a, 0xa1, 0x79, 0x18, 0x17, 0x60, 0x27, 0x6e, 0x44, 0x22, 0x6d, 0xc5, 0xde, 0x2f, 0x16, - 0xde, 0x6d, 0x44, 0x86, 0x0d, 0x47, 0xba, 0x51, 0x8a, 0xca, 0xab, 0x30, 0x2a, 0xa2, 0x14, 0x13, - 0xa3, 0x94, 0x89, 0x80, 0xe5, 0x10, 0x5b, 0x02, 0x8c, 0x0f, 0x8b, 0x39, 0x59, 0x91, 0xca, 0x5b, - 0x00, 0x6d, 0x95, 0x55, 0xe2, 0x93, 0xa6, 0x1c, 0x89, 0x99, 0x8d, 0xc4, 0x94, 0xa7, 0x42, 0x8d, - 0xc4, 0xdc, 0xc4, 0x3e, 0x51, 0x58, 0xbb, 0x80, 0x34, 0xbe, 0xd1, 0xe0, 0x7f, 0xbb, 0x4a, 0x28, - 0xde, 0x97, 0x61, 0x4c, 0xd0, 0xc8, 0x24, 0x1c, 0x19, 0x90, 0xb8, 0x42, 0xa0, 0xb7, 0x3b, 0xf8, - 0x0d, 0x0b, 0x7e, 0xa7, 0xfa, 0xf2, 0x53, 0x49, 0x8a, 0x04, 0x75, 0x98, 0x13, 0xfc, 0x6e, 0x34, - 0xd2, 0x94, 0xc4, 0x5c, 0x55, 0x93, 0xa3, 0xf7, 0xe1, 0x68, 0xc9, 0x9e, 0x62, 0x7f, 0x02, 0x26, - 0x6b, 0x72, 0xdd, 0x69, 0xab, 0x5f, 0xb1, 0x0f, 0xd4, 0x0a, 0xc1, 0xe8, 0x25, 0x38, 0x28, 0x27, - 0xea, 0xd2, 0x46, 0xec, 0xe1, 0x74, 0x47, 0x50, 0xad, 0xd8, 0x93, 0x62, 0x75, 0x4d, 0x2d, 0x1a, - 0x9f, 0x14, 0x4f, 0xc4, 0x2d, 0xe6, 0xb3, 0x41, 0x4e, 0x44, 0xd7, 0x8c, 0x86, 0xf7, 0x3c, 0xa3, - 0xef, 0xb4, 0xe2, 0x31, 0x90, 0xe5, 0x55, 0x93, 0xaf, 0x43, 0x25, 0x62, 0x7e, 0x3e, 0xa0, 0xc5, - 0xd2, 0x01, 0xdd, 0x6e, 0x90, 0x06, 0xf1, 0x6e, 0x11, 0xc6, 0x8a, 0x1a, 0x0b, 0xdc, 0xf3, 0x1b, - 0xd3, 0xf7, 0x1a, 0xcc, 0x0b, 0x8e, 0x37, 0x31, 0x27, 0x8c, 0x97, 0x0a, 0x15, 0x7b, 0x1d, 0x93, - 0xd8, 0x4f, 0x62, 0x4f, 0x4e, 0x61, 0x01, 0x26, 0xa4, 0x8a, 0x35, 0xda, 0x88, 0xb9, 0x1a, 0x01, - 0x88, 0xa5, 0x1b, 0xd9, 0x4a, 0x97, 0x92, 0x23, 0x7b, 0x56, 0xf2, 0x27, 0x0d, 0x8e, 0x95, 0xb3, - 0x54, 0x7a, 0xda, 0x30, 0x13, 0x8a, 0x2d, 0xc9, 0xd4, 0x29, 0x88, 0x7b, 0xb2, 0xbf, 0xb8, 0x37, - 0x03, 0xc6, 0xed, 0xa9, 0xb0, 0x33, 0xf7, 0xf3, 0xd3, 0xf8, 0x0a, 0x54, 0x05, 0xf9, 0x3b, 0x38, - 0x0c, 0x3c, 0xcc, 0x69, 0x7a, 0x33, 0xd8, 0x22, 0xb5, 0x9d, 0x5a, 0x98, 0xf7, 0x8a, 0x8e, 0xc2, - 0xfe, 0x26, 0x0e, 0x1d, 0xec, 0x79, 0xa9, 0x10, 0x79, 0xdc, 0xde, 0xd7, 0xc4, 0xe1, 0x75, 0xcf, - 0x4b, 0x0d, 0x02, 0x0b, 0x3d, 0xc1, 0xaa, 0xf9, 0x35, 0x89, 0x0e, 0x83, 0x2d, 0xa2, 0x6e, 0x94, - 0x53, 0xa5, 0x3d, 0x97, 0xa4, 0xc8, 0xca, 0x64, 0xff, 0x8c, 0xab, 0xaa, 0xcc, 0x1b, 0x24, 0x24, - 0xbe, 0xa0, 0x5d, 0x46, 0xd2, 0x23, 0x9d, 0x24, 0x3d, 0x22, 0x49, 0xfa, 0x70, 0xbc, 0x37, 0x5a, - 0xb1, 0xbc, 0x21, 0xe1, 0x05, 0x96, 0xa7, 0x4b, 0x59, 0x96, 0xe5, 0xc8, 0x0a, 0x09, 0x9a, 0x9f, - 0x16, 0x6f, 0xbd, 0x3b, 0x38, 0x7c, 0x8f, 0xf0, 0xff, 0xf4, 0x93, 0xfe, 0x55, 0x53, 0xd7, 0x5a, - 0x07, 0x81, 0xd6, 0x47, 0x0d, 0xcd, 0x5c, 0xe2, 0xfc, 0xf4, 0x55, 0x9f, 0x3e, 0x09, 0xbb, 0x80, - 0x40, 0xe7, 0x00, 0x71, 0xca, 0x71, 0xe8, 0x34, 0x29, 0x0f, 0x62, 0xdf, 0x49, 0xe8, 0xc7, 0x24, - 0x15, 0x64, 0x47, 0xec, 0x69, 0xb1, 0x73, 0x47, 0x6c, 0x6c, 0x66, 0xeb, 0x5d, 0xc7, 0x73, 0x64, - 0xef, 0xc7, 0xf3, 0x9f, 0x61, 0x98, 0xec, 0xbc, 0x82, 0x5f, 0x80, 0x03, 0x2d, 0x29, 0x5d, 0x92, - 0x2a, 0x35, 0x27, 0x72, 0x35, 0x5d, 0x92, 0xa2, 0x55, 0x38, 0xd2, 0x71, 0x4b, 0x3b, 0x41, 0xcc, - 0x49, 0xda, 0xc4, 0xa1, 0xba, 0x05, 0x0e, 0x15, 0xaf, 0xeb, 0x0d, 0xb5, 0x97, 0x75, 0xb8, 0x15, - 0xa4, 0x8c, 0x3b, 0x6e, 0x48, 0x6b, 0x1f, 0x39, 0x75, 0x12, 0xf8, 0x75, 0x2e, 0xb8, 0x57, 0xec, - 0x69, 0xb1, 0xb3, 0x96, 0x6d, 0xac, 0x8b, 0x75, 0xb4, 0x0e, 0x53, 0x21, 0x6e, 0x05, 0x67, 0x2e, - 0x67, 0xae, 0x22, 0xda, 0xd4, 0x4d, 0xe9, 0x70, 0xcc, 0xdc, 0x02, 0x99, 0xef, 0xe7, 0x16, 0x68, - 0xad, 0xf2, 0xe0, 0xcf, 0x05, 0xcd, 0x9e, 0xcc, 0x80, 0x22, 0x57, 0xb6, 0x83, 0xce, 0xc0, 0x0c, - 0x4e, 0x12, 0xa7, 0x8e, 0x59, 0xdd, 0x49, 0x29, 0xe5, 0x4e, 0x9d, 0x6c, 0xcf, 0x8d, 0x8a, 0x33, - 0x7c, 0x10, 0x27, 0xc9, 0x3a, 0x66, 0x75, 0x9b, 0x52, 0xbe, 0x4e, 0xb6, 0xd1, 0x12, 0xcc, 0x32, - 0x82, 0x43, 0x92, 0x3a, 0x2d, 0x44, 0x16, 0x3c, 0x26, 0x82, 0xa7, 0xe5, 0xd6, 0x75, 0x09, 0xc9, - 0xc2, 0x17, 0x61, 0x46, 0x85, 0xab, 0x96, 0x30, 0xab, 0xcf, 0xed, 0x13, 0xc1, 0x53, 0x72, 0x43, - 0x76, 0x84, 0x59, 0xdd, 0xf8, 0x51, 0x13, 0xcf, 0xd1, 0xee, 0x4b, 0x1d, 0xcd, 0xc2, 0x28, 0xdf, - 0x76, 0x02, 0x4f, 0x7d, 0x57, 0x15, 0xbe, 0xbd, 0xe1, 0xa1, 0xc3, 0x30, 0x16, 0x31, 0x3f, 0x5b, - 0x1d, 0x16, 0xab, 0xa3, 0x11, 0xf3, 0x37, 0xbc, 0x6c, 0x38, 0x25, 0xea, 0x4d, 0xb8, 0x05, 0xe1, - 0xae, 0x01, 0xec, 0x41, 0xb3, 0x71, 0xb7, 0xa5, 0xd7, 0x34, 0x8c, 0x44, 0xcc, 0x57, 0x0a, 0x65, - 0x3f, 0x8d, 0x26, 0xcc, 0xec, 0xba, 0x32, 0x07, 0x39, 0x27, 0xf9, 0x43, 0x37, 0xbc, 0xb7, 0x87, - 0xee, 0xc2, 0xa3, 0x09, 0x18, 0x15, 0x1f, 0x1c, 0xfa, 0x4c, 0x83, 0x31, 0x69, 0xfb, 0xd0, 0xa9, - 0x5e, 0x69, 0xba, 0x3c, 0xa6, 0x7e, 0xba, 0x7f, 0xa0, 0xac, 0x66, 0x9c, 0xf8, 0xfc, 0xb7, 0xbf, - 0xbf, 0x1c, 0xfe, 0x3f, 0x9a, 0xb7, 0x7a, 0x5b, 0x5e, 0xf4, 0x95, 0x06, 0xe3, 0x2d, 0x9b, 0x88, - 0x16, 0x7b, 0x27, 0xef, 0x76, 0xa0, 0xfa, 0xd9, 0x81, 0x62, 0x15, 0x97, 0x65, 0xc1, 0xe5, 0x2c, - 0x3a, 0x63, 0xf5, 0x34, 0xd7, 0xcc, 0xba, 0xd7, 0x52, 0xfe, 0xb5, 0xc5, 0xfb, 0xe8, 0x0b, 0x0d, - 0xa0, 0xed, 0x04, 0x51, 0xbf, 0x72, 0x45, 0x4b, 0xaa, 0x9f, 0x1b, 0x2c, 0x78, 0x20, 0xa1, 0x94, - 0x8b, 0xfc, 0x5a, 0x83, 0x03, 0x45, 0x73, 0x87, 0x96, 0x7a, 0xd7, 0x28, 0x31, 0x88, 0xba, 0x39, - 0x68, 0xb8, 0x22, 0xb5, 0x28, 0x48, 0xbd, 0x88, 0x8c, 0x52, 0x52, 0x1d, 0x17, 0x15, 0xfa, 0x36, - 0x1f, 0xa2, 0x78, 0xe4, 0xfb, 0x0d, 0xb1, 0xe0, 0x85, 0xfa, 0x0e, 0xb1, 0xe8, 0x48, 0x8c, 0xcb, - 0x82, 0xd2, 0x2a, 0xba, 0x30, 0xf0, 0x10, 0xad, 0x48, 0x7e, 0x01, 0x0c, 0xfd, 0xa0, 0xc1, 0x54, - 0x97, 0xd3, 0x41, 0xe7, 0x7b, 0x17, 0x2f, 0xb7, 0x6e, 0xfa, 0xf2, 0x33, 0x20, 0x14, 0xe9, 0x15, - 0x41, 0x7a, 0x09, 0x9d, 0x7d, 0x0a, 0xe9, 0xcb, 0xd2, 0x27, 0xb5, 0xd9, 0xfe, 0xac, 0x01, 0xda, - 0x6d, 0x2d, 0xd0, 0x4a, 0xef, 0xf2, 0x3d, 0x8d, 0x90, 0xbe, 0xfa, 0x6c, 0x20, 0x45, 0xfb, 0x8a, - 0xa0, 0x7d, 0x11, 0xad, 0x94, 0xd2, 0x6e, 0xbd, 0xb0, 0xc2, 0x7b, 0x08, 0xa4, 0x75, 0x2f, 0xb7, - 0x5b, 0xf7, 0xd1, 0x2f, 0x1a, 0xcc, 0x96, 0x78, 0x0e, 0xf4, 0x14, 0x2a, 0xbd, 0x4d, 0x92, 0x7e, - 0xf1, 0x19, 0x51, 0xaa, 0x83, 0xab, 0xa2, 0x83, 0x97, 0xd1, 0x6a, 0x69, 0x07, 0x5e, 0x0b, 0x59, - 0x6c, 0x21, 0x37, 0x63, 0xf7, 0xb3, 0xf3, 0x32, 0x51, 0x30, 0x24, 0xa8, 0xdf, 0x17, 0xdd, 0x61, - 0x9c, 0xf4, 0xa5, 0x01, 0xa3, 0x15, 0xd5, 0x6b, 0x82, 0xea, 0x25, 0xf4, 0xca, 0xe0, 0x07, 0xbb, - 0x3d, 0x01, 0x46, 0xf8, 0xda, 0x3b, 0x0f, 0x1f, 0x57, 0xb5, 0x47, 0x8f, 0xab, 0xda, 0x5f, 0x8f, - 0xab, 0xda, 0x83, 0x27, 0xd5, 0xa1, 0x47, 0x4f, 0xaa, 0x43, 0xbf, 0x3f, 0xa9, 0x0e, 0x7d, 0x70, - 0xde, 0x0f, 0x78, 0xbd, 0xe1, 0x9a, 0x35, 0x1a, 0xe5, 0xc9, 0x6b, 0x75, 0x1c, 0xc4, 0xad, 0x4a, - 0xdb, 0xed, 0x5a, 0x7c, 0x27, 0x21, 0xcc, 0x1d, 0x13, 0xaf, 0xd9, 0xca, 0xbf, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x82, 0xd7, 0x47, 0xa2, 0x60, 0x11, 0x00, 0x00, + // 1408 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0xdc, 0xc4, + 0x17, 0x8f, 0x37, 0x9b, 0xb4, 0x79, 0x69, 0x9a, 0x64, 0xd2, 0xf6, 0x9b, 0x6e, 0xda, 0x4d, 0xbf, + 0x2e, 0xf4, 0x47, 0xd2, 0xd8, 0x4d, 0x93, 0x02, 0xfd, 0x01, 0x55, 0xd3, 0x52, 0x12, 0xd4, 0xa2, + 0xd4, 0x40, 0x0f, 0x5c, 0xcc, 0xec, 0x7a, 0xe2, 0xb5, 0xf0, 0x7a, 0x5c, 0xcf, 0xec, 0x92, 0xa8, + 0x14, 0x21, 0xc4, 0x91, 0x43, 0x25, 0x0e, 0x08, 0x21, 0x21, 0x10, 0x47, 0xfe, 0x02, 0x04, 0x07, + 0x8e, 0x3d, 0x16, 0x71, 0xe1, 0x04, 0xa8, 0x41, 0xfc, 0x1d, 0xc8, 0x33, 0xe3, 0x5d, 0xef, 0xc6, + 0xee, 0x6e, 0xa2, 0x8a, 0xdb, 0x66, 0xde, 0xfb, 0xcc, 0xfb, 0xbc, 0xcf, 0x1b, 0xcf, 0x7c, 0x02, + 0xb3, 0x15, 0x5c, 0xd9, 0xf2, 0x69, 0x60, 0x92, 0x90, 0x56, 0x6b, 0x5e, 0xe0, 0x9a, 0xcd, 0x45, + 0xf3, 0x7e, 0x83, 0x44, 0x5b, 0x46, 0x18, 0x51, 0x4e, 0xd1, 0x94, 0x4a, 0x30, 0x92, 0x04, 0xa3, + 0xb9, 0x58, 0x3a, 0xe4, 0x52, 0x97, 0x8a, 0xb8, 0x19, 0xff, 0x92, 0xa9, 0xa5, 0x59, 0x97, 0x52, + 0xd7, 0x27, 0xa6, 0xf8, 0xab, 0xd2, 0xd8, 0x30, 0xb9, 0x57, 0x27, 0x8c, 0xe3, 0x7a, 0xa8, 0x12, + 0x8e, 0xa9, 0x04, 0x1c, 0x7a, 0x26, 0x0e, 0x02, 0xca, 0x31, 0xf7, 0x68, 0xc0, 0x54, 0x74, 0xae, + 0x4a, 0x59, 0x9d, 0x32, 0xb3, 0x82, 0x19, 0x91, 0x14, 0xcc, 0xe6, 0x62, 0x85, 0x70, 0xbc, 0x68, + 0x86, 0xd8, 0xf5, 0x02, 0x91, 0xac, 0x72, 0x4f, 0x64, 0xd1, 0x0e, 0x71, 0x84, 0xeb, 0xc9, 0x6e, + 0x7a, 0x56, 0x46, 0xab, 0x07, 0x91, 0xa3, 0x1f, 0x02, 0x74, 0x37, 0xae, 0xb3, 0x2e, 0x80, 0x16, + 0xb9, 0xdf, 0x20, 0x8c, 0xeb, 0xeb, 0x30, 0xd5, 0xb1, 0xca, 0x42, 0x1a, 0x30, 0x82, 0x2e, 0xc1, + 0xb0, 0x2c, 0x30, 0xad, 0x9d, 0xd0, 0xce, 0x8c, 0x5e, 0x98, 0x31, 0x32, 0x94, 0x31, 0x24, 0x68, + 0xa5, 0xf8, 0xf8, 0x8f, 0xd9, 0x01, 0x4b, 0x01, 0xf4, 0x65, 0x38, 0x2c, 0x76, 0x7c, 0x3d, 0x4e, + 0x5c, 0x0b, 0x36, 0xa8, 0x2a, 0x85, 0x66, 0x60, 0x44, 0x80, 0xed, 0xa0, 0x51, 0x17, 0xdb, 0x16, + 0xad, 0xfd, 0x62, 0xe1, 0xad, 0x46, 0x5d, 0xb7, 0xe0, 0x48, 0x37, 0x4a, 0x51, 0x79, 0x05, 0x86, + 0x44, 0x96, 0x62, 0xa2, 0x67, 0x32, 0x11, 0xb0, 0x04, 0x62, 0x49, 0x80, 0xfe, 0x7e, 0x7a, 0x4f, + 0x96, 0xa6, 0x72, 0x0b, 0xa0, 0xad, 0xb2, 0xda, 0xf8, 0x94, 0x21, 0x47, 0x62, 0xc4, 0x23, 0x31, + 0xe4, 0xa9, 0x50, 0x23, 0x31, 0xd6, 0xb1, 0x4b, 0x14, 0xd6, 0x4a, 0x21, 0xf5, 0x6f, 0x34, 0xf8, + 0xdf, 0x8e, 0x12, 0x8a, 0xf7, 0x65, 0x18, 0x16, 0x34, 0x62, 0x09, 0x07, 0xfb, 0x24, 0xae, 0x10, + 0xe8, 0x8d, 0x0e, 0x7e, 0x05, 0xc1, 0xef, 0x74, 0x4f, 0x7e, 0x6a, 0x93, 0x34, 0xc1, 0x12, 0x4c, + 0x0b, 0x7e, 0x37, 0x1a, 0x51, 0x44, 0x02, 0xae, 0xaa, 0xc9, 0xd1, 0xbb, 0x70, 0x34, 0x23, 0xa6, + 0xd8, 0x9f, 0x84, 0xb1, 0xaa, 0x5c, 0xb7, 0xdb, 0xea, 0x17, 0xad, 0x03, 0xd5, 0x54, 0x32, 0x7a, + 0x11, 0x0e, 0xca, 0x89, 0x56, 0x68, 0x23, 0x70, 0x70, 0xb4, 0x25, 0xa8, 0x16, 0xad, 0x31, 0xb1, + 0xba, 0xa2, 0x16, 0xf5, 0x8f, 0xd2, 0x27, 0xe2, 0x0e, 0x73, 0x59, 0x3f, 0x27, 0xa2, 0x6b, 0x46, + 0x85, 0x3d, 0xcf, 0xe8, 0x3b, 0x2d, 0x7d, 0x0c, 0x64, 0x79, 0xd5, 0xe4, 0x6b, 0x50, 0xac, 0x33, + 0x37, 0x19, 0xd0, 0x5c, 0xe6, 0x80, 0xee, 0x36, 0x48, 0x83, 0x38, 0x77, 0x08, 0x63, 0x69, 0x8d, + 0x05, 0xee, 0xf9, 0x8d, 0xe9, 0x7b, 0x0d, 0x66, 0x04, 0xc7, 0xdb, 0x98, 0x13, 0xc6, 0x33, 0x85, + 0x0a, 0x9c, 0x8e, 0x49, 0xec, 0x27, 0x81, 0x23, 0xa7, 0x30, 0x0b, 0xa3, 0x52, 0xc5, 0x2a, 0x6d, + 0x04, 0x5c, 0x8d, 0x00, 0xc4, 0xd2, 0x8d, 0x78, 0xa5, 0x4b, 0xc9, 0xc1, 0x3d, 0x2b, 0xf9, 0x93, + 0x06, 0xc7, 0xb2, 0x59, 0x2a, 0x3d, 0x2d, 0x98, 0xf4, 0x45, 0x48, 0x32, 0xb5, 0x53, 0xe2, 0x9e, + 0xea, 0x2d, 0xee, 0x6d, 0x8f, 0x71, 0x6b, 0xdc, 0xef, 0xdc, 0xfb, 0xf9, 0x69, 0x7c, 0x05, 0xca, + 0x82, 0xfc, 0x3d, 0xec, 0x7b, 0x0e, 0xe6, 0x34, 0xba, 0xed, 0x6d, 0x90, 0xea, 0x56, 0xd5, 0x4f, + 0x7a, 0x45, 0x47, 0x61, 0x7f, 0x13, 0xfb, 0x36, 0x76, 0x9c, 0x48, 0x88, 0x3c, 0x62, 0xed, 0x6b, + 0x62, 0xff, 0xba, 0xe3, 0x44, 0xfa, 0x67, 0x1a, 0xcc, 0xe6, 0xa2, 0x55, 0xf7, 0xf9, 0x70, 0x74, + 0x4b, 0x86, 0x7c, 0x6f, 0x83, 0x4c, 0x17, 0x84, 0x1e, 0xf3, 0x99, 0x7a, 0xdc, 0xc3, 0xfe, 0xdb, + 0x1c, 0x73, 0xf2, 0x6e, 0xe8, 0x60, 0xde, 0x6e, 0x23, 0xde, 0x27, 0xae, 0xa7, 0x5f, 0x55, 0x2c, + 0x6e, 0x12, 0x9f, 0xb8, 0xa2, 0xad, 0xac, 0x26, 0x1c, 0xd2, 0xc9, 0xc2, 0x21, 0xb2, 0x09, 0x17, + 0x4e, 0xe4, 0xa3, 0x55, 0x13, 0x37, 0x24, 0x5c, 0x30, 0x95, 0xf7, 0xe2, 0x99, 0x4c, 0xa6, 0x59, + 0x7b, 0xc4, 0x85, 0x04, 0xcd, 0x8f, 0xd3, 0xb7, 0x62, 0xdc, 0x13, 0xe1, 0xff, 0xe9, 0x27, 0xff, + 0xab, 0xa6, 0xae, 0xbd, 0x0e, 0x02, 0xad, 0x8f, 0x1e, 0x9a, 0xc9, 0x10, 0x93, 0xd3, 0x59, 0xce, + 0x9b, 0x86, 0x4c, 0xb3, 0x52, 0x08, 0x74, 0x0e, 0x10, 0xa7, 0x1c, 0xfb, 0x76, 0x93, 0x72, 0x2f, + 0x70, 0xed, 0x90, 0x7e, 0x48, 0x22, 0x41, 0x76, 0xd0, 0x9a, 0x10, 0x91, 0x7b, 0x22, 0xb0, 0x1e, + 0xaf, 0x77, 0x1d, 0xdf, 0xc1, 0xbd, 0x1f, 0xdf, 0x7f, 0x0a, 0x30, 0xd6, 0x79, 0x45, 0xff, 0x1f, + 0x0e, 0xb4, 0xa4, 0xac, 0x90, 0x48, 0xa9, 0x39, 0x9a, 0xa8, 0x59, 0x21, 0x11, 0x5a, 0x86, 0x23, + 0x1d, 0xb7, 0xb8, 0xed, 0x05, 0x9c, 0x44, 0x4d, 0xec, 0xab, 0x5b, 0xe2, 0x50, 0xfa, 0x3a, 0x5f, + 0x53, 0xb1, 0xb8, 0xc3, 0x0d, 0x2f, 0x62, 0xdc, 0xae, 0xf8, 0xb4, 0xfa, 0x81, 0x5d, 0x23, 0x9e, + 0x5b, 0xe3, 0x82, 0x7b, 0xd1, 0x9a, 0x10, 0x91, 0x95, 0x38, 0xb0, 0x2a, 0xd6, 0xd1, 0x2a, 0x8c, + 0xfb, 0xb8, 0x95, 0x1c, 0xbb, 0xa0, 0xe9, 0xa2, 0x68, 0xb3, 0x64, 0x48, 0x07, 0x64, 0x24, 0x16, + 0xc9, 0x78, 0x27, 0xb1, 0x48, 0x2b, 0xc5, 0x47, 0x7f, 0xce, 0x6a, 0xd6, 0x58, 0x0c, 0x14, 0x7b, + 0xc5, 0x11, 0x74, 0x16, 0x26, 0x71, 0x18, 0xda, 0x35, 0xcc, 0x6a, 0x76, 0x44, 0x29, 0xb7, 0x6b, + 0x64, 0x73, 0x7a, 0x48, 0x9c, 0xe1, 0x83, 0x38, 0x0c, 0x57, 0x31, 0xab, 0x59, 0x94, 0xf2, 0x55, + 0xb2, 0x89, 0x16, 0x60, 0x8a, 0x11, 0xec, 0x93, 0xc8, 0x6e, 0x21, 0xe2, 0xe4, 0x61, 0x91, 0x3c, + 0x21, 0x43, 0xd7, 0x25, 0x24, 0x4e, 0x9f, 0x83, 0x49, 0x95, 0xae, 0x5a, 0xc2, 0xac, 0x36, 0xbd, + 0x4f, 0x24, 0x8f, 0xcb, 0x80, 0xec, 0x08, 0xb3, 0x9a, 0xfe, 0xa3, 0x26, 0x9e, 0xab, 0x9d, 0x97, + 0x3e, 0x9a, 0x82, 0x21, 0xbe, 0x69, 0x7b, 0x8e, 0xfa, 0xae, 0x8a, 0x7c, 0x73, 0xcd, 0x41, 0x87, + 0x61, 0xb8, 0xce, 0xdc, 0x78, 0xb5, 0x20, 0x56, 0x87, 0xea, 0xcc, 0x5d, 0x73, 0xe2, 0xe1, 0x64, + 0xa8, 0x37, 0x5a, 0x49, 0x09, 0x77, 0x0d, 0x60, 0x0f, 0x9a, 0x8d, 0x54, 0x5a, 0x7a, 0x4d, 0xc0, + 0x60, 0x9d, 0xb9, 0x4a, 0xa1, 0xf8, 0xa7, 0xde, 0x84, 0xc9, 0x1d, 0x57, 0x6a, 0x3f, 0xe7, 0x24, + 0x79, 0x08, 0x0b, 0x7b, 0x7b, 0x08, 0xf5, 0xaf, 0x35, 0x38, 0x92, 0x7d, 0x77, 0xa1, 0xe3, 0x00, + 0x2c, 0x5e, 0xb6, 0x1d, 0xc2, 0xaa, 0x4a, 0xb9, 0x11, 0xb1, 0x72, 0x93, 0xb0, 0xea, 0x0e, 0x9d, + 0x0a, 0xbd, 0x74, 0x1a, 0xdc, 0xb5, 0x4e, 0x17, 0x9e, 0x8c, 0xc2, 0x90, 0xb8, 0x0e, 0xd0, 0x27, + 0x1a, 0x0c, 0x4b, 0xd3, 0x8a, 0x4e, 0xe7, 0x35, 0xd9, 0xe5, 0x90, 0x4b, 0x67, 0x7a, 0x27, 0xca, + 0x56, 0xf5, 0x93, 0x9f, 0xfe, 0xf6, 0xf7, 0x17, 0x85, 0xe3, 0x68, 0xc6, 0xcc, 0x37, 0xec, 0xe8, + 0x4b, 0x0d, 0x46, 0x5a, 0x26, 0x17, 0xcd, 0xe5, 0x6f, 0xde, 0xed, 0x9f, 0x4b, 0xf3, 0x7d, 0xe5, + 0x2a, 0x2e, 0x8b, 0x82, 0xcb, 0x3c, 0x3a, 0x6b, 0xe6, 0xfe, 0x6b, 0xc0, 0xcc, 0x07, 0xad, 0x73, + 0xf1, 0xea, 0xdc, 0x43, 0xf4, 0xb9, 0x06, 0xd0, 0xf6, 0xb1, 0xa8, 0x57, 0xb9, 0xb4, 0xa1, 0x2e, + 0x9d, 0xeb, 0x2f, 0xb9, 0x2f, 0xa1, 0x94, 0x07, 0xfe, 0x4a, 0x83, 0x03, 0x69, 0x6b, 0x8a, 0x16, + 0xf2, 0x6b, 0x64, 0xd8, 0xdb, 0x92, 0xd1, 0x6f, 0xba, 0x22, 0x35, 0x27, 0x48, 0xbd, 0x80, 0xf4, + 0x4c, 0x52, 0x1d, 0xd7, 0x28, 0xfa, 0x36, 0x19, 0xa2, 0xb0, 0x28, 0xbd, 0x86, 0x98, 0x72, 0x72, + 0x3d, 0x87, 0x98, 0xf6, 0x53, 0xfa, 0x65, 0x41, 0x69, 0x19, 0x5d, 0xe8, 0x7b, 0x88, 0x66, 0x5d, + 0x7e, 0x9f, 0x0c, 0xfd, 0xa0, 0xc1, 0x78, 0x97, 0x4f, 0x43, 0xe7, 0xf3, 0x8b, 0x67, 0x1b, 0xcf, + 0xd2, 0xe2, 0x2e, 0x10, 0x8a, 0xf4, 0x92, 0x20, 0xbd, 0x80, 0xe6, 0x9f, 0x41, 0xfa, 0xb2, 0x74, + 0x79, 0x6d, 0xb6, 0x3f, 0x6b, 0x80, 0x76, 0x5a, 0x2b, 0xb4, 0x94, 0x5f, 0x3e, 0xd7, 0xc6, 0x95, + 0x96, 0x77, 0x07, 0x52, 0xb4, 0xaf, 0x08, 0xda, 0x17, 0xd1, 0x52, 0x26, 0xed, 0xd6, 0xfb, 0x2f, + 0x9c, 0x91, 0x40, 0x9a, 0x0f, 0x12, 0xb7, 0xf7, 0x10, 0xfd, 0xa2, 0xc1, 0x54, 0x86, 0x23, 0x42, + 0xcf, 0xa0, 0x92, 0x6f, 0xe1, 0x4a, 0x17, 0x77, 0x89, 0x52, 0x1d, 0x5c, 0x15, 0x1d, 0xbc, 0x84, + 0x96, 0x33, 0x3b, 0x70, 0x5a, 0xc8, 0x74, 0x0b, 0x89, 0x55, 0x7c, 0x18, 0x9f, 0x97, 0xd1, 0x94, + 0x5d, 0x42, 0xbd, 0xbe, 0xe8, 0x0e, 0x5b, 0x57, 0x5a, 0xe8, 0x33, 0x5b, 0x51, 0xbd, 0x26, 0xa8, + 0x5e, 0x42, 0x2f, 0xf7, 0x7f, 0xb0, 0xdb, 0x13, 0x60, 0x84, 0xaf, 0xbc, 0xf9, 0xf8, 0x69, 0x59, + 0x7b, 0xf2, 0xb4, 0xac, 0xfd, 0xf5, 0xb4, 0xac, 0x3d, 0xda, 0x2e, 0x0f, 0x3c, 0xd9, 0x2e, 0x0f, + 0xfc, 0xbe, 0x5d, 0x1e, 0x78, 0xef, 0xbc, 0xeb, 0xf1, 0x5a, 0xa3, 0x62, 0x54, 0x69, 0x3d, 0xd9, + 0xbc, 0x5a, 0xc3, 0x5e, 0xd0, 0xaa, 0xb4, 0xd9, 0xae, 0xc5, 0xb7, 0x42, 0xc2, 0x2a, 0xc3, 0xe2, + 0x0d, 0x59, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x10, 0x0c, 0x81, 0x1e, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2179,15 +2253,24 @@ func (m *QueryValidatorLifecycleResponse) MarshalToSizedBuffer(dAtA []byte) (int _ = i var l int _ = l - if m.ValLife != nil { - { - size, err := m.ValLife.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.ValLife) > 0 { + for iNdEx := len(m.ValLife) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValLife[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } + } + if len(m.ValAddr) > 0 { + i -= len(m.ValAddr) + copy(dAtA[i:], m.ValAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ValAddr))) i-- dAtA[i] = 0xa } @@ -2395,12 +2478,12 @@ func (m *EpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x2a } if m.LastBlockTime != nil { - n13, err13 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime):]) - if err13 != nil { - return 0, err13 + n12, err12 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.LastBlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime):]) + if err12 != nil { + return 0, err12 } - i -= n13 - i = encodeVarintQuery(dAtA, i, uint64(n13)) + i -= n12 + i = encodeVarintQuery(dAtA, i, uint64(n12)) i-- dAtA[i] = 0x22 } @@ -2450,12 +2533,12 @@ func (m *QueuedMessageResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x2a } if m.BlockTime != nil { - n14, err14 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.BlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime):]) - if err14 != nil { - return 0, err14 + n13, err13 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.BlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime):]) + if err13 != nil { + return 0, err13 } - i -= n14 - i = encodeVarintQuery(dAtA, i, uint64(n14)) + i -= n13 + i = encodeVarintQuery(dAtA, i, uint64(n13)) i-- dAtA[i] = 0x22 } @@ -2523,6 +2606,51 @@ func (m *QueuedMessageList) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ValStateUpdateResponse) 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 *ValStateUpdateResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValStateUpdateResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BlockTime != nil { + n14, err14 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.BlockTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime):]) + if err14 != nil { + return 0, err14 + } + i -= n14 + i = encodeVarintQuery(dAtA, i, uint64(n14)) + i-- + dAtA[i] = 0x1a + } + if m.BlockHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x10 + } + if len(m.StateDesc) > 0 { + i -= len(m.StateDesc) + copy(dAtA[i:], m.StateDesc) + i = encodeVarintQuery(dAtA, i, uint64(len(m.StateDesc))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -2727,10 +2855,16 @@ func (m *QueryValidatorLifecycleResponse) Size() (n int) { } var l int _ = l - if m.ValLife != nil { - l = m.ValLife.Size() + l = len(m.ValAddr) + if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if len(m.ValLife) > 0 { + for _, e := range m.ValLife { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -2878,6 +3012,26 @@ func (m *QueuedMessageList) Size() (n int) { return n } +func (m *ValStateUpdateResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.StateDesc) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.BlockHeight != 0 { + n += 1 + sovQuery(uint64(m.BlockHeight)) + } + if m.BlockTime != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.BlockTime) + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -4097,6 +4251,38 @@ func (m *QueryValidatorLifecycleResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ValLife", wireType) } @@ -4125,10 +4311,8 @@ func (m *QueryValidatorLifecycleResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.ValLife == nil { - m.ValLife = &ValidatorLifecycle{} - } - if err := m.ValLife.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ValLife = append(m.ValLife, &ValStateUpdateResponse{}) + if err := m.ValLife[len(m.ValLife)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -5108,6 +5292,143 @@ func (m *QueuedMessageList) Unmarshal(dAtA []byte) error { } return nil } +func (m *ValStateUpdateResponse) 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 ErrIntOverflowQuery + } + 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: ValStateUpdateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValStateUpdateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StateDesc", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StateDesc = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockTime == nil { + m.BlockTime = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.BlockTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From f943c63dbd8114ba52dfd87c9f51770a5f090914 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 12 Mar 2024 18:22:54 +0100 Subject: [PATCH 042/119] fix checking evidence existance --- x/finality/keeper/evidence.go | 2 +- x/finality/keeper/msg_server_test.go | 74 ++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/x/finality/keeper/evidence.go b/x/finality/keeper/evidence.go index 0d9f610ad..dafa4d8fb 100644 --- a/x/finality/keeper/evidence.go +++ b/x/finality/keeper/evidence.go @@ -17,7 +17,7 @@ func (k Keeper) SetEvidence(ctx context.Context, evidence *types.Evidence) { func (k Keeper) HasEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool { store := k.evidenceStore(ctx, fpBtcPK) - return store.Has(fpBtcPK.MustMarshal()) + return store.Has(sdk.Uint64ToBigEndian(height)) } func (k Keeper) GetEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) (*types.Evidence, error) { diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index eab9337bb..275f0da8f 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -4,6 +4,7 @@ import ( "context" "math/rand" "testing" + "time" "cosmossdk.io/core/header" "github.com/babylonchain/babylon/testutil/datagen" @@ -209,3 +210,76 @@ func FuzzAddFinalitySig(f *testing.F) { require.Equal(t, bstypes.ErrFpAlreadySlashed, err) }) } + +func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + bsKeeper := types.NewMockBTCStakingKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) + ms := keeper.NewMsgServerImpl(*fKeeper) + // create and register a random finality provider + btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, btcSK) + require.NoError(t, err) + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + fpBTCPKBytes := fpBTCPK.MustMarshal() + require.NoError(t, err) + bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), + gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + // commit some public randomness + startHeight := uint64(0) + numPubRand := uint64(200) + srList, msgCommitPubRandList, err := + datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, + numPubRand) + require.NoError(t, err) + _, err = ms.CommitPubRandList(ctx, msgCommitPubRandList) + require.NoError(t, err) + // set a block height of 1 and some random list + blockHeight := uint64(1) + sr, _ := srList[startHeight+blockHeight], + msgCommitPubRandList.PubRandList[startHeight+blockHeight] + // generate two random hashes, one for the canonical block and + // one for a fork block + canonicalHash := datagen.GenRandomByteArray(r, 32) + forkHash := datagen.GenRandomByteArray(r, 32) + signer := datagen.GenRandomAccount().Address + require.NoError(t, err) + // (1) Set a canonical hash at height 1 + ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: canonicalHash}) + fKeeper.IndexBlock(ctx) + // (2) Vote for a different block at height 1, this will make us have + // some "evidence" + ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: forkHash}) + msg1, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, + blockHeight, forkHash) + + require.NoError(t, err) + bsKeeper.EXPECT().GetVotingPower(gomock.Any(), + gomock.Eq(fpBTCPKBytes), + gomock.Eq(blockHeight)).Return(uint64(1)).AnyTimes() + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), + gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg1) + require.NoError(t, err) + // (3) Now vote for the canonical block at height 1. This should slash Finality provider + msg, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, + blockHeight, canonicalHash) + ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: canonicalHash}) + require.NoError(t, err) + bsKeeper.EXPECT().GetVotingPower(gomock.Any(), + gomock.Eq(fpBTCPKBytes), + gomock.Eq(blockHeight)).Return(uint64(1)).AnyTimes() + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), + gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + bsKeeper.EXPECT().SlashFinalityProvider(gomock.Any(), + gomock.Eq(fpBTCPKBytes)).Return(nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg) + require.NoError(t, err) + sig, err := fKeeper.GetSig(ctx, blockHeight, fpBTCPK) + require.NoError(t, err) + require.Equal(t, msg.FinalitySig.MustMarshal(), + sig.MustMarshal()) +} From 0668b47229ae5da83e4c720c6dfe6926486896e1 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Wed, 13 Mar 2024 07:25:35 -0300 Subject: [PATCH 043/119] fix: `x/btclightclient` import/export gen state (#550) * fix: import/export gen state, add new property for all btc headers info * chore: add test checking store after genstate import/export * chore: add btc header validate to genstate * fix: remove check for height 0 * chore: delete func GetAllHeaderInfos to use GetMainChainFrom and add pointers to genstate.BtcHeaders * chore: add todo for genstate validation * chore: moved BTCLightGenRandomChain to datagen package as GenRandBtcChainInsertingInKeeper * fix: validate that genstate initiates with at least one btc header in its state * chore: update func name from ChainToChainBytes to NewBTCHeaderBytesList * chore: update func name from ToBlockHeader to NewBlockHeader * chore: prioritize btclightclient module in genesis import/export order --- app/app.go | 2 +- cmd/babylond/cmd/genesis.go | 2 +- proto/babylon/btclightclient/v1/genesis.proto | 2 +- test/e2e/initialization/config.go | 2 +- testutil/datagen/btc_header_info.go | 32 +++++ testutil/helper/store.go | 120 ++++++++++++++++++ testutil/keeper/btclightclient.go | 31 +++-- types/btc_header_bytes.go | 12 +- x/btclightclient/genesis.go | 21 ++- x/btclightclient/genesis_test.go | 74 ++++++++++- x/btclightclient/keeper/grpc_query_test.go | 22 ++-- x/btclightclient/keeper/keeper.go | 8 ++ x/btclightclient/keeper/keeper_test.go | 34 ++--- x/btclightclient/keeper/msg_server_test.go | 18 +-- x/btclightclient/keeper/state_test.go | 6 +- x/btclightclient/keeper/utils_test.go | 37 ------ x/btclightclient/types/btc_header_info.go | 33 +++++ .../types/btc_header_info_test.go | 89 +++++++++++++ x/btclightclient/types/genesis.go | 29 ++++- x/btclightclient/types/genesis.pb.go | 64 ++++++---- x/btclightclient/types/genesis_test.go | 17 ++- 21 files changed, 508 insertions(+), 147 deletions(-) create mode 100644 testutil/helper/store.go diff --git a/app/app.go b/app/app.go index 9d9aa6436..1441509e4 100644 --- a/app/app.go +++ b/app/app.go @@ -906,8 +906,8 @@ func NewBabylonApp( feegrant.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName, circuittypes.ModuleName, // Babylon modules - epochingtypes.ModuleName, btclightclienttypes.ModuleName, + epochingtypes.ModuleName, btccheckpointtypes.ModuleName, checkpointingtypes.ModuleName, monitortypes.ModuleName, diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index fba8dbf6f..47a7e58d6 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -138,7 +138,7 @@ func PrepareGenesis( // btclightclient genesis btclightclientGenState := btclightclienttypes.DefaultGenesis() - btclightclientGenState.BaseBtcHeader = genesisParams.BtclightclientBaseBtcHeader + btclightclientGenState.BtcHeaders = []*btclightclienttypes.BTCHeaderInfo{&genesisParams.BtclightclientBaseBtcHeader} btclightclientGenState.Params = genesisParams.BtclightclientParams genesisState[btclightclienttypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(btclightclientGenState) diff --git a/proto/babylon/btclightclient/v1/genesis.proto b/proto/babylon/btclightclient/v1/genesis.proto index 4de7fce3d..4d747e3f7 100644 --- a/proto/babylon/btclightclient/v1/genesis.proto +++ b/proto/babylon/btclightclient/v1/genesis.proto @@ -10,5 +10,5 @@ option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; // GenesisState defines the btclightclient module's genesis state. message GenesisState { Params params = 1 [(gogoproto.nullable) = false]; - BTCHeaderInfo base_btc_header = 2 [ (gogoproto.nullable) = false ]; + repeated BTCHeaderInfo btc_headers = 2; } diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index 96f39e72e..418a86371 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -314,7 +314,7 @@ func updateBtcLightClientGenesis(blcGenState *blctypes.GenesisState) { panic(err) } work := blctypes.CalcWork(&baseBtcHeader) - blcGenState.BaseBtcHeader = *blctypes.NewBTCHeaderInfo(&baseBtcHeader, baseBtcHeader.Hash(), 0, &work) + blcGenState.BtcHeaders = []*blctypes.BTCHeaderInfo{blctypes.NewBTCHeaderInfo(&baseBtcHeader, baseBtcHeader.Hash(), 0, &work)} } func updateBtccheckpointGenesis(btccheckpointGenState *btccheckpointtypes.GenesisState) { diff --git a/testutil/datagen/btc_header_info.go b/testutil/datagen/btc_header_info.go index 7cd54ebf9..fd81ff63b 100644 --- a/testutil/datagen/btc_header_info.go +++ b/testutil/datagen/btc_header_info.go @@ -1,17 +1,21 @@ package datagen import ( + "context" "math/big" "math/rand" + "testing" "time" sdkmath "cosmossdk.io/math" bbn "github.com/babylonchain/babylon/types" + btclightclientk "github.com/babylonchain/babylon/x/btclightclient/keeper" btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" + "github.com/stretchr/testify/require" ) type RetargetInfo struct { @@ -270,6 +274,34 @@ func GenRandomValidChainStartingFrom( return headers } +// GenRandBtcChainInsertingInKeeper generates random BTCHeaderInfo and insert its headers +// into the keeper store. +// this function must not be used at difficulty adjustment boundaries, as then +// difficulty adjustment calculation will fail +func GenRandBtcChainInsertingInKeeper( + t *testing.T, + r *rand.Rand, + k *btclightclientk.Keeper, + ctx context.Context, + initialHeight uint64, + chainLength uint64, +) (*btclightclienttypes.BTCHeaderInfo, *BTCHeaderPartialChain) { + genesisHeader := NewBTCHeaderChainWithLength(r, initialHeight, 0, 1) + genesisHeaderInfo := genesisHeader.GetChainInfo()[0] + k.SetBaseBTCHeader(ctx, *genesisHeaderInfo) + randomChain := NewBTCHeaderChainFromParentInfo( + r, + genesisHeaderInfo, + uint32(chainLength), + ) + err := k.InsertHeaders(ctx, randomChain.ChainToBytes()) + require.NoError(t, err) + tip := k.GetTipInfo(ctx) + randomChainTipInfo := randomChain.GetTipInfo() + require.True(t, tip.Eq(randomChainTipInfo)) + return genesisHeaderInfo, randomChain +} + func ChainToInfoChain( chain []*wire.BlockHeader, initialHeaderNumber uint64, diff --git a/testutil/helper/store.go b/testutil/helper/store.go new file mode 100644 index 000000000..a304932f7 --- /dev/null +++ b/testutil/helper/store.go @@ -0,0 +1,120 @@ +package helper + +import ( + "bytes" + "fmt" + "sync" + + corestore "cosmossdk.io/core/store" + dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/types/kv" +) + +// DiffKVStores compares two KVstores and returns all the key/value pairs +// that differ from one another. It also skips value comparison for a set of provided prefixes. +func DiffKVStores(a, b corestore.KVStore, prefixesToSkip [][]byte) (diffA, diffB []kv.Pair) { + iterA, err := a.Iterator(nil, nil) + if err != nil { + panic(err) + } + defer iterA.Close() + + iterB, err := b.Iterator(nil, nil) + if err != nil { + panic(err) + } + defer iterB.Close() + + var wg sync.WaitGroup + + wg.Add(1) + kvAs := make([]kv.Pair, 0) + go func() { + defer wg.Done() + kvAs = getKVPairs(iterA, prefixesToSkip) + }() + + wg.Add(1) + kvBs := make([]kv.Pair, 0) + go func() { + defer wg.Done() + kvBs = getKVPairs(iterB, prefixesToSkip) + }() + + wg.Wait() + + if len(kvAs) != len(kvBs) { + fmt.Printf("KV stores are different: %d key/value pairs in store A and %d key/value pairs in store B\n", len(kvAs), len(kvBs)) + } + + return getDiffFromKVPair(kvAs, kvBs) +} + +// getDiffFromKVPair compares two KVstores and returns all the key/value pairs +func getDiffFromKVPair(kvAs, kvBs []kv.Pair) (diffA, diffB []kv.Pair) { + // we assume that kvBs is equal or larger than kvAs + // if not, we swap the two + if len(kvAs) > len(kvBs) { + kvAs, kvBs = kvBs, kvAs + // we need to swap the diffA and diffB as well + defer func() { + diffA, diffB = diffB, diffA + }() + } + + // in case kvAs is empty we can return early + // since there is nothing to compare + // if kvAs == kvBs, then diffA and diffB will be empty + if len(kvAs) == 0 { + return []kv.Pair{}, kvBs + } + + index := make(map[string][]byte, len(kvBs)) + for _, kv := range kvBs { + index[string(kv.Key)] = kv.Value + } + + for _, kvA := range kvAs { + if kvBValue, ok := index[string(kvA.Key)]; !ok { + diffA = append(diffA, kvA) + diffB = append(diffB, kv.Pair{Key: kvA.Key}) // the key is missing from kvB so we append a pair with an empty value + } else if !bytes.Equal(kvA.Value, kvBValue) { + diffA = append(diffA, kvA) + diffB = append(diffB, kv.Pair{Key: kvA.Key, Value: kvBValue}) + } else { + // values are equal, so we remove the key from the index + delete(index, string(kvA.Key)) + } + } + + // add the remaining keys from kvBs + for key, value := range index { + diffA = append(diffA, kv.Pair{Key: []byte(key)}) // the key is missing from kvA so we append a pair with an empty value + diffB = append(diffB, kv.Pair{Key: []byte(key), Value: value}) + } + + return diffA, diffB +} + +func getKVPairs(iter dbm.Iterator, prefixesToSkip [][]byte) (kvs []kv.Pair) { + for iter.Valid() { + key, value := iter.Key(), iter.Value() + + // do not add the KV pair if the key is prefixed to be skipped. + skip := false + for _, prefix := range prefixesToSkip { + if bytes.HasPrefix(key, prefix) { + skip = true + break + } + } + + if !skip { + kvs = append(kvs, kv.Pair{Key: key, Value: value}) + } + + iter.Next() + } + + return kvs +} diff --git a/testutil/keeper/btclightclient.go b/testutil/keeper/btclightclient.go index d4e371894..e3ca1e3e6 100644 --- a/testutil/keeper/btclightclient.go +++ b/testutil/keeper/btclightclient.go @@ -4,10 +4,12 @@ import ( "testing" "cosmossdk.io/core/header" + corestore "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/store" storemetrics "cosmossdk.io/store/metrics" storetypes "cosmossdk.io/store/types" + "github.com/btcsuite/btcd/wire" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/codec" @@ -20,16 +22,26 @@ import ( bapp "github.com/babylonchain/babylon/app" bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + btclightclientk "github.com/babylonchain/babylon/x/btclightclient/keeper" + btclightclientt "github.com/babylonchain/babylon/x/btclightclient/types" ) -func BTCLightClientKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { - return BTCLightClientKeeperWithCustomParams(t, types.DefaultParams()) +func BTCLightClientKeeper(t testing.TB) (*btclightclientk.Keeper, sdk.Context) { + k, ctx, _ := BTCLightClientKeeperWithCustomParams(t, btclightclientt.DefaultParams()) + return k, ctx } -func BTCLightClientKeeperWithCustomParams(t testing.TB, p types.Params) (*keeper.Keeper, sdk.Context) { - storeKey := storetypes.NewKVStoreKey(types.StoreKey) +// NewBTCHeaderBytesList takes a list of block headers and parses it to BTCHeaderBytes. +func NewBTCHeaderBytesList(chain []*wire.BlockHeader) []bbn.BTCHeaderBytes { + chainBytes := make([]bbn.BTCHeaderBytes, len(chain)) + for i, header := range chain { + chainBytes[i] = bbn.NewBTCHeaderBytesFromBlockHeader(header) + } + return chainBytes +} + +func BTCLightClientKeeperWithCustomParams(t testing.TB, p btclightclientt.Params) (*btclightclientk.Keeper, sdk.Context, corestore.KVStoreService) { + storeKey := storetypes.NewKVStoreKey(btclightclientt.StoreKey) db := dbm.NewMemDB() stateStore := store.NewCommitMultiStore(db, log.NewTestLogger(t), storemetrics.NewNoOpMetrics()) @@ -41,9 +53,10 @@ func BTCLightClientKeeperWithCustomParams(t testing.TB, p types.Params) (*keeper testCfg := bbn.ParseBtcOptionsFromConfig(bapp.EmptyAppOptions{}) - k := keeper.NewKeeper( + stServ := runtime.NewKVStoreService(storeKey) + k := btclightclientk.NewKeeper( cdc, - runtime.NewKVStoreService(storeKey), + stServ, testCfg, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) @@ -55,5 +68,5 @@ func BTCLightClientKeeperWithCustomParams(t testing.TB, p types.Params) (*keeper panic(err) } - return &k, ctx + return &k, ctx, stServ } diff --git a/types/btc_header_bytes.go b/types/btc_header_bytes.go index af11630c4..a4ff2c741 100644 --- a/types/btc_header_bytes.go +++ b/types/btc_header_bytes.go @@ -5,10 +5,11 @@ import ( "encoding/hex" "encoding/json" "errors" - "github.com/btcsuite/btcd/blockchain" - "github.com/btcsuite/btcd/wire" "math/big" "time" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/wire" ) type BTCHeaderBytes []byte @@ -71,7 +72,7 @@ func (m *BTCHeaderBytes) Unmarshal(data []byte) error { return errors.New("invalid header length") } // Verify that the bytes can be transformed to a *wire.BlockHeader object - _, err := toBlockHeader(data) + _, err := NewBlockHeader(data) if err != nil { return errors.New("bytes do not correspond to a *wire.BlockHeader object") } @@ -116,7 +117,7 @@ func (m *BTCHeaderBytes) Size() int { } func (m BTCHeaderBytes) ToBlockHeader() *wire.BlockHeader { - header, err := toBlockHeader(m) + header, err := NewBlockHeader(m) // There was a parsing error if err != nil { panic("BTCHeaderBytes cannot be converted to a block header object") @@ -172,7 +173,8 @@ func (m *BTCHeaderBytes) Difficulty() *big.Int { return blockchain.CompactToBig(m.Bits()) } -func toBlockHeader(data []byte) (*wire.BlockHeader, error) { +// NewBlockHeader creates a block header from bytes. +func NewBlockHeader(data []byte) (*wire.BlockHeader, error) { // Create an empty header header := &wire.BlockHeader{} diff --git a/x/btclightclient/genesis.go b/x/btclightclient/genesis.go index d19d9dfee..81d2f3ff5 100644 --- a/x/btclightclient/genesis.go +++ b/x/btclightclient/genesis.go @@ -9,27 +9,22 @@ import ( // InitGenesis initializes the capability module's state from a provided genesis // state. -func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { - if err := genState.Validate(); err != nil { +func InitGenesis(ctx context.Context, k keeper.Keeper, gs types.GenesisState) { + if err := gs.Validate(); err != nil { panic(err) } - k.SetBaseBTCHeader(ctx, genState.BaseBtcHeader) - if err := k.SetParams(ctx, genState.Params); err != nil { + if err := k.SetParams(ctx, gs.Params); err != nil { panic(err) } + + k.InsertHeaderInfos(ctx, gs.BtcHeaders) } // ExportGenesis returns the capability module's exported genesis. func ExportGenesis(ctx context.Context, k keeper.Keeper) *types.GenesisState { - genesis := types.DefaultGenesis() - baseBTCHeader := k.GetBaseBTCHeader(ctx) - if baseBTCHeader == nil { - panic("A base BTC Header has not been set") + return &types.GenesisState{ + Params: k.GetParams(ctx), + BtcHeaders: k.GetMainChainFrom(ctx, 0), } - - genesis.BaseBtcHeader = *baseBTCHeader - genesis.Params = k.GetParams(ctx) - - return genesis } diff --git a/x/btclightclient/genesis_test.go b/x/btclightclient/genesis_test.go index 3f9ca2a2f..a91066e4f 100644 --- a/x/btclightclient/genesis_test.go +++ b/x/btclightclient/genesis_test.go @@ -1,19 +1,27 @@ package btclightclient_test import ( + "math/rand" "testing" + "time" + "github.com/babylonchain/babylon/testutil/datagen" + thelper "github.com/babylonchain/babylon/testutil/helper" keepertest "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/testutil/nullify" "github.com/babylonchain/babylon/x/btclightclient" + "github.com/babylonchain/babylon/x/btclightclient/keeper" "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/cometbft/cometbft/crypto/secp256k1" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestGenesis(t *testing.T) { baseHeaderInfo := types.SimnetGenesisBlock() genesisState := types.GenesisState{ - BaseBtcHeader: baseHeaderInfo, + BtcHeaders: []*types.BTCHeaderInfo{&baseHeaderInfo}, } k, ctx := keepertest.BTCLightClientKeeper(t) @@ -24,3 +32,67 @@ func TestGenesis(t *testing.T) { nullify.Fill(&genesisState) nullify.Fill(got) } + +func TestImportExport(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + sender1 := secp256k1.GenPrivKey() + address1, err := sdk.AccAddressFromHexUnsafe(sender1.PubKey().Address().String()) + require.NoError(t, err) + sender2 := secp256k1.GenPrivKey() + address2, err := sdk.AccAddressFromHexUnsafe(sender2.PubKey().Address().String()) + require.NoError(t, err) + + params := types.NewParams( + // only sender1 and sender2 are allowed to update + []string{address1.String(), address2.String()}, + ) + + k, ctx, stServ := keepertest.BTCLightClientKeeperWithCustomParams(t, params) + srv := keeper.NewMsgServerImpl(*k) + + _, chain := datagen.GenRandBtcChainInsertingInKeeper(t, r, k, ctx, 0, 10) + initTip := chain.GetTipInfo() + + chainExtension := datagen.GenRandomValidChainStartingFrom( + r, + initTip.Height, + initTip.Header.ToBlockHeader(), + nil, + 10, + ) + + // sender 1 is allowed to update, it should succeed + msg := &types.MsgInsertHeaders{Signer: address1.String(), Headers: keepertest.NewBTCHeaderBytesList(chainExtension)} + _, err = srv.InsertHeaders(ctx, msg) + require.NoError(t, err) + + newTip := k.GetTipInfo(ctx) + require.NotNil(t, newTip) + + newChainExt := datagen.GenRandomValidChainStartingFrom( + r, + newTip.Height, + newTip.Header.ToBlockHeader(), + nil, + 10, + ) + + msg1 := &types.MsgInsertHeaders{Signer: address2.String(), Headers: keepertest.NewBTCHeaderBytesList(newChainExt)} + _, err = srv.InsertHeaders(ctx, msg1) + require.NoError(t, err) + + genState := btclightclient.ExportGenesis(ctx, *k) + KvA := stServ.OpenKVStore(ctx) + + kB, ctxb, stServB := keepertest.BTCLightClientKeeperWithCustomParams(t, params) + btclightclient.InitGenesis(ctxb, *kB, *genState) + + infos := kB.GetMainChainFrom(ctxb, 0) + require.Equal(t, len(infos), len(genState.BtcHeaders), "it should have the same amount of headers from before") + + KvB := stServB.OpenKVStore(ctxb) + + failedKVAs, failedKVBs := thelper.DiffKVStores(KvA, KvB, [][]byte{}) + require.Equal(t, len(failedKVAs), len(failedKVBs), "unequal sets of key-values to compare btcligthclient") + require.Equal(t, len(failedKVAs), 0, "should not exist any difference froms states.") +} diff --git a/x/btclightclient/keeper/grpc_query_test.go b/x/btclightclient/keeper/grpc_query_test.go index 15289a490..1d2829614 100644 --- a/x/btclightclient/keeper/grpc_query_test.go +++ b/x/btclightclient/keeper/grpc_query_test.go @@ -8,7 +8,7 @@ import ( bbn "github.com/babylonchain/babylon/types" "github.com/cosmos/cosmos-sdk/types/query" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" + keepertest "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/x/btclightclient/types" ) @@ -34,7 +34,7 @@ func FuzzHashesQuery(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil request resp, err := blcKeeper.Hashes(ctx, nil) @@ -59,7 +59,7 @@ func FuzzHashesQuery(f *testing.F) { t.Errorf("Invalid key led to a nil error") } - baseHeader, chain := genRandomChain( + baseHeader, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -133,7 +133,7 @@ func FuzzContainsQuery(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input resp, err := blcKeeper.Contains(ctx, nil) @@ -145,7 +145,7 @@ func FuzzContainsQuery(f *testing.F) { } // Generate a random chain of headers and insert it into storage - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -200,7 +200,7 @@ func FuzzMainChainQuery(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input resp, err := blcKeeper.MainChain(ctx, nil) @@ -226,7 +226,7 @@ func FuzzMainChainQuery(f *testing.F) { } // Generate a random chain of headers and insert it into storage - base, chain := genRandomChain( + base, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -327,7 +327,7 @@ func FuzzTipQuery(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input resp, err := blcKeeper.Tip(ctx, nil) @@ -339,7 +339,7 @@ func FuzzTipQuery(f *testing.F) { } // Generate a random chain of headers and insert it into storage - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -373,7 +373,7 @@ func FuzzBaseHeaderQuery(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input resp, err := blcKeeper.BaseHeader(ctx, nil) @@ -385,7 +385,7 @@ func FuzzBaseHeaderQuery(f *testing.F) { } // Generate a random chain of headers and insert it into storage - base, _ := genRandomChain( + base, _ := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index 78e370c6c..942734798 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -94,6 +94,14 @@ func (k Keeper) insertHeaders( return nil } +// InsertHeaderInfos inserts multiple headers info at the store. +func (k Keeper) InsertHeaderInfos(ctx context.Context, infos []*types.BTCHeaderInfo) { + hs := k.headersState(ctx) + for _, inf := range infos { + hs.insertHeader(inf) + } +} + func (k Keeper) InsertHeaders(ctx context.Context, headers []bbn.BTCHeaderBytes) error { if len(headers) == 0 { return types.ErrEmptyMessage diff --git a/x/btclightclient/keeper/keeper_test.go b/x/btclightclient/keeper/keeper_test.go index df9d6bb53..93e1ff905 100644 --- a/x/btclightclient/keeper/keeper_test.go +++ b/x/btclightclient/keeper/keeper_test.go @@ -11,7 +11,7 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" + keepertest "github.com/babylonchain/babylon/testutil/keeper" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) @@ -32,7 +32,7 @@ func FuzzKeeperMainChainDepth(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input depth, err := blcKeeper.MainChainDepth(ctx, nil) @@ -53,7 +53,7 @@ func FuzzKeeperMainChainDepth(f *testing.F) { t.Errorf("Non existing header led to a result that is not -1") } - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -85,7 +85,7 @@ func FuzzKeeperBlockHeight(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) // Test nil input height, err := blcKeeper.BlockHeight(ctx, nil) @@ -106,7 +106,7 @@ func FuzzKeeperBlockHeight(f *testing.F) { t.Errorf("Non existing header led to a result that is not -1") } - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -130,9 +130,9 @@ func FuzzKeeperInsertValidChainExtension(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -160,7 +160,7 @@ func FuzzKeeperInsertValidChainExtension(f *testing.F) { extendedChainWork := oldTip.Work.Add(*chainExtensionWork) extendedChainHeight := uint64(uint32(oldTip.Height) + newChainLength) - err := blcKeeper.InsertHeaders(ctx, chainToChainBytes(chainToInsert)) + err := blcKeeper.InsertHeaders(ctx, keepertest.NewBTCHeaderBytesList(chainToInsert)) require.NoError(t, err) // updated tip @@ -213,8 +213,8 @@ func FuzzKeeperInsertValidBetterChain(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) - _, chain := genRandomChain( + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -247,7 +247,7 @@ func FuzzKeeperInsertValidBetterChain(f *testing.F) { require.True(t, len(removedBranch) > 0) - err := blcKeeper.InsertHeaders(ctx, chainToChainBytes(chainToInsert)) + err := blcKeeper.InsertHeaders(ctx, keepertest.NewBTCHeaderBytesList(chainToInsert)) require.NoError(t, err) // updated tip @@ -319,8 +319,8 @@ func FuzzKeeperInsertInvalidChain(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) - _, _ = genRandomChain( + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) + _, _ = datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -358,7 +358,7 @@ func FuzzKeeperInsertInvalidChain(f *testing.F) { // bump the nonce, it should fail validation and tip should not change chainToInsert[3].Nonce = chainToInsert[3].Nonce + 1 - errInvalidHeader := blcKeeper.InsertHeaders(ctx, chainToChainBytes(chainToInsert)) + errInvalidHeader := blcKeeper.InsertHeaders(ctx, keepertest.NewBTCHeaderBytesList(chainToInsert)) require.Error(t, errInvalidHeader) newTip := blcKeeper.GetTipInfo(ctx) // tip did not change @@ -374,7 +374,7 @@ func FuzzKeeperInsertInvalidChain(f *testing.F) { nil, 1, ) - errWorseChain := blcKeeper.InsertHeaders(ctx, chainToChainBytes(worseChain)) + errWorseChain := blcKeeper.InsertHeaders(ctx, keepertest.NewBTCHeaderBytesList(worseChain)) require.Error(t, errWorseChain) require.True(t, errors.Is(errWorseChain, types.ErrChainWithNotEnoughWork)) }) @@ -386,7 +386,7 @@ func FuzzKeeperValdateHeaderAtDifficultyAdjustmentBoundaries(f *testing.F) { f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) numBlockPerRetarget := types.BlocksPerRetarget(&chaincfg.SimNetParams) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) genesisHeader := bbn.NewBTCHeaderBytesFromBlockHeader(&chaincfg.SimNetParams.GenesisBlock.Header) genesisHash := bbn.NewBTCHeaderHashBytesFromChainhash(chaincfg.SimNetParams.GenesisHash) @@ -413,7 +413,7 @@ func FuzzKeeperValdateHeaderAtDifficultyAdjustmentBoundaries(f *testing.F) { require.Error(t, err) randomChainWithoutLastHeader := randomChain.Headers[:len(randomChain.Headers)-1] - chain := chainToChainBytes(randomChainWithoutLastHeader) + chain := keepertest.NewBTCHeaderBytesList(randomChainWithoutLastHeader) // now all headers are valid, and we are below adjustment boundary err = blcKeeper.InsertHeaders(ctx, chain) require.NoError(t, err) diff --git a/x/btclightclient/keeper/msg_server_test.go b/x/btclightclient/keeper/msg_server_test.go index a3dacb251..8d9bd3735 100644 --- a/x/btclightclient/keeper/msg_server_test.go +++ b/x/btclightclient/keeper/msg_server_test.go @@ -22,7 +22,7 @@ func setupMsgServer(t testing.TB) (types.MsgServer, *keeper.Keeper, context.Cont } func setupMsgServerWithCustomParams(t testing.TB, p types.Params) (types.MsgServer, *keeper.Keeper, context.Context) { - k, ctx := keepertest.BTCLightClientKeeperWithCustomParams(t, p) + k, ctx, _ := keepertest.BTCLightClientKeeperWithCustomParams(t, p) return keeper.NewMsgServerImpl(*k), k, ctx } @@ -38,7 +38,7 @@ func FuzzMsgServerInsertNewTip(f *testing.F) { r := rand.New(rand.NewSource(seed)) srv, blcKeeper, sdkCtx := setupMsgServer(t) ctx := sdk.UnwrapSDKContext(sdkCtx) - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -67,7 +67,7 @@ func FuzzMsgServerInsertNewTip(f *testing.F) { ) chainExtensionWork := chainWork(chainExtension) - msg := &types.MsgInsertHeaders{Signer: address.String(), Headers: chainToChainBytes(chainExtension)} + msg := &types.MsgInsertHeaders{Signer: address.String(), Headers: keepertest.NewBTCHeaderBytesList(chainExtension)} _, err := srv.InsertHeaders(sdkCtx, msg) require.NoError(t, err) @@ -99,7 +99,7 @@ func FuzzMsgServerReorgChain(f *testing.F) { ctx := sdk.UnwrapSDKContext(sdkCtx) chainLength := datagen.RandomInt(r, 50) + 10 - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -134,7 +134,7 @@ func FuzzMsgServerReorgChain(f *testing.F) { uint32(forkChainLen), ) chainExtensionWork := chainWork(chainExtension) - msg := &types.MsgInsertHeaders{Signer: address.String(), Headers: chainToChainBytes(chainExtension)} + msg := &types.MsgInsertHeaders{Signer: address.String(), Headers: keepertest.NewBTCHeaderBytesList(chainExtension)} _, err := srv.InsertHeaders(sdkCtx, msg) require.NoError(t, err) @@ -173,7 +173,7 @@ func TestAllowUpdatesOnlyFromReportesInTheList(t *testing.T) { srv, blcKeeper, sdkCtx := setupMsgServerWithCustomParams(t, params) ctx := sdk.UnwrapSDKContext(sdkCtx) - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, @@ -201,7 +201,7 @@ func TestAllowUpdatesOnlyFromReportesInTheList(t *testing.T) { ) // sender 1 is allowed to update, it should succeed - msg := &types.MsgInsertHeaders{Signer: address1.String(), Headers: chainToChainBytes(chainExtension)} + msg := &types.MsgInsertHeaders{Signer: address1.String(), Headers: keepertest.NewBTCHeaderBytesList(chainExtension)} _, err = srv.InsertHeaders(sdkCtx, msg) require.NoError(t, err) @@ -217,13 +217,13 @@ func TestAllowUpdatesOnlyFromReportesInTheList(t *testing.T) { ) // sender 3 is not allowed to update, it should fail - msg1 := &types.MsgInsertHeaders{Signer: address3.String(), Headers: chainToChainBytes(newChainExt)} + msg1 := &types.MsgInsertHeaders{Signer: address3.String(), Headers: keepertest.NewBTCHeaderBytesList(newChainExt)} _, err = srv.InsertHeaders(sdkCtx, msg1) require.Error(t, err) require.ErrorIs(t, err, types.ErrUnauthorizedReporter) // sender 2 is allowed to update, it should succeed - msg1 = &types.MsgInsertHeaders{Signer: address2.String(), Headers: chainToChainBytes(newChainExt)} + msg1 = &types.MsgInsertHeaders{Signer: address2.String(), Headers: keepertest.NewBTCHeaderBytesList(newChainExt)} _, err = srv.InsertHeaders(sdkCtx, msg1) require.NoError(t, err) } diff --git a/x/btclightclient/keeper/state_test.go b/x/btclightclient/keeper/state_test.go index 296509e62..eb1e3c892 100644 --- a/x/btclightclient/keeper/state_test.go +++ b/x/btclightclient/keeper/state_test.go @@ -7,7 +7,7 @@ import ( bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" + keepertest "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) @@ -28,7 +28,7 @@ func FuzzHeadersStateCreateHeader(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - blcKeeper, ctx := testkeeper.BTCLightClientKeeper(t) + blcKeeper, ctx := keepertest.BTCLightClientKeeper(t) state := blcKeeper.HeadersState(ctx) // operations no empty state @@ -62,7 +62,7 @@ func FuzzHeadersStateCreateHeader(f *testing.F) { initchainHeight := datagen.RandomInt(r, 50) + 10 // populate the state with random chain - _, chain := genRandomChain( + _, chain := datagen.GenRandBtcChainInsertingInKeeper( t, r, blcKeeper, diff --git a/x/btclightclient/keeper/utils_test.go b/x/btclightclient/keeper/utils_test.go index 413918cc3..ec1131655 100644 --- a/x/btclightclient/keeper/utils_test.go +++ b/x/btclightclient/keeper/utils_test.go @@ -3,12 +3,9 @@ package keeper_test import ( "context" "math/big" - "math/rand" "testing" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btclightclient/keeper" "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/blockchain" @@ -54,32 +51,6 @@ func allFieldsEqual(a *types.BTCHeaderInfo, b *types.BTCHeaderInfo) bool { return a.Height == b.Height && a.Hash.Eq(b.Hash) && a.Header.Eq(b.Header) && a.Work.Equal(*b.Work) } -// this function must not be used at difficulty adjustment boundaries, as then -// difficulty adjustment calculation will fail -func genRandomChain( - t *testing.T, - r *rand.Rand, - k *keeper.Keeper, - ctx context.Context, - initialHeight uint64, - chainLength uint64, -) (*types.BTCHeaderInfo, *datagen.BTCHeaderPartialChain) { - genesisHeader := datagen.NewBTCHeaderChainWithLength(r, initialHeight, 0, 1) - genesisHeaderInfo := genesisHeader.GetChainInfo()[0] - k.SetBaseBTCHeader(ctx, *genesisHeaderInfo) - randomChain := datagen.NewBTCHeaderChainFromParentInfo( - r, - genesisHeaderInfo, - uint32(chainLength), - ) - err := k.InsertHeaders(ctx, randomChain.ChainToBytes()) - require.NoError(t, err) - tip := k.GetTipInfo(ctx) - randomChainTipInfo := randomChain.GetTipInfo() - require.True(t, allFieldsEqual(tip, randomChainTipInfo)) - return genesisHeaderInfo, randomChain -} - func checkTip( t *testing.T, ctx context.Context, @@ -107,14 +78,6 @@ func checkTip( require.True(t, currentTip.Header.Hash().ToChainhash().IsEqual(&expectedTipHeaderHash)) } -func chainToChainBytes(chain []*wire.BlockHeader) []bbn.BTCHeaderBytes { - chainBytes := make([]bbn.BTCHeaderBytes, len(chain)) - for i, header := range chain { - chainBytes[i] = bbn.NewBTCHeaderBytesFromBlockHeader(header) - } - return chainBytes -} - func chainWork(chain []*wire.BlockHeader) *sdkmath.Uint { totalWork := sdkmath.NewUint(0) for _, header := range chain { diff --git a/x/btclightclient/types/btc_header_info.go b/x/btclightclient/types/btc_header_info.go index bb16a839c..fb3c5e6a3 100644 --- a/x/btclightclient/types/btc_header_info.go +++ b/x/btclightclient/types/btc_header_info.go @@ -1,6 +1,9 @@ package types import ( + "errors" + "fmt" + sdkmath "cosmossdk.io/math" bbn "github.com/babylonchain/babylon/types" ) @@ -21,3 +24,33 @@ func (m *BTCHeaderInfo) HasParent(parent *BTCHeaderInfo) bool { func (m *BTCHeaderInfo) Eq(other *BTCHeaderInfo) bool { return m.Hash.Eq(other.Hash) } + +// Validate verifies that the information inside the BTCHeaderInfo is valid. +func (m *BTCHeaderInfo) Validate() error { + if m.Header == nil { + return errors.New("header is nil") + } + if m.Hash == nil { + return errors.New("hash is nil") + } + if m.Work == nil { + return errors.New("work is nil") + } + + if m.Work.IsZero() { + return errors.New("work is zero") + } + + btcHeader, err := bbn.NewBlockHeader(*m.Header) + if err != nil { + return err + } + + blkHash := btcHeader.BlockHash() + headerHash := bbn.NewBTCHeaderHashBytesFromChainhash(&blkHash) + if !m.Hash.Eq(&headerHash) { + return fmt.Errorf("BTC header hash is not equal to generated hash from header %s != %s", m.Hash, &headerHash) + } + + return nil +} diff --git a/x/btclightclient/types/btc_header_info_test.go b/x/btclightclient/types/btc_header_info_test.go index 8a9e8d2ea..f0afe81cd 100644 --- a/x/btclightclient/types/btc_header_info_test.go +++ b/x/btclightclient/types/btc_header_info_test.go @@ -2,13 +2,17 @@ package types_test import ( "bytes" + "errors" + "fmt" "math/rand" "testing" sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/stretchr/testify/require" ) func FuzzNewHeaderInfo(f *testing.F) { @@ -57,3 +61,88 @@ func FuzzNewHeaderInfo(f *testing.F) { } }) } + +func TestBTCHeaderInfoValidate(t *testing.T) { + r := rand.New(rand.NewSource(120)) + valid := *datagen.GenRandomBTCHeaderInfo(r) + valid2 := *datagen.GenRandomBTCHeaderInfo(r) + zeroUint := sdkmath.ZeroUint() + + tcs := []struct { + title string + info types.BTCHeaderInfo + expectedErr error + }{ + { + "valid", + valid, + nil, + }, + { + "valid2", + valid2, + nil, + }, + { + "invalid: header nil", + types.BTCHeaderInfo{}, + errors.New("header is nil"), + }, + { + "invalid: hash nil", + types.BTCHeaderInfo{ + Header: valid.Header, + }, + errors.New("hash is nil"), + }, + { + "invalid: work nil", + types.BTCHeaderInfo{ + Header: valid.Header, + Hash: valid.Hash, + }, + errors.New("work is nil"), + }, + { + "invalid: work is zero", + types.BTCHeaderInfo{ + Header: valid.Header, + Hash: valid.Hash, + Work: &zeroUint, + Height: valid.Height, + }, + errors.New("work is zero"), + }, + { + "invalid: bad block header", + types.BTCHeaderInfo{ + Header: &bbn.BTCHeaderBytes{byte(1)}, + Hash: valid.Hash, + Work: valid.Work, + Height: valid.Height, + }, + errors.New("unexpected EOF"), + }, + { + "invalid: bad block header", + types.BTCHeaderInfo{ + Header: valid.Header, + Hash: valid2.Hash, + Work: valid.Work, + Height: valid.Height, + }, + fmt.Errorf("BTC header hash is not equal to generated hash from header %s != %s", valid2.Hash, valid.Hash), + }, + } + + for _, tc := range tcs { + t.Run(tc.title, func(t *testing.T) { + actErr := tc.info.Validate() + if tc.expectedErr != nil { + require.EqualError(t, actErr, tc.expectedErr.Error()) + return + } + require.NoError(t, actErr) + }) + } +} diff --git a/x/btclightclient/types/genesis.go b/x/btclightclient/types/genesis.go index 2f5300632..203c4e11b 100644 --- a/x/btclightclient/types/genesis.go +++ b/x/btclightclient/types/genesis.go @@ -1,6 +1,7 @@ package types import ( + "errors" "fmt" bbn "github.com/babylonchain/babylon/types" @@ -29,28 +30,44 @@ func DefaultGenesis() *GenesisState { defaultBaseHeader := SimnetGenesisBlock() return &GenesisState{ - BaseBtcHeader: defaultBaseHeader, - Params: DefaultParams(), + BtcHeaders: []*BTCHeaderInfo{&defaultBaseHeader}, + Params: DefaultParams(), } } // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return fmt.Errorf("invalid params in genesis: %w", err) + } + + // Initial btc header serves as de-facto genesis header for the module. + // At least one BTC Header is needed to apply all validation rules to the next headers. + // If we don't have an initial btc header, we cannot validate the rules on the next (as it has no parent). + // All following headers that are to be inserted in chain are going to be validated based on the previous ones. + // (all parent-child relantionships, all difficulty transitions). + if len(gs.BtcHeaders) == 0 { + // if you have no initial header, you can't validate the following ones. + return errors.New("no btc header set on genesis") + } + // We Require that genesis block is difficulty adjustment block, so that we can // properly calculate the difficulty adjustments in the future. // TODO: Even though number of block per re-target depends on the network, in reality it // is always 2016. Maybe we should consider moving it to param, or try to pass // it through - isRetarget := IsRetargetBlock(&gs.BaseBtcHeader, &chaincfg.MainNetParams) - + isRetarget := IsRetargetBlock(gs.BtcHeaders[0], &chaincfg.MainNetParams) if !isRetarget { return fmt.Errorf("genesis block must be a difficulty adjustment block") } - if err := gs.Params.Validate(); err != nil { - return fmt.Errorf("invalid params in genesis: %w", err) + for _, header := range gs.BtcHeaders { + if err := header.Validate(); err != nil { + return err + } } + // TODO: validate headers have proper parent-child relationships and proper proof of work return nil } diff --git a/x/btclightclient/types/genesis.pb.go b/x/btclightclient/types/genesis.pb.go index d3cc8819a..df669279a 100644 --- a/x/btclightclient/types/genesis.pb.go +++ b/x/btclightclient/types/genesis.pb.go @@ -25,8 +25,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the btclightclient module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - BaseBtcHeader BTCHeaderInfo `protobuf:"bytes,2,opt,name=base_btc_header,json=baseBtcHeader,proto3" json:"base_btc_header"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + BtcHeaders []*BTCHeaderInfo `protobuf:"bytes,2,rep,name=btc_headers,json=btcHeaders,proto3" json:"btc_headers,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -69,11 +69,11 @@ func (m *GenesisState) GetParams() Params { return Params{} } -func (m *GenesisState) GetBaseBtcHeader() BTCHeaderInfo { +func (m *GenesisState) GetBtcHeaders() []*BTCHeaderInfo { if m != nil { - return m.BaseBtcHeader + return m.BtcHeaders } - return BTCHeaderInfo{} + return nil } func init() { @@ -85,24 +85,23 @@ func init() { } var fileDescriptor_4f95902e4096217a = []byte{ - // 260 bytes of a gzipped FileDescriptorProto + // 256 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4f, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0xfa, 0xe9, 0xa9, 0x79, 0xa9, 0xc5, 0x99, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x92, 0x50, 0x85, 0x7a, 0xa8, 0x0a, 0xf5, 0xca, 0x0c, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xaa, 0xf4, 0x41, 0x2c, 0x88, 0x06, 0x29, 0x3d, 0xdc, 0x26, 0xa3, 0x19, 0x01, 0x51, - 0xaf, 0x86, 0x5b, 0x7d, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, 0x21, 0x4a, 0xcb, 0x19, 0xb9, 0x78, + 0xaf, 0x86, 0x5b, 0x7d, 0x41, 0x62, 0x51, 0x62, 0x2e, 0xd4, 0x21, 0x4a, 0xb3, 0x18, 0xb9, 0x78, 0xdc, 0x21, 0x4e, 0x0b, 0x2e, 0x49, 0x2c, 0x49, 0x15, 0xb2, 0xe7, 0x62, 0x83, 0x28, 0x90, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd4, 0xc3, 0xe9, 0x54, 0xbd, 0x00, 0xb0, 0x42, 0x27, 0x96, - 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0xda, 0x84, 0xc2, 0xb8, 0xf8, 0x93, 0x12, 0x8b, 0x53, 0xe3, - 0x93, 0x4a, 0x92, 0xe3, 0x33, 0x52, 0x13, 0x53, 0x52, 0x8b, 0x24, 0x98, 0xc0, 0x26, 0x69, 0xe0, - 0x31, 0xc9, 0x29, 0xc4, 0xd9, 0x03, 0xac, 0xd6, 0x33, 0x2f, 0x2d, 0x1f, 0x6a, 0x20, 0x2f, 0xc8, - 0x18, 0xa7, 0x92, 0x64, 0x88, 0x84, 0x53, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, - 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, - 0x31, 0x44, 0x99, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0xad, - 0x48, 0xce, 0x48, 0xcc, 0xcc, 0x83, 0x71, 0xf4, 0x2b, 0xd0, 0x43, 0xa1, 0xa4, 0xb2, 0x20, 0xb5, - 0x38, 0x89, 0x0d, 0x1c, 0x04, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x0c, 0x15, 0x34, - 0xb6, 0x01, 0x00, 0x00, + 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0xda, 0x84, 0x3c, 0xb9, 0xb8, 0x93, 0x4a, 0x92, 0xe3, 0x33, + 0x52, 0x13, 0x53, 0x52, 0x8b, 0x8a, 0x25, 0x98, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0x34, 0xf0, 0x98, + 0xe2, 0x14, 0xe2, 0xec, 0x01, 0x56, 0xec, 0x99, 0x97, 0x96, 0x1f, 0xc4, 0x95, 0x54, 0x92, 0x0c, + 0xe1, 0x16, 0x3b, 0x05, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, + 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x59, + 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xe4, 0xe4, 0x8c, 0xc4, + 0xcc, 0x3c, 0x18, 0x47, 0xbf, 0x02, 0xdd, 0xe3, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, + 0x5f, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xed, 0x4f, 0xca, 0x25, 0xa9, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -125,16 +124,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - { - size, err := m.BaseBtcHeader.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.BtcHeaders) > 0 { + for iNdEx := len(m.BtcHeaders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BtcHeaders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0x12 { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -167,8 +170,12 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) - l = m.BaseBtcHeader.Size() - n += 1 + l + sovGenesis(uint64(l)) + if len(m.BtcHeaders) > 0 { + for _, e := range m.BtcHeaders { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -242,7 +249,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BaseBtcHeader", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field BtcHeaders", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -269,7 +276,8 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.BaseBtcHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.BtcHeaders = append(m.BtcHeaders, &BTCHeaderInfo{}) + if err := m.BtcHeaders[len(m.BtcHeaders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/btclightclient/types/genesis_test.go b/x/btclightclient/types/genesis_test.go index 15e458280..29695c129 100644 --- a/x/btclightclient/types/genesis_test.go +++ b/x/btclightclient/types/genesis_test.go @@ -19,18 +19,27 @@ func TestGenesisState_Validate(t *testing.T) { valid: true, }, { - desc: "valid genesis state", + desc: "invalid genesis state, no btc header", genState: &types.GenesisState{}, - valid: true, + valid: false, + }, + { + desc: "invalid genesis state", + genState: &types.GenesisState{ + BtcHeaders: []*types.BTCHeaderInfo{&types.BTCHeaderInfo{ + Height: 1, + }}, + }, + valid: false, }, } { t.Run(tc.desc, func(t *testing.T) { err := tc.genState.Validate() if tc.valid { require.NoError(t, err) - } else { - require.Error(t, err) + return } + require.Error(t, err) }) } } From 6bc8f51b3ce61544529857211cd80ffde189b61c Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 13 Mar 2024 18:22:56 +0100 Subject: [PATCH 044/119] Generating and parsing enhanced staking tx --- btcstaking/enhanced_staking.go | 413 ++++++++++++++++++++++++++++ btcstaking/enhanced_staking_test.go | 98 +++++++ 2 files changed, 511 insertions(+) create mode 100644 btcstaking/enhanced_staking.go create mode 100644 btcstaking/enhanced_staking_test.go diff --git a/btcstaking/enhanced_staking.go b/btcstaking/enhanced_staking.go new file mode 100644 index 000000000..61f88ab31 --- /dev/null +++ b/btcstaking/enhanced_staking.go @@ -0,0 +1,413 @@ +package btcstaking + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" +) + +const ( + // length of magic prefix indentifying staking transactions + MagicBytesLen = 4 + // 4 bytes magic bytes + 1 byte version + 32 bytes staker public key + 32 bytes finality provider public key + 2 bytes staking time + V0OpReturnDataSize = 71 +) + +type EnhancedStakingInfo struct { + StakingOutput *wire.TxOut + scriptHolder *taprootScriptHolder + timeLockPathLeafHash chainhash.Hash + unbondingPathLeafHash chainhash.Hash + slashingPathLeafHash chainhash.Hash + OpReturnOutput *wire.TxOut +} + +// XonlyPubKey is a wrapper around btcec.PublicKey that represents BTC public +// key deserialized from a 32-byte array i.e with implicit assumption thah Y coordinate +// is even. +type XonlyPubKey struct { + PubKey *btcec.PublicKey +} + +func XOnlyPublicKeyFromBytes(pkBytes []byte) (*XonlyPubKey, error) { + pk, err := schnorr.ParsePubKey(pkBytes) + + if err != nil { + return nil, err + } + + return &XonlyPubKey{pk}, nil +} + +func (p *XonlyPubKey) Marshall() []byte { + return schnorr.SerializePubKey(p.PubKey) +} + +func uint16ToBytes(v uint16) []byte { + var buf [2]byte + binary.BigEndian.PutUint16(buf[:], v) + return buf[:] +} + +func uint16FromBytes(b []byte) (uint16, error) { + if len(b) != 2 { + return 0, fmt.Errorf("invalid uint16 bytes length: %d", len(b)) + } + + return binary.BigEndian.Uint16(b), nil +} + +// V0OpReturnData represents the data that is embedded in the OP_RETURN output +// It marshalls to exactly 71 bytes +type V0OpReturnData struct { + MagicBytes []byte + Version byte + StakerPublicKey *XonlyPubKey + FinalityProviderPublicKey *XonlyPubKey + StakingTime uint16 +} + +func NewV0OpReturnData( + magicBytes []byte, + stakerPublicKey []byte, + finalityProviderPublicKey []byte, + stakingTime []byte, +) (*V0OpReturnData, error) { + if len(magicBytes) != MagicBytesLen { + return nil, fmt.Errorf("cannot create op_return data: invalid magic bytes length: %d, expected: %d", len(magicBytes), MagicBytesLen) + } + + stakerKey, err := XOnlyPublicKeyFromBytes(stakerPublicKey) + + if err != nil { + return nil, fmt.Errorf("cannot create op_return data: %w", err) + } + + fpKey, err := XOnlyPublicKeyFromBytes(finalityProviderPublicKey) + + if err != nil { + return nil, fmt.Errorf("cannot create op_return data: %w", err) + } + + stakingTimeValue, err := uint16FromBytes(stakingTime) + + if err != nil { + return nil, fmt.Errorf("cannot create op_return data: %w", err) + } + + return &V0OpReturnData{ + MagicBytes: magicBytes, + Version: 0, + StakerPublicKey: stakerKey, + FinalityProviderPublicKey: fpKey, + StakingTime: stakingTimeValue, + }, nil +} + +func NewV0OpReturnDataFromParsed( + magicBytes []byte, + stakerPublicKey *btcec.PublicKey, + finalityProviderPublicKey *btcec.PublicKey, + stakingTime uint16, +) (*V0OpReturnData, error) { + if len(magicBytes) != MagicBytesLen { + return nil, fmt.Errorf("cannot create op_return data: invalid magic bytes length: %d, expected: %d", len(magicBytes), MagicBytesLen) + } + + if stakerPublicKey == nil { + return nil, fmt.Errorf("cannot create op_return data: nil staker public key") + } + + if finalityProviderPublicKey == nil { + return nil, fmt.Errorf("cannot create op_return data: nil finality provider public key") + } + + return &V0OpReturnData{ + MagicBytes: magicBytes, + Version: 0, + StakerPublicKey: &XonlyPubKey{stakerPublicKey}, + FinalityProviderPublicKey: &XonlyPubKey{finalityProviderPublicKey}, + StakingTime: stakingTime, + }, nil +} + +func NewV0OpReturnDataFromBytes(b []byte) (*V0OpReturnData, error) { + if len(b) != V0OpReturnDataSize { + return nil, fmt.Errorf("invalid op return data length: %d, expected: %d", len(b), V0OpReturnDataSize) + } + magicBytes := b[:MagicBytesLen] + + version := b[MagicBytesLen] + + if version != 0 { + return nil, fmt.Errorf("invalid op return version: %d, expected: %d", version, 0) + } + + stakerPublicKey := b[MagicBytesLen+1 : MagicBytesLen+1+schnorr.PubKeyBytesLen] + finalityProviderPublicKey := b[MagicBytesLen+1+schnorr.PubKeyBytesLen : MagicBytesLen+1+schnorr.PubKeyBytesLen*2] + stakingTime := b[MagicBytesLen+1+schnorr.PubKeyBytesLen*2:] + return NewV0OpReturnData(magicBytes, stakerPublicKey, finalityProviderPublicKey, stakingTime) +} + +func NewV0OpReturnDataFromTxOutput(out *wire.TxOut) (*V0OpReturnData, error) { + if out == nil { + return nil, fmt.Errorf("nil tx output") + } + + // We are adding `+2` as each op return has additional 2 for: + // 1. OP_RETURN opcode - which signalizes that data is provably unspendable + // 2. OP_DATA_71 opcode - which pushes 71 bytes of data to the stack + if len(out.PkScript) != V0OpReturnDataSize+2 { + return nil, fmt.Errorf("invalid op return data length: %d, expected: %d", len(out.PkScript), V0OpReturnDataSize+2) + } + + if !txscript.IsNullData(out.PkScript) { + return nil, fmt.Errorf("invalid op return script") + } + + return NewV0OpReturnDataFromBytes(out.PkScript[2:]) +} + +func (d *V0OpReturnData) Marshall() []byte { + var data []byte + data = append(data, d.MagicBytes...) + data = append(data, d.Version) + data = append(data, d.StakerPublicKey.Marshall()...) + data = append(data, d.FinalityProviderPublicKey.Marshall()...) + data = append(data, uint16ToBytes(d.StakingTime)...) + return data +} + +func (d *V0OpReturnData) ToTxOutput(v int64) (*wire.TxOut, error) { + dataScript, err := txscript.NullDataScript(d.Marshall()) + if err != nil { + return nil, err + } + return wire.NewTxOut(v, dataScript), nil +} + +// BuildV0EnhancedStakingOutputs crates outputs which every staking transaction must have +func BuildV0EnhancedStakingOutputs( + magicBytes []byte, + stakerKey *btcec.PublicKey, + fpKey *btcec.PublicKey, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + stakingTime uint16, + stakingAmount btcutil.Amount, + net *chaincfg.Params, +) (*EnhancedStakingInfo, error) { + info, err := BuildStakingInfo( + stakerKey, + []*btcec.PublicKey{fpKey}, + covenantKeys, + covenantQuorum, + stakingTime, + stakingAmount, + net, + ) + if err != nil { + return nil, err + } + + opReturnData, err := NewV0OpReturnDataFromParsed(magicBytes, stakerKey, fpKey, stakingTime) + + if err != nil { + return nil, err + } + + dataOutput, err := opReturnData.ToTxOutput(0) + + if err != nil { + return nil, err + } + + return &EnhancedStakingInfo{ + StakingOutput: info.StakingOutput, + scriptHolder: info.scriptHolder, + timeLockPathLeafHash: info.timeLockPathLeafHash, + unbondingPathLeafHash: info.unbondingPathLeafHash, + slashingPathLeafHash: info.slashingPathLeafHash, + OpReturnOutput: dataOutput, + }, nil +} + +// BuildV0EnhancedStakingOutputs crates outputs which every staking transaction must have and +// returns the not-funded transaction with these outputs +func BuildV0EnhancedStakingOutputsAndTx( + magicBytes []byte, + stakerKey *btcec.PublicKey, + fpKey *btcec.PublicKey, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + stakingTime uint16, + stakingAmount btcutil.Amount, + net *chaincfg.Params, +) (*EnhancedStakingInfo, *wire.MsgTx, error) { + info, err := BuildV0EnhancedStakingOutputs( + magicBytes, + stakerKey, + fpKey, + covenantKeys, + covenantQuorum, + stakingTime, + stakingAmount, + net, + ) + if err != nil { + return nil, nil, err + } + + tx := wire.NewMsgTx(2) + tx.AddTxOut(info.StakingOutput) + tx.AddTxOut(info.OpReturnOutput) + return info, tx, nil +} + +func (i *EnhancedStakingInfo) TimeLockPathSpendInfo() (*SpendInfo, error) { + return i.scriptHolder.scriptSpendInfoByName(i.timeLockPathLeafHash) +} + +func (i *EnhancedStakingInfo) UnbondingPathSpendInfo() (*SpendInfo, error) { + return i.scriptHolder.scriptSpendInfoByName(i.unbondingPathLeafHash) +} + +func (i *EnhancedStakingInfo) SlashingPathSpendInfo() (*SpendInfo, error) { + return i.scriptHolder.scriptSpendInfoByName(i.slashingPathLeafHash) +} + +type ParsedV0StakingTx struct { + StakingOutput *wire.TxOut + StakingOutputIdx int + OpReturnOutput *wire.TxOut + OpReturnOutputIdx int + OpReturnData *V0OpReturnData +} + +// ParseV0StakingTx takes btc transaction checks whether it is a staking transaction and if so, it parses it. +func ParseV0StakingTx( + tx *wire.MsgTx, + expectedMagicBytes []byte, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + net *chaincfg.Params, +) (*ParsedV0StakingTx, error) { + // 1. Basic arguments checks + if tx == nil { + return nil, fmt.Errorf("nil tx") + } + + if len(expectedMagicBytes) != MagicBytesLen { + return nil, fmt.Errorf("invalid magic bytes length: %d, expected: %d", len(expectedMagicBytes), MagicBytesLen) + } + + if len(covenantKeys) == 0 { + return nil, fmt.Errorf("no covenant keys specified") + } + + if covenantQuorum > uint32(len(covenantKeys)) { + return nil, fmt.Errorf("covenant quorum is greater than the number of covenant keys") + } + + // 2 Identify whether the transaction has expected shape + if len(tx.TxOut) < 2 { + return nil, fmt.Errorf("staking tx must have at least 2 outputs") + } + + var opReturnData *V0OpReturnData + var opReturnOutputIdx int + for i, o := range tx.TxOut { + output := o + d, err := NewV0OpReturnDataFromTxOutput(output) + + if err != nil { + // this is not an op return output recognized by Babylon, move forward + continue + } + // this case should not happen as standard bitcoin node propagation rules + // disallow multiple op return outputs in a single transaction. However, miner could + // include multiple op return outputs in a single transaction. In such case, we should + // return an error. + if opReturnData != nil { + return nil, fmt.Errorf("multiple op return outputs found") + } + + opReturnData = d + opReturnOutputIdx = i + } + + if opReturnData == nil { + return nil, fmt.Errorf("tansaction does not have expected op return output") + } + + // at this point we know that transaction has op return output which seems to matches + // the expected shape. Check the magic bytes and version. + if !bytes.Equal(opReturnData.MagicBytes, expectedMagicBytes) { + return nil, fmt.Errorf("unexpcted magic bytes: %s, expected: %s", + hex.EncodeToString(opReturnData.MagicBytes), + hex.EncodeToString(expectedMagicBytes), + ) + } + + if opReturnData.Version != 0 { + return nil, fmt.Errorf("unexpcted version: %d, expected: %d", opReturnData.Version, 0) + } + + // Op return seems to be valid V0 op return output. Now, we need to check whether + // the staking output exists and is valid. + stakingInfo, err := BuildStakingInfo( + opReturnData.StakerPublicKey.PubKey, + []*btcec.PublicKey{opReturnData.FinalityProviderPublicKey.PubKey}, + covenantKeys, + covenantQuorum, + opReturnData.StakingTime, + // we can pass 0 here, as staking amount is not used when creating taproot address + 0, + net, + ) + + if err != nil { + return nil, fmt.Errorf("cannot build staking info: %w", err) + } + + var stakingOutput *wire.TxOut + var stakingOutputIdx int + // go through all transaction outputs and try to find expected staking output + for i, o := range tx.TxOut { + output := o + + if !bytes.Equal(output.PkScript, stakingInfo.StakingOutput.PkScript) { + // this is not the staking output we are looking for + continue + } + + if stakingOutput != nil { + // we only allow for on staking output per transaction + return nil, fmt.Errorf("multiple staking outputs found in staking transaction") + } + + stakingOutput = output + stakingOutputIdx = i + } + + if stakingOutput == nil { + return nil, fmt.Errorf("staking output not found in potential staking transaction") + } + + return &ParsedV0StakingTx{ + StakingOutput: stakingOutput, + StakingOutputIdx: stakingOutputIdx, + OpReturnOutput: tx.TxOut[opReturnOutputIdx], + OpReturnOutputIdx: opReturnOutputIdx, + OpReturnData: opReturnData, + }, nil +} diff --git a/btcstaking/enhanced_staking_test.go b/btcstaking/enhanced_staking_test.go new file mode 100644 index 000000000..5e2583334 --- /dev/null +++ b/btcstaking/enhanced_staking_test.go @@ -0,0 +1,98 @@ +package btcstaking_test + +import ( + "math" + "math/rand" + "testing" + + "github.com/babylonchain/babylon/btcstaking" + + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/wire" + "github.com/stretchr/testify/require" +) + +func generateTxFromOutputs(r *rand.Rand, info *btcstaking.EnhancedStakingInfo) (*wire.MsgTx, int, int) { + numOutputs := 20 + + stakingOutputIdx := r.Intn(numOutputs - 1) + opReturnOutputIdx := r.Intn(numOutputs - 1) + + if stakingOutputIdx == opReturnOutputIdx { + opReturnOutputIdx = stakingOutputIdx + 1 + } + tx := wire.NewMsgTx(2) + for i := 0; i < numOutputs; i++ { + if i == stakingOutputIdx { + tx.AddTxOut(info.StakingOutput) + } else if i == opReturnOutputIdx { + tx.AddTxOut(info.OpReturnOutput) + } else { + tx.AddTxOut(wire.NewTxOut(int64(r.Int63n(1000000000)+10000), datagen.GenRandomByteArray(r, 32))) + } + } + + return tx, stakingOutputIdx, opReturnOutputIdx +} + +// Property: Every staking tx generated by our generator should be properly parsed by +// our parser +func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 100) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + // 3 - 10 covenants + numCovenantKeys := uint32(r.Int31n(7) + 3) + quroum := uint32(numCovenantKeys - 2) + stakingAmount := btcutil.Amount(r.Int63n(1000000000) + 10000) + stakingTime := uint16(r.Int31n(math.MaxUint16-1) + 1) + magicBytes := datagen.GenRandomByteArray(r, btcstaking.MagicBytesLen) + net := &chaincfg.MainNetParams + + sc := GenerateTestScenario(r, t, 1, numCovenantKeys, quroum, stakingAmount, stakingTime) + + outputs, err := btcstaking.BuildV0EnhancedStakingOutputs( + magicBytes, + sc.StakerKey.PubKey(), + sc.FinalityProviderKeys[0].PubKey(), + sc.CovenantPublicKeys(), + quroum, + stakingTime, + stakingAmount, + net, + ) + + require.NoError(t, err) + require.NotNil(t, outputs) + + tx, stakingOutputIdx, opReturnOutputIdx := generateTxFromOutputs(r, outputs) + + parsedTx, err := btcstaking.ParseV0StakingTx( + tx, + magicBytes, + sc.CovenantPublicKeys(), + quroum, + net, + ) + require.NoError(t, err) + require.NotNil(t, parsedTx) + + require.Equal(t, outputs.StakingOutput.PkScript, parsedTx.StakingOutput.PkScript) + require.Equal(t, outputs.StakingOutput.Value, parsedTx.StakingOutput.Value) + require.Equal(t, stakingOutputIdx, parsedTx.StakingOutputIdx) + + require.Equal(t, outputs.OpReturnOutput.PkScript, parsedTx.OpReturnOutput.PkScript) + require.Equal(t, outputs.OpReturnOutput.Value, parsedTx.OpReturnOutput.Value) + require.Equal(t, opReturnOutputIdx, parsedTx.OpReturnOutputIdx) + + require.Equal(t, magicBytes, parsedTx.OpReturnData.MagicBytes) + require.Equal(t, uint8(0), parsedTx.OpReturnData.Version) + require.Equal(t, stakingTime, parsedTx.OpReturnData.StakingTime) + + require.Equal(t, schnorr.SerializePubKey(sc.StakerKey.PubKey()), parsedTx.OpReturnData.StakerPublicKey.Marshall()) + require.Equal(t, schnorr.SerializePubKey(sc.FinalityProviderKeys[0].PubKey()), parsedTx.OpReturnData.FinalityProviderPublicKey.Marshall()) + }) +} From dc82fe70e6f259adddd656f74a14a5b29a75295e Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Thu, 14 Mar 2024 12:19:18 +0100 Subject: [PATCH 045/119] Refactor and add function for quick checks --- btcstaking/enhanced_staking.go | 175 +++++++++++++++++++++------- btcstaking/enhanced_staking_test.go | 7 ++ 2 files changed, 138 insertions(+), 44 deletions(-) diff --git a/btcstaking/enhanced_staking.go b/btcstaking/enhanced_staking.go index 61f88ab31..f26b9c7cb 100644 --- a/btcstaking/enhanced_staking.go +++ b/btcstaking/enhanced_staking.go @@ -32,7 +32,7 @@ type EnhancedStakingInfo struct { } // XonlyPubKey is a wrapper around btcec.PublicKey that represents BTC public -// key deserialized from a 32-byte array i.e with implicit assumption thah Y coordinate +// key deserialized from a 32-byte array i.e with implicit assumption that Y coordinate // is even. type XonlyPubKey struct { PubKey *btcec.PublicKey @@ -158,7 +158,7 @@ func NewV0OpReturnDataFromBytes(b []byte) (*V0OpReturnData, error) { return NewV0OpReturnData(magicBytes, stakerPublicKey, finalityProviderPublicKey, stakingTime) } -func NewV0OpReturnDataFromTxOutput(out *wire.TxOut) (*V0OpReturnData, error) { +func getV0OpReturnBytes(out *wire.TxOut) ([]byte, error) { if out == nil { return nil, fmt.Errorf("nil tx output") } @@ -174,7 +174,17 @@ func NewV0OpReturnDataFromTxOutput(out *wire.TxOut) (*V0OpReturnData, error) { return nil, fmt.Errorf("invalid op return script") } - return NewV0OpReturnDataFromBytes(out.PkScript[2:]) + return out.PkScript[2:], nil +} + +func NewV0OpReturnDataFromTxOutput(out *wire.TxOut) (*V0OpReturnData, error) { + data, err := getV0OpReturnBytes(out) + + if err != nil { + return nil, fmt.Errorf("cannot parse op return data: %w", err) + } + + return NewV0OpReturnDataFromBytes(data) } func (d *V0OpReturnData) Marshall() []byte { @@ -293,7 +303,70 @@ type ParsedV0StakingTx struct { OpReturnData *V0OpReturnData } -// ParseV0StakingTx takes btc transaction checks whether it is a staking transaction and if so, it parses it. +func tryToGetOpReturnDataFromOutputs(outputs []*wire.TxOut) (*V0OpReturnData, int, error) { + // lack of outputs is not an error + if len(outputs) == 0 { + return nil, -1, nil + } + + var opReturnData *V0OpReturnData + var opReturnOutputIdx int + + for i, o := range outputs { + output := o + d, err := NewV0OpReturnDataFromTxOutput(output) + + if err != nil { + // this is not an op return output recognized by Babylon, move forward + continue + } + // this case should not happen as standard bitcoin node propagation rules + // disallow multiple op return outputs in a single transaction. However, miner could + // include multiple op return outputs in a single transaction. In such case, we should + // return an error. + if opReturnData != nil { + return nil, -1, fmt.Errorf("multiple op return outputs found") + } + + opReturnData = d + opReturnOutputIdx = i + } + + return opReturnData, opReturnOutputIdx, nil +} + +func tryToGetStakingOutput(outputs []*wire.TxOut, stakingOutputPkScript []byte) (*wire.TxOut, int, error) { + // lack of outputs is not an error + if len(outputs) == 0 { + return nil, -1, nil + } + + var stakingOutput *wire.TxOut + var stakingOutputIdx int + + for i, o := range outputs { + output := o + + if !bytes.Equal(output.PkScript, stakingOutputPkScript) { + // this is not the staking output we are looking for + continue + } + + if stakingOutput != nil { + // we only allow for on staking output per transaction + return nil, -1, fmt.Errorf("multiple staking outputs found") + } + + stakingOutput = output + stakingOutputIdx = i + } + + return stakingOutput, stakingOutputIdx, nil +} + +// ParseV0StakingTx takes btc transaction checks whether it is a staking transaction and if so parses it +// for easy data retrieval. +// It does all necessary checks to ensure that the transaction is valid staking transaction. func ParseV0StakingTx( tx *wire.MsgTx, expectedMagicBytes []byte, @@ -323,36 +396,20 @@ func ParseV0StakingTx( return nil, fmt.Errorf("staking tx must have at least 2 outputs") } - var opReturnData *V0OpReturnData - var opReturnOutputIdx int - for i, o := range tx.TxOut { - output := o - d, err := NewV0OpReturnDataFromTxOutput(output) - - if err != nil { - // this is not an op return output recognized by Babylon, move forward - continue - } - // this case should not happen as standard bitcoin node propagation rules - // disallow multiple op return outputs in a single transaction. However, miner could - // include multiple op return outputs in a single transaction. In such case, we should - // return an error. - if opReturnData != nil { - return nil, fmt.Errorf("multiple op return outputs found") - } + opReturnData, opReturnOutputIdx, err := tryToGetOpReturnDataFromOutputs(tx.TxOut) - opReturnData = d - opReturnOutputIdx = i + if err != nil { + return nil, fmt.Errorf("cannot parse staking transaction: %w", err) } if opReturnData == nil { - return nil, fmt.Errorf("tansaction does not have expected op return output") + return nil, fmt.Errorf("transaction does not have expected op return output") } - // at this point we know that transaction has op return output which seems to matches + // at this point we know that transaction has op return output which seems to match // the expected shape. Check the magic bytes and version. if !bytes.Equal(opReturnData.MagicBytes, expectedMagicBytes) { - return nil, fmt.Errorf("unexpcted magic bytes: %s, expected: %s", + return nil, fmt.Errorf("unexpected magic bytes: %s, expected: %s", hex.EncodeToString(opReturnData.MagicBytes), hex.EncodeToString(expectedMagicBytes), ) @@ -362,7 +419,7 @@ func ParseV0StakingTx( return nil, fmt.Errorf("unexpcted version: %d, expected: %d", opReturnData.Version, 0) } - // Op return seems to be valid V0 op return output. Now, we need to check whether + // 3: Op return seems to be valid V0 op return output. Now, we need to check whether // the staking output exists and is valid. stakingInfo, err := BuildStakingInfo( opReturnData.StakerPublicKey.PubKey, @@ -379,24 +436,10 @@ func ParseV0StakingTx( return nil, fmt.Errorf("cannot build staking info: %w", err) } - var stakingOutput *wire.TxOut - var stakingOutputIdx int - // go through all transaction outputs and try to find expected staking output - for i, o := range tx.TxOut { - output := o - - if !bytes.Equal(output.PkScript, stakingInfo.StakingOutput.PkScript) { - // this is not the staking output we are looking for - continue - } - - if stakingOutput != nil { - // we only allow for on staking output per transaction - return nil, fmt.Errorf("multiple staking outputs found in staking transaction") - } + stakingOutput, stakingOutputIdx, err := tryToGetStakingOutput(tx.TxOut, stakingInfo.StakingOutput.PkScript) - stakingOutput = output - stakingOutputIdx = i + if err != nil { + return nil, fmt.Errorf("cannot parse staking transaction: %w", err) } if stakingOutput == nil { @@ -411,3 +454,47 @@ func ParseV0StakingTx( OpReturnData: opReturnData, }, nil } + +// IsV0StakingTx checks whether transaction maybe a valid staking transaction. It +// checks: +// 1. Whether the transaction has at least 2 outputs +// 2. have an op return output +// 3. op return output has expected magic bytes +// This function is much faster than ParseV0StakingTx, as it does not perform +// all necessary checks. +func IsPossibleV0StakingTx(tx *wire.MsgTx, expectedMagicBytes []byte) bool { + if len(expectedMagicBytes) != MagicBytesLen { + return false + } + + if len(tx.TxOut) < 2 { + return false + } + + var possibleStakingTx = false + for _, o := range tx.TxOut { + output := o + + data, err := getV0OpReturnBytes(output) + + if err != nil { + // this is not an op return output recognized by Babylon, move forward + continue + } + + if !bytes.Equal(data[:MagicBytesLen], expectedMagicBytes) { + // this is not the op return output we are looking for as magic bytes do not match + continue + } + + if possibleStakingTx { + // this is second output that matches the magic bytes, we do not allow for multiple op return outputs + // so this is not a valid staking transaction + continue + } + + possibleStakingTx = true + } + + return possibleStakingTx +} diff --git a/btcstaking/enhanced_staking_test.go b/btcstaking/enhanced_staking_test.go index 5e2583334..6c26e6f20 100644 --- a/btcstaking/enhanced_staking_test.go +++ b/btcstaking/enhanced_staking_test.go @@ -41,6 +41,7 @@ func generateTxFromOutputs(r *rand.Rand, info *btcstaking.EnhancedStakingInfo) ( // Property: Every staking tx generated by our generator should be properly parsed by // our parser func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { + // lot of seeds as test is pretty fast and we want to test a lot of different values datagen.AddRandomSeedsToFuzzer(f, 100) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) @@ -70,6 +71,10 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { tx, stakingOutputIdx, opReturnOutputIdx := generateTxFromOutputs(r, outputs) + // ParseV0StakingTx and IsPossibleV0StakingTx should be consistent and recognize + // the same tx as a valid staking tx + require.True(t, btcstaking.IsPossibleV0StakingTx(tx, magicBytes)) + parsedTx, err := btcstaking.ParseV0StakingTx( tx, magicBytes, @@ -96,3 +101,5 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { require.Equal(t, schnorr.SerializePubKey(sc.FinalityProviderKeys[0].PubKey()), parsedTx.OpReturnData.FinalityProviderPublicKey.Marshall()) }) } + +// TODO Negative test cases From 5ca83e82523290fd1cae10e7cce557414fbf3f9b Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 14 Mar 2024 08:31:22 -0300 Subject: [PATCH 046/119] fix: `x/finality` import/export gen state (#557) * chore: removed unused func * fix: add missing structures for genstate * chore: add basic structures needed for storing the finality state * feat: add new properties to init genesis * feat: add evidences and blocks to export gen state * chore: start to load vote store * fix: proto finality_sig sequence * chore: removed named return * chore: add init genesis method to keeper * chore: add export genesis method to keeper and set blocks and evideces to private funcs * chore: add test to verify load of all evidences * chore: add test to verify load of all evidences * feat: add get votes and test to verify load of all vote signatures * feat: add get public randomness and finalized test of export genesis * chore: moved export genesis funcs to genesis.go * chore: renamed genstate property commited_randoms to public_randomness --- proto/babylon/finality/v1/genesis.proto | 32 + x/finality/genesis.go | 18 +- x/finality/keeper/evidence.go | 24 +- x/finality/keeper/genesis.go | 196 ++++++ x/finality/keeper/genesis_test.go | 95 +++ x/finality/keeper/grpc_query.go | 3 +- x/finality/keeper/public_randomness.go | 26 +- x/finality/keeper/votes.go | 26 +- x/finality/types/genesis.go | 1 + x/finality/types/genesis.pb.go | 826 +++++++++++++++++++++++- x/finality/types/keys.go | 4 - 11 files changed, 1200 insertions(+), 51 deletions(-) create mode 100644 x/finality/keeper/genesis.go create mode 100644 x/finality/keeper/genesis_test.go diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index f33e6ed15..7c1b4c62f 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -3,10 +3,42 @@ package babylon.finality.v1; import "gogoproto/gogo.proto"; import "babylon/finality/v1/params.proto"; +import "babylon/finality/v1/finality.proto"; option go_package = "github.com/babylonchain/babylon/x/finality/types"; // GenesisState defines the finality module's genesis state. message GenesisState { + // params the current params of the state. Params params = 1 [(gogoproto.nullable) = false]; + // indexed_blocks all the btc blocks and if their status are finalized. + repeated IndexedBlock indexed_blocks = 2; + // evidences all the evidences ever registered. + repeated Evidence evidences = 3; + // votes_sigs contains all the votes of finality providers ever registered. + repeated VoteSig vote_sigs = 4; + // public_randomness contains all the public randomness ever commited from the finality providers. + repeated PublicRandomness public_randomness = 5; } + +// VoteSig the vote of an finality provider +// with the block of the vote, the finality provider btc public key and the vote signature. +message VoteSig { + // block_height is the height of the voted block. + uint64 block_height = 1; + // fp_btc_pk is the BTC PK of the finality provider that casts this vote + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // finality_sig is the finality signature to this block + // where finality signature is an EOTS signature, i.e. + bytes finality_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; +} + +// PublicRandomness the block height and public randomness that the finality provider has submitted. +message PublicRandomness { + // block_height is the height of block which the finality provider submited public randomness. + uint64 block_height = 1; + // fp_btc_pk is the BTC PK of the finality provider that casts this vote. + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pub_rand is the public randomness the finality provider has committed to. + bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; +} \ No newline at end of file diff --git a/x/finality/genesis.go b/x/finality/genesis.go index 6f771fb4b..bf1974280 100644 --- a/x/finality/genesis.go +++ b/x/finality/genesis.go @@ -2,21 +2,27 @@ package finality import ( "context" + "github.com/babylonchain/babylon/x/finality/keeper" "github.com/babylonchain/babylon/x/finality/types" ) // InitGenesis initializes the module's state from a provided genesis state. -func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { - if err := k.SetParams(ctx, genState.Params); err != nil { +func InitGenesis(ctx context.Context, k keeper.Keeper, gs types.GenesisState) { + if err := gs.Validate(); err != nil { + panic(err) + } + + if err := k.InitGenesis(ctx, gs); err != nil { panic(err) } } // ExportGenesis returns the module's exported genesis func ExportGenesis(ctx context.Context, k keeper.Keeper) *types.GenesisState { - genesis := types.DefaultGenesis() - genesis.Params = k.GetParams(ctx) - - return genesis + gs, err := k.ExportGenesis(ctx) + if err != nil { + panic(err) + } + return gs } diff --git a/x/finality/keeper/evidence.go b/x/finality/keeper/evidence.go index dafa4d8fb..393058d4b 100644 --- a/x/finality/keeper/evidence.go +++ b/x/finality/keeper/evidence.go @@ -11,12 +11,12 @@ import ( ) func (k Keeper) SetEvidence(ctx context.Context, evidence *types.Evidence) { - store := k.evidenceStore(ctx, evidence.FpBtcPk) + store := k.evidenceFpStore(ctx, evidence.FpBtcPk) store.Set(sdk.Uint64ToBigEndian(evidence.BlockHeight), k.cdc.MustMarshal(evidence)) } func (k Keeper) HasEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool { - store := k.evidenceStore(ctx, fpBtcPK) + store := k.evidenceFpStore(ctx, fpBtcPK) return store.Has(sdk.Uint64ToBigEndian(height)) } @@ -24,7 +24,7 @@ func (k Keeper) GetEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, heig if uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) < height { return nil, types.ErrHeightTooHigh } - store := k.evidenceStore(ctx, fpBtcPK) + store := k.evidenceFpStore(ctx, fpBtcPK) evidenceBytes := store.Get(sdk.Uint64ToBigEndian(height)) if len(evidenceBytes) == 0 { return nil, types.ErrEvidenceNotFound @@ -40,7 +40,7 @@ func (k Keeper) GetEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, heig // an evidence, which happens when the finality provider signed a fork block // but hasn't signed the canonical block yet. func (k Keeper) GetFirstSlashableEvidence(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) *types.Evidence { - store := k.evidenceStore(ctx, fpBtcPK) + store := k.evidenceFpStore(ctx, fpBtcPK) iter := store.Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -54,12 +54,20 @@ func (k Keeper) GetFirstSlashableEvidence(ctx context.Context, fpBtcPK *bbn.BIP3 return nil } -// evidenceStore returns the KVStore of the evidences +// evidenceFpStore returns the KVStore of the evidences // prefix: EvidenceKey // key: (finality provider PK || height) // value: Evidence -func (k Keeper) evidenceStore(ctx context.Context, fpBTCPK *bbn.BIP340PubKey) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - eStore := prefix.NewStore(storeAdapter, types.EvidenceKey) +func (k Keeper) evidenceFpStore(ctx context.Context, fpBTCPK *bbn.BIP340PubKey) prefix.Store { + eStore := k.evidenceStore(ctx) return prefix.NewStore(eStore, fpBTCPK.MustMarshal()) } + +// evidenceStore returns the KVStore of the evidences +// prefix: EvidenceKey +// key: (prefix) +// value: Evidence +func (k Keeper) evidenceStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.EvidenceKey) +} diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go new file mode 100644 index 000000000..286a671e2 --- /dev/null +++ b/x/finality/keeper/genesis.go @@ -0,0 +1,196 @@ +package keeper + +import ( + "context" + "fmt" + + bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/finality/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis initializes the keeper state from a provided initial genesis state. +func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { + for _, idxBlock := range gs.IndexedBlocks { + k.SetBlock(ctx, idxBlock) + } + + for _, evidence := range gs.Evidences { + k.SetEvidence(ctx, evidence) + } + + for _, voteSig := range gs.VoteSigs { + k.SetSig(ctx, voteSig.BlockHeight, voteSig.FpBtcPk, voteSig.FinalitySig) + } + + for _, pubRand := range gs.PublicRandomness { + k.SetPubRandList(ctx, pubRand.FpBtcPk, pubRand.BlockHeight, []bbn.SchnorrPubRand{*pubRand.PubRand}) + } + + return k.SetParams(ctx, gs.Params) +} + +// ExportGenesis returns the keeper state into a exported genesis state. +func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) { + blocks, err := k.blocks(ctx) + if err != nil { + return nil, err + } + + evidences, err := k.evidences(ctx) + if err != nil { + return nil, err + } + + voteSigs, err := k.voteSigs(ctx) + if err != nil { + return nil, err + } + + pubRandomness, err := k.publicRandomness(ctx) + if err != nil { + return nil, err + } + + return &types.GenesisState{ + Params: k.GetParams(ctx), + IndexedBlocks: blocks, + Evidences: evidences, + VoteSigs: voteSigs, + PublicRandomness: pubRandomness, + }, nil +} + +// blocks loads all blocks stored. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) blocks(ctx context.Context) ([]*types.IndexedBlock, error) { + blocks := make([]*types.IndexedBlock, 0) + + iter := k.blockStore(ctx).Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var blk types.IndexedBlock + if err := k.cdc.Unmarshal(iter.Value(), &blk); err != nil { + return nil, err + } + blocks = append(blocks, &blk) + } + + return blocks, nil +} + +// evidences loads all evidences stored. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) evidences(ctx context.Context) (evidences []*types.Evidence, err error) { + evidences = make([]*types.Evidence, 0) + + iter := k.evidenceStore(ctx).Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var evd types.Evidence + if err := k.cdc.Unmarshal(iter.Value(), &evd); err != nil { + return nil, err + } + evidences = append(evidences, &evd) + } + + return evidences, nil +} + +// voteSigs iterates over all votes on the store, parses the height and the finality provider +// public key from the iterator key and the finality signature from the iterator value. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) voteSigs(ctx context.Context) ([]*types.VoteSig, error) { + store := k.voteStore(ctx) + iter := store.Iterator(nil, nil) + defer iter.Close() + + voteSigs := make([]*types.VoteSig, 0) + for ; iter.Valid(); iter.Next() { + // key contains the height and the fp + blkHeight, fpBTCPK, err := parseBlkHeightAndPubKeyFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + finalitySig, err := bbn.NewSchnorrEOTSSig(iter.Value()) + if err != nil { + return nil, err + } + + voteSigs = append(voteSigs, &types.VoteSig{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + FinalitySig: finalitySig, + }) + } + + return voteSigs, nil +} + +// publicRandomness iterates over all commited randoms on the store, parses the finality provider public key +// and the height from the iterator key and the commited random from the iterator value. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) publicRandomness(ctx context.Context) ([]*types.PublicRandomness, error) { + store := k.pubRandStore(ctx) + iter := store.Iterator(nil, nil) + defer iter.Close() + + commtRandoms := make([]*types.PublicRandomness, 0) + for ; iter.Valid(); iter.Next() { + // key contains the fp and the block height + fpBTCPK, blkHeight, err := parsePubKeyAndBlkHeightFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + pubRand, err := bbn.NewSchnorrPubRand(iter.Value()) + if err != nil { + return nil, err + } + + commtRandoms = append(commtRandoms, &types.PublicRandomness{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + PubRand: pubRand, + }) + } + + return commtRandoms, nil +} + +// parseBlkHeightAndPubKeyFromStoreKey expects to receive a key with +// BigEndianUint64(blkHeight) || BIP340PubKey(fpBTCPK) +func parseBlkHeightAndPubKeyFromStoreKey(key []byte) (blkHeight uint64, fpBTCPK *bbn.BIP340PubKey, err error) { + sizeBigEndian := 8 + if len(key) < sizeBigEndian+1 { + return 0, nil, fmt.Errorf("key not long enough to parse block height and BIP340PubKey: %s", key) + } + + fpBTCPK, err = bbn.NewBIP340PubKey(key[sizeBigEndian:]) + if err != nil { + return 0, nil, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + blkHeight = sdk.BigEndianToUint64(key[:sizeBigEndian]) + return blkHeight, fpBTCPK, nil +} + +// parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with +// BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) +func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { + sizeBigEndian := 8 + keyLen := len(key) + if keyLen < sizeBigEndian+1 { + return nil, 0, fmt.Errorf("key not long enough to parse BIP340PubKey and block height: %s", key) + } + + startKeyHeight := keyLen - sizeBigEndian + fpBTCPK, err = bbn.NewBIP340PubKey(key[:startKeyHeight]) + if err != nil { + return nil, 0, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + blkHeight = sdk.BigEndianToUint64(key[startKeyHeight:]) + return fpBTCPK, blkHeight, nil +} diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go new file mode 100644 index 000000000..d8768fec2 --- /dev/null +++ b/x/finality/keeper/genesis_test.go @@ -0,0 +1,95 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + "github.com/babylonchain/babylon/testutil/datagen" + keepertest "github.com/babylonchain/babylon/testutil/keeper" + bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/finality/types" + "github.com/stretchr/testify/require" +) + +func TestExportGenesis(t *testing.T) { + k, ctx := keepertest.FinalityKeeper(t, nil, nil) + + r := rand.New(rand.NewSource(10)) + btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) + + srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + require.NoError(t, err) + + sr := srList[startHeight+blkHeight] + blockHash := datagen.GenRandomByteArray(r, 32) + signer := datagen.GenRandomAccount().Address + msgAddFinalitySig, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blkHeight, blockHash) + require.NoError(t, err) + + allVotes := make([]*types.VoteSig, numPubRand) + allBlocks := make([]*types.IndexedBlock, numPubRand) + allEvidences := make([]*types.Evidence, numPubRand) + allPublicRandomness := make([]*types.PublicRandomness, numPubRand) + for i := 0; i < int(numPubRand); i++ { + // Votes + vt := &types.VoteSig{ + FpBtcPk: fpBTCPK, + BlockHeight: blkHeight, + FinalitySig: msgAddFinalitySig.FinalitySig, + } + k.SetSig(ctx, vt.BlockHeight, vt.FpBtcPk, vt.FinalitySig) + allVotes[i] = vt + + // Blocks + blk := &types.IndexedBlock{ + Height: blkHeight, + AppHash: blockHash, + Finalized: i%2 == 0, + } + k.SetBlock(ctx, blk) + allBlocks[i] = blk + + // Evidences + evidence := &types.Evidence{ + FpBtcPk: fpBTCPK, + BlockHeight: blkHeight, + PubRand: &msgCommitPubRandList.PubRandList[i], + ForkAppHash: msgAddFinalitySig.BlockAppHash, + ForkFinalitySig: msgAddFinalitySig.FinalitySig, + CanonicalAppHash: blockHash, + CanonicalFinalitySig: msgAddFinalitySig.FinalitySig, + } + k.SetEvidence(ctx, evidence) + allEvidences[i] = evidence + + // PubRandoms + pubRand := msgCommitPubRandList.PubRandList[i] + k.SetPubRandList(ctx, fpBTCPK, blkHeight, []bbn.SchnorrPubRand{pubRand}) + randomness := &types.PublicRandomness{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + PubRand: &pubRand, + } + allPublicRandomness[i] = randomness + + // updates the block everytime to make sure something is different. + blkHeight++ + } + require.Equal(t, len(allVotes), int(numPubRand)) + require.Equal(t, len(allBlocks), int(numPubRand)) + require.Equal(t, len(allEvidences), int(numPubRand)) + require.Equal(t, len(allPublicRandomness), int(numPubRand)) + + gs, err := k.ExportGenesis(ctx) + require.NoError(t, err) + require.Equal(t, k.GetParams(ctx), gs.Params) + + require.Equal(t, allVotes, gs.VoteSigs) + require.Equal(t, allBlocks, gs.IndexedBlocks) + require.Equal(t, allEvidences, gs.Evidences) + require.Equal(t, allPublicRandomness, gs.PublicRandomness) +} diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index f6cd86d56..6f867bb08 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" @@ -30,7 +31,7 @@ func (k Keeper) ListPublicRandomness(ctx context.Context, req *types.QueryListPu } sdkCtx := sdk.UnwrapSDKContext(ctx) - store := k.pubRandStore(sdkCtx, fpBTCPK) + store := k.pubRandFpStore(sdkCtx, fpBTCPK) pubRandMap := map[uint64]*bbn.SchnorrPubRand{} pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { height := sdk.BigEndianToUint64(key) diff --git a/x/finality/keeper/public_randomness.go b/x/finality/keeper/public_randomness.go index d83abdf36..e21e5a4e5 100644 --- a/x/finality/keeper/public_randomness.go +++ b/x/finality/keeper/public_randomness.go @@ -19,7 +19,7 @@ func (k Keeper) SetPubRandList(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, s cacheCtx, writeCache := sdkCtx.CacheContext() // write to a KV store cache - store := k.pubRandStore(cacheCtx, fpBtcPK) + store := k.pubRandFpStore(cacheCtx, fpBtcPK) for i, pr := range pubRandList { height := startHeight + uint64(i) store.Set(sdk.Uint64ToBigEndian(height), pr) @@ -30,12 +30,12 @@ func (k Keeper) SetPubRandList(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, s } func (k Keeper) HasPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool { - store := k.pubRandStore(ctx, fpBtcPK) + store := k.pubRandFpStore(ctx, fpBtcPK) return store.Has(sdk.Uint64ToBigEndian(height)) } func (k Keeper) GetPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) (*bbn.SchnorrPubRand, error) { - store := k.pubRandStore(ctx, fpBtcPK) + store := k.pubRandFpStore(ctx, fpBtcPK) prBytes := store.Get(sdk.Uint64ToBigEndian(height)) if len(prBytes) == 0 { return nil, types.ErrPubRandNotFound @@ -44,7 +44,7 @@ func (k Keeper) GetPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, heigh } func (k Keeper) IsFirstPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) bool { - store := k.pubRandStore(ctx, fpBtcPK) + store := k.pubRandFpStore(ctx, fpBtcPK) iter := store.ReverseIterator(nil, nil) // if the iterator is not valid, then this finality provider does not commit any randomness @@ -53,7 +53,7 @@ func (k Keeper) IsFirstPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) b // GetLastPubRand retrieves the last public randomness committed by the given finality provider func (k Keeper) GetLastPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) (uint64, *bbn.SchnorrPubRand, error) { - store := k.pubRandStore(ctx, fpBtcPK) + store := k.pubRandFpStore(ctx, fpBtcPK) iter := store.ReverseIterator(nil, nil) if !iter.Valid() { @@ -70,12 +70,20 @@ func (k Keeper) GetLastPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) ( return height, pubRand, nil } -// pubRandStore returns the KVStore of the public randomness +// pubRandFpStore returns the KVStore of the public randomness // prefix: PubRandKey // key: (finality provider || PK block height) // value: PublicRandomness -func (k Keeper) pubRandStore(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - prefixedStore := prefix.NewStore(storeAdapter, types.PubRandKey) +func (k Keeper) pubRandFpStore(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) prefix.Store { + prefixedStore := k.pubRandStore(ctx) return prefix.NewStore(prefixedStore, fpBtcPK.MustMarshal()) } + +// pubRandStore returns the KVStore of the public randomness +// prefix: PubRandKey +// key: (prefix) +// value: PublicRandomness +func (k Keeper) pubRandStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.PubRandKey) +} diff --git a/x/finality/keeper/votes.go b/x/finality/keeper/votes.go index 44bd6352b..ffc13a8dc 100644 --- a/x/finality/keeper/votes.go +++ b/x/finality/keeper/votes.go @@ -13,12 +13,12 @@ import ( ) func (k Keeper) SetSig(ctx context.Context, height uint64, fpBtcPK *bbn.BIP340PubKey, sig *bbn.SchnorrEOTSSig) { - store := k.voteStore(ctx, height) + store := k.voteHeightStore(ctx, height) store.Set(fpBtcPK.MustMarshal(), sig.MustMarshal()) } func (k Keeper) HasSig(ctx context.Context, height uint64, fpBtcPK *bbn.BIP340PubKey) bool { - store := k.voteStore(ctx, height) + store := k.voteHeightStore(ctx, height) return store.Has(fpBtcPK.MustMarshal()) } @@ -26,7 +26,7 @@ func (k Keeper) GetSig(ctx context.Context, height uint64, fpBtcPK *bbn.BIP340Pu if uint64(sdk.UnwrapSDKContext(ctx).HeaderInfo().Height) < height { return nil, types.ErrHeightTooHigh } - store := k.voteStore(ctx, height) + store := k.voteHeightStore(ctx, height) sigBytes := store.Get(fpBtcPK.MustMarshal()) if len(sigBytes) == 0 { return nil, types.ErrVoteNotFound @@ -40,7 +40,7 @@ func (k Keeper) GetSig(ctx context.Context, height uint64, fpBtcPK *bbn.BIP340Pu // GetSigSet gets all EOTS signatures at a given height func (k Keeper) GetSigSet(ctx context.Context, height uint64) map[string]*bbn.SchnorrEOTSSig { - store := k.voteStore(ctx, height) + store := k.voteHeightStore(ctx, height) iter := store.Iterator(nil, nil) defer iter.Close() @@ -68,7 +68,7 @@ func (k Keeper) GetSigSet(ctx context.Context, height uint64) map[string]*bbn.Sc // GetVoters gets returns a map of voters' BTC PKs to the given height func (k Keeper) GetVoters(ctx context.Context, height uint64) map[string]struct{} { - store := k.voteStore(ctx, height) + store := k.voteHeightStore(ctx, height) iter := store.Iterator(nil, nil) defer iter.Close() @@ -90,12 +90,20 @@ func (k Keeper) GetVoters(ctx context.Context, height uint64) map[string]struct{ return voterBTCPKs } -// voteStore returns the KVStore of the votes +// voteHeightStore returns the KVStore of the votes // prefix: VoteKey // key: (block height || finality provider PK) // value: EOTS sig -func (k Keeper) voteStore(ctx context.Context, height uint64) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - prefixedStore := prefix.NewStore(storeAdapter, types.VoteKey) +func (k Keeper) voteHeightStore(ctx context.Context, height uint64) prefix.Store { + prefixedStore := k.voteStore(ctx) return prefix.NewStore(prefixedStore, sdk.Uint64ToBigEndian(height)) } + +// voteStore returns the KVStore of the votes +// prefix: VoteKey +// key: (prefix) +// value: EOTS sig +func (k Keeper) voteStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.VoteKey) +} diff --git a/x/finality/types/genesis.go b/x/finality/types/genesis.go index 9d633ecd7..cd58e53e4 100644 --- a/x/finality/types/genesis.go +++ b/x/finality/types/genesis.go @@ -10,5 +10,6 @@ func DefaultGenesis() *GenesisState { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { + // TODO: add validate to IndexedBlocks, Evidences, VoteSigs, PublicRandomness return gs.Params.Validate() } diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 59249a222..304c7855c 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -25,7 +26,16 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the finality module's genesis state. type GenesisState struct { + // params the current params of the state. Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // indexed_blocks all the btc blocks and if their status are finalized. + IndexedBlocks []*IndexedBlock `protobuf:"bytes,2,rep,name=indexed_blocks,json=indexedBlocks,proto3" json:"indexed_blocks,omitempty"` + // evidences all the evidences ever registered. + Evidences []*Evidence `protobuf:"bytes,3,rep,name=evidences,proto3" json:"evidences,omitempty"` + // votes_sigs contains all the votes of finality providers ever registered. + VoteSigs []*VoteSig `protobuf:"bytes,4,rep,name=vote_sigs,json=voteSigs,proto3" json:"vote_sigs,omitempty"` + // public_randomness contains all the public randomness ever commited from the finality providers. + PublicRandomness []*PublicRandomness `protobuf:"bytes,5,rep,name=public_randomness,json=publicRandomness,proto3" json:"public_randomness,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -68,27 +78,177 @@ func (m *GenesisState) GetParams() Params { return Params{} } +func (m *GenesisState) GetIndexedBlocks() []*IndexedBlock { + if m != nil { + return m.IndexedBlocks + } + return nil +} + +func (m *GenesisState) GetEvidences() []*Evidence { + if m != nil { + return m.Evidences + } + return nil +} + +func (m *GenesisState) GetVoteSigs() []*VoteSig { + if m != nil { + return m.VoteSigs + } + return nil +} + +func (m *GenesisState) GetPublicRandomness() []*PublicRandomness { + if m != nil { + return m.PublicRandomness + } + return nil +} + +// VoteSig the vote of an finality provider +// with the block of the vote, the finality provider btc public key and the vote signature. +type VoteSig struct { + // block_height is the height of the voted block. + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // fp_btc_pk is the BTC PK of the finality provider that casts this vote + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // finality_sig is the finality signature to this block + // where finality signature is an EOTS signature, i.e. + FinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,3,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` +} + +func (m *VoteSig) Reset() { *m = VoteSig{} } +func (m *VoteSig) String() string { return proto.CompactTextString(m) } +func (*VoteSig) ProtoMessage() {} +func (*VoteSig) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{1} +} +func (m *VoteSig) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VoteSig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VoteSig.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 *VoteSig) XXX_Merge(src proto.Message) { + xxx_messageInfo_VoteSig.Merge(m, src) +} +func (m *VoteSig) XXX_Size() int { + return m.Size() +} +func (m *VoteSig) XXX_DiscardUnknown() { + xxx_messageInfo_VoteSig.DiscardUnknown(m) +} + +var xxx_messageInfo_VoteSig proto.InternalMessageInfo + +func (m *VoteSig) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +// PublicRandomness the block height and public randomness that the finality provider has submitted. +type PublicRandomness struct { + // block_height is the height of block which the finality provider submited public randomness. + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // fp_btc_pk is the BTC PK of the finality provider that casts this vote. + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // pub_rand is the public randomness the finality provider has committed to. + PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` +} + +func (m *PublicRandomness) Reset() { *m = PublicRandomness{} } +func (m *PublicRandomness) String() string { return proto.CompactTextString(m) } +func (*PublicRandomness) ProtoMessage() {} +func (*PublicRandomness) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{2} +} +func (m *PublicRandomness) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PublicRandomness) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PublicRandomness.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 *PublicRandomness) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicRandomness.Merge(m, src) +} +func (m *PublicRandomness) XXX_Size() int { + return m.Size() +} +func (m *PublicRandomness) XXX_DiscardUnknown() { + xxx_messageInfo_PublicRandomness.DiscardUnknown(m) +} + +var xxx_messageInfo_PublicRandomness proto.InternalMessageInfo + +func (m *PublicRandomness) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "babylon.finality.v1.GenesisState") + proto.RegisterType((*VoteSig)(nil), "babylon.finality.v1.VoteSig") + proto.RegisterType((*PublicRandomness)(nil), "babylon.finality.v1.PublicRandomness") } func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 200 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4a, 0x4c, 0xaa, - 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, - 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, - 0x2a, 0xd1, 0x83, 0x29, 0xd1, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xeb, - 0x83, 0x58, 0x10, 0xa5, 0x52, 0x0a, 0xd8, 0x4c, 0x2b, 0x48, 0x2c, 0x4a, 0xcc, 0x85, 0x1a, 0xa6, - 0xe4, 0xc9, 0xc5, 0xe3, 0x0e, 0x31, 0x3d, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0xc8, 0x92, 0x8b, 0x0d, - 0x22, 0x2f, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x87, 0xc5, 0x36, 0xbd, 0x00, 0xb0, - 0x12, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x1a, 0x9c, 0xbc, 0x4e, 0x3c, 0x92, 0x63, - 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, - 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x20, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, - 0x3f, 0x57, 0x1f, 0x6a, 0x5c, 0x72, 0x46, 0x62, 0x66, 0x1e, 0x8c, 0xa3, 0x5f, 0x81, 0x70, 0x60, - 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x75, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x58, 0x11, 0xae, 0xb4, 0x0f, 0x01, 0x00, 0x00, + // 483 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0x87, 0x9b, 0xb6, 0xac, 0xab, 0x5b, 0xd0, 0x08, 0x1c, 0xa2, 0x02, 0xe9, 0x1f, 0x09, 0xa9, + 0xa7, 0x64, 0xeb, 0x26, 0xc4, 0xc4, 0x2d, 0xd2, 0xc4, 0x06, 0x07, 0x22, 0x07, 0x71, 0x80, 0x43, + 0x14, 0xa7, 0x6e, 0x62, 0xb5, 0xb5, 0xad, 0xd8, 0x89, 0xd6, 0x6f, 0xc1, 0xc7, 0xda, 0x71, 0x47, + 0x34, 0x89, 0x82, 0xda, 0x2f, 0x82, 0xe2, 0xa4, 0x1b, 0x9a, 0x22, 0x81, 0xb8, 0x70, 0xb3, 0x9d, + 0xe7, 0x7d, 0xfc, 0xbe, 0xbf, 0xc8, 0x60, 0x88, 0x02, 0xb4, 0x5a, 0x30, 0x6a, 0xcf, 0x08, 0x0d, + 0x16, 0x44, 0xae, 0xec, 0xec, 0xc8, 0x8e, 0x30, 0xc5, 0x82, 0x08, 0x8b, 0x27, 0x4c, 0x32, 0xfd, + 0x49, 0x89, 0x58, 0x3b, 0xc4, 0xca, 0x8e, 0x7a, 0x4f, 0x23, 0x16, 0x31, 0xf5, 0xdd, 0xce, 0x57, + 0x05, 0xda, 0x1b, 0x54, 0xd9, 0x78, 0x90, 0x04, 0xcb, 0x52, 0xd6, 0x1b, 0x55, 0x11, 0xb7, 0x62, + 0xc5, 0x8c, 0x7e, 0xd4, 0x41, 0xf7, 0x6d, 0xd1, 0x82, 0x27, 0x03, 0x89, 0xf5, 0x53, 0xb0, 0x57, + 0x48, 0x0c, 0x6d, 0xa0, 0x8d, 0x3b, 0x93, 0x67, 0x56, 0x45, 0x4b, 0x96, 0xab, 0x10, 0xa7, 0x79, + 0xb5, 0xee, 0xd7, 0x60, 0x59, 0xa0, 0x9f, 0x83, 0x47, 0x84, 0x4e, 0xf1, 0x25, 0x9e, 0xfa, 0x68, + 0xc1, 0xc2, 0xb9, 0x30, 0xea, 0x83, 0xc6, 0xb8, 0x33, 0x19, 0x56, 0x2a, 0x2e, 0x0a, 0xd4, 0xc9, + 0x49, 0xf8, 0x90, 0xfc, 0xb6, 0x13, 0xfa, 0x1b, 0xd0, 0xc6, 0x19, 0x99, 0x62, 0x1a, 0x62, 0x61, + 0x34, 0x94, 0xe4, 0x45, 0xa5, 0xe4, 0xac, 0xa4, 0xe0, 0x1d, 0xaf, 0x9f, 0x82, 0x76, 0xc6, 0x24, + 0xf6, 0x05, 0x89, 0x84, 0xd1, 0x54, 0xc5, 0xcf, 0x2b, 0x8b, 0x3f, 0x31, 0x89, 0x3d, 0x12, 0xc1, + 0xfd, 0xac, 0x58, 0x08, 0x1d, 0x82, 0xc7, 0x3c, 0x45, 0x0b, 0x12, 0xfa, 0x49, 0x40, 0xa7, 0x6c, + 0x49, 0xb1, 0x10, 0xc6, 0x03, 0xa5, 0x78, 0x59, 0x9d, 0x83, 0xa2, 0xe1, 0x2d, 0x0c, 0x0f, 0xf8, + 0xbd, 0x93, 0xd1, 0x77, 0x0d, 0xb4, 0xca, 0x9b, 0xf4, 0x21, 0xe8, 0xaa, 0x64, 0xfc, 0x18, 0x93, + 0x28, 0x96, 0x2a, 0xe2, 0x26, 0xec, 0xa8, 0xb3, 0x73, 0x75, 0xa4, 0x43, 0xd0, 0x9e, 0x71, 0x1f, + 0xc9, 0xd0, 0xe7, 0x73, 0xa3, 0x3e, 0xd0, 0xc6, 0x5d, 0xe7, 0xd5, 0xcd, 0xba, 0x3f, 0x89, 0x88, + 0x8c, 0x53, 0x64, 0x85, 0x6c, 0x69, 0x97, 0x8d, 0x84, 0x71, 0x40, 0xe8, 0x6e, 0x63, 0xcb, 0x15, + 0xc7, 0xc2, 0x72, 0x2e, 0xdc, 0xe3, 0x93, 0x43, 0x37, 0x45, 0xef, 0xf1, 0x0a, 0xb6, 0x66, 0xdc, + 0x91, 0xa1, 0x3b, 0xd7, 0xbf, 0x80, 0xee, 0xae, 0xe9, 0x3c, 0x15, 0xa3, 0xa1, 0xb4, 0xaf, 0x6f, + 0xd6, 0xfd, 0x93, 0xbf, 0xd3, 0x7a, 0x61, 0x4c, 0x59, 0x92, 0x9c, 0x7d, 0xf8, 0xe8, 0xe5, 0x81, + 0x75, 0x76, 0x36, 0x8f, 0x44, 0xa3, 0xb5, 0x06, 0x0e, 0xee, 0xc7, 0xf0, 0xbf, 0x06, 0xf5, 0xc0, + 0x3e, 0x4f, 0x91, 0xfa, 0x79, 0xff, 0x3c, 0xa4, 0x9b, 0xa2, 0x7c, 0x10, 0xd8, 0xe2, 0xc5, 0xc2, + 0x79, 0x77, 0xb5, 0x31, 0xb5, 0xeb, 0x8d, 0xa9, 0xfd, 0xdc, 0x98, 0xda, 0xd7, 0xad, 0x59, 0xbb, + 0xde, 0x9a, 0xb5, 0x6f, 0x5b, 0xb3, 0xf6, 0xf9, 0xf0, 0x4f, 0xe2, 0xcb, 0xbb, 0xa7, 0xa7, 0xee, + 0x40, 0x7b, 0xea, 0xd5, 0x1d, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x48, 0x67, 0xec, 0x5e, 0x0b, + 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -111,6 +271,62 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PublicRandomness) > 0 { + for iNdEx := len(m.PublicRandomness) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PublicRandomness[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.VoteSigs) > 0 { + for iNdEx := len(m.VoteSigs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VoteSigs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Evidences) > 0 { + for iNdEx := len(m.Evidences) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Evidences[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.IndexedBlocks) > 0 { + for iNdEx := len(m.IndexedBlocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IndexedBlocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { @@ -124,6 +340,110 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *VoteSig) 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 *VoteSig) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VoteSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.FinalitySig != nil { + { + size := m.FinalitySig.Size() + i -= size + if _, err := m.FinalitySig.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *PublicRandomness) 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 *PublicRandomness) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PublicRandomness) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PubRand != nil { + { + size := m.PubRand.Size() + i -= size + if _, err := m.PubRand.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -143,6 +463,70 @@ func (m *GenesisState) Size() (n int) { _ = l l = m.Params.Size() n += 1 + l + sovGenesis(uint64(l)) + if len(m.IndexedBlocks) > 0 { + for _, e := range m.IndexedBlocks { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Evidences) > 0 { + for _, e := range m.Evidences { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.VoteSigs) > 0 { + for _, e := range m.VoteSigs { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.PublicRandomness) > 0 { + for _, e := range m.PublicRandomness { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *VoteSig) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeight)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.FinalitySig != nil { + l = m.FinalitySig.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *PublicRandomness) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeight)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.PubRand != nil { + l = m.PubRand.Size() + n += 1 + l + sovGenesis(uint64(l)) + } return n } @@ -214,6 +598,420 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IndexedBlocks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IndexedBlocks = append(m.IndexedBlocks, &IndexedBlock{}) + if err := m.IndexedBlocks[len(m.IndexedBlocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Evidences", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Evidences = append(m.Evidences, &Evidence{}) + if err := m.Evidences[len(m.Evidences)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VoteSigs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VoteSigs = append(m.VoteSigs, &VoteSig{}) + if err := m.VoteSigs[len(m.VoteSigs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicRandomness", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicRandomness = append(m.PublicRandomness, &PublicRandomness{}) + if err := m.PublicRandomness[len(m.PublicRandomness)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VoteSig) 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 ErrIntOverflowGenesis + } + 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: VoteSig: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VoteSig: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalitySig", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.SchnorrEOTSSig + m.FinalitySig = &v + if err := m.FinalitySig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PublicRandomness) 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 ErrIntOverflowGenesis + } + 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: PublicRandomness: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicRandomness: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.SchnorrPubRand + m.PubRand = &v + if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 0a5ce2e40..4e596001b 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -22,7 +22,3 @@ var ( EvidenceKey = []byte{0x05} // key prefix for evidences NextHeightToFinalizeKey = []byte{0x06} // key prefix for next height to finalise ) - -func KeyPrefix(p string) []byte { - return []byte(p) -} From 735630088708365cda133155feb97e7fb1310bad Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Thu, 14 Mar 2024 16:56:37 +0100 Subject: [PATCH 047/119] Pr comments --- ...ced_staking.go => identifiable_staking.go} | 92 ++++++++----------- ...g_test.go => identifiable_staking_test.go} | 21 ++--- btcstaking/identifiable_staking_types.go | 27 ++++++ 3 files changed, 72 insertions(+), 68 deletions(-) rename btcstaking/{enhanced_staking.go => identifiable_staking.go} (81%) rename btcstaking/{enhanced_staking_test.go => identifiable_staking_test.go} (83%) create mode 100644 btcstaking/identifiable_staking_types.go diff --git a/btcstaking/enhanced_staking.go b/btcstaking/identifiable_staking.go similarity index 81% rename from btcstaking/enhanced_staking.go rename to btcstaking/identifiable_staking.go index f26b9c7cb..cd28468c9 100644 --- a/btcstaking/enhanced_staking.go +++ b/btcstaking/identifiable_staking.go @@ -20,9 +20,11 @@ const ( MagicBytesLen = 4 // 4 bytes magic bytes + 1 byte version + 32 bytes staker public key + 32 bytes finality provider public key + 2 bytes staking time V0OpReturnDataSize = 71 + + v0OpReturnCreationErrMsg = "cannot create V0 op_return data" ) -type EnhancedStakingInfo struct { +type IdentifiableStakingInfo struct { StakingOutput *wire.TxOut scriptHolder *taprootScriptHolder timeLockPathLeafHash chainhash.Hash @@ -31,27 +33,6 @@ type EnhancedStakingInfo struct { OpReturnOutput *wire.TxOut } -// XonlyPubKey is a wrapper around btcec.PublicKey that represents BTC public -// key deserialized from a 32-byte array i.e with implicit assumption that Y coordinate -// is even. -type XonlyPubKey struct { - PubKey *btcec.PublicKey -} - -func XOnlyPublicKeyFromBytes(pkBytes []byte) (*XonlyPubKey, error) { - pk, err := schnorr.ParsePubKey(pkBytes) - - if err != nil { - return nil, err - } - - return &XonlyPubKey{pk}, nil -} - -func (p *XonlyPubKey) Marshall() []byte { - return schnorr.SerializePubKey(p.PubKey) -} - func uint16ToBytes(v uint16) []byte { var buf [2]byte binary.BigEndian.PutUint16(buf[:], v) @@ -83,34 +64,28 @@ func NewV0OpReturnData( stakingTime []byte, ) (*V0OpReturnData, error) { if len(magicBytes) != MagicBytesLen { - return nil, fmt.Errorf("cannot create op_return data: invalid magic bytes length: %d, expected: %d", len(magicBytes), MagicBytesLen) + return nil, fmt.Errorf("%s: invalid magic bytes length: %d, expected: %d", v0OpReturnCreationErrMsg, len(magicBytes), MagicBytesLen) } stakerKey, err := XOnlyPublicKeyFromBytes(stakerPublicKey) if err != nil { - return nil, fmt.Errorf("cannot create op_return data: %w", err) + return nil, fmt.Errorf("%s:invalid staker public key:%w", v0OpReturnCreationErrMsg, err) } fpKey, err := XOnlyPublicKeyFromBytes(finalityProviderPublicKey) if err != nil { - return nil, fmt.Errorf("cannot create op_return data: %w", err) + return nil, fmt.Errorf("%s:invalid finality provider public key:%w", v0OpReturnCreationErrMsg, err) } stakingTimeValue, err := uint16FromBytes(stakingTime) if err != nil { - return nil, fmt.Errorf("cannot create op_return data: %w", err) + return nil, fmt.Errorf("%s:invalid staking time:%w", v0OpReturnCreationErrMsg, err) } - return &V0OpReturnData{ - MagicBytes: magicBytes, - Version: 0, - StakerPublicKey: stakerKey, - FinalityProviderPublicKey: fpKey, - StakingTime: stakingTimeValue, - }, nil + return NewV0OpReturnDataFromParsed(magicBytes, stakerKey.PubKey, fpKey.PubKey, stakingTimeValue) } func NewV0OpReturnDataFromParsed( @@ -120,15 +95,15 @@ func NewV0OpReturnDataFromParsed( stakingTime uint16, ) (*V0OpReturnData, error) { if len(magicBytes) != MagicBytesLen { - return nil, fmt.Errorf("cannot create op_return data: invalid magic bytes length: %d, expected: %d", len(magicBytes), MagicBytesLen) + return nil, fmt.Errorf("%s:invalid magic bytes length: %d, expected: %d", v0OpReturnCreationErrMsg, len(magicBytes), MagicBytesLen) } if stakerPublicKey == nil { - return nil, fmt.Errorf("cannot create op_return data: nil staker public key") + return nil, fmt.Errorf("%s:nil staker public key", v0OpReturnCreationErrMsg) } if finalityProviderPublicKey == nil { - return nil, fmt.Errorf("cannot create op_return data: nil finality provider public key") + return nil, fmt.Errorf("%s: nil finality provider public key", v0OpReturnCreationErrMsg) } return &V0OpReturnData{ @@ -197,16 +172,16 @@ func (d *V0OpReturnData) Marshall() []byte { return data } -func (d *V0OpReturnData) ToTxOutput(v int64) (*wire.TxOut, error) { +func (d *V0OpReturnData) ToTxOutput() (*wire.TxOut, error) { dataScript, err := txscript.NullDataScript(d.Marshall()) if err != nil { return nil, err } - return wire.NewTxOut(v, dataScript), nil + return wire.NewTxOut(0, dataScript), nil } -// BuildV0EnhancedStakingOutputs crates outputs which every staking transaction must have -func BuildV0EnhancedStakingOutputs( +// BuildV0IdentifiableStakingOutputs creates outputs which every staking transaction must have +func BuildV0IdentifiableStakingOutputs( magicBytes []byte, stakerKey *btcec.PublicKey, fpKey *btcec.PublicKey, @@ -215,7 +190,7 @@ func BuildV0EnhancedStakingOutputs( stakingTime uint16, stakingAmount btcutil.Amount, net *chaincfg.Params, -) (*EnhancedStakingInfo, error) { +) (*IdentifiableStakingInfo, error) { info, err := BuildStakingInfo( stakerKey, []*btcec.PublicKey{fpKey}, @@ -235,13 +210,13 @@ func BuildV0EnhancedStakingOutputs( return nil, err } - dataOutput, err := opReturnData.ToTxOutput(0) + dataOutput, err := opReturnData.ToTxOutput() if err != nil { return nil, err } - return &EnhancedStakingInfo{ + return &IdentifiableStakingInfo{ StakingOutput: info.StakingOutput, scriptHolder: info.scriptHolder, timeLockPathLeafHash: info.timeLockPathLeafHash, @@ -251,9 +226,9 @@ func BuildV0EnhancedStakingOutputs( }, nil } -// BuildV0EnhancedStakingOutputs crates outputs which every staking transaction must have and +// BuildV0IdentifiableStakingOutputsAndTx creates outputs which every staking transaction must have and // returns the not-funded transaction with these outputs -func BuildV0EnhancedStakingOutputsAndTx( +func BuildV0IdentifiableStakingOutputsAndTx( magicBytes []byte, stakerKey *btcec.PublicKey, fpKey *btcec.PublicKey, @@ -262,8 +237,8 @@ func BuildV0EnhancedStakingOutputsAndTx( stakingTime uint16, stakingAmount btcutil.Amount, net *chaincfg.Params, -) (*EnhancedStakingInfo, *wire.MsgTx, error) { - info, err := BuildV0EnhancedStakingOutputs( +) (*IdentifiableStakingInfo, *wire.MsgTx, error) { + info, err := BuildV0IdentifiableStakingOutputs( magicBytes, stakerKey, fpKey, @@ -283,15 +258,15 @@ func BuildV0EnhancedStakingOutputsAndTx( return info, tx, nil } -func (i *EnhancedStakingInfo) TimeLockPathSpendInfo() (*SpendInfo, error) { +func (i *IdentifiableStakingInfo) TimeLockPathSpendInfo() (*SpendInfo, error) { return i.scriptHolder.scriptSpendInfoByName(i.timeLockPathLeafHash) } -func (i *EnhancedStakingInfo) UnbondingPathSpendInfo() (*SpendInfo, error) { +func (i *IdentifiableStakingInfo) UnbondingPathSpendInfo() (*SpendInfo, error) { return i.scriptHolder.scriptSpendInfoByName(i.unbondingPathLeafHash) } -func (i *EnhancedStakingInfo) SlashingPathSpendInfo() (*SpendInfo, error) { +func (i *IdentifiableStakingInfo) SlashingPathSpendInfo() (*SpendInfo, error) { return i.scriptHolder.scriptSpendInfoByName(i.slashingPathLeafHash) } @@ -353,7 +328,7 @@ func tryToGetStakingOutput(outputs []*wire.TxOut, stakingOutputPkScript []byte) } if stakingOutput != nil { - // we only allow for on staking output per transaction + // we only allow for one staking output per transaction return nil, -1, fmt.Errorf("multiple staking outputs found") } @@ -364,7 +339,7 @@ func tryToGetStakingOutput(outputs []*wire.TxOut, stakingOutputPkScript []byte) return stakingOutput, stakingOutputIdx, nil } -// ParseV0StakingTx takes btc transaction checks whether it is a staking transaction and if so parses it +// ParseV0StakingTx takes a btc transaction and checks whether it is a staking transaction and if so parses it // for easy data retrieval. // It does all necessary checks to ensure that the transaction is valid staking transaction. func ParseV0StakingTx( @@ -391,7 +366,7 @@ func ParseV0StakingTx( return nil, fmt.Errorf("covenant quorum is greater than the number of covenant keys") } - // 2 Identify whether the transaction has expected shape + // 2. Identify whether the transaction has expected shape if len(tx.TxOut) < 2 { return nil, fmt.Errorf("staking tx must have at least 2 outputs") } @@ -419,7 +394,7 @@ func ParseV0StakingTx( return nil, fmt.Errorf("unexpcted version: %d, expected: %d", opReturnData.Version, 0) } - // 3: Op return seems to be valid V0 op return output. Now, we need to check whether + // 3. Op return seems to be valid V0 op return output. Now, we need to check whether // the staking output exists and is valid. stakingInfo, err := BuildStakingInfo( opReturnData.StakerPublicKey.PubKey, @@ -455,7 +430,7 @@ func ParseV0StakingTx( }, nil } -// IsV0StakingTx checks whether transaction maybe a valid staking transaction. It +// IsPossibleV0StakingTx checks whether transaction may be a valid staking transaction // checks: // 1. Whether the transaction has at least 2 outputs // 2. have an op return output @@ -487,10 +462,15 @@ func IsPossibleV0StakingTx(tx *wire.MsgTx, expectedMagicBytes []byte) bool { continue } + if data[MagicBytesLen] != 0 { + // this is not the v0 op return output + continue + } + if possibleStakingTx { // this is second output that matches the magic bytes, we do not allow for multiple op return outputs // so this is not a valid staking transaction - continue + return false } possibleStakingTx = true diff --git a/btcstaking/enhanced_staking_test.go b/btcstaking/identifiable_staking_test.go similarity index 83% rename from btcstaking/enhanced_staking_test.go rename to btcstaking/identifiable_staking_test.go index 6c26e6f20..fb714a7d4 100644 --- a/btcstaking/enhanced_staking_test.go +++ b/btcstaking/identifiable_staking_test.go @@ -15,23 +15,20 @@ import ( "github.com/stretchr/testify/require" ) -func generateTxFromOutputs(r *rand.Rand, info *btcstaking.EnhancedStakingInfo) (*wire.MsgTx, int, int) { - numOutputs := 20 +func generateTxFromOutputs(r *rand.Rand, info *btcstaking.IdentifiableStakingInfo) (*wire.MsgTx, int, int) { + numOutputs := r.Int31n(18) + 2 - stakingOutputIdx := r.Intn(numOutputs - 1) - opReturnOutputIdx := r.Intn(numOutputs - 1) + stakingOutputIdx := int(r.Int31n(numOutputs)) + opReturnOutputIdx := int(datagen.RandomIntOtherThan(r, int(stakingOutputIdx), int(numOutputs))) - if stakingOutputIdx == opReturnOutputIdx { - opReturnOutputIdx = stakingOutputIdx + 1 - } tx := wire.NewMsgTx(2) - for i := 0; i < numOutputs; i++ { + for i := 0; i < int(numOutputs); i++ { if i == stakingOutputIdx { tx.AddTxOut(info.StakingOutput) } else if i == opReturnOutputIdx { tx.AddTxOut(info.OpReturnOutput) } else { - tx.AddTxOut(wire.NewTxOut(int64(r.Int63n(1000000000)+10000), datagen.GenRandomByteArray(r, 32))) + tx.AddTxOut(wire.NewTxOut((r.Int63n(1000000000) + 10000), datagen.GenRandomByteArray(r, 32))) } } @@ -42,12 +39,12 @@ func generateTxFromOutputs(r *rand.Rand, info *btcstaking.EnhancedStakingInfo) ( // our parser func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { // lot of seeds as test is pretty fast and we want to test a lot of different values - datagen.AddRandomSeedsToFuzzer(f, 100) + datagen.AddRandomSeedsToFuzzer(f, 1000) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) // 3 - 10 covenants numCovenantKeys := uint32(r.Int31n(7) + 3) - quroum := uint32(numCovenantKeys - 2) + quroum := uint32(r.Intn(int(numCovenantKeys)) + 1) stakingAmount := btcutil.Amount(r.Int63n(1000000000) + 10000) stakingTime := uint16(r.Int31n(math.MaxUint16-1) + 1) magicBytes := datagen.GenRandomByteArray(r, btcstaking.MagicBytesLen) @@ -55,7 +52,7 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { sc := GenerateTestScenario(r, t, 1, numCovenantKeys, quroum, stakingAmount, stakingTime) - outputs, err := btcstaking.BuildV0EnhancedStakingOutputs( + outputs, err := btcstaking.BuildV0IdentifiableStakingOutputs( magicBytes, sc.StakerKey.PubKey(), sc.FinalityProviderKeys[0].PubKey(), diff --git a/btcstaking/identifiable_staking_types.go b/btcstaking/identifiable_staking_types.go new file mode 100644 index 000000000..b1ce12702 --- /dev/null +++ b/btcstaking/identifiable_staking_types.go @@ -0,0 +1,27 @@ +package btcstaking + +import ( + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" +) + +// XonlyPubKey is a wrapper around btcec.PublicKey that represents BTC public +// key deserialized from a 32-byte array i.e with implicit assumption that Y coordinate +// is even. +type XonlyPubKey struct { + PubKey *btcec.PublicKey +} + +func XOnlyPublicKeyFromBytes(pkBytes []byte) (*XonlyPubKey, error) { + pk, err := schnorr.ParsePubKey(pkBytes) + + if err != nil { + return nil, err + } + + return &XonlyPubKey{pk}, nil +} + +func (p *XonlyPubKey) Marshall() []byte { + return schnorr.SerializePubKey(p.PubKey) +} From 2aeac1ae6833453b9ab09404da3837fb9afbc3b0 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 15 Mar 2024 15:57:21 +1100 Subject: [PATCH 048/119] fix: fix flaky test `FuzzFinalityProviderPowerAtHeight` (#575) --- x/btcstaking/keeper/grpc_query_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index 9a365abc3..d85095278 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -296,7 +296,7 @@ func FuzzFinalityProviderPowerAtHeight(f *testing.F) { // case where the voting power store is not updated in // the given height - requestHeight := datagen.RandomIntOtherThan(r, int(randomHeight), 100) + 1 + requestHeight := randomHeight + datagen.RandomInt(r, 10) + 1 req2 := &types.QueryFinalityProviderPowerAtHeightRequest{ FpBtcPkHex: fp.BtcPk.MarshalHex(), Height: requestHeight, From 3c0e8a960ef770236ee3d8a432104472821e74d7 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 15 Mar 2024 19:39:56 +1100 Subject: [PATCH 049/119] fix sorting bug in multisig script (#571) Co-authored-by: KonradStaniec --- btcstaking/scripts_utils.go | 16 +++++----- btcstaking/staking_utils_test.go | 35 ++++++++++++++++++++++ x/btcstaking/types/btc_slashing_tx_test.go | 8 ++--- 3 files changed, 48 insertions(+), 11 deletions(-) create mode 100644 btcstaking/staking_utils_test.go diff --git a/btcstaking/scripts_utils.go b/btcstaking/scripts_utils.go index e9e2a2928..e021248bd 100644 --- a/btcstaking/scripts_utils.go +++ b/btcstaking/scripts_utils.go @@ -37,16 +37,18 @@ func assembleMultiSigScript( return builder.Script() } -// sortKeys takes a set of schnorr public keys and returns a new slice that is +// SortKeys takes a set of schnorr public keys and returns a new slice that is // a copy of the keys sorted in lexicographical order bytes on the x-only // pubkey serialization. -func sortKeys(keys []*btcec.PublicKey) []*btcec.PublicKey { - sort.SliceStable(keys, func(i, j int) bool { - keyIBytes := schnorr.SerializePubKey(keys[i]) - keyJBytes := schnorr.SerializePubKey(keys[j]) +func SortKeys(keys []*btcec.PublicKey) []*btcec.PublicKey { + sortedKeys := make([]*btcec.PublicKey, len(keys)) + copy(sortedKeys, keys) + sort.SliceStable(sortedKeys, func(i, j int) bool { + keyIBytes := schnorr.SerializePubKey(sortedKeys[i]) + keyJBytes := schnorr.SerializePubKey(sortedKeys[j]) return bytes.Compare(keyIBytes, keyJBytes) == -1 }) - return keys + return sortedKeys } // prepareKeys prepares keys to be used in multisig script @@ -59,7 +61,7 @@ func prepareKeysForMultisigScript(keys []*btcec.PublicKey) ([]*btcec.PublicKey, return nil, fmt.Errorf("cannot create multisig script with less than 2 keys") } - sortedKeys := sortKeys(keys) + sortedKeys := SortKeys(keys) for i := 0; i < len(sortedKeys)-1; i++ { if bytes.Equal(schnorr.SerializePubKey(sortedKeys[i]), schnorr.SerializePubKey(sortedKeys[i+1])) { diff --git a/btcstaking/staking_utils_test.go b/btcstaking/staking_utils_test.go new file mode 100644 index 000000000..e286ad05e --- /dev/null +++ b/btcstaking/staking_utils_test.go @@ -0,0 +1,35 @@ +package btcstaking_test + +import ( + "math/rand" + "testing" + "time" + + "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" + "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/stretchr/testify/require" +) + +func TestSortKeys(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + + _, pks, err := datagen.GenRandomBTCKeyPairs(r, 10) + require.NoError(t, err) + + sortedPKs := btcstaking.SortKeys(pks) + + btcPKs := bbn.NewBIP340PKsFromBTCPKs(pks) + sortedBTCPKs := bbn.SortBIP340PKs(btcPKs) + + // ensure sorted PKs and sorted BIP340 PKs are in reverse order + for i := range sortedPKs { + pkBytes := schnorr.SerializePubKey(sortedPKs[i]) + + btcPK := sortedBTCPKs[len(sortedBTCPKs)-1-i] + btcPKBytes := btcPK.MustMarshal() + + require.Equal(t, pkBytes, btcPKBytes, "comparing %d-th key", i) + } +} diff --git a/x/btcstaking/types/btc_slashing_tx_test.go b/x/btcstaking/types/btc_slashing_tx_test.go index 292613426..68c2ecee3 100644 --- a/x/btcstaking/types/btc_slashing_tx_test.go +++ b/x/btcstaking/types/btc_slashing_tx_test.go @@ -45,6 +45,10 @@ func FuzzSlashingTxWithWitness(f *testing.F) { covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5) require.NoError(t, err) covenantQuorum := uint32(3) + bsParams := types.Params{ + CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), + CovenantQuorum: covenantQuorum, + } slashingChangeLockTime := uint16(101) // generate staking/slashing tx @@ -83,10 +87,6 @@ func FuzzSlashingTxWithWitness(f *testing.F) { ) require.NoError(t, err) - bsParams := types.Params{ - CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), - CovenantQuorum: covenantQuorum, - } covSigs, err := types.GetOrderedCovenantSignatures(0, covenantSigs, &bsParams) require.NoError(t, err) From 79615c6b057de041a9f4c1c4466ef212a0c678d6 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 15 Mar 2024 21:06:14 +1100 Subject: [PATCH 050/119] btcstaking: restaking support and tests (#567) --- btcstaking/types.go | 4 +- testutil/datagen/btcstaking.go | 22 +-- testutil/datagen/covenant.go | 6 +- types/btc_schnorr_pk.go | 8 +- x/btcstaking/keeper/msg_server.go | 10 +- x/btcstaking/types/btc_delegation.go | 36 ++++- x/btcstaking/types/btc_delegation_test.go | 93 ++++++------ x/btcstaking/types/btc_slashing_tx.go | 58 ++++++-- x/btcstaking/types/btc_slashing_tx_test.go | 156 ++++++++++++++++++-- x/btcstaking/types/btc_undelegation_test.go | 100 ++++++------- x/btcstaking/types/btcstaking.go | 6 +- 11 files changed, 340 insertions(+), 159 deletions(-) diff --git a/btcstaking/types.go b/btcstaking/types.go index 3de6a2bf3..4d1185acd 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -300,7 +300,7 @@ func newBabylonScriptPaths( return nil, err } - fpSigScript, err := buildMultiSigScript( + fpMultisigScript, err := buildMultiSigScript( fpKeys, // we always require only one finality provider to sign 1, @@ -319,7 +319,7 @@ func newBabylonScriptPaths( slashingPathScript := aggregateScripts( stakerSigScript, - fpSigScript, + fpMultisigScript, covenantMultisigScript, ) diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 8c5323aab..f3ffa213a 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -111,13 +111,9 @@ func GenRandomBTCDelegation( covenantBTCPKs = append(covenantBTCPKs, covenantSK.PubKey()) } // list of finality provider PKs - fpPKs := []*btcec.PublicKey{} - for _, fpBTCPK := range fpBTCPKs { - fpPK, err := fpBTCPK.ToBTCPK() - if err != nil { - return nil, err - } - fpPKs = append(fpPKs, fpPK) + fpPKs, err := bbn.NewBTCPKsFromBIP340PKs(fpBTCPKs) + if err != nil { + return nil, err } // BTC delegation Babylon key pairs @@ -153,22 +149,20 @@ func GenRandomBTCDelegation( slashingPathSpendInfo, err := stakingSlashingInfo.StakingInfo.SlashingPathSpendInfo() require.NoError(t, err) - stakingMsgTx := stakingSlashingInfo.StakingTx - - // delegator sig + // delegator pre-signs slashing tx delegatorSig, err := stakingSlashingInfo.SlashingTx.Sign( - stakingMsgTx, + stakingSlashingInfo.StakingTx, StakingOutIdx, slashingPathSpendInfo.GetPkScriptPath(), delSK, ) require.NoError(t, err) - // covenant sigs + // covenant pre-signs slashing tx covenantSigs, err := GenCovenantAdaptorSigs( covenantSKs, fpPKs, - stakingMsgTx, + stakingSlashingInfo.StakingTx, slashingPathSpendInfo.GetPkScriptPath(), stakingSlashingInfo.SlashingTx, ) @@ -237,7 +231,7 @@ func GenRandomBTCDelegation( covUnbondingSlashingSigs, covUnbondingSigs, err := unbondingSlashingInfo.GenCovenantSigs( covenantSKs, fpPKs, - stakingMsgTx, + stakingSlashingInfo.StakingTx, unbondingPathSpendInfo.GetPkScriptPath(), ) require.NoError(t, err) diff --git a/testutil/datagen/covenant.go b/testutil/datagen/covenant.go index ae2fd835b..9961b5055 100644 --- a/testutil/datagen/covenant.go +++ b/testutil/datagen/covenant.go @@ -12,7 +12,7 @@ import ( func GenCovenantAdaptorSigs( covenantSKs []*btcec.PrivateKey, - valPKs []*btcec.PublicKey, + fpPKs []*btcec.PublicKey, fundingTx *wire.MsgTx, pkScriptPath []byte, slashingTx *bstypes.BTCSlashingTx, @@ -23,8 +23,8 @@ func GenCovenantAdaptorSigs( CovPk: bbn.NewBIP340PubKeyFromBTCPK(covenantSK.PubKey()), AdaptorSigs: [][]byte{}, } - for _, valPK := range valPKs { - encKey, err := asig.NewEncryptionKeyFromBTCPK(valPK) + for _, fpPK := range fpPKs { + encKey, err := asig.NewEncryptionKeyFromBTCPK(fpPK) if err != nil { return nil, err } diff --git a/types/btc_schnorr_pk.go b/types/btc_schnorr_pk.go index f297747dd..dfcf1cb19 100644 --- a/types/btc_schnorr_pk.go +++ b/types/btc_schnorr_pk.go @@ -113,19 +113,19 @@ func (pk *BIP340PubKey) Equals(pk2 *BIP340PubKey) bool { } func NewBTCPKsFromBIP340PKs(pks []BIP340PubKey) ([]*btcec.PublicKey, error) { - btcPks := make([]*btcec.PublicKey, 0, len(pks)) - for _, pk := range pks { + btcPks := make([]*btcec.PublicKey, len(pks)) + for i, pk := range pks { btcPK, err := pk.ToBTCPK() if err != nil { return nil, err } - btcPks = append(btcPks, btcPK) + btcPks[i] = btcPK } return btcPks, nil } func NewBIP340PKsFromBTCPKs(btcPKs []*btcec.PublicKey) []BIP340PubKey { - pks := make([]BIP340PubKey, 0, len(btcPKs)) + pks := []BIP340PubKey{} for _, btcPK := range btcPKs { pks = append(pks, *NewBIP340PubKeyFromBTCPK(btcPK)) } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 60af18f3d..0f40225e6 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -462,10 +462,8 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove return &types.MsgAddCovenantSigsResponse{}, nil } - // Note: we assume the order of adaptor sigs is matched to the - // order of finality providers in the delegation - // TODO: ensure the order for restaking, currently, we only have one finality provider - // one covenant emulator + // Check that the number of covenant sigs and number of the + // finality providers are matched if len(req.SlashingTxSigs) != len(btcDel.FpBtcPkList) { return nil, types.ErrInvalidCovenantSig.Wrapf( "number of covenant signatures: %d, number of finality providers being staked to: %d", @@ -498,10 +496,6 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove // Check that the number of covenant sigs and number of the // finality providers are matched - // Note: we assume the order of adaptor sigs is matched to the - // order of finality providers in the delegation - // TODO: ensure the order for restaking, currently, we only have one finality provider - // one covenant emulator if len(req.SlashingUnbondingTxSigs) != len(btcDel.FpBtcPkList) { return nil, types.ErrInvalidCovenantSig.Wrapf( "number of covenant signatures: %d, number of finality providers being staked to: %d", diff --git a/x/btcstaking/types/btc_delegation.go b/x/btcstaking/types/btc_delegation.go index c2b1f5833..7a8a27961 100644 --- a/x/btcstaking/types/btc_delegation.go +++ b/x/btcstaking/types/btc_delegation.go @@ -309,6 +309,21 @@ func (d *BTCDelegation) GetUnbondingInfo(bsParams *Params, btcNet *chaincfg.Para return unbondingInfo, nil } +// findFPIdx returns the index of the given finality provider +// among all restaked finality providers +func (d *BTCDelegation) findFPIdx(fpBTCPK *bbn.BIP340PubKey) (int, error) { + for i, pk := range d.FpBtcPkList { + if pk.Equals(fpBTCPK) { + return i, nil + } + } + return 0, fmt.Errorf("the given finality provider's PK is not found in the BTC delegation") +} + +// BuildSlashingTxWithWitness uses the given finality provider's SK to complete +// the signatures on the slashing tx, such that the slashing tx obtains full +// witness and can be submitted to Bitcoin. +// This happens after the finality provider is slashed and its SK is extracted. func (d *BTCDelegation) BuildSlashingTxWithWitness(bsParams *Params, btcNet *chaincfg.Params, fpSK *btcec.PrivateKey) (*wire.MsgTx, error) { stakingMsgTx, err := bbn.NewBTCTxFromBytes(d.StakingTx) if err != nil { @@ -325,8 +340,13 @@ func (d *BTCDelegation) BuildSlashingTxWithWitness(bsParams *Params, btcNet *cha return nil, fmt.Errorf("could not get slashing spend info: %v", err) } - // TODO: work with restaking - covAdaptorSigs, err := GetOrderedCovenantSignatures(0, d.CovenantSigs, bsParams) + // get the list of covenant signatures encrypted by the given finality provider's PK + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpSK.PubKey()) + fpIdx, err := d.findFPIdx(fpBTCPK) + if err != nil { + return nil, err + } + covAdaptorSigs, err := GetOrderedCovenantSignatures(fpIdx, d.CovenantSigs, bsParams) if err != nil { return nil, fmt.Errorf("failed to get ordered covenant adaptor signatures: %w", err) } @@ -334,6 +354,7 @@ func (d *BTCDelegation) BuildSlashingTxWithWitness(bsParams *Params, btcNet *cha // assemble witness for slashing tx slashingMsgTxWithWitness, err := d.SlashingTx.BuildSlashingTxWithWitness( fpSK, + d.FpBtcPkList, stakingMsgTx, d.StakingOutputIdx, d.DelegatorSig, @@ -368,8 +389,14 @@ func (d *BTCDelegation) BuildUnbondingSlashingTxWithWitness(bsParams *Params, bt return nil, fmt.Errorf("could not get unbonding slashing spend info: %v", err) } - // TODO: work with restaking - covAdaptorSigs, err := GetOrderedCovenantSignatures(0, d.BtcUndelegation.CovenantSlashingSigs, bsParams) + // get the list of covenant signatures encrypted by the given finality provider's PK + fpPK := fpSK.PubKey() + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpPK) + fpIdx, err := d.findFPIdx(fpBTCPK) + if err != nil { + return nil, err + } + covAdaptorSigs, err := GetOrderedCovenantSignatures(fpIdx, d.BtcUndelegation.CovenantSlashingSigs, bsParams) if err != nil { return nil, fmt.Errorf("failed to get ordered covenant adaptor signatures: %w", err) } @@ -377,6 +404,7 @@ func (d *BTCDelegation) BuildUnbondingSlashingTxWithWitness(bsParams *Params, bt // assemble witness for unbonding slashing tx slashingMsgTxWithWitness, err := d.BtcUndelegation.SlashingTx.BuildSlashingTxWithWitness( fpSK, + d.FpBtcPkList, unbondingMsgTx, 0, d.BtcUndelegation.DelegatorSlashingSig, diff --git a/x/btcstaking/types/btc_delegation_test.go b/x/btcstaking/types/btc_delegation_test.go index 92ee43742..deac36dd8 100644 --- a/x/btcstaking/types/btc_delegation_test.go +++ b/x/btcstaking/types/btc_delegation_test.go @@ -74,89 +74,86 @@ func FuzzBTCDelegation_SlashingTx(f *testing.F) { r := rand.New(rand.NewSource(seed)) net := &chaincfg.SimNetParams - delSK, delPK, err := datagen.GenRandomBTCKeyPair(r) + delSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - delBTCPK := bbn.NewBIP340PubKeyFromBTCPK(delPK) - fpSK, fpPK, err := datagen.GenRandomBTCKeyPair(r) + // restaked to a random number of finality providers + numRestakedFPs := int(datagen.RandomInt(r, 10) + 1) + fpSKs, fpPKs, err := datagen.GenRandomBTCKeyPairs(r, numRestakedFPs) require.NoError(t, err) - fpPKList := []*btcec.PublicKey{fpPK} + fpBTCPKs := bbn.NewBIP340PKsFromBTCPKs(fpPKs) + + // a random finality provider gets slashed + slashedFPIdx := int(datagen.RandomInt(r, numRestakedFPs)) + fpSK := fpSKs[slashedFPIdx] // (3, 5) covenant committee covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5) require.NoError(t, err) covenantQuorum := uint32(3) + bsParams := &types.Params{ + CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), + CovenantQuorum: covenantQuorum, + } stakingTimeBlocks := uint16(5) stakingValue := int64(2 * 10e8) slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) require.NoError(t, err) - slashingChangeLockTime := uint16(101) - - // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. - // NOTE - if the rate is higher or lower, it may produce slashing or change outputs - // with value below the dust threshold, causing test failure. - // Our goal is not to test failure due to such extreme cases here; - // this is already covered in FuzzGeneratingValidStakingSlashingTx slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) - testInfo := datagen.GenBTCStakingSlashingInfo( + unbondingTime := uint16(100) + 1 + slashingChangeLockTime := unbondingTime + + // construct the BTC delegation with everything + btcDel, err := datagen.GenRandomBTCDelegation( r, t, - net, + fpBTCPKs, delSK, - fpPKList, - covenantPKs, + covenantSKs, covenantQuorum, - stakingTimeBlocks, - stakingValue, slashingAddress.EncodeAddress(), + 1000, + uint64(1000+stakingTimeBlocks), + uint64(stakingValue), slashingRate, slashingChangeLockTime, ) require.NoError(t, err) - stakingTxBytes, err := bbn.SerializeBTCTx(testInfo.StakingTx) + stakingInfo, err := btcDel.GetStakingInfo(bsParams, net) require.NoError(t, err) - // spend info of the slashing tx - slashingSpendInfo, err := testInfo.StakingInfo.SlashingPathSpendInfo() + // TESTING + orderedCovenantPKs := bbn.SortBIP340PKs(bsParams.CovenantPks) + covSigsForFP, err := types.GetOrderedCovenantSignatures(slashedFPIdx, btcDel.CovenantSigs, bsParams) require.NoError(t, err) - // delegator signs the slashing tx - delSig, err := testInfo.SlashingTx.Sign(testInfo.StakingTx, 0, slashingSpendInfo.GetPkScriptPath(), delSK) + fpPK := fpSK.PubKey() + encKey, err := asig.NewEncryptionKeyFromBTCPK(fpPK) require.NoError(t, err) - // covenant signs (using adaptor signature) the slashing tx - covenantSigs, err := datagen.GenCovenantAdaptorSigs(covenantSKs, []*btcec.PublicKey{fpPK}, testInfo.StakingTx, slashingSpendInfo.GetPkScriptPath(), testInfo.SlashingTx) + slashingSpendInfo, err := stakingInfo.SlashingPathSpendInfo() require.NoError(t, err) - covenantSigs = covenantSigs[2:] // discard 2 out of 5 signatures - - // construct the BTC delegation with everything - btcDel := &types.BTCDelegation{ - BabylonPk: nil, // not relevant here - BtcPk: delBTCPK, - Pop: nil, // not relevant here - FpBtcPkList: bbn.NewBIP340PKsFromBTCPKs(fpPKList), - StartHeight: 1000, // not relevant here - EndHeight: uint64(1000 + stakingTimeBlocks), - TotalSat: uint64(stakingValue), - StakingTx: stakingTxBytes, - StakingOutputIdx: 0, - SlashingTx: testInfo.SlashingTx, - DelegatorSig: delSig, - CovenantSigs: covenantSigs, - } - - bsParams := &types.Params{ - CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), - CovenantQuorum: covenantQuorum, + for i := range covSigsForFP { + if covSigsForFP[i] == nil { + continue + } + err := btcDel.SlashingTx.EncVerifyAdaptorSignature( + stakingInfo.StakingOutput.PkScript, + stakingInfo.StakingOutput.Value, + slashingSpendInfo.GetPkScriptPath(), + orderedCovenantPKs[i].MustToBTCPK(), + encKey, + covSigsForFP[i], + ) + require.NoError(t, err) } - btcNet := &chaincfg.SimNetParams // build slashing tx with witness for spending the staking tx - slashingTxWithWitness, err := btcDel.BuildSlashingTxWithWitness(bsParams, btcNet, fpSK) + slashingTxWithWitness, err := btcDel.BuildSlashingTxWithWitness(bsParams, net, fpSK) require.NoError(t, err) // assert execution - btctest.AssertSlashingTxExecution(t, testInfo.StakingInfo.StakingOutput, slashingTxWithWitness) + btctest.AssertSlashingTxExecution(t, stakingInfo.StakingOutput, slashingTxWithWitness) }) } diff --git a/x/btcstaking/types/btc_slashing_tx.go b/x/btcstaking/types/btc_slashing_tx.go index 6fae8be20..234a879f4 100644 --- a/x/btcstaking/types/btc_slashing_tx.go +++ b/x/btcstaking/types/btc_slashing_tx.go @@ -247,44 +247,80 @@ func (tx *BTCSlashingTx) EncVerifyAdaptorSignatures( } +// findFPIdxInWitness returns the index of the finality provider's signature +// in the witness stack of 1-out-of-n multisig from finality providers +// Note: the signatures are sorted in reverse lexical order since the PKs +// in the staking script are sorted in lexical order and BTC script execution +// is stack based +func findFPIdxInWitness(fpSK *btcec.PrivateKey, fpBTCPKs []bbn.BIP340PubKey) (int, error) { + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpSK.PubKey()) + sortedFPBTCPKList := bbn.SortBIP340PKs(fpBTCPKs) + for i, pk := range sortedFPBTCPKList { + if pk.Equals(fpBTCPK) { + return i, nil + } + } + return 0, fmt.Errorf("the given finality provider's PK is not found in the BTC delegation") +} + +// BuildSlashingTxWithWitness builds the witness for the slashing tx, including +// - a (covenant_quorum, covenant_committee_size) multisig from covenant committee +// - a (1, num_restaked_finality_providers) multisig from the slashed finality provider +// - 1 Schnorr signature from the staker func (tx *BTCSlashingTx) BuildSlashingTxWithWitness( fpSK *btcec.PrivateKey, + fpBTCPKs []bbn.BIP340PubKey, fundingMsgTx *wire.MsgTx, outputIdx uint32, delegatorSig *bbn.BIP340Signature, covenantSigs []*asig.AdaptorSignature, slashingPathSpendInfo *btcstaking.SpendInfo, ) (*wire.MsgTx, error) { - fpSig, err := tx.Sign(fundingMsgTx, outputIdx, slashingPathSpendInfo.GetPkScriptPath(), fpSK) - if err != nil { - return nil, fmt.Errorf("failed to sign slashing tx for the finality provider: %w", err) - } - + /* + construct covenant committee's part of witness, i.e., + a quorum number of covenant Schnorr signatures + */ // decrypt covenant adaptor signature to Schnorr signature using finality provider's SK, // then marshal decKey, err := asig.NewDecyptionKeyFromBTCSK(fpSK) if err != nil { return nil, fmt.Errorf("failed to get decryption key from BTC SK: %w", err) } - - var covSigs []*schnorr.Signature - for _, covenantSig := range covenantSigs { + // decrypt each covenant adaptor signature to Schnorr signature + covSigs := make([]*schnorr.Signature, len(covenantSigs)) + for i, covenantSig := range covenantSigs { if covenantSig != nil { - covSigs = append(covSigs, covenantSig.Decrypt(decKey)) + covSigs[i] = covenantSig.Decrypt(decKey) } else { - covSigs = append(covSigs, nil) + covSigs[i] = nil } } + /* + construct finality providers' part of witness, i.e., + 1 out of numRestakedFPs signature + */ + fpIdxInWitness, err := findFPIdxInWitness(fpSK, fpBTCPKs) + if err != nil { + return nil, err + } + fpSigs := make([]*schnorr.Signature, len(fpBTCPKs)) + fpSig, err := tx.Sign(fundingMsgTx, outputIdx, slashingPathSpendInfo.GetPkScriptPath(), fpSK) + if err != nil { + return nil, fmt.Errorf("failed to sign slashing tx for the finality provider: %w", err) + } + fpSigs[fpIdxInWitness] = fpSig.MustToBTCSig() + // construct witness witness, err := slashingPathSpendInfo.CreateSlashingPathWitness( covSigs, - []*schnorr.Signature{fpSig.MustToBTCSig()}, // TODO: work with restaking + fpSigs, delegatorSig.MustToBTCSig(), ) if err != nil { return nil, err } + // add witness to slashing tx slashingMsgTxWithWitness, err := tx.ToMsgTx() if err != nil { diff --git a/x/btcstaking/types/btc_slashing_tx_test.go b/x/btcstaking/types/btc_slashing_tx_test.go index 68c2ecee3..1db74328f 100644 --- a/x/btcstaking/types/btc_slashing_tx_test.go +++ b/x/btcstaking/types/btc_slashing_tx_test.go @@ -5,15 +5,115 @@ import ( "testing" sdkmath "cosmossdk.io/math" + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" btctest "github.com/babylonchain/babylon/testutil/bitcoin" "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/stretchr/testify/require" ) +// FuzzSlashingTx_VerifySigAndASig ensures properly generated adaptor signatures and +// the corresponding Schnorr signatures can be verified as valid +func FuzzSlashingTx_VerifySigAndASig(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + var ( + stakingValue = int64(2 * 10e8) + stakingTimeBlocks = uint16(5) + net = &chaincfg.SimNetParams + ) + + // slashing address and key pairs + slashingAddress, err := datagen.GenRandomBTCAddress(r, net) + require.NoError(t, err) + // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. + // NOTE - if the rate is higher or lower, it may produce slashing or change outputs + // with value below the dust threshold, causing test failure. + // Our goal is not to test failure due to such extreme cases here; + // this is already covered in FuzzGeneratingValidStakingSlashingTx + slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + + // restaked to a random number of finality providers + numRestakedFPs := int(datagen.RandomInt(r, 10) + 1) + fpSKs, fpPKs, err := datagen.GenRandomBTCKeyPairs(r, numRestakedFPs) + require.NoError(t, err) + + // use a random fp SK/PK + fpIdx := int(datagen.RandomInt(r, numRestakedFPs)) + fpSK, fpPK := fpSKs[fpIdx], fpPKs[fpIdx] + decKey, err := asig.NewDecyptionKeyFromBTCSK(fpSK) + require.NoError(t, err) + encKey, err := asig.NewEncryptionKeyFromBTCPK(fpPK) + require.NoError(t, err) + + delSK, _, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + // (3, 5) covenant committee + covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5) + require.NoError(t, err) + covenantQuorum := uint32(3) + slashingChangeLockTime := uint16(101) + + // use a random covenant SK/PK + covIdx := int(datagen.RandomInt(r, 5)) + covSK, covPK := covenantSKs[covIdx], covenantPKs[covIdx] + + // generate staking/slashing tx + testStakingInfo := datagen.GenBTCStakingSlashingInfo( + r, + t, + net, + delSK, + fpPKs, + covenantPKs, + covenantQuorum, + stakingTimeBlocks, + stakingValue, + slashingAddress.EncodeAddress(), + slashingRate, + slashingChangeLockTime, + ) + + stakingTx := testStakingInfo.StakingTx + slashingTx := testStakingInfo.SlashingTx + + slashingSpendInfo, err := testStakingInfo.StakingInfo.SlashingPathSpendInfo() + require.NoError(t, err) + slashingPkScriptPath := slashingSpendInfo.GetPkScriptPath() + + // ensure covenant adaptor signature can be correctly generated and verified + covASig, err := slashingTx.EncSign(stakingTx, 0, slashingPkScriptPath, covSK, encKey) + require.NoError(t, err) + err = slashingTx.EncVerifyAdaptorSignature( + testStakingInfo.StakingInfo.GetPkScript(), + testStakingInfo.StakingInfo.StakingOutput.Value, + slashingPkScriptPath, + covPK, + encKey, + covASig, + ) + require.NoError(t, err) + + // decrypt covenant adaptor signature and ensure the resulting Schnorr signature + // can be verified + covSig := covASig.Decrypt(decKey) + err = slashingTx.VerifySignature( + testStakingInfo.StakingInfo.GetPkScript(), + testStakingInfo.StakingInfo.StakingOutput.Value, + slashingPkScriptPath, + covPK, + bbn.NewBIP340SignatureFromBTCSig(covSig), + ) + require.NoError(t, err) + }) +} + func FuzzSlashingTxWithWitness(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) @@ -25,7 +125,7 @@ func FuzzSlashingTxWithWitness(f *testing.F) { net = &chaincfg.SimNetParams ) - // slashing address and key paris + // slashing address and key pairs slashingAddress, err := datagen.GenRandomBTCAddress(r, net) require.NoError(t, err) // Generate a slashing rate in the range [0.1, 0.50] i.e., 10-50%. @@ -35,13 +135,24 @@ func FuzzSlashingTxWithWitness(f *testing.F) { // this is already covered in FuzzGeneratingValidStakingSlashingTx slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) - // TODO: test restaking - fpSK, fpPK, err := datagen.GenRandomBTCKeyPair(r) + // restaked to a random number of finality providers + numRestakedFPs := int(datagen.RandomInt(r, 10) + 1) + fpSKs, fpPKs, err := datagen.GenRandomBTCKeyPairs(r, numRestakedFPs) + require.NoError(t, err) + fpBTCPKs := bbn.NewBIP340PKsFromBTCPKs(fpPKs) + + // a random finality provider gets slashed + fpIdx := int(datagen.RandomInt(r, numRestakedFPs)) + fpSK, fpPK := fpSKs[fpIdx], fpPKs[fpIdx] + encKey, err := asig.NewEncryptionKeyFromBTCPK(fpPK) + require.NoError(t, err) + decKey, err := asig.NewDecyptionKeyFromBTCSK(fpSK) require.NoError(t, err) delSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) + // (3, 5) covenant committee covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5) require.NoError(t, err) covenantQuorum := uint32(3) @@ -57,7 +168,7 @@ func FuzzSlashingTxWithWitness(f *testing.F) { t, net, delSK, - []*btcec.PublicKey{fpPK}, + fpPKs, covenantPKs, covenantQuorum, stakingTimeBlocks, @@ -74,24 +185,49 @@ func FuzzSlashingTxWithWitness(f *testing.F) { require.NoError(t, err) slashingPkScriptPath := slashingSpendInfo.GetPkScriptPath() - // sign slashing tx + // delegator signs slashing tx delSig, err := slashingTx.Sign(stakingMsgTx, 0, slashingPkScriptPath, delSK) require.NoError(t, err) + // get covenant Schnorr signatures covenantSigs, err := datagen.GenCovenantAdaptorSigs( covenantSKs, - []*btcec.PublicKey{fpPK}, + fpPKs, stakingMsgTx, slashingPkScriptPath, slashingTx, ) require.NoError(t, err) - - covSigs, err := types.GetOrderedCovenantSignatures(0, covenantSigs, &bsParams) + covSigsForFP, err := types.GetOrderedCovenantSignatures(fpIdx, covenantSigs, &bsParams) require.NoError(t, err) + // ensure all covenant signatures encrypted by the slashed + // finality provider's PK are verified + orderedCovenantPKs := bbn.SortBIP340PKs(bsParams.CovenantPks) + for i := range covSigsForFP { + err := slashingTx.EncVerifyAdaptorSignature( + testStakingInfo.StakingInfo.StakingOutput.PkScript, + testStakingInfo.StakingInfo.StakingOutput.Value, + slashingPkScriptPath, + orderedCovenantPKs[i].MustToBTCPK(), + encKey, + covSigsForFP[i], + ) + require.NoError(t, err, "verifying covenant adaptor sig at %d", i) + + covSchnorrSig := covSigsForFP[i].Decrypt(decKey) + err = slashingTx.VerifySignature( + testStakingInfo.StakingInfo.StakingOutput.PkScript, + testStakingInfo.StakingInfo.StakingOutput.Value, + slashingPkScriptPath, + orderedCovenantPKs[i].MustToBTCPK(), + bbn.NewBIP340SignatureFromBTCSig(covSchnorrSig), + ) + require.NoError(t, err, "verifying covenant Schnorr sig at %d", i) + } + // create slashing tx with witness - slashingMsgTxWithWitness, err := slashingTx.BuildSlashingTxWithWitness(fpSK, stakingMsgTx, 0, delSig, covSigs, slashingSpendInfo) + slashingMsgTxWithWitness, err := slashingTx.BuildSlashingTxWithWitness(fpSK, fpBTCPKs, stakingMsgTx, 0, delSig, covSigsForFP, slashingSpendInfo) require.NoError(t, err) // verify slashing tx with witness diff --git a/x/btcstaking/types/btc_undelegation_test.go b/x/btcstaking/types/btc_undelegation_test.go index 8b62027ed..88e16f081 100644 --- a/x/btcstaking/types/btc_undelegation_test.go +++ b/x/btcstaking/types/btc_undelegation_test.go @@ -5,13 +5,12 @@ import ( "testing" sdkmath "cosmossdk.io/math" + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" btctest "github.com/babylonchain/babylon/testutil/bitcoin" "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" ) @@ -25,14 +24,28 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { delSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fpSK, fpPK, err := datagen.GenRandomBTCKeyPair(r) + // restaked to a random number of finality providers + numRestakedFPs := int(datagen.RandomInt(r, 10) + 1) + fpSKs, fpPKs, err := datagen.GenRandomBTCKeyPairs(r, numRestakedFPs) + fpBTCPKs := bbn.NewBIP340PKsFromBTCPKs(fpPKs) + require.NoError(t, err) + + // a random finality provider gets slashed + slashedFPIdx := int(datagen.RandomInt(r, numRestakedFPs)) + fpSK, fpPK := fpSKs[slashedFPIdx], fpPKs[slashedFPIdx] + decKey, err := asig.NewDecyptionKeyFromBTCSK(fpSK) + require.NoError(t, err) + encKey, err := asig.NewEncryptionKeyFromBTCPK(fpPK) require.NoError(t, err) - fpPKList := []*btcec.PublicKey{fpPK} // (3, 5) covenant committee covenantSKs, covenantPKs, err := datagen.GenRandomBTCKeyPairs(r, 5) require.NoError(t, err) covenantQuorum := uint32(3) + bsParams := &types.Params{ + CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), + CovenantQuorum: covenantQuorum, + } stakingTimeBlocks := uint16(5) stakingValue := int64(2 * 10e8) @@ -41,14 +54,13 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) unbondingTime := uint16(100) + 1 - unbondingValue := stakingValue - 1000 slashingChangeLockTime := unbondingTime // construct the BTC delegation with everything btcDel, err := datagen.GenRandomBTCDelegation( r, t, - bbn.NewBIP340PKsFromBTCPKs(fpPKList), + fpBTCPKs, delSK, covenantSKs, covenantQuorum, @@ -61,56 +73,38 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { ) require.NoError(t, err) - stakingTxHash := btcDel.MustGetStakingTxHash() - - testInfo := datagen.GenBTCUnbondingSlashingInfo( - r, - t, - net, - delSK, - fpPKList, - covenantPKs, - covenantQuorum, - wire.NewOutPoint(&stakingTxHash, 0), - unbondingTime, - unbondingValue, - slashingAddress.EncodeAddress(), - slashingRate, - slashingChangeLockTime, - ) + unbondingInfo, err := btcDel.GetUnbondingInfo(bsParams, net) require.NoError(t, err) - // delegator signs the unbonding slashing tx - delSlashingTxSig, err := testInfo.GenDelSlashingTxSig(delSK) + // TESTING + orderedCovenantPKs := bbn.SortBIP340PKs(bsParams.CovenantPks) + covSigsForFP, err := types.GetOrderedCovenantSignatures(slashedFPIdx, btcDel.BtcUndelegation.CovenantSlashingSigs, bsParams) require.NoError(t, err) - - unbondingTxBytes, err := bbn.SerializeBTCTx(testInfo.UnbondingTx) + slashingSpendInfo, err := unbondingInfo.SlashingPathSpendInfo() require.NoError(t, err) - - // spend info of the unbonding slashing tx - unbondingSlashingSpendInfo, err := testInfo.UnbondingInfo.SlashingPathSpendInfo() - require.NoError(t, err) - // covenant signs (using adaptor signature) the slashing tx - covenantSigs, err := datagen.GenCovenantAdaptorSigs( - covenantSKs, - []*btcec.PublicKey{fpPK}, - testInfo.UnbondingTx, - unbondingSlashingSpendInfo.GetPkScriptPath(), - testInfo.SlashingTx, - ) - require.NoError(t, err) - btcDel.BtcUndelegation = &types.BTCUndelegation{ - UnbondingTx: unbondingTxBytes, - SlashingTx: testInfo.SlashingTx, - DelegatorUnbondingSig: nil, // not relevant here - DelegatorSlashingSig: delSlashingTxSig, - CovenantSlashingSigs: covenantSigs, - CovenantUnbondingSigList: nil, // not relevant here - } - - bsParams := &types.Params{ - CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), - CovenantQuorum: covenantQuorum, + for i := range covSigsForFP { + if covSigsForFP[i] == nil { + continue + } + err := btcDel.BtcUndelegation.SlashingTx.EncVerifyAdaptorSignature( + unbondingInfo.UnbondingOutput.PkScript, + unbondingInfo.UnbondingOutput.Value, + slashingSpendInfo.GetPkScriptPath(), + orderedCovenantPKs[i].MustToBTCPK(), + encKey, + covSigsForFP[i], + ) + require.NoError(t, err) + + covSig := covSigsForFP[i].Decrypt(decKey) + err = btcDel.BtcUndelegation.SlashingTx.VerifySignature( + unbondingInfo.UnbondingOutput.PkScript, + unbondingInfo.UnbondingOutput.Value, + slashingSpendInfo.GetPkScriptPath(), + orderedCovenantPKs[i].MustToBTCPK(), + bbn.NewBIP340SignatureFromBTCSig(covSig), + ) + require.NoError(t, err) } // build slashing tx with witness for spending the unbonding tx @@ -118,6 +112,6 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { require.NoError(t, err) // assert the execution - btctest.AssertSlashingTxExecution(t, testInfo.UnbondingInfo.UnbondingOutput, unbondingSlashingTxWithWitness) + btctest.AssertSlashingTxExecution(t, unbondingInfo.UnbondingOutput, unbondingSlashingTxWithWitness) }) } diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 971fefeeb..bea07a683 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -71,8 +71,10 @@ func NewSignatureInfo(pk *bbn.BIP340PubKey, sig *bbn.BIP340Signature) *Signature // the order of covenant adaptor signatures will follow the reverse lexicographical order // of signing public keys, in order to be used as tx witness func GetOrderedCovenantSignatures(fpIdx int, covSigsList []*CovenantAdaptorSignatures, params *Params) ([]*asig.AdaptorSignature, error) { - // construct the map where key is the covenant PK and value is this - // covenant member's adaptor signature encrypted by the given finality provider's PK + // construct the map where + // - key is the covenant PK, and + // - value is this covenant member's adaptor signature encrypted + // by the given finality provider's PK covSigsMap := map[string]*asig.AdaptorSignature{} for _, covSigs := range covSigsList { // find the adaptor signature at the corresponding finality provider's index From 4a3691c08e87812faabe10b2774c46852a93df66 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 15 Mar 2024 11:26:09 +0100 Subject: [PATCH 051/119] New parameter to specify min value in unbonding output --- btcstaking/staking.go | 4 +- btcstaking/staking_test.go | 2 +- btcstaking/types.go | 8 +- proto/babylon/btcstaking/v1/params.proto | 11 +++ x/btcstaking/keeper/keeper_test.go | 4 +- x/btcstaking/keeper/msg_server.go | 13 ++- x/btcstaking/keeper/msg_server_test.go | 72 ++++++++++++++ x/btcstaking/types/genesis_test.go | 18 ++++ x/btcstaking/types/params.go | 8 +- x/btcstaking/types/params.pb.go | 117 ++++++++++++++++------- 10 files changed, 214 insertions(+), 43 deletions(-) diff --git a/btcstaking/staking.go b/btcstaking/staking.go index 47a224298..c9e91b662 100644 --- a/btcstaking/staking.go +++ b/btcstaking/staking.go @@ -44,7 +44,7 @@ func buildSlashingTxFromOutpoint( } // Validate slashing rate - if !IsSlashingRateValid(slashingRate) { + if !IsRateValid(slashingRate) { return nil, ErrInvalidSlashingRate } @@ -350,7 +350,7 @@ func CheckTransactions( } // Check if slashing rate is in the valid range (0,1) - if !IsSlashingRateValid(slashingRate) { + if !IsRateValid(slashingRate) { return ErrInvalidSlashingRate } diff --git a/btcstaking/staking_test.go b/btcstaking/staking_test.go index 1837bf719..2937157fd 100644 --- a/btcstaking/staking_test.go +++ b/btcstaking/staking_test.go @@ -155,7 +155,7 @@ func testSlashingTx( &chaincfg.MainNetParams, ) - if btcstaking.IsSlashingRateValid(slashingRate) { + if btcstaking.IsRateValid(slashingRate) { // If the slashing rate is valid i.e., in the range (0,1) with at most 2 decimal places, // it is still possible that the slashing transaction is invalid. The following checks will confirm that // slashing tx is not constructed if diff --git a/btcstaking/types.go b/btcstaking/types.go index 3de6a2bf3..022ec4901 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -473,15 +473,15 @@ func (i *UnbondingInfo) SlashingPathSpendInfo() (*SpendInfo, error) { return i.scriptHolder.scriptSpendInfoByName(i.slashingPathLeafHash) } -// IsSlashingRateValid checks if the given slashing rate is between the valid range i.e., (0,1) with a precision of at most 2 decimal places. -func IsSlashingRateValid(slashingRate sdkmath.LegacyDec) bool { +// IsRateValid checks if the given rate is between the valid range i.e., (0,1) with a precision of at most 2 decimal places. +func IsRateValid(rate sdkmath.LegacyDec) bool { // Check if the slashing rate is between 0 and 1 - if slashingRate.LTE(sdkmath.LegacyZeroDec()) || slashingRate.GTE(sdkmath.LegacyOneDec()) { + if rate.LTE(sdkmath.LegacyZeroDec()) || rate.GTE(sdkmath.LegacyOneDec()) { return false } // Multiply by 100 to move the decimal places and check if precision is at most 2 decimal places - multipliedRate := slashingRate.Mul(sdkmath.LegacyNewDec(100)) + multipliedRate := rate.Mul(sdkmath.LegacyNewDec(100)) // Truncate the rate to remove decimal places truncatedRate := multipliedRate.TruncateDec() diff --git a/proto/babylon/btcstaking/v1/params.proto b/proto/babylon/btcstaking/v1/params.proto index b140adecc..66de0c17d 100644 --- a/proto/babylon/btcstaking/v1/params.proto +++ b/proto/babylon/btcstaking/v1/params.proto @@ -39,4 +39,15 @@ message Params { uint32 max_active_finality_providers = 7; // min_unbonding_time is the minimum time for unbonding transaction timelock in BTC blocks uint32 min_unbonding_time = 8; + + // min_unbonding_value is the minimum amount of BTC that are required in unbonding + // output, expressed as a fraction of staking output + // example: if min_unbonding_value=0.9, than unbonding output value + // must be at least 90% of staking output, for staking request to be considered + // valid + string min_unbonding_value = 9 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; } diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 5aa7a92c6..b22dc336f 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -96,6 +96,7 @@ func (h *Helper) GenAndApplyCustomParams( SlashingRate: sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2), MaxActiveFinalityProviders: 100, MinUnbondingTime: minUnbondingTime, + MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), }) h.NoError(err) return covenantSKs, covenantPKs @@ -140,6 +141,7 @@ func (h *Helper) CreateDelegationCustom( changeAddress string, stakingValue int64, stakingTime uint16, + unbondingValue int64, unbondingTime uint16, ) (string, *btcec.PrivateKey, *btcec.PublicKey, *types.MsgCreateBTCDelegation, error) { delSK, delPK, err := datagen.GenRandomBTCKeyPair(r) @@ -208,7 +210,6 @@ func (h *Helper) CreateDelegationCustom( stkTxHash := testStakingInfo.StakingTx.TxHash() stkOutputIdx := uint32(0) - unbondingValue := stakingValue - 1000 testUnbondingInfo := datagen.GenBTCUnbondingSlashingInfo( r, h.t, @@ -281,6 +282,7 @@ func (h *Helper) CreateDelegation( changeAddress, stakingValue, stakingTime, + stakingValue-1000, uint16(minUnbondingTime)+1, ) diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 60af18f3d..ed262aaf9 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -389,9 +389,9 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, types.ErrInvalidSlashingTx.Wrapf("invalid delegator signature: %v", err) } - // Check unbonding tx against staking tx. - // - that input points to the staking tx, staking output + // Check unbonding tx fees against staking tx. // - fee is larger than 0 + // - ubonding output value is is at leat `MinUnbondingValue` percent of staking output value if unbondingMsgTx.TxOut[0].Value >= stakingMsgTx.TxOut[newBTCDel.StakingOutputIdx].Value { // Note: we do not enfore any minimum fee for unbonding tx, we only require that it is larger than 0 // Given that unbonding tx must not be replacable and we do not allow sending it second time, it places @@ -401,6 +401,15 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding tx fee must be larger that 0") } + // this conversions must always succeed, as it is part of our params + minUnbondingRate := params.MinUnbondingValue.MustFloat64() + // Caluclate min unbonding output value based on staking output, use btc native multiplication + minUnbondingOutputValue := btcutil.Amount(stakingMsgTx.TxOut[newBTCDel.StakingOutputIdx].Value).MulF64(minUnbondingRate) + + if btcutil.Amount(unbondingMsgTx.TxOut[0].Value) < minUnbondingOutputValue { + return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingOutputValue) + } + // all good, add BTC undelegation newBTCDel.BtcUndelegation = &types.BTCUndelegation{ UnbondingTx: req.UnbondingTx, diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 72098155c..00285210c 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -649,6 +649,7 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { changeAddress.EncodeAddress(), stakingValue, 1000, + stakingValue-1000, tt.unbondingTimeInDelegation, ) if tt.err != nil { @@ -665,6 +666,77 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { } } +func TestMinimalUnbondingValue(t *testing.T) { + tests := []struct { + name string + stakingValue int64 + unbondingValueInDelegation int64 + err error + }{ + { + name: "successful delegation when unbonding value is >=80% of staking value", + stakingValue: 10000, + unbondingValueInDelegation: 8000, + err: nil, + }, + { + name: "failed delegation when unbonding value is <80% of staking value", + stakingValue: 10000, + unbondingValueInDelegation: 7999, + err: types.ErrInvalidUnbondingTx, + }, + { + name: "failed delegation when unbonding value >= stake value", + stakingValue: 10000, + unbondingValueInDelegation: 10000, + err: types.ErrInvalidUnbondingTx, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters, by default minimal unbonding value is 80% of staking value + _, _ = h.GenAndApplyParams(r) + + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) + + // generate and insert new finality provider + _, fpPK, _ := h.CreateFinalityProvider(r) + + // generate and insert new BTC delegation + stakingTxHash, _, _, _, err := h.CreateDelegationCustom( + r, + fpPK, + changeAddress.EncodeAddress(), + tt.stakingValue, + 1000, + tt.unbondingValueInDelegation, + 1000, + ) + if tt.err != nil { + require.Error(t, err) + require.True(t, errors.Is(err, tt.err)) + } else { + require.NoError(t, err) + // Retrieve delegation from keeper + delegation, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) + require.NoError(t, err) + require.NotNil(t, delegation) + } + }) + } +} + func createNDelegationsForFinalityProvider( r *rand.Rand, t *testing.T, diff --git a/x/btcstaking/types/genesis_test.go b/x/btcstaking/types/genesis_test.go index 00ee5d73d..258350c1d 100644 --- a/x/btcstaking/types/genesis_test.go +++ b/x/btcstaking/types/genesis_test.go @@ -31,6 +31,7 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), MaxActiveFinalityProviders: 100, + MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), }, }, valid: true, @@ -46,6 +47,23 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyZeroDec(), // invalid slashing rate MaxActiveFinalityProviders: 100, + MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), + }, + }, + valid: false, + }, + { + desc: "invalid unbonding value in genesis", + genState: &types.GenesisState{ + Params: types.Params{ + CovenantPks: types.DefaultParams().CovenantPks, + CovenantQuorum: types.DefaultParams().CovenantQuorum, + SlashingAddress: types.DefaultParams().SlashingAddress, + MinSlashingTxFeeSat: 500, + MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), + SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), + MaxActiveFinalityProviders: 100, + MinUnbondingValue: sdkmath.LegacyZeroDec(), }, }, valid: false, diff --git a/x/btcstaking/types/params.go b/x/btcstaking/types/params.go index 8e923fca7..877fc7a94 100644 --- a/x/btcstaking/types/params.go +++ b/x/btcstaking/types/params.go @@ -64,6 +64,8 @@ func DefaultParams() Params { // The default minimum unbonding time is 0, which effectively defaults to checkpoint // finalization timeout. MinUnbondingTime: 0, + // By default unbonding value is 0.8 + MinUnbondingValue: sdkmath.LegacyNewDecWithPrec(8, 1), // 8 * 10^{-1} = 0.8 } } @@ -138,10 +140,14 @@ func (p Params) Validate() error { return err } - if !btcstaking.IsSlashingRateValid(p.SlashingRate) { + if !btcstaking.IsRateValid(p.SlashingRate) { return btcstaking.ErrInvalidSlashingRate } + if !btcstaking.IsRateValid(p.MinUnbondingValue) { + return fmt.Errorf("minimum unbonding value is invalid. it should be fraction in range (0, 1) with at 2 decimal places precision") + } + if err := validateMaxActiveFinalityProviders(p.MaxActiveFinalityProviders); err != nil { return err } diff --git a/x/btcstaking/types/params.pb.go b/x/btcstaking/types/params.pb.go index 642dda4e6..670917443 100644 --- a/x/btcstaking/types/params.pb.go +++ b/x/btcstaking/types/params.pb.go @@ -50,6 +50,12 @@ type Params struct { MaxActiveFinalityProviders uint32 `protobuf:"varint,7,opt,name=max_active_finality_providers,json=maxActiveFinalityProviders,proto3" json:"max_active_finality_providers,omitempty"` // min_unbonding_time is the minimum time for unbonding transaction timelock in BTC blocks MinUnbondingTime uint32 `protobuf:"varint,8,opt,name=min_unbonding_time,json=minUnbondingTime,proto3" json:"min_unbonding_time,omitempty"` + // min_unbonding_value is the minimum amount of BTC that are required in unbonding + // output, expressed as a fraction of staking output + // example: if min_unbonding_value=0.9, than unbonding output value + // must be at least 90% of staking output, for staking request to be considered + // valid + MinUnbondingValue cosmossdk_io_math.LegacyDec `protobuf:"bytes,9,opt,name=min_unbonding_value,json=minUnbondingValue,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_unbonding_value"` } func (m *Params) Reset() { *m = Params{} } @@ -128,38 +134,39 @@ func init() { } var fileDescriptor_8d1392776a3e15b9 = []byte{ - // 483 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x6f, 0xd3, 0x3c, - 0x18, 0xc7, 0x93, 0xb7, 0x7d, 0x0b, 0x98, 0x8e, 0x8d, 0x00, 0x22, 0x14, 0x91, 0x56, 0xe3, 0x40, - 0x91, 0x20, 0xa1, 0x6c, 0xe2, 0xc0, 0xad, 0x05, 0x4d, 0x42, 0xec, 0x10, 0xd2, 0x81, 0x04, 0x17, - 0xcb, 0x71, 0xbc, 0xd4, 0x6a, 0x6d, 0x97, 0xd8, 0x89, 0x92, 0x6f, 0x01, 0x37, 0x8e, 0x7c, 0x08, - 0x3e, 0xc4, 0x8e, 0x13, 0x27, 0xb4, 0x43, 0x85, 0xda, 0x2f, 0x82, 0xe2, 0x24, 0x85, 0x1b, 0xdc, - 0xe2, 0xff, 0xf3, 0xf3, 0xcf, 0xf1, 0xe3, 0x07, 0xec, 0x87, 0x28, 0x2c, 0x16, 0x82, 0x7b, 0xa1, - 0xc2, 0x52, 0xa1, 0x39, 0xe5, 0xb1, 0x97, 0x8d, 0xbc, 0x25, 0x4a, 0x10, 0x93, 0xee, 0x32, 0x11, - 0x4a, 0x58, 0xb7, 0x6a, 0xc6, 0xfd, 0xcd, 0xb8, 0xd9, 0xa8, 0x77, 0x33, 0x16, 0xb1, 0xd0, 0x84, - 0x57, 0x7e, 0x55, 0x70, 0xef, 0x0e, 0x16, 0x92, 0x09, 0x09, 0xab, 0x42, 0xb5, 0xa8, 0x4a, 0xfb, - 0x9f, 0xdb, 0xa0, 0xe3, 0x6b, 0xb1, 0xf5, 0x1e, 0x74, 0xb1, 0xc8, 0x08, 0x47, 0x5c, 0xc1, 0xe5, - 0x5c, 0xda, 0xe6, 0xa0, 0x35, 0xec, 0x4e, 0x9e, 0x5d, 0xac, 0xfa, 0x4f, 0x63, 0xaa, 0x66, 0x69, - 0xe8, 0x62, 0xc1, 0xbc, 0xfa, 0x5c, 0x3c, 0x43, 0x94, 0x37, 0x0b, 0x4f, 0x15, 0x4b, 0x22, 0xdd, - 0xc9, 0x2b, 0xff, 0xe0, 0xf0, 0x89, 0x9f, 0x86, 0xaf, 0x49, 0x11, 0x5c, 0x6d, 0x5c, 0xfe, 0x5c, - 0x5a, 0x0f, 0xc0, 0xee, 0x56, 0xfd, 0x31, 0x15, 0x49, 0xca, 0xec, 0xff, 0x06, 0xe6, 0x70, 0x27, - 0xb8, 0xd6, 0xc4, 0x6f, 0x74, 0x6a, 0x3d, 0x04, 0x7b, 0x72, 0x81, 0xe4, 0x8c, 0xf2, 0x18, 0xa2, - 0x28, 0x4a, 0x88, 0x94, 0x76, 0x6b, 0x60, 0x0e, 0xaf, 0x04, 0xbb, 0x4d, 0x3e, 0xae, 0x62, 0xeb, - 0x10, 0xdc, 0x66, 0x94, 0xc3, 0x2d, 0xae, 0x72, 0x78, 0x4a, 0x08, 0x94, 0x48, 0xd9, 0xed, 0x81, - 0x39, 0x6c, 0x05, 0x37, 0x18, 0xe5, 0xd3, 0xba, 0x7a, 0x92, 0x1f, 0x11, 0x32, 0x45, 0xca, 0x9a, - 0x82, 0x32, 0x86, 0x58, 0x30, 0x46, 0xa5, 0xa4, 0x82, 0xc3, 0x04, 0x29, 0x62, 0xff, 0x5f, 0x9e, - 0x31, 0xb9, 0x7f, 0xb6, 0xea, 0x1b, 0x17, 0xab, 0xfe, 0xdd, 0xaa, 0x45, 0x32, 0x9a, 0xbb, 0x54, - 0x78, 0x0c, 0xa9, 0x99, 0x7b, 0x4c, 0x62, 0x84, 0x8b, 0x97, 0x04, 0x07, 0xd7, 0x19, 0xe5, 0x2f, - 0xb6, 0xdb, 0x03, 0xa4, 0x88, 0xf5, 0x0e, 0xec, 0x6c, 0x7f, 0x43, 0xeb, 0x3a, 0x5a, 0x37, 0xfa, - 0x07, 0xdd, 0xf7, 0x6f, 0x8f, 0x41, 0xfd, 0x20, 0xa5, 0xbc, 0xdb, 0x78, 0xb4, 0x77, 0x0c, 0xee, - 0x31, 0x94, 0x43, 0x84, 0x15, 0xcd, 0x08, 0x3c, 0xa5, 0x1c, 0x2d, 0xa8, 0x2a, 0xca, 0x67, 0xcc, - 0x68, 0x44, 0x12, 0x69, 0x5f, 0xd2, 0x4d, 0xec, 0x31, 0x94, 0x8f, 0x35, 0x73, 0x54, 0x23, 0x7e, - 0x43, 0x58, 0x8f, 0x80, 0x55, 0xde, 0x37, 0xe5, 0xa1, 0xe0, 0x91, 0x6e, 0x13, 0x65, 0xc4, 0xbe, - 0xac, 0xf7, 0xed, 0x31, 0xca, 0xdf, 0x36, 0x85, 0x13, 0xca, 0xc8, 0xf3, 0xf6, 0x97, 0xaf, 0x7d, - 0x63, 0x72, 0x7c, 0xb6, 0x76, 0xcc, 0xf3, 0xb5, 0x63, 0xfe, 0x5c, 0x3b, 0xe6, 0xa7, 0x8d, 0x63, - 0x9c, 0x6f, 0x1c, 0xe3, 0xc7, 0xc6, 0x31, 0x3e, 0xfc, 0x75, 0x10, 0xf2, 0x3f, 0x67, 0x56, 0x4f, - 0x45, 0xd8, 0xd1, 0x83, 0x76, 0xf0, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x9a, 0xce, 0xa4, 0xfd, 0xd6, - 0x02, 0x00, 0x00, + // 505 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0x80, 0x1b, 0x5a, 0x0a, 0x33, 0x1d, 0xdb, 0x0c, 0x88, 0x50, 0x44, 0x5a, 0x8d, 0x03, 0x45, + 0x82, 0x84, 0xb2, 0x89, 0x03, 0xb7, 0x16, 0x34, 0x09, 0xb1, 0x43, 0x49, 0xc7, 0x24, 0xb8, 0x58, + 0x2f, 0xa9, 0x97, 0x5a, 0xad, 0xed, 0x12, 0x3b, 0x51, 0xfb, 0x2f, 0x38, 0x72, 0xe4, 0x47, 0xf0, + 0x23, 0x76, 0x9c, 0x38, 0xa1, 0x1d, 0x2a, 0xd4, 0xfe, 0x05, 0x7e, 0x00, 0x8a, 0xd3, 0x74, 0xbb, + 0x81, 0x76, 0x8b, 0xdf, 0xfb, 0xfc, 0xbd, 0xf8, 0xf9, 0x19, 0xed, 0x06, 0x10, 0xcc, 0xc6, 0x52, + 0x78, 0x81, 0x0e, 0x95, 0x86, 0x11, 0x13, 0x91, 0x97, 0xb6, 0xbd, 0x09, 0xc4, 0xc0, 0x95, 0x3b, + 0x89, 0xa5, 0x96, 0xf8, 0xde, 0x8a, 0x71, 0x2f, 0x18, 0x37, 0x6d, 0xd7, 0xef, 0x46, 0x32, 0x92, + 0x86, 0xf0, 0xb2, 0xaf, 0x1c, 0xae, 0x3f, 0x08, 0xa5, 0xe2, 0x52, 0x91, 0x3c, 0x91, 0x2f, 0xf2, + 0xd4, 0xee, 0x9f, 0x0a, 0xaa, 0xf6, 0x8c, 0x18, 0x7f, 0x42, 0xb5, 0x50, 0xa6, 0x54, 0x80, 0xd0, + 0x64, 0x32, 0x52, 0xb6, 0xd5, 0x2c, 0xb7, 0x6a, 0xdd, 0x57, 0xe7, 0xf3, 0xc6, 0xcb, 0x88, 0xe9, + 0x61, 0x12, 0xb8, 0xa1, 0xe4, 0xde, 0xaa, 0x6e, 0x38, 0x04, 0x26, 0x8a, 0x85, 0xa7, 0x67, 0x13, + 0xaa, 0xdc, 0xee, 0xbb, 0xde, 0xde, 0xfe, 0x8b, 0x5e, 0x12, 0xbc, 0xa7, 0x33, 0xff, 0x56, 0xe1, + 0xea, 0x8d, 0x14, 0x7e, 0x82, 0xb6, 0xd6, 0xea, 0x2f, 0x89, 0x8c, 0x13, 0x6e, 0x5f, 0x6b, 0x5a, + 0xad, 0x4d, 0xff, 0x76, 0x11, 0xfe, 0x60, 0xa2, 0xf8, 0x29, 0xda, 0x56, 0x63, 0x50, 0x43, 0x26, + 0x22, 0x02, 0x83, 0x41, 0x4c, 0x95, 0xb2, 0xcb, 0x4d, 0xab, 0xb5, 0xe1, 0x6f, 0x15, 0xf1, 0x4e, + 0x1e, 0xc6, 0xfb, 0xe8, 0x3e, 0x67, 0x82, 0xac, 0x71, 0x3d, 0x25, 0x27, 0x94, 0x12, 0x05, 0xda, + 0xae, 0x34, 0xad, 0x56, 0xd9, 0xbf, 0xc3, 0x99, 0xe8, 0xaf, 0xb2, 0x47, 0xd3, 0x03, 0x4a, 0xfb, + 0xa0, 0x71, 0x1f, 0x65, 0x61, 0x12, 0x4a, 0xce, 0x99, 0x52, 0x4c, 0x0a, 0x12, 0x83, 0xa6, 0xf6, + 0xf5, 0xac, 0x46, 0xf7, 0xf1, 0xe9, 0xbc, 0x51, 0x3a, 0x9f, 0x37, 0x1e, 0xe6, 0x2d, 0x52, 0x83, + 0x91, 0xcb, 0xa4, 0xc7, 0x41, 0x0f, 0xdd, 0x43, 0x1a, 0x41, 0x38, 0x7b, 0x4b, 0x43, 0x7f, 0x87, + 0x33, 0xf1, 0x66, 0xbd, 0xdd, 0x07, 0x4d, 0xf1, 0x31, 0xda, 0x5c, 0xff, 0x86, 0xd1, 0x55, 0x8d, + 0xae, 0xfd, 0x1f, 0xba, 0x9f, 0x3f, 0x9e, 0xa3, 0xd5, 0x85, 0x64, 0xf2, 0x5a, 0xe1, 0x31, 0xde, + 0x0e, 0x7a, 0xc4, 0x61, 0x4a, 0x20, 0xd4, 0x2c, 0xa5, 0xe4, 0x84, 0x09, 0x18, 0x33, 0x3d, 0xcb, + 0xae, 0x31, 0x65, 0x03, 0x1a, 0x2b, 0xfb, 0x86, 0x69, 0x62, 0x9d, 0xc3, 0xb4, 0x63, 0x98, 0x83, + 0x15, 0xd2, 0x2b, 0x08, 0xfc, 0x0c, 0xe1, 0xec, 0xbc, 0x89, 0x08, 0xa4, 0x18, 0x98, 0x36, 0x31, + 0x4e, 0xed, 0x9b, 0x66, 0xdf, 0x36, 0x67, 0xe2, 0x63, 0x91, 0x38, 0x62, 0x9c, 0x62, 0xc8, 0xbb, + 0x73, 0x41, 0xa7, 0x30, 0x4e, 0xa8, 0xbd, 0x71, 0xd5, 0xe3, 0xec, 0x5c, 0xae, 0x70, 0x9c, 0xb9, + 0x5e, 0x57, 0xbe, 0x7d, 0x6f, 0x94, 0xba, 0x87, 0xa7, 0x0b, 0xc7, 0x3a, 0x5b, 0x38, 0xd6, 0xef, + 0x85, 0x63, 0x7d, 0x5d, 0x3a, 0xa5, 0xb3, 0xa5, 0x53, 0xfa, 0xb5, 0x74, 0x4a, 0x9f, 0xff, 0x39, + 0x6b, 0xd3, 0xcb, 0xcf, 0xc2, 0x0c, 0x5e, 0x50, 0x35, 0xb3, 0xbc, 0xf7, 0x37, 0x00, 0x00, 0xff, + 0xff, 0xec, 0x97, 0x30, 0x5b, 0x39, 0x03, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -182,6 +189,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size := m.MinUnbondingValue.Size() + i -= size + if _, err := m.MinUnbondingValue.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a if m.MinUnbondingTime != 0 { i = encodeVarintParams(dAtA, i, uint64(m.MinUnbondingTime)) i-- @@ -289,6 +306,8 @@ func (m *Params) Size() (n int) { if m.MinUnbondingTime != 0 { n += 1 + sovParams(uint64(m.MinUnbondingTime)) } + l = m.MinUnbondingValue.Size() + n += 1 + l + sovParams(uint64(l)) return n } @@ -538,6 +557,40 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinUnbondingValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinUnbondingValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) From 0b43744e08ee1175e2817b681fa3da077c101c21 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 15 Mar 2024 11:31:39 +0100 Subject: [PATCH 052/119] Change param name --- proto/babylon/btcstaking/v1/params.proto | 6 +- x/btcstaking/keeper/keeper_test.go | 2 +- x/btcstaking/keeper/msg_server.go | 2 +- x/btcstaking/keeper/msg_server_test.go | 2 +- x/btcstaking/types/genesis_test.go | 6 +- x/btcstaking/types/params.go | 4 +- x/btcstaking/types/params.pb.go | 82 ++++++++++++------------ 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/proto/babylon/btcstaking/v1/params.proto b/proto/babylon/btcstaking/v1/params.proto index 66de0c17d..555a0481e 100644 --- a/proto/babylon/btcstaking/v1/params.proto +++ b/proto/babylon/btcstaking/v1/params.proto @@ -40,12 +40,12 @@ message Params { // min_unbonding_time is the minimum time for unbonding transaction timelock in BTC blocks uint32 min_unbonding_time = 8; - // min_unbonding_value is the minimum amount of BTC that are required in unbonding + // min_unbonding_rate is the minimum amount of BTC that are required in unbonding // output, expressed as a fraction of staking output - // example: if min_unbonding_value=0.9, than unbonding output value + // example: if min_unbonding_rate=0.9, than unbonding output value // must be at least 90% of staking output, for staking request to be considered // valid - string min_unbonding_value = 9 [ + string min_unbonding_rate = 9 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", (gogoproto.nullable) = false diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index b22dc336f..8075ad97b 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -96,7 +96,7 @@ func (h *Helper) GenAndApplyCustomParams( SlashingRate: sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2), MaxActiveFinalityProviders: 100, MinUnbondingTime: minUnbondingTime, - MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), }) h.NoError(err) return covenantSKs, covenantPKs diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index ed262aaf9..40b7f48ae 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -402,7 +402,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } // this conversions must always succeed, as it is part of our params - minUnbondingRate := params.MinUnbondingValue.MustFloat64() + minUnbondingRate := params.MinUnbondingRate.MustFloat64() // Caluclate min unbonding output value based on staking output, use btc native multiplication minUnbondingOutputValue := btcutil.Amount(stakingMsgTx.TxOut[newBTCDel.StakingOutputIdx].Value).MulF64(minUnbondingRate) diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 00285210c..a9248dc86 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -666,7 +666,7 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { } } -func TestMinimalUnbondingValue(t *testing.T) { +func TestMinimalUnbondingRate(t *testing.T) { tests := []struct { name string stakingValue int64 diff --git a/x/btcstaking/types/genesis_test.go b/x/btcstaking/types/genesis_test.go index 258350c1d..857ed2f72 100644 --- a/x/btcstaking/types/genesis_test.go +++ b/x/btcstaking/types/genesis_test.go @@ -31,7 +31,7 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), MaxActiveFinalityProviders: 100, - MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), }, }, valid: true, @@ -47,7 +47,7 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyZeroDec(), // invalid slashing rate MaxActiveFinalityProviders: 100, - MinUnbondingValue: sdkmath.LegacyMustNewDecFromStr("0.8"), + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), }, }, valid: false, @@ -63,7 +63,7 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), MaxActiveFinalityProviders: 100, - MinUnbondingValue: sdkmath.LegacyZeroDec(), + MinUnbondingRate: sdkmath.LegacyZeroDec(), }, }, valid: false, diff --git a/x/btcstaking/types/params.go b/x/btcstaking/types/params.go index 877fc7a94..cd1835a46 100644 --- a/x/btcstaking/types/params.go +++ b/x/btcstaking/types/params.go @@ -65,7 +65,7 @@ func DefaultParams() Params { // finalization timeout. MinUnbondingTime: 0, // By default unbonding value is 0.8 - MinUnbondingValue: sdkmath.LegacyNewDecWithPrec(8, 1), // 8 * 10^{-1} = 0.8 + MinUnbondingRate: sdkmath.LegacyNewDecWithPrec(8, 1), // 8 * 10^{-1} = 0.8 } } @@ -144,7 +144,7 @@ func (p Params) Validate() error { return btcstaking.ErrInvalidSlashingRate } - if !btcstaking.IsRateValid(p.MinUnbondingValue) { + if !btcstaking.IsRateValid(p.MinUnbondingRate) { return fmt.Errorf("minimum unbonding value is invalid. it should be fraction in range (0, 1) with at 2 decimal places precision") } diff --git a/x/btcstaking/types/params.pb.go b/x/btcstaking/types/params.pb.go index 670917443..bf4cc12f2 100644 --- a/x/btcstaking/types/params.pb.go +++ b/x/btcstaking/types/params.pb.go @@ -50,12 +50,12 @@ type Params struct { MaxActiveFinalityProviders uint32 `protobuf:"varint,7,opt,name=max_active_finality_providers,json=maxActiveFinalityProviders,proto3" json:"max_active_finality_providers,omitempty"` // min_unbonding_time is the minimum time for unbonding transaction timelock in BTC blocks MinUnbondingTime uint32 `protobuf:"varint,8,opt,name=min_unbonding_time,json=minUnbondingTime,proto3" json:"min_unbonding_time,omitempty"` - // min_unbonding_value is the minimum amount of BTC that are required in unbonding + // min_unbonding_rate is the minimum amount of BTC that are required in unbonding // output, expressed as a fraction of staking output - // example: if min_unbonding_value=0.9, than unbonding output value + // example: if min_unbonding_rate=0.9, than unbonding output value // must be at least 90% of staking output, for staking request to be considered // valid - MinUnbondingValue cosmossdk_io_math.LegacyDec `protobuf:"bytes,9,opt,name=min_unbonding_value,json=minUnbondingValue,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_unbonding_value"` + MinUnbondingRate cosmossdk_io_math.LegacyDec `protobuf:"bytes,9,opt,name=min_unbonding_rate,json=minUnbondingRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_unbonding_rate"` } func (m *Params) Reset() { *m = Params{} } @@ -134,39 +134,39 @@ func init() { } var fileDescriptor_8d1392776a3e15b9 = []byte{ - // 505 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0x41, 0x6f, 0xd3, 0x30, - 0x14, 0x80, 0x1b, 0x5a, 0x0a, 0x33, 0x1d, 0xdb, 0x0c, 0x88, 0x50, 0x44, 0x5a, 0x8d, 0x03, 0x45, - 0x82, 0x84, 0xb2, 0x89, 0x03, 0xb7, 0x16, 0x34, 0x09, 0xb1, 0x43, 0x49, 0xc7, 0x24, 0xb8, 0x58, - 0x2f, 0xa9, 0x97, 0x5a, 0xad, 0xed, 0x12, 0x3b, 0x51, 0xfb, 0x2f, 0x38, 0x72, 0xe4, 0x47, 0xf0, - 0x23, 0x76, 0x9c, 0x38, 0xa1, 0x1d, 0x2a, 0xd4, 0xfe, 0x05, 0x7e, 0x00, 0x8a, 0xd3, 0x74, 0xbb, - 0x81, 0x76, 0x8b, 0xdf, 0xfb, 0xfc, 0xbd, 0xf8, 0xf9, 0x19, 0xed, 0x06, 0x10, 0xcc, 0xc6, 0x52, - 0x78, 0x81, 0x0e, 0x95, 0x86, 0x11, 0x13, 0x91, 0x97, 0xb6, 0xbd, 0x09, 0xc4, 0xc0, 0x95, 0x3b, - 0x89, 0xa5, 0x96, 0xf8, 0xde, 0x8a, 0x71, 0x2f, 0x18, 0x37, 0x6d, 0xd7, 0xef, 0x46, 0x32, 0x92, - 0x86, 0xf0, 0xb2, 0xaf, 0x1c, 0xae, 0x3f, 0x08, 0xa5, 0xe2, 0x52, 0x91, 0x3c, 0x91, 0x2f, 0xf2, - 0xd4, 0xee, 0x9f, 0x0a, 0xaa, 0xf6, 0x8c, 0x18, 0x7f, 0x42, 0xb5, 0x50, 0xa6, 0x54, 0x80, 0xd0, - 0x64, 0x32, 0x52, 0xb6, 0xd5, 0x2c, 0xb7, 0x6a, 0xdd, 0x57, 0xe7, 0xf3, 0xc6, 0xcb, 0x88, 0xe9, - 0x61, 0x12, 0xb8, 0xa1, 0xe4, 0xde, 0xaa, 0x6e, 0x38, 0x04, 0x26, 0x8a, 0x85, 0xa7, 0x67, 0x13, - 0xaa, 0xdc, 0xee, 0xbb, 0xde, 0xde, 0xfe, 0x8b, 0x5e, 0x12, 0xbc, 0xa7, 0x33, 0xff, 0x56, 0xe1, - 0xea, 0x8d, 0x14, 0x7e, 0x82, 0xb6, 0xd6, 0xea, 0x2f, 0x89, 0x8c, 0x13, 0x6e, 0x5f, 0x6b, 0x5a, - 0xad, 0x4d, 0xff, 0x76, 0x11, 0xfe, 0x60, 0xa2, 0xf8, 0x29, 0xda, 0x56, 0x63, 0x50, 0x43, 0x26, - 0x22, 0x02, 0x83, 0x41, 0x4c, 0x95, 0xb2, 0xcb, 0x4d, 0xab, 0xb5, 0xe1, 0x6f, 0x15, 0xf1, 0x4e, - 0x1e, 0xc6, 0xfb, 0xe8, 0x3e, 0x67, 0x82, 0xac, 0x71, 0x3d, 0x25, 0x27, 0x94, 0x12, 0x05, 0xda, - 0xae, 0x34, 0xad, 0x56, 0xd9, 0xbf, 0xc3, 0x99, 0xe8, 0xaf, 0xb2, 0x47, 0xd3, 0x03, 0x4a, 0xfb, - 0xa0, 0x71, 0x1f, 0x65, 0x61, 0x12, 0x4a, 0xce, 0x99, 0x52, 0x4c, 0x0a, 0x12, 0x83, 0xa6, 0xf6, - 0xf5, 0xac, 0x46, 0xf7, 0xf1, 0xe9, 0xbc, 0x51, 0x3a, 0x9f, 0x37, 0x1e, 0xe6, 0x2d, 0x52, 0x83, - 0x91, 0xcb, 0xa4, 0xc7, 0x41, 0x0f, 0xdd, 0x43, 0x1a, 0x41, 0x38, 0x7b, 0x4b, 0x43, 0x7f, 0x87, - 0x33, 0xf1, 0x66, 0xbd, 0xdd, 0x07, 0x4d, 0xf1, 0x31, 0xda, 0x5c, 0xff, 0x86, 0xd1, 0x55, 0x8d, - 0xae, 0xfd, 0x1f, 0xba, 0x9f, 0x3f, 0x9e, 0xa3, 0xd5, 0x85, 0x64, 0xf2, 0x5a, 0xe1, 0x31, 0xde, - 0x0e, 0x7a, 0xc4, 0x61, 0x4a, 0x20, 0xd4, 0x2c, 0xa5, 0xe4, 0x84, 0x09, 0x18, 0x33, 0x3d, 0xcb, - 0xae, 0x31, 0x65, 0x03, 0x1a, 0x2b, 0xfb, 0x86, 0x69, 0x62, 0x9d, 0xc3, 0xb4, 0x63, 0x98, 0x83, - 0x15, 0xd2, 0x2b, 0x08, 0xfc, 0x0c, 0xe1, 0xec, 0xbc, 0x89, 0x08, 0xa4, 0x18, 0x98, 0x36, 0x31, - 0x4e, 0xed, 0x9b, 0x66, 0xdf, 0x36, 0x67, 0xe2, 0x63, 0x91, 0x38, 0x62, 0x9c, 0x62, 0xc8, 0xbb, - 0x73, 0x41, 0xa7, 0x30, 0x4e, 0xa8, 0xbd, 0x71, 0xd5, 0xe3, 0xec, 0x5c, 0xae, 0x70, 0x9c, 0xb9, - 0x5e, 0x57, 0xbe, 0x7d, 0x6f, 0x94, 0xba, 0x87, 0xa7, 0x0b, 0xc7, 0x3a, 0x5b, 0x38, 0xd6, 0xef, - 0x85, 0x63, 0x7d, 0x5d, 0x3a, 0xa5, 0xb3, 0xa5, 0x53, 0xfa, 0xb5, 0x74, 0x4a, 0x9f, 0xff, 0x39, - 0x6b, 0xd3, 0xcb, 0xcf, 0xc2, 0x0c, 0x5e, 0x50, 0x35, 0xb3, 0xbc, 0xf7, 0x37, 0x00, 0x00, 0xff, - 0xff, 0xec, 0x97, 0x30, 0x5b, 0x39, 0x03, 0x00, 0x00, + // 502 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcd, 0x8e, 0xd3, 0x3c, + 0x14, 0x86, 0x9b, 0xaf, 0xfd, 0x0a, 0x63, 0x3a, 0xcc, 0x60, 0x40, 0x84, 0x22, 0xd2, 0x6a, 0x58, + 0x50, 0x24, 0x48, 0x28, 0x33, 0x62, 0xc1, 0xae, 0x05, 0x8d, 0x84, 0x98, 0x45, 0x48, 0x07, 0x24, + 0xd8, 0x58, 0x4e, 0xe2, 0x49, 0xad, 0xd6, 0x76, 0x89, 0x9d, 0x28, 0xb9, 0x0b, 0x96, 0x2c, 0xb9, + 0x08, 0x2e, 0x62, 0x96, 0x23, 0x56, 0x68, 0x16, 0x15, 0x6a, 0xef, 0x80, 0x2b, 0x40, 0x71, 0x92, + 0xf2, 0xb3, 0x01, 0xb1, 0x8b, 0xdf, 0xf3, 0xfa, 0x39, 0x39, 0x3f, 0x06, 0x7b, 0x3e, 0xf6, 0xf3, + 0xb9, 0xe0, 0x8e, 0xaf, 0x02, 0xa9, 0xf0, 0x8c, 0xf2, 0xc8, 0x49, 0x87, 0xce, 0x02, 0xc7, 0x98, + 0x49, 0x7b, 0x11, 0x0b, 0x25, 0xe0, 0xf5, 0xca, 0x63, 0xff, 0xf0, 0xd8, 0xe9, 0xb0, 0x7b, 0x2d, + 0x12, 0x91, 0xd0, 0x0e, 0xa7, 0xf8, 0x2a, 0xcd, 0xdd, 0x9b, 0x81, 0x90, 0x4c, 0x48, 0x54, 0x06, + 0xca, 0x43, 0x19, 0xda, 0xfb, 0xd6, 0x02, 0x6d, 0x57, 0x83, 0xe1, 0x1b, 0xd0, 0x09, 0x44, 0x4a, + 0x38, 0xe6, 0x0a, 0x2d, 0x66, 0xd2, 0x34, 0xfa, 0xcd, 0x41, 0x67, 0xfc, 0xf8, 0x7c, 0xd9, 0x7b, + 0x14, 0x51, 0x35, 0x4d, 0x7c, 0x3b, 0x10, 0xcc, 0xa9, 0xf2, 0x06, 0x53, 0x4c, 0x79, 0x7d, 0x70, + 0x54, 0xbe, 0x20, 0xd2, 0x1e, 0x3f, 0x77, 0xf7, 0x0f, 0x1e, 0xba, 0x89, 0xff, 0x82, 0xe4, 0xde, + 0xa5, 0x9a, 0xe5, 0xce, 0x24, 0xbc, 0x0b, 0x76, 0x36, 0xe8, 0x77, 0x89, 0x88, 0x13, 0x66, 0xfe, + 0xd7, 0x37, 0x06, 0xdb, 0xde, 0xe5, 0x5a, 0x7e, 0xa9, 0x55, 0x78, 0x0f, 0xec, 0xca, 0x39, 0x96, + 0x53, 0xca, 0x23, 0x84, 0xc3, 0x30, 0x26, 0x52, 0x9a, 0xcd, 0xbe, 0x31, 0xd8, 0xf2, 0x76, 0x6a, + 0x7d, 0x54, 0xca, 0xf0, 0x00, 0xdc, 0x60, 0x94, 0xa3, 0x8d, 0x5d, 0x65, 0xe8, 0x84, 0x10, 0x24, + 0xb1, 0x32, 0x5b, 0x7d, 0x63, 0xd0, 0xf4, 0xae, 0x32, 0xca, 0x27, 0x55, 0xf4, 0x38, 0x3b, 0x24, + 0x64, 0x82, 0x15, 0x9c, 0x80, 0x42, 0x46, 0x81, 0x60, 0x8c, 0x4a, 0x49, 0x05, 0x47, 0x31, 0x56, + 0xc4, 0xfc, 0xbf, 0xc8, 0x31, 0xbe, 0x73, 0xba, 0xec, 0x35, 0xce, 0x97, 0xbd, 0x5b, 0x65, 0x8b, + 0x64, 0x38, 0xb3, 0xa9, 0x70, 0x18, 0x56, 0x53, 0xfb, 0x88, 0x44, 0x38, 0xc8, 0x9f, 0x91, 0xc0, + 0xbb, 0xc2, 0x28, 0x7f, 0xba, 0xb9, 0xee, 0x61, 0x45, 0xe0, 0x6b, 0xb0, 0xbd, 0xf9, 0x0d, 0x8d, + 0x6b, 0x6b, 0xdc, 0xf0, 0x2f, 0x70, 0x9f, 0x3f, 0x3d, 0x00, 0xd5, 0x40, 0x0a, 0x78, 0xa7, 0xe6, + 0x68, 0xee, 0x08, 0xdc, 0x66, 0x38, 0x43, 0x38, 0x50, 0x34, 0x25, 0xe8, 0x84, 0x72, 0x3c, 0xa7, + 0x2a, 0x2f, 0xc6, 0x98, 0xd2, 0x90, 0xc4, 0xd2, 0xbc, 0xa0, 0x9b, 0xd8, 0x65, 0x38, 0x1b, 0x69, + 0xcf, 0x61, 0x65, 0x71, 0x6b, 0x07, 0xbc, 0x0f, 0x60, 0x51, 0x6f, 0xc2, 0x7d, 0xc1, 0x43, 0xdd, + 0x26, 0xca, 0x88, 0x79, 0x51, 0xdf, 0xdb, 0x65, 0x94, 0xbf, 0xaa, 0x03, 0xc7, 0x94, 0x11, 0x88, + 0x7e, 0x77, 0xeb, 0x6a, 0xb6, 0xfe, 0xb5, 0x9a, 0x5f, 0x12, 0x14, 0x15, 0x3d, 0x69, 0x7d, 0xf8, + 0xd8, 0x6b, 0x8c, 0x8f, 0x4e, 0x57, 0x96, 0x71, 0xb6, 0xb2, 0x8c, 0xaf, 0x2b, 0xcb, 0x78, 0xbf, + 0xb6, 0x1a, 0x67, 0x6b, 0xab, 0xf1, 0x65, 0x6d, 0x35, 0xde, 0xfe, 0x71, 0xd3, 0xb2, 0x9f, 0x1f, + 0x85, 0x5e, 0x3b, 0xbf, 0xad, 0x37, 0x79, 0xff, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xc0, + 0xc2, 0x59, 0x37, 0x03, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -190,9 +190,9 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { var l int _ = l { - size := m.MinUnbondingValue.Size() + size := m.MinUnbondingRate.Size() i -= size - if _, err := m.MinUnbondingValue.MarshalTo(dAtA[i:]); err != nil { + if _, err := m.MinUnbondingRate.MarshalTo(dAtA[i:]); err != nil { return 0, err } i = encodeVarintParams(dAtA, i, uint64(size)) @@ -306,7 +306,7 @@ func (m *Params) Size() (n int) { if m.MinUnbondingTime != 0 { n += 1 + sovParams(uint64(m.MinUnbondingTime)) } - l = m.MinUnbondingValue.Size() + l = m.MinUnbondingRate.Size() n += 1 + l + sovParams(uint64(l)) return n } @@ -559,7 +559,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { } case 9: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MinUnbondingValue", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MinUnbondingRate", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -587,7 +587,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.MinUnbondingValue.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.MinUnbondingRate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex From 9620a7712067cb2101796d6fdcb674bd95da0a0e Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 15 Mar 2024 11:41:37 +0100 Subject: [PATCH 053/119] And new parameter to genesis flags --- cmd/babylond/cmd/flags.go | 5 +++++ cmd/babylond/cmd/genesis.go | 5 +++-- cmd/babylond/cmd/testnet.go | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmd/babylond/cmd/flags.go b/cmd/babylond/cmd/flags.go index ee7c61488..70f7fc109 100644 --- a/cmd/babylond/cmd/flags.go +++ b/cmd/babylond/cmd/flags.go @@ -37,6 +37,7 @@ const ( flagCovenantQuorum = "covenant-quorum" flagMaxActiveFinalityProviders = "max-active-finality-providers" flagMinUnbondingTime = "min-unbonding-time" + flagMinUnbondingRate = "min-unbonding-rate" flagSlashingAddress = "slashing-address" flagMinSlashingFee = "min-slashing-fee-sat" flagSlashingRate = "slashing-rate" @@ -69,6 +70,7 @@ type GenesisCLIArgs struct { SlashingRate math.LegacyDec MaxActiveFinalityProviders uint32 MinUnbondingTime uint16 + MinUnbondingRate math.LegacyDec MinPubRand uint64 MinCommissionRate math.LegacyDec } @@ -97,6 +99,7 @@ func addGenesisFlags(cmd *cobra.Command) { cmd.Flags().String(flagSlashingRate, "0.1", "Bitcoin staking slashing rate") cmd.Flags().Uint32(flagMaxActiveFinalityProviders, 100, "Bitcoin staking maximum active finality providers") cmd.Flags().Uint16(flagMinUnbondingTime, 0, "Min timelock on unbonding transaction in btc blocks") + cmd.Flags().String(flagMinUnbondingRate, "0.8", "Min amount of btc required in unbonding output expressed as a fraction of staking output") // finality args cmd.Flags().Uint64(flagMinPubRand, 100, "Bitcoin staking minimum public randomness commit") // inflation args @@ -130,6 +133,7 @@ func parseGenesisFlags(cmd *cobra.Command) *GenesisCLIArgs { slashingRate, _ := cmd.Flags().GetString(flagSlashingRate) maxActiveFinalityProviders, _ := cmd.Flags().GetUint32(flagMaxActiveFinalityProviders) minUnbondingTime, _ := cmd.Flags().GetUint16(flagMinUnbondingTime) + minUnbondingRate, _ := cmd.Flags().GetString(flagMinUnbondingRate) minPubRand, _ := cmd.Flags().GetUint64(flagMinPubRand) genesisTimeUnix, _ := cmd.Flags().GetInt64(flagGenesisTime) inflationRateChange, _ := cmd.Flags().GetFloat64(flagInflationRateChange) @@ -169,6 +173,7 @@ func parseGenesisFlags(cmd *cobra.Command) *GenesisCLIArgs { SlashingRate: math.LegacyMustNewDecFromStr(slashingRate), MaxActiveFinalityProviders: maxActiveFinalityProviders, MinUnbondingTime: minUnbondingTime, + MinUnbondingRate: math.LegacyMustNewDecFromStr(minUnbondingRate), MinPubRand: minPubRand, GenesisTime: genesisTime, InflationRateChange: inflationRateChange, diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 47a7e58d6..51ff7928c 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -75,7 +75,7 @@ Example: genesisCliArgs.CovenantPKs, genesisCliArgs.CovenantQuorum, genesisCliArgs.SlashingAddress, genesisCliArgs.MinSlashingTransactionFeeSat, genesisCliArgs.MinCommissionRate, genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, - genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinPubRand, genesisCliArgs.InflationRateChange, + genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, genesisCliArgs.MinPubRand, genesisCliArgs.InflationRateChange, genesisCliArgs.InflationMin, genesisCliArgs.InflationMax, genesisCliArgs.GoalBonded, genesisCliArgs.BlocksPerYear, genesisCliArgs.GenesisTime, genesisCliArgs.BlockGasLimit, genesisCliArgs.VoteExtensionEnableHeight) } else if network == "mainnet" { @@ -240,7 +240,7 @@ type GenesisParams struct { func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint64, btcFinalizationTimeout uint64, checkpointTag string, epochInterval uint64, baseBtcHeaderHex string, baseBtcHeaderHeight uint64, allowedReporters []string, covenantPKs []string, covenantQuorum uint32, slashingAddress string, minSlashingFee int64, - minCommissionRate sdkmath.LegacyDec, slashingRate sdkmath.LegacyDec, maxActiveFinalityProviders uint32, minUnbondingTime uint16, + minCommissionRate sdkmath.LegacyDec, slashingRate sdkmath.LegacyDec, maxActiveFinalityProviders uint32, minUnbondingTime uint16, minUnbondingRate sdkmath.LegacyDec, minPubRand uint64, inflationRateChange float64, inflationMin float64, inflationMax float64, goalBonded float64, blocksPerYear uint64, genesisTime time.Time, blockGasLimit int64, voteExtensionEnableHeight int64) GenesisParams { @@ -343,6 +343,7 @@ func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint6 genParams.BtcstakingParams.SlashingRate = slashingRate genParams.BtcstakingParams.MaxActiveFinalityProviders = maxActiveFinalityProviders genParams.BtcstakingParams.MinUnbondingTime = uint32(minUnbondingTime) + genParams.BtcstakingParams.MinUnbondingRate = minUnbondingRate if err := genParams.BtcstakingParams.Validate(); err != nil { panic(err) } diff --git a/cmd/babylond/cmd/testnet.go b/cmd/babylond/cmd/testnet.go index 6a9e8e348..5864a4039 100644 --- a/cmd/babylond/cmd/testnet.go +++ b/cmd/babylond/cmd/testnet.go @@ -97,7 +97,7 @@ Example: genesisCliArgs.EpochInterval, genesisCliArgs.BaseBtcHeaderHex, genesisCliArgs.BaseBtcHeaderHeight, genesisCliArgs.AllowedReporterAddresses, genesisCliArgs.CovenantPKs, genesisCliArgs.CovenantQuorum, genesisCliArgs.SlashingAddress, genesisCliArgs.MinSlashingTransactionFeeSat, genesisCliArgs.MinCommissionRate, - genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, genesisCliArgs.MinUnbondingTime, + genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, genesisCliArgs.MinPubRand, genesisCliArgs.InflationRateChange, genesisCliArgs.InflationMin, genesisCliArgs.InflationMax, genesisCliArgs.GoalBonded, genesisCliArgs.BlocksPerYear, genesisCliArgs.GenesisTime, genesisCliArgs.BlockGasLimit, genesisCliArgs.VoteExtensionEnableHeight) From fd1ac97d86ec4a0b05827e2a1da0ccc6a1e0bb1f Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Mon, 18 Mar 2024 11:08:12 +0100 Subject: [PATCH 054/119] Move min unbonding calculation to separate function --- proto/babylon/btcstaking/v1/params.proto | 2 +- x/btcstaking/keeper/msg_server.go | 24 +++++++++++++++++------- x/btcstaking/types/params.pb.go | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/proto/babylon/btcstaking/v1/params.proto b/proto/babylon/btcstaking/v1/params.proto index 555a0481e..d48483be7 100644 --- a/proto/babylon/btcstaking/v1/params.proto +++ b/proto/babylon/btcstaking/v1/params.proto @@ -42,7 +42,7 @@ message Params { // min_unbonding_rate is the minimum amount of BTC that are required in unbonding // output, expressed as a fraction of staking output - // example: if min_unbonding_rate=0.9, than unbonding output value + // example: if min_unbonding_rate=0.9, then the unbonding output value // must be at least 90% of staking output, for staking request to be considered // valid string min_unbonding_rate = 9 [ diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 40b7f48ae..ca094ad2b 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -12,6 +12,7 @@ import ( "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -135,6 +136,19 @@ func (ms msgServer) EditFinalityProvider(ctx context.Context, req *types.MsgEdit return &types.MsgEditFinalityProviderResponse{}, nil } +// caluculateMinimumUnbondingValue calculates minimum unbonding value basend on current staking output value +// and params.MinUnbondingRate +func caluculateMinimumUnbondingValue( + stakingOutput *wire.TxOut, + params *types.Params, +) btcutil.Amount { + // this conversions must always succeed, as it is part of our params + minUnbondingRate := params.MinUnbondingRate.MustFloat64() + // Caluclate min unbonding output value based on staking output, use btc native multiplication + minUnbondingOutputValue := btcutil.Amount(stakingOutput.Value).MulF64(minUnbondingRate) + return minUnbondingOutputValue +} + // CreateBTCDelegation creates a BTC delegation // TODO: refactor this handler. It's now too convoluted func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCreateBTCDelegation) (*types.MsgCreateBTCDelegationResponse, error) { @@ -401,13 +415,9 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding tx fee must be larger that 0") } - // this conversions must always succeed, as it is part of our params - minUnbondingRate := params.MinUnbondingRate.MustFloat64() - // Caluclate min unbonding output value based on staking output, use btc native multiplication - minUnbondingOutputValue := btcutil.Amount(stakingMsgTx.TxOut[newBTCDel.StakingOutputIdx].Value).MulF64(minUnbondingRate) - - if btcutil.Amount(unbondingMsgTx.TxOut[0].Value) < minUnbondingOutputValue { - return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingOutputValue) + minUnbondingValue := caluculateMinimumUnbondingValue(stakingMsgTx.TxOut[stakingOutputIdx], ¶ms) + if btcutil.Amount(unbondingMsgTx.TxOut[0].Value) < minUnbondingValue { + return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingValue) } // all good, add BTC undelegation diff --git a/x/btcstaking/types/params.pb.go b/x/btcstaking/types/params.pb.go index bf4cc12f2..a49699288 100644 --- a/x/btcstaking/types/params.pb.go +++ b/x/btcstaking/types/params.pb.go @@ -52,7 +52,7 @@ type Params struct { MinUnbondingTime uint32 `protobuf:"varint,8,opt,name=min_unbonding_time,json=minUnbondingTime,proto3" json:"min_unbonding_time,omitempty"` // min_unbonding_rate is the minimum amount of BTC that are required in unbonding // output, expressed as a fraction of staking output - // example: if min_unbonding_rate=0.9, than unbonding output value + // example: if min_unbonding_rate=0.9, then the unbonding output value // must be at least 90% of staking output, for staking request to be considered // valid MinUnbondingRate cosmossdk_io_math.LegacyDec `protobuf:"bytes,9,opt,name=min_unbonding_rate,json=minUnbondingRate,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_unbonding_rate"` From bc4943f41c791a4bbb2591e3522af829cafc966b Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Tue, 19 Mar 2024 09:20:43 -0300 Subject: [PATCH 055/119] fix: import/export of `x/btcstaking` (#572) * chore: add initial genstate properties from state * chore: add todos * chore: add todo not used * chore: add new genstate properties to InitGenesis * chore: add export genesis of btcstaking module state * chore: add test for gen export * chore: simplified test * chore: moved solely genstate funcs to genesis.go * chore: moved solely genstate funcs to genesis.go * chore: add comment about events property * chore: add test check export genesis for chains height and btc delegators * fix: header info instead of block height * chore: add test for Idx events * chore: set ctx to helper as well * chore: moved parse of KV keys out of utils * chore: removed get prefix --- btcstaking/types.go | 20 + proto/babylon/btcstaking/v1/genesis.proto | 65 + x/btcstaking/genesis.go | 17 +- x/btcstaking/keeper/btc_delegators.go | 22 +- x/btcstaking/keeper/genesis.go | 295 ++++ x/btcstaking/keeper/genesis_test.go | 176 ++ x/btcstaking/keeper/grpc_query.go | 6 +- x/btcstaking/keeper/power_dist_change.go | 21 +- x/btcstaking/keeper/voting_power_table.go | 44 +- x/btcstaking/types/btc_delegation.go | 3 + x/btcstaking/types/genesis.go | 2 +- x/btcstaking/types/genesis.pb.go | 1765 ++++++++++++++++++++- x/btcstaking/types/keys.go | 4 - x/finality/keeper/genesis.go | 20 +- 14 files changed, 2352 insertions(+), 108 deletions(-) create mode 100644 x/btcstaking/keeper/genesis.go create mode 100644 x/btcstaking/keeper/genesis_test.go diff --git a/btcstaking/types.go b/btcstaking/types.go index ac5c8817d..416401238 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -12,6 +12,9 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" + + bbn "github.com/babylonchain/babylon/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( @@ -555,3 +558,20 @@ func BuildRelativeTimelockTaprootScript( PkScript: taprootPkScript, }, nil } + +// ParseBlkHeightAndPubKeyFromStoreKey expects to receive a key with +// BigEndianUint64(blkHeight) || BIP340PubKey(fpBTCPK) +func ParseBlkHeightAndPubKeyFromStoreKey(key []byte) (blkHeight uint64, fpBTCPK *bbn.BIP340PubKey, err error) { + sizeBigEndian := 8 + if len(key) < sizeBigEndian+1 { + return 0, nil, fmt.Errorf("key not long enough to parse block height and BIP340PubKey: %s", key) + } + + fpBTCPK, err = bbn.NewBIP340PubKey(key[sizeBigEndian:]) + if err != nil { + return 0, nil, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + blkHeight = sdk.BigEndianToUint64(key[:sizeBigEndian]) + return blkHeight, fpBTCPK, nil +} diff --git a/proto/babylon/btcstaking/v1/genesis.proto b/proto/babylon/btcstaking/v1/genesis.proto index 406cba75a..5b3f67070 100644 --- a/proto/babylon/btcstaking/v1/genesis.proto +++ b/proto/babylon/btcstaking/v1/genesis.proto @@ -3,10 +3,75 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "babylon/btcstaking/v1/params.proto"; +import "babylon/btcstaking/v1/btcstaking.proto"; +import "babylon/btcstaking/v1/incentive.proto"; +import "babylon/btcstaking/v1/events.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; // GenesisState defines the btcstaking module's genesis state. message GenesisState { Params params = 1 [(gogoproto.nullable) = false]; + // finality_providers all the finality providers registered. + repeated FinalityProvider finality_providers = 2; + // btc_delegations all the btc delegations in the state. + repeated BTCDelegation btc_delegations = 3; + // voting_powers the voting power of every finality provider at every block height. + repeated VotingPowerFP voting_powers = 4; + // block_height_chains the block height of babylon and bitcoin. + repeated BlockHeightBbnToBtc block_height_chains = 5; + // btc_delegators contains all the btc delegators with the associated finality provider. + repeated BTCDelegator btc_delegators = 6; + // all the events and its indexes. + repeated EventIndex events = 7; + // vp_dst_cache is the table of all providers voting power with the total at one specific block. + // TODO: remove this after not storing in the keeper store it anymore. + repeated VotingPowerDistCacheBlkHeight vp_dst_cache = 8; } + +// VotingPowerFP contains the information about the voting power +// of an finality provider in a specific block height. +message VotingPowerFP { + // block_height is the height of the block the voting power was stored. + uint64 block_height = 1; + // fp_btc_pk the finality provider btc public key. + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // voting_power is the power of the finality provider at this specific block height. + uint64 voting_power = 3; +} + +// VotingPowerDistCacheBlkHeight the total voting power of the finality providers at one specific block height +message VotingPowerDistCacheBlkHeight { + // block_height is the height of the block the voting power distribution cached was stored. + uint64 block_height = 1; + // vp_distribution the finality providers distribution cache at that height. + VotingPowerDistCache vp_distribution = 2; +} + +// BlockHeightBbnToBtc stores the btc <-> bbn block. +message BlockHeightBbnToBtc { + // block_height_bbn is the height of the block in the babylon chain. + uint64 block_height_bbn = 1; + // block_height_btc is the height of the block in the BTC. + uint64 block_height_btc = 2; +} + +// BTCDelegator BTC delegator information with the associated finality provider. +message BTCDelegator { + // idx the btc delegator index. + BTCDelegatorDelegationIndex idx = 1; + // fp_btc_pk the finality provider btc public key. + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // del_btc_pk the delegator btc public key. + bytes del_btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; +} + +// EventIndex contains the event and its index. +message EventIndex { + // idx is the index the event was stored. + uint64 idx = 1; + // block_height_btc is the height of the block in the BTC chain. + uint64 block_height_btc = 2; + // event the event stored. + EventPowerDistUpdate event = 3; +} \ No newline at end of file diff --git a/x/btcstaking/genesis.go b/x/btcstaking/genesis.go index 4131d8bd4..4b89af9ff 100644 --- a/x/btcstaking/genesis.go +++ b/x/btcstaking/genesis.go @@ -2,21 +2,26 @@ package btcstaking import ( "context" + "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" ) // InitGenesis initializes the module's state from a provided genesis state. -func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { - if err := k.SetParams(ctx, genState.Params); err != nil { +func InitGenesis(ctx context.Context, k keeper.Keeper, gs types.GenesisState) { + if err := gs.Validate(); err != nil { + panic(err) + } + if err := k.InitGenesis(ctx, gs); err != nil { panic(err) } } // ExportGenesis returns the module's exported genesis func ExportGenesis(ctx context.Context, k keeper.Keeper) *types.GenesisState { - genesis := types.DefaultGenesis() - genesis.Params = k.GetParams(ctx) - - return genesis + gs, err := k.ExportGenesis(ctx) + if err != nil { + panic(err) + } + return gs } diff --git a/x/btcstaking/keeper/btc_delegators.go b/x/btcstaking/keeper/btc_delegators.go index c6684dee7..a8023166a 100644 --- a/x/btcstaking/keeper/btc_delegators.go +++ b/x/btcstaking/keeper/btc_delegators.go @@ -16,7 +16,7 @@ import ( func (k Keeper) getBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey) *types.BTCDelegatorDelegationIndex { fpBTCPKBytes := fpBTCPK.MustMarshal() delBTCPKBytes := delBTCPK.MustMarshal() - store := k.btcDelegatorStore(ctx, fpBTCPK) + store := k.btcDelegatorFpStore(ctx, fpBTCPK) // ensure the finality provider exists if !k.HasFinalityProvider(ctx, fpBTCPKBytes) { @@ -34,8 +34,8 @@ func (k Keeper) getBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn return &btcDelIndex } -func (k Keeper) setBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK *bbn.BIP340PubKey, delBTCPK *bbn.BIP340PubKey, btcDelIndex *types.BTCDelegatorDelegationIndex) { - store := k.btcDelegatorStore(ctx, fpBTCPK) +func (k Keeper) setBTCDelegatorDelegationIndex(ctx context.Context, fpBTCPK, delBTCPK *bbn.BIP340PubKey, btcDelIndex *types.BTCDelegatorDelegationIndex) { + store := k.btcDelegatorFpStore(ctx, fpBTCPK) btcDelIndexBytes := k.cdc.MustMarshal(btcDelIndex) store.Set(*delBTCPK, btcDelIndexBytes) } @@ -60,12 +60,20 @@ func (k Keeper) getBTCDelegatorDelegations(ctx context.Context, fpBTCPK *bbn.BIP return &types.BTCDelegatorDelegations{Dels: btcDels} } -// btcDelegatorStore returns the KVStore of the BTC delegators +// btcDelegatorFpStore returns the KVStore of the BTC delegators // prefix: BTCDelegatorKey || finality provider's Bitcoin secp256k1 PK // key: delegator's Bitcoin secp256k1 PK // value: BTCDelegatorDelegationIndex (a list of BTCDelegations' staking tx hashes) -func (k Keeper) btcDelegatorStore(ctx context.Context, fpBTCPK *bbn.BIP340PubKey) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - delegationStore := prefix.NewStore(storeAdapter, types.BTCDelegatorKey) +func (k Keeper) btcDelegatorFpStore(ctx context.Context, fpBTCPK *bbn.BIP340PubKey) prefix.Store { + delegationStore := k.btcDelegatorStore(ctx) return prefix.NewStore(delegationStore, fpBTCPK.MustMarshal()) } + +// btcDelegatorFpStore returns the KVStore of the BTC delegators +// prefix: BTCDelegatorKey +// key: finality provider's Bitcoin secp256k1 PK || delegator's Bitcoin secp256k1 PK +// value: BTCDelegatorDelegationIndex (a list of BTCDelegations' staking tx hashes) +func (k Keeper) btcDelegatorStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.BTCDelegatorKey) +} diff --git a/x/btcstaking/keeper/genesis.go b/x/btcstaking/keeper/genesis.go new file mode 100644 index 000000000..a63e3e319 --- /dev/null +++ b/x/btcstaking/keeper/genesis.go @@ -0,0 +1,295 @@ +package keeper + +import ( + "context" + "fmt" + + btcstk "github.com/babylonchain/babylon/btcstaking" + bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/btcstaking/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis initializes the module's state from a provided genesis state. +func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { + if err := k.SetParams(ctx, gs.Params); err != nil { + return err + } + + for _, fp := range gs.FinalityProviders { + k.SetFinalityProvider(ctx, fp) + } + + for _, btcDel := range gs.BtcDelegations { + k.setBTCDelegation(ctx, btcDel) + } + + for _, fpVP := range gs.VotingPowers { + k.SetVotingPower(ctx, *fpVP.FpBtcPk, fpVP.BlockHeight, fpVP.VotingPower) + } + + for _, blocks := range gs.BlockHeightChains { + k.setBlockHeightChains(ctx, blocks) + } + + for _, del := range gs.BtcDelegators { + k.setBTCDelegatorDelegationIndex(ctx, del.FpBtcPk, del.DelBtcPk, del.Idx) + } + + // Events are generated on block `N` to be processed at block `N+1` + // When ExportGenesis is called the node already stopped at block N. + // In this case the events on the state would refer to the block `N+1` + // Since InitGenesis occurs before BeginBlock, the genesis state would be properly + // stored in the KV store for when BeginBlock process the events. + for _, evt := range gs.Events { + if err := k.setEventIdx(ctx, evt); err != nil { + return err + } + } + + for _, vpCache := range gs.VpDstCache { + k.setVotingPowerDistCache(ctx, vpCache.BlockHeight, vpCache.VpDistribution) + } + + return nil +} + +// ExportGenesis returns the module's exported genesis +func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) { + fps, err := k.finalityProviders(ctx) + if err != nil { + return nil, err + } + + dels, err := k.btcDelegations(ctx) + if err != nil { + return nil, err + } + + vpFps, err := k.fpVotingPowers(ctx) + if err != nil { + return nil, err + } + + btcDels, err := k.btcDelegators(ctx) + if err != nil { + return nil, err + } + + evts, err := k.eventIdxs(ctx) + if err != nil { + return nil, err + } + + vpsCache, err := k.votingPowersDistCacheBlkHeight(ctx) + if err != nil { + return nil, err + } + + return &types.GenesisState{ + Params: k.GetParams(ctx), + FinalityProviders: fps, + BtcDelegations: dels, + VotingPowers: vpFps, + BlockHeightChains: k.blockHeightChains(ctx), + BtcDelegators: btcDels, + Events: evts, + VpDstCache: vpsCache, + }, nil +} + +func (k Keeper) finalityProviders(ctx context.Context) ([]*types.FinalityProvider, error) { + fps := make([]*types.FinalityProvider, 0) + iter := k.finalityProviderStore(ctx).Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var fp types.FinalityProvider + if err := fp.Unmarshal(iter.Value()); err != nil { + return nil, err + } + fps = append(fps, &fp) + } + + return fps, nil +} + +func (k Keeper) btcDelegations(ctx context.Context) ([]*types.BTCDelegation, error) { + dels := make([]*types.BTCDelegation, 0) + iter := k.btcDelegationStore(ctx).Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var del types.BTCDelegation + if err := del.Unmarshal(iter.Value()); err != nil { + return nil, err + } + dels = append(dels, &del) + } + + return dels, nil +} + +// fpVotingPowers gets the voting power of a given finality provider at a given Babylon height. +func (k Keeper) fpVotingPowers(ctx context.Context) ([]*types.VotingPowerFP, error) { + iter := k.votingPowerStore(ctx).Iterator(nil, nil) + defer iter.Close() + + vpFps := make([]*types.VotingPowerFP, 0) + + for ; iter.Valid(); iter.Next() { + blkHeight, fpBTCPK, err := btcstk.ParseBlkHeightAndPubKeyFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + + vp := sdk.BigEndianToUint64(iter.Value()) + vpFps = append(vpFps, &types.VotingPowerFP{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + VotingPower: vp, + }) + } + + return vpFps, nil +} + +func (k Keeper) blockHeightChains(ctx context.Context) []*types.BlockHeightBbnToBtc { + iter := k.btcHeightStore(ctx).Iterator(nil, nil) + defer iter.Close() + + blocks := make([]*types.BlockHeightBbnToBtc, 0) + for ; iter.Valid(); iter.Next() { + blocks = append(blocks, &types.BlockHeightBbnToBtc{ + BlockHeightBbn: sdk.BigEndianToUint64(iter.Key()), + BlockHeightBtc: sdk.BigEndianToUint64(iter.Value()), + }) + } + + return blocks +} + +func (k Keeper) btcDelegators(ctx context.Context) ([]*types.BTCDelegator, error) { + iter := k.btcDelegatorStore(ctx).Iterator(nil, nil) + defer iter.Close() + + dels := make([]*types.BTCDelegator, 0) + for ; iter.Valid(); iter.Next() { + fpBTCPK, delBTCPK, err := parseBIP340PubKeysFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + var btcDelIndex types.BTCDelegatorDelegationIndex + if err := btcDelIndex.Unmarshal(iter.Value()); err != nil { + return nil, err + } + + dels = append(dels, &types.BTCDelegator{ + Idx: &btcDelIndex, + FpBtcPk: fpBTCPK, + DelBtcPk: delBTCPK, + }) + } + + return dels, nil +} + +// eventIdxs sets an event into the store. +func (k Keeper) eventIdxs( + ctx context.Context, +) ([]*types.EventIndex, error) { + iter := k.powerDistUpdateEventStore(ctx).Iterator(nil, nil) + defer iter.Close() + + evts := make([]*types.EventIndex, 0) + for ; iter.Valid(); iter.Next() { + blkHeight, idx, err := parseUintsFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + + var evt types.EventPowerDistUpdate + if err := evt.Unmarshal(iter.Value()); err != nil { + return nil, err + } + + evts = append(evts, &types.EventIndex{ + Idx: idx, + BlockHeightBtc: blkHeight, + Event: &evt, + }) + } + + return evts, nil +} + +func (k Keeper) votingPowersDistCacheBlkHeight(ctx context.Context) ([]*types.VotingPowerDistCacheBlkHeight, error) { + vps := make([]*types.VotingPowerDistCacheBlkHeight, 0) + iter := k.votingPowerDistCacheStore(ctx).Iterator(nil, nil) + defer iter.Close() + + for ; iter.Valid(); iter.Next() { + var dc types.VotingPowerDistCache + if err := dc.Unmarshal(iter.Value()); err != nil { + return nil, err + } + vps = append(vps, &types.VotingPowerDistCacheBlkHeight{ + BlockHeight: sdk.BigEndianToUint64(iter.Key()), + VpDistribution: &dc, + }) + } + + return vps, nil +} + +func (k Keeper) setBlockHeightChains(ctx context.Context, blocks *types.BlockHeightBbnToBtc) { + store := k.btcHeightStore(ctx) + store.Set(sdk.Uint64ToBigEndian(blocks.BlockHeightBbn), sdk.Uint64ToBigEndian(blocks.BlockHeightBtc)) +} + +// setEventIdx sets an event into the store. +func (k Keeper) setEventIdx( + ctx context.Context, + evt *types.EventIndex, +) error { + store := k.powerDistUpdateEventBtcHeightStore(ctx, evt.BlockHeightBtc) + + bz, err := evt.Event.Marshal() + if err != nil { + return err + } + store.Set(sdk.Uint64ToBigEndian(evt.Idx), bz) + + return nil +} + +// parseUintsFromStoreKey expects to receive a key with +// BigEndianUint64(blkHeight) || BigEndianUint64(Idx) +func parseUintsFromStoreKey(key []byte) (blkHeight, idx uint64, err error) { + sizeBigEndian := 8 + if len(key) < sizeBigEndian*2 { + return 0, 0, fmt.Errorf("key not long enough to parse two uint64: %s", key) + } + + return sdk.BigEndianToUint64(key[:sizeBigEndian]), sdk.BigEndianToUint64(key[sizeBigEndian:]), nil +} + +// parseBIP340PubKeysFromStoreKey expects to receive a key with +// BIP340PubKey(fpBTCPK) || BIP340PubKey(delBTCPK) +func parseBIP340PubKeysFromStoreKey(key []byte) (fpBTCPK, delBTCPK *bbn.BIP340PubKey, err error) { + if len(key) < bbn.BIP340PubKeyLen*2 { + return nil, nil, fmt.Errorf("key not long enough to parse two BIP340PubKey: %s", key) + } + + fpBTCPK, err = bbn.NewBIP340PubKey(key[:bbn.BIP340PubKeyLen]) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + delBTCPK, err = bbn.NewBIP340PubKey(key[bbn.BIP340PubKeyLen:]) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + return fpBTCPK, delBTCPK, nil +} diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go new file mode 100644 index 000000000..174317034 --- /dev/null +++ b/x/btcstaking/keeper/genesis_test.go @@ -0,0 +1,176 @@ +package keeper_test + +import ( + "bytes" + "math" + "math/rand" + "testing" + + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" + btclightclientt "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/stretchr/testify/require" +) + +func TestExportGenesis(t *testing.T) { + r, h := rand.New(rand.NewSource(11)), helper.NewHelper(t) + k, btclcK, btcCheckK, ctx := h.App.BTCStakingKeeper, h.App.BTCLightClientKeeper, h.App.BtcCheckpointKeeper, h.Ctx + numFps := 3 + + fps := datagen.CreateNFinalityProviders(r, t, numFps) + params := k.GetParams(ctx) + wValue := btcCheckK.GetParams(ctx).CheckpointFinalizationTimeout + + chainsHeight := make([]*types.BlockHeightBbnToBtc, 0) + // creates the first as it starts already with an chain height from the helper. + chainsHeight = append(chainsHeight, &types.BlockHeightBbnToBtc{ + BlockHeightBbn: 1, + BlockHeightBtc: 0, + }) + vpFps := make(map[string]*types.VotingPowerFP, 0) + btcDelegations := make([]*types.BTCDelegation, 0) + eventsIdx := make(map[uint64]*types.EventIndex, 0) + btcDelegatorIndex := make(map[string]*types.BTCDelegator, 0) + + blkHeight := uint64(r.Int63n(1000)) + math.MaxUint16 + totalDelegations := 0 + + for _, fp := range fps { + btcHead := btclcK.GetTipInfo(ctx) + btcHead.Height = blkHeight + 100 + btclcK.InsertHeaderInfos(ctx, []*btclightclientt.BTCHeaderInfo{ + btcHead, + }) + + // set finality + h.AddFinalityProvider(fp) + + stakingValue := r.Int31n(200000) + 10000 + numDelegations := r.Int31n(10) + delegations := createNDelegationsForFinalityProvider( + r, + t, + fp.BtcPk.MustToBTCPK(), + int64(stakingValue), + int(numDelegations), + params.CovenantQuorum, + ) + vp := uint64(stakingValue) + + // sets voting power + k.SetVotingPower(ctx, *fp.BtcPk, blkHeight, vp) + vpFps[fp.BtcPk.MarshalHex()] = &types.VotingPowerFP{ + BlockHeight: blkHeight, + FpBtcPk: fp.BtcPk, + VotingPower: vp, + } + + for _, del := range delegations { + totalDelegations++ + + // sets delegations + h.AddDelegation(del) + btcDelegations = append(btcDelegations, del) + + // BTC delegators idx + stakingTxHash, err := del.GetStakingTxHash() + h.NoError(err) + + idxDelegatorStk := types.NewBTCDelegatorDelegationIndex() + err = idxDelegatorStk.Add(stakingTxHash) + h.NoError(err) + + btcDelegatorIndex[del.BtcPk.MarshalHex()] = &types.BTCDelegator{ + Idx: &types.BTCDelegatorDelegationIndex{ + StakingTxHashList: idxDelegatorStk.StakingTxHashList, + }, + FpBtcPk: fp.BtcPk, + DelBtcPk: del.BtcPk, + } + + // record event that the BTC delegation will become unbonded at endHeight-w + unbondedEvent := types.NewEventPowerDistUpdateWithBTCDel(&types.EventBTCDelegationStateUpdate{ + StakingTxHash: stakingTxHash.String(), + NewState: types.BTCDelegationStatus_UNBONDED, + }) + + // events + idxEvent := uint64(totalDelegations - 1) + eventsIdx[idxEvent] = &types.EventIndex{ + Idx: idxEvent, + BlockHeightBtc: del.EndHeight - wValue, + Event: unbondedEvent, + } + } + + // sets chain heights + header := ctx.HeaderInfo() + header.Height = int64(blkHeight) + ctx = ctx.WithHeaderInfo(header) + h.Ctx = ctx + + k.IndexBTCHeight(ctx) + chainsHeight = append(chainsHeight, &types.BlockHeightBbnToBtc{ + BlockHeightBbn: blkHeight, + BlockHeightBtc: btcHead.Height, + }) + + blkHeight++ // each fp increase blk height to modify data in state. + } + + gs, err := k.ExportGenesis(ctx) + h.NoError(err) + require.Equal(t, k.GetParams(ctx), gs.Params) + + // finality providers + correctFps := 0 + for _, fp := range fps { + for _, gsfp := range gs.FinalityProviders { + if !bytes.Equal(fp.BabylonPk.Address(), gsfp.BabylonPk.Address()) { + continue + } + require.EqualValues(t, fp, gsfp) + correctFps++ + } + } + require.Equal(t, correctFps, numFps) + + // btc delegations + correctDels := 0 + for _, del := range btcDelegations { + for _, gsdel := range gs.BtcDelegations { + if !bytes.Equal(del.BabylonPk.Address(), gsdel.BabylonPk.Address()) { + continue + } + correctDels++ + require.Equal(t, del, gsdel) + } + } + require.Equal(t, correctDels, len(btcDelegations)) + + // voting powers + for _, gsFpVp := range gs.VotingPowers { + vp := vpFps[gsFpVp.FpBtcPk.MarshalHex()] + require.Equal(t, gsFpVp, vp) + } + + // chains height + require.Equal(t, chainsHeight, gs.BlockHeightChains) + + // btc delegators + require.Equal(t, totalDelegations, len(gs.BtcDelegators)) + for _, btcDel := range gs.BtcDelegators { + idxBtcDel := btcDelegatorIndex[btcDel.DelBtcPk.MarshalHex()] + require.Equal(t, btcDel, idxBtcDel) + } + + // events + require.Equal(t, totalDelegations, len(gs.Events)) + for _, evt := range gs.Events { + evtIdx := eventsIdx[evt.Idx] + require.Equal(t, evt, evtIdx) + } + + // TODO: vp dst cache +} diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index ffa92e458..f687cdb36 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -136,7 +136,7 @@ func (k Keeper) FinalityProviderPowerAtHeight(ctx context.Context, req *types.Qu return nil, types.ErrFpNotFound } - store := k.votingPowerStore(ctx, req.Height) + store := k.votingPowerBbnBlockHeightStore(ctx, req.Height) iter := store.ReverseIterator(nil, nil) defer iter.Close() @@ -174,7 +174,7 @@ func (k Keeper) ActiveFinalityProvidersAtHeight(ctx context.Context, req *types. } sdkCtx := sdk.UnwrapSDKContext(ctx) - store := k.votingPowerStore(sdkCtx, req.Height) + store := k.votingPowerBbnBlockHeightStore(sdkCtx, req.Height) var finalityProvidersWithMeta []*types.FinalityProviderWithMeta pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { @@ -236,7 +236,7 @@ func (k Keeper) FinalityProviderDelegations(ctx context.Context, req *types.Quer } sdkCtx := sdk.UnwrapSDKContext(ctx) - btcDelStore := k.btcDelegatorStore(sdkCtx, fpPK) + btcDelStore := k.btcDelegatorFpStore(sdkCtx, fpPK) currentWValue := k.btccKeeper.GetParams(ctx).CheckpointFinalizationTimeout btcHeight := k.btclcKeeper.GetTipInfo(ctx).Height diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index c3617fa9c..cd34cf8fa 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -231,7 +231,7 @@ func (k Keeper) addPowerDistUpdateEvent( btcHeight uint64, event *types.EventPowerDistUpdate, ) { - store := k.powerDistUpdateEventStore(ctx, btcHeight) + store := k.powerDistUpdateEventBtcHeightStore(ctx, btcHeight) // get event index eventIdx := uint64(0) // event index starts from 0 @@ -251,7 +251,7 @@ func (k Keeper) addPowerDistUpdateEvent( // This is called after processing all BTC delegation events in `BeginBlocker` // nolint:unused func (k Keeper) ClearPowerDistUpdateEvents(ctx context.Context, btcHeight uint64) { - store := k.powerDistUpdateEventStore(ctx, btcHeight) + store := k.powerDistUpdateEventBtcHeightStore(ctx, btcHeight) keys := [][]byte{} // get all keys @@ -291,7 +291,7 @@ func (k Keeper) IteratePowerDistUpdateEvents( btcHeight uint64, handleFunc func(event *types.EventPowerDistUpdate) bool, ) { - store := k.powerDistUpdateEventStore(ctx, btcHeight) + store := k.powerDistUpdateEventBtcHeightStore(ctx, btcHeight) iter := store.Iterator(nil, nil) defer iter.Close() for ; iter.Valid(); iter.Next() { @@ -304,13 +304,22 @@ func (k Keeper) IteratePowerDistUpdateEvents( } } +// powerDistUpdateEventBtcHeightStore returns the KVStore of events that affect +// voting power distribution +// prefix: PowerDistUpdateKey || BTC height +// key: event index) +// value: BTCDelegationStatus +func (k Keeper) powerDistUpdateEventBtcHeightStore(ctx context.Context, btcHeight uint64) prefix.Store { + store := k.powerDistUpdateEventStore(ctx) + return prefix.NewStore(store, sdk.Uint64ToBigEndian(btcHeight)) +} + // powerDistUpdateEventStore returns the KVStore of events that affect // voting power distribution // prefix: PowerDistUpdateKey // key: (BTC height || event index) // value: BTCDelegationStatus -func (k Keeper) powerDistUpdateEventStore(ctx context.Context, btcHeight uint64) prefix.Store { +func (k Keeper) powerDistUpdateEventStore(ctx context.Context) prefix.Store { storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - store := prefix.NewStore(storeAdapter, types.PowerDistUpdateKey) - return prefix.NewStore(store, sdk.Uint64ToBigEndian(btcHeight)) + return prefix.NewStore(storeAdapter, types.PowerDistUpdateKey) } diff --git a/x/btcstaking/keeper/voting_power_table.go b/x/btcstaking/keeper/voting_power_table.go index c5bb04903..7b5297c5e 100644 --- a/x/btcstaking/keeper/voting_power_table.go +++ b/x/btcstaking/keeper/voting_power_table.go @@ -13,18 +13,25 @@ import ( ) // IterateActiveFPs iterates over all finality providers that are not slashed -func (k Keeper) IterateActiveFPs(ctx context.Context, handler func(fp *types.FinalityProvider) bool) { +func (k Keeper) IterateActiveFPs(ctx context.Context, handler func(fp *types.FinalityProvider) (shouldContinue bool)) { + k.IterateFPs(ctx, func(fp *types.FinalityProvider) (shouldContinue bool) { + if fp.IsSlashed() { + // slashed finality provider is removed from finality provider set + return true + } + + return handler(fp) + }) +} + +// IterateFPs iterates over all finality providers. +func (k Keeper) IterateFPs(ctx context.Context, handler func(fp *types.FinalityProvider) (shouldContinue bool)) { // filter out all finality providers with positive voting power fpIter := k.finalityProviderStore(ctx).Iterator(nil, nil) defer fpIter.Close() for ; fpIter.Valid(); fpIter.Next() { var fp types.FinalityProvider k.cdc.MustUnmarshal(fpIter.Value(), &fp) - if fp.IsSlashed() { - // slashed finality provider is removed from finality provider set - continue - } - shouldContinue := handler(&fp) if !shouldContinue { return @@ -32,9 +39,8 @@ func (k Keeper) IterateActiveFPs(ctx context.Context, handler func(fp *types.Fin } } -// SetVotingPower sets the voting power of a given finality provider at a given Babylon height func (k Keeper) SetVotingPower(ctx context.Context, fpBTCPK []byte, height uint64, power uint64) { - store := k.votingPowerStore(ctx, height) + store := k.votingPowerBbnBlockHeightStore(ctx, height) store.Set(fpBTCPK, sdk.Uint64ToBigEndian(power)) } @@ -43,7 +49,7 @@ func (k Keeper) GetVotingPower(ctx context.Context, fpBTCPK []byte, height uint6 if !k.HasFinalityProvider(ctx, fpBTCPK) { return 0 } - store := k.votingPowerStore(ctx, height) + store := k.votingPowerBbnBlockHeightStore(ctx, height) powerBytes := store.Get(fpBTCPK) if len(powerBytes) == 0 { return 0 @@ -86,7 +92,7 @@ func (k Keeper) GetCurrentVotingPower(ctx context.Context, fpBTCPK []byte) (uint // HasVotingPowerTable checks if the voting power table exists at a given height func (k Keeper) HasVotingPowerTable(ctx context.Context, height uint64) bool { - store := k.votingPowerStore(ctx, height) + store := k.votingPowerBbnBlockHeightStore(ctx, height) iter := store.Iterator(nil, nil) defer iter.Close() return iter.Valid() @@ -94,7 +100,7 @@ func (k Keeper) HasVotingPowerTable(ctx context.Context, height uint64) bool { // GetVotingPowerTable gets the voting power table, i.e., finality provider set at a given height func (k Keeper) GetVotingPowerTable(ctx context.Context, height uint64) map[string]uint64 { - store := k.votingPowerStore(ctx, height) + store := k.votingPowerBbnBlockHeightStore(ctx, height) iter := store.Iterator(nil, nil) defer iter.Close() @@ -142,12 +148,20 @@ func (k Keeper) IsBTCStakingActivated(ctx context.Context) bool { return iter.Valid() } -// votingPowerStore returns the KVStore of the finality providers' voting power +// votingPowerBbnBlockHeightStore returns the KVStore of the finality providers' voting power // prefix: (VotingPowerKey || Babylon block height) // key: Bitcoin secp256k1 PK // value: voting power quantified in Satoshi -func (k Keeper) votingPowerStore(ctx context.Context, height uint64) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - votingPowerStore := prefix.NewStore(storeAdapter, types.VotingPowerKey) +func (k Keeper) votingPowerBbnBlockHeightStore(ctx context.Context, height uint64) prefix.Store { + votingPowerStore := k.votingPowerStore(ctx) return prefix.NewStore(votingPowerStore, sdk.Uint64ToBigEndian(height)) } + +// votingPowerStore returns the KVStore of the finality providers' voting power +// prefix: (VotingPowerKey) +// key: Babylon block height || Bitcoin secp256k1 PK +// value: voting power quantified in Satoshi +func (k Keeper) votingPowerStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.VotingPowerKey) +} diff --git a/x/btcstaking/types/btc_delegation.go b/x/btcstaking/types/btc_delegation.go index 7a8a27961..0d496965d 100644 --- a/x/btcstaking/types/btc_delegation.go +++ b/x/btcstaking/types/btc_delegation.go @@ -309,6 +309,7 @@ func (d *BTCDelegation) GetUnbondingInfo(bsParams *Params, btcNet *chaincfg.Para return unbondingInfo, nil } +// TODO: verify to remove, not used in babylon, only for tests // findFPIdx returns the index of the given finality provider // among all restaked finality providers func (d *BTCDelegation) findFPIdx(fpBTCPK *bbn.BIP340PubKey) (int, error) { @@ -324,6 +325,7 @@ func (d *BTCDelegation) findFPIdx(fpBTCPK *bbn.BIP340PubKey) (int, error) { // the signatures on the slashing tx, such that the slashing tx obtains full // witness and can be submitted to Bitcoin. // This happens after the finality provider is slashed and its SK is extracted. +// TODO: verify not used func (d *BTCDelegation) BuildSlashingTxWithWitness(bsParams *Params, btcNet *chaincfg.Params, fpSK *btcec.PrivateKey) (*wire.MsgTx, error) { stakingMsgTx, err := bbn.NewBTCTxFromBytes(d.StakingTx) if err != nil { @@ -373,6 +375,7 @@ func (d *BTCDelegation) BuildSlashingTxWithWitness(bsParams *Params, btcNet *cha return slashingMsgTxWithWitness, nil } +// TODO: verify to remove, func not used by babylon, used in side car processes. func (d *BTCDelegation) BuildUnbondingSlashingTxWithWitness(bsParams *Params, btcNet *chaincfg.Params, fpSK *btcec.PrivateKey) (*wire.MsgTx, error) { unbondingMsgTx, err := bbn.NewBTCTxFromBytes(d.BtcUndelegation.UnbondingTx) if err != nil { diff --git a/x/btcstaking/types/genesis.go b/x/btcstaking/types/genesis.go index ab1a56d77..a258e6808 100644 --- a/x/btcstaking/types/genesis.go +++ b/x/btcstaking/types/genesis.go @@ -11,6 +11,6 @@ func DefaultGenesis() *GenesisState { // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { - + // TODO: add validation to other properties of genstate. return gs.Params.Validate() } diff --git a/x/btcstaking/types/genesis.pb.go b/x/btcstaking/types/genesis.pb.go index 2ccb1d1d9..eb1f839f3 100644 --- a/x/btcstaking/types/genesis.pb.go +++ b/x/btcstaking/types/genesis.pb.go @@ -5,6 +5,7 @@ package types import ( fmt "fmt" + github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -26,6 +27,21 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the btcstaking module's genesis state. type GenesisState struct { Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // finality_providers all the finality providers registered. + FinalityProviders []*FinalityProvider `protobuf:"bytes,2,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` + // btc_delegations all the btc delegations in the state. + BtcDelegations []*BTCDelegation `protobuf:"bytes,3,rep,name=btc_delegations,json=btcDelegations,proto3" json:"btc_delegations,omitempty"` + // voting_powers the voting power of every finality provider at every block height. + VotingPowers []*VotingPowerFP `protobuf:"bytes,4,rep,name=voting_powers,json=votingPowers,proto3" json:"voting_powers,omitempty"` + // block_height_chains the block height of babylon and bitcoin. + BlockHeightChains []*BlockHeightBbnToBtc `protobuf:"bytes,5,rep,name=block_height_chains,json=blockHeightChains,proto3" json:"block_height_chains,omitempty"` + // btc_delegators contains all the btc delegators with the associated finality provider. + BtcDelegators []*BTCDelegator `protobuf:"bytes,6,rep,name=btc_delegators,json=btcDelegators,proto3" json:"btc_delegators,omitempty"` + // all the events and its indexes. + Events []*EventIndex `protobuf:"bytes,7,rep,name=events,proto3" json:"events,omitempty"` + // vp_dst_cache is the table of all providers voting power with the total at one specific block. + // TODO: remove this after not storing in the keeper store it anymore. + VpDstCache []*VotingPowerDistCacheBlkHeight `protobuf:"bytes,8,rep,name=vp_dst_cache,json=vpDstCache,proto3" json:"vp_dst_cache,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -68,8 +84,344 @@ func (m *GenesisState) GetParams() Params { return Params{} } +func (m *GenesisState) GetFinalityProviders() []*FinalityProvider { + if m != nil { + return m.FinalityProviders + } + return nil +} + +func (m *GenesisState) GetBtcDelegations() []*BTCDelegation { + if m != nil { + return m.BtcDelegations + } + return nil +} + +func (m *GenesisState) GetVotingPowers() []*VotingPowerFP { + if m != nil { + return m.VotingPowers + } + return nil +} + +func (m *GenesisState) GetBlockHeightChains() []*BlockHeightBbnToBtc { + if m != nil { + return m.BlockHeightChains + } + return nil +} + +func (m *GenesisState) GetBtcDelegators() []*BTCDelegator { + if m != nil { + return m.BtcDelegators + } + return nil +} + +func (m *GenesisState) GetEvents() []*EventIndex { + if m != nil { + return m.Events + } + return nil +} + +func (m *GenesisState) GetVpDstCache() []*VotingPowerDistCacheBlkHeight { + if m != nil { + return m.VpDstCache + } + return nil +} + +// VotingPowerFP contains the information about the voting power +// of an finality provider in a specific block height. +type VotingPowerFP struct { + // block_height is the height of the block the voting power was stored. + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // fp_btc_pk the finality provider btc public key. + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // voting_power is the power of the finality provider at this specific block height. + VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` +} + +func (m *VotingPowerFP) Reset() { *m = VotingPowerFP{} } +func (m *VotingPowerFP) String() string { return proto.CompactTextString(m) } +func (*VotingPowerFP) ProtoMessage() {} +func (*VotingPowerFP) Descriptor() ([]byte, []int) { + return fileDescriptor_85d7b95fa5620238, []int{1} +} +func (m *VotingPowerFP) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VotingPowerFP) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VotingPowerFP.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 *VotingPowerFP) XXX_Merge(src proto.Message) { + xxx_messageInfo_VotingPowerFP.Merge(m, src) +} +func (m *VotingPowerFP) XXX_Size() int { + return m.Size() +} +func (m *VotingPowerFP) XXX_DiscardUnknown() { + xxx_messageInfo_VotingPowerFP.DiscardUnknown(m) +} + +var xxx_messageInfo_VotingPowerFP proto.InternalMessageInfo + +func (m *VotingPowerFP) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *VotingPowerFP) GetVotingPower() uint64 { + if m != nil { + return m.VotingPower + } + return 0 +} + +// VotingPowerDistCacheBlkHeight the total voting power of the finality providers at one specific block height +type VotingPowerDistCacheBlkHeight struct { + // block_height is the height of the block the voting power distribution cached was stored. + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // vp_distribution the finality providers distribution cache at that height. + VpDistribution *VotingPowerDistCache `protobuf:"bytes,2,opt,name=vp_distribution,json=vpDistribution,proto3" json:"vp_distribution,omitempty"` +} + +func (m *VotingPowerDistCacheBlkHeight) Reset() { *m = VotingPowerDistCacheBlkHeight{} } +func (m *VotingPowerDistCacheBlkHeight) String() string { return proto.CompactTextString(m) } +func (*VotingPowerDistCacheBlkHeight) ProtoMessage() {} +func (*VotingPowerDistCacheBlkHeight) Descriptor() ([]byte, []int) { + return fileDescriptor_85d7b95fa5620238, []int{2} +} +func (m *VotingPowerDistCacheBlkHeight) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *VotingPowerDistCacheBlkHeight) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_VotingPowerDistCacheBlkHeight.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 *VotingPowerDistCacheBlkHeight) XXX_Merge(src proto.Message) { + xxx_messageInfo_VotingPowerDistCacheBlkHeight.Merge(m, src) +} +func (m *VotingPowerDistCacheBlkHeight) XXX_Size() int { + return m.Size() +} +func (m *VotingPowerDistCacheBlkHeight) XXX_DiscardUnknown() { + xxx_messageInfo_VotingPowerDistCacheBlkHeight.DiscardUnknown(m) +} + +var xxx_messageInfo_VotingPowerDistCacheBlkHeight proto.InternalMessageInfo + +func (m *VotingPowerDistCacheBlkHeight) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + +func (m *VotingPowerDistCacheBlkHeight) GetVpDistribution() *VotingPowerDistCache { + if m != nil { + return m.VpDistribution + } + return nil +} + +// BlockHeightBbnToBtc stores the btc <-> bbn block. +type BlockHeightBbnToBtc struct { + // block_height_bbn is the height of the block in the babylon chain. + BlockHeightBbn uint64 `protobuf:"varint,1,opt,name=block_height_bbn,json=blockHeightBbn,proto3" json:"block_height_bbn,omitempty"` + // block_height_btc is the height of the block in the BTC. + BlockHeightBtc uint64 `protobuf:"varint,2,opt,name=block_height_btc,json=blockHeightBtc,proto3" json:"block_height_btc,omitempty"` +} + +func (m *BlockHeightBbnToBtc) Reset() { *m = BlockHeightBbnToBtc{} } +func (m *BlockHeightBbnToBtc) String() string { return proto.CompactTextString(m) } +func (*BlockHeightBbnToBtc) ProtoMessage() {} +func (*BlockHeightBbnToBtc) Descriptor() ([]byte, []int) { + return fileDescriptor_85d7b95fa5620238, []int{3} +} +func (m *BlockHeightBbnToBtc) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlockHeightBbnToBtc) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlockHeightBbnToBtc.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 *BlockHeightBbnToBtc) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlockHeightBbnToBtc.Merge(m, src) +} +func (m *BlockHeightBbnToBtc) XXX_Size() int { + return m.Size() +} +func (m *BlockHeightBbnToBtc) XXX_DiscardUnknown() { + xxx_messageInfo_BlockHeightBbnToBtc.DiscardUnknown(m) +} + +var xxx_messageInfo_BlockHeightBbnToBtc proto.InternalMessageInfo + +func (m *BlockHeightBbnToBtc) GetBlockHeightBbn() uint64 { + if m != nil { + return m.BlockHeightBbn + } + return 0 +} + +func (m *BlockHeightBbnToBtc) GetBlockHeightBtc() uint64 { + if m != nil { + return m.BlockHeightBtc + } + return 0 +} + +// BTCDelegator BTC delegator information with the associated finality provider. +type BTCDelegator struct { + // idx the btc delegator index. + Idx *BTCDelegatorDelegationIndex `protobuf:"bytes,1,opt,name=idx,proto3" json:"idx,omitempty"` + // fp_btc_pk the finality provider btc public key. + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // del_btc_pk the delegator btc public key. + DelBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=del_btc_pk,json=delBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"del_btc_pk,omitempty"` +} + +func (m *BTCDelegator) Reset() { *m = BTCDelegator{} } +func (m *BTCDelegator) String() string { return proto.CompactTextString(m) } +func (*BTCDelegator) ProtoMessage() {} +func (*BTCDelegator) Descriptor() ([]byte, []int) { + return fileDescriptor_85d7b95fa5620238, []int{4} +} +func (m *BTCDelegator) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BTCDelegator) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BTCDelegator.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 *BTCDelegator) XXX_Merge(src proto.Message) { + xxx_messageInfo_BTCDelegator.Merge(m, src) +} +func (m *BTCDelegator) XXX_Size() int { + return m.Size() +} +func (m *BTCDelegator) XXX_DiscardUnknown() { + xxx_messageInfo_BTCDelegator.DiscardUnknown(m) +} + +var xxx_messageInfo_BTCDelegator proto.InternalMessageInfo + +func (m *BTCDelegator) GetIdx() *BTCDelegatorDelegationIndex { + if m != nil { + return m.Idx + } + return nil +} + +// EventIndex contains the event and its index. +type EventIndex struct { + // idx is the index the event was stored. + Idx uint64 `protobuf:"varint,1,opt,name=idx,proto3" json:"idx,omitempty"` + // block_height_btc is the height of the block in the BTC chain. + BlockHeightBtc uint64 `protobuf:"varint,2,opt,name=block_height_btc,json=blockHeightBtc,proto3" json:"block_height_btc,omitempty"` + // event the event stored. + Event *EventPowerDistUpdate `protobuf:"bytes,3,opt,name=event,proto3" json:"event,omitempty"` +} + +func (m *EventIndex) Reset() { *m = EventIndex{} } +func (m *EventIndex) String() string { return proto.CompactTextString(m) } +func (*EventIndex) ProtoMessage() {} +func (*EventIndex) Descriptor() ([]byte, []int) { + return fileDescriptor_85d7b95fa5620238, []int{5} +} +func (m *EventIndex) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventIndex.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 *EventIndex) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventIndex.Merge(m, src) +} +func (m *EventIndex) XXX_Size() int { + return m.Size() +} +func (m *EventIndex) XXX_DiscardUnknown() { + xxx_messageInfo_EventIndex.DiscardUnknown(m) +} + +var xxx_messageInfo_EventIndex proto.InternalMessageInfo + +func (m *EventIndex) GetIdx() uint64 { + if m != nil { + return m.Idx + } + return 0 +} + +func (m *EventIndex) GetBlockHeightBtc() uint64 { + if m != nil { + return m.BlockHeightBtc + } + return 0 +} + +func (m *EventIndex) GetEvent() *EventPowerDistUpdate { + if m != nil { + return m.Event + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "babylon.btcstaking.v1.GenesisState") + proto.RegisterType((*VotingPowerFP)(nil), "babylon.btcstaking.v1.VotingPowerFP") + proto.RegisterType((*VotingPowerDistCacheBlkHeight)(nil), "babylon.btcstaking.v1.VotingPowerDistCacheBlkHeight") + proto.RegisterType((*BlockHeightBbnToBtc)(nil), "babylon.btcstaking.v1.BlockHeightBbnToBtc") + proto.RegisterType((*BTCDelegator)(nil), "babylon.btcstaking.v1.BTCDelegator") + proto.RegisterType((*EventIndex)(nil), "babylon.btcstaking.v1.EventIndex") } func init() { @@ -77,20 +429,51 @@ func init() { } var fileDescriptor_85d7b95fa5620238 = []byte{ - // 202 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4e, 0x4a, 0x4c, 0xaa, - 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x2e, 0x2e, 0x49, 0xcc, 0xce, 0xcc, 0x4b, 0xd7, 0x2f, - 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x12, 0x85, 0x2a, 0xd2, 0x43, 0x28, 0xd2, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, - 0xab, 0xd0, 0x07, 0xb1, 0x20, 0x8a, 0xa5, 0x94, 0xb0, 0x9b, 0x58, 0x90, 0x58, 0x94, 0x98, 0x0b, - 0x35, 0x50, 0xc9, 0x9b, 0x8b, 0xc7, 0x1d, 0x62, 0x43, 0x70, 0x49, 0x62, 0x49, 0xaa, 0x90, 0x35, - 0x17, 0x1b, 0x44, 0x5e, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x56, 0x0f, 0xab, 0x8d, 0x7a, - 0x01, 0x60, 0x45, 0x4e, 0x2c, 0x27, 0xee, 0xc9, 0x33, 0x04, 0x41, 0xb5, 0x38, 0xf9, 0x9c, 0x78, - 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, - 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x51, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, - 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xc0, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, 0x18, 0x47, 0xbf, 0x02, - 0xd9, 0x91, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, 0x17, 0x1a, 0x03, 0x02, 0x00, 0x00, - 0xff, 0xff, 0x64, 0xf3, 0x4d, 0xdf, 0x19, 0x01, 0x00, 0x00, + // 699 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x4f, 0x4f, 0xdb, 0x30, + 0x18, 0xc6, 0x1b, 0x5a, 0x0a, 0x73, 0x4b, 0x01, 0xb3, 0x49, 0x11, 0x12, 0x05, 0xc2, 0xfe, 0x54, + 0x9b, 0x94, 0x8e, 0x82, 0x26, 0x4d, 0x3b, 0x2d, 0x74, 0x6c, 0xec, 0x8f, 0x14, 0x65, 0x1d, 0x07, + 0x2e, 0x51, 0x9c, 0xb8, 0xa9, 0xd5, 0x10, 0x47, 0xb1, 0xc9, 0xe8, 0x67, 0xd8, 0x65, 0xc7, 0x7d, + 0x85, 0x7d, 0x13, 0x8e, 0x1c, 0xa7, 0x1d, 0xd0, 0x04, 0x5f, 0x62, 0xa7, 0x69, 0x8a, 0x13, 0x48, + 0x60, 0x2d, 0x74, 0x9a, 0x76, 0xab, 0xad, 0xe7, 0xfd, 0xf9, 0x7d, 0x5e, 0x3f, 0x6e, 0xc0, 0x1a, + 0xb2, 0xd0, 0xc0, 0xa3, 0x7e, 0x13, 0x71, 0x9b, 0x71, 0xab, 0x4f, 0x7c, 0xb7, 0x19, 0xad, 0x37, + 0x5d, 0xec, 0x63, 0x46, 0x98, 0x1a, 0x84, 0x94, 0x53, 0x78, 0x27, 0x15, 0xa9, 0x99, 0x48, 0x8d, + 0xd6, 0x17, 0x6f, 0xbb, 0xd4, 0xa5, 0x42, 0xd1, 0x8c, 0x7f, 0x25, 0xe2, 0x45, 0x65, 0x38, 0x31, + 0xb0, 0x42, 0x6b, 0x3f, 0x05, 0x2e, 0xde, 0x1f, 0xae, 0xc9, 0xe1, 0x13, 0xdd, 0xbd, 0xe1, 0x3a, + 0xe2, 0xdb, 0xd8, 0xe7, 0x24, 0xc2, 0xd7, 0x1f, 0x89, 0x23, 0xec, 0xf3, 0xf4, 0x48, 0xe5, 0x67, + 0x09, 0x54, 0x5f, 0x26, 0xae, 0xde, 0x73, 0x8b, 0x63, 0xf8, 0x0c, 0x94, 0x93, 0x9e, 0x64, 0x69, + 0x45, 0x6a, 0x54, 0x5a, 0x4b, 0xea, 0x50, 0x97, 0xaa, 0x2e, 0x44, 0x5a, 0xe9, 0xe8, 0x64, 0xb9, + 0x60, 0xa4, 0x25, 0x70, 0x17, 0xc0, 0x2e, 0xf1, 0x2d, 0x8f, 0xf0, 0x81, 0x19, 0x84, 0x34, 0x22, + 0x0e, 0x0e, 0x99, 0x3c, 0xb1, 0x52, 0x6c, 0x54, 0x5a, 0x0f, 0x46, 0x80, 0xb6, 0xd3, 0x02, 0x3d, + 0xd5, 0x1b, 0xf3, 0xdd, 0x2b, 0x3b, 0x0c, 0xbe, 0x03, 0xb3, 0x88, 0xdb, 0xa6, 0x83, 0x3d, 0xec, + 0x5a, 0x9c, 0x50, 0x9f, 0xc9, 0x45, 0x01, 0xbd, 0x3b, 0x02, 0xaa, 0x75, 0xb6, 0xda, 0x17, 0x62, + 0xa3, 0x86, 0xb8, 0x9d, 0x2d, 0x19, 0xdc, 0x01, 0x33, 0x11, 0xe5, 0xc4, 0x77, 0xcd, 0x80, 0x7e, + 0x8c, 0x3b, 0x2c, 0x5d, 0x0b, 0xdb, 0x15, 0x5a, 0x3d, 0x96, 0x6e, 0xeb, 0x46, 0x35, 0xca, 0x96, + 0x0c, 0xee, 0x81, 0x05, 0xe4, 0x51, 0xbb, 0x6f, 0xf6, 0x30, 0x71, 0x7b, 0xdc, 0xb4, 0x7b, 0x16, + 0xf1, 0x99, 0x3c, 0x29, 0x80, 0x0f, 0x47, 0x75, 0x17, 0x57, 0xbc, 0x12, 0x05, 0x1a, 0xf2, 0x3b, + 0x54, 0xe3, 0xb6, 0x31, 0x8f, 0xb2, 0xcd, 0x2d, 0x01, 0x81, 0xaf, 0x41, 0x2d, 0xe7, 0x9a, 0x86, + 0x4c, 0x2e, 0x0b, 0xec, 0xda, 0x8d, 0xa6, 0x69, 0x68, 0xcc, 0x64, 0x9e, 0x69, 0xc8, 0xe0, 0x53, + 0x50, 0x4e, 0xee, 0x5d, 0x9e, 0x12, 0x8c, 0xd5, 0x11, 0x8c, 0x17, 0xb1, 0x68, 0xc7, 0x77, 0xf0, + 0xa1, 0x91, 0x16, 0xc0, 0x5d, 0x50, 0x8d, 0x02, 0xd3, 0x61, 0xdc, 0xb4, 0x2d, 0xbb, 0x87, 0xe5, + 0x69, 0x01, 0xd8, 0xbc, 0x79, 0x58, 0x6d, 0xc2, 0xf8, 0x56, 0x5c, 0xa2, 0x79, 0xa9, 0x31, 0x03, + 0x44, 0x41, 0x3b, 0xdd, 0x54, 0xbe, 0x4a, 0x60, 0xe6, 0xd2, 0x68, 0xe1, 0x2a, 0xa8, 0xe6, 0x87, + 0x29, 0x12, 0x58, 0x32, 0x2a, 0xb9, 0xc9, 0x40, 0x03, 0xdc, 0xea, 0x06, 0x66, 0x3c, 0x96, 0xa0, + 0x2f, 0x4f, 0xac, 0x48, 0x8d, 0xaa, 0xf6, 0xe4, 0xfb, 0xc9, 0x72, 0xcb, 0x25, 0xbc, 0x77, 0x80, + 0x54, 0x9b, 0xee, 0x37, 0xd3, 0xbe, 0xc4, 0x4d, 0x9c, 0x2f, 0x9a, 0x7c, 0x10, 0x60, 0xa6, 0x6a, + 0x3b, 0xfa, 0xc6, 0xe6, 0x63, 0xfd, 0x00, 0xbd, 0xc1, 0x03, 0x63, 0xaa, 0x1b, 0x68, 0xdc, 0xd6, + 0xfb, 0xf1, 0xb1, 0xf9, 0x38, 0xc8, 0xc5, 0xe4, 0xd8, 0xdc, 0x3d, 0x2b, 0x5f, 0x24, 0xb0, 0x74, + 0xad, 0xb3, 0x71, 0x7a, 0xef, 0x80, 0xd9, 0x78, 0x90, 0x84, 0xf1, 0x90, 0xa0, 0x83, 0x38, 0x8a, + 0xc2, 0x41, 0xa5, 0xf5, 0xe8, 0x2f, 0x66, 0x69, 0xd4, 0xa2, 0xa0, 0x9d, 0x43, 0x28, 0x04, 0x2c, + 0x0c, 0xc9, 0x13, 0x6c, 0x80, 0xb9, 0x4b, 0xc1, 0x44, 0xc8, 0x4f, 0x7b, 0xaa, 0xa1, 0x4b, 0xf2, + 0x3f, 0x95, 0xdc, 0x16, 0x7d, 0x5d, 0x51, 0x72, 0x5b, 0xf9, 0x25, 0x81, 0x6a, 0x3e, 0x64, 0xb0, + 0x0d, 0x8a, 0xc4, 0x39, 0x4c, 0xff, 0x29, 0x5a, 0x63, 0xc4, 0x32, 0x7b, 0x85, 0x49, 0xc6, 0xe2, + 0xf2, 0xff, 0x72, 0xa7, 0x1d, 0x00, 0x1c, 0xec, 0x9d, 0x43, 0x8b, 0xff, 0x04, 0x9d, 0x76, 0xb0, + 0x27, 0xa8, 0xca, 0x27, 0x09, 0x80, 0xec, 0x85, 0xc0, 0xb9, 0xcc, 0x7e, 0x29, 0xb1, 0x32, 0xf6, + 0x2c, 0xe1, 0x73, 0x30, 0x29, 0xde, 0x97, 0xe8, 0x6d, 0x74, 0x04, 0xc4, 0x69, 0x17, 0x09, 0xf8, + 0x10, 0x38, 0x16, 0xc7, 0x46, 0x52, 0xa9, 0xbd, 0x3d, 0x3a, 0xad, 0x4b, 0xc7, 0xa7, 0x75, 0xe9, + 0xc7, 0x69, 0x5d, 0xfa, 0x7c, 0x56, 0x2f, 0x1c, 0x9f, 0xd5, 0x0b, 0xdf, 0xce, 0xea, 0x85, 0xbd, + 0x1b, 0x5d, 0x1e, 0xe6, 0xbf, 0x09, 0xc2, 0x32, 0x2a, 0x8b, 0x0f, 0xc2, 0xc6, 0xef, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xef, 0xb6, 0x5b, 0xcd, 0xfb, 0x06, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -113,48 +496,1293 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.VpDstCache) > 0 { + for iNdEx := len(m.VpDstCache) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VpDstCache[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.Events) > 0 { + for iNdEx := len(m.Events) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Events[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.BtcDelegators) > 0 { + for iNdEx := len(m.BtcDelegators) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BtcDelegators[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.BlockHeightChains) > 0 { + for iNdEx := len(m.BlockHeightChains) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BlockHeightChains[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.VotingPowers) > 0 { + for iNdEx := len(m.VotingPowers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.VotingPowers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.BtcDelegations) > 0 { + for iNdEx := len(m.BtcDelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.BtcDelegations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.FinalityProviders) > 0 { + for iNdEx := len(m.FinalityProviders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FinalityProviders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } { size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *VotingPowerFP) 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 *VotingPowerFP) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VotingPowerFP) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.VotingPower != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.VotingPower)) + i-- + dAtA[i] = 0x18 + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *VotingPowerDistCacheBlkHeight) 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 *VotingPowerDistCacheBlkHeight) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *VotingPowerDistCacheBlkHeight) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.VpDistribution != nil { + { + size, err := m.VpDistribution.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *BlockHeightBbnToBtc) 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 *BlockHeightBbnToBtc) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlockHeightBbnToBtc) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.BlockHeightBtc != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeightBtc)) + i-- + dAtA[i] = 0x10 + } + if m.BlockHeightBbn != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeightBbn)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *BTCDelegator) 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 *BTCDelegator) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BTCDelegator) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.DelBtcPk != nil { + { + size := m.DelBtcPk.Size() + i -= size + if _, err := m.DelBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Idx != nil { + { + size, err := m.Idx.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventIndex) 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 *EventIndex) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Event != nil { + { + size, err := m.Event.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.BlockHeightBtc != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeightBtc)) + i-- + dAtA[i] = 0x10 + } + if m.Idx != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Idx)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.FinalityProviders) > 0 { + for _, e := range m.FinalityProviders { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.BtcDelegations) > 0 { + for _, e := range m.BtcDelegations { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.VotingPowers) > 0 { + for _, e := range m.VotingPowers { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.BlockHeightChains) > 0 { + for _, e := range m.BlockHeightChains { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.BtcDelegators) > 0 { + for _, e := range m.BtcDelegators { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.VpDstCache) > 0 { + for _, e := range m.VpDstCache { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *VotingPowerFP) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeight)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.VotingPower != 0 { + n += 1 + sovGenesis(uint64(m.VotingPower)) + } + return n +} + +func (m *VotingPowerDistCacheBlkHeight) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeight)) + } + if m.VpDistribution != nil { + l = m.VpDistribution.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *BlockHeightBbnToBtc) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeightBbn != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeightBbn)) + } + if m.BlockHeightBtc != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeightBtc)) + } + return n +} + +func (m *BTCDelegator) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Idx != nil { + l = m.Idx.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.DelBtcPk != nil { + l = m.DelBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *EventIndex) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Idx != 0 { + n += 1 + sovGenesis(uint64(m.Idx)) + } + if m.BlockHeightBtc != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeightBtc)) + } + if m.Event != nil { + l = m.Event.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalityProviders", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FinalityProviders = append(m.FinalityProviders, &FinalityProvider{}) + if err := m.FinalityProviders[len(m.FinalityProviders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcDelegations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BtcDelegations = append(m.BtcDelegations, &BTCDelegation{}) + if err := m.BtcDelegations[len(m.BtcDelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPowers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VotingPowers = append(m.VotingPowers, &VotingPowerFP{}) + if err := m.VotingPowers[len(m.VotingPowers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeightChains", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BlockHeightChains = append(m.BlockHeightChains, &BlockHeightBbnToBtc{}) + if err := m.BlockHeightChains[len(m.BlockHeightChains)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcDelegators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BtcDelegators = append(m.BtcDelegators, &BTCDelegator{}) + if err := m.BtcDelegators[len(m.BtcDelegators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, &EventIndex{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VpDstCache", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.VpDstCache = append(m.VpDstCache, &VotingPowerDistCacheBlkHeight{}) + if err := m.VpDstCache[len(m.VpDstCache)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VotingPowerFP) 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 ErrIntOverflowGenesis + } + 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: VotingPowerFP: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VotingPowerFP: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) + } + m.VotingPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotingPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VotingPowerDistCacheBlkHeight) 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 ErrIntOverflowGenesis + } + 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: VotingPowerDistCacheBlkHeight: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VotingPowerDistCacheBlkHeight: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field VpDistribution", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.VpDistribution == nil { + m.VpDistribution = &VotingPowerDistCache{} + } + if err := m.VpDistribution.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlockHeightBbnToBtc) 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 ErrIntOverflowGenesis + } + 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: BlockHeightBbnToBtc: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockHeightBbnToBtc: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeightBbn", wireType) + } + m.BlockHeightBbn = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeightBbn |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeightBtc", wireType) + } + m.BlockHeightBtc = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeightBtc |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - i-- - dAtA[i] = 0xa - return len(dAtA) - i, nil -} -func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { - offset -= sovGenesis(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ + if iNdEx > l { + return io.ErrUnexpectedEOF } - dAtA[offset] = uint8(v) - return base + return nil } -func (m *GenesisState) Size() (n int) { - if m == nil { - return 0 +func (m *BTCDelegator) 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 ErrIntOverflowGenesis + } + 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: BTCDelegator: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BTCDelegator: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Idx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Idx == nil { + m.Idx = &BTCDelegatorDelegationIndex{} + } + if err := m.Idx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.DelBtcPk = &v + if err := m.DelBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) - return n -} -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *GenesisState) Unmarshal(dAtA []byte) error { +func (m *EventIndex) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -177,15 +1805,53 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + return fmt.Errorf("proto: EventIndex: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: EventIndex: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Idx", wireType) + } + m.Idx = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Idx |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeightBtc", wireType) + } + m.BlockHeightBtc = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeightBtc |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Event", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -212,7 +1878,10 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Event == nil { + m.Event = &EventPowerDistUpdate{} + } + if err := m.Event.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/btcstaking/types/keys.go b/x/btcstaking/types/keys.go index 12af82740..099e808cd 100644 --- a/x/btcstaking/types/keys.go +++ b/x/btcstaking/types/keys.go @@ -24,7 +24,3 @@ var ( VotingPowerDistCacheKey = []byte{0x07} // key prefix for voting power distribution cache PowerDistUpdateKey = []byte{0x08} // key prefix for power distribution update events ) - -func KeyPrefix(p string) []byte { - return []byte(p) -} diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index 286a671e2..57fcac889 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + btcstk "github.com/babylonchain/babylon/btcstaking" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -110,7 +111,7 @@ func (k Keeper) voteSigs(ctx context.Context) ([]*types.VoteSig, error) { voteSigs := make([]*types.VoteSig, 0) for ; iter.Valid(); iter.Next() { // key contains the height and the fp - blkHeight, fpBTCPK, err := parseBlkHeightAndPubKeyFromStoreKey(iter.Key()) + blkHeight, fpBTCPK, err := btcstk.ParseBlkHeightAndPubKeyFromStoreKey(iter.Key()) if err != nil { return nil, err } @@ -159,23 +160,6 @@ func (k Keeper) publicRandomness(ctx context.Context) ([]*types.PublicRandomness return commtRandoms, nil } -// parseBlkHeightAndPubKeyFromStoreKey expects to receive a key with -// BigEndianUint64(blkHeight) || BIP340PubKey(fpBTCPK) -func parseBlkHeightAndPubKeyFromStoreKey(key []byte) (blkHeight uint64, fpBTCPK *bbn.BIP340PubKey, err error) { - sizeBigEndian := 8 - if len(key) < sizeBigEndian+1 { - return 0, nil, fmt.Errorf("key not long enough to parse block height and BIP340PubKey: %s", key) - } - - fpBTCPK, err = bbn.NewBIP340PubKey(key[sizeBigEndian:]) - if err != nil { - return 0, nil, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) - } - - blkHeight = sdk.BigEndianToUint64(key[:sizeBigEndian]) - return blkHeight, fpBTCPK, nil -} - // parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with // BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { From c3eb71bffa0943ded0ca38adb30957a9fde9a2a3 Mon Sep 17 00:00:00 2001 From: Vitalis Salis Date: Fri, 22 Mar 2024 18:56:53 +0400 Subject: [PATCH 056/119] fix: incentive: Use the LCD query path utilised by other modules (#590) --- proto/babylon/incentive/query.proto | 10 +-- .../e2e/configurer/chain/queries_incentive.go | 8 +- x/incentive/types/query.pb.go | 80 +++++++++---------- x/incentive/types/query.pb.gw.go | 8 +- 4 files changed, 53 insertions(+), 53 deletions(-) diff --git a/proto/babylon/incentive/query.proto b/proto/babylon/incentive/query.proto index 22985e390..1239786e1 100644 --- a/proto/babylon/incentive/query.proto +++ b/proto/babylon/incentive/query.proto @@ -12,19 +12,19 @@ option go_package = "github.com/babylonchain/babylon/x/incentive/types"; service Query { // Parameters queries the parameters of the module. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/babylonchain/babylon/incentive/params"; + option (google.api.http).get = "/babylon/incentive/params"; } // RewardGauge queries the reward gauge of a given stakeholder address rpc RewardGauges(QueryRewardGaugesRequest) returns (QueryRewardGaugesResponse) { - option (google.api.http).get = "/babylonchain/babylon/incentive/address/{address}/reward_gauge"; + option (google.api.http).get = "/babylon/incentive/address/{address}/reward_gauge"; } // BTCStakingGauge queries the BTC staking gauge of a given height rpc BTCStakingGauge(QueryBTCStakingGaugeRequest) returns (QueryBTCStakingGaugeResponse) { - option (google.api.http).get = "/babylonchain/babylon/incentive/btc_staking_gauge/{height}"; + option (google.api.http).get = "/babylon/incentive/btc_staking_gauge/{height}"; } // BTCTimestampingGauge queries the BTC timestamping gauge of a given epoch rpc BTCTimestampingGauge(QueryBTCTimestampingGaugeRequest) returns (QueryBTCTimestampingGaugeResponse) { - option (google.api.http).get = "/babylonchain/babylon/incentive/btc_timestamping_gauge/{epoch_num}"; + option (google.api.http).get = "/babylon/incentive/btc_timestamping_gauge/{epoch_num}"; } } @@ -72,4 +72,4 @@ message QueryBTCTimestampingGaugeRequest { message QueryBTCTimestampingGaugeResponse { // gauge is the BTC timestamping gauge at the queried epoch Gauge gauge = 1; -} \ No newline at end of file +} diff --git a/test/e2e/configurer/chain/queries_incentive.go b/test/e2e/configurer/chain/queries_incentive.go index 5f8dce124..9416d9866 100644 --- a/test/e2e/configurer/chain/queries_incentive.go +++ b/test/e2e/configurer/chain/queries_incentive.go @@ -11,7 +11,7 @@ import ( ) func (n *NodeConfig) QueryBTCStakingGauge(height uint64) (*incentivetypes.Gauge, error) { - path := fmt.Sprintf("/babylonchain/babylon/incentive/btc_staking_gauge/%d", height) + path := fmt.Sprintf("/babylon/incentive/btc_staking_gauge/%d", height) bz, err := n.QueryGRPCGateway(path, url.Values{}) if err != nil { return nil, err @@ -26,7 +26,7 @@ func (n *NodeConfig) QueryBTCStakingGauge(height uint64) (*incentivetypes.Gauge, } func (n *NodeConfig) QueryIncentiveParams() (*incentivetypes.Params, error) { - path := "/babylonchain/babylon/incentive/params" + path := "/babylon/incentive/params" bz, err := n.QueryGRPCGateway(path, url.Values{}) require.NoError(n.t, err) @@ -39,7 +39,7 @@ func (n *NodeConfig) QueryIncentiveParams() (*incentivetypes.Params, error) { } func (n *NodeConfig) QueryRewardGauge(sAddr sdk.AccAddress) (map[string]*incentivetypes.RewardGauge, error) { - path := fmt.Sprintf("/babylonchain/babylon/incentive/address/%s/reward_gauge", sAddr.String()) + path := fmt.Sprintf("/babylon/incentive/address/%s/reward_gauge", sAddr.String()) bz, err := n.QueryGRPCGateway(path, url.Values{}) if err != nil { return nil, err @@ -53,7 +53,7 @@ func (n *NodeConfig) QueryRewardGauge(sAddr sdk.AccAddress) (map[string]*incenti } func (n *NodeConfig) QueryBTCTimestampingGauge(epoch uint64) (*incentivetypes.Gauge, error) { - path := fmt.Sprintf("/babylonchain/babylon/incentive/btc_timestamping_gauge/%d", epoch) + path := fmt.Sprintf("/babylon/incentive/btc_timestamping_gauge/%d", epoch) bz, err := n.QueryGRPCGateway(path, url.Values{}) if err != nil { return nil, err diff --git a/x/incentive/types/query.pb.go b/x/incentive/types/query.pb.go index bacf7178d..46405c449 100644 --- a/x/incentive/types/query.pb.go +++ b/x/incentive/types/query.pb.go @@ -404,46 +404,46 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/query.proto", fileDescriptor_e1a59cc0c7c44135) } var fileDescriptor_e1a59cc0c7c44135 = []byte{ - // 615 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0xeb, 0x6e, 0x2d, 0xcc, 0x1b, 0x82, 0x99, 0x0a, 0x65, 0xd9, 0x08, 0x5d, 0x24, 0xa6, - 0x4a, 0xa0, 0x44, 0x74, 0x45, 0xa0, 0x09, 0x0d, 0x54, 0xfe, 0x49, 0x20, 0x55, 0x90, 0xed, 0xc4, - 0xa5, 0x72, 0x53, 0x2b, 0x8d, 0xd6, 0xc4, 0x59, 0xe2, 0x0c, 0xaa, 0xa9, 0x17, 0x2e, 0x5c, 0x91, - 0xf8, 0x24, 0x5c, 0xf8, 0x0c, 0xbb, 0x80, 0x26, 0x71, 0xe1, 0x84, 0xa0, 0xe5, 0x83, 0xa0, 0xda, - 0x6e, 0x95, 0xad, 0xe9, 0xda, 0xed, 0xe6, 0xfa, 0x7d, 0xfc, 0xbc, 0xbf, 0xd7, 0x79, 0x5c, 0x78, - 0xb3, 0x81, 0x1b, 0x9d, 0x36, 0xf5, 0x4d, 0xd7, 0xb7, 0x89, 0xcf, 0xdc, 0x03, 0x62, 0xee, 0xc7, - 0x24, 0xec, 0x18, 0x41, 0x48, 0x19, 0x45, 0xcb, 0xb2, 0x6c, 0x8c, 0xca, 0x6a, 0xc1, 0xa1, 0x0e, - 0xe5, 0x55, 0x73, 0xb0, 0x12, 0x42, 0x75, 0xcd, 0xa1, 0xd4, 0x69, 0x13, 0x13, 0x07, 0xae, 0x89, - 0x7d, 0x9f, 0x32, 0xcc, 0x5c, 0xea, 0x47, 0xb2, 0xaa, 0x8d, 0x77, 0x09, 0x70, 0x88, 0xbd, 0x61, - 0x7d, 0x7d, 0xbc, 0x3e, 0x5a, 0x09, 0x89, 0x5e, 0x80, 0xe8, 0xed, 0x00, 0xec, 0x0d, 0x3f, 0x67, - 0x91, 0xfd, 0x98, 0x44, 0x4c, 0xaf, 0xc1, 0xeb, 0x27, 0x76, 0xa3, 0x80, 0xfa, 0x11, 0x41, 0x0f, - 0x60, 0x5e, 0xf8, 0x2b, 0xa0, 0x08, 0x4a, 0x8b, 0xe5, 0x15, 0x63, 0x6c, 0x0e, 0x43, 0x1c, 0xa9, - 0xce, 0x1f, 0xfd, 0xbe, 0x95, 0xb1, 0xa4, 0x5c, 0xaf, 0x40, 0x85, 0xfb, 0x59, 0xe4, 0x3d, 0x0e, - 0x9b, 0x2f, 0x71, 0xec, 0x90, 0x61, 0x2f, 0xa4, 0xc0, 0x4b, 0xb8, 0xd9, 0x0c, 0x49, 0x24, 0x5c, - 0x17, 0xac, 0xe1, 0x4f, 0xfd, 0x2f, 0x80, 0x2b, 0x29, 0xc7, 0x24, 0x8c, 0x0d, 0xaf, 0x84, 0x7c, - 0xbf, 0xee, 0xf0, 0x82, 0x02, 0x8a, 0x73, 0xa5, 0xc5, 0xf2, 0x76, 0x0a, 0xd3, 0x44, 0x13, 0x23, - 0xb9, 0xf9, 0xdc, 0x67, 0x61, 0xc7, 0x5a, 0x0a, 0x13, 0x5b, 0x6a, 0x1d, 0x2e, 0x8f, 0x49, 0xd0, - 0x35, 0x38, 0xb7, 0x47, 0x3a, 0x92, 0x76, 0xb0, 0x44, 0x15, 0x98, 0x3b, 0xc0, 0xed, 0x98, 0x28, - 0x59, 0x7e, 0x2f, 0x5a, 0x0a, 0x43, 0xc2, 0xc6, 0x12, 0xe2, 0xad, 0xec, 0x43, 0xa0, 0xdf, 0x87, - 0xab, 0x9c, 0xae, 0xba, 0xfb, 0x74, 0x87, 0xe1, 0x3d, 0xd7, 0x77, 0x84, 0x44, 0x5e, 0xce, 0x0d, - 0x98, 0x6f, 0x11, 0xd7, 0x69, 0x31, 0xde, 0x6d, 0xde, 0x92, 0xbf, 0xf4, 0x1a, 0x5c, 0x4b, 0x3f, - 0x26, 0x2f, 0xc7, 0x80, 0x39, 0x7e, 0x2b, 0xf2, 0x43, 0x29, 0x29, 0x40, 0x12, 0x85, 0xcb, 0xf4, - 0xc7, 0xb0, 0x38, 0xf4, 0xdb, 0x75, 0x3d, 0x12, 0x31, 0xec, 0x05, 0xa7, 0x59, 0x56, 0xe1, 0x02, - 0x09, 0xa8, 0xdd, 0xaa, 0xfb, 0xb1, 0x27, 0x71, 0x2e, 0xf3, 0x8d, 0x5a, 0xec, 0xe9, 0x3b, 0x70, - 0xfd, 0x0c, 0x83, 0x8b, 0x51, 0x95, 0x7f, 0xe4, 0x60, 0x8e, 0xbb, 0xa2, 0x4f, 0x00, 0xe6, 0x45, - 0xb2, 0xd0, 0xed, 0x49, 0x1f, 0xf8, 0x44, 0x84, 0xd5, 0x8d, 0x69, 0x32, 0xc1, 0xa4, 0x1b, 0x1f, - 0x7f, 0xfe, 0xfb, 0x92, 0x2d, 0xa1, 0x0d, 0x53, 0xea, 0xed, 0x16, 0x76, 0x7d, 0x73, 0xd2, 0xcb, - 0x42, 0x5f, 0x01, 0x5c, 0x4a, 0x46, 0x02, 0xdd, 0x99, 0x2d, 0x70, 0x82, 0xea, 0xee, 0x79, 0xd2, - 0xa9, 0xbf, 0xe0, 0x6c, 0x4f, 0xd0, 0xf6, 0x34, 0x36, 0xf9, 0x62, 0xcc, 0x43, 0xb9, 0xe8, 0x9a, - 0xc9, 0xa7, 0x81, 0xbe, 0x01, 0x78, 0xf5, 0x54, 0x52, 0x90, 0x31, 0x89, 0x24, 0x3d, 0x89, 0xaa, - 0x39, 0xb3, 0x5e, 0xc2, 0x57, 0x39, 0xfc, 0x23, 0xb4, 0x35, 0x0d, 0xbe, 0xc1, 0xec, 0x7a, 0x24, - 0x1c, 0x04, 0xaf, 0x79, 0x28, 0x52, 0xde, 0x45, 0xdf, 0x01, 0x2c, 0xa4, 0x25, 0x0a, 0x6d, 0x9e, - 0x41, 0x33, 0x29, 0xc0, 0x6a, 0xe5, 0x7c, 0x87, 0xe4, 0x1c, 0xaf, 0xf8, 0x1c, 0xcf, 0x50, 0x75, - 0x96, 0x39, 0x58, 0xc2, 0x66, 0x38, 0xcc, 0xe8, 0xd1, 0x74, 0xab, 0xaf, 0x8f, 0x7a, 0x1a, 0x38, - 0xee, 0x69, 0xe0, 0x4f, 0x4f, 0x03, 0x9f, 0xfb, 0x5a, 0xe6, 0xb8, 0xaf, 0x65, 0x7e, 0xf5, 0xb5, - 0xcc, 0xbb, 0x7b, 0x8e, 0xcb, 0x5a, 0x71, 0xc3, 0xb0, 0xa9, 0x97, 0xde, 0xe7, 0x43, 0xa2, 0x13, - 0xeb, 0x04, 0x24, 0x6a, 0xe4, 0xf9, 0x3f, 0xf8, 0xe6, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0b, - 0x2f, 0x3f, 0xc6, 0x6c, 0x06, 0x00, 0x00, + // 610 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x3f, 0x6f, 0xd3, 0x40, + 0x18, 0xc6, 0xe3, 0xb4, 0x09, 0xf4, 0x5a, 0x04, 0x3d, 0x22, 0xe4, 0x38, 0xc5, 0x24, 0x96, 0x40, + 0x95, 0x00, 0x5b, 0xcd, 0x1f, 0x15, 0x90, 0x00, 0x29, 0x08, 0x31, 0x20, 0x45, 0xe0, 0x76, 0x62, + 0x89, 0x2e, 0xce, 0xc9, 0xb1, 0x1a, 0xfb, 0x5c, 0xfb, 0x5c, 0x08, 0x55, 0x16, 0x3e, 0x01, 0x12, + 0x13, 0x3b, 0x0b, 0xdf, 0x82, 0xb1, 0x63, 0x25, 0x16, 0x26, 0x04, 0x09, 0x1f, 0x04, 0xe5, 0xee, + 0x1c, 0xb9, 0x8d, 0x5d, 0x5a, 0xb6, 0xf3, 0xfb, 0x3e, 0xef, 0xf3, 0xfe, 0x72, 0x7e, 0x1c, 0x70, + 0xb3, 0x87, 0x7a, 0xa3, 0x21, 0xf1, 0x0c, 0xc7, 0xb3, 0xb0, 0x47, 0x9d, 0x03, 0x6c, 0xec, 0x47, + 0x38, 0x18, 0xe9, 0x7e, 0x40, 0x28, 0x81, 0xeb, 0xa2, 0xad, 0xcf, 0xdb, 0x4a, 0xc9, 0x26, 0x36, + 0x61, 0x5d, 0x63, 0x76, 0xe2, 0x42, 0x65, 0xc3, 0x26, 0xc4, 0x1e, 0x62, 0x03, 0xf9, 0x8e, 0x81, + 0x3c, 0x8f, 0x50, 0x44, 0x1d, 0xe2, 0x85, 0xa2, 0xab, 0x2e, 0x6e, 0xf1, 0x51, 0x80, 0xdc, 0xb8, + 0x5f, 0x5b, 0xec, 0xcf, 0x4f, 0x5c, 0xa2, 0x95, 0x00, 0x7c, 0x3d, 0x03, 0x7b, 0xc5, 0xe6, 0x4c, + 0xbc, 0x1f, 0xe1, 0x90, 0x6a, 0x1d, 0x70, 0xfd, 0x44, 0x35, 0xf4, 0x89, 0x17, 0x62, 0xb8, 0x0d, + 0x8a, 0xdc, 0x5f, 0x96, 0xaa, 0xd2, 0xe6, 0x6a, 0xbd, 0xac, 0x2f, 0xfc, 0x0e, 0x9d, 0x8f, 0xb4, + 0x97, 0x8f, 0x7e, 0xde, 0xca, 0x99, 0x42, 0xae, 0x35, 0x81, 0xcc, 0xfc, 0x4c, 0xfc, 0x16, 0x05, + 0xfd, 0x17, 0x28, 0xb2, 0x71, 0xbc, 0x0b, 0xca, 0xe0, 0x12, 0xea, 0xf7, 0x03, 0x1c, 0x72, 0xd7, + 0x15, 0x33, 0x7e, 0xd4, 0x7e, 0x4b, 0xa0, 0x9c, 0x32, 0x26, 0x60, 0x2c, 0x70, 0x25, 0x60, 0xf5, + 0xae, 0xcd, 0x1a, 0xb2, 0x54, 0x5d, 0xda, 0x5c, 0xad, 0x3f, 0x49, 0x61, 0xca, 0x34, 0xd1, 0x93, + 0xc5, 0xe7, 0x1e, 0x0d, 0x46, 0xe6, 0x5a, 0x90, 0x28, 0x29, 0x5d, 0xb0, 0xbe, 0x20, 0x81, 0xd7, + 0xc0, 0xd2, 0x1e, 0x1e, 0x09, 0xda, 0xd9, 0x11, 0x36, 0x41, 0xe1, 0x00, 0x0d, 0x23, 0x2c, 0xe7, + 0xd9, 0xbd, 0xa8, 0x29, 0x0c, 0x09, 0x1b, 0x93, 0x8b, 0x1f, 0xe5, 0x1f, 0x48, 0x5a, 0x0b, 0x54, + 0x18, 0x5d, 0x7b, 0xf7, 0xd9, 0x0e, 0x45, 0x7b, 0x8e, 0x67, 0x73, 0x89, 0xb8, 0x9c, 0x1b, 0xa0, + 0x38, 0xc0, 0x8e, 0x3d, 0xa0, 0x6c, 0xdb, 0xb2, 0x29, 0x9e, 0xb4, 0x0e, 0xd8, 0x48, 0x1f, 0x13, + 0x97, 0xa3, 0x83, 0x02, 0xbb, 0x15, 0xf1, 0xa2, 0xe4, 0x14, 0x20, 0x81, 0xc2, 0x64, 0xda, 0x53, + 0x50, 0x8d, 0xfd, 0x76, 0x1d, 0x17, 0x87, 0x14, 0xb9, 0xfe, 0x69, 0x96, 0x0a, 0x58, 0xc1, 0x3e, + 0xb1, 0x06, 0x5d, 0x2f, 0x72, 0x05, 0xce, 0x65, 0x56, 0xe8, 0x44, 0xae, 0xb6, 0x03, 0x6a, 0x67, + 0x18, 0xfc, 0x1f, 0x55, 0xfd, 0x73, 0x01, 0x14, 0x98, 0x2b, 0x7c, 0x0f, 0x8a, 0x3c, 0x58, 0xf0, + 0x76, 0xd6, 0xfb, 0x3d, 0x91, 0x60, 0xe5, 0xce, 0xbf, 0x64, 0x1c, 0x49, 0xab, 0x7d, 0xf8, 0xfe, + 0xe7, 0x53, 0xbe, 0x02, 0xcb, 0x46, 0xd6, 0xb7, 0x04, 0xbf, 0x48, 0x60, 0x2d, 0x19, 0x02, 0x78, + 0xf7, 0x7c, 0x11, 0xe3, 0x20, 0xf7, 0x2e, 0x92, 0x47, 0xed, 0x21, 0xc3, 0x69, 0xc0, 0xad, 0x14, + 0x1c, 0xf1, 0x59, 0x18, 0x87, 0xe2, 0x30, 0x36, 0x92, 0xf9, 0x87, 0x5f, 0x25, 0x70, 0xf5, 0x54, + 0x1c, 0xa0, 0x9e, 0xb5, 0x3c, 0x3d, 0x6e, 0x8a, 0x71, 0x6e, 0xbd, 0xe0, 0x6d, 0x31, 0x5e, 0x03, + 0xde, 0x4f, 0xe1, 0xed, 0x51, 0xab, 0x1b, 0xf2, 0x21, 0x8e, 0x68, 0x1c, 0xf2, 0xf4, 0x8e, 0xe1, + 0x37, 0x09, 0x94, 0xd2, 0x92, 0x02, 0x1b, 0x67, 0x00, 0x64, 0x05, 0x53, 0x69, 0x5e, 0x6c, 0x48, + 0xa0, 0x3f, 0x66, 0xe8, 0xdb, 0xb0, 0x95, 0x81, 0x4e, 0x13, 0x93, 0x31, 0xff, 0x3c, 0xff, 0xe3, + 0xf6, 0xcb, 0xa3, 0x89, 0x2a, 0x1d, 0x4f, 0x54, 0xe9, 0xd7, 0x44, 0x95, 0x3e, 0x4e, 0xd5, 0xdc, + 0xf1, 0x54, 0xcd, 0xfd, 0x98, 0xaa, 0xb9, 0x37, 0x5b, 0xb6, 0x43, 0x07, 0x51, 0x4f, 0xb7, 0x88, + 0x1b, 0x5b, 0x5b, 0x03, 0xe4, 0x78, 0xf3, 0x3d, 0xef, 0x12, 0x9b, 0xe8, 0xc8, 0xc7, 0x61, 0xaf, + 0xc8, 0xfe, 0x8c, 0x1b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x1f, 0x12, 0x0c, 0x37, 0x06, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/incentive/types/query.pb.gw.go b/x/incentive/types/query.pb.gw.go index 5b8468f06..584a8f9c2 100644 --- a/x/incentive/types/query.pb.gw.go +++ b/x/incentive/types/query.pb.gw.go @@ -436,13 +436,13 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylonchain", "babylon", "incentive", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"babylon", "incentive", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_RewardGauges_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"babylonchain", "babylon", "incentive", "address", "reward_gauge"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_RewardGauges_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"babylon", "incentive", "address", "reward_gauge"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_BTCStakingGauge_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylonchain", "babylon", "incentive", "btc_staking_gauge", "height"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_BTCStakingGauge_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"babylon", "incentive", "btc_staking_gauge", "height"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_BTCTimestampingGauge_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylonchain", "babylon", "incentive", "btc_timestamping_gauge", "epoch_num"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_BTCTimestampingGauge_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"babylon", "incentive", "btc_timestamping_gauge", "epoch_num"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( From aacea7fcff6762146c76ef26b8a9d8111068dff4 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 26 Mar 2024 08:56:11 +0100 Subject: [PATCH 057/119] Increase min expedited deposit (#596) --- cmd/babylond/cmd/genesis.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 51ff7928c..702280617 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -286,13 +286,14 @@ func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint6 genParams.MintParams.GoalBonded = sdkmath.LegacyMustNewDecFromStr(fmt.Sprintf("%f", goalBonded)) genParams.GovParams = govv1.DefaultParams() + // TODO investigate those numbers genParams.GovParams.MinDeposit = sdk.NewCoins(sdk.NewCoin( genParams.NativeCoinMetadatas[0].Base, sdkmath.NewInt(2_500_000_000), )) genParams.GovParams.ExpeditedMinDeposit = sdk.NewCoins(sdk.NewCoin( genParams.NativeCoinMetadatas[0].Base, - sdkmath.NewInt(2_500_000_000), + sdkmath.NewInt(10_000_000_000), )) genParams.CrisisConstantFee = sdk.NewCoin( From 8d76979ef05742206a74166c480c69b44b082798 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 27 Mar 2024 15:20:09 +1100 Subject: [PATCH 058/119] fix: fix non-determinism in voting power rotation (#597) --- x/btcstaking/keeper/power_dist_change.go | 19 +++++-- x/btcstaking/keeper/power_dist_change_test.go | 52 +++++++++++++++++++ 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index cd34cf8fa..1f0ff4de2 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "sort" "cosmossdk.io/store/prefix" bbn "github.com/babylonchain/babylon/types" @@ -51,7 +52,7 @@ func (k Keeper) UpdatePowerDist(ctx context.Context) { // reconcile old voting power distribution cache and new events // to construct the new distribution - newDc := k.processAllPowerDistUpdateEvents(ctx, dc, events, maxActiveFps) + newDc := k.ProcessAllPowerDistUpdateEvents(ctx, dc, events, maxActiveFps) // record voting power and cache for this height k.recordVotingPowerAndCache(ctx, newDc, maxActiveFps) @@ -90,13 +91,13 @@ func (k Keeper) recordMetrics(dc *types.VotingPowerDistCache, maxActiveFps uint3 // TODO: record number of BTC delegations under different status } -// processAllPowerDistUpdateEvents processes all events that affect +// ProcessAllPowerDistUpdateEvents processes all events that affect // voting power distribution and returns a new distribution cache. // The following events will affect the voting power distribution: // - newly active BTC delegations // - newly unbonded BTC delegations // - slashed finality providers -func (k Keeper) processAllPowerDistUpdateEvents( +func (k Keeper) ProcessAllPowerDistUpdateEvents( ctx context.Context, dc *types.VotingPowerDistCache, events []*types.EventPowerDistUpdate, @@ -192,7 +193,16 @@ func (k Keeper) processAllPowerDistUpdateEvents( /* process new BTC delegations under new finality providers in activeBTCDels */ - for fpBTCPKHex, fpActiveBTCDels := range activeBTCDels { + // sort new finality providers in activeBTCDels to ensure determinism + fpBTCPKHexList := make([]string, 0, len(activeBTCDels)) + for fpBTCPKHex := range activeBTCDels { + fpBTCPKHexList = append(fpBTCPKHexList, fpBTCPKHex) + } + sort.SliceStable(fpBTCPKHexList, func(i, j int) bool { + return fpBTCPKHexList[i] < fpBTCPKHexList[j] + }) + // for each new finality provider, apply the new BTC delegations to the new dist cache + for _, fpBTCPKHex := range fpBTCPKHexList { // get the finality provider and initialise its dist info fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(fpBTCPKHex) if err != nil { @@ -205,6 +215,7 @@ func (k Keeper) processAllPowerDistUpdateEvents( fpDistInfo := types.NewFinalityProviderDistInfo(newFP) // add each BTC delegation + fpActiveBTCDels := activeBTCDels[fpBTCPKHex] for _, d := range fpActiveBTCDels { fpDistInfo.AddBTCDel(d) } diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index 393693167..a37776ee7 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -7,10 +7,62 @@ import ( "github.com/babylonchain/babylon/testutil/datagen" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/btcsuite/btcd/btcec/v2" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) +func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters + h.GenAndApplyParams(r) + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) + + // generate and insert a number of new finality providers + fpPKs := []*btcec.PublicKey{} + for i := 0; i < 5; i++ { + _, fpPK, _ := h.CreateFinalityProvider(r) + fpPKs = append(fpPKs, fpPK) + } + + // empty dist cache + dc := types.NewVotingPowerDistCache() + + stakingValue := int64(2 * 10e8) + + // generate many new BTC delegations under each finality provider, and their corresponding events + events := []*types.EventPowerDistUpdate{} + for _, fpPK := range fpPKs { + for i := 0; i < 5; i++ { + _, _, _, _, del := h.CreateDelegation(r, fpPK, changeAddress.EncodeAddress(), stakingValue, 1000) + event := types.NewEventPowerDistUpdateWithBTCDel(&types.EventBTCDelegationStateUpdate{ + StakingTxHash: del.MustGetStakingTxHash().String(), + NewState: types.BTCDelegationStatus_ACTIVE, + }) + events = append(events, event) + } + } + + newDc := h.BTCStakingKeeper.ProcessAllPowerDistUpdateEvents(h.Ctx, dc, events, 100) + for i := 0; i < 10; i++ { + newDc2 := h.BTCStakingKeeper.ProcessAllPowerDistUpdateEvents(h.Ctx, dc, events, 100) + require.Equal(t, newDc, newDc2) + } + }) +} + func FuzzFinalityProviderEvents(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) From 5a5ada1efb5232a833ba8000cb35255866aa6fd0 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 27 Mar 2024 18:04:45 +0100 Subject: [PATCH 059/119] Versioned staking params (#593) * Add explicit params versioning * Export/Import genesis for versioned params --- cmd/babylond/cmd/genesis.go | 3 +- proto/babylon/btcstaking/v1/btcstaking.proto | 2 + proto/babylon/btcstaking/v1/genesis.proto | 5 +- proto/babylon/btcstaking/v1/params.proto | 10 + proto/babylon/btcstaking/v1/query.proto | 19 +- x/btcstaking/genesis_test.go | 3 +- x/btcstaking/keeper/btc_delegations.go | 3 +- x/btcstaking/keeper/genesis.go | 10 +- x/btcstaking/keeper/genesis_test.go | 2 +- x/btcstaking/keeper/msg_server.go | 66 +- x/btcstaking/keeper/msg_server_test.go | 67 +- x/btcstaking/keeper/params.go | 123 +++- x/btcstaking/keeper/params_test.go | 74 ++ x/btcstaking/keeper/query_params.go | 15 + x/btcstaking/keeper/query_params_test.go | 44 ++ x/btcstaking/types/btcstaking.pb.go | 187 +++-- x/btcstaking/types/errors.go | 1 + x/btcstaking/types/genesis.go | 17 +- x/btcstaking/types/genesis.pb.go | 128 ++-- x/btcstaking/types/genesis_test.go | 18 +- x/btcstaking/types/params.pb.go | 280 +++++++- x/btcstaking/types/query.go | 1 + x/btcstaking/types/query.pb.go | 678 +++++++++++++++---- x/btcstaking/types/query.pb.gw.go | 101 +++ 24 files changed, 1492 insertions(+), 365 deletions(-) diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 702280617..0c8d84319 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -154,7 +154,8 @@ func PrepareGenesis( // btcstaking module genesis btcstakingGenState := btcstakingtypes.DefaultGenesis() - btcstakingGenState.Params = genesisParams.BtcstakingParams + // here we can start only from single params, which will be initially labelled version 0 + btcstakingGenState.Params = []*btcstakingtypes.Params{&genesisParams.BtcstakingParams} genesisState[btcstakingtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(btcstakingGenState) // finality module genesis diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 93feda6d3..9f9778a5c 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -98,6 +98,8 @@ message BTCDelegation { uint32 unbonding_time = 13; // btc_undelegation is the information about the early unbonding path of the BTC delegation BTCUndelegation btc_undelegation = 14; + // version of the params used to validate the delegation + uint32 params_version = 15; } // BTCUndelegation contains the information about the early unbonding path of the BTC delegation diff --git a/proto/babylon/btcstaking/v1/genesis.proto b/proto/babylon/btcstaking/v1/genesis.proto index 5b3f67070..bc8529454 100644 --- a/proto/babylon/btcstaking/v1/genesis.proto +++ b/proto/babylon/btcstaking/v1/genesis.proto @@ -11,7 +11,8 @@ option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; // GenesisState defines the btcstaking module's genesis state. message GenesisState { - Params params = 1 [(gogoproto.nullable) = false]; + // different versions of params used through the history of the chain + repeated Params params = 1; // finality_providers all the finality providers registered. repeated FinalityProvider finality_providers = 2; // btc_delegations all the btc delegations in the state. @@ -74,4 +75,4 @@ message EventIndex { uint64 block_height_btc = 2; // event the event stored. EventPowerDistUpdate event = 3; -} \ No newline at end of file +} diff --git a/proto/babylon/btcstaking/v1/params.proto b/proto/babylon/btcstaking/v1/params.proto index d48483be7..d705a3c1f 100644 --- a/proto/babylon/btcstaking/v1/params.proto +++ b/proto/babylon/btcstaking/v1/params.proto @@ -51,3 +51,13 @@ message Params { (gogoproto.nullable) = false ]; } + +// StoredParams attach information about the version of stored parameters +message StoredParams { + // version of the stored parameters. Each parameters update + // increments version number by 1 + uint32 version = 1; + + // NOTE: Parameters must always be provided + Params params = 2 [(gogoproto.nullable) = false]; +} diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 492de61d4..e3f385b57 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -19,6 +19,10 @@ service Query { rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { option (google.api.http).get = "/babylon/btcstaking/v1/params"; } + // ParamsByVersion queries the parameters of the module for a specific version of past params. + rpc ParamsByVersion(QueryParamsByVersionRequest) returns (QueryParamsByVersionResponse) { + option (google.api.http).get = "/babylon/btcstaking/v1/params/{version}"; + } // FinalityProviders queries all finality providers rpc FinalityProviders(QueryFinalityProvidersRequest) returns (QueryFinalityProvidersResponse) { @@ -76,6 +80,17 @@ message QueryParamsResponse { Params params = 1 [(gogoproto.nullable) = false]; } +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsByVersionRequest { + uint32 version = 1; +} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsByVersionResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} + // QueryFinalityProvidersRequest is the request type for the // Query/FinalityProviders RPC method. message QueryFinalityProvidersRequest { @@ -267,6 +282,8 @@ message BTCDelegationResponse { uint32 unbonding_time = 13; // undelegation_response is the undelegation info of this delegation. BTCUndelegationResponse undelegation_response = 14; + // params version used to validate delegation + uint32 params_version = 15; } // BTCUndelegationResponse provides all necessary info about the undeleagation @@ -330,4 +347,4 @@ message FinalityProviderResponse { uint64 height = 8; // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 9; -} \ No newline at end of file +} diff --git a/x/btcstaking/genesis_test.go b/x/btcstaking/genesis_test.go index 9b2dd0a14..928def07c 100644 --- a/x/btcstaking/genesis_test.go +++ b/x/btcstaking/genesis_test.go @@ -11,8 +11,9 @@ import ( ) func TestGenesis(t *testing.T) { + p := types.DefaultParams() genesisState := types.GenesisState{ - Params: types.DefaultParams(), + Params: []*types.Params{&p}, } k, ctx := keepertest.BTCStakingKeeper(t, nil, nil) diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index cb4a25a72..beade47a1 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -78,6 +78,7 @@ func (k Keeper) addCovenantSigsToBTCDelegation( parsedSlashingAdaptorSignatures []asig.AdaptorSignature, unbondingTxSig *bbn.BIP340Signature, parsedUnbondingSlashingAdaptorSignatures []asig.AdaptorSignature, + params *types.Params, ) { // All is fine add received signatures to the BTC delegation and BtcUndelegation btcDel.AddCovenantSigs( @@ -91,7 +92,7 @@ func (k Keeper) addCovenantSigsToBTCDelegation( // If reaching the covenant quorum after this msg, the BTC delegation becomes // active. Then, record and emit this event - if len(btcDel.CovenantSigs) == int(k.GetParams(ctx).CovenantQuorum) { + if len(btcDel.CovenantSigs) == int(params.CovenantQuorum) { // notify subscriber event := &types.EventBTCDelegationStateUpdate{ StakingTxHash: btcDel.MustGetStakingTxHash().String(), diff --git a/x/btcstaking/keeper/genesis.go b/x/btcstaking/keeper/genesis.go index a63e3e319..211329c43 100644 --- a/x/btcstaking/keeper/genesis.go +++ b/x/btcstaking/keeper/genesis.go @@ -12,8 +12,12 @@ import ( // InitGenesis initializes the module's state from a provided genesis state. func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { - if err := k.SetParams(ctx, gs.Params); err != nil { - return err + // save all past params versions + for _, p := range gs.Params { + params := p + if err := k.SetParams(ctx, *params); err != nil { + return err + } } for _, fp := range gs.FinalityProviders { @@ -87,7 +91,7 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) } return &types.GenesisState{ - Params: k.GetParams(ctx), + Params: k.GetAllParams(ctx), FinalityProviders: fps, BtcDelegations: dels, VotingPowers: vpFps, diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go index 174317034..5c0eb2606 100644 --- a/x/btcstaking/keeper/genesis_test.go +++ b/x/btcstaking/keeper/genesis_test.go @@ -121,7 +121,7 @@ func TestExportGenesis(t *testing.T) { gs, err := k.ExportGenesis(ctx) h.NoError(err) - require.Equal(t, k.GetParams(ctx), gs.Params) + require.Equal(t, k.GetParams(ctx), *gs.Params[0]) // finality providers correctFps := 0 diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 2952abdec..2bfdcb253 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -160,11 +160,11 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, status.Errorf(codes.InvalidArgument, "%v", err) } - params := ms.GetParams(ctx) + vp := ms.GetParamsWithVersion(ctx) btccParams := ms.btccKeeper.GetParams(ctx) kValue, wValue := btccParams.BtcConfirmationDepth, btccParams.CheckpointFinalizationTimeout - minUnbondingTime := types.MinimumUnbondingTime(params, btccParams) + minUnbondingTime := types.MinimumUnbondingTime(vp.Params, btccParams) // Check unbonding time (staking time from unbonding tx) is larger than min unbonding time // which is larger value from: @@ -209,7 +209,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre if err != nil { return nil, types.ErrInvalidStakingTx.Wrapf("cannot parse finality provider PK list: %v", err) } - covenantPKs, err := bbn.NewBTCPKsFromBIP340PKs(params.CovenantPks) + covenantPKs, err := bbn.NewBTCPKsFromBIP340PKs(vp.Params.CovenantPks) if err != nil { // programming error panic("failed to parse covenant PKs in KVStore") @@ -220,7 +220,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre stakerPk, fpPKs, covenantPKs, - params.CovenantQuorum, + vp.Params.CovenantQuorum, uint16(req.StakingTime), btcutil.Amount(req.StakingValue), ms.btcNet, @@ -267,7 +267,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre // decode slashing address // TODO: Decode slashing address only once, as it is the same for all BTC delegations - slashingAddr, err := btcutil.DecodeAddress(params.SlashingAddress, ms.btcNet) + slashingAddr, err := btcutil.DecodeAddress(vp.Params.SlashingAddress, ms.btcNet) if err != nil { panic(fmt.Errorf("failed to decode slashing address in genesis: %w", err)) } @@ -277,8 +277,8 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre slashingMsgTx, stakingMsgTx, stakingOutputIdx, - params.MinSlashingTxFeeSat, - params.SlashingRate, + vp.Params.MinSlashingTxFeeSat, + vp.Params.SlashingRate, slashingAddr, stakerPk, validatedUnbondingTime, @@ -321,8 +321,9 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre SlashingTx: req.SlashingTx, DelegatorSig: req.DelegatorSlashingSig, UnbondingTime: uint32(validatedUnbondingTime), - CovenantSigs: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant - BtcUndelegation: nil, // this will be constructed in below code + CovenantSigs: nil, // NOTE: covenant signature will be submitted in a separate msg by covenant + BtcUndelegation: nil, // this will be constructed in below code + ParamsVersion: vp.Version, // version of the params against delegations was validated } /* @@ -353,7 +354,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre newBTCDel.BtcPk.MustToBTCPK(), fpPKs, covenantPKs, - params.CovenantQuorum, + vp.Params.CovenantQuorum, validatedUnbondingTime, btcutil.Amount(req.UnbondingValue), ms.btcNet, @@ -373,9 +374,9 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre unbondingSlashingMsgTx, unbondingMsgTx, unbondingOutputIdx, - params.MinSlashingTxFeeSat, - params.SlashingRate, - params.MustGetSlashingAddress(ms.btcNet), + vp.Params.MinSlashingTxFeeSat, + vp.Params.SlashingRate, + vp.Params.MustGetSlashingAddress(ms.btcNet), stakerPk, validatedUnbondingTime, ms.btcNet, @@ -415,7 +416,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding tx fee must be larger that 0") } - minUnbondingValue := caluculateMinimumUnbondingValue(stakingMsgTx.TxOut[stakingOutputIdx], ¶ms) + minUnbondingValue := caluculateMinimumUnbondingValue(stakingMsgTx.TxOut[stakingOutputIdx], &vp.Params) if btcutil.Amount(unbondingMsgTx.TxOut[0].Value) < minUnbondingValue { return nil, types.ErrInvalidUnbondingTx.Wrapf("unbonding output value must be at least %s, based on staking output", minUnbondingValue) } @@ -438,6 +439,22 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return &types.MsgCreateBTCDelegationResponse{}, nil } +func (ms msgServer) getBTCDelWithParams( + ctx context.Context, + stakingTxHash string) (*types.BTCDelegation, *types.Params, error) { + btcDel, err := ms.GetBTCDelegation(ctx, stakingTxHash) + if err != nil { + return nil, nil, err + } + + bsParams := ms.GetParamsByVersion(ctx, btcDel.ParamsVersion) + if bsParams == nil { + panic("params version in BTC delegation is not found") + } + + return btcDel, bsParams, nil +} + // AddCovenantSig adds signatures from covenants to a BTC delegation // TODO: refactor this handler. Now it's too convoluted func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCovenantSigs) (*types.MsgAddCovenantSigsResponse, error) { @@ -449,10 +466,8 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove return nil, status.Errorf(codes.InvalidArgument, "%v", err) } - params := ms.GetParams(ctx) + btcDel, params, err := ms.getBTCDelWithParams(ctx, req.StakingTxHash) - // ensure BTC delegation exists - btcDel, err := ms.GetBTCDelegation(ctx, req.StakingTxHash) if err != nil { return nil, err } @@ -492,7 +507,7 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove /* Verify each covenant adaptor signature over slashing tx */ - stakingInfo, err := btcDel.GetStakingInfo(¶ms, ms.btcNet) + stakingInfo, err := btcDel.GetStakingInfo(params, ms.btcNet) if err != nil { panic(fmt.Errorf("failed to get staking info from a verified delegation: %w", err)) } @@ -549,7 +564,7 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove verify each adaptor signature on slashing unbonding tx */ unbondingOutput := unbondingMsgTx.TxOut[0] // unbonding tx always have only one output - unbondingInfo, err := btcDel.GetUnbondingInfo(¶ms, ms.btcNet) + unbondingInfo, err := btcDel.GetUnbondingInfo(params, ms.btcNet) if err != nil { panic(err) } @@ -579,6 +594,7 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove parsedSlashingAdaptorSignatures, req.UnbondingTxSig, parsedUnbondingSlashingAdaptorSignatures, + params, ) return &types.MsgAddCovenantSigsResponse{}, nil @@ -596,10 +612,8 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele return nil, status.Errorf(codes.InvalidArgument, "%v", err) } - bsParams := ms.GetParams(ctx) + btcDel, bsParams, err := ms.getBTCDelWithParams(ctx, req.StakingTxHash) - // ensure BTC delegation exists - btcDel, err := ms.GetBTCDelegation(ctx, req.StakingTxHash) if err != nil { return nil, err } @@ -616,7 +630,7 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele if err != nil { panic(fmt.Errorf("failed to parse unbonding tx from existing delegation with hash %s : %v", req.StakingTxHash, err)) } - stakingInfo, err := btcDel.GetStakingInfo(&bsParams, ms.btcNet) + stakingInfo, err := btcDel.GetStakingInfo(bsParams, ms.btcNet) if err != nil { panic(fmt.Errorf("failed to get staking info from a verified delegation: %w", err)) } @@ -650,13 +664,13 @@ func (ms msgServer) SelectiveSlashingEvidence(goCtx context.Context, req *types. defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeySelectiveSlashingEvidence) ctx := sdk.UnwrapSDKContext(goCtx) - bsParams := ms.GetParams(ctx) - // ensure BTC delegation exists - btcDel, err := ms.GetBTCDelegation(ctx, req.StakingTxHash) + btcDel, bsParams, err := ms.getBTCDelWithParams(ctx, req.StakingTxHash) + if err != nil { return nil, err } + // ensure the BTC delegation is active, or its BTC undelegation receives an // unbonding signature from the staker btcTip := ms.btclcKeeper.GetTipInfo(ctx) diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index a9248dc86..fe72f8b77 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -11,7 +11,6 @@ import ( sdkmath "cosmossdk.io/math" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" testhelper "github.com/babylonchain/babylon/testutil/helper" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -80,7 +79,7 @@ func FuzzMsgEditFinalityProvider(f *testing.F) { f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - h := helper.NewHelper(t) + h := testhelper.NewHelper(t) bsKeeper := h.App.BTCStakingKeeper msgSrvr := keeper.NewMsgServerImpl(bsKeeper) @@ -174,6 +173,70 @@ func FuzzCreateBTCDelegation(f *testing.F) { }) } +func TestProperVersionInDelegation(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper) + + // set all parameters + h.GenAndApplyParams(r) + + changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) + require.NoError(t, err) + + // generate and insert new finality provider + _, fpPK, _ := h.CreateFinalityProvider(r) + + // generate and insert new BTC delegation + stakingValue := int64(2 * 10e8) + stakingTxHash, _, _, _, _ := h.CreateDelegation( + r, + fpPK, + changeAddress.EncodeAddress(), + stakingValue, + 1000, + ) + + // ensure consistency between the msg and the BTC delegation in DB + actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) + h.NoError(err) + err = actualDel.ValidateBasic() + h.NoError(err) + // Current version will be `1` as: + // - version `0` is initialized by `NewHelper` + // - version `1` is set by `GenAndApplyParams` + require.Equal(t, uint32(1), actualDel.ParamsVersion) + + customMinUnbondingTime := uint32(2000) + currentParams := h.BTCStakingKeeper.GetParams(h.Ctx) + currentParams.MinUnbondingTime = 2000 + // Update new params + err = h.BTCStakingKeeper.SetParams(h.Ctx, currentParams) + require.NoError(t, err) + // create new delegation + stakingTxHash1, _, _, _, err := h.CreateDelegationCustom( + r, + fpPK, + changeAddress.EncodeAddress(), + stakingValue, + 1000, + stakingValue-1000, + uint16(customMinUnbondingTime)+1, + ) + require.NoError(t, err) + actualDel1, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash1) + h.NoError(err) + err = actualDel1.ValidateBasic() + h.NoError(err) + // Assert that the new delegation has the updated params version + require.Equal(t, uint32(2), actualDel1.ParamsVersion) +} + func FuzzAddCovenantSigs(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) diff --git a/x/btcstaking/keeper/params.go b/x/btcstaking/keeper/params.go index 4859efb28..4a9978c7a 100644 --- a/x/btcstaking/keeper/params.go +++ b/x/btcstaking/keeper/params.go @@ -2,34 +2,131 @@ package keeper import ( "context" + "encoding/binary" + "fmt" + "cosmossdk.io/math" + "cosmossdk.io/store/prefix" "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cosmos/cosmos-sdk/runtime" ) +// cosmos-sdk does not have utils for uint32 +func uint32ToBytes(v uint32) []byte { + var buf [4]byte + binary.BigEndian.PutUint32(buf[:], v) + return buf[:] +} +func uint32FromBytes(b []byte) (uint32, error) { + if len(b) != 4 { + return 0, fmt.Errorf("invalid uint32 bytes length: %d", len(b)) + } + + return binary.BigEndian.Uint32(b), nil +} + +func mustUint32FromBytes(b []byte) uint32 { + v, err := uint32FromBytes(b) + if err != nil { + panic(err) + } + + return v +} + +func (k Keeper) paramsStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.ParamsKey) +} + +func (k Keeper) nextParamsVersion(ctx context.Context) uint32 { + paramsStore := k.paramsStore(ctx) + it := paramsStore.ReverseIterator(nil, nil) + defer it.Close() + + if !it.Valid() { + return 0 + } + + return mustUint32FromBytes(it.Key()) + 1 +} + +func (k Keeper) getLastParams(ctx context.Context) *types.StoredParams { + paramsStore := k.paramsStore(ctx) + it := paramsStore.ReverseIterator(nil, nil) + defer it.Close() + + if !it.Valid() { + return nil + } + var sp types.StoredParams + k.cdc.MustUnmarshal(it.Value(), &sp) + return &sp +} + // SetParams sets the x/btcstaking module parameters. func (k Keeper) SetParams(ctx context.Context, p types.Params) error { if err := p.Validate(); err != nil { return err } - store := k.storeService.OpenKVStore(ctx) - bz := k.cdc.MustMarshal(&p) - return store.Set(types.ParamsKey, bz) -} -// GetParams returns the current x/btcstaking module parameters. -func (k Keeper) GetParams(ctx context.Context) (p types.Params) { - store := k.storeService.OpenKVStore(ctx) - bz, err := store.Get(types.ParamsKey) - if err != nil { - panic(err) + nextVersion := k.nextParamsVersion(ctx) + paramsStore := k.paramsStore(ctx) + + sp := types.StoredParams{ + Params: p, + Version: nextVersion, } - if bz == nil { - return p + + paramsStore.Set(uint32ToBytes(nextVersion), k.cdc.MustMarshal(&sp)) + return nil +} + +func (k Keeper) GetAllParams(ctx context.Context) []*types.Params { + paramsStore := k.paramsStore(ctx) + it := paramsStore.Iterator(nil, nil) + defer it.Close() + + var p []*types.Params + for ; it.Valid(); it.Next() { + var sp types.StoredParams + k.cdc.MustUnmarshal(it.Value(), &sp) + p = append(p, &sp.Params) } - k.cdc.MustUnmarshal(bz, &p) + return p } +func (k Keeper) GetParamsByVersion(ctx context.Context, v uint32) *types.Params { + paramsStore := k.paramsStore(ctx) + spBytes := paramsStore.Get(uint32ToBytes(v)) + if len(spBytes) == 0 { + return nil + } + + var sp types.StoredParams + k.cdc.MustUnmarshal(spBytes, &sp) + return &sp.Params +} + +func mustGetLastParams(ctx context.Context, k Keeper) types.StoredParams { + sp := k.getLastParams(ctx) + if sp == nil { + panic("last params not found") + } + + return *sp +} + +// GetParams returns the latest x/btcstaking module parameters. +func (k Keeper) GetParams(ctx context.Context) types.Params { + return mustGetLastParams(ctx, k).Params +} + +func (k Keeper) GetParamsWithVersion(ctx context.Context) types.StoredParams { + return mustGetLastParams(ctx, k) +} + // MinCommissionRate returns the minimal commission rate of finality providers func (k Keeper) MinCommissionRate(ctx context.Context) math.LegacyDec { return k.GetParams(ctx).MinCommissionRate diff --git a/x/btcstaking/keeper/params_test.go b/x/btcstaking/keeper/params_test.go index adf55969b..3c1ac1562 100644 --- a/x/btcstaking/keeper/params_test.go +++ b/x/btcstaking/keeper/params_test.go @@ -1,8 +1,11 @@ package keeper_test import ( + "math" + "math/rand" "testing" + "github.com/babylonchain/babylon/testutil/datagen" testkeeper "github.com/babylonchain/babylon/testutil/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" @@ -17,3 +20,74 @@ func TestGetParams(t *testing.T) { require.EqualValues(t, params, k.GetParams(ctx)) } + +func TestGetParamsVersions(t *testing.T) { + k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + params := types.DefaultParams() + + pv := k.GetParamsWithVersion(ctx) + + require.EqualValues(t, params, pv.Params) + require.EqualValues(t, uint32(0), pv.Version) + + params1 := types.DefaultParams() + params1.MinSlashingTxFeeSat = 23400 + + err := k.SetParams(ctx, params1) + require.NoError(t, err) + + pv = k.GetParamsWithVersion(ctx) + p := k.GetParams(ctx) + require.EqualValues(t, params1, pv.Params) + require.EqualValues(t, params1, p) + require.EqualValues(t, uint32(1), pv.Version) + + pv0 := k.GetParamsByVersion(ctx, 0) + require.NotNil(t, pv0) + require.EqualValues(t, params, *pv0) + pv1 := k.GetParamsByVersion(ctx, 1) + require.NotNil(t, pv1) + require.EqualValues(t, params1, *pv1) +} + +// Property: All public methods related to params are consistent with each other +func FuzzParamsVersioning(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + numVersionsToGenerate := r.Intn(100) + 1 + params0 := k.GetParams(ctx) + var generatedParams []*types.Params + generatedParams = append(generatedParams, ¶ms0) + + for i := 0; i < numVersionsToGenerate; i++ { + params := types.DefaultParams() + // randomize two parameters so each params are slightly different + params.MinSlashingTxFeeSat = r.Int63() + params.MinUnbondingTime = uint32(r.Intn(math.MaxUint16)) + err := k.SetParams(ctx, params) + require.NoError(t, err) + generatedParams = append(generatedParams, ¶ms) + } + + allParams := k.GetAllParams(ctx) + + require.Equal(t, len(generatedParams), len(allParams)) + + for i := 0; i < len(generatedParams); i++ { + // Check that params from aggregate query are ok + require.EqualValues(t, *generatedParams[i], *allParams[i]) + + // Check retrieval by version is ok + paramByVersion := k.GetParamsByVersion(ctx, uint32(i)) + require.NotNil(t, paramByVersion) + require.EqualValues(t, *generatedParams[i], *paramByVersion) + } + + lastParams := k.GetParams(ctx) + lastVer := k.GetParamsByVersion(ctx, uint32(len(generatedParams)-1)) + require.EqualValues(t, *generatedParams[len(generatedParams)-1], lastParams) + require.EqualValues(t, lastParams, *lastVer) + }) +} diff --git a/x/btcstaking/keeper/query_params.go b/x/btcstaking/keeper/query_params.go index 1dda6409c..51e391d52 100644 --- a/x/btcstaking/keeper/query_params.go +++ b/x/btcstaking/keeper/query_params.go @@ -17,3 +17,18 @@ func (k Keeper) Params(goCtx context.Context, req *types.QueryParamsRequest) (*t return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil } + +func (k Keeper) ParamsByVersion(goCtx context.Context, req *types.QueryParamsByVersionRequest) (*types.QueryParamsByVersionResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + + pv := k.GetParamsByVersion(ctx, req.Version) + + if pv == nil { + return nil, types.ErrParamsNotFound.Wrapf("version %d does not exists", req.Version) + } + + return &types.QueryParamsByVersionResponse{Params: *pv}, nil +} diff --git a/x/btcstaking/keeper/query_params_test.go b/x/btcstaking/keeper/query_params_test.go index b4c07587b..6c4e8cbb8 100644 --- a/x/btcstaking/keeper/query_params_test.go +++ b/x/btcstaking/keeper/query_params_test.go @@ -19,3 +19,47 @@ func TestParamsQuery(t *testing.T) { require.NoError(t, err) require.Equal(t, &types.QueryParamsResponse{Params: params}, response) } + +func TestParamsByVersionQuery(t *testing.T) { + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + + // starting with `1` as BTCStakingKeeper creates params with version 0 + params1 := types.DefaultParams() + params1.MinUnbondingTime = 10000 + params2 := types.DefaultParams() + params2.MinUnbondingTime = 20000 + params3 := types.DefaultParams() + params3.MinUnbondingTime = 30000 + + // Check that after update we always return the latest version of params throuh Params query + err := keeper.SetParams(ctx, params1) + require.NoError(t, err) + response, err := keeper.Params(ctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsResponse{Params: params1}, response) + + err = keeper.SetParams(ctx, params2) + require.NoError(t, err) + response, err = keeper.Params(ctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsResponse{Params: params2}, response) + + err = keeper.SetParams(ctx, params3) + require.NoError(t, err) + response, err = keeper.Params(ctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsResponse{Params: params3}, response) + + // Check that each past version is available through ParamsByVersion query + resp0, err := keeper.ParamsByVersion(ctx, &types.QueryParamsByVersionRequest{Version: 1}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsByVersionResponse{Params: params1}, resp0) + + resp1, err := keeper.ParamsByVersion(ctx, &types.QueryParamsByVersionRequest{Version: 2}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsByVersionResponse{Params: params2}, resp1) + + resp2, err := keeper.ParamsByVersion(ctx, &types.QueryParamsByVersionRequest{Version: 3}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsByVersionResponse{Params: params3}, resp2) +} diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index fe2ec5157..7decf89b8 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -284,6 +284,8 @@ type BTCDelegation struct { UnbondingTime uint32 `protobuf:"varint,13,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` // btc_undelegation is the information about the early unbonding path of the BTC delegation BtcUndelegation *BTCUndelegation `protobuf:"bytes,14,opt,name=btc_undelegation,json=btcUndelegation,proto3" json:"btc_undelegation,omitempty"` + // version of the params used to validate the delegation + ParamsVersion uint32 `protobuf:"varint,15,opt,name=params_version,json=paramsVersion,proto3" json:"params_version,omitempty"` } func (m *BTCDelegation) Reset() { *m = BTCDelegation{} } @@ -389,6 +391,13 @@ func (m *BTCDelegation) GetBtcUndelegation() *BTCUndelegation { return nil } +func (m *BTCDelegation) GetParamsVersion() uint32 { + if m != nil { + return m.ParamsVersion + } + return 0 +} + // BTCUndelegation contains the information about the early unbonding path of the BTC delegation type BTCUndelegation struct { // unbonding_tx is the transaction which will transfer the funds from staking @@ -735,81 +744,82 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1175 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x14, 0xce, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0xad, 0x3b, 0x4d, 0xd3, 0x6d, 0x23, 0x92, 0x60, 0x4a, - 0x65, 0x21, 0xba, 0x6e, 0xd2, 0x1f, 0x01, 0x17, 0x48, 0x75, 0x9c, 0xd2, 0xa8, 0xad, 0x6b, 0xd6, - 0x0e, 0x08, 0x90, 0x58, 0xad, 0x77, 0xc7, 0xeb, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, 0x37, - 0xe0, 0x06, 0x89, 0x5b, 0xee, 0x79, 0x04, 0x9e, 0x01, 0xf5, 0xb2, 0xe2, 0x06, 0x94, 0x8b, 0x08, - 0xb5, 0x2f, 0x82, 0x66, 0x76, 0xf6, 0xc7, 0x6d, 0x53, 0x68, 0xdd, 0x3b, 0xcf, 0x9c, 0x73, 0xbe, - 0xf3, 0xcd, 0xf9, 0x3e, 0xcf, 0x2c, 0x5c, 0xeb, 0x99, 0xbd, 0xf9, 0x88, 0x78, 0xf5, 0x1e, 0xb3, - 0x28, 0x33, 0x87, 0xae, 0xe7, 0xd4, 0xa7, 0xbb, 0xa9, 0x95, 0xe6, 0x07, 0x84, 0x11, 0x74, 0x51, - 0xe6, 0x69, 0xa9, 0xc8, 0x74, 0xf7, 0xca, 0xba, 0x43, 0x1c, 0x22, 0x32, 0xea, 0xfc, 0x57, 0x98, - 0x7c, 0xe5, 0xb2, 0x45, 0xe8, 0x98, 0x50, 0x23, 0x0c, 0x84, 0x0b, 0x19, 0xaa, 0x86, 0xab, 0xba, - 0x15, 0xcc, 0x7d, 0x46, 0xea, 0x14, 0x5b, 0xfe, 0xde, 0xed, 0x3b, 0xc3, 0xdd, 0xfa, 0x10, 0xcf, - 0xa3, 0x9c, 0xab, 0x32, 0x27, 0xe1, 0xd3, 0xc3, 0xcc, 0xdc, 0xad, 0x2f, 0x30, 0xba, 0xb2, 0xfd, - 0x6a, 0xe6, 0x3e, 0xf1, 0xc3, 0x84, 0xea, 0x5f, 0x59, 0xa8, 0xdc, 0x73, 0x3d, 0x73, 0xe4, 0xb2, - 0x79, 0x3b, 0x20, 0x53, 0xd7, 0xc6, 0x01, 0x3a, 0x80, 0xa2, 0x8d, 0xa9, 0x15, 0xb8, 0x3e, 0x73, - 0x89, 0xa7, 0x2a, 0x3b, 0x4a, 0xad, 0xb8, 0xf7, 0x81, 0x26, 0x39, 0x26, 0x27, 0x13, 0x1d, 0xb5, - 0x66, 0x92, 0xaa, 0xa7, 0xeb, 0xd0, 0x23, 0x00, 0x8b, 0x8c, 0xc7, 0x2e, 0xa5, 0x1c, 0x25, 0xb3, - 0xa3, 0xd4, 0x0a, 0x8d, 0xeb, 0xc7, 0x27, 0xdb, 0x9b, 0x21, 0x10, 0xb5, 0x87, 0x9a, 0x4b, 0xea, - 0x63, 0x93, 0x0d, 0xb4, 0x87, 0xd8, 0x31, 0xad, 0x79, 0x13, 0x5b, 0x7f, 0xfe, 0x7e, 0x1d, 0x64, - 0x9f, 0x26, 0xb6, 0xf4, 0x14, 0x00, 0xfa, 0x1c, 0x40, 0x9e, 0xc6, 0xf0, 0x87, 0x6a, 0x56, 0x90, - 0xda, 0x8e, 0x48, 0x85, 0xa3, 0xd2, 0xe2, 0x51, 0x69, 0xed, 0x49, 0xef, 0x01, 0x9e, 0xeb, 0x05, - 0x59, 0xd2, 0x1e, 0xa2, 0x47, 0x90, 0xef, 0x31, 0x8b, 0xd7, 0xe6, 0x76, 0x94, 0x5a, 0xa9, 0x71, - 0xe7, 0xf8, 0x64, 0x7b, 0xcf, 0x71, 0xd9, 0x60, 0xd2, 0xd3, 0x2c, 0x32, 0xae, 0xcb, 0x4c, 0x6b, - 0x60, 0xba, 0x5e, 0xb4, 0xa8, 0xb3, 0xb9, 0x8f, 0xa9, 0xd6, 0x38, 0x6c, 0xdf, 0xbc, 0x75, 0x43, - 0x42, 0xae, 0xf6, 0x98, 0xd5, 0x1e, 0xa2, 0xcf, 0x20, 0xeb, 0x13, 0x5f, 0x5d, 0x15, 0x3c, 0x6a, - 0xda, 0x2b, 0xa5, 0xd7, 0xda, 0x01, 0x21, 0xfd, 0xc7, 0xfd, 0x36, 0xa1, 0x14, 0x8b, 0x53, 0xe8, - 0xbc, 0x08, 0xdd, 0x82, 0x0d, 0x3a, 0x32, 0xe9, 0x00, 0xdb, 0x46, 0x74, 0xa4, 0x01, 0x76, 0x9d, - 0x01, 0x53, 0xf3, 0x3b, 0x4a, 0x2d, 0xa7, 0xaf, 0xcb, 0x68, 0x23, 0x0c, 0xde, 0x17, 0x31, 0xf4, - 0x31, 0xa0, 0xb8, 0x8a, 0x59, 0x51, 0xc5, 0x9a, 0xa8, 0xa8, 0x44, 0x15, 0xcc, 0x0a, 0xb3, 0xab, - 0x3f, 0x65, 0x40, 0x7d, 0x51, 0xd9, 0xaf, 0x5d, 0x36, 0x78, 0x84, 0x99, 0x99, 0x9a, 0x85, 0xf2, - 0x2e, 0x66, 0xb1, 0x01, 0x79, 0xc9, 0x26, 0x23, 0xd8, 0xc8, 0x15, 0x7a, 0x1f, 0x4a, 0x53, 0xc2, - 0x5c, 0xcf, 0x31, 0x7c, 0xf2, 0x23, 0x0e, 0x84, 0x68, 0x39, 0xbd, 0x18, 0xee, 0xb5, 0xf9, 0xd6, - 0x6b, 0x46, 0x91, 0x7b, 0xe3, 0x51, 0xac, 0x9e, 0x32, 0x8a, 0x27, 0x79, 0x28, 0x37, 0xba, 0xfb, - 0x4d, 0x3c, 0xc2, 0x8e, 0xc9, 0x5e, 0xf6, 0x92, 0xb2, 0x84, 0x97, 0x32, 0xef, 0xd0, 0x4b, 0xd9, - 0xb7, 0xf1, 0xd2, 0x77, 0x70, 0xb6, 0xef, 0x1b, 0x21, 0x1b, 0x63, 0xe4, 0x52, 0x3e, 0xb8, 0xec, - 0x12, 0x94, 0x8a, 0x7d, 0xbf, 0xc1, 0x49, 0x3d, 0x74, 0xa9, 0x10, 0x90, 0x32, 0x33, 0x60, 0x8b, - 0x13, 0x2e, 0x8a, 0x3d, 0x29, 0xc5, 0x7b, 0x00, 0xd8, 0xb3, 0x17, 0xfd, 0x5b, 0xc0, 0x9e, 0x2d, - 0xc3, 0x9b, 0x50, 0x60, 0x84, 0x99, 0x23, 0x83, 0x9a, 0x91, 0x57, 0xcf, 0x88, 0x8d, 0x8e, 0x29, - 0x6a, 0xe5, 0x01, 0x0d, 0x36, 0x53, 0xcf, 0xf0, 0x51, 0xea, 0x05, 0xb9, 0xd3, 0x9d, 0x09, 0x95, - 0x65, 0x98, 0x4c, 0x98, 0x3f, 0x61, 0x86, 0x6b, 0xcf, 0xd4, 0xc2, 0x8e, 0x52, 0x2b, 0xeb, 0x15, - 0x19, 0x79, 0x2c, 0x02, 0x87, 0xf6, 0x0c, 0xed, 0x41, 0x51, 0x28, 0x2f, 0xd1, 0x40, 0x08, 0x73, - 0xfe, 0xf8, 0x64, 0x9b, 0x6b, 0xdf, 0x91, 0x91, 0xee, 0x4c, 0x07, 0x1a, 0xff, 0x46, 0xdf, 0x43, - 0xd9, 0x0e, 0x5d, 0x41, 0x02, 0x83, 0xba, 0x8e, 0x5a, 0x14, 0x55, 0x9f, 0x1e, 0x9f, 0x6c, 0xdf, - 0x7e, 0x93, 0xd9, 0x75, 0x5c, 0xc7, 0x33, 0xd9, 0x24, 0xc0, 0x7a, 0x29, 0xc6, 0xeb, 0xb8, 0x0e, - 0x3a, 0x82, 0xb2, 0x45, 0xa6, 0xd8, 0x33, 0x3d, 0xc6, 0xe1, 0xa9, 0x5a, 0xda, 0xc9, 0xd6, 0x8a, - 0x7b, 0x37, 0x4e, 0x91, 0x78, 0x5f, 0xe6, 0xde, 0xb5, 0x4d, 0x3f, 0x44, 0x08, 0x51, 0xa9, 0x5e, - 0x8a, 0x60, 0x3a, 0xae, 0x43, 0xd1, 0x87, 0x70, 0x76, 0xe2, 0xf5, 0x88, 0x67, 0x8b, 0xb3, 0xba, - 0x63, 0xac, 0x96, 0xc5, 0x50, 0xca, 0xf1, 0x6e, 0xd7, 0x1d, 0x63, 0xf4, 0x25, 0x54, 0xb8, 0x2f, - 0x26, 0x9e, 0x1d, 0x3b, 0x5f, 0x3d, 0x2b, 0x3c, 0x76, 0xed, 0x14, 0x02, 0x8d, 0xee, 0xfe, 0x51, - 0x2a, 0x5b, 0x3f, 0xd7, 0x63, 0x56, 0x7a, 0xa3, 0xfa, 0x6b, 0x0e, 0xce, 0xbd, 0x90, 0xc4, 0x4d, - 0x92, 0x62, 0x33, 0x0b, 0xaf, 0x14, 0xbd, 0x98, 0x70, 0x79, 0x49, 0x9b, 0xcc, 0xff, 0xd1, 0xe6, - 0x07, 0xb8, 0x94, 0x68, 0x93, 0x34, 0xe0, 0x2a, 0x65, 0x97, 0x55, 0xe9, 0x62, 0x8c, 0x7c, 0x14, - 0x01, 0x73, 0xb9, 0x08, 0x6c, 0xa4, 0xec, 0x10, 0x11, 0xe6, 0x1d, 0x73, 0xcb, 0x76, 0x5c, 0x4f, - 0x7c, 0x21, 0x71, 0x79, 0xc3, 0x3e, 0x6c, 0x24, 0xfe, 0x48, 0xf5, 0xa3, 0xea, 0xea, 0x5b, 0x1a, - 0x65, 0x3d, 0x36, 0x4a, 0xd2, 0x86, 0x22, 0x0b, 0x36, 0xe3, 0x3e, 0x0b, 0xa3, 0x0c, 0x6f, 0x8c, - 0xbc, 0x68, 0x76, 0xf5, 0x94, 0x66, 0x31, 0xfa, 0xa1, 0xd7, 0x27, 0xba, 0x1a, 0x01, 0xa5, 0x27, - 0xc7, 0x2f, 0x8b, 0x6a, 0x07, 0x2e, 0x25, 0xb7, 0x2c, 0x09, 0x92, 0xeb, 0x96, 0xa2, 0x4f, 0x20, - 0x67, 0xe3, 0x11, 0x55, 0x95, 0xd7, 0x36, 0x5a, 0xb8, 0xa3, 0x75, 0x51, 0x51, 0x6d, 0xc1, 0xe6, - 0xab, 0x41, 0x0f, 0x3d, 0x1b, 0xcf, 0x50, 0x1d, 0xd6, 0x93, 0x1b, 0xc4, 0x18, 0x98, 0x74, 0x10, - 0x9e, 0x88, 0x37, 0x2a, 0xe9, 0xe7, 0xe3, 0xbb, 0xe4, 0xbe, 0x49, 0x07, 0x82, 0xe4, 0x6f, 0x0a, - 0x94, 0x17, 0x0e, 0x84, 0xee, 0x41, 0x66, 0xe9, 0x77, 0x30, 0xe3, 0x0f, 0xd1, 0x03, 0xc8, 0x72, - 0xa7, 0x64, 0x96, 0x75, 0x0a, 0x47, 0xa9, 0xfe, 0xac, 0xc0, 0xe5, 0x53, 0x45, 0xe6, 0xcf, 0x8f, - 0x45, 0xa6, 0xef, 0xe0, 0xf9, 0xb6, 0xc8, 0xb4, 0x3d, 0xe4, 0x7f, 0x60, 0x33, 0xec, 0x11, 0x7a, - 0x2f, 0x23, 0x86, 0x57, 0x34, 0xe3, 0xbe, 0xb4, 0xfa, 0x87, 0x02, 0x97, 0x3b, 0x78, 0x84, 0x2d, - 0xe6, 0x4e, 0x71, 0x64, 0xad, 0x03, 0xfe, 0x51, 0xe1, 0x59, 0x18, 0x5d, 0x83, 0x73, 0x2f, 0xa8, - 0x20, 0x88, 0x15, 0xf4, 0xf2, 0x82, 0x00, 0x48, 0x87, 0x42, 0xfc, 0x56, 0x2d, 0xf9, 0x72, 0xae, - 0xc9, 0x67, 0x0a, 0x5d, 0x87, 0x0b, 0x01, 0xe6, 0x9e, 0x0c, 0xb0, 0x6d, 0x48, 0x74, 0x1a, 0x7e, - 0x1f, 0x96, 0xf4, 0x4a, 0x1c, 0xba, 0xc7, 0xd3, 0x3b, 0xc3, 0x8f, 0x0e, 0xe0, 0xc2, 0x82, 0xcd, - 0x3a, 0xcc, 0x64, 0x13, 0x8a, 0x8a, 0xb0, 0xd6, 0x3e, 0x68, 0x35, 0x0f, 0x5b, 0x5f, 0x54, 0x56, - 0x10, 0x40, 0xfe, 0xee, 0x7e, 0xf7, 0xf0, 0xab, 0x83, 0x8a, 0x82, 0x4a, 0x70, 0xe6, 0xa8, 0xd5, - 0x78, 0xdc, 0x6a, 0x1e, 0x34, 0x2b, 0x19, 0xb4, 0x06, 0xd9, 0xbb, 0xad, 0x6f, 0x2a, 0xd9, 0xc6, - 0xc3, 0x27, 0xcf, 0xb6, 0x94, 0xa7, 0xcf, 0xb6, 0x94, 0x7f, 0x9e, 0x6d, 0x29, 0xbf, 0x3c, 0xdf, - 0x5a, 0x79, 0xfa, 0x7c, 0x6b, 0xe5, 0xef, 0xe7, 0x5b, 0x2b, 0xdf, 0xfe, 0xe7, 0x61, 0x66, 0xe9, - 0x8f, 0x71, 0x71, 0xb2, 0x5e, 0x5e, 0x7c, 0x8c, 0xdf, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0xc4, - 0x5e, 0xb6, 0xaa, 0x69, 0x0c, 0x00, 0x00, + // 1197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, + 0x17, 0xcf, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x7f, 0x92, 0xbf, + 0x29, 0x95, 0x85, 0xa8, 0xdd, 0xa4, 0x1f, 0x02, 0x2e, 0x90, 0xea, 0x38, 0xa5, 0x51, 0xdb, 0xd4, + 0xac, 0x93, 0x22, 0x40, 0x62, 0x35, 0xde, 0x9d, 0xac, 0x57, 0xb6, 0x77, 0x96, 0x9d, 0xb1, 0xb1, + 0xdf, 0x80, 0x1b, 0x24, 0x6e, 0xb9, 0xe7, 0x11, 0x78, 0x06, 0xc4, 0x65, 0xc5, 0x0d, 0x28, 0x17, + 0x11, 0x6a, 0x1f, 0x80, 0x57, 0x40, 0x33, 0x3b, 0xfb, 0xe1, 0xb6, 0x29, 0xb4, 0xce, 0x9d, 0x67, + 0xce, 0x39, 0xbf, 0xf3, 0xf1, 0xfb, 0xf9, 0xcc, 0xc2, 0xf5, 0x2e, 0xee, 0x4e, 0x07, 0xd4, 0x6b, + 0x74, 0xb9, 0xc5, 0x38, 0xee, 0xbb, 0x9e, 0xd3, 0x18, 0x6f, 0xa5, 0x4e, 0x75, 0x3f, 0xa0, 0x9c, + 0xa2, 0x4b, 0xca, 0xaf, 0x9e, 0xb2, 0x8c, 0xb7, 0xae, 0xae, 0x38, 0xd4, 0xa1, 0xd2, 0xa3, 0x21, + 0x7e, 0x85, 0xce, 0x57, 0xaf, 0x58, 0x94, 0x0d, 0x29, 0x33, 0x43, 0x43, 0x78, 0x50, 0xa6, 0x6a, + 0x78, 0x6a, 0x58, 0xc1, 0xd4, 0xe7, 0xb4, 0xc1, 0x88, 0xe5, 0x6f, 0xdf, 0xb9, 0xdb, 0xdf, 0x6a, + 0xf4, 0xc9, 0x34, 0xf2, 0xb9, 0xa6, 0x7c, 0x92, 0x7a, 0xba, 0x84, 0xe3, 0xad, 0xc6, 0x4c, 0x45, + 0x57, 0x37, 0x5e, 0x5f, 0xb9, 0x4f, 0xfd, 0xd0, 0xa1, 0xfa, 0x47, 0x16, 0x2a, 0xf7, 0x5d, 0x0f, + 0x0f, 0x5c, 0x3e, 0x6d, 0x07, 0x74, 0xec, 0xda, 0x24, 0x40, 0xbb, 0x50, 0xb4, 0x09, 0xb3, 0x02, + 0xd7, 0xe7, 0x2e, 0xf5, 0x74, 0x6d, 0x53, 0xab, 0x15, 0xb7, 0xdf, 0xab, 0xab, 0x1a, 0x93, 0xce, + 0x64, 0xc6, 0x7a, 0x2b, 0x71, 0x35, 0xd2, 0x71, 0xe8, 0x31, 0x80, 0x45, 0x87, 0x43, 0x97, 0x31, + 0x81, 0x92, 0xd9, 0xd4, 0x6a, 0x85, 0xe6, 0x8d, 0xe3, 0x93, 0x8d, 0xb5, 0x10, 0x88, 0xd9, 0xfd, + 0xba, 0x4b, 0x1b, 0x43, 0xcc, 0x7b, 0xf5, 0x47, 0xc4, 0xc1, 0xd6, 0xb4, 0x45, 0xac, 0xdf, 0x7f, + 0xb9, 0x01, 0x2a, 0x4f, 0x8b, 0x58, 0x46, 0x0a, 0x00, 0x7d, 0x0a, 0xa0, 0xba, 0x31, 0xfd, 0xbe, + 0x9e, 0x95, 0x45, 0x6d, 0x44, 0x45, 0x85, 0xa3, 0xaa, 0xc7, 0xa3, 0xaa, 0xb7, 0x47, 0xdd, 0x87, + 0x64, 0x6a, 0x14, 0x54, 0x48, 0xbb, 0x8f, 0x1e, 0x43, 0xbe, 0xcb, 0x2d, 0x11, 0x9b, 0xdb, 0xd4, + 0x6a, 0xa5, 0xe6, 0xdd, 0xe3, 0x93, 0x8d, 0x6d, 0xc7, 0xe5, 0xbd, 0x51, 0xb7, 0x6e, 0xd1, 0x61, + 0x43, 0x79, 0x5a, 0x3d, 0xec, 0x7a, 0xd1, 0xa1, 0xc1, 0xa7, 0x3e, 0x61, 0xf5, 0xe6, 0x5e, 0xfb, + 0xd6, 0xed, 0x9b, 0x0a, 0x72, 0xb1, 0xcb, 0xad, 0x76, 0x1f, 0x7d, 0x02, 0x59, 0x9f, 0xfa, 0xfa, + 0xa2, 0xac, 0xa3, 0x56, 0x7f, 0x2d, 0xf5, 0xf5, 0x76, 0x40, 0xe9, 0xd1, 0x93, 0xa3, 0x36, 0x65, + 0x8c, 0xc8, 0x2e, 0x0c, 0x11, 0x84, 0x6e, 0xc3, 0x2a, 0x1b, 0x60, 0xd6, 0x23, 0xb6, 0x19, 0xb5, + 0xd4, 0x23, 0xae, 0xd3, 0xe3, 0x7a, 0x7e, 0x53, 0xab, 0xe5, 0x8c, 0x15, 0x65, 0x6d, 0x86, 0xc6, + 0x07, 0xd2, 0x86, 0x3e, 0x04, 0x14, 0x47, 0x71, 0x2b, 0x8a, 0x58, 0x92, 0x11, 0x95, 0x28, 0x82, + 0x5b, 0xa1, 0x77, 0xf5, 0xfb, 0x0c, 0xe8, 0x2f, 0x33, 0xfb, 0x85, 0xcb, 0x7b, 0x8f, 0x09, 0xc7, + 0xa9, 0x59, 0x68, 0x67, 0x31, 0x8b, 0x55, 0xc8, 0xab, 0x6a, 0x32, 0xb2, 0x1a, 0x75, 0x42, 0xff, + 0x87, 0xd2, 0x98, 0x72, 0xd7, 0x73, 0x4c, 0x9f, 0x7e, 0x47, 0x02, 0x49, 0x5a, 0xce, 0x28, 0x86, + 0x77, 0x6d, 0x71, 0xf5, 0x86, 0x51, 0xe4, 0xde, 0x7a, 0x14, 0x8b, 0xa7, 0x8c, 0xe2, 0xef, 0x3c, + 0x94, 0x9b, 0x07, 0x3b, 0x2d, 0x32, 0x20, 0x0e, 0xe6, 0xaf, 0x6a, 0x49, 0x9b, 0x43, 0x4b, 0x99, + 0x33, 0xd4, 0x52, 0xf6, 0x5d, 0xb4, 0xf4, 0x35, 0x9c, 0x3f, 0xf2, 0xcd, 0xb0, 0x1a, 0x73, 0xe0, + 0x32, 0x31, 0xb8, 0xec, 0x1c, 0x25, 0x15, 0x8f, 0xfc, 0xa6, 0x28, 0xea, 0x91, 0xcb, 0x24, 0x81, + 0x8c, 0xe3, 0x80, 0xcf, 0x4e, 0xb8, 0x28, 0xef, 0x14, 0x15, 0xff, 0x03, 0x20, 0x9e, 0x3d, 0xab, + 0xdf, 0x02, 0xf1, 0x6c, 0x65, 0x5e, 0x83, 0x02, 0xa7, 0x1c, 0x0f, 0x4c, 0x86, 0x23, 0xad, 0x9e, + 0x93, 0x17, 0x1d, 0x2c, 0x63, 0x55, 0x83, 0x26, 0x9f, 0xe8, 0xe7, 0xc4, 0x28, 0x8d, 0x82, 0xba, + 0x39, 0x98, 0x48, 0x96, 0x95, 0x99, 0x8e, 0xb8, 0x3f, 0xe2, 0xa6, 0x6b, 0x4f, 0xf4, 0xc2, 0xa6, + 0x56, 0x2b, 0x1b, 0x15, 0x65, 0x79, 0x22, 0x0d, 0x7b, 0xf6, 0x04, 0x6d, 0x43, 0x51, 0x32, 0xaf, + 0xd0, 0x40, 0x12, 0x73, 0xe1, 0xf8, 0x64, 0x43, 0x70, 0xdf, 0x51, 0x96, 0x83, 0x89, 0x01, 0x2c, + 0xfe, 0x8d, 0xbe, 0x81, 0xb2, 0x1d, 0xaa, 0x82, 0x06, 0x26, 0x73, 0x1d, 0xbd, 0x28, 0xa3, 0x3e, + 0x3e, 0x3e, 0xd9, 0xb8, 0xf3, 0x36, 0xb3, 0xeb, 0xb8, 0x8e, 0x87, 0xf9, 0x28, 0x20, 0x46, 0x29, + 0xc6, 0xeb, 0xb8, 0x0e, 0x3a, 0x84, 0xb2, 0x45, 0xc7, 0xc4, 0xc3, 0x1e, 0x17, 0xf0, 0x4c, 0x2f, + 0x6d, 0x66, 0x6b, 0xc5, 0xed, 0x9b, 0xa7, 0x50, 0xbc, 0xa3, 0x7c, 0xef, 0xd9, 0xd8, 0x0f, 0x11, + 0x42, 0x54, 0x66, 0x94, 0x22, 0x98, 0x8e, 0xeb, 0x30, 0xf4, 0x3e, 0x9c, 0x1f, 0x79, 0x5d, 0xea, + 0xd9, 0xb2, 0x57, 0x77, 0x48, 0xf4, 0xb2, 0x1c, 0x4a, 0x39, 0xbe, 0x3d, 0x70, 0x87, 0x04, 0x7d, + 0x0e, 0x15, 0xa1, 0x8b, 0x91, 0x67, 0xc7, 0xca, 0xd7, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa5, 0x80, + 0xe6, 0xc1, 0xce, 0x61, 0xca, 0xdb, 0x58, 0xee, 0x72, 0x2b, 0x7d, 0x21, 0x32, 0xfb, 0x38, 0xc0, + 0x43, 0x66, 0x8e, 0x49, 0x20, 0xf7, 0xfa, 0x72, 0x98, 0x39, 0xbc, 0x7d, 0x1a, 0x5e, 0x56, 0x7f, + 0xca, 0xc1, 0xf2, 0x4b, 0x58, 0x42, 0x4b, 0xa9, 0xa2, 0x27, 0xe1, 0xe6, 0x31, 0x8a, 0x49, 0xc9, + 0xaf, 0x50, 0x98, 0xf9, 0x2f, 0x14, 0x7e, 0x0b, 0x97, 0x13, 0x0a, 0x93, 0x04, 0x82, 0xcc, 0xec, + 0xbc, 0x64, 0x5e, 0x8a, 0x91, 0x0f, 0x23, 0x60, 0xc1, 0x2a, 0x85, 0xd5, 0x94, 0x6a, 0xa2, 0x82, + 0x45, 0xc6, 0xdc, 0xbc, 0x19, 0x57, 0x12, 0xf9, 0x28, 0x5c, 0x91, 0xf0, 0x08, 0x56, 0x13, 0x19, + 0xa5, 0xf2, 0x31, 0x7d, 0xf1, 0x1d, 0xf5, 0xb4, 0x12, 0xeb, 0x29, 0x49, 0xc3, 0x90, 0x05, 0x6b, + 0x71, 0x9e, 0x99, 0x51, 0x86, 0x8b, 0x25, 0x2f, 0x93, 0x5d, 0x3b, 0x25, 0x59, 0x8c, 0xbe, 0xe7, + 0x1d, 0x51, 0x43, 0x8f, 0x80, 0xd2, 0x93, 0x13, 0x3b, 0xa5, 0xda, 0x81, 0xcb, 0xc9, 0x32, 0xa6, + 0x41, 0xb2, 0x95, 0x19, 0xfa, 0x08, 0x72, 0x36, 0x19, 0x30, 0x5d, 0x7b, 0x63, 0xa2, 0x99, 0x55, + 0x6e, 0xc8, 0x88, 0xea, 0x3e, 0xac, 0xbd, 0x1e, 0x74, 0xcf, 0xb3, 0xc9, 0x04, 0x35, 0x60, 0x25, + 0x59, 0x34, 0x66, 0x0f, 0xb3, 0x5e, 0xd8, 0x91, 0x48, 0x54, 0x32, 0x2e, 0xc4, 0x2b, 0xe7, 0x01, + 0x66, 0x3d, 0x59, 0xe4, 0xcf, 0x1a, 0x94, 0x67, 0x1a, 0x42, 0xf7, 0x21, 0x33, 0xf7, 0x73, 0x99, + 0xf1, 0xfb, 0xe8, 0x21, 0x64, 0x85, 0x52, 0x32, 0xf3, 0x2a, 0x45, 0xa0, 0x54, 0x7f, 0xd0, 0xe0, + 0xca, 0xa9, 0x24, 0x8b, 0x57, 0xca, 0xa2, 0xe3, 0x33, 0x78, 0xe5, 0x2d, 0x3a, 0x6e, 0xf7, 0xc5, + 0x1f, 0x18, 0x87, 0x39, 0x42, 0xed, 0x65, 0xe4, 0xf0, 0x8a, 0x38, 0xce, 0xcb, 0xaa, 0xbf, 0x6a, + 0x70, 0xa5, 0x43, 0x06, 0xc4, 0xe2, 0xee, 0x98, 0x44, 0xd2, 0xda, 0x15, 0xdf, 0x1e, 0x9e, 0x45, + 0xd0, 0x75, 0x58, 0x7e, 0x89, 0x05, 0x59, 0x58, 0xc1, 0x28, 0xcf, 0x10, 0x80, 0x0c, 0x28, 0xc4, + 0x4f, 0xda, 0x9c, 0x0f, 0xec, 0x92, 0x7a, 0xcd, 0xd0, 0x0d, 0xb8, 0x18, 0x10, 0xa1, 0xc9, 0x80, + 0xd8, 0xa6, 0x42, 0x67, 0xe1, 0x67, 0x64, 0xc9, 0xa8, 0xc4, 0xa6, 0xfb, 0xc2, 0xbd, 0xd3, 0xff, + 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc3, 0x31, 0x1f, 0x31, 0x54, 0x84, 0xa5, 0xf6, 0xee, 0x7e, + 0x6b, 0x6f, 0xff, 0xb3, 0xca, 0x02, 0x02, 0xc8, 0xdf, 0xdb, 0x39, 0xd8, 0x7b, 0xba, 0x5b, 0xd1, + 0x50, 0x09, 0xce, 0x1d, 0xee, 0x37, 0x9f, 0xec, 0xb7, 0x76, 0x5b, 0x95, 0x0c, 0x5a, 0x82, 0xec, + 0xbd, 0xfd, 0x2f, 0x2b, 0xd9, 0xe6, 0xa3, 0xdf, 0x9e, 0xaf, 0x6b, 0xcf, 0x9e, 0xaf, 0x6b, 0x7f, + 0x3d, 0x5f, 0xd7, 0x7e, 0x7c, 0xb1, 0xbe, 0xf0, 0xec, 0xc5, 0xfa, 0xc2, 0x9f, 0x2f, 0xd6, 0x17, + 0xbe, 0xfa, 0xd7, 0x66, 0x26, 0xe9, 0x6f, 0x76, 0xd9, 0x59, 0x37, 0x2f, 0xbf, 0xd9, 0x6f, 0xfd, + 0x13, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xb8, 0x1f, 0xd2, 0x90, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -980,6 +990,11 @@ func (m *BTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ParamsVersion != 0 { + i = encodeVarintBtcstaking(dAtA, i, uint64(m.ParamsVersion)) + i-- + dAtA[i] = 0x78 + } if m.BtcUndelegation != nil { { size, err := m.BtcUndelegation.MarshalToSizedBuffer(dAtA[:i]) @@ -1550,6 +1565,9 @@ func (m *BTCDelegation) Size() (n int) { l = m.BtcUndelegation.Size() n += 1 + l + sovBtcstaking(uint64(l)) } + if m.ParamsVersion != 0 { + n += 1 + sovBtcstaking(uint64(m.ParamsVersion)) + } return n } @@ -2551,6 +2569,25 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ParamsVersion", wireType) + } + m.ParamsVersion = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ParamsVersion |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipBtcstaking(dAtA[iNdEx:]) diff --git a/x/btcstaking/types/errors.go b/x/btcstaking/types/errors.go index 959641b57..83f148368 100644 --- a/x/btcstaking/types/errors.go +++ b/x/btcstaking/types/errors.go @@ -29,4 +29,5 @@ var ( ErrInvalidBTCUndelegateReq = errorsmod.Register(ModuleName, 1120, "invalid undelegation request") ErrVotingPowerTableNotUpdated = errorsmod.Register(ModuleName, 1121, "voting power table has not been updated") ErrVotingPowerDistCacheNotFound = errorsmod.Register(ModuleName, 1122, "the voting power distribution cache is not found") + ErrParamsNotFound = errorsmod.Register(ModuleName, 1123, "the parameters are not found") ) diff --git a/x/btcstaking/types/genesis.go b/x/btcstaking/types/genesis.go index a258e6808..281e8abea 100644 --- a/x/btcstaking/types/genesis.go +++ b/x/btcstaking/types/genesis.go @@ -1,16 +1,27 @@ package types +import "fmt" + // DefaultGenesis returns the default genesis state func DefaultGenesis() *GenesisState { + p := DefaultParams() return &GenesisState{ - - Params: DefaultParams(), + Params: []*Params{&p}, } } // Validate performs basic genesis state validation returning an error upon any // failure. func (gs GenesisState) Validate() error { + if len(gs.Params) == 0 { + return fmt.Errorf("params cannot be empty") + } + // TODO: add validation to other properties of genstate. - return gs.Params.Validate() + for _, params := range gs.Params { + if err := params.Validate(); err != nil { + return err + } + } + return nil } diff --git a/x/btcstaking/types/genesis.pb.go b/x/btcstaking/types/genesis.pb.go index eb1f839f3..087dcb664 100644 --- a/x/btcstaking/types/genesis.pb.go +++ b/x/btcstaking/types/genesis.pb.go @@ -26,7 +26,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the btcstaking module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // different versions of params used through the history of the chain + Params []*Params `protobuf:"bytes,1,rep,name=params,proto3" json:"params,omitempty"` // finality_providers all the finality providers registered. FinalityProviders []*FinalityProvider `protobuf:"bytes,2,rep,name=finality_providers,json=finalityProviders,proto3" json:"finality_providers,omitempty"` // btc_delegations all the btc delegations in the state. @@ -77,11 +78,11 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo -func (m *GenesisState) GetParams() Params { +func (m *GenesisState) GetParams() []*Params { if m != nil { return m.Params } - return Params{} + return nil } func (m *GenesisState) GetFinalityProviders() []*FinalityProvider { @@ -429,51 +430,51 @@ func init() { } var fileDescriptor_85d7b95fa5620238 = []byte{ - // 699 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x4f, 0x4f, 0xdb, 0x30, - 0x18, 0xc6, 0x1b, 0x5a, 0x0a, 0x73, 0x4b, 0x01, 0xb3, 0x49, 0x11, 0x12, 0x05, 0xc2, 0xfe, 0x54, - 0x9b, 0x94, 0x8e, 0x82, 0x26, 0x4d, 0x3b, 0x2d, 0x74, 0x6c, 0xec, 0x8f, 0x14, 0x65, 0x1d, 0x07, - 0x2e, 0x51, 0x9c, 0xb8, 0xa9, 0xd5, 0x10, 0x47, 0xb1, 0xc9, 0xe8, 0x67, 0xd8, 0x65, 0xc7, 0x7d, - 0x85, 0x7d, 0x13, 0x8e, 0x1c, 0xa7, 0x1d, 0xd0, 0x04, 0x5f, 0x62, 0xa7, 0x69, 0x8a, 0x13, 0x48, - 0x60, 0x2d, 0x74, 0x9a, 0x76, 0xab, 0xad, 0xe7, 0xfd, 0xf9, 0x7d, 0x5e, 0x3f, 0x6e, 0xc0, 0x1a, - 0xb2, 0xd0, 0xc0, 0xa3, 0x7e, 0x13, 0x71, 0x9b, 0x71, 0xab, 0x4f, 0x7c, 0xb7, 0x19, 0xad, 0x37, - 0x5d, 0xec, 0x63, 0x46, 0x98, 0x1a, 0x84, 0x94, 0x53, 0x78, 0x27, 0x15, 0xa9, 0x99, 0x48, 0x8d, - 0xd6, 0x17, 0x6f, 0xbb, 0xd4, 0xa5, 0x42, 0xd1, 0x8c, 0x7f, 0x25, 0xe2, 0x45, 0x65, 0x38, 0x31, - 0xb0, 0x42, 0x6b, 0x3f, 0x05, 0x2e, 0xde, 0x1f, 0xae, 0xc9, 0xe1, 0x13, 0xdd, 0xbd, 0xe1, 0x3a, - 0xe2, 0xdb, 0xd8, 0xe7, 0x24, 0xc2, 0xd7, 0x1f, 0x89, 0x23, 0xec, 0xf3, 0xf4, 0x48, 0xe5, 0x67, - 0x09, 0x54, 0x5f, 0x26, 0xae, 0xde, 0x73, 0x8b, 0x63, 0xf8, 0x0c, 0x94, 0x93, 0x9e, 0x64, 0x69, - 0x45, 0x6a, 0x54, 0x5a, 0x4b, 0xea, 0x50, 0x97, 0xaa, 0x2e, 0x44, 0x5a, 0xe9, 0xe8, 0x64, 0xb9, - 0x60, 0xa4, 0x25, 0x70, 0x17, 0xc0, 0x2e, 0xf1, 0x2d, 0x8f, 0xf0, 0x81, 0x19, 0x84, 0x34, 0x22, - 0x0e, 0x0e, 0x99, 0x3c, 0xb1, 0x52, 0x6c, 0x54, 0x5a, 0x0f, 0x46, 0x80, 0xb6, 0xd3, 0x02, 0x3d, - 0xd5, 0x1b, 0xf3, 0xdd, 0x2b, 0x3b, 0x0c, 0xbe, 0x03, 0xb3, 0x88, 0xdb, 0xa6, 0x83, 0x3d, 0xec, - 0x5a, 0x9c, 0x50, 0x9f, 0xc9, 0x45, 0x01, 0xbd, 0x3b, 0x02, 0xaa, 0x75, 0xb6, 0xda, 0x17, 0x62, - 0xa3, 0x86, 0xb8, 0x9d, 0x2d, 0x19, 0xdc, 0x01, 0x33, 0x11, 0xe5, 0xc4, 0x77, 0xcd, 0x80, 0x7e, - 0x8c, 0x3b, 0x2c, 0x5d, 0x0b, 0xdb, 0x15, 0x5a, 0x3d, 0x96, 0x6e, 0xeb, 0x46, 0x35, 0xca, 0x96, - 0x0c, 0xee, 0x81, 0x05, 0xe4, 0x51, 0xbb, 0x6f, 0xf6, 0x30, 0x71, 0x7b, 0xdc, 0xb4, 0x7b, 0x16, - 0xf1, 0x99, 0x3c, 0x29, 0x80, 0x0f, 0x47, 0x75, 0x17, 0x57, 0xbc, 0x12, 0x05, 0x1a, 0xf2, 0x3b, - 0x54, 0xe3, 0xb6, 0x31, 0x8f, 0xb2, 0xcd, 0x2d, 0x01, 0x81, 0xaf, 0x41, 0x2d, 0xe7, 0x9a, 0x86, - 0x4c, 0x2e, 0x0b, 0xec, 0xda, 0x8d, 0xa6, 0x69, 0x68, 0xcc, 0x64, 0x9e, 0x69, 0xc8, 0xe0, 0x53, - 0x50, 0x4e, 0xee, 0x5d, 0x9e, 0x12, 0x8c, 0xd5, 0x11, 0x8c, 0x17, 0xb1, 0x68, 0xc7, 0x77, 0xf0, - 0xa1, 0x91, 0x16, 0xc0, 0x5d, 0x50, 0x8d, 0x02, 0xd3, 0x61, 0xdc, 0xb4, 0x2d, 0xbb, 0x87, 0xe5, - 0x69, 0x01, 0xd8, 0xbc, 0x79, 0x58, 0x6d, 0xc2, 0xf8, 0x56, 0x5c, 0xa2, 0x79, 0xa9, 0x31, 0x03, - 0x44, 0x41, 0x3b, 0xdd, 0x54, 0xbe, 0x4a, 0x60, 0xe6, 0xd2, 0x68, 0xe1, 0x2a, 0xa8, 0xe6, 0x87, - 0x29, 0x12, 0x58, 0x32, 0x2a, 0xb9, 0xc9, 0x40, 0x03, 0xdc, 0xea, 0x06, 0x66, 0x3c, 0x96, 0xa0, - 0x2f, 0x4f, 0xac, 0x48, 0x8d, 0xaa, 0xf6, 0xe4, 0xfb, 0xc9, 0x72, 0xcb, 0x25, 0xbc, 0x77, 0x80, - 0x54, 0x9b, 0xee, 0x37, 0xd3, 0xbe, 0xc4, 0x4d, 0x9c, 0x2f, 0x9a, 0x7c, 0x10, 0x60, 0xa6, 0x6a, - 0x3b, 0xfa, 0xc6, 0xe6, 0x63, 0xfd, 0x00, 0xbd, 0xc1, 0x03, 0x63, 0xaa, 0x1b, 0x68, 0xdc, 0xd6, - 0xfb, 0xf1, 0xb1, 0xf9, 0x38, 0xc8, 0xc5, 0xe4, 0xd8, 0xdc, 0x3d, 0x2b, 0x5f, 0x24, 0xb0, 0x74, - 0xad, 0xb3, 0x71, 0x7a, 0xef, 0x80, 0xd9, 0x78, 0x90, 0x84, 0xf1, 0x90, 0xa0, 0x83, 0x38, 0x8a, - 0xc2, 0x41, 0xa5, 0xf5, 0xe8, 0x2f, 0x66, 0x69, 0xd4, 0xa2, 0xa0, 0x9d, 0x43, 0x28, 0x04, 0x2c, - 0x0c, 0xc9, 0x13, 0x6c, 0x80, 0xb9, 0x4b, 0xc1, 0x44, 0xc8, 0x4f, 0x7b, 0xaa, 0xa1, 0x4b, 0xf2, - 0x3f, 0x95, 0xdc, 0x16, 0x7d, 0x5d, 0x51, 0x72, 0x5b, 0xf9, 0x25, 0x81, 0x6a, 0x3e, 0x64, 0xb0, - 0x0d, 0x8a, 0xc4, 0x39, 0x4c, 0xff, 0x29, 0x5a, 0x63, 0xc4, 0x32, 0x7b, 0x85, 0x49, 0xc6, 0xe2, - 0xf2, 0xff, 0x72, 0xa7, 0x1d, 0x00, 0x1c, 0xec, 0x9d, 0x43, 0x8b, 0xff, 0x04, 0x9d, 0x76, 0xb0, - 0x27, 0xa8, 0xca, 0x27, 0x09, 0x80, 0xec, 0x85, 0xc0, 0xb9, 0xcc, 0x7e, 0x29, 0xb1, 0x32, 0xf6, - 0x2c, 0xe1, 0x73, 0x30, 0x29, 0xde, 0x97, 0xe8, 0x6d, 0x74, 0x04, 0xc4, 0x69, 0x17, 0x09, 0xf8, - 0x10, 0x38, 0x16, 0xc7, 0x46, 0x52, 0xa9, 0xbd, 0x3d, 0x3a, 0xad, 0x4b, 0xc7, 0xa7, 0x75, 0xe9, - 0xc7, 0x69, 0x5d, 0xfa, 0x7c, 0x56, 0x2f, 0x1c, 0x9f, 0xd5, 0x0b, 0xdf, 0xce, 0xea, 0x85, 0xbd, - 0x1b, 0x5d, 0x1e, 0xe6, 0xbf, 0x09, 0xc2, 0x32, 0x2a, 0x8b, 0x0f, 0xc2, 0xc6, 0xef, 0x00, 0x00, - 0x00, 0xff, 0xff, 0xef, 0xb6, 0x5b, 0xcd, 0xfb, 0x06, 0x00, 0x00, + // 694 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0xdd, 0x4e, 0xd4, 0x4e, + 0x18, 0xc6, 0x29, 0xbb, 0x2c, 0xfc, 0x67, 0x97, 0x05, 0x86, 0xbf, 0x49, 0x43, 0xc2, 0x0a, 0xc5, + 0x8f, 0x8d, 0x26, 0x5d, 0x59, 0xd0, 0xc4, 0x43, 0xcb, 0x8a, 0xe2, 0x47, 0xd2, 0xd4, 0x95, 0x03, + 0x4e, 0x9a, 0x4e, 0x3b, 0xdb, 0x9d, 0x6c, 0x99, 0x69, 0x3a, 0x43, 0x65, 0xaf, 0xc1, 0x13, 0x0f, + 0xbd, 0x05, 0xef, 0xc4, 0x43, 0x0e, 0x8d, 0x07, 0xc6, 0xc0, 0x1d, 0x78, 0x01, 0xc6, 0x74, 0x5a, + 0x68, 0xc1, 0x5d, 0xc0, 0x18, 0xcf, 0x3a, 0x93, 0xe7, 0xfd, 0xcd, 0xfb, 0xbc, 0xf3, 0x4c, 0x0a, + 0xd6, 0x90, 0x83, 0x86, 0x01, 0xa3, 0x2d, 0x24, 0x5c, 0x2e, 0x9c, 0x01, 0xa1, 0x7e, 0x2b, 0x5e, + 0x6f, 0xf9, 0x98, 0x62, 0x4e, 0xb8, 0x1e, 0x46, 0x4c, 0x30, 0x78, 0x23, 0x13, 0xe9, 0xb9, 0x48, + 0x8f, 0xd7, 0x97, 0xfe, 0xf7, 0x99, 0xcf, 0xa4, 0xa2, 0x95, 0x7c, 0xa5, 0xe2, 0x25, 0x6d, 0x34, + 0x31, 0x74, 0x22, 0x67, 0x3f, 0x03, 0x2e, 0xdd, 0x19, 0xad, 0x29, 0xe0, 0x53, 0xdd, 0xed, 0xd1, + 0x3a, 0x42, 0x5d, 0x4c, 0x05, 0x89, 0xf1, 0xe5, 0x47, 0xe2, 0x18, 0x53, 0x91, 0x1d, 0xa9, 0xfd, + 0x28, 0x83, 0xda, 0xb3, 0xd4, 0xd5, 0x1b, 0xe1, 0x08, 0x0c, 0x1f, 0x82, 0x4a, 0xda, 0x93, 0xaa, + 0xac, 0x94, 0x9a, 0xd5, 0xf6, 0xb2, 0x3e, 0xd2, 0xa5, 0x6e, 0x4a, 0x91, 0x95, 0x89, 0xe1, 0x2e, + 0x80, 0x3d, 0x42, 0x9d, 0x80, 0x88, 0xa1, 0x1d, 0x46, 0x2c, 0x26, 0x1e, 0x8e, 0xb8, 0x3a, 0x29, + 0x11, 0x77, 0xc7, 0x20, 0xb6, 0xb3, 0x02, 0x33, 0xd3, 0x5b, 0x0b, 0xbd, 0x0b, 0x3b, 0x1c, 0xbe, + 0x06, 0x73, 0x48, 0xb8, 0xb6, 0x87, 0x03, 0xec, 0x3b, 0x82, 0x30, 0xca, 0xd5, 0x92, 0x84, 0xde, + 0x1a, 0x03, 0x35, 0xba, 0x5b, 0x9d, 0x33, 0xb1, 0x55, 0x47, 0xc2, 0xcd, 0x97, 0x1c, 0xee, 0x80, + 0xd9, 0x98, 0x09, 0x42, 0x7d, 0x3b, 0x64, 0xef, 0x92, 0x0e, 0xcb, 0x97, 0xc2, 0x76, 0xa5, 0xd6, + 0x4c, 0xa4, 0xdb, 0xa6, 0x55, 0x8b, 0xf3, 0x25, 0x87, 0x7b, 0x60, 0x11, 0x05, 0xcc, 0x1d, 0xd8, + 0x7d, 0x4c, 0xfc, 0xbe, 0xb0, 0xdd, 0xbe, 0x43, 0x28, 0x57, 0xa7, 0x24, 0xf0, 0xde, 0xb8, 0xee, + 0x92, 0x8a, 0xe7, 0xb2, 0xc0, 0x40, 0xb4, 0xcb, 0x0c, 0xe1, 0x5a, 0x0b, 0x28, 0xdf, 0xdc, 0x92, + 0x10, 0xf8, 0x02, 0xd4, 0x0b, 0xae, 0x59, 0xc4, 0xd5, 0x8a, 0xc4, 0xae, 0x5d, 0x69, 0x9a, 0x45, + 0xd6, 0x6c, 0xee, 0x99, 0x45, 0x1c, 0x3e, 0x06, 0x95, 0xf4, 0xc6, 0xd5, 0x69, 0xc9, 0x58, 0x1d, + 0xc3, 0x78, 0x9a, 0x88, 0x76, 0xa8, 0x87, 0x0f, 0xad, 0xac, 0x00, 0xee, 0x82, 0x5a, 0x1c, 0xda, + 0x1e, 0x17, 0xb6, 0xeb, 0xb8, 0x7d, 0xac, 0xce, 0x48, 0xc0, 0xe6, 0xd5, 0xc3, 0xea, 0x10, 0x2e, + 0xb6, 0x92, 0x12, 0x23, 0xc8, 0x8c, 0x59, 0x20, 0x0e, 0x3b, 0xd9, 0xa6, 0xf6, 0x49, 0x01, 0xb3, + 0xe7, 0x46, 0x0b, 0x57, 0x41, 0xad, 0x38, 0x4c, 0x55, 0x59, 0x51, 0x9a, 0x65, 0xab, 0x5a, 0x98, + 0x0c, 0xb4, 0xc0, 0x7f, 0xbd, 0xd0, 0x4e, 0xc6, 0x12, 0x0e, 0xd4, 0xc9, 0x15, 0xa5, 0x59, 0x33, + 0x1e, 0x7d, 0xfd, 0x76, 0xb3, 0xed, 0x13, 0xd1, 0x3f, 0x40, 0xba, 0xcb, 0xf6, 0x5b, 0x59, 0x5f, + 0xf2, 0x26, 0x4e, 0x17, 0x2d, 0x31, 0x0c, 0x31, 0xd7, 0x8d, 0x1d, 0x73, 0x63, 0xf3, 0x81, 0x79, + 0x80, 0x5e, 0xe2, 0xa1, 0x35, 0xdd, 0x0b, 0x0d, 0xe1, 0x9a, 0x83, 0xe4, 0xd8, 0x62, 0x1c, 0xd4, + 0x52, 0x7a, 0x6c, 0xe1, 0x9e, 0xb5, 0x8f, 0x0a, 0x58, 0xbe, 0xd4, 0xd9, 0x75, 0x7a, 0xef, 0x82, + 0xb9, 0x64, 0x90, 0x84, 0x8b, 0x88, 0xa0, 0x83, 0x24, 0x8a, 0xd2, 0x41, 0xb5, 0x7d, 0xff, 0x0f, + 0x66, 0x69, 0xd5, 0xe3, 0xb0, 0x53, 0x40, 0x68, 0x04, 0x2c, 0x8e, 0xc8, 0x13, 0x6c, 0x82, 0xf9, + 0x73, 0xc1, 0x44, 0x88, 0x66, 0x3d, 0xd5, 0xd1, 0x39, 0xf9, 0xef, 0x4a, 0xe1, 0xca, 0xbe, 0x2e, + 0x28, 0x85, 0xab, 0xfd, 0x54, 0x40, 0xad, 0x18, 0x32, 0xd8, 0x01, 0x25, 0xe2, 0x1d, 0x4a, 0x6e, + 0xb5, 0xdd, 0xbe, 0x46, 0x2c, 0xf3, 0x57, 0x98, 0x66, 0x2c, 0x29, 0xff, 0x27, 0x77, 0xda, 0x05, + 0xc0, 0xc3, 0xc1, 0x29, 0xb4, 0xf4, 0x57, 0xd0, 0x19, 0x0f, 0x07, 0x92, 0xaa, 0xbd, 0x57, 0x00, + 0xc8, 0x5f, 0x08, 0x9c, 0xcf, 0xed, 0x97, 0x53, 0x2b, 0xd7, 0x9e, 0x25, 0x7c, 0x02, 0xa6, 0xe4, + 0xfb, 0x92, 0xbd, 0x8d, 0x8f, 0x80, 0x3c, 0xed, 0x2c, 0x01, 0x6f, 0x43, 0xcf, 0x11, 0xd8, 0x4a, + 0x2b, 0x8d, 0x57, 0x9f, 0x8f, 0x1b, 0xca, 0xd1, 0x71, 0x43, 0xf9, 0x7e, 0xdc, 0x50, 0x3e, 0x9c, + 0x34, 0x26, 0x8e, 0x4e, 0x1a, 0x13, 0x5f, 0x4e, 0x1a, 0x13, 0x7b, 0x57, 0xba, 0x3c, 0x2c, 0xfe, + 0x0d, 0xa4, 0x65, 0x54, 0x91, 0xbf, 0x82, 0x8d, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x75, 0xe9, + 0x80, 0x92, 0xf5, 0x06, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -594,16 +595,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x12 } } - { - size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.Params) > 0 { + for iNdEx := len(m.Params) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Params[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) } - i-- - dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -846,8 +851,12 @@ func (m *GenesisState) Size() (n int) { } var l int _ = l - l = m.Params.Size() - n += 1 + l + sovGenesis(uint64(l)) + if len(m.Params) > 0 { + for _, e := range m.Params { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } if len(m.FinalityProviders) > 0 { for _, e := range m.FinalityProviders { l = e.Size() @@ -1047,7 +1056,8 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Params = append(m.Params, &Params{}) + if err := m.Params[len(m.Params)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/btcstaking/types/genesis_test.go b/x/btcstaking/types/genesis_test.go index 857ed2f72..6de9bc033 100644 --- a/x/btcstaking/types/genesis_test.go +++ b/x/btcstaking/types/genesis_test.go @@ -23,7 +23,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "valid genesis state", genState: &types.GenesisState{ - Params: types.Params{ + Params: []*types.Params{&types.Params{ CovenantPks: types.DefaultParams().CovenantPks, CovenantQuorum: types.DefaultParams().CovenantQuorum, SlashingAddress: types.DefaultParams().SlashingAddress, @@ -31,15 +31,15 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), MaxActiveFinalityProviders: 100, - MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), - }, + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), + }}, }, valid: true, }, { desc: "invalid slashing rate in genesis", genState: &types.GenesisState{ - Params: types.Params{ + Params: []*types.Params{&types.Params{ CovenantPks: types.DefaultParams().CovenantPks, CovenantQuorum: types.DefaultParams().CovenantQuorum, SlashingAddress: types.DefaultParams().SlashingAddress, @@ -47,15 +47,15 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyZeroDec(), // invalid slashing rate MaxActiveFinalityProviders: 100, - MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), }, - }, + }}, valid: false, }, { desc: "invalid unbonding value in genesis", genState: &types.GenesisState{ - Params: types.Params{ + Params: []*types.Params{&types.Params{ CovenantPks: types.DefaultParams().CovenantPks, CovenantQuorum: types.DefaultParams().CovenantQuorum, SlashingAddress: types.DefaultParams().SlashingAddress, @@ -63,9 +63,9 @@ func TestGenesisState_Validate(t *testing.T) { MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.5"), SlashingRate: sdkmath.LegacyMustNewDecFromStr("0.1"), MaxActiveFinalityProviders: 100, - MinUnbondingRate: sdkmath.LegacyZeroDec(), + MinUnbondingRate: sdkmath.LegacyZeroDec(), }, - }, + }}, valid: false, }, } diff --git a/x/btcstaking/types/params.pb.go b/x/btcstaking/types/params.pb.go index a49699288..a8ccd45f3 100644 --- a/x/btcstaking/types/params.pb.go +++ b/x/btcstaking/types/params.pb.go @@ -125,8 +125,65 @@ func (m *Params) GetMinUnbondingTime() uint32 { return 0 } +// StoredParams attach information about the version of stored parameters +type StoredParams struct { + // version of the stored parameters. Each parameters update + // increments version number by 1 + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` + // NOTE: Parameters must always be provided + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *StoredParams) Reset() { *m = StoredParams{} } +func (m *StoredParams) String() string { return proto.CompactTextString(m) } +func (*StoredParams) ProtoMessage() {} +func (*StoredParams) Descriptor() ([]byte, []int) { + return fileDescriptor_8d1392776a3e15b9, []int{1} +} +func (m *StoredParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *StoredParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_StoredParams.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 *StoredParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_StoredParams.Merge(m, src) +} +func (m *StoredParams) XXX_Size() int { + return m.Size() +} +func (m *StoredParams) XXX_DiscardUnknown() { + xxx_messageInfo_StoredParams.DiscardUnknown(m) +} + +var xxx_messageInfo_StoredParams proto.InternalMessageInfo + +func (m *StoredParams) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *StoredParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + func init() { proto.RegisterType((*Params)(nil), "babylon.btcstaking.v1.Params") + proto.RegisterType((*StoredParams)(nil), "babylon.btcstaking.v1.StoredParams") } func init() { @@ -134,39 +191,42 @@ func init() { } var fileDescriptor_8d1392776a3e15b9 = []byte{ - // 502 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcd, 0x8e, 0xd3, 0x3c, - 0x14, 0x86, 0x9b, 0xaf, 0xfd, 0x0a, 0x63, 0x3a, 0xcc, 0x60, 0x40, 0x84, 0x22, 0xd2, 0x6a, 0x58, - 0x50, 0x24, 0x48, 0x28, 0x33, 0x62, 0xc1, 0xae, 0x05, 0x8d, 0x84, 0x98, 0x45, 0x48, 0x07, 0x24, - 0xd8, 0x58, 0x4e, 0xe2, 0x49, 0xad, 0xd6, 0x76, 0x89, 0x9d, 0x28, 0xb9, 0x0b, 0x96, 0x2c, 0xb9, - 0x08, 0x2e, 0x62, 0x96, 0x23, 0x56, 0x68, 0x16, 0x15, 0x6a, 0xef, 0x80, 0x2b, 0x40, 0x71, 0x92, - 0xf2, 0xb3, 0x01, 0xb1, 0x8b, 0xdf, 0xf3, 0xfa, 0x39, 0x39, 0x3f, 0x06, 0x7b, 0x3e, 0xf6, 0xf3, - 0xb9, 0xe0, 0x8e, 0xaf, 0x02, 0xa9, 0xf0, 0x8c, 0xf2, 0xc8, 0x49, 0x87, 0xce, 0x02, 0xc7, 0x98, - 0x49, 0x7b, 0x11, 0x0b, 0x25, 0xe0, 0xf5, 0xca, 0x63, 0xff, 0xf0, 0xd8, 0xe9, 0xb0, 0x7b, 0x2d, - 0x12, 0x91, 0xd0, 0x0e, 0xa7, 0xf8, 0x2a, 0xcd, 0xdd, 0x9b, 0x81, 0x90, 0x4c, 0x48, 0x54, 0x06, - 0xca, 0x43, 0x19, 0xda, 0xfb, 0xd6, 0x02, 0x6d, 0x57, 0x83, 0xe1, 0x1b, 0xd0, 0x09, 0x44, 0x4a, - 0x38, 0xe6, 0x0a, 0x2d, 0x66, 0xd2, 0x34, 0xfa, 0xcd, 0x41, 0x67, 0xfc, 0xf8, 0x7c, 0xd9, 0x7b, - 0x14, 0x51, 0x35, 0x4d, 0x7c, 0x3b, 0x10, 0xcc, 0xa9, 0xf2, 0x06, 0x53, 0x4c, 0x79, 0x7d, 0x70, - 0x54, 0xbe, 0x20, 0xd2, 0x1e, 0x3f, 0x77, 0xf7, 0x0f, 0x1e, 0xba, 0x89, 0xff, 0x82, 0xe4, 0xde, - 0xa5, 0x9a, 0xe5, 0xce, 0x24, 0xbc, 0x0b, 0x76, 0x36, 0xe8, 0x77, 0x89, 0x88, 0x13, 0x66, 0xfe, - 0xd7, 0x37, 0x06, 0xdb, 0xde, 0xe5, 0x5a, 0x7e, 0xa9, 0x55, 0x78, 0x0f, 0xec, 0xca, 0x39, 0x96, - 0x53, 0xca, 0x23, 0x84, 0xc3, 0x30, 0x26, 0x52, 0x9a, 0xcd, 0xbe, 0x31, 0xd8, 0xf2, 0x76, 0x6a, - 0x7d, 0x54, 0xca, 0xf0, 0x00, 0xdc, 0x60, 0x94, 0xa3, 0x8d, 0x5d, 0x65, 0xe8, 0x84, 0x10, 0x24, - 0xb1, 0x32, 0x5b, 0x7d, 0x63, 0xd0, 0xf4, 0xae, 0x32, 0xca, 0x27, 0x55, 0xf4, 0x38, 0x3b, 0x24, - 0x64, 0x82, 0x15, 0x9c, 0x80, 0x42, 0x46, 0x81, 0x60, 0x8c, 0x4a, 0x49, 0x05, 0x47, 0x31, 0x56, - 0xc4, 0xfc, 0xbf, 0xc8, 0x31, 0xbe, 0x73, 0xba, 0xec, 0x35, 0xce, 0x97, 0xbd, 0x5b, 0x65, 0x8b, - 0x64, 0x38, 0xb3, 0xa9, 0x70, 0x18, 0x56, 0x53, 0xfb, 0x88, 0x44, 0x38, 0xc8, 0x9f, 0x91, 0xc0, - 0xbb, 0xc2, 0x28, 0x7f, 0xba, 0xb9, 0xee, 0x61, 0x45, 0xe0, 0x6b, 0xb0, 0xbd, 0xf9, 0x0d, 0x8d, - 0x6b, 0x6b, 0xdc, 0xf0, 0x2f, 0x70, 0x9f, 0x3f, 0x3d, 0x00, 0xd5, 0x40, 0x0a, 0x78, 0xa7, 0xe6, - 0x68, 0xee, 0x08, 0xdc, 0x66, 0x38, 0x43, 0x38, 0x50, 0x34, 0x25, 0xe8, 0x84, 0x72, 0x3c, 0xa7, - 0x2a, 0x2f, 0xc6, 0x98, 0xd2, 0x90, 0xc4, 0xd2, 0xbc, 0xa0, 0x9b, 0xd8, 0x65, 0x38, 0x1b, 0x69, - 0xcf, 0x61, 0x65, 0x71, 0x6b, 0x07, 0xbc, 0x0f, 0x60, 0x51, 0x6f, 0xc2, 0x7d, 0xc1, 0x43, 0xdd, - 0x26, 0xca, 0x88, 0x79, 0x51, 0xdf, 0xdb, 0x65, 0x94, 0xbf, 0xaa, 0x03, 0xc7, 0x94, 0x11, 0x88, - 0x7e, 0x77, 0xeb, 0x6a, 0xb6, 0xfe, 0xb5, 0x9a, 0x5f, 0x12, 0x14, 0x15, 0x3d, 0x69, 0x7d, 0xf8, - 0xd8, 0x6b, 0x8c, 0x8f, 0x4e, 0x57, 0x96, 0x71, 0xb6, 0xb2, 0x8c, 0xaf, 0x2b, 0xcb, 0x78, 0xbf, - 0xb6, 0x1a, 0x67, 0x6b, 0xab, 0xf1, 0x65, 0x6d, 0x35, 0xde, 0xfe, 0x71, 0xd3, 0xb2, 0x9f, 0x1f, - 0x85, 0x5e, 0x3b, 0xbf, 0xad, 0x37, 0x79, 0xff, 0x7b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe1, 0xc0, - 0xc2, 0x59, 0x37, 0x03, 0x00, 0x00, + // 547 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcd, 0x6e, 0xd3, 0x4c, + 0x14, 0x8d, 0xbf, 0xe4, 0x4b, 0xe9, 0x34, 0xa5, 0x65, 0x00, 0x61, 0x82, 0xea, 0x44, 0x61, 0x41, + 0x90, 0xc0, 0x26, 0x6d, 0xc5, 0x02, 0x56, 0x09, 0xa8, 0x12, 0xa2, 0x8b, 0xe0, 0x14, 0x24, 0xd8, + 0x8c, 0xc6, 0xf6, 0xd4, 0x19, 0x25, 0x33, 0x13, 0x3c, 0x13, 0xcb, 0x7e, 0x0b, 0x96, 0x2c, 0x79, + 0x08, 0x1e, 0xa2, 0xcb, 0x8a, 0x15, 0xea, 0x22, 0x42, 0xc9, 0x1b, 0xf0, 0x04, 0xc8, 0x63, 0x3b, + 0xfc, 0x08, 0x09, 0xc4, 0xce, 0xf7, 0xdc, 0x73, 0xcf, 0xfd, 0xf1, 0x19, 0xd0, 0xf1, 0xb0, 0x97, + 0x4e, 0x05, 0x77, 0x3c, 0xe5, 0x4b, 0x85, 0x27, 0x94, 0x87, 0x4e, 0xdc, 0x73, 0x66, 0x38, 0xc2, + 0x4c, 0xda, 0xb3, 0x48, 0x28, 0x01, 0xaf, 0x17, 0x1c, 0xfb, 0x3b, 0xc7, 0x8e, 0x7b, 0xcd, 0x6b, + 0xa1, 0x08, 0x85, 0x66, 0x38, 0xd9, 0x57, 0x4e, 0x6e, 0xde, 0xf4, 0x85, 0x64, 0x42, 0xa2, 0x3c, + 0x91, 0x07, 0x79, 0xaa, 0xf3, 0xb5, 0x06, 0xea, 0x43, 0x2d, 0x0c, 0x5f, 0x83, 0x86, 0x2f, 0x62, + 0xc2, 0x31, 0x57, 0x68, 0x36, 0x91, 0xa6, 0xd1, 0xae, 0x76, 0x1b, 0x83, 0x87, 0x17, 0x8b, 0xd6, + 0x7e, 0x48, 0xd5, 0x78, 0xee, 0xd9, 0xbe, 0x60, 0x4e, 0xd1, 0xd7, 0x1f, 0x63, 0xca, 0xcb, 0xc0, + 0x51, 0xe9, 0x8c, 0x48, 0x7b, 0xf0, 0x6c, 0x78, 0x70, 0xf8, 0x60, 0x38, 0xf7, 0x9e, 0x93, 0xd4, + 0xdd, 0x2a, 0xb5, 0x86, 0x13, 0x09, 0xef, 0x80, 0x9d, 0xb5, 0xf4, 0xdb, 0xb9, 0x88, 0xe6, 0xcc, + 0xfc, 0xaf, 0x6d, 0x74, 0xb7, 0xdd, 0xcb, 0x25, 0xfc, 0x42, 0xa3, 0xf0, 0x2e, 0xd8, 0x95, 0x53, + 0x2c, 0xc7, 0x94, 0x87, 0x08, 0x07, 0x41, 0x44, 0xa4, 0x34, 0xab, 0x6d, 0xa3, 0xbb, 0xe9, 0xee, + 0x94, 0x78, 0x3f, 0x87, 0xe1, 0x21, 0xb8, 0xc1, 0x28, 0x47, 0x6b, 0xba, 0x4a, 0xd0, 0x29, 0x21, + 0x48, 0x62, 0x65, 0xd6, 0xda, 0x46, 0xb7, 0xea, 0x5e, 0x65, 0x94, 0x8f, 0x8a, 0xec, 0x49, 0x72, + 0x44, 0xc8, 0x08, 0x2b, 0x38, 0x02, 0x19, 0x8c, 0x7c, 0xc1, 0x18, 0x95, 0x92, 0x0a, 0x8e, 0x22, + 0xac, 0x88, 0xf9, 0x7f, 0xd6, 0x63, 0x70, 0xfb, 0x6c, 0xd1, 0xaa, 0x5c, 0x2c, 0x5a, 0xb7, 0xf2, + 0x13, 0xc9, 0x60, 0x62, 0x53, 0xe1, 0x30, 0xac, 0xc6, 0xf6, 0x31, 0x09, 0xb1, 0x9f, 0x3e, 0x25, + 0xbe, 0x7b, 0x85, 0x51, 0xfe, 0x64, 0x5d, 0xee, 0x62, 0x45, 0xe0, 0x2b, 0xb0, 0xbd, 0x1e, 0x43, + 0xcb, 0xd5, 0xb5, 0x5c, 0xef, 0x2f, 0xe4, 0x3e, 0x7d, 0xbc, 0x0f, 0x8a, 0x1f, 0x92, 0x89, 0x37, + 0x4a, 0x1d, 0xad, 0xdb, 0x07, 0x7b, 0x0c, 0x27, 0x08, 0xfb, 0x8a, 0xc6, 0x04, 0x9d, 0x52, 0x8e, + 0xa7, 0x54, 0xa5, 0xd9, 0x6f, 0x8c, 0x69, 0x40, 0x22, 0x69, 0x6e, 0xe8, 0x23, 0x36, 0x19, 0x4e, + 0xfa, 0x9a, 0x73, 0x54, 0x50, 0x86, 0x25, 0x03, 0xde, 0x03, 0x30, 0xdb, 0x77, 0xce, 0x3d, 0xc1, + 0x03, 0x7d, 0x26, 0xca, 0x88, 0x79, 0x49, 0xd7, 0xed, 0x32, 0xca, 0x5f, 0x96, 0x89, 0x13, 0xca, + 0x08, 0x44, 0xbf, 0xb2, 0xf5, 0x36, 0x9b, 0xff, 0xba, 0xcd, 0x4f, 0x0d, 0xb2, 0x8d, 0x1e, 0xd5, + 0xde, 0x7f, 0x68, 0x55, 0x3a, 0x04, 0x34, 0x46, 0x4a, 0x44, 0x24, 0x28, 0x9c, 0x67, 0x82, 0x8d, + 0x98, 0x44, 0xd9, 0x39, 0x4d, 0x43, 0x4f, 0x56, 0x86, 0xf0, 0x31, 0xa8, 0xe7, 0xb6, 0xd7, 0x7e, + 0xd9, 0xda, 0xdf, 0xb3, 0x7f, 0xeb, 0x7b, 0x3b, 0x17, 0x1a, 0xd4, 0xb2, 0x19, 0xdd, 0xa2, 0x64, + 0x70, 0x7c, 0xb6, 0xb4, 0x8c, 0xf3, 0xa5, 0x65, 0x7c, 0x59, 0x5a, 0xc6, 0xbb, 0x95, 0x55, 0x39, + 0x5f, 0x59, 0x95, 0xcf, 0x2b, 0xab, 0xf2, 0xe6, 0x8f, 0x86, 0x4e, 0x7e, 0x7c, 0x7b, 0xda, 0xdd, + 0x5e, 0x5d, 0x3f, 0x98, 0x83, 0x6f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x91, 0xdb, 0xb2, 0x9e, + 0x03, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -263,6 +323,44 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *StoredParams) 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 *StoredParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *StoredParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.Version != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.Version)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintParams(dAtA []byte, offset int, v uint64) int { offset -= sovParams(v) base := offset @@ -311,6 +409,20 @@ func (m *Params) Size() (n int) { return n } +func (m *StoredParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Version != 0 { + n += 1 + sovParams(uint64(m.Version)) + } + l = m.Params.Size() + n += 1 + l + sovParams(uint64(l)) + return n +} + func sovParams(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -612,6 +724,108 @@ func (m *Params) Unmarshal(dAtA []byte) error { } return nil } +func (m *StoredParams) 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 ErrIntOverflowParams + } + 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: StoredParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoredParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipParams(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 0016e4adb..1907483ff 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -20,6 +20,7 @@ func NewBTCDelegationResponse(btcDel *BTCDelegation, status BTCDelegationStatus) StatusDesc: status.String(), UnbondingTime: btcDel.UnbondingTime, UndelegationResponse: nil, + ParamsVersion: btcDel.ParamsVersion, } if btcDel.SlashingTx != nil { diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 8fcbb4924..ee5452bbb 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -118,6 +118,97 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +// QueryParamsRequest is request type for the Query/Params RPC method. +type QueryParamsByVersionRequest struct { + Version uint32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *QueryParamsByVersionRequest) Reset() { *m = QueryParamsByVersionRequest{} } +func (m *QueryParamsByVersionRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsByVersionRequest) ProtoMessage() {} +func (*QueryParamsByVersionRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{2} +} +func (m *QueryParamsByVersionRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsByVersionRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsByVersionRequest.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 *QueryParamsByVersionRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsByVersionRequest.Merge(m, src) +} +func (m *QueryParamsByVersionRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsByVersionRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsByVersionRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsByVersionRequest proto.InternalMessageInfo + +func (m *QueryParamsByVersionRequest) GetVersion() uint32 { + if m != nil { + return m.Version + } + return 0 +} + +// QueryParamsResponse is response type for the Query/Params RPC method. +type QueryParamsByVersionResponse struct { + // params holds all the parameters of this module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsByVersionResponse) Reset() { *m = QueryParamsByVersionResponse{} } +func (m *QueryParamsByVersionResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsByVersionResponse) ProtoMessage() {} +func (*QueryParamsByVersionResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_74d49d26f7429697, []int{3} +} +func (m *QueryParamsByVersionResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsByVersionResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsByVersionResponse.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 *QueryParamsByVersionResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsByVersionResponse.Merge(m, src) +} +func (m *QueryParamsByVersionResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsByVersionResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsByVersionResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsByVersionResponse proto.InternalMessageInfo + +func (m *QueryParamsByVersionResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + // QueryFinalityProvidersRequest is the request type for the // Query/FinalityProviders RPC method. type QueryFinalityProvidersRequest struct { @@ -129,7 +220,7 @@ func (m *QueryFinalityProvidersRequest) Reset() { *m = QueryFinalityProv func (m *QueryFinalityProvidersRequest) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProvidersRequest) ProtoMessage() {} func (*QueryFinalityProvidersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{2} + return fileDescriptor_74d49d26f7429697, []int{4} } func (m *QueryFinalityProvidersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -178,7 +269,7 @@ func (m *QueryFinalityProvidersResponse) Reset() { *m = QueryFinalityPro func (m *QueryFinalityProvidersResponse) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProvidersResponse) ProtoMessage() {} func (*QueryFinalityProvidersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{3} + return fileDescriptor_74d49d26f7429697, []int{5} } func (m *QueryFinalityProvidersResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -231,7 +322,7 @@ func (m *QueryFinalityProviderRequest) Reset() { *m = QueryFinalityProvi func (m *QueryFinalityProviderRequest) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProviderRequest) ProtoMessage() {} func (*QueryFinalityProviderRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{4} + return fileDescriptor_74d49d26f7429697, []int{6} } func (m *QueryFinalityProviderRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -277,7 +368,7 @@ func (m *QueryFinalityProviderResponse) Reset() { *m = QueryFinalityProv func (m *QueryFinalityProviderResponse) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProviderResponse) ProtoMessage() {} func (*QueryFinalityProviderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{5} + return fileDescriptor_74d49d26f7429697, []int{7} } func (m *QueryFinalityProviderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -326,7 +417,7 @@ func (m *QueryBTCDelegationsRequest) Reset() { *m = QueryBTCDelegationsR func (m *QueryBTCDelegationsRequest) String() string { return proto.CompactTextString(m) } func (*QueryBTCDelegationsRequest) ProtoMessage() {} func (*QueryBTCDelegationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{6} + return fileDescriptor_74d49d26f7429697, []int{8} } func (m *QueryBTCDelegationsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -382,7 +473,7 @@ func (m *QueryBTCDelegationsResponse) Reset() { *m = QueryBTCDelegations func (m *QueryBTCDelegationsResponse) String() string { return proto.CompactTextString(m) } func (*QueryBTCDelegationsResponse) ProtoMessage() {} func (*QueryBTCDelegationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{7} + return fileDescriptor_74d49d26f7429697, []int{9} } func (m *QueryBTCDelegationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -444,7 +535,7 @@ func (m *QueryFinalityProviderPowerAtHeightRequest) String() string { } func (*QueryFinalityProviderPowerAtHeightRequest) ProtoMessage() {} func (*QueryFinalityProviderPowerAtHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{8} + return fileDescriptor_74d49d26f7429697, []int{10} } func (m *QueryFinalityProviderPowerAtHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -502,7 +593,7 @@ func (m *QueryFinalityProviderPowerAtHeightResponse) String() string { } func (*QueryFinalityProviderPowerAtHeightResponse) ProtoMessage() {} func (*QueryFinalityProviderPowerAtHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{9} + return fileDescriptor_74d49d26f7429697, []int{11} } func (m *QueryFinalityProviderPowerAtHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -553,7 +644,7 @@ func (m *QueryFinalityProviderCurrentPowerRequest) Reset() { func (m *QueryFinalityProviderCurrentPowerRequest) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProviderCurrentPowerRequest) ProtoMessage() {} func (*QueryFinalityProviderCurrentPowerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{10} + return fileDescriptor_74d49d26f7429697, []int{12} } func (m *QueryFinalityProviderCurrentPowerRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -606,7 +697,7 @@ func (m *QueryFinalityProviderCurrentPowerResponse) String() string { } func (*QueryFinalityProviderCurrentPowerResponse) ProtoMessage() {} func (*QueryFinalityProviderCurrentPowerResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{11} + return fileDescriptor_74d49d26f7429697, []int{13} } func (m *QueryFinalityProviderCurrentPowerResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -666,7 +757,7 @@ func (m *QueryActiveFinalityProvidersAtHeightRequest) String() string { } func (*QueryActiveFinalityProvidersAtHeightRequest) ProtoMessage() {} func (*QueryActiveFinalityProvidersAtHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{12} + return fileDescriptor_74d49d26f7429697, []int{14} } func (m *QueryActiveFinalityProvidersAtHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -726,7 +817,7 @@ func (m *QueryActiveFinalityProvidersAtHeightResponse) String() string { } func (*QueryActiveFinalityProvidersAtHeightResponse) ProtoMessage() {} func (*QueryActiveFinalityProvidersAtHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{13} + return fileDescriptor_74d49d26f7429697, []int{15} } func (m *QueryActiveFinalityProvidersAtHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -777,7 +868,7 @@ func (m *QueryActivatedHeightRequest) Reset() { *m = QueryActivatedHeigh func (m *QueryActivatedHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryActivatedHeightRequest) ProtoMessage() {} func (*QueryActivatedHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{14} + return fileDescriptor_74d49d26f7429697, []int{16} } func (m *QueryActivatedHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -815,7 +906,7 @@ func (m *QueryActivatedHeightResponse) Reset() { *m = QueryActivatedHeig func (m *QueryActivatedHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryActivatedHeightResponse) ProtoMessage() {} func (*QueryActivatedHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{15} + return fileDescriptor_74d49d26f7429697, []int{17} } func (m *QueryActivatedHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -868,7 +959,7 @@ func (m *QueryFinalityProviderDelegationsRequest) Reset() { func (m *QueryFinalityProviderDelegationsRequest) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProviderDelegationsRequest) ProtoMessage() {} func (*QueryFinalityProviderDelegationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{16} + return fileDescriptor_74d49d26f7429697, []int{18} } func (m *QueryFinalityProviderDelegationsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -926,7 +1017,7 @@ func (m *QueryFinalityProviderDelegationsResponse) Reset() { func (m *QueryFinalityProviderDelegationsResponse) String() string { return proto.CompactTextString(m) } func (*QueryFinalityProviderDelegationsResponse) ProtoMessage() {} func (*QueryFinalityProviderDelegationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{17} + return fileDescriptor_74d49d26f7429697, []int{19} } func (m *QueryFinalityProviderDelegationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -980,7 +1071,7 @@ func (m *QueryBTCDelegationRequest) Reset() { *m = QueryBTCDelegationReq func (m *QueryBTCDelegationRequest) String() string { return proto.CompactTextString(m) } func (*QueryBTCDelegationRequest) ProtoMessage() {} func (*QueryBTCDelegationRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{18} + return fileDescriptor_74d49d26f7429697, []int{20} } func (m *QueryBTCDelegationRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1027,7 +1118,7 @@ func (m *QueryBTCDelegationResponse) Reset() { *m = QueryBTCDelegationRe func (m *QueryBTCDelegationResponse) String() string { return proto.CompactTextString(m) } func (*QueryBTCDelegationResponse) ProtoMessage() {} func (*QueryBTCDelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{19} + return fileDescriptor_74d49d26f7429697, []int{21} } func (m *QueryBTCDelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1103,13 +1194,15 @@ type BTCDelegationResponse struct { UnbondingTime uint32 `protobuf:"varint,13,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` // undelegation_response is the undelegation info of this delegation. UndelegationResponse *BTCUndelegationResponse `protobuf:"bytes,14,opt,name=undelegation_response,json=undelegationResponse,proto3" json:"undelegation_response,omitempty"` + // params version used to validate delegation + ParamsVersion uint32 `protobuf:"varint,15,opt,name=params_version,json=paramsVersion,proto3" json:"params_version,omitempty"` } func (m *BTCDelegationResponse) Reset() { *m = BTCDelegationResponse{} } func (m *BTCDelegationResponse) String() string { return proto.CompactTextString(m) } func (*BTCDelegationResponse) ProtoMessage() {} func (*BTCDelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{20} + return fileDescriptor_74d49d26f7429697, []int{22} } func (m *BTCDelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1222,6 +1315,13 @@ func (m *BTCDelegationResponse) GetUndelegationResponse() *BTCUndelegationRespon return nil } +func (m *BTCDelegationResponse) GetParamsVersion() uint32 { + if m != nil { + return m.ParamsVersion + } + return 0 +} + // BTCUndelegationResponse provides all necessary info about the undeleagation type BTCUndelegationResponse struct { // unbonding_tx is the transaction which will transfer the funds from staking @@ -1254,7 +1354,7 @@ func (m *BTCUndelegationResponse) Reset() { *m = BTCUndelegationResponse func (m *BTCUndelegationResponse) String() string { return proto.CompactTextString(m) } func (*BTCUndelegationResponse) ProtoMessage() {} func (*BTCUndelegationResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{21} + return fileDescriptor_74d49d26f7429697, []int{23} } func (m *BTCUndelegationResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1334,7 +1434,7 @@ func (m *BTCDelegatorDelegationsResponse) Reset() { *m = BTCDelegatorDel func (m *BTCDelegatorDelegationsResponse) String() string { return proto.CompactTextString(m) } func (*BTCDelegatorDelegationsResponse) ProtoMessage() {} func (*BTCDelegatorDelegationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{22} + return fileDescriptor_74d49d26f7429697, []int{24} } func (m *BTCDelegatorDelegationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1401,7 +1501,7 @@ func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderRespon func (m *FinalityProviderResponse) String() string { return proto.CompactTextString(m) } func (*FinalityProviderResponse) ProtoMessage() {} func (*FinalityProviderResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_74d49d26f7429697, []int{23} + return fileDescriptor_74d49d26f7429697, []int{25} } func (m *FinalityProviderResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1482,6 +1582,8 @@ func (m *FinalityProviderResponse) GetVotingPower() uint64 { func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btcstaking.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btcstaking.v1.QueryParamsResponse") + proto.RegisterType((*QueryParamsByVersionRequest)(nil), "babylon.btcstaking.v1.QueryParamsByVersionRequest") + proto.RegisterType((*QueryParamsByVersionResponse)(nil), "babylon.btcstaking.v1.QueryParamsByVersionResponse") proto.RegisterType((*QueryFinalityProvidersRequest)(nil), "babylon.btcstaking.v1.QueryFinalityProvidersRequest") proto.RegisterType((*QueryFinalityProvidersResponse)(nil), "babylon.btcstaking.v1.QueryFinalityProvidersResponse") proto.RegisterType((*QueryFinalityProviderRequest)(nil), "babylon.btcstaking.v1.QueryFinalityProviderRequest") @@ -1509,119 +1611,124 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1792 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0xdf, 0x6f, 0xdb, 0x5c, - 0x19, 0xae, 0xdb, 0x34, 0x5f, 0xfb, 0xa6, 0x49, 0xbb, 0xf3, 0x75, 0x6b, 0x96, 0xae, 0x4d, 0x17, - 0xf6, 0x75, 0x69, 0xb7, 0xd9, 0x6b, 0xda, 0xf5, 0x62, 0x83, 0x6d, 0x4d, 0xbb, 0xad, 0xfb, 0x51, - 0x2d, 0xb8, 0xab, 0x90, 0x00, 0x11, 0x39, 0xce, 0x89, 0x63, 0x35, 0xb1, 0x3d, 0xfb, 0xa4, 0x24, - 0x9a, 0x7a, 0xc3, 0x05, 0x77, 0x48, 0x48, 0x70, 0xc5, 0x3f, 0x00, 0x12, 0x97, 0xec, 0x0a, 0x89, - 0xfb, 0x71, 0x37, 0x8d, 0x0b, 0xd0, 0x2e, 0x26, 0xb4, 0x21, 0x90, 0x90, 0x10, 0xe2, 0x86, 0x6b, - 0xe4, 0xe3, 0xe3, 0xd8, 0x49, 0xec, 0x34, 0x69, 0xcb, 0x5d, 0xe3, 0xf3, 0xfe, 0x7a, 0xde, 0xf7, - 0x39, 0x8f, 0xcf, 0x71, 0xe1, 0x6a, 0x49, 0x2a, 0xb5, 0x6a, 0xba, 0x26, 0x94, 0x88, 0x6c, 0x11, - 0xe9, 0x50, 0xd5, 0x14, 0xe1, 0x68, 0x4d, 0x78, 0xdd, 0xc0, 0x66, 0x8b, 0x37, 0x4c, 0x9d, 0xe8, - 0xe8, 0x22, 0x33, 0xe1, 0x3d, 0x13, 0xfe, 0x68, 0x2d, 0x35, 0xab, 0xe8, 0x8a, 0x4e, 0x2d, 0x04, - 0xfb, 0x2f, 0xc7, 0x38, 0x75, 0x45, 0xd1, 0x75, 0xa5, 0x86, 0x05, 0xc9, 0x50, 0x05, 0x49, 0xd3, - 0x74, 0x22, 0x11, 0x55, 0xd7, 0x2c, 0xb6, 0x7a, 0x59, 0xd6, 0xad, 0xba, 0x6e, 0x15, 0x1d, 0x37, - 0xe7, 0x07, 0x5b, 0xca, 0x38, 0xbf, 0x04, 0xd9, 0x6c, 0x19, 0x44, 0x17, 0x2c, 0x2c, 0x1b, 0xb9, - 0x3b, 0x9b, 0x87, 0x6b, 0xc2, 0x21, 0x6e, 0xb9, 0x36, 0xd7, 0x98, 0x8d, 0x57, 0x68, 0x09, 0x13, - 0x69, 0xcd, 0xfd, 0xcd, 0xac, 0x56, 0x99, 0x55, 0x49, 0xb2, 0xb0, 0x03, 0xa4, 0x6d, 0x68, 0x48, - 0x8a, 0xaa, 0xd1, 0x8a, 0xdc, 0xac, 0xc1, 0xf0, 0x0d, 0xc9, 0x94, 0xea, 0x6e, 0xd6, 0xe5, 0x60, - 0x1b, 0x5f, 0x37, 0x1c, 0xbb, 0x74, 0x48, 0x2c, 0xdd, 0x70, 0x0c, 0x32, 0xb3, 0x80, 0xbe, 0x6b, - 0x97, 0x53, 0xa0, 0xd1, 0x45, 0xfc, 0xba, 0x81, 0x2d, 0x92, 0x11, 0xe1, 0xeb, 0x8e, 0xa7, 0x96, - 0xa1, 0x6b, 0x16, 0x46, 0xf7, 0x20, 0xea, 0x54, 0x91, 0xe4, 0x96, 0xb8, 0x6c, 0x2c, 0xb7, 0xc0, - 0x07, 0x8e, 0x81, 0x77, 0xdc, 0xf2, 0x91, 0x77, 0x9f, 0xd2, 0x23, 0x22, 0x73, 0xc9, 0x28, 0xb0, - 0x40, 0x63, 0x3e, 0x56, 0x35, 0xa9, 0xa6, 0x92, 0x56, 0xc1, 0xd4, 0x8f, 0xd4, 0x32, 0x36, 0xdd, - 0xa4, 0xe8, 0x31, 0x80, 0xd7, 0x0b, 0x96, 0x61, 0x99, 0x67, 0x03, 0xb1, 0x1b, 0xc7, 0x3b, 0x0c, - 0x60, 0x8d, 0xe3, 0x0b, 0x92, 0x82, 0x99, 0xaf, 0xe8, 0xf3, 0xcc, 0xfc, 0x91, 0x83, 0xc5, 0xb0, - 0x4c, 0x0c, 0xc8, 0x8f, 0x00, 0x55, 0xd8, 0xa2, 0x3d, 0x77, 0x67, 0x35, 0xc9, 0x2d, 0x8d, 0x65, - 0x63, 0x39, 0x21, 0x04, 0x54, 0x77, 0x34, 0x37, 0x98, 0x78, 0xa1, 0xd2, 0x9d, 0x07, 0x3d, 0xe9, - 0x80, 0x32, 0x4a, 0xa1, 0x5c, 0x3f, 0x11, 0x0a, 0x8b, 0xe7, 0xc7, 0xb2, 0x05, 0x57, 0x02, 0xa1, - 0xb8, 0x3d, 0xbb, 0x0a, 0xf1, 0x8a, 0x51, 0x2c, 0x11, 0xb9, 0x68, 0x1c, 0x16, 0xab, 0xb8, 0x49, - 0xdb, 0x36, 0x29, 0x42, 0xc5, 0xc8, 0x13, 0xb9, 0x70, 0xb8, 0x8b, 0x9b, 0x99, 0xe3, 0x90, 0xbe, - 0xb7, 0x9b, 0xf1, 0x43, 0xb8, 0xd0, 0xd3, 0x0c, 0xd6, 0xfe, 0xa1, 0x7b, 0x31, 0xd3, 0xdd, 0x8b, - 0xcc, 0x6f, 0x38, 0x48, 0xd1, 0xfc, 0xf9, 0x57, 0xdb, 0x3b, 0xb8, 0x86, 0x15, 0x67, 0xf3, 0xb9, - 0x00, 0xf2, 0x10, 0xb5, 0x88, 0x44, 0x1a, 0x0e, 0xa5, 0x12, 0xb9, 0xd5, 0x90, 0x8c, 0x1d, 0xde, - 0xfb, 0xd4, 0x43, 0x64, 0x9e, 0x5d, 0xc4, 0x19, 0x3d, 0x35, 0x71, 0xfe, 0xc0, 0xc1, 0x7c, 0x60, - 0xa9, 0xac, 0x51, 0x07, 0x30, 0x6d, 0x77, 0xba, 0xec, 0x2d, 0x31, 0xca, 0xdc, 0x1c, 0xa4, 0xe8, - 0x76, 0x8f, 0x12, 0x25, 0x22, 0xfb, 0xc2, 0x9f, 0x1f, 0x59, 0x2a, 0xb0, 0x12, 0x38, 0xe9, 0x82, - 0xfe, 0x63, 0x6c, 0x6e, 0x91, 0x5d, 0xac, 0x2a, 0x55, 0x32, 0x38, 0x73, 0xd0, 0x25, 0x88, 0x56, - 0xa9, 0x0f, 0x2d, 0x2a, 0x22, 0xb2, 0x5f, 0x99, 0x97, 0xb0, 0x3a, 0x48, 0x1e, 0xd6, 0xb5, 0xab, - 0x30, 0x75, 0xa4, 0x13, 0x55, 0x53, 0x8a, 0x86, 0xbd, 0x4e, 0xf3, 0x44, 0xc4, 0x98, 0xf3, 0x8c, - 0xba, 0x64, 0xf6, 0x20, 0x1b, 0x18, 0x70, 0xbb, 0x61, 0x9a, 0x58, 0x23, 0xd4, 0x68, 0x08, 0xc6, - 0x87, 0xf5, 0xa1, 0x33, 0x1c, 0x2b, 0xcf, 0x03, 0xc9, 0xf9, 0x41, 0xf6, 0x94, 0x3d, 0xda, 0x5b, - 0xf6, 0xcf, 0x38, 0xb8, 0x41, 0x13, 0x6d, 0xc9, 0x44, 0x3d, 0xc2, 0x3d, 0x72, 0xd3, 0xdd, 0xf2, - 0xb0, 0x54, 0xe7, 0xc5, 0xdf, 0x3f, 0x73, 0x70, 0x73, 0xb0, 0x7a, 0xce, 0x51, 0x06, 0xbf, 0xa7, - 0x92, 0xea, 0x1e, 0x26, 0xd2, 0xff, 0x55, 0x06, 0x17, 0xd8, 0xc6, 0xa4, 0xc0, 0x24, 0x82, 0xcb, - 0x1d, 0x8d, 0xcd, 0x6c, 0x32, 0x95, 0xec, 0x59, 0xee, 0x3f, 0xe3, 0xcc, 0x2f, 0x39, 0xb8, 0x1e, - 0xc8, 0x94, 0x00, 0xa1, 0x1a, 0x60, 0xbf, 0x9c, 0xd7, 0x1c, 0xff, 0xc1, 0x85, 0xec, 0x87, 0x20, - 0x51, 0x32, 0xe1, 0xb2, 0x4f, 0x94, 0x74, 0x33, 0x40, 0x9e, 0x36, 0x4f, 0x94, 0x27, 0x3d, 0x28, - 0xb4, 0x38, 0xe7, 0x09, 0x55, 0x87, 0xc1, 0xf9, 0xcd, 0xf5, 0x19, 0x5c, 0xee, 0x15, 0x5c, 0xb7, - 0xe3, 0xb7, 0xe0, 0x6b, 0x56, 0x6c, 0x91, 0x34, 0x8b, 0x55, 0xc9, 0xaa, 0xfa, 0xfa, 0x3e, 0xc3, - 0x96, 0x5e, 0x35, 0x77, 0x25, 0xab, 0x6a, 0xef, 0xfa, 0xd7, 0x41, 0xef, 0x99, 0x76, 0x9b, 0xf6, - 0x21, 0xd1, 0xa9, 0xdd, 0xec, 0x0d, 0x37, 0x9c, 0x74, 0xc7, 0x3b, 0xa4, 0x3b, 0xf3, 0x9f, 0x71, - 0xb8, 0x18, 0x9c, 0x6e, 0x0f, 0xa2, 0x0e, 0x55, 0x68, 0x9a, 0xa9, 0xfc, 0xe6, 0xc7, 0x4f, 0xe9, - 0x9c, 0xa2, 0x92, 0x6a, 0xa3, 0xc4, 0xcb, 0x7a, 0x5d, 0x60, 0x49, 0xe5, 0xaa, 0xa4, 0x6a, 0xee, - 0x0f, 0x81, 0xb4, 0x0c, 0x6c, 0xf1, 0xf9, 0xa7, 0x85, 0xf5, 0x8d, 0xdb, 0x85, 0x46, 0xe9, 0x39, - 0x6e, 0x89, 0xe3, 0x25, 0x9b, 0x5c, 0xe8, 0x07, 0x90, 0xf0, 0xc8, 0x57, 0x53, 0x2d, 0x5b, 0x91, - 0xc7, 0xce, 0x10, 0x36, 0xc6, 0x58, 0xfb, 0x42, 0xa5, 0xcc, 0x9e, 0xb2, 0x88, 0x64, 0x92, 0x22, - 0xdb, 0x23, 0x63, 0x8e, 0xd2, 0xd1, 0x67, 0xce, 0x46, 0x42, 0x0b, 0x00, 0x58, 0x2b, 0xbb, 0x06, - 0x11, 0x6a, 0x30, 0x89, 0x35, 0xb6, 0xcf, 0xd0, 0x3c, 0x4c, 0x12, 0x9d, 0x48, 0xb5, 0xa2, 0x25, - 0x91, 0xe4, 0x38, 0x5d, 0x9d, 0xa0, 0x0f, 0xf6, 0x25, 0x82, 0xae, 0x41, 0xc2, 0x3f, 0x46, 0xdc, - 0x4c, 0x46, 0xe9, 0x04, 0xa7, 0xbc, 0x09, 0xe2, 0x26, 0x5a, 0x86, 0x69, 0xab, 0x26, 0x59, 0x55, - 0x9f, 0xd9, 0x57, 0xd4, 0x2c, 0xee, 0x3e, 0x76, 0xec, 0xee, 0xc0, 0x9c, 0x47, 0x75, 0xba, 0x54, - 0xb4, 0x54, 0x85, 0xda, 0x4f, 0x50, 0xfb, 0xd9, 0xf6, 0xf2, 0xbe, 0xbd, 0xba, 0xaf, 0x2a, 0xb6, - 0xdb, 0x01, 0xc4, 0x65, 0xfd, 0x08, 0x6b, 0x92, 0x46, 0x6c, 0x7b, 0x2b, 0x39, 0x49, 0x77, 0xc6, - 0xed, 0x90, 0xe9, 0x6f, 0x33, 0xdb, 0xad, 0xb2, 0x64, 0xd8, 0x91, 0x54, 0x45, 0x93, 0x48, 0xc3, - 0xc4, 0x96, 0x38, 0xe5, 0x86, 0xd9, 0x57, 0x15, 0x0b, 0xdd, 0x04, 0xe4, 0x62, 0xd3, 0x1b, 0xc4, - 0x68, 0x90, 0xa2, 0x5a, 0x6e, 0x26, 0x61, 0x89, 0xcb, 0xc6, 0xdb, 0x0c, 0x7d, 0x49, 0x17, 0x9e, - 0x96, 0xe9, 0xfb, 0x54, 0xa2, 0xca, 0x9c, 0x8c, 0x2d, 0x71, 0xd9, 0x09, 0x91, 0xfd, 0x42, 0x69, - 0x88, 0x39, 0x27, 0x99, 0x62, 0x19, 0x5b, 0x72, 0x72, 0xca, 0x11, 0x16, 0xe7, 0xd1, 0x0e, 0xb6, - 0x64, 0xf4, 0x0d, 0x24, 0x1a, 0x5a, 0x49, 0xd7, 0xca, 0xb4, 0x3b, 0x6a, 0x1d, 0x27, 0xe3, 0x34, - 0x45, 0xbc, 0xfd, 0xf4, 0x95, 0x5a, 0xc7, 0x48, 0x86, 0x8b, 0x0d, 0xcd, 0x63, 0x78, 0xd1, 0x64, - 0x6c, 0x4c, 0x26, 0x28, 0xd5, 0xf9, 0x70, 0xaa, 0x1f, 0xf8, 0xdc, 0xda, 0x64, 0x9f, 0x6d, 0x04, - 0x3c, 0xcd, 0xbc, 0x1d, 0x83, 0xb9, 0x10, 0x0f, 0x94, 0x85, 0x19, 0x5f, 0x9d, 0x4d, 0xdf, 0x76, - 0xf5, 0xea, 0x77, 0xc6, 0xf8, 0x1d, 0x98, 0xf7, 0xc6, 0xe8, 0xf9, 0xb8, 0xa3, 0x1c, 0xa5, 0x4e, - 0xc9, 0xb6, 0xc9, 0x81, 0x6b, 0xc1, 0xc6, 0x29, 0xc3, 0x7c, 0x7b, 0x9c, 0x9d, 0xde, 0x74, 0x73, - 0x8c, 0xd1, 0xe1, 0x5e, 0x0b, 0xc1, 0xdb, 0x9e, 0xe6, 0x53, 0xad, 0xa2, 0x8b, 0x49, 0x37, 0x90, - 0x3f, 0x07, 0xdd, 0x17, 0x01, 0x94, 0x8c, 0x04, 0x51, 0xf2, 0x1e, 0xa4, 0xba, 0x28, 0xe9, 0x87, - 0x32, 0x4e, 0x5d, 0xe6, 0x3a, 0x59, 0xe9, 0x21, 0xa9, 0xc0, 0x25, 0x8f, 0x98, 0x3e, 0x5f, 0x2b, - 0x19, 0x3d, 0x25, 0x43, 0x67, 0xdb, 0x0c, 0xf5, 0x32, 0x59, 0x19, 0x19, 0xd2, 0x27, 0xc8, 0x3d, - 0x7a, 0x08, 0x91, 0x32, 0xae, 0x9d, 0xee, 0x4c, 0x4b, 0x3d, 0x33, 0xbf, 0x8a, 0x40, 0x32, 0xf4, - 0x9a, 0xf1, 0x08, 0x62, 0x36, 0xbd, 0x4d, 0xd5, 0xf0, 0xc9, 0xef, 0xb7, 0xdc, 0xb7, 0x86, 0x97, - 0xc1, 0x79, 0x65, 0xec, 0x78, 0xa6, 0xa2, 0xdf, 0x0f, 0xed, 0x01, 0xc8, 0x7a, 0xbd, 0xae, 0x5a, - 0x96, 0xfb, 0xee, 0x99, 0xcc, 0xdf, 0xfa, 0xf8, 0x29, 0x3d, 0xef, 0x04, 0xb2, 0xca, 0x87, 0xbc, - 0xaa, 0x0b, 0x75, 0x89, 0x54, 0xf9, 0x17, 0x58, 0x91, 0xe4, 0xd6, 0x0e, 0x96, 0x3f, 0xbc, 0xbd, - 0x05, 0x2c, 0xcf, 0x0e, 0x96, 0x45, 0x5f, 0x00, 0x74, 0x1f, 0x80, 0xe1, 0xb4, 0xc5, 0x7a, 0x8c, - 0x16, 0x95, 0x76, 0x8b, 0x72, 0xee, 0xfd, 0x7c, 0xfb, 0xde, 0xcf, 0x33, 0xf9, 0x9c, 0x64, 0x2e, - 0x85, 0x43, 0x9f, 0xd0, 0x47, 0xce, 0x43, 0xe8, 0xef, 0xc2, 0x98, 0xa1, 0x1b, 0x94, 0x34, 0xb1, - 0x5c, 0x36, 0xec, 0x7a, 0x6d, 0xea, 0x7a, 0xe5, 0x65, 0xa5, 0xa0, 0x5b, 0x16, 0xa6, 0x28, 0x44, - 0xdb, 0x09, 0x6d, 0xc0, 0x25, 0xca, 0x20, 0x5c, 0x2e, 0xba, 0x90, 0x98, 0x60, 0x47, 0xa9, 0x24, - 0xcf, 0xb2, 0xd5, 0xbc, 0xb3, 0xc8, 0xb4, 0xdb, 0x96, 0x30, 0xd7, 0x8b, 0xc8, 0xae, 0xc7, 0x57, - 0xd4, 0x63, 0xc6, 0xf5, 0x20, 0x32, 0xb3, 0xf6, 0x4e, 0x52, 0x13, 0x7d, 0x4f, 0xcb, 0x93, 0x3d, - 0xa7, 0xe5, 0xdc, 0xbf, 0xa7, 0x61, 0x9c, 0xbe, 0xa0, 0xd1, 0x4f, 0x39, 0x88, 0x3a, 0x9f, 0x08, - 0xd0, 0x4a, 0x08, 0xc4, 0xde, 0x6f, 0x12, 0xa9, 0xd5, 0x41, 0x4c, 0x99, 0x48, 0x7d, 0xf3, 0x93, - 0x3f, 0xfd, 0xed, 0x17, 0xa3, 0x69, 0xb4, 0x20, 0xf4, 0xfb, 0x96, 0x82, 0x7e, 0xc7, 0xc1, 0x85, - 0x9e, 0x53, 0x32, 0xda, 0xe8, 0x97, 0x28, 0xec, 0xeb, 0x45, 0xea, 0xce, 0x90, 0x5e, 0xac, 0xd2, - 0x35, 0x5a, 0xe9, 0x0d, 0xb4, 0x12, 0x52, 0x69, 0xef, 0xf9, 0x1c, 0x7d, 0xe0, 0x60, 0xa6, 0x3b, - 0x20, 0x5a, 0x1f, 0x26, 0xbd, 0x5b, 0xf3, 0xc6, 0x70, 0x4e, 0xac, 0xe4, 0x7d, 0x5a, 0xf2, 0x1e, - 0x7a, 0x3e, 0x70, 0xc9, 0xc2, 0x9b, 0x8e, 0xa3, 0xf3, 0x71, 0xaf, 0x09, 0xfa, 0x35, 0x07, 0x89, - 0xce, 0x6b, 0x37, 0x5a, 0xeb, 0x57, 0x5d, 0xe0, 0xd7, 0x84, 0x54, 0x6e, 0x18, 0x17, 0x06, 0x87, - 0xa7, 0x70, 0xb2, 0x68, 0x59, 0x08, 0xfd, 0xa6, 0xe6, 0x3f, 0x53, 0xa3, 0xbf, 0x73, 0x90, 0x3e, - 0xe1, 0x82, 0x85, 0xf2, 0xfd, 0xea, 0x18, 0xec, 0xb6, 0x98, 0xda, 0x3e, 0x53, 0x0c, 0x06, 0xee, - 0x2e, 0x05, 0xb7, 0x81, 0x72, 0x43, 0xcc, 0xca, 0xd9, 0xd2, 0xc7, 0xe8, 0xbf, 0x1c, 0x2c, 0xf4, - 0xbd, 0xe2, 0xa3, 0x87, 0xc3, 0xf0, 0x27, 0xe8, 0x2b, 0x44, 0x6a, 0xeb, 0x0c, 0x11, 0x18, 0xc4, - 0x02, 0x85, 0xf8, 0x0c, 0xed, 0x9e, 0x9e, 0x8e, 0x54, 0xb3, 0x3c, 0xe0, 0xff, 0xe4, 0xe0, 0x4a, - 0xbf, 0x6f, 0x07, 0xe8, 0xc1, 0x30, 0x55, 0x07, 0x7c, 0xc4, 0x48, 0x3d, 0x3c, 0x7d, 0x00, 0x86, - 0xfa, 0x09, 0x45, 0xbd, 0x85, 0x1e, 0x9c, 0x11, 0x35, 0xfa, 0x2d, 0x07, 0xd3, 0x5d, 0xf7, 0x66, - 0x94, 0x3b, 0x91, 0x7a, 0x3d, 0x77, 0xf0, 0xd4, 0xfa, 0x50, 0x3e, 0x0c, 0x85, 0x40, 0x51, 0xac, - 0xa0, 0xeb, 0x21, 0x28, 0x24, 0xd7, 0x8f, 0xbd, 0x97, 0xd0, 0xbf, 0x38, 0x98, 0xef, 0x73, 0x2b, - 0x46, 0xf7, 0x87, 0x69, 0x6c, 0x80, 0x80, 0x3c, 0x38, 0xb5, 0x3f, 0x43, 0xb4, 0x47, 0x11, 0x3d, - 0x41, 0x8f, 0x4e, 0x3f, 0x17, 0xbf, 0xd8, 0xfc, 0x9e, 0x83, 0x78, 0x87, 0x6e, 0xa1, 0xdb, 0x03, - 0x4b, 0x9c, 0x8b, 0x69, 0x6d, 0x08, 0x0f, 0x86, 0x62, 0x87, 0xa2, 0xb8, 0x8f, 0xbe, 0x3d, 0x98, - 0x26, 0x0a, 0x6f, 0x02, 0x2e, 0xea, 0xc7, 0xf9, 0x17, 0xef, 0x3e, 0x2f, 0x72, 0xef, 0x3f, 0x2f, - 0x72, 0x7f, 0xfd, 0xbc, 0xc8, 0xfd, 0xfc, 0xcb, 0xe2, 0xc8, 0xfb, 0x2f, 0x8b, 0x23, 0x7f, 0xf9, - 0xb2, 0x38, 0xf2, 0xfd, 0x13, 0x4f, 0x48, 0x4d, 0x7f, 0x42, 0x7a, 0x5c, 0x2a, 0x45, 0xe9, 0x3f, - 0x2c, 0xd6, 0xff, 0x17, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x4b, 0x83, 0xf4, 0x1e, 0x1a, 0x00, 0x00, + // 1869 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, + 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x3f, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, + 0x58, 0x98, 0x21, 0x26, 0x50, 0x69, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, + 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x8a, 0x3d, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, + 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0xaa, 0xd4, 0x73, 0x2b, 0xf5, 0xd8, 0x3d, 0x55, + 0xea, 0x7d, 0x7b, 0x5b, 0x6d, 0x0f, 0xad, 0x38, 0xa0, 0x0a, 0xaa, 0x56, 0xaa, 0xd4, 0x6b, 0xcf, + 0xd5, 0xbc, 0xf7, 0xc6, 0x33, 0xb6, 0x67, 0x1c, 0x3b, 0xc9, 0xde, 0xe2, 0x79, 0xdf, 0xff, 0xef, + 0xf7, 0x7e, 0xef, 0xbd, 0x2f, 0x70, 0xa9, 0x62, 0x56, 0x3a, 0x0d, 0xe2, 0xea, 0x15, 0x66, 0x51, + 0x66, 0xee, 0x38, 0xae, 0xad, 0xef, 0xae, 0xe9, 0x2f, 0x5b, 0xd8, 0xef, 0x68, 0x9e, 0x4f, 0x18, + 0x41, 0x67, 0xa4, 0x88, 0x16, 0x89, 0x68, 0xbb, 0x6b, 0xb9, 0x45, 0x9b, 0xd8, 0x84, 0x4b, 0xe8, + 0xc1, 0x5f, 0x42, 0x38, 0x77, 0xc1, 0x26, 0xc4, 0x6e, 0x60, 0xdd, 0xf4, 0x1c, 0xdd, 0x74, 0x5d, + 0xc2, 0x4c, 0xe6, 0x10, 0x97, 0xca, 0xd5, 0xf3, 0x16, 0xa1, 0x4d, 0x42, 0xcb, 0x42, 0x4d, 0xfc, + 0x90, 0x4b, 0xaa, 0xf8, 0xa5, 0x5b, 0x7e, 0xc7, 0x63, 0x44, 0xa7, 0xd8, 0xf2, 0x0a, 0x77, 0xee, + 0xee, 0xac, 0xe9, 0x3b, 0xb8, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x15, 0xcc, 0xcc, 0xb5, + 0xf0, 0xb7, 0x94, 0xba, 0x2e, 0xa5, 0x2a, 0x26, 0xc5, 0x22, 0x91, 0xae, 0xa0, 0x67, 0xda, 0x8e, + 0xcb, 0x23, 0x0a, 0xbd, 0x26, 0xa7, 0xef, 0x99, 0xbe, 0xd9, 0x0c, 0xbd, 0x5e, 0x49, 0x96, 0x89, + 0x55, 0x43, 0xc8, 0xe5, 0x53, 0x6c, 0x11, 0x4f, 0x08, 0xa8, 0x8b, 0x80, 0xbe, 0x17, 0x84, 0x53, + 0xe2, 0xd6, 0x0d, 0xfc, 0xb2, 0x85, 0x29, 0x53, 0x0d, 0x78, 0xaf, 0xe7, 0x2b, 0xf5, 0x88, 0x4b, + 0x31, 0xfa, 0x08, 0x32, 0x22, 0x8a, 0xac, 0x72, 0x51, 0x59, 0x9d, 0x29, 0x2c, 0x6b, 0x89, 0x6d, + 0xd0, 0x84, 0x5a, 0x71, 0xea, 0xcb, 0x37, 0xf9, 0x63, 0x86, 0x54, 0x51, 0xbf, 0x0d, 0x4b, 0x31, + 0x9b, 0xc5, 0xce, 0xf7, 0xb1, 0x4f, 0x1d, 0xe2, 0x4a, 0x97, 0x28, 0x0b, 0x27, 0x76, 0xc5, 0x17, + 0x6e, 0x7c, 0xce, 0x08, 0x7f, 0xaa, 0x9f, 0xc3, 0x85, 0x64, 0xc5, 0xa3, 0x88, 0xca, 0x86, 0x65, + 0x6e, 0xfc, 0x13, 0xc7, 0x35, 0x1b, 0x0e, 0xeb, 0x94, 0x7c, 0xb2, 0xeb, 0x54, 0xb1, 0x1f, 0x96, + 0x02, 0x7d, 0x02, 0x10, 0x75, 0x48, 0x7a, 0xb8, 0xa2, 0x49, 0x98, 0x04, 0xed, 0xd4, 0x04, 0x2e, + 0x65, 0x3b, 0xb5, 0x92, 0x69, 0x63, 0xa9, 0x6b, 0xc4, 0x34, 0xd5, 0xbf, 0x28, 0xb0, 0x92, 0xe6, + 0x49, 0x26, 0xf2, 0x63, 0x40, 0x35, 0xb9, 0x18, 0xa0, 0x51, 0xac, 0x66, 0x95, 0x8b, 0x93, 0xab, + 0x33, 0x05, 0x3d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xe3, 0x74, 0xad, 0xdf, 0x0f, 0x7a, 0xd4, + 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0x36, 0x64, 0x47, 0x06, + 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0xb9, 0x9a, 0x57, 0xae, 0x30, 0xab, 0xec, 0xed, 0x94, 0xeb, 0xb8, + 0xcd, 0xcb, 0x36, 0x6d, 0x40, 0xcd, 0x2b, 0x32, 0xab, 0xb4, 0xf3, 0x18, 0xb7, 0xd5, 0xbd, 0x94, + 0xba, 0x77, 0x8b, 0xf1, 0x23, 0x38, 0x3d, 0x50, 0x0c, 0x59, 0xfe, 0xb1, 0x6b, 0xb1, 0xd0, 0x5f, + 0x0b, 0xf5, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xe2, 0xf3, 0x87, 0x9b, 0xb8, 0x81, 0x6d, 0x41, 0x09, + 0x61, 0x02, 0x45, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x80, 0xd4, 0x7c, 0xe1, 0x7a, 0x8a, 0xc7, 0x1e, + 0xed, 0x6d, 0xae, 0x61, 0x48, 0xcd, 0x3e, 0xe0, 0x4c, 0x1c, 0x18, 0x38, 0x7f, 0x56, 0xe4, 0xc6, + 0xe9, 0x0f, 0x55, 0x16, 0xea, 0x05, 0x9c, 0x0a, 0x2a, 0x5d, 0x8d, 0x96, 0x24, 0x64, 0x6e, 0x8c, + 0x12, 0x74, 0xb7, 0x46, 0xf3, 0x15, 0x66, 0xc5, 0xcc, 0x1f, 0x1d, 0x58, 0x6a, 0x70, 0x2d, 0xb1, + 0xd3, 0x25, 0xf2, 0x13, 0xec, 0x6f, 0xb0, 0xc7, 0xd8, 0xb1, 0xeb, 0x6c, 0x74, 0xe4, 0xa0, 0xb3, + 0x90, 0xa9, 0x73, 0x1d, 0x1e, 0xd4, 0x94, 0x21, 0x7f, 0xa9, 0xcf, 0xe0, 0xfa, 0x28, 0x7e, 0x64, + 0xd5, 0x2e, 0xc1, 0xec, 0x2e, 0x61, 0x8e, 0x6b, 0x97, 0xbd, 0x60, 0x9d, 0xfb, 0x99, 0x32, 0x66, + 0xc4, 0x37, 0xae, 0xa2, 0x6e, 0xc1, 0x6a, 0xa2, 0xc1, 0x87, 0x2d, 0xdf, 0xc7, 0x2e, 0xe3, 0x42, + 0x63, 0x20, 0x3e, 0xad, 0x0e, 0xbd, 0xe6, 0x64, 0x78, 0x51, 0x92, 0x4a, 0x3c, 0xc9, 0x81, 0xb0, + 0x27, 0x06, 0xc3, 0xfe, 0xb9, 0x02, 0x1f, 0x70, 0x47, 0x1b, 0x16, 0x73, 0x76, 0xf1, 0x00, 0xdd, + 0xf4, 0x97, 0x3c, 0xcd, 0xd5, 0x51, 0xe1, 0xf7, 0x6f, 0x0a, 0xdc, 0x18, 0x2d, 0x9e, 0x23, 0xa4, + 0xc1, 0x1f, 0x38, 0xac, 0xbe, 0x85, 0x99, 0xf9, 0x8d, 0xd2, 0xe0, 0xb2, 0xdc, 0x98, 0x3c, 0x31, + 0x93, 0xe1, 0x6a, 0x4f, 0x61, 0xd5, 0xbb, 0x92, 0x25, 0x07, 0x96, 0x87, 0xf7, 0x58, 0xfd, 0x95, + 0x02, 0x57, 0x13, 0x91, 0x92, 0x40, 0x54, 0x23, 0xec, 0x97, 0xa3, 0xea, 0xe3, 0xbf, 0x95, 0x94, + 0xfd, 0x90, 0x44, 0x4a, 0x3e, 0x9c, 0x8f, 0x91, 0x12, 0xf1, 0x13, 0xe8, 0xe9, 0xee, 0xbe, 0xf4, + 0x44, 0x92, 0x4c, 0x1b, 0xe7, 0x22, 0xa2, 0xea, 0x11, 0x38, 0xba, 0xbe, 0x7e, 0x0a, 0xe7, 0x07, + 0x09, 0x37, 0xac, 0xf8, 0x4d, 0x78, 0x4f, 0x06, 0x5b, 0x66, 0xed, 0x72, 0xdd, 0xa4, 0xf5, 0x58, + 0xdd, 0x17, 0xe4, 0xd2, 0xf3, 0xf6, 0x63, 0x93, 0xd6, 0x83, 0x5d, 0xff, 0x32, 0xe9, 0x9c, 0xe9, + 0x96, 0x69, 0x1b, 0xe6, 0x7b, 0xb9, 0x5b, 0x9e, 0x70, 0xe3, 0x51, 0xf7, 0x5c, 0x0f, 0x75, 0xab, + 0xbf, 0xce, 0xc0, 0x99, 0x64, 0x77, 0x5b, 0x90, 0x11, 0x50, 0xe1, 0x6e, 0x66, 0x8b, 0x77, 0x5f, + 0xbf, 0xc9, 0x17, 0x6c, 0x87, 0xd5, 0x5b, 0x15, 0xcd, 0x22, 0x4d, 0x5d, 0x3a, 0xb5, 0xea, 0xa6, + 0xe3, 0x86, 0x3f, 0x74, 0xd6, 0xf1, 0x30, 0xd5, 0x8a, 0x4f, 0x4a, 0xb7, 0xd7, 0x6f, 0x95, 0x5a, + 0x95, 0xcf, 0x70, 0xc7, 0x38, 0x5e, 0x09, 0xc0, 0x85, 0x3e, 0x87, 0xf9, 0x08, 0x7c, 0x0d, 0x87, + 0x06, 0x8c, 0x3c, 0x79, 0x08, 0xb3, 0x33, 0x12, 0xb5, 0x4f, 0x1d, 0x8e, 0xec, 0x59, 0xca, 0x4c, + 0x9f, 0x95, 0xe5, 0x1e, 0x99, 0x14, 0x4c, 0xc7, 0xbf, 0x89, 0x8d, 0x84, 0x96, 0x01, 0xb0, 0x5b, + 0x0d, 0x05, 0xa6, 0xb8, 0xc0, 0x34, 0x76, 0xe5, 0x3e, 0x43, 0x4b, 0x30, 0xcd, 0x08, 0x33, 0x1b, + 0x65, 0x6a, 0xb2, 0xec, 0x71, 0xbe, 0x7a, 0x92, 0x7f, 0xd8, 0x36, 0x19, 0xba, 0x0c, 0xf3, 0xf1, + 0x36, 0xe2, 0x76, 0x36, 0xc3, 0x3b, 0x38, 0x1b, 0x75, 0x10, 0xb7, 0xd1, 0x15, 0x38, 0x45, 0x1b, + 0x26, 0xad, 0xc7, 0xc4, 0x4e, 0x70, 0xb1, 0xb9, 0xf0, 0xb3, 0x90, 0xbb, 0x03, 0xe7, 0x22, 0xa8, + 0xf3, 0xa5, 0x32, 0x75, 0x6c, 0x2e, 0x7f, 0x92, 0xcb, 0x2f, 0x76, 0x97, 0xb7, 0x83, 0xd5, 0x6d, + 0xc7, 0x0e, 0xd4, 0x5e, 0xc0, 0x9c, 0x45, 0x76, 0xb1, 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0xd9, 0x69, + 0xbe, 0x33, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0xdd, 0xa8, 0x9a, 0x5e, 0x60, 0xc9, 0xb1, 0x5d, + 0x93, 0xb5, 0x7c, 0x4c, 0x8d, 0xd9, 0xd0, 0xcc, 0xb6, 0x63, 0x53, 0x74, 0x03, 0x50, 0x98, 0x1b, + 0x69, 0x31, 0xaf, 0xc5, 0xca, 0x4e, 0xb5, 0x9d, 0x05, 0x7e, 0xab, 0x0e, 0x11, 0xfa, 0x8c, 0x2f, + 0x3c, 0xa9, 0xf2, 0xf3, 0xd4, 0xe4, 0xcc, 0x9c, 0x9d, 0xb9, 0xa8, 0xac, 0x9e, 0x34, 0xe4, 0x2f, + 0x94, 0x87, 0x19, 0x71, 0x93, 0x29, 0x57, 0x31, 0xb5, 0xb2, 0xb3, 0x82, 0x58, 0xc4, 0xa7, 0x4d, + 0x4c, 0x2d, 0xf4, 0x3e, 0xcc, 0xb7, 0xdc, 0x0a, 0x71, 0xab, 0xbc, 0x3a, 0x4e, 0x13, 0x67, 0xe7, + 0xb8, 0x8b, 0xb9, 0xee, 0xd7, 0xe7, 0x4e, 0x13, 0x23, 0x0b, 0xce, 0xb4, 0xdc, 0x08, 0xe1, 0x65, + 0x5f, 0xa2, 0x31, 0x3b, 0xcf, 0xa1, 0xae, 0xa5, 0x43, 0xfd, 0x45, 0x4c, 0xad, 0x0b, 0xf6, 0xc5, + 0x56, 0xc2, 0xd7, 0x20, 0x16, 0x71, 0xa1, 0x2f, 0x87, 0x8f, 0x88, 0x53, 0x22, 0x16, 0xf1, 0x55, + 0x3e, 0x19, 0xd4, 0x2f, 0x26, 0xe1, 0x5c, 0x8a, 0x61, 0xb4, 0x0a, 0x0b, 0xb1, 0x74, 0xda, 0xb1, + 0x5d, 0x1d, 0xa5, 0x29, 0xba, 0xfd, 0x5d, 0x58, 0x8a, 0xba, 0x1d, 0xe9, 0x84, 0x1d, 0x9f, 0xe0, + 0x4a, 0xd9, 0xae, 0xc8, 0x8b, 0x50, 0x42, 0x76, 0xdd, 0x82, 0xa5, 0x6e, 0xd7, 0x7b, 0xb5, 0xf9, + 0x1e, 0x9a, 0xe4, 0x18, 0xb8, 0x9c, 0x52, 0x96, 0x6e, 0xd3, 0x9f, 0xb8, 0x35, 0x62, 0x64, 0x43, + 0x43, 0x71, 0x1f, 0x7c, 0xfb, 0x24, 0x20, 0x77, 0x2a, 0x09, 0xb9, 0x1f, 0x41, 0xae, 0x0f, 0xb9, + 0xf1, 0x54, 0x8e, 0x73, 0x95, 0x73, 0xbd, 0xe0, 0x8d, 0x32, 0xa9, 0xc1, 0xd9, 0x08, 0xbf, 0x31, + 0x5d, 0x9a, 0xcd, 0x1c, 0x10, 0xc8, 0x8b, 0x5d, 0x20, 0x47, 0x9e, 0xa8, 0x6a, 0x41, 0x7e, 0x9f, + 0x53, 0x01, 0x3d, 0x80, 0xa9, 0x2a, 0x6e, 0x1c, 0xec, 0xea, 0xcb, 0x35, 0xd5, 0xdf, 0x4c, 0x41, + 0x36, 0xf5, 0x35, 0xf2, 0x31, 0xcc, 0x04, 0xbb, 0xc0, 0x77, 0xbc, 0x18, 0x4b, 0x7f, 0x2b, 0x3c, + 0x5c, 0x22, 0x0f, 0xe2, 0x64, 0xd9, 0x8c, 0x44, 0x8d, 0xb8, 0x1e, 0xda, 0x02, 0xb0, 0x48, 0xb3, + 0xe9, 0x50, 0x1a, 0x1e, 0x51, 0xd3, 0xc5, 0x9b, 0xaf, 0xdf, 0xe4, 0x97, 0x84, 0x21, 0x5a, 0xdd, + 0xd1, 0x1c, 0xa2, 0x37, 0x4d, 0x56, 0xd7, 0x9e, 0x62, 0xdb, 0xb4, 0x3a, 0x9b, 0xd8, 0xfa, 0xfa, + 0x8b, 0x9b, 0x20, 0xfd, 0x6c, 0x62, 0xcb, 0x88, 0x19, 0x40, 0xf7, 0x00, 0x64, 0x9e, 0x01, 0xa7, + 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0x68, 0xa1, 0x75, 0x87, 0x16, 0x9a, 0x64, 0xd9, 0x69, + 0xa9, 0x52, 0xda, 0x89, 0x9d, 0x07, 0x53, 0x47, 0x71, 0x1e, 0x7c, 0x08, 0x93, 0x1e, 0xf1, 0x38, + 0x68, 0x66, 0x0a, 0xab, 0x69, 0xaf, 0x70, 0x9f, 0x90, 0xda, 0xb3, 0x5a, 0x89, 0x50, 0x8a, 0x79, + 0x16, 0x46, 0xa0, 0x84, 0xd6, 0xe1, 0x2c, 0x47, 0x10, 0xae, 0x96, 0xc3, 0x94, 0x24, 0xaf, 0x67, + 0x38, 0x73, 0x2f, 0xca, 0xd5, 0xa2, 0x58, 0x94, 0x14, 0x1f, 0x30, 0x5d, 0xa8, 0xc5, 0xac, 0x50, + 0xe3, 0x04, 0xd7, 0x58, 0x08, 0x35, 0x98, 0x25, 0xa5, 0xa3, 0x0b, 0xd7, 0xc9, 0xa1, 0x97, 0xea, + 0xe9, 0x81, 0x4b, 0x75, 0xe1, 0xb7, 0xa7, 0xe1, 0x38, 0x3f, 0xc7, 0xd1, 0xcf, 0x14, 0xc8, 0x88, + 0x49, 0x02, 0xba, 0x96, 0x92, 0xe2, 0xe0, 0x40, 0x25, 0x77, 0x7d, 0x14, 0x51, 0x81, 0x35, 0xf5, + 0xfd, 0x9f, 0xfe, 0xf5, 0x9f, 0xbf, 0x9c, 0xc8, 0xa3, 0x65, 0x7d, 0xd8, 0x20, 0x08, 0xfd, 0x41, + 0x81, 0x53, 0x7d, 0x23, 0x11, 0x54, 0xd8, 0xdf, 0x4d, 0xff, 0xe0, 0x25, 0x77, 0x7b, 0x2c, 0x1d, + 0x19, 0xa3, 0xce, 0x63, 0xbc, 0x86, 0xae, 0x0e, 0x8d, 0x51, 0x7f, 0x25, 0xd9, 0x78, 0x0f, 0xfd, + 0x51, 0x81, 0xd3, 0x03, 0x57, 0x7f, 0xb4, 0x3e, 0xcc, 0x77, 0xda, 0x48, 0x26, 0x77, 0x67, 0x4c, + 0x2d, 0x19, 0xf3, 0x1a, 0x8f, 0xf9, 0x03, 0x74, 0x2d, 0x25, 0xe6, 0xc1, 0x47, 0x07, 0xfa, 0x5a, + 0x81, 0x85, 0x7e, 0x83, 0xe8, 0xf6, 0x38, 0xee, 0xc3, 0x98, 0xd7, 0xc7, 0x53, 0x92, 0x21, 0x6f, + 0xf3, 0x90, 0xb7, 0xd0, 0x67, 0x23, 0x87, 0xac, 0xbf, 0xea, 0x79, 0x0f, 0xec, 0x0d, 0x8a, 0xa0, + 0xdf, 0x29, 0x30, 0xdf, 0x3b, 0x4b, 0x40, 0x6b, 0xc3, 0xa2, 0x4b, 0x1c, 0x91, 0xe4, 0x0a, 0xe3, + 0xa8, 0xc8, 0x74, 0x34, 0x9e, 0xce, 0x2a, 0xba, 0xa2, 0xa7, 0x8e, 0x2f, 0xe3, 0x0f, 0x05, 0xf4, + 0x2f, 0x05, 0xf2, 0xfb, 0xbc, 0x1a, 0x51, 0x71, 0x58, 0x1c, 0xa3, 0x3d, 0x81, 0x73, 0x0f, 0x0f, + 0x65, 0x43, 0x26, 0xf7, 0x21, 0x4f, 0x6e, 0x1d, 0x15, 0xc6, 0xe8, 0x95, 0x20, 0xa0, 0x3d, 0xf4, + 0x3f, 0x05, 0x96, 0x87, 0xce, 0x2d, 0xd0, 0x83, 0x71, 0xf0, 0x93, 0x34, 0x5a, 0xc9, 0x6d, 0x1c, + 0xc2, 0x82, 0x4c, 0xb1, 0xc4, 0x53, 0xfc, 0x14, 0x3d, 0x3e, 0x38, 0x1c, 0x39, 0xc3, 0x46, 0x89, + 0xff, 0x47, 0x81, 0x0b, 0xc3, 0x06, 0x22, 0xe8, 0xfe, 0x38, 0x51, 0x27, 0x4c, 0x66, 0x72, 0x0f, + 0x0e, 0x6e, 0x40, 0x66, 0xfd, 0x88, 0x67, 0xbd, 0x81, 0xee, 0x1f, 0x32, 0x6b, 0xce, 0xd8, 0x7d, + 0xc3, 0x80, 0xe1, 0x8c, 0x9d, 0x3c, 0x58, 0x18, 0xce, 0xd8, 0x29, 0xd3, 0x86, 0x7d, 0x19, 0xdb, + 0x0c, 0xf5, 0xe4, 0x29, 0x8a, 0xfe, 0xab, 0xc0, 0xd2, 0x90, 0xa7, 0x3e, 0xba, 0x37, 0x4e, 0x61, + 0x13, 0x08, 0xe4, 0xfe, 0x81, 0xf5, 0x65, 0x46, 0x5b, 0x3c, 0xa3, 0x47, 0xe8, 0xe3, 0x83, 0xf7, + 0x25, 0x4e, 0x36, 0x7f, 0x52, 0x60, 0xae, 0x87, 0xb7, 0xd0, 0xad, 0x91, 0x29, 0x2e, 0xcc, 0x69, + 0x6d, 0x0c, 0x0d, 0x99, 0xc5, 0x26, 0xcf, 0xe2, 0x1e, 0xfa, 0xce, 0x68, 0x9c, 0xa8, 0xbf, 0x4a, + 0x98, 0x3e, 0xec, 0x15, 0x9f, 0x7e, 0xf9, 0x76, 0x45, 0xf9, 0xea, 0xed, 0x8a, 0xf2, 0x8f, 0xb7, + 0x2b, 0xca, 0x2f, 0xde, 0xad, 0x1c, 0xfb, 0xea, 0xdd, 0xca, 0xb1, 0xbf, 0xbf, 0x5b, 0x39, 0xf6, + 0xc3, 0x7d, 0xef, 0x73, 0xed, 0xb8, 0x43, 0x7e, 0xb9, 0xab, 0x64, 0xf8, 0xff, 0x86, 0x6e, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x9b, 0xda, 0xbf, 0x89, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1638,6 +1745,8 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // ParamsByVersion queries the parameters of the module for a specific version of past params. + ParamsByVersion(ctx context.Context, in *QueryParamsByVersionRequest, opts ...grpc.CallOption) (*QueryParamsByVersionResponse, error) // FinalityProviders queries all finality providers FinalityProviders(ctx context.Context, in *QueryFinalityProvidersRequest, opts ...grpc.CallOption) (*QueryFinalityProvidersResponse, error) // FinalityProvider info about one finality provider @@ -1676,6 +1785,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) ParamsByVersion(ctx context.Context, in *QueryParamsByVersionRequest, opts ...grpc.CallOption) (*QueryParamsByVersionResponse, error) { + out := new(QueryParamsByVersionResponse) + err := c.cc.Invoke(ctx, "/babylon.btcstaking.v1.Query/ParamsByVersion", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) FinalityProviders(ctx context.Context, in *QueryFinalityProvidersRequest, opts ...grpc.CallOption) (*QueryFinalityProvidersResponse, error) { out := new(QueryFinalityProvidersResponse) err := c.cc.Invoke(ctx, "/babylon.btcstaking.v1.Query/FinalityProviders", in, out, opts...) @@ -1761,6 +1879,8 @@ func (c *queryClient) BTCDelegation(ctx context.Context, in *QueryBTCDelegationR type QueryServer interface { // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // ParamsByVersion queries the parameters of the module for a specific version of past params. + ParamsByVersion(context.Context, *QueryParamsByVersionRequest) (*QueryParamsByVersionResponse, error) // FinalityProviders queries all finality providers FinalityProviders(context.Context, *QueryFinalityProvidersRequest) (*QueryFinalityProvidersResponse, error) // FinalityProvider info about one finality provider @@ -1789,6 +1909,9 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) ParamsByVersion(ctx context.Context, req *QueryParamsByVersionRequest) (*QueryParamsByVersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ParamsByVersion not implemented") +} func (*UnimplementedQueryServer) FinalityProviders(ctx context.Context, req *QueryFinalityProvidersRequest) (*QueryFinalityProvidersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method FinalityProviders not implemented") } @@ -1839,6 +1962,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_ParamsByVersion_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsByVersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ParamsByVersion(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.btcstaking.v1.Query/ParamsByVersion", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ParamsByVersion(ctx, req.(*QueryParamsByVersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_FinalityProviders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryFinalityProvidersRequest) if err := dec(in); err != nil { @@ -2009,6 +2150,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "ParamsByVersion", + Handler: _Query_ParamsByVersion_Handler, + }, { MethodName: "FinalityProviders", Handler: _Query_FinalityProviders_Handler, @@ -2106,6 +2251,67 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryParamsByVersionRequest) 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 *QueryParamsByVersionRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsByVersionRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Version != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Version)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryParamsByVersionResponse) 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 *QueryParamsByVersionResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsByVersionResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *QueryFinalityProvidersRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2786,6 +2992,11 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.ParamsVersion != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ParamsVersion)) + i-- + dAtA[i] = 0x78 + } if m.UndelegationResponse != nil { { size, err := m.UndelegationResponse.MarshalToSizedBuffer(dAtA[:i]) @@ -3154,6 +3365,29 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QueryParamsByVersionRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Version != 0 { + n += 1 + sovQuery(uint64(m.Version)) + } + return n +} + +func (m *QueryParamsByVersionResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + func (m *QueryFinalityProvidersRequest) Size() (n int) { if m == nil { return 0 @@ -3481,6 +3715,9 @@ func (m *BTCDelegationResponse) Size() (n int) { l = m.UndelegationResponse.Size() n += 1 + l + sovQuery(uint64(l)) } + if m.ParamsVersion != 0 { + n += 1 + sovQuery(uint64(m.ParamsVersion)) + } return n } @@ -3716,6 +3953,158 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryParamsByVersionRequest) 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 ErrIntOverflowQuery + } + 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: QueryParamsByVersionRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsByVersionRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + m.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Version |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsByVersionResponse) 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 ErrIntOverflowQuery + } + 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: QueryParamsByVersionResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsByVersionResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryFinalityProvidersRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -5817,6 +6206,25 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ParamsVersion", wireType) + } + m.ParamsVersion = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ParamsVersion |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/btcstaking/types/query.pb.gw.go b/x/btcstaking/types/query.pb.gw.go index 01da4f93d..532fbec7f 100644 --- a/x/btcstaking/types/query.pb.gw.go +++ b/x/btcstaking/types/query.pb.gw.go @@ -51,6 +51,60 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } +func request_Query_ParamsByVersion_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsByVersionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["version"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version") + } + + protoReq.Version, err = runtime.Uint32(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version", err) + } + + msg, err := client.ParamsByVersion(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ParamsByVersion_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsByVersionRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["version"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "version") + } + + protoReq.Version, err = runtime.Uint32(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "version", err) + } + + msg, err := server.ParamsByVersion(ctx, &protoReq) + return msg, metadata, err + +} + var ( filter_Query_FinalityProviders_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} ) @@ -552,6 +606,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ParamsByVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ParamsByVersion_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ParamsByVersion_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_FinalityProviders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -820,6 +897,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ParamsByVersion_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ParamsByVersion_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ParamsByVersion_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_FinalityProviders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -1006,6 +1103,8 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "btcstaking", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ParamsByVersion_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "btcstaking", "v1", "params", "version"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_FinalityProviders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "btcstaking", "v1", "finality_providers"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_FinalityProvider_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "btcstaking", "v1", "finality_providers", "fp_btc_pk_hex", "finality_provider"}, "", runtime.AssumeColonVerbOpt(false))) @@ -1028,6 +1127,8 @@ var ( var ( forward_Query_Params_0 = runtime.ForwardResponseMessage + forward_Query_ParamsByVersion_0 = runtime.ForwardResponseMessage + forward_Query_FinalityProviders_0 = runtime.ForwardResponseMessage forward_Query_FinalityProvider_0 = runtime.ForwardResponseMessage From db5aca12aa56977789326fda89b2554bdd1de97c Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 1 Apr 2024 11:34:29 -0300 Subject: [PATCH 060/119] chore: add gen-helpers subcommand (#587) * chore: scripts for btc del testing * chore: removed testnet files * feat: add cli to add genkeys to genstate of x/checkpointing * chore: add check for state path * chore: moved from genhelpper to genhelpers * chore: fix misspells and removed leftovers/bad debugging comments * chore: add script to start btc chain * chore: rename chain data files * chore: add pattern of pid to all processes * feat: start btc and vigilante * chore: add block generation at each 20sec * feat: add possibility to set base btc header * chore: add run of submitter * chore: add more descriptive err * fix: simnet conf to app.toml and set vote_extensions_enable_height in consensus to 1 * feat: add covd * chore: fix vigilante separated conf for submitter and reporter * feat: add eots * feat: add fpds * chore: add funds to covenant acc * feat: inserting pending btc delegation * chore: starting with active btc dels * feat: script phase 2 testing * fix: removed bad start comment * fix: add sleep for node fully starts with dels * chore: removed genhelper ckpt-gen-key command * chore: moved gen bls commands to genhelpers subcommand and removed ckpt-gen-key * chore: add descriptive error on btclightclient.MsgInsertHeaders * chore: add comments and removed unused vars * fix: bring back IsRetargetBlock validation * chore: moved side-car processes script to babylond-deployments * chore: rollback to chaincfg.MainNetParams * chore: update CmdAddBls comment * chore: removed all devnet scripts --- .gitignore | 2 +- app/ante_btc_validation_decorator.go | 2 +- cmd/babylond/cmd/create_bls_key.go | 19 +++++++++++--- .../{add_gen_bls.go => genhelpers/bls_add.go} | 7 ++--- .../bls_add_test.go} | 17 ++++++------ .../{genbls.go => genhelpers/bls_create.go} | 7 ++--- .../bls_create_test.go} | 8 +++--- cmd/babylond/cmd/genhelpers/cmd.go | 26 +++++++++++++++++++ cmd/babylond/cmd/root.go | 4 +-- x/checkpointing/keeper/registration_state.go | 1 + 10 files changed, 68 insertions(+), 25 deletions(-) rename cmd/babylond/cmd/{add_gen_bls.go => genhelpers/bls_add.go} (93%) rename cmd/babylond/cmd/{add_gen_bls_test.go => genhelpers/bls_add_test.go} (92%) rename cmd/babylond/cmd/{genbls.go => genhelpers/bls_create.go} (91%) rename cmd/babylond/cmd/{genbls_test.go => genhelpers/bls_create_test.go} (94%) create mode 100644 cmd/babylond/cmd/genhelpers/cmd.go diff --git a/.gitignore b/.gitignore index cf18c804e..1919b38b7 100644 --- a/.gitignore +++ b/.gitignore @@ -214,4 +214,4 @@ docs/diagrams/plantuml.jar .testnets/ .testnet/ mytestnet/ -output/ +output/ \ No newline at end of file diff --git a/app/ante_btc_validation_decorator.go b/app/ante_btc_validation_decorator.go index 79f800257..46a003bb1 100644 --- a/app/ante_btc_validation_decorator.go +++ b/app/ante_btc_validation_decorator.go @@ -42,7 +42,7 @@ func (bvd BtcValidationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulat powLimit := bvd.BtcCfg.PowLimit() err := msg.ValidateHeaders(&powLimit) if err != nil { - return ctx, btclightclient.ErrInvalidProofOfWOrk + return ctx, btclightclient.ErrInvalidProofOfWOrk.Wrapf("MsgInsertHeaders error: %s - PoW Limit - %s", err.Error(), powLimit.String()) } default: // NOOP in case of other messages diff --git a/cmd/babylond/cmd/create_bls_key.go b/cmd/babylond/cmd/create_bls_key.go index d72c5301d..ab402874e 100644 --- a/cmd/babylond/cmd/create_bls_key.go +++ b/cmd/babylond/cmd/create_bls_key.go @@ -60,12 +60,25 @@ func CreateBlsKey(home string, addr sdk.AccAddress) error { nodeCfg := cmtconfig.DefaultConfig() keyPath := filepath.Join(home, nodeCfg.PrivValidatorKeyFile()) statePath := filepath.Join(home, nodeCfg.PrivValidatorStateFile()) - if !cmtos.FileExists(keyPath) { - return errors.New("validator key file does not exist") + + pv, err := LoadWrappedFilePV(keyPath, statePath) + if err != nil { + return err } - pv := privval.LoadWrappedFilePV(keyPath, statePath) + wrappedPV := privval.NewWrappedFilePV(pv.GetValPrivKey(), bls12381.GenPrivKey(), keyPath, statePath) wrappedPV.SetAccAddress(addr) return nil } + +// LoadWrappedFilePV loads the wrapped file private key from the file path. +func LoadWrappedFilePV(keyPath, statePath string) (*privval.WrappedFilePV, error) { + if !cmtos.FileExists(keyPath) { + return nil, errors.New("validator key file does not exist") + } + if !cmtos.FileExists(statePath) { + return nil, errors.New("validator state file does not exist") + } + return privval.LoadWrappedFilePV(keyPath, statePath), nil +} diff --git a/cmd/babylond/cmd/add_gen_bls.go b/cmd/babylond/cmd/genhelpers/bls_add.go similarity index 93% rename from cmd/babylond/cmd/add_gen_bls.go rename to cmd/babylond/cmd/genhelpers/bls_add.go index a55e17736..70d0a9f91 100644 --- a/cmd/babylond/cmd/add_gen_bls.go +++ b/cmd/babylond/cmd/genhelpers/bls_add.go @@ -1,4 +1,4 @@ -package cmd +package genhelpers import ( "encoding/json" @@ -16,9 +16,10 @@ import ( "github.com/babylonchain/babylon/x/checkpointing/types" ) -func AddGenBlsCmd(validator genutiltypes.MessageValidator) *cobra.Command { +// CmdAddBls CLI adds the BLS key file with proof of possesion into the genesis state. +func CmdAddBls(validator genutiltypes.MessageValidator) *cobra.Command { cmd := &cobra.Command{ - Use: "add-genesis-bls [genesis_bls_file]", + Use: "add-bls [genesis_bls_file]", Short: "Add a genesis BLS key to genesis.json", Long: `Add a genesis BLS key per validator and update the pregenesis file in place to include their BLS keys in the checkpointing module's genesis state.' diff --git a/cmd/babylond/cmd/add_gen_bls_test.go b/cmd/babylond/cmd/genhelpers/bls_add_test.go similarity index 92% rename from cmd/babylond/cmd/add_gen_bls_test.go rename to cmd/babylond/cmd/genhelpers/bls_add_test.go index f261c2c09..015900c48 100644 --- a/cmd/babylond/cmd/add_gen_bls_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_add_test.go @@ -1,4 +1,4 @@ -package cmd_test +package genhelpers_test import ( "context" @@ -8,6 +8,7 @@ import ( dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/cosmos-sdk/server/config" + "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/x/genutil" @@ -30,7 +31,7 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" "github.com/babylonchain/babylon/privval" "github.com/babylonchain/babylon/testutil/cli" "github.com/babylonchain/babylon/testutil/datagen" @@ -67,7 +68,7 @@ func newConfig() depinject.Config { // test adding genesis BLS keys without gentx // error is expected -func Test_AddGenBlsCmdWithoutGentx(t *testing.T) { +func Test_CmdCreateAddWithoutGentx(t *testing.T) { home := t.TempDir() logger := log.NewNopLogger() cmtcfg, err := genutiltest.CreateDefaultCometConfig(home) @@ -86,7 +87,7 @@ func Test_AddGenBlsCmdWithoutGentx(t *testing.T) { gentxModule := bbn.BasicModuleManager[genutiltypes.ModuleName].(genutil.AppModuleBasic) appCodec := bbn.AppCodec() - err = genutiltest.ExecInitCmd(testMbm, home, appCodec) + err = genutiltest.ExecInitCmd(module.NewBasicManager(genutil.AppModuleBasic{}), home, appCodec) require.NoError(t, err) serverCtx := server.NewContext(viper.New(), cmtcfg, logger) @@ -104,7 +105,7 @@ func Test_AddGenBlsCmdWithoutGentx(t *testing.T) { genKeyFileName := filepath.Join(home, fmt.Sprintf("gen-bls-%s.json", genKey.ValidatorAddress)) err = tempfile.WriteFileAtomic(genKeyFileName, jsonBytes, 0600) require.NoError(t, err) - addGenBlsCmd := cmd.AddGenBlsCmd(gentxModule.GenTxValidator) + addGenBlsCmd := genhelpers.CmdAddBls(gentxModule.GenTxValidator) addGenBlsCmd.SetArgs( []string{genKeyFileName}, ) @@ -114,7 +115,7 @@ func Test_AddGenBlsCmdWithoutGentx(t *testing.T) { // test adding genesis BLS keys with gentx // error is expected if adding duplicate -func Test_AddGenBlsCmdWithGentx(t *testing.T) { +func Test_CmdAddBlsWithGentx(t *testing.T) { db := dbm.NewMemDB() signer, err := app.SetupTestPrivSigner() require.NoError(t, err) @@ -144,7 +145,7 @@ func Test_AddGenBlsCmdWithGentx(t *testing.T) { for i := 0; i < cfg.NumValidators; i++ { v := testNetwork.Validators[i] // build and create genesis BLS key - genBlsCmd := cmd.GenBlsCmd() + genBlsCmd := genhelpers.CmdCreateBls() nodeCfg := cmtconfig.DefaultConfig() homeDir := filepath.Join(v.Dir, "simd") nodeCfg.SetRoot(homeDir) @@ -160,7 +161,7 @@ func Test_AddGenBlsCmdWithGentx(t *testing.T) { require.NotNil(t, genKey) // add genesis BLS key to the target context - addBlsCmd := cmd.AddGenBlsCmd(gentxModule.GenTxValidator) + addBlsCmd := genhelpers.CmdAddBls(gentxModule.GenTxValidator) _, err = cli.ExecTestCLICmd(targetCtx, addBlsCmd, []string{genKeyFileName}) require.NoError(t, err) appState, _, err := genutiltypes.GenesisStateFromGenFile(targetGenesisFile) diff --git a/cmd/babylond/cmd/genbls.go b/cmd/babylond/cmd/genhelpers/bls_create.go similarity index 91% rename from cmd/babylond/cmd/genbls.go rename to cmd/babylond/cmd/genhelpers/bls_create.go index b667178b8..e5f0ff0f8 100644 --- a/cmd/babylond/cmd/genbls.go +++ b/cmd/babylond/cmd/genhelpers/bls_create.go @@ -1,4 +1,4 @@ -package cmd +package genhelpers import ( "errors" @@ -14,9 +14,10 @@ import ( "github.com/babylonchain/babylon/privval" ) -func GenBlsCmd() *cobra.Command { +// CmdCreateBls CLI command to create BLS file with proof of possesion. +func CmdCreateBls() *cobra.Command { cmd := &cobra.Command{ - Use: "create-genesis-bls", + Use: "create-bls", Short: "Create genesis BLS key file for the validator", Long: strings.TrimSpace(`genbls will create a BLS key file that consists of {address, bls_pub_key, pop, pub_key} where pop is the proof-of-possession that proves diff --git a/cmd/babylond/cmd/genbls_test.go b/cmd/babylond/cmd/genhelpers/bls_create_test.go similarity index 94% rename from cmd/babylond/cmd/genbls_test.go rename to cmd/babylond/cmd/genhelpers/bls_create_test.go index b79486fb1..b9d2826f9 100644 --- a/cmd/babylond/cmd/genbls_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_create_test.go @@ -1,4 +1,4 @@ -package cmd_test +package genhelpers_test import ( "bufio" @@ -23,12 +23,12 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" "github.com/babylonchain/babylon/privval" "github.com/babylonchain/babylon/x/checkpointing/types" ) -func Test_GenBlsCmd(t *testing.T) { +func Test_CmdCreateBls(t *testing.T) { home := t.TempDir() logger := log.NewNopLogger() cfg, err := genutiltest.CreateDefaultCometConfig(home) @@ -55,7 +55,7 @@ func Test_GenBlsCmd(t *testing.T) { ctx := context.Background() ctx = context.WithValue(ctx, server.ServerContextKey, serverCtx) ctx = context.WithValue(ctx, client.ClientContextKey, &clientCtx) - genBlsCmd := cmd.GenBlsCmd() + genBlsCmd := genhelpers.CmdCreateBls() genBlsCmd.SetArgs([]string{fmt.Sprintf("--%s=%s", flags.FlagHome, home)}) // create keyring to get the validator address diff --git a/cmd/babylond/cmd/genhelpers/cmd.go b/cmd/babylond/cmd/genhelpers/cmd.go new file mode 100644 index 000000000..22d77400b --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/cmd.go @@ -0,0 +1,26 @@ +package genhelpers + +import ( + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" +) + +// CmdGenHelpers helpers for manipulating the genesis file. +func CmdGenHelpers(validator genutiltypes.MessageValidator) *cobra.Command { + cmd := &cobra.Command{ + Use: "gen-helpers", + Short: "Useful commands for creating the genesis state", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + CmdCreateBls(), + CmdAddBls(validator), + ) + + return cmd +} diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index 94025ee60..329be3354 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -41,6 +41,7 @@ import ( "github.com/babylonchain/babylon/app" "github.com/babylonchain/babylon/app/params" + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" ) // NewRootCmd creates a new root command for babylond. It is called once in the @@ -186,9 +187,8 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxEncodingConfig, basic AddGenesisAccountCmd(app.DefaultNodeHome), cmtcli.NewCompletionCmd(rootCmd, true), TestnetCmd(basicManager, banktypes.GenesisBalancesIterator{}), + genhelpers.CmdGenHelpers(gentxModule.GenTxValidator), CreateBlsKeyCmd(), - GenBlsCmd(), - AddGenBlsCmd(gentxModule.GenTxValidator), debug.Cmd(), confixcmd.ConfigCommand(), ) diff --git a/x/checkpointing/keeper/registration_state.go b/x/checkpointing/keeper/registration_state.go index 4649439e7..84a052c68 100644 --- a/x/checkpointing/keeper/registration_state.go +++ b/x/checkpointing/keeper/registration_state.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" "github.com/babylonchain/babylon/crypto/bls12381" From 84d6f5b3d77106843382e01afc2b190edca267a3 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Tue, 2 Apr 2024 09:01:10 +0200 Subject: [PATCH 061/119] u/relayer versions (#568) * Update babylon_contract to latest release * Use hermes-relayer v1.8.2 for e2e tests * Enable btc timestamping hermes relayer test * Sync up Hermes BTC timestampting phase 2 test with Cosmos relayer test * Increase container init / exec timeouts * Extend context deadline for e2e tests --- .circleci/config.yml | 1 + .../btc_timestamping_phase2_hermes_test.go | 65 ++++++++++++------ test/e2e/bytecode/babylon_contract.wasm | Bin 624300 -> 717442 bytes test/e2e/bytecode/version.txt | 2 +- test/e2e/containers/config.go | 5 +- test/e2e/containers/containers.go | 4 +- test/e2e/e2e_test.go | 7 +- 7 files changed, 52 insertions(+), 32 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 399f63355..97920cdec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -47,6 +47,7 @@ jobs: - add_ssh_keys - run: name: Run e2e tests + no_output_timeout: 20m command: | sudo ln -s /usr/local/go/bin/go /usr/bin/go sudo make test-e2e diff --git a/test/e2e/btc_timestamping_phase2_hermes_test.go b/test/e2e/btc_timestamping_phase2_hermes_test.go index 0029da76e..51490d369 100644 --- a/test/e2e/btc_timestamping_phase2_hermes_test.go +++ b/test/e2e/btc_timestamping_phase2_hermes_test.go @@ -6,7 +6,6 @@ import ( "github.com/babylonchain/babylon/test/e2e/configurer" "github.com/babylonchain/babylon/test/e2e/initialization" ct "github.com/babylonchain/babylon/x/checkpointing/types" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/types/query" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "github.com/stretchr/testify/suite" @@ -57,24 +56,45 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes s.NoError(err) // Validate channel state and kind (Babylon side) - babylonChannelsResp, err := babylonNode.QueryIBCChannels() - s.NoError(err) - s.Len(babylonChannelsResp.Channels, 1) - babylonChannel := babylonChannelsResp.Channels[0] - // channel has to be open and ordered - s.Equal(channeltypes.OPEN, babylonChannel.State) - s.Equal(channeltypes.ORDERED, babylonChannel.Ordering) - // the counterparty has to be the Babylon smart contract - s.Contains(babylonChannel.Counterparty.PortId, "wasm.") - - // Validate channel state (CZ side) - czChannelsResp, err := czNode.QueryIBCChannels() - s.NoError(err) - s.Len(czChannelsResp.Channels, 2) // TODO: why 2 channels? - czChannel := czChannelsResp.Channels[0] - s.Equal(channeltypes.OPEN, czChannel.State) - s.Equal(channeltypes.ORDERED, czChannel.Ordering) - s.Equal(zctypes.PortID, czChannel.Counterparty.PortId) + // Wait until the channel (Babylon side) is open + var babylonChannel *channeltypes.IdentifiedChannel + s.Eventually(func() bool { + babylonChannelsResp, err := babylonNode.QueryIBCChannels() + if err != nil { + return false + } + if len(babylonChannelsResp.Channels) != 1 { + return false + } + // channel has to be open and ordered + babylonChannel = babylonChannelsResp.Channels[0] + if babylonChannel.State != channeltypes.OPEN { + return false + } + s.Equal(channeltypes.ORDERED, babylonChannel.Ordering) + // the counterparty has to be the Babylon smart contract + s.Contains(babylonChannel.Counterparty.PortId, "wasm.") + return true + }, time.Minute, time.Second*2) + + // Wait until the channel (CZ side) is open + var czChannel *channeltypes.IdentifiedChannel + s.Eventually(func() bool { + czChannelsResp, err := czNode.QueryIBCChannels() + if err != nil { + return false + } + if len(czChannelsResp.Channels) != 1 { + return false + } + czChannel = czChannelsResp.Channels[0] + if czChannel.State != channeltypes.OPEN { + return false + } + s.Equal(channeltypes.ORDERED, czChannel.Ordering) + s.Equal(babylonChannel.PortId, czChannel.Counterparty.PortId) + return true + }, time.Minute, time.Second*2) // Query checkpoint chain info for the consumer chain listHeaderResp, err := babylonNode.QueryListHeaders(initialization.ChainBID, &query.PageRequest{Limit: 1}) @@ -105,8 +125,9 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes }, time.Minute, time.Second*2) // ensure the next receive sequence number of Babylon contract is also 3 + var nextSequenceRecv *channeltypes.QueryNextSequenceReceiveResponse s.Eventually(func() bool { - nextSequenceRecv, err := czNode.QueryNextSequenceReceive(babylonChannel.Counterparty.ChannelId, babylonChannel.Counterparty.PortId) + nextSequenceRecv, err = czNode.QueryNextSequenceReceive(babylonChannel.Counterparty.ChannelId, babylonChannel.Counterparty.PortId) if err != nil { return false } @@ -115,8 +136,8 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes }, time.Minute, time.Second*2) // Ensure the IBC packet acknowledgements (on chain B) are there - lastSequence := endEpochNum - for seq := uint64(1); seq < lastSequence; seq++ { + nextSequence := nextSequenceRecv.NextSequenceReceive + for seq := uint64(1); seq < nextSequence; seq++ { var seqResp *channeltypes.QueryPacketAcknowledgementResponse s.Eventually(func() bool { seqResp, err = czNode.QueryPacketAcknowledgement(czChannel.ChannelId, czChannel.PortId, seq) diff --git a/test/e2e/bytecode/babylon_contract.wasm b/test/e2e/bytecode/babylon_contract.wasm index f43c2f17416363e9da968b60dcec0ec9a9404c10..546c200eb754ea571693d3b84996e73fb4c903fa 100644 GIT binary patch literal 717442 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�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 z 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

=H5Xe?il3?<`QiE;2Qu(;SvTH3WJZ2%Kd)^on% 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 U1x|qwFa~&cu?1PL3r`#V00b0@8~^|S diff --git a/test/e2e/bytecode/version.txt b/test/e2e/bytecode/version.txt index 3e53cef7d..fb7a04cff 100644 --- a/test/e2e/bytecode/version.txt +++ b/test/e2e/bytecode/version.txt @@ -1 +1 @@ -535d854ed239020edd3e93cc202a7c1bcbd1a162 +v0.4.0 diff --git a/test/e2e/containers/config.go b/test/e2e/containers/config.go index f253858fa..964367871 100644 --- a/test/e2e/containers/config.go +++ b/test/e2e/containers/config.go @@ -13,12 +13,11 @@ const ( BabylonContainerName = "babylonchain/babylond" hermesRelayerRepository = "informalsystems/hermes" - // TODO: Replace with version tag once we have a working version - hermesRelayerTag = "master" + hermesRelayerTag = "v1.8.2" // Built using the `build-cosmos-relayer-docker` target on an Intel (amd64) machine and pushed to ECR cosmosRelayerRepository = "public.ecr.aws/t9e9i3h0/cosmos-relayer" // TODO: Replace with version tag once we have a working version - cosmosRelayerTag = "main" + cosmosRelayerTag = "main" ) // NewImageConfig returns ImageConfig needed for running e2e test. diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index 8ce88dbd5..6195562e5 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -89,7 +89,7 @@ func (m *Manager) ExecCmd(t *testing.T, containerName string, command []string, errBuf bytes.Buffer ) - ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() if m.isDebugLogEnabled { @@ -146,7 +146,7 @@ func (m *Manager) ExecCmd(t *testing.T, containerName string, command []string, return true }, - time.Minute, + 2*time.Minute, 50*time.Millisecond, "tx returned a non-zero code", ) diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 422123171..4c877c6c8 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -21,10 +21,9 @@ func TestBTCTimestampingTestSuite(t *testing.T) { // TestBTCTimestampingPhase2HermesTestSuite tests BTC timestamping phase 2 protocol end-to-end, // with the Hermes relayer -// TODO: Uncomment once we have a working Hermes version / release -//func TestBTCTimestampingPhase2HermesTestSuite(t *testing.T) { -// suite.Run(t, new(BTCTimestampingPhase2HermesTestSuite)) -//} +func TestBTCTimestampingPhase2HermesTestSuite(t *testing.T) { + suite.Run(t, new(BTCTimestampingPhase2HermesTestSuite)) +} // TestBTCTimestampingPhase2RlyTestSuite tests BTC timestamping phase 2 protocol end-to-end, // with the Go relayer From cedce9a9438e1c7f4694e6a2b6a3172390a62681 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 3 Apr 2024 16:33:57 +1100 Subject: [PATCH 062/119] rpc: merge rpc-client into Babylon repo (#607) --- client/README.md | 3 + client/client/client.go | 100 +++++++++++ client/client/keys.go | 49 ++++++ client/client/keys_test.go | 59 +++++++ client/client/log.go | 40 +++++ client/client/retry_utils.go | 26 +++ client/client/tx.go | 151 ++++++++++++++++ client/config/babylon_config.go | 95 +++++++++++ client/config/babylon_query_config.go | 30 ++++ client/config/babylon_query_config_test.go | 15 ++ client/docs/versions | 0 client/query/btccheckpoint.go | 63 +++++++ client/query/btclightclient.go | 78 +++++++++ client/query/btcstaking.go | 168 ++++++++++++++++++ client/query/checkpointing.go | 113 ++++++++++++ client/query/client.go | 95 +++++++++++ client/query/epoching.go | 95 +++++++++++ client/query/finality.go | 111 ++++++++++++ client/query/incentive.go | 34 ++++ client/query/monitor.go | 50 ++++++ client/query/staking.go | 33 ++++ client/query/tendermint.go | 60 +++++++ client/query/zoneconcierge.go | 96 +++++++++++ client/tx/tx.go | 116 ------------- go.mod | 74 ++++---- go.sum | 189 ++++++++++++++------- 26 files changed, 1732 insertions(+), 211 deletions(-) create mode 100644 client/README.md create mode 100644 client/client/client.go create mode 100644 client/client/keys.go create mode 100644 client/client/keys_test.go create mode 100644 client/client/log.go create mode 100644 client/client/retry_utils.go create mode 100644 client/client/tx.go create mode 100644 client/config/babylon_config.go create mode 100644 client/config/babylon_query_config.go create mode 100644 client/config/babylon_query_config_test.go delete mode 100644 client/docs/versions create mode 100644 client/query/btccheckpoint.go create mode 100644 client/query/btclightclient.go create mode 100644 client/query/btcstaking.go create mode 100644 client/query/checkpointing.go create mode 100644 client/query/client.go create mode 100644 client/query/epoching.go create mode 100644 client/query/finality.go create mode 100644 client/query/incentive.go create mode 100644 client/query/monitor.go create mode 100644 client/query/staking.go create mode 100644 client/query/tendermint.go create mode 100644 client/query/zoneconcierge.go delete mode 100644 client/tx/tx.go diff --git a/client/README.md b/client/README.md new file mode 100644 index 000000000..d0d4a9be1 --- /dev/null +++ b/client/README.md @@ -0,0 +1,3 @@ +# client + +client is meant to be imported as a library in other Babylon repos to easily navigate and interact with the Babylon nodes. diff --git a/client/client/client.go b/client/client/client.go new file mode 100644 index 000000000..14b84fc15 --- /dev/null +++ b/client/client/client.go @@ -0,0 +1,100 @@ +package client + +import ( + "context" + "time" + + bbn "github.com/babylonchain/babylon/app" + "github.com/babylonchain/babylon/client/config" + "github.com/babylonchain/babylon/client/query" + rpchttp "github.com/cometbft/cometbft/rpc/client/http" + "github.com/cosmos/relayer/v2/relayer/chains/cosmos" + "go.uber.org/zap" +) + +type Client struct { + *query.QueryClient + + provider *cosmos.CosmosProvider + timeout time.Duration + logger *zap.Logger + cfg *config.BabylonConfig +} + +func New(cfg *config.BabylonConfig, logger *zap.Logger) (*Client, error) { + var ( + zapLogger *zap.Logger + err error + ) + + // ensure cfg is valid + if err := cfg.Validate(); err != nil { + return nil, err + } + + // use the existing logger or create a new one if not given + zapLogger = logger + if zapLogger == nil { + zapLogger, err = newRootLogger("console", true) + if err != nil { + return nil, err + } + } + + provider, err := cfg.ToCosmosProviderConfig().NewProvider( + zapLogger, + "", // TODO: set home path + true, + "babylon", + ) + if err != nil { + return nil, err + } + + cp := provider.(*cosmos.CosmosProvider) + cp.PCfg.KeyDirectory = cfg.KeyDirectory + + // Create tmp Babylon app to retrieve and register codecs + // Need to override this manually as otherwise option from config is ignored + encCfg := bbn.GetEncodingConfig() + cp.Cdc = cosmos.Codec{ + InterfaceRegistry: encCfg.InterfaceRegistry, + Marshaler: encCfg.Codec, + TxConfig: encCfg.TxConfig, + Amino: encCfg.Amino, + } + + // initialise Cosmos provider + // NOTE: this will create a RPC client. The RPC client will be used for + // submitting txs and making ad hoc queries. It won't create WebSocket + // connection with Babylon node + err = cp.Init(context.Background()) + if err != nil { + return nil, err + } + + // create a queryClient so that the Client inherits all query functions + // TODO: merge this RPC client with the one in `cp` after Cosmos side + // finishes the migration to new RPC client + // see https://github.com/strangelove-ventures/cometbft-client + c, err := rpchttp.NewWithTimeout(cp.PCfg.RPCAddr, "/websocket", uint(cfg.Timeout.Seconds())) + if err != nil { + return nil, err + } + queryClient, err := query.NewWithClient(c, cfg.Timeout) + if err != nil { + return nil, err + } + + return &Client{ + queryClient, + cp, + cfg.Timeout, + zapLogger, + cfg, + }, nil +} + +func (c *Client) GetConfig() *config.BabylonConfig { + return c.cfg +} diff --git a/client/client/keys.go b/client/client/keys.go new file mode 100644 index 000000000..baf6b7bac --- /dev/null +++ b/client/client/keys.go @@ -0,0 +1,49 @@ +package client + +import ( + "fmt" + "path" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/juju/fslock" +) + +func (c *Client) GetAddr() (string, error) { + return c.provider.Address() +} + +func (c *Client) MustGetAddr() string { + addr, err := c.provider.Address() + if err != nil { + panic(fmt.Errorf("failed to get signer: %v", err)) + } + return addr +} + +func (c *Client) GetKeyring() keyring.Keyring { + return c.provider.Keybase +} + +// accessKeyWithLock triggers a function that access key ring while acquiring +// the file system lock, in order to remain thread-safe when multiple concurrent +// relayers are running on the same machine and accessing the same keyring +// adapted from +// https://github.com/babylonchain/babylon-relayer/blob/f962d0940832a8f84f747c5d9cbc67bc1b156386/bbnrelayer/utils.go#L212 +func (c *Client) accessKeyWithLock(accessFunc func()) error { + // use lock file to guard concurrent access to the keyring + lockFilePath := path.Join(c.provider.PCfg.KeyDirectory, "keys.lock") + lock := fslock.New(lockFilePath) + if err := lock.Lock(); err != nil { + return fmt.Errorf("failed to acquire file system lock (%s): %w", lockFilePath, err) + } + + // trigger function that access keyring + accessFunc() + + // unlock and release access + if err := lock.Unlock(); err != nil { + return fmt.Errorf("error unlocking file system lock (%s), please manually delete", lockFilePath) + } + + return nil +} diff --git a/client/client/keys_test.go b/client/client/keys_test.go new file mode 100644 index 000000000..5b1a716ec --- /dev/null +++ b/client/client/keys_test.go @@ -0,0 +1,59 @@ +package client_test + +import ( + "math/rand" + "strings" + "testing" + + bbn "github.com/babylonchain/babylon/app" + "github.com/babylonchain/babylon/client/client" + "github.com/babylonchain/babylon/client/config" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/stretchr/testify/require" +) + +func FuzzKeys(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + // create a keyring + keyringName := datagen.GenRandomHexStr(r, 10) + dir := t.TempDir() + mockIn := strings.NewReader("") + cdc := bbn.GetEncodingConfig() + kr, err := keyring.New(keyringName, "test", dir, mockIn, cdc.Codec) + require.NoError(t, err) + + // create a random key pair in this keyring + keyName := datagen.GenRandomHexStr(r, 10) + _, _, err = kr.NewMnemonic( + keyName, + keyring.English, + hd.CreateHDPath(118, 0, 0).String(), + keyring.DefaultBIP39Passphrase, + hd.Secp256k1, + ) + require.NoError(t, err) + + // create a Babylon client with this random keyring + cfg := config.DefaultBabylonConfig() + cfg.KeyDirectory = dir + cfg.Key = keyName + cl, err := client.New(&cfg, nil) + require.NoError(t, err) + + // retrieve the key info from key ring + keys, err := kr.List() + require.NoError(t, err) + require.Equal(t, 1, len(keys)) + + // test if the key is consistent in Babylon client and keyring + bbnAddr := cl.MustGetAddr() + addr, _ := keys[0].GetAddress() + require.Equal(t, addr.String(), bbnAddr) + }) +} diff --git a/client/client/log.go b/client/client/log.go new file mode 100644 index 000000000..ae9b45a96 --- /dev/null +++ b/client/client/log.go @@ -0,0 +1,40 @@ +package client + +import ( + "fmt" + zaplogfmt "github.com/jsternberg/zap-logfmt" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "os" + "time" +) + +func newRootLogger(format string, debug bool) (*zap.Logger, error) { + cfg := zap.NewProductionEncoderConfig() + cfg.EncodeTime = func(ts time.Time, encoder zapcore.PrimitiveArrayEncoder) { + encoder.AppendString(ts.UTC().Format("2006-01-02T15:04:05.000000Z07:00")) + } + cfg.LevelKey = "lvl" + + var enc zapcore.Encoder + switch format { + case "json": + enc = zapcore.NewJSONEncoder(cfg) + case "auto", "console": + enc = zapcore.NewConsoleEncoder(cfg) + case "logfmt": + enc = zaplogfmt.NewEncoder(cfg) + default: + return nil, fmt.Errorf("unrecognized log format %q", format) + } + + level := zap.InfoLevel + if debug { + level = zap.DebugLevel + } + return zap.New(zapcore.NewCore( + enc, + os.Stderr, + level, + )), nil +} diff --git a/client/client/retry_utils.go b/client/client/retry_utils.go new file mode 100644 index 000000000..f9bef5fe0 --- /dev/null +++ b/client/client/retry_utils.go @@ -0,0 +1,26 @@ +package client + +import ( + "cosmossdk.io/errors" + "github.com/avast/retry-go/v4" + "strings" + "time" +) + +// Variables used for retries +var ( + rtyAttNum = uint(5) + rtyAtt = retry.Attempts(rtyAttNum) + rtyDel = retry.Delay(time.Millisecond * 400) + rtyErr = retry.LastErrorOnly(true) +) + +func errorContained(err error, errList []*errors.Error) bool { + for _, e := range errList { + if strings.Contains(err.Error(), e.Error()) { + return true + } + } + + return false +} diff --git a/client/client/tx.go b/client/client/tx.go new file mode 100644 index 000000000..52d5244f2 --- /dev/null +++ b/client/client/tx.go @@ -0,0 +1,151 @@ +package client + +import ( + "context" + "fmt" + "sync" + + "cosmossdk.io/errors" + "github.com/avast/retry-go/v4" + btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/relayer/v2/relayer/chains/cosmos" + pv "github.com/cosmos/relayer/v2/relayer/provider" + "go.uber.org/zap" +) + +// ToProviderMsgs converts a list of sdk.Msg to a list of provider.RelayerMessage +func ToProviderMsgs(msgs []sdk.Msg) []pv.RelayerMessage { + relayerMsgs := []pv.RelayerMessage{} + for _, m := range msgs { + relayerMsgs = append(relayerMsgs, cosmos.NewCosmosMessage(m, func(signer string) {})) + } + return relayerMsgs +} + +// SendMsgToMempool sends a message to the mempool. +// It does not wait for the messages to be included. +func (c *Client) SendMsgToMempool(ctx context.Context, msg sdk.Msg) error { + return c.SendMsgsToMempool(ctx, []sdk.Msg{msg}) +} + +// SendMsgsToMempool sends a set of messages to the mempool. +// It does not wait for the messages to be included. +func (c *Client) SendMsgsToMempool(ctx context.Context, msgs []sdk.Msg) error { + relayerMsgs := ToProviderMsgs(msgs) + if err := retry.Do(func() error { + var sendMsgErr error + krErr := c.accessKeyWithLock(func() { + sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*pv.RelayerTxResponse, error){}) + }) + if krErr != nil { + c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(krErr)) + return retry.Unrecoverable(krErr) + } + return sendMsgErr + }, retry.Context(ctx), rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + c.logger.Debug("retrying", zap.Uint("attemp", n+1), zap.Uint("max_attempts", rtyAttNum), zap.Error(err)) + })); err != nil { + return err + } + + return nil +} + +// ReliablySendMsg reliable sends a message to the chain. +// It utilizes a file lock as well as a keyring lock to ensure atomic access. +// TODO: needs tests +func (c *Client) ReliablySendMsg(ctx context.Context, msg sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) { + return c.ReliablySendMsgs(ctx, []sdk.Msg{msg}, expectedErrors, unrecoverableErrors) +} + +// ReliablySendMsgs reliably sends a list of messages to the chain. +// It utilizes a file lock as well as a keyring lock to ensure atomic access. +// TODO: needs tests +func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) { + var ( + rlyResp *pv.RelayerTxResponse + callbackErr error + wg sync.WaitGroup + ) + + callback := func(rtr *pv.RelayerTxResponse, err error) { + rlyResp = rtr + callbackErr = err + wg.Done() + } + + wg.Add(1) + + // convert message type + relayerMsgs := ToProviderMsgs(msgs) + + // TODO: consider using Babylon's retry package + if err := retry.Do(func() error { + var sendMsgErr error + krErr := c.accessKeyWithLock(func() { + sendMsgErr = c.provider.SendMessagesToMempool(ctx, relayerMsgs, "", ctx, []func(*pv.RelayerTxResponse, error){callback}) + }) + if krErr != nil { + c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(krErr)) + return retry.Unrecoverable(krErr) + } + if sendMsgErr != nil { + if errorContained(sendMsgErr, unrecoverableErrors) { + c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(sendMsgErr)) + return retry.Unrecoverable(sendMsgErr) + } + if errorContained(sendMsgErr, expectedErrors) { + // this is necessary because if err is returned + // the callback function will not be executed so + // that the inside wg.Done will not be executed + wg.Done() + c.logger.Error("expected err when submitting the tx, skip retrying", zap.Error(sendMsgErr)) + return nil + } + return sendMsgErr + } + return nil + }, retry.Context(ctx), rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + c.logger.Debug("retrying", zap.Uint("attemp", n+1), zap.Uint("max_attempts", rtyAttNum), zap.Error(err)) + })); err != nil { + return nil, err + } + + wg.Wait() + + if callbackErr != nil { + if errorContained(callbackErr, expectedErrors) { + return nil, nil + } + return nil, callbackErr + } + + if rlyResp == nil { + // this case could happen if the error within the retry is an expected error + return nil, nil + } + + if rlyResp.Code != 0 { + return rlyResp, fmt.Errorf("transaction failed with code: %d", rlyResp.Code) + } + + return rlyResp, nil +} + +// We do not expose ctx in our client calls, which means: +// - we do not support cancellation of submitting messages +// - the only timeout is the block inclusion timeout i.e block-timeout +// TODO: To properly support cancellation we need to expose ctx in our client calls +func (c *Client) InsertBTCSpvProof(ctx context.Context, msg *btcctypes.MsgInsertBTCSpvProof) (*pv.RelayerTxResponse, error) { + return c.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{}) +} + +func (c *Client) InsertHeaders(ctx context.Context, msg *btclctypes.MsgInsertHeaders) (*pv.RelayerTxResponse, error) { + return c.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{}) +} + +// TODO: implement necessary message invocations here +// - MsgInconsistencyEvidence +// - MsgStallingEvidence diff --git a/client/config/babylon_config.go b/client/config/babylon_config.go new file mode 100644 index 000000000..a332e2633 --- /dev/null +++ b/client/config/babylon_config.go @@ -0,0 +1,95 @@ +package config + +import ( + "fmt" + "github.com/cosmos/relayer/v2/relayer/chains/cosmos" + "net/url" + "os" + "path/filepath" + "time" +) + +// BabylonConfig defines configuration for the Babylon client +// adapted from https://github.com/strangelove-ventures/lens/blob/v0.5.1/client/config.go +type BabylonConfig struct { + Key string `mapstructure:"key"` + ChainID string `mapstructure:"chain-id"` + RPCAddr string `mapstructure:"rpc-addr"` + GRPCAddr string `mapstructure:"grpc-addr"` + AccountPrefix string `mapstructure:"account-prefix"` + KeyringBackend string `mapstructure:"keyring-backend"` + GasAdjustment float64 `mapstructure:"gas-adjustment"` + GasPrices string `mapstructure:"gas-prices"` + KeyDirectory string `mapstructure:"key-directory"` + Debug bool `mapstructure:"debug"` + Timeout time.Duration `mapstructure:"timeout"` + BlockTimeout time.Duration `mapstructure:"block-timeout"` + OutputFormat string `mapstructure:"output-format"` + SignModeStr string `mapstructure:"sign-mode"` + SubmitterAddress string `mapstructure:"submitter-address"` +} + +func (cfg *BabylonConfig) Validate() error { + if _, err := url.Parse(cfg.RPCAddr); err != nil { + return fmt.Errorf("rpc-addr is not correctly formatted: %w", err) + } + if cfg.Timeout <= 0 { + return fmt.Errorf("timeout must be positive") + } + if cfg.BlockTimeout < 0 { + return fmt.Errorf("block-timeout can't be negative") + } + return nil +} + +func (cfg *BabylonConfig) ToCosmosProviderConfig() cosmos.CosmosProviderConfig { + return cosmos.CosmosProviderConfig{ + Key: cfg.Key, + ChainID: cfg.ChainID, + RPCAddr: cfg.RPCAddr, + AccountPrefix: cfg.AccountPrefix, + KeyringBackend: cfg.KeyringBackend, + GasAdjustment: cfg.GasAdjustment, + GasPrices: cfg.GasPrices, + KeyDirectory: cfg.KeyDirectory, + Debug: cfg.Debug, + Timeout: cfg.Timeout.String(), + BlockTimeout: cfg.BlockTimeout.String(), + OutputFormat: cfg.OutputFormat, + SignModeStr: cfg.SignModeStr, + } +} + +func DefaultBabylonConfig() BabylonConfig { + return BabylonConfig{ + Key: "node0", + ChainID: "chain-test", + // see https://docs.cosmos.network/master/core/grpc_rest.html for default ports + // TODO: configure HTTPS for Babylon's RPC server + // TODO: how to use Cosmos SDK's RPC server (port 1317) rather than Tendermint's RPC server (port 26657)? + RPCAddr: "http://localhost:26657", + // TODO: how to support GRPC in the Babylon client? + GRPCAddr: "https://localhost:9090", + AccountPrefix: "bbn", + KeyringBackend: "test", + GasAdjustment: 1.2, + GasPrices: "0.01ubbn", + KeyDirectory: defaultBabylonHome(), + Debug: true, + Timeout: 20 * time.Second, + OutputFormat: "json", + SignModeStr: "direct", + SubmitterAddress: "bbn1v6k7k9s8md3k29cu9runasstq5zaa0lpznk27w", // this is currently a placeholder, will not recognized by Babylon + } +} + +// defaultBabylonHome returns the default Babylon node directory, which is $HOME/.babylond +// copied from https://github.com/babylonchain/babylon/blob/648b804bc492ded2cb826ba261d7164b4614d78a/app/app.go#L205-L210 +func defaultBabylonHome() string { + userHomeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + + return filepath.Join(userHomeDir, ".babylond") +} diff --git a/client/config/babylon_query_config.go b/client/config/babylon_query_config.go new file mode 100644 index 000000000..5a378f221 --- /dev/null +++ b/client/config/babylon_query_config.go @@ -0,0 +1,30 @@ +package config + +import ( + "fmt" + "net/url" + "time" +) + +// BabylonConfig defines configuration for the Babylon query client +type BabylonQueryConfig struct { + RPCAddr string `mapstructure:"rpc-addr"` + Timeout time.Duration `mapstructure:"timeout"` +} + +func (cfg *BabylonQueryConfig) Validate() error { + if _, err := url.Parse(cfg.RPCAddr); err != nil { + return fmt.Errorf("cfg.RPCAddr is not correctly formatted: %w", err) + } + if cfg.Timeout <= 0 { + return fmt.Errorf("cfg.Timeout must be positive") + } + return nil +} + +func DefaultBabylonQueryConfig() BabylonQueryConfig { + return BabylonQueryConfig{ + RPCAddr: "http://localhost:26657", + Timeout: 20 * time.Second, + } +} diff --git a/client/config/babylon_query_config_test.go b/client/config/babylon_query_config_test.go new file mode 100644 index 000000000..ba758a1ae --- /dev/null +++ b/client/config/babylon_query_config_test.go @@ -0,0 +1,15 @@ +package config_test + +import ( + "testing" + + "github.com/babylonchain/babylon/client/config" + "github.com/stretchr/testify/require" +) + +// TestBabylonQueryConfig ensures that the default Babylon query config is valid +func TestBabylonQueryConfig(t *testing.T) { + defaultConfig := config.DefaultBabylonQueryConfig() + err := defaultConfig.Validate() + require.NoError(t, err) +} diff --git a/client/docs/versions b/client/docs/versions deleted file mode 100644 index e69de29bb..000000000 diff --git a/client/query/btccheckpoint.go b/client/query/btccheckpoint.go new file mode 100644 index 000000000..974dbe7ef --- /dev/null +++ b/client/query/btccheckpoint.go @@ -0,0 +1,63 @@ +package query + +import ( + "context" + + btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryBTCCheckpoint queries the BTCCheckpoint module of the Babylon node +// according to the given function +func (c *QueryClient) QueryBTCCheckpoint(f func(ctx context.Context, queryClient btcctypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := btcctypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// BTCCheckpointParams queries btccheckpoint module's parameters via ChainClient +func (c *QueryClient) BTCCheckpointParams() (*btcctypes.QueryParamsResponse, error) { + var resp *btcctypes.QueryParamsResponse + err := c.QueryBTCCheckpoint(func(ctx context.Context, queryClient btcctypes.QueryClient) error { + var err error + req := &btcctypes.QueryParamsRequest{} + resp, err = queryClient.Params(ctx, req) + return err + }) + + return resp, err +} + +// BTCCheckpointInfo queries btccheckpoint module for the Bitcoin position of an epoch +func (c *QueryClient) BTCCheckpointInfo(epochNumber uint64) (*btcctypes.QueryBtcCheckpointInfoResponse, error) { + var resp *btcctypes.QueryBtcCheckpointInfoResponse + err := c.QueryBTCCheckpoint(func(ctx context.Context, queryClient btcctypes.QueryClient) error { + var err error + req := &btcctypes.QueryBtcCheckpointInfoRequest{ + EpochNum: epochNumber, + } + resp, err = queryClient.BtcCheckpointInfo(ctx, req) + return err + }) + + return resp, err +} + +// BTCCheckpointsInfo queries btccheckpoint module for the Bitcoin position of an epoch range +func (c *QueryClient) BTCCheckpointsInfo(pagination *sdkquerytypes.PageRequest) (*btcctypes.QueryBtcCheckpointsInfoResponse, error) { + var resp *btcctypes.QueryBtcCheckpointsInfoResponse + err := c.QueryBTCCheckpoint(func(ctx context.Context, queryClient btcctypes.QueryClient) error { + var err error + req := &btcctypes.QueryBtcCheckpointsInfoRequest{ + Pagination: pagination, + } + resp, err = queryClient.BtcCheckpointsInfo(ctx, req) + return err + }) + return resp, err +} diff --git a/client/query/btclightclient.go b/client/query/btclightclient.go new file mode 100644 index 000000000..a20e0c19d --- /dev/null +++ b/client/query/btclightclient.go @@ -0,0 +1,78 @@ +package query + +import ( + "context" + + btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryBTCLightclient queries the BTCLightclient module of the Babylon node +// according to the given function +func (c *QueryClient) QueryBTCLightclient(f func(ctx context.Context, queryClient btclctypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := btclctypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// BTCHeaderChainTip queries hash/height of the latest BTC block in the btclightclient module +func (c *QueryClient) BTCHeaderChainTip() (*btclctypes.QueryTipResponse, error) { + var resp *btclctypes.QueryTipResponse + err := c.QueryBTCLightclient(func(ctx context.Context, queryClient btclctypes.QueryClient) error { + var err error + req := &btclctypes.QueryTipRequest{} + resp, err = queryClient.Tip(ctx, req) + return err + }) + + return resp, err +} + +// BTCBaseHeader queries the base BTC header of the btclightclient module +func (c *QueryClient) BTCBaseHeader() (*btclctypes.QueryBaseHeaderResponse, error) { + var resp *btclctypes.QueryBaseHeaderResponse + err := c.QueryBTCLightclient(func(ctx context.Context, queryClient btclctypes.QueryClient) error { + var err error + req := &btclctypes.QueryBaseHeaderRequest{} + resp, err = queryClient.BaseHeader(ctx, req) + return err + }) + + return resp, err +} + +// ContainsBTCBlock queries the btclightclient module for the existence of a block hash +func (c *QueryClient) ContainsBTCBlock(blockHash *chainhash.Hash) (*btclctypes.QueryContainsBytesResponse, error) { + var resp *btclctypes.QueryContainsBytesResponse + err := c.QueryBTCLightclient(func(ctx context.Context, queryClient btclctypes.QueryClient) error { + var err error + req := &btclctypes.QueryContainsBytesRequest{ + Hash: blockHash.CloneBytes(), + } + resp, err = queryClient.ContainsBytes(ctx, req) + return err + }) + + return resp, err +} + +// BTCMainChain queries the btclightclient module for the BTC canonical chain +func (c *QueryClient) BTCMainChain(pagination *sdkquerytypes.PageRequest) (*btclctypes.QueryMainChainResponse, error) { + var resp *btclctypes.QueryMainChainResponse + err := c.QueryBTCLightclient(func(ctx context.Context, queryClient btclctypes.QueryClient) error { + var err error + req := &btclctypes.QueryMainChainRequest{ + Pagination: pagination, + } + resp, err = queryClient.MainChain(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/btcstaking.go b/client/query/btcstaking.go new file mode 100644 index 000000000..4a9b17e68 --- /dev/null +++ b/client/query/btcstaking.go @@ -0,0 +1,168 @@ +package query + +import ( + "context" + + btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryBTCStaking queries the BTCStaking module of the Babylon node according to the given function +func (c *QueryClient) QueryBTCStaking(f func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := btcstakingtypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// BTCStakingParams queries the BTC staking module parameters +func (c *QueryClient) BTCStakingParams() (*btcstakingtypes.QueryParamsResponse, error) { + var resp *btcstakingtypes.QueryParamsResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryParamsRequest{} + resp, err = queryClient.Params(ctx, req) + return err + }) + + return resp, err +} + +// BTCStakingParamsByVersion queries the BTC staking module parameters at a given version +func (c *QueryClient) BTCStakingParamsByVersion(version uint32) (*btcstakingtypes.QueryParamsByVersionResponse, error) { + var resp *btcstakingtypes.QueryParamsByVersionResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryParamsByVersionRequest{Version: version} + resp, err = queryClient.ParamsByVersion(ctx, req) + return err + }) + + return resp, err +} + +// FinalityProvider queries the BTCStaking module for a given finlaity provider +func (c *QueryClient) FinalityProvider(fpBtcPkHex string) (*btcstakingtypes.QueryFinalityProviderResponse, error) { + var resp *btcstakingtypes.QueryFinalityProviderResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryFinalityProviderRequest{ + FpBtcPkHex: fpBtcPkHex, + } + resp, err = queryClient.FinalityProvider(ctx, req) + return err + }) + + return resp, err +} + +// FinalityProviders queries the BTCStaking module for all finality providers +func (c *QueryClient) FinalityProviders(pagination *sdkquerytypes.PageRequest) (*btcstakingtypes.QueryFinalityProvidersResponse, error) { + var resp *btcstakingtypes.QueryFinalityProvidersResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryFinalityProvidersRequest{ + Pagination: pagination, + } + resp, err = queryClient.FinalityProviders(ctx, req) + return err + }) + + return resp, err +} + +// FinalityProviderDelegations queries the BTCStaking module for all delegations of a finality provider +func (c *QueryClient) FinalityProviderDelegations(fpBtcPkHex string, pagination *sdkquerytypes.PageRequest) (*btcstakingtypes.QueryFinalityProviderDelegationsResponse, error) { + var resp *btcstakingtypes.QueryFinalityProviderDelegationsResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryFinalityProviderDelegationsRequest{ + FpBtcPkHex: fpBtcPkHex, + Pagination: pagination, + } + resp, err = queryClient.FinalityProviderDelegations(ctx, req) + return err + }) + + return resp, err +} + +// BTCDelegations queries the BTCStaking module for all delegations under a given status +func (c *QueryClient) BTCDelegations(status btcstakingtypes.BTCDelegationStatus, pagination *sdkquerytypes.PageRequest) (*btcstakingtypes.QueryBTCDelegationsResponse, error) { + var resp *btcstakingtypes.QueryBTCDelegationsResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryBTCDelegationsRequest{ + Status: status, + Pagination: pagination, + } + resp, err = queryClient.BTCDelegations(ctx, req) + return err + }) + + return resp, err +} + +// BTCDelegation queries the BTCStaking module to retrieve delegation by corresponding staking tx hash +func (c *QueryClient) BTCDelegation(stakingTxHashHex string) (*btcstakingtypes.QueryBTCDelegationResponse, error) { + var resp *btcstakingtypes.QueryBTCDelegationResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryBTCDelegationRequest{ + StakingTxHashHex: stakingTxHashHex, + } + resp, err = queryClient.BTCDelegation(ctx, req) + return err + }) + + return resp, err +} + +// ActiveFinalityProvidersAtHeight queries the BTCStaking module for all finality providers +// with non-zero voting power at a given height +func (c *QueryClient) ActiveFinalityProvidersAtHeight(height uint64, pagination *sdkquerytypes.PageRequest) (*btcstakingtypes.QueryActiveFinalityProvidersAtHeightResponse, error) { + var resp *btcstakingtypes.QueryActiveFinalityProvidersAtHeightResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryActiveFinalityProvidersAtHeightRequest{ + Height: height, + Pagination: pagination, + } + resp, err = queryClient.ActiveFinalityProvidersAtHeight(ctx, req) + return err + }) + + return resp, err +} + +// FinalityProviderPowerAtHeight queries the BTCStaking module for the power of a finality provider at a given height +func (c *QueryClient) FinalityProviderPowerAtHeight(fpBtcPkHex string, height uint64) (*btcstakingtypes.QueryFinalityProviderPowerAtHeightResponse, error) { + var resp *btcstakingtypes.QueryFinalityProviderPowerAtHeightResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryFinalityProviderPowerAtHeightRequest{ + FpBtcPkHex: fpBtcPkHex, + Height: height, + } + resp, err = queryClient.FinalityProviderPowerAtHeight(ctx, req) + return err + }) + + return resp, err +} + +func (c *QueryClient) ActivatedHeight() (*btcstakingtypes.QueryActivatedHeightResponse, error) { + var resp *btcstakingtypes.QueryActivatedHeightResponse + err := c.QueryBTCStaking(func(ctx context.Context, queryClient btcstakingtypes.QueryClient) error { + var err error + req := &btcstakingtypes.QueryActivatedHeightRequest{} + resp, err = queryClient.ActivatedHeight(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/checkpointing.go b/client/query/checkpointing.go new file mode 100644 index 000000000..50afba26c --- /dev/null +++ b/client/query/checkpointing.go @@ -0,0 +1,113 @@ +package query + +import ( + "context" + + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryCheckpointing queries the Checkpointing module of the Babylon node +// according to the given function +func (c *QueryClient) QueryCheckpointing(f func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := checkpointingtypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// RawCheckpoint queries the checkpointing module for the raw checkpoint for an epoch number +func (c *QueryClient) RawCheckpoint(epochNumber uint64) (*checkpointingtypes.QueryRawCheckpointResponse, error) { + var resp *checkpointingtypes.QueryRawCheckpointResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryRawCheckpointRequest{ + EpochNum: epochNumber, + } + resp, err = queryClient.RawCheckpoint(ctx, req) + return err + }) + + return resp, err +} + +// RawCheckpointList queries the checkpointing module for a list of raw checkpoints +func (c *QueryClient) RawCheckpointList(status checkpointingtypes.CheckpointStatus, pagination *sdkquerytypes.PageRequest) (*checkpointingtypes.QueryRawCheckpointListResponse, error) { + var resp *checkpointingtypes.QueryRawCheckpointListResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryRawCheckpointListRequest{ + Status: status, + Pagination: pagination, + } + resp, err = queryClient.RawCheckpointList(ctx, req) + return err + }) + + return resp, err +} + +// BlsPublicKeyList queries the checkpointing module for the list of BLS keys for an epoch +func (c *QueryClient) BlsPublicKeyList(epochNumber uint64, pagination *sdkquerytypes.PageRequest) (*checkpointingtypes.QueryBlsPublicKeyListResponse, error) { + var resp *checkpointingtypes.QueryBlsPublicKeyListResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryBlsPublicKeyListRequest{ + EpochNum: epochNumber, + Pagination: pagination, + } + resp, err = queryClient.BlsPublicKeyList(ctx, req) + return err + }) + + return resp, err +} + +// RawCheckpoints queries the checkpointing module for a set of raw checkpoints +func (c *QueryClient) RawCheckpoints(pagination *sdkquerytypes.PageRequest) (*checkpointingtypes.QueryRawCheckpointsResponse, error) { + var resp *checkpointingtypes.QueryRawCheckpointsResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryRawCheckpointsRequest{ + Pagination: pagination, + } + resp, err = queryClient.RawCheckpoints(ctx, req) + return err + }) + + return resp, err +} + +// EpochStatusCount queries the checkpointing module for the status of the latest `epochCount` epochs` +func (c *QueryClient) EpochStatusCount(epochCount uint64) (*checkpointingtypes.QueryRecentEpochStatusCountResponse, error) { + var resp *checkpointingtypes.QueryRecentEpochStatusCountResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryRecentEpochStatusCountRequest{ + EpochCount: epochCount, + } + resp, err = queryClient.RecentEpochStatusCount(ctx, req) + return err + }) + + return resp, err +} + +// LatestEpochFromStatus queries the checkpointing module for the last checkpoint with a particular status +func (c *QueryClient) LatestEpochFromStatus(status checkpointingtypes.CheckpointStatus) (*checkpointingtypes.QueryLastCheckpointWithStatusResponse, error) { + var resp *checkpointingtypes.QueryLastCheckpointWithStatusResponse + err := c.QueryCheckpointing(func(ctx context.Context, queryClient checkpointingtypes.QueryClient) error { + var err error + req := &checkpointingtypes.QueryLastCheckpointWithStatusRequest{ + Status: status, + } + resp, err = queryClient.LastCheckpointWithStatus(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/client.go b/client/query/client.go new file mode 100644 index 000000000..17c60e98d --- /dev/null +++ b/client/query/client.go @@ -0,0 +1,95 @@ +package query + +import ( + "context" + "fmt" + "strconv" + "time" + + "github.com/cosmos/cosmos-sdk/types/query" + + "github.com/babylonchain/babylon/client/config" + rpcclient "github.com/cometbft/cometbft/rpc/client" + "github.com/cosmos/cosmos-sdk/client" + grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" + "google.golang.org/grpc/metadata" +) + +// QueryClient is a client that can only perform queries to a Babylon node +// It only requires `Cfg` to have `Timeout` and `RPCAddr`, but not other fields +// such as keyring, chain ID, etc.. +type QueryClient struct { + RPCClient rpcclient.Client + timeout time.Duration +} + +// New creates a new QueryClient according to the given config +func New(cfg *config.BabylonQueryConfig) (*QueryClient, error) { + if err := cfg.Validate(); err != nil { + return nil, err + } + + tmClient, err := client.NewClientFromNode(cfg.RPCAddr) + if err != nil { + return nil, err + } + + return &QueryClient{ + RPCClient: tmClient, + timeout: cfg.Timeout, + }, nil +} + +// NewWithClient creates a new QueryClient with a given existing rpcClient and timeout +// used by `client/` where `ChainClient` already creates an rpc client +func NewWithClient(rpcClient rpcclient.Client, timeout time.Duration) (*QueryClient, error) { + if timeout <= 0 { + return nil, fmt.Errorf("timeout must be positive") + } + + client := &QueryClient{ + RPCClient: rpcClient, + timeout: timeout, + } + + return client, nil +} + +func (c *QueryClient) Start() error { + return c.RPCClient.Start() +} + +func (c *QueryClient) Stop() error { + return c.RPCClient.Stop() +} + +func (c *QueryClient) IsRunning() bool { + return c.RPCClient.IsRunning() +} + +// getQueryContext returns a context that includes the height and uses the timeout from the config +// (adapted from https://github.com/strangelove-ventures/lens/blob/v0.5.4/client/query/query_options.go#L29-L36) +func (c *QueryClient) getQueryContext() (context.Context, context.CancelFunc) { + defaultOptions := DefaultQueryOptions() + ctx, cancel := context.WithTimeout(context.Background(), c.timeout) + strHeight := strconv.Itoa(int(defaultOptions.Height)) + ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, strHeight) + return ctx, cancel +} + +type QueryOptions struct { + Pagination *query.PageRequest + Height int64 +} + +func DefaultQueryOptions() *QueryOptions { + return &QueryOptions{ + Pagination: &query.PageRequest{ + Key: []byte(""), + Offset: 0, + Limit: 1000, + CountTotal: true, + }, + Height: 0, + } +} diff --git a/client/query/epoching.go b/client/query/epoching.go new file mode 100644 index 000000000..a94743737 --- /dev/null +++ b/client/query/epoching.go @@ -0,0 +1,95 @@ +package query + +import ( + "context" + + epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryEpoching queries the Epoching module of the Babylon node +// according to the given function +func (c *QueryClient) QueryEpoching(f func(ctx context.Context, queryClient epochingtypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := epochingtypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// EpochingParams queries epoching module's parameters via ChainClient +func (c *QueryClient) EpochingParams() (*epochingtypes.QueryParamsResponse, error) { + var resp *epochingtypes.QueryParamsResponse + err := c.QueryEpoching(func(ctx context.Context, queryClient epochingtypes.QueryClient) error { + var err error + req := &epochingtypes.QueryParamsRequest{} + resp, err = queryClient.Params(ctx, req) + return err + }) + + return resp, err +} + +// CurrentEpoch queries the current epoch number via ChainClient +func (c *QueryClient) CurrentEpoch() (*epochingtypes.QueryCurrentEpochResponse, error) { + var resp *epochingtypes.QueryCurrentEpochResponse + err := c.QueryEpoching(func(ctx context.Context, queryClient epochingtypes.QueryClient) error { + var err error + req := &epochingtypes.QueryCurrentEpochRequest{} + resp, err = queryClient.CurrentEpoch(ctx, req) + return err + }) + + return resp, err +} + +// EpochsInfo queries the epoching module for the maintained epochs +func (c *QueryClient) EpochsInfo(pagination *sdkquerytypes.PageRequest) (*epochingtypes.QueryEpochsInfoResponse, error) { + var resp *epochingtypes.QueryEpochsInfoResponse + err := c.QueryEpoching(func(ctx context.Context, queryClient epochingtypes.QueryClient) error { + var err error + req := &epochingtypes.QueryEpochsInfoRequest{ + Pagination: pagination, + } + resp, err = queryClient.EpochsInfo(ctx, req) + return err + }) + + return resp, err +} + +// LatestEpochMsgs queries the epoching module for the latest messages maintained in its delayed +// staking queue until a specified endEpoch. +func (c *QueryClient) LatestEpochMsgs(endEpoch uint64, epochCount uint64, pagination *sdkquerytypes.PageRequest) (*epochingtypes.QueryLatestEpochMsgsResponse, error) { + var resp *epochingtypes.QueryLatestEpochMsgsResponse + err := c.QueryEpoching(func(ctx context.Context, queryClient epochingtypes.QueryClient) error { + var err error + req := &epochingtypes.QueryLatestEpochMsgsRequest{ + EndEpoch: endEpoch, + EpochCount: epochCount, + Pagination: pagination, + } + resp, err = queryClient.LatestEpochMsgs(ctx, req) + return err + }) + + return resp, err +} + +// DelegationLifecycle queries the epoching module for the lifecycle of a delegator. +func (c *QueryClient) DelegationLifecycle(delegator string) (*epochingtypes.QueryDelegationLifecycleResponse, error) { + var resp *epochingtypes.QueryDelegationLifecycleResponse + err := c.QueryEpoching(func(ctx context.Context, queryClient epochingtypes.QueryClient) error { + var err error + req := &epochingtypes.QueryDelegationLifecycleRequest{ + DelAddr: delegator, + } + resp, err = queryClient.DelegationLifecycle(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/finality.go b/client/query/finality.go new file mode 100644 index 000000000..117821468 --- /dev/null +++ b/client/query/finality.go @@ -0,0 +1,111 @@ +package query + +import ( + "context" + + finalitytypes "github.com/babylonchain/babylon/x/finality/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryFinality queries the Finality module of the Babylon node according to the given function +func (c *QueryClient) QueryFinality(f func(ctx context.Context, queryClient finalitytypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := finalitytypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// FinalityParams queries the finality module parameters +func (c *QueryClient) FinalityParams() (*finalitytypes.Params, error) { + var resp *finalitytypes.QueryParamsResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryParamsRequest{} + resp, err = queryClient.Params(ctx, req) + return err + }) + + return &resp.Params, err +} + +// VotesAtHeight queries the Finality module to get signature set at a given babylon block height +func (c *QueryClient) VotesAtHeight(height uint64) (*finalitytypes.QueryVotesAtHeightResponse, error) { + var resp *finalitytypes.QueryVotesAtHeightResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryVotesAtHeightRequest{ + Height: height, + } + resp, err = queryClient.VotesAtHeight(ctx, req) + return err + }) + + return resp, err +} + +// ListBlocks queries the Finality module to get blocks with a given status. +func (c *QueryClient) ListBlocks(status finalitytypes.QueriedBlockStatus, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListBlocksResponse, error) { + var resp *finalitytypes.QueryListBlocksResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryListBlocksRequest{ + Status: status, + Pagination: pagination, + } + resp, err = queryClient.ListBlocks(ctx, req) + return err + }) + + return resp, err +} + +// Block queries a block at a given height. +func (c *QueryClient) Block(height uint64) (*finalitytypes.QueryBlockResponse, error) { + var resp *finalitytypes.QueryBlockResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryBlockRequest{ + Height: height, + } + resp, err = queryClient.Block(ctx, req) + return err + }) + + return resp, err +} + +// ListEvidences queries the Finality module to get evidences after a given height. +func (c *QueryClient) ListEvidences(startHeight uint64, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListEvidencesResponse, error) { + var resp *finalitytypes.QueryListEvidencesResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryListEvidencesRequest{ + StartHeight: startHeight, + Pagination: pagination, + } + resp, err = queryClient.ListEvidences(ctx, req) + return err + }) + + return resp, err +} + +// ListPublicRandomness is a range query for public randomness of a given finality provider. +func (c *QueryClient) ListPublicRandomness(fpBtcPkHex string, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListPublicRandomnessResponse, error) { + var resp *finalitytypes.QueryListPublicRandomnessResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryListPublicRandomnessRequest{ + FpBtcPkHex: fpBtcPkHex, + Pagination: pagination, + } + resp, err = queryClient.ListPublicRandomness(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/incentive.go b/client/query/incentive.go new file mode 100644 index 000000000..fe45356a1 --- /dev/null +++ b/client/query/incentive.go @@ -0,0 +1,34 @@ +package query + +import ( + "context" + + incentivetypes "github.com/babylonchain/babylon/x/incentive/types" + "github.com/cosmos/cosmos-sdk/client" +) + +// QueryIncentive queries the Incentive module of the Babylon node +func (c *QueryClient) QueryIncentive(f func(ctx context.Context, queryClient incentivetypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := incentivetypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// RewardGauges queries the Incentive module to get all reward gauges +func (c *QueryClient) RewardGauges(address string) (*incentivetypes.QueryRewardGaugesResponse, error) { + var resp *incentivetypes.QueryRewardGaugesResponse + err := c.QueryIncentive(func(ctx context.Context, queryClient incentivetypes.QueryClient) error { + var err error + req := &incentivetypes.QueryRewardGaugesRequest{ + Address: address, + } + resp, err = queryClient.RewardGauges(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/monitor.go b/client/query/monitor.go new file mode 100644 index 000000000..3ca35f95d --- /dev/null +++ b/client/query/monitor.go @@ -0,0 +1,50 @@ +package query + +import ( + "context" + + monitortypes "github.com/babylonchain/babylon/x/monitor/types" + "github.com/cosmos/cosmos-sdk/client" +) + +// QueryMonitor queries the Monitor module of the Babylon node +// according to the given function +func (c *QueryClient) QueryMonitor(f func(ctx context.Context, queryClient monitortypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := monitortypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// EndedEpochBTCHeight queries the tip height of BTC light client at epoch ends +func (c *QueryClient) EndedEpochBTCHeight(epochNum uint64) (*monitortypes.QueryEndedEpochBtcHeightResponse, error) { + var resp *monitortypes.QueryEndedEpochBtcHeightResponse + err := c.QueryMonitor(func(ctx context.Context, queryClient monitortypes.QueryClient) error { + var err error + req := &monitortypes.QueryEndedEpochBtcHeightRequest{ + EpochNum: epochNum, + } + resp, err = queryClient.EndedEpochBtcHeight(ctx, req) + return err + }) + + return resp, err +} + +// ReportedCheckpointBTCHeight queries the tip height of BTC light client when a given checkpoint is reported +func (c *QueryClient) ReportedCheckpointBTCHeight(hashStr string) (*monitortypes.QueryReportedCheckpointBtcHeightResponse, error) { + var resp *monitortypes.QueryReportedCheckpointBtcHeightResponse + err := c.QueryMonitor(func(ctx context.Context, queryClient monitortypes.QueryClient) error { + var err error + req := &monitortypes.QueryReportedCheckpointBtcHeightRequest{ + CkptHash: hashStr, + } + resp, err = queryClient.ReportedCheckpointBtcHeight(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/staking.go b/client/query/staking.go new file mode 100644 index 000000000..ae6bbe3ab --- /dev/null +++ b/client/query/staking.go @@ -0,0 +1,33 @@ +package query + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/client" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// QueryStaking queries the Staking module of the Babylon node +// according to the given function +func (c *QueryClient) QueryStaking(f func(ctx context.Context, queryClient stakingtypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := stakingtypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// StakingParams queries btccheckpoint module's parameters via ChainClient +func (c *QueryClient) StakingParams() (*stakingtypes.QueryParamsResponse, error) { + var resp *stakingtypes.QueryParamsResponse + err := c.QueryStaking(func(ctx context.Context, queryClient stakingtypes.QueryClient) error { + var err error + req := &stakingtypes.QueryParamsRequest{} + resp, err = queryClient.Params(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/query/tendermint.go b/client/query/tendermint.go new file mode 100644 index 000000000..cf00304dc --- /dev/null +++ b/client/query/tendermint.go @@ -0,0 +1,60 @@ +package query + +import ( + "context" + "strings" + + coretypes "github.com/cometbft/cometbft/rpc/core/types" +) + +// GetStatus returns the status of the tendermint node +func (c *QueryClient) GetStatus() (*coretypes.ResultStatus, error) { + ctx, cancel := c.getQueryContext() + defer cancel() + + return c.RPCClient.Status(ctx) +} + +// GetBlock returns the tendermint block at a specific height +func (c *QueryClient) GetBlock(height int64) (*coretypes.ResultBlock, error) { + ctx, cancel := c.getQueryContext() + defer cancel() + + return c.RPCClient.Block(ctx, &height) +} + +// BlockSearch searches for blocks satisfying the events specified on the events list +func (c *QueryClient) BlockSearch(events []string, page *int, perPage *int, orderBy string) (*coretypes.ResultBlockSearch, error) { + ctx, cancel := c.getQueryContext() + defer cancel() + + return c.RPCClient.BlockSearch(ctx, strings.Join(events, " AND "), page, perPage, orderBy) +} + +// TxSearch searches for transactions satisfying the events specified on the events list +func (c *QueryClient) TxSearch(events []string, prove bool, page *int, perPage *int, orderBy string) (*coretypes.ResultTxSearch, error) { + ctx, cancel := c.getQueryContext() + defer cancel() + + return c.RPCClient.TxSearch(ctx, strings.Join(events, " AND "), prove, page, perPage, orderBy) +} + +// GetTx returns the transaction with the specified hash +func (c *QueryClient) GetTx(hash []byte) (*coretypes.ResultTx, error) { + ctx, cancel := c.getQueryContext() + defer cancel() + + return c.RPCClient.Tx(ctx, hash, false) +} + +func (c *QueryClient) Subscribe(subscriber, query string, outCapacity ...int) (out <-chan coretypes.ResultEvent, err error) { + return c.RPCClient.Subscribe(context.Background(), subscriber, query, outCapacity...) +} + +func (c *QueryClient) Unsubscribe(subscriber, query string) error { + return c.RPCClient.Unsubscribe(context.Background(), subscriber, query) +} + +func (c *QueryClient) UnsubscribeAll(subscriber string) error { + return c.RPCClient.UnsubscribeAll(context.Background(), subscriber) +} diff --git a/client/query/zoneconcierge.go b/client/query/zoneconcierge.go new file mode 100644 index 000000000..95f3c5331 --- /dev/null +++ b/client/query/zoneconcierge.go @@ -0,0 +1,96 @@ +package query + +import ( + "context" + + zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/cosmos/cosmos-sdk/client" + sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" +) + +// QueryZoneConcierge queries the ZoneConcierge module of the Babylon node +// according to the given function +func (c *QueryClient) QueryZoneConcierge(f func(ctx context.Context, queryClient zctypes.QueryClient) error) error { + ctx, cancel := c.getQueryContext() + defer cancel() + + clientCtx := client.Context{Client: c.RPCClient} + queryClient := zctypes.NewQueryClient(clientCtx) + + return f(ctx, queryClient) +} + +// FinalizedConnectedChainsInfo queries the zoneconcierge module to get the finalization information for a connected chain +func (c *QueryClient) FinalizedConnectedChainsInfo(chainIds []string) (*zctypes.QueryFinalizedChainsInfoResponse, error) { + var resp *zctypes.QueryFinalizedChainsInfoResponse + err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { + var err error + req := &zctypes.QueryFinalizedChainsInfoRequest{ + ChainIds: chainIds, + } + resp, err = queryClient.FinalizedChainsInfo(ctx, req) + return err + }) + + return resp, err +} + +// ConnectedChainsInfo queries the zoneconcierge module to get information for a connected chain +func (c *QueryClient) ConnectedChainsInfo(chainIds []string) (*zctypes.QueryChainsInfoResponse, error) { + var resp *zctypes.QueryChainsInfoResponse + err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { + var err error + req := &zctypes.QueryChainsInfoRequest{ + ChainIds: chainIds, + } + resp, err = queryClient.ChainsInfo(ctx, req) + return err + }) + + return resp, err +} + +// ConnectedChainList queries the zoneconierge module for the chain IDs of the connected chains +func (c *QueryClient) ConnectedChainList() (*zctypes.QueryChainListResponse, error) { + var resp *zctypes.QueryChainListResponse + err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { + var err error + req := &zctypes.QueryChainListRequest{} + resp, err = queryClient.ChainList(ctx, req) + return err + }) + + return resp, err +} + +// ConnectedChainHeaders queries the zoneconcierge module for the headers of a connected chain +func (c *QueryClient) ConnectedChainHeaders(chainID string, pagination *sdkquerytypes.PageRequest) (*zctypes.QueryListHeadersResponse, error) { + var resp *zctypes.QueryListHeadersResponse + err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { + var err error + req := &zctypes.QueryListHeadersRequest{ + ChainId: chainID, + Pagination: pagination, + } + resp, err = queryClient.ListHeaders(ctx, req) + return err + }) + + return resp, err +} + +// ConnectedChainsEpochInfo queries the zoneconcierge module for the chain information of a connected chain at a particular epoch +func (c *QueryClient) ConnectedChainsEpochInfo(chainIds []string, epochNum uint64) (*zctypes.QueryEpochChainsInfoResponse, error) { + var resp *zctypes.QueryEpochChainsInfoResponse + err := c.QueryZoneConcierge(func(ctx context.Context, queryClient zctypes.QueryClient) error { + var err error + req := &zctypes.QueryEpochChainsInfoRequest{ + ChainIds: chainIds, + EpochNum: epochNum, + } + resp, err = queryClient.EpochChainsInfo(ctx, req) + return err + }) + + return resp, err +} diff --git a/client/tx/tx.go b/client/tx/tx.go deleted file mode 100644 index 97128e375..000000000 --- a/client/tx/tx.go +++ /dev/null @@ -1,116 +0,0 @@ -package tx - -import ( - "context" - "errors" - "fmt" - - "github.com/cosmos/cosmos-sdk/client" - sdktx "github.com/cosmos/cosmos-sdk/client/tx" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/babylonchain/babylon/types" -) - -func SendMsgToComet(ctx context.Context, clientCtx client.Context, msg sdk.Msg) (*sdk.TxResponse, error) { - return SendMsgsToComet(ctx, clientCtx, []sdk.Msg{msg}) -} - -func SendMsgsToComet(ctx context.Context, clientCtx client.Context, msgs []sdk.Msg) (*sdk.TxResponse, error) { - gasPrice, gasAdjustment := types.MustGetGasSettings(clientCtx.HomeDir, clientCtx.Viper) - txf := sdktx.Factory{}. - WithTxConfig(clientCtx.TxConfig). - WithAccountRetriever(clientCtx.AccountRetriever). - WithKeybase(clientCtx.Keyring). - WithChainID(clientCtx.ChainID). - WithFeePayer(clientCtx.FeePayer). - WithGasPrices(gasPrice). - WithGasAdjustment(gasAdjustment) - - return BroadcastTx(ctx, clientCtx, txf, msgs...) -} - -// BroadcastTx attempts to generate, sign and broadcast a transaction with the -// given set of messages. It will also simulate gas requirements if necessary. -// It will return an error upon failure. -// The code is based on cosmos-sdk: https://github.com/cosmos/cosmos-sdk/blob/7781cdb3d20bc7ebac017452897ce1e6ab3903ef/client/tx/tx.go#L65 -// it treats non-zero response code as errors -func BroadcastTx(ctx context.Context, clientCtx client.Context, txf sdktx.Factory, msgs ...sdk.Msg) (*sdk.TxResponse, error) { - txf, err := prepareFactory(clientCtx, txf) - if err != nil { - return nil, err - } - - _, adjusted, err := sdktx.CalculateGas(clientCtx, txf, msgs...) - if err != nil { - return nil, err - } - - if adjusted <= 0 { - return nil, errors.New("calculated gas should be positive") - } - - txf = txf.WithGas(adjusted) - - tx, err := txf.BuildUnsignedTx(msgs...) - if err != nil { - return nil, err - } - - tx.SetFeeGranter(clientCtx.GetFeeGranterAddress()) - - err = sdktx.Sign(ctx, txf, clientCtx.GetFromName(), tx, true) - if err != nil { - return nil, err - } - - txBytes, err := clientCtx.TxConfig.TxEncoder()(tx.GetTx()) - if err != nil { - return nil, err - } - - // broadcast to a comet node - res, err := clientCtx.BroadcastTx(txBytes) - if err != nil { - return nil, err - } - - // transaction was executed, log the success or failure using the tx response code - // NOTE: error is nil, logic should use the returned error to determine if the - // transaction was successfully executed. - if res.Code != 0 { - _ = clientCtx.PrintProto(res) - return res, fmt.Errorf("transaction failed with code: %d", res.Code) - } - - return res, nil -} - -// prepareFactory ensures the account defined by ctx.GetFromAddress() exists and -// if the account number and/or the account sequence number are zero (not set), -// they will be queried for and set on the provided Factory. A new Factory with -// the updated fields will be returned. -func prepareFactory(clientCtx client.Context, txf sdktx.Factory) (sdktx.Factory, error) { - from := clientCtx.GetFromAddress() - - if err := txf.AccountRetriever().EnsureExists(clientCtx, from); err != nil { - return txf, err - } - - initNum, initSeq := txf.AccountNumber(), txf.Sequence() - if initNum == 0 || initSeq == 0 { - num, seq, err := txf.AccountRetriever().GetAccountNumberSequence(clientCtx, from) - if err != nil { - return txf, err - } - - if initNum == 0 { - txf = txf.WithAccountNumber(num) - } - if initSeq == 0 { - txf = txf.WithSequence(seq) - } - } - - return txf, nil -} diff --git a/go.mod b/go.mod index 3c453131d..02d8f88c1 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( // to fix the gasLimit problem // should be replaced by a released version if there's any github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 + github.com/cosmos/relayer/v2 v2.5.1 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/pkg/errors v0.9.1 @@ -26,12 +27,12 @@ require ( ) require ( - cosmossdk.io/api v0.7.2 + cosmossdk.io/api v0.7.3 cosmossdk.io/client/v2 v2.0.0-beta.1 cosmossdk.io/core v0.11.0 cosmossdk.io/depinject v1.0.0-alpha.4 cosmossdk.io/errors v1.0.1 - cosmossdk.io/log v1.3.0 + cosmossdk.io/log v1.3.1 cosmossdk.io/math v1.2.0 cosmossdk.io/store v1.0.2 cosmossdk.io/tools/confix v0.1.0 @@ -41,12 +42,13 @@ require ( cosmossdk.io/x/tx v0.13.0 cosmossdk.io/x/upgrade v0.1.0 github.com/CosmWasm/wasmvm v1.5.2 + github.com/avast/retry-go/v4 v4.5.1 github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 github.com/cosmos/cosmos-db v1.0.0 - github.com/cosmos/cosmos-proto v1.0.0-beta.3 + github.com/cosmos/cosmos-proto v1.0.0-beta.4 github.com/cosmos/gogoproto v1.4.11 github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.0.0 @@ -56,8 +58,11 @@ require ( github.com/golang/protobuf v1.5.3 github.com/hashicorp/go-metrics v0.5.1 github.com/jinzhu/copier v0.3.5 + github.com/jsternberg/zap-logfmt v1.3.0 + github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b github.com/ory/dockertest/v3 v3.9.1 github.com/vulpine-io/io-test v1.0.0 + go.uber.org/zap v1.26.0 google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f ) @@ -71,7 +76,7 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/iavl v1.0.0 // indirect + github.com/cosmos/iavl v1.0.1 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect @@ -85,11 +90,11 @@ require ( github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/gorilla/handlers v1.5.2 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -99,7 +104,7 @@ require ( github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.6 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -109,9 +114,9 @@ require ( github.com/mtibben/percent v0.2.1 // indirect github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.17.0 - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/client_golang v1.18.0 + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect @@ -123,9 +128,9 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/zondax/hid v0.9.2 // indirect go.etcd.io/bbolt v1.3.8 // indirect - golang.org/x/crypto v0.18.0 - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/crypto v0.19.0 + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect nhooyr.io/websocket v1.8.6 // indirect @@ -146,20 +151,23 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/aead/siphash v1.0.1 // indirect - github.com/aws/aws-sdk-go v1.44.224 // indirect + github.com/aws/aws-sdk-go v1.44.312 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/bits-and-blooms/bitset v1.8.0 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20231102162011-844f0582c2eb // indirect + github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/creachadair/atomicfile v0.3.1 // indirect github.com/creachadair/tomledit v0.0.24 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -168,10 +176,12 @@ require ( github.com/docker/cli v23.0.1+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/dot v1.6.0 // indirect + github.com/emicklei/dot v1.6.1 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/go-ethereum v1.13.14 // indirect github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.0 // indirect @@ -184,12 +194,13 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.1 // indirect + github.com/hashicorp/go-getter v1.7.2 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/imdario/mergo v0.3.13 // indirect @@ -197,12 +208,12 @@ require ( github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/linxGnu/grocksdb v1.8.6 // indirect + github.com/linxGnu/grocksdb v1.8.12 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect @@ -210,13 +221,15 @@ require ( github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/zerolog v1.31.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rs/zerolog v1.32.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/strangelove-ventures/cometbft-client v0.1.0 // indirect github.com/tidwall/btree v1.7.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect @@ -224,13 +237,13 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect + golang.org/x/mod v0.15.0 // indirect + golang.org/x/net v0.21.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/tools v0.18.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.153.0 // indirect google.golang.org/appengine v1.6.8 // indirect @@ -238,6 +251,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect pgregory.net/rapid v1.1.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) @@ -250,6 +264,8 @@ replace ( // TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409 github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1 + github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 + // Downgraded to stable version see: https://github.com/cosmos/cosmos-sdk/pull/14952 github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 ) diff --git a/go.sum b/go.sum index 474d59744..7061588b8 100644 --- a/go.sum +++ b/go.sum @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.2 h1:BO3i5fvKMKvfaUiMkCznxViuBEfyWA/k6w2eAF6q1C4= -cosmossdk.io/api v0.7.2/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= +cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -196,8 +196,8 @@ cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98ok cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.0 h1:L0Z0XstClo2kOU4h3V1iDoE5Ji64sg5HLOogzGg67Oo= -cosmossdk.io/log v1.3.0/go.mod h1:HIDyvWLqZe2ovlWabsDN4aPMpY/nUEquAhgfTf2ZzB8= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= @@ -242,6 +242,10 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= @@ -262,11 +266,13 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= +github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= -github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= +github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -278,8 +284,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c= -github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d h1:zsO4lp+bjv5XvPTF58Vq+qgmZEYZttJK+CWtSZhKenI= github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6ZhUWvbk7PdWVmOaak10o86cqMUYEmn1CZNGEI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -363,8 +369,8 @@ github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZ github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20231102162011-844f0582c2eb h1:6Po+YYKT5B5ZXN0wd2rwFBaebM0LufPf8p4zxOd48Kg= -github.com/cockroachdb/pebble v0.0.0-20231102162011-844f0582c2eb/go.mod h1:acMRUGd/BK8AUmQNK3spUCCGzFLZU2bSST3NMXSq2Kc= +github.com/cockroachdb/pebble v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= +github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= @@ -374,6 +380,10 @@ github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfF github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= @@ -388,8 +398,8 @@ github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= -github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= -github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= +github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= +github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 h1:Pjvcy7wHUoYh253LvNv5Dyx+d3SNkRPsDZH+FytqZ3w= github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987/go.mod h1:0D9mrUy1eAUMQuvYzf2xvhEPk2ta9w7XH1zcYvyFiuM= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= @@ -399,8 +409,8 @@ github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.0 h1:bw6t0Mv/mVCJvlMTOPHWLs5uUE3BRBfVWCRelOzl+so= -github.com/cosmos/iavl v1.0.0/go.mod h1:CmTGqMnRnucjxbjduneZXT+0vPgNElYvdefjX2q9tYc= +github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= +github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= @@ -411,9 +421,15 @@ github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= +github.com/cosmos/relayer/v2 v2.5.1 h1:gYYD/xywc0Lw3957NmWuyJr9idKQmhgVuVoLIiBNYog= +github.com/cosmos/relayer/v2 v2.5.1/go.mod h1:KygWPbGY9ley9Q42CMg5uzmrf4BIe+EfxU5j44xrLRQ= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q= github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU= github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ= @@ -469,8 +485,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/emicklei/dot v1.6.0 h1:vUzuoVE8ipzS7QkES4UfxdpCwdU2U97m2Pb2tQCoYRY= -github.com/emicklei/dot v1.6.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= +github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -482,6 +498,10 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= @@ -501,8 +521,10 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= -github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= -github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -526,6 +548,8 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= @@ -551,16 +575,12 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= @@ -602,8 +622,9 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= @@ -657,6 +678,7 @@ github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -690,8 +712,9 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= @@ -709,8 +732,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.1 h1:SWiSWN/42qdpR0MdhaOc/bLR48PLuP1ZQtYLRlM69uY= -github.com/hashicorp/go-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.2 h1:uJDtyXwEfalmp1PqdxuhZqrNkUyClZAhVeZYTArbqkg= +github.com/hashicorp/go-getter v1.7.2/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -750,6 +773,10 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -793,12 +820,14 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.3.0 h1:z1n1AOHVVydOOVuyphbOKyR4NICDQFiJMn1IK5hVQ5Y= +github.com/jsternberg/zap-logfmt v1.3.0/go.mod h1:N3DENp9WNmCZxvkBD/eReWwz1149BK6jEN9cQ4fNwZE= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b h1:FQ7+9fxhyp82ks9vAuyPzG0/vVbWwMwLJ+P6yJI5FN8= +github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b/go.mod h1:HMcgvsgd0Fjj4XXDkbjdmlbI505rUPBs6WBMYg2pXks= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= @@ -807,8 +836,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= +github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -823,6 +852,10 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= @@ -831,8 +864,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.8.6 h1:O7I6SIGPrypf3f/gmrrLUBQDKfO8uOoYdWf4gLS06tc= -github.com/linxGnu/grocksdb v1.8.6/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= +github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -854,9 +887,9 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= @@ -873,6 +906,9 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= @@ -908,6 +944,8 @@ github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQ github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -974,24 +1012,24 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1003,18 +1041,22 @@ github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3c github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1 h1:OHEc+q5iIAXpqiqFKeLpu5NwTIkVXUs48vFMwzqpqY4= +github.com/regen-network/protobuf v1.3.3-alpha.regen.1/go.mod h1:2DjTFR1HhMQhiWC5sZ4OhQ3+NtdbZ6oBDKQwq5Ou+FI= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1028,6 +1070,8 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -1065,6 +1109,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/strangelove-ventures/cometbft-client v0.1.0 h1:fcA652QaaR0LDnyJOZVjZKtuyAawnVXaq/p1MWJSYD4= +github.com/strangelove-ventures/cometbft-client v0.1.0/go.mod h1:QzThgjzvsGgUNVNpGPitmxOWMIhp6a0oqf80nCRNt/0= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -1098,10 +1144,16 @@ github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2l github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= @@ -1154,6 +1206,8 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1163,6 +1217,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -1180,8 +1236,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1193,8 +1249,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= +golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1222,8 +1278,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1288,8 +1344,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1315,8 +1371,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1332,8 +1388,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1440,16 +1496,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1472,10 +1528,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1535,8 +1589,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1629,6 +1683,7 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1832,6 +1887,8 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From 1ee4d649d9556f463c998a7ac78d3f365423992e Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Wed, 3 Apr 2024 08:43:30 -0300 Subject: [PATCH 063/119] feat: add genhelper option to set finality providers (#603) * feat: add genhelper option to set finality providers * chore: fix short cli description on set-finality-providers * chore: add check of existing finality providers by using a map * chore: add check for duplicated fps * chore: update long comment on set-finality-providers * feat: add test for CmdSetFp * fix: lint * chore: reduce if map by key * chore: refactory to use testutil/helper --- cmd/babylond/cmd/genhelpers/cmd.go | 1 + .../cmd/genhelpers/set_finality_providers.go | 127 ++++++++++++++++++ .../genhelpers/set_finality_providers_test.go | 94 +++++++++++++ x/btcstaking/types/genesis.go | 19 ++- 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 cmd/babylond/cmd/genhelpers/set_finality_providers.go create mode 100644 cmd/babylond/cmd/genhelpers/set_finality_providers_test.go diff --git a/cmd/babylond/cmd/genhelpers/cmd.go b/cmd/babylond/cmd/genhelpers/cmd.go index 22d77400b..bc5cabaf7 100644 --- a/cmd/babylond/cmd/genhelpers/cmd.go +++ b/cmd/babylond/cmd/genhelpers/cmd.go @@ -20,6 +20,7 @@ func CmdGenHelpers(validator genutiltypes.MessageValidator) *cobra.Command { cmd.AddCommand( CmdCreateBls(), CmdAddBls(validator), + CmdSetFp(), ) return cmd diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers.go b/cmd/babylond/cmd/genhelpers/set_finality_providers.go new file mode 100644 index 000000000..e6658a739 --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers.go @@ -0,0 +1,127 @@ +package genhelpers + +import ( + "encoding/json" + "errors" + "fmt" + "os" + + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + cmtos "github.com/cometbft/cometbft/libs/os" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + + "github.com/spf13/cobra" +) + +// CmdSetFp CLI sets finality providers into the genesis state. +func CmdSetFp() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-finality-providers [path/to/finality_providers.json]", + Short: "Set the finality providers from the given json file into the genesis.json", + Long: `Reads finality providers structures from the given json file and update the genesis.json file +in place to include the finality providers in the btcstaking module's genesis state. +Duplicated finality providers are not allowed and it will prompt an error. +`, + Example: `babylond gen-helpers set-finality-providers path/to/finality_providers.json +Possible content of 'finality_providers.json' is +{ + "finality_providers": [ + { + "description": { + "moniker": "val-fp", + "identity": "", + "website": "", + "security_contact": "", + "details": "" + }, + "commission": "0.050000000000000000", + "babylon_pk": { + "key": "A6FTeYaKkvi8cOXSmVF+2n+q58WV/qffI99YucsvrGsk" + }, + "btc_pk": "625057f9828753569c478b1aa826205395222bcdbefafe9653dfdc638d18eadc", + "pop": { + "btc_sig_type": "BIP340", + "babylon_sig": "/RJyVqBEm/PDkQQTDgdPj84MywTu6LUVXDWUlPBgDGo1qsU/Rg+kJhBRwxCEKs8PYmoADcp4FiH2vVyAqRG2UA==", + "btc_sig": "OaLj+w2loH0O88cT2IEdUoV4Swx+RWagk632+mKs5wVRBM63D6uwW+lCLIjxVBfOYQRFzT2D9943k10Whw5a7Q==" + }, + "slashed_babylon_height": "0", + "slashed_btc_height": "0" + } + ] +} +`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + config := server.GetServerContextFromCmd(cmd).Config + config.SetRoot(clientCtx.HomeDir) + + finalityProvidersInputPath := args[0] + if !cmtos.FileExists(finalityProvidersInputPath) { + return errors.New("finality providers input file does not exist") + } + + fpsBz, err := os.ReadFile(finalityProvidersInputPath) + if err != nil { + return err + } + + var inputFps btcstktypes.GenesisState + err = clientCtx.Codec.UnmarshalJSON(fpsBz, &inputFps) + if err != nil { + return err + } + + genFile := config.GenesisFile() + appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + btcstkGenState := btcstktypes.GenesisStateFromAppState(clientCtx.Codec, appState) + + genStateFpsByBtcPk := make(map[string]struct{}, 0) + for _, fpGen := range btcstkGenState.FinalityProviders { + key := fpGen.BtcPk.MarshalHex() + if _, ok := genStateFpsByBtcPk[key]; ok { + return fmt.Errorf("bad genesis state, there is more than one finality provider with the same btc key %s", key) + } + genStateFpsByBtcPk[key] = struct{}{} + } + + newFps := make([]*btcstktypes.FinalityProvider, 0, len(inputFps.FinalityProviders)) + for _, fp := range inputFps.FinalityProviders { + if err := fp.ValidateBasic(); err != nil { + return fmt.Errorf("failed to validate basic finality provider: %w", err) + } + + key := fp.BtcPk.MarshalHex() + if _, ok := genStateFpsByBtcPk[key]; ok { + return fmt.Errorf("error: finality provider: %+v\nwas already set on genesis, or contains the same BtcPk %s than another finality provider", fp, key) + } + + // sets the fp to the genstate to avoid having 2 fps with same btc pk in the input + genStateFpsByBtcPk[key] = struct{}{} + newFps = append(newFps, fp) + } + btcstkGenState.FinalityProviders = append(btcstkGenState.FinalityProviders, newFps...) + + btcstkGenStateWithFps, err := clientCtx.Codec.MarshalJSON(&btcstkGenState) + if err != nil { + return fmt.Errorf("failed to marshal btcstaking genesis state: %w", err) + } + appState[btcstktypes.ModuleName] = btcstkGenStateWithFps + + appStateJSON, err := json.Marshal(appState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + genDoc.AppState = appStateJSON + return genutil.ExportGenesisFile(genDoc, genFile) + }, + } + + return cmd +} diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go new file mode 100644 index 000000000..d9fe19361 --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go @@ -0,0 +1,94 @@ +package genhelpers_test + +import ( + "context" + "encoding/hex" + "fmt" + "math/rand" + "path/filepath" + "testing" + + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cometbft/cometbft/libs/tempfile" + "github.com/cosmos/cosmos-sdk/client" + genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/stretchr/testify/require" +) + +func FuzzCmdSetFp(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + qntFps := int(datagen.RandomInt(r, 10)) + 1 + fpsToAdd := make([]*btcstktypes.FinalityProvider, qntFps) + for i := 0; i < qntFps; i++ { + fp, err := datagen.GenRandomFinalityProvider(r) + require.NoError(t, err) + fpsToAdd[i] = fp + } + + home := t.TempDir() + h := helper.NewHelper(t) + + app := h.App + cdc := app.AppCodec() + + err := genutiltest.ExecInitCmd(app.BasicModuleManager, home, cdc) + require.NoError(t, err) + + clientCtx := client.Context{}. + WithCodec(app.AppCodec()). + WithHomeDir(home). + WithTxConfig(app.TxConfig()) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + jsonBytes, err := cdc.MarshalJSON(&btcstktypes.GenesisState{ + FinalityProviders: fpsToAdd, + }) + require.NoError(t, err) + + fpsToAddFilePath := filepath.Join(home, "fpsToAdd.json") + err = tempfile.WriteFileAtomic(fpsToAddFilePath, jsonBytes, 0600) + require.NoError(t, err) + + cmdSetFp := genhelpers.CmdSetFp() + cmdSetFp.SetArgs([]string{fpsToAddFilePath}) + cmdSetFp.SetContext(ctx) + + // Runs the cmd to write into the genesis + err = cmdSetFp.Execute() + require.NoError(t, err) + + cmtcfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(t, err) + + // Verifies that the new genesis were created + appState, _, err := genutiltypes.GenesisStateFromGenFile(cmtcfg.GenesisFile()) + require.NoError(t, err) + + btcstkGenState := btcstktypes.GenesisStateFromAppState(cdc, appState) + // make sure the same quantity of finality providers were created. + require.Equal(t, qntFps, len(btcstkGenState.FinalityProviders)) + + for i := 0; i < qntFps; i++ { + bzAdd, err := fpsToAdd[i].Marshal() + require.NoError(t, err) + + bzGen, err := btcstkGenState.FinalityProviders[i].Marshal() + require.NoError(t, err) + + require.Equal(t, hex.EncodeToString(bzAdd), hex.EncodeToString(bzGen)) + } + + // tries to add again, it should error out + err = cmdSetFp.Execute() + fp := fpsToAdd[0] + require.EqualError(t, err, fmt.Errorf("error: finality provider: %+v\nwas already set on genesis, or contains the same BtcPk %s than another finality provider", fp, fp.BtcPk.MarshalHex()).Error()) + }) +} diff --git a/x/btcstaking/types/genesis.go b/x/btcstaking/types/genesis.go index 281e8abea..73ad67db2 100644 --- a/x/btcstaking/types/genesis.go +++ b/x/btcstaking/types/genesis.go @@ -1,6 +1,11 @@ package types -import "fmt" +import ( + "encoding/json" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" +) // DefaultGenesis returns the default genesis state func DefaultGenesis() *GenesisState { @@ -25,3 +30,15 @@ func (gs GenesisState) Validate() error { } return nil } + +// GenesisStateFromAppState returns x/btcstaking GenesisState given raw application +// genesis state. +func GenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage) GenesisState { + var genesisState GenesisState + + if appState[ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) + } + + return genesisState +} From de9fc155b3b788d06f450c3aa2d84e5285e0e3a9 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 27 Mar 2024 16:12:18 +1100 Subject: [PATCH 064/119] finality: BIP-32 based randomness derivation (#594) --- crypto/eots/eots.go | 13 - crypto/eots/eots_test.go | 4 - crypto/eots/randomness.go | 154 +++++++++ crypto/eots/randomness_bench_test.go | 74 +++++ crypto/eots/randomness_test.go | 95 ++++++ proto/babylon/btcstaking/v1/btcstaking.proto | 12 +- proto/babylon/btcstaking/v1/query.proto | 10 +- proto/babylon/btcstaking/v1/tx.proto | 2 + test/e2e/btc_staking_e2e_test.go | 6 +- .../configurer/chain/commands_btcstaking.go | 4 +- testutil/datagen/btcstaking.go | 42 ++- x/btcstaking/client/cli/tx.go | 20 +- x/btcstaking/keeper/grpc_query.go | 1 + x/btcstaking/keeper/keeper_test.go | 37 ++- x/btcstaking/keeper/msg_server.go | 17 +- x/btcstaking/keeper/msg_server_test.go | 26 +- x/btcstaking/types/btcstaking.pb.go | 278 +++++++++++----- x/btcstaking/types/msg.go | 3 + x/btcstaking/types/query.go | 1 + x/btcstaking/types/query.pb.go | 310 ++++++++++-------- x/btcstaking/types/tx.pb.go | 217 +++++++----- x/finality/keeper/msg_server.go | 1 + x/finality/keeper/msg_server_test.go | 16 +- x/finality/keeper/votes_bench_test.go | 10 +- 24 files changed, 971 insertions(+), 382 deletions(-) create mode 100644 crypto/eots/randomness.go create mode 100644 crypto/eots/randomness_bench_test.go create mode 100644 crypto/eots/randomness_test.go diff --git a/crypto/eots/eots.go b/crypto/eots/eots.go index 932051b46..0459a4b51 100644 --- a/crypto/eots/eots.go +++ b/crypto/eots/eots.go @@ -15,8 +15,6 @@ import ( type ModNScalar = btcec.ModNScalar type PrivateKey = secp256k1.PrivateKey type PublicKey = secp256k1.PublicKey -type PrivateRand = secp256k1.ModNScalar -type PublicRand = secp256k1.FieldVal // The Signature is only the S part of the BEP-340 Schnorr signatures. type Signature = ModNScalar @@ -31,17 +29,6 @@ func PubGen(k *PrivateKey) *PublicKey { return k.PubKey() } -// RandGen returns the value to be used as random value when signing, and the associated public value. -func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { - pk, err := KeyGen(randSource) - if err != nil { - return nil, nil, err - } - var j secp256k1.JacobianPoint - pk.PubKey().AsJacobian(&j) - return &pk.Key, &j.X, nil -} - // hash function is used for hashing the message input for all functions of the library. // Wrapper around sha256 in order to change only one function if the input hashing function is changed. func hash(message []byte) [32]byte { diff --git a/crypto/eots/eots_test.go b/crypto/eots/eots_test.go index 91865b4d0..d41e57156 100644 --- a/crypto/eots/eots_test.go +++ b/crypto/eots/eots_test.go @@ -13,10 +13,6 @@ import ( "github.com/vulpine-io/io-test/v1/pkg/iotest" ) -// TODO: possible improvements -// test KeyGen, PubGen, RandGen give consistent results with deterministic randomness source -// test compare signatures against btcec - func FuzzSignAndVerify(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) diff --git a/crypto/eots/randomness.go b/crypto/eots/randomness.go new file mode 100644 index 000000000..428fe1f55 --- /dev/null +++ b/crypto/eots/randomness.go @@ -0,0 +1,154 @@ +package eots + +import ( + "fmt" + "io" + + "github.com/btcsuite/btcd/btcutil/hdkeychain" + "github.com/btcsuite/btcd/chaincfg" + "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +type MasterSecretRand struct { + k *hdkeychain.ExtendedKey +} +type MasterPublicRand struct { + k *hdkeychain.ExtendedKey +} + +type PrivateRand = secp256k1.ModNScalar +type PublicRand = secp256k1.FieldVal + +// RandGen returns the value to be used as random value when signing, and the associated public value. +func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { + pk, err := KeyGen(randSource) + if err != nil { + return nil, nil, err + } + var j secp256k1.JacobianPoint + pk.PubKey().AsJacobian(&j) + return &pk.Key, &j.X, nil +} + +func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRand, error) { + // get random seed + var seed [32]byte + if _, err := io.ReadFull(randSource, seed[:]); err != nil { + return nil, nil, err + } + // generate new master key pair + masterSK, err := hdkeychain.NewMaster(seed[:], &chaincfg.MainNetParams) + if err != nil { + return nil, nil, err + } + masterPK, err := masterSK.Neuter() + if err != nil { + return nil, nil, err + } + + return &MasterSecretRand{masterSK}, &MasterPublicRand{masterPK}, nil +} + +func (msr *MasterSecretRand) Validate() error { + if !msr.k.IsPrivate() { + return fmt.Errorf("underlying key is not a private key") + } + return nil +} + +func NewMasterSecretRandFromBase58(s string) (*MasterSecretRand, error) { + k, err := hdkeychain.NewKeyFromString(s) + if err != nil { + return nil, err + } + if !k.IsPrivate() { + return nil, fmt.Errorf("the given string does not correspond to a secret key") + } + return &MasterSecretRand{k}, nil +} + +func NewMasterSecretRand(b []byte) (*MasterSecretRand, error) { + return NewMasterSecretRandFromBase58(string(b)) +} + +func (msr *MasterSecretRand) MasterPubicRand() (*MasterPublicRand, error) { + masterPK, err := msr.k.Neuter() + if err != nil { + return nil, err + } + return &MasterPublicRand{masterPK}, nil +} + +func (msr *MasterSecretRand) DeriveRandPair(height uint32) (*PrivateRand, *PublicRand, error) { + // get child SK, then child SK in BTC format, and finally private randomness + childSK, err := msr.k.Derive(height) + if err != nil { + return nil, nil, err + } + childBTCSK, err := childSK.ECPrivKey() + if err != nil { + return nil, nil, err + } + privRand := &childBTCSK.Key + + // get child PK in BTC format, and then public randomness + childBTCPK := childBTCSK.PubKey() + var j secp256k1.JacobianPoint + childBTCPK.AsJacobian(&j) + pubRand := &j.X + + return privRand, pubRand, nil +} + +func (msr *MasterSecretRand) MarshalBase58() string { + return msr.k.String() +} + +func (msr *MasterSecretRand) Marshal() []byte { + return []byte(msr.MarshalBase58()) +} + +func NewMasterPublicRandFromBase58(s string) (*MasterPublicRand, error) { + k, err := hdkeychain.NewKeyFromString(s) + if err != nil { + return nil, err + } + if k.IsPrivate() { + return nil, fmt.Errorf("the given string does not correspond to a public key") + } + return &MasterPublicRand{k}, nil +} + +func NewMasterPublicRand(b []byte) (*MasterPublicRand, error) { + return NewMasterPublicRandFromBase58(string(b)) +} + +func (mpr *MasterPublicRand) Validate() error { + if mpr.k.IsPrivate() { + return fmt.Errorf("underlying key is not a public key") + } + return nil +} + +func (mpr *MasterPublicRand) DerivePubRand(height uint32) (*PublicRand, error) { + childPK, err := mpr.k.Derive(height) + if err != nil { + return nil, err + } + childBTCPK, err := childPK.ECPubKey() + if err != nil { + return nil, err + } + var j secp256k1.JacobianPoint + childBTCPK.AsJacobian(&j) + pubRand := &j.X + return pubRand, nil +} + +func (mpr *MasterPublicRand) MarshalBase58() string { + return mpr.k.String() +} + +func (mpr *MasterPublicRand) Marshal() []byte { + return []byte(mpr.MarshalBase58()) +} diff --git a/crypto/eots/randomness_bench_test.go b/crypto/eots/randomness_bench_test.go new file mode 100644 index 000000000..4a6fd0e57 --- /dev/null +++ b/crypto/eots/randomness_bench_test.go @@ -0,0 +1,74 @@ +package eots_test + +import ( + "math/rand" + "os" + "runtime/pprof" + "testing" + "time" + + "github.com/babylonchain/babylon/crypto/eots" + "github.com/stretchr/testify/require" +) + +func BenchmarkDeriveRandomness(b *testing.B) { + r := rand.New(rand.NewSource(time.Now().Unix())) + + // master randomness pair + msr, mpr, err := eots.NewMasterRandPair(r) + require.NoError(b, err) + require.NoError(b, msr.Validate()) + require.NoError(b, mpr.Validate()) + + // Start the CPU profiler + cpuProfileFile := "/tmp/bench_verify_derive_randomness.pprof" + f, err := os.Create(cpuProfileFile) + if err != nil { + b.Fatal(err) + } + defer f.Close() + if err := pprof.StartCPUProfile(f); err != nil { + b.Fatal(err) + } + defer pprof.StopCPUProfile() + + // Reset timer before the benchmark loop starts + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, _, err := msr.DeriveRandPair(uint32(i)) + require.NoError(b, err) + } +} + +func BenchmarkUnmarshalMasterPubRand(b *testing.B) { + r := rand.New(rand.NewSource(time.Now().Unix())) + + // master randomness pair + msr, mpr, err := eots.NewMasterRandPair(r) + require.NoError(b, err) + require.NoError(b, msr.Validate()) + require.NoError(b, mpr.Validate()) + + mprStr := mpr.MarshalBase58() + + // Start the CPU profiler + cpuProfileFile := "/tmp/bench_unmarshal_pubrand.pprof" + f, err := os.Create(cpuProfileFile) + if err != nil { + b.Fatal(err) + } + defer f.Close() + if err := pprof.StartCPUProfile(f); err != nil { + b.Fatal(err) + } + defer pprof.StopCPUProfile() + + // Reset timer before the benchmark loop starts + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := eots.NewMasterPublicRandFromBase58(mprStr) + require.NoError(b, err) + } +} diff --git a/crypto/eots/randomness_test.go b/crypto/eots/randomness_test.go new file mode 100644 index 000000000..11451e979 --- /dev/null +++ b/crypto/eots/randomness_test.go @@ -0,0 +1,95 @@ +package eots_test + +import ( + "math/rand" + "testing" + + "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/stretchr/testify/require" +) + +func FuzzBIP32RandomnessCodec(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + // master randomness pair + msr, mpr, err := eots.NewMasterRandPair(r) + require.NoError(t, err) + require.NoError(t, msr.Validate()) + require.NoError(t, mpr.Validate()) + + // roundtrip of marshaling/unmarshaling msr to/from string + msrStr := msr.MarshalBase58() + msr2, err := eots.NewMasterSecretRandFromBase58(msrStr) + require.NoError(t, err) + require.Equal(t, msr.Marshal(), msr2.Marshal()) + + // roundtrip of marshaling/unmarshaling msr to/from bytes + msrBytes := msr.Marshal() + msr2, err = eots.NewMasterSecretRand(msrBytes) + require.NoError(t, err) + require.Equal(t, msr.Marshal(), msr2.Marshal()) + + // roundtrip of marshaling/unmarshaling mpr to/from string + mprStr := mpr.MarshalBase58() + mpr2, err := eots.NewMasterPublicRandFromBase58(mprStr) + require.NoError(t, err) + require.Equal(t, mpr.Marshal(), mpr2.Marshal()) + + // roundtrip of marshaling/unmarshaling mpr to/from bytes + mprBytes := mpr.Marshal() + mpr2, err = eots.NewMasterPublicRand(mprBytes) + require.NoError(t, err) + require.Equal(t, mpr.Marshal(), mpr2.Marshal()) + }) +} + +func FuzzBIP32RandomnessDerivation(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + // EOTS key pair + sk, err := eots.KeyGen(r) + require.NoError(t, err) + pk := eots.PubGen(sk) + + // master randomness pair + msr, mpr, err := eots.NewMasterRandPair(r) + require.NoError(t, err) + require.NoError(t, msr.Validate()) + require.NoError(t, mpr.Validate()) + + // ensure msr can derive mpr + mpr2, err := msr.MasterPubicRand() + require.NoError(t, err) + require.NoError(t, mpr2.Validate()) + require.Equal(t, mpr, mpr2) + + height := uint32(datagen.RandomInt(r, 10000)) + + // derive pair of randomness via master secret randomness at this height + sr, pr, err := msr.DeriveRandPair(height) + require.NoError(t, err) + + // derive public randomness via master public randomness at this height + pr2, err := mpr.DerivePubRand(height) + require.NoError(t, err) + + // assert consistency of public randomness + require.Equal(t, pr, pr2) + + // sign EOTS using secret randomness + msg := datagen.GenRandomByteArray(r, 100) + sig, err := eots.Sign(sk, sr, msg) + require.NoError(t, err) + + // verify EOTS sig using public key + err = eots.Verify(pk, pr, msg, sig) + require.NoError(t, err) + }) +} diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 9f9778a5c..c5fd0f36e 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -25,14 +25,16 @@ message FinalityProvider { bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; + // master_pub_rand is the master public randomness of the finality provider + string master_pub_rand = 6; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 6; + uint64 slashed_babylon_height = 7; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 7; + uint64 slashed_btc_height = 8; } // FinalityProviderWithMeta wraps the FinalityProvider with metadata. @@ -44,14 +46,16 @@ message FinalityProviderWithMeta { uint64 height = 2; // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 3; + // master_pub_rand is the master public randomness of the finality provider + string master_pub_rand = 4; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 4; + uint64 slashed_babylon_height = 5; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 5; + uint64 slashed_btc_height = 6; } // BTCDelegation defines a BTC delegation diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index e3f385b57..798cccb7b 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -335,16 +335,18 @@ message FinalityProviderResponse { bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; + // master_pub_rand is the master public randomness of the finality provider + string master_pub_rand = 6; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 6; + uint64 slashed_babylon_height = 7; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 7; + uint64 slashed_btc_height = 8; // height is the queried Babylon height - uint64 height = 8; + uint64 height = 9; // voting_power is the voting power of this finality provider at the given height - uint64 voting_power = 9; + uint64 voting_power = 10; } diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index 8d2d5a642..d73e86686 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -54,6 +54,8 @@ message MsgCreateFinalityProvider { bytes btc_pk = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 6; + // master_pub_rand is the master public randomness of the finality provider + string master_pub_rand = 7; } // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider message MsgCreateFinalityProviderResponse {} diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 04aa36010..ccf21e77d 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -79,9 +79,11 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { create a random finality provider on Babylon */ // NOTE: we use the node's secret key as Babylon secret key for the finality provider - fp, err = datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, nonValidatorNode.SecretKey) + msr, _, err := eots.NewMasterRandPair(r) s.NoError(err) - nonValidatorNode.CreateFinalityProvider(fp.BabylonPk, fp.BtcPk, fp.Pop, fp.Description.Moniker, fp.Description.Identity, fp.Description.Website, fp.Description.SecurityContact, fp.Description.Details, fp.Commission) + fp, err = datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, nonValidatorNode.SecretKey, msr) + s.NoError(err) + nonValidatorNode.CreateFinalityProvider(fp.BabylonPk, fp.BtcPk, fp.Pop, fp.MasterPubRand, fp.Description.Moniker, fp.Description.Identity, fp.Description.Website, fp.Description.SecurityContact, fp.Description.Details, fp.Commission) // wait for a block so that above txs take effect nonValidatorNode.WaitForNextBlock() diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index 7397af143..3847ba250 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -20,7 +20,7 @@ import ( bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) -func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossession, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { +func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossession, masterPubRand string, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { n.LogActionF("creating finality provider") // get babylon PK hex @@ -34,7 +34,7 @@ func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK * require.NoError(n.t, err) cmd := []string{ - "babylond", "tx", "btcstaking", "create-finality-provider", babylonPKHex, btcPKHex, popHex, "--from=val", "--moniker", moniker, "--identity", identity, "--website", website, "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), + "babylond", "tx", "btcstaking", "create-finality-provider", babylonPKHex, btcPKHex, popHex, masterPubRand, "--from=val", "--moniker", moniker, "--identity", identity, "--website", website, "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), } _, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index f3ffa213a..50bc7864e 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -18,6 +18,7 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) @@ -28,12 +29,22 @@ const ( ) func GenRandomFinalityProvider(r *rand.Rand) (*bstypes.FinalityProvider, error) { - // key pairs + // BTC key pairs btcSK, _, err := GenRandomBTCKeyPair(r) if err != nil { return nil, err } - return GenRandomFinalityProviderWithBTCSK(r, btcSK) + // Babylon key pairs + bbnSK, _, err := GenRandomSecp256k1KeyPair(r) + if err != nil { + return nil, err + } + // master secret randomness + msr, _, err := eots.NewMasterRandPair(r) + if err != nil { + return nil, err + } + return GenRandomCustomFinalityProvider(r, btcSK, bbnSK, msr) } func CreateNFinalityProviders(r *rand.Rand, t *testing.T, n int) []*bstypes.FinalityProvider { @@ -46,14 +57,6 @@ func CreateNFinalityProviders(r *rand.Rand, t *testing.T, n int) []*bstypes.Fina return fps } -func GenRandomFinalityProviderWithBTCSK(r *rand.Rand, btcSK *btcec.PrivateKey) (*bstypes.FinalityProvider, error) { - bbnSK, _, err := GenRandomSecp256k1KeyPair(r) - if err != nil { - return nil, err - } - return GenRandomFinalityProviderWithBTCBabylonSKs(r, btcSK, bbnSK) -} - func GenRandomCommission(r *rand.Rand) sdkmath.LegacyDec { return sdkmath.LegacyNewDecWithPrec(int64(RandomInt(r, 49)+1), 2) // [1/100, 50/100] } @@ -62,7 +65,7 @@ func GenRandomDescription(r *rand.Rand) *stakingtypes.Description { return &stakingtypes.Description{Moniker: GenRandomHexStr(r, 10)} } -func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey) (*bstypes.FinalityProvider, error) { +func GenRandomCustomFinalityProvider(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey, msr *eots.MasterSecretRand) (*bstypes.FinalityProvider, error) { // commission commission := GenRandomCommission(r) // description @@ -80,12 +83,19 @@ func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.Priva if err != nil { return nil, err } + // master pub rand + mpr, err := msr.MasterPubicRand() + if err != nil { + return nil, err + } + return &bstypes.FinalityProvider{ - Description: description, - Commission: &commission, - BabylonPk: secp256k1PK, - BtcPk: bip340PK, - Pop: pop, + Description: description, + Commission: &commission, + BabylonPk: secp256k1PK, + BtcPk: bip340PK, + Pop: pop, + MasterPubRand: mpr.MarshalBase58(), }, nil } diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 0557bebcf..d3b170c13 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -52,8 +52,8 @@ func GetTxCmd() *cobra.Command { func NewCreateFinalityProvicerCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-finality-provider [babylon_pk] [btc_pk] [pop]", - Args: cobra.ExactArgs(3), + Use: "create-finality-provider [babylon_pk] [btc_pk] [pop] [master_pub_rand]", + Args: cobra.ExactArgs(4), Short: "Create a finality provider", Long: strings.TrimSpace( `Create a finality provider.`, // TODO: example @@ -108,13 +108,17 @@ func NewCreateFinalityProvicerCmd() *cobra.Command { return err } + // get master public randomness in base58 string + mpr := args[3] + msg := types.MsgCreateFinalityProvider{ - Signer: clientCtx.FromAddress.String(), - Description: &description, - Commission: &rate, - BabylonPk: &babylonPK, - BtcPk: btcPK, - Pop: pop, + Signer: clientCtx.FromAddress.String(), + Description: &description, + Commission: &rate, + BabylonPk: &babylonPK, + BtcPk: btcPK, + Pop: pop, + MasterPubRand: mpr, } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index f687cdb36..fa6a6a7ae 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -189,6 +189,7 @@ func (k Keeper) ActiveFinalityProvidersAtHeight(ctx context.Context, req *types. BtcPk: finalityProvider.BtcPk, Height: req.Height, VotingPower: votingPower, + MasterPubRand: finalityProvider.MasterPubRand, SlashedBabylonHeight: finalityProvider.SlashedBabylonHeight, SlashedBtcHeight: finalityProvider.SlashedBtcHeight, } diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 8075ad97b..b324cf329 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -6,6 +6,7 @@ import ( "cosmossdk.io/core/header" sdkmath "cosmossdk.io/math" + "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -96,16 +97,21 @@ func (h *Helper) GenAndApplyCustomParams( SlashingRate: sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2), MaxActiveFinalityProviders: 100, MinUnbondingTime: minUnbondingTime, - MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), + MinUnbondingRate: sdkmath.LegacyMustNewDecFromStr("0.8"), }) h.NoError(err) return covenantSKs, covenantPKs } func CreateFinalityProvider(r *rand.Rand, t *testing.T) *types.FinalityProvider { - fpSK, _, err := datagen.GenRandomBTCKeyPair(r) + fpBTCSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, fpSK) + fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) + require.NoError(t, err) + msr, _, err := eots.NewMasterRandPair(r) + require.NoError(t, err) + + fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBBNSK, msr) require.NoError(t, err) return &types.FinalityProvider{ @@ -118,21 +124,28 @@ func CreateFinalityProvider(r *rand.Rand, t *testing.T) *types.FinalityProvider } func (h *Helper) CreateFinalityProvider(r *rand.Rand) (*btcec.PrivateKey, *btcec.PublicKey, *types.FinalityProvider) { - fpSK, fpPK, err := datagen.GenRandomBTCKeyPair(r) + fpBTCSK, fpBTCPK, err := datagen.GenRandomBTCKeyPair(r) h.NoError(err) - fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, fpSK) + fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) + h.NoError(err) + msr, _, err := eots.NewMasterRandPair(r) + h.NoError(err) + + fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBBNSK, msr) h.NoError(err) + msgNewFp := types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp.Description, - Commission: fp.Commission, - BabylonPk: fp.BabylonPk, - BtcPk: fp.BtcPk, - Pop: fp.Pop, + Signer: datagen.GenRandomAccount().Address, + Description: fp.Description, + Commission: fp.Commission, + BabylonPk: fp.BabylonPk, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + MasterPubRand: fp.MasterPubRand, } _, err = h.MsgServer.CreateFinalityProvider(h.Ctx, &msgNewFp) h.NoError(err) - return fpSK, fpPK, fp + return fpBTCSK, fpBTCPK, fp } func (h *Helper) CreateDelegationCustom( diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 2bfdcb253..1c81a3be4 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -8,6 +8,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" @@ -80,13 +81,19 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return nil, types.ErrFpRegistered } + // ensure the master public randomness is valid + if _, err := eots.NewMasterPublicRandFromBase58(req.MasterPubRand); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%v", err) + } + // all good, add this finality provider fp := types.FinalityProvider{ - Description: req.Description, - Commission: req.Commission, - BabylonPk: req.BabylonPk, - BtcPk: req.BtcPk, - Pop: req.Pop, + Description: req.Description, + Commission: req.Commission, + BabylonPk: req.BabylonPk, + BtcPk: req.BtcPk, + Pop: req.Pop, + MasterPubRand: req.MasterPubRand, } ms.SetFinalityProvider(ctx, &fp) diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index fe72f8b77..9d631eb93 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -40,12 +40,13 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp.Description, - Commission: fp.Commission, - BabylonPk: fp.BabylonPk, - BtcPk: fp.BtcPk, - Pop: fp.Pop, + Signer: datagen.GenRandomAccount().Address, + Description: fp.Description, + Commission: fp.Commission, + BabylonPk: fp.BabylonPk, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + MasterPubRand: fp.MasterPubRand, } _, err = h.MsgServer.CreateFinalityProvider(h.Ctx, msg) require.NoError(t, err) @@ -61,12 +62,13 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { // duplicated finality providers should not pass for _, fp2 := range fps { msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp2.Description, - Commission: fp2.Commission, - BabylonPk: fp2.BabylonPk, - BtcPk: fp2.BtcPk, - Pop: fp2.Pop, + Signer: datagen.GenRandomAccount().Address, + Description: fp2.Description, + Commission: fp2.Commission, + BabylonPk: fp2.BabylonPk, + BtcPk: fp2.BtcPk, + Pop: fp2.Pop, + MasterPubRand: fp2.MasterPubRand, } _, err := h.MsgServer.CreateFinalityProvider(h.Ctx, msg) require.Error(t, err) diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index 7decf89b8..e4424b0c8 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -82,14 +82,16 @@ type FinalityProvider struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` + // master_pub_rand is the master public randomness of the finality provider + MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,7,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,8,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProvider) Reset() { *m = FinalityProvider{} } @@ -146,6 +148,13 @@ func (m *FinalityProvider) GetPop() *ProofOfPossession { return nil } +func (m *FinalityProvider) GetMasterPubRand() string { + if m != nil { + return m.MasterPubRand + } + return "" +} + func (m *FinalityProvider) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -169,14 +178,16 @@ type FinalityProviderWithMeta struct { Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + // master_pub_rand is the master public randomness of the finality provider + MasterPubRand string `protobuf:"bytes,4,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,4,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,5,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,5,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,6,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProviderWithMeta) Reset() { *m = FinalityProviderWithMeta{} } @@ -226,6 +237,13 @@ func (m *FinalityProviderWithMeta) GetVotingPower() uint64 { return 0 } +func (m *FinalityProviderWithMeta) GetMasterPubRand() string { + if m != nil { + return m.MasterPubRand + } + return "" +} + func (m *FinalityProviderWithMeta) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -744,82 +762,84 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1197 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, - 0x17, 0xcf, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x7f, 0x92, 0xbf, - 0x29, 0x95, 0x85, 0xa8, 0xdd, 0xa4, 0x1f, 0x02, 0x2e, 0x90, 0xea, 0x38, 0xa5, 0x51, 0xdb, 0xd4, - 0xac, 0x93, 0x22, 0x40, 0x62, 0x35, 0xde, 0x9d, 0xac, 0x57, 0xb6, 0x77, 0x96, 0x9d, 0xb1, 0xb1, - 0xdf, 0x80, 0x1b, 0x24, 0x6e, 0xb9, 0xe7, 0x11, 0x78, 0x06, 0xc4, 0x65, 0xc5, 0x0d, 0x28, 0x17, - 0x11, 0x6a, 0x1f, 0x80, 0x57, 0x40, 0x33, 0x3b, 0xfb, 0xe1, 0xb6, 0x29, 0xb4, 0xce, 0x9d, 0x67, - 0xce, 0x39, 0xbf, 0xf3, 0xf1, 0xfb, 0xf9, 0xcc, 0xc2, 0xf5, 0x2e, 0xee, 0x4e, 0x07, 0xd4, 0x6b, - 0x74, 0xb9, 0xc5, 0x38, 0xee, 0xbb, 0x9e, 0xd3, 0x18, 0x6f, 0xa5, 0x4e, 0x75, 0x3f, 0xa0, 0x9c, - 0xa2, 0x4b, 0xca, 0xaf, 0x9e, 0xb2, 0x8c, 0xb7, 0xae, 0xae, 0x38, 0xd4, 0xa1, 0xd2, 0xa3, 0x21, - 0x7e, 0x85, 0xce, 0x57, 0xaf, 0x58, 0x94, 0x0d, 0x29, 0x33, 0x43, 0x43, 0x78, 0x50, 0xa6, 0x6a, - 0x78, 0x6a, 0x58, 0xc1, 0xd4, 0xe7, 0xb4, 0xc1, 0x88, 0xe5, 0x6f, 0xdf, 0xb9, 0xdb, 0xdf, 0x6a, - 0xf4, 0xc9, 0x34, 0xf2, 0xb9, 0xa6, 0x7c, 0x92, 0x7a, 0xba, 0x84, 0xe3, 0xad, 0xc6, 0x4c, 0x45, - 0x57, 0x37, 0x5e, 0x5f, 0xb9, 0x4f, 0xfd, 0xd0, 0xa1, 0xfa, 0x47, 0x16, 0x2a, 0xf7, 0x5d, 0x0f, - 0x0f, 0x5c, 0x3e, 0x6d, 0x07, 0x74, 0xec, 0xda, 0x24, 0x40, 0xbb, 0x50, 0xb4, 0x09, 0xb3, 0x02, - 0xd7, 0xe7, 0x2e, 0xf5, 0x74, 0x6d, 0x53, 0xab, 0x15, 0xb7, 0xdf, 0xab, 0xab, 0x1a, 0x93, 0xce, - 0x64, 0xc6, 0x7a, 0x2b, 0x71, 0x35, 0xd2, 0x71, 0xe8, 0x31, 0x80, 0x45, 0x87, 0x43, 0x97, 0x31, - 0x81, 0x92, 0xd9, 0xd4, 0x6a, 0x85, 0xe6, 0x8d, 0xe3, 0x93, 0x8d, 0xb5, 0x10, 0x88, 0xd9, 0xfd, - 0xba, 0x4b, 0x1b, 0x43, 0xcc, 0x7b, 0xf5, 0x47, 0xc4, 0xc1, 0xd6, 0xb4, 0x45, 0xac, 0xdf, 0x7f, - 0xb9, 0x01, 0x2a, 0x4f, 0x8b, 0x58, 0x46, 0x0a, 0x00, 0x7d, 0x0a, 0xa0, 0xba, 0x31, 0xfd, 0xbe, - 0x9e, 0x95, 0x45, 0x6d, 0x44, 0x45, 0x85, 0xa3, 0xaa, 0xc7, 0xa3, 0xaa, 0xb7, 0x47, 0xdd, 0x87, - 0x64, 0x6a, 0x14, 0x54, 0x48, 0xbb, 0x8f, 0x1e, 0x43, 0xbe, 0xcb, 0x2d, 0x11, 0x9b, 0xdb, 0xd4, - 0x6a, 0xa5, 0xe6, 0xdd, 0xe3, 0x93, 0x8d, 0x6d, 0xc7, 0xe5, 0xbd, 0x51, 0xb7, 0x6e, 0xd1, 0x61, - 0x43, 0x79, 0x5a, 0x3d, 0xec, 0x7a, 0xd1, 0xa1, 0xc1, 0xa7, 0x3e, 0x61, 0xf5, 0xe6, 0x5e, 0xfb, - 0xd6, 0xed, 0x9b, 0x0a, 0x72, 0xb1, 0xcb, 0xad, 0x76, 0x1f, 0x7d, 0x02, 0x59, 0x9f, 0xfa, 0xfa, - 0xa2, 0xac, 0xa3, 0x56, 0x7f, 0x2d, 0xf5, 0xf5, 0x76, 0x40, 0xe9, 0xd1, 0x93, 0xa3, 0x36, 0x65, - 0x8c, 0xc8, 0x2e, 0x0c, 0x11, 0x84, 0x6e, 0xc3, 0x2a, 0x1b, 0x60, 0xd6, 0x23, 0xb6, 0x19, 0xb5, - 0xd4, 0x23, 0xae, 0xd3, 0xe3, 0x7a, 0x7e, 0x53, 0xab, 0xe5, 0x8c, 0x15, 0x65, 0x6d, 0x86, 0xc6, - 0x07, 0xd2, 0x86, 0x3e, 0x04, 0x14, 0x47, 0x71, 0x2b, 0x8a, 0x58, 0x92, 0x11, 0x95, 0x28, 0x82, - 0x5b, 0xa1, 0x77, 0xf5, 0xfb, 0x0c, 0xe8, 0x2f, 0x33, 0xfb, 0x85, 0xcb, 0x7b, 0x8f, 0x09, 0xc7, - 0xa9, 0x59, 0x68, 0x67, 0x31, 0x8b, 0x55, 0xc8, 0xab, 0x6a, 0x32, 0xb2, 0x1a, 0x75, 0x42, 0xff, - 0x87, 0xd2, 0x98, 0x72, 0xd7, 0x73, 0x4c, 0x9f, 0x7e, 0x47, 0x02, 0x49, 0x5a, 0xce, 0x28, 0x86, - 0x77, 0x6d, 0x71, 0xf5, 0x86, 0x51, 0xe4, 0xde, 0x7a, 0x14, 0x8b, 0xa7, 0x8c, 0xe2, 0xef, 0x3c, - 0x94, 0x9b, 0x07, 0x3b, 0x2d, 0x32, 0x20, 0x0e, 0xe6, 0xaf, 0x6a, 0x49, 0x9b, 0x43, 0x4b, 0x99, - 0x33, 0xd4, 0x52, 0xf6, 0x5d, 0xb4, 0xf4, 0x35, 0x9c, 0x3f, 0xf2, 0xcd, 0xb0, 0x1a, 0x73, 0xe0, - 0x32, 0x31, 0xb8, 0xec, 0x1c, 0x25, 0x15, 0x8f, 0xfc, 0xa6, 0x28, 0xea, 0x91, 0xcb, 0x24, 0x81, - 0x8c, 0xe3, 0x80, 0xcf, 0x4e, 0xb8, 0x28, 0xef, 0x14, 0x15, 0xff, 0x03, 0x20, 0x9e, 0x3d, 0xab, - 0xdf, 0x02, 0xf1, 0x6c, 0x65, 0x5e, 0x83, 0x02, 0xa7, 0x1c, 0x0f, 0x4c, 0x86, 0x23, 0xad, 0x9e, - 0x93, 0x17, 0x1d, 0x2c, 0x63, 0x55, 0x83, 0x26, 0x9f, 0xe8, 0xe7, 0xc4, 0x28, 0x8d, 0x82, 0xba, - 0x39, 0x98, 0x48, 0x96, 0x95, 0x99, 0x8e, 0xb8, 0x3f, 0xe2, 0xa6, 0x6b, 0x4f, 0xf4, 0xc2, 0xa6, - 0x56, 0x2b, 0x1b, 0x15, 0x65, 0x79, 0x22, 0x0d, 0x7b, 0xf6, 0x04, 0x6d, 0x43, 0x51, 0x32, 0xaf, - 0xd0, 0x40, 0x12, 0x73, 0xe1, 0xf8, 0x64, 0x43, 0x70, 0xdf, 0x51, 0x96, 0x83, 0x89, 0x01, 0x2c, - 0xfe, 0x8d, 0xbe, 0x81, 0xb2, 0x1d, 0xaa, 0x82, 0x06, 0x26, 0x73, 0x1d, 0xbd, 0x28, 0xa3, 0x3e, - 0x3e, 0x3e, 0xd9, 0xb8, 0xf3, 0x36, 0xb3, 0xeb, 0xb8, 0x8e, 0x87, 0xf9, 0x28, 0x20, 0x46, 0x29, - 0xc6, 0xeb, 0xb8, 0x0e, 0x3a, 0x84, 0xb2, 0x45, 0xc7, 0xc4, 0xc3, 0x1e, 0x17, 0xf0, 0x4c, 0x2f, - 0x6d, 0x66, 0x6b, 0xc5, 0xed, 0x9b, 0xa7, 0x50, 0xbc, 0xa3, 0x7c, 0xef, 0xd9, 0xd8, 0x0f, 0x11, - 0x42, 0x54, 0x66, 0x94, 0x22, 0x98, 0x8e, 0xeb, 0x30, 0xf4, 0x3e, 0x9c, 0x1f, 0x79, 0x5d, 0xea, - 0xd9, 0xb2, 0x57, 0x77, 0x48, 0xf4, 0xb2, 0x1c, 0x4a, 0x39, 0xbe, 0x3d, 0x70, 0x87, 0x04, 0x7d, - 0x0e, 0x15, 0xa1, 0x8b, 0x91, 0x67, 0xc7, 0xca, 0xd7, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa5, 0x80, - 0xe6, 0xc1, 0xce, 0x61, 0xca, 0xdb, 0x58, 0xee, 0x72, 0x2b, 0x7d, 0x21, 0x32, 0xfb, 0x38, 0xc0, - 0x43, 0x66, 0x8e, 0x49, 0x20, 0xf7, 0xfa, 0x72, 0x98, 0x39, 0xbc, 0x7d, 0x1a, 0x5e, 0x56, 0x7f, - 0xca, 0xc1, 0xf2, 0x4b, 0x58, 0x42, 0x4b, 0xa9, 0xa2, 0x27, 0xe1, 0xe6, 0x31, 0x8a, 0x49, 0xc9, - 0xaf, 0x50, 0x98, 0xf9, 0x2f, 0x14, 0x7e, 0x0b, 0x97, 0x13, 0x0a, 0x93, 0x04, 0x82, 0xcc, 0xec, - 0xbc, 0x64, 0x5e, 0x8a, 0x91, 0x0f, 0x23, 0x60, 0xc1, 0x2a, 0x85, 0xd5, 0x94, 0x6a, 0xa2, 0x82, - 0x45, 0xc6, 0xdc, 0xbc, 0x19, 0x57, 0x12, 0xf9, 0x28, 0x5c, 0x91, 0xf0, 0x08, 0x56, 0x13, 0x19, - 0xa5, 0xf2, 0x31, 0x7d, 0xf1, 0x1d, 0xf5, 0xb4, 0x12, 0xeb, 0x29, 0x49, 0xc3, 0x90, 0x05, 0x6b, - 0x71, 0x9e, 0x99, 0x51, 0x86, 0x8b, 0x25, 0x2f, 0x93, 0x5d, 0x3b, 0x25, 0x59, 0x8c, 0xbe, 0xe7, - 0x1d, 0x51, 0x43, 0x8f, 0x80, 0xd2, 0x93, 0x13, 0x3b, 0xa5, 0xda, 0x81, 0xcb, 0xc9, 0x32, 0xa6, - 0x41, 0xb2, 0x95, 0x19, 0xfa, 0x08, 0x72, 0x36, 0x19, 0x30, 0x5d, 0x7b, 0x63, 0xa2, 0x99, 0x55, - 0x6e, 0xc8, 0x88, 0xea, 0x3e, 0xac, 0xbd, 0x1e, 0x74, 0xcf, 0xb3, 0xc9, 0x04, 0x35, 0x60, 0x25, - 0x59, 0x34, 0x66, 0x0f, 0xb3, 0x5e, 0xd8, 0x91, 0x48, 0x54, 0x32, 0x2e, 0xc4, 0x2b, 0xe7, 0x01, - 0x66, 0x3d, 0x59, 0xe4, 0xcf, 0x1a, 0x94, 0x67, 0x1a, 0x42, 0xf7, 0x21, 0x33, 0xf7, 0x73, 0x99, - 0xf1, 0xfb, 0xe8, 0x21, 0x64, 0x85, 0x52, 0x32, 0xf3, 0x2a, 0x45, 0xa0, 0x54, 0x7f, 0xd0, 0xe0, - 0xca, 0xa9, 0x24, 0x8b, 0x57, 0xca, 0xa2, 0xe3, 0x33, 0x78, 0xe5, 0x2d, 0x3a, 0x6e, 0xf7, 0xc5, - 0x1f, 0x18, 0x87, 0x39, 0x42, 0xed, 0x65, 0xe4, 0xf0, 0x8a, 0x38, 0xce, 0xcb, 0xaa, 0xbf, 0x6a, - 0x70, 0xa5, 0x43, 0x06, 0xc4, 0xe2, 0xee, 0x98, 0x44, 0xd2, 0xda, 0x15, 0xdf, 0x1e, 0x9e, 0x45, - 0xd0, 0x75, 0x58, 0x7e, 0x89, 0x05, 0x59, 0x58, 0xc1, 0x28, 0xcf, 0x10, 0x80, 0x0c, 0x28, 0xc4, - 0x4f, 0xda, 0x9c, 0x0f, 0xec, 0x92, 0x7a, 0xcd, 0xd0, 0x0d, 0xb8, 0x18, 0x10, 0xa1, 0xc9, 0x80, - 0xd8, 0xa6, 0x42, 0x67, 0xe1, 0x67, 0x64, 0xc9, 0xa8, 0xc4, 0xa6, 0xfb, 0xc2, 0xbd, 0xd3, 0xff, - 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc3, 0x31, 0x1f, 0x31, 0x54, 0x84, 0xa5, 0xf6, 0xee, 0x7e, - 0x6b, 0x6f, 0xff, 0xb3, 0xca, 0x02, 0x02, 0xc8, 0xdf, 0xdb, 0x39, 0xd8, 0x7b, 0xba, 0x5b, 0xd1, - 0x50, 0x09, 0xce, 0x1d, 0xee, 0x37, 0x9f, 0xec, 0xb7, 0x76, 0x5b, 0x95, 0x0c, 0x5a, 0x82, 0xec, - 0xbd, 0xfd, 0x2f, 0x2b, 0xd9, 0xe6, 0xa3, 0xdf, 0x9e, 0xaf, 0x6b, 0xcf, 0x9e, 0xaf, 0x6b, 0x7f, - 0x3d, 0x5f, 0xd7, 0x7e, 0x7c, 0xb1, 0xbe, 0xf0, 0xec, 0xc5, 0xfa, 0xc2, 0x9f, 0x2f, 0xd6, 0x17, - 0xbe, 0xfa, 0xd7, 0x66, 0x26, 0xe9, 0x6f, 0x76, 0xd9, 0x59, 0x37, 0x2f, 0xbf, 0xd9, 0x6f, 0xfd, - 0x13, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xb8, 0x1f, 0xd2, 0x90, 0x0c, 0x00, 0x00, + // 1226 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xdb, 0x6e, 0x1b, 0x45, + 0x18, 0xce, 0xda, 0x8e, 0x53, 0xff, 0xb6, 0x1b, 0x77, 0x9a, 0xa6, 0xdb, 0x46, 0x24, 0xc6, 0x94, + 0xca, 0x42, 0xd4, 0x6e, 0xd2, 0x83, 0x80, 0x0b, 0xa4, 0x3a, 0x4e, 0x69, 0xd4, 0x36, 0x35, 0xeb, + 0xa4, 0x08, 0x90, 0x58, 0xcd, 0xee, 0x8e, 0xed, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, 0x87, + 0x40, 0xe2, 0x96, 0x7b, 0x1e, 0x80, 0x0b, 0x9e, 0x01, 0x71, 0x59, 0x71, 0x85, 0x72, 0x11, 0xa1, + 0xf6, 0x01, 0x78, 0x04, 0xd0, 0x1c, 0xbc, 0xb6, 0xdb, 0x04, 0x68, 0xdd, 0x3b, 0xef, 0x7f, 0xf8, + 0xfe, 0xc3, 0xf7, 0x79, 0x66, 0x17, 0xae, 0x3b, 0xd8, 0x19, 0xf7, 0x68, 0x50, 0x75, 0xb8, 0xcb, + 0x38, 0xee, 0xfa, 0x41, 0xbb, 0x3a, 0xdc, 0x9e, 0x79, 0xaa, 0x84, 0x11, 0xe5, 0x14, 0x5d, 0xd2, + 0x71, 0x95, 0x19, 0xcf, 0x70, 0xfb, 0xea, 0x5a, 0x9b, 0xb6, 0xa9, 0x8c, 0xa8, 0x8a, 0x5f, 0x2a, + 0xf8, 0xea, 0x15, 0x97, 0xb2, 0x3e, 0x65, 0xb6, 0x72, 0xa8, 0x07, 0xed, 0x2a, 0xa9, 0xa7, 0xaa, + 0x1b, 0x8d, 0x43, 0x4e, 0xab, 0x8c, 0xb8, 0xe1, 0xce, 0x9d, 0xbb, 0xdd, 0xed, 0x6a, 0x97, 0x8c, + 0x27, 0x31, 0xd7, 0x74, 0xcc, 0xb4, 0x1f, 0x87, 0x70, 0xbc, 0x5d, 0x9d, 0xeb, 0xe8, 0xea, 0xd6, + 0xe9, 0x9d, 0x87, 0x34, 0x54, 0x01, 0xa5, 0xbf, 0x93, 0x50, 0xb8, 0xef, 0x07, 0xb8, 0xe7, 0xf3, + 0x71, 0x23, 0xa2, 0x43, 0xdf, 0x23, 0x11, 0xda, 0x83, 0xac, 0x47, 0x98, 0x1b, 0xf9, 0x21, 0xf7, + 0x69, 0x60, 0x1a, 0x45, 0xa3, 0x9c, 0xdd, 0x79, 0xaf, 0xa2, 0x7b, 0x9c, 0x4e, 0x26, 0x2b, 0x56, + 0xea, 0xd3, 0x50, 0x6b, 0x36, 0x0f, 0x3d, 0x06, 0x70, 0x69, 0xbf, 0xef, 0x33, 0x26, 0x50, 0x12, + 0x45, 0xa3, 0x9c, 0xa9, 0xdd, 0x38, 0x3e, 0xd9, 0xda, 0x50, 0x40, 0xcc, 0xeb, 0x56, 0x7c, 0x5a, + 0xed, 0x63, 0xde, 0xa9, 0x3c, 0x22, 0x6d, 0xec, 0x8e, 0xeb, 0xc4, 0xfd, 0xfd, 0x97, 0x1b, 0xa0, + 0xeb, 0xd4, 0x89, 0x6b, 0xcd, 0x00, 0xa0, 0x4f, 0x01, 0xf4, 0x34, 0x76, 0xd8, 0x35, 0x93, 0xb2, + 0xa9, 0xad, 0x49, 0x53, 0x6a, 0x55, 0x95, 0x78, 0x55, 0x95, 0xc6, 0xc0, 0x79, 0x48, 0xc6, 0x56, + 0x46, 0xa7, 0x34, 0xba, 0xe8, 0x31, 0xa4, 0x1d, 0xee, 0x8a, 0xdc, 0x54, 0xd1, 0x28, 0xe7, 0x6a, + 0x77, 0x8f, 0x4f, 0xb6, 0x76, 0xda, 0x3e, 0xef, 0x0c, 0x9c, 0x8a, 0x4b, 0xfb, 0x55, 0x1d, 0xe9, + 0x76, 0xb0, 0x1f, 0x4c, 0x1e, 0xaa, 0x7c, 0x1c, 0x12, 0x56, 0xa9, 0xed, 0x37, 0x6e, 0xdd, 0xbe, + 0xa9, 0x21, 0x97, 0x1d, 0xee, 0x36, 0xba, 0xe8, 0x13, 0x48, 0x86, 0x34, 0x34, 0x97, 0x65, 0x1f, + 0xe5, 0xca, 0xa9, 0xd4, 0x57, 0x1a, 0x11, 0xa5, 0xad, 0x27, 0xad, 0x06, 0x65, 0x8c, 0xc8, 0x29, + 0x2c, 0x91, 0x84, 0xae, 0xc3, 0x6a, 0x1f, 0x33, 0x4e, 0x22, 0x3b, 0x1c, 0x38, 0x76, 0x84, 0x03, + 0xcf, 0x4c, 0x8b, 0xf5, 0x58, 0x79, 0x65, 0x6e, 0x0c, 0x1c, 0x0b, 0x07, 0x1e, 0xba, 0x0d, 0xeb, + 0xac, 0x87, 0x59, 0x87, 0x78, 0xf6, 0x64, 0xf4, 0x0e, 0xf1, 0xdb, 0x1d, 0x6e, 0xae, 0x14, 0x8d, + 0x72, 0xca, 0x5a, 0xd3, 0xde, 0x9a, 0x72, 0x3e, 0x90, 0x3e, 0xf4, 0x21, 0xa0, 0x38, 0x8b, 0xbb, + 0x93, 0x8c, 0x73, 0x32, 0xa3, 0x30, 0xc9, 0xe0, 0xae, 0x8a, 0x2e, 0xfd, 0x9c, 0x00, 0xf3, 0x65, + 0x05, 0x7c, 0xe1, 0xf3, 0xce, 0x63, 0xc2, 0xf1, 0xcc, 0xce, 0x8c, 0xb7, 0xb1, 0xb3, 0x75, 0x48, + 0xeb, 0x6e, 0x12, 0xb2, 0x1b, 0xfd, 0x84, 0xde, 0x85, 0xdc, 0x90, 0x72, 0x3f, 0x68, 0xdb, 0x21, + 0xfd, 0x8e, 0x44, 0x92, 0xdc, 0x94, 0x95, 0x55, 0xb6, 0x86, 0x30, 0x9d, 0xb6, 0xb2, 0xd4, 0xeb, + 0xad, 0x6c, 0xf9, 0xb5, 0x57, 0x96, 0x3e, 0x63, 0x65, 0x7f, 0xa5, 0x21, 0x5f, 0x3b, 0xdc, 0xad, + 0x93, 0x1e, 0x69, 0x63, 0xfe, 0xaa, 0x36, 0x8d, 0x05, 0xb4, 0x99, 0x78, 0x8b, 0xda, 0x4c, 0xbe, + 0x89, 0x36, 0xbf, 0x86, 0xf3, 0xad, 0xd0, 0x56, 0xdd, 0xd8, 0x3d, 0x9f, 0x71, 0x33, 0x55, 0x4c, + 0x2e, 0xd0, 0x52, 0xb6, 0x15, 0xd6, 0x44, 0x53, 0x8f, 0x7c, 0x26, 0x89, 0x66, 0x1c, 0x47, 0x7c, + 0x9e, 0x93, 0xac, 0xb4, 0x69, 0x2a, 0xde, 0x01, 0x20, 0x81, 0x37, 0x4f, 0x41, 0x86, 0x04, 0x9e, + 0x76, 0x6f, 0x40, 0x86, 0x53, 0x8e, 0x7b, 0x36, 0xc3, 0x93, 0x7f, 0xc1, 0x39, 0x69, 0x68, 0x62, + 0x99, 0xab, 0x07, 0xb4, 0xf9, 0x48, 0x2a, 0x3e, 0x67, 0x65, 0xb4, 0xe5, 0x70, 0x24, 0x59, 0xd6, + 0x6e, 0x3a, 0xe0, 0xe1, 0x80, 0xdb, 0xbe, 0x37, 0x32, 0x33, 0x45, 0xa3, 0x9c, 0xb7, 0x0a, 0xda, + 0xf3, 0x44, 0x3a, 0xf6, 0xbd, 0x11, 0xda, 0x81, 0xac, 0x64, 0x5e, 0xa3, 0x81, 0x24, 0xe6, 0xc2, + 0xf1, 0xc9, 0x96, 0xe0, 0xbe, 0xa9, 0x3d, 0x87, 0x23, 0x0b, 0x58, 0xfc, 0x1b, 0x7d, 0x03, 0x79, + 0x4f, 0xa9, 0x82, 0x46, 0x36, 0xf3, 0xdb, 0x66, 0x56, 0x66, 0x7d, 0x7c, 0x7c, 0xb2, 0x75, 0xe7, + 0x75, 0x76, 0xd7, 0xf4, 0xdb, 0x01, 0xe6, 0x83, 0x88, 0x58, 0xb9, 0x18, 0xaf, 0xe9, 0xb7, 0xd1, + 0x11, 0xe4, 0x5d, 0x3a, 0x24, 0x01, 0x0e, 0xb8, 0x80, 0x67, 0x66, 0xae, 0x98, 0x2c, 0x67, 0x77, + 0x6e, 0x9e, 0x41, 0xf1, 0xae, 0x8e, 0xbd, 0xe7, 0xe1, 0x50, 0x21, 0x28, 0x54, 0x66, 0xe5, 0x26, + 0x30, 0x4d, 0xbf, 0xcd, 0xd0, 0xfb, 0x70, 0x7e, 0x10, 0x38, 0x34, 0xf0, 0xe4, 0xac, 0x7e, 0x9f, + 0x98, 0x79, 0xb9, 0x94, 0x7c, 0x6c, 0x3d, 0xf4, 0xfb, 0x04, 0x7d, 0x0e, 0x05, 0xa1, 0x8b, 0x41, + 0xe0, 0xc5, 0xca, 0x37, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa3, 0x81, 0xda, 0xe1, 0xee, 0xd1, 0x4c, + 0xb4, 0xb5, 0xea, 0x70, 0x77, 0xd6, 0x20, 0x2a, 0x87, 0x38, 0xc2, 0x7d, 0x66, 0x0f, 0x49, 0x24, + 0xef, 0x89, 0x55, 0x55, 0x59, 0x59, 0x9f, 0x2a, 0x63, 0xe9, 0xc7, 0x14, 0xac, 0xbe, 0x84, 0x25, + 0xb4, 0x34, 0xd3, 0xf4, 0x48, 0x9d, 0x50, 0x56, 0x76, 0xda, 0xf2, 0x2b, 0x14, 0x26, 0xfe, 0x0f, + 0x85, 0xdf, 0xc2, 0xe5, 0x29, 0x85, 0xd3, 0x02, 0x82, 0xcc, 0xe4, 0xa2, 0x64, 0x5e, 0x8a, 0x91, + 0x8f, 0x26, 0xc0, 0x82, 0x55, 0x0a, 0xeb, 0x33, 0xaa, 0x99, 0x34, 0x2c, 0x2a, 0xa6, 0x16, 0xad, + 0xb8, 0x36, 0x95, 0x8f, 0xc6, 0x15, 0x05, 0x5b, 0xb0, 0x3e, 0x95, 0xd1, 0x4c, 0x3d, 0x66, 0x2e, + 0xbf, 0xa1, 0x9e, 0xd6, 0x62, 0x3d, 0x4d, 0xcb, 0x30, 0xe4, 0xc2, 0x46, 0x5c, 0x67, 0x6e, 0x95, + 0xea, 0x60, 0x49, 0xcb, 0x62, 0xd7, 0xce, 0x28, 0x16, 0xa3, 0xef, 0x07, 0x2d, 0x6a, 0x99, 0x13, + 0xa0, 0xd9, 0xcd, 0x89, 0x33, 0xa5, 0xd4, 0x84, 0xcb, 0xd3, 0xc3, 0x98, 0x46, 0xd3, 0x53, 0x99, + 0xa1, 0x8f, 0x20, 0xe5, 0x91, 0x1e, 0x33, 0x8d, 0x7f, 0x2d, 0x34, 0x77, 0x94, 0x5b, 0x32, 0xa3, + 0x74, 0x00, 0x1b, 0xa7, 0x83, 0xee, 0x07, 0x1e, 0x19, 0xa1, 0x2a, 0xac, 0x4d, 0x0f, 0x1a, 0xbb, + 0x83, 0x59, 0x47, 0x4d, 0x24, 0x0a, 0xe5, 0xac, 0x0b, 0xf1, 0x91, 0xf3, 0x00, 0xb3, 0x8e, 0x6c, + 0xf2, 0x27, 0x03, 0xf2, 0x73, 0x03, 0xa1, 0xfb, 0x90, 0x58, 0xf8, 0x5a, 0x4d, 0x84, 0x5d, 0xf4, + 0x10, 0x92, 0x42, 0x29, 0x89, 0x45, 0x95, 0x22, 0x50, 0x4a, 0xdf, 0x1b, 0x70, 0xe5, 0x4c, 0x92, + 0xc5, 0x2d, 0xe5, 0xd2, 0xe1, 0x5b, 0x78, 0x1b, 0x70, 0xe9, 0xb0, 0xd1, 0x15, 0x7f, 0x60, 0xac, + 0x6a, 0x28, 0xed, 0x25, 0xe4, 0xf2, 0xb2, 0x38, 0xae, 0xcb, 0x4a, 0xbf, 0x1a, 0x70, 0xa5, 0x49, + 0x7a, 0xc4, 0xe5, 0xfe, 0x90, 0x4c, 0xa4, 0xb5, 0x27, 0xde, 0x51, 0x02, 0x97, 0x88, 0x77, 0x82, + 0x97, 0x58, 0x90, 0x8d, 0x65, 0xac, 0xfc, 0x1c, 0x01, 0xc8, 0x82, 0x4c, 0x7c, 0xa5, 0x2d, 0x78, + 0xc1, 0xae, 0xe8, 0xdb, 0x0c, 0xdd, 0x80, 0x8b, 0x11, 0x11, 0x9a, 0x8c, 0x88, 0x67, 0x6b, 0x74, + 0xa6, 0x5e, 0x4b, 0x73, 0x56, 0x21, 0x76, 0xdd, 0x17, 0xe1, 0xcd, 0xee, 0x07, 0x7b, 0x70, 0x71, + 0x4e, 0x66, 0x4d, 0x8e, 0xf9, 0x80, 0xa1, 0x2c, 0xac, 0x34, 0xf6, 0x0e, 0xea, 0xfb, 0x07, 0x9f, + 0x15, 0x96, 0x10, 0x40, 0xfa, 0xde, 0xee, 0xe1, 0xfe, 0xd3, 0xbd, 0x82, 0x81, 0x72, 0x70, 0xee, + 0xe8, 0xa0, 0xf6, 0xe4, 0xa0, 0xbe, 0x57, 0x2f, 0x24, 0xd0, 0x0a, 0x24, 0xef, 0x1d, 0x7c, 0x59, + 0x48, 0xd6, 0x1e, 0xfd, 0xf6, 0x7c, 0xd3, 0x78, 0xf6, 0x7c, 0xd3, 0xf8, 0xf3, 0xf9, 0xa6, 0xf1, + 0xc3, 0x8b, 0xcd, 0xa5, 0x67, 0x2f, 0x36, 0x97, 0xfe, 0x78, 0xb1, 0xb9, 0xf4, 0xd5, 0x7f, 0x0e, + 0x33, 0x9a, 0xfd, 0x06, 0x90, 0x93, 0x39, 0x69, 0xf9, 0x0d, 0x70, 0xeb, 0x9f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x1d, 0xc6, 0x0a, 0x0c, 0xe0, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -845,12 +865,19 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x40 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x38 + } + if len(m.MasterPubRand) > 0 { + i -= len(m.MasterPubRand) + copy(dAtA[i:], m.MasterPubRand) + i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.MasterPubRand))) + i-- + dAtA[i] = 0x32 } if m.Pop != nil { { @@ -938,12 +965,19 @@ func (m *FinalityProviderWithMeta) MarshalToSizedBuffer(dAtA []byte) (int, error if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x30 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x28 + } + if len(m.MasterPubRand) > 0 { + i -= len(m.MasterPubRand) + copy(dAtA[i:], m.MasterPubRand) + i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.MasterPubRand))) + i-- + dAtA[i] = 0x22 } if m.VotingPower != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.VotingPower)) @@ -1470,6 +1504,10 @@ func (m *FinalityProvider) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovBtcstaking(uint64(l)) } + l = len(m.MasterPubRand) + if l > 0 { + n += 1 + l + sovBtcstaking(uint64(l)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1495,6 +1533,10 @@ func (m *FinalityProviderWithMeta) Size() (n int) { if m.VotingPower != 0 { n += 1 + sovBtcstaking(uint64(m.VotingPower)) } + l = len(m.MasterPubRand) + if l > 0 { + n += 1 + l + sovBtcstaking(uint64(l)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1910,6 +1952,38 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + 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 ErrInvalidLengthBtcstaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthBtcstaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MasterPubRand = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -1928,7 +2002,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { break } } - case 7: + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -2071,6 +2145,38 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { } } case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + 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 ErrInvalidLengthBtcstaking + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthBtcstaking + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MasterPubRand = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -2089,7 +2195,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { break } } - case 5: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index ba77caf15..6bc0059ba 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -51,6 +51,9 @@ func (m *MsgCreateFinalityProvider) ValidateBasic() error { if err := m.Pop.ValidateBasic(); err != nil { return err } + if len(m.MasterPubRand) == 0 { + return fmt.Errorf("empty master public randomness") + } return nil } diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 1907483ff..0b174453b 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -63,6 +63,7 @@ func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPowe BabylonPk: f.BabylonPk, BtcPk: f.BtcPk, Pop: f.Pop, + MasterPubRand: f.MasterPubRand, SlashedBabylonHeight: f.SlashedBabylonHeight, SlashedBtcHeight: f.SlashedBtcHeight, Height: bbnBlockHeight, diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index ee5452bbb..8eb455408 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1483,18 +1483,20 @@ type FinalityProviderResponse struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` + // master_pub_rand is the master public randomness of the finality provider + MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,7,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,8,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` // height is the queried Babylon height - Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"` + Height uint64 `protobuf:"varint,9,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height - VotingPower uint64 `protobuf:"varint,9,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + VotingPower uint64 `protobuf:"varint,10,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } @@ -1551,6 +1553,13 @@ func (m *FinalityProviderResponse) GetPop() *ProofOfPossession { return nil } +func (m *FinalityProviderResponse) GetMasterPubRand() string { + if m != nil { + return m.MasterPubRand + } + return "" +} + func (m *FinalityProviderResponse) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -1611,124 +1620,126 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1869 bytes of a gzipped FileDescriptorProto + // 1894 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, - 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x3f, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, - 0x58, 0x98, 0x21, 0x26, 0x50, 0x69, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, - 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x8a, 0x3d, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, - 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0xaa, 0xd4, 0x73, 0x2b, 0xf5, 0xd8, 0x3d, 0x55, - 0xea, 0x7d, 0x7b, 0x5b, 0x6d, 0x0f, 0xad, 0x38, 0xa0, 0x0a, 0xaa, 0x56, 0xaa, 0xd4, 0x6b, 0xcf, - 0xd5, 0xbc, 0xf7, 0xc6, 0x33, 0xb6, 0x67, 0x1c, 0x3b, 0xc9, 0xde, 0xe2, 0x79, 0xdf, 0xff, 0xef, - 0xf7, 0x7e, 0xef, 0xbd, 0x2f, 0x70, 0xa9, 0x62, 0x56, 0x3a, 0x0d, 0xe2, 0xea, 0x15, 0x66, 0x51, - 0x66, 0xee, 0x38, 0xae, 0xad, 0xef, 0xae, 0xe9, 0x2f, 0x5b, 0xd8, 0xef, 0x68, 0x9e, 0x4f, 0x18, - 0x41, 0x67, 0xa4, 0x88, 0x16, 0x89, 0x68, 0xbb, 0x6b, 0xb9, 0x45, 0x9b, 0xd8, 0x84, 0x4b, 0xe8, - 0xc1, 0x5f, 0x42, 0x38, 0x77, 0xc1, 0x26, 0xc4, 0x6e, 0x60, 0xdd, 0xf4, 0x1c, 0xdd, 0x74, 0x5d, - 0xc2, 0x4c, 0xe6, 0x10, 0x97, 0xca, 0xd5, 0xf3, 0x16, 0xa1, 0x4d, 0x42, 0xcb, 0x42, 0x4d, 0xfc, - 0x90, 0x4b, 0xaa, 0xf8, 0xa5, 0x5b, 0x7e, 0xc7, 0x63, 0x44, 0xa7, 0xd8, 0xf2, 0x0a, 0x77, 0xee, - 0xee, 0xac, 0xe9, 0x3b, 0xb8, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x15, 0xcc, 0xcc, 0xb5, - 0xf0, 0xb7, 0x94, 0xba, 0x2e, 0xa5, 0x2a, 0x26, 0xc5, 0x22, 0x91, 0xae, 0xa0, 0x67, 0xda, 0x8e, - 0xcb, 0x23, 0x0a, 0xbd, 0x26, 0xa7, 0xef, 0x99, 0xbe, 0xd9, 0x0c, 0xbd, 0x5e, 0x49, 0x96, 0x89, - 0x55, 0x43, 0xc8, 0xe5, 0x53, 0x6c, 0x11, 0x4f, 0x08, 0xa8, 0x8b, 0x80, 0xbe, 0x17, 0x84, 0x53, - 0xe2, 0xd6, 0x0d, 0xfc, 0xb2, 0x85, 0x29, 0x53, 0x0d, 0x78, 0xaf, 0xe7, 0x2b, 0xf5, 0x88, 0x4b, - 0x31, 0xfa, 0x08, 0x32, 0x22, 0x8a, 0xac, 0x72, 0x51, 0x59, 0x9d, 0x29, 0x2c, 0x6b, 0x89, 0x6d, - 0xd0, 0x84, 0x5a, 0x71, 0xea, 0xcb, 0x37, 0xf9, 0x63, 0x86, 0x54, 0x51, 0xbf, 0x0d, 0x4b, 0x31, - 0x9b, 0xc5, 0xce, 0xf7, 0xb1, 0x4f, 0x1d, 0xe2, 0x4a, 0x97, 0x28, 0x0b, 0x27, 0x76, 0xc5, 0x17, - 0x6e, 0x7c, 0xce, 0x08, 0x7f, 0xaa, 0x9f, 0xc3, 0x85, 0x64, 0xc5, 0xa3, 0x88, 0xca, 0x86, 0x65, - 0x6e, 0xfc, 0x13, 0xc7, 0x35, 0x1b, 0x0e, 0xeb, 0x94, 0x7c, 0xb2, 0xeb, 0x54, 0xb1, 0x1f, 0x96, - 0x02, 0x7d, 0x02, 0x10, 0x75, 0x48, 0x7a, 0xb8, 0xa2, 0x49, 0x98, 0x04, 0xed, 0xd4, 0x04, 0x2e, - 0x65, 0x3b, 0xb5, 0x92, 0x69, 0x63, 0xa9, 0x6b, 0xc4, 0x34, 0xd5, 0xbf, 0x28, 0xb0, 0x92, 0xe6, - 0x49, 0x26, 0xf2, 0x63, 0x40, 0x35, 0xb9, 0x18, 0xa0, 0x51, 0xac, 0x66, 0x95, 0x8b, 0x93, 0xab, - 0x33, 0x05, 0x3d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xe3, 0x74, 0xad, 0xdf, 0x0f, 0x7a, 0xd4, - 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0x36, 0x64, 0x47, 0x06, - 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0xb9, 0x9a, 0x57, 0xae, 0x30, 0xab, 0xec, 0xed, 0x94, 0xeb, 0xb8, - 0xcd, 0xcb, 0x36, 0x6d, 0x40, 0xcd, 0x2b, 0x32, 0xab, 0xb4, 0xf3, 0x18, 0xb7, 0xd5, 0xbd, 0x94, - 0xba, 0x77, 0x8b, 0xf1, 0x23, 0x38, 0x3d, 0x50, 0x0c, 0x59, 0xfe, 0xb1, 0x6b, 0xb1, 0xd0, 0x5f, - 0x0b, 0xf5, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xe2, 0xf3, 0x87, 0x9b, 0xb8, 0x81, 0x6d, 0x41, 0x09, - 0x61, 0x02, 0x45, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x80, 0xd4, 0x7c, 0xe1, 0x7a, 0x8a, 0xc7, 0x1e, - 0xed, 0x6d, 0xae, 0x61, 0x48, 0xcd, 0x3e, 0xe0, 0x4c, 0x1c, 0x18, 0x38, 0x7f, 0x56, 0xe4, 0xc6, - 0xe9, 0x0f, 0x55, 0x16, 0xea, 0x05, 0x9c, 0x0a, 0x2a, 0x5d, 0x8d, 0x96, 0x24, 0x64, 0x6e, 0x8c, - 0x12, 0x74, 0xb7, 0x46, 0xf3, 0x15, 0x66, 0xc5, 0xcc, 0x1f, 0x1d, 0x58, 0x6a, 0x70, 0x2d, 0xb1, - 0xd3, 0x25, 0xf2, 0x13, 0xec, 0x6f, 0xb0, 0xc7, 0xd8, 0xb1, 0xeb, 0x6c, 0x74, 0xe4, 0xa0, 0xb3, - 0x90, 0xa9, 0x73, 0x1d, 0x1e, 0xd4, 0x94, 0x21, 0x7f, 0xa9, 0xcf, 0xe0, 0xfa, 0x28, 0x7e, 0x64, - 0xd5, 0x2e, 0xc1, 0xec, 0x2e, 0x61, 0x8e, 0x6b, 0x97, 0xbd, 0x60, 0x9d, 0xfb, 0x99, 0x32, 0x66, - 0xc4, 0x37, 0xae, 0xa2, 0x6e, 0xc1, 0x6a, 0xa2, 0xc1, 0x87, 0x2d, 0xdf, 0xc7, 0x2e, 0xe3, 0x42, - 0x63, 0x20, 0x3e, 0xad, 0x0e, 0xbd, 0xe6, 0x64, 0x78, 0x51, 0x92, 0x4a, 0x3c, 0xc9, 0x81, 0xb0, - 0x27, 0x06, 0xc3, 0xfe, 0xb9, 0x02, 0x1f, 0x70, 0x47, 0x1b, 0x16, 0x73, 0x76, 0xf1, 0x00, 0xdd, - 0xf4, 0x97, 0x3c, 0xcd, 0xd5, 0x51, 0xe1, 0xf7, 0x6f, 0x0a, 0xdc, 0x18, 0x2d, 0x9e, 0x23, 0xa4, - 0xc1, 0x1f, 0x38, 0xac, 0xbe, 0x85, 0x99, 0xf9, 0x8d, 0xd2, 0xe0, 0xb2, 0xdc, 0x98, 0x3c, 0x31, - 0x93, 0xe1, 0x6a, 0x4f, 0x61, 0xd5, 0xbb, 0x92, 0x25, 0x07, 0x96, 0x87, 0xf7, 0x58, 0xfd, 0x95, - 0x02, 0x57, 0x13, 0x91, 0x92, 0x40, 0x54, 0x23, 0xec, 0x97, 0xa3, 0xea, 0xe3, 0xbf, 0x95, 0x94, - 0xfd, 0x90, 0x44, 0x4a, 0x3e, 0x9c, 0x8f, 0x91, 0x12, 0xf1, 0x13, 0xe8, 0xe9, 0xee, 0xbe, 0xf4, - 0x44, 0x92, 0x4c, 0x1b, 0xe7, 0x22, 0xa2, 0xea, 0x11, 0x38, 0xba, 0xbe, 0x7e, 0x0a, 0xe7, 0x07, - 0x09, 0x37, 0xac, 0xf8, 0x4d, 0x78, 0x4f, 0x06, 0x5b, 0x66, 0xed, 0x72, 0xdd, 0xa4, 0xf5, 0x58, - 0xdd, 0x17, 0xe4, 0xd2, 0xf3, 0xf6, 0x63, 0x93, 0xd6, 0x83, 0x5d, 0xff, 0x32, 0xe9, 0x9c, 0xe9, - 0x96, 0x69, 0x1b, 0xe6, 0x7b, 0xb9, 0x5b, 0x9e, 0x70, 0xe3, 0x51, 0xf7, 0x5c, 0x0f, 0x75, 0xab, - 0xbf, 0xce, 0xc0, 0x99, 0x64, 0x77, 0x5b, 0x90, 0x11, 0x50, 0xe1, 0x6e, 0x66, 0x8b, 0x77, 0x5f, - 0xbf, 0xc9, 0x17, 0x6c, 0x87, 0xd5, 0x5b, 0x15, 0xcd, 0x22, 0x4d, 0x5d, 0x3a, 0xb5, 0xea, 0xa6, - 0xe3, 0x86, 0x3f, 0x74, 0xd6, 0xf1, 0x30, 0xd5, 0x8a, 0x4f, 0x4a, 0xb7, 0xd7, 0x6f, 0x95, 0x5a, - 0x95, 0xcf, 0x70, 0xc7, 0x38, 0x5e, 0x09, 0xc0, 0x85, 0x3e, 0x87, 0xf9, 0x08, 0x7c, 0x0d, 0x87, - 0x06, 0x8c, 0x3c, 0x79, 0x08, 0xb3, 0x33, 0x12, 0xb5, 0x4f, 0x1d, 0x8e, 0xec, 0x59, 0xca, 0x4c, - 0x9f, 0x95, 0xe5, 0x1e, 0x99, 0x14, 0x4c, 0xc7, 0xbf, 0x89, 0x8d, 0x84, 0x96, 0x01, 0xb0, 0x5b, - 0x0d, 0x05, 0xa6, 0xb8, 0xc0, 0x34, 0x76, 0xe5, 0x3e, 0x43, 0x4b, 0x30, 0xcd, 0x08, 0x33, 0x1b, - 0x65, 0x6a, 0xb2, 0xec, 0x71, 0xbe, 0x7a, 0x92, 0x7f, 0xd8, 0x36, 0x19, 0xba, 0x0c, 0xf3, 0xf1, - 0x36, 0xe2, 0x76, 0x36, 0xc3, 0x3b, 0x38, 0x1b, 0x75, 0x10, 0xb7, 0xd1, 0x15, 0x38, 0x45, 0x1b, - 0x26, 0xad, 0xc7, 0xc4, 0x4e, 0x70, 0xb1, 0xb9, 0xf0, 0xb3, 0x90, 0xbb, 0x03, 0xe7, 0x22, 0xa8, - 0xf3, 0xa5, 0x32, 0x75, 0x6c, 0x2e, 0x7f, 0x92, 0xcb, 0x2f, 0x76, 0x97, 0xb7, 0x83, 0xd5, 0x6d, - 0xc7, 0x0e, 0xd4, 0x5e, 0xc0, 0x9c, 0x45, 0x76, 0xb1, 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0xd9, 0x69, - 0xbe, 0x33, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0xdd, 0xa8, 0x9a, 0x5e, 0x60, 0xc9, 0xb1, 0x5d, - 0x93, 0xb5, 0x7c, 0x4c, 0x8d, 0xd9, 0xd0, 0xcc, 0xb6, 0x63, 0x53, 0x74, 0x03, 0x50, 0x98, 0x1b, - 0x69, 0x31, 0xaf, 0xc5, 0xca, 0x4e, 0xb5, 0x9d, 0x05, 0x7e, 0xab, 0x0e, 0x11, 0xfa, 0x8c, 0x2f, - 0x3c, 0xa9, 0xf2, 0xf3, 0xd4, 0xe4, 0xcc, 0x9c, 0x9d, 0xb9, 0xa8, 0xac, 0x9e, 0x34, 0xe4, 0x2f, - 0x94, 0x87, 0x19, 0x71, 0x93, 0x29, 0x57, 0x31, 0xb5, 0xb2, 0xb3, 0x82, 0x58, 0xc4, 0xa7, 0x4d, - 0x4c, 0x2d, 0xf4, 0x3e, 0xcc, 0xb7, 0xdc, 0x0a, 0x71, 0xab, 0xbc, 0x3a, 0x4e, 0x13, 0x67, 0xe7, - 0xb8, 0x8b, 0xb9, 0xee, 0xd7, 0xe7, 0x4e, 0x13, 0x23, 0x0b, 0xce, 0xb4, 0xdc, 0x08, 0xe1, 0x65, - 0x5f, 0xa2, 0x31, 0x3b, 0xcf, 0xa1, 0xae, 0xa5, 0x43, 0xfd, 0x45, 0x4c, 0xad, 0x0b, 0xf6, 0xc5, - 0x56, 0xc2, 0xd7, 0x20, 0x16, 0x71, 0xa1, 0x2f, 0x87, 0x8f, 0x88, 0x53, 0x22, 0x16, 0xf1, 0x55, - 0x3e, 0x19, 0xd4, 0x2f, 0x26, 0xe1, 0x5c, 0x8a, 0x61, 0xb4, 0x0a, 0x0b, 0xb1, 0x74, 0xda, 0xb1, - 0x5d, 0x1d, 0xa5, 0x29, 0xba, 0xfd, 0x5d, 0x58, 0x8a, 0xba, 0x1d, 0xe9, 0x84, 0x1d, 0x9f, 0xe0, - 0x4a, 0xd9, 0xae, 0xc8, 0x8b, 0x50, 0x42, 0x76, 0xdd, 0x82, 0xa5, 0x6e, 0xd7, 0x7b, 0xb5, 0xf9, - 0x1e, 0x9a, 0xe4, 0x18, 0xb8, 0x9c, 0x52, 0x96, 0x6e, 0xd3, 0x9f, 0xb8, 0x35, 0x62, 0x64, 0x43, - 0x43, 0x71, 0x1f, 0x7c, 0xfb, 0x24, 0x20, 0x77, 0x2a, 0x09, 0xb9, 0x1f, 0x41, 0xae, 0x0f, 0xb9, - 0xf1, 0x54, 0x8e, 0x73, 0x95, 0x73, 0xbd, 0xe0, 0x8d, 0x32, 0xa9, 0xc1, 0xd9, 0x08, 0xbf, 0x31, - 0x5d, 0x9a, 0xcd, 0x1c, 0x10, 0xc8, 0x8b, 0x5d, 0x20, 0x47, 0x9e, 0xa8, 0x6a, 0x41, 0x7e, 0x9f, - 0x53, 0x01, 0x3d, 0x80, 0xa9, 0x2a, 0x6e, 0x1c, 0xec, 0xea, 0xcb, 0x35, 0xd5, 0xdf, 0x4c, 0x41, - 0x36, 0xf5, 0x35, 0xf2, 0x31, 0xcc, 0x04, 0xbb, 0xc0, 0x77, 0xbc, 0x18, 0x4b, 0x7f, 0x2b, 0x3c, - 0x5c, 0x22, 0x0f, 0xe2, 0x64, 0xd9, 0x8c, 0x44, 0x8d, 0xb8, 0x1e, 0xda, 0x02, 0xb0, 0x48, 0xb3, - 0xe9, 0x50, 0x1a, 0x1e, 0x51, 0xd3, 0xc5, 0x9b, 0xaf, 0xdf, 0xe4, 0x97, 0x84, 0x21, 0x5a, 0xdd, - 0xd1, 0x1c, 0xa2, 0x37, 0x4d, 0x56, 0xd7, 0x9e, 0x62, 0xdb, 0xb4, 0x3a, 0x9b, 0xd8, 0xfa, 0xfa, - 0x8b, 0x9b, 0x20, 0xfd, 0x6c, 0x62, 0xcb, 0x88, 0x19, 0x40, 0xf7, 0x00, 0x64, 0x9e, 0x01, 0xa7, - 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0x68, 0xa1, 0x75, 0x87, 0x16, 0x9a, 0x64, 0xd9, 0x69, - 0xa9, 0x52, 0xda, 0x89, 0x9d, 0x07, 0x53, 0x47, 0x71, 0x1e, 0x7c, 0x08, 0x93, 0x1e, 0xf1, 0x38, - 0x68, 0x66, 0x0a, 0xab, 0x69, 0xaf, 0x70, 0x9f, 0x90, 0xda, 0xb3, 0x5a, 0x89, 0x50, 0x8a, 0x79, - 0x16, 0x46, 0xa0, 0x84, 0xd6, 0xe1, 0x2c, 0x47, 0x10, 0xae, 0x96, 0xc3, 0x94, 0x24, 0xaf, 0x67, - 0x38, 0x73, 0x2f, 0xca, 0xd5, 0xa2, 0x58, 0x94, 0x14, 0x1f, 0x30, 0x5d, 0xa8, 0xc5, 0xac, 0x50, - 0xe3, 0x04, 0xd7, 0x58, 0x08, 0x35, 0x98, 0x25, 0xa5, 0xa3, 0x0b, 0xd7, 0xc9, 0xa1, 0x97, 0xea, - 0xe9, 0x81, 0x4b, 0x75, 0xe1, 0xb7, 0xa7, 0xe1, 0x38, 0x3f, 0xc7, 0xd1, 0xcf, 0x14, 0xc8, 0x88, - 0x49, 0x02, 0xba, 0x96, 0x92, 0xe2, 0xe0, 0x40, 0x25, 0x77, 0x7d, 0x14, 0x51, 0x81, 0x35, 0xf5, - 0xfd, 0x9f, 0xfe, 0xf5, 0x9f, 0xbf, 0x9c, 0xc8, 0xa3, 0x65, 0x7d, 0xd8, 0x20, 0x08, 0xfd, 0x41, - 0x81, 0x53, 0x7d, 0x23, 0x11, 0x54, 0xd8, 0xdf, 0x4d, 0xff, 0xe0, 0x25, 0x77, 0x7b, 0x2c, 0x1d, - 0x19, 0xa3, 0xce, 0x63, 0xbc, 0x86, 0xae, 0x0e, 0x8d, 0x51, 0x7f, 0x25, 0xd9, 0x78, 0x0f, 0xfd, - 0x51, 0x81, 0xd3, 0x03, 0x57, 0x7f, 0xb4, 0x3e, 0xcc, 0x77, 0xda, 0x48, 0x26, 0x77, 0x67, 0x4c, - 0x2d, 0x19, 0xf3, 0x1a, 0x8f, 0xf9, 0x03, 0x74, 0x2d, 0x25, 0xe6, 0xc1, 0x47, 0x07, 0xfa, 0x5a, - 0x81, 0x85, 0x7e, 0x83, 0xe8, 0xf6, 0x38, 0xee, 0xc3, 0x98, 0xd7, 0xc7, 0x53, 0x92, 0x21, 0x6f, - 0xf3, 0x90, 0xb7, 0xd0, 0x67, 0x23, 0x87, 0xac, 0xbf, 0xea, 0x79, 0x0f, 0xec, 0x0d, 0x8a, 0xa0, - 0xdf, 0x29, 0x30, 0xdf, 0x3b, 0x4b, 0x40, 0x6b, 0xc3, 0xa2, 0x4b, 0x1c, 0x91, 0xe4, 0x0a, 0xe3, - 0xa8, 0xc8, 0x74, 0x34, 0x9e, 0xce, 0x2a, 0xba, 0xa2, 0xa7, 0x8e, 0x2f, 0xe3, 0x0f, 0x05, 0xf4, - 0x2f, 0x05, 0xf2, 0xfb, 0xbc, 0x1a, 0x51, 0x71, 0x58, 0x1c, 0xa3, 0x3d, 0x81, 0x73, 0x0f, 0x0f, - 0x65, 0x43, 0x26, 0xf7, 0x21, 0x4f, 0x6e, 0x1d, 0x15, 0xc6, 0xe8, 0x95, 0x20, 0xa0, 0x3d, 0xf4, - 0x3f, 0x05, 0x96, 0x87, 0xce, 0x2d, 0xd0, 0x83, 0x71, 0xf0, 0x93, 0x34, 0x5a, 0xc9, 0x6d, 0x1c, - 0xc2, 0x82, 0x4c, 0xb1, 0xc4, 0x53, 0xfc, 0x14, 0x3d, 0x3e, 0x38, 0x1c, 0x39, 0xc3, 0x46, 0x89, - 0xff, 0x47, 0x81, 0x0b, 0xc3, 0x06, 0x22, 0xe8, 0xfe, 0x38, 0x51, 0x27, 0x4c, 0x66, 0x72, 0x0f, - 0x0e, 0x6e, 0x40, 0x66, 0xfd, 0x88, 0x67, 0xbd, 0x81, 0xee, 0x1f, 0x32, 0x6b, 0xce, 0xd8, 0x7d, - 0xc3, 0x80, 0xe1, 0x8c, 0x9d, 0x3c, 0x58, 0x18, 0xce, 0xd8, 0x29, 0xd3, 0x86, 0x7d, 0x19, 0xdb, - 0x0c, 0xf5, 0xe4, 0x29, 0x8a, 0xfe, 0xab, 0xc0, 0xd2, 0x90, 0xa7, 0x3e, 0xba, 0x37, 0x4e, 0x61, - 0x13, 0x08, 0xe4, 0xfe, 0x81, 0xf5, 0x65, 0x46, 0x5b, 0x3c, 0xa3, 0x47, 0xe8, 0xe3, 0x83, 0xf7, - 0x25, 0x4e, 0x36, 0x7f, 0x52, 0x60, 0xae, 0x87, 0xb7, 0xd0, 0xad, 0x91, 0x29, 0x2e, 0xcc, 0x69, - 0x6d, 0x0c, 0x0d, 0x99, 0xc5, 0x26, 0xcf, 0xe2, 0x1e, 0xfa, 0xce, 0x68, 0x9c, 0xa8, 0xbf, 0x4a, - 0x98, 0x3e, 0xec, 0x15, 0x9f, 0x7e, 0xf9, 0x76, 0x45, 0xf9, 0xea, 0xed, 0x8a, 0xf2, 0x8f, 0xb7, - 0x2b, 0xca, 0x2f, 0xde, 0xad, 0x1c, 0xfb, 0xea, 0xdd, 0xca, 0xb1, 0xbf, 0xbf, 0x5b, 0x39, 0xf6, - 0xc3, 0x7d, 0xef, 0x73, 0xed, 0xb8, 0x43, 0x7e, 0xb9, 0xab, 0x64, 0xf8, 0xff, 0x86, 0x6e, 0xff, - 0x3f, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x9b, 0xda, 0xbf, 0x89, 0x1b, 0x00, 0x00, + 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x38, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, + 0x58, 0xf0, 0x10, 0x13, 0xa8, 0xb4, 0xdb, 0x02, 0x31, 0xd9, 0x05, 0x76, 0x89, 0x70, 0x27, 0xd0, + 0x4a, 0xdd, 0xaa, 0xa3, 0xe7, 0xf1, 0xf3, 0x78, 0x94, 0x78, 0x66, 0x98, 0xf7, 0x9c, 0xda, 0x42, + 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0x97, 0x9e, 0x5b, 0xa9, 0xc7, 0xee, 0xa9, 0x52, + 0x2f, 0x3d, 0x6d, 0x6f, 0xab, 0xed, 0xa1, 0x15, 0x07, 0x54, 0x41, 0xd5, 0x4a, 0x95, 0x7a, 0xed, + 0xb9, 0x9a, 0xf7, 0xde, 0x78, 0xc6, 0xf6, 0x8c, 0x63, 0x27, 0xd9, 0x5b, 0xfc, 0xde, 0xf7, 0xff, + 0xfb, 0xbd, 0xdf, 0x9b, 0xf7, 0x05, 0x2e, 0x55, 0x71, 0xb5, 0xb3, 0xe3, 0x3a, 0x5a, 0x95, 0x99, + 0x94, 0xe1, 0x6d, 0xdb, 0xb1, 0xb4, 0xdd, 0x55, 0xed, 0x65, 0x8b, 0xf8, 0x9d, 0xa2, 0xe7, 0xbb, + 0xcc, 0x45, 0x67, 0xa4, 0x48, 0x31, 0x12, 0x29, 0xee, 0xae, 0xe6, 0x17, 0x2c, 0xd7, 0x72, 0xb9, + 0x84, 0x16, 0xfc, 0x25, 0x84, 0xf3, 0x17, 0x2c, 0xd7, 0xb5, 0x76, 0x88, 0x86, 0x3d, 0x5b, 0xc3, + 0x8e, 0xe3, 0x32, 0xcc, 0x6c, 0xd7, 0xa1, 0x72, 0xf7, 0xbc, 0xe9, 0xd2, 0xa6, 0x4b, 0x0d, 0xa1, + 0x26, 0x7e, 0xc8, 0x2d, 0x55, 0xfc, 0xd2, 0x4c, 0xbf, 0xe3, 0x31, 0x57, 0xa3, 0xc4, 0xf4, 0x4a, + 0x77, 0xee, 0x6e, 0xaf, 0x6a, 0xdb, 0xa4, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x55, 0xc2, + 0xf0, 0x6a, 0xf8, 0x5b, 0x4a, 0x5d, 0x97, 0x52, 0x55, 0x4c, 0x89, 0x48, 0xa4, 0x2b, 0xe8, 0x61, + 0xcb, 0x76, 0x78, 0x44, 0xa1, 0xd7, 0xe4, 0xf4, 0x3d, 0xec, 0xe3, 0x66, 0xe8, 0xf5, 0x4a, 0xb2, + 0x4c, 0xac, 0x1a, 0x42, 0xae, 0x90, 0x62, 0xcb, 0xf5, 0x84, 0x80, 0xba, 0x00, 0xe8, 0x7b, 0x41, + 0x38, 0x15, 0x6e, 0x5d, 0x27, 0x2f, 0x5b, 0x84, 0x32, 0x55, 0x87, 0xf7, 0x7a, 0x56, 0xa9, 0xe7, + 0x3a, 0x94, 0xa0, 0x8f, 0x20, 0x23, 0xa2, 0xc8, 0x29, 0x17, 0x95, 0x95, 0x99, 0xd2, 0x52, 0x31, + 0xb1, 0x0d, 0x45, 0xa1, 0x56, 0x9e, 0xfa, 0xf2, 0x4d, 0xe1, 0x98, 0x2e, 0x55, 0xd4, 0x6f, 0xc3, + 0x62, 0xcc, 0x66, 0xb9, 0xf3, 0x7d, 0xe2, 0x53, 0xdb, 0x75, 0xa4, 0x4b, 0x94, 0x83, 0x13, 0xbb, + 0x62, 0x85, 0x1b, 0xcf, 0xea, 0xe1, 0x4f, 0xf5, 0x73, 0xb8, 0x90, 0xac, 0x78, 0x14, 0x51, 0x59, + 0xb0, 0xc4, 0x8d, 0x7f, 0x62, 0x3b, 0x78, 0xc7, 0x66, 0x9d, 0x8a, 0xef, 0xee, 0xda, 0x35, 0xe2, + 0x87, 0xa5, 0x40, 0x9f, 0x00, 0x44, 0x1d, 0x92, 0x1e, 0xae, 0x14, 0x25, 0x4c, 0x82, 0x76, 0x16, + 0x05, 0x2e, 0x65, 0x3b, 0x8b, 0x15, 0x6c, 0x11, 0xa9, 0xab, 0xc7, 0x34, 0xd5, 0xbf, 0x28, 0xb0, + 0x9c, 0xe6, 0x49, 0x26, 0xf2, 0x63, 0x40, 0x75, 0xb9, 0x19, 0xa0, 0x51, 0xec, 0xe6, 0x94, 0x8b, + 0x93, 0x2b, 0x33, 0x25, 0x2d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xfd, 0x74, 0xbd, 0xdf, 0x0f, + 0x7a, 0xd4, 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0xd6, 0x65, + 0x47, 0x06, 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0x6c, 0xdd, 0x33, 0xaa, 0xcc, 0x34, 0xbc, 0x6d, 0xa3, + 0x41, 0xda, 0xbc, 0x6c, 0xd3, 0x3a, 0xd4, 0xbd, 0x32, 0x33, 0x2b, 0xdb, 0x8f, 0x49, 0x5b, 0xdd, + 0x4b, 0xa9, 0x7b, 0xb7, 0x18, 0x3f, 0x82, 0xd3, 0x03, 0xc5, 0x90, 0xe5, 0x1f, 0xbb, 0x16, 0xf3, + 0xfd, 0xb5, 0x50, 0x7f, 0xa7, 0x40, 0x9e, 0xfb, 0x2f, 0x3f, 0x7f, 0xb8, 0x41, 0x76, 0x88, 0x25, + 0x28, 0x21, 0x4c, 0xa0, 0x0c, 0x19, 0xca, 0x30, 0x6b, 0x09, 0x48, 0xcd, 0x95, 0xae, 0xa7, 0x78, + 0xec, 0xd1, 0xde, 0xe2, 0x1a, 0xba, 0xd4, 0xec, 0x03, 0xce, 0xc4, 0x81, 0x81, 0xf3, 0x27, 0x45, + 0x1e, 0x9c, 0xfe, 0x50, 0x65, 0xa1, 0x5e, 0xc0, 0xa9, 0xa0, 0xd2, 0xb5, 0x68, 0x4b, 0x42, 0xe6, + 0xc6, 0x28, 0x41, 0x77, 0x6b, 0x34, 0x57, 0x65, 0x66, 0xcc, 0xfc, 0xd1, 0x81, 0xa5, 0x0e, 0xd7, + 0x12, 0x3b, 0x5d, 0x71, 0x7f, 0x42, 0xfc, 0x75, 0xf6, 0x98, 0xd8, 0x56, 0x83, 0x8d, 0x8e, 0x1c, + 0x74, 0x16, 0x32, 0x0d, 0xae, 0xc3, 0x83, 0x9a, 0xd2, 0xe5, 0x2f, 0xf5, 0x19, 0x5c, 0x1f, 0xc5, + 0x8f, 0xac, 0xda, 0x25, 0x98, 0xdd, 0x75, 0x99, 0xed, 0x58, 0x86, 0x17, 0xec, 0x73, 0x3f, 0x53, + 0xfa, 0x8c, 0x58, 0xe3, 0x2a, 0xea, 0x26, 0xac, 0x24, 0x1a, 0x7c, 0xd8, 0xf2, 0x7d, 0xe2, 0x30, + 0x2e, 0x34, 0x06, 0xe2, 0xd3, 0xea, 0xd0, 0x6b, 0x4e, 0x86, 0x17, 0x25, 0xa9, 0xc4, 0x93, 0x1c, + 0x08, 0x7b, 0x62, 0x30, 0xec, 0x9f, 0x2b, 0xf0, 0x01, 0x77, 0xb4, 0x6e, 0x32, 0x7b, 0x97, 0x0c, + 0xd0, 0x4d, 0x7f, 0xc9, 0xd3, 0x5c, 0x1d, 0x15, 0x7e, 0xff, 0xa6, 0xc0, 0x8d, 0xd1, 0xe2, 0x39, + 0x42, 0x1a, 0xfc, 0x81, 0xcd, 0x1a, 0x9b, 0x84, 0xe1, 0x6f, 0x94, 0x06, 0x97, 0xe4, 0xc1, 0xe4, + 0x89, 0x61, 0x46, 0x6a, 0x3d, 0x85, 0x55, 0xef, 0x4a, 0x96, 0x1c, 0xd8, 0x1e, 0xde, 0x63, 0xf5, + 0x57, 0x0a, 0x5c, 0x4d, 0x44, 0x4a, 0x02, 0x51, 0x8d, 0x70, 0x5e, 0x8e, 0xaa, 0x8f, 0xff, 0x56, + 0x52, 0xce, 0x43, 0x12, 0x29, 0xf9, 0x70, 0x3e, 0x46, 0x4a, 0xae, 0x9f, 0x40, 0x4f, 0x77, 0xf7, + 0xa5, 0x27, 0x37, 0xc9, 0xb4, 0x7e, 0x2e, 0x22, 0xaa, 0x1e, 0x81, 0xa3, 0xeb, 0xeb, 0xa7, 0x70, + 0x7e, 0x90, 0x70, 0xc3, 0x8a, 0xdf, 0x84, 0xf7, 0x64, 0xb0, 0x06, 0x6b, 0x1b, 0x0d, 0x4c, 0x1b, + 0xb1, 0xba, 0xcf, 0xcb, 0xad, 0xe7, 0xed, 0xc7, 0x98, 0x36, 0x82, 0x53, 0xff, 0x32, 0xe9, 0x9e, + 0xe9, 0x96, 0x69, 0x0b, 0xe6, 0x7a, 0xb9, 0x5b, 0xde, 0x70, 0xe3, 0x51, 0x77, 0xb6, 0x87, 0xba, + 0xd5, 0x5f, 0x67, 0xe0, 0x4c, 0xb2, 0xbb, 0x4d, 0xc8, 0x08, 0xa8, 0x70, 0x37, 0xb3, 0xe5, 0xbb, + 0xaf, 0xdf, 0x14, 0x4a, 0x96, 0xcd, 0x1a, 0xad, 0x6a, 0xd1, 0x74, 0x9b, 0x9a, 0x74, 0x6a, 0x36, + 0xb0, 0xed, 0x84, 0x3f, 0x34, 0xd6, 0xf1, 0x08, 0x2d, 0x96, 0x9f, 0x54, 0x6e, 0xaf, 0xdd, 0xaa, + 0xb4, 0xaa, 0x9f, 0x91, 0x8e, 0x7e, 0xbc, 0x1a, 0x80, 0x0b, 0x7d, 0x0e, 0x73, 0x11, 0xf8, 0x76, + 0x6c, 0x1a, 0x30, 0xf2, 0xe4, 0x21, 0xcc, 0xce, 0x48, 0xd4, 0x3e, 0xb5, 0x39, 0xb2, 0x67, 0x29, + 0xc3, 0x3e, 0x33, 0xe4, 0x19, 0x99, 0x14, 0x4c, 0xc7, 0xd7, 0xc4, 0x41, 0x42, 0x4b, 0x00, 0xc4, + 0xa9, 0x85, 0x02, 0x53, 0x5c, 0x60, 0x9a, 0x38, 0xf2, 0x9c, 0xa1, 0x45, 0x98, 0x66, 0x2e, 0xc3, + 0x3b, 0x06, 0xc5, 0x2c, 0x77, 0x9c, 0xef, 0x9e, 0xe4, 0x0b, 0x5b, 0x98, 0xa1, 0xcb, 0x30, 0x17, + 0x6f, 0x23, 0x69, 0xe7, 0x32, 0xbc, 0x83, 0xb3, 0x51, 0x07, 0x49, 0x1b, 0x5d, 0x81, 0x53, 0x74, + 0x07, 0xd3, 0x46, 0x4c, 0xec, 0x04, 0x17, 0xcb, 0x86, 0xcb, 0x42, 0xee, 0x0e, 0x9c, 0x8b, 0xa0, + 0xce, 0xb7, 0x0c, 0x6a, 0x5b, 0x5c, 0xfe, 0x24, 0x97, 0x5f, 0xe8, 0x6e, 0x6f, 0x05, 0xbb, 0x5b, + 0xb6, 0x15, 0xa8, 0xbd, 0x80, 0xac, 0xe9, 0xee, 0x12, 0x07, 0x3b, 0x2c, 0x90, 0xa7, 0xb9, 0x69, + 0x7e, 0x32, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0x5d, 0xaf, 0x61, 0x2f, 0xb0, 0x64, 0x5b, 0x0e, + 0x66, 0x2d, 0x9f, 0x50, 0x7d, 0x36, 0x34, 0xb3, 0x65, 0x5b, 0x14, 0xdd, 0x00, 0x14, 0xe6, 0xe6, + 0xb6, 0x98, 0xd7, 0x62, 0x86, 0x5d, 0x6b, 0xe7, 0x80, 0x7f, 0x55, 0x87, 0x08, 0x7d, 0xc6, 0x37, + 0x9e, 0xd4, 0xf8, 0x7d, 0x8a, 0x39, 0x33, 0xe7, 0x66, 0x2e, 0x2a, 0x2b, 0x27, 0x75, 0xf9, 0x0b, + 0x15, 0x60, 0x46, 0x7c, 0xc9, 0x18, 0x35, 0x42, 0xcd, 0xdc, 0xac, 0x20, 0x16, 0xb1, 0xb4, 0x41, + 0xa8, 0x89, 0xde, 0x87, 0xb9, 0x96, 0x53, 0x75, 0x9d, 0x1a, 0xaf, 0x8e, 0xdd, 0x24, 0xb9, 0x2c, + 0x77, 0x91, 0xed, 0xae, 0x3e, 0xb7, 0x9b, 0x04, 0x99, 0x70, 0xa6, 0xe5, 0x44, 0x08, 0x37, 0x7c, + 0x89, 0xc6, 0xdc, 0x1c, 0x87, 0x7a, 0x31, 0x1d, 0xea, 0x2f, 0x62, 0x6a, 0x5d, 0xb0, 0x2f, 0xb4, + 0x12, 0x56, 0x83, 0x58, 0xc4, 0x07, 0xbd, 0x11, 0x3e, 0x22, 0x4e, 0x89, 0x58, 0xc4, 0xaa, 0x7c, + 0x32, 0xa8, 0x5f, 0x4c, 0xc2, 0xb9, 0x14, 0xc3, 0x68, 0x05, 0xe6, 0x63, 0xe9, 0xb4, 0x63, 0xa7, + 0x3a, 0x4a, 0x53, 0x74, 0xfb, 0xbb, 0xb0, 0x18, 0x75, 0x3b, 0xd2, 0x09, 0x3b, 0x3e, 0xc1, 0x95, + 0x72, 0x5d, 0x91, 0x17, 0xa1, 0x84, 0xec, 0xba, 0x09, 0x8b, 0xdd, 0xae, 0xf7, 0x6a, 0xf3, 0x33, + 0x34, 0xc9, 0x31, 0x70, 0x39, 0xa5, 0x2c, 0xdd, 0xa6, 0x3f, 0x71, 0xea, 0xae, 0x9e, 0x0b, 0x0d, + 0xc5, 0x7d, 0xf0, 0xe3, 0x93, 0x80, 0xdc, 0xa9, 0x24, 0xe4, 0x7e, 0x04, 0xf9, 0x3e, 0xe4, 0xc6, + 0x53, 0x39, 0xce, 0x55, 0xce, 0xf5, 0x82, 0x37, 0xca, 0xa4, 0x0e, 0x67, 0x23, 0xfc, 0xc6, 0x74, + 0x69, 0x2e, 0x73, 0x40, 0x20, 0x2f, 0x74, 0x81, 0x1c, 0x79, 0xa2, 0xaa, 0x09, 0x85, 0x7d, 0x6e, + 0x05, 0xf4, 0x00, 0xa6, 0x6a, 0x64, 0xe7, 0x60, 0x9f, 0xbe, 0x5c, 0x53, 0xfd, 0xf3, 0x14, 0xe4, + 0x52, 0x5f, 0x23, 0x1f, 0xc3, 0x4c, 0x70, 0x0a, 0x7c, 0xdb, 0x8b, 0xb1, 0xf4, 0xb7, 0xc2, 0xcb, + 0x25, 0xf2, 0x20, 0x6e, 0x96, 0x8d, 0x48, 0x54, 0x8f, 0xeb, 0xa1, 0x4d, 0x00, 0xd3, 0x6d, 0x36, + 0x6d, 0x4a, 0xc3, 0x2b, 0x6a, 0xba, 0x7c, 0xf3, 0xf5, 0x9b, 0xc2, 0xa2, 0x30, 0x44, 0x6b, 0xdb, + 0x45, 0xdb, 0xd5, 0x9a, 0x98, 0x35, 0x8a, 0x4f, 0x89, 0x85, 0xcd, 0xce, 0x06, 0x31, 0xbf, 0xfe, + 0xe2, 0x26, 0x48, 0x3f, 0x1b, 0xc4, 0xd4, 0x63, 0x06, 0xd0, 0x3d, 0x00, 0x99, 0x67, 0xc0, 0xe9, + 0x93, 0x3c, 0xa8, 0x42, 0x18, 0x94, 0x18, 0x5a, 0x14, 0xbb, 0x43, 0x8b, 0xa2, 0x64, 0xd9, 0x69, + 0xa9, 0x52, 0xd9, 0x8e, 0xdd, 0x07, 0x53, 0x47, 0x71, 0x1f, 0x7c, 0x08, 0x93, 0x9e, 0xeb, 0x71, + 0xd0, 0xcc, 0x94, 0x56, 0xd2, 0x5e, 0xe1, 0xbe, 0xeb, 0xd6, 0x9f, 0xd5, 0x2b, 0x2e, 0xa5, 0x84, + 0x67, 0xa1, 0x07, 0x4a, 0x01, 0x5e, 0x9b, 0x98, 0x32, 0xe2, 0x1b, 0x5e, 0xab, 0x6a, 0xf8, 0xd8, + 0xa9, 0x49, 0x42, 0xce, 0x8a, 0xe5, 0x4a, 0xab, 0xaa, 0x63, 0xa7, 0x86, 0xd6, 0xe0, 0x2c, 0x47, + 0x1a, 0xa9, 0x19, 0x61, 0xea, 0x92, 0xff, 0x4f, 0x70, 0x86, 0x5f, 0x90, 0xbb, 0x65, 0xb1, 0x29, + 0xaf, 0x82, 0x80, 0x11, 0x43, 0x2d, 0x66, 0x86, 0x1a, 0x27, 0xb9, 0xc6, 0x7c, 0xa8, 0xc1, 0x4c, + 0x29, 0x1d, 0x7d, 0x98, 0x4d, 0x0f, 0xfd, 0xf8, 0x86, 0x81, 0x8f, 0xef, 0xd2, 0x6f, 0x4e, 0xc3, + 0x71, 0x7e, 0xdf, 0xa3, 0x9f, 0x29, 0x90, 0x11, 0x13, 0x07, 0x74, 0x2d, 0xa5, 0x14, 0x83, 0x83, + 0x97, 0xfc, 0xf5, 0x51, 0x44, 0x05, 0x26, 0xd5, 0xf7, 0x7f, 0xfa, 0xd7, 0x7f, 0xfe, 0x72, 0xa2, + 0x80, 0x96, 0xb4, 0x61, 0x03, 0x23, 0xf4, 0x7b, 0x05, 0x4e, 0xf5, 0x8d, 0x4e, 0x50, 0x69, 0x7f, + 0x37, 0xfd, 0x03, 0x9a, 0xfc, 0xed, 0xb1, 0x74, 0x64, 0x8c, 0x1a, 0x8f, 0xf1, 0x1a, 0xba, 0x3a, + 0x34, 0x46, 0xed, 0x95, 0x64, 0xed, 0x3d, 0xf4, 0x07, 0x05, 0x4e, 0x0f, 0x3c, 0x11, 0xd0, 0xda, + 0x30, 0xdf, 0x69, 0xa3, 0x9b, 0xfc, 0x9d, 0x31, 0xb5, 0x64, 0xcc, 0xab, 0x3c, 0xe6, 0x0f, 0xd0, + 0xb5, 0x94, 0x98, 0x07, 0x1f, 0x27, 0xe8, 0x6b, 0x05, 0xe6, 0xfb, 0x0d, 0xa2, 0xdb, 0xe3, 0xb8, + 0x0f, 0x63, 0x5e, 0x1b, 0x4f, 0x49, 0x86, 0xbc, 0xc5, 0x43, 0xde, 0x44, 0x9f, 0x8d, 0x1c, 0xb2, + 0xf6, 0xaa, 0xe7, 0xdd, 0xb0, 0x37, 0x28, 0x82, 0x7e, 0xab, 0xc0, 0x5c, 0xef, 0xcc, 0x01, 0xad, + 0x0e, 0x8b, 0x2e, 0x71, 0x94, 0x92, 0x2f, 0x8d, 0xa3, 0x22, 0xd3, 0x29, 0xf2, 0x74, 0x56, 0xd0, + 0x15, 0x2d, 0x75, 0xcc, 0x19, 0x7f, 0x50, 0xa0, 0x7f, 0x29, 0x50, 0xd8, 0xe7, 0x75, 0x89, 0xca, + 0xc3, 0xe2, 0x18, 0xed, 0xa9, 0x9c, 0x7f, 0x78, 0x28, 0x1b, 0x32, 0xb9, 0x0f, 0x79, 0x72, 0x6b, + 0xa8, 0x34, 0x46, 0xaf, 0x04, 0x01, 0xed, 0xa1, 0xff, 0x29, 0xb0, 0x34, 0x74, 0xbe, 0x81, 0x1e, + 0x8c, 0x83, 0x9f, 0xa4, 0x11, 0x4c, 0x7e, 0xfd, 0x10, 0x16, 0x64, 0x8a, 0x15, 0x9e, 0xe2, 0xa7, + 0xe8, 0xf1, 0xc1, 0xe1, 0xc8, 0x19, 0x36, 0x4a, 0xfc, 0x3f, 0x0a, 0x5c, 0x18, 0x36, 0x38, 0x41, + 0xf7, 0xc7, 0x89, 0x3a, 0x61, 0x82, 0x93, 0x7f, 0x70, 0x70, 0x03, 0x32, 0xeb, 0x47, 0x3c, 0xeb, + 0x75, 0x74, 0xff, 0x90, 0x59, 0x73, 0xc6, 0xee, 0x1b, 0x1a, 0x0c, 0x67, 0xec, 0xe4, 0x01, 0xc4, + 0x70, 0xc6, 0x4e, 0x99, 0x4a, 0xec, 0xcb, 0xd8, 0x38, 0xd4, 0x93, 0xb7, 0x28, 0xfa, 0xaf, 0x02, + 0x8b, 0x43, 0x46, 0x02, 0xe8, 0xde, 0x38, 0x85, 0x4d, 0x20, 0x90, 0xfb, 0x07, 0xd6, 0x97, 0x19, + 0x6d, 0xf2, 0x8c, 0x1e, 0xa1, 0x8f, 0x0f, 0xde, 0x97, 0x38, 0xd9, 0xfc, 0x51, 0x81, 0x6c, 0x0f, + 0x6f, 0xa1, 0x5b, 0x23, 0x53, 0x5c, 0x98, 0xd3, 0xea, 0x18, 0x1a, 0x32, 0x8b, 0x0d, 0x9e, 0xc5, + 0x3d, 0xf4, 0x9d, 0xd1, 0x38, 0x51, 0x7b, 0x95, 0x30, 0xa5, 0xd8, 0x2b, 0x3f, 0xfd, 0xf2, 0xed, + 0xb2, 0xf2, 0xd5, 0xdb, 0x65, 0xe5, 0x1f, 0x6f, 0x97, 0x95, 0x5f, 0xbc, 0x5b, 0x3e, 0xf6, 0xd5, + 0xbb, 0xe5, 0x63, 0x7f, 0x7f, 0xb7, 0x7c, 0xec, 0x87, 0xfb, 0x7e, 0xf7, 0xb5, 0xe3, 0x0e, 0xf9, + 0x47, 0x60, 0x35, 0xc3, 0xff, 0x87, 0x74, 0xfb, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xb0, + 0x98, 0x47, 0xb1, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3254,22 +3265,29 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error if m.VotingPower != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) i-- - dAtA[i] = 0x48 + dAtA[i] = 0x50 } if m.Height != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Height)) i-- - dAtA[i] = 0x40 + dAtA[i] = 0x48 } if m.SlashedBtcHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x40 } if m.SlashedBabylonHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x38 + } + if len(m.MasterPubRand) > 0 { + i -= len(m.MasterPubRand) + copy(dAtA[i:], m.MasterPubRand) + i = encodeVarintQuery(dAtA, i, uint64(len(m.MasterPubRand))) + i-- + dAtA[i] = 0x32 } if m.Pop != nil { { @@ -3799,6 +3817,10 @@ func (m *FinalityProviderResponse) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovQuery(uint64(l)) } + l = len(m.MasterPubRand) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovQuery(uint64(m.SlashedBabylonHeight)) } @@ -6785,6 +6807,38 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MasterPubRand = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -6803,7 +6857,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 7: + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -6822,7 +6876,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 8: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } @@ -6841,7 +6895,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 9: + case 10: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) } diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index e1c979153..e369fcca4 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -49,6 +49,8 @@ type MsgCreateFinalityProvider struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,5,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,6,opt,name=pop,proto3" json:"pop,omitempty"` + // master_pub_rand is the master public randomness of the finality provider + MasterPubRand string `protobuf:"bytes,7,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` } func (m *MsgCreateFinalityProvider) Reset() { *m = MsgCreateFinalityProvider{} } @@ -112,6 +114,13 @@ func (m *MsgCreateFinalityProvider) GetPop() *ProofOfPossession { return nil } +func (m *MsgCreateFinalityProvider) GetMasterPubRand() string { + if m != nil { + return m.MasterPubRand + } + return "" +} + // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider type MsgCreateFinalityProviderResponse struct { } @@ -870,88 +879,89 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1284 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0xdb, 0xc6, - 0x13, 0x35, 0x2d, 0x5b, 0xf9, 0x79, 0x64, 0xd9, 0xfe, 0x31, 0x8e, 0x43, 0xb3, 0x89, 0x24, 0x3b, - 0x69, 0xe2, 0x04, 0x35, 0x15, 0x3b, 0x8d, 0xd1, 0x26, 0x40, 0x81, 0xc8, 0x76, 0x90, 0xa0, 0x11, - 0x2a, 0x50, 0x76, 0x0f, 0xed, 0x41, 0xa0, 0xa8, 0x35, 0xb5, 0x90, 0xc4, 0x25, 0xb8, 0x6b, 0x41, - 0x42, 0x81, 0xa2, 0x08, 0x7a, 0x2d, 0xd0, 0x53, 0x0f, 0xbd, 0xf5, 0x1b, 0xe4, 0x90, 0x8f, 0xd0, - 0x43, 0x8e, 0x41, 0x4e, 0x85, 0x0b, 0x18, 0x45, 0x52, 0x20, 0x87, 0x9e, 0x7b, 0x2f, 0x48, 0x2e, - 0x97, 0xa4, 0x2a, 0x36, 0x76, 0x9c, 0x1b, 0x77, 0xf7, 0xcd, 0xcc, 0x9b, 0x37, 0xb3, 0x7f, 0x08, - 0x85, 0xa6, 0xd1, 0x1c, 0x76, 0x89, 0x5d, 0x6e, 0x32, 0x93, 0x32, 0xa3, 0x83, 0x6d, 0xab, 0xdc, - 0xdf, 0x28, 0xb3, 0x81, 0xe6, 0xb8, 0x84, 0x11, 0xf9, 0x02, 0x5f, 0xd7, 0xa2, 0x75, 0xad, 0xbf, - 0xa1, 0x2e, 0x5a, 0xc4, 0x22, 0x3e, 0xa2, 0xec, 0x7d, 0x05, 0x60, 0x75, 0xd9, 0x24, 0xb4, 0x47, - 0x68, 0x23, 0x58, 0x08, 0x06, 0x7c, 0xe9, 0x62, 0x30, 0x2a, 0xf7, 0xa8, 0xef, 0xbf, 0x47, 0x2d, - 0xbe, 0xb0, 0xca, 0x17, 0x4c, 0x77, 0xe8, 0x30, 0x52, 0xa6, 0xc8, 0x74, 0x36, 0xef, 0x6c, 0x75, - 0x36, 0xca, 0x1d, 0x34, 0x0c, 0x8d, 0x57, 0xc7, 0x93, 0x74, 0x0c, 0xd7, 0xe8, 0x85, 0x98, 0x8f, - 0x62, 0x18, 0xb3, 0x8d, 0xcc, 0x8e, 0x43, 0xb0, 0xcd, 0x3c, 0x58, 0x62, 0x82, 0xa3, 0xaf, 0xf2, - 0xa8, 0x91, 0xb7, 0x26, 0x62, 0xc6, 0x46, 0x38, 0xe6, 0xa8, 0x62, 0x4a, 0x5c, 0xe2, 0x04, 0x80, - 0xd5, 0x5f, 0x32, 0xb0, 0x5c, 0xa5, 0xd6, 0xb6, 0x8b, 0x0c, 0x86, 0x1e, 0x60, 0xdb, 0xe8, 0x62, - 0x36, 0xac, 0xb9, 0xa4, 0x8f, 0x5b, 0xc8, 0x95, 0x97, 0x20, 0x4b, 0xb1, 0x65, 0x23, 0x57, 0x91, - 0x4a, 0xd2, 0xda, 0x8c, 0xce, 0x47, 0xf2, 0x2e, 0xe4, 0x5a, 0x88, 0x9a, 0x2e, 0x76, 0x18, 0x26, - 0xb6, 0x32, 0x59, 0x92, 0xd6, 0x72, 0x9b, 0x57, 0x34, 0xae, 0x57, 0xa4, 0xb2, 0x4f, 0x49, 0xdb, - 0x89, 0xa0, 0x7a, 0xdc, 0x4e, 0xae, 0x02, 0x98, 0xa4, 0xd7, 0xc3, 0x94, 0x7a, 0x5e, 0x32, 0x5e, - 0x88, 0xca, 0xfa, 0xd1, 0x71, 0xf1, 0x83, 0xc0, 0x11, 0x6d, 0x75, 0x34, 0x4c, 0xca, 0x3d, 0x83, - 0xb5, 0xb5, 0xc7, 0xc8, 0x32, 0xcc, 0xe1, 0x0e, 0x32, 0x5f, 0x3e, 0x5b, 0x07, 0x1e, 0x67, 0x07, - 0x99, 0x7a, 0xcc, 0x81, 0xfc, 0x19, 0x00, 0x4f, 0xb7, 0xe1, 0x74, 0x94, 0x29, 0x9f, 0x54, 0x31, - 0x24, 0x15, 0x54, 0x47, 0x13, 0xd5, 0xd1, 0x6a, 0x87, 0xcd, 0xcf, 0xd1, 0x50, 0x9f, 0xe1, 0x26, - 0xb5, 0x8e, 0x5c, 0x85, 0x6c, 0x93, 0x99, 0x9e, 0xed, 0x74, 0x49, 0x5a, 0x9b, 0xad, 0x6c, 0x1d, - 0x1d, 0x17, 0x37, 0x2d, 0xcc, 0xda, 0x87, 0x4d, 0xcd, 0x24, 0xbd, 0x32, 0x47, 0x9a, 0x6d, 0x03, - 0xdb, 0xe1, 0xa0, 0xcc, 0x86, 0x0e, 0xa2, 0x5a, 0xe5, 0x51, 0xed, 0xf6, 0xc7, 0xb7, 0xb8, 0xcb, - 0xe9, 0x26, 0x33, 0x6b, 0x1d, 0xf9, 0x2e, 0x64, 0x1c, 0xe2, 0x28, 0x59, 0x9f, 0xc7, 0x9a, 0x36, - 0xb6, 0x0d, 0xb5, 0x9a, 0x4b, 0xc8, 0xc1, 0x17, 0x07, 0x35, 0x42, 0x29, 0xf2, 0xb3, 0xd0, 0x3d, - 0xa3, 0xbb, 0xb9, 0x27, 0x6f, 0x9e, 0xde, 0xe4, 0x6a, 0xaf, 0x5e, 0x81, 0x95, 0xd4, 0x12, 0xe9, - 0x88, 0x3a, 0xc4, 0xa6, 0x68, 0xf5, 0x2f, 0x09, 0x2e, 0x56, 0xa9, 0xb5, 0xdb, 0xc2, 0xec, 0xc4, - 0x65, 0xbc, 0x20, 0x12, 0xf6, 0x2a, 0x38, 0x1b, 0x12, 0x1f, 0xa9, 0x6e, 0xe6, 0xbd, 0x54, 0x77, - 0xea, 0x8c, 0xd5, 0x4d, 0x4a, 0xb2, 0x02, 0xc5, 0x94, 0x64, 0x85, 0x20, 0xbf, 0x9f, 0x83, 0x25, - 0x21, 0x5b, 0x65, 0x6f, 0x7b, 0x07, 0x75, 0x91, 0x65, 0xf8, 0xcc, 0xd2, 0xf4, 0x48, 0x36, 0xd0, - 0xe4, 0xa9, 0x1b, 0x88, 0x57, 0x3c, 0xf3, 0x0e, 0x15, 0x8f, 0x35, 0xdf, 0xd4, 0xfb, 0x68, 0xbe, - 0xaf, 0x61, 0xee, 0xc0, 0x69, 0x04, 0x1e, 0x1b, 0x5d, 0x4c, 0x99, 0x32, 0x5d, 0xca, 0x9c, 0xc1, - 0x6d, 0xee, 0xc0, 0xa9, 0x78, 0x8e, 0x1f, 0x63, 0xca, 0xe4, 0x15, 0x98, 0xe5, 0x09, 0x35, 0x18, - 0xee, 0x21, 0xbf, 0xc5, 0xf3, 0x7a, 0x8e, 0xcf, 0xed, 0xe1, 0x1e, 0x92, 0xaf, 0x40, 0x3e, 0x84, - 0xf4, 0x8d, 0xee, 0x21, 0x52, 0xce, 0x95, 0xa4, 0xb5, 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xcd, 0xc9, - 0x0f, 0x01, 0x84, 0x9f, 0x81, 0xf2, 0x3f, 0x5f, 0xb6, 0x1b, 0x71, 0xd9, 0x62, 0xa7, 0x5e, 0x7f, - 0x43, 0xdb, 0x73, 0x0d, 0x9b, 0x1a, 0xa6, 0x57, 0xc2, 0x47, 0xf6, 0x01, 0xd1, 0x67, 0xc2, 0x80, - 0x03, 0x79, 0x13, 0x72, 0xb4, 0x6b, 0xd0, 0x36, 0x77, 0x35, 0xe3, 0x4b, 0xf8, 0xff, 0xa3, 0xe3, - 0x62, 0xbe, 0xb2, 0xb7, 0x5d, 0xe7, 0x2b, 0x7b, 0x03, 0x1d, 0xa8, 0xf8, 0x96, 0x09, 0x2c, 0xb5, - 0x82, 0x9e, 0x20, 0x6e, 0x43, 0x58, 0x53, 0x6c, 0x29, 0xe0, 0x9b, 0x7f, 0x7a, 0x74, 0x5c, 0xbc, - 0x73, 0x1a, 0xa9, 0xea, 0xd8, 0xb2, 0x0d, 0x76, 0xe8, 0x22, 0x7d, 0x51, 0x38, 0x0e, 0x63, 0xd7, - 0xb1, 0x25, 0x7f, 0x08, 0x73, 0x87, 0x76, 0x93, 0xd8, 0x2d, 0x21, 0x5c, 0xce, 0x17, 0x2e, 0x2f, - 0x66, 0x7d, 0xe9, 0x56, 0x60, 0x36, 0x06, 0x1b, 0x28, 0xb3, 0xfe, 0xde, 0xcc, 0x45, 0xa0, 0x81, - 0x7c, 0x1d, 0xe6, 0x23, 0x48, 0xa0, 0x6f, 0xde, 0xd7, 0x37, 0x0a, 0x10, 0x28, 0xbc, 0x0b, 0x17, - 0x22, 0x60, 0x5c, 0xa1, 0xb9, 0x34, 0x85, 0xce, 0x0b, 0x7c, 0x34, 0x29, 0x3f, 0x91, 0xa0, 0x14, - 0x69, 0x35, 0xc6, 0xa3, 0xa7, 0xda, 0xfc, 0x59, 0x55, 0xbb, 0x2c, 0x42, 0xec, 0x8f, 0x72, 0xa8, - 0x63, 0x2b, 0x79, 0x00, 0x94, 0xa0, 0x30, 0x7e, 0x73, 0x8b, 0xfd, 0xff, 0xf7, 0x24, 0xc8, 0x55, - 0x6a, 0xdd, 0x6f, 0xb5, 0xb6, 0x49, 0x1f, 0xd9, 0x86, 0xcd, 0xea, 0xd8, 0xa2, 0xa9, 0x7b, 0xff, - 0x01, 0x4c, 0x86, 0xe7, 0xe0, 0x3b, 0x6f, 0x92, 0x49, 0xa7, 0x23, 0x5f, 0x83, 0xf9, 0xa8, 0xa7, - 0x1b, 0x6d, 0x83, 0xb6, 0x83, 0x8b, 0x4d, 0xcf, 0x8b, 0x6e, 0x7d, 0x68, 0xd0, 0xb6, 0xbc, 0x06, - 0x0b, 0xb1, 0x7a, 0x78, 0x02, 0x52, 0x65, 0xca, 0xdb, 0xa2, 0xfa, 0x5c, 0xd4, 0xa3, 0x3e, 0x63, - 0x13, 0x16, 0xe2, 0xfd, 0xe0, 0x6b, 0x3d, 0x7d, 0x56, 0xad, 0xe7, 0x62, 0xed, 0xe4, 0xf5, 0xe6, - 0x3d, 0x50, 0x05, 0x9d, 0xd1, 0x68, 0x54, 0xc9, 0xfa, 0xc4, 0x2e, 0x86, 0x88, 0xfd, 0x84, 0x2d, - 0x4d, 0x56, 0xe6, 0x12, 0xa8, 0xff, 0x96, 0x5d, 0x54, 0xe5, 0x57, 0x09, 0x16, 0xaa, 0xd4, 0xaa, - 0xec, 0x6d, 0xef, 0xdb, 0xbc, 0xdc, 0x28, 0xb5, 0x26, 0x63, 0xb4, 0x9c, 0x1c, 0xa7, 0xe5, 0x38, - 0x85, 0x32, 0xef, 0x59, 0xa1, 0x64, 0x92, 0x2a, 0x28, 0xa3, 0x59, 0x88, 0x14, 0x7f, 0x96, 0xe0, - 0x52, 0x95, 0x5a, 0x75, 0xd4, 0x45, 0x26, 0xc3, 0x7d, 0x14, 0xf6, 0xf0, 0xae, 0x77, 0x3f, 0xd9, - 0xe6, 0xd9, 0xd3, 0x5d, 0x87, 0xf3, 0x2e, 0x32, 0x49, 0x1f, 0xb9, 0xa8, 0xd5, 0xe0, 0xa7, 0x3c, - 0xed, 0x04, 0x19, 0xeb, 0x0b, 0x62, 0xe9, 0x81, 0x77, 0x62, 0xd7, 0x3b, 0x49, 0xe2, 0xd7, 0xe0, - 0xea, 0x7f, 0x71, 0x13, 0x49, 0xfc, 0x24, 0xc1, 0x7c, 0x95, 0x5a, 0xfb, 0x4e, 0xcb, 0x60, 0xa8, - 0xe6, 0x3f, 0x53, 0xe5, 0x2d, 0x98, 0x31, 0x0e, 0x59, 0x9b, 0xb8, 0x98, 0x0d, 0x03, 0xea, 0x15, - 0xe5, 0xe5, 0xb3, 0xf5, 0x45, 0x7e, 0x41, 0xde, 0x6f, 0xb5, 0x5c, 0x44, 0x69, 0x9d, 0xb9, 0xd8, - 0xb6, 0xf4, 0x08, 0x2a, 0xdf, 0x83, 0x6c, 0xf0, 0xd0, 0xe5, 0x57, 0xea, 0xe5, 0xb4, 0x9b, 0xd1, - 0x07, 0x55, 0xa6, 0x9e, 0x1f, 0x17, 0x27, 0x74, 0x6e, 0x72, 0x77, 0xce, 0x63, 0x1f, 0x39, 0x5b, - 0x5d, 0xf6, 0x9f, 0x39, 0x71, 0x5e, 0x21, 0xe7, 0xcd, 0x3f, 0xb3, 0x90, 0xa9, 0x52, 0x4b, 0xfe, - 0x5e, 0x82, 0xa5, 0x94, 0x07, 0xed, 0xad, 0x94, 0xd0, 0xa9, 0xef, 0x2b, 0xf5, 0x93, 0xd3, 0x5a, - 0x84, 0x74, 0xe4, 0x6f, 0x61, 0x71, 0xec, 0x6b, 0x4c, 0x4b, 0xf7, 0x38, 0x0e, 0xaf, 0x6e, 0x9d, - 0x0e, 0x2f, 0xe2, 0x7f, 0x03, 0xe7, 0xc7, 0x3d, 0x7e, 0xd6, 0xdf, 0x96, 0x50, 0x02, 0xae, 0xde, - 0x39, 0x15, 0x5c, 0x04, 0x27, 0x30, 0x3f, 0x7a, 0xf2, 0xde, 0x48, 0xf7, 0x34, 0x02, 0x55, 0x37, - 0x4e, 0x0c, 0x15, 0x01, 0x31, 0xe4, 0x93, 0x87, 0xca, 0xf5, 0x74, 0x1f, 0x09, 0xa0, 0x5a, 0x3e, - 0x21, 0x50, 0x84, 0xfa, 0x41, 0x82, 0xe5, 0xf4, 0xdd, 0x7d, 0x3b, 0xdd, 0x5d, 0xaa, 0x91, 0x7a, - 0xef, 0x1d, 0x8c, 0x04, 0x9f, 0x03, 0x98, 0x4d, 0xec, 0xd3, 0x6b, 0xe9, 0xce, 0xe2, 0x38, 0x55, - 0x3b, 0x19, 0x2e, 0x8c, 0xa3, 0x4e, 0x7f, 0xf7, 0xe6, 0xe9, 0x4d, 0xa9, 0xf2, 0xf8, 0xf9, 0xab, - 0x82, 0xf4, 0xe2, 0x55, 0x41, 0xfa, 0xe3, 0x55, 0x41, 0xfa, 0xf1, 0x75, 0x61, 0xe2, 0xc5, 0xeb, - 0xc2, 0xc4, 0x6f, 0xaf, 0x0b, 0x13, 0x5f, 0xbd, 0xf5, 0xce, 0x1c, 0xc4, 0xff, 0x43, 0xfd, 0x63, - 0xb7, 0x99, 0xf5, 0xff, 0x43, 0x6f, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xd3, 0xc8, 0xf6, - 0xc7, 0x0f, 0x00, 0x00, + // 1307 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x13, 0xc7, + 0x1b, 0xce, 0xc6, 0x89, 0xf9, 0xe5, 0x75, 0x9c, 0xe4, 0xb7, 0x84, 0xb0, 0xd9, 0x82, 0x9d, 0x04, + 0x0a, 0x01, 0x35, 0x6b, 0x12, 0x4a, 0xd4, 0x82, 0x54, 0x09, 0x27, 0x41, 0xa0, 0x62, 0xd5, 0x5a, + 0x27, 0x3d, 0xb4, 0x07, 0x6b, 0xbd, 0x3b, 0x59, 0x8f, 0x6c, 0xef, 0xac, 0x76, 0xc6, 0x96, 0xad, + 0x4a, 0x55, 0x85, 0x7a, 0xad, 0xd4, 0x53, 0x0f, 0xfd, 0x14, 0x1c, 0xf8, 0x08, 0x3d, 0xd0, 0x1b, + 0xe2, 0x54, 0xa5, 0x52, 0x54, 0x41, 0x25, 0x0e, 0x3d, 0xf7, 0x5e, 0xed, 0xec, 0xec, 0x1f, 0xbb, + 0xde, 0x92, 0x10, 0x6e, 0xde, 0x99, 0xe7, 0xfd, 0xf7, 0xbc, 0xcf, 0xbc, 0x33, 0x86, 0x42, 0xc3, + 0x68, 0x0c, 0xda, 0xc4, 0x29, 0x35, 0x98, 0x49, 0x99, 0xd1, 0xc2, 0x8e, 0x5d, 0xea, 0x6d, 0x96, + 0x58, 0x5f, 0x73, 0x3d, 0xc2, 0x88, 0x7c, 0x41, 0xec, 0x6b, 0xf1, 0xbe, 0xd6, 0xdb, 0x54, 0x17, + 0x6d, 0x62, 0x13, 0x8e, 0x28, 0xf9, 0xbf, 0x02, 0xb0, 0xba, 0x6c, 0x12, 0xda, 0x21, 0xb4, 0x1e, + 0x6c, 0x04, 0x1f, 0x62, 0xeb, 0x62, 0xf0, 0x55, 0xea, 0x50, 0xee, 0xbf, 0x43, 0x6d, 0xb1, 0xb1, + 0x26, 0x36, 0x4c, 0x6f, 0xe0, 0x32, 0x52, 0xa2, 0xc8, 0x74, 0xb7, 0xee, 0x6c, 0xb7, 0x36, 0x4b, + 0x2d, 0x34, 0x08, 0x8d, 0xd7, 0xc6, 0x27, 0xe9, 0x1a, 0x9e, 0xd1, 0x09, 0x31, 0x1f, 0x25, 0x30, + 0x66, 0x13, 0x99, 0x2d, 0x97, 0x60, 0x87, 0xf9, 0xb0, 0xa1, 0x05, 0x81, 0xbe, 0x2a, 0xa2, 0xc6, + 0xde, 0x1a, 0x88, 0x19, 0x9b, 0xe1, 0xb7, 0x40, 0x15, 0x53, 0xe2, 0x12, 0x37, 0x00, 0xac, 0xfd, + 0x9a, 0x81, 0xe5, 0x0a, 0xb5, 0x77, 0x3c, 0x64, 0x30, 0xf4, 0x00, 0x3b, 0x46, 0x1b, 0xb3, 0x41, + 0xd5, 0x23, 0x3d, 0x6c, 0x21, 0x4f, 0x5e, 0x82, 0x2c, 0xc5, 0xb6, 0x83, 0x3c, 0x45, 0x5a, 0x91, + 0xd6, 0x67, 0x74, 0xf1, 0x25, 0xef, 0x41, 0xce, 0x42, 0xd4, 0xf4, 0xb0, 0xcb, 0x30, 0x71, 0x94, + 0xc9, 0x15, 0x69, 0x3d, 0xb7, 0x75, 0x45, 0x13, 0x7c, 0xc5, 0x2c, 0xf3, 0x94, 0xb4, 0xdd, 0x18, + 0xaa, 0x27, 0xed, 0xe4, 0x0a, 0x80, 0x49, 0x3a, 0x1d, 0x4c, 0xa9, 0xef, 0x25, 0xe3, 0x87, 0x28, + 0x6f, 0x1c, 0x1d, 0x17, 0x3f, 0x08, 0x1c, 0x51, 0xab, 0xa5, 0x61, 0x52, 0xea, 0x18, 0xac, 0xa9, + 0x3d, 0x46, 0xb6, 0x61, 0x0e, 0x76, 0x91, 0xf9, 0xf2, 0xd9, 0x06, 0x88, 0x38, 0xbb, 0xc8, 0xd4, + 0x13, 0x0e, 0xe4, 0xcf, 0x00, 0x44, 0xb9, 0x75, 0xb7, 0xa5, 0x4c, 0xf1, 0xa4, 0x8a, 0x61, 0x52, + 0x41, 0x77, 0xb4, 0xa8, 0x3b, 0x5a, 0xb5, 0xdb, 0xf8, 0x1c, 0x0d, 0xf4, 0x19, 0x61, 0x52, 0x6d, + 0xc9, 0x15, 0xc8, 0x36, 0x98, 0xe9, 0xdb, 0x4e, 0xaf, 0x48, 0xeb, 0xb3, 0xe5, 0xed, 0xa3, 0xe3, + 0xe2, 0x96, 0x8d, 0x59, 0xb3, 0xdb, 0xd0, 0x4c, 0xd2, 0x29, 0x09, 0xa4, 0xd9, 0x34, 0xb0, 0x13, + 0x7e, 0x94, 0xd8, 0xc0, 0x45, 0x54, 0x2b, 0x3f, 0xaa, 0xde, 0xfe, 0xf8, 0x96, 0x70, 0x39, 0xdd, + 0x60, 0x66, 0xb5, 0x25, 0xdf, 0x85, 0x8c, 0x4b, 0x5c, 0x25, 0xcb, 0xf3, 0x58, 0xd7, 0xc6, 0xca, + 0x50, 0xab, 0x7a, 0x84, 0x1c, 0x7e, 0x71, 0x58, 0x25, 0x94, 0x22, 0x5e, 0x85, 0xee, 0x1b, 0xc9, + 0xd7, 0x60, 0xbe, 0x63, 0x50, 0x86, 0xbc, 0xba, 0xdb, 0x6d, 0xd4, 0x3d, 0xc3, 0xb1, 0x94, 0x73, + 0xbc, 0x03, 0xf9, 0x60, 0xb9, 0xda, 0x6d, 0xe8, 0x86, 0x63, 0xdd, 0xcd, 0x3d, 0x79, 0xf3, 0xf4, + 0xa6, 0xe8, 0xca, 0xda, 0x15, 0x58, 0x4d, 0x6d, 0xa5, 0x8e, 0xa8, 0x4b, 0x1c, 0x8a, 0xd6, 0xfe, + 0x92, 0xe0, 0x62, 0x85, 0xda, 0x7b, 0x16, 0x66, 0x27, 0x6e, 0xf7, 0x85, 0x88, 0x18, 0xbf, 0xd3, + 0xb3, 0x61, 0x81, 0x23, 0x2a, 0xc8, 0xbc, 0x17, 0x15, 0x4c, 0x9d, 0x51, 0x05, 0xc3, 0x94, 0xac, + 0x42, 0x31, 0xa5, 0xd8, 0x88, 0x90, 0xdf, 0xcf, 0xc1, 0x52, 0x44, 0x5b, 0x79, 0x7f, 0x67, 0x17, + 0xb5, 0x91, 0x6d, 0xf0, 0xcc, 0xd2, 0xf8, 0x18, 0x16, 0xda, 0xe4, 0xa9, 0x85, 0x26, 0x94, 0x91, + 0x79, 0x17, 0x65, 0xc4, 0x22, 0x9d, 0x7a, 0x1f, 0x22, 0xfd, 0x1a, 0xe6, 0x0e, 0xdd, 0x7a, 0xe0, + 0xb1, 0xde, 0xc6, 0x94, 0x29, 0xd3, 0x2b, 0x99, 0x33, 0xb8, 0xcd, 0x1d, 0xba, 0x65, 0xdf, 0xf1, + 0x63, 0x4c, 0x99, 0xbc, 0x0a, 0xb3, 0xa2, 0xa0, 0x3a, 0xc3, 0x1d, 0xc4, 0x8f, 0x42, 0x5e, 0xcf, + 0x89, 0xb5, 0x7d, 0xdc, 0x41, 0xf2, 0x15, 0xc8, 0x87, 0x90, 0x9e, 0xd1, 0xee, 0x22, 0x2e, 0xf3, + 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xaf, 0xc9, 0x0f, 0x01, 0x22, 0x3f, 0x7d, 0xe5, 0x7f, 0x9c, 0xb6, + 0x1b, 0x49, 0xda, 0x12, 0xd3, 0xb1, 0xb7, 0xa9, 0xed, 0x7b, 0x86, 0x43, 0x0d, 0xd3, 0x6f, 0xe1, + 0x23, 0xe7, 0x90, 0xe8, 0x33, 0x61, 0xc0, 0xbe, 0xbc, 0x05, 0x39, 0xda, 0x36, 0x68, 0x53, 0xb8, + 0x9a, 0xe1, 0x14, 0xfe, 0xff, 0xe8, 0xb8, 0x98, 0x2f, 0xef, 0xef, 0xd4, 0xc4, 0xce, 0x7e, 0x5f, + 0x07, 0x1a, 0xfd, 0x96, 0x09, 0x2c, 0x59, 0x81, 0x26, 0x88, 0x57, 0x8f, 0xac, 0x29, 0xb6, 0x15, + 0xe0, 0xe6, 0x9f, 0x1e, 0x1d, 0x17, 0xef, 0x9c, 0x86, 0xaa, 0x1a, 0xb6, 0x1d, 0x83, 0x75, 0x3d, + 0xa4, 0x2f, 0x46, 0x8e, 0xc3, 0xd8, 0x35, 0x6c, 0xcb, 0x1f, 0xc2, 0x5c, 0xd7, 0x69, 0x10, 0xc7, + 0x8a, 0x88, 0xcb, 0x71, 0xe2, 0xf2, 0xd1, 0x2a, 0xa7, 0x6e, 0x15, 0x66, 0x13, 0xb0, 0xbe, 0x32, + 0xcb, 0xcf, 0x66, 0x2e, 0x06, 0xf5, 0xe5, 0xeb, 0x30, 0x1f, 0x43, 0x02, 0x7e, 0xf3, 0x9c, 0xdf, + 0x38, 0x40, 0xc0, 0xf0, 0x1e, 0x5c, 0x88, 0x81, 0x49, 0x86, 0xe6, 0xd2, 0x18, 0x3a, 0x1f, 0xe1, + 0xe3, 0x45, 0xf9, 0x89, 0x04, 0x2b, 0x31, 0x57, 0x63, 0x3c, 0xfa, 0xac, 0xcd, 0x9f, 0x95, 0xb5, + 0xcb, 0x51, 0x88, 0x83, 0xd1, 0x1c, 0x6a, 0xd8, 0x1e, 0x1e, 0x00, 0x2b, 0x50, 0x18, 0x7f, 0xb8, + 0xa3, 0xf3, 0xff, 0xf7, 0x24, 0xc8, 0x15, 0x6a, 0xdf, 0xb7, 0xac, 0x1d, 0xd2, 0x43, 0x8e, 0xe1, + 0xb0, 0x1a, 0xb6, 0x69, 0xea, 0xd9, 0x7f, 0x00, 0x93, 0xe1, 0x1c, 0x7c, 0xe7, 0x43, 0x32, 0xe9, + 0xb6, 0xfc, 0x09, 0x1f, 0x6b, 0xba, 0xde, 0x34, 0x68, 0x33, 0xb8, 0x00, 0xf5, 0x7c, 0xa4, 0xd6, + 0x87, 0x06, 0x6d, 0xca, 0xeb, 0xb0, 0x90, 0xe8, 0x87, 0x4f, 0x20, 0x55, 0xa6, 0xfc, 0x23, 0xaa, + 0xcf, 0xc5, 0x1a, 0xe5, 0x19, 0x9b, 0xb0, 0x90, 0xd4, 0x03, 0xe7, 0x7a, 0xfa, 0xac, 0x5c, 0xcf, + 0x25, 0xe4, 0xe4, 0x6b, 0xf3, 0x1e, 0xa8, 0x51, 0x3a, 0xa3, 0xd1, 0xa8, 0x92, 0xe5, 0x89, 0x5d, + 0x0c, 0x11, 0x07, 0x43, 0xb6, 0x74, 0xb8, 0x33, 0x97, 0x40, 0xfd, 0x37, 0xed, 0x51, 0x57, 0x7e, + 0x91, 0x60, 0xa1, 0x42, 0xed, 0xf2, 0xfe, 0xce, 0x81, 0x23, 0xda, 0x8d, 0x52, 0x7b, 0x32, 0x86, + 0xcb, 0xc9, 0x71, 0x5c, 0x8e, 0x63, 0x28, 0xf3, 0x9e, 0x19, 0x1a, 0x2e, 0x52, 0x05, 0x65, 0xb4, + 0x8a, 0xa8, 0xc4, 0x9f, 0x25, 0xb8, 0x54, 0xa1, 0x76, 0x0d, 0xb5, 0x91, 0xc9, 0x70, 0x0f, 0x85, + 0x1a, 0xde, 0xf3, 0xef, 0x27, 0xc7, 0x3c, 0x7b, 0xb9, 0x1b, 0x70, 0xde, 0x43, 0x26, 0xe9, 0x21, + 0x0f, 0x59, 0x75, 0x31, 0xe5, 0x69, 0x2b, 0xa8, 0x58, 0x5f, 0x88, 0xb6, 0x1e, 0xf8, 0x13, 0xbb, + 0xd6, 0x1a, 0x4e, 0xfc, 0x1a, 0x5c, 0xfd, 0xaf, 0xdc, 0xa2, 0x22, 0x7e, 0x92, 0x60, 0xbe, 0x42, + 0xed, 0x03, 0xd7, 0x32, 0x18, 0xaa, 0xf2, 0xe7, 0xac, 0xbc, 0x0d, 0x33, 0x46, 0x97, 0x35, 0x89, + 0x87, 0xd9, 0x20, 0x48, 0xbd, 0xac, 0xbc, 0x7c, 0xb6, 0xb1, 0x28, 0x2e, 0xc8, 0xfb, 0x96, 0xe5, + 0x21, 0x4a, 0x6b, 0xcc, 0xc3, 0x8e, 0xad, 0xc7, 0x50, 0xf9, 0x1e, 0x64, 0x83, 0x07, 0xb1, 0xb8, + 0x52, 0x2f, 0xa7, 0xdd, 0x8c, 0x1c, 0x54, 0x9e, 0x7a, 0x7e, 0x5c, 0x9c, 0xd0, 0x85, 0xc9, 0xdd, + 0x39, 0x3f, 0xfb, 0xd8, 0xd9, 0xda, 0x32, 0x7f, 0xe6, 0x24, 0xf3, 0x0a, 0x73, 0xde, 0xfa, 0x33, + 0x0b, 0x99, 0x0a, 0xb5, 0xe5, 0xef, 0x25, 0x58, 0x4a, 0x79, 0xf8, 0xde, 0x4a, 0x09, 0x9d, 0xfa, + 0xbe, 0x52, 0x3f, 0x39, 0xad, 0x45, 0x98, 0x8e, 0xfc, 0x2d, 0x2c, 0x8e, 0x7d, 0x8d, 0x69, 0xe9, + 0x1e, 0xc7, 0xe1, 0xd5, 0xed, 0xd3, 0xe1, 0xa3, 0xf8, 0xdf, 0xc0, 0xf9, 0x71, 0x8f, 0x9f, 0x8d, + 0xb7, 0x15, 0x34, 0x04, 0x57, 0xef, 0x9c, 0x0a, 0x1e, 0x05, 0x27, 0x30, 0x3f, 0x3a, 0x79, 0x6f, + 0xa4, 0x7b, 0x1a, 0x81, 0xaa, 0x9b, 0x27, 0x86, 0x46, 0x01, 0x31, 0xe4, 0x87, 0x87, 0xca, 0xf5, + 0x74, 0x1f, 0x43, 0x40, 0xb5, 0x74, 0x42, 0x60, 0x14, 0xea, 0x07, 0x09, 0x96, 0xd3, 0x4f, 0xf7, + 0xed, 0x74, 0x77, 0xa9, 0x46, 0xea, 0xbd, 0x77, 0x30, 0x8a, 0xf2, 0x39, 0x84, 0xd9, 0xa1, 0x73, + 0x7a, 0x2d, 0xdd, 0x59, 0x12, 0xa7, 0x6a, 0x27, 0xc3, 0x85, 0x71, 0xd4, 0xe9, 0xef, 0xde, 0x3c, + 0xbd, 0x29, 0x95, 0x1f, 0x3f, 0x7f, 0x55, 0x90, 0x5e, 0xbc, 0x2a, 0x48, 0x7f, 0xbc, 0x2a, 0x48, + 0x3f, 0xbe, 0x2e, 0x4c, 0xbc, 0x78, 0x5d, 0x98, 0xf8, 0xed, 0x75, 0x61, 0xe2, 0xab, 0xb7, 0xde, + 0x99, 0xfd, 0xe4, 0xff, 0x55, 0x3e, 0x76, 0x1b, 0x59, 0xfe, 0x7f, 0xf5, 0xf6, 0x3f, 0x01, 0x00, + 0x00, 0xff, 0xff, 0xa3, 0xb5, 0x5f, 0xec, 0xef, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1286,6 +1296,13 @@ func (m *MsgCreateFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l + if len(m.MasterPubRand) > 0 { + i -= len(m.MasterPubRand) + copy(dAtA[i:], m.MasterPubRand) + i = encodeVarintTx(dAtA, i, uint64(len(m.MasterPubRand))) + i-- + dAtA[i] = 0x3a + } if m.Pop != nil { { size, err := m.Pop.MarshalToSizedBuffer(dAtA[:i]) @@ -1998,6 +2015,10 @@ func (m *MsgCreateFinalityProvider) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovTx(uint64(l)) } + l = len(m.MasterPubRand) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -2496,6 +2517,38 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MasterPubRand = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index f5b910389..e3a08fdad 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -177,6 +177,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal } // CommitPubRandList commits a list of EOTS public randomness +// TODO: replace with BIP-32 randomness derivation func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommitPubRandList) (*types.MsgCommitPubRandListResponse, error) { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCommitPubRandList) diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 275f0da8f..af417f9c6 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -7,6 +7,7 @@ import ( "time" "cosmossdk.io/core/header" + "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -114,8 +115,13 @@ func FuzzAddFinalitySig(f *testing.F) { // create and register a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, btcSK) + fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) require.NoError(t, err) + msr, _, err := eots.NewMasterRandPair(r) + require.NoError(t, err) + fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) + require.NoError(t, err) + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() require.NoError(t, err) @@ -218,11 +224,17 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { bsKeeper := types.NewMockBTCStakingKeeper(ctrl) fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) ms := keeper.NewMsgServerImpl(*fKeeper) + // create and register a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, btcSK) + fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) require.NoError(t, err) + msr, _, err := eots.NewMasterRandPair(r) + require.NoError(t, err) + fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) + require.NoError(t, err) + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() require.NoError(t, err) diff --git a/x/finality/keeper/votes_bench_test.go b/x/finality/keeper/votes_bench_test.go index c22a6cba4..3055bf25d 100644 --- a/x/finality/keeper/votes_bench_test.go +++ b/x/finality/keeper/votes_bench_test.go @@ -8,6 +8,7 @@ import ( "time" "cosmossdk.io/core/header" + "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -29,10 +30,15 @@ func benchmarkAddFinalitySig(b *testing.B) { // create a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(b, err) + fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) + require.NoError(b, err) + msr, _, err := eots.NewMasterRandPair(r) + require.NoError(b, err) + fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) + require.NoError(b, err) + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() - fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, btcSK) - require.NoError(b, err) // register the finality provider bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() From b27b6082fb8df1fa3367d09dcac9f85650e85751 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 27 Mar 2024 20:11:31 +1100 Subject: [PATCH 065/119] finality: replacing committed public randomness with derived ones (#595) --- cmd/babylond/cmd/flags.go | 6 - cmd/babylond/cmd/genesis.go | 6 +- cmd/babylond/cmd/testnet.go | 3 +- crypto/eots/randomness.go | 25 +- proto/babylon/btcstaking/v1/btcstaking.proto | 2 + proto/babylon/btcstaking/v1/query.proto | 1 + proto/babylon/btcstaking/v1/tx.proto | 1 + proto/babylon/finality/v1/finality.proto | 5 +- proto/babylon/finality/v1/genesis.proto | 12 - proto/babylon/finality/v1/params.proto | 4 - proto/babylon/finality/v1/query.proto | 27 - proto/babylon/finality/v1/tx.proto | 23 - test/e2e/btc_staking_e2e_test.go | 36 +- .../configurer/chain/commands_btcstaking.go | 34 - .../configurer/chain/queries_btcstaking.go | 13 - testutil/datagen/finality.go | 48 +- types/btc_schnorr_pub_rand.go | 76 -- types/btc_schnorr_pub_rand_test.go | 35 - x/btcstaking/types/btcstaking.go | 18 + x/btcstaking/types/btcstaking.pb.go | 2 + x/btcstaking/types/query.pb.go | 1 + x/btcstaking/types/tx.pb.go | 1 + x/finality/client/cli/query.go | 34 - x/finality/client/cli/tx.go | 61 -- x/finality/keeper/genesis.go | 69 +- x/finality/keeper/genesis_test.go | 22 +- x/finality/keeper/grpc_query.go | 35 - x/finality/keeper/grpc_query_test.go | 39 - x/finality/keeper/msg_server.go | 60 +- x/finality/keeper/msg_server_test.go | 111 +-- x/finality/keeper/public_randomness.go | 89 --- .../keeper/public_randomness_bench_test.go | 69 -- x/finality/keeper/votes_bench_test.go | 10 +- x/finality/types/codec.go | 2 - x/finality/types/finality.go | 14 +- x/finality/types/finality.pb.go | 102 +-- x/finality/types/genesis.pb.go | 385 +-------- x/finality/types/genesis_test.go | 4 +- x/finality/types/keys.go | 7 +- x/finality/types/metrics.go | 3 +- x/finality/types/msg.go | 45 +- x/finality/types/msg_test.go | 28 +- x/finality/types/params.go | 15 +- x/finality/types/params.pb.go | 53 +- x/finality/types/query.pb.go | 752 ++---------------- x/finality/types/query.pb.gw.go | 119 --- x/finality/types/tx.pb.go | 613 +------------- 47 files changed, 307 insertions(+), 2813 deletions(-) delete mode 100644 types/btc_schnorr_pub_rand.go delete mode 100644 types/btc_schnorr_pub_rand_test.go delete mode 100644 x/finality/keeper/public_randomness.go delete mode 100644 x/finality/keeper/public_randomness_bench_test.go diff --git a/cmd/babylond/cmd/flags.go b/cmd/babylond/cmd/flags.go index 70f7fc109..3d154b980 100644 --- a/cmd/babylond/cmd/flags.go +++ b/cmd/babylond/cmd/flags.go @@ -41,7 +41,6 @@ const ( flagSlashingAddress = "slashing-address" flagMinSlashingFee = "min-slashing-fee-sat" flagSlashingRate = "slashing-rate" - flagMinPubRand = "min-pub-rand" flagMinCommissionRate = "min-commission-rate" ) @@ -71,7 +70,6 @@ type GenesisCLIArgs struct { MaxActiveFinalityProviders uint32 MinUnbondingTime uint16 MinUnbondingRate math.LegacyDec - MinPubRand uint64 MinCommissionRate math.LegacyDec } @@ -100,8 +98,6 @@ func addGenesisFlags(cmd *cobra.Command) { cmd.Flags().Uint32(flagMaxActiveFinalityProviders, 100, "Bitcoin staking maximum active finality providers") cmd.Flags().Uint16(flagMinUnbondingTime, 0, "Min timelock on unbonding transaction in btc blocks") cmd.Flags().String(flagMinUnbondingRate, "0.8", "Min amount of btc required in unbonding output expressed as a fraction of staking output") - // finality args - cmd.Flags().Uint64(flagMinPubRand, 100, "Bitcoin staking minimum public randomness commit") // inflation args cmd.Flags().Float64(flagInflationRateChange, 0.13, "Inflation rate change") cmd.Flags().Float64(flagInflationMax, 0.2, "Maximum inflation") @@ -134,7 +130,6 @@ func parseGenesisFlags(cmd *cobra.Command) *GenesisCLIArgs { maxActiveFinalityProviders, _ := cmd.Flags().GetUint32(flagMaxActiveFinalityProviders) minUnbondingTime, _ := cmd.Flags().GetUint16(flagMinUnbondingTime) minUnbondingRate, _ := cmd.Flags().GetString(flagMinUnbondingRate) - minPubRand, _ := cmd.Flags().GetUint64(flagMinPubRand) genesisTimeUnix, _ := cmd.Flags().GetInt64(flagGenesisTime) inflationRateChange, _ := cmd.Flags().GetFloat64(flagInflationRateChange) inflationMax, _ := cmd.Flags().GetFloat64(flagInflationMax) @@ -174,7 +169,6 @@ func parseGenesisFlags(cmd *cobra.Command) *GenesisCLIArgs { MaxActiveFinalityProviders: maxActiveFinalityProviders, MinUnbondingTime: minUnbondingTime, MinUnbondingRate: math.LegacyMustNewDecFromStr(minUnbondingRate), - MinPubRand: minPubRand, GenesisTime: genesisTime, InflationRateChange: inflationRateChange, InflationMax: inflationMax, diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 0c8d84319..8d7d6cb93 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -75,7 +75,7 @@ Example: genesisCliArgs.CovenantPKs, genesisCliArgs.CovenantQuorum, genesisCliArgs.SlashingAddress, genesisCliArgs.MinSlashingTransactionFeeSat, genesisCliArgs.MinCommissionRate, genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, - genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, genesisCliArgs.MinPubRand, genesisCliArgs.InflationRateChange, + genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, genesisCliArgs.InflationRateChange, genesisCliArgs.InflationMin, genesisCliArgs.InflationMax, genesisCliArgs.GoalBonded, genesisCliArgs.BlocksPerYear, genesisCliArgs.GenesisTime, genesisCliArgs.BlockGasLimit, genesisCliArgs.VoteExtensionEnableHeight) } else if network == "mainnet" { @@ -241,8 +241,7 @@ type GenesisParams struct { func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint64, btcFinalizationTimeout uint64, checkpointTag string, epochInterval uint64, baseBtcHeaderHex string, baseBtcHeaderHeight uint64, allowedReporters []string, covenantPKs []string, covenantQuorum uint32, slashingAddress string, minSlashingFee int64, - minCommissionRate sdkmath.LegacyDec, slashingRate sdkmath.LegacyDec, maxActiveFinalityProviders uint32, minUnbondingTime uint16, minUnbondingRate sdkmath.LegacyDec, - minPubRand uint64, inflationRateChange float64, + minCommissionRate sdkmath.LegacyDec, slashingRate sdkmath.LegacyDec, maxActiveFinalityProviders uint32, minUnbondingTime uint16, minUnbondingRate sdkmath.LegacyDec, inflationRateChange float64, inflationMin float64, inflationMax float64, goalBonded float64, blocksPerYear uint64, genesisTime time.Time, blockGasLimit int64, voteExtensionEnableHeight int64) GenesisParams { @@ -351,7 +350,6 @@ func TestnetGenesisParams(maxActiveValidators uint32, btcConfirmationDepth uint6 } genParams.FinalityParams = finalitytypes.DefaultParams() - genParams.FinalityParams.MinPubRand = minPubRand if err := genParams.FinalityParams.Validate(); err != nil { panic(err) } diff --git a/cmd/babylond/cmd/testnet.go b/cmd/babylond/cmd/testnet.go index 5864a4039..13886c348 100644 --- a/cmd/babylond/cmd/testnet.go +++ b/cmd/babylond/cmd/testnet.go @@ -97,8 +97,7 @@ Example: genesisCliArgs.EpochInterval, genesisCliArgs.BaseBtcHeaderHex, genesisCliArgs.BaseBtcHeaderHeight, genesisCliArgs.AllowedReporterAddresses, genesisCliArgs.CovenantPKs, genesisCliArgs.CovenantQuorum, genesisCliArgs.SlashingAddress, genesisCliArgs.MinSlashingTransactionFeeSat, genesisCliArgs.MinCommissionRate, - genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, - genesisCliArgs.MinPubRand, genesisCliArgs.InflationRateChange, genesisCliArgs.InflationMin, + genesisCliArgs.SlashingRate, genesisCliArgs.MaxActiveFinalityProviders, genesisCliArgs.MinUnbondingTime, genesisCliArgs.MinUnbondingRate, genesisCliArgs.InflationRateChange, genesisCliArgs.InflationMin, genesisCliArgs.InflationMax, genesisCliArgs.GoalBonded, genesisCliArgs.BlocksPerYear, genesisCliArgs.GenesisTime, genesisCliArgs.BlockGasLimit, genesisCliArgs.VoteExtensionEnableHeight) diff --git a/crypto/eots/randomness.go b/crypto/eots/randomness.go index 428fe1f55..e785208b8 100644 --- a/crypto/eots/randomness.go +++ b/crypto/eots/randomness.go @@ -1,6 +1,7 @@ package eots import ( + "errors" "fmt" "io" @@ -32,15 +33,32 @@ func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRand, error) { // get random seed - var seed [32]byte + var ( + seed [32]byte + err error + ) if _, err := io.ReadFull(randSource, seed[:]); err != nil { return nil, nil, err } // generate new master key pair - masterSK, err := hdkeychain.NewMaster(seed[:], &chaincfg.MainNetParams) - if err != nil { + var masterSK *hdkeychain.ExtendedKey + for { + masterSK, err = hdkeychain.NewMaster(seed[:], &chaincfg.MainNetParams) + // if all good, use this master SK + if err == nil { + break + } + // NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed + // will derive to an unusable secret key. The ErrUnusableSeed error will be + // returned if this should occur. We need to try to generate a new master SK + // again + if errors.Is(err, hdkeychain.ErrUnusableSeed) { + continue + } + // some other unrecoverable error, return error return nil, nil, err } + masterPK, err := masterSK.Neuter() if err != nil { return nil, nil, err @@ -79,6 +97,7 @@ func (msr *MasterSecretRand) MasterPubicRand() (*MasterPublicRand, error) { return &MasterPublicRand{masterPK}, nil } +// TODO: extend to support uint64 func (msr *MasterSecretRand) DeriveRandPair(height uint32) (*PrivateRand, *PublicRand, error) { // get child SK, then child SK in BTC format, and finally private randomness childSK, err := msr.k.Derive(height) diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index c5fd0f36e..81f965ba2 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -26,6 +26,7 @@ message FinalityProvider { // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string string master_pub_rand = 6; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. @@ -47,6 +48,7 @@ message FinalityProviderWithMeta { // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 3; // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string string master_pub_rand = 4; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 798cccb7b..e036d5694 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -336,6 +336,7 @@ message FinalityProviderResponse { // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string string master_pub_rand = 6; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index d73e86686..e27d90f72 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -55,6 +55,7 @@ message MsgCreateFinalityProvider { // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 6; // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string string master_pub_rand = 7; } // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index 5f2a3d159..9e9ddce16 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -23,8 +23,9 @@ message Evidence { bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // block_height is the height of the conflicting blocks uint64 block_height = 2; - // pub_rand is the public randomness the finality provider has committed to - bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + // master_pub_rand is the master public randomness the finality provider has committed to + // encoded as a base58 string + string master_pub_rand = 3; // canonical_app_hash is the AppHash of the canonical block bytes canonical_app_hash = 4; // fork_app_hash is the AppHash of the fork block diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index 7c1b4c62f..40f43fb0a 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -17,8 +17,6 @@ message GenesisState { repeated Evidence evidences = 3; // votes_sigs contains all the votes of finality providers ever registered. repeated VoteSig vote_sigs = 4; - // public_randomness contains all the public randomness ever commited from the finality providers. - repeated PublicRandomness public_randomness = 5; } // VoteSig the vote of an finality provider @@ -32,13 +30,3 @@ message VoteSig { // where finality signature is an EOTS signature, i.e. bytes finality_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; } - -// PublicRandomness the block height and public randomness that the finality provider has submitted. -message PublicRandomness { - // block_height is the height of block which the finality provider submited public randomness. - uint64 block_height = 1; - // fp_btc_pk is the BTC PK of the finality provider that casts this vote. - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pub_rand is the public randomness the finality provider has committed to. - bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; -} \ No newline at end of file diff --git a/proto/babylon/finality/v1/params.proto b/proto/babylon/finality/v1/params.proto index c5dce2cc9..d317ece41 100644 --- a/proto/babylon/finality/v1/params.proto +++ b/proto/babylon/finality/v1/params.proto @@ -8,8 +8,4 @@ option go_package = "github.com/babylonchain/babylon/x/finality/types"; // Params defines the parameters for the module. message Params { option (gogoproto.goproto_stringer) = false; - - // min_pub_rand is the minimum number of public randomness each - // message should commit - uint64 min_pub_rand = 1; } diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index 7c618d127..eade35577 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -16,11 +16,6 @@ service Query { option (google.api.http).get = "/babylon/finality/v1/params"; } - // ListPublicRandomness is a range query for public randomness of a given finality provider - rpc ListPublicRandomness(QueryListPublicRandomnessRequest) returns (QueryListPublicRandomnessResponse) { - option (google.api.http).get = "/babylon/finality/v1/finality_providers/{fp_btc_pk_hex}/public_randomness_list"; - } - // Block queries a block at a given height rpc Block(QueryBlockRequest) returns (QueryBlockResponse) { option (google.api.http).get = "/babylon/finality/v1/blocks/{height}"; @@ -56,28 +51,6 @@ message QueryParamsResponse { Params params = 1 [(gogoproto.nullable) = false]; } -// QueryListPublicRandomnessRequest is the request type for the -// Query/ListPublicRandomness RPC method. -message QueryListPublicRandomnessRequest { - // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider - string fp_btc_pk_hex = 1; - - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; -} - -// QueryListPublicRandomnessResponse is the response type for the -// Query/ListPublicRandomness RPC method. -message QueryListPublicRandomnessResponse { - // pub_rand_map is the map where the key is the height and the value - // is the public randomness at this height for the given finality provider - map pub_rand_map = 1 [(gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; - - // pagination defines the pagination in the response. - cosmos.base.query.v1beta1.PageResponse pagination = 2; -} - - // QueriedBlockStatus is the status of blocks that the querier wants to query. enum QueriedBlockStatus { // NON_FINALIZED means the block is not finalised diff --git a/proto/babylon/finality/v1/tx.proto b/proto/babylon/finality/v1/tx.proto index 11a55fe31..2965ab511 100644 --- a/proto/babylon/finality/v1/tx.proto +++ b/proto/babylon/finality/v1/tx.proto @@ -14,8 +14,6 @@ service Msg { // AddFinalitySig adds a finality signature to a given block rpc AddFinalitySig(MsgAddFinalitySig) returns (MsgAddFinalitySigResponse); - // CommitPubRandList commits a list of public randomness for EOTS - rpc CommitPubRandList(MsgCommitPubRandList) returns (MsgCommitPubRandListResponse); // TODO: msg for evidence of equivocation. this is not specified yet // UpdateParams updates the finality module parameters. rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); @@ -41,27 +39,6 @@ message MsgAddFinalitySig { // MsgAddFinalitySigResponse is the response to the MsgAddFinalitySig message message MsgAddFinalitySigResponse{} -// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS -message MsgCommitPubRandList { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // start_height is the start block height of the list of public randomness - uint64 start_height = 3; - // pub_rand_list is the list of public randomness - repeated bytes pub_rand_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; - // sig is the signature on (start_height || pub_rand_list) signed by - // SK corresponding to fp_btc_pk. This prevents others to commit public - // randomness on behalf of fp_btc_pk - // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts - // the tx submitter to be the holder of fp_btc_pk. Decide this later - bytes sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; -} -// MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message -message MsgCommitPubRandListResponse{} - // MsgUpdateParams defines a message for updating finality module parameters. message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index ccf21e77d..ad5c022d3 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -32,6 +32,7 @@ var ( // finality provider fpBTCSK, _, _ = datagen.GenRandomBTCKeyPair(r) fp *bstypes.FinalityProvider + msr *eots.MasterSecretRand // BTC delegation delBTCSK, delBTCPK, _ = datagen.GenRandomBTCKeyPair(r) // covenant @@ -79,7 +80,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { create a random finality provider on Babylon */ // NOTE: we use the node's secret key as Babylon secret key for the finality provider - msr, _, err := eots.NewMasterRandPair(r) + msr, _, err = eots.NewMasterRandPair(r) s.NoError(err) fp, err = datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, nonValidatorNode.SecretKey, msr) s.NoError(err) @@ -332,10 +333,9 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { s.Equal(activeFps[0].VotingPower, activeDel.VotingPower(currentBtcTip.Height, initialization.BabylonBtcFinalizationPeriod, params.CovenantQuorum)) } -// Test2CommitPublicRandomnessAndSubmitFinalitySignature is an end-to-end -// test for user story 3: finality provider commits public randomness and submits -// finality signature, such that blocks can be finalised. -func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignature() { +// Test3SubmitFinalitySignature is an end-to-end test for user story 3: +// finality provider and submits finality signature, such that blocks can be finalised. +func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { chainA := s.configurer.GetChainConfig(0) chainA.WaitUntilHeight(1) nonValidatorNode, err := chainA.GetNodeAtIndex(2) @@ -345,28 +345,6 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat activatedHeight := nonValidatorNode.QueryActivatedHeight() s.Positive(activatedHeight) - /* - commit a number of public randomness since activatedHeight - */ - // commit public randomness list - srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, activatedHeight, 100) - s.NoError(err) - nonValidatorNode.CommitPubRandList( - msgCommitPubRandList.FpBtcPk, - msgCommitPubRandList.StartHeight, - msgCommitPubRandList.PubRandList, - msgCommitPubRandList.Sig, - ) - - // ensure public randomness list is eventually committed - nonValidatorNode.WaitForNextBlock() - var pubRandMap map[uint64]*bbn.SchnorrPubRand - s.Eventually(func() bool { - pubRandMap = nonValidatorNode.QueryListPublicRandomness(fp.BtcPk) - return len(pubRandMap) > 0 - }, time.Minute, time.Second*5) - s.Equal(pubRandMap[activatedHeight].MustMarshal(), msgCommitPubRandList.PubRandList[0].MustMarshal()) - // no reward gauge for finality provider and delegation yet fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) @@ -385,7 +363,9 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat msgToSign := append(sdk.Uint64ToBigEndian(activatedHeight), appHash...) // generate EOTS signature - sig, err := eots.Sign(fpBTCSK, srList[0], msgToSign) + sr, _, err := msr.DeriveRandPair(uint32(activatedHeight)) + s.NoError(err) + sig, err := eots.Sign(fpBTCSK, sr, msgToSign) s.NoError(err) eotsSig := bbn.NewSchnorrEOTSSigFromModNScalar(sig) // submit finality signature diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index 3847ba250..ab1f9267f 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -133,40 +133,6 @@ func (n *NodeConfig) AddCovenantSigs(covPK *bbn.BIP340PubKey, stakingTxHash stri n.LogActionF("successfully added covenant signatures") } -func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight uint64, pubRandList []bbn.SchnorrPubRand, sig *bbn.BIP340Signature) { - n.LogActionF("committing public randomness list") - - cmd := []string{"babylond", "tx", "finality", "commit-pubrand-list"} - - // add finality provider BTC PK to cmd - fpBTCPKHex := fpBTCPK.MarshalHex() - cmd = append(cmd, fpBTCPKHex) - - // add start height to cmd - startHeightStr := strconv.FormatUint(startHeight, 10) - cmd = append(cmd, startHeightStr) - - // add each pubrand to cmd - for _, pr := range pubRandList { - prHex := pr.ToHexStr() - cmd = append(cmd, prHex) - } - - // add sig to cmd - sigHex := sig.ToHexStr() - cmd = append(cmd, sigHex) - - // specify used key - cmd = append(cmd, "--from=val") - - // gas - cmd = append(cmd, "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3") - - _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) - require.NoError(n.t, err) - n.LogActionF("successfully committed public randomness list") -} - func (n *NodeConfig) AddFinalitySig(fpBTCPK *bbn.BIP340PubKey, blockHeight uint64, blockLch []byte, finalitySig *bbn.SchnorrEOTSSig) { n.LogActionF("add finality signature") diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index a4153050d..c71640f64 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -93,19 +93,6 @@ func (n *NodeConfig) QueryActivatedHeight() uint64 { return resp.Height } -// TODO: pagination support -func (n *NodeConfig) QueryListPublicRandomness(fpBTCPK *bbn.BIP340PubKey) map[uint64]*bbn.SchnorrPubRand { - path := fmt.Sprintf("/babylon/finality/v1/finality_providers/%s/public_randomness_list", fpBTCPK.MarshalHex()) - bz, err := n.QueryGRPCGateway(path, url.Values{}) - require.NoError(n.t, err) - - var resp ftypes.QueryListPublicRandomnessResponse - err = util.Cdc.UnmarshalJSON(bz, &resp) - require.NoError(n.t, err) - - return resp.PubRandMap -} - func (n *NodeConfig) QueryVotesAtHeight(height uint64) []bbn.BIP340PubKey { path := fmt.Sprintf("/babylon/finality/v1/votes/%d", height) bz, err := n.QueryGRPCGateway(path, url.Values{}) diff --git a/testutil/datagen/finality.go b/testutil/datagen/finality.go index 73eae543b..8b5048b1f 100644 --- a/testutil/datagen/finality.go +++ b/testutil/datagen/finality.go @@ -7,53 +7,17 @@ import ( bbn "github.com/babylonchain/babylon/types" ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcec/v2/schnorr" sdk "github.com/cosmos/cosmos-sdk/types" ) -func GenRandomPubRandList(r *rand.Rand, numPubRand uint64) ([]*eots.PrivateRand, []bbn.SchnorrPubRand, error) { - srList := []*eots.PrivateRand{} - prList := []bbn.SchnorrPubRand{} - for i := uint64(0); i < numPubRand; i++ { - eotsSR, eotsPR, err := eots.RandGen(r) - if err != nil { - return nil, nil, err - } - pr := bbn.NewSchnorrPubRandFromFieldVal(eotsPR) - srList = append(srList, eotsSR) - prList = append(prList, *pr) - } - return srList, prList, nil -} - -func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeight uint64, numPubRand uint64) ([]*eots.PrivateRand, *ftypes.MsgCommitPubRandList, error) { - srList, prList, err := GenRandomPubRandList(r, numPubRand) - if err != nil { - return nil, nil, err - } - - msg := &ftypes.MsgCommitPubRandList{ - Signer: GenRandomAccount().Address, - FpBtcPk: bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()), - StartHeight: startHeight, - PubRandList: prList, - } - hash, err := msg.HashToSign() - if err != nil { - return nil, nil, err - } - schnorrSig, err := schnorr.Sign(sk, hash) - if err != nil { - return nil, nil, err - } - msg.Sig = bbn.NewBIP340SignatureFromBTCSig(schnorrSig) - return srList, msg, nil -} - func GenRandomEvidence(r *rand.Rand, sk *btcec.PrivateKey, height uint64) (*ftypes.Evidence, error) { pk := sk.PubKey() bip340PK := bbn.NewBIP340PubKeyFromBTCPK(pk) - sr, pr, err := eots.RandGen(r) + msr, mpr, err := eots.NewMasterRandPair(r) + if err != nil { + return nil, err + } + sr, _, err := msr.DeriveRandPair(uint32(height)) if err != nil { return nil, err } @@ -71,7 +35,7 @@ func GenRandomEvidence(r *rand.Rand, sk *btcec.PrivateKey, height uint64) (*ftyp evidence := &ftypes.Evidence{ FpBtcPk: bip340PK, BlockHeight: height, - PubRand: bbn.NewSchnorrPubRandFromFieldVal(pr), + MasterPubRand: mpr.MarshalBase58(), CanonicalAppHash: cAppHash, ForkAppHash: fAppHash, CanonicalFinalitySig: bbn.NewSchnorrEOTSSigFromModNScalar(cSig), diff --git a/types/btc_schnorr_pub_rand.go b/types/btc_schnorr_pub_rand.go deleted file mode 100644 index be92231d2..000000000 --- a/types/btc_schnorr_pub_rand.go +++ /dev/null @@ -1,76 +0,0 @@ -package types - -import ( - "encoding/hex" - "fmt" - - "github.com/btcsuite/btcd/btcec/v2" -) - -type SchnorrPubRand []byte - -const SchnorrPubRandLen = 32 - -func NewSchnorrPubRand(data []byte) (*SchnorrPubRand, error) { - var pr SchnorrPubRand - err := pr.Unmarshal(data) - return &pr, err -} - -func NewSchnorrPubRandFromHex(prHex string) (*SchnorrPubRand, error) { - prBytes, err := hex.DecodeString(prHex) - if err != nil { - return nil, err - } - return NewSchnorrPubRand(prBytes) -} - -func NewSchnorrPubRandFromFieldVal(r *btcec.FieldVal) *SchnorrPubRand { - prBytes := r.Bytes() - pr := SchnorrPubRand(prBytes[:]) - return &pr -} - -func (pr SchnorrPubRand) ToFieldVal() *btcec.FieldVal { - var r btcec.FieldVal - r.SetByteSlice(pr) - return &r -} - -func (pr SchnorrPubRand) Size() int { - return len(pr.MustMarshal()) -} - -func (pr SchnorrPubRand) Marshal() ([]byte, error) { - return pr, nil -} - -func (pr SchnorrPubRand) MustMarshal() []byte { - prBytes, err := pr.Marshal() - if err != nil { - panic(err) - } - return prBytes -} - -func (pr SchnorrPubRand) MarshalTo(data []byte) (int, error) { - bz, err := pr.Marshal() - if err != nil { - return 0, err - } - copy(data, bz) - return len(data), nil -} - -func (pr *SchnorrPubRand) Unmarshal(data []byte) error { - if len(data) != SchnorrPubRandLen { - return fmt.Errorf("invalid data length") - } - *pr = data - return nil -} - -func (pr *SchnorrPubRand) ToHexStr() string { - prBytes := pr.MustMarshal() - return hex.EncodeToString(prBytes) -} diff --git a/types/btc_schnorr_pub_rand_test.go b/types/btc_schnorr_pub_rand_test.go deleted file mode 100644 index 06e22387e..000000000 --- a/types/btc_schnorr_pub_rand_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package types_test - -import ( - "math/rand" - "testing" - - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/stretchr/testify/require" -) - -func FuzzSchnorrPubRand(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - - randBytes := datagen.GenRandomByteArray(r, 32) - var fieldVal btcec.FieldVal - fieldVal.SetByteSlice(randBytes) - - // FieldVal -> SchnorrPubRand -> FieldVal - pubRand := types.NewSchnorrPubRandFromFieldVal(&fieldVal) - fieldVal2 := pubRand.ToFieldVal() - require.True(t, fieldVal.Equals(fieldVal2)) - - // SchnorrPubRand -> bytes -> SchnorrPubRand - randBytes2 := pubRand.MustMarshal() - pubRand2, err := types.NewSchnorrPubRand(randBytes) - require.NoError(t, err) - require.Equal(t, randBytes, randBytes2) - require.Equal(t, pubRand, pubRand2) - }) -} diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index bea07a683..700a687f4 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -5,6 +5,7 @@ import ( "sort" "cosmossdk.io/math" + "github.com/babylonchain/babylon/crypto/eots" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -35,6 +36,23 @@ func (fp *FinalityProvider) ValidateBasic() error { return nil } +// MustGetPubRand gets the public randomness at the given height for the +// finality provider. It is derived from its master public randomness. +func (fp *FinalityProvider) MustGetPubRand(height uint64) *eots.PublicRand { + mpr, err := eots.NewMasterPublicRandFromBase58(fp.MasterPubRand) + if err != nil { + // fp is a DB object and mpr has been verified. This + // must be a programming error + panic(err) + } + pr, err := mpr.DerivePubRand(uint32(height)) + if err != nil { + // must be a programming error + panic(err) + } + return pr +} + // SortFinalityProviders sorts the finality providers slice, // from higher to lower voting power func SortFinalityProviders(fps []*FinalityProviderDistInfo) { diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index e4424b0c8..b7cb360e9 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -83,6 +83,7 @@ type FinalityProvider struct { // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. @@ -179,6 +180,7 @@ type FinalityProviderWithMeta struct { // voting_power is the voting power of this finality provider at the given height VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string MasterPubRand string `protobuf:"bytes,4,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 8eb455408..dabd668ff 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1484,6 +1484,7 @@ type FinalityProviderResponse struct { // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index e369fcca4..46631347f 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -50,6 +50,7 @@ type MsgCreateFinalityProvider struct { // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,6,opt,name=pop,proto3" json:"pop,omitempty"` // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string MasterPubRand string `protobuf:"bytes,7,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` } diff --git a/x/finality/client/cli/query.go b/x/finality/client/cli/query.go index 7198e450f..855b60fa0 100644 --- a/x/finality/client/cli/query.go +++ b/x/finality/client/cli/query.go @@ -29,7 +29,6 @@ func GetQueryCmd(queryRoute string) *cobra.Command { } cmd.AddCommand(CmdQueryParams()) - cmd.AddCommand(CmdListPublicRandomness()) cmd.AddCommand(CmdBlock()) cmd.AddCommand(CmdListBlocks()) cmd.AddCommand(CmdVotesAtHeight()) @@ -67,39 +66,6 @@ func CmdVotesAtHeight() *cobra.Command { return cmd } -func CmdListPublicRandomness() *cobra.Command { - cmd := &cobra.Command{ - Use: "list-public-randomness [fp_btc_pk_hex]", - Short: "list public randomness committed by a given finality provider", - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - - queryClient := types.NewQueryClient(clientCtx) - - pageReq, err := client.ReadPageRequest(cmd.Flags()) - if err != nil { - return err - } - - res, err := queryClient.ListPublicRandomness(cmd.Context(), &types.QueryListPublicRandomnessRequest{ - FpBtcPkHex: args[0], - Pagination: pageReq, - }) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "list-public-randomness") - - return cmd -} - func CmdListBlocks() *cobra.Command { cmd := &cobra.Command{ Use: "list-blocks", diff --git a/x/finality/client/cli/tx.go b/x/finality/client/cli/tx.go index bf4b4178b..5729fd4ad 100644 --- a/x/finality/client/cli/tx.go +++ b/x/finality/client/cli/tx.go @@ -25,73 +25,12 @@ func GetTxCmd() *cobra.Command { } cmd.AddCommand( - NewCommitPubRandListCmd(), NewAddFinalitySigCmd(), ) return cmd } -func NewCommitPubRandListCmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "commit-pubrand-list [fp_btc_pk] [start_height] [pub_rand1] [pub_rand2] ... [sig]", - Args: cobra.MinimumNArgs(4), - Short: "Commit a list of public randomness", - Long: strings.TrimSpace( - `Commit a list of public randomness.`, // TODO: example - ), - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - - // get finality provider BTC PK - fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(args[0]) - if err != nil { - return err - } - - // get start height - startHeight, err := strconv.ParseUint(args[1], 10, 64) - if err != nil { - return err - } - - // get signature - sig, err := bbn.NewBIP340SignatureFromHex(args[len(args)-1]) - if err != nil { - return err - } - - // get pub rand list - pubRandHexList := args[2 : len(args)-1] - pubRandList := []bbn.SchnorrPubRand{} - for _, prHex := range pubRandHexList { - pr, err := bbn.NewSchnorrPubRandFromHex(prHex) - if err != nil { - return err - } - pubRandList = append(pubRandList, *pr) - } - - msg := types.MsgCommitPubRandList{ - Signer: clientCtx.FromAddress.String(), - FpBtcPk: fpBTCPK, - StartHeight: startHeight, - PubRandList: pubRandList, - Sig: sig, - } - - return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) - }, - } - - flags.AddTxFlagsToCmd(cmd) - - return cmd -} - func NewAddFinalitySigCmd() *cobra.Command { cmd := &cobra.Command{ Use: "add-finality-sig [fp_btc_pk] [block_height] [block_app_hash] [finality_sig]", diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index 57fcac889..dd497b23b 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -2,12 +2,10 @@ package keeper import ( "context" - "fmt" btcstk "github.com/babylonchain/babylon/btcstaking" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) // InitGenesis initializes the keeper state from a provided initial genesis state. @@ -24,10 +22,6 @@ func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { k.SetSig(ctx, voteSig.BlockHeight, voteSig.FpBtcPk, voteSig.FinalitySig) } - for _, pubRand := range gs.PublicRandomness { - k.SetPubRandList(ctx, pubRand.FpBtcPk, pubRand.BlockHeight, []bbn.SchnorrPubRand{*pubRand.PubRand}) - } - return k.SetParams(ctx, gs.Params) } @@ -48,17 +42,11 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) return nil, err } - pubRandomness, err := k.publicRandomness(ctx) - if err != nil { - return nil, err - } - return &types.GenesisState{ - Params: k.GetParams(ctx), - IndexedBlocks: blocks, - Evidences: evidences, - VoteSigs: voteSigs, - PublicRandomness: pubRandomness, + Params: k.GetParams(ctx), + IndexedBlocks: blocks, + Evidences: evidences, + VoteSigs: voteSigs, }, nil } @@ -129,52 +117,3 @@ func (k Keeper) voteSigs(ctx context.Context) ([]*types.VoteSig, error) { return voteSigs, nil } - -// publicRandomness iterates over all commited randoms on the store, parses the finality provider public key -// and the height from the iterator key and the commited random from the iterator value. -// This function has high resource consumption and should be only used on export genesis. -func (k Keeper) publicRandomness(ctx context.Context) ([]*types.PublicRandomness, error) { - store := k.pubRandStore(ctx) - iter := store.Iterator(nil, nil) - defer iter.Close() - - commtRandoms := make([]*types.PublicRandomness, 0) - for ; iter.Valid(); iter.Next() { - // key contains the fp and the block height - fpBTCPK, blkHeight, err := parsePubKeyAndBlkHeightFromStoreKey(iter.Key()) - if err != nil { - return nil, err - } - pubRand, err := bbn.NewSchnorrPubRand(iter.Value()) - if err != nil { - return nil, err - } - - commtRandoms = append(commtRandoms, &types.PublicRandomness{ - BlockHeight: blkHeight, - FpBtcPk: fpBTCPK, - PubRand: pubRand, - }) - } - - return commtRandoms, nil -} - -// parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with -// BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) -func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { - sizeBigEndian := 8 - keyLen := len(key) - if keyLen < sizeBigEndian+1 { - return nil, 0, fmt.Errorf("key not long enough to parse BIP340PubKey and block height: %s", key) - } - - startKeyHeight := keyLen - sizeBigEndian - fpBTCPK, err = bbn.NewBIP340PubKey(key[:startKeyHeight]) - if err != nil { - return nil, 0, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) - } - - blkHeight = sdk.BigEndianToUint64(key[startKeyHeight:]) - return fpBTCPK, blkHeight, nil -} diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index d8768fec2..3ee233cbe 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -4,6 +4,7 @@ import ( "math/rand" "testing" + "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -17,14 +18,14 @@ func TestExportGenesis(t *testing.T) { r := rand.New(rand.NewSource(10)) btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) + msr, mpr, err := eots.NewMasterRandPair(r) + require.NoError(t, err) fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) - srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + sr, _, err := msr.DeriveRandPair(uint32(startHeight + blkHeight)) require.NoError(t, err) - - sr := srList[startHeight+blkHeight] blockHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address msgAddFinalitySig, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blkHeight, blockHash) @@ -33,7 +34,6 @@ func TestExportGenesis(t *testing.T) { allVotes := make([]*types.VoteSig, numPubRand) allBlocks := make([]*types.IndexedBlock, numPubRand) allEvidences := make([]*types.Evidence, numPubRand) - allPublicRandomness := make([]*types.PublicRandomness, numPubRand) for i := 0; i < int(numPubRand); i++ { // Votes vt := &types.VoteSig{ @@ -57,32 +57,21 @@ func TestExportGenesis(t *testing.T) { evidence := &types.Evidence{ FpBtcPk: fpBTCPK, BlockHeight: blkHeight, - PubRand: &msgCommitPubRandList.PubRandList[i], ForkAppHash: msgAddFinalitySig.BlockAppHash, ForkFinalitySig: msgAddFinalitySig.FinalitySig, CanonicalAppHash: blockHash, CanonicalFinalitySig: msgAddFinalitySig.FinalitySig, + MasterPubRand: mpr.MarshalBase58(), } k.SetEvidence(ctx, evidence) allEvidences[i] = evidence - // PubRandoms - pubRand := msgCommitPubRandList.PubRandList[i] - k.SetPubRandList(ctx, fpBTCPK, blkHeight, []bbn.SchnorrPubRand{pubRand}) - randomness := &types.PublicRandomness{ - BlockHeight: blkHeight, - FpBtcPk: fpBTCPK, - PubRand: &pubRand, - } - allPublicRandomness[i] = randomness - // updates the block everytime to make sure something is different. blkHeight++ } require.Equal(t, len(allVotes), int(numPubRand)) require.Equal(t, len(allBlocks), int(numPubRand)) require.Equal(t, len(allEvidences), int(numPubRand)) - require.Equal(t, len(allPublicRandomness), int(numPubRand)) gs, err := k.ExportGenesis(ctx) require.NoError(t, err) @@ -91,5 +80,4 @@ func TestExportGenesis(t *testing.T) { require.Equal(t, allVotes, gs.VoteSigs) require.Equal(t, allBlocks, gs.IndexedBlocks) require.Equal(t, allEvidences, gs.Evidences) - require.Equal(t, allPublicRandomness, gs.PublicRandomness) } diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index 6f867bb08..c874d28d3 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -18,41 +18,6 @@ import ( var _ types.QueryServer = Keeper{} -// ListPublicRandomness returns a list of public randomness committed by a given -// finality provider -func (k Keeper) ListPublicRandomness(ctx context.Context, req *types.QueryListPublicRandomnessRequest) (*types.QueryListPublicRandomnessResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "empty request") - } - - fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(req.FpBtcPkHex) - if err != nil { - return nil, status.Errorf(codes.InvalidArgument, "failed to unmarshal finality provider BTC PK hex: %v", err) - } - - sdkCtx := sdk.UnwrapSDKContext(ctx) - store := k.pubRandFpStore(sdkCtx, fpBTCPK) - pubRandMap := map[uint64]*bbn.SchnorrPubRand{} - pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { - height := sdk.BigEndianToUint64(key) - pubRand, err := bbn.NewSchnorrPubRand(value) - if err != nil { - panic("failed to unmarshal EOTS public randomness in KVStore") - } - pubRandMap[height] = pubRand - return nil - }) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - - resp := &types.QueryListPublicRandomnessResponse{ - PubRandMap: pubRandMap, - Pagination: pageRes, - } - return resp, nil -} - func (k Keeper) Block(ctx context.Context, req *types.QueryBlockRequest) (*types.QueryBlockResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index d9f6c1430..beeb99986 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -14,45 +14,6 @@ import ( "github.com/babylonchain/babylon/x/finality/types" ) -func FuzzListPublicRandomness(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - - // Setup keeper and context - keeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) - ctx = sdk.UnwrapSDKContext(ctx) - - // add a random list of EOTS public randomness - fpBTCPK, err := datagen.GenRandomBIP340PubKey(r) - require.NoError(t, err) - startHeight := datagen.RandomInt(r, 100) - numPubRand := datagen.RandomInt(r, 1000) + 2 - _, prList, err := datagen.GenRandomPubRandList(r, numPubRand) - require.NoError(t, err) - keeper.SetPubRandList(ctx, fpBTCPK, startHeight, prList) - - // perform a query to pubrand list and assert consistency - // NOTE: pagination is already tested in Cosmos SDK so we don't test it here again, - // instead only ensure it takes effect - limit := datagen.RandomInt(r, int(numPubRand)-1) + 1 - req := &types.QueryListPublicRandomnessRequest{ - FpBtcPkHex: fpBTCPK.MarshalHex(), - Pagination: &query.PageRequest{ - Limit: limit, - }, - } - resp, err := keeper.ListPublicRandomness(ctx, req) - require.NoError(t, err) - require.Equal(t, int(limit), len(resp.PubRandMap)) // check if pagination takes effect - for i := startHeight; i < startHeight+limit; i++ { - expectedPR := prList[i-startHeight] - actualPR := resp.PubRandMap[i] - require.Equal(t, expectedPR.MustMarshal(), actualPR.MustMarshal()) - } - }) -} - func FuzzBlock(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index e3a08fdad..720424738 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -97,18 +97,15 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } - // ensure the finality provider has committed public randomness - pubRand, err := ms.GetPubRand(ctx, fpPK, req.BlockHeight) - if err != nil { - return nil, types.ErrPubRandNotFound - } + // derive public randomness at this height from the master public randomness + pubRand := fp.MustGetPubRand(req.BlockHeight) // verify EOTS signature w.r.t. public randomness fpBTCPK, err := fpPK.ToBTCPK() if err != nil { return nil, err } - if err := eots.Verify(fpBTCPK, pubRand.ToFieldVal(), req.MsgToSign(), req.FinalitySig.ToModNScalar()); err != nil { + if err := eots.Verify(fpBTCPK, pubRand, req.MsgToSign(), req.FinalitySig.ToModNScalar()); err != nil { return nil, types.ErrInvalidFinalitySig.Wrapf("the EOTS signature is invalid: %v", err) } @@ -124,7 +121,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal evidence := &types.Evidence{ FpBtcPk: req.FpBtcPk, BlockHeight: req.BlockHeight, - PubRand: pubRand, + MasterPubRand: fp.MasterPubRand, CanonicalAppHash: indexedBlock.AppHash, CanonicalFinalitySig: nil, ForkAppHash: req.BlockAppHash, @@ -176,55 +173,6 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } -// CommitPubRandList commits a list of EOTS public randomness -// TODO: replace with BIP-32 randomness derivation -func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommitPubRandList) (*types.MsgCommitPubRandListResponse, error) { - defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCommitPubRandList) - - ctx := sdk.UnwrapSDKContext(goCtx) - - // ensure the request contains enough number of public randomness - minPubRand := ms.GetParams(ctx).MinPubRand - givenPubRand := len(req.PubRandList) - if uint64(givenPubRand) < minPubRand { - return nil, types.ErrTooFewPubRand.Wrapf("required minimum: %d, actual: %d", minPubRand, givenPubRand) - } - - // ensure the finality provider is registered - if req.FpBtcPk == nil { - return nil, types.ErrInvalidPubRand.Wrap("empty finality provider public key") - } - fpBTCPKBytes := req.FpBtcPk.MustMarshal() - if !ms.BTCStakingKeeper.HasFinalityProvider(ctx, fpBTCPKBytes) { - return nil, bstypes.ErrFpNotFound.Wrapf("the finality provider with BTC PK %v is not registered", fpBTCPKBytes) - } - - // this finality provider has not commit any public randomness, - // commit the given public randomness list and return - if ms.IsFirstPubRand(ctx, req.FpBtcPk) { - ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) - return &types.MsgCommitPubRandListResponse{}, nil - } - - // ensure height and req.StartHeight do not overlap, i.e., height < req.StartHeight - height, _, err := ms.GetLastPubRand(ctx, req.FpBtcPk) - if err != nil { - return nil, err - } - if height >= req.StartHeight { - return nil, types.ErrInvalidPubRand.Wrapf("the start height (%d) has overlap with the height of the highest public randomness (%d)", req.StartHeight, height) - } - - // verify signature over the list - if err := req.VerifySig(); err != nil { - return nil, types.ErrInvalidPubRand.Wrapf("invalid signature over the public randomness list: %v", err) - } - - // all good, commit the given public randomness list - ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) - return &types.MsgCommitPubRandListResponse{}, nil -} - // slashFinalityProvider slashes a finality provider with the given evidence // including setting its voting power to zero, extracting its BTC SK, // and emit an event diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index af417f9c6..4ab589626 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -29,77 +29,6 @@ func TestMsgServer(t *testing.T) { require.NotNil(t, ctx) } -func FuzzCommitPubRandList(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - ctrl := gomock.NewController(t) - defer ctrl.Finish() - - bsKeeper := types.NewMockBTCStakingKeeper(ctrl) - fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) - ms := keeper.NewMsgServerImpl(*fKeeper) - - // create a random finality provider - btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - fpBTCPKBytes := fpBTCPK.MustMarshal() - - // Case 1: fail if the finality provider is not registered - bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(false).Times(1) - startHeight := datagen.RandomInt(r, 10) - numPubRand := uint64(200) - _, msg, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) - require.NoError(t, err) - _, err = ms.CommitPubRandList(ctx, msg) - require.Error(t, err) - // register the finality provider - bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() - - // Case 2: commit a list of 0 { + i -= len(m.MasterPubRand) + copy(dAtA[i:], m.MasterPubRand) + i = encodeVarintFinality(dAtA, i, uint64(len(m.MasterPubRand))) i-- dAtA[i] = 0x1a } @@ -384,8 +387,8 @@ func (m *Evidence) Size() (n int) { if m.BlockHeight != 0 { n += 1 + sovFinality(uint64(m.BlockHeight)) } - if m.PubRand != nil { - l = m.PubRand.Size() + l = len(m.MasterPubRand) + if l > 0 { n += 1 + l + sovFinality(uint64(l)) } l = len(m.CanonicalAppHash) @@ -621,9 +624,9 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { } case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) } - var byteLen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowFinality @@ -633,26 +636,23 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthFinality } - postIndex := iNdEx + byteLen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthFinality } if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrPubRand - m.PubRand = &v - if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.MasterPubRand = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 304c7855c..32fd61946 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -34,8 +34,6 @@ type GenesisState struct { Evidences []*Evidence `protobuf:"bytes,3,rep,name=evidences,proto3" json:"evidences,omitempty"` // votes_sigs contains all the votes of finality providers ever registered. VoteSigs []*VoteSig `protobuf:"bytes,4,rep,name=vote_sigs,json=voteSigs,proto3" json:"vote_sigs,omitempty"` - // public_randomness contains all the public randomness ever commited from the finality providers. - PublicRandomness []*PublicRandomness `protobuf:"bytes,5,rep,name=public_randomness,json=publicRandomness,proto3" json:"public_randomness,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -99,13 +97,6 @@ func (m *GenesisState) GetVoteSigs() []*VoteSig { return nil } -func (m *GenesisState) GetPublicRandomness() []*PublicRandomness { - if m != nil { - return m.PublicRandomness - } - return nil -} - // VoteSig the vote of an finality provider // with the block of the vote, the finality provider btc public key and the vote signature. type VoteSig struct { @@ -158,97 +149,42 @@ func (m *VoteSig) GetBlockHeight() uint64 { return 0 } -// PublicRandomness the block height and public randomness that the finality provider has submitted. -type PublicRandomness struct { - // block_height is the height of block which the finality provider submited public randomness. - BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` - // fp_btc_pk is the BTC PK of the finality provider that casts this vote. - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` - // pub_rand is the public randomness the finality provider has committed to. - PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` -} - -func (m *PublicRandomness) Reset() { *m = PublicRandomness{} } -func (m *PublicRandomness) String() string { return proto.CompactTextString(m) } -func (*PublicRandomness) ProtoMessage() {} -func (*PublicRandomness) Descriptor() ([]byte, []int) { - return fileDescriptor_52dc577f74d797d1, []int{2} -} -func (m *PublicRandomness) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PublicRandomness) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PublicRandomness.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 *PublicRandomness) XXX_Merge(src proto.Message) { - xxx_messageInfo_PublicRandomness.Merge(m, src) -} -func (m *PublicRandomness) XXX_Size() int { - return m.Size() -} -func (m *PublicRandomness) XXX_DiscardUnknown() { - xxx_messageInfo_PublicRandomness.DiscardUnknown(m) -} - -var xxx_messageInfo_PublicRandomness proto.InternalMessageInfo - -func (m *PublicRandomness) GetBlockHeight() uint64 { - if m != nil { - return m.BlockHeight - } - return 0 -} - func init() { proto.RegisterType((*GenesisState)(nil), "babylon.finality.v1.GenesisState") proto.RegisterType((*VoteSig)(nil), "babylon.finality.v1.VoteSig") - proto.RegisterType((*PublicRandomness)(nil), "babylon.finality.v1.PublicRandomness") } func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 483 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0x87, 0x9b, 0xb6, 0xac, 0xab, 0x5b, 0xd0, 0x08, 0x1c, 0xa2, 0x02, 0xe9, 0x1f, 0x09, 0xa9, - 0xa7, 0x64, 0xeb, 0x26, 0xc4, 0xc4, 0x2d, 0xd2, 0xc4, 0x06, 0x07, 0x22, 0x07, 0x71, 0x80, 0x43, - 0x14, 0xa7, 0x6e, 0x62, 0xb5, 0xb5, 0xad, 0xd8, 0x89, 0xd6, 0x6f, 0xc1, 0xc7, 0xda, 0x71, 0x47, - 0x34, 0x89, 0x82, 0xda, 0x2f, 0x82, 0xe2, 0xa4, 0x1b, 0x9a, 0x22, 0x81, 0xb8, 0x70, 0xb3, 0x9d, - 0xe7, 0x7d, 0xfc, 0xbe, 0xbf, 0xc8, 0x60, 0x88, 0x02, 0xb4, 0x5a, 0x30, 0x6a, 0xcf, 0x08, 0x0d, - 0x16, 0x44, 0xae, 0xec, 0xec, 0xc8, 0x8e, 0x30, 0xc5, 0x82, 0x08, 0x8b, 0x27, 0x4c, 0x32, 0xfd, - 0x49, 0x89, 0x58, 0x3b, 0xc4, 0xca, 0x8e, 0x7a, 0x4f, 0x23, 0x16, 0x31, 0xf5, 0xdd, 0xce, 0x57, - 0x05, 0xda, 0x1b, 0x54, 0xd9, 0x78, 0x90, 0x04, 0xcb, 0x52, 0xd6, 0x1b, 0x55, 0x11, 0xb7, 0x62, - 0xc5, 0x8c, 0x7e, 0xd4, 0x41, 0xf7, 0x6d, 0xd1, 0x82, 0x27, 0x03, 0x89, 0xf5, 0x53, 0xb0, 0x57, - 0x48, 0x0c, 0x6d, 0xa0, 0x8d, 0x3b, 0x93, 0x67, 0x56, 0x45, 0x4b, 0x96, 0xab, 0x10, 0xa7, 0x79, - 0xb5, 0xee, 0xd7, 0x60, 0x59, 0xa0, 0x9f, 0x83, 0x47, 0x84, 0x4e, 0xf1, 0x25, 0x9e, 0xfa, 0x68, - 0xc1, 0xc2, 0xb9, 0x30, 0xea, 0x83, 0xc6, 0xb8, 0x33, 0x19, 0x56, 0x2a, 0x2e, 0x0a, 0xd4, 0xc9, - 0x49, 0xf8, 0x90, 0xfc, 0xb6, 0x13, 0xfa, 0x1b, 0xd0, 0xc6, 0x19, 0x99, 0x62, 0x1a, 0x62, 0x61, - 0x34, 0x94, 0xe4, 0x45, 0xa5, 0xe4, 0xac, 0xa4, 0xe0, 0x1d, 0xaf, 0x9f, 0x82, 0x76, 0xc6, 0x24, - 0xf6, 0x05, 0x89, 0x84, 0xd1, 0x54, 0xc5, 0xcf, 0x2b, 0x8b, 0x3f, 0x31, 0x89, 0x3d, 0x12, 0xc1, - 0xfd, 0xac, 0x58, 0x08, 0x1d, 0x82, 0xc7, 0x3c, 0x45, 0x0b, 0x12, 0xfa, 0x49, 0x40, 0xa7, 0x6c, - 0x49, 0xb1, 0x10, 0xc6, 0x03, 0xa5, 0x78, 0x59, 0x9d, 0x83, 0xa2, 0xe1, 0x2d, 0x0c, 0x0f, 0xf8, - 0xbd, 0x93, 0xd1, 0x77, 0x0d, 0xb4, 0xca, 0x9b, 0xf4, 0x21, 0xe8, 0xaa, 0x64, 0xfc, 0x18, 0x93, - 0x28, 0x96, 0x2a, 0xe2, 0x26, 0xec, 0xa8, 0xb3, 0x73, 0x75, 0xa4, 0x43, 0xd0, 0x9e, 0x71, 0x1f, - 0xc9, 0xd0, 0xe7, 0x73, 0xa3, 0x3e, 0xd0, 0xc6, 0x5d, 0xe7, 0xd5, 0xcd, 0xba, 0x3f, 0x89, 0x88, - 0x8c, 0x53, 0x64, 0x85, 0x6c, 0x69, 0x97, 0x8d, 0x84, 0x71, 0x40, 0xe8, 0x6e, 0x63, 0xcb, 0x15, - 0xc7, 0xc2, 0x72, 0x2e, 0xdc, 0xe3, 0x93, 0x43, 0x37, 0x45, 0xef, 0xf1, 0x0a, 0xb6, 0x66, 0xdc, - 0x91, 0xa1, 0x3b, 0xd7, 0xbf, 0x80, 0xee, 0xae, 0xe9, 0x3c, 0x15, 0xa3, 0xa1, 0xb4, 0xaf, 0x6f, - 0xd6, 0xfd, 0x93, 0xbf, 0xd3, 0x7a, 0x61, 0x4c, 0x59, 0x92, 0x9c, 0x7d, 0xf8, 0xe8, 0xe5, 0x81, - 0x75, 0x76, 0x36, 0x8f, 0x44, 0xa3, 0xb5, 0x06, 0x0e, 0xee, 0xc7, 0xf0, 0xbf, 0x06, 0xf5, 0xc0, - 0x3e, 0x4f, 0x91, 0xfa, 0x79, 0xff, 0x3c, 0xa4, 0x9b, 0xa2, 0x7c, 0x10, 0xd8, 0xe2, 0xc5, 0xc2, - 0x79, 0x77, 0xb5, 0x31, 0xb5, 0xeb, 0x8d, 0xa9, 0xfd, 0xdc, 0x98, 0xda, 0xd7, 0xad, 0x59, 0xbb, - 0xde, 0x9a, 0xb5, 0x6f, 0x5b, 0xb3, 0xf6, 0xf9, 0xf0, 0x4f, 0xe2, 0xcb, 0xbb, 0xa7, 0xa7, 0xee, - 0x40, 0x7b, 0xea, 0xd5, 0x1d, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x48, 0x67, 0xec, 0x5e, 0x0b, - 0x04, 0x00, 0x00, + // 421 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x8f, 0x93, 0x40, + 0x14, 0x80, 0xa1, 0x6d, 0x76, 0xed, 0x80, 0x1e, 0x46, 0x0f, 0xa4, 0x2a, 0xa5, 0x3d, 0xf5, 0x04, + 0xbb, 0xdd, 0x8d, 0x71, 0xe3, 0x8d, 0x64, 0xe3, 0xae, 0x1e, 0x24, 0x60, 0x3c, 0xe8, 0x81, 0x00, + 0x9d, 0x0e, 0x93, 0x76, 0x19, 0xc2, 0x4c, 0x49, 0xf9, 0x0d, 0x5e, 0xfc, 0x59, 0x3d, 0xf6, 0x68, + 0x9a, 0xd8, 0x98, 0xf6, 0x8f, 0x18, 0x06, 0xb0, 0x1e, 0x48, 0xdc, 0xdb, 0xbc, 0xc7, 0xf7, 0xbe, + 0xf7, 0x1e, 0x79, 0x60, 0x14, 0x06, 0x61, 0xb1, 0xa4, 0x89, 0x35, 0x27, 0x49, 0xb0, 0x24, 0xbc, + 0xb0, 0xf2, 0x4b, 0x0b, 0xa3, 0x04, 0x31, 0xc2, 0xcc, 0x34, 0xa3, 0x9c, 0xc2, 0xe7, 0x35, 0x62, + 0x36, 0x88, 0x99, 0x5f, 0x0e, 0x5e, 0x60, 0x8a, 0xa9, 0xf8, 0x6e, 0x95, 0xaf, 0x0a, 0x1d, 0x18, + 0x6d, 0xb6, 0x34, 0xc8, 0x82, 0x87, 0x5a, 0x36, 0x18, 0xb7, 0x11, 0x7f, 0xc5, 0x82, 0x19, 0x7f, + 0xef, 0x00, 0xf5, 0x7d, 0x35, 0x82, 0xc7, 0x03, 0x8e, 0xe0, 0x0d, 0x38, 0xab, 0x24, 0x9a, 0x6c, + 0xc8, 0x13, 0x65, 0xfa, 0xd2, 0x6c, 0x19, 0xc9, 0x74, 0x04, 0x62, 0xf7, 0x36, 0xfb, 0xa1, 0xe4, + 0xd6, 0x05, 0xf0, 0x0e, 0x3c, 0x23, 0xc9, 0x0c, 0xad, 0xd1, 0xcc, 0x0f, 0x97, 0x34, 0x5a, 0x30, + 0xad, 0x63, 0x74, 0x27, 0xca, 0x74, 0xd4, 0xaa, 0xb8, 0xaf, 0x50, 0xbb, 0x24, 0xdd, 0xa7, 0xe4, + 0x9f, 0x88, 0xc1, 0x77, 0xa0, 0x8f, 0x72, 0x32, 0x43, 0x49, 0x84, 0x98, 0xd6, 0x15, 0x92, 0xd7, + 0xad, 0x92, 0xdb, 0x9a, 0x72, 0x4f, 0x3c, 0xbc, 0x01, 0xfd, 0x9c, 0x72, 0xe4, 0x33, 0x82, 0x99, + 0xd6, 0x13, 0xc5, 0xaf, 0x5a, 0x8b, 0xbf, 0x50, 0x8e, 0x3c, 0x82, 0xdd, 0x27, 0x79, 0xf5, 0x60, + 0xe3, 0x5f, 0x32, 0x38, 0xaf, 0xb3, 0x70, 0x04, 0x54, 0xb1, 0x85, 0x1f, 0x23, 0x82, 0x63, 0x2e, + 0x7e, 0x47, 0xcf, 0x55, 0x44, 0xee, 0x4e, 0xa4, 0xa0, 0x0b, 0xfa, 0xf3, 0xd4, 0x0f, 0x79, 0xe4, + 0xa7, 0x0b, 0xad, 0x63, 0xc8, 0x13, 0xd5, 0x7e, 0xb3, 0xdb, 0x0f, 0xa7, 0x98, 0xf0, 0x78, 0x15, + 0x9a, 0x11, 0x7d, 0xb0, 0xea, 0xbe, 0x51, 0x1c, 0x90, 0xa4, 0x09, 0x2c, 0x5e, 0xa4, 0x88, 0x99, + 0xf6, 0xbd, 0x73, 0x75, 0x7d, 0xe1, 0xac, 0xc2, 0x8f, 0xa8, 0x70, 0xcf, 0xe7, 0xa9, 0xcd, 0x23, + 0x67, 0x01, 0xbf, 0x01, 0xb5, 0x99, 0xb1, 0xdc, 0x40, 0xeb, 0x0a, 0xed, 0xdb, 0xdd, 0x7e, 0x78, + 0xfd, 0x38, 0xad, 0x17, 0xc5, 0x09, 0xcd, 0xb2, 0xdb, 0x4f, 0x9f, 0xbd, 0x72, 0x39, 0xa5, 0xb1, + 0x79, 0x04, 0xdb, 0x1f, 0x36, 0x07, 0x5d, 0xde, 0x1e, 0x74, 0xf9, 0xf7, 0x41, 0x97, 0x7f, 0x1c, + 0x75, 0x69, 0x7b, 0xd4, 0xa5, 0x9f, 0x47, 0x5d, 0xfa, 0x7a, 0xf1, 0x3f, 0xf9, 0xfa, 0x74, 0x45, + 0xa2, 0x4f, 0x78, 0x26, 0x0e, 0xe8, 0xea, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x01, 0x09, + 0x37, 0xd6, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -271,20 +207,6 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.PublicRandomness) > 0 { - for iNdEx := len(m.PublicRandomness) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.PublicRandomness[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - } if len(m.VoteSigs) > 0 { for iNdEx := len(m.VoteSigs) - 1; iNdEx >= 0; iNdEx-- { { @@ -392,58 +314,6 @@ func (m *VoteSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *PublicRandomness) 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 *PublicRandomness) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PublicRandomness) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.PubRand != nil { - { - size := m.PubRand.Size() - i -= size - if _, err := m.PubRand.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.FpBtcPk != nil { - { - size := m.FpBtcPk.Size() - i -= size - if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintGenesis(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.BlockHeight != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -481,12 +351,6 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.PublicRandomness) > 0 { - for _, e := range m.PublicRandomness { - l = e.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - } return n } @@ -510,26 +374,6 @@ func (m *VoteSig) Size() (n int) { return n } -func (m *PublicRandomness) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BlockHeight != 0 { - n += 1 + sovGenesis(uint64(m.BlockHeight)) - } - if m.FpBtcPk != nil { - l = m.FpBtcPk.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - if m.PubRand != nil { - l = m.PubRand.Size() - n += 1 + l + sovGenesis(uint64(l)) - } - return n -} - func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -700,40 +544,6 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PublicRandomness", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PublicRandomness = append(m.PublicRandomness, &PublicRandomness{}) - if err := m.PublicRandomness[len(m.PublicRandomness)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -894,145 +704,6 @@ func (m *VoteSig) Unmarshal(dAtA []byte) error { } return nil } -func (m *PublicRandomness) 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 ErrIntOverflowGenesis - } - 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: PublicRandomness: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PublicRandomness: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) - } - m.BlockHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.BlockHeight |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.BIP340PubKey - m.FpBtcPk = &v - if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowGenesis - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.SchnorrPubRand - m.PubRand = &v - if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenesis(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthGenesis - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/genesis_test.go b/x/finality/types/genesis_test.go index 97dbf25c2..760de2ed5 100644 --- a/x/finality/types/genesis_test.go +++ b/x/finality/types/genesis_test.go @@ -21,9 +21,7 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "valid genesis state", genState: &types.GenesisState{ - Params: types.Params{ - MinPubRand: 200, - }, + Params: types.Params{}, }, valid: true, }, diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 4e596001b..2c51b410f 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -17,8 +17,7 @@ const ( var ( BlockKey = []byte{0x01} // key prefix for blocks VoteKey = []byte{0x02} // key prefix for votes - PubRandKey = []byte{0x03} // key prefix for public randomness - ParamsKey = []byte{0x04} // key prefix for the parameters - EvidenceKey = []byte{0x05} // key prefix for evidences - NextHeightToFinalizeKey = []byte{0x06} // key prefix for next height to finalise + ParamsKey = []byte{0x03} // key prefix for the parameters + EvidenceKey = []byte{0x04} // key prefix for evidences + NextHeightToFinalizeKey = []byte{0x05} // key prefix for next height to finalise ) diff --git a/x/finality/types/metrics.go b/x/finality/types/metrics.go index 84c131add..cb9e8339f 100644 --- a/x/finality/types/metrics.go +++ b/x/finality/types/metrics.go @@ -7,8 +7,7 @@ import ( // performance oriented metrics measuring the execution time of each message const ( - MetricsKeyCommitPubRandList = "commit_pub_rand_list" - MetricsKeyAddFinalitySig = "add_finality_sig" + MetricsKeyAddFinalitySig = "add_finality_sig" ) // Metrics for monitoring block finalization status diff --git a/x/finality/types/msg.go b/x/finality/types/msg.go index af941426f..90f951672 100644 --- a/x/finality/types/msg.go +++ b/x/finality/types/msg.go @@ -1,12 +1,9 @@ package types import ( - "fmt" - "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/btcec/v2" - "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -14,7 +11,6 @@ import ( var ( _ sdk.Msg = &MsgUpdateParams{} _ sdk.Msg = &MsgAddFinalitySig{} - _ sdk.Msg = &MsgCommitPubRandList{} ) func NewMsgAddFinalitySig(signer string, sk *btcec.PrivateKey, sr *eots.PrivateRand, blockHeight uint64, blockHash []byte) (*MsgAddFinalitySig, error) { @@ -38,49 +34,16 @@ func (m *MsgAddFinalitySig) MsgToSign() []byte { return msgToSignForVote(m.BlockHeight, m.BlockAppHash) } -func (m *MsgAddFinalitySig) VerifyEOTSSig(pubRand *bbn.SchnorrPubRand) error { +func (m *MsgAddFinalitySig) VerifyEOTSSig(mpr *eots.MasterPublicRand) error { msgToSign := m.MsgToSign() pk, err := m.FpBtcPk.ToBTCPK() if err != nil { return err } - - return eots.Verify(pk, pubRand.ToFieldVal(), msgToSign, m.FinalitySig.ToModNScalar()) -} - -// HashToSign returns a 32-byte hash of (start_height || pub_rand_list) -// The signature in MsgCommitPubRandList will be on this hash -func (m *MsgCommitPubRandList) HashToSign() ([]byte, error) { - hasher := tmhash.New() - if _, err := hasher.Write(sdk.Uint64ToBigEndian(m.StartHeight)); err != nil { - return nil, err - } - for _, pr := range m.PubRandList { - if _, err := hasher.Write(pr.MustMarshal()); err != nil { - return nil, err - } - } - return hasher.Sum(nil), nil -} - -func (m *MsgCommitPubRandList) VerifySig() error { - msgHash, err := m.HashToSign() + pubRand, err := mpr.DerivePubRand(uint32(m.BlockHeight)) if err != nil { return err } - pk, err := m.FpBtcPk.ToBTCPK() - if err != nil { - return err - } - if m.Sig == nil { - return fmt.Errorf("empty signature") - } - schnorrSig, err := m.Sig.ToBTCSig() - if err != nil { - return err - } - if !schnorrSig.Verify(msgHash, pk) { - return fmt.Errorf("failed to verify signature") - } - return nil + + return eots.Verify(pk, pubRand, msgToSign, m.FinalitySig.ToModNScalar()) } diff --git a/x/finality/types/msg_test.go b/x/finality/types/msg_test.go index 9dafd9d14..78977c1cb 100644 --- a/x/finality/types/msg_test.go +++ b/x/finality/types/msg_test.go @@ -6,7 +6,6 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" "github.com/stretchr/testify/require" ) @@ -19,37 +18,20 @@ func FuzzMsgAddFinalitySig(f *testing.F) { sk, err := eots.KeyGen(r) require.NoError(t, err) - sr, pr, err := eots.RandGen(r) + msr, mpr, err := eots.NewMasterRandPair(r) require.NoError(t, err) blockHeight := datagen.RandomInt(r, 10) blockHash := datagen.GenRandomByteArray(r, 32) + sr, _, err := msr.DeriveRandPair(uint32(blockHeight)) + require.NoError(t, err) + signer := datagen.GenRandomAccount().Address msg, err := types.NewMsgAddFinalitySig(signer, sk, sr, blockHeight, blockHash) require.NoError(t, err) // verify msg's EOTS sig against the given public randomness - err = msg.VerifyEOTSSig(bbn.NewSchnorrPubRandFromFieldVal(pr)) - require.NoError(t, err) - }) -} - -func FuzzMsgCommitPubRandList(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - - sk, _, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - - startHeight := datagen.RandomInt(r, 10) - numPubRand := datagen.RandomInt(r, 100) + 1 - _, msg, err := datagen.GenRandomMsgCommitPubRandList(r, sk, startHeight, numPubRand) - require.NoError(t, err) - - // sanity checks, including verifying signature - err = msg.VerifySig() + err = msg.VerifyEOTSSig(mpr) require.NoError(t, err) }) } diff --git a/x/finality/types/params.go b/x/finality/types/params.go index de592797b..957716b08 100644 --- a/x/finality/types/params.go +++ b/x/finality/types/params.go @@ -1,7 +1,6 @@ package types import ( - "fmt" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" ) @@ -15,9 +14,7 @@ func ParamKeyTable() paramtypes.KeyTable { // DefaultParams returns a default set of parameters func DefaultParams() Params { - return Params{ - MinPubRand: 100, - } + return Params{} } // ParamSetPairs get the params.ParamSet @@ -25,18 +22,8 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{} } -func validateMinPubRand(minPubRand uint64) error { - if minPubRand == 0 { - return fmt.Errorf("min Pub Rand cannot be 0") - } - return nil -} - // Validate validates the set of params func (p Params) Validate() error { - if err := validateMinPubRand(p.MinPubRand); err != nil { - return err - } return nil } diff --git a/x/finality/types/params.pb.go b/x/finality/types/params.pb.go index fe81592df..e967d01e6 100644 --- a/x/finality/types/params.pb.go +++ b/x/finality/types/params.pb.go @@ -25,9 +25,6 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { - // min_pub_rand is the minimum number of public randomness each - // message should commit - MinPubRand uint64 `protobuf:"varint,1,opt,name=min_pub_rand,json=minPubRand,proto3" json:"min_pub_rand,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -62,13 +59,6 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo -func (m *Params) GetMinPubRand() uint64 { - if m != nil { - return m.MinPubRand - } - return 0 -} - func init() { proto.RegisterType((*Params)(nil), "babylon.finality.v1.Params") } @@ -76,19 +66,17 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/params.proto", fileDescriptor_25539c9a61c72ee9) } var fileDescriptor_25539c9a61c72ee9 = []byte{ - // 192 bytes of a gzipped FileDescriptorProto + // 158 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, 0xd0, 0x83, 0xa9, 0xd0, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xeb, 0x83, - 0x58, 0x10, 0xa5, 0x4a, 0x06, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x42, 0x0a, 0x5c, 0x3c, 0xb9, 0x99, - 0x79, 0xf1, 0x05, 0xa5, 0x49, 0xf1, 0x45, 0x89, 0x79, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x2c, - 0x41, 0x5c, 0xb9, 0x99, 0x79, 0x01, 0xa5, 0x49, 0x41, 0x89, 0x79, 0x29, 0x56, 0x2c, 0x33, 0x16, - 0xc8, 0x33, 0x38, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, - 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x41, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0x05, 0xc9, 0x19, 0x89, - 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0xc2, 0xc9, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, - 0x47, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x3d, 0x78, 0xb7, 0xd3, 0x00, 0x00, 0x00, + 0x58, 0x10, 0xa5, 0x4a, 0x7c, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x56, 0x2c, 0x33, 0x16, 0xc8, 0x33, + 0x38, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, + 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x41, 0x7a, 0x66, + 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xfc, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, + 0x18, 0x47, 0xbf, 0x02, 0xe1, 0xa0, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x15, 0xc6, + 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x67, 0x01, 0xe8, 0x48, 0xb1, 0x00, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -111,11 +99,6 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.MinPubRand != 0 { - i = encodeVarintParams(dAtA, i, uint64(m.MinPubRand)) - i-- - dAtA[i] = 0x8 - } return len(dAtA) - i, nil } @@ -136,9 +119,6 @@ func (m *Params) Size() (n int) { } var l int _ = l - if m.MinPubRand != 0 { - n += 1 + sovParams(uint64(m.MinPubRand)) - } return n } @@ -177,25 +157,6 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field MinPubRand", wireType) - } - m.MinPubRand = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowParams - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.MinPubRand |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index a4b12e2ea..c4b874973 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -146,112 +146,6 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } -// QueryListPublicRandomnessRequest is the request type for the -// Query/ListPublicRandomness RPC method. -type QueryListPublicRandomnessRequest struct { - // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider - FpBtcPkHex string `protobuf:"bytes,1,opt,name=fp_btc_pk_hex,json=fpBtcPkHex,proto3" json:"fp_btc_pk_hex,omitempty"` - // pagination defines an optional pagination for the request. - Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` -} - -func (m *QueryListPublicRandomnessRequest) Reset() { *m = QueryListPublicRandomnessRequest{} } -func (m *QueryListPublicRandomnessRequest) String() string { return proto.CompactTextString(m) } -func (*QueryListPublicRandomnessRequest) ProtoMessage() {} -func (*QueryListPublicRandomnessRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{2} -} -func (m *QueryListPublicRandomnessRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryListPublicRandomnessRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryListPublicRandomnessRequest.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 *QueryListPublicRandomnessRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryListPublicRandomnessRequest.Merge(m, src) -} -func (m *QueryListPublicRandomnessRequest) XXX_Size() int { - return m.Size() -} -func (m *QueryListPublicRandomnessRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryListPublicRandomnessRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryListPublicRandomnessRequest proto.InternalMessageInfo - -func (m *QueryListPublicRandomnessRequest) GetFpBtcPkHex() string { - if m != nil { - return m.FpBtcPkHex - } - return "" -} - -func (m *QueryListPublicRandomnessRequest) GetPagination() *query.PageRequest { - if m != nil { - return m.Pagination - } - return nil -} - -// QueryListPublicRandomnessResponse is the response type for the -// Query/ListPublicRandomness RPC method. -type QueryListPublicRandomnessResponse struct { - // pub_rand_map is the map where the key is the height and the value - // is the public randomness at this height for the given finality provider - PubRandMap map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,1,rep,name=pub_rand_map,json=pubRandMap,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // pagination defines the pagination in the response. - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` -} - -func (m *QueryListPublicRandomnessResponse) Reset() { *m = QueryListPublicRandomnessResponse{} } -func (m *QueryListPublicRandomnessResponse) String() string { return proto.CompactTextString(m) } -func (*QueryListPublicRandomnessResponse) ProtoMessage() {} -func (*QueryListPublicRandomnessResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{3} -} -func (m *QueryListPublicRandomnessResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QueryListPublicRandomnessResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QueryListPublicRandomnessResponse.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 *QueryListPublicRandomnessResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryListPublicRandomnessResponse.Merge(m, src) -} -func (m *QueryListPublicRandomnessResponse) XXX_Size() int { - return m.Size() -} -func (m *QueryListPublicRandomnessResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryListPublicRandomnessResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QueryListPublicRandomnessResponse proto.InternalMessageInfo - -func (m *QueryListPublicRandomnessResponse) GetPagination() *query.PageResponse { - if m != nil { - return m.Pagination - } - return nil -} - // QueryBlockRequest is the request type for the // Query/Block RPC method. type QueryBlockRequest struct { @@ -263,7 +157,7 @@ func (m *QueryBlockRequest) Reset() { *m = QueryBlockRequest{} } func (m *QueryBlockRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlockRequest) ProtoMessage() {} func (*QueryBlockRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{4} + return fileDescriptor_32bddab77af6fdae, []int{2} } func (m *QueryBlockRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -310,7 +204,7 @@ func (m *QueryBlockResponse) Reset() { *m = QueryBlockResponse{} } func (m *QueryBlockResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlockResponse) ProtoMessage() {} func (*QueryBlockResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{5} + return fileDescriptor_32bddab77af6fdae, []int{3} } func (m *QueryBlockResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -359,7 +253,7 @@ func (m *QueryListBlocksRequest) Reset() { *m = QueryListBlocksRequest{} func (m *QueryListBlocksRequest) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksRequest) ProtoMessage() {} func (*QueryListBlocksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{6} + return fileDescriptor_32bddab77af6fdae, []int{4} } func (m *QueryListBlocksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -415,7 +309,7 @@ func (m *QueryListBlocksResponse) Reset() { *m = QueryListBlocksResponse func (m *QueryListBlocksResponse) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksResponse) ProtoMessage() {} func (*QueryListBlocksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{7} + return fileDescriptor_32bddab77af6fdae, []int{5} } func (m *QueryListBlocksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +363,7 @@ func (m *QueryVotesAtHeightRequest) Reset() { *m = QueryVotesAtHeightReq func (m *QueryVotesAtHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightRequest) ProtoMessage() {} func (*QueryVotesAtHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{8} + return fileDescriptor_32bddab77af6fdae, []int{6} } func (m *QueryVotesAtHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -517,7 +411,7 @@ func (m *QueryVotesAtHeightResponse) Reset() { *m = QueryVotesAtHeightRe func (m *QueryVotesAtHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightResponse) ProtoMessage() {} func (*QueryVotesAtHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{9} + return fileDescriptor_32bddab77af6fdae, []int{7} } func (m *QueryVotesAtHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -558,7 +452,7 @@ func (m *QueryEvidenceRequest) Reset() { *m = QueryEvidenceRequest{} } func (m *QueryEvidenceRequest) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceRequest) ProtoMessage() {} func (*QueryEvidenceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{10} + return fileDescriptor_32bddab77af6fdae, []int{8} } func (m *QueryEvidenceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,7 +498,7 @@ func (m *QueryEvidenceResponse) Reset() { *m = QueryEvidenceResponse{} } func (m *QueryEvidenceResponse) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceResponse) ProtoMessage() {} func (*QueryEvidenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{11} + return fileDescriptor_32bddab77af6fdae, []int{9} } func (m *QueryEvidenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -654,7 +548,7 @@ func (m *QueryListEvidencesRequest) Reset() { *m = QueryListEvidencesReq func (m *QueryListEvidencesRequest) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesRequest) ProtoMessage() {} func (*QueryListEvidencesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{12} + return fileDescriptor_32bddab77af6fdae, []int{10} } func (m *QueryListEvidencesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -710,7 +604,7 @@ func (m *QueryListEvidencesResponse) Reset() { *m = QueryListEvidencesRe func (m *QueryListEvidencesResponse) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesResponse) ProtoMessage() {} func (*QueryListEvidencesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{13} + return fileDescriptor_32bddab77af6fdae, []int{11} } func (m *QueryListEvidencesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -757,9 +651,6 @@ func init() { proto.RegisterEnum("babylon.finality.v1.QueriedBlockStatus", QueriedBlockStatus_name, QueriedBlockStatus_value) proto.RegisterType((*QueryParamsRequest)(nil), "babylon.finality.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.finality.v1.QueryParamsResponse") - proto.RegisterType((*QueryListPublicRandomnessRequest)(nil), "babylon.finality.v1.QueryListPublicRandomnessRequest") - proto.RegisterType((*QueryListPublicRandomnessResponse)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse") - proto.RegisterMapType((map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse.PubRandMapEntry") proto.RegisterType((*QueryBlockRequest)(nil), "babylon.finality.v1.QueryBlockRequest") proto.RegisterType((*QueryBlockResponse)(nil), "babylon.finality.v1.QueryBlockResponse") proto.RegisterType((*QueryListBlocksRequest)(nil), "babylon.finality.v1.QueryListBlocksRequest") @@ -775,72 +666,61 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 1028 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0x38, 0x8d, 0x9b, 0xbc, 0xc4, 0x90, 0x4e, 0x4d, 0x09, 0x2e, 0x75, 0x9c, 0x2d, 0x24, - 0x21, 0xa9, 0x76, 0x1b, 0xa7, 0x94, 0x16, 0x84, 0x4a, 0x2c, 0x12, 0x12, 0x68, 0x5d, 0xb3, 0x95, - 0x2a, 0xd1, 0x8b, 0x35, 0x6b, 0x4f, 0xec, 0x55, 0xec, 0x9d, 0xed, 0xee, 0xac, 0x15, 0xab, 0xaa, - 0x84, 0x38, 0xf4, 0x04, 0x12, 0x12, 0x17, 0x2e, 0x3d, 0xd0, 0x2b, 0xff, 0x48, 0x8f, 0x91, 0xb8, - 0xa0, 0x4a, 0x44, 0x28, 0xe1, 0xc6, 0x3f, 0x81, 0x76, 0x66, 0xd6, 0x8e, 0xc3, 0xfa, 0x47, 0xab, - 0xdc, 0xbc, 0x33, 0xef, 0xc7, 0xf7, 0xbe, 0xf7, 0xe6, 0x7b, 0x86, 0x79, 0x8b, 0x58, 0xed, 0x06, - 0x73, 0x8c, 0x5d, 0xdb, 0x21, 0x0d, 0x9b, 0xb7, 0x8d, 0xd6, 0x9a, 0xf1, 0x38, 0xa0, 0x5e, 0x5b, - 0x77, 0x3d, 0xc6, 0x19, 0xbe, 0xa8, 0x0c, 0xf4, 0xc8, 0x40, 0x6f, 0xad, 0x65, 0xd2, 0x35, 0x56, - 0x63, 0xe2, 0xde, 0x08, 0x7f, 0x49, 0xd3, 0xcc, 0xfb, 0x35, 0xc6, 0x6a, 0x0d, 0x6a, 0x10, 0xd7, - 0x36, 0x88, 0xe3, 0x30, 0x4e, 0xb8, 0xcd, 0x1c, 0x5f, 0xdd, 0xae, 0x54, 0x98, 0xdf, 0x64, 0xbe, - 0x61, 0x11, 0x9f, 0xca, 0x0c, 0x46, 0x6b, 0xcd, 0xa2, 0x9c, 0xac, 0x19, 0x2e, 0xa9, 0xd9, 0x8e, - 0x30, 0x56, 0xb6, 0xb9, 0x38, 0x54, 0x2e, 0xf1, 0x48, 0x33, 0x8a, 0xa6, 0xc5, 0x59, 0x74, 0x20, - 0x0a, 0x1b, 0x2d, 0x0d, 0xf8, 0xdb, 0x30, 0x4f, 0x49, 0x38, 0x9a, 0xf4, 0x71, 0x40, 0x7d, 0xae, - 0x95, 0xe0, 0x62, 0xcf, 0xa9, 0xef, 0x32, 0xc7, 0xa7, 0xf8, 0x36, 0x24, 0x65, 0x82, 0x39, 0x94, - 0x43, 0xcb, 0xd3, 0xf9, 0xcb, 0x7a, 0x4c, 0xe1, 0xba, 0x74, 0x2a, 0x9c, 0x7b, 0x79, 0x38, 0x3f, - 0x66, 0x2a, 0x07, 0xed, 0x27, 0x04, 0x39, 0x11, 0xf2, 0xae, 0xed, 0xf3, 0x52, 0x60, 0x35, 0xec, - 0x8a, 0x49, 0x9c, 0x2a, 0x6b, 0x3a, 0xd4, 0x8f, 0xd2, 0xe2, 0x05, 0x48, 0xed, 0xba, 0x65, 0x8b, - 0x57, 0xca, 0xee, 0x5e, 0xb9, 0x4e, 0xf7, 0x45, 0x9a, 0x29, 0x13, 0x76, 0xdd, 0x02, 0xaf, 0x94, - 0xf6, 0xb6, 0xe9, 0x3e, 0xde, 0x02, 0xe8, 0x32, 0x31, 0x97, 0x10, 0x30, 0x16, 0x75, 0x49, 0x9b, - 0x1e, 0xd2, 0xa6, 0xcb, 0xc6, 0x28, 0xda, 0xf4, 0x12, 0xa9, 0x51, 0x15, 0xde, 0x3c, 0xe1, 0xa9, - 0x1d, 0x24, 0x60, 0x61, 0x00, 0x1e, 0x55, 0xf0, 0x0b, 0x04, 0x33, 0x6e, 0x60, 0x95, 0x3d, 0xe2, - 0x54, 0xcb, 0x4d, 0xe2, 0xce, 0xa1, 0xdc, 0xf8, 0xf2, 0x74, 0x7e, 0x2b, 0xb6, 0xee, 0xa1, 0xe1, - 0xf4, 0x52, 0x60, 0x85, 0xa7, 0xf7, 0x88, 0xbb, 0xe9, 0x70, 0xaf, 0x5d, 0xb8, 0xf5, 0xea, 0x70, - 0xfe, 0x46, 0xcd, 0xe6, 0xf5, 0xc0, 0xd2, 0x2b, 0xac, 0x69, 0xa8, 0xa8, 0x95, 0x3a, 0xb1, 0x9d, - 0xe8, 0xc3, 0xe0, 0x6d, 0x97, 0xfa, 0xfa, 0x83, 0x4a, 0xdd, 0x61, 0x9e, 0xa7, 0x22, 0x98, 0xe0, - 0x76, 0x42, 0xe1, 0xaf, 0x62, 0x28, 0x59, 0x1a, 0x4a, 0x89, 0x84, 0x74, 0x92, 0x93, 0xcc, 0xe7, - 0xf0, 0xf6, 0x29, 0x84, 0x78, 0x16, 0xc6, 0xf7, 0x68, 0x5b, 0xf4, 0xe1, 0x9c, 0x19, 0xfe, 0xc4, - 0x69, 0x98, 0x68, 0x91, 0x46, 0x40, 0x45, 0xa2, 0x19, 0x53, 0x7e, 0x7c, 0x9a, 0xb8, 0x85, 0xb4, - 0x55, 0xb8, 0x20, 0x28, 0x28, 0x34, 0x58, 0x65, 0x2f, 0x6a, 0xe9, 0x25, 0x48, 0xd6, 0xa9, 0x5d, - 0xab, 0x73, 0x15, 0x43, 0x7d, 0x69, 0xf7, 0xd4, 0xdc, 0x29, 0x63, 0xc5, 0xf7, 0x27, 0x30, 0x61, - 0x85, 0x07, 0x6a, 0xbe, 0x16, 0x62, 0x79, 0xde, 0x71, 0xaa, 0x74, 0x9f, 0x56, 0xa5, 0xa7, 0xb4, - 0xd7, 0x7e, 0x43, 0x70, 0xa9, 0xc3, 0xbf, 0xb8, 0xe9, 0x0c, 0xd5, 0x1d, 0x48, 0xfa, 0x9c, 0xf0, - 0x40, 0x0e, 0xed, 0x5b, 0xf9, 0xa5, 0xbe, 0xcd, 0xb3, 0x55, 0xd0, 0x07, 0xc2, 0xdc, 0x54, 0x6e, - 0x67, 0x36, 0x72, 0xcf, 0x11, 0xbc, 0xfb, 0x3f, 0x8c, 0xdd, 0x97, 0x25, 0x0a, 0xf1, 0xd5, 0x84, - 0x8d, 0x50, 0xb9, 0x72, 0x38, 0xb3, 0xf6, 0x6b, 0xeb, 0xf0, 0x9e, 0x80, 0xf7, 0x90, 0x71, 0xea, - 0x6f, 0xf0, 0x6d, 0xd1, 0xa8, 0x61, 0x7d, 0x6c, 0x42, 0x26, 0xce, 0x49, 0x95, 0x75, 0x1f, 0xce, - 0xcb, 0xd7, 0x2c, 0xeb, 0x9a, 0x29, 0xdc, 0x7c, 0x75, 0x38, 0x9f, 0x1f, 0x6d, 0xe2, 0x0b, 0x3b, - 0xa5, 0xf5, 0x1b, 0xd7, 0x4b, 0x81, 0xf5, 0x0d, 0x6d, 0x9b, 0x49, 0x2b, 0x14, 0x00, 0x5f, 0xbb, - 0x0d, 0x69, 0x91, 0x6e, 0xb3, 0x65, 0x57, 0xa9, 0x53, 0xa1, 0xa3, 0x2b, 0x87, 0x66, 0xc2, 0x3b, - 0xa7, 0x5c, 0x3b, 0xdc, 0x4f, 0x52, 0x75, 0xa6, 0xe6, 0xee, 0x4a, 0x2c, 0xfb, 0x1d, 0xc7, 0x8e, - 0xb9, 0xf6, 0x0c, 0x29, 0xce, 0xc2, 0x96, 0x46, 0xf7, 0x27, 0xe4, 0x6c, 0xc6, 0xe7, 0xc4, 0xe3, - 0xe5, 0x1e, 0xe6, 0xa6, 0xc5, 0x99, 0x24, 0xea, 0xcc, 0x66, 0xeb, 0x05, 0x52, 0x7d, 0x38, 0x05, - 0x44, 0x95, 0xf8, 0x19, 0x4c, 0x45, 0x98, 0xa3, 0x09, 0x1b, 0x52, 0x63, 0xd7, 0xfe, 0xcc, 0x06, - 0x6c, 0xe5, 0x8e, 0x7c, 0xf3, 0xbd, 0xcf, 0x0c, 0x5f, 0x80, 0x54, 0xf1, 0x7e, 0xb1, 0xbc, 0xb5, - 0x53, 0xdc, 0xb8, 0xbb, 0xf3, 0x68, 0xf3, 0xcb, 0xd9, 0x31, 0x9c, 0x82, 0xa9, 0xee, 0x27, 0xc2, - 0xe7, 0x61, 0x7c, 0xa3, 0xf8, 0xdd, 0x6c, 0x22, 0xff, 0xef, 0x24, 0x4c, 0x88, 0x2a, 0xf1, 0xf7, - 0x08, 0x92, 0x72, 0xcf, 0xe0, 0xfe, 0xef, 0xb9, 0x77, 0xa9, 0x65, 0x96, 0x87, 0x1b, 0x4a, 0xd0, - 0xda, 0xd5, 0x1f, 0xfe, 0xf8, 0xe7, 0x97, 0xc4, 0x15, 0x7c, 0xd9, 0xe8, 0xbf, 0x63, 0xf1, 0x5f, - 0x08, 0xd2, 0x71, 0x6a, 0x8f, 0x3f, 0x7e, 0xdd, 0xed, 0x20, 0xe1, 0xdd, 0x7c, 0xb3, 0xa5, 0xa2, - 0x3d, 0x14, 0x60, 0x4b, 0xb8, 0x68, 0x0c, 0x5a, 0xf7, 0x65, 0xd7, 0x63, 0x61, 0x47, 0x3d, 0xdf, - 0x78, 0xd2, 0xf3, 0x52, 0x9e, 0x1a, 0xae, 0x88, 0x2c, 0x76, 0x9c, 0x0c, 0x5d, 0x6e, 0xd8, 0x3e, - 0xc7, 0xcf, 0x10, 0x4c, 0x88, 0x3e, 0xe1, 0xc5, 0xfe, 0xc8, 0x4e, 0x6a, 0x7d, 0x66, 0x69, 0xa8, - 0x9d, 0x82, 0x7c, 0x4d, 0x40, 0x5e, 0xc4, 0x1f, 0xc4, 0x42, 0x96, 0xba, 0x66, 0x3c, 0x91, 0xaf, - 0xe6, 0x29, 0xfe, 0x11, 0x01, 0x74, 0x25, 0x13, 0xaf, 0x0e, 0xe6, 0xa9, 0x47, 0xfc, 0x33, 0xd7, - 0x46, 0x33, 0x1e, 0xa9, 0xef, 0x4a, 0x6f, 0x9f, 0x23, 0x48, 0xf5, 0xa8, 0x1d, 0xd6, 0xfb, 0x27, - 0x89, 0xd3, 0xd2, 0x8c, 0x31, 0xb2, 0xbd, 0xc2, 0xb5, 0x2a, 0x70, 0x7d, 0x88, 0xaf, 0xc6, 0xe2, - 0x6a, 0x85, 0x3e, 0x5d, 0xba, 0x7e, 0x47, 0x30, 0x19, 0x3d, 0x63, 0xfc, 0x51, 0xff, 0x54, 0xa7, - 0x24, 0x34, 0xb3, 0x32, 0x8a, 0xa9, 0x02, 0xb4, 0x2d, 0x00, 0x15, 0xf0, 0x17, 0x6f, 0x3a, 0x73, - 0x91, 0xba, 0xe0, 0x5f, 0x11, 0xa4, 0x7a, 0x34, 0x6b, 0x10, 0x9b, 0x71, 0x2a, 0x3b, 0x88, 0xcd, - 0x58, 0x31, 0xd4, 0x16, 0x05, 0xf8, 0x1c, 0xce, 0xc6, 0x82, 0xef, 0xe8, 0x5e, 0xe1, 0xeb, 0x97, - 0x47, 0x59, 0x74, 0x70, 0x94, 0x45, 0x7f, 0x1f, 0x65, 0xd1, 0xcf, 0xc7, 0xd9, 0xb1, 0x83, 0xe3, - 0xec, 0xd8, 0x9f, 0xc7, 0xd9, 0xb1, 0x47, 0xd7, 0x87, 0x6d, 0xb0, 0xfd, 0x6e, 0x48, 0xb1, 0xcc, - 0xac, 0xa4, 0xf8, 0xb7, 0xbd, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x08, 0x51, 0x06, - 0x4b, 0x0c, 0x00, 0x00, + // 854 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x4f, 0x33, 0x45, + 0x18, 0xee, 0xf0, 0x7d, 0x94, 0x8f, 0xf9, 0xbe, 0x1a, 0x18, 0x10, 0x71, 0x91, 0x02, 0x8b, 0x16, + 0x04, 0xb2, 0x43, 0x8b, 0xd1, 0x10, 0x0f, 0x48, 0x23, 0x48, 0x15, 0x4b, 0x5d, 0x13, 0x13, 0xb9, + 0x34, 0xbb, 0x65, 0xd8, 0x6e, 0x68, 0x77, 0x96, 0xee, 0xb4, 0x69, 0x43, 0x48, 0x8c, 0x07, 0x2e, + 0x7a, 0x30, 0xf1, 0xe2, 0x85, 0x83, 0x5e, 0xfd, 0x47, 0x38, 0x92, 0x78, 0x31, 0x1e, 0x88, 0x01, + 0xff, 0x10, 0xb3, 0x33, 0xb3, 0x5d, 0x16, 0xb6, 0xb4, 0x07, 0x6e, 0xec, 0xcc, 0xf3, 0xbe, 0xcf, + 0xf3, 0xfe, 0x98, 0x87, 0xc2, 0x39, 0xd3, 0x30, 0x3b, 0x35, 0xea, 0xe0, 0x63, 0xdb, 0x31, 0x6a, + 0x36, 0xeb, 0xe0, 0x56, 0x16, 0x9f, 0x36, 0x49, 0xa3, 0xa3, 0xb9, 0x0d, 0xca, 0x28, 0x9a, 0x90, + 0x00, 0x2d, 0x00, 0x68, 0xad, 0xac, 0x32, 0x69, 0x51, 0x8b, 0xf2, 0x7b, 0xec, 0xff, 0x25, 0xa0, + 0xca, 0x7b, 0x16, 0xa5, 0x56, 0x8d, 0x60, 0xc3, 0xb5, 0xb1, 0xe1, 0x38, 0x94, 0x19, 0xcc, 0xa6, + 0x8e, 0x27, 0x6f, 0x57, 0x2a, 0xd4, 0xab, 0x53, 0x0f, 0x9b, 0x86, 0x47, 0x04, 0x03, 0x6e, 0x65, + 0x4d, 0xc2, 0x8c, 0x2c, 0x76, 0x0d, 0xcb, 0x76, 0x38, 0x58, 0x62, 0xe7, 0xe3, 0x54, 0xb9, 0x46, + 0xc3, 0xa8, 0x07, 0xd9, 0xd4, 0x38, 0x44, 0x57, 0x22, 0xc7, 0xa8, 0x93, 0x10, 0x7d, 0xe3, 0xf3, + 0x94, 0x78, 0xa0, 0x4e, 0x4e, 0x9b, 0xc4, 0x63, 0x6a, 0x09, 0x4e, 0x44, 0x4e, 0x3d, 0x97, 0x3a, + 0x1e, 0x41, 0x9b, 0x30, 0x29, 0x08, 0xa6, 0xc1, 0x3c, 0x58, 0x7e, 0x9d, 0x9b, 0xd1, 0x62, 0x0a, + 0xd7, 0x44, 0x50, 0xfe, 0xe5, 0xd5, 0xcd, 0x5c, 0x42, 0x97, 0x01, 0xea, 0x2a, 0x1c, 0xe7, 0x19, + 0xf3, 0x35, 0x5a, 0x39, 0x91, 0x34, 0x68, 0x0a, 0x26, 0xab, 0xc4, 0xb6, 0xaa, 0x8c, 0xe7, 0x7b, + 0xa9, 0xcb, 0x2f, 0xf5, 0x6b, 0x29, 0x4a, 0x82, 0x25, 0xfb, 0x27, 0x70, 0xd8, 0xf4, 0x0f, 0x24, + 0xf9, 0x42, 0x2c, 0x79, 0xc1, 0x39, 0x22, 0x6d, 0x72, 0x24, 0x22, 0x05, 0x5e, 0xfd, 0x1d, 0xc0, + 0x29, 0x9e, 0x6f, 0xdf, 0xf6, 0x18, 0xbf, 0x09, 0x0a, 0x45, 0x5b, 0x30, 0xe9, 0x31, 0x83, 0x35, + 0x45, 0x45, 0x6f, 0xe5, 0x96, 0x62, 0x93, 0xfa, 0xc1, 0xb6, 0x4c, 0xfa, 0x2d, 0x87, 0xeb, 0x32, + 0x0c, 0xed, 0x42, 0x18, 0x4e, 0x66, 0x7a, 0x88, 0x2b, 0xcb, 0x68, 0x62, 0x8c, 0x9a, 0x3f, 0x46, + 0x4d, 0x2c, 0x8a, 0x1c, 0xa3, 0x56, 0x32, 0x2c, 0x22, 0xc9, 0xf5, 0x7b, 0x91, 0xea, 0x25, 0x80, + 0xef, 0x3c, 0xd2, 0x18, 0xb6, 0x9d, 0x17, 0xe2, 0x8b, 0x7c, 0x31, 0x58, 0xe5, 0x32, 0x00, 0x7d, + 0x11, 0x23, 0x6f, 0xa9, 0xaf, 0x3c, 0xc1, 0x1b, 0xd1, 0xb7, 0x01, 0xdf, 0xe5, 0xf2, 0xbe, 0xa3, + 0x8c, 0x78, 0xdb, 0x6c, 0x8f, 0x0f, 0xaa, 0xdf, 0x1c, 0xeb, 0x50, 0x89, 0x0b, 0x92, 0x65, 0x1d, + 0xc0, 0x11, 0x93, 0x55, 0xca, 0xae, 0xac, 0xeb, 0x4d, 0xfe, 0xe3, 0x7f, 0x6e, 0xe6, 0x72, 0x96, + 0xcd, 0xaa, 0x4d, 0x53, 0xab, 0xd0, 0x3a, 0x96, 0x55, 0x56, 0xaa, 0x86, 0xed, 0x04, 0x1f, 0x98, + 0x75, 0x5c, 0xe2, 0x69, 0xf9, 0x42, 0x69, 0xe3, 0xa3, 0xf5, 0x52, 0xd3, 0xfc, 0x8a, 0x74, 0xf4, + 0xa4, 0xc9, 0x2a, 0xa5, 0x13, 0x4f, 0xdd, 0x84, 0x93, 0x9c, 0x6e, 0xa7, 0x65, 0x1f, 0x11, 0xa7, + 0x12, 0xf4, 0x19, 0x2d, 0xc0, 0xd4, 0xb1, 0x5b, 0x16, 0x5c, 0xe5, 0x2a, 0x69, 0x73, 0x95, 0xa3, + 0x3a, 0x3c, 0x76, 0xf3, 0x7e, 0xe0, 0x1e, 0x69, 0xab, 0x3a, 0x7c, 0xfb, 0x41, 0x68, 0xb7, 0xf7, + 0xaf, 0x88, 0x3c, 0x93, 0x7b, 0x37, 0x1b, 0xdb, 0xfd, 0x6e, 0x60, 0x17, 0xae, 0x5e, 0x00, 0xd9, + 0x33, 0x7f, 0xa4, 0xc1, 0xbd, 0x17, 0x8a, 0x7a, 0xe3, 0x31, 0xa3, 0xc1, 0xca, 0x91, 0xce, 0xbd, + 0xe6, 0x67, 0xa2, 0x51, 0xcf, 0xb6, 0x5b, 0x7f, 0x00, 0x39, 0x87, 0x07, 0x42, 0x64, 0x89, 0x9f, + 0xc2, 0xd1, 0x40, 0x73, 0xb0, 0x61, 0x7d, 0x6a, 0x0c, 0xf1, 0xcf, 0xb6, 0x60, 0x2b, 0x5b, 0xe2, + 0xcd, 0x47, 0x9f, 0x19, 0x1a, 0x87, 0xa9, 0xe2, 0x41, 0xb1, 0xbc, 0x5b, 0x28, 0x6e, 0xef, 0x17, + 0x0e, 0x77, 0x3e, 0x1f, 0x4b, 0xa0, 0x14, 0x1c, 0x0d, 0x3f, 0x01, 0x1a, 0x81, 0x2f, 0xb6, 0x8b, + 0xdf, 0x8f, 0x0d, 0xe5, 0x7e, 0x1a, 0x81, 0xc3, 0xbc, 0x4a, 0xf4, 0x03, 0x80, 0x49, 0x61, 0x42, + 0xa8, 0xf7, 0x7b, 0x8e, 0x3a, 0x9e, 0xb2, 0xdc, 0x1f, 0x28, 0x44, 0xab, 0x8b, 0x3f, 0xfe, 0xf5, + 0xdf, 0xaf, 0x43, 0xb3, 0x68, 0x06, 0xf7, 0x36, 0x60, 0x74, 0x01, 0xe0, 0x30, 0xaf, 0x03, 0x65, + 0x7a, 0x27, 0xbe, 0xef, 0x85, 0xca, 0x52, 0x5f, 0x9c, 0xe4, 0x5f, 0xe3, 0xfc, 0x19, 0xf4, 0x7e, + 0x2c, 0xbf, 0x78, 0xf7, 0xf8, 0x4c, 0x6c, 0xd5, 0x39, 0xfa, 0x19, 0x40, 0x18, 0x5a, 0x0a, 0x5a, + 0xed, 0xcd, 0xf2, 0xc8, 0x1c, 0x95, 0xb5, 0xc1, 0xc0, 0x03, 0xf5, 0x45, 0xfa, 0xd1, 0x25, 0x80, + 0xa9, 0x88, 0x1b, 0x20, 0xad, 0x37, 0x49, 0x9c, 0xd7, 0x28, 0x78, 0x60, 0xbc, 0xd4, 0xb5, 0xca, + 0x75, 0x7d, 0x80, 0x16, 0x63, 0x75, 0xb5, 0xfc, 0x98, 0xb0, 0x5d, 0x7f, 0x02, 0xf8, 0x2a, 0x58, + 0x73, 0xf4, 0x61, 0x6f, 0xaa, 0x07, 0x16, 0xa3, 0xac, 0x0c, 0x02, 0x95, 0x82, 0xf6, 0xb8, 0xa0, + 0x3c, 0xfa, 0x0c, 0x3f, 0xf5, 0xff, 0xb9, 0xec, 0x36, 0xa8, 0x1f, 0xd9, 0xf0, 0xf0, 0x59, 0xc4, + 0xbd, 0xce, 0x71, 0xf0, 0xfa, 0xd0, 0x6f, 0x00, 0xa6, 0x22, 0x6f, 0xfa, 0xa9, 0x6e, 0xc6, 0xb9, + 0xd0, 0x53, 0xdd, 0x8c, 0x35, 0x0b, 0x35, 0xc3, 0xc5, 0xcf, 0xa3, 0x74, 0xac, 0xf8, 0xae, 0x2f, + 0xe4, 0xbf, 0xbc, 0xba, 0x4d, 0x83, 0xeb, 0xdb, 0x34, 0xf8, 0xf7, 0x36, 0x0d, 0x7e, 0xb9, 0x4b, + 0x27, 0xae, 0xef, 0xd2, 0x89, 0xbf, 0xef, 0xd2, 0x89, 0xc3, 0xf5, 0x7e, 0x0e, 0xdf, 0x0e, 0x53, + 0x72, 0xb3, 0x37, 0x93, 0xfc, 0xa7, 0xca, 0xc6, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x11, + 0x04, 0x7a, 0x88, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -857,8 +737,6 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) - // ListPublicRandomness is a range query for public randomness of a given finality provider - ListPublicRandomness(ctx context.Context, in *QueryListPublicRandomnessRequest, opts ...grpc.CallOption) (*QueryListPublicRandomnessResponse, error) // Block queries a block at a given height Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -888,15 +766,6 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } -func (c *queryClient) ListPublicRandomness(ctx context.Context, in *QueryListPublicRandomnessRequest, opts ...grpc.CallOption) (*QueryListPublicRandomnessResponse, error) { - out := new(QueryListPublicRandomnessResponse) - err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/ListPublicRandomness", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *queryClient) Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) { out := new(QueryBlockResponse) err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/Block", in, out, opts...) @@ -946,8 +815,6 @@ func (c *queryClient) ListEvidences(ctx context.Context, in *QueryListEvidencesR type QueryServer interface { // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) - // ListPublicRandomness is a range query for public randomness of a given finality provider - ListPublicRandomness(context.Context, *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) // Block queries a block at a given height Block(context.Context, *QueryBlockRequest) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -967,9 +834,6 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } -func (*UnimplementedQueryServer) ListPublicRandomness(ctx context.Context, req *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListPublicRandomness not implemented") -} func (*UnimplementedQueryServer) Block(ctx context.Context, req *QueryBlockRequest) (*QueryBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Block not implemented") } @@ -1008,24 +872,6 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } -func _Query_ListPublicRandomness_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryListPublicRandomnessRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(QueryServer).ListPublicRandomness(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/babylon.finality.v1.Query/ListPublicRandomness", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).ListPublicRandomness(ctx, req.(*QueryListPublicRandomnessRequest)) - } - return interceptor(ctx, in, info, handler) -} - func _Query_Block_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryBlockRequest) if err := dec(in); err != nil { @@ -1124,10 +970,6 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, - { - MethodName: "ListPublicRandomness", - Handler: _Query_ListPublicRandomness_Handler, - }, { MethodName: "Block", Handler: _Query_Block_Handler, @@ -1209,107 +1051,6 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QueryListPublicRandomnessRequest) 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 *QueryListPublicRandomnessRequest) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryListPublicRandomnessRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.FpBtcPkHex) > 0 { - i -= len(m.FpBtcPkHex) - copy(dAtA[i:], m.FpBtcPkHex) - i = encodeVarintQuery(dAtA, i, uint64(len(m.FpBtcPkHex))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *QueryListPublicRandomnessResponse) 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 *QueryListPublicRandomnessResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryListPublicRandomnessResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.PubRandMap) > 0 { - for k := range m.PubRandMap { - v := m.PubRandMap[k] - baseI := i - if v != nil { - { - size := v.Size() - i -= size - if _, err := v.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - i = encodeVarintQuery(dAtA, i, uint64(k)) - i-- - dAtA[i] = 0x8 - i = encodeVarintQuery(dAtA, i, uint64(baseI-i)) - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - func (m *QueryBlockRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1712,49 +1453,6 @@ func (m *QueryParamsResponse) Size() (n int) { return n } -func (m *QueryListPublicRandomnessRequest) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.FpBtcPkHex) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - -func (m *QueryListPublicRandomnessResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.PubRandMap) > 0 { - for k, v := range m.PubRandMap { - _ = k - _ = v - l = 0 - if v != nil { - l = v.Size() - l += 1 + sovQuery(uint64(l)) - } - mapEntrySize := 1 + sovQuery(uint64(k)) + l - n += mapEntrySize + 1 + sovQuery(uint64(mapEntrySize)) - } - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n -} - func (m *QueryBlockRequest) Size() (n int) { if m == nil { return 0 @@ -2042,326 +1740,6 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryListPublicRandomnessRequest) 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 ErrIntOverflowQuery - } - 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: QueryListPublicRandomnessRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryListPublicRandomnessRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkHex", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.FpBtcPkHex = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *QueryListPublicRandomnessResponse) 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 ErrIntOverflowQuery - } - 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: QueryListPublicRandomnessResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: QueryListPublicRandomnessResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubRandMap", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.PubRandMap == nil { - m.PubRandMap = make(map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand) - } - var mapkey uint64 - var mapvalue1 github_com_babylonchain_babylon_types.SchnorrPubRand - var mapvalue = &mapvalue1 - for iNdEx < postIndex { - entryPreIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - if fieldNum == 1 { - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapkey |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - } else if fieldNum == 2 { - var mapbyteLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - mapbyteLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intMapbyteLen := int(mapbyteLen) - if intMapbyteLen < 0 { - return ErrInvalidLengthQuery - } - postbytesIndex := iNdEx + intMapbyteLen - if postbytesIndex < 0 { - return ErrInvalidLengthQuery - } - if postbytesIndex > l { - return io.ErrUnexpectedEOF - } - if err := mapvalue.Unmarshal(dAtA[iNdEx:postbytesIndex]); err != nil { - return err - } - iNdEx = postbytesIndex - } else { - iNdEx = entryPreIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > postIndex { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - m.PubRandMap[mapkey] = ((*github_com_babylonchain_babylon_types.SchnorrPubRand)(mapvalue)) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipQuery(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthQuery - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *QueryBlockRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/query.pb.gw.go b/x/finality/types/query.pb.gw.go index 1d001a7a0..7672bd263 100644 --- a/x/finality/types/query.pb.gw.go +++ b/x/finality/types/query.pb.gw.go @@ -51,78 +51,6 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } -var ( - filter_Query_ListPublicRandomness_0 = &utilities.DoubleArray{Encoding: map[string]int{"fp_btc_pk_hex": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_Query_ListPublicRandomness_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryListPublicRandomnessRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["fp_btc_pk_hex"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") - } - - protoReq.FpBtcPkHex, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPublicRandomness_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.ListPublicRandomness(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Query_ListPublicRandomness_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryListPublicRandomnessRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["fp_btc_pk_hex"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") - } - - protoReq.FpBtcPkHex, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) - } - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPublicRandomness_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.ListPublicRandomness(ctx, &protoReq) - return msg, metadata, err - -} - func request_Query_Block_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryBlockRequest var metadata runtime.ServerMetadata @@ -386,29 +314,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_ListPublicRandomness_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - var stream runtime.ServerTransportStream - ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Query_ListPublicRandomness_0(rctx, inboundMarshaler, server, req, pathParams) - md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_ListPublicRandomness_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -585,26 +490,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_ListPublicRandomness_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Query_ListPublicRandomness_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Query_ListPublicRandomness_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -711,8 +596,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_ListPublicRandomness_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "finality", "v1", "finality_providers", "fp_btc_pk_hex", "public_randomness_list"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_Block_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "finality", "v1", "blocks", "height"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ListBlocks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "blocks"}, "", runtime.AssumeColonVerbOpt(false))) @@ -727,8 +610,6 @@ var ( var ( forward_Query_Params_0 = runtime.ForwardResponseMessage - forward_Query_ListPublicRandomness_0 = runtime.ForwardResponseMessage - forward_Query_Block_0 = runtime.ForwardResponseMessage forward_Query_ListBlocks_0 = runtime.ForwardResponseMessage diff --git a/x/finality/types/tx.pb.go b/x/finality/types/tx.pb.go index 0579dbfd0..0ff2273b7 100644 --- a/x/finality/types/tx.pb.go +++ b/x/finality/types/tx.pb.go @@ -138,107 +138,6 @@ func (m *MsgAddFinalitySigResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgAddFinalitySigResponse proto.InternalMessageInfo -// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS -type MsgCommitPubRandList struct { - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` - // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` - // start_height is the start block height of the list of public randomness - StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` - // pub_rand_list is the list of public randomness - PubRandList []github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,4,rep,name=pub_rand_list,json=pubRandList,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_list,omitempty"` - // sig is the signature on (start_height || pub_rand_list) signed by - // SK corresponding to fp_btc_pk. This prevents others to commit public - // randomness on behalf of fp_btc_pk - // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts - // the tx submitter to be the holder of fp_btc_pk. Decide this later - Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,5,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` -} - -func (m *MsgCommitPubRandList) Reset() { *m = MsgCommitPubRandList{} } -func (m *MsgCommitPubRandList) String() string { return proto.CompactTextString(m) } -func (*MsgCommitPubRandList) ProtoMessage() {} -func (*MsgCommitPubRandList) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{2} -} -func (m *MsgCommitPubRandList) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *MsgCommitPubRandList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_MsgCommitPubRandList.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 *MsgCommitPubRandList) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgCommitPubRandList.Merge(m, src) -} -func (m *MsgCommitPubRandList) XXX_Size() int { - return m.Size() -} -func (m *MsgCommitPubRandList) XXX_DiscardUnknown() { - xxx_messageInfo_MsgCommitPubRandList.DiscardUnknown(m) -} - -var xxx_messageInfo_MsgCommitPubRandList proto.InternalMessageInfo - -func (m *MsgCommitPubRandList) GetSigner() string { - if m != nil { - return m.Signer - } - return "" -} - -func (m *MsgCommitPubRandList) GetStartHeight() uint64 { - if m != nil { - return m.StartHeight - } - return 0 -} - -// MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message -type MsgCommitPubRandListResponse struct { -} - -func (m *MsgCommitPubRandListResponse) Reset() { *m = MsgCommitPubRandListResponse{} } -func (m *MsgCommitPubRandListResponse) String() string { return proto.CompactTextString(m) } -func (*MsgCommitPubRandListResponse) ProtoMessage() {} -func (*MsgCommitPubRandListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{3} -} -func (m *MsgCommitPubRandListResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *MsgCommitPubRandListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_MsgCommitPubRandListResponse.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 *MsgCommitPubRandListResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgCommitPubRandListResponse.Merge(m, src) -} -func (m *MsgCommitPubRandListResponse) XXX_Size() int { - return m.Size() -} -func (m *MsgCommitPubRandListResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MsgCommitPubRandListResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_MsgCommitPubRandListResponse proto.InternalMessageInfo - // MsgUpdateParams defines a message for updating finality module parameters. type MsgUpdateParams struct { // authority is the address of the governance account. @@ -256,7 +155,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{4} + return fileDescriptor_2dd6da066b6baf1d, []int{2} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -307,7 +206,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{5} + return fileDescriptor_2dd6da066b6baf1d, []int{3} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -339,8 +238,6 @@ var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo func init() { proto.RegisterType((*MsgAddFinalitySig)(nil), "babylon.finality.v1.MsgAddFinalitySig") proto.RegisterType((*MsgAddFinalitySigResponse)(nil), "babylon.finality.v1.MsgAddFinalitySigResponse") - proto.RegisterType((*MsgCommitPubRandList)(nil), "babylon.finality.v1.MsgCommitPubRandList") - proto.RegisterType((*MsgCommitPubRandListResponse)(nil), "babylon.finality.v1.MsgCommitPubRandListResponse") proto.RegisterType((*MsgUpdateParams)(nil), "babylon.finality.v1.MsgUpdateParams") proto.RegisterType((*MsgUpdateParamsResponse)(nil), "babylon.finality.v1.MsgUpdateParamsResponse") } @@ -348,48 +245,41 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/tx.proto", fileDescriptor_2dd6da066b6baf1d) } var fileDescriptor_2dd6da066b6baf1d = []byte{ - // 644 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0x8d, 0x93, 0xb4, 0x9f, 0x3a, 0xc9, 0x57, 0x54, 0x53, 0x51, 0x37, 0xad, 0x9c, 0x10, 0x55, - 0xa8, 0x54, 0x60, 0xf7, 0x8f, 0x8a, 0x76, 0xd7, 0x20, 0x50, 0xa1, 0x44, 0x44, 0x0e, 0x6c, 0x00, - 0xc9, 0x1a, 0xff, 0x64, 0x3c, 0x6a, 0xec, 0x19, 0x3c, 0x93, 0xaa, 0xd9, 0x21, 0x9e, 0x80, 0x05, - 0x0f, 0x52, 0x21, 0x1e, 0xa2, 0x1b, 0xa4, 0x8a, 0x15, 0xaa, 0x44, 0x84, 0xda, 0x45, 0x5f, 0x03, - 0xc5, 0x1e, 0x37, 0x6d, 0x92, 0x8a, 0xc0, 0x82, 0x9d, 0xef, 0x9c, 0x33, 0xf7, 0xdc, 0x7b, 0xe6, - 0x5e, 0x83, 0x79, 0x0b, 0x5a, 0xed, 0x26, 0x09, 0xf4, 0x06, 0x0e, 0x60, 0x13, 0xf3, 0xb6, 0xbe, - 0xbf, 0xa2, 0xf3, 0x03, 0x8d, 0x86, 0x84, 0x13, 0xf9, 0xa6, 0x40, 0xb5, 0x04, 0xd5, 0xf6, 0x57, - 0x0a, 0xd3, 0x88, 0x20, 0x12, 0xe1, 0x7a, 0xf7, 0x2b, 0xa6, 0x16, 0x66, 0x6d, 0xc2, 0x7c, 0xc2, - 0xcc, 0x18, 0x88, 0x03, 0x01, 0xcd, 0xc4, 0x91, 0xee, 0x33, 0xd4, 0xcd, 0xee, 0x33, 0x24, 0x80, - 0xd2, 0x30, 0x71, 0x0a, 0x43, 0xe8, 0x8b, 0xab, 0xe5, 0xcf, 0x69, 0x30, 0x55, 0x65, 0x68, 0xdb, - 0x71, 0x9e, 0x08, 0x4a, 0x1d, 0x23, 0xf9, 0x16, 0x18, 0x67, 0x18, 0x05, 0x6e, 0xa8, 0x48, 0x25, - 0x69, 0x71, 0xc2, 0x10, 0x91, 0x6c, 0x80, 0x89, 0x06, 0x35, 0x2d, 0x6e, 0x9b, 0x74, 0x4f, 0x49, - 0x97, 0xa4, 0xc5, 0x7c, 0x65, 0xe3, 0xa4, 0x53, 0x5c, 0x45, 0x98, 0x7b, 0x2d, 0x4b, 0xb3, 0x89, - 0xaf, 0x0b, 0x45, 0xdb, 0x83, 0x38, 0x48, 0x02, 0x9d, 0xb7, 0xa9, 0xcb, 0xb4, 0xca, 0xd3, 0xda, - 0xda, 0xfa, 0x72, 0xad, 0x65, 0xed, 0xba, 0x6d, 0xe3, 0xbf, 0x06, 0xad, 0x70, 0xbb, 0xb6, 0x27, - 0xdf, 0x06, 0x79, 0xab, 0x49, 0xec, 0x3d, 0xd3, 0x73, 0x31, 0xf2, 0xb8, 0x92, 0x29, 0x49, 0x8b, - 0x59, 0x23, 0x17, 0x9d, 0xed, 0x44, 0x47, 0xf2, 0x02, 0x98, 0x8c, 0x29, 0x90, 0x52, 0xd3, 0x83, - 0xcc, 0x53, 0xb2, 0x5d, 0x6d, 0x23, 0xbe, 0xb8, 0x4d, 0xe9, 0x0e, 0x64, 0x9e, 0xfc, 0x06, 0xe4, - 0x93, 0x36, 0x4d, 0x86, 0x91, 0x32, 0x16, 0xd5, 0xf7, 0xf0, 0xa4, 0x53, 0x5c, 0x1f, 0xad, 0xbe, - 0xba, 0xed, 0x05, 0x24, 0x0c, 0x1f, 0xbf, 0x78, 0x59, 0xaf, 0x63, 0x64, 0xe4, 0x1a, 0x3d, 0x47, - 0xb6, 0x72, 0x1f, 0xce, 0x0f, 0x97, 0x84, 0x0d, 0xe5, 0x39, 0x30, 0x3b, 0xe0, 0x99, 0xe1, 0x32, - 0x4a, 0x02, 0xe6, 0x96, 0x7f, 0xa4, 0xc1, 0x74, 0x95, 0xa1, 0x47, 0xc4, 0xf7, 0x31, 0xaf, 0xb5, - 0x2c, 0x03, 0x06, 0xce, 0x73, 0xcc, 0xf8, 0xbf, 0x36, 0x95, 0x71, 0x18, 0xf2, 0x3e, 0x53, 0xa3, - 0x33, 0x61, 0xea, 0x5b, 0xf0, 0x3f, 0x6d, 0x59, 0x66, 0x08, 0x03, 0xc7, 0x6c, 0x62, 0xc6, 0x95, - 0x6c, 0x29, 0xf3, 0x57, 0x7e, 0x89, 0x1e, 0x8d, 0x1c, 0xbd, 0xd4, 0xec, 0x2e, 0xc8, 0xf4, 0xde, - 0x60, 0xf3, 0xa4, 0x53, 0x7c, 0xf0, 0x27, 0xed, 0xd4, 0x31, 0x0a, 0x20, 0x6f, 0x85, 0xae, 0xd1, - 0xcd, 0x72, 0xd5, 0x7c, 0x15, 0xcc, 0x0f, 0xb3, 0xf7, 0xc2, 0xff, 0x4f, 0x12, 0xb8, 0x51, 0x65, - 0xe8, 0x15, 0x75, 0x20, 0x77, 0x6b, 0xd1, 0xac, 0xcb, 0x1b, 0x60, 0x02, 0xb6, 0xb8, 0x47, 0x42, - 0xcc, 0xdb, 0xb1, 0xfb, 0x15, 0xe5, 0xdb, 0x97, 0xfb, 0xd3, 0x62, 0x8b, 0xb6, 0x1d, 0x27, 0x74, - 0x19, 0xab, 0xf3, 0x10, 0x07, 0xc8, 0xe8, 0x51, 0xe5, 0x4d, 0x30, 0x1e, 0x6f, 0x4b, 0xf4, 0x2e, - 0xb9, 0xd5, 0x39, 0x6d, 0xc8, 0xbe, 0x6a, 0xb1, 0x48, 0x25, 0x7b, 0xd4, 0x29, 0xa6, 0x0c, 0x71, - 0x61, 0x6b, 0xb2, 0x5b, 0x73, 0x2f, 0x55, 0x79, 0x16, 0xcc, 0xf4, 0x55, 0x95, 0x54, 0xbc, 0xfa, - 0x35, 0x0d, 0x32, 0x55, 0x86, 0x64, 0x0f, 0x4c, 0xf6, 0xed, 0xe1, 0x9d, 0xa1, 0x7a, 0x03, 0xb3, - 0x57, 0xd0, 0x46, 0xe3, 0x25, 0x8a, 0xf2, 0x3b, 0x30, 0x35, 0x38, 0x9f, 0x77, 0xaf, 0x4b, 0x32, - 0x40, 0x2d, 0xac, 0x8c, 0x4c, 0xbd, 0x90, 0xb4, 0x40, 0xfe, 0xca, 0x93, 0x2c, 0x5c, 0x97, 0xe2, - 0x32, 0xab, 0x70, 0x6f, 0x14, 0x56, 0xa2, 0x51, 0x18, 0x7b, 0x7f, 0x7e, 0xb8, 0x24, 0x55, 0x9e, - 0x1d, 0x9d, 0xaa, 0xd2, 0xf1, 0xa9, 0x2a, 0xfd, 0x3c, 0x55, 0xa5, 0x8f, 0x67, 0x6a, 0xea, 0xf8, - 0x4c, 0x4d, 0x7d, 0x3f, 0x53, 0x53, 0xaf, 0x97, 0x7f, 0x37, 0x84, 0x07, 0xbd, 0x3f, 0x65, 0x34, - 0x8f, 0xd6, 0x78, 0xf4, 0x9b, 0x5c, 0xfb, 0x15, 0x00, 0x00, 0xff, 0xff, 0x01, 0xd6, 0x89, 0xb4, - 0xc7, 0x05, 0x00, 0x00, + // 531 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x6f, 0xd3, 0x30, + 0x1c, 0x6d, 0xf6, 0xa7, 0xa8, 0x6e, 0x55, 0x44, 0x98, 0x58, 0xda, 0xa1, 0xb4, 0x54, 0x13, 0xaa, + 0x26, 0x48, 0xb6, 0x6e, 0x9a, 0x60, 0xb7, 0x46, 0x02, 0x0d, 0x50, 0x45, 0x95, 0xc2, 0x05, 0x0e, + 0x91, 0x93, 0xa6, 0xb6, 0xd5, 0x36, 0xb6, 0x62, 0x77, 0x5a, 0x6e, 0x88, 0x4f, 0xc0, 0x81, 0x0f, + 0x32, 0x21, 0x3e, 0xc4, 0x8e, 0x13, 0x27, 0xd4, 0x43, 0x85, 0xda, 0xc3, 0xbe, 0x06, 0x6a, 0xe2, + 0xa8, 0xb0, 0x15, 0xd1, 0x9b, 0x7f, 0x7e, 0xef, 0xe7, 0xf7, 0xfc, 0xfc, 0x33, 0x78, 0xe8, 0x42, + 0x37, 0x1a, 0xd0, 0xc0, 0xec, 0x91, 0x00, 0x0e, 0x88, 0x88, 0xcc, 0xb3, 0x03, 0x53, 0x9c, 0x1b, + 0x2c, 0xa4, 0x82, 0xaa, 0xf7, 0x25, 0x6a, 0xa4, 0xa8, 0x71, 0x76, 0x50, 0xde, 0x42, 0x14, 0xd1, + 0x18, 0x37, 0xe7, 0xab, 0x84, 0x5a, 0x2e, 0x79, 0x94, 0x0f, 0x29, 0x77, 0x12, 0x20, 0x29, 0x24, + 0xb4, 0x9d, 0x54, 0xe6, 0x90, 0xa3, 0xf9, 0xe9, 0x43, 0x8e, 0x24, 0x50, 0x5d, 0x26, 0xce, 0x60, + 0x08, 0x87, 0xb2, 0xb5, 0xf6, 0x6d, 0x0d, 0xdc, 0x6b, 0x71, 0xd4, 0xec, 0x76, 0x5f, 0x4a, 0x4a, + 0x87, 0x20, 0xf5, 0x01, 0xc8, 0x72, 0x82, 0x02, 0x3f, 0xd4, 0x94, 0xaa, 0x52, 0xcf, 0xd9, 0xb2, + 0x52, 0x6d, 0x90, 0xeb, 0x31, 0xc7, 0x15, 0x9e, 0xc3, 0xfa, 0xda, 0x5a, 0x55, 0xa9, 0x17, 0xac, + 0xe3, 0xf1, 0xa4, 0xd2, 0x40, 0x44, 0xe0, 0x91, 0x6b, 0x78, 0x74, 0x68, 0x4a, 0x45, 0x0f, 0x43, + 0x12, 0xa4, 0x85, 0x29, 0x22, 0xe6, 0x73, 0xc3, 0x7a, 0xd5, 0x3e, 0x3c, 0xda, 0x6f, 0x8f, 0xdc, + 0x37, 0x7e, 0x64, 0xdf, 0xe9, 0x31, 0x4b, 0x78, 0xed, 0xbe, 0xfa, 0x08, 0x14, 0xdc, 0x01, 0xf5, + 0xfa, 0x0e, 0xf6, 0x09, 0xc2, 0x42, 0x5b, 0xaf, 0x2a, 0xf5, 0x0d, 0x3b, 0x1f, 0xef, 0x9d, 0xc6, + 0x5b, 0xea, 0x2e, 0x28, 0x26, 0x14, 0xc8, 0x98, 0x83, 0x21, 0xc7, 0xda, 0xc6, 0x5c, 0xdb, 0x4e, + 0x1a, 0x9b, 0x8c, 0x9d, 0x42, 0x8e, 0xd5, 0x8f, 0xa0, 0x90, 0x5e, 0xd3, 0xe1, 0x04, 0x69, 0x9b, + 0xb1, 0xbf, 0x67, 0xe3, 0x49, 0xe5, 0x68, 0x35, 0x7f, 0x1d, 0x0f, 0x07, 0x34, 0x0c, 0x5f, 0xbc, + 0x7d, 0xd7, 0xe9, 0x10, 0x64, 0xe7, 0x7b, 0x8b, 0x44, 0x4e, 0xf2, 0x9f, 0xaf, 0x2f, 0xf6, 0x64, + 0x0c, 0xb5, 0x1d, 0x50, 0xba, 0x95, 0x99, 0xed, 0x73, 0x46, 0x03, 0xee, 0xd7, 0xbe, 0x2a, 0xe0, + 0x6e, 0x8b, 0xa3, 0xf7, 0xac, 0x0b, 0x85, 0xdf, 0x8e, 0xb3, 0x56, 0x8f, 0x41, 0x0e, 0x8e, 0x04, + 0xa6, 0x21, 0x11, 0x51, 0x12, 0xa9, 0xa5, 0xfd, 0xf8, 0xfe, 0x74, 0x4b, 0xbe, 0x62, 0xb3, 0xdb, + 0x0d, 0x7d, 0xce, 0x3b, 0x22, 0x24, 0x01, 0xb2, 0x17, 0x54, 0xf5, 0x39, 0xc8, 0x26, 0xaf, 0x15, + 0x87, 0x9d, 0x6f, 0xec, 0x18, 0x4b, 0xe6, 0xc5, 0x48, 0x44, 0xac, 0x8d, 0xcb, 0x49, 0x25, 0x63, + 0xcb, 0x86, 0x93, 0xe2, 0xdc, 0xf0, 0xe2, 0xa8, 0x5a, 0x09, 0x6c, 0xdf, 0x70, 0x95, 0x3a, 0x6e, + 0x8c, 0x15, 0xb0, 0xde, 0xe2, 0x48, 0xc5, 0xa0, 0x78, 0x63, 0x0e, 0x1e, 0x2f, 0xd5, 0xbb, 0x75, + 0xf7, 0xb2, 0xb1, 0x1a, 0x2f, 0x55, 0x54, 0x5d, 0x50, 0xf8, 0x2b, 0x9f, 0xdd, 0x7f, 0xf5, 0xff, + 0xc9, 0x2a, 0x3f, 0x59, 0x85, 0x95, 0x6a, 0x94, 0x37, 0x3f, 0x5d, 0x5f, 0xec, 0x29, 0xd6, 0xeb, + 0xcb, 0xa9, 0xae, 0x5c, 0x4d, 0x75, 0xe5, 0xd7, 0x54, 0x57, 0xbe, 0xcc, 0xf4, 0xcc, 0xd5, 0x4c, + 0xcf, 0xfc, 0x9c, 0xe9, 0x99, 0x0f, 0xfb, 0xff, 0x9b, 0x8a, 0xf3, 0xc5, 0xb7, 0x89, 0x07, 0xc4, + 0xcd, 0xc6, 0x7f, 0xe6, 0xf0, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0x9d, 0x41, 0x5a, 0xd4, + 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -406,8 +296,6 @@ const _ = grpc.SupportPackageIsVersion4 type MsgClient interface { // AddFinalitySig adds a finality signature to a given block AddFinalitySig(ctx context.Context, in *MsgAddFinalitySig, opts ...grpc.CallOption) (*MsgAddFinalitySigResponse, error) - // CommitPubRandList commits a list of public randomness for EOTS - CommitPubRandList(ctx context.Context, in *MsgCommitPubRandList, opts ...grpc.CallOption) (*MsgCommitPubRandListResponse, error) // TODO: msg for evidence of equivocation. this is not specified yet // UpdateParams updates the finality module parameters. UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) @@ -430,15 +318,6 @@ func (c *msgClient) AddFinalitySig(ctx context.Context, in *MsgAddFinalitySig, o return out, nil } -func (c *msgClient) CommitPubRandList(ctx context.Context, in *MsgCommitPubRandList, opts ...grpc.CallOption) (*MsgCommitPubRandListResponse, error) { - out := new(MsgCommitPubRandListResponse) - err := c.cc.Invoke(ctx, "/babylon.finality.v1.Msg/CommitPubRandList", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { out := new(MsgUpdateParamsResponse) err := c.cc.Invoke(ctx, "/babylon.finality.v1.Msg/UpdateParams", in, out, opts...) @@ -452,8 +331,6 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts type MsgServer interface { // AddFinalitySig adds a finality signature to a given block AddFinalitySig(context.Context, *MsgAddFinalitySig) (*MsgAddFinalitySigResponse, error) - // CommitPubRandList commits a list of public randomness for EOTS - CommitPubRandList(context.Context, *MsgCommitPubRandList) (*MsgCommitPubRandListResponse, error) // TODO: msg for evidence of equivocation. this is not specified yet // UpdateParams updates the finality module parameters. UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) @@ -466,9 +343,6 @@ type UnimplementedMsgServer struct { func (*UnimplementedMsgServer) AddFinalitySig(ctx context.Context, req *MsgAddFinalitySig) (*MsgAddFinalitySigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddFinalitySig not implemented") } -func (*UnimplementedMsgServer) CommitPubRandList(ctx context.Context, req *MsgCommitPubRandList) (*MsgCommitPubRandListResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CommitPubRandList not implemented") -} func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } @@ -495,24 +369,6 @@ func _Msg_AddFinalitySig_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } -func _Msg_CommitPubRandList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgCommitPubRandList) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MsgServer).CommitPubRandList(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/babylon.finality.v1.Msg/CommitPubRandList", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).CommitPubRandList(ctx, req.(*MsgCommitPubRandList)) - } - return interceptor(ctx, in, info, handler) -} - func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgUpdateParams) if err := dec(in); err != nil { @@ -539,10 +395,6 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "AddFinalitySig", Handler: _Msg_AddFinalitySig_Handler, }, - { - MethodName: "CommitPubRandList", - Handler: _Msg_CommitPubRandList_Handler, - }, { MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, @@ -641,102 +493,6 @@ func (m *MsgAddFinalitySigResponse) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *MsgCommitPubRandList) 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 *MsgCommitPubRandList) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MsgCommitPubRandList) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Sig != nil { - { - size := m.Sig.Size() - i -= size - if _, err := m.Sig.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if len(m.PubRandList) > 0 { - for iNdEx := len(m.PubRandList) - 1; iNdEx >= 0; iNdEx-- { - { - size := m.PubRandList[iNdEx].Size() - i -= size - if _, err := m.PubRandList[iNdEx].MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - } - if m.StartHeight != 0 { - i = encodeVarintTx(dAtA, i, uint64(m.StartHeight)) - i-- - dAtA[i] = 0x18 - } - if m.FpBtcPk != nil { - { - size := m.FpBtcPk.Size() - i -= size - if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *MsgCommitPubRandListResponse) 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 *MsgCommitPubRandListResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *MsgCommitPubRandListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - return len(dAtA) - i, nil -} - func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -848,45 +604,6 @@ func (m *MsgAddFinalitySigResponse) Size() (n int) { return n } -func (m *MsgCommitPubRandList) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Signer) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } - if m.FpBtcPk != nil { - l = m.FpBtcPk.Size() - n += 1 + l + sovTx(uint64(l)) - } - if m.StartHeight != 0 { - n += 1 + sovTx(uint64(m.StartHeight)) - } - if len(m.PubRandList) > 0 { - for _, e := range m.PubRandList { - l = e.Size() - n += 1 + l + sovTx(uint64(l)) - } - } - if m.Sig != nil { - l = m.Sig.Size() - n += 1 + l + sovTx(uint64(l)) - } - return n -} - -func (m *MsgCommitPubRandListResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - return n -} - func (m *MsgUpdateParams) Size() (n int) { if m == nil { return 0 @@ -1172,262 +889,6 @@ func (m *MsgAddFinalitySigResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgCommitPubRandList) 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 ErrIntOverflowTx - } - 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: MsgCommitPubRandList: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgCommitPubRandList: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - 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 ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Signer = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.BIP340PubKey - m.FpBtcPk = &v - if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) - } - m.StartHeight = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.StartHeight |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubRandList", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.SchnorrPubRand - m.PubRandList = append(m.PubRandList, v) - if err := m.PubRandList[len(m.PubRandList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Sig", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v github_com_babylonchain_babylon_types.BIP340Signature - m.Sig = &v - if err := m.Sig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *MsgCommitPubRandListResponse) 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 ErrIntOverflowTx - } - 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: MsgCommitPubRandListResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: MsgCommitPubRandListResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipTx(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTx - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From 80a77c268b19863c677bf3baec47d97e8be22592 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 2 Apr 2024 12:30:16 +1100 Subject: [PATCH 066/119] finality: BTC timestamping master public randomness (#598) --- app/app.go | 1 + proto/babylon/btcstaking/v1/btcstaking.proto | 12 +- proto/babylon/btcstaking/v1/query.proto | 10 +- test/e2e/btc_staking_e2e_test.go | 39 ++- testutil/keeper/btcstaking.go | 2 + wasmbinding/test/custom_query_test.go | 5 +- wasmbinding/wasm.go | 2 +- x/btcstaking/genesis_test.go | 2 +- x/btcstaking/keeper/bench_test.go | 3 +- x/btcstaking/keeper/btc_height_index_test.go | 2 +- x/btcstaking/keeper/grpc_query.go | 1 + x/btcstaking/keeper/grpc_query_test.go | 19 +- x/btcstaking/keeper/incentive_test.go | 3 +- x/btcstaking/keeper/keeper.go | 7 + x/btcstaking/keeper/keeper_test.go | 13 +- x/btcstaking/keeper/msg_server.go | 13 +- x/btcstaking/keeper/msg_server_test.go | 43 ++- x/btcstaking/keeper/params_test.go | 6 +- x/btcstaking/keeper/power_dist_change_test.go | 9 +- x/btcstaking/keeper/query_params_test.go | 4 +- .../keeper/voting_power_table_test.go | 9 +- x/btcstaking/types/btcstaking.pb.go | 246 ++++++++++----- x/btcstaking/types/errors.go | 39 +-- x/btcstaking/types/expected_keepers.go | 6 + x/btcstaking/types/mocked_keepers.go | 53 ++++ x/btcstaking/types/query.go | 1 + x/btcstaking/types/query.pb.go | 295 ++++++++++-------- x/checkpointing/genesis.go | 2 + x/checkpointing/keeper/keeper.go | 30 ++ x/checkpointing/types/errors.go | 1 + x/checkpointing/types/keys.go | 2 + x/epoching/keeper/epochs.go | 3 +- x/finality/keeper/keeper.go | 5 + x/finality/keeper/msg_server.go | 9 + x/finality/keeper/msg_server_test.go | 43 ++- x/finality/types/expected_keepers.go | 1 + x/finality/types/mocked_keepers.go | 23 +- x/zoneconcierge/keeper/epochs.go | 29 +- x/zoneconcierge/keeper/grpc_query.go | 4 +- x/zoneconcierge/keeper/grpc_query_test.go | 1 + x/zoneconcierge/keeper/hooks.go | 3 - x/zoneconcierge/types/errors.go | 9 +- x/zoneconcierge/types/expected_keepers.go | 1 + x/zoneconcierge/types/keys.go | 5 +- x/zoneconcierge/types/mocked_keepers.go | 15 + 45 files changed, 680 insertions(+), 351 deletions(-) diff --git a/app/app.go b/app/app.go index 1441509e4..61b162a08 100644 --- a/app/app.go +++ b/app/app.go @@ -678,6 +678,7 @@ func NewBabylonApp( runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]), &btclightclientKeeper, &btcCheckpointKeeper, + &checkpointingKeeper, btcNetParams, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 81f965ba2..7987bd5cf 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -28,14 +28,16 @@ message FinalityProvider { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string string master_pub_rand = 6; + // registered_epoch is the epoch when this finality provider is registered + uint64 registered_epoch = 7; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 7; + uint64 slashed_babylon_height = 8; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 8; + uint64 slashed_btc_height = 9; } // FinalityProviderWithMeta wraps the FinalityProvider with metadata. @@ -50,14 +52,16 @@ message FinalityProviderWithMeta { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string string master_pub_rand = 4; + // registered_epoch is the epoch when this finality provider is registered + uint64 registered_epoch = 5; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 5; + uint64 slashed_babylon_height = 6; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 6; + uint64 slashed_btc_height = 7; } // BTCDelegation defines a BTC delegation diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index e036d5694..badd43ee0 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -338,16 +338,18 @@ message FinalityProviderResponse { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string string master_pub_rand = 6; + // registered_epoch is the epoch when this finality provider is registered + uint64 registered_epoch = 7; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 7; + uint64 slashed_babylon_height = 8; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 8; + uint64 slashed_btc_height = 9; // height is the queried Babylon height - uint64 height = 9; + uint64 height = 10; // voting_power is the voting power of this finality provider at the given height - uint64 voting_power = 10; + uint64 voting_power = 11; } diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index ad5c022d3..c1de3d182 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -92,6 +92,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { // query the existence of finality provider and assert equivalence actualFps := nonValidatorNode.QueryFinalityProviders() s.Len(actualFps, 1) + fp.RegisteredEpoch = actualFps[0].RegisteredEpoch // remember registered epoch s.equalFinalityProviderResp(fp, actualFps[0]) /* @@ -341,26 +342,39 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) + // finalise epochs until the registered epoch of the finality provider + // so that the finality provider can vote + var ( + startEpoch = uint64(1) + endEpoch = fp.RegisteredEpoch + ) + nonValidatorNode.FinalizeSealedEpochs(startEpoch, endEpoch) + // get activated height activatedHeight := nonValidatorNode.QueryActivatedHeight() s.Positive(activatedHeight) - // no reward gauge for finality provider and delegation yet + // no reward gauge for finality provider yet fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.Error(err) + fpRewardGauges, err := nonValidatorNode.QueryRewardGauge(fpBabylonAddr) + s.NoError(err) + _, ok := fpRewardGauges[itypes.FinalityProviderType.String()] + s.False(ok) + + // no reward gauge for BTC delegator yet delBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - _, err = nonValidatorNode.QueryRewardGauge(delBabylonAddr) - s.Error(err) + btcDelRewardGauges, err := nonValidatorNode.QueryRewardGauge(delBabylonAddr) + s.NoError(err) + _, ok = btcDelRewardGauges[itypes.BTCDelegationType.String()] + s.False(ok) /* - submit finality signature + generate finality signature */ // get block to vote blockToVote, err := nonValidatorNode.QueryBlock(int64(activatedHeight)) s.NoError(err) appHash := blockToVote.AppHash - msgToSign := append(sdk.Uint64ToBigEndian(activatedHeight), appHash...) // generate EOTS signature sr, _, err := msr.DeriveRandPair(uint32(activatedHeight)) @@ -368,6 +382,10 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { sig, err := eots.Sign(fpBTCSK, sr, msgToSign) s.NoError(err) eotsSig := bbn.NewSchnorrEOTSSigFromModNScalar(sig) + + /* + submit finality signature + */ // submit finality signature nonValidatorNode.AddFinalitySig(fp.BtcPk, activatedHeight, appHash, eotsSig) @@ -389,13 +407,14 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { s.Equal(appHash.Bytes(), finalizedBlocks[0].AppHash) // ensure finality provider has received rewards after the block is finalised - fpRewardGauges, err := nonValidatorNode.QueryRewardGauge(fpBabylonAddr) + fpRewardGauges, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) s.NoError(err) fpRewardGauge, ok := fpRewardGauges[itypes.FinalityProviderType.String()] s.True(ok) s.True(fpRewardGauge.Coins.IsAllPositive()) + // ensure BTC delegation has received rewards after the block is finalised - btcDelRewardGauges, err := nonValidatorNode.QueryRewardGauge(delBabylonAddr) + btcDelRewardGauges, err = nonValidatorNode.QueryRewardGauge(delBabylonAddr) s.NoError(err) btcDelRewardGauge, ok := btcDelRewardGauges[itypes.BTCDelegationType.String()] s.True(ok) @@ -602,6 +621,8 @@ func (s *BTCStakingTestSuite) equalFinalityProviderResp(fp *bstypes.FinalityProv s.Equal(fp.BabylonPk, fpResp.BabylonPk) s.Equal(fp.BtcPk, fpResp.BtcPk) s.Equal(fp.Pop, fpResp.Pop) + s.Equal(fp.MasterPubRand, fpResp.MasterPubRand) + s.Equal(fp.RegisteredEpoch, fpResp.RegisteredEpoch) s.Equal(fp.SlashedBabylonHeight, fpResp.SlashedBabylonHeight) s.Equal(fp.SlashedBtcHeight, fpResp.SlashedBtcHeight) } diff --git a/testutil/keeper/btcstaking.go b/testutil/keeper/btcstaking.go index 58f2af369..4402aa477 100644 --- a/testutil/keeper/btcstaking.go +++ b/testutil/keeper/btcstaking.go @@ -27,6 +27,7 @@ func BTCStakingKeeper( t testing.TB, btclcKeeper types.BTCLightClientKeeper, btccKeeper types.BtcCheckpointKeeper, + ckptKeeper types.CheckpointingKeeper, ) (*keeper.Keeper, sdk.Context) { storeKey := storetypes.NewKVStoreKey(types.StoreKey) @@ -43,6 +44,7 @@ func BTCStakingKeeper( runtime.NewKVStoreService(storeKey), btclcKeeper, btccKeeper, + ckptKeeper, &chaincfg.SimNetParams, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index c52c84f8b..bbe4d09c0 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -74,9 +74,8 @@ func TestFinalizedEpoch(t *testing.T) { // There is no finalized epoch yet so we require an error queryCustomErr(t, ctx, babylonApp, contractAddress, query) - epoch := babylonApp.EpochingKeeper.IncEpoch(ctx) - - _ = babylonApp.ZoneConciergeKeeper.Hooks().AfterRawCheckpointFinalized(ctx, epoch.EpochNumber) + epoch := babylonApp.EpochingKeeper.InitEpoch(ctx) + babylonApp.CheckpointingKeeper.SetCheckpointFinalized(ctx, epoch.EpochNumber) resp := bindings.LatestFinalizedEpochInfoResponse{} queryCustom(t, ctx, babylonApp, contractAddress, query, &resp) diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index c96ecd884..de0ce7dbd 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -56,7 +56,7 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag return bz, nil case contractQuery.LatestFinalizedEpochInfo != nil: - epoch, err := qp.zcKeeper.GetFinalizedEpoch(ctx) + epoch, err := qp.zcKeeper.GetLastFinalizedEpoch(ctx) if err != nil { return nil, err diff --git a/x/btcstaking/genesis_test.go b/x/btcstaking/genesis_test.go index 928def07c..357ccfe0d 100644 --- a/x/btcstaking/genesis_test.go +++ b/x/btcstaking/genesis_test.go @@ -16,7 +16,7 @@ func TestGenesis(t *testing.T) { Params: []*types.Params{&p}, } - k, ctx := keepertest.BTCStakingKeeper(t, nil, nil) + k, ctx := keepertest.BTCStakingKeeper(t, nil, nil, nil) btcstaking.InitGenesis(ctx, *k, genesisState) got := btcstaking.ExportGenesis(ctx, *k) require.NotNil(t, got) diff --git a/x/btcstaking/keeper/bench_test.go b/x/btcstaking/keeper/bench_test.go index 0e0333d16..405a9119f 100644 --- a/x/btcstaking/keeper/bench_test.go +++ b/x/btcstaking/keeper/bench_test.go @@ -23,7 +23,8 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { defer ctrl.Finish() btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(b, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(b, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) diff --git a/x/btcstaking/keeper/btc_height_index_test.go b/x/btcstaking/keeper/btc_height_index_test.go index b874b3750..819e92dd3 100644 --- a/x/btcstaking/keeper/btc_height_index_test.go +++ b/x/btcstaking/keeper/btc_height_index_test.go @@ -22,7 +22,7 @@ func FuzzBTCHeightIndex(f *testing.F) { // mock BTC light client btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) - keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, nil) + keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, nil, nil) // randomise Babylon height and BTC height babylonHeight := datagen.RandomInt(r, 100) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index fa6a6a7ae..5790c9ad0 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -192,6 +192,7 @@ func (k Keeper) ActiveFinalityProvidersAtHeight(ctx context.Context, req *types. MasterPubRand: finalityProvider.MasterPubRand, SlashedBabylonHeight: finalityProvider.SlashedBabylonHeight, SlashedBtcHeight: finalityProvider.SlashedBtcHeight, + RegisteredEpoch: finalityProvider.RegisteredEpoch, } finalityProvidersWithMeta = append(finalityProvidersWithMeta, &finalityProviderWithMeta) } diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index d85095278..a5868cac9 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -27,7 +27,7 @@ func FuzzActivatedHeight(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // not activated yet @@ -52,7 +52,7 @@ func FuzzFinalityProviders(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // Generate random finality providers and add them to kv store @@ -117,7 +117,7 @@ func FuzzFinalityProvider(f *testing.F) { f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) ctx = sdk.UnwrapSDKContext(ctx) // Generate random finality providers and add them to kv store @@ -173,7 +173,8 @@ func FuzzPendingBTCDelegations(f *testing.F) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -273,7 +274,7 @@ func FuzzFinalityProviderPowerAtHeight(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) // random finality provider fp, err := datagen.GenRandomFinalityProvider(r) @@ -322,7 +323,7 @@ func FuzzFinalityProviderCurrentVotingPower(f *testing.F) { r := rand.New(rand.NewSource(seed)) // Setup keeper and context - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) // random finality provider fp, err := datagen.GenRandomFinalityProvider(r) @@ -374,7 +375,8 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 10}).AnyTimes() btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) @@ -491,7 +493,8 @@ func FuzzFinalityProviderDelegations(f *testing.F) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 09a75efeb..7adac41a6 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -22,7 +22,8 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index d239b4aff..ee16b0250 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -20,6 +20,7 @@ type ( btclcKeeper types.BTCLightClientKeeper btccKeeper types.BtcCheckpointKeeper + ckptKeeper types.CheckpointingKeeper btcNet *chaincfg.Params // the address capable of executing a MsgUpdateParams message. Typically, this @@ -34,6 +35,7 @@ func NewKeeper( btclcKeeper types.BTCLightClientKeeper, btccKeeper types.BtcCheckpointKeeper, + ckptKeeper types.CheckpointingKeeper, btcNet *chaincfg.Params, authority string, @@ -44,6 +46,7 @@ func NewKeeper( btclcKeeper: btclcKeeper, btccKeeper: btccKeeper, + ckptKeeper: ckptKeeper, btcNet: btcNet, authority: authority, @@ -67,3 +70,7 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { return nil } + +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + return k.ckptKeeper.GetLastFinalizedEpoch(ctx) +} diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index b324cf329..53ad2e405 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -14,6 +14,7 @@ import ( btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" + etypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" @@ -30,12 +31,13 @@ type Helper struct { BTCStakingKeeper *keeper.Keeper BTCLightClientKeeper *types.MockBTCLightClientKeeper BTCCheckpointKeeper *types.MockBtcCheckpointKeeper + CheckpointingKeeper *types.MockCheckpointingKeeper MsgServer types.MsgServer Net *chaincfg.Params } -func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKeeper *types.MockBtcCheckpointKeeper) *Helper { - k, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper) +func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKeeper *types.MockBtcCheckpointKeeper, ckptKeeper *types.MockCheckpointingKeeper) *Helper { + k, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) ctx = ctx.WithHeaderInfo(header.Info{Height: 1}) msgSrvr := keeper.NewMsgServerImpl(*k) @@ -45,6 +47,7 @@ func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKe BTCStakingKeeper: k, BTCLightClientKeeper: btclcKeeper, BTCCheckpointKeeper: btccKeeper, + CheckpointingKeeper: ckptKeeper, MsgServer: msgSrvr, Net: &chaincfg.SimNetParams, } @@ -134,6 +137,11 @@ func (h *Helper) CreateFinalityProvider(r *rand.Rand) (*btcec.PrivateKey, *btcec fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBBNSK, msr) h.NoError(err) + registeredEpoch := uint64(10) + fp.RegisteredEpoch = registeredEpoch + + h.CheckpointingKeeper.EXPECT().GetEpoch(gomock.Eq(h.Ctx)).Return(&etypes.Epoch{EpochNumber: registeredEpoch}).Times(1) + msgNewFp := types.MsgCreateFinalityProvider{ Signer: datagen.GenRandomAccount().Address, Description: fp.Description, @@ -143,6 +151,7 @@ func (h *Helper) CreateFinalityProvider(r *rand.Rand) (*btcec.PrivateKey, *btcec Pop: fp.Pop, MasterPubRand: fp.MasterPubRand, } + _, err = h.MsgServer.CreateFinalityProvider(h.Ctx, &msgNewFp) h.NoError(err) return fpBTCSK, fpBTCPK, fp diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 1c81a3be4..067ccac88 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -88,12 +88,13 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg // all good, add this finality provider fp := types.FinalityProvider{ - Description: req.Description, - Commission: req.Commission, - BabylonPk: req.BabylonPk, - BtcPk: req.BtcPk, - Pop: req.Pop, - MasterPubRand: req.MasterPubRand, + Description: req.Description, + Commission: req.Commission, + BabylonPk: req.BabylonPk, + BtcPk: req.BtcPk, + Pop: req.Pop, + MasterPubRand: req.MasterPubRand, + RegisteredEpoch: ms.ckptKeeper.GetEpoch(ctx).EpochNumber, } ms.SetFinalityProvider(ctx, &fp) diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 9d631eb93..fc1ad15b0 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -16,6 +16,7 @@ import ( btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" + etypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" @@ -32,13 +33,26 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - h := NewHelper(t, nil, nil) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // mock BTC light client and BTC checkpoint modules + btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) + btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) + + // set all parameters + h.GenAndApplyParams(r) // generate new finality providers fps := []*types.FinalityProvider{} for i := 0; i < int(datagen.RandomInt(r, 10)); i++ { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) + + h.CheckpointingKeeper.EXPECT().GetEpoch(gomock.Eq(h.Ctx)).Return(&etypes.Epoch{EpochNumber: 10}).Times(1) + msg := &types.MsgCreateFinalityProvider{ Signer: datagen.GenRandomAccount().Address, Description: fp.Description, @@ -139,7 +153,8 @@ func FuzzCreateBTCDelegation(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters h.GenAndApplyParams(r) @@ -183,7 +198,8 @@ func TestProperVersionInDelegation(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters h.GenAndApplyParams(r) @@ -250,7 +266,8 @@ func FuzzAddCovenantSigs(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -314,7 +331,8 @@ func FuzzBTCUndelegate(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -386,7 +404,8 @@ func FuzzSelectiveSlashing(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -452,7 +471,8 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -528,7 +548,8 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes() - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set covenant PK to params _, covenantPKs := h.GenAndApplyParams(r) @@ -695,7 +716,8 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters _, _ = h.GenAndApplyCustomParams(r, tt.finalizationTimeout, tt.minUnbondingTime) @@ -767,7 +789,8 @@ func TestMinimalUnbondingRate(t *testing.T) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters, by default minimal unbonding value is 80% of staking value _, _ = h.GenAndApplyParams(r) diff --git a/x/btcstaking/keeper/params_test.go b/x/btcstaking/keeper/params_test.go index 3c1ac1562..18056c153 100644 --- a/x/btcstaking/keeper/params_test.go +++ b/x/btcstaking/keeper/params_test.go @@ -12,7 +12,7 @@ import ( ) func TestGetParams(t *testing.T) { - k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) params := types.DefaultParams() err := k.SetParams(ctx, params) @@ -22,7 +22,7 @@ func TestGetParams(t *testing.T) { } func TestGetParamsVersions(t *testing.T) { - k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) params := types.DefaultParams() pv := k.GetParamsWithVersion(ctx) @@ -55,7 +55,7 @@ func FuzzParamsVersioning(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + k, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) numVersionsToGenerate := r.Intn(100) + 1 params0 := k.GetParams(ctx) var generatedParams []*types.Params diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index a37776ee7..da4ec9502 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -23,7 +23,8 @@ func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters h.GenAndApplyParams(r) @@ -74,7 +75,8 @@ func FuzzFinalityProviderEvents(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -151,7 +153,8 @@ func FuzzBTCDelegationEvents(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) diff --git a/x/btcstaking/keeper/query_params_test.go b/x/btcstaking/keeper/query_params_test.go index 6c4e8cbb8..fefd0ae45 100644 --- a/x/btcstaking/keeper/query_params_test.go +++ b/x/btcstaking/keeper/query_params_test.go @@ -9,7 +9,7 @@ import ( ) func TestParamsQuery(t *testing.T) { - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) params := types.DefaultParams() err := keeper.SetParams(ctx, params) @@ -21,7 +21,7 @@ func TestParamsQuery(t *testing.T) { } func TestParamsByVersionQuery(t *testing.T) { - keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil) + keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil) // starting with `1` as BTCStakingKeeper creates params with version 0 params1 := types.DefaultParams() diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index 0696d8708..82ac32e6d 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -23,7 +23,8 @@ func FuzzVotingPowerTable(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -161,7 +162,8 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) @@ -245,7 +247,8 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { // mock BTC light client and BTC checkpoint modules btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl) btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl) - h := NewHelper(t, btclcKeeper, btccKeeper) + ckptKeeper := types.NewMockCheckpointingKeeper(ctrl) + h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper) // set all parameters covenantSKs, _ := h.GenAndApplyParams(r) diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index b7cb360e9..3c46186df 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -85,14 +85,16 @@ type FinalityProvider struct { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` + // registered_epoch is the epoch when this finality provider is registered + RegisteredEpoch uint64 `protobuf:"varint,7,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,7,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,8,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,8,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,9,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProvider) Reset() { *m = FinalityProvider{} } @@ -156,6 +158,13 @@ func (m *FinalityProvider) GetMasterPubRand() string { return "" } +func (m *FinalityProvider) GetRegisteredEpoch() uint64 { + if m != nil { + return m.RegisteredEpoch + } + return 0 +} + func (m *FinalityProvider) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -182,14 +191,16 @@ type FinalityProviderWithMeta struct { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string MasterPubRand string `protobuf:"bytes,4,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` + // registered_epoch is the epoch when this finality provider is registered + RegisteredEpoch uint64 `protobuf:"varint,5,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,5,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,6,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProviderWithMeta) Reset() { *m = FinalityProviderWithMeta{} } @@ -246,6 +257,13 @@ func (m *FinalityProviderWithMeta) GetMasterPubRand() string { return "" } +func (m *FinalityProviderWithMeta) GetRegisteredEpoch() uint64 { + if m != nil { + return m.RegisteredEpoch + } + return 0 +} + func (m *FinalityProviderWithMeta) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -764,84 +782,86 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1226 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xdb, 0x6e, 0x1b, 0x45, - 0x18, 0xce, 0xda, 0x8e, 0x53, 0xff, 0xb6, 0x1b, 0x77, 0x9a, 0xa6, 0xdb, 0x46, 0x24, 0xc6, 0x94, - 0xca, 0x42, 0xd4, 0x6e, 0xd2, 0x83, 0x80, 0x0b, 0xa4, 0x3a, 0x4e, 0x69, 0xd4, 0x36, 0x35, 0xeb, - 0xa4, 0x08, 0x90, 0x58, 0xcd, 0xee, 0x8e, 0xed, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, 0x87, - 0x40, 0xe2, 0x96, 0x7b, 0x1e, 0x80, 0x0b, 0x9e, 0x01, 0x71, 0x59, 0x71, 0x85, 0x72, 0x11, 0xa1, - 0xf6, 0x01, 0x78, 0x04, 0xd0, 0x1c, 0xbc, 0xb6, 0xdb, 0x04, 0x68, 0xdd, 0x3b, 0xef, 0x7f, 0xf8, - 0xfe, 0xc3, 0xf7, 0x79, 0x66, 0x17, 0xae, 0x3b, 0xd8, 0x19, 0xf7, 0x68, 0x50, 0x75, 0xb8, 0xcb, - 0x38, 0xee, 0xfa, 0x41, 0xbb, 0x3a, 0xdc, 0x9e, 0x79, 0xaa, 0x84, 0x11, 0xe5, 0x14, 0x5d, 0xd2, - 0x71, 0x95, 0x19, 0xcf, 0x70, 0xfb, 0xea, 0x5a, 0x9b, 0xb6, 0xa9, 0x8c, 0xa8, 0x8a, 0x5f, 0x2a, - 0xf8, 0xea, 0x15, 0x97, 0xb2, 0x3e, 0x65, 0xb6, 0x72, 0xa8, 0x07, 0xed, 0x2a, 0xa9, 0xa7, 0xaa, - 0x1b, 0x8d, 0x43, 0x4e, 0xab, 0x8c, 0xb8, 0xe1, 0xce, 0x9d, 0xbb, 0xdd, 0xed, 0x6a, 0x97, 0x8c, - 0x27, 0x31, 0xd7, 0x74, 0xcc, 0xb4, 0x1f, 0x87, 0x70, 0xbc, 0x5d, 0x9d, 0xeb, 0xe8, 0xea, 0xd6, - 0xe9, 0x9d, 0x87, 0x34, 0x54, 0x01, 0xa5, 0xbf, 0x93, 0x50, 0xb8, 0xef, 0x07, 0xb8, 0xe7, 0xf3, - 0x71, 0x23, 0xa2, 0x43, 0xdf, 0x23, 0x11, 0xda, 0x83, 0xac, 0x47, 0x98, 0x1b, 0xf9, 0x21, 0xf7, - 0x69, 0x60, 0x1a, 0x45, 0xa3, 0x9c, 0xdd, 0x79, 0xaf, 0xa2, 0x7b, 0x9c, 0x4e, 0x26, 0x2b, 0x56, - 0xea, 0xd3, 0x50, 0x6b, 0x36, 0x0f, 0x3d, 0x06, 0x70, 0x69, 0xbf, 0xef, 0x33, 0x26, 0x50, 0x12, - 0x45, 0xa3, 0x9c, 0xa9, 0xdd, 0x38, 0x3e, 0xd9, 0xda, 0x50, 0x40, 0xcc, 0xeb, 0x56, 0x7c, 0x5a, - 0xed, 0x63, 0xde, 0xa9, 0x3c, 0x22, 0x6d, 0xec, 0x8e, 0xeb, 0xc4, 0xfd, 0xfd, 0x97, 0x1b, 0xa0, - 0xeb, 0xd4, 0x89, 0x6b, 0xcd, 0x00, 0xa0, 0x4f, 0x01, 0xf4, 0x34, 0x76, 0xd8, 0x35, 0x93, 0xb2, - 0xa9, 0xad, 0x49, 0x53, 0x6a, 0x55, 0x95, 0x78, 0x55, 0x95, 0xc6, 0xc0, 0x79, 0x48, 0xc6, 0x56, - 0x46, 0xa7, 0x34, 0xba, 0xe8, 0x31, 0xa4, 0x1d, 0xee, 0x8a, 0xdc, 0x54, 0xd1, 0x28, 0xe7, 0x6a, - 0x77, 0x8f, 0x4f, 0xb6, 0x76, 0xda, 0x3e, 0xef, 0x0c, 0x9c, 0x8a, 0x4b, 0xfb, 0x55, 0x1d, 0xe9, - 0x76, 0xb0, 0x1f, 0x4c, 0x1e, 0xaa, 0x7c, 0x1c, 0x12, 0x56, 0xa9, 0xed, 0x37, 0x6e, 0xdd, 0xbe, - 0xa9, 0x21, 0x97, 0x1d, 0xee, 0x36, 0xba, 0xe8, 0x13, 0x48, 0x86, 0x34, 0x34, 0x97, 0x65, 0x1f, - 0xe5, 0xca, 0xa9, 0xd4, 0x57, 0x1a, 0x11, 0xa5, 0xad, 0x27, 0xad, 0x06, 0x65, 0x8c, 0xc8, 0x29, - 0x2c, 0x91, 0x84, 0xae, 0xc3, 0x6a, 0x1f, 0x33, 0x4e, 0x22, 0x3b, 0x1c, 0x38, 0x76, 0x84, 0x03, - 0xcf, 0x4c, 0x8b, 0xf5, 0x58, 0x79, 0x65, 0x6e, 0x0c, 0x1c, 0x0b, 0x07, 0x1e, 0xba, 0x0d, 0xeb, - 0xac, 0x87, 0x59, 0x87, 0x78, 0xf6, 0x64, 0xf4, 0x0e, 0xf1, 0xdb, 0x1d, 0x6e, 0xae, 0x14, 0x8d, - 0x72, 0xca, 0x5a, 0xd3, 0xde, 0x9a, 0x72, 0x3e, 0x90, 0x3e, 0xf4, 0x21, 0xa0, 0x38, 0x8b, 0xbb, - 0x93, 0x8c, 0x73, 0x32, 0xa3, 0x30, 0xc9, 0xe0, 0xae, 0x8a, 0x2e, 0xfd, 0x9c, 0x00, 0xf3, 0x65, - 0x05, 0x7c, 0xe1, 0xf3, 0xce, 0x63, 0xc2, 0xf1, 0xcc, 0xce, 0x8c, 0xb7, 0xb1, 0xb3, 0x75, 0x48, - 0xeb, 0x6e, 0x12, 0xb2, 0x1b, 0xfd, 0x84, 0xde, 0x85, 0xdc, 0x90, 0x72, 0x3f, 0x68, 0xdb, 0x21, - 0xfd, 0x8e, 0x44, 0x92, 0xdc, 0x94, 0x95, 0x55, 0xb6, 0x86, 0x30, 0x9d, 0xb6, 0xb2, 0xd4, 0xeb, - 0xad, 0x6c, 0xf9, 0xb5, 0x57, 0x96, 0x3e, 0x63, 0x65, 0x7f, 0xa5, 0x21, 0x5f, 0x3b, 0xdc, 0xad, - 0x93, 0x1e, 0x69, 0x63, 0xfe, 0xaa, 0x36, 0x8d, 0x05, 0xb4, 0x99, 0x78, 0x8b, 0xda, 0x4c, 0xbe, - 0x89, 0x36, 0xbf, 0x86, 0xf3, 0xad, 0xd0, 0x56, 0xdd, 0xd8, 0x3d, 0x9f, 0x71, 0x33, 0x55, 0x4c, - 0x2e, 0xd0, 0x52, 0xb6, 0x15, 0xd6, 0x44, 0x53, 0x8f, 0x7c, 0x26, 0x89, 0x66, 0x1c, 0x47, 0x7c, - 0x9e, 0x93, 0xac, 0xb4, 0x69, 0x2a, 0xde, 0x01, 0x20, 0x81, 0x37, 0x4f, 0x41, 0x86, 0x04, 0x9e, - 0x76, 0x6f, 0x40, 0x86, 0x53, 0x8e, 0x7b, 0x36, 0xc3, 0x93, 0x7f, 0xc1, 0x39, 0x69, 0x68, 0x62, - 0x99, 0xab, 0x07, 0xb4, 0xf9, 0x48, 0x2a, 0x3e, 0x67, 0x65, 0xb4, 0xe5, 0x70, 0x24, 0x59, 0xd6, - 0x6e, 0x3a, 0xe0, 0xe1, 0x80, 0xdb, 0xbe, 0x37, 0x32, 0x33, 0x45, 0xa3, 0x9c, 0xb7, 0x0a, 0xda, - 0xf3, 0x44, 0x3a, 0xf6, 0xbd, 0x11, 0xda, 0x81, 0xac, 0x64, 0x5e, 0xa3, 0x81, 0x24, 0xe6, 0xc2, - 0xf1, 0xc9, 0x96, 0xe0, 0xbe, 0xa9, 0x3d, 0x87, 0x23, 0x0b, 0x58, 0xfc, 0x1b, 0x7d, 0x03, 0x79, - 0x4f, 0xa9, 0x82, 0x46, 0x36, 0xf3, 0xdb, 0x66, 0x56, 0x66, 0x7d, 0x7c, 0x7c, 0xb2, 0x75, 0xe7, - 0x75, 0x76, 0xd7, 0xf4, 0xdb, 0x01, 0xe6, 0x83, 0x88, 0x58, 0xb9, 0x18, 0xaf, 0xe9, 0xb7, 0xd1, - 0x11, 0xe4, 0x5d, 0x3a, 0x24, 0x01, 0x0e, 0xb8, 0x80, 0x67, 0x66, 0xae, 0x98, 0x2c, 0x67, 0x77, - 0x6e, 0x9e, 0x41, 0xf1, 0xae, 0x8e, 0xbd, 0xe7, 0xe1, 0x50, 0x21, 0x28, 0x54, 0x66, 0xe5, 0x26, - 0x30, 0x4d, 0xbf, 0xcd, 0xd0, 0xfb, 0x70, 0x7e, 0x10, 0x38, 0x34, 0xf0, 0xe4, 0xac, 0x7e, 0x9f, - 0x98, 0x79, 0xb9, 0x94, 0x7c, 0x6c, 0x3d, 0xf4, 0xfb, 0x04, 0x7d, 0x0e, 0x05, 0xa1, 0x8b, 0x41, - 0xe0, 0xc5, 0xca, 0x37, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa3, 0x81, 0xda, 0xe1, 0xee, 0xd1, 0x4c, - 0xb4, 0xb5, 0xea, 0x70, 0x77, 0xd6, 0x20, 0x2a, 0x87, 0x38, 0xc2, 0x7d, 0x66, 0x0f, 0x49, 0x24, - 0xef, 0x89, 0x55, 0x55, 0x59, 0x59, 0x9f, 0x2a, 0x63, 0xe9, 0xc7, 0x14, 0xac, 0xbe, 0x84, 0x25, - 0xb4, 0x34, 0xd3, 0xf4, 0x48, 0x9d, 0x50, 0x56, 0x76, 0xda, 0xf2, 0x2b, 0x14, 0x26, 0xfe, 0x0f, - 0x85, 0xdf, 0xc2, 0xe5, 0x29, 0x85, 0xd3, 0x02, 0x82, 0xcc, 0xe4, 0xa2, 0x64, 0x5e, 0x8a, 0x91, - 0x8f, 0x26, 0xc0, 0x82, 0x55, 0x0a, 0xeb, 0x33, 0xaa, 0x99, 0x34, 0x2c, 0x2a, 0xa6, 0x16, 0xad, - 0xb8, 0x36, 0x95, 0x8f, 0xc6, 0x15, 0x05, 0x5b, 0xb0, 0x3e, 0x95, 0xd1, 0x4c, 0x3d, 0x66, 0x2e, - 0xbf, 0xa1, 0x9e, 0xd6, 0x62, 0x3d, 0x4d, 0xcb, 0x30, 0xe4, 0xc2, 0x46, 0x5c, 0x67, 0x6e, 0x95, - 0xea, 0x60, 0x49, 0xcb, 0x62, 0xd7, 0xce, 0x28, 0x16, 0xa3, 0xef, 0x07, 0x2d, 0x6a, 0x99, 0x13, - 0xa0, 0xd9, 0xcd, 0x89, 0x33, 0xa5, 0xd4, 0x84, 0xcb, 0xd3, 0xc3, 0x98, 0x46, 0xd3, 0x53, 0x99, - 0xa1, 0x8f, 0x20, 0xe5, 0x91, 0x1e, 0x33, 0x8d, 0x7f, 0x2d, 0x34, 0x77, 0x94, 0x5b, 0x32, 0xa3, - 0x74, 0x00, 0x1b, 0xa7, 0x83, 0xee, 0x07, 0x1e, 0x19, 0xa1, 0x2a, 0xac, 0x4d, 0x0f, 0x1a, 0xbb, - 0x83, 0x59, 0x47, 0x4d, 0x24, 0x0a, 0xe5, 0xac, 0x0b, 0xf1, 0x91, 0xf3, 0x00, 0xb3, 0x8e, 0x6c, - 0xf2, 0x27, 0x03, 0xf2, 0x73, 0x03, 0xa1, 0xfb, 0x90, 0x58, 0xf8, 0x5a, 0x4d, 0x84, 0x5d, 0xf4, - 0x10, 0x92, 0x42, 0x29, 0x89, 0x45, 0x95, 0x22, 0x50, 0x4a, 0xdf, 0x1b, 0x70, 0xe5, 0x4c, 0x92, - 0xc5, 0x2d, 0xe5, 0xd2, 0xe1, 0x5b, 0x78, 0x1b, 0x70, 0xe9, 0xb0, 0xd1, 0x15, 0x7f, 0x60, 0xac, - 0x6a, 0x28, 0xed, 0x25, 0xe4, 0xf2, 0xb2, 0x38, 0xae, 0xcb, 0x4a, 0xbf, 0x1a, 0x70, 0xa5, 0x49, - 0x7a, 0xc4, 0xe5, 0xfe, 0x90, 0x4c, 0xa4, 0xb5, 0x27, 0xde, 0x51, 0x02, 0x97, 0x88, 0x77, 0x82, - 0x97, 0x58, 0x90, 0x8d, 0x65, 0xac, 0xfc, 0x1c, 0x01, 0xc8, 0x82, 0x4c, 0x7c, 0xa5, 0x2d, 0x78, - 0xc1, 0xae, 0xe8, 0xdb, 0x0c, 0xdd, 0x80, 0x8b, 0x11, 0x11, 0x9a, 0x8c, 0x88, 0x67, 0x6b, 0x74, - 0xa6, 0x5e, 0x4b, 0x73, 0x56, 0x21, 0x76, 0xdd, 0x17, 0xe1, 0xcd, 0xee, 0x07, 0x7b, 0x70, 0x71, - 0x4e, 0x66, 0x4d, 0x8e, 0xf9, 0x80, 0xa1, 0x2c, 0xac, 0x34, 0xf6, 0x0e, 0xea, 0xfb, 0x07, 0x9f, - 0x15, 0x96, 0x10, 0x40, 0xfa, 0xde, 0xee, 0xe1, 0xfe, 0xd3, 0xbd, 0x82, 0x81, 0x72, 0x70, 0xee, - 0xe8, 0xa0, 0xf6, 0xe4, 0xa0, 0xbe, 0x57, 0x2f, 0x24, 0xd0, 0x0a, 0x24, 0xef, 0x1d, 0x7c, 0x59, - 0x48, 0xd6, 0x1e, 0xfd, 0xf6, 0x7c, 0xd3, 0x78, 0xf6, 0x7c, 0xd3, 0xf8, 0xf3, 0xf9, 0xa6, 0xf1, - 0xc3, 0x8b, 0xcd, 0xa5, 0x67, 0x2f, 0x36, 0x97, 0xfe, 0x78, 0xb1, 0xb9, 0xf4, 0xd5, 0x7f, 0x0e, - 0x33, 0x9a, 0xfd, 0x06, 0x90, 0x93, 0x39, 0x69, 0xf9, 0x0d, 0x70, 0xeb, 0x9f, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x1d, 0xc6, 0x0a, 0x0c, 0xe0, 0x0c, 0x00, 0x00, + // 1254 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5d, 0x6f, 0x1b, 0x45, + 0x17, 0xce, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x37, 0xc9, 0xeb, + 0xb7, 0x6f, 0x15, 0x10, 0xb5, 0x9b, 0xf4, 0x43, 0xc0, 0x05, 0x52, 0x1d, 0xbb, 0x34, 0x6a, 0x9b, + 0x9a, 0x75, 0x52, 0x04, 0x48, 0xac, 0x66, 0x77, 0x27, 0xeb, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, + 0xec, 0x1f, 0x81, 0xc4, 0x2d, 0xf7, 0x5c, 0x71, 0xcd, 0x6f, 0x40, 0x5c, 0x56, 0x5c, 0xa1, 0x20, + 0x45, 0xa8, 0xfd, 0x01, 0xfc, 0x05, 0x34, 0x33, 0xfb, 0x61, 0xb7, 0x09, 0xb4, 0x75, 0xef, 0x3c, + 0xe7, 0xe3, 0x39, 0x67, 0xce, 0xf3, 0xec, 0xcc, 0x18, 0xae, 0x5b, 0xd8, 0x9a, 0xf4, 0xa9, 0x5f, + 0xb7, 0xb8, 0xcd, 0x38, 0xee, 0x79, 0xbe, 0x5b, 0x1f, 0x6d, 0x4f, 0xad, 0x6a, 0x41, 0x48, 0x39, + 0x45, 0x97, 0xa2, 0xb8, 0xda, 0x94, 0x67, 0xb4, 0x7d, 0x75, 0xc5, 0xa5, 0x2e, 0x95, 0x11, 0x75, + 0xf1, 0x4b, 0x05, 0x5f, 0xbd, 0x62, 0x53, 0x36, 0xa0, 0xcc, 0x54, 0x0e, 0xb5, 0x88, 0x5c, 0x55, + 0xb5, 0xaa, 0xdb, 0xe1, 0x24, 0xe0, 0xb4, 0xce, 0x88, 0x1d, 0xec, 0xdc, 0xb9, 0xdb, 0xdb, 0xae, + 0xf7, 0xc8, 0x24, 0x8e, 0xb9, 0x16, 0xc5, 0xa4, 0xfd, 0x58, 0x84, 0xe3, 0xed, 0xfa, 0x4c, 0x47, + 0x57, 0x37, 0x4e, 0xef, 0x3c, 0xa0, 0x81, 0x0a, 0xa8, 0xfe, 0x94, 0x83, 0xca, 0x7d, 0xcf, 0xc7, + 0x7d, 0x8f, 0x4f, 0xda, 0x21, 0x1d, 0x79, 0x0e, 0x09, 0x51, 0x0b, 0x8a, 0x0e, 0x61, 0x76, 0xe8, + 0x05, 0xdc, 0xa3, 0xbe, 0xae, 0x6d, 0x6a, 0x5b, 0xc5, 0x9d, 0xff, 0xd5, 0xa2, 0x1e, 0xd3, 0x9d, + 0xc9, 0x8a, 0xb5, 0x66, 0x1a, 0x6a, 0x4c, 0xe7, 0xa1, 0xc7, 0x00, 0x36, 0x1d, 0x0c, 0x3c, 0xc6, + 0x04, 0x4a, 0x66, 0x53, 0xdb, 0x2a, 0x34, 0x6e, 0x1c, 0x9f, 0x6c, 0xac, 0x29, 0x20, 0xe6, 0xf4, + 0x6a, 0x1e, 0xad, 0x0f, 0x30, 0xef, 0xd6, 0x1e, 0x11, 0x17, 0xdb, 0x93, 0x26, 0xb1, 0x7f, 0xfb, + 0xf9, 0x06, 0x44, 0x75, 0x9a, 0xc4, 0x36, 0xa6, 0x00, 0xd0, 0x27, 0x00, 0xd1, 0x6e, 0xcc, 0xa0, + 0xa7, 0x67, 0x65, 0x53, 0x1b, 0x71, 0x53, 0x6a, 0x54, 0xb5, 0x64, 0x54, 0xb5, 0xf6, 0xd0, 0x7a, + 0x48, 0x26, 0x46, 0x21, 0x4a, 0x69, 0xf7, 0xd0, 0x63, 0xc8, 0x5b, 0xdc, 0x16, 0xb9, 0xb9, 0x4d, + 0x6d, 0xab, 0xd4, 0xb8, 0x7b, 0x7c, 0xb2, 0xb1, 0xe3, 0x7a, 0xbc, 0x3b, 0xb4, 0x6a, 0x36, 0x1d, + 0xd4, 0xa3, 0x48, 0xbb, 0x8b, 0x3d, 0x3f, 0x5e, 0xd4, 0xf9, 0x24, 0x20, 0xac, 0xd6, 0xd8, 0x6b, + 0xdf, 0xba, 0x7d, 0x33, 0x82, 0x5c, 0xb4, 0xb8, 0xdd, 0xee, 0xa1, 0x8f, 0x21, 0x1b, 0xd0, 0x40, + 0x5f, 0x94, 0x7d, 0x6c, 0xd5, 0x4e, 0xa5, 0xbe, 0xd6, 0x0e, 0x29, 0x3d, 0x7a, 0x72, 0xd4, 0xa6, + 0x8c, 0x11, 0xb9, 0x0b, 0x43, 0x24, 0xa1, 0xeb, 0xb0, 0x3c, 0xc0, 0x8c, 0x93, 0xd0, 0x0c, 0x86, + 0x96, 0x19, 0x62, 0xdf, 0xd1, 0xf3, 0x62, 0x3c, 0x46, 0x59, 0x99, 0xdb, 0x43, 0xcb, 0xc0, 0xbe, + 0x83, 0xde, 0x83, 0x4a, 0x48, 0x5c, 0x4f, 0x98, 0x88, 0x63, 0x92, 0x80, 0xda, 0x5d, 0x7d, 0x69, + 0x53, 0xdb, 0xca, 0x19, 0xcb, 0xa9, 0xbd, 0x25, 0xcc, 0xe8, 0x36, 0xac, 0xb2, 0x3e, 0x66, 0x5d, + 0xe2, 0x98, 0xf1, 0x94, 0xba, 0xc4, 0x73, 0xbb, 0x5c, 0x3f, 0x27, 0x13, 0x56, 0x22, 0x6f, 0x43, + 0x39, 0x1f, 0x48, 0x1f, 0xfa, 0x00, 0x50, 0x92, 0xc5, 0xed, 0x38, 0xa3, 0x20, 0x33, 0x2a, 0x71, + 0x06, 0xb7, 0x55, 0x74, 0xf5, 0x8f, 0x0c, 0xe8, 0x2f, 0x8b, 0xe5, 0x73, 0x8f, 0x77, 0x1f, 0x13, + 0x8e, 0xa7, 0xc6, 0xab, 0xbd, 0x8b, 0xf1, 0xae, 0x42, 0x3e, 0xea, 0x26, 0x23, 0xbb, 0x89, 0x56, + 0xe8, 0xbf, 0x50, 0x1a, 0x51, 0xee, 0xf9, 0xae, 0x19, 0xd0, 0x6f, 0x49, 0x28, 0x75, 0x90, 0x33, + 0x8a, 0xca, 0xd6, 0x16, 0xa6, 0xd3, 0xa6, 0x9b, 0x7b, 0xdd, 0xe9, 0x2e, 0xbe, 0xe9, 0x74, 0xf3, + 0x6f, 0x3c, 0xdd, 0xa5, 0x33, 0xa6, 0xfb, 0x57, 0x1e, 0xca, 0x8d, 0x83, 0xdd, 0x26, 0xe9, 0x13, + 0x17, 0xf3, 0x57, 0x15, 0xaf, 0xcd, 0xa1, 0xf8, 0xcc, 0x3b, 0x54, 0x7c, 0xf6, 0x6d, 0x14, 0xff, + 0x15, 0x9c, 0x3f, 0x0a, 0x4c, 0xd5, 0x8d, 0xd9, 0xf7, 0x18, 0xd7, 0x73, 0x9b, 0xd9, 0x39, 0x5a, + 0x2a, 0x1e, 0x05, 0x0d, 0xd1, 0xd4, 0x23, 0x8f, 0x49, 0x4d, 0x30, 0x8e, 0x43, 0x1e, 0x4f, 0x58, + 0x91, 0x58, 0x94, 0xb6, 0x88, 0x8a, 0xff, 0x00, 0x10, 0xdf, 0x99, 0x25, 0xad, 0x40, 0x7c, 0x27, + 0x72, 0xaf, 0x41, 0x81, 0x53, 0x8e, 0xfb, 0x26, 0xc3, 0x31, 0x41, 0xe7, 0xa4, 0xa1, 0x83, 0x65, + 0x6e, 0xb4, 0x41, 0x93, 0x8f, 0xe5, 0xe7, 0x54, 0x32, 0x0a, 0x91, 0xe5, 0x60, 0x2c, 0x59, 0x8e, + 0xdc, 0x74, 0xc8, 0x83, 0x21, 0x37, 0x3d, 0x67, 0x2c, 0xbf, 0xa1, 0xb2, 0x51, 0x89, 0x3c, 0x4f, + 0xa4, 0x63, 0xcf, 0x19, 0xa3, 0x1d, 0x28, 0x4a, 0xe6, 0x23, 0x34, 0x90, 0xc4, 0x5c, 0x38, 0x3e, + 0xd9, 0x10, 0xdc, 0x77, 0x22, 0xcf, 0xc1, 0xd8, 0x00, 0x96, 0xfc, 0x46, 0x5f, 0x43, 0xd9, 0x51, + 0xaa, 0xa0, 0xa1, 0xc9, 0x3c, 0x57, 0x2f, 0xca, 0xac, 0x8f, 0x8e, 0x4f, 0x36, 0xee, 0xbc, 0xc9, + 0xec, 0x3a, 0x9e, 0xeb, 0x63, 0x3e, 0x0c, 0x89, 0x51, 0x4a, 0xf0, 0x3a, 0x9e, 0x8b, 0x0e, 0xa1, + 0x6c, 0xd3, 0x11, 0xf1, 0xb1, 0xcf, 0x05, 0x3c, 0xd3, 0x4b, 0x9b, 0xd9, 0xad, 0xe2, 0xce, 0xcd, + 0x33, 0x28, 0xde, 0x8d, 0x62, 0xef, 0x39, 0x38, 0x50, 0x08, 0x0a, 0x95, 0x19, 0xa5, 0x18, 0xa6, + 0xe3, 0xb9, 0x0c, 0xfd, 0x1f, 0xce, 0x0f, 0x7d, 0x8b, 0xfa, 0x8e, 0xdc, 0xab, 0x37, 0x20, 0x7a, + 0x59, 0x0e, 0xa5, 0x9c, 0x58, 0x0f, 0xbc, 0x01, 0x41, 0x9f, 0x41, 0x45, 0xe8, 0x62, 0xe8, 0x3b, + 0x89, 0xf2, 0xf5, 0xf3, 0x52, 0x63, 0xd7, 0xcf, 0x68, 0xa0, 0x71, 0xb0, 0x7b, 0x38, 0x15, 0x6d, + 0x2c, 0x5b, 0xdc, 0x9e, 0x36, 0x88, 0xca, 0x01, 0x0e, 0xf1, 0x80, 0x99, 0x23, 0x12, 0xca, 0xdb, + 0x67, 0x59, 0x55, 0x56, 0xd6, 0xa7, 0xca, 0x58, 0xfd, 0x21, 0x07, 0xcb, 0x2f, 0x61, 0x09, 0x2d, + 0x4d, 0x35, 0x3d, 0x56, 0x87, 0x99, 0x51, 0x4c, 0x5b, 0x7e, 0x85, 0xc2, 0xcc, 0xeb, 0x50, 0xf8, + 0x0d, 0x5c, 0x4e, 0x29, 0x4c, 0x0b, 0x08, 0x32, 0xb3, 0xf3, 0x92, 0x79, 0x29, 0x41, 0x3e, 0x8c, + 0x81, 0x05, 0xab, 0x14, 0x56, 0xa7, 0x54, 0x13, 0x37, 0x2c, 0x2a, 0xe6, 0xe6, 0xad, 0xb8, 0x92, + 0xca, 0x27, 0xc2, 0x15, 0x05, 0x8f, 0x60, 0x35, 0x95, 0xd1, 0x54, 0x3d, 0xa6, 0x2f, 0xbe, 0xa5, + 0x9e, 0x56, 0x12, 0x3d, 0xa5, 0x65, 0x18, 0xb2, 0x61, 0x2d, 0xa9, 0x33, 0x33, 0x4a, 0x75, 0xb0, + 0xe4, 0x65, 0xb1, 0x6b, 0x67, 0x14, 0x4b, 0xd0, 0xf7, 0xfc, 0x23, 0x6a, 0xe8, 0x31, 0xd0, 0xf4, + 0xe4, 0xc4, 0x99, 0x52, 0xed, 0xc0, 0xe5, 0xf4, 0x30, 0xa6, 0x61, 0x7a, 0x2a, 0x33, 0xf4, 0x21, + 0xe4, 0x1c, 0xd2, 0x67, 0xba, 0xf6, 0x8f, 0x85, 0x66, 0x8e, 0x72, 0x43, 0x66, 0x54, 0xf7, 0x61, + 0xed, 0x74, 0xd0, 0x3d, 0xdf, 0x21, 0x63, 0x54, 0x87, 0x95, 0xf4, 0xa0, 0x31, 0xbb, 0x98, 0x75, + 0xd5, 0x8e, 0x44, 0xa1, 0x92, 0x71, 0x21, 0x39, 0x72, 0x1e, 0x60, 0xd6, 0x95, 0x4d, 0xfe, 0xa8, + 0x41, 0x79, 0x66, 0x43, 0xe8, 0x3e, 0x64, 0xe6, 0xbe, 0x81, 0x33, 0x41, 0x0f, 0x3d, 0x84, 0xac, + 0x50, 0x4a, 0x66, 0x5e, 0xa5, 0x08, 0x94, 0xea, 0x77, 0x1a, 0x5c, 0x39, 0x93, 0x64, 0x71, 0x4b, + 0xd9, 0x74, 0xf4, 0x0e, 0x1e, 0x0e, 0x36, 0x1d, 0xb5, 0x7b, 0xe2, 0x03, 0xc6, 0xaa, 0x86, 0xd2, + 0x5e, 0x46, 0x0e, 0xaf, 0x88, 0x93, 0xba, 0xac, 0xfa, 0x8b, 0x06, 0x57, 0x3a, 0xa4, 0x4f, 0x6c, + 0xee, 0x8d, 0x48, 0x2c, 0xad, 0x96, 0x78, 0xce, 0xf8, 0x36, 0x11, 0xcf, 0x87, 0x97, 0x58, 0x90, + 0x8d, 0x15, 0x8c, 0xf2, 0x0c, 0x01, 0xc8, 0x80, 0x42, 0x72, 0xa5, 0xcd, 0x79, 0xc1, 0x2e, 0x45, + 0xb7, 0x19, 0xba, 0x01, 0x17, 0x43, 0x22, 0x34, 0x29, 0x5e, 0x24, 0x11, 0x3a, 0x53, 0x8f, 0xdd, + 0x92, 0x51, 0x49, 0x5c, 0xf7, 0x45, 0x78, 0xa7, 0xf7, 0x7e, 0x0b, 0x2e, 0xce, 0xc8, 0xac, 0xc3, + 0x31, 0x1f, 0x32, 0x54, 0x84, 0xa5, 0x76, 0x6b, 0xbf, 0xb9, 0xb7, 0xff, 0x69, 0x65, 0x01, 0x01, + 0xe4, 0xef, 0xed, 0x1e, 0xec, 0x3d, 0x6d, 0x55, 0x34, 0x54, 0x82, 0x73, 0x87, 0xfb, 0x8d, 0x27, + 0xfb, 0xcd, 0x56, 0xb3, 0x92, 0x41, 0x4b, 0x90, 0xbd, 0xb7, 0xff, 0x45, 0x25, 0xdb, 0x78, 0xf4, + 0xeb, 0xf3, 0x75, 0xed, 0xd9, 0xf3, 0x75, 0xed, 0xcf, 0xe7, 0xeb, 0xda, 0xf7, 0x2f, 0xd6, 0x17, + 0x9e, 0xbd, 0x58, 0x5f, 0xf8, 0xfd, 0xc5, 0xfa, 0xc2, 0x97, 0xff, 0xba, 0x99, 0xf1, 0xf4, 0x3f, + 0x0b, 0xb9, 0x33, 0x2b, 0x2f, 0xff, 0x59, 0xdc, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x55, 0xdf, + 0x12, 0xf0, 0x36, 0x0d, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -867,11 +887,16 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x40 + dAtA[i] = 0x48 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- + dAtA[i] = 0x40 + } + if m.RegisteredEpoch != 0 { + i = encodeVarintBtcstaking(dAtA, i, uint64(m.RegisteredEpoch)) + i-- dAtA[i] = 0x38 } if len(m.MasterPubRand) > 0 { @@ -967,11 +992,16 @@ func (m *FinalityProviderWithMeta) MarshalToSizedBuffer(dAtA []byte) (int, error if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x38 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- + dAtA[i] = 0x30 + } + if m.RegisteredEpoch != 0 { + i = encodeVarintBtcstaking(dAtA, i, uint64(m.RegisteredEpoch)) + i-- dAtA[i] = 0x28 } if len(m.MasterPubRand) > 0 { @@ -1510,6 +1540,9 @@ func (m *FinalityProvider) Size() (n int) { if l > 0 { n += 1 + l + sovBtcstaking(uint64(l)) } + if m.RegisteredEpoch != 0 { + n += 1 + sovBtcstaking(uint64(m.RegisteredEpoch)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1539,6 +1572,9 @@ func (m *FinalityProviderWithMeta) Size() (n int) { if l > 0 { n += 1 + l + sovBtcstaking(uint64(l)) } + if m.RegisteredEpoch != 0 { + n += 1 + sovBtcstaking(uint64(m.RegisteredEpoch)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1986,6 +2022,25 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { m.MasterPubRand = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) + } + m.RegisteredEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RegisteredEpoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -2004,7 +2059,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { break } } - case 8: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -2179,6 +2234,25 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { m.MasterPubRand = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) + } + m.RegisteredEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RegisteredEpoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -2197,7 +2271,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { break } } - case 6: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } diff --git a/x/btcstaking/types/errors.go b/x/btcstaking/types/errors.go index 83f148368..5de1421d5 100644 --- a/x/btcstaking/types/errors.go +++ b/x/btcstaking/types/errors.go @@ -11,23 +11,24 @@ var ( ErrBTCDelegationNotFound = errorsmod.Register(ModuleName, 1102, "the BTC delegation is not found") ErrFpRegistered = errorsmod.Register(ModuleName, 1103, "the finality provider has already been registered") ErrFpAlreadySlashed = errorsmod.Register(ModuleName, 1104, "the finality provider has already been slashed") - ErrBTCStakingNotActivated = errorsmod.Register(ModuleName, 1105, "the BTC staking protocol is not activated yet") - ErrBTCHeightNotFound = errorsmod.Register(ModuleName, 1106, "the BTC height is not found") - ErrReusedStakingTx = errorsmod.Register(ModuleName, 1107, "the BTC staking tx is already used") - ErrInvalidCovenantPK = errorsmod.Register(ModuleName, 1108, "the BTC staking tx specifies a wrong covenant PK") - ErrInvalidStakingTx = errorsmod.Register(ModuleName, 1109, "the BTC staking tx is not valid") - ErrInvalidSlashingTx = errorsmod.Register(ModuleName, 1110, "the BTC slashing tx is not valid") - ErrInvalidCovenantSig = errorsmod.Register(ModuleName, 1111, "the covenant signature is not valid") - ErrCommissionLTMinRate = errorsmod.Register(ModuleName, 1112, "commission cannot be less than min rate") - ErrCommissionGTMaxRate = errorsmod.Register(ModuleName, 1113, "commission cannot be more than one") - ErrInvalidDelegationState = errorsmod.Register(ModuleName, 1114, "Unexpected delegation state") - ErrInvalidUnbondingTx = errorsmod.Register(ModuleName, 1115, "the BTC unbonding tx is not valid") - ErrRewardDistCacheNotFound = errorsmod.Register(ModuleName, 1116, "the reward distribution cache is not found") - ErrEmptyFpList = errorsmod.Register(ModuleName, 1117, "the finality provider list is empty") - ErrInvalidProofOfPossession = errorsmod.Register(ModuleName, 1118, "the proof of possession is not valid") - ErrDuplicatedFp = errorsmod.Register(ModuleName, 1119, "the staking request contains duplicated finality provider public key") - ErrInvalidBTCUndelegateReq = errorsmod.Register(ModuleName, 1120, "invalid undelegation request") - ErrVotingPowerTableNotUpdated = errorsmod.Register(ModuleName, 1121, "voting power table has not been updated") - ErrVotingPowerDistCacheNotFound = errorsmod.Register(ModuleName, 1122, "the voting power distribution cache is not found") - ErrParamsNotFound = errorsmod.Register(ModuleName, 1123, "the parameters are not found") + ErrFpNotBTCTimestamped = errorsmod.Register(ModuleName, 1105, "the finality provider is not BTC timestamped yet") + ErrBTCStakingNotActivated = errorsmod.Register(ModuleName, 1106, "the BTC staking protocol is not activated yet") + ErrBTCHeightNotFound = errorsmod.Register(ModuleName, 1107, "the BTC height is not found") + ErrReusedStakingTx = errorsmod.Register(ModuleName, 1108, "the BTC staking tx is already used") + ErrInvalidCovenantPK = errorsmod.Register(ModuleName, 1109, "the BTC staking tx specifies a wrong covenant PK") + ErrInvalidStakingTx = errorsmod.Register(ModuleName, 1110, "the BTC staking tx is not valid") + ErrInvalidSlashingTx = errorsmod.Register(ModuleName, 1111, "the BTC slashing tx is not valid") + ErrInvalidCovenantSig = errorsmod.Register(ModuleName, 1112, "the covenant signature is not valid") + ErrCommissionLTMinRate = errorsmod.Register(ModuleName, 1113, "commission cannot be less than min rate") + ErrCommissionGTMaxRate = errorsmod.Register(ModuleName, 1114, "commission cannot be more than one") + ErrInvalidDelegationState = errorsmod.Register(ModuleName, 1115, "Unexpected delegation state") + ErrInvalidUnbondingTx = errorsmod.Register(ModuleName, 1116, "the BTC unbonding tx is not valid") + ErrRewardDistCacheNotFound = errorsmod.Register(ModuleName, 1117, "the reward distribution cache is not found") + ErrEmptyFpList = errorsmod.Register(ModuleName, 1118, "the finality provider list is empty") + ErrInvalidProofOfPossession = errorsmod.Register(ModuleName, 1119, "the proof of possession is not valid") + ErrDuplicatedFp = errorsmod.Register(ModuleName, 1120, "the staking request contains duplicated finality provider public key") + ErrInvalidBTCUndelegateReq = errorsmod.Register(ModuleName, 1121, "invalid undelegation request") + ErrVotingPowerTableNotUpdated = errorsmod.Register(ModuleName, 1122, "voting power table has not been updated") + ErrVotingPowerDistCacheNotFound = errorsmod.Register(ModuleName, 1123, "the voting power distribution cache is not found") + ErrParamsNotFound = errorsmod.Register(ModuleName, 1124, "the parameters are not found") ) diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index 02df0f74a..a9b6aaea8 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -7,6 +7,7 @@ import ( bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + etypes "github.com/babylonchain/babylon/x/epoching/types" ) type BTCLightClientKeeper interface { @@ -19,3 +20,8 @@ type BtcCheckpointKeeper interface { GetPowLimit() *big.Int GetParams(ctx context.Context) (p btcctypes.Params) } + +type CheckpointingKeeper interface { + GetEpoch(ctx context.Context) *etypes.Epoch + GetLastFinalizedEpoch(ctx context.Context) (uint64, error) +} diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index 75fd1c5d4..6234f71b3 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -12,6 +12,7 @@ import ( types "github.com/babylonchain/babylon/types" types0 "github.com/babylonchain/babylon/x/btccheckpoint/types" types1 "github.com/babylonchain/babylon/x/btclightclient/types" + types2 "github.com/babylonchain/babylon/x/epoching/types" gomock "github.com/golang/mock/gomock" ) @@ -130,3 +131,55 @@ func (mr *MockBtcCheckpointKeeperMockRecorder) GetPowLimit() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPowLimit", reflect.TypeOf((*MockBtcCheckpointKeeper)(nil).GetPowLimit)) } + +// MockCheckpointingKeeper is a mock of CheckpointingKeeper interface. +type MockCheckpointingKeeper struct { + ctrl *gomock.Controller + recorder *MockCheckpointingKeeperMockRecorder +} + +// MockCheckpointingKeeperMockRecorder is the mock recorder for MockCheckpointingKeeper. +type MockCheckpointingKeeperMockRecorder struct { + mock *MockCheckpointingKeeper +} + +// NewMockCheckpointingKeeper creates a new mock instance. +func NewMockCheckpointingKeeper(ctrl *gomock.Controller) *MockCheckpointingKeeper { + mock := &MockCheckpointingKeeper{ctrl: ctrl} + mock.recorder = &MockCheckpointingKeeperMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCheckpointingKeeper) EXPECT() *MockCheckpointingKeeperMockRecorder { + return m.recorder +} + +// GetEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetEpoch(ctx context.Context) *types2.Epoch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEpoch", ctx) + ret0, _ := ret[0].(*types2.Epoch) + return ret0 +} + +// GetEpoch indicates an expected call of GetEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetEpoch), ctx) +} + +// GetLastFinalizedEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetLastFinalizedEpoch), ctx) +} diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 0b174453b..5cc3dc5e8 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -64,6 +64,7 @@ func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPowe BtcPk: f.BtcPk, Pop: f.Pop, MasterPubRand: f.MasterPubRand, + RegisteredEpoch: f.RegisteredEpoch, SlashedBabylonHeight: f.SlashedBabylonHeight, SlashedBtcHeight: f.SlashedBtcHeight, Height: bbnBlockHeight, diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index dabd668ff..5b6931218 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1486,18 +1486,20 @@ type FinalityProviderResponse struct { // master_pub_rand is the master public randomness of the finality provider // encoded as a base58 string MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` + // registered_epoch is the epoch when this finality provider is registered + RegisteredEpoch uint64 `protobuf:"varint,7,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,7,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,8,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,8,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,9,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` // height is the queried Babylon height - Height uint64 `protobuf:"varint,9,opt,name=height,proto3" json:"height,omitempty"` + Height uint64 `protobuf:"varint,10,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height - VotingPower uint64 `protobuf:"varint,10,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + VotingPower uint64 `protobuf:"varint,11,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } @@ -1561,6 +1563,13 @@ func (m *FinalityProviderResponse) GetMasterPubRand() string { return "" } +func (m *FinalityProviderResponse) GetRegisteredEpoch() uint64 { + if m != nil { + return m.RegisteredEpoch + } + return 0 +} + func (m *FinalityProviderResponse) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -1621,126 +1630,127 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1894 bytes of a gzipped FileDescriptorProto + // 1916 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, - 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x38, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, - 0x58, 0xf0, 0x10, 0x13, 0xa8, 0xb4, 0xdb, 0x02, 0x31, 0xd9, 0x05, 0x76, 0x89, 0x70, 0x27, 0xd0, - 0x4a, 0xdd, 0xaa, 0xa3, 0xe7, 0xf1, 0xf3, 0x78, 0x94, 0x78, 0x66, 0x98, 0xf7, 0x9c, 0xda, 0x42, - 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0x97, 0x9e, 0x5b, 0xa9, 0xc7, 0xee, 0xa9, 0x52, - 0x2f, 0x3d, 0x6d, 0x6f, 0xab, 0xed, 0xa1, 0x15, 0x07, 0x54, 0x41, 0xd5, 0x4a, 0x95, 0x7a, 0xed, - 0xb9, 0x9a, 0xf7, 0xde, 0x78, 0xc6, 0xf6, 0x8c, 0x63, 0x27, 0xd9, 0x5b, 0xfc, 0xde, 0xf7, 0xff, - 0xfb, 0xbd, 0xdf, 0x9b, 0xf7, 0x05, 0x2e, 0x55, 0x71, 0xb5, 0xb3, 0xe3, 0x3a, 0x5a, 0x95, 0x99, - 0x94, 0xe1, 0x6d, 0xdb, 0xb1, 0xb4, 0xdd, 0x55, 0xed, 0x65, 0x8b, 0xf8, 0x9d, 0xa2, 0xe7, 0xbb, - 0xcc, 0x45, 0x67, 0xa4, 0x48, 0x31, 0x12, 0x29, 0xee, 0xae, 0xe6, 0x17, 0x2c, 0xd7, 0x72, 0xb9, - 0x84, 0x16, 0xfc, 0x25, 0x84, 0xf3, 0x17, 0x2c, 0xd7, 0xb5, 0x76, 0x88, 0x86, 0x3d, 0x5b, 0xc3, - 0x8e, 0xe3, 0x32, 0xcc, 0x6c, 0xd7, 0xa1, 0x72, 0xf7, 0xbc, 0xe9, 0xd2, 0xa6, 0x4b, 0x0d, 0xa1, - 0x26, 0x7e, 0xc8, 0x2d, 0x55, 0xfc, 0xd2, 0x4c, 0xbf, 0xe3, 0x31, 0x57, 0xa3, 0xc4, 0xf4, 0x4a, - 0x77, 0xee, 0x6e, 0xaf, 0x6a, 0xdb, 0xa4, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x55, 0xc2, - 0xf0, 0x6a, 0xf8, 0x5b, 0x4a, 0x5d, 0x97, 0x52, 0x55, 0x4c, 0x89, 0x48, 0xa4, 0x2b, 0xe8, 0x61, - 0xcb, 0x76, 0x78, 0x44, 0xa1, 0xd7, 0xe4, 0xf4, 0x3d, 0xec, 0xe3, 0x66, 0xe8, 0xf5, 0x4a, 0xb2, - 0x4c, 0xac, 0x1a, 0x42, 0xae, 0x90, 0x62, 0xcb, 0xf5, 0x84, 0x80, 0xba, 0x00, 0xe8, 0x7b, 0x41, - 0x38, 0x15, 0x6e, 0x5d, 0x27, 0x2f, 0x5b, 0x84, 0x32, 0x55, 0x87, 0xf7, 0x7a, 0x56, 0xa9, 0xe7, - 0x3a, 0x94, 0xa0, 0x8f, 0x20, 0x23, 0xa2, 0xc8, 0x29, 0x17, 0x95, 0x95, 0x99, 0xd2, 0x52, 0x31, - 0xb1, 0x0d, 0x45, 0xa1, 0x56, 0x9e, 0xfa, 0xf2, 0x4d, 0xe1, 0x98, 0x2e, 0x55, 0xd4, 0x6f, 0xc3, - 0x62, 0xcc, 0x66, 0xb9, 0xf3, 0x7d, 0xe2, 0x53, 0xdb, 0x75, 0xa4, 0x4b, 0x94, 0x83, 0x13, 0xbb, - 0x62, 0x85, 0x1b, 0xcf, 0xea, 0xe1, 0x4f, 0xf5, 0x73, 0xb8, 0x90, 0xac, 0x78, 0x14, 0x51, 0x59, - 0xb0, 0xc4, 0x8d, 0x7f, 0x62, 0x3b, 0x78, 0xc7, 0x66, 0x9d, 0x8a, 0xef, 0xee, 0xda, 0x35, 0xe2, - 0x87, 0xa5, 0x40, 0x9f, 0x00, 0x44, 0x1d, 0x92, 0x1e, 0xae, 0x14, 0x25, 0x4c, 0x82, 0x76, 0x16, - 0x05, 0x2e, 0x65, 0x3b, 0x8b, 0x15, 0x6c, 0x11, 0xa9, 0xab, 0xc7, 0x34, 0xd5, 0xbf, 0x28, 0xb0, - 0x9c, 0xe6, 0x49, 0x26, 0xf2, 0x63, 0x40, 0x75, 0xb9, 0x19, 0xa0, 0x51, 0xec, 0xe6, 0x94, 0x8b, - 0x93, 0x2b, 0x33, 0x25, 0x2d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xfd, 0x74, 0xbd, 0xdf, 0x0f, - 0x7a, 0xd4, 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0xd6, 0x65, - 0x47, 0x06, 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0x6c, 0xdd, 0x33, 0xaa, 0xcc, 0x34, 0xbc, 0x6d, 0xa3, - 0x41, 0xda, 0xbc, 0x6c, 0xd3, 0x3a, 0xd4, 0xbd, 0x32, 0x33, 0x2b, 0xdb, 0x8f, 0x49, 0x5b, 0xdd, - 0x4b, 0xa9, 0x7b, 0xb7, 0x18, 0x3f, 0x82, 0xd3, 0x03, 0xc5, 0x90, 0xe5, 0x1f, 0xbb, 0x16, 0xf3, - 0xfd, 0xb5, 0x50, 0x7f, 0xa7, 0x40, 0x9e, 0xfb, 0x2f, 0x3f, 0x7f, 0xb8, 0x41, 0x76, 0x88, 0x25, - 0x28, 0x21, 0x4c, 0xa0, 0x0c, 0x19, 0xca, 0x30, 0x6b, 0x09, 0x48, 0xcd, 0x95, 0xae, 0xa7, 0x78, - 0xec, 0xd1, 0xde, 0xe2, 0x1a, 0xba, 0xd4, 0xec, 0x03, 0xce, 0xc4, 0x81, 0x81, 0xf3, 0x27, 0x45, - 0x1e, 0x9c, 0xfe, 0x50, 0x65, 0xa1, 0x5e, 0xc0, 0xa9, 0xa0, 0xd2, 0xb5, 0x68, 0x4b, 0x42, 0xe6, - 0xc6, 0x28, 0x41, 0x77, 0x6b, 0x34, 0x57, 0x65, 0x66, 0xcc, 0xfc, 0xd1, 0x81, 0xa5, 0x0e, 0xd7, - 0x12, 0x3b, 0x5d, 0x71, 0x7f, 0x42, 0xfc, 0x75, 0xf6, 0x98, 0xd8, 0x56, 0x83, 0x8d, 0x8e, 0x1c, - 0x74, 0x16, 0x32, 0x0d, 0xae, 0xc3, 0x83, 0x9a, 0xd2, 0xe5, 0x2f, 0xf5, 0x19, 0x5c, 0x1f, 0xc5, - 0x8f, 0xac, 0xda, 0x25, 0x98, 0xdd, 0x75, 0x99, 0xed, 0x58, 0x86, 0x17, 0xec, 0x73, 0x3f, 0x53, - 0xfa, 0x8c, 0x58, 0xe3, 0x2a, 0xea, 0x26, 0xac, 0x24, 0x1a, 0x7c, 0xd8, 0xf2, 0x7d, 0xe2, 0x30, - 0x2e, 0x34, 0x06, 0xe2, 0xd3, 0xea, 0xd0, 0x6b, 0x4e, 0x86, 0x17, 0x25, 0xa9, 0xc4, 0x93, 0x1c, - 0x08, 0x7b, 0x62, 0x30, 0xec, 0x9f, 0x2b, 0xf0, 0x01, 0x77, 0xb4, 0x6e, 0x32, 0x7b, 0x97, 0x0c, - 0xd0, 0x4d, 0x7f, 0xc9, 0xd3, 0x5c, 0x1d, 0x15, 0x7e, 0xff, 0xa6, 0xc0, 0x8d, 0xd1, 0xe2, 0x39, - 0x42, 0x1a, 0xfc, 0x81, 0xcd, 0x1a, 0x9b, 0x84, 0xe1, 0x6f, 0x94, 0x06, 0x97, 0xe4, 0xc1, 0xe4, - 0x89, 0x61, 0x46, 0x6a, 0x3d, 0x85, 0x55, 0xef, 0x4a, 0x96, 0x1c, 0xd8, 0x1e, 0xde, 0x63, 0xf5, - 0x57, 0x0a, 0x5c, 0x4d, 0x44, 0x4a, 0x02, 0x51, 0x8d, 0x70, 0x5e, 0x8e, 0xaa, 0x8f, 0xff, 0x56, - 0x52, 0xce, 0x43, 0x12, 0x29, 0xf9, 0x70, 0x3e, 0x46, 0x4a, 0xae, 0x9f, 0x40, 0x4f, 0x77, 0xf7, - 0xa5, 0x27, 0x37, 0xc9, 0xb4, 0x7e, 0x2e, 0x22, 0xaa, 0x1e, 0x81, 0xa3, 0xeb, 0xeb, 0xa7, 0x70, - 0x7e, 0x90, 0x70, 0xc3, 0x8a, 0xdf, 0x84, 0xf7, 0x64, 0xb0, 0x06, 0x6b, 0x1b, 0x0d, 0x4c, 0x1b, - 0xb1, 0xba, 0xcf, 0xcb, 0xad, 0xe7, 0xed, 0xc7, 0x98, 0x36, 0x82, 0x53, 0xff, 0x32, 0xe9, 0x9e, - 0xe9, 0x96, 0x69, 0x0b, 0xe6, 0x7a, 0xb9, 0x5b, 0xde, 0x70, 0xe3, 0x51, 0x77, 0xb6, 0x87, 0xba, - 0xd5, 0x5f, 0x67, 0xe0, 0x4c, 0xb2, 0xbb, 0x4d, 0xc8, 0x08, 0xa8, 0x70, 0x37, 0xb3, 0xe5, 0xbb, - 0xaf, 0xdf, 0x14, 0x4a, 0x96, 0xcd, 0x1a, 0xad, 0x6a, 0xd1, 0x74, 0x9b, 0x9a, 0x74, 0x6a, 0x36, - 0xb0, 0xed, 0x84, 0x3f, 0x34, 0xd6, 0xf1, 0x08, 0x2d, 0x96, 0x9f, 0x54, 0x6e, 0xaf, 0xdd, 0xaa, - 0xb4, 0xaa, 0x9f, 0x91, 0x8e, 0x7e, 0xbc, 0x1a, 0x80, 0x0b, 0x7d, 0x0e, 0x73, 0x11, 0xf8, 0x76, - 0x6c, 0x1a, 0x30, 0xf2, 0xe4, 0x21, 0xcc, 0xce, 0x48, 0xd4, 0x3e, 0xb5, 0x39, 0xb2, 0x67, 0x29, - 0xc3, 0x3e, 0x33, 0xe4, 0x19, 0x99, 0x14, 0x4c, 0xc7, 0xd7, 0xc4, 0x41, 0x42, 0x4b, 0x00, 0xc4, - 0xa9, 0x85, 0x02, 0x53, 0x5c, 0x60, 0x9a, 0x38, 0xf2, 0x9c, 0xa1, 0x45, 0x98, 0x66, 0x2e, 0xc3, - 0x3b, 0x06, 0xc5, 0x2c, 0x77, 0x9c, 0xef, 0x9e, 0xe4, 0x0b, 0x5b, 0x98, 0xa1, 0xcb, 0x30, 0x17, - 0x6f, 0x23, 0x69, 0xe7, 0x32, 0xbc, 0x83, 0xb3, 0x51, 0x07, 0x49, 0x1b, 0x5d, 0x81, 0x53, 0x74, - 0x07, 0xd3, 0x46, 0x4c, 0xec, 0x04, 0x17, 0xcb, 0x86, 0xcb, 0x42, 0xee, 0x0e, 0x9c, 0x8b, 0xa0, - 0xce, 0xb7, 0x0c, 0x6a, 0x5b, 0x5c, 0xfe, 0x24, 0x97, 0x5f, 0xe8, 0x6e, 0x6f, 0x05, 0xbb, 0x5b, - 0xb6, 0x15, 0xa8, 0xbd, 0x80, 0xac, 0xe9, 0xee, 0x12, 0x07, 0x3b, 0x2c, 0x90, 0xa7, 0xb9, 0x69, - 0x7e, 0x32, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0x5d, 0xaf, 0x61, 0x2f, 0xb0, 0x64, 0x5b, 0x0e, - 0x66, 0x2d, 0x9f, 0x50, 0x7d, 0x36, 0x34, 0xb3, 0x65, 0x5b, 0x14, 0xdd, 0x00, 0x14, 0xe6, 0xe6, - 0xb6, 0x98, 0xd7, 0x62, 0x86, 0x5d, 0x6b, 0xe7, 0x80, 0x7f, 0x55, 0x87, 0x08, 0x7d, 0xc6, 0x37, - 0x9e, 0xd4, 0xf8, 0x7d, 0x8a, 0x39, 0x33, 0xe7, 0x66, 0x2e, 0x2a, 0x2b, 0x27, 0x75, 0xf9, 0x0b, - 0x15, 0x60, 0x46, 0x7c, 0xc9, 0x18, 0x35, 0x42, 0xcd, 0xdc, 0xac, 0x20, 0x16, 0xb1, 0xb4, 0x41, - 0xa8, 0x89, 0xde, 0x87, 0xb9, 0x96, 0x53, 0x75, 0x9d, 0x1a, 0xaf, 0x8e, 0xdd, 0x24, 0xb9, 0x2c, - 0x77, 0x91, 0xed, 0xae, 0x3e, 0xb7, 0x9b, 0x04, 0x99, 0x70, 0xa6, 0xe5, 0x44, 0x08, 0x37, 0x7c, - 0x89, 0xc6, 0xdc, 0x1c, 0x87, 0x7a, 0x31, 0x1d, 0xea, 0x2f, 0x62, 0x6a, 0x5d, 0xb0, 0x2f, 0xb4, - 0x12, 0x56, 0x83, 0x58, 0xc4, 0x07, 0xbd, 0x11, 0x3e, 0x22, 0x4e, 0x89, 0x58, 0xc4, 0xaa, 0x7c, - 0x32, 0xa8, 0x5f, 0x4c, 0xc2, 0xb9, 0x14, 0xc3, 0x68, 0x05, 0xe6, 0x63, 0xe9, 0xb4, 0x63, 0xa7, - 0x3a, 0x4a, 0x53, 0x74, 0xfb, 0xbb, 0xb0, 0x18, 0x75, 0x3b, 0xd2, 0x09, 0x3b, 0x3e, 0xc1, 0x95, - 0x72, 0x5d, 0x91, 0x17, 0xa1, 0x84, 0xec, 0xba, 0x09, 0x8b, 0xdd, 0xae, 0xf7, 0x6a, 0xf3, 0x33, - 0x34, 0xc9, 0x31, 0x70, 0x39, 0xa5, 0x2c, 0xdd, 0xa6, 0x3f, 0x71, 0xea, 0xae, 0x9e, 0x0b, 0x0d, - 0xc5, 0x7d, 0xf0, 0xe3, 0x93, 0x80, 0xdc, 0xa9, 0x24, 0xe4, 0x7e, 0x04, 0xf9, 0x3e, 0xe4, 0xc6, - 0x53, 0x39, 0xce, 0x55, 0xce, 0xf5, 0x82, 0x37, 0xca, 0xa4, 0x0e, 0x67, 0x23, 0xfc, 0xc6, 0x74, - 0x69, 0x2e, 0x73, 0x40, 0x20, 0x2f, 0x74, 0x81, 0x1c, 0x79, 0xa2, 0xaa, 0x09, 0x85, 0x7d, 0x6e, - 0x05, 0xf4, 0x00, 0xa6, 0x6a, 0x64, 0xe7, 0x60, 0x9f, 0xbe, 0x5c, 0x53, 0xfd, 0xf3, 0x14, 0xe4, - 0x52, 0x5f, 0x23, 0x1f, 0xc3, 0x4c, 0x70, 0x0a, 0x7c, 0xdb, 0x8b, 0xb1, 0xf4, 0xb7, 0xc2, 0xcb, - 0x25, 0xf2, 0x20, 0x6e, 0x96, 0x8d, 0x48, 0x54, 0x8f, 0xeb, 0xa1, 0x4d, 0x00, 0xd3, 0x6d, 0x36, - 0x6d, 0x4a, 0xc3, 0x2b, 0x6a, 0xba, 0x7c, 0xf3, 0xf5, 0x9b, 0xc2, 0xa2, 0x30, 0x44, 0x6b, 0xdb, - 0x45, 0xdb, 0xd5, 0x9a, 0x98, 0x35, 0x8a, 0x4f, 0x89, 0x85, 0xcd, 0xce, 0x06, 0x31, 0xbf, 0xfe, - 0xe2, 0x26, 0x48, 0x3f, 0x1b, 0xc4, 0xd4, 0x63, 0x06, 0xd0, 0x3d, 0x00, 0x99, 0x67, 0xc0, 0xe9, - 0x93, 0x3c, 0xa8, 0x42, 0x18, 0x94, 0x18, 0x5a, 0x14, 0xbb, 0x43, 0x8b, 0xa2, 0x64, 0xd9, 0x69, - 0xa9, 0x52, 0xd9, 0x8e, 0xdd, 0x07, 0x53, 0x47, 0x71, 0x1f, 0x7c, 0x08, 0x93, 0x9e, 0xeb, 0x71, - 0xd0, 0xcc, 0x94, 0x56, 0xd2, 0x5e, 0xe1, 0xbe, 0xeb, 0xd6, 0x9f, 0xd5, 0x2b, 0x2e, 0xa5, 0x84, - 0x67, 0xa1, 0x07, 0x4a, 0x01, 0x5e, 0x9b, 0x98, 0x32, 0xe2, 0x1b, 0x5e, 0xab, 0x6a, 0xf8, 0xd8, - 0xa9, 0x49, 0x42, 0xce, 0x8a, 0xe5, 0x4a, 0xab, 0xaa, 0x63, 0xa7, 0x86, 0xd6, 0xe0, 0x2c, 0x47, - 0x1a, 0xa9, 0x19, 0x61, 0xea, 0x92, 0xff, 0x4f, 0x70, 0x86, 0x5f, 0x90, 0xbb, 0x65, 0xb1, 0x29, - 0xaf, 0x82, 0x80, 0x11, 0x43, 0x2d, 0x66, 0x86, 0x1a, 0x27, 0xb9, 0xc6, 0x7c, 0xa8, 0xc1, 0x4c, - 0x29, 0x1d, 0x7d, 0x98, 0x4d, 0x0f, 0xfd, 0xf8, 0x86, 0x81, 0x8f, 0xef, 0xd2, 0x6f, 0x4e, 0xc3, - 0x71, 0x7e, 0xdf, 0xa3, 0x9f, 0x29, 0x90, 0x11, 0x13, 0x07, 0x74, 0x2d, 0xa5, 0x14, 0x83, 0x83, - 0x97, 0xfc, 0xf5, 0x51, 0x44, 0x05, 0x26, 0xd5, 0xf7, 0x7f, 0xfa, 0xd7, 0x7f, 0xfe, 0x72, 0xa2, - 0x80, 0x96, 0xb4, 0x61, 0x03, 0x23, 0xf4, 0x7b, 0x05, 0x4e, 0xf5, 0x8d, 0x4e, 0x50, 0x69, 0x7f, - 0x37, 0xfd, 0x03, 0x9a, 0xfc, 0xed, 0xb1, 0x74, 0x64, 0x8c, 0x1a, 0x8f, 0xf1, 0x1a, 0xba, 0x3a, - 0x34, 0x46, 0xed, 0x95, 0x64, 0xed, 0x3d, 0xf4, 0x07, 0x05, 0x4e, 0x0f, 0x3c, 0x11, 0xd0, 0xda, - 0x30, 0xdf, 0x69, 0xa3, 0x9b, 0xfc, 0x9d, 0x31, 0xb5, 0x64, 0xcc, 0xab, 0x3c, 0xe6, 0x0f, 0xd0, - 0xb5, 0x94, 0x98, 0x07, 0x1f, 0x27, 0xe8, 0x6b, 0x05, 0xe6, 0xfb, 0x0d, 0xa2, 0xdb, 0xe3, 0xb8, - 0x0f, 0x63, 0x5e, 0x1b, 0x4f, 0x49, 0x86, 0xbc, 0xc5, 0x43, 0xde, 0x44, 0x9f, 0x8d, 0x1c, 0xb2, - 0xf6, 0xaa, 0xe7, 0xdd, 0xb0, 0x37, 0x28, 0x82, 0x7e, 0xab, 0xc0, 0x5c, 0xef, 0xcc, 0x01, 0xad, - 0x0e, 0x8b, 0x2e, 0x71, 0x94, 0x92, 0x2f, 0x8d, 0xa3, 0x22, 0xd3, 0x29, 0xf2, 0x74, 0x56, 0xd0, - 0x15, 0x2d, 0x75, 0xcc, 0x19, 0x7f, 0x50, 0xa0, 0x7f, 0x29, 0x50, 0xd8, 0xe7, 0x75, 0x89, 0xca, - 0xc3, 0xe2, 0x18, 0xed, 0xa9, 0x9c, 0x7f, 0x78, 0x28, 0x1b, 0x32, 0xb9, 0x0f, 0x79, 0x72, 0x6b, - 0xa8, 0x34, 0x46, 0xaf, 0x04, 0x01, 0xed, 0xa1, 0xff, 0x29, 0xb0, 0x34, 0x74, 0xbe, 0x81, 0x1e, - 0x8c, 0x83, 0x9f, 0xa4, 0x11, 0x4c, 0x7e, 0xfd, 0x10, 0x16, 0x64, 0x8a, 0x15, 0x9e, 0xe2, 0xa7, - 0xe8, 0xf1, 0xc1, 0xe1, 0xc8, 0x19, 0x36, 0x4a, 0xfc, 0x3f, 0x0a, 0x5c, 0x18, 0x36, 0x38, 0x41, - 0xf7, 0xc7, 0x89, 0x3a, 0x61, 0x82, 0x93, 0x7f, 0x70, 0x70, 0x03, 0x32, 0xeb, 0x47, 0x3c, 0xeb, - 0x75, 0x74, 0xff, 0x90, 0x59, 0x73, 0xc6, 0xee, 0x1b, 0x1a, 0x0c, 0x67, 0xec, 0xe4, 0x01, 0xc4, - 0x70, 0xc6, 0x4e, 0x99, 0x4a, 0xec, 0xcb, 0xd8, 0x38, 0xd4, 0x93, 0xb7, 0x28, 0xfa, 0xaf, 0x02, - 0x8b, 0x43, 0x46, 0x02, 0xe8, 0xde, 0x38, 0x85, 0x4d, 0x20, 0x90, 0xfb, 0x07, 0xd6, 0x97, 0x19, - 0x6d, 0xf2, 0x8c, 0x1e, 0xa1, 0x8f, 0x0f, 0xde, 0x97, 0x38, 0xd9, 0xfc, 0x51, 0x81, 0x6c, 0x0f, - 0x6f, 0xa1, 0x5b, 0x23, 0x53, 0x5c, 0x98, 0xd3, 0xea, 0x18, 0x1a, 0x32, 0x8b, 0x0d, 0x9e, 0xc5, - 0x3d, 0xf4, 0x9d, 0xd1, 0x38, 0x51, 0x7b, 0x95, 0x30, 0xa5, 0xd8, 0x2b, 0x3f, 0xfd, 0xf2, 0xed, - 0xb2, 0xf2, 0xd5, 0xdb, 0x65, 0xe5, 0x1f, 0x6f, 0x97, 0x95, 0x5f, 0xbc, 0x5b, 0x3e, 0xf6, 0xd5, - 0xbb, 0xe5, 0x63, 0x7f, 0x7f, 0xb7, 0x7c, 0xec, 0x87, 0xfb, 0x7e, 0xf7, 0xb5, 0xe3, 0x0e, 0xf9, - 0x47, 0x60, 0x35, 0xc3, 0xff, 0x87, 0x74, 0xfb, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xb0, - 0x98, 0x47, 0xb1, 0x1b, 0x00, 0x00, + 0x19, 0x67, 0x12, 0xe3, 0x25, 0x9f, 0xe3, 0x24, 0xbc, 0x0d, 0x60, 0x1c, 0x12, 0xc3, 0x94, 0x85, + 0x84, 0x05, 0x0f, 0x31, 0x81, 0x4a, 0xbb, 0x2d, 0x10, 0x13, 0x16, 0xd8, 0x25, 0xc2, 0x9d, 0x40, + 0x2b, 0x75, 0xab, 0x8e, 0xc6, 0xe3, 0xe7, 0xf1, 0x28, 0xf6, 0xcc, 0x30, 0xef, 0x39, 0xb5, 0x85, + 0x72, 0xe9, 0xa1, 0xb7, 0x4a, 0x95, 0xda, 0x43, 0x2f, 0x3d, 0xb7, 0x52, 0x8f, 0xdd, 0x53, 0xa5, + 0xde, 0xb7, 0xb7, 0xd5, 0xf6, 0xd0, 0x6a, 0x0f, 0xa8, 0x82, 0xaa, 0x95, 0x2a, 0x71, 0xed, 0xb9, + 0x9a, 0xf7, 0xde, 0x78, 0xc6, 0xf6, 0x8c, 0x63, 0x27, 0xd9, 0x5b, 0xfc, 0xde, 0xf7, 0xff, 0xfb, + 0xbd, 0xdf, 0x9b, 0xf7, 0x05, 0x2e, 0x55, 0xf5, 0x6a, 0xb7, 0xe9, 0xd8, 0x4a, 0x95, 0x1a, 0x84, + 0xea, 0xbb, 0x96, 0x6d, 0x2a, 0x7b, 0xeb, 0xca, 0xcb, 0x36, 0xf6, 0xba, 0x45, 0xd7, 0x73, 0xa8, + 0x83, 0xce, 0x08, 0x91, 0x62, 0x28, 0x52, 0xdc, 0x5b, 0xcf, 0x2f, 0x9a, 0x8e, 0xe9, 0x30, 0x09, + 0xc5, 0xff, 0x8b, 0x0b, 0xe7, 0x2f, 0x98, 0x8e, 0x63, 0x36, 0xb1, 0xa2, 0xbb, 0x96, 0xa2, 0xdb, + 0xb6, 0x43, 0x75, 0x6a, 0x39, 0x36, 0x11, 0xbb, 0xe7, 0x0d, 0x87, 0xb4, 0x1c, 0xa2, 0x71, 0x35, + 0xfe, 0x43, 0x6c, 0xc9, 0xfc, 0x97, 0x62, 0x78, 0x5d, 0x97, 0x3a, 0x0a, 0xc1, 0x86, 0x5b, 0xba, + 0x7d, 0x67, 0x77, 0x5d, 0xd9, 0xc5, 0xdd, 0x40, 0xe6, 0xb2, 0x90, 0x09, 0x03, 0xad, 0x62, 0xaa, + 0xaf, 0x07, 0xbf, 0x85, 0xd4, 0x35, 0x21, 0x55, 0xd5, 0x09, 0xe6, 0x89, 0xf4, 0x04, 0x5d, 0xdd, + 0xb4, 0x6c, 0x16, 0x51, 0xe0, 0x35, 0x3e, 0x7d, 0x57, 0xf7, 0xf4, 0x56, 0xe0, 0xf5, 0x4a, 0xbc, + 0x4c, 0xa4, 0x1a, 0x5c, 0xae, 0x90, 0x60, 0xcb, 0x71, 0xb9, 0x80, 0xbc, 0x08, 0xe8, 0x07, 0x7e, + 0x38, 0x15, 0x66, 0x5d, 0xc5, 0x2f, 0xdb, 0x98, 0x50, 0x59, 0x85, 0xf7, 0xfb, 0x56, 0x89, 0xeb, + 0xd8, 0x04, 0xa3, 0x8f, 0x21, 0xcd, 0xa3, 0xc8, 0x49, 0x17, 0xa5, 0xd5, 0x4c, 0x69, 0xb9, 0x18, + 0xdb, 0x86, 0x22, 0x57, 0x2b, 0xa7, 0xbe, 0x7c, 0x5d, 0x38, 0xa1, 0x0a, 0x15, 0xf9, 0xbb, 0xb0, + 0x14, 0xb1, 0x59, 0xee, 0xfe, 0x10, 0x7b, 0xc4, 0x72, 0x6c, 0xe1, 0x12, 0xe5, 0xe0, 0xbd, 0x3d, + 0xbe, 0xc2, 0x8c, 0x67, 0xd5, 0xe0, 0xa7, 0xfc, 0x39, 0x5c, 0x88, 0x57, 0x3c, 0x8e, 0xa8, 0x4c, + 0x58, 0x66, 0xc6, 0x3f, 0xb1, 0x6c, 0xbd, 0x69, 0xd1, 0x6e, 0xc5, 0x73, 0xf6, 0xac, 0x1a, 0xf6, + 0x82, 0x52, 0xa0, 0x4f, 0x00, 0xc2, 0x0e, 0x09, 0x0f, 0x57, 0x8a, 0x02, 0x26, 0x7e, 0x3b, 0x8b, + 0x1c, 0x97, 0xa2, 0x9d, 0xc5, 0x8a, 0x6e, 0x62, 0xa1, 0xab, 0x46, 0x34, 0xe5, 0xbf, 0x4a, 0xb0, + 0x92, 0xe4, 0x49, 0x24, 0xf2, 0x53, 0x40, 0x75, 0xb1, 0xe9, 0xa3, 0x91, 0xef, 0xe6, 0xa4, 0x8b, + 0xd3, 0xab, 0x99, 0x92, 0x92, 0x90, 0xd4, 0xa0, 0xb5, 0xc0, 0x98, 0x7a, 0xba, 0x3e, 0xe8, 0x07, + 0x3d, 0xea, 0x4b, 0x65, 0x8a, 0xa5, 0x72, 0xf5, 0xc0, 0x54, 0x84, 0xbd, 0x68, 0x2e, 0x9b, 0xa2, + 0x23, 0xc3, 0xce, 0x79, 0xcd, 0x2e, 0x41, 0xb6, 0xee, 0x6a, 0x55, 0x6a, 0x68, 0xee, 0xae, 0xd6, + 0xc0, 0x1d, 0x56, 0xb6, 0x19, 0x15, 0xea, 0x6e, 0x99, 0x1a, 0x95, 0xdd, 0xc7, 0xb8, 0x23, 0xef, + 0x27, 0xd4, 0xbd, 0x57, 0x8c, 0x9f, 0xc0, 0xe9, 0xa1, 0x62, 0x88, 0xf2, 0x4f, 0x5c, 0x8b, 0x85, + 0xc1, 0x5a, 0xc8, 0x7f, 0x90, 0x20, 0xcf, 0xfc, 0x97, 0x9f, 0x3f, 0xd8, 0xc2, 0x4d, 0x6c, 0x72, + 0x4a, 0x08, 0x12, 0x28, 0x43, 0x9a, 0x50, 0x9d, 0xb6, 0x39, 0xa4, 0xe6, 0x4a, 0xd7, 0x12, 0x3c, + 0xf6, 0x69, 0xef, 0x30, 0x0d, 0x55, 0x68, 0x0e, 0x00, 0x67, 0xea, 0xd0, 0xc0, 0xf9, 0x8b, 0x24, + 0x0e, 0xce, 0x60, 0xa8, 0xa2, 0x50, 0x2f, 0x60, 0xde, 0xaf, 0x74, 0x2d, 0xdc, 0x12, 0x90, 0xb9, + 0x3e, 0x4e, 0xd0, 0xbd, 0x1a, 0xcd, 0x55, 0xa9, 0x11, 0x31, 0x7f, 0x7c, 0x60, 0xa9, 0xc3, 0x5a, + 0x6c, 0xa7, 0x2b, 0xce, 0xcf, 0xb0, 0xb7, 0x49, 0x1f, 0x63, 0xcb, 0x6c, 0xd0, 0xf1, 0x91, 0x83, + 0xce, 0x42, 0xba, 0xc1, 0x74, 0x58, 0x50, 0x29, 0x55, 0xfc, 0x92, 0x9f, 0xc1, 0xb5, 0x71, 0xfc, + 0x88, 0xaa, 0x5d, 0x82, 0xd9, 0x3d, 0x87, 0x5a, 0xb6, 0xa9, 0xb9, 0xfe, 0x3e, 0xf3, 0x93, 0x52, + 0x33, 0x7c, 0x8d, 0xa9, 0xc8, 0xdb, 0xb0, 0x1a, 0x6b, 0xf0, 0x41, 0xdb, 0xf3, 0xb0, 0x4d, 0x99, + 0xd0, 0x04, 0x88, 0x4f, 0xaa, 0x43, 0xbf, 0x39, 0x11, 0x5e, 0x98, 0xa4, 0x14, 0x4d, 0x72, 0x28, + 0xec, 0xa9, 0xe1, 0xb0, 0x7f, 0x29, 0xc1, 0x87, 0xcc, 0xd1, 0xa6, 0x41, 0xad, 0x3d, 0x3c, 0x44, + 0x37, 0x83, 0x25, 0x4f, 0x72, 0x75, 0x5c, 0xf8, 0xfd, 0xbb, 0x04, 0xd7, 0xc7, 0x8b, 0xe7, 0x18, + 0x69, 0xf0, 0x47, 0x16, 0x6d, 0x6c, 0x63, 0xaa, 0x7f, 0xab, 0x34, 0xb8, 0x2c, 0x0e, 0x26, 0x4b, + 0x4c, 0xa7, 0xb8, 0xd6, 0x57, 0x58, 0xf9, 0x8e, 0x60, 0xc9, 0xa1, 0xed, 0xd1, 0x3d, 0x96, 0x7f, + 0x23, 0xc1, 0xd5, 0x58, 0xa4, 0xc4, 0x10, 0xd5, 0x18, 0xe7, 0xe5, 0xb8, 0xfa, 0xf8, 0x1f, 0x29, + 0xe1, 0x3c, 0xc4, 0x91, 0x92, 0x07, 0xe7, 0x23, 0xa4, 0xe4, 0x78, 0x31, 0xf4, 0x74, 0xe7, 0x40, + 0x7a, 0x72, 0xe2, 0x4c, 0xab, 0xe7, 0x42, 0xa2, 0xea, 0x13, 0x38, 0xbe, 0xbe, 0x7e, 0x0a, 0xe7, + 0x87, 0x09, 0x37, 0xa8, 0xf8, 0x0d, 0x78, 0x5f, 0x04, 0xab, 0xd1, 0x8e, 0xd6, 0xd0, 0x49, 0x23, + 0x52, 0xf7, 0x05, 0xb1, 0xf5, 0xbc, 0xf3, 0x58, 0x27, 0x0d, 0xff, 0xd4, 0xbf, 0x8c, 0xbb, 0x67, + 0x7a, 0x65, 0xda, 0x81, 0xb9, 0x7e, 0xee, 0x16, 0x37, 0xdc, 0x64, 0xd4, 0x9d, 0xed, 0xa3, 0x6e, + 0xf9, 0xb7, 0x69, 0x38, 0x13, 0xef, 0x6e, 0x1b, 0xd2, 0x1c, 0x2a, 0xcc, 0xcd, 0x6c, 0xf9, 0xce, + 0x37, 0xaf, 0x0b, 0x25, 0xd3, 0xa2, 0x8d, 0x76, 0xb5, 0x68, 0x38, 0x2d, 0x45, 0x38, 0x35, 0x1a, + 0xba, 0x65, 0x07, 0x3f, 0x14, 0xda, 0x75, 0x31, 0x29, 0x96, 0x9f, 0x54, 0x6e, 0x6d, 0xdc, 0xac, + 0xb4, 0xab, 0x9f, 0xe1, 0xae, 0x7a, 0xb2, 0xea, 0x83, 0x0b, 0x7d, 0x0e, 0x73, 0x21, 0xf8, 0x9a, + 0x16, 0xf1, 0x19, 0x79, 0xfa, 0x08, 0x66, 0x33, 0x02, 0xb5, 0x4f, 0x2d, 0x86, 0xec, 0x59, 0x42, + 0x75, 0x8f, 0x6a, 0xe2, 0x8c, 0x4c, 0x73, 0xa6, 0x63, 0x6b, 0xfc, 0x20, 0xa1, 0x65, 0x00, 0x6c, + 0xd7, 0x02, 0x81, 0x14, 0x13, 0x98, 0xc1, 0xb6, 0x38, 0x67, 0x68, 0x09, 0x66, 0xa8, 0x43, 0xf5, + 0xa6, 0x46, 0x74, 0x9a, 0x3b, 0xc9, 0x76, 0x4f, 0xb1, 0x85, 0x1d, 0x9d, 0xa2, 0xcb, 0x30, 0x17, + 0x6d, 0x23, 0xee, 0xe4, 0xd2, 0xac, 0x83, 0xb3, 0x61, 0x07, 0x71, 0x07, 0x5d, 0x81, 0x79, 0xd2, + 0xd4, 0x49, 0x23, 0x22, 0xf6, 0x1e, 0x13, 0xcb, 0x06, 0xcb, 0x5c, 0xee, 0x36, 0x9c, 0x0b, 0xa1, + 0xce, 0xb6, 0x34, 0x62, 0x99, 0x4c, 0xfe, 0x14, 0x93, 0x5f, 0xec, 0x6d, 0xef, 0xf8, 0xbb, 0x3b, + 0x96, 0xe9, 0xab, 0xbd, 0x80, 0xac, 0xe1, 0xec, 0x61, 0x5b, 0xb7, 0xa9, 0x2f, 0x4f, 0x72, 0x33, + 0xec, 0x64, 0xdc, 0x4c, 0xe8, 0xfe, 0x03, 0x21, 0xbb, 0x59, 0xd3, 0x5d, 0xdf, 0x92, 0x65, 0xda, + 0x3a, 0x6d, 0x7b, 0x98, 0xa8, 0xb3, 0x81, 0x99, 0x1d, 0xcb, 0x24, 0xe8, 0x3a, 0xa0, 0x20, 0x37, + 0xa7, 0x4d, 0xdd, 0x36, 0xd5, 0xac, 0x5a, 0x27, 0x07, 0xec, 0xab, 0x3a, 0x40, 0xe8, 0x33, 0xb6, + 0xf1, 0xa4, 0xc6, 0xee, 0x53, 0x9d, 0x31, 0x73, 0x2e, 0x73, 0x51, 0x5a, 0x3d, 0xa5, 0x8a, 0x5f, + 0xa8, 0x00, 0x19, 0xfe, 0x25, 0xa3, 0xd5, 0x30, 0x31, 0x72, 0xb3, 0x9c, 0x58, 0xf8, 0xd2, 0x16, + 0x26, 0x06, 0xfa, 0x00, 0xe6, 0xda, 0x76, 0xd5, 0xb1, 0x6b, 0xac, 0x3a, 0x56, 0x0b, 0xe7, 0xb2, + 0xcc, 0x45, 0xb6, 0xb7, 0xfa, 0xdc, 0x6a, 0x61, 0x64, 0xc0, 0x99, 0xb6, 0x1d, 0x22, 0x5c, 0xf3, + 0x04, 0x1a, 0x73, 0x73, 0x0c, 0xea, 0xc5, 0x64, 0xa8, 0xbf, 0x88, 0xa8, 0xf5, 0xc0, 0xbe, 0xd8, + 0x8e, 0x59, 0xf5, 0x63, 0xe1, 0x1f, 0xf4, 0x5a, 0xf0, 0x88, 0x98, 0xe7, 0xb1, 0xf0, 0x55, 0xf1, + 0x64, 0x90, 0xbf, 0x98, 0x86, 0x73, 0x09, 0x86, 0xd1, 0x2a, 0x2c, 0x44, 0xd2, 0xe9, 0x44, 0x4e, + 0x75, 0x98, 0x26, 0xef, 0xf6, 0xf7, 0x61, 0x29, 0xec, 0x76, 0xa8, 0x13, 0x74, 0x7c, 0x8a, 0x29, + 0xe5, 0x7a, 0x22, 0x2f, 0x02, 0x09, 0xd1, 0x75, 0x03, 0x96, 0x7a, 0x5d, 0xef, 0xd7, 0x66, 0x67, + 0x68, 0x9a, 0x61, 0xe0, 0x72, 0x42, 0x59, 0x7a, 0x4d, 0x7f, 0x62, 0xd7, 0x1d, 0x35, 0x17, 0x18, + 0x8a, 0xfa, 0x60, 0xc7, 0x27, 0x06, 0xb9, 0xa9, 0x38, 0xe4, 0x7e, 0x0c, 0xf9, 0x01, 0xe4, 0x46, + 0x53, 0x39, 0xc9, 0x54, 0xce, 0xf5, 0x83, 0x37, 0xcc, 0xa4, 0x0e, 0x67, 0x43, 0xfc, 0x46, 0x74, + 0x49, 0x2e, 0x7d, 0x48, 0x20, 0x2f, 0xf6, 0x80, 0x1c, 0x7a, 0x22, 0xb2, 0x01, 0x85, 0x03, 0x6e, + 0x05, 0x74, 0x1f, 0x52, 0x35, 0xdc, 0x3c, 0xdc, 0xa7, 0x2f, 0xd3, 0x94, 0xdf, 0xa5, 0x20, 0x97, + 0xf8, 0x1a, 0x79, 0x08, 0x19, 0xff, 0x14, 0x78, 0x96, 0x1b, 0x61, 0xe9, 0xef, 0x04, 0x97, 0x4b, + 0xe8, 0x81, 0xdf, 0x2c, 0x5b, 0xa1, 0xa8, 0x1a, 0xd5, 0x43, 0xdb, 0x00, 0x86, 0xd3, 0x6a, 0x59, + 0x84, 0x04, 0x57, 0xd4, 0x4c, 0xf9, 0xc6, 0x37, 0xaf, 0x0b, 0x4b, 0xdc, 0x10, 0xa9, 0xed, 0x16, + 0x2d, 0x47, 0x69, 0xe9, 0xb4, 0x51, 0x7c, 0x8a, 0x4d, 0xdd, 0xe8, 0x6e, 0x61, 0xe3, 0xeb, 0x2f, + 0x6e, 0x80, 0xf0, 0xb3, 0x85, 0x0d, 0x35, 0x62, 0x00, 0xdd, 0x05, 0x10, 0x79, 0xfa, 0x9c, 0x3e, + 0xcd, 0x82, 0x2a, 0x04, 0x41, 0xf1, 0xa1, 0x45, 0xb1, 0x37, 0xb4, 0x28, 0x0a, 0x96, 0x9d, 0x11, + 0x2a, 0x95, 0xdd, 0xc8, 0x7d, 0x90, 0x3a, 0x8e, 0xfb, 0xe0, 0x23, 0x98, 0x76, 0x1d, 0x97, 0x81, + 0x26, 0x53, 0x5a, 0x4d, 0x7a, 0x85, 0x7b, 0x8e, 0x53, 0x7f, 0x56, 0xaf, 0x38, 0x84, 0x60, 0x96, + 0x85, 0xea, 0x2b, 0xf9, 0x78, 0x6d, 0xe9, 0x84, 0x62, 0x4f, 0x73, 0xdb, 0x55, 0xcd, 0xd3, 0xed, + 0x9a, 0x20, 0xe4, 0x2c, 0x5f, 0xae, 0xb4, 0xab, 0xaa, 0x6e, 0xd7, 0xd0, 0x1a, 0x2c, 0x78, 0xd8, + 0xb4, 0xfc, 0x25, 0x5c, 0xd3, 0xb0, 0xeb, 0x18, 0x0d, 0x46, 0xc9, 0x29, 0x75, 0x3e, 0x5c, 0x7f, + 0xe8, 0x2f, 0xa3, 0x0d, 0x38, 0xcb, 0x40, 0x89, 0x6b, 0x5a, 0x50, 0x25, 0x71, 0x55, 0x9c, 0x62, + 0x0a, 0x8b, 0x62, 0xb7, 0xcc, 0x37, 0xc5, 0xad, 0xe1, 0x93, 0x67, 0xa0, 0x45, 0x8d, 0x40, 0x63, + 0x86, 0x69, 0x2c, 0x04, 0x1a, 0xd4, 0x10, 0xd2, 0xe1, 0x37, 0x1c, 0x8c, 0xfc, 0x4e, 0xcf, 0x0c, + 0x7d, 0xa7, 0x97, 0x7e, 0x77, 0x1a, 0x4e, 0xb2, 0x4f, 0x03, 0xf4, 0x0b, 0x09, 0xd2, 0x7c, 0x38, + 0x81, 0xd6, 0x12, 0xaa, 0x36, 0x3c, 0xa3, 0xc9, 0x5f, 0x1b, 0x47, 0x94, 0xc3, 0x57, 0xfe, 0xe0, + 0xe7, 0x7f, 0xfb, 0xd7, 0xaf, 0xa7, 0x0a, 0x68, 0x59, 0x19, 0x35, 0x5b, 0x42, 0x7f, 0x94, 0x60, + 0x7e, 0x60, 0xca, 0x82, 0x4a, 0x07, 0xbb, 0x19, 0x9c, 0xe5, 0xe4, 0x6f, 0x4d, 0xa4, 0x23, 0x62, + 0x54, 0x58, 0x8c, 0x6b, 0xe8, 0xea, 0xc8, 0x18, 0x95, 0x57, 0x82, 0xe0, 0xf7, 0xd1, 0x9f, 0x24, + 0x38, 0x3d, 0xf4, 0x9a, 0x40, 0x1b, 0xa3, 0x7c, 0x27, 0x4d, 0x79, 0xf2, 0xb7, 0x27, 0xd4, 0x12, + 0x31, 0xaf, 0xb3, 0x98, 0x3f, 0x44, 0x6b, 0x09, 0x31, 0x0f, 0xbf, 0x63, 0xd0, 0xd7, 0x12, 0x2c, + 0x0c, 0x1a, 0x44, 0xb7, 0x26, 0x71, 0x1f, 0xc4, 0xbc, 0x31, 0x99, 0x92, 0x08, 0x79, 0x87, 0x85, + 0xbc, 0x8d, 0x3e, 0x1b, 0x3b, 0x64, 0xe5, 0x55, 0xdf, 0x13, 0x63, 0x7f, 0x58, 0x04, 0xfd, 0x5e, + 0x82, 0xb9, 0xfe, 0xf1, 0x04, 0x5a, 0x1f, 0x15, 0x5d, 0xec, 0xd4, 0x25, 0x5f, 0x9a, 0x44, 0x45, + 0xa4, 0x53, 0x64, 0xe9, 0xac, 0xa2, 0x2b, 0x4a, 0xe2, 0x44, 0x34, 0xfa, 0xf6, 0x40, 0xff, 0x96, + 0xa0, 0x70, 0xc0, 0x43, 0x14, 0x95, 0x47, 0xc5, 0x31, 0xde, 0xab, 0x3a, 0xff, 0xe0, 0x48, 0x36, + 0x44, 0x72, 0x1f, 0xb1, 0xe4, 0x36, 0x50, 0x69, 0x82, 0x5e, 0x71, 0x02, 0xda, 0x47, 0xff, 0x93, + 0x60, 0x79, 0xe4, 0x28, 0x04, 0xdd, 0x9f, 0x04, 0x3f, 0x71, 0xd3, 0x9a, 0xfc, 0xe6, 0x11, 0x2c, + 0x88, 0x14, 0x2b, 0x2c, 0xc5, 0x4f, 0xd1, 0xe3, 0xc3, 0xc3, 0x91, 0x31, 0x6c, 0x98, 0xf8, 0x7f, + 0x25, 0xb8, 0x30, 0x6a, 0xc6, 0x82, 0xee, 0x4d, 0x12, 0x75, 0xcc, 0xb0, 0x27, 0x7f, 0xff, 0xf0, + 0x06, 0x44, 0xd6, 0x8f, 0x58, 0xd6, 0x9b, 0xe8, 0xde, 0x11, 0xb3, 0x66, 0x8c, 0x3d, 0x30, 0x5f, + 0x18, 0xcd, 0xd8, 0xf1, 0xb3, 0x8a, 0xd1, 0x8c, 0x9d, 0x30, 0xc0, 0x38, 0x90, 0xb1, 0xf5, 0x40, + 0x4f, 0xdc, 0xa2, 0xe8, 0x9d, 0x04, 0x4b, 0x23, 0xa6, 0x07, 0xe8, 0xee, 0x24, 0x85, 0x8d, 0x21, + 0x90, 0x7b, 0x87, 0xd6, 0x17, 0x19, 0x6d, 0xb3, 0x8c, 0x1e, 0xa1, 0x87, 0x87, 0xef, 0x4b, 0x94, + 0x6c, 0xfe, 0x2c, 0x41, 0xb6, 0x8f, 0xb7, 0xd0, 0xcd, 0xb1, 0x29, 0x2e, 0xc8, 0x69, 0x7d, 0x02, + 0x0d, 0x91, 0xc5, 0x16, 0xcb, 0xe2, 0x2e, 0xfa, 0xde, 0x78, 0x9c, 0xa8, 0xbc, 0x8a, 0x19, 0x68, + 0xec, 0x97, 0x9f, 0x7e, 0xf9, 0x66, 0x45, 0xfa, 0xea, 0xcd, 0x8a, 0xf4, 0xcf, 0x37, 0x2b, 0xd2, + 0xaf, 0xde, 0xae, 0x9c, 0xf8, 0xea, 0xed, 0xca, 0x89, 0x7f, 0xbc, 0x5d, 0x39, 0xf1, 0xe3, 0x03, + 0x3f, 0x11, 0x3b, 0x51, 0x87, 0xec, 0x7b, 0xb1, 0x9a, 0x66, 0xff, 0x6e, 0xba, 0xf5, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xf5, 0xa2, 0xf3, 0xc9, 0xdc, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3266,21 +3276,26 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error if m.VotingPower != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) i-- - dAtA[i] = 0x50 + dAtA[i] = 0x58 } if m.Height != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Height)) i-- - dAtA[i] = 0x48 + dAtA[i] = 0x50 } if m.SlashedBtcHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x40 + dAtA[i] = 0x48 } if m.SlashedBabylonHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- + dAtA[i] = 0x40 + } + if m.RegisteredEpoch != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.RegisteredEpoch)) + i-- dAtA[i] = 0x38 } if len(m.MasterPubRand) > 0 { @@ -3822,6 +3837,9 @@ func (m *FinalityProviderResponse) Size() (n int) { if l > 0 { n += 1 + l + sovQuery(uint64(l)) } + if m.RegisteredEpoch != 0 { + n += 1 + sovQuery(uint64(m.RegisteredEpoch)) + } if m.SlashedBabylonHeight != 0 { n += 1 + sovQuery(uint64(m.SlashedBabylonHeight)) } @@ -6840,6 +6858,25 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { m.MasterPubRand = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) + } + m.RegisteredEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RegisteredEpoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -6858,7 +6895,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 8: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -6877,7 +6914,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 9: + case 10: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } @@ -6896,7 +6933,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 10: + case 11: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) } diff --git a/x/checkpointing/genesis.go b/x/checkpointing/genesis.go index 1641e7805..5976a76db 100644 --- a/x/checkpointing/genesis.go +++ b/x/checkpointing/genesis.go @@ -2,6 +2,7 @@ package checkpointing import ( "context" + "github.com/babylonchain/babylon/x/checkpointing/keeper" "github.com/babylonchain/babylon/x/checkpointing/types" ) @@ -10,6 +11,7 @@ import ( // state. func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { k.SetGenBlsKeys(ctx, genState.GenesisKeys) + // TODO: should we consider epoch 0 to be finalised at genesis? } // ExportGenesis returns the capability module's exported genesis. diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index d5262b4e5..51dea97ee 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -297,7 +297,11 @@ func (k Keeper) SetCheckpointConfirmed(ctx context.Context, epoch uint64) { // and records the associated state update in lifecycle func (k Keeper) SetCheckpointFinalized(ctx context.Context, epoch uint64) { sdkCtx := sdk.UnwrapSDKContext(ctx) + // set the checkpoint's status to be finalised ckpt := k.setCheckpointStatus(ctx, epoch, types.Confirmed, types.Finalized) + // remember the last finalised epoch + k.SetLastFinalizedEpoch(ctx, epoch) + // emit event err := sdkCtx.EventManager().EmitTypedEvent( &types.EventCheckpointFinalized{Checkpoint: ckpt}, ) @@ -395,3 +399,29 @@ func (k Keeper) GetTotalVotingPower(ctx context.Context, epochNumber uint64) int func (k Keeper) GetPubKeyByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (cmtprotocrypto.PublicKey, error) { return k.epochingKeeper.GetPubKeyByConsAddr(ctx, consAddr) } + +// GetLastFinalizedEpoch gets the last finalised epoch +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + store := k.storeService.OpenKVStore(ctx) + has, err := store.Has(types.LastFinalizedEpochKey) + if err != nil { + panic(err) + } + if !has { + return 0, types.ErrFinalizedEpochNotFound + } + epochNumberBytes, err := store.Get(types.LastFinalizedEpochKey) + if err != nil { + panic(err) + } + return sdk.BigEndianToUint64(epochNumberBytes), nil +} + +// SetLastFinalizedEpoch sets the last finalised epoch +func (k Keeper) SetLastFinalizedEpoch(ctx context.Context, epochNumber uint64) { + store := k.storeService.OpenKVStore(ctx) + epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber) + if err := store.Set(types.LastFinalizedEpochKey, epochNumberBytes); err != nil { + panic(err) + } +} diff --git a/x/checkpointing/types/errors.go b/x/checkpointing/types/errors.go index f212924c6..4ad8c42b2 100644 --- a/x/checkpointing/types/errors.go +++ b/x/checkpointing/types/errors.go @@ -19,4 +19,5 @@ var ( ErrConflictingCheckpoint = errorsmod.Register(ModuleName, 1213, "Conflicting checkpoint is found") ErrInvalidAppHash = errorsmod.Register(ModuleName, 1214, "Provided app hash is Invalid") ErrInsufficientVotingPower = errorsmod.Register(ModuleName, 1215, "Accumulated voting power is not greater than 2/3 of total power") + ErrFinalizedEpochNotFound = errorsmod.Register(ModuleName, 1216, "cannot find a finalized epoch") ) diff --git a/x/checkpointing/types/keys.go b/x/checkpointing/types/keys.go index 735e8c505..53847c1c4 100644 --- a/x/checkpointing/types/keys.go +++ b/x/checkpointing/types/keys.go @@ -31,6 +31,8 @@ var ( AddrToBlsKeyPrefix = append(RegistrationPrefix, 0x0) // where we save the concrete BLS public keys BlsKeyToAddrPrefix = append(RegistrationPrefix, 0x1) // where we save BLS key set + + LastFinalizedEpochKey = []byte{0x04} // LastFinalizedEpochKey defines the key to store the last finalised epoch ) // CkptsObjectKey defines epoch diff --git a/x/epoching/keeper/epochs.go b/x/epoching/keeper/epochs.go index 48ff16606..6ded3bc3a 100644 --- a/x/epoching/keeper/epochs.go +++ b/x/epoching/keeper/epochs.go @@ -33,7 +33,7 @@ func (k Keeper) getEpochInfo(ctx context.Context, epochNumber uint64) (*types.Ep } // InitEpoch sets the zero epoch number to DB -func (k Keeper) InitEpoch(ctx context.Context) { +func (k Keeper) InitEpoch(ctx context.Context) *types.Epoch { header := sdk.UnwrapSDKContext(ctx).HeaderInfo() if header.Height > 0 { panic("InitEpoch can be invoked only at genesis") @@ -41,6 +41,7 @@ func (k Keeper) InitEpoch(ctx context.Context) { epochInterval := k.GetParams(ctx).EpochInterval epoch := types.NewEpoch(0, epochInterval, 0, &header.Time) k.setEpochInfo(ctx, 0, &epoch) + return &epoch } // GetEpoch fetches the current epoch diff --git a/x/finality/keeper/keeper.go b/x/finality/keeper/keeper.go index ebea17422..26bedbd26 100644 --- a/x/finality/keeper/keeper.go +++ b/x/finality/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "context" "fmt" corestoretypes "cosmossdk.io/core/store" @@ -45,3 +46,7 @@ func NewKeeper( func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } + +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + return k.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) +} diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index 720424738..fc880715a 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -77,6 +77,15 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return nil, bstypes.ErrFpAlreadySlashed } + // ensure the finality provider's registered epoch is already finalised by BTC timestamping + finalizedEpoch, err := ms.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) + if err != nil { + panic(err) // only programming error + } + if finalizedEpoch < fp.RegisteredEpoch { + return nil, bstypes.ErrFpNotBTCTimestamped + } + // ensure the finality provider has voting power at this height if req.FpBtcPk == nil { return nil, types.ErrInvalidFinalitySig.Wrap("empty finality provider BTC PK") diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 4ab589626..d04e34e1d 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "context" + "errors" "math/rand" "testing" "time" @@ -51,6 +52,10 @@ func FuzzAddFinalitySig(f *testing.F) { fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) require.NoError(t, err) + // randomise registered epoch for this finality provider + registeredEpoch := datagen.RandomInt(r, 10) + 10 + fp.RegisteredEpoch = registeredEpoch + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() require.NoError(t, err) @@ -66,7 +71,29 @@ func FuzzAddFinalitySig(f *testing.F) { msg, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blockHeight, blockHash) require.NoError(t, err) - // Case 1: fail if the finality provider does not have voting power + // Case 1: slashed finality proivder cannot vote + fp.SlashedBabylonHeight = blockHeight + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg) + require.True(t, errors.Is(err, bstypes.ErrFpAlreadySlashed)) + + // reset slashed height + fp.SlashedBabylonHeight = 0 + + // Case 2: fail if the finality provider's registered epoch is not finalised + // by BTC timestamping yet + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) + finalizedEpoch := registeredEpoch - 1 + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch, nil).Times(1) + _, err = ms.AddFinalitySig(ctx, msg) + require.Error(t, err) + require.True(t, errors.Is(err, bstypes.ErrFpNotBTCTimestamped)) + + // make the registered finality provider BTC-timestamped + finalizedEpoch = registeredEpoch + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch, nil).AnyTimes() + + // Case 3: fail if the finality provider does not have voting power bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(0)).Times(1) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) _, err = ms.AddFinalitySig(ctx, msg) @@ -75,7 +102,7 @@ func FuzzAddFinalitySig(f *testing.F) { // mock voting power bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(1)).AnyTimes() - // Case 2: successful if the finality provider has voting power and has not casted this vote yet + // Case 4: successful if the finality provider has voting power and has not casted this vote yet // index this block first ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: blockHash}) fKeeper.IndexBlock(ctx) @@ -88,13 +115,13 @@ func FuzzAddFinalitySig(f *testing.F) { require.NoError(t, err) require.Equal(t, msg.FinalitySig.MustMarshal(), sig.MustMarshal()) - // Case 3: In case of duplicate vote return success + // Case 5: In case of duplicate vote return success bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) resp, err := ms.AddFinalitySig(ctx, msg) require.NoError(t, err) require.NotNil(t, resp) - // Case 4: the finality provider is slashed if it votes for a fork + // Case 6: the finality provider is slashed if it votes for a fork blockHash2 := datagen.GenRandomByteArray(r, 32) msg2, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blockHeight, blockHash2) require.NoError(t, err) @@ -122,12 +149,6 @@ func FuzzAddFinalitySig(f *testing.F) { // not affect verification require.True(t, btcSK.Key.Equals(&btcSK2.Key) || btcSK.Key.Negate().Equals(&btcSK2.Key)) require.Equal(t, btcSK.PubKey().SerializeCompressed()[1:], btcSK2.PubKey().SerializeCompressed()[1:]) - - // Case 5: slashed finality proivder cannot vote - fp.SlashedBabylonHeight = blockHeight - bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) - _, err = ms.AddFinalitySig(ctx, msg) - require.Equal(t, bstypes.ErrFpAlreadySlashed, err) }) } @@ -148,6 +169,8 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { require.NoError(t, err) fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) require.NoError(t, err) + fp.RegisteredEpoch = 10 + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch, nil).AnyTimes() fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index 942646ba4..2327e35c7 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -16,6 +16,7 @@ type BTCStakingKeeper interface { GetBTCStakingActivatedHeight(ctx context.Context) (uint64, error) GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) RemoveVotingPowerDistCache(ctx context.Context, height uint64) + GetLastFinalizedEpoch(ctx context.Context) (uint64, error) } // IncentiveKeeper defines the expected interface needed to distribute rewards. diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index c5ffaa3e7..df47e89c1 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -65,6 +65,21 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetFinalityProvider(ctx, fpBTCPK int return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetFinalityProvider), ctx, fpBTCPK) } +// GetLastFinalizedEpoch mocks base method. +func (m *MockBTCStakingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. +func (mr *MockBTCStakingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockBTCStakingKeeper)(nil).GetLastFinalizedEpoch), ctx) +} + // GetParams mocks base method. func (m *MockBTCStakingKeeper) GetParams(ctx context.Context) types.Params { m.ctrl.T.Helper() @@ -186,13 +201,13 @@ func (m *MockIncentiveKeeper) EXPECT() *MockIncentiveKeeperMockRecorder { } // RewardBTCStaking mocks base method. -func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, dc *types.VotingPowerDistCache) { +func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, filteredDc *types.VotingPowerDistCache) { m.ctrl.T.Helper() - m.ctrl.Call(m, "RewardBTCStaking", ctx, height, dc) + m.ctrl.Call(m, "RewardBTCStaking", ctx, height, filteredDc) } // RewardBTCStaking indicates an expected call of RewardBTCStaking. -func (mr *MockIncentiveKeeperMockRecorder) RewardBTCStaking(ctx, height, dc interface{}) *gomock.Call { +func (mr *MockIncentiveKeeperMockRecorder) RewardBTCStaking(ctx, height, filteredDc interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RewardBTCStaking", reflect.TypeOf((*MockIncentiveKeeper)(nil).RewardBTCStaking), ctx, height, dc) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RewardBTCStaking", reflect.TypeOf((*MockIncentiveKeeper)(nil).RewardBTCStaking), ctx, height, filteredDc) } diff --git a/x/zoneconcierge/keeper/epochs.go b/x/zoneconcierge/keeper/epochs.go index ad0a478d0..1b0db91da 100644 --- a/x/zoneconcierge/keeper/epochs.go +++ b/x/zoneconcierge/keeper/epochs.go @@ -5,7 +5,6 @@ import ( epochingtypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/babylonchain/babylon/x/zoneconcierge/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) // GetLastSentSegment get last broadcasted btc light client segment @@ -37,32 +36,8 @@ func (k Keeper) setLastSentSegment(ctx context.Context, segment *types.BTCChainS } } -// GetFinalizedEpoch gets the last finalised epoch -// used upon querying the last BTC-finalised chain info for CZs -func (k Keeper) GetFinalizedEpoch(ctx context.Context) (uint64, error) { - store := k.storeService.OpenKVStore(ctx) - has, err := store.Has(types.FinalizedEpochKey) - if err != nil { - panic(err) - } - if !has { - return 0, types.ErrFinalizedEpochNotFound - } - epochNumberBytes, err := store.Get(types.FinalizedEpochKey) - if err != nil { - panic(err) - } - return sdk.BigEndianToUint64(epochNumberBytes), nil -} - -// setFinalizedEpoch sets the last finalised epoch -// called upon each AfterRawCheckpointFinalized hook invocation -func (k Keeper) setFinalizedEpoch(ctx context.Context, epochNumber uint64) { - store := k.storeService.OpenKVStore(ctx) - epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber) - if err := store.Set(types.FinalizedEpochKey, epochNumberBytes); err != nil { - panic(err) - } +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + return k.checkpointingKeeper.GetLastFinalizedEpoch(ctx) } func (k Keeper) GetEpoch(ctx context.Context) *epochingtypes.Epoch { diff --git a/x/zoneconcierge/keeper/grpc_query.go b/x/zoneconcierge/keeper/grpc_query.go index 657915801..2f2f7587d 100644 --- a/x/zoneconcierge/keeper/grpc_query.go +++ b/x/zoneconcierge/keeper/grpc_query.go @@ -238,7 +238,7 @@ func (k Keeper) FinalizedChainsInfo(c context.Context, req *types.QueryFinalized resp := &types.QueryFinalizedChainsInfoResponse{FinalizedChainsInfo: []*types.FinalizedChainInfo{}} // find the last finalised epoch - lastFinalizedEpoch, err := k.GetFinalizedEpoch(ctx) + lastFinalizedEpoch, err := k.GetLastFinalizedEpoch(ctx) if err != nil { return nil, err } @@ -320,7 +320,7 @@ func (k Keeper) FinalizedChainInfoUntilHeight(c context.Context, req *types.Quer resp := &types.QueryFinalizedChainInfoUntilHeightResponse{} // find the last finalised epoch - lastFinalizedEpoch, err := k.GetFinalizedEpoch(ctx) + lastFinalizedEpoch, err := k.GetLastFinalizedEpoch(ctx) if err != nil { return nil, err } diff --git a/x/zoneconcierge/keeper/grpc_query_test.go b/x/zoneconcierge/keeper/grpc_query_test.go index ba6dbf6e5..70a5351f6 100644 --- a/x/zoneconcierge/keeper/grpc_query_test.go +++ b/x/zoneconcierge/keeper/grpc_query_test.go @@ -424,6 +424,7 @@ func FuzzFinalizedChainInfo(f *testing.F) { hooks.AfterEpochEnds(ctx, epoch.EpochNumber) err := hooks.AfterRawCheckpointFinalized(ctx, epoch.EpochNumber) require.NoError(t, err) + checkpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(epoch.EpochNumber, nil).AnyTimes() // check if the chain info of this epoch is recorded or not resp, err := zcKeeper.FinalizedChainsInfo(ctx, &zctypes.QueryFinalizedChainsInfoRequest{ChainIds: chainIDs, Prove: true}) diff --git a/x/zoneconcierge/keeper/hooks.go b/x/zoneconcierge/keeper/hooks.go index f49d823c1..7079dd0b1 100644 --- a/x/zoneconcierge/keeper/hooks.go +++ b/x/zoneconcierge/keeper/hooks.go @@ -30,9 +30,6 @@ func (h Hooks) AfterEpochEnds(ctx context.Context, epoch uint64) { // AfterRawCheckpointFinalized is triggered upon an epoch has been finalised func (h Hooks) AfterRawCheckpointFinalized(ctx context.Context, epoch uint64) error { - // upon an epoch has been finalised, update the last finalised epoch - h.k.setFinalizedEpoch(ctx, epoch) - headersToBroadcast := h.k.getHeadersToBroadcast(ctx) // send BTC timestamp to all open channels with ZoneConcierge diff --git a/x/zoneconcierge/types/errors.go b/x/zoneconcierge/types/errors.go index f37cae374..8d033faf5 100644 --- a/x/zoneconcierge/types/errors.go +++ b/x/zoneconcierge/types/errors.go @@ -12,9 +12,8 @@ var ( ErrChainInfoNotFound = errorsmod.Register(ModuleName, 1104, "no chain info exists") ErrEpochChainInfoNotFound = errorsmod.Register(ModuleName, 1105, "no chain info exists at this epoch") ErrEpochHeadersNotFound = errorsmod.Register(ModuleName, 1106, "no timestamped header exists at this epoch") - ErrFinalizedEpochNotFound = errorsmod.Register(ModuleName, 1107, "cannot find a finalized epoch") - ErrInvalidProofEpochSealed = errorsmod.Register(ModuleName, 1108, "invalid ProofEpochSealed") - ErrInvalidMerkleProof = errorsmod.Register(ModuleName, 1109, "invalid Merkle inclusion proof") - ErrInvalidChainInfo = errorsmod.Register(ModuleName, 1110, "invalid chain info") - ErrInvalidChainIDs = errorsmod.Register(ModuleName, 1111, "chain ids contain duplicates or empty strings") + ErrInvalidProofEpochSealed = errorsmod.Register(ModuleName, 1107, "invalid ProofEpochSealed") + ErrInvalidMerkleProof = errorsmod.Register(ModuleName, 1108, "invalid Merkle inclusion proof") + ErrInvalidChainInfo = errorsmod.Register(ModuleName, 1109, "invalid chain info") + ErrInvalidChainIDs = errorsmod.Register(ModuleName, 1110, "chain ids contain duplicates or empty strings") ) diff --git a/x/zoneconcierge/types/expected_keepers.go b/x/zoneconcierge/types/expected_keepers.go index 303c584ce..895cdb598 100644 --- a/x/zoneconcierge/types/expected_keepers.go +++ b/x/zoneconcierge/types/expected_keepers.go @@ -97,6 +97,7 @@ type BtcCheckpointKeeper interface { type CheckpointingKeeper interface { GetBLSPubKeySet(ctx context.Context, epochNumber uint64) ([]*checkpointingtypes.ValidatorWithBlsKey, error) GetRawCheckpoint(ctx context.Context, epochNumber uint64) (*checkpointingtypes.RawCheckpointWithMeta, error) + GetLastFinalizedEpoch(ctx context.Context) (uint64, error) } type EpochingKeeper interface { diff --git a/x/zoneconcierge/types/keys.go b/x/zoneconcierge/types/keys.go index bafe72112..5dd9d5dc5 100644 --- a/x/zoneconcierge/types/keys.go +++ b/x/zoneconcierge/types/keys.go @@ -33,9 +33,8 @@ var ( CanonicalChainKey = []byte{0x13} // CanonicalChainKey defines the key to store the canonical chain for each CZ in store ForkKey = []byte{0x14} // ForkKey defines the key to store the forks for each CZ in store EpochChainInfoKey = []byte{0x15} // EpochChainInfoKey defines the key to store each epoch's latests chain info for each CZ in store - FinalizedEpochKey = []byte{0x16} // FinalizedEpochKey defines the key to store the last finalised epoch - LastSentBTCSegmentKey = []byte{0x17} // LastSentBTCSegmentKey is key holding last btc light client segment sent to other cosmos zones - ParamsKey = []byte{0x18} // key prefix for the parameters + LastSentBTCSegmentKey = []byte{0x16} // LastSentBTCSegmentKey is key holding last btc light client segment sent to other cosmos zones + ParamsKey = []byte{0x17} // key prefix for the parameters ) func KeyPrefix(p string) []byte { diff --git a/x/zoneconcierge/types/mocked_keepers.go b/x/zoneconcierge/types/mocked_keepers.go index 16f242bc4..68e619a09 100644 --- a/x/zoneconcierge/types/mocked_keepers.go +++ b/x/zoneconcierge/types/mocked_keepers.go @@ -721,6 +721,21 @@ func (mr *MockCheckpointingKeeperMockRecorder) GetBLSPubKeySet(ctx, epochNumber return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBLSPubKeySet", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetBLSPubKeySet), ctx, epochNumber) } +// GetLastFinalizedEpoch mocks base method. +func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. +func (mr *MockCheckpointingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetLastFinalizedEpoch), ctx) +} + // GetRawCheckpoint mocks base method. func (m *MockCheckpointingKeeper) GetRawCheckpoint(ctx context.Context, epochNumber uint64) (*types2.RawCheckpointWithMeta, error) { m.ctrl.T.Helper() From 6bade698b29679ce01f38d379f8ebd23c6878bd2 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 2 Apr 2024 17:59:45 +1100 Subject: [PATCH 067/119] finality: update docs for randomness derivation/timestamping (#604) --- x/btcstaking/README.md | 73 +++++++++++++++-------- x/finality/README.md | 132 ++++++++++------------------------------- 2 files changed, 78 insertions(+), 127 deletions(-) diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index 7ab64e7c0..ea65b9301 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -131,6 +131,17 @@ message Params { uint32 max_active_finality_providers = 7; // min_unbonding_time is the minimum time for unbonding transaction timelock in BTC blocks uint32 min_unbonding_time = 8; + + // min_unbonding_rate is the minimum amount of BTC that are required in unbonding + // output, expressed as a fraction of staking output + // example: if min_unbonding_rate=0.9, then the unbonding output value + // must be at least 90% of staking output, for staking request to be considered + // valid + string min_unbonding_rate = 9 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false + ]; } ``` @@ -146,28 +157,33 @@ finality provider. ```protobuf // FinalityProvider defines a finality provider message FinalityProvider { - // description defines the description terms for the finality provider. - cosmos.staking.v1beta1.Description description = 1; - // commission defines the commission rate of the finality provider. - string commission = 2 [ - (cosmos_proto.scalar) = "cosmos.Dec", - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" - ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 3; - // btc_pk is the Bitcoin secp256k1 PK of this finality provider - // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 5; - // slashed_babylon_height indicates the Babylon height when - // the finality provider is slashed. - // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 6; - // slashed_btc_height indicates the BTC height when - // the finality provider is slashed. - // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 7; + // description defines the description terms for the finality provider. + cosmos.staking.v1beta1.Description description = 1; + // commission defines the commission rate of the finality provider. + string commission = 2 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" + ]; + // babylon_pk is the Babylon secp256k1 PK of this finality provider + cosmos.crypto.secp256k1.PubKey babylon_pk = 3; + // btc_pk is the Bitcoin secp256k1 PK of this finality provider + // the PK follows encoding in BIP-340 spec + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of babylon_pk and btc_pk + ProofOfPossession pop = 5; + // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string + string master_pub_rand = 6; + // registered_epoch is the epoch when this finality provider is registered + uint64 registered_epoch = 7; + // slashed_babylon_height indicates the Babylon height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_babylon_height = 8; + // slashed_btc_height indicates the BTC height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_btc_height = 9; } ``` @@ -183,7 +199,6 @@ identifies a `BTCDelegation` as creating a BTC delegation requires the staker to submit a staking transaction to Bitcoin. ```protobuf - // BTCDelegation defines a BTC delegation message BTCDelegation { // babylon_pk is the Babylon secp256k1 PK of this BTC delegation @@ -228,6 +243,8 @@ message BTCDelegation { uint32 unbonding_time = 13; // btc_undelegation is the information about the early unbonding path of the BTC delegation BTCUndelegation btc_undelegation = 14; + // version of the params used to validate the delegation + uint32 params_version = 15; } // BTCUndelegation contains the information about the early unbonding path of the BTC delegation @@ -347,9 +364,9 @@ message MsgCreateFinalityProvider { string signer = 1; - // description defines the description terms for the finality provider. + // description defines the description terms for the finality provider cosmos.staking.v1beta1.Description description = 2; - // commission defines the commission rate of finality provider. + // commission defines the commission rate of the finality provider string commission = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" @@ -361,6 +378,9 @@ message MsgCreateFinalityProvider { bytes btc_pk = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 6; + // master_pub_rand is the master public randomness of the finality provider + // encoded as a base58 string + string master_pub_rand = 7; } ``` @@ -393,7 +413,8 @@ Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: 2. Ensure the given commission rate is at least the `MinCommissionRate` in the parameters and at most 100%. 3. Ensure the finality provider does not exist already. -4. Create a `FinalityProvider` object and save it to finality provider storage. +4. Ensure the committed master public randomness is in the correct format. +5. Create a `FinalityProvider` object and save it to finality provider storage. ### MsgEditFinalityProvider diff --git a/x/finality/README.md b/x/finality/README.md index b0bd37c2c..f8c63a4b0 100644 --- a/x/finality/README.md +++ b/x/finality/README.md @@ -9,8 +9,6 @@ The Finality module is responsible for handling finality votes, maintaining the finalization status of blocks, and identifying equivocating finality providers in the finalization rounds. This includes: -- handling requests for committing EOTS public randomness from finality - providers; - handling requests for submitting finality votes from finality providers; - maintaining the finalization status of blocks; and - maintaining equivocation evidences of culpable finality providers. @@ -20,13 +18,10 @@ in the finalization rounds. This includes: - [Table of contents](#table-of-contents) - [Concepts](#concepts) - [States](#states) - - [Parameters](#parameters) - - [Public randomness](#public-randomness) - [Finality votes](#finality-votes) - [Indexed blocks with finalization status](#indexed-blocks-with-finalization-status) - [Equivocation evidences](#equivocation-evidences) - [Messages](#messages) - - [MsgCommitPubRandList](#msgcommitpubrandlist) - [MsgAddFinalitySig](#msgaddfinalitysig) - [MsgUpdateParams](#msgupdateparams) - [EndBlocker](#endblocker) @@ -79,17 +74,21 @@ adversarial finality providers. **Interaction between finality providers and the Finality module.** In order to participate in the finality voting round, an active finality provider with BTC delegations (as specified in the [BTC Staking module](../btcstaking/README.md)) -needs to interact with the Finality module as follows: - -- **Committing EOTS public randomness.** The finality provider proactively - commits a list of *EOTS public randomness* for future heights to the Finality - module. EOTS ensures that given an EOTS public randomness, a signer can only - sign a single message. Otherwise, anyone can extract the signer's secret key - by using two EOTS signatures on different messages, the corresponding EOTS - public randomness, and the signer's public key. -- **Submitting EOTS signatures.** Upon a new block, if the finality provider has - committed an EOTS public randomness at this height, then it submits an EOTS - signature w.r.t. the committed EOTS public randomness to the Finality module. +needs to interact with Babylon as follows: + +- **Committing EOTS master public randomness.** The finality provider needs to + generate a pair of EOTS master secret/public randomness, and commit the master + public randomness when registering itself to Babylon. The EOTS master + secret/public randomness allows to derive a EOTS secret/public randomness + deterministically for each given height, respectively. Babylon further + requires the epoch of the finality provider registration to be finalized by + BTC timestamping before the registered finality provider can submit finality + signatures. This ensures that each finality provider has a unique public + randomness for each height, and that if the finality provider submits two + finality signatures over two conflicting blocks, anyone can extract the + finality provider's secret key using EOTS. +- **Submitting EOTS signatures.** Upon a new block, the finality provider + submits an EOTS signature w.r.t. the derived public randomness at that height. The Finality module will verify the EOTS signature, and check if there are known EOTS signatures on conflicting blocks from this finality provider. If yes, then this constitutes an equivocation, and the Finality module will save @@ -106,39 +105,6 @@ transactions to the Bitcoin network. The Finality module maintains the following KV stores. -### Parameters - -The [parameter storage](./keeper/params.go) maintains the Finality module's -parameters. The Finality module's parameters are represented as a `Params` -[object](../../proto/babylon/finality/v1/params.proto) defined as follows: - -```protobuf -// Params defines the parameters for the module. -message Params { - option (gogoproto.goproto_stringer) = false; - - // min_pub_rand is the minimum number of public randomness each - // message should commit - uint64 min_pub_rand = 1; -} -``` - -### Public randomness - -The [public randomness storage](./keeper/public_randomness.go) maintains the -list of EOTS public randomness that each finality provider commits to Babylon. -The key is the finality provider's Bitcoin secp256k1 public key concatenated -with the block height, and the value is a `SchnorrPubRand` -[object](../../types/btc_schnorr_pub_rand.go) representing the EOTS public -randomness that this finality provider commits at this height. The -`SchnorrPubRand` is a point on the secp256k1 curve, and is defined as a 32-byte -array in the implementation. - -```go -type SchnorrPubRand []byte -const SchnorrPubRandLen = 32 -``` - ### Finality votes The [finality vote storage](./keeper/votes.go) maintains the finality votes of @@ -147,9 +113,9 @@ finality provider's Bitcoin secp256k1 public key, and the value is a `SchnorrEOTSSig` [object](../../types/btc_schnorr_eots.go) representing an EOTS signature. Here, the EOTS signature is signed over a block's height and `AppHash` by the finality provider, using the private randomness corresponding -to the EOTS public randomness it commits to at the block's height. The EOTS -signature serves as a finality vote on this block from this finality provider. -It is a 32-byte scalar and is defined as a 32-byte array in the implementation. +to the EOTS public randomness derived using the block height. The EOTS signature +serves as a finality vote on this block from this finality provider. It is a +32-byte scalar and is defined as a 32-byte array in the implementation. ```go type SchnorrEOTSSig []byte @@ -191,12 +157,13 @@ secp256k1 secret key, as per EOTS's extractability property. // Evidence is the evidence that a finality provider has signed finality // signatures with correct public randomness on two conflicting Babylon headers message Evidence { - // fp_btc_pk is the BTC Pk of the finality provider that casts this vote + // fp_btc_pk is the BTC PK of the finality provider that casts this vote bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // block_height is the height of the conflicting blocks uint64 block_height = 2; - // pub_rand is the public randomness the finality provider has committed to - bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + // master_pub_rand is the master public randomness the finality provider has committed to + // encoded as a base58 string + string master_pub_rand = 3; // canonical_app_hash is the AppHash of the canonical block bytes canonical_app_hash = 4; // fork_app_hash is the AppHash of the fork block @@ -220,45 +187,6 @@ message formats are defined at The message handlers are defined at [x/finality/keeper/msg_server.go](./keeper/msg_server.go). -### MsgCommitPubRandList - -The `MsgCommitPubRandList` message is used for committing a list of EOTS public -randomness that will be used by a finality provider in the future. It is -typically submitted by a finality provider via the [finality -provider](https://github.com/babylonchain/finality-provider) program. - -```protobuf -// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS -message MsgCommitPubRandList { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // start_height is the start block height of the list of public randomness - uint64 start_height = 3; - // pub_rand_list is the list of public randomness - repeated bytes pub_rand_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; - // sig is the signature on (start_height || pub_rand_list) signed by - // SK corresponding to fp_btc_pk. This prevents others to commit public - // randomness on behalf of fp_btc_pk - // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts - // the tx submitter to be the holder of fp_btc_pk. Decide this later - bytes sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; -} -``` - -Upon `MsgCommitPubRandList`, a Babylon node will execute as follows: - -1. Ensure the message contains at least `MinPubRand` number of EOTS public - randomness, where `MinPubRand` is defined in the module parameters. -2. Ensure the finality provider has been registered in Babylon. -3. Ensure the list of EOTS public randomness does not overlap with existing EOTS - public randomness that this finality provider previously committed before. -4. Verify the Schnorr signature over the list of public randomness signed by the - finality provider. -5. Store the list of EOTS public randomness to the public randomness storage. - ### MsgAddFinalitySig The `MsgAddFinalitySig` message is used for submitting a finality vote, i.e., an @@ -290,18 +218,20 @@ Upon `MsgAddFinalitySig`, a Babylon node will execute as follows: 1. Ensure the finality provider has been registered in Babylon and is not slashed. -2. Ensure the finality provider has voting power at this height. -3. Ensure the finality provider has not previously casted the same vote. -4. Ensure the finality provider has a committed EOTS public randomness at this - height. -5. Verify the EOTS signature w.r.t. the committed EOTS public randomness. -6. If the voted block's `AppHash` is different from the canonical block at the +2. Ensure the epoch that the finality provider is registered has been finalized + by BTC timestamping. +3. Ensure the finality provider has voting power at this height. +4. Ensure the finality provider has not previously casted the same vote. +5. Derive the EOTS public randomness using the committed EOTS master public + randomness and the block height. +6. Verify the EOTS signature w.r.t. the derived EOTS public randomness. +7. If the voted block's `AppHash` is different from the canonical block at the same height known by the Babylon node, then this means the finality provider has voted for a fork. Babylon node buffers this finality vote to the evidence storage. If the finality provider has also voted for the block at the same height, then this finality provider is slashed, i.e., its voting power is removed, equivocation evidence is recorded, and a slashing event is emitted. -7. If the voted block's `AppHash` is same as that of the canonical block at the +8. If the voted block's `AppHash` is same as that of the canonical block at the same height, then this means the finality provider has voted for the canonical block, and the Babylon node will store this finality vote to the finality vote storage. If the finality provider has also voted for a fork From db96167e7f69c04dc66912fcc06c886dee1e8698 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 3 Apr 2024 17:21:50 +1100 Subject: [PATCH 068/119] chore: finalised epoch 0 at genesis (#606) --- wasmbinding/test/custom_query_test.go | 10 +++++++--- wasmbinding/wasm.go | 7 +------ x/btcstaking/client/cli/tx.go | 8 ++++---- x/btcstaking/keeper/keeper.go | 2 +- x/btcstaking/types/expected_keepers.go | 2 +- x/btcstaking/types/mocked_keepers.go | 5 ++--- x/checkpointing/genesis.go | 3 ++- x/checkpointing/keeper/keeper.go | 13 ++++--------- x/checkpointing/types/errors.go | 1 - x/finality/keeper/keeper.go | 2 +- x/finality/keeper/msg_server.go | 5 +---- x/finality/keeper/msg_server_test.go | 6 +++--- x/finality/types/expected_keepers.go | 2 +- x/finality/types/mocked_keepers.go | 5 ++--- x/zoneconcierge/keeper/epochs.go | 2 +- x/zoneconcierge/keeper/grpc_query.go | 12 ++---------- x/zoneconcierge/keeper/grpc_query_test.go | 2 +- x/zoneconcierge/types/expected_keepers.go | 2 +- x/zoneconcierge/types/mocked_keepers.go | 5 ++--- 19 files changed, 37 insertions(+), 57 deletions(-) diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index bbe4d09c0..8054fb94f 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -71,13 +71,16 @@ func TestFinalizedEpoch(t *testing.T) { LatestFinalizedEpochInfo: &struct{}{}, } - // There is no finalized epoch yet so we require an error - queryCustomErr(t, ctx, babylonApp, contractAddress, query) + // Only epoch 0 is finalised at genesis + resp := bindings.LatestFinalizedEpochInfoResponse{} + queryCustom(t, ctx, babylonApp, contractAddress, query, &resp) + require.Equal(t, resp.EpochInfo.EpochNumber, uint64(0)) + require.Equal(t, resp.EpochInfo.LastBlockHeight, uint64(0)) epoch := babylonApp.EpochingKeeper.InitEpoch(ctx) babylonApp.CheckpointingKeeper.SetCheckpointFinalized(ctx, epoch.EpochNumber) - resp := bindings.LatestFinalizedEpochInfoResponse{} + resp = bindings.LatestFinalizedEpochInfoResponse{} queryCustom(t, ctx, babylonApp, contractAddress, query, &resp) require.Equal(t, resp.EpochInfo.EpochNumber, epoch.EpochNumber) require.Equal(t, resp.EpochInfo.LastBlockHeight, epoch.GetLastBlockHeight()) @@ -326,6 +329,7 @@ func queryCustom( require.NoError(t, err) } +//nolint:unused func queryCustomErr( t *testing.T, ctx sdk.Context, diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index de0ce7dbd..aaf525bf9 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -56,12 +56,7 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag return bz, nil case contractQuery.LatestFinalizedEpochInfo != nil: - epoch, err := qp.zcKeeper.GetLastFinalizedEpoch(ctx) - - if err != nil { - return nil, err - } - + epoch := qp.zcKeeper.GetLastFinalizedEpoch(ctx) epochInfo, err := qp.epochingKeeper.GetHistoricalEpoch(ctx, epoch) if err != nil { diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index d3b170c13..3ab7e7a36 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -39,8 +39,8 @@ func GetTxCmd() *cobra.Command { } cmd.AddCommand( - NewCreateFinalityProvicerCmd(), - NewEditFinalityProvicerCmd(), + NewCreateFinalityProviderCmd(), + NewEditFinalityProviderCmd(), NewCreateBTCDelegationCmd(), NewAddCovenantSigsCmd(), NewBTCUndelegateCmd(), @@ -50,7 +50,7 @@ func GetTxCmd() *cobra.Command { return cmd } -func NewCreateFinalityProvicerCmd() *cobra.Command { +func NewCreateFinalityProviderCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-finality-provider [babylon_pk] [btc_pk] [pop] [master_pub_rand]", Args: cobra.ExactArgs(4), @@ -138,7 +138,7 @@ func NewCreateFinalityProvicerCmd() *cobra.Command { return cmd } -func NewEditFinalityProvicerCmd() *cobra.Command { +func NewEditFinalityProviderCmd() *cobra.Command { cmd := &cobra.Command{ Use: "edit-finality-provider [btc_pk]", Args: cobra.ExactArgs(1), diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index ee16b0250..6c0b9ca68 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -71,6 +71,6 @@ func (k Keeper) BeginBlocker(ctx context.Context) error { return nil } -func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { return k.ckptKeeper.GetLastFinalizedEpoch(ctx) } diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index a9b6aaea8..2f8b0428d 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -23,5 +23,5 @@ type BtcCheckpointKeeper interface { type CheckpointingKeeper interface { GetEpoch(ctx context.Context) *etypes.Epoch - GetLastFinalizedEpoch(ctx context.Context) (uint64, error) + GetLastFinalizedEpoch(ctx context.Context) uint64 } diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index 6234f71b3..4211211d8 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -170,12 +170,11 @@ func (mr *MockCheckpointingKeeperMockRecorder) GetEpoch(ctx interface{}) *gomock } // GetLastFinalizedEpoch mocks base method. -func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + return ret0 } // GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. diff --git a/x/checkpointing/genesis.go b/x/checkpointing/genesis.go index 5976a76db..206293cc5 100644 --- a/x/checkpointing/genesis.go +++ b/x/checkpointing/genesis.go @@ -11,7 +11,8 @@ import ( // state. func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { k.SetGenBlsKeys(ctx, genState.GenesisKeys) - // TODO: should we consider epoch 0 to be finalised at genesis? + // set epoch 0 to be finalised at genesis + k.SetLastFinalizedEpoch(ctx, 0) } // ExportGenesis returns the capability module's exported genesis. diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index 51dea97ee..b99649c39 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -401,20 +401,15 @@ func (k Keeper) GetPubKeyByConsAddr(ctx context.Context, consAddr sdk.ConsAddres } // GetLastFinalizedEpoch gets the last finalised epoch -func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { store := k.storeService.OpenKVStore(ctx) - has, err := store.Has(types.LastFinalizedEpochKey) - if err != nil { - panic(err) - } - if !has { - return 0, types.ErrFinalizedEpochNotFound - } epochNumberBytes, err := store.Get(types.LastFinalizedEpochKey) if err != nil { + // we have set epoch 0 to be finalised at genesis so this can + // only be a programming error panic(err) } - return sdk.BigEndianToUint64(epochNumberBytes), nil + return sdk.BigEndianToUint64(epochNumberBytes) } // SetLastFinalizedEpoch sets the last finalised epoch diff --git a/x/checkpointing/types/errors.go b/x/checkpointing/types/errors.go index 4ad8c42b2..f212924c6 100644 --- a/x/checkpointing/types/errors.go +++ b/x/checkpointing/types/errors.go @@ -19,5 +19,4 @@ var ( ErrConflictingCheckpoint = errorsmod.Register(ModuleName, 1213, "Conflicting checkpoint is found") ErrInvalidAppHash = errorsmod.Register(ModuleName, 1214, "Provided app hash is Invalid") ErrInsufficientVotingPower = errorsmod.Register(ModuleName, 1215, "Accumulated voting power is not greater than 2/3 of total power") - ErrFinalizedEpochNotFound = errorsmod.Register(ModuleName, 1216, "cannot find a finalized epoch") ) diff --git a/x/finality/keeper/keeper.go b/x/finality/keeper/keeper.go index 26bedbd26..590d54eee 100644 --- a/x/finality/keeper/keeper.go +++ b/x/finality/keeper/keeper.go @@ -47,6 +47,6 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } -func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { return k.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) } diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index fc880715a..47d602b0d 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -78,10 +78,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal } // ensure the finality provider's registered epoch is already finalised by BTC timestamping - finalizedEpoch, err := ms.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) - if err != nil { - panic(err) // only programming error - } + finalizedEpoch := ms.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) if finalizedEpoch < fp.RegisteredEpoch { return nil, bstypes.ErrFpNotBTCTimestamped } diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index d04e34e1d..d643583e5 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -84,14 +84,14 @@ func FuzzAddFinalitySig(f *testing.F) { // by BTC timestamping yet bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) finalizedEpoch := registeredEpoch - 1 - bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch, nil).Times(1) + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch).Times(1) _, err = ms.AddFinalitySig(ctx, msg) require.Error(t, err) require.True(t, errors.Is(err, bstypes.ErrFpNotBTCTimestamped)) // make the registered finality provider BTC-timestamped finalizedEpoch = registeredEpoch - bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch, nil).AnyTimes() + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(finalizedEpoch).AnyTimes() // Case 3: fail if the finality provider does not have voting power bsKeeper.EXPECT().GetVotingPower(gomock.Any(), gomock.Eq(fpBTCPKBytes), gomock.Eq(blockHeight)).Return(uint64(0)).Times(1) @@ -170,7 +170,7 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { fp, err := datagen.GenRandomCustomFinalityProvider(r, btcSK, fpBBNSK, msr) require.NoError(t, err) fp.RegisteredEpoch = 10 - bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch, nil).AnyTimes() + bsKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) fpBTCPKBytes := fpBTCPK.MustMarshal() diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index 2327e35c7..cbf8d2072 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -16,7 +16,7 @@ type BTCStakingKeeper interface { GetBTCStakingActivatedHeight(ctx context.Context) (uint64, error) GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) RemoveVotingPowerDistCache(ctx context.Context, height uint64) - GetLastFinalizedEpoch(ctx context.Context) (uint64, error) + GetLastFinalizedEpoch(ctx context.Context) uint64 } // IncentiveKeeper defines the expected interface needed to distribute rewards. diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index df47e89c1..ecef9983e 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -66,12 +66,11 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetFinalityProvider(ctx, fpBTCPK int } // GetLastFinalizedEpoch mocks base method. -func (m *MockBTCStakingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (m *MockBTCStakingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + return ret0 } // GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. diff --git a/x/zoneconcierge/keeper/epochs.go b/x/zoneconcierge/keeper/epochs.go index 1b0db91da..9c70fc9c6 100644 --- a/x/zoneconcierge/keeper/epochs.go +++ b/x/zoneconcierge/keeper/epochs.go @@ -36,7 +36,7 @@ func (k Keeper) setLastSentSegment(ctx context.Context, segment *types.BTCChainS } } -func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { return k.checkpointingKeeper.GetLastFinalizedEpoch(ctx) } diff --git a/x/zoneconcierge/keeper/grpc_query.go b/x/zoneconcierge/keeper/grpc_query.go index 2f2f7587d..3d35be8aa 100644 --- a/x/zoneconcierge/keeper/grpc_query.go +++ b/x/zoneconcierge/keeper/grpc_query.go @@ -238,11 +238,7 @@ func (k Keeper) FinalizedChainsInfo(c context.Context, req *types.QueryFinalized resp := &types.QueryFinalizedChainsInfoResponse{FinalizedChainsInfo: []*types.FinalizedChainInfo{}} // find the last finalised epoch - lastFinalizedEpoch, err := k.GetLastFinalizedEpoch(ctx) - if err != nil { - return nil, err - } - + lastFinalizedEpoch := k.GetLastFinalizedEpoch(ctx) for _, chainID := range req.ChainIds { // check if chain ID is valid if !k.HasChainInfo(ctx, chainID) { @@ -320,11 +316,7 @@ func (k Keeper) FinalizedChainInfoUntilHeight(c context.Context, req *types.Quer resp := &types.QueryFinalizedChainInfoUntilHeightResponse{} // find the last finalised epoch - lastFinalizedEpoch, err := k.GetLastFinalizedEpoch(ctx) - if err != nil { - return nil, err - } - + lastFinalizedEpoch := k.GetLastFinalizedEpoch(ctx) // find the chain info in the last finalised epoch chainInfo, err := k.GetEpochChainInfo(ctx, req.ChainId, lastFinalizedEpoch) if err != nil { diff --git a/x/zoneconcierge/keeper/grpc_query_test.go b/x/zoneconcierge/keeper/grpc_query_test.go index 70a5351f6..08c5cab8b 100644 --- a/x/zoneconcierge/keeper/grpc_query_test.go +++ b/x/zoneconcierge/keeper/grpc_query_test.go @@ -424,7 +424,7 @@ func FuzzFinalizedChainInfo(f *testing.F) { hooks.AfterEpochEnds(ctx, epoch.EpochNumber) err := hooks.AfterRawCheckpointFinalized(ctx, epoch.EpochNumber) require.NoError(t, err) - checkpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(epoch.EpochNumber, nil).AnyTimes() + checkpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(epoch.EpochNumber).AnyTimes() // check if the chain info of this epoch is recorded or not resp, err := zcKeeper.FinalizedChainsInfo(ctx, &zctypes.QueryFinalizedChainsInfoRequest{ChainIds: chainIDs, Prove: true}) diff --git a/x/zoneconcierge/types/expected_keepers.go b/x/zoneconcierge/types/expected_keepers.go index 895cdb598..695af1467 100644 --- a/x/zoneconcierge/types/expected_keepers.go +++ b/x/zoneconcierge/types/expected_keepers.go @@ -97,7 +97,7 @@ type BtcCheckpointKeeper interface { type CheckpointingKeeper interface { GetBLSPubKeySet(ctx context.Context, epochNumber uint64) ([]*checkpointingtypes.ValidatorWithBlsKey, error) GetRawCheckpoint(ctx context.Context, epochNumber uint64) (*checkpointingtypes.RawCheckpointWithMeta, error) - GetLastFinalizedEpoch(ctx context.Context) (uint64, error) + GetLastFinalizedEpoch(ctx context.Context) uint64 } type EpochingKeeper interface { diff --git a/x/zoneconcierge/types/mocked_keepers.go b/x/zoneconcierge/types/mocked_keepers.go index 68e619a09..f5eb253fc 100644 --- a/x/zoneconcierge/types/mocked_keepers.go +++ b/x/zoneconcierge/types/mocked_keepers.go @@ -722,12 +722,11 @@ func (mr *MockCheckpointingKeeperMockRecorder) GetBLSPubKeySet(ctx, epochNumber } // GetLastFinalizedEpoch mocks base method. -func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) (uint64, error) { +func (m *MockCheckpointingKeeper) GetLastFinalizedEpoch(ctx context.Context) uint64 { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetLastFinalizedEpoch", ctx) ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + return ret0 } // GetLastFinalizedEpoch indicates an expected call of GetLastFinalizedEpoch. From 0b2826f2fcdccb75da8874494504e54302bae11f Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 3 Apr 2024 17:29:48 +1100 Subject: [PATCH 069/119] remove ListPublicRandomness query --- client/query/finality.go | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/client/query/finality.go b/client/query/finality.go index 117821468..18220c3ec 100644 --- a/client/query/finality.go +++ b/client/query/finality.go @@ -93,19 +93,3 @@ func (c *QueryClient) ListEvidences(startHeight uint64, pagination *sdkquerytype return resp, err } - -// ListPublicRandomness is a range query for public randomness of a given finality provider. -func (c *QueryClient) ListPublicRandomness(fpBtcPkHex string, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListPublicRandomnessResponse, error) { - var resp *finalitytypes.QueryListPublicRandomnessResponse - err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { - var err error - req := &finalitytypes.QueryListPublicRandomnessRequest{ - FpBtcPkHex: fpBtcPkHex, - Pagination: pagination, - } - resp, err = queryClient.ListPublicRandomness(ctx, req) - return err - }) - - return resp, err -} From 876274952b303ccacf0cc3fb70d821eba363751d Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Thu, 4 Apr 2024 17:52:01 +1100 Subject: [PATCH 070/119] btcstaking: disabling delegation requests to non-timestamped finality providers (#609) --- test/e2e/btc_staking_e2e_test.go | 26 ++++++---- x/btcstaking/README.md | 6 ++- x/btcstaking/keeper/incentive_test.go | 3 ++ x/btcstaking/keeper/keeper_test.go | 4 +- x/btcstaking/keeper/msg_server.go | 21 +++++++-- x/btcstaking/keeper/msg_server_test.go | 47 +++++++++++++++---- x/btcstaking/keeper/power_dist_change_test.go | 9 ++++ .../keeper/voting_power_table_test.go | 9 ++++ x/checkpointing/genesis.go | 1 + 9 files changed, 101 insertions(+), 25 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index c1de3d182..27f3bb29c 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -22,6 +22,7 @@ import ( bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" ftypes "github.com/babylonchain/babylon/x/finality/types" itypes "github.com/babylonchain/babylon/x/incentive/types" ) @@ -179,6 +180,23 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) s.NoError(err) + // finalise epochs until the registered epoch of the finality provider + // so that the finality provider can receive BTC delegations + var ( + startEpoch = uint64(1) + endEpoch = fp.RegisteredEpoch + ) + // wait until the end epoch is sealed + s.Eventually(func() bool { + resp, err := nonValidatorNode.QueryRawCheckpoint(endEpoch) + if err != nil { + return false + } + return resp.Status == ckpttypes.Sealed + }, time.Minute, time.Second*5) + // finalise these epochs + nonValidatorNode.FinalizeSealedEpochs(startEpoch, endEpoch) + // submit the message for creating BTC delegation nonValidatorNode.CreateBTCDelegation( delBabylonSK.PubKey().(*secp256k1.PubKey), @@ -342,14 +360,6 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) - // finalise epochs until the registered epoch of the finality provider - // so that the finality provider can vote - var ( - startEpoch = uint64(1) - endEpoch = fp.RegisteredEpoch - ) - nonValidatorNode.FinalizeSealedEpochs(startEpoch, endEpoch) - // get activated height activatedHeight := nonValidatorNode.QueryActivatedHeight() s.Positive(activatedHeight) diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index ea65b9301..deb963b65 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -413,8 +413,10 @@ Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: 2. Ensure the given commission rate is at least the `MinCommissionRate` in the parameters and at most 100%. 3. Ensure the finality provider does not exist already. -4. Ensure the committed master public randomness is in the correct format. -5. Create a `FinalityProvider` object and save it to finality provider storage. +4. Ensure the finality provider is not slashed. +5. Ensure the finality provider is registered at an epoch that has been BTC-timestamped. +6. Ensure the committed master public randomness is in the correct format. +7. Create a `FinalityProvider` object and save it to finality provider storage. ### MsgEditFinalityProvider diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 7adac41a6..24337ff97 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -42,6 +42,9 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { } } + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() + // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations and add covenant signatures to activate them numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 53ad2e405..4a7b3833c 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -256,11 +256,12 @@ func (h *Helper) CreateDelegationCustom( h.NoError(err) // all good, construct and send MsgCreateBTCDelegation message + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpPK) msgCreateBTCDel := &types.MsgCreateBTCDelegation{ Signer: signer, BabylonPk: delBabylonPK.(*secp256k1.PubKey), BtcPk: stPk, - FpBtcPkList: []bbn.BIP340PubKey{*bbn.NewBIP340PubKeyFromBTCPK(fpPK)}, + FpBtcPkList: []bbn.BIP340PubKey{*fpBTCPK}, Pop: pop, StakingTime: uint32(stakingTimeBlocks), StakingValue: stakingValue, @@ -275,7 +276,6 @@ func (h *Helper) CreateDelegationCustom( } _, err = h.MsgServer.CreateBTCDelegation(h.Ctx, msgCreateBTCDel) - if err != nil { return "", nil, nil, nil, err } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 067ccac88..2d9d01d92 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -192,10 +192,22 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre return nil, types.ErrInvalidProofOfPossession.Wrapf("error while validating proof of posession: %v", err) } - // Ensure all finality providers are known to Babylon + // Ensure all finality providers are known to Babylon, are not slashed, + // and their registered epochs are finalised + lastFinalizedEpoch := ms.GetLastFinalizedEpoch(ctx) for _, fpBTCPK := range req.FpBtcPkList { - if !ms.HasFinalityProvider(ctx, fpBTCPK) { - return nil, types.ErrFpNotFound.Wrapf("finality provider pk: %s", fpBTCPK.MarshalHex()) + // get this finality provider + fp, err := ms.GetFinalityProvider(ctx, fpBTCPK) + if err != nil { + return nil, err + } + // ensure the finality provider is not slashed + if fp.IsSlashed() { + return nil, types.ErrFpAlreadySlashed + } + // ensure the finality provider's registered epoch is finalised + if lastFinalizedEpoch < fp.RegisteredEpoch { + return nil, types.ErrFpNotBTCTimestamped } } @@ -698,11 +710,12 @@ func (ms msgServer) SelectiveSlashingEvidence(goCtx context.Context, req *types. return nil, types.ErrFpNotFound.Wrapf("BTC delegation is not staked to the finality provider") } - // ensure the finality provider exists and is not slashed + // ensure the finality provider exists fp, err := ms.GetFinalityProvider(ctx, fpBTCPK.MustMarshal()) if err != nil { panic(types.ErrFpNotFound.Wrapf("failing to find the finality provider with BTC delegations")) } + // ensure the finality provider is not slashed if fp.IsSlashed() { return nil, types.ErrFpAlreadySlashed } diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index fc1ad15b0..0bc378c0d 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -163,7 +163,10 @@ func FuzzCreateBTCDelegation(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -208,7 +211,10 @@ func TestProperVersionInDelegation(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -276,7 +282,10 @@ func FuzzAddCovenantSigs(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -344,7 +353,10 @@ func FuzzBTCUndelegate(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -415,9 +427,12 @@ func FuzzSelectiveSlashing(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - fpSK, fpPK, _ := h.CreateFinalityProvider(r) + fpSK, fpPK, fp := h.CreateFinalityProvider(r) fpBtcPk := bbn.NewBIP340PubKeyFromBTCPK(fpPK) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) + // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( @@ -482,9 +497,12 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - fpSK, fpPK, _ := h.CreateFinalityProvider(r) + fpSK, fpPK, fp := h.CreateFinalityProvider(r) fpBtcPk := bbn.NewBIP340PubKeyFromBTCPK(fpPK) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) + // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( @@ -647,10 +665,11 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { h.NoError(err) // all good, construct and send MsgCreateBTCDelegation message + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpPK) msgCreateBTCDel := &types.MsgCreateBTCDelegation{ Signer: signer, BabylonPk: delBabylonPK.(*secp256k1.PubKey), - FpBtcPkList: []bbn.BIP340PubKey{*bbn.NewBIP340PubKeyFromBTCPK(fpPK)}, + FpBtcPkList: []bbn.BIP340PubKey{*fpBTCPK}, BtcPk: bbn.NewBIP340PubKeyFromBTCPK(delSK.PubKey()), Pop: pop, StakingTime: uint32(stakingTimeBlocks), @@ -664,6 +683,10 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { UnbondingSlashingTx: testUnbondingInfo.SlashingTx, DelegatorUnbondingSlashingSig: delUnbondingSlashingSig, } + + // mock last finalised epoch + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(0)) + _, err = h.MsgServer.CreateBTCDelegation(h.Ctx, msgCreateBTCDel) require.Error(t, err) require.True(t, errors.Is(err, types.ErrFpNotFound)) @@ -726,7 +749,10 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).MaxTimes(1) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -799,7 +825,10 @@ func TestMinimalUnbondingRate(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, _ := h.CreateFinalityProvider(r) + _, fpPK, fp := h.CreateFinalityProvider(r) + + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).MaxTimes(1) // generate and insert new BTC delegation stakingTxHash, _, _, _, err := h.CreateDelegationCustom( diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index da4ec9502..cce512c36 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -38,6 +38,9 @@ func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { fpPKs = append(fpPKs, fpPK) } + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() + // empty dist cache dc := types.NewVotingPowerDistCache() @@ -86,6 +89,9 @@ func FuzzFinalityProviderEvents(f *testing.F) { // generate and insert new finality provider _, fpPK, fp := h.CreateFinalityProvider(r) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() + /* insert new BTC delegation and give it covenant quorum ensure that it has voting power @@ -164,6 +170,9 @@ func FuzzBTCDelegationEvents(f *testing.F) { // generate and insert new finality provider _, fpPK, fp := h.CreateFinalityProvider(r) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() + // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) expectedStakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index 82ac32e6d..c68d264e7 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -40,6 +40,9 @@ func FuzzVotingPowerTable(f *testing.F) { fps = append(fps, fp) } + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() + // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 @@ -170,6 +173,9 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) h.NoError(err) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() + // generate a random batch of finality providers, each with a BTC delegation with random power fpsWithMeta := []*types.FinalityProviderDistInfo{} numFps := datagen.RandomInt(r, 300) + 1 @@ -263,6 +269,9 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) h.NoError(err) + // mock that the registered epoch is finalised + h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() + numFps := datagen.RandomInt(r, 20) + 10 numActiveFPs := int(min(numFps, uint64(bsParams.MaxActiveFinalityProviders))) diff --git a/x/checkpointing/genesis.go b/x/checkpointing/genesis.go index 206293cc5..f285f08d1 100644 --- a/x/checkpointing/genesis.go +++ b/x/checkpointing/genesis.go @@ -9,6 +9,7 @@ import ( // InitGenesis initializes the capability module's state from a provided genesis // state. +// TODO: importing/exporting genesis func InitGenesis(ctx context.Context, k keeper.Keeper, genState types.GenesisState) { k.SetGenBlsKeys(ctx, genState.GenesisKeys) // set epoch 0 to be finalised at genesis From 5f6c6472bd1b2ac0e9dc2928aa3892f4596ab2c7 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Thu, 4 Apr 2024 10:57:46 -0300 Subject: [PATCH 071/119] feat: add set-btc-dels to genstate from file input (#608) * feat: add set-btc-dels to genstate from file input * chore: refactory and add check if btc delegation finality probider exists * chore: add check for insert btc del with invalid fp --- cmd/babylond/cmd/genhelpers/cmd.go | 1 + .../cmd/genhelpers/set_btc_delegations.go | 157 +++++++++++++++++ .../genhelpers/set_btc_delegations_test.go | 164 ++++++++++++++++++ .../cmd/genhelpers/set_finality_providers.go | 89 ++++++---- .../genhelpers/set_finality_providers_test.go | 18 +- 5 files changed, 394 insertions(+), 35 deletions(-) create mode 100644 cmd/babylond/cmd/genhelpers/set_btc_delegations.go create mode 100644 cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go diff --git a/cmd/babylond/cmd/genhelpers/cmd.go b/cmd/babylond/cmd/genhelpers/cmd.go index bc5cabaf7..7c99433e8 100644 --- a/cmd/babylond/cmd/genhelpers/cmd.go +++ b/cmd/babylond/cmd/genhelpers/cmd.go @@ -21,6 +21,7 @@ func CmdGenHelpers(validator genutiltypes.MessageValidator) *cobra.Command { CmdCreateBls(), CmdAddBls(validator), CmdSetFp(), + CmdSetBtcDels(), ) return cmd diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations.go new file mode 100644 index 000000000..15427d573 --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations.go @@ -0,0 +1,157 @@ +package genhelpers + +import ( + "fmt" + + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + + "github.com/spf13/cobra" +) + +// CmdSetBtcDels CLI sets bitcoin delegations into the genesis state. +func CmdSetBtcDels() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-btc-delegations [path/to/btc_delegations.json]", + Short: "Set the BTC delegations from the given json file into the genesis.json", + Long: `Reads BTC delegation structures from the given json file and update the genesis.json file +in place to include the delegations in the btcstaking module's genesis state. +Duplicated BTC delegations are not allowed and it will prompt an error. +`, + Example: `babylond gen-helpers set-btc-delegations path/to/btc_delegations.json +Possible content of 'btc_delegations.json' is +{ + "btc_delegations": [ + { + "babylon_pk": { + "key": "AkCmkLYWjr0/49MCK3lzTqKC1MiPSldXgoqP0EdtV8m1" + }, + "btc_pk": "5ea8d7dfe920f5aecb1f4411b1b3e6684031ecb7a282df65107a615adc562a48", + "pop": { + "btc_sig_type": "BIP340", + "babylon_sig": "gjqXTQdgzC6AX/lnj3T3QV5vV+jtKDKwJOP9jMpZdb90MoIKRGV7j/A6lwbgsnUzbsvd4L19U7/3cOZqYBfQAg==", + "btc_sig": "Gx0VxuXgjiLvdCIIx1eN9JE9mqo+qvIo48cUhTCbM6uTxt59HTJiVGloHE518OXk+vQrNcHB+bZFqX+T5wMS9w==" + }, + "fp_btc_pk_list": [ + "3d6a1db7bffaebed71831fae74d32bf78e97884c41634cc1a80b0ebbffe1c7dd" + ], + "start_height": "127", + "end_height": "10127", + "total_sat": "1000000", + "staking_tx": "AQAAAAF/cxe2A5/IsfYkwiVTA795y/X16NDBpqETC3kiv27AKgAAAABrSDBFAiEA8inc8+grbO6iJbl1VwJjR4Y89dK7ATcEz3XnJPNd37MCIGd0wpfu3Hz4+hjVXatnKCTViUG2SPiD83k/+yhy9bIIASEDXqjX3+kg9a7LH0QRsbPmaEAx7Leigt9lEHphWtxWKkj/////AkBCDwAAAAAAIlEg8eeUnPklLO9pkkhYMkoQFW7gxAmd4W781NwChbc9WSe0mPYpAQAAABl2qRS9MnviWBrF4wvpgMpBhIFGQHnOWYisAAAAAA==", + "staking_output_idx": 0, + "slashing_tx": "AQAAAAES8FBlJfWXZSLzImp6AjfD1bosph2q02QhTIjDo9T8bQAAAAAA/////wKghgEAAAAAABl2qRQBAQEBAQEBAQEBAQEBAQEBAQEBAYisuLcNAAAAAAAiUSD1hd0Q7BOqlMAZY6fqBidPwKe7jLRXtdGcpgQjVIhr8wAAAAA=", + "delegator_sig": "2i6kTpmzn0pJAbY+v5Ktf0yo6YNhucVZC4clg4YVVZKU7dVh9DKEzrichq5C1eFgaRr+YYtEyxtTlVwhyOg2Ag==", + "covenant_sigs": [ + { + "cov_pk": "e76137fda8dff755a0879264c4eb3c3574ab77b6c5589f47b090203e4938d065", + "adaptor_sigs": [ + "Ann3xe0L1gIHWS2+hhHwRDTPz5RoCFzBBte0xkhJ0VRUWDB2a46Pl1miZ9y+jyseZNYcps+DeE1cB/S54oeVQYEA" + ] + } + ], + "unbonding_time": 101, + "btc_undelegation": { + "unbonding_tx": "AgAAAAES8FBlJfWXZSLzImp6AjfD1bosph2q02QhTIjDo9T8bQAAAAAA/////wGsMA8AAAAAACJRIEObJoQoxADSVZ3K8dV0Req4coALcrefxibIBmWItvVDAAAAAA==", + "slashing_tx": "AQAAAAGGZtqTIrJN8TDOMw+bbENzXLECv1Z1E4idjZ2UiHnsbAAAAAAA/////wLehAEAAAAAABl2qRQBAQEBAQEBAQEBAQEBAQEBAQEBAYis5qcNAAAAAAAiUSD1hd0Q7BOqlMAZY6fqBidPwKe7jLRXtdGcpgQjVIhr8wAAAAA=", + "delegator_unbonding_sig": null, + "delegator_slashing_sig": "P6GSaJdbIhEED+k74T1sRYzTYHUhzg8/NDGvwR+sBHXhKsT8O82XRaHyvjFXAVCLK0sa5oxSOTndMmY3SKHNsw==", + "covenant_slashing_sigs": [ + { + "cov_pk": "e76137fda8dff755a0879264c4eb3c3574ab77b6c5589f47b090203e4938d065", + "adaptor_sigs": [ + "AjZrivh6++7Wu7OWFRxLAv2SHPvf0VhZM7pZK7oWP3KoWKdPpBcNotFqjdCQE2TTSshS4qpEuwYMLtMMzYqIOKYA" + ] + } + ], + "covenant_unbonding_sig_list": [ + { + "pk": "e76137fda8dff755a0879264c4eb3c3574ab77b6c5589f47b090203e4938d065", + "sig": "t+zUA4qtNCKREviFUtwWh46QNEov033whhF2i89oF2mEoa55k7Hq68TAY+jiGeeTJU1BM7Q4Qfu8XFuv3c1WAw==" + } + ] + }, + "params_version": 0 + } + ], +} +`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + config := server.GetServerContextFromCmd(cmd).Config + config.SetRoot(clientCtx.HomeDir) + + inputBtcDels, err := getBtcStakingGenStateFromFile(clientCtx.Codec, args[0]) + if err != nil { + return err + } + + genFile := config.GenesisFile() + appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + btcstkGenState := btcstktypes.GenesisStateFromAppState(clientCtx.Codec, appState) + + genStateBtcDelsByTxHash := make(map[string]struct{}, 0) + for _, del := range btcstkGenState.BtcDelegations { + hash, err := del.GetStakingTxHash() + if err != nil { + return err + } + + key := hash.String() + if _, ok := genStateBtcDelsByTxHash[key]; ok { + return fmt.Errorf("bad genesis state, there is more than one btc delegator with the same staking tx hash %s", key) + } + genStateBtcDelsByTxHash[key] = struct{}{} + } + + genStateFpsByBtcPk, err := mapFinalityProvidersByBtcPk(btcstkGenState.FinalityProviders) + if err != nil { + return fmt.Errorf("bad gen state: %w", err) + } + + newDels := make([]*btcstktypes.BTCDelegation, 0, len(inputBtcDels.BtcDelegations)) + for _, del := range inputBtcDels.BtcDelegations { + if err := del.ValidateBasic(); err != nil { + return fmt.Errorf("failed to validate basic btc delegation: %w", err) + } + + hash, err := del.GetStakingTxHash() + if err != nil { + return err + } + + key := hash.String() + if _, ok := genStateBtcDelsByTxHash[key]; ok { + return fmt.Errorf("error: btc delegation: %+v\nwas already set on genesis, or contains the same staking tx hash %s than another btc delegation", del, key) + } + + for _, fpBTCpk := range del.FpBtcPkList { + fpKey := fpBTCpk.MarshalHex() + if _, ok := genStateFpsByBtcPk[fpKey]; !ok { + return fmt.Errorf("error: btc delegation: %+v\nhas an associated finality provider that is not set on genesis %s", del, fpKey) + } + } + + genStateBtcDelsByTxHash[key] = struct{}{} + newDels = append(newDels, del) + } + btcstkGenState.BtcDelegations = append(btcstkGenState.BtcDelegations, newDels...) + + err = replaceModOnGenesis(clientCtx.Codec, genDoc, appState, btcstktypes.ModuleName, &btcstkGenState) + if err != nil { + return err + } + + return genutil.ExportGenesisFile(genDoc, genFile) + }, + } + + return cmd +} diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go new file mode 100644 index 000000000..ab881ed09 --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go @@ -0,0 +1,164 @@ +package genhelpers_test + +import ( + "context" + "encoding/hex" + "fmt" + "math/rand" + "path/filepath" + "testing" + + sdkmath "cosmossdk.io/math" + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" + bbn "github.com/babylonchain/babylon/types" + btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/btcsuite/btcd/chaincfg" + "github.com/cosmos/cosmos-sdk/client" + genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/stretchr/testify/require" +) + +func FuzzCmdSetBtcDels(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r, h := rand.New(rand.NewSource(seed)), helper.NewHelper(t) + app := h.App + cdc := app.AppCodec() + home := t.TempDir() + + clientCtx := client.Context{}. + WithCodec(app.AppCodec()). + WithHomeDir(home). + WithTxConfig(app.TxConfig()) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + err := genutiltest.ExecInitCmd(app.BasicModuleManager, home, cdc) + require.NoError(t, err) + + qntBtcDels := int(datagen.RandomInt(r, 10)) + 1 + btcDelsToAdd := make([]*btcstktypes.BTCDelegation, qntBtcDels) + + fp, err := datagen.GenRandomFinalityProvider(r) + require.NoError(t, err) + + // write fp to genesis + fpsToAddFilePath := filepath.Join(home, "fpsToAdd.json") + writeFileProto(t, cdc, fpsToAddFilePath, &btcstktypes.GenesisState{ + FinalityProviders: []*btcstktypes.FinalityProvider{fp}, + }) + + cmdSetFp := genhelpers.CmdSetFp() + cmdSetFp.SetArgs([]string{fpsToAddFilePath}) + cmdSetFp.SetContext(ctx) + + // Runs the cmd to write into the genesis + err = cmdSetFp.Execute() + require.NoError(t, err) + + covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) + slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) + require.NoError(t, err) + + startHeight := datagen.RandomInt(r, 100) + 1 + endHeight := datagen.RandomInt(r, 1000) + startHeight + btcctypes.DefaultParams().CheckpointFinalizationTimeout + 1 + slashingRate := sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2) + slashingChangeLockTime := uint16(101) + + for i := 0; i < qntBtcDels; i++ { + delSK, _, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + del, err := datagen.GenRandomBTCDelegation( + r, + t, + []bbn.BIP340PubKey{*fp.BtcPk}, + delSK, + covenantSKs, + covenantQuorum, + slashingAddress.EncodeAddress(), + startHeight, endHeight, 10000, + slashingRate, + slashingChangeLockTime, + ) + require.NoError(t, err) + btcDelsToAdd[i] = del + } + + btcDelsToAddFilePath := filepath.Join(home, "delsToAdd.json") + writeFileProto(t, cdc, btcDelsToAddFilePath, &btcstktypes.GenesisState{ + BtcDelegations: btcDelsToAdd, + }) + + cmdSetBtcDel := genhelpers.CmdSetBtcDels() + cmdSetBtcDel.SetArgs([]string{btcDelsToAddFilePath}) + cmdSetBtcDel.SetContext(ctx) + + // Runs the cmd to write into the genesis + err = cmdSetBtcDel.Execute() + require.NoError(t, err) + + cmtcfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(t, err) + + // Verifies that the new genesis were created + appState, _, err := genutiltypes.GenesisStateFromGenFile(cmtcfg.GenesisFile()) + require.NoError(t, err) + + btcstkGenState := btcstktypes.GenesisStateFromAppState(cdc, appState) + // make sure the same quantity of BTC delegations were created. + require.Equal(t, qntBtcDels, len(btcstkGenState.BtcDelegations)) + + for i := 0; i < qntBtcDels; i++ { + bzAdd, err := btcDelsToAdd[i].Marshal() + require.NoError(t, err) + + bzGen, err := btcstkGenState.BtcDelegations[i].Marshal() + require.NoError(t, err) + + require.Equal(t, hex.EncodeToString(bzAdd), hex.EncodeToString(bzGen)) + } + + // tries to add again, it should error out + btcDel := btcDelsToAdd[0] + + hash, err := btcDel.GetStakingTxHash() + require.NoError(t, err) + key := hash.String() + + err = cmdSetBtcDel.Execute() + require.EqualError(t, err, fmt.Errorf("error: btc delegation: %+v\nwas already set on genesis, or contains the same staking tx hash %s than another btc delegation", btcDel, key).Error()) + + // checks trying to insert a new btc delegation with an finality provider that is not present in genesis. It should error out + notInGenFp, err := datagen.GenRandomFinalityProvider(r) + require.NoError(t, err) + + delSK, _, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + delWithBadFp, err := datagen.GenRandomBTCDelegation( + r, + t, + []bbn.BIP340PubKey{*notInGenFp.BtcPk}, + delSK, + covenantSKs, + covenantQuorum, + slashingAddress.EncodeAddress(), + startHeight, endHeight, 10000, + slashingRate, + slashingChangeLockTime, + ) + require.NoError(t, err) + + writeFileProto(t, cdc, btcDelsToAddFilePath, &btcstktypes.GenesisState{ + BtcDelegations: []*btcstktypes.BTCDelegation{delWithBadFp}, + }) + + err = cmdSetBtcDel.Execute() + require.EqualError(t, err, fmt.Errorf("error: btc delegation: %+v\nhas an associated finality provider that is not set on genesis %s", delWithBadFp, notInGenFp.BtcPk.MarshalHex()).Error()) + }) +} diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers.go b/cmd/babylond/cmd/genhelpers/set_finality_providers.go index e6658a739..eb6346dec 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers.go @@ -2,17 +2,17 @@ package genhelpers import ( "encoding/json" - "errors" "fmt" "os" btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" cmtos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - + "github.com/cosmos/gogoproto/proto" "github.com/spf13/cobra" ) @@ -59,18 +59,7 @@ Possible content of 'finality_providers.json' is config := server.GetServerContextFromCmd(cmd).Config config.SetRoot(clientCtx.HomeDir) - finalityProvidersInputPath := args[0] - if !cmtos.FileExists(finalityProvidersInputPath) { - return errors.New("finality providers input file does not exist") - } - - fpsBz, err := os.ReadFile(finalityProvidersInputPath) - if err != nil { - return err - } - - var inputFps btcstktypes.GenesisState - err = clientCtx.Codec.UnmarshalJSON(fpsBz, &inputFps) + inputFps, err := getBtcStakingGenStateFromFile(clientCtx.Codec, args[0]) if err != nil { return err } @@ -82,13 +71,9 @@ Possible content of 'finality_providers.json' is } btcstkGenState := btcstktypes.GenesisStateFromAppState(clientCtx.Codec, appState) - genStateFpsByBtcPk := make(map[string]struct{}, 0) - for _, fpGen := range btcstkGenState.FinalityProviders { - key := fpGen.BtcPk.MarshalHex() - if _, ok := genStateFpsByBtcPk[key]; ok { - return fmt.Errorf("bad genesis state, there is more than one finality provider with the same btc key %s", key) - } - genStateFpsByBtcPk[key] = struct{}{} + genStateFpsByBtcPk, err := mapFinalityProvidersByBtcPk(btcstkGenState.FinalityProviders) + if err != nil { + return fmt.Errorf("bad gen state: %w", err) } newFps := make([]*btcstktypes.FinalityProvider, 0, len(inputFps.FinalityProviders)) @@ -108,20 +93,66 @@ Possible content of 'finality_providers.json' is } btcstkGenState.FinalityProviders = append(btcstkGenState.FinalityProviders, newFps...) - btcstkGenStateWithFps, err := clientCtx.Codec.MarshalJSON(&btcstkGenState) + err = replaceModOnGenesis(clientCtx.Codec, genDoc, appState, btcstktypes.ModuleName, &btcstkGenState) if err != nil { - return fmt.Errorf("failed to marshal btcstaking genesis state: %w", err) + return err } - appState[btcstktypes.ModuleName] = btcstkGenStateWithFps - appStateJSON, err := json.Marshal(appState) - if err != nil { - return fmt.Errorf("failed to marshal application genesis state: %w", err) - } - genDoc.AppState = appStateJSON return genutil.ExportGenesisFile(genDoc, genFile) }, } return cmd } + +func replaceModOnGenesis( + cdc codec.Codec, + genDoc *genutiltypes.AppGenesis, + appState map[string]json.RawMessage, + modname string, + modGenState proto.Message, +) error { + newModGenState, err := cdc.MarshalJSON(modGenState) + if err != nil { + return fmt.Errorf("failed to marshal %s genesis state: %w", modname, err) + } + appState[modname] = newModGenState + + appStateJSON, err := json.Marshal(appState) + if err != nil { + return fmt.Errorf("failed to marshal application genesis state: %w", err) + } + genDoc.AppState = appStateJSON + return nil +} + +func getBtcStakingGenStateFromFile(cdc codec.Codec, inputFilePath string) (*btcstktypes.GenesisState, error) { + if !cmtos.FileExists(inputFilePath) { + return nil, fmt.Errorf("input file %s does not exists", inputFilePath) + } + + fpsBz, err := os.ReadFile(inputFilePath) + if err != nil { + return nil, err + } + + var genState btcstktypes.GenesisState + err = cdc.UnmarshalJSON(fpsBz, &genState) + if err != nil { + return nil, err + } + + return &genState, nil +} + +func mapFinalityProvidersByBtcPk(fps []*btcstktypes.FinalityProvider) (map[string]struct{}, error) { + genStateFpsByBtcPk := make(map[string]struct{}, 0) + for _, fpGen := range fps { + key := fpGen.BtcPk.MarshalHex() + if _, ok := genStateFpsByBtcPk[key]; ok { + return nil, fmt.Errorf("there is more than one finality provider with the same btc key %s", key) + } + genStateFpsByBtcPk[key] = struct{}{} + } + return genStateFpsByBtcPk, nil +} diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go index d9fe19361..d3a97909a 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go @@ -14,8 +14,10 @@ import ( btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/cometbft/cometbft/libs/tempfile" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/require" ) @@ -48,14 +50,10 @@ func FuzzCmdSetFp(f *testing.F) { WithTxConfig(app.TxConfig()) ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) - jsonBytes, err := cdc.MarshalJSON(&btcstktypes.GenesisState{ + fpsToAddFilePath := filepath.Join(home, "fpsToAdd.json") + writeFileProto(t, cdc, fpsToAddFilePath, &btcstktypes.GenesisState{ FinalityProviders: fpsToAdd, }) - require.NoError(t, err) - - fpsToAddFilePath := filepath.Join(home, "fpsToAdd.json") - err = tempfile.WriteFileAtomic(fpsToAddFilePath, jsonBytes, 0600) - require.NoError(t, err) cmdSetFp := genhelpers.CmdSetFp() cmdSetFp.SetArgs([]string{fpsToAddFilePath}) @@ -92,3 +90,11 @@ func FuzzCmdSetFp(f *testing.F) { require.EqualError(t, err, fmt.Errorf("error: finality provider: %+v\nwas already set on genesis, or contains the same BtcPk %s than another finality provider", fp, fp.BtcPk.MarshalHex()).Error()) }) } + +func writeFileProto(t *testing.T, cdc codec.Codec, fpath string, structToWriteInFile proto.Message) { + jsonBytes, err := cdc.MarshalJSON(structToWriteInFile) + require.NoError(t, err) + + err = tempfile.WriteFileAtomic(fpath, jsonBytes, 0600) + require.NoError(t, err) +} From 682c2d238ca305243d361a512bd0c401eedef1c6 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Fri, 5 Apr 2024 08:11:41 -0300 Subject: [PATCH 072/119] feat: add set-btc-headers to genstate from file input (#610) * feat: add set-btc-dels to genstate from file input * chore: refactory and add check if btc delegation finality probider exists * chore: add check for insert btc del with invalid fp * feat: add set-btc-headers to genhelpers --- cmd/babylond/cmd/genhelpers/cmd.go | 1 + .../cmd/genhelpers/set_btc_headers.go | 122 ++++++++++++++++++ .../cmd/genhelpers/set_btc_headers_test.go | 93 +++++++++++++ .../cmd/genhelpers/set_finality_providers.go | 4 +- x/btclightclient/types/genesis.go | 15 +++ 5 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 cmd/babylond/cmd/genhelpers/set_btc_headers.go create mode 100644 cmd/babylond/cmd/genhelpers/set_btc_headers_test.go diff --git a/cmd/babylond/cmd/genhelpers/cmd.go b/cmd/babylond/cmd/genhelpers/cmd.go index 7c99433e8..46be23a92 100644 --- a/cmd/babylond/cmd/genhelpers/cmd.go +++ b/cmd/babylond/cmd/genhelpers/cmd.go @@ -22,6 +22,7 @@ func CmdGenHelpers(validator genutiltypes.MessageValidator) *cobra.Command { CmdAddBls(validator), CmdSetFp(), CmdSetBtcDels(), + CmdSetBtcHeaders(), ) return cmd diff --git a/cmd/babylond/cmd/genhelpers/set_btc_headers.go b/cmd/babylond/cmd/genhelpers/set_btc_headers.go new file mode 100644 index 000000000..9110f5dab --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_btc_headers.go @@ -0,0 +1,122 @@ +package genhelpers + +import ( + "fmt" + "os" + + cmtos "github.com/cometbft/cometbft/libs/os" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/x/genutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + + btclighttypes "github.com/babylonchain/babylon/x/btclightclient/types" + + "github.com/spf13/cobra" +) + +// CmdSetBtcHeaders CLI sets bitcoin headers into the genesis state. +func CmdSetBtcHeaders() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-btc-headers [path/to/btc_headers.json]", + Short: "Set the BTC headers from the given json file into the genesis.json", + Long: `Reads BTC Headers structures from the given json file and update the genesis.json file +in place to include the btc headers in the btcstaking module's genesis state. +Duplicated BTC headers are not allowed and it will prompt an error. +`, + Example: `babylond gen-helpers set-btc-headers path/to/btc_headers.json +Possible content of 'btc_headers.json' is +{ + "btc_headers": [ + { + "header": "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a45068653ffff7f2002000000", + "hash": "683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6", + "height": "0", + "work": "2" + }, + { + "header": "00000020f67ad7695d9b662a72ff3d8edbbb2de0bfa67b13974bb9910d116d5cbd863e682259b3c6351788d4456e8fbb738dd51fd6aea615f63b10f634021f930c9c34be02150466ffff7f2000000000", + "hash": "6fceca20e50018d9f54632b791144eef4b3f9cb2ced9fa2702c376857a550e03", + "height": "1", + "work": "4" + } + ] +} +`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + config := server.GetServerContextFromCmd(cmd).Config + config.SetRoot(clientCtx.HomeDir) + + inputBtcHeaders, err := getBtcLightGenStateFromFile(clientCtx.Codec, args[0]) + if err != nil { + return err + } + + genFile := config.GenesisFile() + appState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFile) + if err != nil { + return fmt.Errorf("failed to unmarshal genesis state: %w", err) + } + btclightGenState := btclighttypes.GenesisStateFromAppState(clientCtx.Codec, appState) + + genStateBtcHeaderByHash := make(map[string]struct{}, 0) + for _, btcHeader := range btclightGenState.BtcHeaders { + key := btcHeader.Hash.MarshalHex() + if _, ok := genStateBtcHeaderByHash[key]; ok { + return fmt.Errorf("bad genesis state, there is more than one btc header with the same hash %s", key) + } + genStateBtcHeaderByHash[key] = struct{}{} + } + + newBtcHeaders := make([]*btclighttypes.BTCHeaderInfo, 0, len(inputBtcHeaders.BtcHeaders)) + for _, btcHeader := range inputBtcHeaders.BtcHeaders { + if err := btcHeader.Validate(); err != nil { + return fmt.Errorf("failed to validate basic btc header: %w", err) + } + + key := btcHeader.Hash.MarshalHex() + if _, ok := genStateBtcHeaderByHash[key]; ok { + return fmt.Errorf("error: btc header: %+v\nwas already set on genesis, or contains the same hash %s than another btc header", btcHeader, key) + } + genStateBtcHeaderByHash[key] = struct{}{} + newBtcHeaders = append(newBtcHeaders, btcHeader) + } + btclightGenState.BtcHeaders = append(btclightGenState.BtcHeaders, newBtcHeaders...) + + if err := btclightGenState.Validate(); err != nil { + return err + } + + err = replaceModOnGenesis(clientCtx.Codec, genDoc, appState, btclighttypes.ModuleName, &btclightGenState) + if err != nil { + return err + } + + return genutil.ExportGenesisFile(genDoc, genFile) + }, + } + + return cmd +} + +func getBtcLightGenStateFromFile(cdc codec.Codec, inputFilePath string) (*btclighttypes.GenesisState, error) { + if !cmtos.FileExists(inputFilePath) { + return nil, fmt.Errorf("input file %s does not exists", inputFilePath) + } + + bz, err := os.ReadFile(inputFilePath) + if err != nil { + return nil, err + } + + var genState btclighttypes.GenesisState + err = cdc.UnmarshalJSON(bz, &genState) + if err != nil { + return nil, err + } + + return &genState, nil +} diff --git a/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go b/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go new file mode 100644 index 000000000..3659ec232 --- /dev/null +++ b/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go @@ -0,0 +1,93 @@ +package genhelpers_test + +import ( + "context" + "encoding/hex" + "fmt" + "math/rand" + "path/filepath" + "testing" + + "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" + btclighttypes "github.com/babylonchain/babylon/x/btclightclient/types" + + "github.com/cosmos/cosmos-sdk/client" + genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" + genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/stretchr/testify/require" +) + +func FuzzCmdSetBtcHeaders(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + h := helper.NewHelper(t) + app, home := h.App, t.TempDir() + cdc := app.AppCodec() + + err := genutiltest.ExecInitCmd(app.BasicModuleManager, home, cdc) + require.NoError(t, err) + + cmtcfg, err := genutiltest.CreateDefaultCometConfig(home) + require.NoError(t, err) + + appState, _, err := genutiltypes.GenesisStateFromGenFile(cmtcfg.GenesisFile()) + require.NoError(t, err) + btclightGenState := btclighttypes.GenesisStateFromAppState(cdc, appState) + + qntBtcHeaderInGenesis := len(btclightGenState.BtcHeaders) + require.GreaterOrEqual(t, qntBtcHeaderInGenesis, 1) + last := btclightGenState.BtcHeaders[qntBtcHeaderInGenesis-1] + + qntBtcHeaders := int(datagen.RandomInt(r, 10)) + 1 + btcHeadersToAdd := make([]*btclighttypes.BTCHeaderInfo, qntBtcHeaders) + for i := 0; i < qntBtcHeaders; i++ { + new := datagen.GenRandomBTCHeaderInfoWithParent(r, last) + btcHeadersToAdd[i] = new + last = new + } + + clientCtx := client.Context{}. + WithCodec(app.AppCodec()). + WithHomeDir(home). + WithTxConfig(app.TxConfig()) + ctx := context.WithValue(context.Background(), client.ClientContextKey, &clientCtx) + + btcHeadersToAddFilePath := filepath.Join(home, "btcHeadersToAdd.json") + writeFileProto(t, cdc, btcHeadersToAddFilePath, &btclighttypes.GenesisState{ + BtcHeaders: btcHeadersToAdd, + }) + + cmdSetBtcHeaders := genhelpers.CmdSetBtcHeaders() + cmdSetBtcHeaders.SetArgs([]string{btcHeadersToAddFilePath}) + cmdSetBtcHeaders.SetContext(ctx) + + // Runs the cmd to write into the genesis + err = cmdSetBtcHeaders.Execute() + require.NoError(t, err) + + // reloads appstate + appState, _, err = genutiltypes.GenesisStateFromGenFile(cmtcfg.GenesisFile()) + require.NoError(t, err) + btclightGenState = btclighttypes.GenesisStateFromAppState(cdc, appState) + require.Equal(t, qntBtcHeaders+qntBtcHeaderInGenesis, len(btclightGenState.BtcHeaders)) + + for i := 0; i < qntBtcHeaders; i++ { + bzAdd, err := btcHeadersToAdd[i].Marshal() + require.NoError(t, err) + + bzGen, err := btclightGenState.BtcHeaders[qntBtcHeaderInGenesis+i].Marshal() + require.NoError(t, err) + + require.Equal(t, hex.EncodeToString(bzAdd), hex.EncodeToString(bzGen)) + } + + // tries to add again, it should error out + err = cmdSetBtcHeaders.Execute() + btcHeader := btcHeadersToAdd[0] + require.EqualError(t, err, fmt.Errorf("error: btc header: %+v\nwas already set on genesis, or contains the same hash %s than another btc header", btcHeader, btcHeader.Hash.MarshalHex()).Error()) + }) +} diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers.go b/cmd/babylond/cmd/genhelpers/set_finality_providers.go index eb6346dec..502d2ad41 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers.go @@ -131,13 +131,13 @@ func getBtcStakingGenStateFromFile(cdc codec.Codec, inputFilePath string) (*btcs return nil, fmt.Errorf("input file %s does not exists", inputFilePath) } - fpsBz, err := os.ReadFile(inputFilePath) + bz, err := os.ReadFile(inputFilePath) if err != nil { return nil, err } var genState btcstktypes.GenesisState - err = cdc.UnmarshalJSON(fpsBz, &genState) + err = cdc.UnmarshalJSON(bz, &genState) if err != nil { return nil, err } diff --git a/x/btclightclient/types/genesis.go b/x/btclightclient/types/genesis.go index 203c4e11b..8cd976143 100644 --- a/x/btclightclient/types/genesis.go +++ b/x/btclightclient/types/genesis.go @@ -1,11 +1,14 @@ package types import ( + "encoding/json" "errors" "fmt" bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/chaincfg" + + "github.com/cosmos/cosmos-sdk/codec" ) func SimnetGenesisBlock() BTCHeaderInfo { @@ -71,3 +74,15 @@ func (gs GenesisState) Validate() error { return nil } + +// GenesisStateFromAppState returns x/btclightclient GenesisState given raw application +// genesis state. +func GenesisStateFromAppState(cdc codec.Codec, appState map[string]json.RawMessage) GenesisState { + var genesisState GenesisState + + if appState[ModuleName] != nil { + cdc.MustUnmarshalJSON(appState[ModuleName], &genesisState) + } + + return genesisState +} From ffeb9c5b930b3110962646d5586b921eac52a93d Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 16 Apr 2024 09:51:20 +0800 Subject: [PATCH 073/119] chore: constructor function for master secret/public randomness (#616) --- crypto/eots/randomness.go | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/crypto/eots/randomness.go b/crypto/eots/randomness.go index e785208b8..5fc105e31 100644 --- a/crypto/eots/randomness.go +++ b/crypto/eots/randomness.go @@ -31,17 +31,17 @@ func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { return &pk.Key, &j.X, nil } -func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRand, error) { - // get random seed +// NewMasterRandPairFromSeed deterministically generates a pair of +// master/secret randomness from a given seed. +// NOTE: BIP-32 allows to use seed with 16-64 bytes. We used 32 here +// as the seed is typically a 32-byte hash, e.g., finality provider +// uses a hash to derive randomness. +func NewMasterRandPairFromSeed(seed [32]byte) (*MasterSecretRand, *MasterPublicRand, error) { + // generate new master key pair var ( - seed [32]byte - err error + masterSK *hdkeychain.ExtendedKey + err error ) - if _, err := io.ReadFull(randSource, seed[:]); err != nil { - return nil, nil, err - } - // generate new master key pair - var masterSK *hdkeychain.ExtendedKey for { masterSK, err = hdkeychain.NewMaster(seed[:], &chaincfg.MainNetParams) // if all good, use this master SK @@ -67,6 +67,16 @@ func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRa return &MasterSecretRand{masterSK}, &MasterPublicRand{masterPK}, nil } +// NewMasterRandPair generates a pair of master secret/public randomness +func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRand, error) { + // get random seed + var seed [32]byte + if _, err := io.ReadFull(randSource, seed[:]); err != nil { + return nil, nil, err + } + return NewMasterRandPairFromSeed(seed) +} + func (msr *MasterSecretRand) Validate() error { if !msr.k.IsPrivate() { return fmt.Errorf("underlying key is not a private key") From 0bac280e68011eed69bea5504a6d9c5023f87bb4 Mon Sep 17 00:00:00 2001 From: Aaron Chen Date: Thu, 18 Apr 2024 16:42:39 +0800 Subject: [PATCH 074/119] Improve the doc of bitcoin staking script (#618) --- docs/staking-script.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/staking-script.md b/docs/staking-script.md index e49d63873..cc263f7c3 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -30,6 +30,18 @@ The protocol has the following important properties: 7. (WIP) restakable, meaning that the same bitcoin can be staked to secure multiple PoS chains and earn multiple PoS yields + +In the entire Bitcoin staking process, two parties are involved: one is called +the Bitcoin Staker, and the other is called the Finality Provider. + +- **Bitcoin Staker**: A Bitcoin Staker is a person who owns Bitcoin and chooses +to lock up their Bitcoin for a set period of time to secure a PoS chain. +- **Finality Provider**: A Finality Provider is the an entity that votes +in the finality round to provide security assurance to the PoS chain. + +The Bitcoin staker can choose a specific Finality Provider to delegate +their voting power derived from their locked Bitcoin. + The key to making all these possible is special constructions of BTC transactions using BTC scripts. @@ -90,7 +102,7 @@ There are three special transaction types recognized by the Babylon chain: ### Staking Transaction -A BTC holder gains voting power by creating a staking transaction. This is a +A BTC Staker gains voting power by creating a staking transaction. This is a Bitcoin transaction that commits a certain amount of to-be-staked bitcoin to Babylon recognized BTC staking scripts. These scripts lock the stake for a chosen amount of BTC blocks and enable other features such as unbonding and @@ -230,14 +242,14 @@ The main difference between the unbonding and slashing paths is the existence of This leads to following system wide repercussions: -- for staking request to become active, btc holder needs to provide valid +- for staking request to become active, btc staker needs to provide valid unbonding transaction in this staking request. This staking request will become active only when `CovenantThreshold` signatures will be received by Babylon chain. Lack of `FinalityProviderPk` in unbonding path, means that after delegation becomes active, staker can send unbodning transaction any time without asking finality provider for permission. - existence of `FinalityProviderPk` in slashing path, coupled with the fact that - btc holder needs to provide pre-signed slashing transaction which needs to be + btc staker needs to provide pre-signed slashing transaction which needs to be signed by covenant committee for delegation request to become active, leads to situation in which the only signature missing to send slashing transaction to btc is signature of finality provider. @@ -264,7 +276,7 @@ Bitcoin blocks. It commits to a script of the form: where: -- Staker_PK is btc holder public key +- Staker_PK is btc staker public key - Timelock_Blocks is unbonding time. It must be lower or equal 65535, but larger than `max(MinUnbondingTime, CheckpointFinalizationTimeout)`. `MinUnbondingTime` and `CheckpointFinalizationTimeout` are Babylon parameters. From 367b704f14abcbf6a0c6db26caa31924c7808c42 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Mon, 22 Apr 2024 10:28:47 +0200 Subject: [PATCH 075/119] Datagen BTC lc header info response helpers (#623) * Add new header info response helper * Add header info response datagen helpers * Add NewBTCHeaderChainFromParentInfoResponse helper * Methods order * Better version * Use MarshalHex --- testutil/datagen/btc_header_chain.go | 22 ++++++++++++++ testutil/datagen/btc_header_info.go | 36 +++++++++++++++++++++++ x/btclightclient/types/btc_header_info.go | 9 ++++++ 3 files changed, 67 insertions(+) diff --git a/testutil/datagen/btc_header_chain.go b/testutil/datagen/btc_header_chain.go index f2d37ed7f..339fef508 100644 --- a/testutil/datagen/btc_header_chain.go +++ b/testutil/datagen/btc_header_chain.go @@ -69,10 +69,32 @@ func NewBTCHeaderChainFromParent( } } +func NewBTCHeaderChainFromParentInfoResponse( + r *rand.Rand, + parent *types.BTCHeaderInfoResponse, + length uint32, +) *BTCHeaderPartialChain { + headerBytes, err := bbn.NewBTCHeaderBytesFromHex(parent.HeaderHex) + if err != nil { + panic(err) + } + return NewBTCHeaderChainFromParent( + r, + parent.Height+1, + parent.Work, + headerBytes.ToBlockHeader(), + length, + ) +} + func (c *BTCHeaderPartialChain) GetChainInfo() []*types.BTCHeaderInfo { return ChainToInfoChain(c.Headers, c.initialHeaderHeight, c.inititialHeaderTotalWork) } +func (c *BTCHeaderPartialChain) GetChainInfoResponse() []*types.BTCHeaderInfoResponse { + return ChainToInfoResponseChain(c.Headers, c.initialHeaderHeight, c.inititialHeaderTotalWork) +} + func (c *BTCHeaderPartialChain) ChainToBytes() []bbn.BTCHeaderBytes { chainBytes := make([]bbn.BTCHeaderBytes, 0) for _, header := range c.Headers { diff --git a/testutil/datagen/btc_header_info.go b/testutil/datagen/btc_header_info.go index fd81ff63b..d8a773acf 100644 --- a/testutil/datagen/btc_header_info.go +++ b/testutil/datagen/btc_header_info.go @@ -338,6 +338,42 @@ func ChainToInfoChain( return infoChain } +func ChainToInfoResponseChain( + chain []*wire.BlockHeader, + initialHeaderNumber uint64, + initialHeaderTotalWork sdkmath.Uint, +) []*btclightclienttypes.BTCHeaderInfoResponse { + if len(chain) == 0 { + return []*btclightclienttypes.BTCHeaderInfoResponse{} + } + + infoChain := make([]*btclightclienttypes.BTCHeaderInfoResponse, len(chain)) + + totalDifficulty := initialHeaderTotalWork + + for i, header := range chain { + headerWork := btclightclienttypes.CalcHeaderWork(header) + headerTotalDifficulty := btclightclienttypes.CumulativeWork(headerWork, totalDifficulty) + hash := header.BlockHash() + headerBytes := bbn.NewBTCHeaderBytesFromBlockHeader(header) + headerHash := bbn.NewBTCHeaderHashBytesFromChainhash(&hash) + headerNumber := initialHeaderNumber + uint64(i) + + headerInfoResponse := btclightclienttypes.NewBTCHeaderInfoResponse( + &headerBytes, + &headerHash, + headerNumber, + &headerTotalDifficulty, + ) + + infoChain[i] = headerInfoResponse + + totalDifficulty = headerTotalDifficulty + } + + return infoChain +} + func HeaderToHeaderBytes(headers []*wire.BlockHeader) []bbn.BTCHeaderBytes { headerBytes := make([]bbn.BTCHeaderBytes, len(headers)) for i, header := range headers { diff --git a/x/btclightclient/types/btc_header_info.go b/x/btclightclient/types/btc_header_info.go index fb3c5e6a3..17f6a1517 100644 --- a/x/btclightclient/types/btc_header_info.go +++ b/x/btclightclient/types/btc_header_info.go @@ -54,3 +54,12 @@ func (m *BTCHeaderInfo) Validate() error { return nil } + +func NewBTCHeaderInfoResponse(header *bbn.BTCHeaderBytes, headerHash *bbn.BTCHeaderHashBytes, height uint64, work *sdkmath.Uint) *BTCHeaderInfoResponse { + return &BTCHeaderInfoResponse{ + HeaderHex: header.MarshalHex(), + HashHex: headerHash.MarshalHex(), + Height: height, + Work: *work, + } +} From 8e84ff3dbcb10029181447ab90e4b78ccbf64c84 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 24 Apr 2024 19:28:41 +0800 Subject: [PATCH 076/119] chore: unifying usage of verification functions for btc staking txs (#625) --- btcstaking/staking.go | 37 ++++----------------- x/btcstaking/keeper/msg_server.go | 16 ++++----- x/btcstaking/types/btc_delegation_test.go | 3 +- x/btcstaking/types/btc_slashing_tx.go | 19 ++++------- x/btcstaking/types/btc_slashing_tx_test.go | 12 +++---- x/btcstaking/types/btc_undelegation_test.go | 6 ++-- 6 files changed, 27 insertions(+), 66 deletions(-) diff --git a/btcstaking/staking.go b/btcstaking/staking.go index c9e91b662..1fe4af286 100644 --- a/btcstaking/staking.go +++ b/btcstaking/staking.go @@ -575,28 +575,6 @@ func VerifyTransactionSigWithOutput( return fmt.Errorf("funding output must not be nil") } - return VerifyTransactionSigWithOutputData( - transaction, - fundingOutput.PkScript, - fundingOutput.Value, - script, - pubKey, - signature, - ) -} - -// VerifyTransactionSigWithOutputData verifies that: -// - provided transaction has exactly one input -// - provided signature is valid schnorr BIP340 signature -// - provided signature is signing whole provided transaction (SigHashDefault) -func VerifyTransactionSigWithOutputData( - transaction *wire.MsgTx, - fundingOutputPkScript []byte, - fundingOutputValue int64, - script []byte, - pubKey *btcec.PublicKey, - signature []byte) error { - if transaction == nil { return fmt.Errorf("tx to verify not be nil") } @@ -612,8 +590,8 @@ func VerifyTransactionSigWithOutputData( tapLeaf := txscript.NewBaseTapLeaf(script) inputFetcher := txscript.NewCannedPrevOutputFetcher( - fundingOutputPkScript, - fundingOutputValue, + fundingOutput.PkScript, + fundingOutput.Value, ) sigHashes := txscript.NewTxSigHashes(transaction, inputFetcher) @@ -641,14 +619,13 @@ func VerifyTransactionSigWithOutputData( return nil } -// EncVerifyTransactionSigWithOutputData verifies that: +// EncVerifyTransactionSigWithOutput verifies that: // - provided transaction has exactly one input // - provided signature is valid adaptor signature // - provided signature is signing whole provided transaction (SigHashDefault) -func EncVerifyTransactionSigWithOutputData( +func EncVerifyTransactionSigWithOutput( transaction *wire.MsgTx, - fundingOutputPkScript []byte, - fundingOutputValue int64, + fundingOut *wire.TxOut, script []byte, pubKey *btcec.PublicKey, encKey *asig.EncryptionKey, @@ -669,8 +646,8 @@ func EncVerifyTransactionSigWithOutputData( tapLeaf := txscript.NewBaseTapLeaf(script) inputFetcher := txscript.NewCannedPrevOutputFetcher( - fundingOutputPkScript, - fundingOutputValue, + fundingOut.PkScript, + fundingOut.Value, ) sigHashes := txscript.NewTxSigHashes(transaction, inputFetcher) diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 2d9d01d92..5b79883be 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -314,8 +314,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } err = req.SlashingTx.VerifySignature( - stakingInfo.StakingOutput.PkScript, - stakingInfo.StakingOutput.Value, + stakingInfo.StakingOutput, slashingSpendInfo.GetPkScriptPath(), stakerPk, req.DelegatorSlashingSig, @@ -414,8 +413,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre } err = req.UnbondingSlashingTx.VerifySignature( - unbondingInfo.UnbondingOutput.PkScript, - unbondingInfo.UnbondingOutput.Value, + unbondingInfo.UnbondingOutput, unbondingSlashingSpendInfo.GetPkScriptPath(), newBTCDel.BtcPk.MustToBTCPK(), req.DelegatorUnbondingSlashingSig, @@ -569,10 +567,9 @@ func (ms msgServer) AddCovenantSigs(goCtx context.Context, req *types.MsgAddCove // this fails, it is a programming error panic(err) } - if err := btcstaking.VerifyTransactionSigWithOutputData( + if err := btcstaking.VerifyTransactionSigWithOutput( unbondingMsgTx, - stakingInfo.StakingOutput.PkScript, - stakingInfo.StakingOutput.Value, + stakingInfo.StakingOutput, unbondingSpendInfo.GetPkScriptPath(), req.Pk.MustToBTCPK(), *req.UnbondingTxSig, @@ -660,10 +657,9 @@ func (ms msgServer) BTCUndelegate(goCtx context.Context, req *types.MsgBTCUndele // this fails, it is a programming error panic(err) } - if err := btcstaking.VerifyTransactionSigWithOutputData( + if err := btcstaking.VerifyTransactionSigWithOutput( unbondingMsgTx, - stakingInfo.StakingOutput.PkScript, - stakingInfo.StakingOutput.Value, + stakingInfo.StakingOutput, unbondingSpendInfo.GetPkScriptPath(), btcDel.BtcPk.MustToBTCPK(), *req.UnbondingTxSig, diff --git a/x/btcstaking/types/btc_delegation_test.go b/x/btcstaking/types/btc_delegation_test.go index deac36dd8..92ea56c40 100644 --- a/x/btcstaking/types/btc_delegation_test.go +++ b/x/btcstaking/types/btc_delegation_test.go @@ -139,8 +139,7 @@ func FuzzBTCDelegation_SlashingTx(f *testing.F) { continue } err := btcDel.SlashingTx.EncVerifyAdaptorSignature( - stakingInfo.StakingOutput.PkScript, - stakingInfo.StakingOutput.Value, + stakingInfo.StakingOutput, slashingSpendInfo.GetPkScriptPath(), orderedCovenantPKs[i].MustToBTCPK(), encKey, diff --git a/x/btcstaking/types/btc_slashing_tx.go b/x/btcstaking/types/btc_slashing_tx.go index 234a879f4..e6c249d63 100644 --- a/x/btcstaking/types/btc_slashing_tx.go +++ b/x/btcstaking/types/btc_slashing_tx.go @@ -114,8 +114,7 @@ func (tx *BTCSlashingTx) Sign( // VerifySignature verifies a signature on the slashing tx signed by staker, finality provider, or covenant func (tx *BTCSlashingTx) VerifySignature( - fundingPkScript []byte, - fundingAmount int64, + fundingOut *wire.TxOut, slashingPkScriptPath []byte, pk *btcec.PublicKey, sig *bbn.BIP340Signature, @@ -124,10 +123,9 @@ func (tx *BTCSlashingTx) VerifySignature( if err != nil { return err } - return btcstaking.VerifyTransactionSigWithOutputData( + return btcstaking.VerifyTransactionSigWithOutput( msgTx, - fundingPkScript, - fundingAmount, + fundingOut, slashingPkScriptPath, pk, *sig, @@ -165,8 +163,7 @@ func (tx *BTCSlashingTx) EncSign( // EncVerifyAdaptorSignature verifies an adaptor signature on the slashing tx // with the finality provider's public key as encryption key func (tx *BTCSlashingTx) EncVerifyAdaptorSignature( - stakingPkScript []byte, - stakingAmount int64, + fundingOut *wire.TxOut, slashingPkScriptPath []byte, pk *btcec.PublicKey, encKey *asig.EncryptionKey, @@ -176,10 +173,9 @@ func (tx *BTCSlashingTx) EncVerifyAdaptorSignature( if err != nil { return err } - return btcstaking.EncVerifyTransactionSigWithOutputData( + return btcstaking.EncVerifyTransactionSigWithOutput( msgTx, - stakingPkScript, - stakingAmount, + fundingOut, slashingPkScriptPath, pk, encKey, @@ -211,8 +207,7 @@ func (tx *BTCSlashingTx) ParseEncVerifyAdaptorSignatures( return nil, err } err = tx.EncVerifyAdaptorSignature( - fundingOut.PkScript, - fundingOut.Value, + fundingOut, slashingSpendInfo.GetPkScriptPath(), pk.MustToBTCPK(), encKey, diff --git a/x/btcstaking/types/btc_slashing_tx_test.go b/x/btcstaking/types/btc_slashing_tx_test.go index 1db74328f..bdf234df1 100644 --- a/x/btcstaking/types/btc_slashing_tx_test.go +++ b/x/btcstaking/types/btc_slashing_tx_test.go @@ -91,8 +91,7 @@ func FuzzSlashingTx_VerifySigAndASig(f *testing.F) { covASig, err := slashingTx.EncSign(stakingTx, 0, slashingPkScriptPath, covSK, encKey) require.NoError(t, err) err = slashingTx.EncVerifyAdaptorSignature( - testStakingInfo.StakingInfo.GetPkScript(), - testStakingInfo.StakingInfo.StakingOutput.Value, + testStakingInfo.StakingInfo.StakingOutput, slashingPkScriptPath, covPK, encKey, @@ -104,8 +103,7 @@ func FuzzSlashingTx_VerifySigAndASig(f *testing.F) { // can be verified covSig := covASig.Decrypt(decKey) err = slashingTx.VerifySignature( - testStakingInfo.StakingInfo.GetPkScript(), - testStakingInfo.StakingInfo.StakingOutput.Value, + testStakingInfo.StakingInfo.StakingOutput, slashingPkScriptPath, covPK, bbn.NewBIP340SignatureFromBTCSig(covSig), @@ -206,8 +204,7 @@ func FuzzSlashingTxWithWitness(f *testing.F) { orderedCovenantPKs := bbn.SortBIP340PKs(bsParams.CovenantPks) for i := range covSigsForFP { err := slashingTx.EncVerifyAdaptorSignature( - testStakingInfo.StakingInfo.StakingOutput.PkScript, - testStakingInfo.StakingInfo.StakingOutput.Value, + testStakingInfo.StakingInfo.StakingOutput, slashingPkScriptPath, orderedCovenantPKs[i].MustToBTCPK(), encKey, @@ -217,8 +214,7 @@ func FuzzSlashingTxWithWitness(f *testing.F) { covSchnorrSig := covSigsForFP[i].Decrypt(decKey) err = slashingTx.VerifySignature( - testStakingInfo.StakingInfo.StakingOutput.PkScript, - testStakingInfo.StakingInfo.StakingOutput.Value, + testStakingInfo.StakingInfo.StakingOutput, slashingPkScriptPath, orderedCovenantPKs[i].MustToBTCPK(), bbn.NewBIP340SignatureFromBTCSig(covSchnorrSig), diff --git a/x/btcstaking/types/btc_undelegation_test.go b/x/btcstaking/types/btc_undelegation_test.go index 88e16f081..2924810d8 100644 --- a/x/btcstaking/types/btc_undelegation_test.go +++ b/x/btcstaking/types/btc_undelegation_test.go @@ -87,8 +87,7 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { continue } err := btcDel.BtcUndelegation.SlashingTx.EncVerifyAdaptorSignature( - unbondingInfo.UnbondingOutput.PkScript, - unbondingInfo.UnbondingOutput.Value, + unbondingInfo.UnbondingOutput, slashingSpendInfo.GetPkScriptPath(), orderedCovenantPKs[i].MustToBTCPK(), encKey, @@ -98,8 +97,7 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { covSig := covSigsForFP[i].Decrypt(decKey) err = btcDel.BtcUndelegation.SlashingTx.VerifySignature( - unbondingInfo.UnbondingOutput.PkScript, - unbondingInfo.UnbondingOutput.Value, + unbondingInfo.UnbondingOutput, slashingSpendInfo.GetPkScriptPath(), orderedCovenantPKs[i].MustToBTCPK(), bbn.NewBIP340SignatureFromBTCSig(covSig), From 7778c798e236a61c1dfe7d465e4d0cbded6483bb Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 26 Apr 2024 12:10:01 +0200 Subject: [PATCH 077/119] Use NUMEQUAL op code in multisig scripts (#626) * Use NUMEQUAL op code in multisig scripts --- btcstaking/btcstaking_test.go | 38 ++++--------------- btcstaking/scripts_utils.go | 8 ++-- btcstaking/types.go | 6 +-- .../genhelpers/set_btc_delegations_test.go | 4 +- docs/staking-script.md | 14 +++---- testutil/datagen/btcstaking.go | 11 ++---- x/btcstaking/keeper/grpc_query_test.go | 9 +++-- x/btcstaking/keeper/msg_server_test.go | 3 +- x/btcstaking/types/btc_delegation_test.go | 6 ++- x/btcstaking/types/btc_slashing_tx_test.go | 7 +++- x/btcstaking/types/btc_undelegation_test.go | 4 +- 11 files changed, 51 insertions(+), 59 deletions(-) diff --git a/btcstaking/btcstaking_test.go b/btcstaking/btcstaking_test.go index 22f0df961..02bf5f612 100644 --- a/btcstaking/btcstaking_test.go +++ b/btcstaking/btcstaking_test.go @@ -278,6 +278,10 @@ func TestSpendingUnbondingPathCovenant35MultiSig(t *testing.T) { stakingInfo.StakingOutput, si.RevealedLeaf, ) + + covenantSigantures[1] = nil + covenantSigantures[3] = nil + witness, err := si.CreateUnbondingPathWitness(covenantSigantures, stakerSig) require.NoError(t, err) spendStakeTx.TxIn[0].Witness = witness @@ -294,37 +298,6 @@ func TestSpendingUnbondingPathCovenant35MultiSig(t *testing.T) { } btctest.AssertEngineExecution(t, 0, true, newEngine) - numOfCovenantMembers := len(scenario.CovenantKeys) - // with each loop iteration we remove one key from the list of signatures - for i := 0; i < numOfCovenantMembers; i++ { - numOfRemovedSignatures := i + 1 - - covenantSigantures := GenerateSignatures( - t, - scenario.CovenantKeys, - spendStakeTx, - stakingInfo.StakingOutput, - si.RevealedLeaf, - ) - - for j := 0; j <= i; j++ { - // NOTE: Number provides signatures must match number of public keys in the script, - // if we are missing some signatures those must be set to empty signature in witness - covenantSigantures[j] = nil - } - - witness, err := si.CreateUnbondingPathWitness(covenantSigantures, stakerSig) - require.NoError(t, err) - spendStakeTx.TxIn[0].Witness = witness - - if numOfCovenantMembers-numOfRemovedSignatures >= int(scenario.RequiredCovenantSigs) { - // if we are above threshold execution should be successful - btctest.AssertEngineExecution(t, 0, true, newEngine) - } else { - // we are below threshold execution should be unsuccessful - btctest.AssertEngineExecution(t, 0, false, newEngine) - } - } } func TestSpendingUnbondingPathSingleKeyCovenant(t *testing.T) { @@ -461,6 +434,9 @@ func TestSpendingSlashingPathCovenant35MultiSig(t *testing.T) { ) require.NoError(t, err) + covenantSigantures[0] = nil + covenantSigantures[3] = nil + witness, err := si.CreateSlashingPathWitness( covenantSigantures, []*schnorr.Signature{fpSig}, diff --git a/btcstaking/scripts_utils.go b/btcstaking/scripts_utils.go index e021248bd..a21669fbc 100644 --- a/btcstaking/scripts_utils.go +++ b/btcstaking/scripts_utils.go @@ -11,7 +11,8 @@ import ( ) // private helper to assemble multisig script -// SCRIPT: OP_CHEKCSIG OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD OP_GREATERTHANOREQUAL OP_VERIFY +// if `withVerify` is ture script will end with OP_NUMEQUALVERIFY otherwise with OP_NUMEQUAL +// SCRIPT: OP_CHEKCSIG OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD OP_NUMEQUALVERIFY (or OP_NUMEQUAL) func assembleMultiSigScript( pubkeys []*btcec.PublicKey, threshold uint32, @@ -29,9 +30,10 @@ func assembleMultiSigScript( } builder.AddInt64(int64(threshold)) - builder.AddOp(txscript.OP_GREATERTHANOREQUAL) if withVerify { - builder.AddOp(txscript.OP_VERIFY) + builder.AddOp(txscript.OP_NUMEQUALVERIFY) + } else { + builder.AddOp(txscript.OP_NUMEQUAL) } return builder.Script() diff --git a/btcstaking/types.go b/btcstaking/types.go index 416401238..331502a09 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -258,12 +258,12 @@ type babylonScriptPaths struct { timeLockPathScript []byte // unbondingPathScript is the script path for on-demand early unbonding // OP_CHECKSIGVERIFY - // OP_CHECKSIG ... OP_CHECKSIGADD M OP_GREATERTHANOREQUAL OP_VERIFY + // OP_CHECKSIG ... OP_CHECKSIGADD M OP_NUMEQUAL unbondingPathScript []byte // slashingPathScript is the script path for slashing // OP_CHECKSIGVERIFY - // OP_CHECKSIG ... OP_CHECKSIGADD M OP_GREATERTHANOREQUAL OP_VERIFY - // OP_CHECKSIG ... OP_CHECKSIGADD 1 OP_GREATERTHANOREQUAL OP_VERIFY + // OP_CHECKSIG ... OP_CHECKSIGADD 1 OP_NUMEQUALVERIFY + // OP_CHECKSIG ... OP_CHECKSIGADD M OP_NUMEQUAL slashingPathScript []byte } diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go index ab881ed09..8fd7ffae9 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go @@ -60,7 +60,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { err = cmdSetFp.Execute() require.NoError(t, err) - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) + covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) require.NoError(t, err) @@ -79,6 +79,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), startHeight, endHeight, 10000, @@ -146,6 +147,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { []bbn.BIP340PubKey{*notInGenFp.BtcPk}, delSK, covenantSKs, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), startHeight, endHeight, 10000, diff --git a/docs/staking-script.md b/docs/staking-script.md index cc263f7c3..a9a13b5a3 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -31,15 +31,15 @@ The protocol has the following important properties: multiple PoS chains and earn multiple PoS yields -In the entire Bitcoin staking process, two parties are involved: one is called +In the entire Bitcoin staking process, two parties are involved: one is called the Bitcoin Staker, and the other is called the Finality Provider. -- **Bitcoin Staker**: A Bitcoin Staker is a person who owns Bitcoin and chooses +- **Bitcoin Staker**: A Bitcoin Staker is a person who owns Bitcoin and chooses to lock up their Bitcoin for a set period of time to secure a PoS chain. -- **Finality Provider**: A Finality Provider is the an entity that votes +- **Finality Provider**: A Finality Provider is the an entity that votes in the finality round to provide security assurance to the PoS chain. -The Bitcoin staker can choose a specific Finality Provider to delegate +The Bitcoin staker can choose a specific Finality Provider to delegate their voting power derived from their locked Bitcoin. The key to making all these possible is special constructions of BTC @@ -188,7 +188,7 @@ before the timelock expires. It commits to a script of the form: ``` OP_CHECKSIGVERIFY OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD - OP_GREATERTHANOREQUAL + OP_NUMEQUAL ``` where: @@ -212,7 +212,7 @@ delegators in the case of double signing. It commits to a script: OP_CHECKSIGVERIFY OP_CHECKSIGVERIFY OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD - OP_GREATERTHANOREQUAL + OP_NUMEQUAL ``` where: @@ -290,7 +290,7 @@ delegators in the case of double signing. It commits to a script: OP_CHECKSIGVERIFY OP_CHECKSIGVERIFY OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD - OP_GREATERTHANOREQUAL + OP_NUMEQUAL ``` where: diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 50bc7864e..d804b96aa 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -106,6 +106,7 @@ func GenRandomBTCDelegation( fpBTCPKs []bbn.BIP340PubKey, delSK *btcec.PrivateKey, covenantSKs []*btcec.PrivateKey, + covenantPks []*btcec.PublicKey, covenantQuorum uint32, slashingAddress string, startHeight, endHeight, totalSat uint64, @@ -115,11 +116,7 @@ func GenRandomBTCDelegation( net := &chaincfg.SimNetParams delPK := delSK.PubKey() delBTCPK := bbn.NewBIP340PubKeyFromBTCPK(delPK) - // list of covenant PKs - covenantBTCPKs := []*btcec.PublicKey{} - for _, covenantSK := range covenantSKs { - covenantBTCPKs = append(covenantBTCPKs, covenantSK.PubKey()) - } + // list of finality provider PKs fpPKs, err := bbn.NewBTCPKsFromBIP340PKs(fpBTCPKs) if err != nil { @@ -147,7 +144,7 @@ func GenRandomBTCDelegation( net, delSK, fpPKs, - covenantBTCPKs, + covenantPks, covenantQuorum, uint16(endHeight-startHeight), int64(totalSat), @@ -211,7 +208,7 @@ func GenRandomBTCDelegation( net, delSK, fpPKs, - covenantBTCPKs, + covenantPks, covenantQuorum, wire.NewOutPoint(&stkTxHash, StakingOutIdx), w+1, diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index a5868cac9..7a3c7ff24 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -177,7 +177,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) + covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) require.NoError(t, err) slashingChangeLockTime := uint16(101) @@ -216,6 +216,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), startHeight, endHeight, 10000, @@ -379,7 +380,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) + covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) require.NoError(t, err) @@ -421,6 +422,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { []bbn.BIP340PubKey{*fpBTCPK}, delSK, covenantSKs, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), 1, 1000, 10000, @@ -497,7 +499,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper) // covenant and slashing addr - covenantSKs, _, covenantQuorum := datagen.GenCovenantCommittee(r) + covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) require.NoError(t, err) slashingChangeLockTime := uint16(101) @@ -529,6 +531,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), startHeight, endHeight, 10000, diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 0bc378c0d..419a74e82 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -864,7 +864,7 @@ func createNDelegationsForFinalityProvider( ) []*types.BTCDelegation { var delegations []*types.BTCDelegation for i := 0; i < numDelegations; i++ { - covenatnSks, _, err := datagen.GenRandomBTCKeyPairs(r, int(quorum)) + covenatnSks, covenantPks, err := datagen.GenRandomBTCKeyPairs(r, int(quorum)) require.NoError(t, err) delSK, _, err := datagen.GenRandomBTCKeyPair(r) @@ -882,6 +882,7 @@ func createNDelegationsForFinalityProvider( []bbn.BIP340PubKey{*bbn.NewBIP340PubKeyFromBTCPK(fpPK)}, delSK, covenatnSks, + covenantPks, quorum, slashingAddress.EncodeAddress(), 0, diff --git a/x/btcstaking/types/btc_delegation_test.go b/x/btcstaking/types/btc_delegation_test.go index 92ea56c40..7ced72b48 100644 --- a/x/btcstaking/types/btc_delegation_test.go +++ b/x/btcstaking/types/btc_delegation_test.go @@ -105,13 +105,17 @@ func FuzzBTCDelegation_SlashingTx(f *testing.F) { unbondingTime := uint16(100) + 1 slashingChangeLockTime := unbondingTime + // only the quorum of signers provided the signatures + covenantSigners := covenantSKs[:covenantQuorum] + // construct the BTC delegation with everything btcDel, err := datagen.GenRandomBTCDelegation( r, t, fpBTCPKs, delSK, - covenantSKs, + covenantSigners, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), 1000, diff --git a/x/btcstaking/types/btc_slashing_tx_test.go b/x/btcstaking/types/btc_slashing_tx_test.go index bdf234df1..adee66e84 100644 --- a/x/btcstaking/types/btc_slashing_tx_test.go +++ b/x/btcstaking/types/btc_slashing_tx_test.go @@ -187,9 +187,10 @@ func FuzzSlashingTxWithWitness(f *testing.F) { delSig, err := slashingTx.Sign(stakingMsgTx, 0, slashingPkScriptPath, delSK) require.NoError(t, err) + covenantSigners := covenantSKs[:covenantQuorum] // get covenant Schnorr signatures covenantSigs, err := datagen.GenCovenantAdaptorSigs( - covenantSKs, + covenantSigners, fpPKs, stakingMsgTx, slashingPkScriptPath, @@ -203,6 +204,10 @@ func FuzzSlashingTxWithWitness(f *testing.F) { // finality provider's PK are verified orderedCovenantPKs := bbn.SortBIP340PKs(bsParams.CovenantPks) for i := range covSigsForFP { + if covSigsForFP[i] == nil { + continue + } + err := slashingTx.EncVerifyAdaptorSignature( testStakingInfo.StakingInfo.StakingOutput, slashingPkScriptPath, diff --git a/x/btcstaking/types/btc_undelegation_test.go b/x/btcstaking/types/btc_undelegation_test.go index 2924810d8..5f77952d8 100644 --- a/x/btcstaking/types/btc_undelegation_test.go +++ b/x/btcstaking/types/btc_undelegation_test.go @@ -46,6 +46,7 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs), CovenantQuorum: covenantQuorum, } + covenantSigners := covenantSKs[:covenantQuorum] stakingTimeBlocks := uint16(5) stakingValue := int64(2 * 10e8) @@ -62,7 +63,8 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { t, fpBTCPKs, delSK, - covenantSKs, + covenantSigners, + covenantPKs, covenantQuorum, slashingAddress.EncodeAddress(), 1000, From 8811e794926aa4014e2a45d10206a758617a2a31 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 29 Apr 2024 17:52:51 +0800 Subject: [PATCH 078/119] chore: generalising datagen function for BTC delegation (#628) --- .../cmd/genhelpers/set_btc_delegations_test.go | 4 +++- testutil/datagen/btcstaking.go | 6 +++--- x/btcstaking/keeper/grpc_query_test.go | 10 ++++++---- x/btcstaking/keeper/keeper_test.go | 4 ++++ x/btcstaking/keeper/msg_server_test.go | 3 +-- x/btcstaking/types/btc_delegation_test.go | 1 + x/btcstaking/types/btc_undelegation_test.go | 1 + 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go index 8fd7ffae9..a12401389 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go @@ -61,7 +61,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { require.NoError(t, err) covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) + slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.RegressionNetParams) require.NoError(t, err) startHeight := datagen.RandomInt(r, 100) + 1 @@ -76,6 +76,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { del, err := datagen.GenRandomBTCDelegation( r, t, + &chaincfg.RegressionNetParams, []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, @@ -144,6 +145,7 @@ func FuzzCmdSetBtcDels(f *testing.F) { delWithBadFp, err := datagen.GenRandomBTCDelegation( r, t, + &chaincfg.RegressionNetParams, []bbn.BIP340PubKey{*notInGenFp.BtcPk}, delSK, covenantSKs, diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index d804b96aa..656d731c1 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -103,6 +103,7 @@ func GenRandomCustomFinalityProvider(r *rand.Rand, btcSK *btcec.PrivateKey, bbnS func GenRandomBTCDelegation( r *rand.Rand, t *testing.T, + btcNet *chaincfg.Params, fpBTCPKs []bbn.BIP340PubKey, delSK *btcec.PrivateKey, covenantSKs []*btcec.PrivateKey, @@ -113,7 +114,6 @@ func GenRandomBTCDelegation( slashingRate sdkmath.LegacyDec, slashingChangeLockTime uint16, ) (*bstypes.BTCDelegation, error) { - net := &chaincfg.SimNetParams delPK := delSK.PubKey() delBTCPK := bbn.NewBIP340PubKeyFromBTCPK(delPK) @@ -141,7 +141,7 @@ func GenRandomBTCDelegation( stakingSlashingInfo := GenBTCStakingSlashingInfo( r, t, - net, + btcNet, delSK, fpPKs, covenantPks, @@ -205,7 +205,7 @@ func GenRandomBTCDelegation( unbondingSlashingInfo := GenBTCUnbondingSlashingInfo( r, t, - net, + btcNet, delSK, fpPKs, covenantPks, diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index 7a3c7ff24..20095c1dc 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -7,7 +7,6 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/btcsuite/btcd/chaincfg" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "github.com/golang/mock/gomock" @@ -178,7 +177,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) + slashingAddress, err := datagen.GenRandomBTCAddress(r, net) require.NoError(t, err) slashingChangeLockTime := uint16(101) @@ -213,6 +212,7 @@ func FuzzPendingBTCDelegations(f *testing.F) { btcDel, err := datagen.GenRandomBTCDelegation( r, t, + net, []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, @@ -381,7 +381,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) + slashingAddress, err := datagen.GenRandomBTCAddress(r, net) require.NoError(t, err) slashingChangeLockTime := uint16(101) @@ -419,6 +419,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) { btcDel, err := datagen.GenRandomBTCDelegation( r, t, + net, []bbn.BIP340PubKey{*fpBTCPK}, delSK, covenantSKs, @@ -500,7 +501,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { // covenant and slashing addr covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r) - slashingAddress, err := datagen.GenRandomBTCAddress(r, &chaincfg.SimNetParams) + slashingAddress, err := datagen.GenRandomBTCAddress(r, net) require.NoError(t, err) slashingChangeLockTime := uint16(101) @@ -528,6 +529,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) { btcDel, err := datagen.GenRandomBTCDelegation( r, t, + net, []bbn.BIP340PubKey{*fp.BtcPk}, delSK, covenantSKs, diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 4a7b3833c..e53a1657e 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -24,6 +24,10 @@ import ( "github.com/stretchr/testify/require" ) +var ( + net = &chaincfg.SimNetParams +) + type Helper struct { t testing.TB diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 419a74e82..af61629f4 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -18,7 +18,6 @@ import ( "github.com/babylonchain/babylon/x/btcstaking/types" etypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" @@ -870,7 +869,6 @@ func createNDelegationsForFinalityProvider( delSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - net := &chaincfg.SimNetParams slashingAddress, err := datagen.GenRandomBTCAddress(r, net) require.NoError(t, err) @@ -879,6 +877,7 @@ func createNDelegationsForFinalityProvider( del, err := datagen.GenRandomBTCDelegation( r, t, + net, []bbn.BIP340PubKey{*bbn.NewBIP340PubKeyFromBTCPK(fpPK)}, delSK, covenatnSks, diff --git a/x/btcstaking/types/btc_delegation_test.go b/x/btcstaking/types/btc_delegation_test.go index 7ced72b48..c2b53094c 100644 --- a/x/btcstaking/types/btc_delegation_test.go +++ b/x/btcstaking/types/btc_delegation_test.go @@ -112,6 +112,7 @@ func FuzzBTCDelegation_SlashingTx(f *testing.F) { btcDel, err := datagen.GenRandomBTCDelegation( r, t, + &chaincfg.SimNetParams, fpBTCPKs, delSK, covenantSigners, diff --git a/x/btcstaking/types/btc_undelegation_test.go b/x/btcstaking/types/btc_undelegation_test.go index 5f77952d8..1306184d0 100644 --- a/x/btcstaking/types/btc_undelegation_test.go +++ b/x/btcstaking/types/btc_undelegation_test.go @@ -61,6 +61,7 @@ func FuzzBTCUndelegation_SlashingTx(f *testing.F) { btcDel, err := datagen.GenRandomBTCDelegation( r, t, + &chaincfg.SimNetParams, fpBTCPKs, delSK, covenantSigners, From 5333669bd23e0af3bc05f7cd67b228bfaf9af8b2 Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 1 May 2024 10:37:45 +0800 Subject: [PATCH 079/119] chore: fix typos (#630) --- app/app.go | 4 ++-- types/btc_config.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/app.go b/app/app.go index 61b162a08..f4e6ae538 100644 --- a/app/app.go +++ b/app/app.go @@ -293,7 +293,7 @@ func NewBabylonApp( wasmOpts []wasmkeeper.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *BabylonApp { - // we could also take it from global object which should be initilised in rootCmd + // we could also take it from global object which should be initialised in rootCmd // but this way it makes babylon app more testable btcConfig := bbn.ParseBtcOptionsFromConfig(appOpts) powLimit := btcConfig.PowLimit() @@ -747,7 +747,7 @@ func NewBabylonApp( wasmStack = wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCFeeKeeper) wasmStack = ibcfee.NewIBCMiddleware(wasmStack, app.IBCFeeKeeper) - // Create static IBC router, add ibc-tranfer module route, then set and seal it + // Create static IBC router, add ibc-transfer module route, then set and seal it ibcRouter := porttypes.NewRouter(). AddRoute(ibctransfertypes.ModuleName, transferStack). AddRoute(zctypes.ModuleName, zoneConciergeStack). diff --git a/types/btc_config.go b/types/btc_config.go index 078b2a120..21e3cdb17 100644 --- a/types/btc_config.go +++ b/types/btc_config.go @@ -32,7 +32,7 @@ func getParams(opts servertypes.AppOptions) *chaincfg.Params { network, err := cast.ToStringE(valueInterface) if err != nil { - panic("Bitcoin netowrk config should be valid string") + panic("Bitcoin network config should be valid string") } if network == string(BtcMainnet) { From f35c9b1509ef571ae4cfe8a95d9b0ef6b20d5586 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 8 May 2024 09:34:19 +0200 Subject: [PATCH 080/119] Comment out phase2 test (#637) --- test/e2e/e2e_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 5ebccfefe..c0d2f2500 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -21,9 +21,10 @@ func TestBTCTimestampingTestSuite(t *testing.T) { // TestBTCTimestampingPhase2HermesTestSuite tests BTC timestamping phase 2 protocol end-to-end, // with the Hermes relayer -func TestBTCTimestampingPhase2HermesTestSuite(t *testing.T) { - suite.Run(t, new(BTCTimestampingPhase2HermesTestSuite)) -} +// TODO: Uncomment once we have fix broadcasting of timestamps +// func TestBTCTimestampingPhase2HermesTestSuite(t *testing.T) { +// suite.Run(t, new(BTCTimestampingPhase2HermesTestSuite)) +// } // TestBTCTimestampingPhase2RlyTestSuite tests BTC timestamping phase 2 protocol end-to-end, // with the Go relayer From a8c9d27ab1d489eb55c23cbb2c75b87e1a85afdb Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 8 May 2024 18:29:09 +0200 Subject: [PATCH 081/119] Change wording when describing staker (#639) * Change wording when describing staker --- docs/staking-script.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/staking-script.md b/docs/staking-script.md index a9a13b5a3..41e8f5903 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -34,8 +34,11 @@ The protocol has the following important properties: In the entire Bitcoin staking process, two parties are involved: one is called the Bitcoin Staker, and the other is called the Finality Provider. -- **Bitcoin Staker**: A Bitcoin Staker is a person who owns Bitcoin and chooses -to lock up their Bitcoin for a set period of time to secure a PoS chain. +- **Bitcoin Staker**: A Bitcoin Staker is an entity identified by `` +in staking scripts. Note that a staking transaction can be funded from +arbitrary UTXO, including those owned by multsig/MPC/threshold accounts. +Thus, `` is not necessarily the address of the source of the fund. +Rather, it is the controller and beneficiary of the stake after its creation. - **Finality Provider**: A Finality Provider is the an entity that votes in the finality round to provide security assurance to the PoS chain. From 070f1b5e5d7a942234438eb7b6b527d6b36e1a24 Mon Sep 17 00:00:00 2001 From: Mauro Lacy Date: Sat, 11 May 2024 09:58:43 +0200 Subject: [PATCH 082/119] Disable optimized build / blst portable flag (#642) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 718e7da00..38dfecbd8 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ build-linux: GOOS=linux GOARCH=$(if $(findstring aarch64,$(shell uname -m)) || $(findstring arm64,$(shell uname -m)),arm64,amd64) LEDGER_ENABLED=false $(MAKE) build $(BUILD_TARGETS): go.sum $(BUILDDIR)/ - CGO_CFLAGS="-O -D__BLST_PORTABLE__" go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... + go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./... $(BUILDDIR)/: mkdir -p $(BUILDDIR)/ From 693950031e3f5b190868d4bab8ad1afcf65f4464 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Thu, 16 May 2024 09:35:37 +0200 Subject: [PATCH 083/119] Add implementation spec for locking network transactions (#645) * Add implementation spec for locking network transactions --- docs/staking-script.md | 2 +- docs/transaction-impl-spec.md | 373 ++++++++++++++++++++++++++++++++++ 2 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 docs/transaction-impl-spec.md diff --git a/docs/staking-script.md b/docs/staking-script.md index 41e8f5903..1cc147ebb 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -51,7 +51,7 @@ transactions using BTC scripts. ## Preliminary Babylon interaction with Bitcoin is heavily based on Bitcoin's -[Taproot upgrade](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawik). +[Taproot upgrade](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki). This design choice was made due to the heavy usage of [Schnorr signatures](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) that were introduced through the Taproot upgrade. diff --git a/docs/transaction-impl-spec.md b/docs/transaction-impl-spec.md new file mode 100644 index 000000000..17a3b2707 --- /dev/null +++ b/docs/transaction-impl-spec.md @@ -0,0 +1,373 @@ +# Observable Staking Transactions Specification + +## Introduction + +A lock-only network involves users locking their Bitcoin using the self-custodial +Bitcoin Staking script without a Babylon chain operating. +In this document, we precisely define how one can construct +the Bitcoin transactions specified by the Bitcoin Staking protocol. + +## Prerequisites + +- [Scripts doc](staking-script.md) - document which defines how different +Bitcoin Staking scripts look like +- [BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki)- +a document specifying how to spend taproot outputs + +## System parameters + +The lock-only staking system is governed by a set of parameters that specify +what constitutes a valid staking transaction. Based on those, +an observer of the Bitcoin ledger can precisely identify which transactions +are valid staking transactions and whether they should be considered active stake. +These parameters are different depending on the Bitcoin height a transaction is +included in and a constructor of a Bitcoin Staking transaction should take them into +account before propagating a transaction to Bitcoin. +For the rest of the document, we will refer to those parameters as `global_parameters`. + +More details about parameters can be found in the +[parameters spec](https://github.com/babylonchain/networks/tree/main/bbn-test-4/parameters). + +## Taproot outputs + +Taproot outputs are outputs whose locking script is an elliptic curve point `Q` +created as follows: +``` +Q = P + hash(P||m)G +``` +where: +- `P` is the internal public key +- `m` is the root of a Merkle tree whose leaves consist of a version number and a +script + +For Bitcoin Staking transactions, the internal public key is chosen as: + +``` +P = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0) +``` + +This key is described in the +[BIP341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#constructing-and-spending-taproot-outputs) +specification. + +The use of this key as an internal public key disables spending from taproot output +through the key spending path. +The construction of this key can be found [here](../btcstaking/types.go?plain=1#L27). + +## Observable Staking Transactions + +### Staking transaction + +A staker enters the system through the creation of a staking transaction +which locks Bitcoin in the Bitcoin Staking script. + +#### Requirements + +For the transaction to be considered a valid staking transaction, it must: +- have a taproot output which has the key spending path disabled +and commits to a script tree composed of three scripts:: +timelock script, unbonding script, slashing script. +This output is henceforth known as the `staking_output` and +the value in this output is known as `staking_amount` +- have `OP_RETURN` output which contains: `global_parameters.tag`, + `version`, `staker_pk`,`finality_provider_pk`, `staking_time` +- all the values must be valid for the `global_parameters` which are applicable at +the height in which the staking transaction is included in the BTC ledger. + + +#### OP_RETURN output description + +Data in the OP_RETURN output is described by the following struct: + +```go +type V0OpReturnData struct { + MagicBytes []byte + Version byte + StakerPublicKey []byte + FinalityProviderPublicKey []byte + StakingTime []byte +} +``` +The implementation of the struct can be found [here](../btcstaking/identifiable_staking.go?pain=1#L52) + +Fields description: +- `MagicBytes` - 4 bytes, tag which is used to identify the staking transaction +among other transactions in the Bitcoin ledger. +It is specified in the `global_parameters.Tag` field. +- `Version` - 1 byte, current version of the OP_RETURN output +- `StakerPublicKey` - 32 bytes, staker public key. The same key must be used in +the scripts used to create the taproot output in the staking transaction. +- `FinalityProviderPublicKey` - 32 bytes, finality provider public key. The same key +must be used in the scripts used to create the taproot output in the +staking transaction. +- `StakingTime` - 2 bytes big-endian unsigned number, staking time. +The same timelock time must be used in scripts used to create the taproot +output in the staking transaction. + + +This data is serialized as follows: +``` +SerializedStakingData = MagicBytes || Version || StakerPublicKey || FinalityProviderPublicKey || StakingTime +``` + +To transform this data into OP_RETURN data: + +``` +StakingDataPkScript = 0x6a || 0x47 || SerializedStakingData +``` + +where: +- 0x6a - is byte marker representing OP_RETURN op code +- 0x47 - is byte marker representing OP_DATA_71 op code, which pushed 71 bytes onto the stack + +The final OP_RETURN output will have the following shape: +``` +TxOut { + Value: 0, + PkScript: StakingDataPkScript +} +``` + +Logic creating output from data can be found [here](../btcstaking/identifiable_staking.go?pain=1#L175) + + +#### Staking output description + +Staking output should commit to three scripts: +- `timelock_script` +- `unbonding_script` +- `slashing_script` + +Data needed to create `staking_output`: +- `staker_public_key` - chosen by the user sending the staking transaction. It +will be used in every script. This key needs to be put in the OP_RETURN output +in the staking transaction. +- `finality_provider_public_key` - chosen by the user sending the staking +transaction. It will be used as `` in `slashing_script`. In the +lock-only network there is no slashing, so this key has mostly informative purposes. +This key needs to be put in the OP_RETURN output of the staking transaction. +- `staking_time` - chosen by the user sending the staking transaction. It will +be used as locking time in the `timelock_script`. It must be a valid `uint16` number, +in the range `global_parameters.min_staking_time <= staking_time <= global_parameters.max_staking_time`. +It needs to be put in the OP_RETURN output of the staking transaction. +- `covenant_committee_public_keys` - it can be retrieved from +`global_parameters.covenant_pks`. It is set of covenant committee public keys which +will be put in `unbonding_script` and `slashing_script`. +- `covenant_committee_quorum` - it can be retrieved from +`global_parameters.covenant_quorum`. It is quorum of covenant committee +member required to authorize spending using `unbonding_script` or `slashing_script` +- `staking_amout` - chosen by the user, it will be placed in `staking_output.value` +- `btc_network` - btc network on which staking transactions will take place + +#### Building OP_RETRUN and staking output implementation + +The Babylon staking library exposes the [BuildV0IdentifiableStakingOutputsAndTx](../btcstaking/identifiable_staking.go?plain=1#L231) +function with the following signature: + +```go +func BuildV0IdentifiableStakingOutputsAndTx( + magicBytes []byte, + stakerKey *btcec.PublicKey, + fpKey *btcec.PublicKey, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + stakingTime uint16, + stakingAmount btcutil.Amount, + net *chaincfg.Params, +) (*IdentifiableStakingInfo, *wire.MsgTx, error) +``` + +It enables the caller to create valid outputs to put inside an unfunded and not-signed +staking transaction. + +The suggested way of creating and sending a staking transaction using +[bitcoind](https://github.com/bitcoin/bitcoin) is: +1. create `staker_key` in the bitcoind wallet +2. create unfunded and not signed staking transaction using +the `BuildV0IdentifiableStakingOutputsAndTx` function +3. serialize the unfunded and not signed staking transaction to `staking_transaction_hex` +4. call `bitcoin-cli fundrawtransaction "staking_transaction_hex"` to +retrieve `funded_staking_transaction_hex`. +The bitcoind wallet will automatically choose unspent outputs to fund this transaction. +5. call `bitcoin-cli signrawtransactionwithwallet "funded_staking_transaction_hex"`. +This call will sign all inputs of the transaction and return `signed_staking_transaction_hex`. +6. call `bitcoin-cli sendrawtransaction "signed_staking_transaction_hex"` + +### Unbonding transaction + +The unbonding transaction allows the staker to on-demand unbond their +locked Bitcoin stake prior to its original timelock expiration. + +#### Requirements + +For the transaction to be considered a valid unbonding transaction, it must: +- have exactly one input and one output +- input must be valid a staking output +- output must be a taproot output. This taproot output must have disabled +the key spending path, and committed to script tree composed of two scripts: +the timelock script and the slashing script. This output is henceforth known +as the `unbonding_output` +- timelock in the time lock script must be equal to `global_parameters.unbonding_time` +- value in the unbonding output must be equal to `staking_output.value - global_parameters.unbonding_fee` + +#### Building Unbonding output + +The Babylon Bitcoin staking library exposes +the [BuildUnbondingInfo](../btcstaking/types.go?plain=1#416) +function which builds a valid unbonding output. +It has the following signature: + +```go +func BuildUnbondingInfo( + stakerKey *btcec.PublicKey, + fpKeys []*btcec.PublicKey, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + unbondingTime uint16, + unbondingAmount btcutil.Amount, + net *chaincfg.Params, +) (*UnbondingInfo, error) +``` + +where: +- `stakerKey`- must be the same key as the staker key in `staking_transaction` +- `fpKeys` - must contain one key, which is the same finality provider key used +in `staking_transaction` +- `covenantKeys`- are the same covenant keys as used in `staking_transaction` +- `covenantQuorum` - is the same quorum as used in `staking_transaction` +- `unbondingTime` - is equal to `global_parameters.unbonding_time` +- `unbondingAmount` - is equal to `staking_amount - global_parameters.unbonding_fee` + +## Spending taproot outputs + +To create transactions which spend from taproot outputs, either staking output +or unbonding output, providing signatures satisfying the script is not enough. + +The spender must also provide: +- the whole script which is being spent +- the control block which contains: leaf version, internal public key, and proof of +inclusion of the given script in the script tree + +Given that creating scripts is deterministic for given data, it is possible to +avoid storing scripts by re-building scripts when the need arises. + +### Re-creating script and control block + +To build the script and control block necessary to spend from a staking output through the +timelock script, the following function could be implemented + +```go +import ( + // Babylon btc staking library + "github.com/babylonchain/babylon/btcstaking" +) + +func buildTimelockScriptAndControlBlock( + stakerKey *btcec.PublicKey, + finalityProviderKey *btcec.PublicKey, + covenantKeys []*btcec.PublicKey, + covenantQuorum uint32, + stakingTime uint16, + stakingAmount btcutil.Amount, + netParams *chaincfg.Params, +) ([]byte, []byte, error) { + + stakingInfo, err := btcstaking.BuildStakingInfo( + stakerKey, + []*btcec.PublicKey{finalityProviderKey}, + covenantKeys, + covenantQuorum, + stakingTime, + stakingAmount, + netParams, + ) + + if err != nil { + return nil, nil, err + } + + si, err := stakingInfo.TimeLockPathSpendInfo() + + if err != nil { + return nil, nil, err + } + + scriptBytes := si.RevealedLeaf.Script + + controlBlock := si.ControlBlock + + controlBlockBytes, err := controlBlock.ToBytes() + if err != nil { + return nil, nil, err + } + + return scriptBytes, controlBlockBytes, nil +} + +``` + +The returned script and control block can be used to either build the witness directly +or to put them in a PSBT which can be used by bitcoind to create the witness. + +### Creating PSBT to get signature for given taproot path from Bitcoind + +To avoid creating signatures/witness manually, +Bitcoind's [walletprocesspsbt](https://developer.bitcoin.org/reference/rpc/walletprocesspsbt.html) +can be used. To use this Bitcoind endpoint to get signature/witness the wallet must +maintain one of the keys used in the script. + +Example of creating psbt to sign unbonding transaction using unbonding script from +staking output: + +```go +import ( + "github.com/btcsuite/btcd/btcutil/psbt" +) + +func BuildPsbtForSigningUnbondingTransaciton( + unbondingTx *wire.MsgTx, + stakingOutput *wire.TxOut, + stakerKey *btcec.PublicKey, + spentLeaf *txscript.TapLeaf, + controlBlockBytes []byte, +) (string, error) { + psbtPacket, err := psbt.New( + []*wire.OutPoint{&unbondingTx.TxIn[0].PreviousOutPoint}, + unbondingTx.TxOut, + unbondingTx.Version, + unbondingTx.LockTime, + []uint32{unbondingTx.TxIn[0].Sequence}, + ) + + if err != nil { + return "", fmt.Errorf("failed to create PSBT packet with unbonding transaction: %w", err) + } + + psbtPacket.Inputs[0].SighashType = txscript.SigHashDefault + psbtPacket.Inputs[0].WitnessUtxo = stakingOutput + psbtPacket.Inputs[0].Bip32Derivation = []*psbt.Bip32Derivation{ + { + PubKey: stakerKey.SerializeCompressed(), + }, + } + + psbtPacket.Inputs[0].TaprootLeafScript = []*psbt.TaprootTapLeafScript{ + { + ControlBlock: controlBlockBytes, + Script: spentLeaf.Script, + LeafVersion: spentLeaf.LeafVersion, + }, + } + + return psbtPacket.B64Encode() +} + +``` + +Given that to spend through the unbonding script requires more than the +staker's signature, the `walletprocesspsbt` endpoint will produce a new psbt +with the staker signature attached. + +In the case of a timelock path which requires only the staker's signature, +`walletprocesspsbt` would produce the whole witness required to send the +transaction to the BTC network. From e704ac75faabed09bcef0532b200edb41ecadfd3 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 21 May 2024 09:13:28 +1000 Subject: [PATCH 084/119] bump Cosmos SDK and wasmd (#646) --- app/app.go | 34 +-- app/app_test.go | 9 +- app/encoding.go | 20 +- app/genesis.go | 14 +- app/modules.go | 30 ++- app/test_helpers.go | 14 -- cmd/babylond/cmd/genhelpers/bls_add_test.go | 4 +- .../cmd/genhelpers/bls_create_test.go | 2 +- cmd/babylond/cmd/testnet_test.go | 2 +- cmd/babylond/cmd/validate_genesis_test.go | 2 +- go.mod | 103 ++++----- go.sum | 207 ++++++++++-------- test/e2e/initialization/node.go | 24 +- testutil/helper/gen_blocks.go | 133 +++++++---- testutil/helper/helper.go | 27 ++- testutil/keeper/btclightclient.go | 2 +- wasmbinding/test/custom_query_test.go | 2 +- wasmbinding/wasm.go | 2 +- x/btcstaking/keeper/msg_server_test.go | 46 ++-- x/checkpointing/proposal.go | 15 +- x/checkpointing/proposal_test.go | 62 ++++-- x/checkpointing/vote_ext_test.go | 20 +- 22 files changed, 456 insertions(+), 318 deletions(-) diff --git a/app/app.go b/app/app.go index f4e6ae538..1a04c324e 100644 --- a/app/app.go +++ b/app/app.go @@ -156,12 +156,6 @@ const ( // environmental variables - https://github.com/cosmos/cosmos-sdk/pull/10950 BabylonAppEnvPrefix = "" - // TODO review possible capabilities - // The last arguments can contain custom message handlers, and custom query handlers, - // if we want to allow any custom callbacks - // See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md - wasmCapabilities = "iterator,stargate,cosmwasm_1_1,cosmwasm_1_2,babylon" - // According to https://github.com/CosmWasm/wasmd#genesis-configuration chains // using smart contracts should configure proper gas limits per block. // https://medium.com/cosmwasm/cosmwasm-for-ctos-iv-native-integrations-713140bf75fc @@ -172,6 +166,12 @@ const ( ) var ( + // TODO review possible capabilities + // The last arguments can contain custom message handlers, and custom query handlers, + // if we want to allow any custom callbacks + // See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md + wasmCapabilities = []string{"iterator", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "babylon"} + // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string // fee collector account, module accounts and their permissions @@ -381,19 +381,27 @@ func NewBabylonApp( epochingKeeper, ) + // set proposal extension + prepareOpt := func(bApp *baseapp.BaseApp) { + proposalHandler := checkpointing.NewProposalHandler( + logger, &checkpointingKeeper, bApp.Mempool(), bApp) + proposalHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, prepareOpt) + + // set vote extension + voteExtOp := func(bApp *baseapp.BaseApp) { + voteExtHandler := checkpointing.NewVoteExtensionHandler(logger, &checkpointingKeeper) + voteExtHandler.SetHandlers(bApp) + } + baseAppOptions = append(baseAppOptions, voteExtOp) + bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) bApp.SetTxEncoder(txConfig.TxEncoder()) - // set handlers of vote extension - voteExtHandler := checkpointing.NewVoteExtensionHandler(logger, &checkpointingKeeper) - voteExtHandler.SetHandlers(bApp) - proposalHandler := checkpointing.NewProposalHandler( - logger, &checkpointingKeeper, bApp.Mempool(), bApp) - proposalHandler.SetHandlers(bApp) - tkeys := storetypes.NewTransientStoreKeys( paramstypes.TStoreKey, btccheckpointtypes.TStoreKey) // NOTE: The testingkey is just mounted for testing purposes. Actual applications should diff --git a/app/app_test.go b/app/app_test.go index 4e2ac57d0..47599538d 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -4,9 +4,8 @@ import ( "fmt" "testing" - abci "github.com/cometbft/cometbft/abci/types" - "cosmossdk.io/log" + abci "github.com/cometbft/cometbft/abci/types" dbm "github.com/cosmos/cosmos-db" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" @@ -23,7 +22,7 @@ func TestBabylonBlockedAddrs(t *testing.T) { DB: db, InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: EmptyAppOptions{}, + AppOpts: TmpAppOptions(), }) for acc := range BlockedAddresses() { @@ -58,7 +57,7 @@ func TestBabylonBlockedAddrs(t *testing.T) { map[int64]bool{}, 0, signer, - EmptyAppOptions{}, + TmpAppOptions(), EmptyWasmOpts, ) _, err = app2.ExportAppStateAndValidators(false, []string{}, []string{}) @@ -81,7 +80,7 @@ func TestUpgradeStateOnGenesis(t *testing.T) { DB: db, InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: EmptyAppOptions{}, + AppOpts: TmpAppOptions(), }) // make sure the upgrade keeper has version map in state diff --git a/app/encoding.go b/app/encoding.go index 8aa2a472f..0ae2e5a9f 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -1,13 +1,31 @@ package app import ( + "os" + "cosmossdk.io/log" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" dbm "github.com/cosmos/cosmos-db" + "github.com/cosmos/cosmos-sdk/client/flags" + simsutils "github.com/cosmos/cosmos-sdk/testutil/sims" appparams "github.com/babylonchain/babylon/app/params" + bbn "github.com/babylonchain/babylon/types" ) +// TmpAppOptions returns an app option with tmp dir and btc network +func TmpAppOptions() simsutils.AppOptionsMap { + dir, err := os.MkdirTemp("", "babylon-tmp-app") + if err != nil { + panic(err) + } + appOpts := simsutils.AppOptionsMap{ + flags.FlagHome: dir, + "btc-config.network": string(bbn.BtcSimnet), + } + return appOpts +} + func NewTmpBabylonApp() *BabylonApp { signer, _ := SetupTestPrivSigner() return NewBabylonApp( @@ -18,7 +36,7 @@ func NewTmpBabylonApp() *BabylonApp { map[int64]bool{}, 0, signer, - EmptyAppOptions{}, + TmpAppOptions(), []wasmkeeper.Option{}) } diff --git a/app/genesis.go b/app/genesis.go index ae974c8e6..107cc0126 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -1,10 +1,7 @@ package app import ( - "cosmossdk.io/log" "encoding/json" - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - dbm "github.com/cosmos/cosmos-db" "testing" ) @@ -22,15 +19,6 @@ func NewDefaultGenesisState(t *testing.T) GenesisState { t.Helper() // we "pre"-instantiate the application for getting the injected/configured encoding configuration // note, this is not necessary when using app wiring, as depinject can be directly used (see root_v2.go) - tempApp := NewBabylonApp( - log.NewNopLogger(), - dbm.NewMemDB(), - nil, - true, - map[int64]bool{}, - 0, - nil, - EmptyAppOptions{}, - []wasmkeeper.Option{}) + tempApp := NewTmpBabylonApp() return tempApp.DefaultGenesis() } diff --git a/app/modules.go b/app/modules.go index b6482870c..8c2039250 100644 --- a/app/modules.go +++ b/app/modules.go @@ -1,27 +1,45 @@ package app import ( + "github.com/CosmWasm/wasmd/x/wasm/ibctesting" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" "github.com/cosmos/cosmos-sdk/client" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" - ibctestingtypes "github.com/cosmos/ibc-go/v8/testing/types" ) +var _ ibctesting.ChainApp = &BabylonApp{} + // The following functions are required by ibctesting // (copied from https://github.com/osmosis-labs/osmosis/blob/main/app/modules.go) -func (app *BabylonApp) GetStakingKeeper() ibctestingtypes.StakingKeeper { - return app.StakingKeeper -} - func (app *BabylonApp) GetIBCKeeper() *ibckeeper.Keeper { - return app.IBCKeeper // This is a *ibckeeper.Keeper + return app.IBCKeeper } func (app *BabylonApp) GetScopedIBCKeeper() capabilitykeeper.ScopedKeeper { return app.ScopedIBCKeeper } +func (app *BabylonApp) GetBankKeeper() bankkeeper.Keeper { + return app.BankKeeper +} + +func (app *BabylonApp) GetStakingKeeper() *stakingkeeper.Keeper { + return app.StakingKeeper +} + +func (app *BabylonApp) GetAccountKeeper() authkeeper.AccountKeeper { + return app.AccountKeeper +} + +func (app *BabylonApp) GetWasmKeeper() wasmkeeper.Keeper { + return app.WasmKeeper +} + func (app *BabylonApp) GetTxConfig() client.TxConfig { return app.TxConfig() } diff --git a/app/test_helpers.go b/app/test_helpers.go index 5319b8129..b71c69169 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -358,20 +358,6 @@ func initAccountWithCoins(app *BabylonApp, ctx sdk.Context, addr sdk.AccAddress, } } -// EmptyAppOptions is a stub implementing AppOptions -type EmptyAppOptions struct{} - -// Get implements AppOptions -func (ao EmptyAppOptions) Get(o string) interface{} { - // some defaults required for app.toml config - - if o == "btc-config.network" { - return string(bbn.BtcSimnet) - } - - return nil -} - // SignAndDeliverWithoutCommit signs and delivers a transaction. No commit func SignAndDeliverWithoutCommit(t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, msgs []sdk.Msg, fees sdk.Coins, chainID string, accNums, accSeqs []uint64, blockTime time.Time, priv ...cryptotypes.PrivKey) (*abci.ResponseFinalizeBlock, error) { tx, err := simsutils.GenSignedMockTx( diff --git a/cmd/babylond/cmd/genhelpers/bls_add_test.go b/cmd/babylond/cmd/genhelpers/bls_add_test.go index 015900c48..ce5e42545 100644 --- a/cmd/babylond/cmd/genhelpers/bls_add_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_add_test.go @@ -82,7 +82,7 @@ func Test_CmdCreateAddWithoutGentx(t *testing.T) { DB: db, InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: app.EmptyAppOptions{}, + AppOpts: app.TmpAppOptions(), }) gentxModule := bbn.BasicModuleManager[genutiltypes.ModuleName].(genutil.AppModuleBasic) appCodec := bbn.AppCodec() @@ -124,7 +124,7 @@ func Test_CmdAddBlsWithGentx(t *testing.T) { DB: db, InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: app.EmptyAppOptions{}, + AppOpts: app.TmpAppOptions(), }) gentxModule := bbn.BasicModuleManager[genutiltypes.ModuleName].(genutil.AppModuleBasic) diff --git a/cmd/babylond/cmd/genhelpers/bls_create_test.go b/cmd/babylond/cmd/genhelpers/bls_create_test.go index b9d2826f9..259709372 100644 --- a/cmd/babylond/cmd/genhelpers/bls_create_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_create_test.go @@ -41,7 +41,7 @@ func Test_CmdCreateBls(t *testing.T) { DB: dbm.NewMemDB(), InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: app.EmptyAppOptions{}, + AppOpts: app.TmpAppOptions(), }) err = genutiltest.ExecInitCmd(bbn.BasicModuleManager, home, bbn.AppCodec()) require.NoError(t, err) diff --git a/cmd/babylond/cmd/testnet_test.go b/cmd/babylond/cmd/testnet_test.go index f529bdf7e..551f0326d 100644 --- a/cmd/babylond/cmd/testnet_test.go +++ b/cmd/babylond/cmd/testnet_test.go @@ -33,7 +33,7 @@ func Test_TestnetCmd(t *testing.T) { DB: dbm.NewMemDB(), InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: app.EmptyAppOptions{}, + AppOpts: app.TmpAppOptions(), }) err = genutiltest.ExecInitCmd(bbn.BasicModuleManager, home, bbn.AppCodec()) require.NoError(t, err) diff --git a/cmd/babylond/cmd/validate_genesis_test.go b/cmd/babylond/cmd/validate_genesis_test.go index 1d39caa13..017f50b7e 100644 --- a/cmd/babylond/cmd/validate_genesis_test.go +++ b/cmd/babylond/cmd/validate_genesis_test.go @@ -96,7 +96,7 @@ func generateTestGenesisState(t *testing.T, home string, n int) (*app.BabylonApp DB: dbm.NewMemDB(), InvCheckPeriod: 0, SkipUpgradeHeights: map[int64]bool{}, - AppOpts: app.EmptyAppOptions{}, + AppOpts: app.TmpAppOptions(), }) _ = genutiltest.ExecInitCmd(bbn.BasicModuleManager, home, bbn.AppCodec()) diff --git a/go.mod b/go.mod index 02d8f88c1..2f9e1e457 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,11 @@ go 1.21 module github.com/babylonchain/babylon require ( - github.com/CosmWasm/wasmd v0.50.0 + github.com/CosmWasm/wasmd v0.51.0 github.com/btcsuite/btcd v0.24.0 - github.com/cometbft/cometbft v0.38.5 + github.com/cometbft/cometbft v0.38.6 github.com/cometbft/cometbft-db v0.9.1 // indirect - // TODO: the current cosmos-sdk version is a non-released version, which is - // to fix the gasLimit problem - // should be replaced by a released version if there's any - github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 + github.com/cosmos/cosmos-sdk v0.50.6 github.com/cosmos/relayer/v2 v2.5.1 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -18,52 +15,52 @@ require ( github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/supranational/blst v0.3.11 - google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect - google.golang.org/grpc v1.60.1 - google.golang.org/protobuf v1.32.0 + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/grpc v1.63.2 + google.golang.org/protobuf v1.33.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - cosmossdk.io/api v0.7.3 + cosmossdk.io/api v0.7.4 cosmossdk.io/client/v2 v2.0.0-beta.1 cosmossdk.io/core v0.11.0 cosmossdk.io/depinject v1.0.0-alpha.4 cosmossdk.io/errors v1.0.1 cosmossdk.io/log v1.3.1 - cosmossdk.io/math v1.2.0 - cosmossdk.io/store v1.0.2 - cosmossdk.io/tools/confix v0.1.0 + cosmossdk.io/math v1.3.0 + cosmossdk.io/store v1.1.0 + cosmossdk.io/tools/confix v0.1.1 cosmossdk.io/x/circuit v0.1.0 cosmossdk.io/x/evidence v0.1.0 cosmossdk.io/x/feegrant v0.1.0 - cosmossdk.io/x/tx v0.13.0 - cosmossdk.io/x/upgrade v0.1.0 - github.com/CosmWasm/wasmvm v1.5.2 + cosmossdk.io/x/tx v0.13.3 + cosmossdk.io/x/upgrade v0.1.1 + github.com/CosmWasm/wasmvm/v2 v2.0.0 github.com/avast/retry-go/v4 v4.5.1 github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 - github.com/cosmos/cosmos-db v1.0.0 - github.com/cosmos/cosmos-proto v1.0.0-beta.4 - github.com/cosmos/gogoproto v1.4.11 + github.com/cosmos/cosmos-db v1.0.2 + github.com/cosmos/cosmos-proto v1.0.0-beta.5 + github.com/cosmos/gogoproto v1.4.12 github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.0.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/docker/docker v23.0.8+incompatible github.com/golang/mock v1.6.0 - github.com/golang/protobuf v1.5.3 - github.com/hashicorp/go-metrics v0.5.1 + github.com/golang/protobuf v1.5.4 + github.com/hashicorp/go-metrics v0.5.3 github.com/jinzhu/copier v0.3.5 github.com/jsternberg/zap-logfmt v1.3.0 github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b github.com/ory/dockertest/v3 v3.9.1 github.com/vulpine-io/io-test v1.0.0 go.uber.org/zap v1.26.0 - google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f + google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de ) require ( @@ -73,10 +70,10 @@ require ( github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 - github.com/cosmos/iavl v1.0.1 // indirect + github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect @@ -104,7 +101,7 @@ require ( github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.6 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -112,12 +109,12 @@ require ( github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mtibben/percent v0.2.1 // indirect - github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect + github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.18.0 - github.com/prometheus/client_model v0.6.0 // indirect - github.com/prometheus/common v0.47.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.52.2 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rs/cors v1.8.3 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -128,20 +125,20 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/zondax/hid v0.9.2 // indirect go.etcd.io/bbolt v1.3.8 // indirect - golang.org/x/crypto v0.19.0 - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/crypto v0.22.0 + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect nhooyr.io/websocket v1.8.6 // indirect ) require ( - cloud.google.com/go v0.110.10 // indirect - cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go v0.112.0 // indirect + cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.5 // indirect - cloud.google.com/go/storage v1.35.1 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.36.0 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/x/nft v0.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -182,6 +179,8 @@ require ( github.com/fatih/color v1.15.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.0 // indirect @@ -190,11 +189,11 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.2 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-plugin v1.5.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect @@ -208,7 +207,7 @@ require ( github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/linxGnu/grocksdb v1.8.12 // indirect + github.com/linxGnu/grocksdb v1.8.14 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -236,18 +235,22 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/zondax/ledger-go v0.14.3 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240213143201-ec583247a57a // indirect - golang.org/x/mod v0.15.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.6.0 // indirect + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.24.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect + golang.org/x/sync v0.7.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.18.0 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.153.0 // indirect + golang.org/x/tools v0.20.0 // indirect + google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect pgregory.net/rapid v1.1.0 // indirect diff --git a/go.sum b/go.sum index 7061588b8..4b44e4b3c 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -68,8 +68,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= @@ -109,8 +109,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -171,8 +171,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= -cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= -cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= +cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -198,12 +198,12 @@ cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= -cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= -cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= -cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= -cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= -cosmossdk.io/tools/confix v0.1.0 h1:2OOZTtQsDT5e7P3FM5xqM0bPfluAxZlAwxqaDmYBE+E= -cosmossdk.io/tools/confix v0.1.0/go.mod h1:TdXKVYs4gEayav5wM+JHT+kTU2J7fozFNqoVaN+8CdY= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= +cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= +cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= +cosmossdk.io/tools/confix v0.1.1 h1:aexyRv9+y15veH3Qw16lxQwo+ki7r2I+g0yNTEFEQM8= +cosmossdk.io/tools/confix v0.1.1/go.mod h1:nQVvP1tHsGXS83PonPVWJtSbddIqyjEw99L4M3rPJyQ= cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= @@ -212,10 +212,10 @@ cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= cosmossdk.io/x/nft v0.1.0 h1:VhcsFiEK33ODN27kxKLa0r/CeFd8laBfbDBwYqCyYCM= cosmossdk.io/x/nft v0.1.0/go.mod h1:ec4j4QAO4mJZ+45jeYRnW7awLHby1JZANqe1hNZ4S3g= -cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= -cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= -cosmossdk.io/x/upgrade v0.1.0 h1:z1ZZG4UL9ICTNbJDYZ6jOnF9GdEK9wyoEFi4BUScHXE= -cosmossdk.io/x/upgrade v0.1.0/go.mod h1:/6jjNGbiPCNtmA1N+rBtP601sr0g4ZXuj3yC6ClPCGY= +cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= +cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= @@ -225,10 +225,10 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CosmWasm/wasmd v0.50.0 h1:NVaGqCSTRfb9UTDHJwT6nQIWcb6VjlQl88iI+u1+qjE= -github.com/CosmWasm/wasmd v0.50.0/go.mod h1:UjmShW4l9YxaMytwJZ7IB7MWzHiynSZP3DdWrG0FRtk= -github.com/CosmWasm/wasmvm v1.5.2 h1:+pKB1Mz9GZVt1vadxB+EDdD1FOz3dMNjIKq/58/lrag= -github.com/CosmWasm/wasmvm v1.5.2/go.mod h1:Q0bSEtlktzh7W2hhEaifrFp1Erx11ckQZmjq8FLCyys= +github.com/CosmWasm/wasmd v0.51.0 h1:3A2o20RrdF7P1D3Xb+R7A/pHbbHWsYCDXrHLa7S0SC8= +github.com/CosmWasm/wasmd v0.51.0/go.mod h1:7TSaj5HoolghujuVWeExqmcUKgpcYWEySGLSODbnnwY= +github.com/CosmWasm/wasmvm/v2 v2.0.0 h1:IqNCI2G0mvs7K6ej17/I28805rVqnu+Y1cWDqIdwb08= +github.com/CosmWasm/wasmvm/v2 v2.0.0/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -330,8 +330,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= @@ -360,6 +360,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -376,8 +378,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= -github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= +github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk= +github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -396,21 +398,21 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= -github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= -github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= -github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= -github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987 h1:Pjvcy7wHUoYh253LvNv5Dyx+d3SNkRPsDZH+FytqZ3w= -github.com/cosmos/cosmos-sdk v0.50.4-0.20240126152601-c4a2fe2b8987/go.mod h1:0D9mrUy1eAUMQuvYzf2xvhEPk2ta9w7XH1zcYvyFiuM= +github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= +github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= +github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= -github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= +github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= +github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= +github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= @@ -498,6 +500,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= @@ -548,6 +552,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -618,8 +627,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -682,8 +691,8 @@ github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -732,15 +741,15 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.2 h1:uJDtyXwEfalmp1PqdxuhZqrNkUyClZAhVeZYTArbqkg= -github.com/hashicorp/go-getter v1.7.2/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-metrics v0.5.1 h1:rfPwUqFU6uZXNvGl4hzjY8LEBsqFVU4si1H9/Hqck/U= -github.com/hashicorp/go-metrics v0.5.1/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= +github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-plugin v1.5.2 h1:aWv8eimFqWlsEiMrYZdPYl+FdHaBJSN4AWwGWfT1G2Y= @@ -836,8 +845,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI= -github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -864,8 +873,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= -github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= +github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -990,8 +999,8 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= -github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= +github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -1012,32 +1021,32 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= -github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= -github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= -github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= +github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1117,8 +1126,9 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1131,8 +1141,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= @@ -1200,6 +1211,18 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1236,8 +1259,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1249,8 +1272,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE= -golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= +golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1278,8 +1301,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1344,8 +1367,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1371,8 +1394,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1388,8 +1411,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1496,16 +1519,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1589,8 +1612,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1649,8 +1672,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1768,12 +1791,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= +google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1815,8 +1838,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1834,8 +1857,8 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index 5c0bed9d5..93dbb5da5 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -8,16 +8,12 @@ import ( "path/filepath" "strings" - "cosmossdk.io/log" "cosmossdk.io/math" - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" cmtconfig "github.com/cometbft/cometbft/config" cmted25519 "github.com/cometbft/cometbft/crypto/ed25519" cmtos "github.com/cometbft/cometbft/libs/os" "github.com/cometbft/cometbft/p2p" cmttypes "github.com/cometbft/cometbft/types" - dbm "github.com/cosmos/cosmos-db" - "github.com/cosmos/cosmos-sdk/client/flags" sdkcrypto "github.com/cosmos/cosmos-sdk/crypto" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" @@ -25,7 +21,6 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/server" srvconfig "github.com/cosmos/cosmos-sdk/server/config" - simsutils "github.com/cosmos/cosmos-sdk/testutil/sims" sdk "github.com/cosmos/cosmos-sdk/types" sdktx "github.com/cosmos/cosmos-sdk/types/tx" sdksigning "github.com/cosmos/cosmos-sdk/types/tx/signing" @@ -298,28 +293,13 @@ func (n *internalNode) init() error { config.SetRoot(n.configDir()) config.Moniker = n.moniker - appOptions := make(simsutils.AppOptionsMap, 0) - appOptions[flags.FlagHome] = n.configDir() - appOptions["btc-config.network"] = string(bbn.BtcSimnet) - - privSigner := &babylonApp.PrivSigner{WrappedPV: &privval.WrappedFilePV{Key: n.consensusKey}} - // Create a temp app to get the default genesis state - tempApp := babylonApp.NewBabylonApp( - log.NewNopLogger(), - dbm.NewMemDB(), - nil, - true, - map[int64]bool{}, - 0, - privSigner, - appOptions, - []wasmkeeper.Option{}) - appGenesis, err := n.getAppGenesis() if err != nil { return err } + // Create a temp app to get the default genesis state + tempApp := babylonApp.NewTmpBabylonApp() appState, err := json.MarshalIndent(tempApp.DefaultGenesis(), "", " ") if err != nil { return fmt.Errorf("failed to JSON encode app genesis state: %w", err) diff --git a/testutil/helper/gen_blocks.go b/testutil/helper/gen_blocks.go index d19b79756..def52b924 100644 --- a/testutil/helper/gen_blocks.go +++ b/testutil/helper/gen_blocks.go @@ -1,19 +1,58 @@ package helper import ( + "bytes" "fmt" "math/rand" + "sort" + "cosmossdk.io/core/comet" "cosmossdk.io/core/header" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/merkle" cmttypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/babylonchain/babylon/testutil/datagen" ) +// adapted from https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/baseapp/abci_utils_test.go +func ExtendedCommitToLastCommit(ec abci.ExtendedCommitInfo) (abci.ExtendedCommitInfo, abci.CommitInfo, comet.BlockInfo) { + // sort the extended commit info + // below are copied from https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/baseapp/abci_utils_test.go + // Since v0.50.5 Cosmos SDK enforces certain order for vote extensions + sort.SliceStable(ec.Votes, func(i, j int) bool { + if ec.Votes[i].Validator.Power == ec.Votes[j].Validator.Power { + return bytes.Compare(ec.Votes[i].Validator.Address, ec.Votes[j].Validator.Address) == -1 + } + return ec.Votes[i].Validator.Power > ec.Votes[j].Validator.Power + }) + + // convert the extended commit info to last commit info + lastCommit := abci.CommitInfo{ + Round: ec.Round, + Votes: make([]abci.VoteInfo, len(ec.Votes)), + } + + for i, vote := range ec.Votes { + lastCommit.Votes[i] = abci.VoteInfo{ + Validator: abci.Validator{ + Address: vote.Validator.Address, + Power: vote.Validator.Power, + }, + } + } + + return ec, lastCommit, baseapp.NewBlockInfo( + nil, + nil, + nil, + lastCommit, + ) +} + func (h *Helper) genAndApplyEmptyBlock() error { prevHeight := h.App.LastBlockHeight() newHeight := prevHeight + 1 @@ -30,7 +69,7 @@ func (h *Helper) genAndApplyEmptyBlock() error { NextValidatorsHash: valhash, } - resp, err := h.App.FinalizeBlock(&abci.RequestFinalizeBlock{ + _, err = h.App.FinalizeBlock(&abci.RequestFinalizeBlock{ Height: newHeader.Height, NextValidatorsHash: newHeader.NextValidatorsHash, Hash: newHeader.Hash(), @@ -39,13 +78,6 @@ func (h *Helper) genAndApplyEmptyBlock() error { return err } - newHeader.AppHash = resp.AppHash - h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ - Height: newHeader.Height, - AppHash: resp.AppHash, - Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) - _, err = h.App.Commit() if err != nil { return err @@ -76,10 +108,12 @@ func (h *Helper) ApplyEmptyBlockWithVoteExtension(r *rand.Rand) (sdk.Context, er // 1. get previous vote extensions prevEpoch := epoch.EpochNumber blockHash := datagen.GenRandomBlockHash(r) - extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys) + extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys, 0) if err != nil { return emptyCtx, err } + extendedCommitInfo := abci.ExtendedCommitInfo{Votes: extendedVotes} + _, lastCommitInfo, cometInfo := ExtendedCommitToLastCommit(extendedCommitInfo) // 2. create new header valSet, err := h.App.StakingKeeper.GetLastValidators(h.Ctx) @@ -98,12 +132,12 @@ func (h *Helper) ApplyEmptyBlockWithVoteExtension(r *rand.Rand) (sdk.Context, er h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ Height: newHeader.Height, Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) + }).WithBlockHeader(*newHeader.ToProto()).WithCometInfo(cometInfo) // 3. prepare proposal with previous BLS sigs blockTxs := [][]byte{} ppRes, err := h.App.PrepareProposal(&abci.RequestPrepareProposal{ - LocalLastCommit: abci.ExtendedCommitInfo{Votes: extendedVotes}, + LocalLastCommit: extendedCommitInfo, Height: newHeight, }) if err != nil { @@ -113,13 +147,17 @@ func (h *Helper) ApplyEmptyBlockWithVoteExtension(r *rand.Rand) (sdk.Context, er if len(ppRes.Txs) > 0 { blockTxs = ppRes.Txs } - _, err = h.App.ProcessProposal(&abci.RequestProcessProposal{ - Txs: ppRes.Txs, - Height: newHeight, + processRes, err := h.App.ProcessProposal(&abci.RequestProcessProposal{ + ProposedLastCommit: lastCommitInfo, + Txs: ppRes.Txs, + Height: newHeight, }) if err != nil { return emptyCtx, err } + if processRes.Status == abci.ResponseProcessProposal_REJECT { + return emptyCtx, fmt.Errorf("rejected proposal") + } // 4. finalize block resp, err := h.App.FinalizeBlock(&abci.RequestFinalizeBlock{ @@ -136,8 +174,7 @@ func (h *Helper) ApplyEmptyBlockWithVoteExtension(r *rand.Rand) (sdk.Context, er h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ Height: newHeader.Height, AppHash: resp.AppHash, - Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) + }) _, err = h.App.Commit() if err != nil { @@ -161,10 +198,12 @@ func (h *Helper) ApplyEmptyBlockWithValSet(r *rand.Rand, valSetWithKeys *datagen // 1. get previous vote extensions prevEpoch := epoch.EpochNumber blockHash := datagen.GenRandomBlockHash(r) - extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys) + extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys, 0) if err != nil { return emptyCtx, err } + extendedCommitInfo := abci.ExtendedCommitInfo{Votes: extendedVotes} + _, lastCommitInfo, cometInfo := ExtendedCommitToLastCommit(extendedCommitInfo) // 2. create new header valSet, err := h.App.StakingKeeper.GetLastValidators(h.Ctx) @@ -183,7 +222,7 @@ func (h *Helper) ApplyEmptyBlockWithValSet(r *rand.Rand, valSetWithKeys *datagen h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ Height: newHeader.Height, Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) + }).WithBlockHeader(*newHeader.ToProto()).WithCometInfo(cometInfo) // 3. prepare proposal with previous BLS sigs blockTxs := [][]byte{} @@ -199,8 +238,9 @@ func (h *Helper) ApplyEmptyBlockWithValSet(r *rand.Rand, valSetWithKeys *datagen blockTxs = ppRes.Txs } processRes, err := h.App.ProcessProposal(&abci.RequestProcessProposal{ - Txs: ppRes.Txs, - Height: newHeight, + ProposedLastCommit: lastCommitInfo, + Txs: ppRes.Txs, + Height: newHeight, }) if err != nil { return emptyCtx, err @@ -235,7 +275,7 @@ func (h *Helper) ApplyEmptyBlockWithValSet(r *rand.Rand, valSetWithKeys *datagen return h.Ctx, nil } -func (h *Helper) ApplyEmptyBlockWithInvalidBLSSig(r *rand.Rand) (sdk.Context, error) { +func (h *Helper) ApplyEmptyBlockWithInvalidVoteExtensions(r *rand.Rand) (sdk.Context, error) { emptyCtx := sdk.Context{} if h.App.LastBlockHeight() == 0 { if err := h.genAndApplyEmptyBlock(); err != nil { @@ -254,6 +294,8 @@ func (h *Helper) ApplyEmptyBlockWithInvalidBLSSig(r *rand.Rand) (sdk.Context, er if err != nil { return emptyCtx, err } + extendedCommitInfo := abci.ExtendedCommitInfo{Votes: extendedVotes} + _, lastCommitInfo, cometInfo := ExtendedCommitToLastCommit(extendedCommitInfo) res, err := h.App.VerifyVoteExtension(&abci.RequestVerifyVoteExtension{ Hash: blockHash, @@ -281,12 +323,12 @@ func (h *Helper) ApplyEmptyBlockWithInvalidBLSSig(r *rand.Rand) (sdk.Context, er h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ Height: newHeader.Height, Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) + }).WithBlockHeader(*newHeader.ToProto()).WithCometInfo(cometInfo) // 3. prepare proposal with previous BLS sigs blockTxs := [][]byte{} ppRes, err := h.App.PrepareProposal(&abci.RequestPrepareProposal{ - LocalLastCommit: abci.ExtendedCommitInfo{Votes: extendedVotes}, + LocalLastCommit: extendedCommitInfo, Height: newHeight, }) if err != nil { @@ -297,8 +339,9 @@ func (h *Helper) ApplyEmptyBlockWithInvalidBLSSig(r *rand.Rand) (sdk.Context, er blockTxs = ppRes.Txs } processRes, err := h.App.ProcessProposal(&abci.RequestProcessProposal{ - Txs: ppRes.Txs, - Height: newHeight, + ProposedLastCommit: lastCommitInfo, + Txs: ppRes.Txs, + Height: newHeight, }) if err != nil { return emptyCtx, err @@ -333,7 +376,7 @@ func (h *Helper) ApplyEmptyBlockWithInvalidBLSSig(r *rand.Rand) (sdk.Context, er return h.Ctx, nil } -func (h *Helper) ApplyEmptyBlockWithSomeEmptyVoteExtensions(r *rand.Rand) (sdk.Context, error) { +func (h *Helper) ApplyEmptyBlockWithSomeInvalidVoteExtensions(r *rand.Rand) (sdk.Context, error) { emptyCtx := sdk.Context{} if h.App.LastBlockHeight() == 0 { if err := h.genAndApplyEmptyBlock(); err != nil { @@ -348,10 +391,25 @@ func (h *Helper) ApplyEmptyBlockWithSomeEmptyVoteExtensions(r *rand.Rand) (sdk.C // 1. get previous vote extensions prevEpoch := epoch.EpochNumber blockHash := datagen.GenRandomBlockHash(r) - extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys) + extendedVotes, err := h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys, 0) if err != nil { return emptyCtx, err } + extendedCommitInfo := abci.ExtendedCommitInfo{Votes: extendedVotes} + _, lastCommitInfo, cometInfo := ExtendedCommitToLastCommit(extendedCommitInfo) + + if epoch.IsVoteExtensionProposal(h.Ctx) { + // makes a super minority of vote extensions to be invalid, while signatures + // over them are still valid + // In this case the proposal has to be still valid + numInvalidVotes := len(extendedVotes)/3 - 1 + extendedVotes, err = h.getExtendedVotesFromValSet(prevEpoch, uint64(prevHeight), blockHash, valSetWithKeys, numInvalidVotes) + if err != nil { + return emptyCtx, err + } + extendedCommitInfo = abci.ExtendedCommitInfo{Votes: extendedVotes} + _, lastCommitInfo, cometInfo = ExtendedCommitToLastCommit(extendedCommitInfo) + } // 2. create new header valSet, err := h.App.StakingKeeper.GetLastValidators(h.Ctx) @@ -367,25 +425,17 @@ func (h *Helper) ApplyEmptyBlockWithSomeEmptyVoteExtensions(r *rand.Rand) (sdk.C Hash: datagen.GenRandomByteArray(r, 32), }, } + h.Ctx = h.Ctx.WithHeaderInfo(header.Info{ Height: newHeader.Height, Hash: newHeader.Hash(), - }).WithBlockHeader(*newHeader.ToProto()) + }).WithBlockHeader(*newHeader.ToProto()).WithCometInfo(cometInfo) // 3. prepare proposal with previous BLS sigs var blockTxs [][]byte - if epoch.IsVoteExtensionProposal(h.Ctx) { - // nullifies a subset of extended votes - numEmptyVoteExts := len(extendedVotes)/3 - 1 - for i := 0; i < numEmptyVoteExts; i++ { - extendedVotes[i] = abci.ExtendedVoteInfo{ - // generate random vote extension including empty one - VoteExtension: datagen.GenRandomByteArray(r, uint64(r.Intn(10))), - } - } - } + ppRes, err := h.App.PrepareProposal(&abci.RequestPrepareProposal{ - LocalLastCommit: abci.ExtendedCommitInfo{Votes: extendedVotes}, + LocalLastCommit: extendedCommitInfo, Height: newHeight, }) if err != nil { @@ -394,8 +444,9 @@ func (h *Helper) ApplyEmptyBlockWithSomeEmptyVoteExtensions(r *rand.Rand) (sdk.C blockTxs = ppRes.Txs processRes, err := h.App.ProcessProposal(&abci.RequestProcessProposal{ - Txs: blockTxs, - Height: newHeight, + ProposedLastCommit: lastCommitInfo, + Txs: blockTxs, + Height: newHeight, }) if err != nil { return emptyCtx, err diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index b4fba4972..494786f5f 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -2,6 +2,8 @@ package helper import ( "bytes" + "fmt" + "sort" "testing" "cosmossdk.io/core/header" @@ -137,7 +139,17 @@ func (h *Helper) Error(err error) { require.Error(h.t, err) } -func (h *Helper) getExtendedVotesFromValSet(epochNum, height uint64, blockHash checkpointingtypes.BlockHash, valSet *datagen.GenesisValidators) ([]abci.ExtendedVoteInfo, error) { +func (h *Helper) getExtendedVotesFromValSet( + epochNum uint64, + height uint64, + blockHash checkpointingtypes.BlockHash, + valSet *datagen.GenesisValidators, + numInvalidVotes int, +) ([]abci.ExtendedVoteInfo, error) { + if len(valSet.Keys) < numInvalidVotes { + return nil, fmt.Errorf("number of invalid votes is more than the validator set size") + } + valPrivKey := valSet.GetValPrivKeys() blsPrivKeys := valSet.GetBLSPrivKeys() genesisKeys := valSet.GetGenesisKeys() @@ -165,6 +177,10 @@ func (h *Helper) getExtendedVotesFromValSet(epochNum, height uint64, blockHash c Round: int64(0), ChainId: h.App.ChainID(), } + if i < numInvalidVotes { + cve.Extension = []byte("doesn't matter") + } + var cveBuffer bytes.Buffer err = protoio.NewDelimitedWriter(&cveBuffer).WriteMsg(&cve) if err != nil { @@ -196,6 +212,15 @@ func (h *Helper) getExtendedVotesFromValSet(epochNum, height uint64, blockHash c extendedVotes = append(extendedVotes, veInfo) } + // below are copied from https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/baseapp/abci_utils_test.go + // Since v0.50.5 Cosmos SDK enforces certain order for vote extensions + sort.SliceStable(extendedVotes, func(i, j int) bool { + if extendedVotes[i].Validator.Power == extendedVotes[j].Validator.Power { + return bytes.Compare(extendedVotes[i].Validator.Address, extendedVotes[j].Validator.Address) == -1 + } + return extendedVotes[i].Validator.Power > extendedVotes[j].Validator.Power + }) + return extendedVotes, nil } diff --git a/testutil/keeper/btclightclient.go b/testutil/keeper/btclightclient.go index e3ca1e3e6..484c275ee 100644 --- a/testutil/keeper/btclightclient.go +++ b/testutil/keeper/btclightclient.go @@ -51,7 +51,7 @@ func BTCLightClientKeeperWithCustomParams(t testing.TB, p btclightclientt.Params registry := codectypes.NewInterfaceRegistry() cdc := codec.NewProtoCodec(registry) - testCfg := bbn.ParseBtcOptionsFromConfig(bapp.EmptyAppOptions{}) + testCfg := bbn.ParseBtcOptionsFromConfig(bapp.TmpAppOptions()) stServ := runtime.NewKVStoreService(storeKey) k := btclightclientk.NewKeeper( diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index 8054fb94f..6237edaf6 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -10,7 +10,7 @@ import ( "cosmossdk.io/math" "github.com/CosmWasm/wasmd/x/wasm/keeper" - wasmvmtypes "github.com/CosmWasm/wasmvm/types" + wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" "github.com/cometbft/cometbft/crypto" "github.com/cometbft/cometbft/crypto/ed25519" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index aaf525bf9..3dbdbb7e6 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -6,7 +6,7 @@ import ( errorsmod "cosmossdk.io/errors" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - wasmvmtypes "github.com/CosmWasm/wasmvm/types" + wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/wasmbinding/bindings" lcKeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index af61629f4..e41ee0d59 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -9,14 +9,6 @@ import ( "time" sdkmath "cosmossdk.io/math" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" @@ -25,6 +17,15 @@ import ( "github.com/stretchr/testify/require" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + "github.com/babylonchain/babylon/testutil/datagen" + testhelper "github.com/babylonchain/babylon/testutil/helper" + bbn "github.com/babylonchain/babylon/types" + btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonchain/babylon/x/btcstaking/keeper" + "github.com/babylonchain/babylon/x/btcstaking/types" + etypes "github.com/babylonchain/babylon/x/epoching/types" ) func FuzzMsgCreateFinalityProvider(f *testing.F) { @@ -908,14 +909,29 @@ func FuzzDeterminismBtcstakingBeginBlocker(f *testing.F) { f.Fuzz(func(t *testing.T, seed int64) { r := rand.New(rand.NewSource(seed)) - valSet, privSigner, err := datagen.GenesisValidatorSetWithPrivSigner(1) + valSet, privSigner, err := datagen.GenesisValidatorSetWithPrivSigner(2) require.NoError(t, err) - var expectedProviderData map[string]*ExpectedProviderData = make(map[string]*ExpectedProviderData) + var expectedProviderData = make(map[string]*ExpectedProviderData) // Create two test apps from the same set of validators h := testhelper.NewHelperWithValSet(t, valSet, privSigner) h1 := testhelper.NewHelperWithValSet(t, valSet, privSigner) + // app hash should be same at the beginning + appHash1 := hex.EncodeToString(h.Ctx.BlockHeader().AppHash) + appHash2 := hex.EncodeToString(h1.Ctx.BlockHeader().AppHash) + require.Equal(t, appHash1, appHash2) + + // Execute block for both apps + h.Ctx, err = h.ApplyEmptyBlockWithVoteExtension(r) + require.NoError(t, err) + h1.Ctx, err = h1.ApplyEmptyBlockWithVoteExtension(r) + require.NoError(t, err) + // Given that there is no transactions and the data in db is the same + // app hash produced by both apps should be the same + appHash1 = hex.EncodeToString(h.Ctx.BlockHeader().AppHash) + appHash2 = hex.EncodeToString(h1.Ctx.BlockHeader().AppHash) + require.Equal(t, appHash1, appHash2) // Default params are the same in both apps covQuorum := h.App.BTCStakingKeeper.GetParams(h.Ctx).CovenantQuorum @@ -960,16 +976,14 @@ func FuzzDeterminismBtcstakingBeginBlocker(f *testing.F) { } // Execute block for both apps - ctx, err := h.ApplyEmptyBlockWithVoteExtension(r) + h.Ctx, err = h.ApplyEmptyBlockWithVoteExtension(r) require.NoError(t, err) - - ctx1, err := h1.ApplyEmptyBlockWithVoteExtension(r) + h1.Ctx, err = h1.ApplyEmptyBlockWithVoteExtension(r) require.NoError(t, err) - // Given that there is no transactions and the data in db is the same // app hash produced by both apps should be the same - appHash1 := hex.EncodeToString(ctx.BlockHeader().AppHash) - appHash2 := hex.EncodeToString(ctx1.BlockHeader().AppHash) + appHash1 = hex.EncodeToString(h.Ctx.BlockHeader().AppHash) + appHash2 = hex.EncodeToString(h1.Ctx.BlockHeader().AppHash) require.Equal(t, appHash1, appHash2) }) } diff --git a/x/checkpointing/proposal.go b/x/checkpointing/proposal.go index 6947098a1..c4c0bb437 100644 --- a/x/checkpointing/proposal.go +++ b/x/checkpointing/proposal.go @@ -1,6 +1,7 @@ package checkpointing import ( + "bytes" "encoding/hex" "fmt" "slices" @@ -113,7 +114,7 @@ func (h *ProposalHandler) buildCheckpointFromVoteExtensions(ctx sdk.Context, epo return nil, err } ckpt := ckpttypes.NewCheckpointWithMeta(ckpttypes.NewCheckpoint(epoch, prevBlockID), ckpttypes.Accumulating) - validBLSSigs := h.getValidBlsSigs(ctx, extendedVotes) + validBLSSigs := h.getValidBlsSigs(ctx, extendedVotes, prevBlockID) vals := h.ckptKeeper.GetValidatorSet(ctx, epoch) totalPower := h.ckptKeeper.GetTotalVotingPower(ctx, epoch) // TODO: maybe we don't need to verify BLS sigs anymore as they are already @@ -156,7 +157,7 @@ func (h *ProposalHandler) buildCheckpointFromVoteExtensions(ctx sdk.Context, epo return ckpt, nil } -func (h *ProposalHandler) getValidBlsSigs(ctx sdk.Context, extendedVotes []abci.ExtendedVoteInfo) []ckpttypes.BlsSig { +func (h *ProposalHandler) getValidBlsSigs(ctx sdk.Context, extendedVotes []abci.ExtendedVoteInfo, blockHash []byte) []ckpttypes.BlsSig { k := h.ckptKeeper validBLSSigs := make([]ckpttypes.BlsSig, 0, len(extendedVotes)) for _, voteInfo := range extendedVotes { @@ -170,6 +171,14 @@ func (h *ProposalHandler) getValidBlsSigs(ctx sdk.Context, extendedVotes []abci. h.logger.Error("failed to unmarshal vote extension", "err", err) continue } + + if !bytes.Equal(*ve.BlockHash, blockHash) { + h.logger.Error("the BLS sig is signed over unexpected block hash", + "expected", hex.EncodeToString(blockHash), + "got", ve.BlockHash.String()) + continue + } + sig := ve.ToBLSSig() if err := k.VerifyBLSSig(ctx, sig); err != nil { @@ -281,7 +290,7 @@ func (h *ProposalHandler) ProcessProposal() sdk.ProcessProposalHandler { err = baseapp.ValidateVoteExtensions(ctx, h.ckptKeeper, req.Height, ctx.ChainID(), *injectedCkpt.ExtendedCommitInfo) if err != nil { // the returned err will lead to panic as something very wrong happened during consensus - return resReject, err + return resReject, nil } // 4. rebuild the checkpoint from vote extensions and compare it with diff --git a/x/checkpointing/proposal_test.go b/x/checkpointing/proposal_test.go index 1eafcf229..b754547a7 100644 --- a/x/checkpointing/proposal_test.go +++ b/x/checkpointing/proposal_test.go @@ -5,19 +5,11 @@ import ( "fmt" "math/rand" "sort" - - "time" - "testing" + "time" "cosmossdk.io/core/header" "cosmossdk.io/log" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/mocks" - "github.com/babylonchain/babylon/x/checkpointing" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - et "github.com/babylonchain/babylon/x/epoching/types" cbftt "github.com/cometbft/cometbft/abci/types" cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" tendermintTypes "github.com/cometbft/cometbft/proto/tendermint/types" @@ -27,6 +19,14 @@ import ( "github.com/cosmos/gogoproto/proto" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/testutil/helper" + "github.com/babylonchain/babylon/testutil/mocks" + "github.com/babylonchain/babylon/x/checkpointing" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + et "github.com/babylonchain/babylon/x/epoching/types" ) type TestValidator struct { @@ -122,13 +122,27 @@ func genNTestValidators(t *testing.T, n int) []TestValidator { }) } + // below are copied from https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/baseapp/abci_utils_test.go + // Since v0.50.5 Cosmos SDK enforces certain order for vote extensions + sort.SliceStable(vals, func(i, j int) bool { + if vals[i].Power == vals[j].Power { + valAddress1, err := sdk.ValAddressFromBech32(vals[i].Keys.ValidatorAddress) + require.NoError(t, err) + valAddress2, err := sdk.ValAddressFromBech32(vals[j].Keys.ValidatorAddress) + require.NoError(t, err) + return bytes.Compare(valAddress1, valAddress2) == -1 + } + return vals[i].Power > vals[j].Power + }) + return vals } func setupSdkCtx(height int64) sdk.Context { return sdk.Context{}.WithHeaderInfo(header.Info{ - Height: height, - Time: time.Now(), + Height: height, + Time: time.Now(), + ChainID: "test", }).WithConsensusParams(tendermintTypes.ConsensusParams{ Abci: &tendermintTypes.ABCIParams{ VoteExtensionsEnableHeight: 1, @@ -186,15 +200,12 @@ func genVoteExt( return extSignBytes } -func requestPrepareProposal(height int64, votes []cbftt.ExtendedVoteInfo) *cbftt.RequestPrepareProposal { +func requestPrepareProposal(height int64, commitInfo cbftt.ExtendedCommitInfo) *cbftt.RequestPrepareProposal { return &cbftt.RequestPrepareProposal{ - MaxTxBytes: 10000, - Txs: [][]byte{}, - LocalLastCommit: cbftt.ExtendedCommitInfo{ - Round: 0, - Votes: votes, - }, - Height: height, + MaxTxBytes: 10000, + Txs: [][]byte{}, + LocalLastCommit: commitInfo, + Height: height, } } @@ -266,6 +277,7 @@ func generateNValidatorAndVoteExtensions(t *testing.T, n int, bh *checkpointingt extensions = append(extensions, ve) power += validator.Power } + return &ValidatorsAndExtensions{ Vals: validators, Extensions: extensions, @@ -364,7 +376,7 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { bh := randomBlockHash() // each validator has the same voting power numValidators := 9 - invalidValidBlsSig := numValidators/3 - 1 + invalidBlsSig := numValidators/3 - 1 validatorAndExtensions, totalPower := generateNValidatorAndVoteExtensions(t, numValidators, &bh, ec.Epoch.EpochNumber) @@ -373,7 +385,7 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { validator := val ek.EXPECT().GetPubKeyByConsAddr(gomock.Any(), sdk.ConsAddress(validator.ValidatorAddress(t).Bytes())).Return(validator.ProtoPubkey(), nil).AnyTimes() - if i < invalidValidBlsSig { + if i < invalidBlsSig { ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(checkpointingtypes.ErrInvalidBlsSignature).AnyTimes() } else { ek.EXPECT().VerifyBLSSig(gomock.Any(), validatorAndExtensions.Extensions[i].ToBLSSig()).Return(nil).AnyTimes() @@ -478,9 +490,13 @@ func TestPrepareProposalAtVoteExtensionHeight(t *testing.T) { mem, nil, ) - prepareProposalFn := h.PrepareProposal() - prop, err := prepareProposalFn(ec.Ctx, requestPrepareProposal(ec.Ctx.HeaderInfo().Height, scenario.Extensions)) + commitInfo, _, cometInfo := helper.ExtendedCommitToLastCommit(cbftt.ExtendedCommitInfo{Round: 0, Votes: scenario.Extensions}) + scenario.Extensions = commitInfo.Votes + ec.Ctx = ec.Ctx.WithCometInfo(cometInfo) + + req := requestPrepareProposal(ec.Ctx.HeaderInfo().Height, commitInfo) + prop, err := h.PrepareProposal()(ec.Ctx, req) if tt.expectError { require.Error(t, err) } else { diff --git a/x/checkpointing/vote_ext_test.go b/x/checkpointing/vote_ext_test.go index e370ece8b..3b91aaf6b 100644 --- a/x/checkpointing/vote_ext_test.go +++ b/x/checkpointing/vote_ext_test.go @@ -76,9 +76,9 @@ func FuzzAddBLSSigVoteExtension_InsufficientVotingPower(f *testing.F) { }) } -// FuzzAddBLSSigVoteExtension_InvalidBLSSig tests adding BLS signatures -// with invalid BLS signature -func FuzzAddBLSSigVoteExtension_InvalidBLSSig(f *testing.F) { +// FuzzAddBLSSigVoteExtension_InvalidVoteExtensions tests adding BLS signatures +// with invalid BLS signatures +func FuzzAddBLSSigVoteExtension_InvalidVoteExtensions(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { @@ -91,7 +91,7 @@ func FuzzAddBLSSigVoteExtension_InvalidBLSSig(f *testing.F) { interval := ek.GetParams(helper.Ctx).EpochInterval for i := uint64(0); i < interval-1; i++ { - _, err := helper.ApplyEmptyBlockWithInvalidBLSSig(r) + _, err := helper.ApplyEmptyBlockWithInvalidVoteExtensions(r) if i < interval-2 { require.NoError(t, err) } else { @@ -101,9 +101,9 @@ func FuzzAddBLSSigVoteExtension_InvalidBLSSig(f *testing.F) { }) } -// FuzzAddBLSSigVoteExtension_EmptyVoteExtensions tests resilience against -// empty vote extensions -func FuzzAddBLSSigVoteExtension_EmptyVoteExtensions(f *testing.F) { +// FuzzAddBLSSigVoteExtension_SomeInvalidVoteExtensions tests resilience +// of ProcessProposal against invalid vote extensions +func FuzzAddBLSSigVoteExtension_SomeInvalidVoteExtensions(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { @@ -121,11 +121,11 @@ func FuzzAddBLSSigVoteExtension_EmptyVoteExtensions(f *testing.F) { // go to block 10, ensure the checkpoint is finalized interval := ek.GetParams(helper.Ctx).EpochInterval for i := uint64(0); i < interval-2; i++ { - _, err := helper.ApplyEmptyBlockWithSomeEmptyVoteExtensions(r) + _, err := helper.ApplyEmptyBlockWithSomeInvalidVoteExtensions(r) require.NoError(t, err) } // height 11, i.e., 1st block of next epoch - _, err = helper.ApplyEmptyBlockWithSomeEmptyVoteExtensions(r) + _, err = helper.ApplyEmptyBlockWithSomeInvalidVoteExtensions(r) require.NoError(t, err) epoch = ek.GetEpoch(helper.Ctx) @@ -235,7 +235,7 @@ func FuzzExtendVote_NotInValidatorSet(f *testing.F) { // go to block 10, reaching epoch boundary interval := ek.GetParams(helper.Ctx).EpochInterval for i := uint64(0); i < interval-2; i++ { - _, err := helper.ApplyEmptyBlockWithSomeEmptyVoteExtensions(r) + _, err := helper.ApplyEmptyBlockWithSomeInvalidVoteExtensions(r) require.NoError(t, err) } From 2fd3502344143f7110b70a172030d04ee5c2d164 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 21 May 2024 19:20:24 +1000 Subject: [PATCH 085/119] epoching: removing apphash chain in epoching module (#650) --- client/docs/swagger-ui/swagger.yaml | 75 ------- proto/babylon/epoching/v1/epoching.proto | 7 +- proto/babylon/epoching/v1/query.proto | 7 +- x/checkpointing/types/expected_keepers.go | 1 - x/epoching/abci.go | 4 +- x/epoching/keeper/apphash_chain.go | 122 ----------- x/epoching/keeper/apphash_chain_test.go | 50 ----- x/epoching/keeper/epochs.go | 15 +- x/epoching/types/epoching.pb.go | 170 ++++++---------- x/epoching/types/keys.go | 3 +- x/epoching/types/query.go | 1 - x/epoching/types/query.pb.go | 238 +++++++++------------- 12 files changed, 159 insertions(+), 534 deletions(-) delete mode 100644 x/epoching/keeper/apphash_chain.go delete mode 100644 x/epoching/keeper/apphash_chain_test.go diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 1418e426a..3fa9bac6e 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -1646,14 +1646,6 @@ paths: epoch's beginning, and is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: >- - app_hash_root is the Merkle root of all AppHashs in this - epoch - - It will be used for proving a block is in an epoch as - hex string. sealer_app_hash_hex: type: string description: >- @@ -2006,14 +1998,6 @@ paths: beginning, and is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: >- - app_hash_root is the Merkle root of all AppHashs in this - epoch - - It will be used for proving a block is in an epoch as hex - string. sealer_app_hash_hex: type: string description: >- @@ -6498,14 +6482,6 @@ paths: beginning, and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: >- - app_hash_root is the Merkle root of all AppHashs in this - epoch - - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte @@ -7250,14 +7226,6 @@ paths: epoch's beginning, and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: >- - app_hash_root is the Merkle root of all AppHashs in - this epoch - - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte @@ -9899,11 +9867,6 @@ definitions: and is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: |- - app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch as hex string. sealer_app_hash_hex: type: string description: |- @@ -10041,11 +10004,6 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: |- - app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch as hex string. sealer_app_hash_hex: type: string description: |- @@ -10218,13 +10176,6 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root_hex: - type: string - description: >- - app_hash_root is the Merkle root of all AppHashs in this epoch - - It will be used for proving a block is in an epoch as hex - string. sealer_app_hash_hex: type: string description: >- @@ -11422,12 +11373,6 @@ definitions: and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: |- - app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte @@ -11833,12 +11778,6 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: |- - app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte @@ -13169,12 +13108,6 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: |- - app_hash_root is the Merkle root of all AppHashs in this epoch - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte @@ -13663,14 +13596,6 @@ definitions: beginning, and is set upon the end of this epoch. - app_hash_root: - type: string - format: byte - title: >- - app_hash_root is the Merkle root of all AppHashs in this - epoch - - It will be used for proving a block is in an epoch sealer_app_hash: type: string format: byte diff --git a/proto/babylon/epoching/v1/epoching.proto b/proto/babylon/epoching/v1/epoching.proto index 6ea0ddce6..79e579119 100644 --- a/proto/babylon/epoching/v1/epoching.proto +++ b/proto/babylon/epoching/v1/epoching.proto @@ -22,17 +22,14 @@ message Epoch { // finalised. The last_block_time field is nil in the epoch's beginning, and // is set upon the end of this epoch. google.protobuf.Timestamp last_block_time = 4 [ (gogoproto.stdtime) = true ]; - // app_hash_root is the Merkle root of all AppHashs in this epoch - // It will be used for proving a block is in an epoch - bytes app_hash_root = 5; // sealer is the last block of the sealed epoch // sealer_app_hash points to the sealer but stored in the 1st header // of the next epoch - bytes sealer_app_hash = 6; + bytes sealer_app_hash = 5; // sealer_block_hash is the hash of the sealer // the validator set has generated a BLS multisig on the hash, // i.e., hash of the last block in the epoch - bytes sealer_block_hash = 7; + bytes sealer_block_hash = 6; } // QueuedMessage is a message that can change the validator set and is delayed diff --git a/proto/babylon/epoching/v1/query.proto b/proto/babylon/epoching/v1/query.proto index 29f925778..e86999302 100644 --- a/proto/babylon/epoching/v1/query.proto +++ b/proto/babylon/epoching/v1/query.proto @@ -200,17 +200,14 @@ message EpochResponse { // finalised. The last_block_time field is nil in the epoch's beginning, and // is set upon the end of this epoch. google.protobuf.Timestamp last_block_time = 4 [ (gogoproto.stdtime) = true ]; - // app_hash_root is the Merkle root of all AppHashs in this epoch - // It will be used for proving a block is in an epoch as hex string. - string app_hash_root_hex = 5; // sealer is the last block of the sealed epoch // sealer_app_hash points to the sealer but stored in the 1st header // of the next epoch as hex string. - string sealer_app_hash_hex = 6; + string sealer_app_hash_hex = 5; // sealer_block_hash is the hash of the sealer // the validator set has generated a BLS multisig on the hash, // i.e., hash of the last block in the epoch as hex string. - string sealer_block_hash = 7; + string sealer_block_hash = 6; } // QueuedMessageResponse is a message that can change the validator set and is delayed diff --git a/x/checkpointing/types/expected_keepers.go b/x/checkpointing/types/expected_keepers.go index 329cdb67f..4a5b06005 100644 --- a/x/checkpointing/types/expected_keepers.go +++ b/x/checkpointing/types/expected_keepers.go @@ -14,7 +14,6 @@ import ( type EpochingKeeper interface { GetEpoch(ctx context.Context) *epochingtypes.Epoch EnqueueMsg(ctx context.Context, msg epochingtypes.QueuedMessage) - GetAppHash(ctx context.Context, height uint64) ([]byte, error) GetValidatorSet(ctx context.Context, epochNumer uint64) epochingtypes.ValidatorSet GetTotalVotingPower(ctx context.Context, epochNumber uint64) int64 CheckMsgCreateValidator(ctx context.Context, msg *stakingtypes.MsgCreateValidator) error diff --git a/x/epoching/abci.go b/x/epoching/abci.go index eecf14390..14fc82c2b 100644 --- a/x/epoching/abci.go +++ b/x/epoching/abci.go @@ -29,8 +29,6 @@ func BeginBlocker(ctx context.Context, k keeper.Keeper) error { defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker) sdkCtx := sdk.UnwrapSDKContext(ctx) - // record the current AppHash - k.RecordAppHash(ctx) // if this block is the first block of the next epoch // note that we haven't incremented the epoch number yet @@ -84,7 +82,7 @@ func EndBlocker(ctx context.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, e epoch := k.GetEpoch(ctx) if epoch.IsLastBlock(ctx) { // finalise this epoch, i.e., record the current header and the Merkle root of all AppHashs in this epoch - if err := k.RecordLastHeaderAndAppHashRoot(ctx); err != nil { + if err := k.RecordLastHeaderTime(ctx); err != nil { return nil, err } // get all msgs in the msg queue diff --git a/x/epoching/keeper/apphash_chain.go b/x/epoching/keeper/apphash_chain.go deleted file mode 100644 index 3a36b85f4..000000000 --- a/x/epoching/keeper/apphash_chain.go +++ /dev/null @@ -1,122 +0,0 @@ -package keeper - -import ( - "context" - "crypto/sha256" - "fmt" - - errorsmod "cosmossdk.io/errors" - "cosmossdk.io/store/prefix" - "github.com/cometbft/cometbft/crypto/merkle" - cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - "github.com/cosmos/cosmos-sdk/runtime" - sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/babylonchain/babylon/x/epoching/types" -) - -func (k Keeper) setAppHash(ctx context.Context, height uint64, appHash []byte) { - store := k.appHashStore(ctx) - heightBytes := sdk.Uint64ToBigEndian(height) - store.Set(heightBytes, appHash) -} - -// GetAppHash gets the AppHash of the header at the given height -func (k Keeper) GetAppHash(ctx context.Context, height uint64) ([]byte, error) { - store := k.appHashStore(ctx) - heightBytes := sdk.Uint64ToBigEndian(height) - appHash := store.Get(heightBytes) - if appHash == nil { - return nil, errorsmod.Wrapf(types.ErrInvalidHeight, "height %d is not known in DB yet", height) - } - return appHash, nil -} - -// RecordAppHash stores the AppHash of the current header to KVStore -func (k Keeper) RecordAppHash(ctx context.Context) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - height := uint64(sdkCtx.HeaderInfo().Height) - appHash := sdkCtx.HeaderInfo().AppHash - // HACK: the app hash for the first height is set to nil - // instead of the hash of an empty byte slice as intended - // see proposed fix: https://github.com/cosmos/cosmos-sdk/pull/18524 - if height == 1 { - // $ echo -n '' | sha256sum - // e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - emptyHash := sha256.Sum256([]byte{}) - appHash = emptyHash[:] - } - k.setAppHash(ctx, height, appHash) -} - -// GetAllAppHashesForEpoch fetches all AppHashes in the given epoch -func (k Keeper) GetAllAppHashesForEpoch(ctx context.Context, epoch *types.Epoch) ([][]byte, error) { - // if this epoch is the most recent AND has not ended, then we cannot get all AppHashs for this epoch - if k.GetEpoch(ctx).EpochNumber == epoch.EpochNumber && !epoch.IsLastBlock(sdk.UnwrapSDKContext(ctx)) { - return nil, errorsmod.Wrapf(types.ErrInvalidHeight, "GetAllAppHashesForEpoch can only be invoked when this epoch has ended") - } - - // fetch each AppHash in this epoch - appHashs := [][]byte{} - for i := epoch.FirstBlockHeight; i <= epoch.GetLastBlockHeight(); i++ { - appHash, err := k.GetAppHash(ctx, i) - if err != nil { - return nil, err - } - appHashs = append(appHashs, appHash) - } - - return appHashs, nil -} - -// ProveAppHashInEpoch generates a proof that the given appHash is in a given epoch -func (k Keeper) ProveAppHashInEpoch(ctx context.Context, height uint64, epochNumber uint64) (*cmtcrypto.Proof, error) { - // ensure height is inside this epoch - epoch, err := k.GetHistoricalEpoch(ctx, epochNumber) - if err != nil { - return nil, err - } - if !epoch.WithinBoundary(height) { - return nil, errorsmod.Wrapf(types.ErrInvalidHeight, "the given height %d is not in epoch %d (interval [%d, %d])", height, epoch.EpochNumber, epoch.FirstBlockHeight, epoch.GetLastBlockHeight()) - } - - // calculate index of this height in this epoch - idx := height - epoch.FirstBlockHeight - - // fetch all AppHashs, calculate Merkle tree and proof - appHashs, err := k.GetAllAppHashesForEpoch(ctx, epoch) - if err != nil { - return nil, err - } - _, proofs := merkle.ProofsFromByteSlices(appHashs) - - return proofs[idx].ToProto(), nil -} - -// VerifyAppHashInclusion verifies whether the given appHash is in the Merkle tree w.r.t. the appHashRoot -func VerifyAppHashInclusion(appHash []byte, appHashRoot []byte, proof *cmtcrypto.Proof) error { - if len(appHash) != sha256.Size { - return fmt.Errorf("appHash with length %d is not a Sha256 hash", len(appHash)) - } - if len(appHashRoot) != sha256.Size { - return fmt.Errorf("appHash with length %d is not a Sha256 hash", len(appHashRoot)) - } - if proof == nil { - return fmt.Errorf("proof is nil") - } - - unwrappedProof, err := merkle.ProofFromProto(proof) - if err != nil { - return fmt.Errorf("failed to unwrap proof: %w", err) - } - return unwrappedProof.Verify(appHashRoot, appHash) -} - -// appHashStore returns the KVStore for the AppHash of each header -// prefix: AppHashKey -// key: height -// value: AppHash in bytes -func (k Keeper) appHashStore(ctx context.Context) prefix.Store { - storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) - return prefix.NewStore(storeAdapter, types.AppHashKey) -} diff --git a/x/epoching/keeper/apphash_chain_test.go b/x/epoching/keeper/apphash_chain_test.go deleted file mode 100644 index 3b4148dd9..000000000 --- a/x/epoching/keeper/apphash_chain_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package keeper_test - -import ( - "math/rand" - "testing" - - "github.com/stretchr/testify/require" - - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/epoching/keeper" -) - -func FuzzAppHashChain(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - var err error - - helper := testhelper.NewHelper(t) - ctx, k := helper.Ctx, helper.App.EpochingKeeper - // ensure that the epoch info is correct at the genesis - epoch := k.GetEpoch(ctx) - require.Equal(t, epoch.EpochNumber, uint64(1)) - require.Equal(t, epoch.FirstBlockHeight, uint64(1)) - - // set a random epoch interval - epochInterval := k.GetParams(ctx).EpochInterval - - // reach the end of the 1st epoch - expectedHeight := epochInterval - 2 - for i := uint64(0); i < expectedHeight; i++ { - ctx, err = helper.ApplyEmptyBlockWithVoteExtension(r) - require.NoError(t, err) - } - // ensure epoch number is 1 - epoch = k.GetEpoch(ctx) - require.Equal(t, uint64(1), epoch.EpochNumber) - - // ensure prover and verifier are correct - randomHeightInEpoch := uint64(r.Intn(int(expectedHeight)) + 1) - randomAppHash, err := k.GetAppHash(ctx, randomHeightInEpoch) - require.NoError(t, err) - proof, err := k.ProveAppHashInEpoch(ctx, randomHeightInEpoch, epoch.EpochNumber) - require.NoError(t, err) - err = keeper.VerifyAppHashInclusion(randomAppHash, epoch.AppHashRoot, proof) - require.NoError(t, err) - }) -} diff --git a/x/epoching/keeper/epochs.go b/x/epoching/keeper/epochs.go index 6ded3bc3a..8ee863952 100644 --- a/x/epoching/keeper/epochs.go +++ b/x/epoching/keeper/epochs.go @@ -6,7 +6,6 @@ import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/store/prefix" - "github.com/cometbft/cometbft/crypto/merkle" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" @@ -61,9 +60,10 @@ func (k Keeper) GetHistoricalEpoch(ctx context.Context, epochNumber uint64) (*ty return epoch, err } -// RecordLastHeaderAndAppHashRoot records the last header and Merkle root of all AppHashs -// for the current epoch, and stores the epoch metadata to KVStore -func (k Keeper) RecordLastHeaderAndAppHashRoot(ctx context.Context) error { +// RecordLastHeaderTime records the last header's timestamp for the current +// epoch, and stores the epoch metadata to KVStore +// The timestamp is used for unbonding delegations once the epoch is timestamped +func (k Keeper) RecordLastHeaderTime(ctx context.Context) error { epoch := k.GetEpoch(ctx) if !epoch.IsLastBlock(ctx) { return errorsmod.Wrapf(types.ErrInvalidHeight, "RecordLastBlockHeader can only be invoked at the last block of an epoch") @@ -71,13 +71,6 @@ func (k Keeper) RecordLastHeaderAndAppHashRoot(ctx context.Context) error { // record last block header header := sdk.UnwrapSDKContext(ctx).HeaderInfo() epoch.LastBlockTime = &header.Time - // calculate and record the Merkle root - appHashes, err := k.GetAllAppHashesForEpoch(ctx, epoch) - if err != nil { - return err - } - appHashRoot := merkle.HashFromByteSlices(appHashes) - epoch.AppHashRoot = appHashRoot // save back to KVStore k.setEpochInfo(ctx, epoch.EpochNumber, epoch) return nil diff --git a/x/epoching/types/epoching.pb.go b/x/epoching/types/epoching.pb.go index e382650b7..4ce345009 100644 --- a/x/epoching/types/epoching.pb.go +++ b/x/epoching/types/epoching.pb.go @@ -83,17 +83,14 @@ type Epoch struct { // finalised. The last_block_time field is nil in the epoch's beginning, and // is set upon the end of this epoch. LastBlockTime *time.Time `protobuf:"bytes,4,opt,name=last_block_time,json=lastBlockTime,proto3,stdtime" json:"last_block_time,omitempty"` - // app_hash_root is the Merkle root of all AppHashs in this epoch - // It will be used for proving a block is in an epoch - AppHashRoot []byte `protobuf:"bytes,5,opt,name=app_hash_root,json=appHashRoot,proto3" json:"app_hash_root,omitempty"` // sealer is the last block of the sealed epoch // sealer_app_hash points to the sealer but stored in the 1st header // of the next epoch - SealerAppHash []byte `protobuf:"bytes,6,opt,name=sealer_app_hash,json=sealerAppHash,proto3" json:"sealer_app_hash,omitempty"` + SealerAppHash []byte `protobuf:"bytes,5,opt,name=sealer_app_hash,json=sealerAppHash,proto3" json:"sealer_app_hash,omitempty"` // sealer_block_hash is the hash of the sealer // the validator set has generated a BLS multisig on the hash, // i.e., hash of the last block in the epoch - SealerBlockHash []byte `protobuf:"bytes,7,opt,name=sealer_block_hash,json=sealerBlockHash,proto3" json:"sealer_block_hash,omitempty"` + SealerBlockHash []byte `protobuf:"bytes,6,opt,name=sealer_block_hash,json=sealerBlockHash,proto3" json:"sealer_block_hash,omitempty"` } func (m *Epoch) Reset() { *m = Epoch{} } @@ -157,13 +154,6 @@ func (m *Epoch) GetLastBlockTime() *time.Time { return nil } -func (m *Epoch) GetAppHashRoot() []byte { - if m != nil { - return m.AppHashRoot - } - return nil -} - func (m *Epoch) GetSealerAppHash() []byte { if m != nil { return m.SealerAppHash @@ -661,63 +651,62 @@ func init() { } var fileDescriptor_2f2f209d5311f84c = []byte{ - // 897 bytes of a gzipped FileDescriptorProto + // 881 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xdf, 0x6e, 0xe3, 0x44, 0x14, 0xc6, 0xe3, 0xfc, 0x6b, 0x73, 0x92, 0x74, 0xc3, 0xb4, 0x8b, 0xb2, 0x15, 0x4a, 0x4b, 0x10, - 0xa8, 0xaa, 0x90, 0x43, 0x4b, 0xb9, 0x05, 0x35, 0x4d, 0x44, 0x8a, 0x68, 0x56, 0x98, 0x6d, 0x2f, + 0xa8, 0xaa, 0x90, 0x4d, 0x4b, 0xb9, 0x05, 0x35, 0x4d, 0x84, 0x8b, 0x68, 0x56, 0x98, 0x6d, 0x2f, 0xb8, 0xc0, 0x1a, 0xdb, 0x53, 0xdb, 0x5a, 0x7b, 0xc6, 0xf2, 0x8c, 0xb3, 0xed, 0x05, 0xef, 0xb0, - 0xcf, 0xc1, 0x93, 0x70, 0xd9, 0x4b, 0xee, 0x40, 0xed, 0x83, 0x2c, 0x9a, 0x19, 0xc7, 0x49, 0x69, - 0xd4, 0xaa, 0x70, 0x37, 0x73, 0xce, 0x77, 0xbe, 0x99, 0xf3, 0xf3, 0xd1, 0x18, 0xfa, 0x0e, 0x76, - 0xae, 0x23, 0x46, 0x07, 0x24, 0x61, 0x6e, 0x10, 0x52, 0x7f, 0x30, 0x3b, 0x28, 0xd6, 0x66, 0x92, - 0x32, 0xc1, 0xd0, 0x66, 0xae, 0x31, 0x8b, 0xf8, 0xec, 0x60, 0x7b, 0xc7, 0x67, 0xcc, 0x8f, 0xc8, - 0x40, 0x49, 0x9c, 0xec, 0x72, 0x20, 0xc2, 0x98, 0x70, 0x81, 0xe3, 0x44, 0x57, 0x6d, 0x6f, 0xf9, - 0xcc, 0x67, 0x6a, 0x39, 0x90, 0xab, 0x3c, 0xba, 0xe3, 0x32, 0x1e, 0x33, 0x3e, 0xe0, 0x02, 0xbf, - 0xd5, 0xa7, 0x39, 0x44, 0xe0, 0x83, 0x81, 0xb8, 0xca, 0x05, 0xbd, 0x5c, 0xe0, 0x60, 0x4e, 0x8a, - 0xac, 0xcb, 0x42, 0xaa, 0xf3, 0xfd, 0x9b, 0x32, 0xd4, 0xc6, 0xf2, 0x1e, 0xe8, 0x53, 0x68, 0xa9, - 0x0b, 0xd9, 0x34, 0x8b, 0x1d, 0x92, 0x76, 0x8d, 0x5d, 0x63, 0xaf, 0x6a, 0x35, 0x55, 0x6c, 0xaa, - 0x42, 0xe8, 0x08, 0x3e, 0x76, 0xb3, 0x34, 0x25, 0x54, 0xd8, 0x5a, 0x1a, 0x52, 0x41, 0xd2, 0x19, - 0x8e, 0xba, 0x65, 0x25, 0xde, 0xca, 0xb3, 0xca, 0xf0, 0x34, 0xcf, 0xa1, 0x2f, 0x01, 0x5d, 0x86, - 0x29, 0x17, 0xb6, 0x13, 0x31, 0xf7, 0xad, 0x1d, 0x90, 0xd0, 0x0f, 0x44, 0xb7, 0xa2, 0x2a, 0x3a, - 0x2a, 0x33, 0x94, 0x89, 0x89, 0x8a, 0xa3, 0x09, 0xbc, 0x88, 0x70, 0x21, 0x96, 0x14, 0xba, 0xd5, - 0x5d, 0x63, 0xaf, 0x79, 0xb8, 0x6d, 0x6a, 0x44, 0xe6, 0x1c, 0x91, 0xf9, 0x66, 0x8e, 0x68, 0x58, - 0x7d, 0xff, 0xd7, 0x8e, 0x61, 0xb5, 0x65, 0xa1, 0xf2, 0x92, 0x19, 0xd4, 0x87, 0x36, 0x4e, 0x12, - 0x3b, 0xc0, 0x3c, 0xb0, 0x53, 0xc6, 0x44, 0xb7, 0xb6, 0x6b, 0xec, 0xb5, 0xac, 0x26, 0x4e, 0x92, - 0x09, 0xe6, 0x81, 0xc5, 0x98, 0x40, 0x5f, 0xc0, 0x0b, 0x4e, 0x70, 0x44, 0x52, 0x7b, 0x2e, 0xed, - 0xd6, 0x95, 0xaa, 0xad, 0xc3, 0xc7, 0x5a, 0x8b, 0xf6, 0xe1, 0xa3, 0x5c, 0x97, 0x37, 0x21, 0x95, - 0x6b, 0x4a, 0x99, 0x1b, 0xe8, 0x1e, 0x30, 0x0f, 0xfa, 0x1f, 0xaa, 0xd0, 0xfe, 0x29, 0x23, 0x19, - 0xf1, 0xce, 0x08, 0xe7, 0xd8, 0x27, 0x68, 0x13, 0x6a, 0xe2, 0xca, 0x0e, 0x3d, 0xc5, 0xb4, 0x65, - 0x55, 0xc5, 0xd5, 0xa9, 0x87, 0x5e, 0x42, 0x3d, 0xe6, 0xbe, 0x8c, 0x96, 0x55, 0xb4, 0x16, 0x73, - 0xff, 0xd4, 0x93, 0x9f, 0x61, 0x05, 0xa7, 0xa6, 0xb3, 0x84, 0xe8, 0x3b, 0x80, 0xff, 0x40, 0xa7, - 0xe1, 0x14, 0x64, 0x7e, 0x85, 0x2d, 0x79, 0xb4, 0x9b, 0x12, 0x2c, 0x88, 0x3d, 0xc3, 0x51, 0xe8, - 0x61, 0xc1, 0x52, 0x05, 0xa8, 0x79, 0xb8, 0x6f, 0xea, 0x99, 0x31, 0xf3, 0xa1, 0x32, 0xf3, 0xb1, - 0x31, 0xcf, 0xb8, 0x7f, 0xa2, 0x4a, 0x2e, 0xe6, 0x15, 0x93, 0x92, 0x85, 0xe2, 0x07, 0x51, 0x34, - 0x81, 0x96, 0xf4, 0xf7, 0x48, 0x44, 0x7c, 0x2c, 0x88, 0x42, 0xda, 0x3c, 0xfc, 0xec, 0x11, 0xdf, - 0x51, 0x2e, 0x9d, 0x94, 0xac, 0x66, 0xbc, 0xd8, 0xa2, 0x29, 0x6c, 0x48, 0xa7, 0x8c, 0x16, 0x5e, - 0x6b, 0xca, 0xeb, 0xf3, 0x47, 0xbc, 0xce, 0x0b, 0xf1, 0xa4, 0x64, 0xb5, 0xe3, 0xe5, 0xc0, 0xbc, - 0x73, 0x87, 0xf8, 0x21, 0xb5, 0x53, 0x52, 0xb8, 0xae, 0x3f, 0xd9, 0xf9, 0x50, 0x96, 0x58, 0x64, - 0xc9, 0x5a, 0x76, 0xfe, 0xaf, 0x28, 0xfa, 0x0d, 0x76, 0x14, 0x59, 0x4c, 0x5d, 0x12, 0xd9, 0x19, - 0x75, 0x18, 0xf5, 0x42, 0x5a, 0xa0, 0x08, 0x19, 0xed, 0x36, 0xd4, 0x51, 0x47, 0x8f, 0x41, 0x56, - 0xd5, 0xe7, 0xf3, 0xe2, 0x51, 0x51, 0x3b, 0x29, 0x59, 0x9f, 0xc4, 0x8f, 0xe4, 0x87, 0x35, 0xa8, - 0xc4, 0xdc, 0xef, 0xff, 0x6e, 0xc0, 0xc6, 0x05, 0x8e, 0x7e, 0x16, 0x58, 0x90, 0xf3, 0xc4, 0x93, - 0x17, 0x3b, 0x82, 0x1a, 0x97, 0x5b, 0x35, 0x82, 0x1b, 0x87, 0x3d, 0x73, 0xc5, 0x23, 0x64, 0x0e, - 0x19, 0xf5, 0x54, 0x91, 0xa5, 0xc5, 0x0f, 0x86, 0xb1, 0xfc, 0xd4, 0x30, 0x56, 0x9e, 0x3d, 0x8c, - 0x7d, 0x06, 0xa8, 0x98, 0x9c, 0x1f, 0xc3, 0x4b, 0xe2, 0x5e, 0xbb, 0x11, 0x41, 0xaf, 0x60, 0x7d, - 0x86, 0x23, 0x1b, 0x7b, 0x9e, 0x7e, 0x89, 0x1a, 0xd6, 0xda, 0x0c, 0x47, 0xc7, 0x9e, 0x97, 0xa2, - 0x6f, 0x75, 0x2a, 0x0a, 0x2f, 0x49, 0xb7, 0xbc, 0x5b, 0x51, 0x93, 0xb5, 0xaa, 0x9b, 0xfb, 0x04, - 0x54, 0xbd, 0xf4, 0xef, 0x7f, 0x30, 0xe0, 0xe5, 0x82, 0xd9, 0xff, 0x87, 0xb4, 0x7c, 0xd5, 0xf2, - 0xfd, 0xab, 0x1e, 0x40, 0x1d, 0xc7, 0x2c, 0xa3, 0x22, 0x07, 0xf3, 0x6a, 0xfe, 0xd5, 0xe5, 0x73, - 0x5c, 0x7c, 0xf2, 0x13, 0x16, 0x52, 0x2b, 0x17, 0x3e, 0x40, 0x5e, 0x7d, 0x0a, 0x79, 0xed, 0xf9, - 0xc8, 0xdf, 0xc1, 0xe6, 0x02, 0xc0, 0x3d, 0xe6, 0x1e, 0xb9, 0xcf, 0xdc, 0x23, 0xba, 0x91, 0xb1, - 0x4e, 0x2d, 0x31, 0xdf, 0x5f, 0x09, 0x67, 0x25, 0x57, 0x65, 0xa3, 0xd0, 0x7f, 0x03, 0x8d, 0xc5, - 0x2b, 0x81, 0xa0, 0x5a, 0x1c, 0xd5, 0xb2, 0xd4, 0x1a, 0x6d, 0x41, 0x2d, 0x61, 0xef, 0x88, 0x06, - 0x59, 0xb1, 0xf4, 0x66, 0x7f, 0x0a, 0x8d, 0x82, 0x3a, 0x6a, 0xc2, 0xda, 0x89, 0x35, 0x3e, 0x7e, - 0x33, 0x1e, 0x75, 0x4a, 0x08, 0xa0, 0x3e, 0x7c, 0x3d, 0x1d, 0x8d, 0x47, 0x1d, 0x03, 0xb5, 0xa1, - 0x71, 0x3e, 0x95, 0xbb, 0xd3, 0xe9, 0xf7, 0x9d, 0x32, 0x6a, 0xc1, 0xba, 0xde, 0x8e, 0x47, 0x9d, - 0x8a, 0xac, 0xb2, 0xc6, 0x67, 0xaf, 0x2f, 0xc6, 0xa3, 0x4e, 0x75, 0xf8, 0xc3, 0x1f, 0xb7, 0x3d, - 0xe3, 0xe6, 0xb6, 0x67, 0xfc, 0x7d, 0xdb, 0x33, 0xde, 0xdf, 0xf5, 0x4a, 0x37, 0x77, 0xbd, 0xd2, - 0x9f, 0x77, 0xbd, 0xd2, 0x2f, 0x5f, 0xf9, 0xa1, 0x08, 0x32, 0xc7, 0x74, 0x59, 0x3c, 0xc8, 0xfb, - 0x73, 0x03, 0x1c, 0xd2, 0xf9, 0x66, 0x70, 0xb5, 0xf8, 0xb3, 0x8b, 0xeb, 0x84, 0x70, 0xa7, 0xae, - 0x80, 0x7f, 0xfd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x06, 0x18, 0x1e, 0x99, 0xfa, 0x07, 0x00, + 0xcf, 0x81, 0x78, 0x10, 0x2e, 0xf7, 0x92, 0x3b, 0x50, 0xfb, 0x20, 0x8b, 0x66, 0xec, 0x38, 0x29, + 0x8d, 0x5a, 0x95, 0xbd, 0xf3, 0x9c, 0xf3, 0x9d, 0x6f, 0xce, 0xf9, 0xe5, 0x68, 0x02, 0x43, 0x07, + 0x3b, 0xd7, 0x11, 0xa3, 0x06, 0x49, 0x98, 0x1b, 0x84, 0xd4, 0x37, 0x66, 0x07, 0xe5, 0xb7, 0x9e, + 0xa4, 0x4c, 0x30, 0xb4, 0x59, 0x68, 0xf4, 0x32, 0x3e, 0x3b, 0xd8, 0xde, 0xf1, 0x19, 0xf3, 0x23, + 0x62, 0x28, 0x89, 0x93, 0x5d, 0x1a, 0x22, 0x8c, 0x09, 0x17, 0x38, 0x4e, 0xf2, 0xaa, 0xed, 0x2d, + 0x9f, 0xf9, 0x4c, 0x7d, 0x1a, 0xf2, 0xab, 0x88, 0xee, 0xb8, 0x8c, 0xc7, 0x8c, 0x1b, 0x5c, 0xe0, + 0xd7, 0xf9, 0x6d, 0x0e, 0x11, 0xf8, 0xc0, 0x10, 0x57, 0x85, 0x60, 0x50, 0x08, 0x1c, 0xcc, 0x49, + 0x99, 0x75, 0x59, 0x48, 0xf3, 0xfc, 0xf0, 0x8f, 0x2a, 0x34, 0x26, 0xb2, 0x0f, 0xf4, 0x29, 0x74, + 0x54, 0x43, 0x36, 0xcd, 0x62, 0x87, 0xa4, 0x7d, 0x6d, 0x57, 0xdb, 0xab, 0x5b, 0x6d, 0x15, 0x9b, + 0xaa, 0x10, 0x3a, 0x82, 0x8f, 0xdd, 0x2c, 0x4d, 0x09, 0x15, 0x76, 0x2e, 0x0d, 0xa9, 0x20, 0xe9, + 0x0c, 0x47, 0xfd, 0xaa, 0x12, 0x6f, 0x15, 0x59, 0x65, 0x78, 0x5a, 0xe4, 0xd0, 0x97, 0x80, 0x2e, + 0xc3, 0x94, 0x0b, 0xdb, 0x89, 0x98, 0xfb, 0xda, 0x0e, 0x48, 0xe8, 0x07, 0xa2, 0x5f, 0x53, 0x15, + 0x3d, 0x95, 0x19, 0xc9, 0x84, 0xa9, 0xe2, 0xc8, 0x84, 0x67, 0x11, 0x2e, 0xc5, 0x92, 0x42, 0xbf, + 0xbe, 0xab, 0xed, 0xb5, 0x0f, 0xb7, 0xf5, 0x1c, 0x91, 0x3e, 0x47, 0xa4, 0xbf, 0x9a, 0x23, 0x1a, + 0xd5, 0xdf, 0xfe, 0xbd, 0xa3, 0x59, 0x5d, 0x59, 0xa8, 0xbc, 0x64, 0x06, 0x7d, 0x01, 0xcf, 0x38, + 0xc1, 0x11, 0x49, 0x6d, 0x9c, 0x24, 0x76, 0x80, 0x79, 0xd0, 0x6f, 0xec, 0x6a, 0x7b, 0x1d, 0xab, + 0x9b, 0x87, 0x8f, 0x93, 0xc4, 0xc4, 0x3c, 0x40, 0xfb, 0xf0, 0x51, 0xa1, 0x2b, 0x1a, 0x94, 0xca, + 0xa6, 0x52, 0x16, 0x06, 0x79, 0x7f, 0x98, 0x07, 0xc3, 0xf7, 0x75, 0xe8, 0xfe, 0x94, 0x91, 0x8c, + 0x78, 0x67, 0x84, 0x73, 0xec, 0x13, 0xb4, 0x09, 0x0d, 0x71, 0x65, 0x87, 0x9e, 0xe2, 0xd5, 0xb1, + 0xea, 0xe2, 0xea, 0xd4, 0x43, 0xcf, 0xa1, 0x19, 0x73, 0x5f, 0x46, 0xab, 0x2a, 0xda, 0x88, 0xb9, + 0x7f, 0xea, 0x49, 0xc4, 0x2b, 0x18, 0xb4, 0x9d, 0xa5, 0xf1, 0xbf, 0x03, 0xf8, 0x1f, 0x93, 0xb7, + 0x9c, 0x72, 0xea, 0x5f, 0x61, 0x4b, 0x5e, 0xed, 0xa6, 0x04, 0x0b, 0x62, 0xcf, 0x70, 0x14, 0x7a, + 0x58, 0xb0, 0x54, 0x8d, 0xde, 0x3e, 0xdc, 0xd7, 0xf3, 0x7d, 0xd0, 0x8b, 0x85, 0xd1, 0x8b, 0x95, + 0xd0, 0xcf, 0xb8, 0x7f, 0xa2, 0x4a, 0x2e, 0xe6, 0x15, 0x66, 0xc5, 0x42, 0xf1, 0xbd, 0x28, 0x32, + 0xa1, 0x23, 0xfd, 0x3d, 0x12, 0x11, 0x1f, 0x0b, 0xa2, 0x40, 0xb5, 0x0f, 0x3f, 0x7b, 0xc0, 0x77, + 0x5c, 0x48, 0xcd, 0x8a, 0xd5, 0x8e, 0x17, 0x47, 0x34, 0x85, 0x0d, 0xe9, 0x94, 0xd1, 0xd2, 0x6b, + 0x4d, 0x79, 0x7d, 0xfe, 0x80, 0xd7, 0x79, 0x29, 0x36, 0x2b, 0x56, 0x37, 0x5e, 0x0e, 0xcc, 0x27, + 0x77, 0x88, 0x1f, 0x52, 0x3b, 0x25, 0xa5, 0xeb, 0xfa, 0xa3, 0x93, 0x8f, 0x64, 0x89, 0x45, 0x96, + 0xac, 0xe5, 0xe4, 0xff, 0x89, 0xa2, 0xdf, 0x60, 0x47, 0x91, 0xc5, 0xd4, 0x25, 0x91, 0x9d, 0x51, + 0x87, 0x51, 0x2f, 0xa4, 0x25, 0x8a, 0x90, 0xd1, 0x7e, 0x4b, 0x5d, 0x75, 0xf4, 0x10, 0x64, 0x55, + 0x7d, 0x3e, 0x2f, 0x1e, 0x97, 0xb5, 0x66, 0xc5, 0xfa, 0x24, 0x7e, 0x20, 0x3f, 0x6a, 0x40, 0x2d, + 0xe6, 0xfe, 0xf0, 0x77, 0x0d, 0x36, 0x2e, 0x70, 0xf4, 0xb3, 0xc0, 0x82, 0x9c, 0x27, 0x9e, 0x6c, + 0xec, 0x08, 0x1a, 0x5c, 0x1e, 0xd5, 0x0a, 0x6e, 0x1c, 0x0e, 0xf4, 0x15, 0x0f, 0x8c, 0x3e, 0x62, + 0xd4, 0x53, 0x45, 0x56, 0x2e, 0xbe, 0xb7, 0x8c, 0xd5, 0xc7, 0x96, 0xb1, 0xf6, 0xe4, 0x65, 0x1c, + 0x32, 0x40, 0xe5, 0xe6, 0xfc, 0x18, 0x5e, 0x12, 0xf7, 0xda, 0x8d, 0x08, 0x7a, 0x01, 0xeb, 0x33, + 0x1c, 0xd9, 0xd8, 0xf3, 0xf2, 0x57, 0xa6, 0x65, 0xad, 0xcd, 0x70, 0x74, 0xec, 0x79, 0x29, 0xfa, + 0x36, 0x4f, 0x45, 0xe1, 0x25, 0xe9, 0x57, 0x77, 0x6b, 0x6a, 0xb3, 0x56, 0x4d, 0x73, 0x97, 0x80, + 0xaa, 0x97, 0xfe, 0xc3, 0xf7, 0x1a, 0x3c, 0x5f, 0x30, 0xfb, 0x70, 0x48, 0xcb, 0xad, 0x56, 0xef, + 0xb6, 0x7a, 0x00, 0x4d, 0x1c, 0xb3, 0x8c, 0x8a, 0x02, 0xcc, 0x8b, 0xf9, 0xaf, 0x2e, 0x9f, 0xda, + 0xf2, 0x27, 0x3f, 0x61, 0x21, 0xb5, 0x0a, 0xe1, 0x3d, 0xe4, 0xf5, 0xc7, 0x90, 0x37, 0x9e, 0x8e, + 0xfc, 0x0d, 0x6c, 0x2e, 0x00, 0xdc, 0x61, 0xee, 0x91, 0xbb, 0xcc, 0x3d, 0x92, 0x0f, 0x32, 0xc9, + 0x53, 0x4b, 0xcc, 0xf7, 0x57, 0xc2, 0x59, 0xc9, 0x55, 0xd9, 0x28, 0xf4, 0xdf, 0x40, 0x6b, 0xf1, + 0x4a, 0x20, 0xa8, 0x97, 0x57, 0x75, 0x2c, 0xf5, 0x8d, 0xb6, 0xa0, 0x91, 0xb0, 0x37, 0x24, 0x07, + 0x59, 0xb3, 0xf2, 0xc3, 0xfe, 0x14, 0x5a, 0x25, 0x75, 0xd4, 0x86, 0xb5, 0x13, 0x6b, 0x72, 0xfc, + 0x6a, 0x32, 0xee, 0x55, 0x10, 0x40, 0x73, 0xf4, 0x72, 0x3a, 0x9e, 0x8c, 0x7b, 0x1a, 0xea, 0x42, + 0xeb, 0x7c, 0x2a, 0x4f, 0xa7, 0xd3, 0xef, 0x7b, 0x55, 0xd4, 0x81, 0xf5, 0xfc, 0x38, 0x19, 0xf7, + 0x6a, 0xb2, 0xca, 0x9a, 0x9c, 0xbd, 0xbc, 0x98, 0x8c, 0x7b, 0xf5, 0xd1, 0x0f, 0x7f, 0xde, 0x0c, + 0xb4, 0x77, 0x37, 0x03, 0xed, 0x9f, 0x9b, 0x81, 0xf6, 0xf6, 0x76, 0x50, 0x79, 0x77, 0x3b, 0xa8, + 0xfc, 0x75, 0x3b, 0xa8, 0xfc, 0xf2, 0x95, 0x1f, 0x8a, 0x20, 0x73, 0x74, 0x97, 0xc5, 0x46, 0x31, + 0x9f, 0x1b, 0xe0, 0x90, 0xce, 0x0f, 0xc6, 0xd5, 0xe2, 0x5f, 0x5b, 0x5c, 0x27, 0x84, 0x3b, 0x4d, + 0x05, 0xfc, 0xeb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x6a, 0x0b, 0x3c, 0xd6, 0x07, 0x00, 0x00, } @@ -746,20 +735,13 @@ func (m *Epoch) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.SealerBlockHash) i = encodeVarintEpoching(dAtA, i, uint64(len(m.SealerBlockHash))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 } if len(m.SealerAppHash) > 0 { i -= len(m.SealerAppHash) copy(dAtA[i:], m.SealerAppHash) i = encodeVarintEpoching(dAtA, i, uint64(len(m.SealerAppHash))) i-- - dAtA[i] = 0x32 - } - if len(m.AppHashRoot) > 0 { - i -= len(m.AppHashRoot) - copy(dAtA[i:], m.AppHashRoot) - i = encodeVarintEpoching(dAtA, i, uint64(len(m.AppHashRoot))) - i-- dAtA[i] = 0x2a } if m.LastBlockTime != nil { @@ -1214,10 +1196,6 @@ func (m *Epoch) Size() (n int) { l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime) n += 1 + l + sovEpoching(uint64(l)) } - l = len(m.AppHashRoot) - if l > 0 { - n += 1 + l + sovEpoching(uint64(l)) - } l = len(m.SealerAppHash) if l > 0 { n += 1 + l + sovEpoching(uint64(l)) @@ -1545,40 +1523,6 @@ func (m *Epoch) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppHashRoot", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowEpoching - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthEpoching - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthEpoching - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AppHashRoot = append(m.AppHashRoot[:0], dAtA[iNdEx:postIndex]...) - if m.AppHashRoot == nil { - m.AppHashRoot = []byte{} - } - iNdEx = postIndex - case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SealerAppHash", wireType) } @@ -1612,7 +1556,7 @@ func (m *Epoch) Unmarshal(dAtA []byte) error { m.SealerAppHash = []byte{} } iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SealerBlockHash", wireType) } diff --git a/x/epoching/types/keys.go b/x/epoching/types/keys.go index 5ec668b83..c6ac89674 100644 --- a/x/epoching/types/keys.go +++ b/x/epoching/types/keys.go @@ -27,8 +27,7 @@ var ( SlashedValidatorSetKey = []byte{0x17} // key prefix for slashed validator set ValidatorLifecycleKey = []byte{0x18} // key prefix for validator life cycle DelegationLifecycleKey = []byte{0x19} // key prefix for delegation life cycle - AppHashKey = []byte{0x20} // key prefix for the app hash - ParamsKey = []byte{0x21} // key prefix for the parameters + ParamsKey = []byte{0x20} // key prefix for the parameters ) func KeyPrefix(p string) []byte { diff --git a/x/epoching/types/query.go b/x/epoching/types/query.go index 9dbbe889a..7534862c3 100644 --- a/x/epoching/types/query.go +++ b/x/epoching/types/query.go @@ -11,7 +11,6 @@ func (e *Epoch) ToResponse() *EpochResponse { CurrentEpochInterval: e.CurrentEpochInterval, FirstBlockHeight: e.FirstBlockHeight, LastBlockTime: e.LastBlockTime, - AppHashRootHex: hex.EncodeToString(e.AppHashRoot), SealerAppHashHex: hex.EncodeToString(e.SealerAppHash), SealerBlockHash: hex.EncodeToString(e.SealerBlockHash), } diff --git a/x/epoching/types/query.pb.go b/x/epoching/types/query.pb.go index 41d754ff2..ab85b879b 100644 --- a/x/epoching/types/query.pb.go +++ b/x/epoching/types/query.pb.go @@ -955,17 +955,14 @@ type EpochResponse struct { // finalised. The last_block_time field is nil in the epoch's beginning, and // is set upon the end of this epoch. LastBlockTime *time.Time `protobuf:"bytes,4,opt,name=last_block_time,json=lastBlockTime,proto3,stdtime" json:"last_block_time,omitempty"` - // app_hash_root is the Merkle root of all AppHashs in this epoch - // It will be used for proving a block is in an epoch as hex string. - AppHashRootHex string `protobuf:"bytes,5,opt,name=app_hash_root_hex,json=appHashRootHex,proto3" json:"app_hash_root_hex,omitempty"` // sealer is the last block of the sealed epoch // sealer_app_hash points to the sealer but stored in the 1st header // of the next epoch as hex string. - SealerAppHashHex string `protobuf:"bytes,6,opt,name=sealer_app_hash_hex,json=sealerAppHashHex,proto3" json:"sealer_app_hash_hex,omitempty"` + SealerAppHashHex string `protobuf:"bytes,5,opt,name=sealer_app_hash_hex,json=sealerAppHashHex,proto3" json:"sealer_app_hash_hex,omitempty"` // sealer_block_hash is the hash of the sealer // the validator set has generated a BLS multisig on the hash, // i.e., hash of the last block in the epoch as hex string. - SealerBlockHash string `protobuf:"bytes,7,opt,name=sealer_block_hash,json=sealerBlockHash,proto3" json:"sealer_block_hash,omitempty"` + SealerBlockHash string `protobuf:"bytes,6,opt,name=sealer_block_hash,json=sealerBlockHash,proto3" json:"sealer_block_hash,omitempty"` } func (m *EpochResponse) Reset() { *m = EpochResponse{} } @@ -1029,13 +1026,6 @@ func (m *EpochResponse) GetLastBlockTime() *time.Time { return nil } -func (m *EpochResponse) GetAppHashRootHex() string { - if m != nil { - return m.AppHashRootHex - } - return "" -} - func (m *EpochResponse) GetSealerAppHashHex() string { if m != nil { return m.SealerAppHashHex @@ -1278,95 +1268,94 @@ func init() { func init() { proto.RegisterFile("babylon/epoching/v1/query.proto", fileDescriptor_1821b530f2ec2711) } var fileDescriptor_1821b530f2ec2711 = []byte{ - // 1408 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0xdc, 0xc4, - 0x17, 0x8f, 0x37, 0x9b, 0xb4, 0x79, 0x69, 0x9a, 0x64, 0xd2, 0xf6, 0x9b, 0x6e, 0xda, 0x4d, 0xbf, - 0x2e, 0xf4, 0x47, 0xd2, 0xd8, 0x4d, 0x93, 0x02, 0xfd, 0x01, 0x55, 0xd3, 0x52, 0x12, 0xd4, 0xa2, - 0xd4, 0x40, 0x0f, 0x5c, 0xcc, 0xec, 0x7a, 0xe2, 0xb5, 0xf0, 0x7a, 0x5c, 0xcf, 0xec, 0x92, 0xa8, - 0x14, 0x21, 0xc4, 0x91, 0x43, 0x25, 0x0e, 0x08, 0x21, 0x21, 0x10, 0x47, 0xfe, 0x02, 0x04, 0x07, - 0x8e, 0x3d, 0x16, 0x71, 0xe1, 0x04, 0xa8, 0x41, 0xfc, 0x1d, 0xc8, 0x33, 0xe3, 0x5d, 0xef, 0xc6, - 0xee, 0x6e, 0xa2, 0x8a, 0xdb, 0x66, 0xde, 0xfb, 0xcc, 0xfb, 0xbc, 0xcf, 0x1b, 0xcf, 0x7c, 0x02, - 0xb3, 0x15, 0x5c, 0xd9, 0xf2, 0x69, 0x60, 0x92, 0x90, 0x56, 0x6b, 0x5e, 0xe0, 0x9a, 0xcd, 0x45, - 0xf3, 0x7e, 0x83, 0x44, 0x5b, 0x46, 0x18, 0x51, 0x4e, 0xd1, 0x94, 0x4a, 0x30, 0x92, 0x04, 0xa3, - 0xb9, 0x58, 0x3a, 0xe4, 0x52, 0x97, 0x8a, 0xb8, 0x19, 0xff, 0x92, 0xa9, 0xa5, 0x59, 0x97, 0x52, - 0xd7, 0x27, 0xa6, 0xf8, 0xab, 0xd2, 0xd8, 0x30, 0xb9, 0x57, 0x27, 0x8c, 0xe3, 0x7a, 0xa8, 0x12, - 0x8e, 0xa9, 0x04, 0x1c, 0x7a, 0x26, 0x0e, 0x02, 0xca, 0x31, 0xf7, 0x68, 0xc0, 0x54, 0x74, 0xae, - 0x4a, 0x59, 0x9d, 0x32, 0xb3, 0x82, 0x19, 0x91, 0x14, 0xcc, 0xe6, 0x62, 0x85, 0x70, 0xbc, 0x68, - 0x86, 0xd8, 0xf5, 0x02, 0x91, 0xac, 0x72, 0x4f, 0x64, 0xd1, 0x0e, 0x71, 0x84, 0xeb, 0xc9, 0x6e, - 0x7a, 0x56, 0x46, 0xab, 0x07, 0x91, 0xa3, 0x1f, 0x02, 0x74, 0x37, 0xae, 0xb3, 0x2e, 0x80, 0x16, - 0xb9, 0xdf, 0x20, 0x8c, 0xeb, 0xeb, 0x30, 0xd5, 0xb1, 0xca, 0x42, 0x1a, 0x30, 0x82, 0x2e, 0xc1, - 0xb0, 0x2c, 0x30, 0xad, 0x9d, 0xd0, 0xce, 0x8c, 0x5e, 0x98, 0x31, 0x32, 0x94, 0x31, 0x24, 0x68, - 0xa5, 0xf8, 0xf8, 0x8f, 0xd9, 0x01, 0x4b, 0x01, 0xf4, 0x65, 0x38, 0x2c, 0x76, 0x7c, 0x3d, 0x4e, - 0x5c, 0x0b, 0x36, 0xa8, 0x2a, 0x85, 0x66, 0x60, 0x44, 0x80, 0xed, 0xa0, 0x51, 0x17, 0xdb, 0x16, - 0xad, 0xfd, 0x62, 0xe1, 0xad, 0x46, 0x5d, 0xb7, 0xe0, 0x48, 0x37, 0x4a, 0x51, 0x79, 0x05, 0x86, - 0x44, 0x96, 0x62, 0xa2, 0x67, 0x32, 0x11, 0xb0, 0x04, 0x62, 0x49, 0x80, 0xfe, 0x7e, 0x7a, 0x4f, - 0x96, 0xa6, 0x72, 0x0b, 0xa0, 0xad, 0xb2, 0xda, 0xf8, 0x94, 0x21, 0x47, 0x62, 0xc4, 0x23, 0x31, - 0xe4, 0xa9, 0x50, 0x23, 0x31, 0xd6, 0xb1, 0x4b, 0x14, 0xd6, 0x4a, 0x21, 0xf5, 0x6f, 0x34, 0xf8, - 0xdf, 0x8e, 0x12, 0x8a, 0xf7, 0x65, 0x18, 0x16, 0x34, 0x62, 0x09, 0x07, 0xfb, 0x24, 0xae, 0x10, - 0xe8, 0x8d, 0x0e, 0x7e, 0x05, 0xc1, 0xef, 0x74, 0x4f, 0x7e, 0x6a, 0x93, 0x34, 0xc1, 0x12, 0x4c, - 0x0b, 0x7e, 0x37, 0x1a, 0x51, 0x44, 0x02, 0xae, 0xaa, 0xc9, 0xd1, 0xbb, 0x70, 0x34, 0x23, 0xa6, - 0xd8, 0x9f, 0x84, 0xb1, 0xaa, 0x5c, 0xb7, 0xdb, 0xea, 0x17, 0xad, 0x03, 0xd5, 0x54, 0x32, 0x7a, - 0x11, 0x0e, 0xca, 0x89, 0x56, 0x68, 0x23, 0x70, 0x70, 0xb4, 0x25, 0xa8, 0x16, 0xad, 0x31, 0xb1, - 0xba, 0xa2, 0x16, 0xf5, 0x8f, 0xd2, 0x27, 0xe2, 0x0e, 0x73, 0x59, 0x3f, 0x27, 0xa2, 0x6b, 0x46, - 0x85, 0x3d, 0xcf, 0xe8, 0x3b, 0x2d, 0x7d, 0x0c, 0x64, 0x79, 0xd5, 0xe4, 0x6b, 0x50, 0xac, 0x33, - 0x37, 0x19, 0xd0, 0x5c, 0xe6, 0x80, 0xee, 0x36, 0x48, 0x83, 0x38, 0x77, 0x08, 0x63, 0x69, 0x8d, - 0x05, 0xee, 0xf9, 0x8d, 0xe9, 0x7b, 0x0d, 0x66, 0x04, 0xc7, 0xdb, 0x98, 0x13, 0xc6, 0x33, 0x85, - 0x0a, 0x9c, 0x8e, 0x49, 0xec, 0x27, 0x81, 0x23, 0xa7, 0x30, 0x0b, 0xa3, 0x52, 0xc5, 0x2a, 0x6d, - 0x04, 0x5c, 0x8d, 0x00, 0xc4, 0xd2, 0x8d, 0x78, 0xa5, 0x4b, 0xc9, 0xc1, 0x3d, 0x2b, 0xf9, 0x93, - 0x06, 0xc7, 0xb2, 0x59, 0x2a, 0x3d, 0x2d, 0x98, 0xf4, 0x45, 0x48, 0x32, 0xb5, 0x53, 0xe2, 0x9e, - 0xea, 0x2d, 0xee, 0x6d, 0x8f, 0x71, 0x6b, 0xdc, 0xef, 0xdc, 0xfb, 0xf9, 0x69, 0x7c, 0x05, 0xca, - 0x82, 0xfc, 0x3d, 0xec, 0x7b, 0x0e, 0xe6, 0x34, 0xba, 0xed, 0x6d, 0x90, 0xea, 0x56, 0xd5, 0x4f, - 0x7a, 0x45, 0x47, 0x61, 0x7f, 0x13, 0xfb, 0x36, 0x76, 0x9c, 0x48, 0x88, 0x3c, 0x62, 0xed, 0x6b, - 0x62, 0xff, 0xba, 0xe3, 0x44, 0xfa, 0x67, 0x1a, 0xcc, 0xe6, 0xa2, 0x55, 0xf7, 0xf9, 0x70, 0x74, - 0x4b, 0x86, 0x7c, 0x6f, 0x83, 0x4c, 0x17, 0x84, 0x1e, 0xf3, 0x99, 0x7a, 0xdc, 0xc3, 0xfe, 0xdb, - 0x1c, 0x73, 0xf2, 0x6e, 0xe8, 0x60, 0xde, 0x6e, 0x23, 0xde, 0x27, 0xae, 0xa7, 0x5f, 0x55, 0x2c, - 0x6e, 0x12, 0x9f, 0xb8, 0xa2, 0xad, 0xac, 0x26, 0x1c, 0xd2, 0xc9, 0xc2, 0x21, 0xb2, 0x09, 0x17, - 0x4e, 0xe4, 0xa3, 0x55, 0x13, 0x37, 0x24, 0x5c, 0x30, 0x95, 0xf7, 0xe2, 0x99, 0x4c, 0xa6, 0x59, - 0x7b, 0xc4, 0x85, 0x04, 0xcd, 0x8f, 0xd3, 0xb7, 0x62, 0xdc, 0x13, 0xe1, 0xff, 0xe9, 0x27, 0xff, - 0xab, 0xa6, 0xae, 0xbd, 0x0e, 0x02, 0xad, 0x8f, 0x1e, 0x9a, 0xc9, 0x10, 0x93, 0xd3, 0x59, 0xce, - 0x9b, 0x86, 0x4c, 0xb3, 0x52, 0x08, 0x74, 0x0e, 0x10, 0xa7, 0x1c, 0xfb, 0x76, 0x93, 0x72, 0x2f, - 0x70, 0xed, 0x90, 0x7e, 0x48, 0x22, 0x41, 0x76, 0xd0, 0x9a, 0x10, 0x91, 0x7b, 0x22, 0xb0, 0x1e, - 0xaf, 0x77, 0x1d, 0xdf, 0xc1, 0xbd, 0x1f, 0xdf, 0x7f, 0x0a, 0x30, 0xd6, 0x79, 0x45, 0xff, 0x1f, - 0x0e, 0xb4, 0xa4, 0xac, 0x90, 0x48, 0xa9, 0x39, 0x9a, 0xa8, 0x59, 0x21, 0x11, 0x5a, 0x86, 0x23, - 0x1d, 0xb7, 0xb8, 0xed, 0x05, 0x9c, 0x44, 0x4d, 0xec, 0xab, 0x5b, 0xe2, 0x50, 0xfa, 0x3a, 0x5f, - 0x53, 0xb1, 0xb8, 0xc3, 0x0d, 0x2f, 0x62, 0xdc, 0xae, 0xf8, 0xb4, 0xfa, 0x81, 0x5d, 0x23, 0x9e, - 0x5b, 0xe3, 0x82, 0x7b, 0xd1, 0x9a, 0x10, 0x91, 0x95, 0x38, 0xb0, 0x2a, 0xd6, 0xd1, 0x2a, 0x8c, - 0xfb, 0xb8, 0x95, 0x1c, 0xbb, 0xa0, 0xe9, 0xa2, 0x68, 0xb3, 0x64, 0x48, 0x07, 0x64, 0x24, 0x16, - 0xc9, 0x78, 0x27, 0xb1, 0x48, 0x2b, 0xc5, 0x47, 0x7f, 0xce, 0x6a, 0xd6, 0x58, 0x0c, 0x14, 0x7b, - 0xc5, 0x11, 0x74, 0x16, 0x26, 0x71, 0x18, 0xda, 0x35, 0xcc, 0x6a, 0x76, 0x44, 0x29, 0xb7, 0x6b, - 0x64, 0x73, 0x7a, 0x48, 0x9c, 0xe1, 0x83, 0x38, 0x0c, 0x57, 0x31, 0xab, 0x59, 0x94, 0xf2, 0x55, - 0xb2, 0x89, 0x16, 0x60, 0x8a, 0x11, 0xec, 0x93, 0xc8, 0x6e, 0x21, 0xe2, 0xe4, 0x61, 0x91, 0x3c, - 0x21, 0x43, 0xd7, 0x25, 0x24, 0x4e, 0x9f, 0x83, 0x49, 0x95, 0xae, 0x5a, 0xc2, 0xac, 0x36, 0xbd, - 0x4f, 0x24, 0x8f, 0xcb, 0x80, 0xec, 0x08, 0xb3, 0x9a, 0xfe, 0xa3, 0x26, 0x9e, 0xab, 0x9d, 0x97, - 0x3e, 0x9a, 0x82, 0x21, 0xbe, 0x69, 0x7b, 0x8e, 0xfa, 0xae, 0x8a, 0x7c, 0x73, 0xcd, 0x41, 0x87, - 0x61, 0xb8, 0xce, 0xdc, 0x78, 0xb5, 0x20, 0x56, 0x87, 0xea, 0xcc, 0x5d, 0x73, 0xe2, 0xe1, 0x64, - 0xa8, 0x37, 0x5a, 0x49, 0x09, 0x77, 0x0d, 0x60, 0x0f, 0x9a, 0x8d, 0x54, 0x5a, 0x7a, 0x4d, 0xc0, - 0x60, 0x9d, 0xb9, 0x4a, 0xa1, 0xf8, 0xa7, 0xde, 0x84, 0xc9, 0x1d, 0x57, 0x6a, 0x3f, 0xe7, 0x24, - 0x79, 0x08, 0x0b, 0x7b, 0x7b, 0x08, 0xf5, 0xaf, 0x35, 0x38, 0x92, 0x7d, 0x77, 0xa1, 0xe3, 0x00, - 0x2c, 0x5e, 0xb6, 0x1d, 0xc2, 0xaa, 0x4a, 0xb9, 0x11, 0xb1, 0x72, 0x93, 0xb0, 0xea, 0x0e, 0x9d, - 0x0a, 0xbd, 0x74, 0x1a, 0xdc, 0xb5, 0x4e, 0x17, 0x9e, 0x8c, 0xc2, 0x90, 0xb8, 0x0e, 0xd0, 0x27, - 0x1a, 0x0c, 0x4b, 0xd3, 0x8a, 0x4e, 0xe7, 0x35, 0xd9, 0xe5, 0x90, 0x4b, 0x67, 0x7a, 0x27, 0xca, - 0x56, 0xf5, 0x93, 0x9f, 0xfe, 0xf6, 0xf7, 0x17, 0x85, 0xe3, 0x68, 0xc6, 0xcc, 0x37, 0xec, 0xe8, - 0x4b, 0x0d, 0x46, 0x5a, 0x26, 0x17, 0xcd, 0xe5, 0x6f, 0xde, 0xed, 0x9f, 0x4b, 0xf3, 0x7d, 0xe5, - 0x2a, 0x2e, 0x8b, 0x82, 0xcb, 0x3c, 0x3a, 0x6b, 0xe6, 0xfe, 0x6b, 0xc0, 0xcc, 0x07, 0xad, 0x73, - 0xf1, 0xea, 0xdc, 0x43, 0xf4, 0xb9, 0x06, 0xd0, 0xf6, 0xb1, 0xa8, 0x57, 0xb9, 0xb4, 0xa1, 0x2e, - 0x9d, 0xeb, 0x2f, 0xb9, 0x2f, 0xa1, 0x94, 0x07, 0xfe, 0x4a, 0x83, 0x03, 0x69, 0x6b, 0x8a, 0x16, - 0xf2, 0x6b, 0x64, 0xd8, 0xdb, 0x92, 0xd1, 0x6f, 0xba, 0x22, 0x35, 0x27, 0x48, 0xbd, 0x80, 0xf4, - 0x4c, 0x52, 0x1d, 0xd7, 0x28, 0xfa, 0x36, 0x19, 0xa2, 0xb0, 0x28, 0xbd, 0x86, 0x98, 0x72, 0x72, - 0x3d, 0x87, 0x98, 0xf6, 0x53, 0xfa, 0x65, 0x41, 0x69, 0x19, 0x5d, 0xe8, 0x7b, 0x88, 0x66, 0x5d, - 0x7e, 0x9f, 0x0c, 0xfd, 0xa0, 0xc1, 0x78, 0x97, 0x4f, 0x43, 0xe7, 0xf3, 0x8b, 0x67, 0x1b, 0xcf, - 0xd2, 0xe2, 0x2e, 0x10, 0x8a, 0xf4, 0x92, 0x20, 0xbd, 0x80, 0xe6, 0x9f, 0x41, 0xfa, 0xb2, 0x74, - 0x79, 0x6d, 0xb6, 0x3f, 0x6b, 0x80, 0x76, 0x5a, 0x2b, 0xb4, 0x94, 0x5f, 0x3e, 0xd7, 0xc6, 0x95, - 0x96, 0x77, 0x07, 0x52, 0xb4, 0xaf, 0x08, 0xda, 0x17, 0xd1, 0x52, 0x26, 0xed, 0xd6, 0xfb, 0x2f, - 0x9c, 0x91, 0x40, 0x9a, 0x0f, 0x12, 0xb7, 0xf7, 0x10, 0xfd, 0xa2, 0xc1, 0x54, 0x86, 0x23, 0x42, - 0xcf, 0xa0, 0x92, 0x6f, 0xe1, 0x4a, 0x17, 0x77, 0x89, 0x52, 0x1d, 0x5c, 0x15, 0x1d, 0xbc, 0x84, - 0x96, 0x33, 0x3b, 0x70, 0x5a, 0xc8, 0x74, 0x0b, 0x89, 0x55, 0x7c, 0x18, 0x9f, 0x97, 0xd1, 0x94, - 0x5d, 0x42, 0xbd, 0xbe, 0xe8, 0x0e, 0x5b, 0x57, 0x5a, 0xe8, 0x33, 0x5b, 0x51, 0xbd, 0x26, 0xa8, - 0x5e, 0x42, 0x2f, 0xf7, 0x7f, 0xb0, 0xdb, 0x13, 0x60, 0x84, 0xaf, 0xbc, 0xf9, 0xf8, 0x69, 0x59, - 0x7b, 0xf2, 0xb4, 0xac, 0xfd, 0xf5, 0xb4, 0xac, 0x3d, 0xda, 0x2e, 0x0f, 0x3c, 0xd9, 0x2e, 0x0f, - 0xfc, 0xbe, 0x5d, 0x1e, 0x78, 0xef, 0xbc, 0xeb, 0xf1, 0x5a, 0xa3, 0x62, 0x54, 0x69, 0x3d, 0xd9, - 0xbc, 0x5a, 0xc3, 0x5e, 0xd0, 0xaa, 0xb4, 0xd9, 0xae, 0xc5, 0xb7, 0x42, 0xc2, 0x2a, 0xc3, 0xe2, - 0x0d, 0x59, 0xfa, 0x37, 0x00, 0x00, 0xff, 0xff, 0xb2, 0x10, 0x0c, 0x81, 0x1e, 0x12, 0x00, 0x00, + // 1384 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6f, 0x1b, 0x45, + 0x1b, 0xce, 0x3a, 0x4e, 0xbe, 0xe6, 0x4d, 0xf3, 0x25, 0x9d, 0xb4, 0xfd, 0x52, 0xa7, 0x75, 0xfa, + 0x6d, 0xa1, 0x2d, 0x49, 0xb3, 0xdb, 0x34, 0x29, 0xd0, 0x1f, 0x50, 0x35, 0x2d, 0x25, 0x41, 0x2d, + 0x4a, 0x17, 0xe8, 0x81, 0xcb, 0x32, 0xf6, 0x4e, 0xd6, 0x2b, 0xd6, 0xbb, 0xdb, 0x9d, 0xb1, 0x49, + 0x54, 0x8a, 0x10, 0xe2, 0xc8, 0xa1, 0x12, 0x07, 0x84, 0x90, 0x10, 0x88, 0x23, 0x7f, 0x01, 0x2a, + 0x07, 0x8e, 0x3d, 0x16, 0x71, 0xe1, 0x04, 0xa8, 0xe5, 0x0f, 0x41, 0xfb, 0xce, 0xac, 0xbd, 0x76, + 0xd6, 0xb5, 0x13, 0x55, 0xdc, 0xec, 0xf7, 0xe7, 0xf3, 0x3e, 0xef, 0xcc, 0xec, 0x03, 0x73, 0x15, + 0x5a, 0xd9, 0xf6, 0xc3, 0xc0, 0x64, 0x51, 0x58, 0xad, 0x79, 0x81, 0x6b, 0x36, 0x97, 0xcc, 0xbb, + 0x0d, 0x16, 0x6f, 0x1b, 0x51, 0x1c, 0x8a, 0x90, 0x4c, 0xab, 0x00, 0x23, 0x0d, 0x30, 0x9a, 0x4b, + 0xa5, 0x83, 0x6e, 0xe8, 0x86, 0xe8, 0x37, 0x93, 0x5f, 0x32, 0xb4, 0x34, 0xe7, 0x86, 0xa1, 0xeb, + 0x33, 0x13, 0xff, 0x55, 0x1a, 0x9b, 0xa6, 0xf0, 0xea, 0x8c, 0x0b, 0x5a, 0x8f, 0x54, 0xc0, 0x51, + 0x15, 0x40, 0x23, 0xcf, 0xa4, 0x41, 0x10, 0x0a, 0x2a, 0xbc, 0x30, 0xe0, 0xca, 0x3b, 0x5f, 0x0d, + 0x79, 0x3d, 0xe4, 0x66, 0x85, 0x72, 0x26, 0x21, 0x98, 0xcd, 0xa5, 0x0a, 0x13, 0x74, 0xc9, 0x8c, + 0xa8, 0xeb, 0x05, 0x18, 0xac, 0x62, 0x8f, 0xe7, 0xc1, 0x8e, 0x68, 0x4c, 0xeb, 0x69, 0x35, 0x3d, + 0x2f, 0xa2, 0x35, 0x03, 0xc6, 0xe8, 0x07, 0x81, 0xdc, 0x4e, 0xfa, 0x6c, 0x60, 0xa2, 0xc5, 0xee, + 0x36, 0x18, 0x17, 0xfa, 0x06, 0x4c, 0x77, 0x58, 0x79, 0x14, 0x06, 0x9c, 0x91, 0x0b, 0x30, 0x2a, + 0x1b, 0xcc, 0x68, 0xc7, 0xb5, 0xd3, 0xe3, 0xe7, 0x66, 0x8d, 0x1c, 0x66, 0x0c, 0x99, 0xb4, 0x5a, + 0x7c, 0xf4, 0xc7, 0xdc, 0x90, 0xa5, 0x12, 0xf4, 0x15, 0x38, 0x84, 0x15, 0xdf, 0x48, 0x02, 0xd7, + 0x83, 0xcd, 0x50, 0xb5, 0x22, 0xb3, 0x30, 0x86, 0xc9, 0x76, 0xd0, 0xa8, 0x63, 0xd9, 0xa2, 0xb5, + 0x0f, 0x0d, 0x6f, 0x37, 0xea, 0xba, 0x05, 0x87, 0xbb, 0xb3, 0x14, 0x94, 0x57, 0x61, 0x04, 0xa3, + 0x14, 0x12, 0x3d, 0x17, 0x09, 0xa6, 0xa5, 0x29, 0x96, 0x4c, 0xd0, 0x3f, 0xc8, 0xd6, 0xe4, 0x59, + 0x28, 0x37, 0x00, 0xda, 0x2c, 0xab, 0xc2, 0x27, 0x0d, 0xb9, 0x12, 0x23, 0x59, 0x89, 0x21, 0x4f, + 0x85, 0x5a, 0x89, 0xb1, 0x41, 0x5d, 0xa6, 0x72, 0xad, 0x4c, 0xa6, 0xfe, 0xad, 0x06, 0xff, 0xdb, + 0xd1, 0x42, 0xe1, 0xbe, 0x08, 0xa3, 0x08, 0x23, 0xa1, 0x70, 0x78, 0x40, 0xe0, 0x2a, 0x83, 0xbc, + 0xd9, 0x81, 0xaf, 0x80, 0xf8, 0x4e, 0xf5, 0xc5, 0xa7, 0x8a, 0x64, 0x01, 0x96, 0x60, 0x06, 0xf1, + 0x5d, 0x6b, 0xc4, 0x31, 0x0b, 0x84, 0xea, 0x26, 0x57, 0xef, 0xc2, 0x91, 0x1c, 0x9f, 0x42, 0x7f, + 0x02, 0x26, 0xaa, 0xd2, 0x6e, 0xb7, 0xd9, 0x2f, 0x5a, 0xfb, 0xab, 0x99, 0x60, 0xf2, 0x22, 0xfc, + 0x57, 0x6e, 0xb4, 0x12, 0x36, 0x02, 0x87, 0xc6, 0xdb, 0x08, 0xb5, 0x68, 0x4d, 0xa0, 0x75, 0x55, + 0x19, 0xf5, 0x8f, 0xb3, 0x27, 0xe2, 0x16, 0x77, 0xf9, 0x20, 0x27, 0xa2, 0x6b, 0x47, 0x85, 0x3d, + 0xef, 0xe8, 0x7b, 0x2d, 0x7b, 0x0c, 0x64, 0x7b, 0x35, 0xe4, 0xeb, 0x50, 0xac, 0x73, 0x37, 0x5d, + 0xd0, 0x7c, 0xee, 0x82, 0x6e, 0x37, 0x58, 0x83, 0x39, 0xb7, 0x18, 0xe7, 0x59, 0x8e, 0x31, 0xef, + 0xf9, 0xad, 0xe9, 0x07, 0x0d, 0x66, 0x11, 0xe3, 0x4d, 0x2a, 0x18, 0x17, 0xb9, 0x44, 0x05, 0x4e, + 0xc7, 0x26, 0xf6, 0xb1, 0xc0, 0x91, 0x5b, 0x98, 0x83, 0x71, 0xc9, 0x62, 0x35, 0x6c, 0x04, 0x42, + 0xad, 0x00, 0xd0, 0x74, 0x2d, 0xb1, 0x74, 0x31, 0x39, 0xbc, 0x67, 0x26, 0x1f, 0x6a, 0x70, 0x34, + 0x1f, 0xa5, 0xe2, 0xd3, 0x82, 0x03, 0x3e, 0xba, 0x24, 0x52, 0x3b, 0x43, 0xee, 0xc9, 0xfe, 0xe4, + 0xde, 0xf4, 0xb8, 0xb0, 0x26, 0xfd, 0xce, 0xda, 0xcf, 0x8f, 0xe3, 0x4b, 0x50, 0x46, 0xf0, 0x77, + 0xa8, 0xef, 0x39, 0x54, 0x84, 0xf1, 0x4d, 0x6f, 0x93, 0x55, 0xb7, 0xab, 0x7e, 0x3a, 0x2b, 0x39, + 0x02, 0xfb, 0x9a, 0xd4, 0xb7, 0xa9, 0xe3, 0xc4, 0x48, 0xf2, 0x98, 0xf5, 0x9f, 0x26, 0xf5, 0xaf, + 0x3a, 0x4e, 0xac, 0x7f, 0xae, 0xc1, 0x5c, 0xcf, 0x6c, 0x35, 0x7d, 0xef, 0x74, 0x72, 0x43, 0xba, + 0x7c, 0x6f, 0x93, 0xcd, 0x14, 0x90, 0x8f, 0x85, 0x5c, 0x3e, 0xee, 0x50, 0xff, 0x1d, 0x41, 0x05, + 0x7b, 0x2f, 0x72, 0xa8, 0x68, 0x8f, 0x91, 0xd4, 0x49, 0xfa, 0xe9, 0x97, 0x15, 0x8a, 0xeb, 0xcc, + 0x67, 0x2e, 0x8e, 0x95, 0x37, 0x84, 0xc3, 0x3a, 0x51, 0x38, 0x4c, 0x0e, 0xe1, 0xc2, 0xf1, 0xde, + 0xd9, 0x6a, 0x88, 0x6b, 0x32, 0x1d, 0x91, 0xca, 0x77, 0xf1, 0x74, 0x2e, 0xd2, 0xbc, 0x1a, 0x49, + 0x23, 0x84, 0xf9, 0x49, 0xf6, 0x55, 0x4c, 0x66, 0x62, 0xe2, 0x5f, 0xbd, 0xf2, 0xbf, 0x6a, 0xea, + 0xd9, 0xeb, 0x00, 0xd0, 0xba, 0xf4, 0xd0, 0x4c, 0x97, 0x98, 0x9e, 0xce, 0x72, 0xaf, 0x6d, 0xc8, + 0x30, 0x2b, 0x93, 0x41, 0xce, 0x00, 0x11, 0xa1, 0xa0, 0xbe, 0xdd, 0x0c, 0x85, 0x17, 0xb8, 0x76, + 0x14, 0x7e, 0xc4, 0x62, 0x04, 0x3b, 0x6c, 0x4d, 0xa1, 0xe7, 0x0e, 0x3a, 0x36, 0x12, 0x7b, 0xd7, + 0xf1, 0x1d, 0xde, 0xfb, 0xf1, 0x7d, 0x58, 0x80, 0x89, 0xce, 0x27, 0xfa, 0xff, 0xb0, 0xbf, 0x45, + 0x65, 0x85, 0xc5, 0x8a, 0xcd, 0xf1, 0x94, 0xcd, 0x0a, 0x8b, 0xc9, 0x0a, 0x1c, 0xee, 0x78, 0xc5, + 0x6d, 0x2f, 0x10, 0x2c, 0x6e, 0x52, 0x5f, 0xbd, 0x12, 0x07, 0xb3, 0xcf, 0xf9, 0xba, 0xf2, 0x25, + 0x13, 0x6e, 0x7a, 0x31, 0x17, 0x76, 0xc5, 0x0f, 0xab, 0x1f, 0xda, 0x35, 0xe6, 0xb9, 0x35, 0x81, + 0xd8, 0x8b, 0xd6, 0x14, 0x7a, 0x56, 0x13, 0xc7, 0x1a, 0xda, 0xc9, 0x1a, 0x4c, 0xfa, 0xb4, 0x15, + 0x9c, 0xa8, 0xa0, 0x99, 0x22, 0x8e, 0x59, 0x32, 0xa4, 0x02, 0x32, 0x52, 0x89, 0x64, 0xbc, 0x9b, + 0x4a, 0xa4, 0xd5, 0xe2, 0x83, 0x3f, 0xe7, 0x34, 0x6b, 0x22, 0x49, 0xc4, 0x5a, 0x89, 0x87, 0x2c, + 0xc2, 0x34, 0x67, 0xd4, 0x67, 0xb1, 0x4d, 0xa3, 0xc8, 0xae, 0x51, 0x5e, 0xb3, 0x6b, 0x6c, 0x6b, + 0x66, 0x04, 0x4f, 0xf1, 0x94, 0x74, 0x5d, 0x8d, 0xa2, 0x35, 0xca, 0x6b, 0x6b, 0x6c, 0x8b, 0xcc, + 0xc3, 0x01, 0x15, 0xae, 0x70, 0x52, 0x5e, 0x9b, 0x19, 0xc5, 0xe0, 0x49, 0xe9, 0x90, 0x30, 0x29, + 0xaf, 0xe9, 0x3f, 0x69, 0xf8, 0x0d, 0xda, 0xf9, 0x92, 0x93, 0x69, 0x18, 0x11, 0x5b, 0xb6, 0xe7, + 0xa8, 0xcb, 0x52, 0x14, 0x5b, 0xeb, 0x0e, 0x39, 0x04, 0xa3, 0x75, 0xee, 0x26, 0xd6, 0x02, 0x5a, + 0x47, 0xea, 0xdc, 0x5d, 0x77, 0x12, 0xc6, 0x73, 0x28, 0x19, 0xaf, 0x64, 0xd8, 0xb8, 0x02, 0xb0, + 0x07, 0x22, 0xc6, 0x2a, 0x2d, 0x12, 0xa6, 0x60, 0xb8, 0xce, 0x5d, 0x35, 0x74, 0xf2, 0x53, 0x6f, + 0xc2, 0x81, 0x1d, 0xef, 0xe4, 0x20, 0xcb, 0x4f, 0xbf, 0x6e, 0x85, 0xbd, 0x7d, 0xdd, 0xf4, 0x6f, + 0x34, 0x38, 0x9c, 0xff, 0x20, 0x91, 0x63, 0x00, 0x3c, 0x31, 0xdb, 0x0e, 0xe3, 0x55, 0xc5, 0xdc, + 0x18, 0x5a, 0xae, 0x33, 0x5e, 0xdd, 0xc1, 0x53, 0xa1, 0x1f, 0x4f, 0xc3, 0xbb, 0xe6, 0xe9, 0xdc, + 0xe3, 0x71, 0x18, 0xc1, 0x3b, 0x4e, 0x3e, 0xd5, 0x60, 0x54, 0x2a, 0x51, 0x72, 0xaa, 0xd7, 0x90, + 0x5d, 0xb2, 0xb7, 0x74, 0xba, 0x7f, 0xa0, 0x1c, 0x55, 0x3f, 0xf1, 0xd9, 0x6f, 0x7f, 0x7f, 0x59, + 0x38, 0x46, 0x66, 0xcd, 0xde, 0x2a, 0x9c, 0x7c, 0xa5, 0xc1, 0x58, 0x4b, 0xb9, 0x92, 0xf9, 0xde, + 0xc5, 0xbb, 0x45, 0x71, 0x69, 0x61, 0xa0, 0x58, 0x85, 0x65, 0x09, 0xb1, 0x2c, 0x90, 0x97, 0xcc, + 0x9e, 0x7a, 0x9f, 0x9b, 0xf7, 0x5a, 0xe7, 0xe2, 0xb5, 0xf9, 0xfb, 0xe4, 0x0b, 0x0d, 0xa0, 0x2d, + 0x4e, 0x49, 0xbf, 0x76, 0x59, 0x95, 0x5c, 0x3a, 0x33, 0x58, 0xf0, 0x40, 0x44, 0x29, 0x61, 0xfb, + 0xb5, 0x06, 0xfb, 0xb3, 0x7a, 0x93, 0x2c, 0xf6, 0xee, 0x91, 0xa3, 0x59, 0x4b, 0xc6, 0xa0, 0xe1, + 0x0a, 0xd4, 0x3c, 0x82, 0x7a, 0x81, 0xe8, 0xb9, 0xa0, 0x3a, 0xde, 0x46, 0xf2, 0x5d, 0xba, 0x44, + 0xd4, 0x1d, 0xfd, 0x96, 0x98, 0x91, 0x67, 0x7d, 0x97, 0x98, 0x15, 0x49, 0xfa, 0x45, 0x84, 0xb4, + 0x42, 0xce, 0x0d, 0xbc, 0x44, 0xb3, 0x2e, 0xef, 0x27, 0x27, 0x3f, 0x6a, 0x30, 0xd9, 0x25, 0xbe, + 0xc8, 0xd9, 0xde, 0xcd, 0xf3, 0xd5, 0x64, 0x69, 0x69, 0x17, 0x19, 0x0a, 0xf4, 0x32, 0x82, 0x5e, + 0x24, 0x0b, 0xcf, 0x00, 0x7d, 0x51, 0x4a, 0xb7, 0x36, 0xda, 0x9f, 0x35, 0x20, 0x3b, 0xf5, 0x12, + 0x59, 0xee, 0xdd, 0xbe, 0xa7, 0x36, 0x2b, 0xad, 0xec, 0x2e, 0x49, 0xc1, 0xbe, 0x84, 0xb0, 0xcf, + 0x93, 0xe5, 0x5c, 0xd8, 0xad, 0x8f, 0x3a, 0xca, 0x1d, 0xcc, 0x34, 0xef, 0xa5, 0x12, 0xee, 0x3e, + 0xf9, 0x45, 0x83, 0xe9, 0x1c, 0x99, 0x43, 0x9e, 0x01, 0xa5, 0xb7, 0x2e, 0x2b, 0x9d, 0xdf, 0x65, + 0x96, 0x9a, 0xe0, 0x32, 0x4e, 0xf0, 0x32, 0x59, 0xc9, 0x9d, 0xc0, 0x69, 0x65, 0x66, 0x47, 0x48, + 0xf5, 0xdf, 0xfd, 0xe4, 0xbc, 0x8c, 0x67, 0x34, 0x10, 0xe9, 0x77, 0xa3, 0x3b, 0xb4, 0x5a, 0x69, + 0x71, 0xc0, 0x68, 0x05, 0xf5, 0x0a, 0x42, 0xbd, 0x40, 0x5e, 0x19, 0xfc, 0x60, 0xb7, 0x37, 0xc0, + 0x99, 0x58, 0x7d, 0xeb, 0xd1, 0x93, 0xb2, 0xf6, 0xf8, 0x49, 0x59, 0xfb, 0xeb, 0x49, 0x59, 0x7b, + 0xf0, 0xb4, 0x3c, 0xf4, 0xf8, 0x69, 0x79, 0xe8, 0xf7, 0xa7, 0xe5, 0xa1, 0xf7, 0xcf, 0xba, 0x9e, + 0xa8, 0x35, 0x2a, 0x46, 0x35, 0xac, 0xa7, 0xc5, 0xab, 0x35, 0xea, 0x05, 0xad, 0x4e, 0x5b, 0xed, + 0x5e, 0x62, 0x3b, 0x62, 0xbc, 0x32, 0x8a, 0xdf, 0x90, 0xe5, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, + 0xad, 0xee, 0x6f, 0xab, 0xf3, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2461,20 +2450,13 @@ func (m *EpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.SealerBlockHash) i = encodeVarintQuery(dAtA, i, uint64(len(m.SealerBlockHash))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x32 } if len(m.SealerAppHashHex) > 0 { i -= len(m.SealerAppHashHex) copy(dAtA[i:], m.SealerAppHashHex) i = encodeVarintQuery(dAtA, i, uint64(len(m.SealerAppHashHex))) i-- - dAtA[i] = 0x32 - } - if len(m.AppHashRootHex) > 0 { - i -= len(m.AppHashRootHex) - copy(dAtA[i:], m.AppHashRootHex) - i = encodeVarintQuery(dAtA, i, uint64(len(m.AppHashRootHex))) - i-- dAtA[i] = 0x2a } if m.LastBlockTime != nil { @@ -2951,10 +2933,6 @@ func (m *EpochResponse) Size() (n int) { l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.LastBlockTime) n += 1 + l + sovQuery(uint64(l)) } - l = len(m.AppHashRootHex) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } l = len(m.SealerAppHashHex) if l > 0 { n += 1 + l + sovQuery(uint64(l)) @@ -4872,38 +4850,6 @@ func (m *EpochResponse) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AppHashRootHex", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AppHashRootHex = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SealerAppHashHex", wireType) } @@ -4935,7 +4881,7 @@ func (m *EpochResponse) Unmarshal(dAtA []byte) error { } m.SealerAppHashHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SealerBlockHash", wireType) } From 893100ef7bf4268ef2602f6a8326208fac55a038 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 21 May 2024 19:20:48 +1000 Subject: [PATCH 086/119] finality: revert to commiting public randomness (#651) --- crypto/eots/eots.go | 13 + crypto/eots/eots_test.go | 4 + crypto/eots/randomness.go | 183 ----- crypto/eots/randomness_bench_test.go | 74 -- crypto/eots/randomness_test.go | 95 --- proto/babylon/btcstaking/v1/btcstaking.proto | 18 +- proto/babylon/btcstaking/v1/query.proto | 13 +- proto/babylon/btcstaking/v1/tx.proto | 3 - proto/babylon/finality/v1/finality.proto | 5 +- proto/babylon/finality/v1/genesis.proto | 12 + proto/babylon/finality/v1/params.proto | 4 + proto/babylon/finality/v1/query.proto | 26 + proto/babylon/finality/v1/tx.proto | 23 + test/e2e/btc_staking_e2e_test.go | 89 +-- .../configurer/chain/commands_btcstaking.go | 38 +- .../configurer/chain/queries_btcstaking.go | 13 + testutil/datagen/btcstaking.go | 42 +- testutil/datagen/finality.go | 48 +- types/btc_schnorr_pub_rand.go | 76 ++ types/btc_schnorr_pub_rand_test.go | 35 + x/btcstaking/client/cli/tx.go | 20 +- x/btcstaking/keeper/grpc_query.go | 2 - x/btcstaking/keeper/incentive_test.go | 3 - x/btcstaking/keeper/keeper_test.go | 41 +- x/btcstaking/keeper/msg_server.go | 23 +- x/btcstaking/keeper/msg_server_test.go | 73 +- x/btcstaking/keeper/power_dist_change_test.go | 9 - .../keeper/voting_power_table_test.go | 9 - x/btcstaking/types/btcstaking.go | 18 - x/btcstaking/types/btcstaking.pb.go | 354 ++------- x/btcstaking/types/msg.go | 3 - x/btcstaking/types/query.go | 2 - x/btcstaking/types/query.pb.go | 348 +++----- x/btcstaking/types/tx.pb.go | 218 ++--- x/finality/client/cli/query.go | 34 + x/finality/client/cli/tx.go | 61 ++ x/finality/keeper/genesis.go | 69 +- x/finality/keeper/genesis_test.go | 22 +- x/finality/keeper/grpc_query.go | 35 + x/finality/keeper/msg_server.go | 65 +- x/finality/keeper/msg_server_test.go | 156 ++-- x/finality/keeper/public_randomness.go | 89 +++ x/finality/keeper/votes_bench_test.go | 20 +- x/finality/types/codec.go | 2 + x/finality/types/finality.go | 14 +- x/finality/types/finality.pb.go | 102 +-- x/finality/types/genesis.pb.go | 385 ++++++++- x/finality/types/genesis_test.go | 4 +- x/finality/types/keys.go | 7 +- x/finality/types/metrics.go | 3 +- x/finality/types/msg.go | 45 +- x/finality/types/msg_test.go | 28 +- x/finality/types/params.go | 16 +- x/finality/types/params.pb.go | 53 +- x/finality/types/query.pb.go | 752 ++++++++++++++++-- x/finality/types/query.pb.gw.go | 119 +++ x/finality/types/tx.pb.go | 617 +++++++++++++- 57 files changed, 3091 insertions(+), 1544 deletions(-) delete mode 100644 crypto/eots/randomness.go delete mode 100644 crypto/eots/randomness_bench_test.go delete mode 100644 crypto/eots/randomness_test.go create mode 100644 types/btc_schnorr_pub_rand.go create mode 100644 types/btc_schnorr_pub_rand_test.go create mode 100644 x/finality/keeper/public_randomness.go diff --git a/crypto/eots/eots.go b/crypto/eots/eots.go index 0459a4b51..932051b46 100644 --- a/crypto/eots/eots.go +++ b/crypto/eots/eots.go @@ -15,6 +15,8 @@ import ( type ModNScalar = btcec.ModNScalar type PrivateKey = secp256k1.PrivateKey type PublicKey = secp256k1.PublicKey +type PrivateRand = secp256k1.ModNScalar +type PublicRand = secp256k1.FieldVal // The Signature is only the S part of the BEP-340 Schnorr signatures. type Signature = ModNScalar @@ -29,6 +31,17 @@ func PubGen(k *PrivateKey) *PublicKey { return k.PubKey() } +// RandGen returns the value to be used as random value when signing, and the associated public value. +func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { + pk, err := KeyGen(randSource) + if err != nil { + return nil, nil, err + } + var j secp256k1.JacobianPoint + pk.PubKey().AsJacobian(&j) + return &pk.Key, &j.X, nil +} + // hash function is used for hashing the message input for all functions of the library. // Wrapper around sha256 in order to change only one function if the input hashing function is changed. func hash(message []byte) [32]byte { diff --git a/crypto/eots/eots_test.go b/crypto/eots/eots_test.go index d41e57156..91865b4d0 100644 --- a/crypto/eots/eots_test.go +++ b/crypto/eots/eots_test.go @@ -13,6 +13,10 @@ import ( "github.com/vulpine-io/io-test/v1/pkg/iotest" ) +// TODO: possible improvements +// test KeyGen, PubGen, RandGen give consistent results with deterministic randomness source +// test compare signatures against btcec + func FuzzSignAndVerify(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) diff --git a/crypto/eots/randomness.go b/crypto/eots/randomness.go deleted file mode 100644 index 5fc105e31..000000000 --- a/crypto/eots/randomness.go +++ /dev/null @@ -1,183 +0,0 @@ -package eots - -import ( - "errors" - "fmt" - "io" - - "github.com/btcsuite/btcd/btcutil/hdkeychain" - "github.com/btcsuite/btcd/chaincfg" - "github.com/decred/dcrd/dcrec/secp256k1/v4" -) - -type MasterSecretRand struct { - k *hdkeychain.ExtendedKey -} -type MasterPublicRand struct { - k *hdkeychain.ExtendedKey -} - -type PrivateRand = secp256k1.ModNScalar -type PublicRand = secp256k1.FieldVal - -// RandGen returns the value to be used as random value when signing, and the associated public value. -func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { - pk, err := KeyGen(randSource) - if err != nil { - return nil, nil, err - } - var j secp256k1.JacobianPoint - pk.PubKey().AsJacobian(&j) - return &pk.Key, &j.X, nil -} - -// NewMasterRandPairFromSeed deterministically generates a pair of -// master/secret randomness from a given seed. -// NOTE: BIP-32 allows to use seed with 16-64 bytes. We used 32 here -// as the seed is typically a 32-byte hash, e.g., finality provider -// uses a hash to derive randomness. -func NewMasterRandPairFromSeed(seed [32]byte) (*MasterSecretRand, *MasterPublicRand, error) { - // generate new master key pair - var ( - masterSK *hdkeychain.ExtendedKey - err error - ) - for { - masterSK, err = hdkeychain.NewMaster(seed[:], &chaincfg.MainNetParams) - // if all good, use this master SK - if err == nil { - break - } - // NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed - // will derive to an unusable secret key. The ErrUnusableSeed error will be - // returned if this should occur. We need to try to generate a new master SK - // again - if errors.Is(err, hdkeychain.ErrUnusableSeed) { - continue - } - // some other unrecoverable error, return error - return nil, nil, err - } - - masterPK, err := masterSK.Neuter() - if err != nil { - return nil, nil, err - } - - return &MasterSecretRand{masterSK}, &MasterPublicRand{masterPK}, nil -} - -// NewMasterRandPair generates a pair of master secret/public randomness -func NewMasterRandPair(randSource io.Reader) (*MasterSecretRand, *MasterPublicRand, error) { - // get random seed - var seed [32]byte - if _, err := io.ReadFull(randSource, seed[:]); err != nil { - return nil, nil, err - } - return NewMasterRandPairFromSeed(seed) -} - -func (msr *MasterSecretRand) Validate() error { - if !msr.k.IsPrivate() { - return fmt.Errorf("underlying key is not a private key") - } - return nil -} - -func NewMasterSecretRandFromBase58(s string) (*MasterSecretRand, error) { - k, err := hdkeychain.NewKeyFromString(s) - if err != nil { - return nil, err - } - if !k.IsPrivate() { - return nil, fmt.Errorf("the given string does not correspond to a secret key") - } - return &MasterSecretRand{k}, nil -} - -func NewMasterSecretRand(b []byte) (*MasterSecretRand, error) { - return NewMasterSecretRandFromBase58(string(b)) -} - -func (msr *MasterSecretRand) MasterPubicRand() (*MasterPublicRand, error) { - masterPK, err := msr.k.Neuter() - if err != nil { - return nil, err - } - return &MasterPublicRand{masterPK}, nil -} - -// TODO: extend to support uint64 -func (msr *MasterSecretRand) DeriveRandPair(height uint32) (*PrivateRand, *PublicRand, error) { - // get child SK, then child SK in BTC format, and finally private randomness - childSK, err := msr.k.Derive(height) - if err != nil { - return nil, nil, err - } - childBTCSK, err := childSK.ECPrivKey() - if err != nil { - return nil, nil, err - } - privRand := &childBTCSK.Key - - // get child PK in BTC format, and then public randomness - childBTCPK := childBTCSK.PubKey() - var j secp256k1.JacobianPoint - childBTCPK.AsJacobian(&j) - pubRand := &j.X - - return privRand, pubRand, nil -} - -func (msr *MasterSecretRand) MarshalBase58() string { - return msr.k.String() -} - -func (msr *MasterSecretRand) Marshal() []byte { - return []byte(msr.MarshalBase58()) -} - -func NewMasterPublicRandFromBase58(s string) (*MasterPublicRand, error) { - k, err := hdkeychain.NewKeyFromString(s) - if err != nil { - return nil, err - } - if k.IsPrivate() { - return nil, fmt.Errorf("the given string does not correspond to a public key") - } - return &MasterPublicRand{k}, nil -} - -func NewMasterPublicRand(b []byte) (*MasterPublicRand, error) { - return NewMasterPublicRandFromBase58(string(b)) -} - -func (mpr *MasterPublicRand) Validate() error { - if mpr.k.IsPrivate() { - return fmt.Errorf("underlying key is not a public key") - } - return nil -} - -func (mpr *MasterPublicRand) DerivePubRand(height uint32) (*PublicRand, error) { - childPK, err := mpr.k.Derive(height) - if err != nil { - return nil, err - } - childBTCPK, err := childPK.ECPubKey() - if err != nil { - return nil, err - } - var j secp256k1.JacobianPoint - childBTCPK.AsJacobian(&j) - pubRand := &j.X - return pubRand, nil -} - -func (mpr *MasterPublicRand) MarshalBase58() string { - return mpr.k.String() -} - -func (mpr *MasterPublicRand) Marshal() []byte { - return []byte(mpr.MarshalBase58()) -} diff --git a/crypto/eots/randomness_bench_test.go b/crypto/eots/randomness_bench_test.go deleted file mode 100644 index 4a6fd0e57..000000000 --- a/crypto/eots/randomness_bench_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package eots_test - -import ( - "math/rand" - "os" - "runtime/pprof" - "testing" - "time" - - "github.com/babylonchain/babylon/crypto/eots" - "github.com/stretchr/testify/require" -) - -func BenchmarkDeriveRandomness(b *testing.B) { - r := rand.New(rand.NewSource(time.Now().Unix())) - - // master randomness pair - msr, mpr, err := eots.NewMasterRandPair(r) - require.NoError(b, err) - require.NoError(b, msr.Validate()) - require.NoError(b, mpr.Validate()) - - // Start the CPU profiler - cpuProfileFile := "/tmp/bench_verify_derive_randomness.pprof" - f, err := os.Create(cpuProfileFile) - if err != nil { - b.Fatal(err) - } - defer f.Close() - if err := pprof.StartCPUProfile(f); err != nil { - b.Fatal(err) - } - defer pprof.StopCPUProfile() - - // Reset timer before the benchmark loop starts - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _, _, err := msr.DeriveRandPair(uint32(i)) - require.NoError(b, err) - } -} - -func BenchmarkUnmarshalMasterPubRand(b *testing.B) { - r := rand.New(rand.NewSource(time.Now().Unix())) - - // master randomness pair - msr, mpr, err := eots.NewMasterRandPair(r) - require.NoError(b, err) - require.NoError(b, msr.Validate()) - require.NoError(b, mpr.Validate()) - - mprStr := mpr.MarshalBase58() - - // Start the CPU profiler - cpuProfileFile := "/tmp/bench_unmarshal_pubrand.pprof" - f, err := os.Create(cpuProfileFile) - if err != nil { - b.Fatal(err) - } - defer f.Close() - if err := pprof.StartCPUProfile(f); err != nil { - b.Fatal(err) - } - defer pprof.StopCPUProfile() - - // Reset timer before the benchmark loop starts - b.ResetTimer() - - for i := 0; i < b.N; i++ { - _, err := eots.NewMasterPublicRandFromBase58(mprStr) - require.NoError(b, err) - } -} diff --git a/crypto/eots/randomness_test.go b/crypto/eots/randomness_test.go deleted file mode 100644 index 11451e979..000000000 --- a/crypto/eots/randomness_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package eots_test - -import ( - "math/rand" - "testing" - - "github.com/babylonchain/babylon/crypto/eots" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/stretchr/testify/require" -) - -func FuzzBIP32RandomnessCodec(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - - // master randomness pair - msr, mpr, err := eots.NewMasterRandPair(r) - require.NoError(t, err) - require.NoError(t, msr.Validate()) - require.NoError(t, mpr.Validate()) - - // roundtrip of marshaling/unmarshaling msr to/from string - msrStr := msr.MarshalBase58() - msr2, err := eots.NewMasterSecretRandFromBase58(msrStr) - require.NoError(t, err) - require.Equal(t, msr.Marshal(), msr2.Marshal()) - - // roundtrip of marshaling/unmarshaling msr to/from bytes - msrBytes := msr.Marshal() - msr2, err = eots.NewMasterSecretRand(msrBytes) - require.NoError(t, err) - require.Equal(t, msr.Marshal(), msr2.Marshal()) - - // roundtrip of marshaling/unmarshaling mpr to/from string - mprStr := mpr.MarshalBase58() - mpr2, err := eots.NewMasterPublicRandFromBase58(mprStr) - require.NoError(t, err) - require.Equal(t, mpr.Marshal(), mpr2.Marshal()) - - // roundtrip of marshaling/unmarshaling mpr to/from bytes - mprBytes := mpr.Marshal() - mpr2, err = eots.NewMasterPublicRand(mprBytes) - require.NoError(t, err) - require.Equal(t, mpr.Marshal(), mpr2.Marshal()) - }) -} - -func FuzzBIP32RandomnessDerivation(f *testing.F) { - datagen.AddRandomSeedsToFuzzer(f, 10) - - f.Fuzz(func(t *testing.T, seed int64) { - r := rand.New(rand.NewSource(seed)) - - // EOTS key pair - sk, err := eots.KeyGen(r) - require.NoError(t, err) - pk := eots.PubGen(sk) - - // master randomness pair - msr, mpr, err := eots.NewMasterRandPair(r) - require.NoError(t, err) - require.NoError(t, msr.Validate()) - require.NoError(t, mpr.Validate()) - - // ensure msr can derive mpr - mpr2, err := msr.MasterPubicRand() - require.NoError(t, err) - require.NoError(t, mpr2.Validate()) - require.Equal(t, mpr, mpr2) - - height := uint32(datagen.RandomInt(r, 10000)) - - // derive pair of randomness via master secret randomness at this height - sr, pr, err := msr.DeriveRandPair(height) - require.NoError(t, err) - - // derive public randomness via master public randomness at this height - pr2, err := mpr.DerivePubRand(height) - require.NoError(t, err) - - // assert consistency of public randomness - require.Equal(t, pr, pr2) - - // sign EOTS using secret randomness - msg := datagen.GenRandomByteArray(r, 100) - sig, err := eots.Sign(sk, sr, msg) - require.NoError(t, err) - - // verify EOTS sig using public key - err = eots.Verify(pk, pr, msg, sig) - require.NoError(t, err) - }) -} diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 7987bd5cf..9f9778a5c 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -25,19 +25,14 @@ message FinalityProvider { bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 6; - // registered_epoch is the epoch when this finality provider is registered - uint64 registered_epoch = 7; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 8; + uint64 slashed_babylon_height = 6; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 9; + uint64 slashed_btc_height = 7; } // FinalityProviderWithMeta wraps the FinalityProvider with metadata. @@ -49,19 +44,14 @@ message FinalityProviderWithMeta { uint64 height = 2; // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 3; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 4; - // registered_epoch is the epoch when this finality provider is registered - uint64 registered_epoch = 5; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 6; + uint64 slashed_babylon_height = 4; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 7; + uint64 slashed_btc_height = 5; } // BTCDelegation defines a BTC delegation diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index badd43ee0..e3f385b57 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -335,21 +335,16 @@ message FinalityProviderResponse { bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 5; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 6; - // registered_epoch is the epoch when this finality provider is registered - uint64 registered_epoch = 7; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 8; + uint64 slashed_babylon_height = 6; // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 9; + uint64 slashed_btc_height = 7; // height is the queried Babylon height - uint64 height = 10; + uint64 height = 8; // voting_power is the voting power of this finality provider at the given height - uint64 voting_power = 11; + uint64 voting_power = 9; } diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index e27d90f72..8d2d5a642 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -54,9 +54,6 @@ message MsgCreateFinalityProvider { bytes btc_pk = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossession pop = 6; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 7; } // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider message MsgCreateFinalityProviderResponse {} diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index 9e9ddce16..5f2a3d159 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -23,9 +23,8 @@ message Evidence { bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // block_height is the height of the conflicting blocks uint64 block_height = 2; - // master_pub_rand is the master public randomness the finality provider has committed to - // encoded as a base58 string - string master_pub_rand = 3; + // pub_rand is the public randomness the finality provider has committed to + bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; // canonical_app_hash is the AppHash of the canonical block bytes canonical_app_hash = 4; // fork_app_hash is the AppHash of the fork block diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index 40f43fb0a..7c1b4c62f 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -17,6 +17,8 @@ message GenesisState { repeated Evidence evidences = 3; // votes_sigs contains all the votes of finality providers ever registered. repeated VoteSig vote_sigs = 4; + // public_randomness contains all the public randomness ever commited from the finality providers. + repeated PublicRandomness public_randomness = 5; } // VoteSig the vote of an finality provider @@ -30,3 +32,13 @@ message VoteSig { // where finality signature is an EOTS signature, i.e. bytes finality_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; } + +// PublicRandomness the block height and public randomness that the finality provider has submitted. +message PublicRandomness { + // block_height is the height of block which the finality provider submited public randomness. + uint64 block_height = 1; + // fp_btc_pk is the BTC PK of the finality provider that casts this vote. + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pub_rand is the public randomness the finality provider has committed to. + bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; +} \ No newline at end of file diff --git a/proto/babylon/finality/v1/params.proto b/proto/babylon/finality/v1/params.proto index d317ece41..c5dce2cc9 100644 --- a/proto/babylon/finality/v1/params.proto +++ b/proto/babylon/finality/v1/params.proto @@ -8,4 +8,8 @@ option go_package = "github.com/babylonchain/babylon/x/finality/types"; // Params defines the parameters for the module. message Params { option (gogoproto.goproto_stringer) = false; + + // min_pub_rand is the minimum number of public randomness each + // message should commit + uint64 min_pub_rand = 1; } diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index eade35577..47938c2bf 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -16,6 +16,11 @@ service Query { option (google.api.http).get = "/babylon/finality/v1/params"; } + // ListPublicRandomness is a range query for public randomness of a given finality provider + rpc ListPublicRandomness(QueryListPublicRandomnessRequest) returns (QueryListPublicRandomnessResponse) { + option (google.api.http).get = "/babylon/finality/v1/finality_providers/{fp_btc_pk_hex}/public_randomness_list"; + } + // Block queries a block at a given height rpc Block(QueryBlockRequest) returns (QueryBlockResponse) { option (google.api.http).get = "/babylon/finality/v1/blocks/{height}"; @@ -51,6 +56,27 @@ message QueryParamsResponse { Params params = 1 [(gogoproto.nullable) = false]; } +// QueryListPublicRandomnessRequest is the request type for the +// Query/ListPublicRandomness RPC method. +message QueryListPublicRandomnessRequest { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider + string fp_btc_pk_hex = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryListPublicRandomnessResponse is the response type for the +// Query/ListPublicRandomness RPC method. +message QueryListPublicRandomnessResponse { + // pub_rand_map is the map where the key is the height and the value + // is the public randomness at this height for the given finality provider + map pub_rand_map = 1 [(gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + // QueriedBlockStatus is the status of blocks that the querier wants to query. enum QueriedBlockStatus { // NON_FINALIZED means the block is not finalised diff --git a/proto/babylon/finality/v1/tx.proto b/proto/babylon/finality/v1/tx.proto index 2965ab511..5059e91ac 100644 --- a/proto/babylon/finality/v1/tx.proto +++ b/proto/babylon/finality/v1/tx.proto @@ -12,6 +12,8 @@ import "babylon/finality/v1/params.proto"; service Msg { option (cosmos.msg.v1.service) = true; + // CommitPubRandList commits a list of public randomness for EOTS + rpc CommitPubRandList(MsgCommitPubRandList) returns (MsgCommitPubRandListResponse); // AddFinalitySig adds a finality signature to a given block rpc AddFinalitySig(MsgAddFinalitySig) returns (MsgAddFinalitySigResponse); // TODO: msg for evidence of equivocation. this is not specified yet @@ -19,6 +21,27 @@ service Msg { rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); } +// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS +message MsgCommitPubRandList { + option (cosmos.msg.v1.signer) = "signer"; + + string signer = 1; + // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // start_height is the start block height of the list of public randomness + uint64 start_height = 3; + // pub_rand_list is the list of public randomness + repeated bytes pub_rand_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + // sig is the signature on (start_height || pub_rand_list) signed by + // SK corresponding to fp_btc_pk. This prevents others to commit public + // randomness on behalf of fp_btc_pk + // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts + // the tx submitter to be the holder of fp_btc_pk. Decide this later + bytes sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; +} +// MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message +message MsgCommitPubRandListResponse{} + // MsgAddFinalitySig defines a message for adding a finality vote message MsgAddFinalitySig { option (cosmos.msg.v1.signer) = "signer"; diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 27f3bb29c..04aa36010 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -22,7 +22,6 @@ import ( bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" ftypes "github.com/babylonchain/babylon/x/finality/types" itypes "github.com/babylonchain/babylon/x/incentive/types" ) @@ -33,7 +32,6 @@ var ( // finality provider fpBTCSK, _, _ = datagen.GenRandomBTCKeyPair(r) fp *bstypes.FinalityProvider - msr *eots.MasterSecretRand // BTC delegation delBTCSK, delBTCPK, _ = datagen.GenRandomBTCKeyPair(r) // covenant @@ -81,11 +79,9 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { create a random finality provider on Babylon */ // NOTE: we use the node's secret key as Babylon secret key for the finality provider - msr, _, err = eots.NewMasterRandPair(r) + fp, err = datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, nonValidatorNode.SecretKey) s.NoError(err) - fp, err = datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, nonValidatorNode.SecretKey, msr) - s.NoError(err) - nonValidatorNode.CreateFinalityProvider(fp.BabylonPk, fp.BtcPk, fp.Pop, fp.MasterPubRand, fp.Description.Moniker, fp.Description.Identity, fp.Description.Website, fp.Description.SecurityContact, fp.Description.Details, fp.Commission) + nonValidatorNode.CreateFinalityProvider(fp.BabylonPk, fp.BtcPk, fp.Pop, fp.Description.Moniker, fp.Description.Identity, fp.Description.Website, fp.Description.SecurityContact, fp.Description.Details, fp.Commission) // wait for a block so that above txs take effect nonValidatorNode.WaitForNextBlock() @@ -93,7 +89,6 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { // query the existence of finality provider and assert equivalence actualFps := nonValidatorNode.QueryFinalityProviders() s.Len(actualFps, 1) - fp.RegisteredEpoch = actualFps[0].RegisteredEpoch // remember registered epoch s.equalFinalityProviderResp(fp, actualFps[0]) /* @@ -180,23 +175,6 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) s.NoError(err) - // finalise epochs until the registered epoch of the finality provider - // so that the finality provider can receive BTC delegations - var ( - startEpoch = uint64(1) - endEpoch = fp.RegisteredEpoch - ) - // wait until the end epoch is sealed - s.Eventually(func() bool { - resp, err := nonValidatorNode.QueryRawCheckpoint(endEpoch) - if err != nil { - return false - } - return resp.Status == ckpttypes.Sealed - }, time.Minute, time.Second*5) - // finalise these epochs - nonValidatorNode.FinalizeSealedEpochs(startEpoch, endEpoch) - // submit the message for creating BTC delegation nonValidatorNode.CreateBTCDelegation( delBabylonSK.PubKey().(*secp256k1.PubKey), @@ -352,9 +330,10 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { s.Equal(activeFps[0].VotingPower, activeDel.VotingPower(currentBtcTip.Height, initialization.BabylonBtcFinalizationPeriod, params.CovenantQuorum)) } -// Test3SubmitFinalitySignature is an end-to-end test for user story 3: -// finality provider and submits finality signature, such that blocks can be finalised. -func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { +// Test2CommitPublicRandomnessAndSubmitFinalitySignature is an end-to-end +// test for user story 3: finality provider commits public randomness and submits +// finality signature, such that blocks can be finalised. +func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignature() { chainA := s.configurer.GetChainConfig(0) chainA.WaitUntilHeight(1) nonValidatorNode, err := chainA.GetNodeAtIndex(2) @@ -364,38 +343,49 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { activatedHeight := nonValidatorNode.QueryActivatedHeight() s.Positive(activatedHeight) - // no reward gauge for finality provider yet - fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - fpRewardGauges, err := nonValidatorNode.QueryRewardGauge(fpBabylonAddr) - s.NoError(err) - _, ok := fpRewardGauges[itypes.FinalityProviderType.String()] - s.False(ok) + /* + commit a number of public randomness since activatedHeight + */ + // commit public randomness list + srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, activatedHeight, 100) + s.NoError(err) + nonValidatorNode.CommitPubRandList( + msgCommitPubRandList.FpBtcPk, + msgCommitPubRandList.StartHeight, + msgCommitPubRandList.PubRandList, + msgCommitPubRandList.Sig, + ) + + // ensure public randomness list is eventually committed + nonValidatorNode.WaitForNextBlock() + var pubRandMap map[uint64]*bbn.SchnorrPubRand + s.Eventually(func() bool { + pubRandMap = nonValidatorNode.QueryListPublicRandomness(fp.BtcPk) + return len(pubRandMap) > 0 + }, time.Minute, time.Second*5) + s.Equal(pubRandMap[activatedHeight].MustMarshal(), msgCommitPubRandList.PubRandList[0].MustMarshal()) - // no reward gauge for BTC delegator yet + // no reward gauge for finality provider and delegation yet + fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) + _, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) + s.Error(err) delBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) - btcDelRewardGauges, err := nonValidatorNode.QueryRewardGauge(delBabylonAddr) - s.NoError(err) - _, ok = btcDelRewardGauges[itypes.BTCDelegationType.String()] - s.False(ok) + _, err = nonValidatorNode.QueryRewardGauge(delBabylonAddr) + s.Error(err) /* - generate finality signature + submit finality signature */ // get block to vote blockToVote, err := nonValidatorNode.QueryBlock(int64(activatedHeight)) s.NoError(err) appHash := blockToVote.AppHash + msgToSign := append(sdk.Uint64ToBigEndian(activatedHeight), appHash...) // generate EOTS signature - sr, _, err := msr.DeriveRandPair(uint32(activatedHeight)) - s.NoError(err) - sig, err := eots.Sign(fpBTCSK, sr, msgToSign) + sig, err := eots.Sign(fpBTCSK, srList[0], msgToSign) s.NoError(err) eotsSig := bbn.NewSchnorrEOTSSigFromModNScalar(sig) - - /* - submit finality signature - */ // submit finality signature nonValidatorNode.AddFinalitySig(fp.BtcPk, activatedHeight, appHash, eotsSig) @@ -417,14 +407,13 @@ func (s *BTCStakingTestSuite) Test3SubmitFinalitySignature() { s.Equal(appHash.Bytes(), finalizedBlocks[0].AppHash) // ensure finality provider has received rewards after the block is finalised - fpRewardGauges, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr) + fpRewardGauges, err := nonValidatorNode.QueryRewardGauge(fpBabylonAddr) s.NoError(err) fpRewardGauge, ok := fpRewardGauges[itypes.FinalityProviderType.String()] s.True(ok) s.True(fpRewardGauge.Coins.IsAllPositive()) - // ensure BTC delegation has received rewards after the block is finalised - btcDelRewardGauges, err = nonValidatorNode.QueryRewardGauge(delBabylonAddr) + btcDelRewardGauges, err := nonValidatorNode.QueryRewardGauge(delBabylonAddr) s.NoError(err) btcDelRewardGauge, ok := btcDelRewardGauges[itypes.BTCDelegationType.String()] s.True(ok) @@ -631,8 +620,6 @@ func (s *BTCStakingTestSuite) equalFinalityProviderResp(fp *bstypes.FinalityProv s.Equal(fp.BabylonPk, fpResp.BabylonPk) s.Equal(fp.BtcPk, fpResp.BtcPk) s.Equal(fp.Pop, fpResp.Pop) - s.Equal(fp.MasterPubRand, fpResp.MasterPubRand) - s.Equal(fp.RegisteredEpoch, fpResp.RegisteredEpoch) s.Equal(fp.SlashedBabylonHeight, fpResp.SlashedBabylonHeight) s.Equal(fp.SlashedBtcHeight, fpResp.SlashedBtcHeight) } diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index ab1f9267f..7397af143 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -20,7 +20,7 @@ import ( bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) -func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossession, masterPubRand string, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { +func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossession, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { n.LogActionF("creating finality provider") // get babylon PK hex @@ -34,7 +34,7 @@ func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK * require.NoError(n.t, err) cmd := []string{ - "babylond", "tx", "btcstaking", "create-finality-provider", babylonPKHex, btcPKHex, popHex, masterPubRand, "--from=val", "--moniker", moniker, "--identity", identity, "--website", website, "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), + "babylond", "tx", "btcstaking", "create-finality-provider", babylonPKHex, btcPKHex, popHex, "--from=val", "--moniker", moniker, "--identity", identity, "--website", website, "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), } _, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) @@ -133,6 +133,40 @@ func (n *NodeConfig) AddCovenantSigs(covPK *bbn.BIP340PubKey, stakingTxHash stri n.LogActionF("successfully added covenant signatures") } +func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight uint64, pubRandList []bbn.SchnorrPubRand, sig *bbn.BIP340Signature) { + n.LogActionF("committing public randomness list") + + cmd := []string{"babylond", "tx", "finality", "commit-pubrand-list"} + + // add finality provider BTC PK to cmd + fpBTCPKHex := fpBTCPK.MarshalHex() + cmd = append(cmd, fpBTCPKHex) + + // add start height to cmd + startHeightStr := strconv.FormatUint(startHeight, 10) + cmd = append(cmd, startHeightStr) + + // add each pubrand to cmd + for _, pr := range pubRandList { + prHex := pr.ToHexStr() + cmd = append(cmd, prHex) + } + + // add sig to cmd + sigHex := sig.ToHexStr() + cmd = append(cmd, sigHex) + + // specify used key + cmd = append(cmd, "--from=val") + + // gas + cmd = append(cmd, "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3") + + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) + require.NoError(n.t, err) + n.LogActionF("successfully committed public randomness list") +} + func (n *NodeConfig) AddFinalitySig(fpBTCPK *bbn.BIP340PubKey, blockHeight uint64, blockLch []byte, finalitySig *bbn.SchnorrEOTSSig) { n.LogActionF("add finality signature") diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index c71640f64..a4153050d 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -93,6 +93,19 @@ func (n *NodeConfig) QueryActivatedHeight() uint64 { return resp.Height } +// TODO: pagination support +func (n *NodeConfig) QueryListPublicRandomness(fpBTCPK *bbn.BIP340PubKey) map[uint64]*bbn.SchnorrPubRand { + path := fmt.Sprintf("/babylon/finality/v1/finality_providers/%s/public_randomness_list", fpBTCPK.MarshalHex()) + bz, err := n.QueryGRPCGateway(path, url.Values{}) + require.NoError(n.t, err) + + var resp ftypes.QueryListPublicRandomnessResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + require.NoError(n.t, err) + + return resp.PubRandMap +} + func (n *NodeConfig) QueryVotesAtHeight(height uint64) []bbn.BIP340PubKey { path := fmt.Sprintf("/babylon/finality/v1/votes/%d", height) bz, err := n.QueryGRPCGateway(path, url.Values{}) diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 656d731c1..382df22cc 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -18,7 +18,6 @@ import ( "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/btcstaking" - "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) @@ -29,22 +28,12 @@ const ( ) func GenRandomFinalityProvider(r *rand.Rand) (*bstypes.FinalityProvider, error) { - // BTC key pairs + // key pairs btcSK, _, err := GenRandomBTCKeyPair(r) if err != nil { return nil, err } - // Babylon key pairs - bbnSK, _, err := GenRandomSecp256k1KeyPair(r) - if err != nil { - return nil, err - } - // master secret randomness - msr, _, err := eots.NewMasterRandPair(r) - if err != nil { - return nil, err - } - return GenRandomCustomFinalityProvider(r, btcSK, bbnSK, msr) + return GenRandomFinalityProviderWithBTCSK(r, btcSK) } func CreateNFinalityProviders(r *rand.Rand, t *testing.T, n int) []*bstypes.FinalityProvider { @@ -57,6 +46,14 @@ func CreateNFinalityProviders(r *rand.Rand, t *testing.T, n int) []*bstypes.Fina return fps } +func GenRandomFinalityProviderWithBTCSK(r *rand.Rand, btcSK *btcec.PrivateKey) (*bstypes.FinalityProvider, error) { + bbnSK, _, err := GenRandomSecp256k1KeyPair(r) + if err != nil { + return nil, err + } + return GenRandomFinalityProviderWithBTCBabylonSKs(r, btcSK, bbnSK) +} + func GenRandomCommission(r *rand.Rand) sdkmath.LegacyDec { return sdkmath.LegacyNewDecWithPrec(int64(RandomInt(r, 49)+1), 2) // [1/100, 50/100] } @@ -65,7 +62,7 @@ func GenRandomDescription(r *rand.Rand) *stakingtypes.Description { return &stakingtypes.Description{Moniker: GenRandomHexStr(r, 10)} } -func GenRandomCustomFinalityProvider(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey, msr *eots.MasterSecretRand) (*bstypes.FinalityProvider, error) { +func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey) (*bstypes.FinalityProvider, error) { // commission commission := GenRandomCommission(r) // description @@ -83,19 +80,12 @@ func GenRandomCustomFinalityProvider(r *rand.Rand, btcSK *btcec.PrivateKey, bbnS if err != nil { return nil, err } - // master pub rand - mpr, err := msr.MasterPubicRand() - if err != nil { - return nil, err - } - return &bstypes.FinalityProvider{ - Description: description, - Commission: &commission, - BabylonPk: secp256k1PK, - BtcPk: bip340PK, - Pop: pop, - MasterPubRand: mpr.MarshalBase58(), + Description: description, + Commission: &commission, + BabylonPk: secp256k1PK, + BtcPk: bip340PK, + Pop: pop, }, nil } diff --git a/testutil/datagen/finality.go b/testutil/datagen/finality.go index 8b5048b1f..73eae543b 100644 --- a/testutil/datagen/finality.go +++ b/testutil/datagen/finality.go @@ -7,17 +7,53 @@ import ( bbn "github.com/babylonchain/babylon/types" ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/schnorr" sdk "github.com/cosmos/cosmos-sdk/types" ) +func GenRandomPubRandList(r *rand.Rand, numPubRand uint64) ([]*eots.PrivateRand, []bbn.SchnorrPubRand, error) { + srList := []*eots.PrivateRand{} + prList := []bbn.SchnorrPubRand{} + for i := uint64(0); i < numPubRand; i++ { + eotsSR, eotsPR, err := eots.RandGen(r) + if err != nil { + return nil, nil, err + } + pr := bbn.NewSchnorrPubRandFromFieldVal(eotsPR) + srList = append(srList, eotsSR) + prList = append(prList, *pr) + } + return srList, prList, nil +} + +func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeight uint64, numPubRand uint64) ([]*eots.PrivateRand, *ftypes.MsgCommitPubRandList, error) { + srList, prList, err := GenRandomPubRandList(r, numPubRand) + if err != nil { + return nil, nil, err + } + + msg := &ftypes.MsgCommitPubRandList{ + Signer: GenRandomAccount().Address, + FpBtcPk: bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()), + StartHeight: startHeight, + PubRandList: prList, + } + hash, err := msg.HashToSign() + if err != nil { + return nil, nil, err + } + schnorrSig, err := schnorr.Sign(sk, hash) + if err != nil { + return nil, nil, err + } + msg.Sig = bbn.NewBIP340SignatureFromBTCSig(schnorrSig) + return srList, msg, nil +} + func GenRandomEvidence(r *rand.Rand, sk *btcec.PrivateKey, height uint64) (*ftypes.Evidence, error) { pk := sk.PubKey() bip340PK := bbn.NewBIP340PubKeyFromBTCPK(pk) - msr, mpr, err := eots.NewMasterRandPair(r) - if err != nil { - return nil, err - } - sr, _, err := msr.DeriveRandPair(uint32(height)) + sr, pr, err := eots.RandGen(r) if err != nil { return nil, err } @@ -35,7 +71,7 @@ func GenRandomEvidence(r *rand.Rand, sk *btcec.PrivateKey, height uint64) (*ftyp evidence := &ftypes.Evidence{ FpBtcPk: bip340PK, BlockHeight: height, - MasterPubRand: mpr.MarshalBase58(), + PubRand: bbn.NewSchnorrPubRandFromFieldVal(pr), CanonicalAppHash: cAppHash, ForkAppHash: fAppHash, CanonicalFinalitySig: bbn.NewSchnorrEOTSSigFromModNScalar(cSig), diff --git a/types/btc_schnorr_pub_rand.go b/types/btc_schnorr_pub_rand.go new file mode 100644 index 000000000..be92231d2 --- /dev/null +++ b/types/btc_schnorr_pub_rand.go @@ -0,0 +1,76 @@ +package types + +import ( + "encoding/hex" + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" +) + +type SchnorrPubRand []byte + +const SchnorrPubRandLen = 32 + +func NewSchnorrPubRand(data []byte) (*SchnorrPubRand, error) { + var pr SchnorrPubRand + err := pr.Unmarshal(data) + return &pr, err +} + +func NewSchnorrPubRandFromHex(prHex string) (*SchnorrPubRand, error) { + prBytes, err := hex.DecodeString(prHex) + if err != nil { + return nil, err + } + return NewSchnorrPubRand(prBytes) +} + +func NewSchnorrPubRandFromFieldVal(r *btcec.FieldVal) *SchnorrPubRand { + prBytes := r.Bytes() + pr := SchnorrPubRand(prBytes[:]) + return &pr +} + +func (pr SchnorrPubRand) ToFieldVal() *btcec.FieldVal { + var r btcec.FieldVal + r.SetByteSlice(pr) + return &r +} + +func (pr SchnorrPubRand) Size() int { + return len(pr.MustMarshal()) +} + +func (pr SchnorrPubRand) Marshal() ([]byte, error) { + return pr, nil +} + +func (pr SchnorrPubRand) MustMarshal() []byte { + prBytes, err := pr.Marshal() + if err != nil { + panic(err) + } + return prBytes +} + +func (pr SchnorrPubRand) MarshalTo(data []byte) (int, error) { + bz, err := pr.Marshal() + if err != nil { + return 0, err + } + copy(data, bz) + return len(data), nil +} + +func (pr *SchnorrPubRand) Unmarshal(data []byte) error { + if len(data) != SchnorrPubRandLen { + return fmt.Errorf("invalid data length") + } + *pr = data + return nil +} + +func (pr *SchnorrPubRand) ToHexStr() string { + prBytes := pr.MustMarshal() + return hex.EncodeToString(prBytes) +} diff --git a/types/btc_schnorr_pub_rand_test.go b/types/btc_schnorr_pub_rand_test.go new file mode 100644 index 000000000..06e22387e --- /dev/null +++ b/types/btc_schnorr_pub_rand_test.go @@ -0,0 +1,35 @@ +package types_test + +import ( + "math/rand" + "testing" + + "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonchain/babylon/types" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/stretchr/testify/require" +) + +func FuzzSchnorrPubRand(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + randBytes := datagen.GenRandomByteArray(r, 32) + var fieldVal btcec.FieldVal + fieldVal.SetByteSlice(randBytes) + + // FieldVal -> SchnorrPubRand -> FieldVal + pubRand := types.NewSchnorrPubRandFromFieldVal(&fieldVal) + fieldVal2 := pubRand.ToFieldVal() + require.True(t, fieldVal.Equals(fieldVal2)) + + // SchnorrPubRand -> bytes -> SchnorrPubRand + randBytes2 := pubRand.MustMarshal() + pubRand2, err := types.NewSchnorrPubRand(randBytes) + require.NoError(t, err) + require.Equal(t, randBytes, randBytes2) + require.Equal(t, pubRand, pubRand2) + }) +} diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 3ab7e7a36..9f0942dc0 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -52,8 +52,8 @@ func GetTxCmd() *cobra.Command { func NewCreateFinalityProviderCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-finality-provider [babylon_pk] [btc_pk] [pop] [master_pub_rand]", - Args: cobra.ExactArgs(4), + Use: "create-finality-provider [babylon_pk] [btc_pk] [pop]", + Args: cobra.ExactArgs(3), Short: "Create a finality provider", Long: strings.TrimSpace( `Create a finality provider.`, // TODO: example @@ -108,17 +108,13 @@ func NewCreateFinalityProviderCmd() *cobra.Command { return err } - // get master public randomness in base58 string - mpr := args[3] - msg := types.MsgCreateFinalityProvider{ - Signer: clientCtx.FromAddress.String(), - Description: &description, - Commission: &rate, - BabylonPk: &babylonPK, - BtcPk: btcPK, - Pop: pop, - MasterPubRand: mpr, + Signer: clientCtx.FromAddress.String(), + Description: &description, + Commission: &rate, + BabylonPk: &babylonPK, + BtcPk: btcPK, + Pop: pop, } return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index 5790c9ad0..f687cdb36 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -189,10 +189,8 @@ func (k Keeper) ActiveFinalityProvidersAtHeight(ctx context.Context, req *types. BtcPk: finalityProvider.BtcPk, Height: req.Height, VotingPower: votingPower, - MasterPubRand: finalityProvider.MasterPubRand, SlashedBabylonHeight: finalityProvider.SlashedBabylonHeight, SlashedBtcHeight: finalityProvider.SlashedBtcHeight, - RegisteredEpoch: finalityProvider.RegisteredEpoch, } finalityProvidersWithMeta = append(finalityProvidersWithMeta, &finalityProviderWithMeta) } diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 24337ff97..7adac41a6 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -42,9 +42,6 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { } } - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() - // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations and add covenant signatures to activate them numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index e53a1657e..6a2a5229e 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -6,7 +6,6 @@ import ( "cosmossdk.io/core/header" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -14,7 +13,6 @@ import ( btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" @@ -111,14 +109,9 @@ func (h *Helper) GenAndApplyCustomParams( } func CreateFinalityProvider(r *rand.Rand, t *testing.T) *types.FinalityProvider { - fpBTCSK, _, err := datagen.GenRandomBTCKeyPair(r) + fpSK, _, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) - msr, _, err := eots.NewMasterRandPair(r) - require.NoError(t, err) - - fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBBNSK, msr) + fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, fpSK) require.NoError(t, err) return &types.FinalityProvider{ @@ -131,34 +124,22 @@ func CreateFinalityProvider(r *rand.Rand, t *testing.T) *types.FinalityProvider } func (h *Helper) CreateFinalityProvider(r *rand.Rand) (*btcec.PrivateKey, *btcec.PublicKey, *types.FinalityProvider) { - fpBTCSK, fpBTCPK, err := datagen.GenRandomBTCKeyPair(r) - h.NoError(err) - fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) + fpSK, fpPK, err := datagen.GenRandomBTCKeyPair(r) h.NoError(err) - msr, _, err := eots.NewMasterRandPair(r) + fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, fpSK) h.NoError(err) - - fp, err := datagen.GenRandomCustomFinalityProvider(r, fpBTCSK, fpBBNSK, msr) - h.NoError(err) - - registeredEpoch := uint64(10) - fp.RegisteredEpoch = registeredEpoch - - h.CheckpointingKeeper.EXPECT().GetEpoch(gomock.Eq(h.Ctx)).Return(&etypes.Epoch{EpochNumber: registeredEpoch}).Times(1) - msgNewFp := types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp.Description, - Commission: fp.Commission, - BabylonPk: fp.BabylonPk, - BtcPk: fp.BtcPk, - Pop: fp.Pop, - MasterPubRand: fp.MasterPubRand, + Signer: datagen.GenRandomAccount().Address, + Description: fp.Description, + Commission: fp.Commission, + BabylonPk: fp.BabylonPk, + BtcPk: fp.BtcPk, + Pop: fp.Pop, } _, err = h.MsgServer.CreateFinalityProvider(h.Ctx, &msgNewFp) h.NoError(err) - return fpBTCSK, fpBTCPK, fp + return fpSK, fpPK, fp } func (h *Helper) CreateDelegationCustom( diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 5b79883be..1ba83c259 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -8,7 +8,6 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/btcstaking" - "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" @@ -81,20 +80,13 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return nil, types.ErrFpRegistered } - // ensure the master public randomness is valid - if _, err := eots.NewMasterPublicRandFromBase58(req.MasterPubRand); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "%v", err) - } - // all good, add this finality provider fp := types.FinalityProvider{ - Description: req.Description, - Commission: req.Commission, - BabylonPk: req.BabylonPk, - BtcPk: req.BtcPk, - Pop: req.Pop, - MasterPubRand: req.MasterPubRand, - RegisteredEpoch: ms.ckptKeeper.GetEpoch(ctx).EpochNumber, + Description: req.Description, + Commission: req.Commission, + BabylonPk: req.BabylonPk, + BtcPk: req.BtcPk, + Pop: req.Pop, } ms.SetFinalityProvider(ctx, &fp) @@ -194,7 +186,6 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre // Ensure all finality providers are known to Babylon, are not slashed, // and their registered epochs are finalised - lastFinalizedEpoch := ms.GetLastFinalizedEpoch(ctx) for _, fpBTCPK := range req.FpBtcPkList { // get this finality provider fp, err := ms.GetFinalityProvider(ctx, fpBTCPK) @@ -205,10 +196,6 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre if fp.IsSlashed() { return nil, types.ErrFpAlreadySlashed } - // ensure the finality provider's registered epoch is finalised - if lastFinalizedEpoch < fp.RegisteredEpoch { - return nil, types.ErrFpNotBTCTimestamped - } } // Parse staking tx diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index e41ee0d59..d2324d789 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -25,7 +25,6 @@ import ( btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" ) func FuzzMsgCreateFinalityProvider(f *testing.F) { @@ -50,17 +49,13 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { for i := 0; i < int(datagen.RandomInt(r, 10)); i++ { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) - - h.CheckpointingKeeper.EXPECT().GetEpoch(gomock.Eq(h.Ctx)).Return(&etypes.Epoch{EpochNumber: 10}).Times(1) - msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp.Description, - Commission: fp.Commission, - BabylonPk: fp.BabylonPk, - BtcPk: fp.BtcPk, - Pop: fp.Pop, - MasterPubRand: fp.MasterPubRand, + Signer: datagen.GenRandomAccount().Address, + Description: fp.Description, + Commission: fp.Commission, + BabylonPk: fp.BabylonPk, + BtcPk: fp.BtcPk, + Pop: fp.Pop, } _, err = h.MsgServer.CreateFinalityProvider(h.Ctx, msg) require.NoError(t, err) @@ -76,13 +71,12 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { // duplicated finality providers should not pass for _, fp2 := range fps { msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, - Description: fp2.Description, - Commission: fp2.Commission, - BabylonPk: fp2.BabylonPk, - BtcPk: fp2.BtcPk, - Pop: fp2.Pop, - MasterPubRand: fp2.MasterPubRand, + Signer: datagen.GenRandomAccount().Address, + Description: fp2.Description, + Commission: fp2.Commission, + BabylonPk: fp2.BabylonPk, + BtcPk: fp2.BtcPk, + Pop: fp2.Pop, } _, err := h.MsgServer.CreateFinalityProvider(h.Ctx, msg) require.Error(t, err) @@ -163,10 +157,7 @@ func FuzzCreateBTCDelegation(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -211,10 +202,7 @@ func TestProperVersionInDelegation(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -282,10 +270,7 @@ func FuzzAddCovenantSigs(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -353,10 +338,7 @@ func FuzzBTCUndelegate(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -427,12 +409,9 @@ func FuzzSelectiveSlashing(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - fpSK, fpPK, fp := h.CreateFinalityProvider(r) + fpSK, fpPK, _ := h.CreateFinalityProvider(r) fpBtcPk := bbn.NewBIP340PubKeyFromBTCPK(fpPK) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) - // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( @@ -497,12 +476,9 @@ func FuzzSelectiveSlashing_StakingTx(f *testing.F) { require.NoError(t, err) // generate and insert new finality provider - fpSK, fpPK, fp := h.CreateFinalityProvider(r) + fpSK, fpPK, _ := h.CreateFinalityProvider(r) fpBtcPk := bbn.NewBIP340PubKeyFromBTCPK(fpPK) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).Times(1) - // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) stakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( @@ -684,9 +660,6 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { DelegatorUnbondingSlashingSig: delUnbondingSlashingSig, } - // mock last finalised epoch - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(0)) - _, err = h.MsgServer.CreateBTCDelegation(h.Ctx, msgCreateBTCDel) require.Error(t, err) require.True(t, errors.Is(err, types.ErrFpNotFound)) @@ -749,10 +722,7 @@ func TestCorrectUnbondingTimeInDelegation(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).MaxTimes(1) + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) @@ -825,10 +795,7 @@ func TestMinimalUnbondingRate(t *testing.T) { require.NoError(t, err) // generate and insert new finality provider - _, fpPK, fp := h.CreateFinalityProvider(r) - - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).MaxTimes(1) + _, fpPK, _ := h.CreateFinalityProvider(r) // generate and insert new BTC delegation stakingTxHash, _, _, _, err := h.CreateDelegationCustom( diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index cce512c36..da4ec9502 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -38,9 +38,6 @@ func FuzzProcessAllPowerDistUpdateEvents_Determinism(f *testing.F) { fpPKs = append(fpPKs, fpPK) } - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() - // empty dist cache dc := types.NewVotingPowerDistCache() @@ -89,9 +86,6 @@ func FuzzFinalityProviderEvents(f *testing.F) { // generate and insert new finality provider _, fpPK, fp := h.CreateFinalityProvider(r) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() - /* insert new BTC delegation and give it covenant quorum ensure that it has voting power @@ -170,9 +164,6 @@ func FuzzBTCDelegationEvents(f *testing.F) { // generate and insert new finality provider _, fpPK, fp := h.CreateFinalityProvider(r) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(fp.RegisteredEpoch).AnyTimes() - // generate and insert new BTC delegation stakingValue := int64(2 * 10e8) expectedStakingTxHash, _, _, msgCreateBTCDel, actualDel := h.CreateDelegation( diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index c68d264e7..82ac32e6d 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -40,9 +40,6 @@ func FuzzVotingPowerTable(f *testing.F) { fps = append(fps, fp) } - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() - // for the first numFpsWithVotingPower finality providers, generate a random number of BTC delegations numBTCDels := datagen.RandomInt(r, 10) + 1 stakingValue := datagen.RandomInt(r, 100000) + 100000 @@ -173,9 +170,6 @@ func FuzzVotingPowerTable_ActiveFinalityProviders(f *testing.F) { changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) h.NoError(err) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() - // generate a random batch of finality providers, each with a BTC delegation with random power fpsWithMeta := []*types.FinalityProviderDistInfo{} numFps := datagen.RandomInt(r, 300) + 1 @@ -269,9 +263,6 @@ func FuzzVotingPowerTable_ActiveFinalityProviderRotation(f *testing.F) { changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net) h.NoError(err) - // mock that the registered epoch is finalised - h.CheckpointingKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(uint64(10)).AnyTimes() - numFps := datagen.RandomInt(r, 20) + 10 numActiveFPs := int(min(numFps, uint64(bsParams.MaxActiveFinalityProviders))) diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 700a687f4..bea07a683 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -5,7 +5,6 @@ import ( "sort" "cosmossdk.io/math" - "github.com/babylonchain/babylon/crypto/eots" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -36,23 +35,6 @@ func (fp *FinalityProvider) ValidateBasic() error { return nil } -// MustGetPubRand gets the public randomness at the given height for the -// finality provider. It is derived from its master public randomness. -func (fp *FinalityProvider) MustGetPubRand(height uint64) *eots.PublicRand { - mpr, err := eots.NewMasterPublicRandFromBase58(fp.MasterPubRand) - if err != nil { - // fp is a DB object and mpr has been verified. This - // must be a programming error - panic(err) - } - pr, err := mpr.DerivePubRand(uint32(height)) - if err != nil { - // must be a programming error - panic(err) - } - return pr -} - // SortFinalityProviders sorts the finality providers slice, // from higher to lower voting power func SortFinalityProviders(fps []*FinalityProviderDistInfo) { diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index 3c46186df..7decf89b8 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -82,19 +82,14 @@ type FinalityProvider struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` - // registered_epoch is the epoch when this finality provider is registered - RegisteredEpoch uint64 `protobuf:"varint,7,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,8,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,9,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProvider) Reset() { *m = FinalityProvider{} } @@ -151,20 +146,6 @@ func (m *FinalityProvider) GetPop() *ProofOfPossession { return nil } -func (m *FinalityProvider) GetMasterPubRand() string { - if m != nil { - return m.MasterPubRand - } - return "" -} - -func (m *FinalityProvider) GetRegisteredEpoch() uint64 { - if m != nil { - return m.RegisteredEpoch - } - return 0 -} - func (m *FinalityProvider) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -188,19 +169,14 @@ type FinalityProviderWithMeta struct { Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,4,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` - // registered_epoch is the epoch when this finality provider is registered - RegisteredEpoch uint64 `protobuf:"varint,5,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,4,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,5,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` } func (m *FinalityProviderWithMeta) Reset() { *m = FinalityProviderWithMeta{} } @@ -250,20 +226,6 @@ func (m *FinalityProviderWithMeta) GetVotingPower() uint64 { return 0 } -func (m *FinalityProviderWithMeta) GetMasterPubRand() string { - if m != nil { - return m.MasterPubRand - } - return "" -} - -func (m *FinalityProviderWithMeta) GetRegisteredEpoch() uint64 { - if m != nil { - return m.RegisteredEpoch - } - return 0 -} - func (m *FinalityProviderWithMeta) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -782,86 +744,82 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1254 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x5d, 0x6f, 0x1b, 0x45, - 0x17, 0xce, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x37, 0xc9, 0xeb, - 0xb7, 0x6f, 0x15, 0x10, 0xb5, 0x9b, 0xf4, 0x43, 0xc0, 0x05, 0x52, 0x1d, 0xbb, 0x34, 0x6a, 0x9b, - 0x9a, 0x75, 0x52, 0x04, 0x48, 0xac, 0x66, 0x77, 0x27, 0xeb, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, - 0xec, 0x1f, 0x81, 0xc4, 0x2d, 0xf7, 0x5c, 0x71, 0xcd, 0x6f, 0x40, 0x5c, 0x56, 0x5c, 0xa1, 0x20, - 0x45, 0xa8, 0xfd, 0x01, 0xfc, 0x05, 0x34, 0x33, 0xfb, 0x61, 0xb7, 0x09, 0xb4, 0x75, 0xef, 0x3c, - 0xe7, 0xe3, 0x39, 0x67, 0xce, 0xf3, 0xec, 0xcc, 0x18, 0xae, 0x5b, 0xd8, 0x9a, 0xf4, 0xa9, 0x5f, - 0xb7, 0xb8, 0xcd, 0x38, 0xee, 0x79, 0xbe, 0x5b, 0x1f, 0x6d, 0x4f, 0xad, 0x6a, 0x41, 0x48, 0x39, - 0x45, 0x97, 0xa2, 0xb8, 0xda, 0x94, 0x67, 0xb4, 0x7d, 0x75, 0xc5, 0xa5, 0x2e, 0x95, 0x11, 0x75, - 0xf1, 0x4b, 0x05, 0x5f, 0xbd, 0x62, 0x53, 0x36, 0xa0, 0xcc, 0x54, 0x0e, 0xb5, 0x88, 0x5c, 0x55, - 0xb5, 0xaa, 0xdb, 0xe1, 0x24, 0xe0, 0xb4, 0xce, 0x88, 0x1d, 0xec, 0xdc, 0xb9, 0xdb, 0xdb, 0xae, - 0xf7, 0xc8, 0x24, 0x8e, 0xb9, 0x16, 0xc5, 0xa4, 0xfd, 0x58, 0x84, 0xe3, 0xed, 0xfa, 0x4c, 0x47, - 0x57, 0x37, 0x4e, 0xef, 0x3c, 0xa0, 0x81, 0x0a, 0xa8, 0xfe, 0x94, 0x83, 0xca, 0x7d, 0xcf, 0xc7, - 0x7d, 0x8f, 0x4f, 0xda, 0x21, 0x1d, 0x79, 0x0e, 0x09, 0x51, 0x0b, 0x8a, 0x0e, 0x61, 0x76, 0xe8, - 0x05, 0xdc, 0xa3, 0xbe, 0xae, 0x6d, 0x6a, 0x5b, 0xc5, 0x9d, 0xff, 0xd5, 0xa2, 0x1e, 0xd3, 0x9d, - 0xc9, 0x8a, 0xb5, 0x66, 0x1a, 0x6a, 0x4c, 0xe7, 0xa1, 0xc7, 0x00, 0x36, 0x1d, 0x0c, 0x3c, 0xc6, - 0x04, 0x4a, 0x66, 0x53, 0xdb, 0x2a, 0x34, 0x6e, 0x1c, 0x9f, 0x6c, 0xac, 0x29, 0x20, 0xe6, 0xf4, - 0x6a, 0x1e, 0xad, 0x0f, 0x30, 0xef, 0xd6, 0x1e, 0x11, 0x17, 0xdb, 0x93, 0x26, 0xb1, 0x7f, 0xfb, - 0xf9, 0x06, 0x44, 0x75, 0x9a, 0xc4, 0x36, 0xa6, 0x00, 0xd0, 0x27, 0x00, 0xd1, 0x6e, 0xcc, 0xa0, - 0xa7, 0x67, 0x65, 0x53, 0x1b, 0x71, 0x53, 0x6a, 0x54, 0xb5, 0x64, 0x54, 0xb5, 0xf6, 0xd0, 0x7a, - 0x48, 0x26, 0x46, 0x21, 0x4a, 0x69, 0xf7, 0xd0, 0x63, 0xc8, 0x5b, 0xdc, 0x16, 0xb9, 0xb9, 0x4d, - 0x6d, 0xab, 0xd4, 0xb8, 0x7b, 0x7c, 0xb2, 0xb1, 0xe3, 0x7a, 0xbc, 0x3b, 0xb4, 0x6a, 0x36, 0x1d, - 0xd4, 0xa3, 0x48, 0xbb, 0x8b, 0x3d, 0x3f, 0x5e, 0xd4, 0xf9, 0x24, 0x20, 0xac, 0xd6, 0xd8, 0x6b, - 0xdf, 0xba, 0x7d, 0x33, 0x82, 0x5c, 0xb4, 0xb8, 0xdd, 0xee, 0xa1, 0x8f, 0x21, 0x1b, 0xd0, 0x40, - 0x5f, 0x94, 0x7d, 0x6c, 0xd5, 0x4e, 0xa5, 0xbe, 0xd6, 0x0e, 0x29, 0x3d, 0x7a, 0x72, 0xd4, 0xa6, - 0x8c, 0x11, 0xb9, 0x0b, 0x43, 0x24, 0xa1, 0xeb, 0xb0, 0x3c, 0xc0, 0x8c, 0x93, 0xd0, 0x0c, 0x86, - 0x96, 0x19, 0x62, 0xdf, 0xd1, 0xf3, 0x62, 0x3c, 0x46, 0x59, 0x99, 0xdb, 0x43, 0xcb, 0xc0, 0xbe, - 0x83, 0xde, 0x83, 0x4a, 0x48, 0x5c, 0x4f, 0x98, 0x88, 0x63, 0x92, 0x80, 0xda, 0x5d, 0x7d, 0x69, - 0x53, 0xdb, 0xca, 0x19, 0xcb, 0xa9, 0xbd, 0x25, 0xcc, 0xe8, 0x36, 0xac, 0xb2, 0x3e, 0x66, 0x5d, - 0xe2, 0x98, 0xf1, 0x94, 0xba, 0xc4, 0x73, 0xbb, 0x5c, 0x3f, 0x27, 0x13, 0x56, 0x22, 0x6f, 0x43, - 0x39, 0x1f, 0x48, 0x1f, 0xfa, 0x00, 0x50, 0x92, 0xc5, 0xed, 0x38, 0xa3, 0x20, 0x33, 0x2a, 0x71, - 0x06, 0xb7, 0x55, 0x74, 0xf5, 0x8f, 0x0c, 0xe8, 0x2f, 0x8b, 0xe5, 0x73, 0x8f, 0x77, 0x1f, 0x13, - 0x8e, 0xa7, 0xc6, 0xab, 0xbd, 0x8b, 0xf1, 0xae, 0x42, 0x3e, 0xea, 0x26, 0x23, 0xbb, 0x89, 0x56, - 0xe8, 0xbf, 0x50, 0x1a, 0x51, 0xee, 0xf9, 0xae, 0x19, 0xd0, 0x6f, 0x49, 0x28, 0x75, 0x90, 0x33, - 0x8a, 0xca, 0xd6, 0x16, 0xa6, 0xd3, 0xa6, 0x9b, 0x7b, 0xdd, 0xe9, 0x2e, 0xbe, 0xe9, 0x74, 0xf3, - 0x6f, 0x3c, 0xdd, 0xa5, 0x33, 0xa6, 0xfb, 0x57, 0x1e, 0xca, 0x8d, 0x83, 0xdd, 0x26, 0xe9, 0x13, - 0x17, 0xf3, 0x57, 0x15, 0xaf, 0xcd, 0xa1, 0xf8, 0xcc, 0x3b, 0x54, 0x7c, 0xf6, 0x6d, 0x14, 0xff, - 0x15, 0x9c, 0x3f, 0x0a, 0x4c, 0xd5, 0x8d, 0xd9, 0xf7, 0x18, 0xd7, 0x73, 0x9b, 0xd9, 0x39, 0x5a, - 0x2a, 0x1e, 0x05, 0x0d, 0xd1, 0xd4, 0x23, 0x8f, 0x49, 0x4d, 0x30, 0x8e, 0x43, 0x1e, 0x4f, 0x58, - 0x91, 0x58, 0x94, 0xb6, 0x88, 0x8a, 0xff, 0x00, 0x10, 0xdf, 0x99, 0x25, 0xad, 0x40, 0x7c, 0x27, - 0x72, 0xaf, 0x41, 0x81, 0x53, 0x8e, 0xfb, 0x26, 0xc3, 0x31, 0x41, 0xe7, 0xa4, 0xa1, 0x83, 0x65, - 0x6e, 0xb4, 0x41, 0x93, 0x8f, 0xe5, 0xe7, 0x54, 0x32, 0x0a, 0x91, 0xe5, 0x60, 0x2c, 0x59, 0x8e, - 0xdc, 0x74, 0xc8, 0x83, 0x21, 0x37, 0x3d, 0x67, 0x2c, 0xbf, 0xa1, 0xb2, 0x51, 0x89, 0x3c, 0x4f, - 0xa4, 0x63, 0xcf, 0x19, 0xa3, 0x1d, 0x28, 0x4a, 0xe6, 0x23, 0x34, 0x90, 0xc4, 0x5c, 0x38, 0x3e, - 0xd9, 0x10, 0xdc, 0x77, 0x22, 0xcf, 0xc1, 0xd8, 0x00, 0x96, 0xfc, 0x46, 0x5f, 0x43, 0xd9, 0x51, - 0xaa, 0xa0, 0xa1, 0xc9, 0x3c, 0x57, 0x2f, 0xca, 0xac, 0x8f, 0x8e, 0x4f, 0x36, 0xee, 0xbc, 0xc9, - 0xec, 0x3a, 0x9e, 0xeb, 0x63, 0x3e, 0x0c, 0x89, 0x51, 0x4a, 0xf0, 0x3a, 0x9e, 0x8b, 0x0e, 0xa1, - 0x6c, 0xd3, 0x11, 0xf1, 0xb1, 0xcf, 0x05, 0x3c, 0xd3, 0x4b, 0x9b, 0xd9, 0xad, 0xe2, 0xce, 0xcd, - 0x33, 0x28, 0xde, 0x8d, 0x62, 0xef, 0x39, 0x38, 0x50, 0x08, 0x0a, 0x95, 0x19, 0xa5, 0x18, 0xa6, - 0xe3, 0xb9, 0x0c, 0xfd, 0x1f, 0xce, 0x0f, 0x7d, 0x8b, 0xfa, 0x8e, 0xdc, 0xab, 0x37, 0x20, 0x7a, - 0x59, 0x0e, 0xa5, 0x9c, 0x58, 0x0f, 0xbc, 0x01, 0x41, 0x9f, 0x41, 0x45, 0xe8, 0x62, 0xe8, 0x3b, - 0x89, 0xf2, 0xf5, 0xf3, 0x52, 0x63, 0xd7, 0xcf, 0x68, 0xa0, 0x71, 0xb0, 0x7b, 0x38, 0x15, 0x6d, - 0x2c, 0x5b, 0xdc, 0x9e, 0x36, 0x88, 0xca, 0x01, 0x0e, 0xf1, 0x80, 0x99, 0x23, 0x12, 0xca, 0xdb, - 0x67, 0x59, 0x55, 0x56, 0xd6, 0xa7, 0xca, 0x58, 0xfd, 0x21, 0x07, 0xcb, 0x2f, 0x61, 0x09, 0x2d, - 0x4d, 0x35, 0x3d, 0x56, 0x87, 0x99, 0x51, 0x4c, 0x5b, 0x7e, 0x85, 0xc2, 0xcc, 0xeb, 0x50, 0xf8, - 0x0d, 0x5c, 0x4e, 0x29, 0x4c, 0x0b, 0x08, 0x32, 0xb3, 0xf3, 0x92, 0x79, 0x29, 0x41, 0x3e, 0x8c, - 0x81, 0x05, 0xab, 0x14, 0x56, 0xa7, 0x54, 0x13, 0x37, 0x2c, 0x2a, 0xe6, 0xe6, 0xad, 0xb8, 0x92, - 0xca, 0x27, 0xc2, 0x15, 0x05, 0x8f, 0x60, 0x35, 0x95, 0xd1, 0x54, 0x3d, 0xa6, 0x2f, 0xbe, 0xa5, - 0x9e, 0x56, 0x12, 0x3d, 0xa5, 0x65, 0x18, 0xb2, 0x61, 0x2d, 0xa9, 0x33, 0x33, 0x4a, 0x75, 0xb0, - 0xe4, 0x65, 0xb1, 0x6b, 0x67, 0x14, 0x4b, 0xd0, 0xf7, 0xfc, 0x23, 0x6a, 0xe8, 0x31, 0xd0, 0xf4, - 0xe4, 0xc4, 0x99, 0x52, 0xed, 0xc0, 0xe5, 0xf4, 0x30, 0xa6, 0x61, 0x7a, 0x2a, 0x33, 0xf4, 0x21, - 0xe4, 0x1c, 0xd2, 0x67, 0xba, 0xf6, 0x8f, 0x85, 0x66, 0x8e, 0x72, 0x43, 0x66, 0x54, 0xf7, 0x61, - 0xed, 0x74, 0xd0, 0x3d, 0xdf, 0x21, 0x63, 0x54, 0x87, 0x95, 0xf4, 0xa0, 0x31, 0xbb, 0x98, 0x75, - 0xd5, 0x8e, 0x44, 0xa1, 0x92, 0x71, 0x21, 0x39, 0x72, 0x1e, 0x60, 0xd6, 0x95, 0x4d, 0xfe, 0xa8, - 0x41, 0x79, 0x66, 0x43, 0xe8, 0x3e, 0x64, 0xe6, 0xbe, 0x81, 0x33, 0x41, 0x0f, 0x3d, 0x84, 0xac, - 0x50, 0x4a, 0x66, 0x5e, 0xa5, 0x08, 0x94, 0xea, 0x77, 0x1a, 0x5c, 0x39, 0x93, 0x64, 0x71, 0x4b, - 0xd9, 0x74, 0xf4, 0x0e, 0x1e, 0x0e, 0x36, 0x1d, 0xb5, 0x7b, 0xe2, 0x03, 0xc6, 0xaa, 0x86, 0xd2, - 0x5e, 0x46, 0x0e, 0xaf, 0x88, 0x93, 0xba, 0xac, 0xfa, 0x8b, 0x06, 0x57, 0x3a, 0xa4, 0x4f, 0x6c, - 0xee, 0x8d, 0x48, 0x2c, 0xad, 0x96, 0x78, 0xce, 0xf8, 0x36, 0x11, 0xcf, 0x87, 0x97, 0x58, 0x90, - 0x8d, 0x15, 0x8c, 0xf2, 0x0c, 0x01, 0xc8, 0x80, 0x42, 0x72, 0xa5, 0xcd, 0x79, 0xc1, 0x2e, 0x45, - 0xb7, 0x19, 0xba, 0x01, 0x17, 0x43, 0x22, 0x34, 0x29, 0x5e, 0x24, 0x11, 0x3a, 0x53, 0x8f, 0xdd, - 0x92, 0x51, 0x49, 0x5c, 0xf7, 0x45, 0x78, 0xa7, 0xf7, 0x7e, 0x0b, 0x2e, 0xce, 0xc8, 0xac, 0xc3, - 0x31, 0x1f, 0x32, 0x54, 0x84, 0xa5, 0x76, 0x6b, 0xbf, 0xb9, 0xb7, 0xff, 0x69, 0x65, 0x01, 0x01, - 0xe4, 0xef, 0xed, 0x1e, 0xec, 0x3d, 0x6d, 0x55, 0x34, 0x54, 0x82, 0x73, 0x87, 0xfb, 0x8d, 0x27, - 0xfb, 0xcd, 0x56, 0xb3, 0x92, 0x41, 0x4b, 0x90, 0xbd, 0xb7, 0xff, 0x45, 0x25, 0xdb, 0x78, 0xf4, - 0xeb, 0xf3, 0x75, 0xed, 0xd9, 0xf3, 0x75, 0xed, 0xcf, 0xe7, 0xeb, 0xda, 0xf7, 0x2f, 0xd6, 0x17, - 0x9e, 0xbd, 0x58, 0x5f, 0xf8, 0xfd, 0xc5, 0xfa, 0xc2, 0x97, 0xff, 0xba, 0x99, 0xf1, 0xf4, 0x3f, - 0x0b, 0xb9, 0x33, 0x2b, 0x2f, 0xff, 0x59, 0xdc, 0xfa, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x55, 0xdf, - 0x12, 0xf0, 0x36, 0x0d, 0x00, 0x00, + // 1197 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, + 0x17, 0xcf, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x7f, 0x92, 0xbf, + 0x29, 0x95, 0x85, 0xa8, 0xdd, 0xa4, 0x1f, 0x02, 0x2e, 0x90, 0xea, 0x38, 0xa5, 0x51, 0xdb, 0xd4, + 0xac, 0x93, 0x22, 0x40, 0x62, 0x35, 0xde, 0x9d, 0xac, 0x57, 0xb6, 0x77, 0x96, 0x9d, 0xb1, 0xb1, + 0xdf, 0x80, 0x1b, 0x24, 0x6e, 0xb9, 0xe7, 0x11, 0x78, 0x06, 0xc4, 0x65, 0xc5, 0x0d, 0x28, 0x17, + 0x11, 0x6a, 0x1f, 0x80, 0x57, 0x40, 0x33, 0x3b, 0xfb, 0xe1, 0xb6, 0x29, 0xb4, 0xce, 0x9d, 0x67, + 0xce, 0x39, 0xbf, 0xf3, 0xf1, 0xfb, 0xf9, 0xcc, 0xc2, 0xf5, 0x2e, 0xee, 0x4e, 0x07, 0xd4, 0x6b, + 0x74, 0xb9, 0xc5, 0x38, 0xee, 0xbb, 0x9e, 0xd3, 0x18, 0x6f, 0xa5, 0x4e, 0x75, 0x3f, 0xa0, 0x9c, + 0xa2, 0x4b, 0xca, 0xaf, 0x9e, 0xb2, 0x8c, 0xb7, 0xae, 0xae, 0x38, 0xd4, 0xa1, 0xd2, 0xa3, 0x21, + 0x7e, 0x85, 0xce, 0x57, 0xaf, 0x58, 0x94, 0x0d, 0x29, 0x33, 0x43, 0x43, 0x78, 0x50, 0xa6, 0x6a, + 0x78, 0x6a, 0x58, 0xc1, 0xd4, 0xe7, 0xb4, 0xc1, 0x88, 0xe5, 0x6f, 0xdf, 0xb9, 0xdb, 0xdf, 0x6a, + 0xf4, 0xc9, 0x34, 0xf2, 0xb9, 0xa6, 0x7c, 0x92, 0x7a, 0xba, 0x84, 0xe3, 0xad, 0xc6, 0x4c, 0x45, + 0x57, 0x37, 0x5e, 0x5f, 0xb9, 0x4f, 0xfd, 0xd0, 0xa1, 0xfa, 0x47, 0x16, 0x2a, 0xf7, 0x5d, 0x0f, + 0x0f, 0x5c, 0x3e, 0x6d, 0x07, 0x74, 0xec, 0xda, 0x24, 0x40, 0xbb, 0x50, 0xb4, 0x09, 0xb3, 0x02, + 0xd7, 0xe7, 0x2e, 0xf5, 0x74, 0x6d, 0x53, 0xab, 0x15, 0xb7, 0xdf, 0xab, 0xab, 0x1a, 0x93, 0xce, + 0x64, 0xc6, 0x7a, 0x2b, 0x71, 0x35, 0xd2, 0x71, 0xe8, 0x31, 0x80, 0x45, 0x87, 0x43, 0x97, 0x31, + 0x81, 0x92, 0xd9, 0xd4, 0x6a, 0x85, 0xe6, 0x8d, 0xe3, 0x93, 0x8d, 0xb5, 0x10, 0x88, 0xd9, 0xfd, + 0xba, 0x4b, 0x1b, 0x43, 0xcc, 0x7b, 0xf5, 0x47, 0xc4, 0xc1, 0xd6, 0xb4, 0x45, 0xac, 0xdf, 0x7f, + 0xb9, 0x01, 0x2a, 0x4f, 0x8b, 0x58, 0x46, 0x0a, 0x00, 0x7d, 0x0a, 0xa0, 0xba, 0x31, 0xfd, 0xbe, + 0x9e, 0x95, 0x45, 0x6d, 0x44, 0x45, 0x85, 0xa3, 0xaa, 0xc7, 0xa3, 0xaa, 0xb7, 0x47, 0xdd, 0x87, + 0x64, 0x6a, 0x14, 0x54, 0x48, 0xbb, 0x8f, 0x1e, 0x43, 0xbe, 0xcb, 0x2d, 0x11, 0x9b, 0xdb, 0xd4, + 0x6a, 0xa5, 0xe6, 0xdd, 0xe3, 0x93, 0x8d, 0x6d, 0xc7, 0xe5, 0xbd, 0x51, 0xb7, 0x6e, 0xd1, 0x61, + 0x43, 0x79, 0x5a, 0x3d, 0xec, 0x7a, 0xd1, 0xa1, 0xc1, 0xa7, 0x3e, 0x61, 0xf5, 0xe6, 0x5e, 0xfb, + 0xd6, 0xed, 0x9b, 0x0a, 0x72, 0xb1, 0xcb, 0xad, 0x76, 0x1f, 0x7d, 0x02, 0x59, 0x9f, 0xfa, 0xfa, + 0xa2, 0xac, 0xa3, 0x56, 0x7f, 0x2d, 0xf5, 0xf5, 0x76, 0x40, 0xe9, 0xd1, 0x93, 0xa3, 0x36, 0x65, + 0x8c, 0xc8, 0x2e, 0x0c, 0x11, 0x84, 0x6e, 0xc3, 0x2a, 0x1b, 0x60, 0xd6, 0x23, 0xb6, 0x19, 0xb5, + 0xd4, 0x23, 0xae, 0xd3, 0xe3, 0x7a, 0x7e, 0x53, 0xab, 0xe5, 0x8c, 0x15, 0x65, 0x6d, 0x86, 0xc6, + 0x07, 0xd2, 0x86, 0x3e, 0x04, 0x14, 0x47, 0x71, 0x2b, 0x8a, 0x58, 0x92, 0x11, 0x95, 0x28, 0x82, + 0x5b, 0xa1, 0x77, 0xf5, 0xfb, 0x0c, 0xe8, 0x2f, 0x33, 0xfb, 0x85, 0xcb, 0x7b, 0x8f, 0x09, 0xc7, + 0xa9, 0x59, 0x68, 0x67, 0x31, 0x8b, 0x55, 0xc8, 0xab, 0x6a, 0x32, 0xb2, 0x1a, 0x75, 0x42, 0xff, + 0x87, 0xd2, 0x98, 0x72, 0xd7, 0x73, 0x4c, 0x9f, 0x7e, 0x47, 0x02, 0x49, 0x5a, 0xce, 0x28, 0x86, + 0x77, 0x6d, 0x71, 0xf5, 0x86, 0x51, 0xe4, 0xde, 0x7a, 0x14, 0x8b, 0xa7, 0x8c, 0xe2, 0xef, 0x3c, + 0x94, 0x9b, 0x07, 0x3b, 0x2d, 0x32, 0x20, 0x0e, 0xe6, 0xaf, 0x6a, 0x49, 0x9b, 0x43, 0x4b, 0x99, + 0x33, 0xd4, 0x52, 0xf6, 0x5d, 0xb4, 0xf4, 0x35, 0x9c, 0x3f, 0xf2, 0xcd, 0xb0, 0x1a, 0x73, 0xe0, + 0x32, 0x31, 0xb8, 0xec, 0x1c, 0x25, 0x15, 0x8f, 0xfc, 0xa6, 0x28, 0xea, 0x91, 0xcb, 0x24, 0x81, + 0x8c, 0xe3, 0x80, 0xcf, 0x4e, 0xb8, 0x28, 0xef, 0x14, 0x15, 0xff, 0x03, 0x20, 0x9e, 0x3d, 0xab, + 0xdf, 0x02, 0xf1, 0x6c, 0x65, 0x5e, 0x83, 0x02, 0xa7, 0x1c, 0x0f, 0x4c, 0x86, 0x23, 0xad, 0x9e, + 0x93, 0x17, 0x1d, 0x2c, 0x63, 0x55, 0x83, 0x26, 0x9f, 0xe8, 0xe7, 0xc4, 0x28, 0x8d, 0x82, 0xba, + 0x39, 0x98, 0x48, 0x96, 0x95, 0x99, 0x8e, 0xb8, 0x3f, 0xe2, 0xa6, 0x6b, 0x4f, 0xf4, 0xc2, 0xa6, + 0x56, 0x2b, 0x1b, 0x15, 0x65, 0x79, 0x22, 0x0d, 0x7b, 0xf6, 0x04, 0x6d, 0x43, 0x51, 0x32, 0xaf, + 0xd0, 0x40, 0x12, 0x73, 0xe1, 0xf8, 0x64, 0x43, 0x70, 0xdf, 0x51, 0x96, 0x83, 0x89, 0x01, 0x2c, + 0xfe, 0x8d, 0xbe, 0x81, 0xb2, 0x1d, 0xaa, 0x82, 0x06, 0x26, 0x73, 0x1d, 0xbd, 0x28, 0xa3, 0x3e, + 0x3e, 0x3e, 0xd9, 0xb8, 0xf3, 0x36, 0xb3, 0xeb, 0xb8, 0x8e, 0x87, 0xf9, 0x28, 0x20, 0x46, 0x29, + 0xc6, 0xeb, 0xb8, 0x0e, 0x3a, 0x84, 0xb2, 0x45, 0xc7, 0xc4, 0xc3, 0x1e, 0x17, 0xf0, 0x4c, 0x2f, + 0x6d, 0x66, 0x6b, 0xc5, 0xed, 0x9b, 0xa7, 0x50, 0xbc, 0xa3, 0x7c, 0xef, 0xd9, 0xd8, 0x0f, 0x11, + 0x42, 0x54, 0x66, 0x94, 0x22, 0x98, 0x8e, 0xeb, 0x30, 0xf4, 0x3e, 0x9c, 0x1f, 0x79, 0x5d, 0xea, + 0xd9, 0xb2, 0x57, 0x77, 0x48, 0xf4, 0xb2, 0x1c, 0x4a, 0x39, 0xbe, 0x3d, 0x70, 0x87, 0x04, 0x7d, + 0x0e, 0x15, 0xa1, 0x8b, 0x91, 0x67, 0xc7, 0xca, 0xd7, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa5, 0x80, + 0xe6, 0xc1, 0xce, 0x61, 0xca, 0xdb, 0x58, 0xee, 0x72, 0x2b, 0x7d, 0x21, 0x32, 0xfb, 0x38, 0xc0, + 0x43, 0x66, 0x8e, 0x49, 0x20, 0xf7, 0xfa, 0x72, 0x98, 0x39, 0xbc, 0x7d, 0x1a, 0x5e, 0x56, 0x7f, + 0xca, 0xc1, 0xf2, 0x4b, 0x58, 0x42, 0x4b, 0xa9, 0xa2, 0x27, 0xe1, 0xe6, 0x31, 0x8a, 0x49, 0xc9, + 0xaf, 0x50, 0x98, 0xf9, 0x2f, 0x14, 0x7e, 0x0b, 0x97, 0x13, 0x0a, 0x93, 0x04, 0x82, 0xcc, 0xec, + 0xbc, 0x64, 0x5e, 0x8a, 0x91, 0x0f, 0x23, 0x60, 0xc1, 0x2a, 0x85, 0xd5, 0x94, 0x6a, 0xa2, 0x82, + 0x45, 0xc6, 0xdc, 0xbc, 0x19, 0x57, 0x12, 0xf9, 0x28, 0x5c, 0x91, 0xf0, 0x08, 0x56, 0x13, 0x19, + 0xa5, 0xf2, 0x31, 0x7d, 0xf1, 0x1d, 0xf5, 0xb4, 0x12, 0xeb, 0x29, 0x49, 0xc3, 0x90, 0x05, 0x6b, + 0x71, 0x9e, 0x99, 0x51, 0x86, 0x8b, 0x25, 0x2f, 0x93, 0x5d, 0x3b, 0x25, 0x59, 0x8c, 0xbe, 0xe7, + 0x1d, 0x51, 0x43, 0x8f, 0x80, 0xd2, 0x93, 0x13, 0x3b, 0xa5, 0xda, 0x81, 0xcb, 0xc9, 0x32, 0xa6, + 0x41, 0xb2, 0x95, 0x19, 0xfa, 0x08, 0x72, 0x36, 0x19, 0x30, 0x5d, 0x7b, 0x63, 0xa2, 0x99, 0x55, + 0x6e, 0xc8, 0x88, 0xea, 0x3e, 0xac, 0xbd, 0x1e, 0x74, 0xcf, 0xb3, 0xc9, 0x04, 0x35, 0x60, 0x25, + 0x59, 0x34, 0x66, 0x0f, 0xb3, 0x5e, 0xd8, 0x91, 0x48, 0x54, 0x32, 0x2e, 0xc4, 0x2b, 0xe7, 0x01, + 0x66, 0x3d, 0x59, 0xe4, 0xcf, 0x1a, 0x94, 0x67, 0x1a, 0x42, 0xf7, 0x21, 0x33, 0xf7, 0x73, 0x99, + 0xf1, 0xfb, 0xe8, 0x21, 0x64, 0x85, 0x52, 0x32, 0xf3, 0x2a, 0x45, 0xa0, 0x54, 0x7f, 0xd0, 0xe0, + 0xca, 0xa9, 0x24, 0x8b, 0x57, 0xca, 0xa2, 0xe3, 0x33, 0x78, 0xe5, 0x2d, 0x3a, 0x6e, 0xf7, 0xc5, + 0x1f, 0x18, 0x87, 0x39, 0x42, 0xed, 0x65, 0xe4, 0xf0, 0x8a, 0x38, 0xce, 0xcb, 0xaa, 0xbf, 0x6a, + 0x70, 0xa5, 0x43, 0x06, 0xc4, 0xe2, 0xee, 0x98, 0x44, 0xd2, 0xda, 0x15, 0xdf, 0x1e, 0x9e, 0x45, + 0xd0, 0x75, 0x58, 0x7e, 0x89, 0x05, 0x59, 0x58, 0xc1, 0x28, 0xcf, 0x10, 0x80, 0x0c, 0x28, 0xc4, + 0x4f, 0xda, 0x9c, 0x0f, 0xec, 0x92, 0x7a, 0xcd, 0xd0, 0x0d, 0xb8, 0x18, 0x10, 0xa1, 0xc9, 0x80, + 0xd8, 0xa6, 0x42, 0x67, 0xe1, 0x67, 0x64, 0xc9, 0xa8, 0xc4, 0xa6, 0xfb, 0xc2, 0xbd, 0xd3, 0xff, + 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc3, 0x31, 0x1f, 0x31, 0x54, 0x84, 0xa5, 0xf6, 0xee, 0x7e, + 0x6b, 0x6f, 0xff, 0xb3, 0xca, 0x02, 0x02, 0xc8, 0xdf, 0xdb, 0x39, 0xd8, 0x7b, 0xba, 0x5b, 0xd1, + 0x50, 0x09, 0xce, 0x1d, 0xee, 0x37, 0x9f, 0xec, 0xb7, 0x76, 0x5b, 0x95, 0x0c, 0x5a, 0x82, 0xec, + 0xbd, 0xfd, 0x2f, 0x2b, 0xd9, 0xe6, 0xa3, 0xdf, 0x9e, 0xaf, 0x6b, 0xcf, 0x9e, 0xaf, 0x6b, 0x7f, + 0x3d, 0x5f, 0xd7, 0x7e, 0x7c, 0xb1, 0xbe, 0xf0, 0xec, 0xc5, 0xfa, 0xc2, 0x9f, 0x2f, 0xd6, 0x17, + 0xbe, 0xfa, 0xd7, 0x66, 0x26, 0xe9, 0x6f, 0x76, 0xd9, 0x59, 0x37, 0x2f, 0xbf, 0xd9, 0x6f, 0xfd, + 0x13, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xb8, 0x1f, 0xd2, 0x90, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -887,24 +845,12 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x48 + dAtA[i] = 0x38 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x40 - } - if m.RegisteredEpoch != 0 { - i = encodeVarintBtcstaking(dAtA, i, uint64(m.RegisteredEpoch)) - i-- - dAtA[i] = 0x38 - } - if len(m.MasterPubRand) > 0 { - i -= len(m.MasterPubRand) - copy(dAtA[i:], m.MasterPubRand) - i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.MasterPubRand))) - i-- - dAtA[i] = 0x32 + dAtA[i] = 0x30 } if m.Pop != nil { { @@ -992,24 +938,12 @@ func (m *FinalityProviderWithMeta) MarshalToSizedBuffer(dAtA []byte) (int, error if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x28 } if m.SlashedBabylonHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x30 - } - if m.RegisteredEpoch != 0 { - i = encodeVarintBtcstaking(dAtA, i, uint64(m.RegisteredEpoch)) - i-- - dAtA[i] = 0x28 - } - if len(m.MasterPubRand) > 0 { - i -= len(m.MasterPubRand) - copy(dAtA[i:], m.MasterPubRand) - i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.MasterPubRand))) - i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if m.VotingPower != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.VotingPower)) @@ -1536,13 +1470,6 @@ func (m *FinalityProvider) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovBtcstaking(uint64(l)) } - l = len(m.MasterPubRand) - if l > 0 { - n += 1 + l + sovBtcstaking(uint64(l)) - } - if m.RegisteredEpoch != 0 { - n += 1 + sovBtcstaking(uint64(m.RegisteredEpoch)) - } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1568,13 +1495,6 @@ func (m *FinalityProviderWithMeta) Size() (n int) { if m.VotingPower != 0 { n += 1 + sovBtcstaking(uint64(m.VotingPower)) } - l = len(m.MasterPubRand) - if l > 0 { - n += 1 + l + sovBtcstaking(uint64(l)) - } - if m.RegisteredEpoch != 0 { - n += 1 + sovBtcstaking(uint64(m.RegisteredEpoch)) - } if m.SlashedBabylonHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBabylonHeight)) } @@ -1990,57 +1910,6 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - 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 ErrInvalidLengthBtcstaking - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthBtcstaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MasterPubRand = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) - } - m.RegisteredEpoch = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RegisteredEpoch |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -2059,7 +1928,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { break } } - case 9: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -2202,57 +2071,6 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { } } case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - 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 ErrInvalidLengthBtcstaking - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthBtcstaking - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MasterPubRand = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) - } - m.RegisteredEpoch = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowBtcstaking - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RegisteredEpoch |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -2271,7 +2089,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { break } } - case 7: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index 6bc0059ba..ba77caf15 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -51,9 +51,6 @@ func (m *MsgCreateFinalityProvider) ValidateBasic() error { if err := m.Pop.ValidateBasic(); err != nil { return err } - if len(m.MasterPubRand) == 0 { - return fmt.Errorf("empty master public randomness") - } return nil } diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 5cc3dc5e8..1907483ff 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -63,8 +63,6 @@ func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPowe BabylonPk: f.BabylonPk, BtcPk: f.BtcPk, Pop: f.Pop, - MasterPubRand: f.MasterPubRand, - RegisteredEpoch: f.RegisteredEpoch, SlashedBabylonHeight: f.SlashedBabylonHeight, SlashedBtcHeight: f.SlashedBtcHeight, Height: bbnBlockHeight, diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 5b6931218..ee5452bbb 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1483,23 +1483,18 @@ type FinalityProviderResponse struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,6,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` - // registered_epoch is the epoch when this finality provider is registered - RegisteredEpoch uint64 `protobuf:"varint,7,opt,name=registered_epoch,json=registeredEpoch,proto3" json:"registered_epoch,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBabylonHeight uint64 `protobuf:"varint,8,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` + SlashedBabylonHeight uint64 `protobuf:"varint,6,opt,name=slashed_babylon_height,json=slashedBabylonHeight,proto3" json:"slashed_babylon_height,omitempty"` // slashed_btc_height indicates the BTC height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed - SlashedBtcHeight uint64 `protobuf:"varint,9,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` // height is the queried Babylon height - Height uint64 `protobuf:"varint,10,opt,name=height,proto3" json:"height,omitempty"` + Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height - VotingPower uint64 `protobuf:"varint,11,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + VotingPower uint64 `protobuf:"varint,9,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } @@ -1556,20 +1551,6 @@ func (m *FinalityProviderResponse) GetPop() *ProofOfPossession { return nil } -func (m *FinalityProviderResponse) GetMasterPubRand() string { - if m != nil { - return m.MasterPubRand - } - return "" -} - -func (m *FinalityProviderResponse) GetRegisteredEpoch() uint64 { - if m != nil { - return m.RegisteredEpoch - } - return 0 -} - func (m *FinalityProviderResponse) GetSlashedBabylonHeight() uint64 { if m != nil { return m.SlashedBabylonHeight @@ -1630,127 +1611,124 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1916 bytes of a gzipped FileDescriptorProto + // 1869 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, - 0x19, 0x67, 0x12, 0xe3, 0x25, 0x9f, 0xe3, 0x24, 0xbc, 0x0d, 0x60, 0x1c, 0x12, 0xc3, 0x94, 0x85, - 0x84, 0x05, 0x0f, 0x31, 0x81, 0x4a, 0xbb, 0x2d, 0x10, 0x13, 0x16, 0xd8, 0x25, 0xc2, 0x9d, 0x40, - 0x2b, 0x75, 0xab, 0x8e, 0xc6, 0xe3, 0xe7, 0xf1, 0x28, 0xf6, 0xcc, 0x30, 0xef, 0x39, 0xb5, 0x85, - 0x72, 0xe9, 0xa1, 0xb7, 0x4a, 0x95, 0xda, 0x43, 0x2f, 0x3d, 0xb7, 0x52, 0x8f, 0xdd, 0x53, 0xa5, - 0xde, 0xb7, 0xb7, 0xd5, 0xf6, 0xd0, 0x6a, 0x0f, 0xa8, 0x82, 0xaa, 0x95, 0x2a, 0x71, 0xed, 0xb9, - 0x9a, 0xf7, 0xde, 0x78, 0xc6, 0xf6, 0x8c, 0x63, 0x27, 0xd9, 0x5b, 0xfc, 0xde, 0xf7, 0xff, 0xfb, - 0xbd, 0xdf, 0x9b, 0xf7, 0x05, 0x2e, 0x55, 0xf5, 0x6a, 0xb7, 0xe9, 0xd8, 0x4a, 0x95, 0x1a, 0x84, - 0xea, 0xbb, 0x96, 0x6d, 0x2a, 0x7b, 0xeb, 0xca, 0xcb, 0x36, 0xf6, 0xba, 0x45, 0xd7, 0x73, 0xa8, - 0x83, 0xce, 0x08, 0x91, 0x62, 0x28, 0x52, 0xdc, 0x5b, 0xcf, 0x2f, 0x9a, 0x8e, 0xe9, 0x30, 0x09, - 0xc5, 0xff, 0x8b, 0x0b, 0xe7, 0x2f, 0x98, 0x8e, 0x63, 0x36, 0xb1, 0xa2, 0xbb, 0x96, 0xa2, 0xdb, - 0xb6, 0x43, 0x75, 0x6a, 0x39, 0x36, 0x11, 0xbb, 0xe7, 0x0d, 0x87, 0xb4, 0x1c, 0xa2, 0x71, 0x35, - 0xfe, 0x43, 0x6c, 0xc9, 0xfc, 0x97, 0x62, 0x78, 0x5d, 0x97, 0x3a, 0x0a, 0xc1, 0x86, 0x5b, 0xba, - 0x7d, 0x67, 0x77, 0x5d, 0xd9, 0xc5, 0xdd, 0x40, 0xe6, 0xb2, 0x90, 0x09, 0x03, 0xad, 0x62, 0xaa, - 0xaf, 0x07, 0xbf, 0x85, 0xd4, 0x35, 0x21, 0x55, 0xd5, 0x09, 0xe6, 0x89, 0xf4, 0x04, 0x5d, 0xdd, - 0xb4, 0x6c, 0x16, 0x51, 0xe0, 0x35, 0x3e, 0x7d, 0x57, 0xf7, 0xf4, 0x56, 0xe0, 0xf5, 0x4a, 0xbc, - 0x4c, 0xa4, 0x1a, 0x5c, 0xae, 0x90, 0x60, 0xcb, 0x71, 0xb9, 0x80, 0xbc, 0x08, 0xe8, 0x07, 0x7e, - 0x38, 0x15, 0x66, 0x5d, 0xc5, 0x2f, 0xdb, 0x98, 0x50, 0x59, 0x85, 0xf7, 0xfb, 0x56, 0x89, 0xeb, - 0xd8, 0x04, 0xa3, 0x8f, 0x21, 0xcd, 0xa3, 0xc8, 0x49, 0x17, 0xa5, 0xd5, 0x4c, 0x69, 0xb9, 0x18, - 0xdb, 0x86, 0x22, 0x57, 0x2b, 0xa7, 0xbe, 0x7c, 0x5d, 0x38, 0xa1, 0x0a, 0x15, 0xf9, 0xbb, 0xb0, - 0x14, 0xb1, 0x59, 0xee, 0xfe, 0x10, 0x7b, 0xc4, 0x72, 0x6c, 0xe1, 0x12, 0xe5, 0xe0, 0xbd, 0x3d, - 0xbe, 0xc2, 0x8c, 0x67, 0xd5, 0xe0, 0xa7, 0xfc, 0x39, 0x5c, 0x88, 0x57, 0x3c, 0x8e, 0xa8, 0x4c, - 0x58, 0x66, 0xc6, 0x3f, 0xb1, 0x6c, 0xbd, 0x69, 0xd1, 0x6e, 0xc5, 0x73, 0xf6, 0xac, 0x1a, 0xf6, - 0x82, 0x52, 0xa0, 0x4f, 0x00, 0xc2, 0x0e, 0x09, 0x0f, 0x57, 0x8a, 0x02, 0x26, 0x7e, 0x3b, 0x8b, - 0x1c, 0x97, 0xa2, 0x9d, 0xc5, 0x8a, 0x6e, 0x62, 0xa1, 0xab, 0x46, 0x34, 0xe5, 0xbf, 0x4a, 0xb0, - 0x92, 0xe4, 0x49, 0x24, 0xf2, 0x53, 0x40, 0x75, 0xb1, 0xe9, 0xa3, 0x91, 0xef, 0xe6, 0xa4, 0x8b, - 0xd3, 0xab, 0x99, 0x92, 0x92, 0x90, 0xd4, 0xa0, 0xb5, 0xc0, 0x98, 0x7a, 0xba, 0x3e, 0xe8, 0x07, - 0x3d, 0xea, 0x4b, 0x65, 0x8a, 0xa5, 0x72, 0xf5, 0xc0, 0x54, 0x84, 0xbd, 0x68, 0x2e, 0x9b, 0xa2, - 0x23, 0xc3, 0xce, 0x79, 0xcd, 0x2e, 0x41, 0xb6, 0xee, 0x6a, 0x55, 0x6a, 0x68, 0xee, 0xae, 0xd6, - 0xc0, 0x1d, 0x56, 0xb6, 0x19, 0x15, 0xea, 0x6e, 0x99, 0x1a, 0x95, 0xdd, 0xc7, 0xb8, 0x23, 0xef, - 0x27, 0xd4, 0xbd, 0x57, 0x8c, 0x9f, 0xc0, 0xe9, 0xa1, 0x62, 0x88, 0xf2, 0x4f, 0x5c, 0x8b, 0x85, - 0xc1, 0x5a, 0xc8, 0x7f, 0x90, 0x20, 0xcf, 0xfc, 0x97, 0x9f, 0x3f, 0xd8, 0xc2, 0x4d, 0x6c, 0x72, - 0x4a, 0x08, 0x12, 0x28, 0x43, 0x9a, 0x50, 0x9d, 0xb6, 0x39, 0xa4, 0xe6, 0x4a, 0xd7, 0x12, 0x3c, - 0xf6, 0x69, 0xef, 0x30, 0x0d, 0x55, 0x68, 0x0e, 0x00, 0x67, 0xea, 0xd0, 0xc0, 0xf9, 0x8b, 0x24, - 0x0e, 0xce, 0x60, 0xa8, 0xa2, 0x50, 0x2f, 0x60, 0xde, 0xaf, 0x74, 0x2d, 0xdc, 0x12, 0x90, 0xb9, - 0x3e, 0x4e, 0xd0, 0xbd, 0x1a, 0xcd, 0x55, 0xa9, 0x11, 0x31, 0x7f, 0x7c, 0x60, 0xa9, 0xc3, 0x5a, - 0x6c, 0xa7, 0x2b, 0xce, 0xcf, 0xb0, 0xb7, 0x49, 0x1f, 0x63, 0xcb, 0x6c, 0xd0, 0xf1, 0x91, 0x83, - 0xce, 0x42, 0xba, 0xc1, 0x74, 0x58, 0x50, 0x29, 0x55, 0xfc, 0x92, 0x9f, 0xc1, 0xb5, 0x71, 0xfc, - 0x88, 0xaa, 0x5d, 0x82, 0xd9, 0x3d, 0x87, 0x5a, 0xb6, 0xa9, 0xb9, 0xfe, 0x3e, 0xf3, 0x93, 0x52, - 0x33, 0x7c, 0x8d, 0xa9, 0xc8, 0xdb, 0xb0, 0x1a, 0x6b, 0xf0, 0x41, 0xdb, 0xf3, 0xb0, 0x4d, 0x99, - 0xd0, 0x04, 0x88, 0x4f, 0xaa, 0x43, 0xbf, 0x39, 0x11, 0x5e, 0x98, 0xa4, 0x14, 0x4d, 0x72, 0x28, - 0xec, 0xa9, 0xe1, 0xb0, 0x7f, 0x29, 0xc1, 0x87, 0xcc, 0xd1, 0xa6, 0x41, 0xad, 0x3d, 0x3c, 0x44, - 0x37, 0x83, 0x25, 0x4f, 0x72, 0x75, 0x5c, 0xf8, 0xfd, 0xbb, 0x04, 0xd7, 0xc7, 0x8b, 0xe7, 0x18, - 0x69, 0xf0, 0x47, 0x16, 0x6d, 0x6c, 0x63, 0xaa, 0x7f, 0xab, 0x34, 0xb8, 0x2c, 0x0e, 0x26, 0x4b, - 0x4c, 0xa7, 0xb8, 0xd6, 0x57, 0x58, 0xf9, 0x8e, 0x60, 0xc9, 0xa1, 0xed, 0xd1, 0x3d, 0x96, 0x7f, - 0x23, 0xc1, 0xd5, 0x58, 0xa4, 0xc4, 0x10, 0xd5, 0x18, 0xe7, 0xe5, 0xb8, 0xfa, 0xf8, 0x1f, 0x29, - 0xe1, 0x3c, 0xc4, 0x91, 0x92, 0x07, 0xe7, 0x23, 0xa4, 0xe4, 0x78, 0x31, 0xf4, 0x74, 0xe7, 0x40, - 0x7a, 0x72, 0xe2, 0x4c, 0xab, 0xe7, 0x42, 0xa2, 0xea, 0x13, 0x38, 0xbe, 0xbe, 0x7e, 0x0a, 0xe7, - 0x87, 0x09, 0x37, 0xa8, 0xf8, 0x0d, 0x78, 0x5f, 0x04, 0xab, 0xd1, 0x8e, 0xd6, 0xd0, 0x49, 0x23, - 0x52, 0xf7, 0x05, 0xb1, 0xf5, 0xbc, 0xf3, 0x58, 0x27, 0x0d, 0xff, 0xd4, 0xbf, 0x8c, 0xbb, 0x67, - 0x7a, 0x65, 0xda, 0x81, 0xb9, 0x7e, 0xee, 0x16, 0x37, 0xdc, 0x64, 0xd4, 0x9d, 0xed, 0xa3, 0x6e, - 0xf9, 0xb7, 0x69, 0x38, 0x13, 0xef, 0x6e, 0x1b, 0xd2, 0x1c, 0x2a, 0xcc, 0xcd, 0x6c, 0xf9, 0xce, - 0x37, 0xaf, 0x0b, 0x25, 0xd3, 0xa2, 0x8d, 0x76, 0xb5, 0x68, 0x38, 0x2d, 0x45, 0x38, 0x35, 0x1a, - 0xba, 0x65, 0x07, 0x3f, 0x14, 0xda, 0x75, 0x31, 0x29, 0x96, 0x9f, 0x54, 0x6e, 0x6d, 0xdc, 0xac, - 0xb4, 0xab, 0x9f, 0xe1, 0xae, 0x7a, 0xb2, 0xea, 0x83, 0x0b, 0x7d, 0x0e, 0x73, 0x21, 0xf8, 0x9a, - 0x16, 0xf1, 0x19, 0x79, 0xfa, 0x08, 0x66, 0x33, 0x02, 0xb5, 0x4f, 0x2d, 0x86, 0xec, 0x59, 0x42, - 0x75, 0x8f, 0x6a, 0xe2, 0x8c, 0x4c, 0x73, 0xa6, 0x63, 0x6b, 0xfc, 0x20, 0xa1, 0x65, 0x00, 0x6c, - 0xd7, 0x02, 0x81, 0x14, 0x13, 0x98, 0xc1, 0xb6, 0x38, 0x67, 0x68, 0x09, 0x66, 0xa8, 0x43, 0xf5, - 0xa6, 0x46, 0x74, 0x9a, 0x3b, 0xc9, 0x76, 0x4f, 0xb1, 0x85, 0x1d, 0x9d, 0xa2, 0xcb, 0x30, 0x17, - 0x6d, 0x23, 0xee, 0xe4, 0xd2, 0xac, 0x83, 0xb3, 0x61, 0x07, 0x71, 0x07, 0x5d, 0x81, 0x79, 0xd2, - 0xd4, 0x49, 0x23, 0x22, 0xf6, 0x1e, 0x13, 0xcb, 0x06, 0xcb, 0x5c, 0xee, 0x36, 0x9c, 0x0b, 0xa1, - 0xce, 0xb6, 0x34, 0x62, 0x99, 0x4c, 0xfe, 0x14, 0x93, 0x5f, 0xec, 0x6d, 0xef, 0xf8, 0xbb, 0x3b, - 0x96, 0xe9, 0xab, 0xbd, 0x80, 0xac, 0xe1, 0xec, 0x61, 0x5b, 0xb7, 0xa9, 0x2f, 0x4f, 0x72, 0x33, - 0xec, 0x64, 0xdc, 0x4c, 0xe8, 0xfe, 0x03, 0x21, 0xbb, 0x59, 0xd3, 0x5d, 0xdf, 0x92, 0x65, 0xda, - 0x3a, 0x6d, 0x7b, 0x98, 0xa8, 0xb3, 0x81, 0x99, 0x1d, 0xcb, 0x24, 0xe8, 0x3a, 0xa0, 0x20, 0x37, - 0xa7, 0x4d, 0xdd, 0x36, 0xd5, 0xac, 0x5a, 0x27, 0x07, 0xec, 0xab, 0x3a, 0x40, 0xe8, 0x33, 0xb6, - 0xf1, 0xa4, 0xc6, 0xee, 0x53, 0x9d, 0x31, 0x73, 0x2e, 0x73, 0x51, 0x5a, 0x3d, 0xa5, 0x8a, 0x5f, - 0xa8, 0x00, 0x19, 0xfe, 0x25, 0xa3, 0xd5, 0x30, 0x31, 0x72, 0xb3, 0x9c, 0x58, 0xf8, 0xd2, 0x16, - 0x26, 0x06, 0xfa, 0x00, 0xe6, 0xda, 0x76, 0xd5, 0xb1, 0x6b, 0xac, 0x3a, 0x56, 0x0b, 0xe7, 0xb2, - 0xcc, 0x45, 0xb6, 0xb7, 0xfa, 0xdc, 0x6a, 0x61, 0x64, 0xc0, 0x99, 0xb6, 0x1d, 0x22, 0x5c, 0xf3, - 0x04, 0x1a, 0x73, 0x73, 0x0c, 0xea, 0xc5, 0x64, 0xa8, 0xbf, 0x88, 0xa8, 0xf5, 0xc0, 0xbe, 0xd8, - 0x8e, 0x59, 0xf5, 0x63, 0xe1, 0x1f, 0xf4, 0x5a, 0xf0, 0x88, 0x98, 0xe7, 0xb1, 0xf0, 0x55, 0xf1, - 0x64, 0x90, 0xbf, 0x98, 0x86, 0x73, 0x09, 0x86, 0xd1, 0x2a, 0x2c, 0x44, 0xd2, 0xe9, 0x44, 0x4e, - 0x75, 0x98, 0x26, 0xef, 0xf6, 0xf7, 0x61, 0x29, 0xec, 0x76, 0xa8, 0x13, 0x74, 0x7c, 0x8a, 0x29, - 0xe5, 0x7a, 0x22, 0x2f, 0x02, 0x09, 0xd1, 0x75, 0x03, 0x96, 0x7a, 0x5d, 0xef, 0xd7, 0x66, 0x67, - 0x68, 0x9a, 0x61, 0xe0, 0x72, 0x42, 0x59, 0x7a, 0x4d, 0x7f, 0x62, 0xd7, 0x1d, 0x35, 0x17, 0x18, - 0x8a, 0xfa, 0x60, 0xc7, 0x27, 0x06, 0xb9, 0xa9, 0x38, 0xe4, 0x7e, 0x0c, 0xf9, 0x01, 0xe4, 0x46, - 0x53, 0x39, 0xc9, 0x54, 0xce, 0xf5, 0x83, 0x37, 0xcc, 0xa4, 0x0e, 0x67, 0x43, 0xfc, 0x46, 0x74, - 0x49, 0x2e, 0x7d, 0x48, 0x20, 0x2f, 0xf6, 0x80, 0x1c, 0x7a, 0x22, 0xb2, 0x01, 0x85, 0x03, 0x6e, - 0x05, 0x74, 0x1f, 0x52, 0x35, 0xdc, 0x3c, 0xdc, 0xa7, 0x2f, 0xd3, 0x94, 0xdf, 0xa5, 0x20, 0x97, - 0xf8, 0x1a, 0x79, 0x08, 0x19, 0xff, 0x14, 0x78, 0x96, 0x1b, 0x61, 0xe9, 0xef, 0x04, 0x97, 0x4b, - 0xe8, 0x81, 0xdf, 0x2c, 0x5b, 0xa1, 0xa8, 0x1a, 0xd5, 0x43, 0xdb, 0x00, 0x86, 0xd3, 0x6a, 0x59, - 0x84, 0x04, 0x57, 0xd4, 0x4c, 0xf9, 0xc6, 0x37, 0xaf, 0x0b, 0x4b, 0xdc, 0x10, 0xa9, 0xed, 0x16, - 0x2d, 0x47, 0x69, 0xe9, 0xb4, 0x51, 0x7c, 0x8a, 0x4d, 0xdd, 0xe8, 0x6e, 0x61, 0xe3, 0xeb, 0x2f, - 0x6e, 0x80, 0xf0, 0xb3, 0x85, 0x0d, 0x35, 0x62, 0x00, 0xdd, 0x05, 0x10, 0x79, 0xfa, 0x9c, 0x3e, - 0xcd, 0x82, 0x2a, 0x04, 0x41, 0xf1, 0xa1, 0x45, 0xb1, 0x37, 0xb4, 0x28, 0x0a, 0x96, 0x9d, 0x11, - 0x2a, 0x95, 0xdd, 0xc8, 0x7d, 0x90, 0x3a, 0x8e, 0xfb, 0xe0, 0x23, 0x98, 0x76, 0x1d, 0x97, 0x81, - 0x26, 0x53, 0x5a, 0x4d, 0x7a, 0x85, 0x7b, 0x8e, 0x53, 0x7f, 0x56, 0xaf, 0x38, 0x84, 0x60, 0x96, - 0x85, 0xea, 0x2b, 0xf9, 0x78, 0x6d, 0xe9, 0x84, 0x62, 0x4f, 0x73, 0xdb, 0x55, 0xcd, 0xd3, 0xed, - 0x9a, 0x20, 0xe4, 0x2c, 0x5f, 0xae, 0xb4, 0xab, 0xaa, 0x6e, 0xd7, 0xd0, 0x1a, 0x2c, 0x78, 0xd8, - 0xb4, 0xfc, 0x25, 0x5c, 0xd3, 0xb0, 0xeb, 0x18, 0x0d, 0x46, 0xc9, 0x29, 0x75, 0x3e, 0x5c, 0x7f, - 0xe8, 0x2f, 0xa3, 0x0d, 0x38, 0xcb, 0x40, 0x89, 0x6b, 0x5a, 0x50, 0x25, 0x71, 0x55, 0x9c, 0x62, - 0x0a, 0x8b, 0x62, 0xb7, 0xcc, 0x37, 0xc5, 0xad, 0xe1, 0x93, 0x67, 0xa0, 0x45, 0x8d, 0x40, 0x63, - 0x86, 0x69, 0x2c, 0x04, 0x1a, 0xd4, 0x10, 0xd2, 0xe1, 0x37, 0x1c, 0x8c, 0xfc, 0x4e, 0xcf, 0x0c, - 0x7d, 0xa7, 0x97, 0x7e, 0x77, 0x1a, 0x4e, 0xb2, 0x4f, 0x03, 0xf4, 0x0b, 0x09, 0xd2, 0x7c, 0x38, - 0x81, 0xd6, 0x12, 0xaa, 0x36, 0x3c, 0xa3, 0xc9, 0x5f, 0x1b, 0x47, 0x94, 0xc3, 0x57, 0xfe, 0xe0, - 0xe7, 0x7f, 0xfb, 0xd7, 0xaf, 0xa7, 0x0a, 0x68, 0x59, 0x19, 0x35, 0x5b, 0x42, 0x7f, 0x94, 0x60, - 0x7e, 0x60, 0xca, 0x82, 0x4a, 0x07, 0xbb, 0x19, 0x9c, 0xe5, 0xe4, 0x6f, 0x4d, 0xa4, 0x23, 0x62, - 0x54, 0x58, 0x8c, 0x6b, 0xe8, 0xea, 0xc8, 0x18, 0x95, 0x57, 0x82, 0xe0, 0xf7, 0xd1, 0x9f, 0x24, - 0x38, 0x3d, 0xf4, 0x9a, 0x40, 0x1b, 0xa3, 0x7c, 0x27, 0x4d, 0x79, 0xf2, 0xb7, 0x27, 0xd4, 0x12, - 0x31, 0xaf, 0xb3, 0x98, 0x3f, 0x44, 0x6b, 0x09, 0x31, 0x0f, 0xbf, 0x63, 0xd0, 0xd7, 0x12, 0x2c, - 0x0c, 0x1a, 0x44, 0xb7, 0x26, 0x71, 0x1f, 0xc4, 0xbc, 0x31, 0x99, 0x92, 0x08, 0x79, 0x87, 0x85, - 0xbc, 0x8d, 0x3e, 0x1b, 0x3b, 0x64, 0xe5, 0x55, 0xdf, 0x13, 0x63, 0x7f, 0x58, 0x04, 0xfd, 0x5e, - 0x82, 0xb9, 0xfe, 0xf1, 0x04, 0x5a, 0x1f, 0x15, 0x5d, 0xec, 0xd4, 0x25, 0x5f, 0x9a, 0x44, 0x45, - 0xa4, 0x53, 0x64, 0xe9, 0xac, 0xa2, 0x2b, 0x4a, 0xe2, 0x44, 0x34, 0xfa, 0xf6, 0x40, 0xff, 0x96, - 0xa0, 0x70, 0xc0, 0x43, 0x14, 0x95, 0x47, 0xc5, 0x31, 0xde, 0xab, 0x3a, 0xff, 0xe0, 0x48, 0x36, - 0x44, 0x72, 0x1f, 0xb1, 0xe4, 0x36, 0x50, 0x69, 0x82, 0x5e, 0x71, 0x02, 0xda, 0x47, 0xff, 0x93, - 0x60, 0x79, 0xe4, 0x28, 0x04, 0xdd, 0x9f, 0x04, 0x3f, 0x71, 0xd3, 0x9a, 0xfc, 0xe6, 0x11, 0x2c, - 0x88, 0x14, 0x2b, 0x2c, 0xc5, 0x4f, 0xd1, 0xe3, 0xc3, 0xc3, 0x91, 0x31, 0x6c, 0x98, 0xf8, 0x7f, - 0x25, 0xb8, 0x30, 0x6a, 0xc6, 0x82, 0xee, 0x4d, 0x12, 0x75, 0xcc, 0xb0, 0x27, 0x7f, 0xff, 0xf0, - 0x06, 0x44, 0xd6, 0x8f, 0x58, 0xd6, 0x9b, 0xe8, 0xde, 0x11, 0xb3, 0x66, 0x8c, 0x3d, 0x30, 0x5f, - 0x18, 0xcd, 0xd8, 0xf1, 0xb3, 0x8a, 0xd1, 0x8c, 0x9d, 0x30, 0xc0, 0x38, 0x90, 0xb1, 0xf5, 0x40, - 0x4f, 0xdc, 0xa2, 0xe8, 0x9d, 0x04, 0x4b, 0x23, 0xa6, 0x07, 0xe8, 0xee, 0x24, 0x85, 0x8d, 0x21, - 0x90, 0x7b, 0x87, 0xd6, 0x17, 0x19, 0x6d, 0xb3, 0x8c, 0x1e, 0xa1, 0x87, 0x87, 0xef, 0x4b, 0x94, - 0x6c, 0xfe, 0x2c, 0x41, 0xb6, 0x8f, 0xb7, 0xd0, 0xcd, 0xb1, 0x29, 0x2e, 0xc8, 0x69, 0x7d, 0x02, - 0x0d, 0x91, 0xc5, 0x16, 0xcb, 0xe2, 0x2e, 0xfa, 0xde, 0x78, 0x9c, 0xa8, 0xbc, 0x8a, 0x19, 0x68, - 0xec, 0x97, 0x9f, 0x7e, 0xf9, 0x66, 0x45, 0xfa, 0xea, 0xcd, 0x8a, 0xf4, 0xcf, 0x37, 0x2b, 0xd2, - 0xaf, 0xde, 0xae, 0x9c, 0xf8, 0xea, 0xed, 0xca, 0x89, 0x7f, 0xbc, 0x5d, 0x39, 0xf1, 0xe3, 0x03, - 0x3f, 0x11, 0x3b, 0x51, 0x87, 0xec, 0x7b, 0xb1, 0x9a, 0x66, 0xff, 0x6e, 0xba, 0xf5, 0xff, 0x00, - 0x00, 0x00, 0xff, 0xff, 0xf5, 0xa2, 0xf3, 0xc9, 0xdc, 0x1b, 0x00, 0x00, + 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x3f, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, + 0x58, 0x98, 0x21, 0x26, 0x50, 0x69, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, + 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x8a, 0x3d, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, + 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0xaa, 0xd4, 0x73, 0x2b, 0xf5, 0xd8, 0x3d, 0x55, + 0xea, 0x7d, 0x7b, 0x5b, 0x6d, 0x0f, 0xad, 0x38, 0xa0, 0x0a, 0xaa, 0x56, 0xaa, 0xd4, 0x6b, 0xcf, + 0xd5, 0xbc, 0xf7, 0xc6, 0x33, 0xb6, 0x67, 0x1c, 0x3b, 0xc9, 0xde, 0xe2, 0x79, 0xdf, 0xff, 0xef, + 0xf7, 0x7e, 0xef, 0xbd, 0x2f, 0x70, 0xa9, 0x62, 0x56, 0x3a, 0x0d, 0xe2, 0xea, 0x15, 0x66, 0x51, + 0x66, 0xee, 0x38, 0xae, 0xad, 0xef, 0xae, 0xe9, 0x2f, 0x5b, 0xd8, 0xef, 0x68, 0x9e, 0x4f, 0x18, + 0x41, 0x67, 0xa4, 0x88, 0x16, 0x89, 0x68, 0xbb, 0x6b, 0xb9, 0x45, 0x9b, 0xd8, 0x84, 0x4b, 0xe8, + 0xc1, 0x5f, 0x42, 0x38, 0x77, 0xc1, 0x26, 0xc4, 0x6e, 0x60, 0xdd, 0xf4, 0x1c, 0xdd, 0x74, 0x5d, + 0xc2, 0x4c, 0xe6, 0x10, 0x97, 0xca, 0xd5, 0xf3, 0x16, 0xa1, 0x4d, 0x42, 0xcb, 0x42, 0x4d, 0xfc, + 0x90, 0x4b, 0xaa, 0xf8, 0xa5, 0x5b, 0x7e, 0xc7, 0x63, 0x44, 0xa7, 0xd8, 0xf2, 0x0a, 0x77, 0xee, + 0xee, 0xac, 0xe9, 0x3b, 0xb8, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x15, 0xcc, 0xcc, 0xb5, + 0xf0, 0xb7, 0x94, 0xba, 0x2e, 0xa5, 0x2a, 0x26, 0xc5, 0x22, 0x91, 0xae, 0xa0, 0x67, 0xda, 0x8e, + 0xcb, 0x23, 0x0a, 0xbd, 0x26, 0xa7, 0xef, 0x99, 0xbe, 0xd9, 0x0c, 0xbd, 0x5e, 0x49, 0x96, 0x89, + 0x55, 0x43, 0xc8, 0xe5, 0x53, 0x6c, 0x11, 0x4f, 0x08, 0xa8, 0x8b, 0x80, 0xbe, 0x17, 0x84, 0x53, + 0xe2, 0xd6, 0x0d, 0xfc, 0xb2, 0x85, 0x29, 0x53, 0x0d, 0x78, 0xaf, 0xe7, 0x2b, 0xf5, 0x88, 0x4b, + 0x31, 0xfa, 0x08, 0x32, 0x22, 0x8a, 0xac, 0x72, 0x51, 0x59, 0x9d, 0x29, 0x2c, 0x6b, 0x89, 0x6d, + 0xd0, 0x84, 0x5a, 0x71, 0xea, 0xcb, 0x37, 0xf9, 0x63, 0x86, 0x54, 0x51, 0xbf, 0x0d, 0x4b, 0x31, + 0x9b, 0xc5, 0xce, 0xf7, 0xb1, 0x4f, 0x1d, 0xe2, 0x4a, 0x97, 0x28, 0x0b, 0x27, 0x76, 0xc5, 0x17, + 0x6e, 0x7c, 0xce, 0x08, 0x7f, 0xaa, 0x9f, 0xc3, 0x85, 0x64, 0xc5, 0xa3, 0x88, 0xca, 0x86, 0x65, + 0x6e, 0xfc, 0x13, 0xc7, 0x35, 0x1b, 0x0e, 0xeb, 0x94, 0x7c, 0xb2, 0xeb, 0x54, 0xb1, 0x1f, 0x96, + 0x02, 0x7d, 0x02, 0x10, 0x75, 0x48, 0x7a, 0xb8, 0xa2, 0x49, 0x98, 0x04, 0xed, 0xd4, 0x04, 0x2e, + 0x65, 0x3b, 0xb5, 0x92, 0x69, 0x63, 0xa9, 0x6b, 0xc4, 0x34, 0xd5, 0xbf, 0x28, 0xb0, 0x92, 0xe6, + 0x49, 0x26, 0xf2, 0x63, 0x40, 0x35, 0xb9, 0x18, 0xa0, 0x51, 0xac, 0x66, 0x95, 0x8b, 0x93, 0xab, + 0x33, 0x05, 0x3d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xe3, 0x74, 0xad, 0xdf, 0x0f, 0x7a, 0xd4, + 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0x36, 0x64, 0x47, 0x06, + 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0xb9, 0x9a, 0x57, 0xae, 0x30, 0xab, 0xec, 0xed, 0x94, 0xeb, 0xb8, + 0xcd, 0xcb, 0x36, 0x6d, 0x40, 0xcd, 0x2b, 0x32, 0xab, 0xb4, 0xf3, 0x18, 0xb7, 0xd5, 0xbd, 0x94, + 0xba, 0x77, 0x8b, 0xf1, 0x23, 0x38, 0x3d, 0x50, 0x0c, 0x59, 0xfe, 0xb1, 0x6b, 0xb1, 0xd0, 0x5f, + 0x0b, 0xf5, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xe2, 0xf3, 0x87, 0x9b, 0xb8, 0x81, 0x6d, 0x41, 0x09, + 0x61, 0x02, 0x45, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x80, 0xd4, 0x7c, 0xe1, 0x7a, 0x8a, 0xc7, 0x1e, + 0xed, 0x6d, 0xae, 0x61, 0x48, 0xcd, 0x3e, 0xe0, 0x4c, 0x1c, 0x18, 0x38, 0x7f, 0x56, 0xe4, 0xc6, + 0xe9, 0x0f, 0x55, 0x16, 0xea, 0x05, 0x9c, 0x0a, 0x2a, 0x5d, 0x8d, 0x96, 0x24, 0x64, 0x6e, 0x8c, + 0x12, 0x74, 0xb7, 0x46, 0xf3, 0x15, 0x66, 0xc5, 0xcc, 0x1f, 0x1d, 0x58, 0x6a, 0x70, 0x2d, 0xb1, + 0xd3, 0x25, 0xf2, 0x13, 0xec, 0x6f, 0xb0, 0xc7, 0xd8, 0xb1, 0xeb, 0x6c, 0x74, 0xe4, 0xa0, 0xb3, + 0x90, 0xa9, 0x73, 0x1d, 0x1e, 0xd4, 0x94, 0x21, 0x7f, 0xa9, 0xcf, 0xe0, 0xfa, 0x28, 0x7e, 0x64, + 0xd5, 0x2e, 0xc1, 0xec, 0x2e, 0x61, 0x8e, 0x6b, 0x97, 0xbd, 0x60, 0x9d, 0xfb, 0x99, 0x32, 0x66, + 0xc4, 0x37, 0xae, 0xa2, 0x6e, 0xc1, 0x6a, 0xa2, 0xc1, 0x87, 0x2d, 0xdf, 0xc7, 0x2e, 0xe3, 0x42, + 0x63, 0x20, 0x3e, 0xad, 0x0e, 0xbd, 0xe6, 0x64, 0x78, 0x51, 0x92, 0x4a, 0x3c, 0xc9, 0x81, 0xb0, + 0x27, 0x06, 0xc3, 0xfe, 0xb9, 0x02, 0x1f, 0x70, 0x47, 0x1b, 0x16, 0x73, 0x76, 0xf1, 0x00, 0xdd, + 0xf4, 0x97, 0x3c, 0xcd, 0xd5, 0x51, 0xe1, 0xf7, 0x6f, 0x0a, 0xdc, 0x18, 0x2d, 0x9e, 0x23, 0xa4, + 0xc1, 0x1f, 0x38, 0xac, 0xbe, 0x85, 0x99, 0xf9, 0x8d, 0xd2, 0xe0, 0xb2, 0xdc, 0x98, 0x3c, 0x31, + 0x93, 0xe1, 0x6a, 0x4f, 0x61, 0xd5, 0xbb, 0x92, 0x25, 0x07, 0x96, 0x87, 0xf7, 0x58, 0xfd, 0x95, + 0x02, 0x57, 0x13, 0x91, 0x92, 0x40, 0x54, 0x23, 0xec, 0x97, 0xa3, 0xea, 0xe3, 0xbf, 0x95, 0x94, + 0xfd, 0x90, 0x44, 0x4a, 0x3e, 0x9c, 0x8f, 0x91, 0x12, 0xf1, 0x13, 0xe8, 0xe9, 0xee, 0xbe, 0xf4, + 0x44, 0x92, 0x4c, 0x1b, 0xe7, 0x22, 0xa2, 0xea, 0x11, 0x38, 0xba, 0xbe, 0x7e, 0x0a, 0xe7, 0x07, + 0x09, 0x37, 0xac, 0xf8, 0x4d, 0x78, 0x4f, 0x06, 0x5b, 0x66, 0xed, 0x72, 0xdd, 0xa4, 0xf5, 0x58, + 0xdd, 0x17, 0xe4, 0xd2, 0xf3, 0xf6, 0x63, 0x93, 0xd6, 0x83, 0x5d, 0xff, 0x32, 0xe9, 0x9c, 0xe9, + 0x96, 0x69, 0x1b, 0xe6, 0x7b, 0xb9, 0x5b, 0x9e, 0x70, 0xe3, 0x51, 0xf7, 0x5c, 0x0f, 0x75, 0xab, + 0xbf, 0xce, 0xc0, 0x99, 0x64, 0x77, 0x5b, 0x90, 0x11, 0x50, 0xe1, 0x6e, 0x66, 0x8b, 0x77, 0x5f, + 0xbf, 0xc9, 0x17, 0x6c, 0x87, 0xd5, 0x5b, 0x15, 0xcd, 0x22, 0x4d, 0x5d, 0x3a, 0xb5, 0xea, 0xa6, + 0xe3, 0x86, 0x3f, 0x74, 0xd6, 0xf1, 0x30, 0xd5, 0x8a, 0x4f, 0x4a, 0xb7, 0xd7, 0x6f, 0x95, 0x5a, + 0x95, 0xcf, 0x70, 0xc7, 0x38, 0x5e, 0x09, 0xc0, 0x85, 0x3e, 0x87, 0xf9, 0x08, 0x7c, 0x0d, 0x87, + 0x06, 0x8c, 0x3c, 0x79, 0x08, 0xb3, 0x33, 0x12, 0xb5, 0x4f, 0x1d, 0x8e, 0xec, 0x59, 0xca, 0x4c, + 0x9f, 0x95, 0xe5, 0x1e, 0x99, 0x14, 0x4c, 0xc7, 0xbf, 0x89, 0x8d, 0x84, 0x96, 0x01, 0xb0, 0x5b, + 0x0d, 0x05, 0xa6, 0xb8, 0xc0, 0x34, 0x76, 0xe5, 0x3e, 0x43, 0x4b, 0x30, 0xcd, 0x08, 0x33, 0x1b, + 0x65, 0x6a, 0xb2, 0xec, 0x71, 0xbe, 0x7a, 0x92, 0x7f, 0xd8, 0x36, 0x19, 0xba, 0x0c, 0xf3, 0xf1, + 0x36, 0xe2, 0x76, 0x36, 0xc3, 0x3b, 0x38, 0x1b, 0x75, 0x10, 0xb7, 0xd1, 0x15, 0x38, 0x45, 0x1b, + 0x26, 0xad, 0xc7, 0xc4, 0x4e, 0x70, 0xb1, 0xb9, 0xf0, 0xb3, 0x90, 0xbb, 0x03, 0xe7, 0x22, 0xa8, + 0xf3, 0xa5, 0x32, 0x75, 0x6c, 0x2e, 0x7f, 0x92, 0xcb, 0x2f, 0x76, 0x97, 0xb7, 0x83, 0xd5, 0x6d, + 0xc7, 0x0e, 0xd4, 0x5e, 0xc0, 0x9c, 0x45, 0x76, 0xb1, 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0xd9, 0x69, + 0xbe, 0x33, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0xdd, 0xa8, 0x9a, 0x5e, 0x60, 0xc9, 0xb1, 0x5d, + 0x93, 0xb5, 0x7c, 0x4c, 0x8d, 0xd9, 0xd0, 0xcc, 0xb6, 0x63, 0x53, 0x74, 0x03, 0x50, 0x98, 0x1b, + 0x69, 0x31, 0xaf, 0xc5, 0xca, 0x4e, 0xb5, 0x9d, 0x05, 0x7e, 0xab, 0x0e, 0x11, 0xfa, 0x8c, 0x2f, + 0x3c, 0xa9, 0xf2, 0xf3, 0xd4, 0xe4, 0xcc, 0x9c, 0x9d, 0xb9, 0xa8, 0xac, 0x9e, 0x34, 0xe4, 0x2f, + 0x94, 0x87, 0x19, 0x71, 0x93, 0x29, 0x57, 0x31, 0xb5, 0xb2, 0xb3, 0x82, 0x58, 0xc4, 0xa7, 0x4d, + 0x4c, 0x2d, 0xf4, 0x3e, 0xcc, 0xb7, 0xdc, 0x0a, 0x71, 0xab, 0xbc, 0x3a, 0x4e, 0x13, 0x67, 0xe7, + 0xb8, 0x8b, 0xb9, 0xee, 0xd7, 0xe7, 0x4e, 0x13, 0x23, 0x0b, 0xce, 0xb4, 0xdc, 0x08, 0xe1, 0x65, + 0x5f, 0xa2, 0x31, 0x3b, 0xcf, 0xa1, 0xae, 0xa5, 0x43, 0xfd, 0x45, 0x4c, 0xad, 0x0b, 0xf6, 0xc5, + 0x56, 0xc2, 0xd7, 0x20, 0x16, 0x71, 0xa1, 0x2f, 0x87, 0x8f, 0x88, 0x53, 0x22, 0x16, 0xf1, 0x55, + 0x3e, 0x19, 0xd4, 0x2f, 0x26, 0xe1, 0x5c, 0x8a, 0x61, 0xb4, 0x0a, 0x0b, 0xb1, 0x74, 0xda, 0xb1, + 0x5d, 0x1d, 0xa5, 0x29, 0xba, 0xfd, 0x5d, 0x58, 0x8a, 0xba, 0x1d, 0xe9, 0x84, 0x1d, 0x9f, 0xe0, + 0x4a, 0xd9, 0xae, 0xc8, 0x8b, 0x50, 0x42, 0x76, 0xdd, 0x82, 0xa5, 0x6e, 0xd7, 0x7b, 0xb5, 0xf9, + 0x1e, 0x9a, 0xe4, 0x18, 0xb8, 0x9c, 0x52, 0x96, 0x6e, 0xd3, 0x9f, 0xb8, 0x35, 0x62, 0x64, 0x43, + 0x43, 0x71, 0x1f, 0x7c, 0xfb, 0x24, 0x20, 0x77, 0x2a, 0x09, 0xb9, 0x1f, 0x41, 0xae, 0x0f, 0xb9, + 0xf1, 0x54, 0x8e, 0x73, 0x95, 0x73, 0xbd, 0xe0, 0x8d, 0x32, 0xa9, 0xc1, 0xd9, 0x08, 0xbf, 0x31, + 0x5d, 0x9a, 0xcd, 0x1c, 0x10, 0xc8, 0x8b, 0x5d, 0x20, 0x47, 0x9e, 0xa8, 0x6a, 0x41, 0x7e, 0x9f, + 0x53, 0x01, 0x3d, 0x80, 0xa9, 0x2a, 0x6e, 0x1c, 0xec, 0xea, 0xcb, 0x35, 0xd5, 0xdf, 0x4c, 0x41, + 0x36, 0xf5, 0x35, 0xf2, 0x31, 0xcc, 0x04, 0xbb, 0xc0, 0x77, 0xbc, 0x18, 0x4b, 0x7f, 0x2b, 0x3c, + 0x5c, 0x22, 0x0f, 0xe2, 0x64, 0xd9, 0x8c, 0x44, 0x8d, 0xb8, 0x1e, 0xda, 0x02, 0xb0, 0x48, 0xb3, + 0xe9, 0x50, 0x1a, 0x1e, 0x51, 0xd3, 0xc5, 0x9b, 0xaf, 0xdf, 0xe4, 0x97, 0x84, 0x21, 0x5a, 0xdd, + 0xd1, 0x1c, 0xa2, 0x37, 0x4d, 0x56, 0xd7, 0x9e, 0x62, 0xdb, 0xb4, 0x3a, 0x9b, 0xd8, 0xfa, 0xfa, + 0x8b, 0x9b, 0x20, 0xfd, 0x6c, 0x62, 0xcb, 0x88, 0x19, 0x40, 0xf7, 0x00, 0x64, 0x9e, 0x01, 0xa7, + 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0x68, 0xa1, 0x75, 0x87, 0x16, 0x9a, 0x64, 0xd9, 0x69, + 0xa9, 0x52, 0xda, 0x89, 0x9d, 0x07, 0x53, 0x47, 0x71, 0x1e, 0x7c, 0x08, 0x93, 0x1e, 0xf1, 0x38, + 0x68, 0x66, 0x0a, 0xab, 0x69, 0xaf, 0x70, 0x9f, 0x90, 0xda, 0xb3, 0x5a, 0x89, 0x50, 0x8a, 0x79, + 0x16, 0x46, 0xa0, 0x84, 0xd6, 0xe1, 0x2c, 0x47, 0x10, 0xae, 0x96, 0xc3, 0x94, 0x24, 0xaf, 0x67, + 0x38, 0x73, 0x2f, 0xca, 0xd5, 0xa2, 0x58, 0x94, 0x14, 0x1f, 0x30, 0x5d, 0xa8, 0xc5, 0xac, 0x50, + 0xe3, 0x04, 0xd7, 0x58, 0x08, 0x35, 0x98, 0x25, 0xa5, 0xa3, 0x0b, 0xd7, 0xc9, 0xa1, 0x97, 0xea, + 0xe9, 0x81, 0x4b, 0x75, 0xe1, 0xb7, 0xa7, 0xe1, 0x38, 0x3f, 0xc7, 0xd1, 0xcf, 0x14, 0xc8, 0x88, + 0x49, 0x02, 0xba, 0x96, 0x92, 0xe2, 0xe0, 0x40, 0x25, 0x77, 0x7d, 0x14, 0x51, 0x81, 0x35, 0xf5, + 0xfd, 0x9f, 0xfe, 0xf5, 0x9f, 0xbf, 0x9c, 0xc8, 0xa3, 0x65, 0x7d, 0xd8, 0x20, 0x08, 0xfd, 0x41, + 0x81, 0x53, 0x7d, 0x23, 0x11, 0x54, 0xd8, 0xdf, 0x4d, 0xff, 0xe0, 0x25, 0x77, 0x7b, 0x2c, 0x1d, + 0x19, 0xa3, 0xce, 0x63, 0xbc, 0x86, 0xae, 0x0e, 0x8d, 0x51, 0x7f, 0x25, 0xd9, 0x78, 0x0f, 0xfd, + 0x51, 0x81, 0xd3, 0x03, 0x57, 0x7f, 0xb4, 0x3e, 0xcc, 0x77, 0xda, 0x48, 0x26, 0x77, 0x67, 0x4c, + 0x2d, 0x19, 0xf3, 0x1a, 0x8f, 0xf9, 0x03, 0x74, 0x2d, 0x25, 0xe6, 0xc1, 0x47, 0x07, 0xfa, 0x5a, + 0x81, 0x85, 0x7e, 0x83, 0xe8, 0xf6, 0x38, 0xee, 0xc3, 0x98, 0xd7, 0xc7, 0x53, 0x92, 0x21, 0x6f, + 0xf3, 0x90, 0xb7, 0xd0, 0x67, 0x23, 0x87, 0xac, 0xbf, 0xea, 0x79, 0x0f, 0xec, 0x0d, 0x8a, 0xa0, + 0xdf, 0x29, 0x30, 0xdf, 0x3b, 0x4b, 0x40, 0x6b, 0xc3, 0xa2, 0x4b, 0x1c, 0x91, 0xe4, 0x0a, 0xe3, + 0xa8, 0xc8, 0x74, 0x34, 0x9e, 0xce, 0x2a, 0xba, 0xa2, 0xa7, 0x8e, 0x2f, 0xe3, 0x0f, 0x05, 0xf4, + 0x2f, 0x05, 0xf2, 0xfb, 0xbc, 0x1a, 0x51, 0x71, 0x58, 0x1c, 0xa3, 0x3d, 0x81, 0x73, 0x0f, 0x0f, + 0x65, 0x43, 0x26, 0xf7, 0x21, 0x4f, 0x6e, 0x1d, 0x15, 0xc6, 0xe8, 0x95, 0x20, 0xa0, 0x3d, 0xf4, + 0x3f, 0x05, 0x96, 0x87, 0xce, 0x2d, 0xd0, 0x83, 0x71, 0xf0, 0x93, 0x34, 0x5a, 0xc9, 0x6d, 0x1c, + 0xc2, 0x82, 0x4c, 0xb1, 0xc4, 0x53, 0xfc, 0x14, 0x3d, 0x3e, 0x38, 0x1c, 0x39, 0xc3, 0x46, 0x89, + 0xff, 0x47, 0x81, 0x0b, 0xc3, 0x06, 0x22, 0xe8, 0xfe, 0x38, 0x51, 0x27, 0x4c, 0x66, 0x72, 0x0f, + 0x0e, 0x6e, 0x40, 0x66, 0xfd, 0x88, 0x67, 0xbd, 0x81, 0xee, 0x1f, 0x32, 0x6b, 0xce, 0xd8, 0x7d, + 0xc3, 0x80, 0xe1, 0x8c, 0x9d, 0x3c, 0x58, 0x18, 0xce, 0xd8, 0x29, 0xd3, 0x86, 0x7d, 0x19, 0xdb, + 0x0c, 0xf5, 0xe4, 0x29, 0x8a, 0xfe, 0xab, 0xc0, 0xd2, 0x90, 0xa7, 0x3e, 0xba, 0x37, 0x4e, 0x61, + 0x13, 0x08, 0xe4, 0xfe, 0x81, 0xf5, 0x65, 0x46, 0x5b, 0x3c, 0xa3, 0x47, 0xe8, 0xe3, 0x83, 0xf7, + 0x25, 0x4e, 0x36, 0x7f, 0x52, 0x60, 0xae, 0x87, 0xb7, 0xd0, 0xad, 0x91, 0x29, 0x2e, 0xcc, 0x69, + 0x6d, 0x0c, 0x0d, 0x99, 0xc5, 0x26, 0xcf, 0xe2, 0x1e, 0xfa, 0xce, 0x68, 0x9c, 0xa8, 0xbf, 0x4a, + 0x98, 0x3e, 0xec, 0x15, 0x9f, 0x7e, 0xf9, 0x76, 0x45, 0xf9, 0xea, 0xed, 0x8a, 0xf2, 0x8f, 0xb7, + 0x2b, 0xca, 0x2f, 0xde, 0xad, 0x1c, 0xfb, 0xea, 0xdd, 0xca, 0xb1, 0xbf, 0xbf, 0x5b, 0x39, 0xf6, + 0xc3, 0x7d, 0xef, 0x73, 0xed, 0xb8, 0x43, 0x7e, 0xb9, 0xab, 0x64, 0xf8, 0xff, 0x86, 0x6e, 0xff, + 0x3f, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x9b, 0xda, 0xbf, 0x89, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3276,34 +3254,22 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error if m.VotingPower != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) i-- - dAtA[i] = 0x58 + dAtA[i] = 0x48 } if m.Height != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Height)) i-- - dAtA[i] = 0x50 + dAtA[i] = 0x40 } if m.SlashedBtcHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBtcHeight)) i-- - dAtA[i] = 0x48 + dAtA[i] = 0x38 } if m.SlashedBabylonHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SlashedBabylonHeight)) i-- - dAtA[i] = 0x40 - } - if m.RegisteredEpoch != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.RegisteredEpoch)) - i-- - dAtA[i] = 0x38 - } - if len(m.MasterPubRand) > 0 { - i -= len(m.MasterPubRand) - copy(dAtA[i:], m.MasterPubRand) - i = encodeVarintQuery(dAtA, i, uint64(len(m.MasterPubRand))) - i-- - dAtA[i] = 0x32 + dAtA[i] = 0x30 } if m.Pop != nil { { @@ -3833,13 +3799,6 @@ func (m *FinalityProviderResponse) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovQuery(uint64(l)) } - l = len(m.MasterPubRand) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.RegisteredEpoch != 0 { - n += 1 + sovQuery(uint64(m.RegisteredEpoch)) - } if m.SlashedBabylonHeight != 0 { n += 1 + sovQuery(uint64(m.SlashedBabylonHeight)) } @@ -6826,57 +6785,6 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - 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 ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MasterPubRand = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field RegisteredEpoch", wireType) - } - m.RegisteredEpoch = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.RegisteredEpoch |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBabylonHeight", wireType) } @@ -6895,7 +6803,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 9: + case 7: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SlashedBtcHeight", wireType) } @@ -6914,7 +6822,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 10: + case 8: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } @@ -6933,7 +6841,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - case 11: + case 9: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field VotingPower", wireType) } diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index 46631347f..e1c979153 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -49,9 +49,6 @@ type MsgCreateFinalityProvider struct { BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,5,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossession `protobuf:"bytes,6,opt,name=pop,proto3" json:"pop,omitempty"` - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - MasterPubRand string `protobuf:"bytes,7,opt,name=master_pub_rand,json=masterPubRand,proto3" json:"master_pub_rand,omitempty"` } func (m *MsgCreateFinalityProvider) Reset() { *m = MsgCreateFinalityProvider{} } @@ -115,13 +112,6 @@ func (m *MsgCreateFinalityProvider) GetPop() *ProofOfPossession { return nil } -func (m *MsgCreateFinalityProvider) GetMasterPubRand() string { - if m != nil { - return m.MasterPubRand - } - return "" -} - // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider type MsgCreateFinalityProviderResponse struct { } @@ -880,89 +870,88 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1307 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x13, 0xc7, - 0x1b, 0xce, 0xc6, 0x89, 0xf9, 0xe5, 0x75, 0x9c, 0xe4, 0xb7, 0x84, 0xb0, 0xd9, 0x82, 0x9d, 0x04, - 0x0a, 0x01, 0x35, 0x6b, 0x12, 0x4a, 0xd4, 0x82, 0x54, 0x09, 0x27, 0x41, 0xa0, 0x62, 0xd5, 0x5a, - 0x27, 0x3d, 0xb4, 0x07, 0x6b, 0xbd, 0x3b, 0x59, 0x8f, 0x6c, 0xef, 0xac, 0x76, 0xc6, 0x96, 0xad, - 0x4a, 0x55, 0x85, 0x7a, 0xad, 0xd4, 0x53, 0x0f, 0xfd, 0x14, 0x1c, 0xf8, 0x08, 0x3d, 0xd0, 0x1b, - 0xe2, 0x54, 0xa5, 0x52, 0x54, 0x41, 0x25, 0x0e, 0x3d, 0xf7, 0x5e, 0xed, 0xec, 0xec, 0x1f, 0xbb, - 0xde, 0x92, 0x10, 0x6e, 0xde, 0x99, 0xe7, 0xfd, 0xf7, 0xbc, 0xcf, 0xbc, 0x33, 0x86, 0x42, 0xc3, - 0x68, 0x0c, 0xda, 0xc4, 0x29, 0x35, 0x98, 0x49, 0x99, 0xd1, 0xc2, 0x8e, 0x5d, 0xea, 0x6d, 0x96, - 0x58, 0x5f, 0x73, 0x3d, 0xc2, 0x88, 0x7c, 0x41, 0xec, 0x6b, 0xf1, 0xbe, 0xd6, 0xdb, 0x54, 0x17, - 0x6d, 0x62, 0x13, 0x8e, 0x28, 0xf9, 0xbf, 0x02, 0xb0, 0xba, 0x6c, 0x12, 0xda, 0x21, 0xb4, 0x1e, - 0x6c, 0x04, 0x1f, 0x62, 0xeb, 0x62, 0xf0, 0x55, 0xea, 0x50, 0xee, 0xbf, 0x43, 0x6d, 0xb1, 0xb1, - 0x26, 0x36, 0x4c, 0x6f, 0xe0, 0x32, 0x52, 0xa2, 0xc8, 0x74, 0xb7, 0xee, 0x6c, 0xb7, 0x36, 0x4b, - 0x2d, 0x34, 0x08, 0x8d, 0xd7, 0xc6, 0x27, 0xe9, 0x1a, 0x9e, 0xd1, 0x09, 0x31, 0x1f, 0x25, 0x30, - 0x66, 0x13, 0x99, 0x2d, 0x97, 0x60, 0x87, 0xf9, 0xb0, 0xa1, 0x05, 0x81, 0xbe, 0x2a, 0xa2, 0xc6, - 0xde, 0x1a, 0x88, 0x19, 0x9b, 0xe1, 0xb7, 0x40, 0x15, 0x53, 0xe2, 0x12, 0x37, 0x00, 0xac, 0xfd, - 0x9a, 0x81, 0xe5, 0x0a, 0xb5, 0x77, 0x3c, 0x64, 0x30, 0xf4, 0x00, 0x3b, 0x46, 0x1b, 0xb3, 0x41, - 0xd5, 0x23, 0x3d, 0x6c, 0x21, 0x4f, 0x5e, 0x82, 0x2c, 0xc5, 0xb6, 0x83, 0x3c, 0x45, 0x5a, 0x91, - 0xd6, 0x67, 0x74, 0xf1, 0x25, 0xef, 0x41, 0xce, 0x42, 0xd4, 0xf4, 0xb0, 0xcb, 0x30, 0x71, 0x94, - 0xc9, 0x15, 0x69, 0x3d, 0xb7, 0x75, 0x45, 0x13, 0x7c, 0xc5, 0x2c, 0xf3, 0x94, 0xb4, 0xdd, 0x18, - 0xaa, 0x27, 0xed, 0xe4, 0x0a, 0x80, 0x49, 0x3a, 0x1d, 0x4c, 0xa9, 0xef, 0x25, 0xe3, 0x87, 0x28, - 0x6f, 0x1c, 0x1d, 0x17, 0x3f, 0x08, 0x1c, 0x51, 0xab, 0xa5, 0x61, 0x52, 0xea, 0x18, 0xac, 0xa9, - 0x3d, 0x46, 0xb6, 0x61, 0x0e, 0x76, 0x91, 0xf9, 0xf2, 0xd9, 0x06, 0x88, 0x38, 0xbb, 0xc8, 0xd4, - 0x13, 0x0e, 0xe4, 0xcf, 0x00, 0x44, 0xb9, 0x75, 0xb7, 0xa5, 0x4c, 0xf1, 0xa4, 0x8a, 0x61, 0x52, - 0x41, 0x77, 0xb4, 0xa8, 0x3b, 0x5a, 0xb5, 0xdb, 0xf8, 0x1c, 0x0d, 0xf4, 0x19, 0x61, 0x52, 0x6d, - 0xc9, 0x15, 0xc8, 0x36, 0x98, 0xe9, 0xdb, 0x4e, 0xaf, 0x48, 0xeb, 0xb3, 0xe5, 0xed, 0xa3, 0xe3, - 0xe2, 0x96, 0x8d, 0x59, 0xb3, 0xdb, 0xd0, 0x4c, 0xd2, 0x29, 0x09, 0xa4, 0xd9, 0x34, 0xb0, 0x13, - 0x7e, 0x94, 0xd8, 0xc0, 0x45, 0x54, 0x2b, 0x3f, 0xaa, 0xde, 0xfe, 0xf8, 0x96, 0x70, 0x39, 0xdd, - 0x60, 0x66, 0xb5, 0x25, 0xdf, 0x85, 0x8c, 0x4b, 0x5c, 0x25, 0xcb, 0xf3, 0x58, 0xd7, 0xc6, 0xca, - 0x50, 0xab, 0x7a, 0x84, 0x1c, 0x7e, 0x71, 0x58, 0x25, 0x94, 0x22, 0x5e, 0x85, 0xee, 0x1b, 0xc9, - 0xd7, 0x60, 0xbe, 0x63, 0x50, 0x86, 0xbc, 0xba, 0xdb, 0x6d, 0xd4, 0x3d, 0xc3, 0xb1, 0x94, 0x73, - 0xbc, 0x03, 0xf9, 0x60, 0xb9, 0xda, 0x6d, 0xe8, 0x86, 0x63, 0xdd, 0xcd, 0x3d, 0x79, 0xf3, 0xf4, - 0xa6, 0xe8, 0xca, 0xda, 0x15, 0x58, 0x4d, 0x6d, 0xa5, 0x8e, 0xa8, 0x4b, 0x1c, 0x8a, 0xd6, 0xfe, - 0x92, 0xe0, 0x62, 0x85, 0xda, 0x7b, 0x16, 0x66, 0x27, 0x6e, 0xf7, 0x85, 0x88, 0x18, 0xbf, 0xd3, - 0xb3, 0x61, 0x81, 0x23, 0x2a, 0xc8, 0xbc, 0x17, 0x15, 0x4c, 0x9d, 0x51, 0x05, 0xc3, 0x94, 0xac, - 0x42, 0x31, 0xa5, 0xd8, 0x88, 0x90, 0xdf, 0xcf, 0xc1, 0x52, 0x44, 0x5b, 0x79, 0x7f, 0x67, 0x17, - 0xb5, 0x91, 0x6d, 0xf0, 0xcc, 0xd2, 0xf8, 0x18, 0x16, 0xda, 0xe4, 0xa9, 0x85, 0x26, 0x94, 0x91, - 0x79, 0x17, 0x65, 0xc4, 0x22, 0x9d, 0x7a, 0x1f, 0x22, 0xfd, 0x1a, 0xe6, 0x0e, 0xdd, 0x7a, 0xe0, - 0xb1, 0xde, 0xc6, 0x94, 0x29, 0xd3, 0x2b, 0x99, 0x33, 0xb8, 0xcd, 0x1d, 0xba, 0x65, 0xdf, 0xf1, - 0x63, 0x4c, 0x99, 0xbc, 0x0a, 0xb3, 0xa2, 0xa0, 0x3a, 0xc3, 0x1d, 0xc4, 0x8f, 0x42, 0x5e, 0xcf, - 0x89, 0xb5, 0x7d, 0xdc, 0x41, 0xf2, 0x15, 0xc8, 0x87, 0x90, 0x9e, 0xd1, 0xee, 0x22, 0x2e, 0xf3, - 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xaf, 0xc9, 0x0f, 0x01, 0x22, 0x3f, 0x7d, 0xe5, 0x7f, 0x9c, 0xb6, - 0x1b, 0x49, 0xda, 0x12, 0xd3, 0xb1, 0xb7, 0xa9, 0xed, 0x7b, 0x86, 0x43, 0x0d, 0xd3, 0x6f, 0xe1, - 0x23, 0xe7, 0x90, 0xe8, 0x33, 0x61, 0xc0, 0xbe, 0xbc, 0x05, 0x39, 0xda, 0x36, 0x68, 0x53, 0xb8, - 0x9a, 0xe1, 0x14, 0xfe, 0xff, 0xe8, 0xb8, 0x98, 0x2f, 0xef, 0xef, 0xd4, 0xc4, 0xce, 0x7e, 0x5f, - 0x07, 0x1a, 0xfd, 0x96, 0x09, 0x2c, 0x59, 0x81, 0x26, 0x88, 0x57, 0x8f, 0xac, 0x29, 0xb6, 0x15, - 0xe0, 0xe6, 0x9f, 0x1e, 0x1d, 0x17, 0xef, 0x9c, 0x86, 0xaa, 0x1a, 0xb6, 0x1d, 0x83, 0x75, 0x3d, - 0xa4, 0x2f, 0x46, 0x8e, 0xc3, 0xd8, 0x35, 0x6c, 0xcb, 0x1f, 0xc2, 0x5c, 0xd7, 0x69, 0x10, 0xc7, - 0x8a, 0x88, 0xcb, 0x71, 0xe2, 0xf2, 0xd1, 0x2a, 0xa7, 0x6e, 0x15, 0x66, 0x13, 0xb0, 0xbe, 0x32, - 0xcb, 0xcf, 0x66, 0x2e, 0x06, 0xf5, 0xe5, 0xeb, 0x30, 0x1f, 0x43, 0x02, 0x7e, 0xf3, 0x9c, 0xdf, - 0x38, 0x40, 0xc0, 0xf0, 0x1e, 0x5c, 0x88, 0x81, 0x49, 0x86, 0xe6, 0xd2, 0x18, 0x3a, 0x1f, 0xe1, - 0xe3, 0x45, 0xf9, 0x89, 0x04, 0x2b, 0x31, 0x57, 0x63, 0x3c, 0xfa, 0xac, 0xcd, 0x9f, 0x95, 0xb5, - 0xcb, 0x51, 0x88, 0x83, 0xd1, 0x1c, 0x6a, 0xd8, 0x1e, 0x1e, 0x00, 0x2b, 0x50, 0x18, 0x7f, 0xb8, - 0xa3, 0xf3, 0xff, 0xf7, 0x24, 0xc8, 0x15, 0x6a, 0xdf, 0xb7, 0xac, 0x1d, 0xd2, 0x43, 0x8e, 0xe1, - 0xb0, 0x1a, 0xb6, 0x69, 0xea, 0xd9, 0x7f, 0x00, 0x93, 0xe1, 0x1c, 0x7c, 0xe7, 0x43, 0x32, 0xe9, - 0xb6, 0xfc, 0x09, 0x1f, 0x6b, 0xba, 0xde, 0x34, 0x68, 0x33, 0xb8, 0x00, 0xf5, 0x7c, 0xa4, 0xd6, - 0x87, 0x06, 0x6d, 0xca, 0xeb, 0xb0, 0x90, 0xe8, 0x87, 0x4f, 0x20, 0x55, 0xa6, 0xfc, 0x23, 0xaa, - 0xcf, 0xc5, 0x1a, 0xe5, 0x19, 0x9b, 0xb0, 0x90, 0xd4, 0x03, 0xe7, 0x7a, 0xfa, 0xac, 0x5c, 0xcf, - 0x25, 0xe4, 0xe4, 0x6b, 0xf3, 0x1e, 0xa8, 0x51, 0x3a, 0xa3, 0xd1, 0xa8, 0x92, 0xe5, 0x89, 0x5d, - 0x0c, 0x11, 0x07, 0x43, 0xb6, 0x74, 0xb8, 0x33, 0x97, 0x40, 0xfd, 0x37, 0xed, 0x51, 0x57, 0x7e, - 0x91, 0x60, 0xa1, 0x42, 0xed, 0xf2, 0xfe, 0xce, 0x81, 0x23, 0xda, 0x8d, 0x52, 0x7b, 0x32, 0x86, - 0xcb, 0xc9, 0x71, 0x5c, 0x8e, 0x63, 0x28, 0xf3, 0x9e, 0x19, 0x1a, 0x2e, 0x52, 0x05, 0x65, 0xb4, - 0x8a, 0xa8, 0xc4, 0x9f, 0x25, 0xb8, 0x54, 0xa1, 0x76, 0x0d, 0xb5, 0x91, 0xc9, 0x70, 0x0f, 0x85, - 0x1a, 0xde, 0xf3, 0xef, 0x27, 0xc7, 0x3c, 0x7b, 0xb9, 0x1b, 0x70, 0xde, 0x43, 0x26, 0xe9, 0x21, - 0x0f, 0x59, 0x75, 0x31, 0xe5, 0x69, 0x2b, 0xa8, 0x58, 0x5f, 0x88, 0xb6, 0x1e, 0xf8, 0x13, 0xbb, - 0xd6, 0x1a, 0x4e, 0xfc, 0x1a, 0x5c, 0xfd, 0xaf, 0xdc, 0xa2, 0x22, 0x7e, 0x92, 0x60, 0xbe, 0x42, - 0xed, 0x03, 0xd7, 0x32, 0x18, 0xaa, 0xf2, 0xe7, 0xac, 0xbc, 0x0d, 0x33, 0x46, 0x97, 0x35, 0x89, - 0x87, 0xd9, 0x20, 0x48, 0xbd, 0xac, 0xbc, 0x7c, 0xb6, 0xb1, 0x28, 0x2e, 0xc8, 0xfb, 0x96, 0xe5, - 0x21, 0x4a, 0x6b, 0xcc, 0xc3, 0x8e, 0xad, 0xc7, 0x50, 0xf9, 0x1e, 0x64, 0x83, 0x07, 0xb1, 0xb8, - 0x52, 0x2f, 0xa7, 0xdd, 0x8c, 0x1c, 0x54, 0x9e, 0x7a, 0x7e, 0x5c, 0x9c, 0xd0, 0x85, 0xc9, 0xdd, - 0x39, 0x3f, 0xfb, 0xd8, 0xd9, 0xda, 0x32, 0x7f, 0xe6, 0x24, 0xf3, 0x0a, 0x73, 0xde, 0xfa, 0x33, - 0x0b, 0x99, 0x0a, 0xb5, 0xe5, 0xef, 0x25, 0x58, 0x4a, 0x79, 0xf8, 0xde, 0x4a, 0x09, 0x9d, 0xfa, - 0xbe, 0x52, 0x3f, 0x39, 0xad, 0x45, 0x98, 0x8e, 0xfc, 0x2d, 0x2c, 0x8e, 0x7d, 0x8d, 0x69, 0xe9, - 0x1e, 0xc7, 0xe1, 0xd5, 0xed, 0xd3, 0xe1, 0xa3, 0xf8, 0xdf, 0xc0, 0xf9, 0x71, 0x8f, 0x9f, 0x8d, - 0xb7, 0x15, 0x34, 0x04, 0x57, 0xef, 0x9c, 0x0a, 0x1e, 0x05, 0x27, 0x30, 0x3f, 0x3a, 0x79, 0x6f, - 0xa4, 0x7b, 0x1a, 0x81, 0xaa, 0x9b, 0x27, 0x86, 0x46, 0x01, 0x31, 0xe4, 0x87, 0x87, 0xca, 0xf5, - 0x74, 0x1f, 0x43, 0x40, 0xb5, 0x74, 0x42, 0x60, 0x14, 0xea, 0x07, 0x09, 0x96, 0xd3, 0x4f, 0xf7, - 0xed, 0x74, 0x77, 0xa9, 0x46, 0xea, 0xbd, 0x77, 0x30, 0x8a, 0xf2, 0x39, 0x84, 0xd9, 0xa1, 0x73, - 0x7a, 0x2d, 0xdd, 0x59, 0x12, 0xa7, 0x6a, 0x27, 0xc3, 0x85, 0x71, 0xd4, 0xe9, 0xef, 0xde, 0x3c, - 0xbd, 0x29, 0x95, 0x1f, 0x3f, 0x7f, 0x55, 0x90, 0x5e, 0xbc, 0x2a, 0x48, 0x7f, 0xbc, 0x2a, 0x48, - 0x3f, 0xbe, 0x2e, 0x4c, 0xbc, 0x78, 0x5d, 0x98, 0xf8, 0xed, 0x75, 0x61, 0xe2, 0xab, 0xb7, 0xde, - 0x99, 0xfd, 0xe4, 0xff, 0x55, 0x3e, 0x76, 0x1b, 0x59, 0xfe, 0x7f, 0xf5, 0xf6, 0x3f, 0x01, 0x00, - 0x00, 0xff, 0xff, 0xa3, 0xb5, 0x5f, 0xec, 0xef, 0x0f, 0x00, 0x00, + // 1284 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0xdb, 0xc6, + 0x13, 0x35, 0x2d, 0x5b, 0xf9, 0x79, 0x64, 0xd9, 0xfe, 0x31, 0x8e, 0x43, 0xb3, 0x89, 0x24, 0x3b, + 0x69, 0xe2, 0x04, 0x35, 0x15, 0x3b, 0x8d, 0xd1, 0x26, 0x40, 0x81, 0xc8, 0x76, 0x90, 0xa0, 0x11, + 0x2a, 0x50, 0x76, 0x0f, 0xed, 0x41, 0xa0, 0xa8, 0x35, 0xb5, 0x90, 0xc4, 0x25, 0xb8, 0x6b, 0x41, + 0x42, 0x81, 0xa2, 0x08, 0x7a, 0x2d, 0xd0, 0x53, 0x0f, 0xbd, 0xf5, 0x1b, 0xe4, 0x90, 0x8f, 0xd0, + 0x43, 0x8e, 0x41, 0x4e, 0x85, 0x0b, 0x18, 0x45, 0x52, 0x20, 0x87, 0x9e, 0x7b, 0x2f, 0x48, 0x2e, + 0x97, 0xa4, 0x2a, 0x36, 0x76, 0x9c, 0x1b, 0x77, 0xf7, 0xcd, 0xcc, 0x9b, 0x37, 0xb3, 0x7f, 0x08, + 0x85, 0xa6, 0xd1, 0x1c, 0x76, 0x89, 0x5d, 0x6e, 0x32, 0x93, 0x32, 0xa3, 0x83, 0x6d, 0xab, 0xdc, + 0xdf, 0x28, 0xb3, 0x81, 0xe6, 0xb8, 0x84, 0x11, 0xf9, 0x02, 0x5f, 0xd7, 0xa2, 0x75, 0xad, 0xbf, + 0xa1, 0x2e, 0x5a, 0xc4, 0x22, 0x3e, 0xa2, 0xec, 0x7d, 0x05, 0x60, 0x75, 0xd9, 0x24, 0xb4, 0x47, + 0x68, 0x23, 0x58, 0x08, 0x06, 0x7c, 0xe9, 0x62, 0x30, 0x2a, 0xf7, 0xa8, 0xef, 0xbf, 0x47, 0x2d, + 0xbe, 0xb0, 0xca, 0x17, 0x4c, 0x77, 0xe8, 0x30, 0x52, 0xa6, 0xc8, 0x74, 0x36, 0xef, 0x6c, 0x75, + 0x36, 0xca, 0x1d, 0x34, 0x0c, 0x8d, 0x57, 0xc7, 0x93, 0x74, 0x0c, 0xd7, 0xe8, 0x85, 0x98, 0x8f, + 0x62, 0x18, 0xb3, 0x8d, 0xcc, 0x8e, 0x43, 0xb0, 0xcd, 0x3c, 0x58, 0x62, 0x82, 0xa3, 0xaf, 0xf2, + 0xa8, 0x91, 0xb7, 0x26, 0x62, 0xc6, 0x46, 0x38, 0xe6, 0xa8, 0x62, 0x4a, 0x5c, 0xe2, 0x04, 0x80, + 0xd5, 0x5f, 0x32, 0xb0, 0x5c, 0xa5, 0xd6, 0xb6, 0x8b, 0x0c, 0x86, 0x1e, 0x60, 0xdb, 0xe8, 0x62, + 0x36, 0xac, 0xb9, 0xa4, 0x8f, 0x5b, 0xc8, 0x95, 0x97, 0x20, 0x4b, 0xb1, 0x65, 0x23, 0x57, 0x91, + 0x4a, 0xd2, 0xda, 0x8c, 0xce, 0x47, 0xf2, 0x2e, 0xe4, 0x5a, 0x88, 0x9a, 0x2e, 0x76, 0x18, 0x26, + 0xb6, 0x32, 0x59, 0x92, 0xd6, 0x72, 0x9b, 0x57, 0x34, 0xae, 0x57, 0xa4, 0xb2, 0x4f, 0x49, 0xdb, + 0x89, 0xa0, 0x7a, 0xdc, 0x4e, 0xae, 0x02, 0x98, 0xa4, 0xd7, 0xc3, 0x94, 0x7a, 0x5e, 0x32, 0x5e, + 0x88, 0xca, 0xfa, 0xd1, 0x71, 0xf1, 0x83, 0xc0, 0x11, 0x6d, 0x75, 0x34, 0x4c, 0xca, 0x3d, 0x83, + 0xb5, 0xb5, 0xc7, 0xc8, 0x32, 0xcc, 0xe1, 0x0e, 0x32, 0x5f, 0x3e, 0x5b, 0x07, 0x1e, 0x67, 0x07, + 0x99, 0x7a, 0xcc, 0x81, 0xfc, 0x19, 0x00, 0x4f, 0xb7, 0xe1, 0x74, 0x94, 0x29, 0x9f, 0x54, 0x31, + 0x24, 0x15, 0x54, 0x47, 0x13, 0xd5, 0xd1, 0x6a, 0x87, 0xcd, 0xcf, 0xd1, 0x50, 0x9f, 0xe1, 0x26, + 0xb5, 0x8e, 0x5c, 0x85, 0x6c, 0x93, 0x99, 0x9e, 0xed, 0x74, 0x49, 0x5a, 0x9b, 0xad, 0x6c, 0x1d, + 0x1d, 0x17, 0x37, 0x2d, 0xcc, 0xda, 0x87, 0x4d, 0xcd, 0x24, 0xbd, 0x32, 0x47, 0x9a, 0x6d, 0x03, + 0xdb, 0xe1, 0xa0, 0xcc, 0x86, 0x0e, 0xa2, 0x5a, 0xe5, 0x51, 0xed, 0xf6, 0xc7, 0xb7, 0xb8, 0xcb, + 0xe9, 0x26, 0x33, 0x6b, 0x1d, 0xf9, 0x2e, 0x64, 0x1c, 0xe2, 0x28, 0x59, 0x9f, 0xc7, 0x9a, 0x36, + 0xb6, 0x0d, 0xb5, 0x9a, 0x4b, 0xc8, 0xc1, 0x17, 0x07, 0x35, 0x42, 0x29, 0xf2, 0xb3, 0xd0, 0x3d, + 0xa3, 0xbb, 0xb9, 0x27, 0x6f, 0x9e, 0xde, 0xe4, 0x6a, 0xaf, 0x5e, 0x81, 0x95, 0xd4, 0x12, 0xe9, + 0x88, 0x3a, 0xc4, 0xa6, 0x68, 0xf5, 0x2f, 0x09, 0x2e, 0x56, 0xa9, 0xb5, 0xdb, 0xc2, 0xec, 0xc4, + 0x65, 0xbc, 0x20, 0x12, 0xf6, 0x2a, 0x38, 0x1b, 0x12, 0x1f, 0xa9, 0x6e, 0xe6, 0xbd, 0x54, 0x77, + 0xea, 0x8c, 0xd5, 0x4d, 0x4a, 0xb2, 0x02, 0xc5, 0x94, 0x64, 0x85, 0x20, 0xbf, 0x9f, 0x83, 0x25, + 0x21, 0x5b, 0x65, 0x6f, 0x7b, 0x07, 0x75, 0x91, 0x65, 0xf8, 0xcc, 0xd2, 0xf4, 0x48, 0x36, 0xd0, + 0xe4, 0xa9, 0x1b, 0x88, 0x57, 0x3c, 0xf3, 0x0e, 0x15, 0x8f, 0x35, 0xdf, 0xd4, 0xfb, 0x68, 0xbe, + 0xaf, 0x61, 0xee, 0xc0, 0x69, 0x04, 0x1e, 0x1b, 0x5d, 0x4c, 0x99, 0x32, 0x5d, 0xca, 0x9c, 0xc1, + 0x6d, 0xee, 0xc0, 0xa9, 0x78, 0x8e, 0x1f, 0x63, 0xca, 0xe4, 0x15, 0x98, 0xe5, 0x09, 0x35, 0x18, + 0xee, 0x21, 0xbf, 0xc5, 0xf3, 0x7a, 0x8e, 0xcf, 0xed, 0xe1, 0x1e, 0x92, 0xaf, 0x40, 0x3e, 0x84, + 0xf4, 0x8d, 0xee, 0x21, 0x52, 0xce, 0x95, 0xa4, 0xb5, 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xcd, 0xc9, + 0x0f, 0x01, 0x84, 0x9f, 0x81, 0xf2, 0x3f, 0x5f, 0xb6, 0x1b, 0x71, 0xd9, 0x62, 0xa7, 0x5e, 0x7f, + 0x43, 0xdb, 0x73, 0x0d, 0x9b, 0x1a, 0xa6, 0x57, 0xc2, 0x47, 0xf6, 0x01, 0xd1, 0x67, 0xc2, 0x80, + 0x03, 0x79, 0x13, 0x72, 0xb4, 0x6b, 0xd0, 0x36, 0x77, 0x35, 0xe3, 0x4b, 0xf8, 0xff, 0xa3, 0xe3, + 0x62, 0xbe, 0xb2, 0xb7, 0x5d, 0xe7, 0x2b, 0x7b, 0x03, 0x1d, 0xa8, 0xf8, 0x96, 0x09, 0x2c, 0xb5, + 0x82, 0x9e, 0x20, 0x6e, 0x43, 0x58, 0x53, 0x6c, 0x29, 0xe0, 0x9b, 0x7f, 0x7a, 0x74, 0x5c, 0xbc, + 0x73, 0x1a, 0xa9, 0xea, 0xd8, 0xb2, 0x0d, 0x76, 0xe8, 0x22, 0x7d, 0x51, 0x38, 0x0e, 0x63, 0xd7, + 0xb1, 0x25, 0x7f, 0x08, 0x73, 0x87, 0x76, 0x93, 0xd8, 0x2d, 0x21, 0x5c, 0xce, 0x17, 0x2e, 0x2f, + 0x66, 0x7d, 0xe9, 0x56, 0x60, 0x36, 0x06, 0x1b, 0x28, 0xb3, 0xfe, 0xde, 0xcc, 0x45, 0xa0, 0x81, + 0x7c, 0x1d, 0xe6, 0x23, 0x48, 0xa0, 0x6f, 0xde, 0xd7, 0x37, 0x0a, 0x10, 0x28, 0xbc, 0x0b, 0x17, + 0x22, 0x60, 0x5c, 0xa1, 0xb9, 0x34, 0x85, 0xce, 0x0b, 0x7c, 0x34, 0x29, 0x3f, 0x91, 0xa0, 0x14, + 0x69, 0x35, 0xc6, 0xa3, 0xa7, 0xda, 0xfc, 0x59, 0x55, 0xbb, 0x2c, 0x42, 0xec, 0x8f, 0x72, 0xa8, + 0x63, 0x2b, 0x79, 0x00, 0x94, 0xa0, 0x30, 0x7e, 0x73, 0x8b, 0xfd, 0xff, 0xf7, 0x24, 0xc8, 0x55, + 0x6a, 0xdd, 0x6f, 0xb5, 0xb6, 0x49, 0x1f, 0xd9, 0x86, 0xcd, 0xea, 0xd8, 0xa2, 0xa9, 0x7b, 0xff, + 0x01, 0x4c, 0x86, 0xe7, 0xe0, 0x3b, 0x6f, 0x92, 0x49, 0xa7, 0x23, 0x5f, 0x83, 0xf9, 0xa8, 0xa7, + 0x1b, 0x6d, 0x83, 0xb6, 0x83, 0x8b, 0x4d, 0xcf, 0x8b, 0x6e, 0x7d, 0x68, 0xd0, 0xb6, 0xbc, 0x06, + 0x0b, 0xb1, 0x7a, 0x78, 0x02, 0x52, 0x65, 0xca, 0xdb, 0xa2, 0xfa, 0x5c, 0xd4, 0xa3, 0x3e, 0x63, + 0x13, 0x16, 0xe2, 0xfd, 0xe0, 0x6b, 0x3d, 0x7d, 0x56, 0xad, 0xe7, 0x62, 0xed, 0xe4, 0xf5, 0xe6, + 0x3d, 0x50, 0x05, 0x9d, 0xd1, 0x68, 0x54, 0xc9, 0xfa, 0xc4, 0x2e, 0x86, 0x88, 0xfd, 0x84, 0x2d, + 0x4d, 0x56, 0xe6, 0x12, 0xa8, 0xff, 0x96, 0x5d, 0x54, 0xe5, 0x57, 0x09, 0x16, 0xaa, 0xd4, 0xaa, + 0xec, 0x6d, 0xef, 0xdb, 0xbc, 0xdc, 0x28, 0xb5, 0x26, 0x63, 0xb4, 0x9c, 0x1c, 0xa7, 0xe5, 0x38, + 0x85, 0x32, 0xef, 0x59, 0xa1, 0x64, 0x92, 0x2a, 0x28, 0xa3, 0x59, 0x88, 0x14, 0x7f, 0x96, 0xe0, + 0x52, 0x95, 0x5a, 0x75, 0xd4, 0x45, 0x26, 0xc3, 0x7d, 0x14, 0xf6, 0xf0, 0xae, 0x77, 0x3f, 0xd9, + 0xe6, 0xd9, 0xd3, 0x5d, 0x87, 0xf3, 0x2e, 0x32, 0x49, 0x1f, 0xb9, 0xa8, 0xd5, 0xe0, 0xa7, 0x3c, + 0xed, 0x04, 0x19, 0xeb, 0x0b, 0x62, 0xe9, 0x81, 0x77, 0x62, 0xd7, 0x3b, 0x49, 0xe2, 0xd7, 0xe0, + 0xea, 0x7f, 0x71, 0x13, 0x49, 0xfc, 0x24, 0xc1, 0x7c, 0x95, 0x5a, 0xfb, 0x4e, 0xcb, 0x60, 0xa8, + 0xe6, 0x3f, 0x53, 0xe5, 0x2d, 0x98, 0x31, 0x0e, 0x59, 0x9b, 0xb8, 0x98, 0x0d, 0x03, 0xea, 0x15, + 0xe5, 0xe5, 0xb3, 0xf5, 0x45, 0x7e, 0x41, 0xde, 0x6f, 0xb5, 0x5c, 0x44, 0x69, 0x9d, 0xb9, 0xd8, + 0xb6, 0xf4, 0x08, 0x2a, 0xdf, 0x83, 0x6c, 0xf0, 0xd0, 0xe5, 0x57, 0xea, 0xe5, 0xb4, 0x9b, 0xd1, + 0x07, 0x55, 0xa6, 0x9e, 0x1f, 0x17, 0x27, 0x74, 0x6e, 0x72, 0x77, 0xce, 0x63, 0x1f, 0x39, 0x5b, + 0x5d, 0xf6, 0x9f, 0x39, 0x71, 0x5e, 0x21, 0xe7, 0xcd, 0x3f, 0xb3, 0x90, 0xa9, 0x52, 0x4b, 0xfe, + 0x5e, 0x82, 0xa5, 0x94, 0x07, 0xed, 0xad, 0x94, 0xd0, 0xa9, 0xef, 0x2b, 0xf5, 0x93, 0xd3, 0x5a, + 0x84, 0x74, 0xe4, 0x6f, 0x61, 0x71, 0xec, 0x6b, 0x4c, 0x4b, 0xf7, 0x38, 0x0e, 0xaf, 0x6e, 0x9d, + 0x0e, 0x2f, 0xe2, 0x7f, 0x03, 0xe7, 0xc7, 0x3d, 0x7e, 0xd6, 0xdf, 0x96, 0x50, 0x02, 0xae, 0xde, + 0x39, 0x15, 0x5c, 0x04, 0x27, 0x30, 0x3f, 0x7a, 0xf2, 0xde, 0x48, 0xf7, 0x34, 0x02, 0x55, 0x37, + 0x4e, 0x0c, 0x15, 0x01, 0x31, 0xe4, 0x93, 0x87, 0xca, 0xf5, 0x74, 0x1f, 0x09, 0xa0, 0x5a, 0x3e, + 0x21, 0x50, 0x84, 0xfa, 0x41, 0x82, 0xe5, 0xf4, 0xdd, 0x7d, 0x3b, 0xdd, 0x5d, 0xaa, 0x91, 0x7a, + 0xef, 0x1d, 0x8c, 0x04, 0x9f, 0x03, 0x98, 0x4d, 0xec, 0xd3, 0x6b, 0xe9, 0xce, 0xe2, 0x38, 0x55, + 0x3b, 0x19, 0x2e, 0x8c, 0xa3, 0x4e, 0x7f, 0xf7, 0xe6, 0xe9, 0x4d, 0xa9, 0xf2, 0xf8, 0xf9, 0xab, + 0x82, 0xf4, 0xe2, 0x55, 0x41, 0xfa, 0xe3, 0x55, 0x41, 0xfa, 0xf1, 0x75, 0x61, 0xe2, 0xc5, 0xeb, + 0xc2, 0xc4, 0x6f, 0xaf, 0x0b, 0x13, 0x5f, 0xbd, 0xf5, 0xce, 0x1c, 0xc4, 0xff, 0x43, 0xfd, 0x63, + 0xb7, 0x99, 0xf5, 0xff, 0x43, 0x6f, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xd3, 0xc8, 0xf6, + 0xc7, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1297,13 +1286,6 @@ func (m *MsgCreateFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, erro _ = i var l int _ = l - if len(m.MasterPubRand) > 0 { - i -= len(m.MasterPubRand) - copy(dAtA[i:], m.MasterPubRand) - i = encodeVarintTx(dAtA, i, uint64(len(m.MasterPubRand))) - i-- - dAtA[i] = 0x3a - } if m.Pop != nil { { size, err := m.Pop.MarshalToSizedBuffer(dAtA[:i]) @@ -2016,10 +1998,6 @@ func (m *MsgCreateFinalityProvider) Size() (n int) { l = m.Pop.Size() n += 1 + l + sovTx(uint64(l)) } - l = len(m.MasterPubRand) - if l > 0 { - n += 1 + l + sovTx(uint64(l)) - } return n } @@ -2518,38 +2496,6 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - 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 ErrInvalidLengthTx - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.MasterPubRand = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/x/finality/client/cli/query.go b/x/finality/client/cli/query.go index 855b60fa0..7198e450f 100644 --- a/x/finality/client/cli/query.go +++ b/x/finality/client/cli/query.go @@ -29,6 +29,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { } cmd.AddCommand(CmdQueryParams()) + cmd.AddCommand(CmdListPublicRandomness()) cmd.AddCommand(CmdBlock()) cmd.AddCommand(CmdListBlocks()) cmd.AddCommand(CmdVotesAtHeight()) @@ -66,6 +67,39 @@ func CmdVotesAtHeight() *cobra.Command { return cmd } +func CmdListPublicRandomness() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-public-randomness [fp_btc_pk_hex]", + Short: "list public randomness committed by a given finality provider", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.ListPublicRandomness(cmd.Context(), &types.QueryListPublicRandomnessRequest{ + FpBtcPkHex: args[0], + Pagination: pageReq, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "list-public-randomness") + + return cmd +} + func CmdListBlocks() *cobra.Command { cmd := &cobra.Command{ Use: "list-blocks", diff --git a/x/finality/client/cli/tx.go b/x/finality/client/cli/tx.go index 5729fd4ad..bf4b4178b 100644 --- a/x/finality/client/cli/tx.go +++ b/x/finality/client/cli/tx.go @@ -25,12 +25,73 @@ func GetTxCmd() *cobra.Command { } cmd.AddCommand( + NewCommitPubRandListCmd(), NewAddFinalitySigCmd(), ) return cmd } +func NewCommitPubRandListCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "commit-pubrand-list [fp_btc_pk] [start_height] [pub_rand1] [pub_rand2] ... [sig]", + Args: cobra.MinimumNArgs(4), + Short: "Commit a list of public randomness", + Long: strings.TrimSpace( + `Commit a list of public randomness.`, // TODO: example + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + // get finality provider BTC PK + fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(args[0]) + if err != nil { + return err + } + + // get start height + startHeight, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + + // get signature + sig, err := bbn.NewBIP340SignatureFromHex(args[len(args)-1]) + if err != nil { + return err + } + + // get pub rand list + pubRandHexList := args[2 : len(args)-1] + pubRandList := []bbn.SchnorrPubRand{} + for _, prHex := range pubRandHexList { + pr, err := bbn.NewSchnorrPubRandFromHex(prHex) + if err != nil { + return err + } + pubRandList = append(pubRandList, *pr) + } + + msg := types.MsgCommitPubRandList{ + Signer: clientCtx.FromAddress.String(), + FpBtcPk: fpBTCPK, + StartHeight: startHeight, + PubRandList: pubRandList, + Sig: sig, + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + func NewAddFinalitySigCmd() *cobra.Command { cmd := &cobra.Command{ Use: "add-finality-sig [fp_btc_pk] [block_height] [block_app_hash] [finality_sig]", diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index dd497b23b..57fcac889 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -2,10 +2,12 @@ package keeper import ( "context" + "fmt" btcstk "github.com/babylonchain/babylon/btcstaking" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) // InitGenesis initializes the keeper state from a provided initial genesis state. @@ -22,6 +24,10 @@ func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { k.SetSig(ctx, voteSig.BlockHeight, voteSig.FpBtcPk, voteSig.FinalitySig) } + for _, pubRand := range gs.PublicRandomness { + k.SetPubRandList(ctx, pubRand.FpBtcPk, pubRand.BlockHeight, []bbn.SchnorrPubRand{*pubRand.PubRand}) + } + return k.SetParams(ctx, gs.Params) } @@ -42,11 +48,17 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) return nil, err } + pubRandomness, err := k.publicRandomness(ctx) + if err != nil { + return nil, err + } + return &types.GenesisState{ - Params: k.GetParams(ctx), - IndexedBlocks: blocks, - Evidences: evidences, - VoteSigs: voteSigs, + Params: k.GetParams(ctx), + IndexedBlocks: blocks, + Evidences: evidences, + VoteSigs: voteSigs, + PublicRandomness: pubRandomness, }, nil } @@ -117,3 +129,52 @@ func (k Keeper) voteSigs(ctx context.Context) ([]*types.VoteSig, error) { return voteSigs, nil } + +// publicRandomness iterates over all commited randoms on the store, parses the finality provider public key +// and the height from the iterator key and the commited random from the iterator value. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) publicRandomness(ctx context.Context) ([]*types.PublicRandomness, error) { + store := k.pubRandStore(ctx) + iter := store.Iterator(nil, nil) + defer iter.Close() + + commtRandoms := make([]*types.PublicRandomness, 0) + for ; iter.Valid(); iter.Next() { + // key contains the fp and the block height + fpBTCPK, blkHeight, err := parsePubKeyAndBlkHeightFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + pubRand, err := bbn.NewSchnorrPubRand(iter.Value()) + if err != nil { + return nil, err + } + + commtRandoms = append(commtRandoms, &types.PublicRandomness{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + PubRand: pubRand, + }) + } + + return commtRandoms, nil +} + +// parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with +// BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) +func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { + sizeBigEndian := 8 + keyLen := len(key) + if keyLen < sizeBigEndian+1 { + return nil, 0, fmt.Errorf("key not long enough to parse BIP340PubKey and block height: %s", key) + } + + startKeyHeight := keyLen - sizeBigEndian + fpBTCPK, err = bbn.NewBIP340PubKey(key[:startKeyHeight]) + if err != nil { + return nil, 0, fmt.Errorf("failed to parse pub key from key %w: %w", bbn.ErrUnmarshal, err) + } + + blkHeight = sdk.BigEndianToUint64(key[startKeyHeight:]) + return fpBTCPK, blkHeight, nil +} diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index 3ee233cbe..d8768fec2 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -4,7 +4,6 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -18,14 +17,14 @@ func TestExportGenesis(t *testing.T) { r := rand.New(rand.NewSource(10)) btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - msr, mpr, err := eots.NewMasterRandPair(r) - require.NoError(t, err) fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) - sr, _, err := msr.DeriveRandPair(uint32(startHeight + blkHeight)) + srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) require.NoError(t, err) + + sr := srList[startHeight+blkHeight] blockHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address msgAddFinalitySig, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blkHeight, blockHash) @@ -34,6 +33,7 @@ func TestExportGenesis(t *testing.T) { allVotes := make([]*types.VoteSig, numPubRand) allBlocks := make([]*types.IndexedBlock, numPubRand) allEvidences := make([]*types.Evidence, numPubRand) + allPublicRandomness := make([]*types.PublicRandomness, numPubRand) for i := 0; i < int(numPubRand); i++ { // Votes vt := &types.VoteSig{ @@ -57,21 +57,32 @@ func TestExportGenesis(t *testing.T) { evidence := &types.Evidence{ FpBtcPk: fpBTCPK, BlockHeight: blkHeight, + PubRand: &msgCommitPubRandList.PubRandList[i], ForkAppHash: msgAddFinalitySig.BlockAppHash, ForkFinalitySig: msgAddFinalitySig.FinalitySig, CanonicalAppHash: blockHash, CanonicalFinalitySig: msgAddFinalitySig.FinalitySig, - MasterPubRand: mpr.MarshalBase58(), } k.SetEvidence(ctx, evidence) allEvidences[i] = evidence + // PubRandoms + pubRand := msgCommitPubRandList.PubRandList[i] + k.SetPubRandList(ctx, fpBTCPK, blkHeight, []bbn.SchnorrPubRand{pubRand}) + randomness := &types.PublicRandomness{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + PubRand: &pubRand, + } + allPublicRandomness[i] = randomness + // updates the block everytime to make sure something is different. blkHeight++ } require.Equal(t, len(allVotes), int(numPubRand)) require.Equal(t, len(allBlocks), int(numPubRand)) require.Equal(t, len(allEvidences), int(numPubRand)) + require.Equal(t, len(allPublicRandomness), int(numPubRand)) gs, err := k.ExportGenesis(ctx) require.NoError(t, err) @@ -80,4 +91,5 @@ func TestExportGenesis(t *testing.T) { require.Equal(t, allVotes, gs.VoteSigs) require.Equal(t, allBlocks, gs.IndexedBlocks) require.Equal(t, allEvidences, gs.Evidences) + require.Equal(t, allPublicRandomness, gs.PublicRandomness) } diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index c874d28d3..6f867bb08 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -18,6 +18,41 @@ import ( var _ types.QueryServer = Keeper{} +// ListPublicRandomness returns a list of public randomness committed by a given +// finality provider +func (k Keeper) ListPublicRandomness(ctx context.Context, req *types.QueryListPublicRandomnessRequest) (*types.QueryListPublicRandomnessResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(req.FpBtcPkHex) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "failed to unmarshal finality provider BTC PK hex: %v", err) + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + store := k.pubRandFpStore(sdkCtx, fpBTCPK) + pubRandMap := map[uint64]*bbn.SchnorrPubRand{} + pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + height := sdk.BigEndianToUint64(key) + pubRand, err := bbn.NewSchnorrPubRand(value) + if err != nil { + panic("failed to unmarshal EOTS public randomness in KVStore") + } + pubRandMap[height] = pubRand + return nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + resp := &types.QueryListPublicRandomnessResponse{ + PubRandMap: pubRandMap, + Pagination: pageRes, + } + return resp, nil +} + func (k Keeper) Block(ctx context.Context, req *types.QueryBlockRequest) (*types.QueryBlockResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index 47d602b0d..f5b910389 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -77,12 +77,6 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return nil, bstypes.ErrFpAlreadySlashed } - // ensure the finality provider's registered epoch is already finalised by BTC timestamping - finalizedEpoch := ms.BTCStakingKeeper.GetLastFinalizedEpoch(ctx) - if finalizedEpoch < fp.RegisteredEpoch { - return nil, bstypes.ErrFpNotBTCTimestamped - } - // ensure the finality provider has voting power at this height if req.FpBtcPk == nil { return nil, types.ErrInvalidFinalitySig.Wrap("empty finality provider BTC PK") @@ -103,15 +97,18 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } - // derive public randomness at this height from the master public randomness - pubRand := fp.MustGetPubRand(req.BlockHeight) + // ensure the finality provider has committed public randomness + pubRand, err := ms.GetPubRand(ctx, fpPK, req.BlockHeight) + if err != nil { + return nil, types.ErrPubRandNotFound + } // verify EOTS signature w.r.t. public randomness fpBTCPK, err := fpPK.ToBTCPK() if err != nil { return nil, err } - if err := eots.Verify(fpBTCPK, pubRand, req.MsgToSign(), req.FinalitySig.ToModNScalar()); err != nil { + if err := eots.Verify(fpBTCPK, pubRand.ToFieldVal(), req.MsgToSign(), req.FinalitySig.ToModNScalar()); err != nil { return nil, types.ErrInvalidFinalitySig.Wrapf("the EOTS signature is invalid: %v", err) } @@ -127,7 +124,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal evidence := &types.Evidence{ FpBtcPk: req.FpBtcPk, BlockHeight: req.BlockHeight, - MasterPubRand: fp.MasterPubRand, + PubRand: pubRand, CanonicalAppHash: indexedBlock.AppHash, CanonicalFinalitySig: nil, ForkAppHash: req.BlockAppHash, @@ -179,6 +176,54 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } +// CommitPubRandList commits a list of EOTS public randomness +func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommitPubRandList) (*types.MsgCommitPubRandListResponse, error) { + defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricsKeyCommitPubRandList) + + ctx := sdk.UnwrapSDKContext(goCtx) + + // ensure the request contains enough number of public randomness + minPubRand := ms.GetParams(ctx).MinPubRand + givenPubRand := len(req.PubRandList) + if uint64(givenPubRand) < minPubRand { + return nil, types.ErrTooFewPubRand.Wrapf("required minimum: %d, actual: %d", minPubRand, givenPubRand) + } + + // ensure the finality provider is registered + if req.FpBtcPk == nil { + return nil, types.ErrInvalidPubRand.Wrap("empty finality provider public key") + } + fpBTCPKBytes := req.FpBtcPk.MustMarshal() + if !ms.BTCStakingKeeper.HasFinalityProvider(ctx, fpBTCPKBytes) { + return nil, bstypes.ErrFpNotFound.Wrapf("the finality provider with BTC PK %v is not registered", fpBTCPKBytes) + } + + // this finality provider has not commit any public randomness, + // commit the given public randomness list and return + if ms.IsFirstPubRand(ctx, req.FpBtcPk) { + ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) + return &types.MsgCommitPubRandListResponse{}, nil + } + + // ensure height and req.StartHeight do not overlap, i.e., height < req.StartHeight + height, _, err := ms.GetLastPubRand(ctx, req.FpBtcPk) + if err != nil { + return nil, err + } + if height >= req.StartHeight { + return nil, types.ErrInvalidPubRand.Wrapf("the start height (%d) has overlap with the height of the highest public randomness (%d)", req.StartHeight, height) + } + + // verify signature over the list + if err := req.VerifySig(); err != nil { + return nil, types.ErrInvalidPubRand.Wrapf("invalid signature over the public randomness list: %v", err) + } + + // all good, commit the given public randomness list + ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) + return &types.MsgCommitPubRandListResponse{}, nil +} + // slashFinalityProvider slashes a finality provider with the given evidence // including setting its voting power to zero, extracting its BTC SK, // and emit an event diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index d643583e5..275f0da8f 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -2,13 +2,11 @@ package keeper_test import ( "context" - "errors" "math/rand" "testing" "time" "cosmossdk.io/core/header" - "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -30,7 +28,7 @@ func TestMsgServer(t *testing.T) { require.NotNil(t, ctx) } -func FuzzAddFinalitySig(f *testing.F) { +func FuzzCommitPubRandList(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { @@ -42,67 +40,122 @@ func FuzzAddFinalitySig(f *testing.F) { fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, nil) ms := keeper.NewMsgServerImpl(*fKeeper) - // create and register a random finality provider + // create a random finality provider btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) require.NoError(t, err) - fpBBNSK, _, err := datagen.GenRandomSecp256k1KeyPair(r) + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + fpBTCPKBytes := fpBTCPK.MustMarshal() + + // Case 1: fail if the finality provider is not registered + bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(false).Times(1) + startHeight := datagen.RandomInt(r, 10) + numPubRand := uint64(200) + _, msg, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + require.NoError(t, err) + _, err = ms.CommitPubRandList(ctx, msg) + require.Error(t, err) + // register the finality provider + bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(true).AnyTimes() + + // Case 2: commit a list of 0 { - i -= len(m.MasterPubRand) - copy(dAtA[i:], m.MasterPubRand) - i = encodeVarintFinality(dAtA, i, uint64(len(m.MasterPubRand))) + if m.PubRand != nil { + { + size := m.PubRand.Size() + i -= size + if _, err := m.PubRand.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintFinality(dAtA, i, uint64(size)) + } i-- dAtA[i] = 0x1a } @@ -387,8 +384,8 @@ func (m *Evidence) Size() (n int) { if m.BlockHeight != 0 { n += 1 + sovFinality(uint64(m.BlockHeight)) } - l = len(m.MasterPubRand) - if l > 0 { + if m.PubRand != nil { + l = m.PubRand.Size() n += 1 + l + sovFinality(uint64(l)) } l = len(m.CanonicalAppHash) @@ -624,9 +621,9 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { } case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field MasterPubRand", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) } - var stringLen uint64 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowFinality @@ -636,23 +633,26 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if byteLen < 0 { return ErrInvalidLengthFinality } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + byteLen if postIndex < 0 { return ErrInvalidLengthFinality } if postIndex > l { return io.ErrUnexpectedEOF } - m.MasterPubRand = string(dAtA[iNdEx:postIndex]) + var v github_com_babylonchain_babylon_types.SchnorrPubRand + m.PubRand = &v + if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } iNdEx = postIndex case 4: if wireType != 2 { diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 32fd61946..304c7855c 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -34,6 +34,8 @@ type GenesisState struct { Evidences []*Evidence `protobuf:"bytes,3,rep,name=evidences,proto3" json:"evidences,omitempty"` // votes_sigs contains all the votes of finality providers ever registered. VoteSigs []*VoteSig `protobuf:"bytes,4,rep,name=vote_sigs,json=voteSigs,proto3" json:"vote_sigs,omitempty"` + // public_randomness contains all the public randomness ever commited from the finality providers. + PublicRandomness []*PublicRandomness `protobuf:"bytes,5,rep,name=public_randomness,json=publicRandomness,proto3" json:"public_randomness,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -97,6 +99,13 @@ func (m *GenesisState) GetVoteSigs() []*VoteSig { return nil } +func (m *GenesisState) GetPublicRandomness() []*PublicRandomness { + if m != nil { + return m.PublicRandomness + } + return nil +} + // VoteSig the vote of an finality provider // with the block of the vote, the finality provider btc public key and the vote signature. type VoteSig struct { @@ -149,42 +158,97 @@ func (m *VoteSig) GetBlockHeight() uint64 { return 0 } +// PublicRandomness the block height and public randomness that the finality provider has submitted. +type PublicRandomness struct { + // block_height is the height of block which the finality provider submited public randomness. + BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // fp_btc_pk is the BTC PK of the finality provider that casts this vote. + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // pub_rand is the public randomness the finality provider has committed to. + PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` +} + +func (m *PublicRandomness) Reset() { *m = PublicRandomness{} } +func (m *PublicRandomness) String() string { return proto.CompactTextString(m) } +func (*PublicRandomness) ProtoMessage() {} +func (*PublicRandomness) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{2} +} +func (m *PublicRandomness) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PublicRandomness) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PublicRandomness.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 *PublicRandomness) XXX_Merge(src proto.Message) { + xxx_messageInfo_PublicRandomness.Merge(m, src) +} +func (m *PublicRandomness) XXX_Size() int { + return m.Size() +} +func (m *PublicRandomness) XXX_DiscardUnknown() { + xxx_messageInfo_PublicRandomness.DiscardUnknown(m) +} + +var xxx_messageInfo_PublicRandomness proto.InternalMessageInfo + +func (m *PublicRandomness) GetBlockHeight() uint64 { + if m != nil { + return m.BlockHeight + } + return 0 +} + func init() { proto.RegisterType((*GenesisState)(nil), "babylon.finality.v1.GenesisState") proto.RegisterType((*VoteSig)(nil), "babylon.finality.v1.VoteSig") + proto.RegisterType((*PublicRandomness)(nil), "babylon.finality.v1.PublicRandomness") } func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 421 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x8f, 0x93, 0x40, - 0x14, 0x80, 0xa1, 0x6d, 0x76, 0xed, 0x80, 0x1e, 0x46, 0x0f, 0xa4, 0x2a, 0xa5, 0x3d, 0xf5, 0x04, - 0xbb, 0xdd, 0x8d, 0x71, 0xe3, 0x8d, 0x64, 0xe3, 0xae, 0x1e, 0x24, 0x60, 0x3c, 0xe8, 0x81, 0x00, - 0x9d, 0x0e, 0x93, 0x76, 0x19, 0xc2, 0x4c, 0x49, 0xf9, 0x0d, 0x5e, 0xfc, 0x59, 0x3d, 0xf6, 0x68, - 0x9a, 0xd8, 0x98, 0xf6, 0x8f, 0x18, 0x06, 0xb0, 0x1e, 0x48, 0xdc, 0xdb, 0xbc, 0xc7, 0xf7, 0xbe, - 0xf7, 0x1e, 0x79, 0x60, 0x14, 0x06, 0x61, 0xb1, 0xa4, 0x89, 0x35, 0x27, 0x49, 0xb0, 0x24, 0xbc, - 0xb0, 0xf2, 0x4b, 0x0b, 0xa3, 0x04, 0x31, 0xc2, 0xcc, 0x34, 0xa3, 0x9c, 0xc2, 0xe7, 0x35, 0x62, - 0x36, 0x88, 0x99, 0x5f, 0x0e, 0x5e, 0x60, 0x8a, 0xa9, 0xf8, 0x6e, 0x95, 0xaf, 0x0a, 0x1d, 0x18, - 0x6d, 0xb6, 0x34, 0xc8, 0x82, 0x87, 0x5a, 0x36, 0x18, 0xb7, 0x11, 0x7f, 0xc5, 0x82, 0x19, 0x7f, - 0xef, 0x00, 0xf5, 0x7d, 0x35, 0x82, 0xc7, 0x03, 0x8e, 0xe0, 0x0d, 0x38, 0xab, 0x24, 0x9a, 0x6c, - 0xc8, 0x13, 0x65, 0xfa, 0xd2, 0x6c, 0x19, 0xc9, 0x74, 0x04, 0x62, 0xf7, 0x36, 0xfb, 0xa1, 0xe4, - 0xd6, 0x05, 0xf0, 0x0e, 0x3c, 0x23, 0xc9, 0x0c, 0xad, 0xd1, 0xcc, 0x0f, 0x97, 0x34, 0x5a, 0x30, - 0xad, 0x63, 0x74, 0x27, 0xca, 0x74, 0xd4, 0xaa, 0xb8, 0xaf, 0x50, 0xbb, 0x24, 0xdd, 0xa7, 0xe4, - 0x9f, 0x88, 0xc1, 0x77, 0xa0, 0x8f, 0x72, 0x32, 0x43, 0x49, 0x84, 0x98, 0xd6, 0x15, 0x92, 0xd7, - 0xad, 0x92, 0xdb, 0x9a, 0x72, 0x4f, 0x3c, 0xbc, 0x01, 0xfd, 0x9c, 0x72, 0xe4, 0x33, 0x82, 0x99, - 0xd6, 0x13, 0xc5, 0xaf, 0x5a, 0x8b, 0xbf, 0x50, 0x8e, 0x3c, 0x82, 0xdd, 0x27, 0x79, 0xf5, 0x60, - 0xe3, 0x5f, 0x32, 0x38, 0xaf, 0xb3, 0x70, 0x04, 0x54, 0xb1, 0x85, 0x1f, 0x23, 0x82, 0x63, 0x2e, - 0x7e, 0x47, 0xcf, 0x55, 0x44, 0xee, 0x4e, 0xa4, 0xa0, 0x0b, 0xfa, 0xf3, 0xd4, 0x0f, 0x79, 0xe4, - 0xa7, 0x0b, 0xad, 0x63, 0xc8, 0x13, 0xd5, 0x7e, 0xb3, 0xdb, 0x0f, 0xa7, 0x98, 0xf0, 0x78, 0x15, - 0x9a, 0x11, 0x7d, 0xb0, 0xea, 0xbe, 0x51, 0x1c, 0x90, 0xa4, 0x09, 0x2c, 0x5e, 0xa4, 0x88, 0x99, - 0xf6, 0xbd, 0x73, 0x75, 0x7d, 0xe1, 0xac, 0xc2, 0x8f, 0xa8, 0x70, 0xcf, 0xe7, 0xa9, 0xcd, 0x23, - 0x67, 0x01, 0xbf, 0x01, 0xb5, 0x99, 0xb1, 0xdc, 0x40, 0xeb, 0x0a, 0xed, 0xdb, 0xdd, 0x7e, 0x78, - 0xfd, 0x38, 0xad, 0x17, 0xc5, 0x09, 0xcd, 0xb2, 0xdb, 0x4f, 0x9f, 0xbd, 0x72, 0x39, 0xa5, 0xb1, - 0x79, 0x04, 0xdb, 0x1f, 0x36, 0x07, 0x5d, 0xde, 0x1e, 0x74, 0xf9, 0xf7, 0x41, 0x97, 0x7f, 0x1c, - 0x75, 0x69, 0x7b, 0xd4, 0xa5, 0x9f, 0x47, 0x5d, 0xfa, 0x7a, 0xf1, 0x3f, 0xf9, 0xfa, 0x74, 0x45, - 0xa2, 0x4f, 0x78, 0x26, 0x0e, 0xe8, 0xea, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x01, 0x09, - 0x37, 0xd6, 0x02, 0x00, 0x00, + // 483 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0x87, 0x9b, 0xb6, 0xac, 0xab, 0x5b, 0xd0, 0x08, 0x1c, 0xa2, 0x02, 0xe9, 0x1f, 0x09, 0xa9, + 0xa7, 0x64, 0xeb, 0x26, 0xc4, 0xc4, 0x2d, 0xd2, 0xc4, 0x06, 0x07, 0x22, 0x07, 0x71, 0x80, 0x43, + 0x14, 0xa7, 0x6e, 0x62, 0xb5, 0xb5, 0xad, 0xd8, 0x89, 0xd6, 0x6f, 0xc1, 0xc7, 0xda, 0x71, 0x47, + 0x34, 0x89, 0x82, 0xda, 0x2f, 0x82, 0xe2, 0xa4, 0x1b, 0x9a, 0x22, 0x81, 0xb8, 0x70, 0xb3, 0x9d, + 0xe7, 0x7d, 0xfc, 0xbe, 0xbf, 0xc8, 0x60, 0x88, 0x02, 0xb4, 0x5a, 0x30, 0x6a, 0xcf, 0x08, 0x0d, + 0x16, 0x44, 0xae, 0xec, 0xec, 0xc8, 0x8e, 0x30, 0xc5, 0x82, 0x08, 0x8b, 0x27, 0x4c, 0x32, 0xfd, + 0x49, 0x89, 0x58, 0x3b, 0xc4, 0xca, 0x8e, 0x7a, 0x4f, 0x23, 0x16, 0x31, 0xf5, 0xdd, 0xce, 0x57, + 0x05, 0xda, 0x1b, 0x54, 0xd9, 0x78, 0x90, 0x04, 0xcb, 0x52, 0xd6, 0x1b, 0x55, 0x11, 0xb7, 0x62, + 0xc5, 0x8c, 0x7e, 0xd4, 0x41, 0xf7, 0x6d, 0xd1, 0x82, 0x27, 0x03, 0x89, 0xf5, 0x53, 0xb0, 0x57, + 0x48, 0x0c, 0x6d, 0xa0, 0x8d, 0x3b, 0x93, 0x67, 0x56, 0x45, 0x4b, 0x96, 0xab, 0x10, 0xa7, 0x79, + 0xb5, 0xee, 0xd7, 0x60, 0x59, 0xa0, 0x9f, 0x83, 0x47, 0x84, 0x4e, 0xf1, 0x25, 0x9e, 0xfa, 0x68, + 0xc1, 0xc2, 0xb9, 0x30, 0xea, 0x83, 0xc6, 0xb8, 0x33, 0x19, 0x56, 0x2a, 0x2e, 0x0a, 0xd4, 0xc9, + 0x49, 0xf8, 0x90, 0xfc, 0xb6, 0x13, 0xfa, 0x1b, 0xd0, 0xc6, 0x19, 0x99, 0x62, 0x1a, 0x62, 0x61, + 0x34, 0x94, 0xe4, 0x45, 0xa5, 0xe4, 0xac, 0xa4, 0xe0, 0x1d, 0xaf, 0x9f, 0x82, 0x76, 0xc6, 0x24, + 0xf6, 0x05, 0x89, 0x84, 0xd1, 0x54, 0xc5, 0xcf, 0x2b, 0x8b, 0x3f, 0x31, 0x89, 0x3d, 0x12, 0xc1, + 0xfd, 0xac, 0x58, 0x08, 0x1d, 0x82, 0xc7, 0x3c, 0x45, 0x0b, 0x12, 0xfa, 0x49, 0x40, 0xa7, 0x6c, + 0x49, 0xb1, 0x10, 0xc6, 0x03, 0xa5, 0x78, 0x59, 0x9d, 0x83, 0xa2, 0xe1, 0x2d, 0x0c, 0x0f, 0xf8, + 0xbd, 0x93, 0xd1, 0x77, 0x0d, 0xb4, 0xca, 0x9b, 0xf4, 0x21, 0xe8, 0xaa, 0x64, 0xfc, 0x18, 0x93, + 0x28, 0x96, 0x2a, 0xe2, 0x26, 0xec, 0xa8, 0xb3, 0x73, 0x75, 0xa4, 0x43, 0xd0, 0x9e, 0x71, 0x1f, + 0xc9, 0xd0, 0xe7, 0x73, 0xa3, 0x3e, 0xd0, 0xc6, 0x5d, 0xe7, 0xd5, 0xcd, 0xba, 0x3f, 0x89, 0x88, + 0x8c, 0x53, 0x64, 0x85, 0x6c, 0x69, 0x97, 0x8d, 0x84, 0x71, 0x40, 0xe8, 0x6e, 0x63, 0xcb, 0x15, + 0xc7, 0xc2, 0x72, 0x2e, 0xdc, 0xe3, 0x93, 0x43, 0x37, 0x45, 0xef, 0xf1, 0x0a, 0xb6, 0x66, 0xdc, + 0x91, 0xa1, 0x3b, 0xd7, 0xbf, 0x80, 0xee, 0xae, 0xe9, 0x3c, 0x15, 0xa3, 0xa1, 0xb4, 0xaf, 0x6f, + 0xd6, 0xfd, 0x93, 0xbf, 0xd3, 0x7a, 0x61, 0x4c, 0x59, 0x92, 0x9c, 0x7d, 0xf8, 0xe8, 0xe5, 0x81, + 0x75, 0x76, 0x36, 0x8f, 0x44, 0xa3, 0xb5, 0x06, 0x0e, 0xee, 0xc7, 0xf0, 0xbf, 0x06, 0xf5, 0xc0, + 0x3e, 0x4f, 0x91, 0xfa, 0x79, 0xff, 0x3c, 0xa4, 0x9b, 0xa2, 0x7c, 0x10, 0xd8, 0xe2, 0xc5, 0xc2, + 0x79, 0x77, 0xb5, 0x31, 0xb5, 0xeb, 0x8d, 0xa9, 0xfd, 0xdc, 0x98, 0xda, 0xd7, 0xad, 0x59, 0xbb, + 0xde, 0x9a, 0xb5, 0x6f, 0x5b, 0xb3, 0xf6, 0xf9, 0xf0, 0x4f, 0xe2, 0xcb, 0xbb, 0xa7, 0xa7, 0xee, + 0x40, 0x7b, 0xea, 0xd5, 0x1d, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x48, 0x67, 0xec, 0x5e, 0x0b, + 0x04, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -207,6 +271,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PublicRandomness) > 0 { + for iNdEx := len(m.PublicRandomness) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PublicRandomness[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.VoteSigs) > 0 { for iNdEx := len(m.VoteSigs) - 1; iNdEx >= 0; iNdEx-- { { @@ -314,6 +392,58 @@ func (m *VoteSig) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PublicRandomness) 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 *PublicRandomness) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PublicRandomness) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PubRand != nil { + { + size := m.PubRand.Size() + i -= size + if _, err := m.PubRand.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.BlockHeight != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.BlockHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -351,6 +481,12 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.PublicRandomness) > 0 { + for _, e := range m.PublicRandomness { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -374,6 +510,26 @@ func (m *VoteSig) Size() (n int) { return n } +func (m *PublicRandomness) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BlockHeight != 0 { + n += 1 + sovGenesis(uint64(m.BlockHeight)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.PubRand != nil { + l = m.PubRand.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -544,6 +700,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicRandomness", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicRandomness = append(m.PublicRandomness, &PublicRandomness{}) + if err := m.PublicRandomness[len(m.PublicRandomness)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -704,6 +894,145 @@ func (m *VoteSig) Unmarshal(dAtA []byte) error { } return nil } +func (m *PublicRandomness) 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 ErrIntOverflowGenesis + } + 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: PublicRandomness: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicRandomness: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeight", wireType) + } + m.BlockHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BlockHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.SchnorrPubRand + m.PubRand = &v + if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/genesis_test.go b/x/finality/types/genesis_test.go index 760de2ed5..97dbf25c2 100644 --- a/x/finality/types/genesis_test.go +++ b/x/finality/types/genesis_test.go @@ -21,7 +21,9 @@ func TestGenesisState_Validate(t *testing.T) { { desc: "valid genesis state", genState: &types.GenesisState{ - Params: types.Params{}, + Params: types.Params{ + MinPubRand: 200, + }, }, valid: true, }, diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 2c51b410f..4e596001b 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -17,7 +17,8 @@ const ( var ( BlockKey = []byte{0x01} // key prefix for blocks VoteKey = []byte{0x02} // key prefix for votes - ParamsKey = []byte{0x03} // key prefix for the parameters - EvidenceKey = []byte{0x04} // key prefix for evidences - NextHeightToFinalizeKey = []byte{0x05} // key prefix for next height to finalise + PubRandKey = []byte{0x03} // key prefix for public randomness + ParamsKey = []byte{0x04} // key prefix for the parameters + EvidenceKey = []byte{0x05} // key prefix for evidences + NextHeightToFinalizeKey = []byte{0x06} // key prefix for next height to finalise ) diff --git a/x/finality/types/metrics.go b/x/finality/types/metrics.go index cb9e8339f..84c131add 100644 --- a/x/finality/types/metrics.go +++ b/x/finality/types/metrics.go @@ -7,7 +7,8 @@ import ( // performance oriented metrics measuring the execution time of each message const ( - MetricsKeyAddFinalitySig = "add_finality_sig" + MetricsKeyCommitPubRandList = "commit_pub_rand_list" + MetricsKeyAddFinalitySig = "add_finality_sig" ) // Metrics for monitoring block finalization status diff --git a/x/finality/types/msg.go b/x/finality/types/msg.go index 90f951672..ab86316a1 100644 --- a/x/finality/types/msg.go +++ b/x/finality/types/msg.go @@ -1,9 +1,12 @@ package types import ( + fmt "fmt" + "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/btcec/v2" + "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -11,6 +14,7 @@ import ( var ( _ sdk.Msg = &MsgUpdateParams{} _ sdk.Msg = &MsgAddFinalitySig{} + _ sdk.Msg = &MsgCommitPubRandList{} ) func NewMsgAddFinalitySig(signer string, sk *btcec.PrivateKey, sr *eots.PrivateRand, blockHeight uint64, blockHash []byte) (*MsgAddFinalitySig, error) { @@ -34,16 +38,49 @@ func (m *MsgAddFinalitySig) MsgToSign() []byte { return msgToSignForVote(m.BlockHeight, m.BlockAppHash) } -func (m *MsgAddFinalitySig) VerifyEOTSSig(mpr *eots.MasterPublicRand) error { +func (m *MsgAddFinalitySig) VerifyEOTSSig(pubRand *bbn.SchnorrPubRand) error { msgToSign := m.MsgToSign() pk, err := m.FpBtcPk.ToBTCPK() if err != nil { return err } - pubRand, err := mpr.DerivePubRand(uint32(m.BlockHeight)) + + return eots.Verify(pk, pubRand.ToFieldVal(), msgToSign, m.FinalitySig.ToModNScalar()) +} + +// HashToSign returns a 32-byte hash of (start_height || pub_rand_list) +// The signature in MsgCommitPubRandList will be on this hash +func (m *MsgCommitPubRandList) HashToSign() ([]byte, error) { + hasher := tmhash.New() + if _, err := hasher.Write(sdk.Uint64ToBigEndian(m.StartHeight)); err != nil { + return nil, err + } + for _, pr := range m.PubRandList { + if _, err := hasher.Write(pr.MustMarshal()); err != nil { + return nil, err + } + } + return hasher.Sum(nil), nil +} + +func (m *MsgCommitPubRandList) VerifySig() error { + msgHash, err := m.HashToSign() if err != nil { return err } - - return eots.Verify(pk, pubRand, msgToSign, m.FinalitySig.ToModNScalar()) + pk, err := m.FpBtcPk.ToBTCPK() + if err != nil { + return err + } + if m.Sig == nil { + return fmt.Errorf("empty signature") + } + schnorrSig, err := m.Sig.ToBTCSig() + if err != nil { + return err + } + if !schnorrSig.Verify(msgHash, pk) { + return fmt.Errorf("failed to verify signature") + } + return nil } diff --git a/x/finality/types/msg_test.go b/x/finality/types/msg_test.go index 78977c1cb..9dafd9d14 100644 --- a/x/finality/types/msg_test.go +++ b/x/finality/types/msg_test.go @@ -6,6 +6,7 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" "github.com/stretchr/testify/require" ) @@ -18,20 +19,37 @@ func FuzzMsgAddFinalitySig(f *testing.F) { sk, err := eots.KeyGen(r) require.NoError(t, err) - msr, mpr, err := eots.NewMasterRandPair(r) + sr, pr, err := eots.RandGen(r) require.NoError(t, err) blockHeight := datagen.RandomInt(r, 10) blockHash := datagen.GenRandomByteArray(r, 32) - sr, _, err := msr.DeriveRandPair(uint32(blockHeight)) - require.NoError(t, err) - signer := datagen.GenRandomAccount().Address msg, err := types.NewMsgAddFinalitySig(signer, sk, sr, blockHeight, blockHash) require.NoError(t, err) // verify msg's EOTS sig against the given public randomness - err = msg.VerifyEOTSSig(mpr) + err = msg.VerifyEOTSSig(bbn.NewSchnorrPubRandFromFieldVal(pr)) + require.NoError(t, err) + }) +} + +func FuzzMsgCommitPubRandList(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + sk, _, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + startHeight := datagen.RandomInt(r, 10) + numPubRand := datagen.RandomInt(r, 100) + 1 + _, msg, err := datagen.GenRandomMsgCommitPubRandList(r, sk, startHeight, numPubRand) + require.NoError(t, err) + + // sanity checks, including verifying signature + err = msg.VerifySig() require.NoError(t, err) }) } diff --git a/x/finality/types/params.go b/x/finality/types/params.go index 957716b08..437a4e662 100644 --- a/x/finality/types/params.go +++ b/x/finality/types/params.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" ) @@ -14,7 +16,9 @@ func ParamKeyTable() paramtypes.KeyTable { // DefaultParams returns a default set of parameters func DefaultParams() Params { - return Params{} + return Params{ + MinPubRand: 100, + } } // ParamSetPairs get the params.ParamSet @@ -22,8 +26,18 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { return paramtypes.ParamSetPairs{} } +func validateMinPubRand(minPubRand uint64) error { + if minPubRand == 0 { + return fmt.Errorf("min Pub Rand cannot be 0") + } + return nil +} + // Validate validates the set of params func (p Params) Validate() error { + if err := validateMinPubRand(p.MinPubRand); err != nil { + return err + } return nil } diff --git a/x/finality/types/params.pb.go b/x/finality/types/params.pb.go index e967d01e6..fe81592df 100644 --- a/x/finality/types/params.pb.go +++ b/x/finality/types/params.pb.go @@ -25,6 +25,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { + // min_pub_rand is the minimum number of public randomness each + // message should commit + MinPubRand uint64 `protobuf:"varint,1,opt,name=min_pub_rand,json=minPubRand,proto3" json:"min_pub_rand,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -59,6 +62,13 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo +func (m *Params) GetMinPubRand() uint64 { + if m != nil { + return m.MinPubRand + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "babylon.finality.v1.Params") } @@ -66,17 +76,19 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/params.proto", fileDescriptor_25539c9a61c72ee9) } var fileDescriptor_25539c9a61c72ee9 = []byte{ - // 158 bytes of a gzipped FileDescriptorProto + // 192 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, 0xd0, 0x83, 0xa9, 0xd0, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xeb, 0x83, - 0x58, 0x10, 0xa5, 0x4a, 0x7c, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x56, 0x2c, 0x33, 0x16, 0xc8, 0x33, - 0x38, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, - 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x41, 0x7a, 0x66, - 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xfc, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, - 0x18, 0x47, 0xbf, 0x02, 0xe1, 0xa0, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x15, 0xc6, - 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x67, 0x01, 0xe8, 0x48, 0xb1, 0x00, 0x00, 0x00, + 0x58, 0x10, 0xa5, 0x4a, 0x06, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x42, 0x0a, 0x5c, 0x3c, 0xb9, 0x99, + 0x79, 0xf1, 0x05, 0xa5, 0x49, 0xf1, 0x45, 0x89, 0x79, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x2c, + 0x41, 0x5c, 0xb9, 0x99, 0x79, 0x01, 0xa5, 0x49, 0x41, 0x89, 0x79, 0x29, 0x56, 0x2c, 0x33, 0x16, + 0xc8, 0x33, 0x38, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, + 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x41, + 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0x05, 0xc9, 0x19, 0x89, + 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0xc2, 0xc9, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, + 0x47, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x3d, 0x78, 0xb7, 0xd3, 0x00, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -99,6 +111,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.MinPubRand != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MinPubRand)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -119,6 +136,9 @@ func (m *Params) Size() (n int) { } var l int _ = l + if m.MinPubRand != 0 { + n += 1 + sovParams(uint64(m.MinPubRand)) + } return n } @@ -157,6 +177,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinPubRand", wireType) + } + m.MinPubRand = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinPubRand |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index c4b874973..a4b12e2ea 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -146,6 +146,112 @@ func (m *QueryParamsResponse) GetParams() Params { return Params{} } +// QueryListPublicRandomnessRequest is the request type for the +// Query/ListPublicRandomness RPC method. +type QueryListPublicRandomnessRequest struct { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider + FpBtcPkHex string `protobuf:"bytes,1,opt,name=fp_btc_pk_hex,json=fpBtcPkHex,proto3" json:"fp_btc_pk_hex,omitempty"` + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryListPublicRandomnessRequest) Reset() { *m = QueryListPublicRandomnessRequest{} } +func (m *QueryListPublicRandomnessRequest) String() string { return proto.CompactTextString(m) } +func (*QueryListPublicRandomnessRequest) ProtoMessage() {} +func (*QueryListPublicRandomnessRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{2} +} +func (m *QueryListPublicRandomnessRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryListPublicRandomnessRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryListPublicRandomnessRequest.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 *QueryListPublicRandomnessRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryListPublicRandomnessRequest.Merge(m, src) +} +func (m *QueryListPublicRandomnessRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryListPublicRandomnessRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryListPublicRandomnessRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryListPublicRandomnessRequest proto.InternalMessageInfo + +func (m *QueryListPublicRandomnessRequest) GetFpBtcPkHex() string { + if m != nil { + return m.FpBtcPkHex + } + return "" +} + +func (m *QueryListPublicRandomnessRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryListPublicRandomnessResponse is the response type for the +// Query/ListPublicRandomness RPC method. +type QueryListPublicRandomnessResponse struct { + // pub_rand_map is the map where the key is the height and the value + // is the public randomness at this height for the given finality provider + PubRandMap map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,1,rep,name=pub_rand_map,json=pubRandMap,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryListPublicRandomnessResponse) Reset() { *m = QueryListPublicRandomnessResponse{} } +func (m *QueryListPublicRandomnessResponse) String() string { return proto.CompactTextString(m) } +func (*QueryListPublicRandomnessResponse) ProtoMessage() {} +func (*QueryListPublicRandomnessResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{3} +} +func (m *QueryListPublicRandomnessResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryListPublicRandomnessResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryListPublicRandomnessResponse.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 *QueryListPublicRandomnessResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryListPublicRandomnessResponse.Merge(m, src) +} +func (m *QueryListPublicRandomnessResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryListPublicRandomnessResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryListPublicRandomnessResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryListPublicRandomnessResponse proto.InternalMessageInfo + +func (m *QueryListPublicRandomnessResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryBlockRequest is the request type for the // Query/Block RPC method. type QueryBlockRequest struct { @@ -157,7 +263,7 @@ func (m *QueryBlockRequest) Reset() { *m = QueryBlockRequest{} } func (m *QueryBlockRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlockRequest) ProtoMessage() {} func (*QueryBlockRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{2} + return fileDescriptor_32bddab77af6fdae, []int{4} } func (m *QueryBlockRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -204,7 +310,7 @@ func (m *QueryBlockResponse) Reset() { *m = QueryBlockResponse{} } func (m *QueryBlockResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlockResponse) ProtoMessage() {} func (*QueryBlockResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{3} + return fileDescriptor_32bddab77af6fdae, []int{5} } func (m *QueryBlockResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -253,7 +359,7 @@ func (m *QueryListBlocksRequest) Reset() { *m = QueryListBlocksRequest{} func (m *QueryListBlocksRequest) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksRequest) ProtoMessage() {} func (*QueryListBlocksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{4} + return fileDescriptor_32bddab77af6fdae, []int{6} } func (m *QueryListBlocksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -309,7 +415,7 @@ func (m *QueryListBlocksResponse) Reset() { *m = QueryListBlocksResponse func (m *QueryListBlocksResponse) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksResponse) ProtoMessage() {} func (*QueryListBlocksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{5} + return fileDescriptor_32bddab77af6fdae, []int{7} } func (m *QueryListBlocksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -363,7 +469,7 @@ func (m *QueryVotesAtHeightRequest) Reset() { *m = QueryVotesAtHeightReq func (m *QueryVotesAtHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightRequest) ProtoMessage() {} func (*QueryVotesAtHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{6} + return fileDescriptor_32bddab77af6fdae, []int{8} } func (m *QueryVotesAtHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -411,7 +517,7 @@ func (m *QueryVotesAtHeightResponse) Reset() { *m = QueryVotesAtHeightRe func (m *QueryVotesAtHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightResponse) ProtoMessage() {} func (*QueryVotesAtHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{7} + return fileDescriptor_32bddab77af6fdae, []int{9} } func (m *QueryVotesAtHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -452,7 +558,7 @@ func (m *QueryEvidenceRequest) Reset() { *m = QueryEvidenceRequest{} } func (m *QueryEvidenceRequest) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceRequest) ProtoMessage() {} func (*QueryEvidenceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{8} + return fileDescriptor_32bddab77af6fdae, []int{10} } func (m *QueryEvidenceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -498,7 +604,7 @@ func (m *QueryEvidenceResponse) Reset() { *m = QueryEvidenceResponse{} } func (m *QueryEvidenceResponse) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceResponse) ProtoMessage() {} func (*QueryEvidenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{9} + return fileDescriptor_32bddab77af6fdae, []int{11} } func (m *QueryEvidenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -548,7 +654,7 @@ func (m *QueryListEvidencesRequest) Reset() { *m = QueryListEvidencesReq func (m *QueryListEvidencesRequest) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesRequest) ProtoMessage() {} func (*QueryListEvidencesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{10} + return fileDescriptor_32bddab77af6fdae, []int{12} } func (m *QueryListEvidencesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,7 +710,7 @@ func (m *QueryListEvidencesResponse) Reset() { *m = QueryListEvidencesRe func (m *QueryListEvidencesResponse) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesResponse) ProtoMessage() {} func (*QueryListEvidencesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{11} + return fileDescriptor_32bddab77af6fdae, []int{13} } func (m *QueryListEvidencesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -651,6 +757,9 @@ func init() { proto.RegisterEnum("babylon.finality.v1.QueriedBlockStatus", QueriedBlockStatus_name, QueriedBlockStatus_value) proto.RegisterType((*QueryParamsRequest)(nil), "babylon.finality.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.finality.v1.QueryParamsResponse") + proto.RegisterType((*QueryListPublicRandomnessRequest)(nil), "babylon.finality.v1.QueryListPublicRandomnessRequest") + proto.RegisterType((*QueryListPublicRandomnessResponse)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse") + proto.RegisterMapType((map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse.PubRandMapEntry") proto.RegisterType((*QueryBlockRequest)(nil), "babylon.finality.v1.QueryBlockRequest") proto.RegisterType((*QueryBlockResponse)(nil), "babylon.finality.v1.QueryBlockResponse") proto.RegisterType((*QueryListBlocksRequest)(nil), "babylon.finality.v1.QueryListBlocksRequest") @@ -666,61 +775,72 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 854 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x4f, 0x33, 0x45, - 0x18, 0xee, 0xf0, 0x7d, 0x94, 0x8f, 0xf9, 0xbe, 0x1a, 0x18, 0x10, 0x71, 0x91, 0x02, 0x8b, 0x16, - 0x04, 0xb2, 0x43, 0x8b, 0xd1, 0x10, 0x0f, 0x48, 0x23, 0x48, 0x15, 0x4b, 0x5d, 0x13, 0x13, 0xb9, - 0x34, 0xbb, 0x65, 0xd8, 0x6e, 0x68, 0x77, 0x96, 0xee, 0xb4, 0x69, 0x43, 0x48, 0x8c, 0x07, 0x2e, - 0x7a, 0x30, 0xf1, 0xe2, 0x85, 0x83, 0x5e, 0xfd, 0x47, 0x38, 0x92, 0x78, 0x31, 0x1e, 0x88, 0x01, - 0xff, 0x10, 0xb3, 0x33, 0xb3, 0x5d, 0x16, 0xb6, 0xb4, 0x07, 0x6e, 0xec, 0xcc, 0xf3, 0xbe, 0xcf, - 0xf3, 0xfe, 0x98, 0x87, 0xc2, 0x39, 0xd3, 0x30, 0x3b, 0x35, 0xea, 0xe0, 0x63, 0xdb, 0x31, 0x6a, - 0x36, 0xeb, 0xe0, 0x56, 0x16, 0x9f, 0x36, 0x49, 0xa3, 0xa3, 0xb9, 0x0d, 0xca, 0x28, 0x9a, 0x90, - 0x00, 0x2d, 0x00, 0x68, 0xad, 0xac, 0x32, 0x69, 0x51, 0x8b, 0xf2, 0x7b, 0xec, 0xff, 0x25, 0xa0, - 0xca, 0x7b, 0x16, 0xa5, 0x56, 0x8d, 0x60, 0xc3, 0xb5, 0xb1, 0xe1, 0x38, 0x94, 0x19, 0xcc, 0xa6, - 0x8e, 0x27, 0x6f, 0x57, 0x2a, 0xd4, 0xab, 0x53, 0x0f, 0x9b, 0x86, 0x47, 0x04, 0x03, 0x6e, 0x65, - 0x4d, 0xc2, 0x8c, 0x2c, 0x76, 0x0d, 0xcb, 0x76, 0x38, 0x58, 0x62, 0xe7, 0xe3, 0x54, 0xb9, 0x46, - 0xc3, 0xa8, 0x07, 0xd9, 0xd4, 0x38, 0x44, 0x57, 0x22, 0xc7, 0xa8, 0x93, 0x10, 0x7d, 0xe3, 0xf3, - 0x94, 0x78, 0xa0, 0x4e, 0x4e, 0x9b, 0xc4, 0x63, 0x6a, 0x09, 0x4e, 0x44, 0x4e, 0x3d, 0x97, 0x3a, - 0x1e, 0x41, 0x9b, 0x30, 0x29, 0x08, 0xa6, 0xc1, 0x3c, 0x58, 0x7e, 0x9d, 0x9b, 0xd1, 0x62, 0x0a, - 0xd7, 0x44, 0x50, 0xfe, 0xe5, 0xd5, 0xcd, 0x5c, 0x42, 0x97, 0x01, 0xea, 0x2a, 0x1c, 0xe7, 0x19, - 0xf3, 0x35, 0x5a, 0x39, 0x91, 0x34, 0x68, 0x0a, 0x26, 0xab, 0xc4, 0xb6, 0xaa, 0x8c, 0xe7, 0x7b, - 0xa9, 0xcb, 0x2f, 0xf5, 0x6b, 0x29, 0x4a, 0x82, 0x25, 0xfb, 0x27, 0x70, 0xd8, 0xf4, 0x0f, 0x24, - 0xf9, 0x42, 0x2c, 0x79, 0xc1, 0x39, 0x22, 0x6d, 0x72, 0x24, 0x22, 0x05, 0x5e, 0xfd, 0x1d, 0xc0, - 0x29, 0x9e, 0x6f, 0xdf, 0xf6, 0x18, 0xbf, 0x09, 0x0a, 0x45, 0x5b, 0x30, 0xe9, 0x31, 0x83, 0x35, - 0x45, 0x45, 0x6f, 0xe5, 0x96, 0x62, 0x93, 0xfa, 0xc1, 0xb6, 0x4c, 0xfa, 0x2d, 0x87, 0xeb, 0x32, - 0x0c, 0xed, 0x42, 0x18, 0x4e, 0x66, 0x7a, 0x88, 0x2b, 0xcb, 0x68, 0x62, 0x8c, 0x9a, 0x3f, 0x46, - 0x4d, 0x2c, 0x8a, 0x1c, 0xa3, 0x56, 0x32, 0x2c, 0x22, 0xc9, 0xf5, 0x7b, 0x91, 0xea, 0x25, 0x80, - 0xef, 0x3c, 0xd2, 0x18, 0xb6, 0x9d, 0x17, 0xe2, 0x8b, 0x7c, 0x31, 0x58, 0xe5, 0x32, 0x00, 0x7d, - 0x11, 0x23, 0x6f, 0xa9, 0xaf, 0x3c, 0xc1, 0x1b, 0xd1, 0xb7, 0x01, 0xdf, 0xe5, 0xf2, 0xbe, 0xa3, - 0x8c, 0x78, 0xdb, 0x6c, 0x8f, 0x0f, 0xaa, 0xdf, 0x1c, 0xeb, 0x50, 0x89, 0x0b, 0x92, 0x65, 0x1d, - 0xc0, 0x11, 0x93, 0x55, 0xca, 0xae, 0xac, 0xeb, 0x4d, 0xfe, 0xe3, 0x7f, 0x6e, 0xe6, 0x72, 0x96, - 0xcd, 0xaa, 0x4d, 0x53, 0xab, 0xd0, 0x3a, 0x96, 0x55, 0x56, 0xaa, 0x86, 0xed, 0x04, 0x1f, 0x98, - 0x75, 0x5c, 0xe2, 0x69, 0xf9, 0x42, 0x69, 0xe3, 0xa3, 0xf5, 0x52, 0xd3, 0xfc, 0x8a, 0x74, 0xf4, - 0xa4, 0xc9, 0x2a, 0xa5, 0x13, 0x4f, 0xdd, 0x84, 0x93, 0x9c, 0x6e, 0xa7, 0x65, 0x1f, 0x11, 0xa7, - 0x12, 0xf4, 0x19, 0x2d, 0xc0, 0xd4, 0xb1, 0x5b, 0x16, 0x5c, 0xe5, 0x2a, 0x69, 0x73, 0x95, 0xa3, - 0x3a, 0x3c, 0x76, 0xf3, 0x7e, 0xe0, 0x1e, 0x69, 0xab, 0x3a, 0x7c, 0xfb, 0x41, 0x68, 0xb7, 0xf7, - 0xaf, 0x88, 0x3c, 0x93, 0x7b, 0x37, 0x1b, 0xdb, 0xfd, 0x6e, 0x60, 0x17, 0xae, 0x5e, 0x00, 0xd9, - 0x33, 0x7f, 0xa4, 0xc1, 0xbd, 0x17, 0x8a, 0x7a, 0xe3, 0x31, 0xa3, 0xc1, 0xca, 0x91, 0xce, 0xbd, - 0xe6, 0x67, 0xa2, 0x51, 0xcf, 0xb6, 0x5b, 0x7f, 0x00, 0x39, 0x87, 0x07, 0x42, 0x64, 0x89, 0x9f, - 0xc2, 0xd1, 0x40, 0x73, 0xb0, 0x61, 0x7d, 0x6a, 0x0c, 0xf1, 0xcf, 0xb6, 0x60, 0x2b, 0x5b, 0xe2, - 0xcd, 0x47, 0x9f, 0x19, 0x1a, 0x87, 0xa9, 0xe2, 0x41, 0xb1, 0xbc, 0x5b, 0x28, 0x6e, 0xef, 0x17, - 0x0e, 0x77, 0x3e, 0x1f, 0x4b, 0xa0, 0x14, 0x1c, 0x0d, 0x3f, 0x01, 0x1a, 0x81, 0x2f, 0xb6, 0x8b, - 0xdf, 0x8f, 0x0d, 0xe5, 0x7e, 0x1a, 0x81, 0xc3, 0xbc, 0x4a, 0xf4, 0x03, 0x80, 0x49, 0x61, 0x42, - 0xa8, 0xf7, 0x7b, 0x8e, 0x3a, 0x9e, 0xb2, 0xdc, 0x1f, 0x28, 0x44, 0xab, 0x8b, 0x3f, 0xfe, 0xf5, - 0xdf, 0xaf, 0x43, 0xb3, 0x68, 0x06, 0xf7, 0x36, 0x60, 0x74, 0x01, 0xe0, 0x30, 0xaf, 0x03, 0x65, - 0x7a, 0x27, 0xbe, 0xef, 0x85, 0xca, 0x52, 0x5f, 0x9c, 0xe4, 0x5f, 0xe3, 0xfc, 0x19, 0xf4, 0x7e, - 0x2c, 0xbf, 0x78, 0xf7, 0xf8, 0x4c, 0x6c, 0xd5, 0x39, 0xfa, 0x19, 0x40, 0x18, 0x5a, 0x0a, 0x5a, - 0xed, 0xcd, 0xf2, 0xc8, 0x1c, 0x95, 0xb5, 0xc1, 0xc0, 0x03, 0xf5, 0x45, 0xfa, 0xd1, 0x25, 0x80, - 0xa9, 0x88, 0x1b, 0x20, 0xad, 0x37, 0x49, 0x9c, 0xd7, 0x28, 0x78, 0x60, 0xbc, 0xd4, 0xb5, 0xca, - 0x75, 0x7d, 0x80, 0x16, 0x63, 0x75, 0xb5, 0xfc, 0x98, 0xb0, 0x5d, 0x7f, 0x02, 0xf8, 0x2a, 0x58, - 0x73, 0xf4, 0x61, 0x6f, 0xaa, 0x07, 0x16, 0xa3, 0xac, 0x0c, 0x02, 0x95, 0x82, 0xf6, 0xb8, 0xa0, - 0x3c, 0xfa, 0x0c, 0x3f, 0xf5, 0xff, 0xb9, 0xec, 0x36, 0xa8, 0x1f, 0xd9, 0xf0, 0xf0, 0x59, 0xc4, - 0xbd, 0xce, 0x71, 0xf0, 0xfa, 0xd0, 0x6f, 0x00, 0xa6, 0x22, 0x6f, 0xfa, 0xa9, 0x6e, 0xc6, 0xb9, - 0xd0, 0x53, 0xdd, 0x8c, 0x35, 0x0b, 0x35, 0xc3, 0xc5, 0xcf, 0xa3, 0x74, 0xac, 0xf8, 0xae, 0x2f, - 0xe4, 0xbf, 0xbc, 0xba, 0x4d, 0x83, 0xeb, 0xdb, 0x34, 0xf8, 0xf7, 0x36, 0x0d, 0x7e, 0xb9, 0x4b, - 0x27, 0xae, 0xef, 0xd2, 0x89, 0xbf, 0xef, 0xd2, 0x89, 0xc3, 0xf5, 0x7e, 0x0e, 0xdf, 0x0e, 0x53, - 0x72, 0xb3, 0x37, 0x93, 0xfc, 0xa7, 0xca, 0xc6, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc6, 0x11, - 0x04, 0x7a, 0x88, 0x09, 0x00, 0x00, + // 1028 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xce, 0x38, 0x8d, 0x9b, 0xbc, 0xc4, 0x90, 0x4e, 0x4d, 0x09, 0x2e, 0x75, 0x9c, 0x2d, 0x24, + 0x21, 0xa9, 0x76, 0x1b, 0xa7, 0x94, 0x16, 0x84, 0x4a, 0x2c, 0x12, 0x12, 0x68, 0x5d, 0xb3, 0x95, + 0x2a, 0xd1, 0x8b, 0x35, 0x6b, 0x4f, 0xec, 0x55, 0xec, 0x9d, 0xed, 0xee, 0xac, 0x15, 0xab, 0xaa, + 0x84, 0x38, 0xf4, 0x04, 0x12, 0x12, 0x17, 0x2e, 0x3d, 0xd0, 0x2b, 0xff, 0x48, 0x8f, 0x91, 0xb8, + 0xa0, 0x4a, 0x44, 0x28, 0xe1, 0xc6, 0x3f, 0x81, 0x76, 0x66, 0xd6, 0x8e, 0xc3, 0xfa, 0x47, 0xab, + 0xdc, 0xbc, 0x33, 0xef, 0xc7, 0xf7, 0xbe, 0xf7, 0xe6, 0x7b, 0x86, 0x79, 0x8b, 0x58, 0xed, 0x06, + 0x73, 0x8c, 0x5d, 0xdb, 0x21, 0x0d, 0x9b, 0xb7, 0x8d, 0xd6, 0x9a, 0xf1, 0x38, 0xa0, 0x5e, 0x5b, + 0x77, 0x3d, 0xc6, 0x19, 0xbe, 0xa8, 0x0c, 0xf4, 0xc8, 0x40, 0x6f, 0xad, 0x65, 0xd2, 0x35, 0x56, + 0x63, 0xe2, 0xde, 0x08, 0x7f, 0x49, 0xd3, 0xcc, 0xfb, 0x35, 0xc6, 0x6a, 0x0d, 0x6a, 0x10, 0xd7, + 0x36, 0x88, 0xe3, 0x30, 0x4e, 0xb8, 0xcd, 0x1c, 0x5f, 0xdd, 0xae, 0x54, 0x98, 0xdf, 0x64, 0xbe, + 0x61, 0x11, 0x9f, 0xca, 0x0c, 0x46, 0x6b, 0xcd, 0xa2, 0x9c, 0xac, 0x19, 0x2e, 0xa9, 0xd9, 0x8e, + 0x30, 0x56, 0xb6, 0xb9, 0x38, 0x54, 0x2e, 0xf1, 0x48, 0x33, 0x8a, 0xa6, 0xc5, 0x59, 0x74, 0x20, + 0x0a, 0x1b, 0x2d, 0x0d, 0xf8, 0xdb, 0x30, 0x4f, 0x49, 0x38, 0x9a, 0xf4, 0x71, 0x40, 0x7d, 0xae, + 0x95, 0xe0, 0x62, 0xcf, 0xa9, 0xef, 0x32, 0xc7, 0xa7, 0xf8, 0x36, 0x24, 0x65, 0x82, 0x39, 0x94, + 0x43, 0xcb, 0xd3, 0xf9, 0xcb, 0x7a, 0x4c, 0xe1, 0xba, 0x74, 0x2a, 0x9c, 0x7b, 0x79, 0x38, 0x3f, + 0x66, 0x2a, 0x07, 0xed, 0x27, 0x04, 0x39, 0x11, 0xf2, 0xae, 0xed, 0xf3, 0x52, 0x60, 0x35, 0xec, + 0x8a, 0x49, 0x9c, 0x2a, 0x6b, 0x3a, 0xd4, 0x8f, 0xd2, 0xe2, 0x05, 0x48, 0xed, 0xba, 0x65, 0x8b, + 0x57, 0xca, 0xee, 0x5e, 0xb9, 0x4e, 0xf7, 0x45, 0x9a, 0x29, 0x13, 0x76, 0xdd, 0x02, 0xaf, 0x94, + 0xf6, 0xb6, 0xe9, 0x3e, 0xde, 0x02, 0xe8, 0x32, 0x31, 0x97, 0x10, 0x30, 0x16, 0x75, 0x49, 0x9b, + 0x1e, 0xd2, 0xa6, 0xcb, 0xc6, 0x28, 0xda, 0xf4, 0x12, 0xa9, 0x51, 0x15, 0xde, 0x3c, 0xe1, 0xa9, + 0x1d, 0x24, 0x60, 0x61, 0x00, 0x1e, 0x55, 0xf0, 0x0b, 0x04, 0x33, 0x6e, 0x60, 0x95, 0x3d, 0xe2, + 0x54, 0xcb, 0x4d, 0xe2, 0xce, 0xa1, 0xdc, 0xf8, 0xf2, 0x74, 0x7e, 0x2b, 0xb6, 0xee, 0xa1, 0xe1, + 0xf4, 0x52, 0x60, 0x85, 0xa7, 0xf7, 0x88, 0xbb, 0xe9, 0x70, 0xaf, 0x5d, 0xb8, 0xf5, 0xea, 0x70, + 0xfe, 0x46, 0xcd, 0xe6, 0xf5, 0xc0, 0xd2, 0x2b, 0xac, 0x69, 0xa8, 0xa8, 0x95, 0x3a, 0xb1, 0x9d, + 0xe8, 0xc3, 0xe0, 0x6d, 0x97, 0xfa, 0xfa, 0x83, 0x4a, 0xdd, 0x61, 0x9e, 0xa7, 0x22, 0x98, 0xe0, + 0x76, 0x42, 0xe1, 0xaf, 0x62, 0x28, 0x59, 0x1a, 0x4a, 0x89, 0x84, 0x74, 0x92, 0x93, 0xcc, 0xe7, + 0xf0, 0xf6, 0x29, 0x84, 0x78, 0x16, 0xc6, 0xf7, 0x68, 0x5b, 0xf4, 0xe1, 0x9c, 0x19, 0xfe, 0xc4, + 0x69, 0x98, 0x68, 0x91, 0x46, 0x40, 0x45, 0xa2, 0x19, 0x53, 0x7e, 0x7c, 0x9a, 0xb8, 0x85, 0xb4, + 0x55, 0xb8, 0x20, 0x28, 0x28, 0x34, 0x58, 0x65, 0x2f, 0x6a, 0xe9, 0x25, 0x48, 0xd6, 0xa9, 0x5d, + 0xab, 0x73, 0x15, 0x43, 0x7d, 0x69, 0xf7, 0xd4, 0xdc, 0x29, 0x63, 0xc5, 0xf7, 0x27, 0x30, 0x61, + 0x85, 0x07, 0x6a, 0xbe, 0x16, 0x62, 0x79, 0xde, 0x71, 0xaa, 0x74, 0x9f, 0x56, 0xa5, 0xa7, 0xb4, + 0xd7, 0x7e, 0x43, 0x70, 0xa9, 0xc3, 0xbf, 0xb8, 0xe9, 0x0c, 0xd5, 0x1d, 0x48, 0xfa, 0x9c, 0xf0, + 0x40, 0x0e, 0xed, 0x5b, 0xf9, 0xa5, 0xbe, 0xcd, 0xb3, 0x55, 0xd0, 0x07, 0xc2, 0xdc, 0x54, 0x6e, + 0x67, 0x36, 0x72, 0xcf, 0x11, 0xbc, 0xfb, 0x3f, 0x8c, 0xdd, 0x97, 0x25, 0x0a, 0xf1, 0xd5, 0x84, + 0x8d, 0x50, 0xb9, 0x72, 0x38, 0xb3, 0xf6, 0x6b, 0xeb, 0xf0, 0x9e, 0x80, 0xf7, 0x90, 0x71, 0xea, + 0x6f, 0xf0, 0x6d, 0xd1, 0xa8, 0x61, 0x7d, 0x6c, 0x42, 0x26, 0xce, 0x49, 0x95, 0x75, 0x1f, 0xce, + 0xcb, 0xd7, 0x2c, 0xeb, 0x9a, 0x29, 0xdc, 0x7c, 0x75, 0x38, 0x9f, 0x1f, 0x6d, 0xe2, 0x0b, 0x3b, + 0xa5, 0xf5, 0x1b, 0xd7, 0x4b, 0x81, 0xf5, 0x0d, 0x6d, 0x9b, 0x49, 0x2b, 0x14, 0x00, 0x5f, 0xbb, + 0x0d, 0x69, 0x91, 0x6e, 0xb3, 0x65, 0x57, 0xa9, 0x53, 0xa1, 0xa3, 0x2b, 0x87, 0x66, 0xc2, 0x3b, + 0xa7, 0x5c, 0x3b, 0xdc, 0x4f, 0x52, 0x75, 0xa6, 0xe6, 0xee, 0x4a, 0x2c, 0xfb, 0x1d, 0xc7, 0x8e, + 0xb9, 0xf6, 0x0c, 0x29, 0xce, 0xc2, 0x96, 0x46, 0xf7, 0x27, 0xe4, 0x6c, 0xc6, 0xe7, 0xc4, 0xe3, + 0xe5, 0x1e, 0xe6, 0xa6, 0xc5, 0x99, 0x24, 0xea, 0xcc, 0x66, 0xeb, 0x05, 0x52, 0x7d, 0x38, 0x05, + 0x44, 0x95, 0xf8, 0x19, 0x4c, 0x45, 0x98, 0xa3, 0x09, 0x1b, 0x52, 0x63, 0xd7, 0xfe, 0xcc, 0x06, + 0x6c, 0xe5, 0x8e, 0x7c, 0xf3, 0xbd, 0xcf, 0x0c, 0x5f, 0x80, 0x54, 0xf1, 0x7e, 0xb1, 0xbc, 0xb5, + 0x53, 0xdc, 0xb8, 0xbb, 0xf3, 0x68, 0xf3, 0xcb, 0xd9, 0x31, 0x9c, 0x82, 0xa9, 0xee, 0x27, 0xc2, + 0xe7, 0x61, 0x7c, 0xa3, 0xf8, 0xdd, 0x6c, 0x22, 0xff, 0xef, 0x24, 0x4c, 0x88, 0x2a, 0xf1, 0xf7, + 0x08, 0x92, 0x72, 0xcf, 0xe0, 0xfe, 0xef, 0xb9, 0x77, 0xa9, 0x65, 0x96, 0x87, 0x1b, 0x4a, 0xd0, + 0xda, 0xd5, 0x1f, 0xfe, 0xf8, 0xe7, 0x97, 0xc4, 0x15, 0x7c, 0xd9, 0xe8, 0xbf, 0x63, 0xf1, 0x5f, + 0x08, 0xd2, 0x71, 0x6a, 0x8f, 0x3f, 0x7e, 0xdd, 0xed, 0x20, 0xe1, 0xdd, 0x7c, 0xb3, 0xa5, 0xa2, + 0x3d, 0x14, 0x60, 0x4b, 0xb8, 0x68, 0x0c, 0x5a, 0xf7, 0x65, 0xd7, 0x63, 0x61, 0x47, 0x3d, 0xdf, + 0x78, 0xd2, 0xf3, 0x52, 0x9e, 0x1a, 0xae, 0x88, 0x2c, 0x76, 0x9c, 0x0c, 0x5d, 0x6e, 0xd8, 0x3e, + 0xc7, 0xcf, 0x10, 0x4c, 0x88, 0x3e, 0xe1, 0xc5, 0xfe, 0xc8, 0x4e, 0x6a, 0x7d, 0x66, 0x69, 0xa8, + 0x9d, 0x82, 0x7c, 0x4d, 0x40, 0x5e, 0xc4, 0x1f, 0xc4, 0x42, 0x96, 0xba, 0x66, 0x3c, 0x91, 0xaf, + 0xe6, 0x29, 0xfe, 0x11, 0x01, 0x74, 0x25, 0x13, 0xaf, 0x0e, 0xe6, 0xa9, 0x47, 0xfc, 0x33, 0xd7, + 0x46, 0x33, 0x1e, 0xa9, 0xef, 0x4a, 0x6f, 0x9f, 0x23, 0x48, 0xf5, 0xa8, 0x1d, 0xd6, 0xfb, 0x27, + 0x89, 0xd3, 0xd2, 0x8c, 0x31, 0xb2, 0xbd, 0xc2, 0xb5, 0x2a, 0x70, 0x7d, 0x88, 0xaf, 0xc6, 0xe2, + 0x6a, 0x85, 0x3e, 0x5d, 0xba, 0x7e, 0x47, 0x30, 0x19, 0x3d, 0x63, 0xfc, 0x51, 0xff, 0x54, 0xa7, + 0x24, 0x34, 0xb3, 0x32, 0x8a, 0xa9, 0x02, 0xb4, 0x2d, 0x00, 0x15, 0xf0, 0x17, 0x6f, 0x3a, 0x73, + 0x91, 0xba, 0xe0, 0x5f, 0x11, 0xa4, 0x7a, 0x34, 0x6b, 0x10, 0x9b, 0x71, 0x2a, 0x3b, 0x88, 0xcd, + 0x58, 0x31, 0xd4, 0x16, 0x05, 0xf8, 0x1c, 0xce, 0xc6, 0x82, 0xef, 0xe8, 0x5e, 0xe1, 0xeb, 0x97, + 0x47, 0x59, 0x74, 0x70, 0x94, 0x45, 0x7f, 0x1f, 0x65, 0xd1, 0xcf, 0xc7, 0xd9, 0xb1, 0x83, 0xe3, + 0xec, 0xd8, 0x9f, 0xc7, 0xd9, 0xb1, 0x47, 0xd7, 0x87, 0x6d, 0xb0, 0xfd, 0x6e, 0x48, 0xb1, 0xcc, + 0xac, 0xa4, 0xf8, 0xb7, 0xbd, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x08, 0x51, 0x06, + 0x4b, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -737,6 +857,8 @@ const _ = grpc.SupportPackageIsVersion4 type QueryClient interface { // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // ListPublicRandomness is a range query for public randomness of a given finality provider + ListPublicRandomness(ctx context.Context, in *QueryListPublicRandomnessRequest, opts ...grpc.CallOption) (*QueryListPublicRandomnessResponse, error) // Block queries a block at a given height Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -766,6 +888,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . return out, nil } +func (c *queryClient) ListPublicRandomness(ctx context.Context, in *QueryListPublicRandomnessRequest, opts ...grpc.CallOption) (*QueryListPublicRandomnessResponse, error) { + out := new(QueryListPublicRandomnessResponse) + err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/ListPublicRandomness", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) { out := new(QueryBlockResponse) err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/Block", in, out, opts...) @@ -815,6 +946,8 @@ func (c *queryClient) ListEvidences(ctx context.Context, in *QueryListEvidencesR type QueryServer interface { // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // ListPublicRandomness is a range query for public randomness of a given finality provider + ListPublicRandomness(context.Context, *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) // Block queries a block at a given height Block(context.Context, *QueryBlockRequest) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -834,6 +967,9 @@ type UnimplementedQueryServer struct { func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") } +func (*UnimplementedQueryServer) ListPublicRandomness(ctx context.Context, req *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPublicRandomness not implemented") +} func (*UnimplementedQueryServer) Block(ctx context.Context, req *QueryBlockRequest) (*QueryBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Block not implemented") } @@ -872,6 +1008,24 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf return interceptor(ctx, in, info, handler) } +func _Query_ListPublicRandomness_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryListPublicRandomnessRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ListPublicRandomness(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.finality.v1.Query/ListPublicRandomness", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ListPublicRandomness(ctx, req.(*QueryListPublicRandomnessRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_Block_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryBlockRequest) if err := dec(in); err != nil { @@ -970,6 +1124,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Params", Handler: _Query_Params_Handler, }, + { + MethodName: "ListPublicRandomness", + Handler: _Query_ListPublicRandomness_Handler, + }, { MethodName: "Block", Handler: _Query_Block_Handler, @@ -1051,6 +1209,107 @@ func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryListPublicRandomnessRequest) 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 *QueryListPublicRandomnessRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryListPublicRandomnessRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.FpBtcPkHex) > 0 { + i -= len(m.FpBtcPkHex) + copy(dAtA[i:], m.FpBtcPkHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.FpBtcPkHex))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryListPublicRandomnessResponse) 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 *QueryListPublicRandomnessResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryListPublicRandomnessResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.PubRandMap) > 0 { + for k := range m.PubRandMap { + v := m.PubRandMap[k] + baseI := i + if v != nil { + { + size := v.Size() + i -= size + if _, err := v.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + i = encodeVarintQuery(dAtA, i, uint64(k)) + i-- + dAtA[i] = 0x8 + i = encodeVarintQuery(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + func (m *QueryBlockRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1453,6 +1712,49 @@ func (m *QueryParamsResponse) Size() (n int) { return n } +func (m *QueryListPublicRandomnessRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FpBtcPkHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryListPublicRandomnessResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.PubRandMap) > 0 { + for k, v := range m.PubRandMap { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovQuery(uint64(l)) + } + mapEntrySize := 1 + sovQuery(uint64(k)) + l + n += mapEntrySize + 1 + sovQuery(uint64(mapEntrySize)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryBlockRequest) Size() (n int) { if m == nil { return 0 @@ -1740,6 +2042,326 @@ func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryListPublicRandomnessRequest) 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 ErrIntOverflowQuery + } + 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: QueryListPublicRandomnessRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryListPublicRandomnessRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FpBtcPkHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryListPublicRandomnessResponse) 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 ErrIntOverflowQuery + } + 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: QueryListPublicRandomnessResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryListPublicRandomnessResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRandMap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PubRandMap == nil { + m.PubRandMap = make(map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand) + } + var mapkey uint64 + var mapvalue1 github_com_babylonchain_babylon_types.SchnorrPubRand + var mapvalue = &mapvalue1 + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + } else if fieldNum == 2 { + var mapbyteLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapbyteLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intMapbyteLen := int(mapbyteLen) + if intMapbyteLen < 0 { + return ErrInvalidLengthQuery + } + postbytesIndex := iNdEx + intMapbyteLen + if postbytesIndex < 0 { + return ErrInvalidLengthQuery + } + if postbytesIndex > l { + return io.ErrUnexpectedEOF + } + if err := mapvalue.Unmarshal(dAtA[iNdEx:postbytesIndex]); err != nil { + return err + } + iNdEx = postbytesIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.PubRandMap[mapkey] = ((*github_com_babylonchain_babylon_types.SchnorrPubRand)(mapvalue)) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryBlockRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/query.pb.gw.go b/x/finality/types/query.pb.gw.go index 7672bd263..1d001a7a0 100644 --- a/x/finality/types/query.pb.gw.go +++ b/x/finality/types/query.pb.gw.go @@ -51,6 +51,78 @@ func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshal } +var ( + filter_Query_ListPublicRandomness_0 = &utilities.DoubleArray{Encoding: map[string]int{"fp_btc_pk_hex": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_ListPublicRandomness_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryListPublicRandomnessRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPublicRandomness_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListPublicRandomness(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ListPublicRandomness_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryListPublicRandomnessRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPublicRandomness_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListPublicRandomness(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_Block_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryBlockRequest var metadata runtime.ServerMetadata @@ -314,6 +386,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ListPublicRandomness_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ListPublicRandomness_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ListPublicRandomness_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -490,6 +585,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ListPublicRandomness_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ListPublicRandomness_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ListPublicRandomness_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -596,6 +711,8 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie var ( pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ListPublicRandomness_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "finality", "v1", "finality_providers", "fp_btc_pk_hex", "public_randomness_list"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Block_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "finality", "v1", "blocks", "height"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ListBlocks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "blocks"}, "", runtime.AssumeColonVerbOpt(false))) @@ -610,6 +727,8 @@ var ( var ( forward_Query_Params_0 = runtime.ForwardResponseMessage + forward_Query_ListPublicRandomness_0 = runtime.ForwardResponseMessage + forward_Query_Block_0 = runtime.ForwardResponseMessage forward_Query_ListBlocks_0 = runtime.ForwardResponseMessage diff --git a/x/finality/types/tx.pb.go b/x/finality/types/tx.pb.go index 0ff2273b7..9e717dc67 100644 --- a/x/finality/types/tx.pb.go +++ b/x/finality/types/tx.pb.go @@ -31,6 +31,107 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// MsgCommitPubRandList defines a message for committing a list of public randomness for EOTS +type MsgCommitPubRandList struct { + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // start_height is the start block height of the list of public randomness + StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + // pub_rand_list is the list of public randomness + PubRandList []github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,4,rep,name=pub_rand_list,json=pubRandList,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_list,omitempty"` + // sig is the signature on (start_height || pub_rand_list) signed by + // SK corresponding to fp_btc_pk. This prevents others to commit public + // randomness on behalf of fp_btc_pk + // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts + // the tx submitter to be the holder of fp_btc_pk. Decide this later + Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,5,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` +} + +func (m *MsgCommitPubRandList) Reset() { *m = MsgCommitPubRandList{} } +func (m *MsgCommitPubRandList) String() string { return proto.CompactTextString(m) } +func (*MsgCommitPubRandList) ProtoMessage() {} +func (*MsgCommitPubRandList) Descriptor() ([]byte, []int) { + return fileDescriptor_2dd6da066b6baf1d, []int{0} +} +func (m *MsgCommitPubRandList) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCommitPubRandList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCommitPubRandList.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 *MsgCommitPubRandList) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCommitPubRandList.Merge(m, src) +} +func (m *MsgCommitPubRandList) XXX_Size() int { + return m.Size() +} +func (m *MsgCommitPubRandList) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCommitPubRandList.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCommitPubRandList proto.InternalMessageInfo + +func (m *MsgCommitPubRandList) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +func (m *MsgCommitPubRandList) GetStartHeight() uint64 { + if m != nil { + return m.StartHeight + } + return 0 +} + +// MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message +type MsgCommitPubRandListResponse struct { +} + +func (m *MsgCommitPubRandListResponse) Reset() { *m = MsgCommitPubRandListResponse{} } +func (m *MsgCommitPubRandListResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCommitPubRandListResponse) ProtoMessage() {} +func (*MsgCommitPubRandListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_2dd6da066b6baf1d, []int{1} +} +func (m *MsgCommitPubRandListResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCommitPubRandListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCommitPubRandListResponse.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 *MsgCommitPubRandListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCommitPubRandListResponse.Merge(m, src) +} +func (m *MsgCommitPubRandListResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCommitPubRandListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCommitPubRandListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCommitPubRandListResponse proto.InternalMessageInfo + // MsgAddFinalitySig defines a message for adding a finality vote type MsgAddFinalitySig struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` @@ -51,7 +152,7 @@ func (m *MsgAddFinalitySig) Reset() { *m = MsgAddFinalitySig{} } func (m *MsgAddFinalitySig) String() string { return proto.CompactTextString(m) } func (*MsgAddFinalitySig) ProtoMessage() {} func (*MsgAddFinalitySig) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{0} + return fileDescriptor_2dd6da066b6baf1d, []int{2} } func (m *MsgAddFinalitySig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -109,7 +210,7 @@ func (m *MsgAddFinalitySigResponse) Reset() { *m = MsgAddFinalitySigResp func (m *MsgAddFinalitySigResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddFinalitySigResponse) ProtoMessage() {} func (*MsgAddFinalitySigResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{1} + return fileDescriptor_2dd6da066b6baf1d, []int{3} } func (m *MsgAddFinalitySigResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -155,7 +256,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{2} + return fileDescriptor_2dd6da066b6baf1d, []int{4} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -206,7 +307,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_2dd6da066b6baf1d, []int{3} + return fileDescriptor_2dd6da066b6baf1d, []int{5} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -236,6 +337,8 @@ func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo func init() { + proto.RegisterType((*MsgCommitPubRandList)(nil), "babylon.finality.v1.MsgCommitPubRandList") + proto.RegisterType((*MsgCommitPubRandListResponse)(nil), "babylon.finality.v1.MsgCommitPubRandListResponse") proto.RegisterType((*MsgAddFinalitySig)(nil), "babylon.finality.v1.MsgAddFinalitySig") proto.RegisterType((*MsgAddFinalitySigResponse)(nil), "babylon.finality.v1.MsgAddFinalitySigResponse") proto.RegisterType((*MsgUpdateParams)(nil), "babylon.finality.v1.MsgUpdateParams") @@ -245,41 +348,48 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/tx.proto", fileDescriptor_2dd6da066b6baf1d) } var fileDescriptor_2dd6da066b6baf1d = []byte{ - // 531 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x6f, 0xd3, 0x30, - 0x1c, 0x6d, 0xf6, 0xa7, 0xa8, 0x6e, 0x55, 0x44, 0x98, 0x58, 0xda, 0xa1, 0xb4, 0x54, 0x13, 0xaa, - 0x26, 0x48, 0xb6, 0x6e, 0x9a, 0x60, 0xb7, 0x46, 0x02, 0x0d, 0x50, 0x45, 0x95, 0xc2, 0x05, 0x0e, - 0x91, 0x93, 0xa6, 0xb6, 0xd5, 0x36, 0xb6, 0x62, 0x77, 0x5a, 0x6e, 0x88, 0x4f, 0xc0, 0x81, 0x0f, - 0x32, 0x21, 0x3e, 0xc4, 0x8e, 0x13, 0x27, 0xd4, 0x43, 0x85, 0xda, 0xc3, 0xbe, 0x06, 0x6a, 0xe2, - 0xa8, 0xb0, 0x15, 0xd1, 0x9b, 0x7f, 0x7e, 0xef, 0xe7, 0xf7, 0xfc, 0xfc, 0x33, 0x78, 0xe8, 0x42, - 0x37, 0x1a, 0xd0, 0xc0, 0xec, 0x91, 0x00, 0x0e, 0x88, 0x88, 0xcc, 0xb3, 0x03, 0x53, 0x9c, 0x1b, - 0x2c, 0xa4, 0x82, 0xaa, 0xf7, 0x25, 0x6a, 0xa4, 0xa8, 0x71, 0x76, 0x50, 0xde, 0x42, 0x14, 0xd1, - 0x18, 0x37, 0xe7, 0xab, 0x84, 0x5a, 0x2e, 0x79, 0x94, 0x0f, 0x29, 0x77, 0x12, 0x20, 0x29, 0x24, - 0xb4, 0x9d, 0x54, 0xe6, 0x90, 0xa3, 0xf9, 0xe9, 0x43, 0x8e, 0x24, 0x50, 0x5d, 0x26, 0xce, 0x60, - 0x08, 0x87, 0xb2, 0xb5, 0xf6, 0x6d, 0x0d, 0xdc, 0x6b, 0x71, 0xd4, 0xec, 0x76, 0x5f, 0x4a, 0x4a, - 0x87, 0x20, 0xf5, 0x01, 0xc8, 0x72, 0x82, 0x02, 0x3f, 0xd4, 0x94, 0xaa, 0x52, 0xcf, 0xd9, 0xb2, - 0x52, 0x6d, 0x90, 0xeb, 0x31, 0xc7, 0x15, 0x9e, 0xc3, 0xfa, 0xda, 0x5a, 0x55, 0xa9, 0x17, 0xac, - 0xe3, 0xf1, 0xa4, 0xd2, 0x40, 0x44, 0xe0, 0x91, 0x6b, 0x78, 0x74, 0x68, 0x4a, 0x45, 0x0f, 0x43, - 0x12, 0xa4, 0x85, 0x29, 0x22, 0xe6, 0x73, 0xc3, 0x7a, 0xd5, 0x3e, 0x3c, 0xda, 0x6f, 0x8f, 0xdc, - 0x37, 0x7e, 0x64, 0xdf, 0xe9, 0x31, 0x4b, 0x78, 0xed, 0xbe, 0xfa, 0x08, 0x14, 0xdc, 0x01, 0xf5, - 0xfa, 0x0e, 0xf6, 0x09, 0xc2, 0x42, 0x5b, 0xaf, 0x2a, 0xf5, 0x0d, 0x3b, 0x1f, 0xef, 0x9d, 0xc6, - 0x5b, 0xea, 0x2e, 0x28, 0x26, 0x14, 0xc8, 0x98, 0x83, 0x21, 0xc7, 0xda, 0xc6, 0x5c, 0xdb, 0x4e, - 0x1a, 0x9b, 0x8c, 0x9d, 0x42, 0x8e, 0xd5, 0x8f, 0xa0, 0x90, 0x5e, 0xd3, 0xe1, 0x04, 0x69, 0x9b, - 0xb1, 0xbf, 0x67, 0xe3, 0x49, 0xe5, 0x68, 0x35, 0x7f, 0x1d, 0x0f, 0x07, 0x34, 0x0c, 0x5f, 0xbc, - 0x7d, 0xd7, 0xe9, 0x10, 0x64, 0xe7, 0x7b, 0x8b, 0x44, 0x4e, 0xf2, 0x9f, 0xaf, 0x2f, 0xf6, 0x64, - 0x0c, 0xb5, 0x1d, 0x50, 0xba, 0x95, 0x99, 0xed, 0x73, 0x46, 0x03, 0xee, 0xd7, 0xbe, 0x2a, 0xe0, - 0x6e, 0x8b, 0xa3, 0xf7, 0xac, 0x0b, 0x85, 0xdf, 0x8e, 0xb3, 0x56, 0x8f, 0x41, 0x0e, 0x8e, 0x04, - 0xa6, 0x21, 0x11, 0x51, 0x12, 0xa9, 0xa5, 0xfd, 0xf8, 0xfe, 0x74, 0x4b, 0xbe, 0x62, 0xb3, 0xdb, - 0x0d, 0x7d, 0xce, 0x3b, 0x22, 0x24, 0x01, 0xb2, 0x17, 0x54, 0xf5, 0x39, 0xc8, 0x26, 0xaf, 0x15, - 0x87, 0x9d, 0x6f, 0xec, 0x18, 0x4b, 0xe6, 0xc5, 0x48, 0x44, 0xac, 0x8d, 0xcb, 0x49, 0x25, 0x63, - 0xcb, 0x86, 0x93, 0xe2, 0xdc, 0xf0, 0xe2, 0xa8, 0x5a, 0x09, 0x6c, 0xdf, 0x70, 0x95, 0x3a, 0x6e, - 0x8c, 0x15, 0xb0, 0xde, 0xe2, 0x48, 0xc5, 0xa0, 0x78, 0x63, 0x0e, 0x1e, 0x2f, 0xd5, 0xbb, 0x75, - 0xf7, 0xb2, 0xb1, 0x1a, 0x2f, 0x55, 0x54, 0x5d, 0x50, 0xf8, 0x2b, 0x9f, 0xdd, 0x7f, 0xf5, 0xff, - 0xc9, 0x2a, 0x3f, 0x59, 0x85, 0x95, 0x6a, 0x94, 0x37, 0x3f, 0x5d, 0x5f, 0xec, 0x29, 0xd6, 0xeb, - 0xcb, 0xa9, 0xae, 0x5c, 0x4d, 0x75, 0xe5, 0xd7, 0x54, 0x57, 0xbe, 0xcc, 0xf4, 0xcc, 0xd5, 0x4c, - 0xcf, 0xfc, 0x9c, 0xe9, 0x99, 0x0f, 0xfb, 0xff, 0x9b, 0x8a, 0xf3, 0xc5, 0xb7, 0x89, 0x07, 0xc4, - 0xcd, 0xc6, 0x7f, 0xe6, 0xf0, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10, 0x9d, 0x41, 0x5a, 0xd4, - 0x03, 0x00, 0x00, + // 647 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xdf, 0x4e, 0x13, 0x4f, + 0x14, 0xee, 0xb6, 0x85, 0x5f, 0x98, 0xf6, 0x87, 0x61, 0x25, 0xb2, 0x14, 0xb2, 0xad, 0x0d, 0x31, + 0x95, 0xe8, 0x2e, 0xff, 0x24, 0xc2, 0x1d, 0x6b, 0x34, 0x28, 0x36, 0x36, 0x5b, 0xbd, 0x51, 0x93, + 0xcd, 0xec, 0x9f, 0xce, 0x4e, 0xe8, 0xee, 0x8c, 0x3b, 0x53, 0x42, 0xef, 0x8c, 0x4f, 0xe0, 0x85, + 0x0f, 0x42, 0x8c, 0x0f, 0xc1, 0x8d, 0x09, 0xf1, 0xca, 0x90, 0xd8, 0x18, 0xb8, 0xe0, 0x35, 0x4c, + 0x77, 0xa7, 0x14, 0x4a, 0x89, 0xe5, 0xc6, 0xbb, 0x3d, 0x73, 0xbe, 0x73, 0xbe, 0x39, 0xdf, 0x7c, + 0x67, 0xc1, 0xbc, 0x0d, 0xed, 0x76, 0x93, 0x84, 0x7a, 0x03, 0x87, 0xb0, 0x89, 0x79, 0x5b, 0xdf, + 0x5b, 0xd6, 0xf9, 0xbe, 0x46, 0x23, 0xc2, 0x89, 0x7c, 0x5b, 0x64, 0xb5, 0x5e, 0x56, 0xdb, 0x5b, + 0x2e, 0x4c, 0x23, 0x82, 0x48, 0x9c, 0xd7, 0xbb, 0x5f, 0x09, 0xb4, 0x30, 0xeb, 0x10, 0x16, 0x10, + 0x66, 0x25, 0x89, 0x24, 0x10, 0xa9, 0x99, 0x24, 0xd2, 0x03, 0x86, 0xba, 0xdd, 0x03, 0x86, 0x44, + 0xa2, 0x34, 0x8c, 0x9c, 0xc2, 0x08, 0x06, 0xa2, 0xb4, 0xfc, 0x2b, 0x0d, 0xa6, 0xab, 0x0c, 0x3d, + 0x21, 0x41, 0x80, 0x79, 0xad, 0x65, 0x9b, 0x30, 0x74, 0x5f, 0x62, 0xc6, 0xe5, 0x3b, 0x60, 0x9c, + 0x61, 0x14, 0x7a, 0x91, 0x22, 0x95, 0xa4, 0xca, 0x84, 0x29, 0x22, 0xd9, 0x04, 0x13, 0x0d, 0x6a, + 0xd9, 0xdc, 0xb1, 0xe8, 0xae, 0x92, 0x2e, 0x49, 0x95, 0xbc, 0xb1, 0x7e, 0xdc, 0x29, 0xae, 0x20, + 0xcc, 0xfd, 0x96, 0xad, 0x39, 0x24, 0xd0, 0x05, 0xa9, 0xe3, 0x43, 0x1c, 0xf6, 0x02, 0x9d, 0xb7, + 0xa9, 0xc7, 0x34, 0xe3, 0x79, 0x6d, 0x75, 0x6d, 0xa9, 0xd6, 0xb2, 0x77, 0xbc, 0xb6, 0xf9, 0x5f, + 0x83, 0x1a, 0xdc, 0xa9, 0xed, 0xca, 0x77, 0x41, 0x9e, 0x71, 0x18, 0x71, 0xcb, 0xf7, 0x30, 0xf2, + 0xb9, 0x92, 0x29, 0x49, 0x95, 0xac, 0x99, 0x8b, 0xcf, 0xb6, 0xe3, 0x23, 0xf9, 0x3d, 0xf8, 0x9f, + 0xb6, 0x6c, 0x2b, 0x82, 0xa1, 0x6b, 0x35, 0x31, 0xe3, 0x4a, 0xb6, 0x94, 0xa9, 0xe4, 0x8d, 0xc7, + 0xc7, 0x9d, 0xe2, 0xda, 0x68, 0xd4, 0x75, 0xc7, 0x0f, 0x49, 0x14, 0x89, 0x19, 0xcd, 0x1c, 0xbd, + 0x30, 0xec, 0x0e, 0xc8, 0x30, 0x8c, 0x94, 0xb1, 0x78, 0x9c, 0x8d, 0xe3, 0x4e, 0xf1, 0xd1, 0x4d, + 0xc6, 0xa9, 0x63, 0x14, 0x42, 0xde, 0x8a, 0x3c, 0xb3, 0xdb, 0x65, 0x33, 0xf7, 0xe9, 0xec, 0x60, + 0x51, 0xc8, 0x55, 0x56, 0xc1, 0xfc, 0x30, 0x79, 0x4d, 0x8f, 0x51, 0x12, 0x32, 0xaf, 0xfc, 0x35, + 0x0d, 0xa6, 0xaa, 0x0c, 0x6d, 0xb9, 0xee, 0x33, 0xf1, 0x44, 0x75, 0x8c, 0xfe, 0xb5, 0xf8, 0x76, + 0x93, 0x38, 0xbb, 0x03, 0xe2, 0xc7, 0x67, 0x42, 0xfc, 0x05, 0x30, 0x99, 0x40, 0x20, 0xa5, 0x96, + 0x0f, 0x99, 0xaf, 0x64, 0xbb, 0xdc, 0x66, 0x52, 0xb8, 0x45, 0xe9, 0x36, 0x64, 0xbe, 0xfc, 0x0e, + 0xe4, 0x7b, 0x36, 0xb3, 0xfa, 0x6a, 0xde, 0xfc, 0x85, 0x9e, 0xbe, 0x7a, 0x5d, 0xaf, 0x63, 0x64, + 0xe6, 0x1a, 0x7d, 0x45, 0x2e, 0x8b, 0x3a, 0x07, 0x66, 0xaf, 0x68, 0x76, 0xae, 0xe8, 0x17, 0x09, + 0xdc, 0xaa, 0x32, 0xf4, 0x86, 0xba, 0x90, 0x7b, 0xb5, 0xd8, 0xeb, 0xf2, 0x3a, 0x98, 0x80, 0x2d, + 0xee, 0x93, 0x08, 0xf3, 0x76, 0x22, 0xa9, 0xa1, 0xfc, 0xf8, 0xf6, 0x70, 0x5a, 0x6c, 0xd1, 0x96, + 0xeb, 0x46, 0x1e, 0x63, 0x75, 0x1e, 0xe1, 0x10, 0x99, 0x7d, 0xa8, 0xbc, 0x01, 0xc6, 0x93, 0x6d, + 0x89, 0xc5, 0xce, 0xad, 0xcc, 0x69, 0x43, 0xf6, 0x55, 0x4b, 0x48, 0x8c, 0xec, 0x61, 0xa7, 0x98, + 0x32, 0x45, 0xc1, 0xe6, 0x64, 0xf7, 0xc2, 0xfd, 0x56, 0xe5, 0x59, 0x30, 0x33, 0x70, 0xab, 0xde, + 0x8d, 0x57, 0xbe, 0xa7, 0x41, 0xa6, 0xca, 0x90, 0xfc, 0x01, 0x4c, 0x5d, 0xdd, 0xc3, 0xfb, 0x43, + 0x29, 0x87, 0x79, 0xaa, 0xb0, 0x3c, 0x32, 0xb4, 0x47, 0x2d, 0xfb, 0x60, 0x72, 0xc0, 0x7a, 0xf7, + 0xae, 0x6b, 0x72, 0x19, 0x57, 0xd0, 0x46, 0xc3, 0x9d, 0x33, 0xd9, 0x20, 0x7f, 0xe9, 0x49, 0x16, + 0xae, 0xab, 0xbf, 0x88, 0x2a, 0x3c, 0x18, 0x05, 0xd5, 0xe3, 0x28, 0x8c, 0x7d, 0x3c, 0x3b, 0x58, + 0x94, 0x8c, 0x17, 0x87, 0x27, 0xaa, 0x74, 0x74, 0xa2, 0x4a, 0xbf, 0x4f, 0x54, 0xe9, 0xf3, 0xa9, + 0x9a, 0x3a, 0x3a, 0x55, 0x53, 0x3f, 0x4f, 0xd5, 0xd4, 0xdb, 0xa5, 0xbf, 0x19, 0x71, 0xbf, 0xff, + 0xa7, 0x8c, 0x3d, 0x69, 0x8f, 0xc7, 0xbf, 0xc9, 0xd5, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe1, + 0x58, 0x48, 0x68, 0xc7, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -294,6 +404,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type MsgClient interface { + // CommitPubRandList commits a list of public randomness for EOTS + CommitPubRandList(ctx context.Context, in *MsgCommitPubRandList, opts ...grpc.CallOption) (*MsgCommitPubRandListResponse, error) // AddFinalitySig adds a finality signature to a given block AddFinalitySig(ctx context.Context, in *MsgAddFinalitySig, opts ...grpc.CallOption) (*MsgAddFinalitySigResponse, error) // TODO: msg for evidence of equivocation. this is not specified yet @@ -309,6 +421,15 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { return &msgClient{cc} } +func (c *msgClient) CommitPubRandList(ctx context.Context, in *MsgCommitPubRandList, opts ...grpc.CallOption) (*MsgCommitPubRandListResponse, error) { + out := new(MsgCommitPubRandListResponse) + err := c.cc.Invoke(ctx, "/babylon.finality.v1.Msg/CommitPubRandList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) AddFinalitySig(ctx context.Context, in *MsgAddFinalitySig, opts ...grpc.CallOption) (*MsgAddFinalitySigResponse, error) { out := new(MsgAddFinalitySigResponse) err := c.cc.Invoke(ctx, "/babylon.finality.v1.Msg/AddFinalitySig", in, out, opts...) @@ -329,6 +450,8 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts // MsgServer is the server API for Msg service. type MsgServer interface { + // CommitPubRandList commits a list of public randomness for EOTS + CommitPubRandList(context.Context, *MsgCommitPubRandList) (*MsgCommitPubRandListResponse, error) // AddFinalitySig adds a finality signature to a given block AddFinalitySig(context.Context, *MsgAddFinalitySig) (*MsgAddFinalitySigResponse, error) // TODO: msg for evidence of equivocation. this is not specified yet @@ -340,6 +463,9 @@ type MsgServer interface { type UnimplementedMsgServer struct { } +func (*UnimplementedMsgServer) CommitPubRandList(ctx context.Context, req *MsgCommitPubRandList) (*MsgCommitPubRandListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CommitPubRandList not implemented") +} func (*UnimplementedMsgServer) AddFinalitySig(ctx context.Context, req *MsgAddFinalitySig) (*MsgAddFinalitySigResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddFinalitySig not implemented") } @@ -351,6 +477,24 @@ func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) } +func _Msg_CommitPubRandList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCommitPubRandList) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CommitPubRandList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.finality.v1.Msg/CommitPubRandList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CommitPubRandList(ctx, req.(*MsgCommitPubRandList)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_AddFinalitySig_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgAddFinalitySig) if err := dec(in); err != nil { @@ -391,6 +535,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "babylon.finality.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "CommitPubRandList", + Handler: _Msg_CommitPubRandList_Handler, + }, { MethodName: "AddFinalitySig", Handler: _Msg_AddFinalitySig_Handler, @@ -404,6 +552,102 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Metadata: "babylon/finality/v1/tx.proto", } +func (m *MsgCommitPubRandList) 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 *MsgCommitPubRandList) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCommitPubRandList) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Sig != nil { + { + size := m.Sig.Size() + i -= size + if _, err := m.Sig.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.PubRandList) > 0 { + for iNdEx := len(m.PubRandList) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.PubRandList[iNdEx].Size() + i -= size + if _, err := m.PubRandList[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if m.StartHeight != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.StartHeight)) + i-- + dAtA[i] = 0x18 + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCommitPubRandListResponse) 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 *MsgCommitPubRandListResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCommitPubRandListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *MsgAddFinalitySig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -567,6 +811,45 @@ func encodeVarintTx(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *MsgCommitPubRandList) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovTx(uint64(l)) + } + if m.StartHeight != 0 { + n += 1 + sovTx(uint64(m.StartHeight)) + } + if len(m.PubRandList) > 0 { + for _, e := range m.PubRandList { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + if m.Sig != nil { + l = m.Sig.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgCommitPubRandListResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgAddFinalitySig) Size() (n int) { if m == nil { return 0 @@ -634,6 +917,262 @@ func sovTx(x uint64) (n int) { func sozTx(x uint64) (n int) { return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *MsgCommitPubRandList) 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 ErrIntOverflowTx + } + 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: MsgCommitPubRandList: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCommitPubRandList: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) + } + m.StartHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRandList", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.SchnorrPubRand + m.PubRandList = append(m.PubRandList, v) + if err := m.PubRandList[len(m.PubRandList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sig", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340Signature + m.Sig = &v + if err := m.Sig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCommitPubRandListResponse) 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 ErrIntOverflowTx + } + 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: MsgCommitPubRandListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCommitPubRandListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From add420f074751cf53edea5b7a55cca3d34291f5b Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 21 May 2024 18:04:14 +0200 Subject: [PATCH 087/119] Add test vectors for other implementations of scripts (#648) * Add test vectors for other implementations of scripts --- btcstaking/staking_testvectors_test.go | 432 +++++++++++++++++++++++++ btcstaking/testvectors/vectors.json | 215 ++++++++++++ 2 files changed, 647 insertions(+) create mode 100644 btcstaking/staking_testvectors_test.go create mode 100644 btcstaking/testvectors/vectors.json diff --git a/btcstaking/staking_testvectors_test.go b/btcstaking/staking_testvectors_test.go new file mode 100644 index 000000000..52521e21b --- /dev/null +++ b/btcstaking/staking_testvectors_test.go @@ -0,0 +1,432 @@ +package btcstaking_test + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/babylonchain/babylon/btcstaking" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" + "github.com/stretchr/testify/require" +) + +func getBtcNetworkParams(network string) (*chaincfg.Params, error) { + switch network { + case "testnet3": + return &chaincfg.TestNet3Params, nil + case "mainnet": + return &chaincfg.MainNetParams, nil + case "regtest": + return &chaincfg.RegressionNetParams, nil + case "simnet": + return &chaincfg.SimNetParams, nil + case "signet": + return &chaincfg.SigNetParams, nil + default: + return nil, fmt.Errorf("unknown network %s", network) + } +} + +func serializeBTCTx(tx *wire.MsgTx) ([]byte, error) { + var txBuf bytes.Buffer + if err := tx.Serialize(&txBuf); err != nil { + return nil, err + } + return txBuf.Bytes(), nil +} + +func serializeBTCTxToHex(tx *wire.MsgTx) (string, error) { + bytes, err := serializeBTCTx(tx) + + if err != nil { + return "", err + } + + return hex.EncodeToString(bytes), nil +} + +func ReadTestCases() *TestCases { + // Open the JSON file + file, err := os.Open("./testvectors/vectors.json") + if err != nil { + panic(fmt.Errorf("Error opening file: %w", err)) + } + defer file.Close() + + // Create a decoder + decoder := json.NewDecoder(file) + + // Create a variable of the type of your struct + var cases TestCases + + // Decode the JSON data into the struct + if err := decoder.Decode(&cases); err != nil { + panic(fmt.Sprintf("Error decoding JSON: %s", err)) + } + + return &cases +} + +type Parameters struct { + CovenantPublicKeys []string `json:"covenant_public_keys"` + CovenantQuorum int `json:"covenant_quorum"` + FinalityProviderPublicKeys []string `json:"finality_provider_public_keys"` + StakerPublicKey string `json:"staker_public_key"` + StakingTime int `json:"staking_time"` + StakingValue int `json:"staking_value"` + StakingTxHash string `json:"staking_tx_hash"` + StakingOutputIndex int `json:"staking_output_index"` + UnbondingTxVersion int `json:"unbonding_tx_version"` + UnbondingTime int `json:"unbonding_time"` + UnbondingFee int `json:"unbonding_fee"` + MagicBytes string `json:"magic_bytes"` + Network string `json:"network"` +} + +type Expected struct { + StakingOutputPkScript string `json:"staking_output_pkscript_hex"` + StakingOutputValue int `json:"staking_output_value"` + StakingTransactionTimeLockScript string `json:"staking_transaction_timelock_script_hex"` + StakingTransactionUnbondingScript string `json:"staking_transaction_unbonding_script_hex"` + StakingTransactionSlashingScript string `json:"staking_transaction_slashing_script_hex"` + UnbondingTransactionHex string `json:"unbonding_transaction_hex"` + UnbondingTransactionTimeLockScript string `json:"unbonding_transaction_time_lock_script_hex"` + UnbondingTransactionSlashingScript string `json:"unbonding_transaction_slashing_script_hex"` + OpReturnScript string `json:"op_return_script_hex"` +} + +type TestCase struct { + Description string `json:"name"` + Parameters *Parameters `json:"parameters"` + Expected *Expected `json:"expected"` +} + +type TestCases struct { + Test []TestCase `json:"vectors"` +} + +type ParsedParams struct { + CovenantPublicKeys []*btcec.PublicKey + CovenantQuorum uint32 + FinalityProviderPublicKeys []*btcec.PublicKey + StakerPublicKey *btcec.PublicKey + StakingTime uint16 + StakingValue btcutil.Amount + StakingTxHash *chainhash.Hash + StakingOutputIndex uint32 + UnbondingTxVersion uint32 + UnbondingTime uint16 + UnbondingFee btcutil.Amount + MagicBytes []byte + Network *chaincfg.Params +} + +// function which parses Parameters +func parseTestParams(t *testing.T, p *Parameters) (*ParsedParams, error) { + covenantKeys := keysToPubKeys(t, p.CovenantPublicKeys) + finalityKeys := keysToPubKeys(t, p.FinalityProviderPublicKeys) + stakerPk := keysToPubKeys(t, []string{p.StakerPublicKey})[0] + + stakingTxHash, err := chainhash.NewHashFromStr(p.StakingTxHash) + if err != nil { + return nil, err + } + + magicBytes, err := hex.DecodeString(p.MagicBytes) + if err != nil { + return nil, err + } + + network, err := getBtcNetworkParams(p.Network) + if err != nil { + return nil, err + } + + return &ParsedParams{ + CovenantPublicKeys: covenantKeys, + CovenantQuorum: uint32(p.CovenantQuorum), + FinalityProviderPublicKeys: finalityKeys, + StakerPublicKey: stakerPk, + StakingTime: uint16(p.StakingTime), + StakingValue: btcutil.Amount(p.StakingValue), + StakingTxHash: stakingTxHash, + StakingOutputIndex: uint32(p.StakingOutputIndex), + UnbondingTxVersion: uint32(p.UnbondingTxVersion), + UnbondingTime: uint16(p.UnbondingTime), + UnbondingFee: btcutil.Amount(p.UnbondingFee), + MagicBytes: magicBytes, + Network: network, + }, nil +} + +func TestVectorsCompatiblity(t *testing.T) { + cases := ReadTestCases() + + for _, tc := range cases.Test { + t.Logf("Running test case: %s", tc.Description) + parsedParams, err := parseTestParams(t, tc.Parameters) + + if err != nil { + require.NoError(t, fmt.Errorf("error parsing test parameters for case %s: %w", tc.Description, err)) + } + + info, err := btcstaking.BuildStakingInfo( + parsedParams.StakerPublicKey, + parsedParams.FinalityProviderPublicKeys, + parsedParams.CovenantPublicKeys, + parsedParams.CovenantQuorum, + parsedParams.StakingTime, + parsedParams.StakingValue, + parsedParams.Network, + ) + + if err != nil { + require.NoError(t, fmt.Errorf("error building staking info for case %s: %w", tc.Description, err)) + } + + sti, err := info.TimeLockPathSpendInfo() + + if err != nil { + require.NoError(t, fmt.Errorf("error building staking timelock path spend info for case %s: %w", tc.Description, err)) + } + + sui, err := info.UnbondingPathSpendInfo() + + if err != nil { + require.NoError(t, fmt.Errorf("error building staking unbonding path spend info for case %s: %w", tc.Description, err)) + } + + ssi, err := info.SlashingPathSpendInfo() + + if err != nil { + require.NoError(t, fmt.Errorf("error building staking slashing path spend info for case %s: %w", tc.Description, err)) + } + + ubInfo, err := btcstaking.BuildUnbondingInfo( + parsedParams.StakerPublicKey, + parsedParams.FinalityProviderPublicKeys, + parsedParams.CovenantPublicKeys, + parsedParams.CovenantQuorum, + parsedParams.UnbondingTime, + parsedParams.StakingValue-parsedParams.UnbondingFee, + parsedParams.Network, + ) + + if err != nil { + require.NoError(t, fmt.Errorf("error building unbonding info for case %s: %w", tc.Description, err)) + } + + uti, err := ubInfo.TimeLockPathSpendInfo() + if err != nil { + require.NoError(t, fmt.Errorf("error building unbonding timelock path spend info for case %s: %w", tc.Description, err)) + } + usi, err := ubInfo.SlashingPathSpendInfo() + + if err != nil { + require.NoError(t, fmt.Errorf("error building unbonding slashing path spend info for case %s: %w", tc.Description, err)) + } + + ubtTx := wire.NewMsgTx(2) + ubtTx.AddTxIn(wire.NewTxIn( + wire.NewOutPoint( + parsedParams.StakingTxHash, + parsedParams.StakingOutputIndex, + ), + nil, + nil, + )) + ubtTx.AddTxOut(ubInfo.UnbondingOutput) + + serializedUbtTx, err := serializeBTCTx(ubtTx) + if err != nil { + require.NoError(t, fmt.Errorf("error serializing unbonding tx for case %s: %w", tc.Description, err)) + } + + require.Equal(t, tc.Expected.StakingOutputPkScript, hex.EncodeToString(info.StakingOutput.PkScript), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.StakingOutputValue, int(info.StakingOutput.Value), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.StakingTransactionTimeLockScript, hex.EncodeToString(sti.RevealedLeaf.Script), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.StakingTransactionUnbondingScript, hex.EncodeToString(sui.RevealedLeaf.Script), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.StakingTransactionSlashingScript, hex.EncodeToString(ssi.RevealedLeaf.Script), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.UnbondingTransactionHex, hex.EncodeToString(serializedUbtTx), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.UnbondingTransactionTimeLockScript, hex.EncodeToString(uti.RevealedLeaf.Script), fmt.Sprintf("failed case: %s", tc.Description)) + require.Equal(t, tc.Expected.UnbondingTransactionSlashingScript, hex.EncodeToString(usi.RevealedLeaf.Script), fmt.Sprintf("failed case: %s", tc.Description)) + + if tc.Expected.OpReturnScript != "" { + data, err := btcstaking.NewV0OpReturnDataFromParsed( + parsedParams.MagicBytes, + parsedParams.StakerPublicKey, + parsedParams.FinalityProviderPublicKeys[0], + parsedParams.StakingTime, + ) + + if err != nil { + require.NoError(t, fmt.Errorf("error building op_return data for case %s: %w", tc.Description, err)) + } + + opReturnOutput, err := data.ToTxOutput() + + if err != nil { + require.NoError(t, fmt.Errorf("error building op_return output for case %s: %w", tc.Description, err)) + } + + require.Equal(t, tc.Expected.OpReturnScript, hex.EncodeToString(opReturnOutput.PkScript), fmt.Sprintf("failed case: %s", tc.Description)) + } + } +} + +func generateKeys(t *testing.T, num int) []string { + var keys []string + + for i := 0; i < num; i++ { + k, err := btcec.NewPrivateKey() + require.NoError(t, err) + + keys = append(keys, hex.EncodeToString(k.PubKey().SerializeCompressed())) + } + return keys +} + +func keysToPubKeys(t *testing.T, keys []string) []*btcec.PublicKey { + var pks []*btcec.PublicKey + + for _, key := range keys { + b, err := hex.DecodeString(key) + require.NoError(t, err) + + pk, err := btcec.ParsePubKey(b) + require.NoError(t, err) + + pks = append(pks, pk) + } + + return pks +} + +// helper to easily generate test cases +func GenerateTestCase( + t *testing.T, + desc string, + numCovenantKeys int, + covenantQuorum int, + numFinalityKeys int, + stakingAmout int, + stakingTime int, + unbondingTime int, + unbondingFee int, + magicBytes []byte, +) string { + emptyHash := [32]byte{} + eh, err := chainhash.NewHash(emptyHash[:]) + require.NoError(t, err) + covenantKeys := generateKeys(t, numCovenantKeys) + finalityKeys := generateKeys(t, numFinalityKeys) + stakerKeys := generateKeys(t, 1) + + info, err := btcstaking.BuildStakingInfo( + keysToPubKeys(t, stakerKeys)[0], + keysToPubKeys(t, finalityKeys), + keysToPubKeys(t, covenantKeys), + uint32(covenantQuorum), + uint16(stakingTime), + btcutil.Amount(stakingAmout), + &chaincfg.MainNetParams, + ) + require.NoError(t, err) + sti, err := info.TimeLockPathSpendInfo() + require.NoError(t, err) + sui, err := info.UnbondingPathSpendInfo() + require.NoError(t, err) + ssi, err := info.SlashingPathSpendInfo() + require.NoError(t, err) + + unbondingInfo, err := btcstaking.BuildUnbondingInfo( + keysToPubKeys(t, stakerKeys)[0], + keysToPubKeys(t, finalityKeys), + keysToPubKeys(t, covenantKeys), + uint32(covenantQuorum), + uint16(unbondingTime), + btcutil.Amount(stakingAmout)-btcutil.Amount(unbondingFee), + &chaincfg.MainNetParams, + ) + + require.NoError(t, err) + + ubtTx := wire.NewMsgTx(2) + ubtTx.AddTxIn(wire.NewTxIn( + wire.NewOutPoint( + eh, + 0, + ), + nil, + nil, + )) + ubtTx.AddTxOut(unbondingInfo.UnbondingOutput) + ubtTxHex, err := serializeBTCTxToHex(ubtTx) + require.NoError(t, err) + uti, err := unbondingInfo.TimeLockPathSpendInfo() + require.NoError(t, err) + usi, err := unbondingInfo.SlashingPathSpendInfo() + require.NoError(t, err) + + opReturnOutput := "" + // if there is more build op_return output + if len(finalityKeys) == 1 { + opInfo, err := btcstaking.BuildV0IdentifiableStakingOutputs( + magicBytes, + keysToPubKeys(t, stakerKeys)[0], + keysToPubKeys(t, finalityKeys)[0], + keysToPubKeys(t, covenantKeys), + uint32(covenantQuorum), + uint16(stakingTime), + btcutil.Amount(stakingAmout), + &chaincfg.MainNetParams, + ) + require.NoError(t, err) + opReturnOutput = hex.EncodeToString(opInfo.OpReturnOutput.PkScript) + } + + params := Parameters{ + CovenantPublicKeys: covenantKeys, + CovenantQuorum: covenantQuorum, + FinalityProviderPublicKeys: finalityKeys, + StakerPublicKey: stakerKeys[0], + StakingTime: stakingTime, + StakingValue: stakingAmout, + StakingTxHash: eh.String(), + StakingOutputIndex: 0, + UnbondingTxVersion: 2, + UnbondingTime: unbondingTime, + UnbondingFee: unbondingFee, + MagicBytes: hex.EncodeToString(magicBytes), + Network: "mainnet", + } + + expected := Expected{ + StakingOutputPkScript: hex.EncodeToString(info.StakingOutput.PkScript), + StakingOutputValue: int(info.StakingOutput.Value), + StakingTransactionTimeLockScript: hex.EncodeToString(sti.RevealedLeaf.Script), + StakingTransactionUnbondingScript: hex.EncodeToString(sui.RevealedLeaf.Script), + StakingTransactionSlashingScript: hex.EncodeToString(ssi.RevealedLeaf.Script), + UnbondingTransactionHex: ubtTxHex, + UnbondingTransactionTimeLockScript: hex.EncodeToString(uti.RevealedLeaf.Script), + UnbondingTransactionSlashingScript: hex.EncodeToString(usi.RevealedLeaf.Script), + OpReturnScript: opReturnOutput, + } + + tc := TestCase{ + Description: desc, + Parameters: ¶ms, + Expected: &expected, + } + + marshaled, err := json.MarshalIndent(&tc, "", "") + require.NoError(t, err) + return string(marshaled) +} diff --git a/btcstaking/testvectors/vectors.json b/btcstaking/testvectors/vectors.json new file mode 100644 index 000000000..0ca091df3 --- /dev/null +++ b/btcstaking/testvectors/vectors.json @@ -0,0 +1,215 @@ +{ + "vectors": [ + { + "name": "1 finality key, 1 covenant key, 1 staker key with op_return", + "parameters": { + "covenant_public_keys": [ + "024852a5d3e79cfdee1bda4ea729e879c1db0f19230eadd3cb96d3cb1efa8d30fa" + ], + "covenant_quorum": 1, + "finality_provider_public_keys": [ + "0246542ccdcbde8a8c147c8d00f14d47f0d5c13c684d27497fc4610c7a4def15e5" + ], + "staker_public_key": "024000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafd", + "staking_time": 1000, + "staking_value": 100000, + "staking_tx_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "staking_output_index": 0, + "unbonding_tx_version": 2, + "unbonding_time": 100, + "unbonding_fee": 2000, + "magic_bytes": "01020304", + "network": "mainnet" + }, + "expected": { + "staking_output_pkscript_hex": "5120b2b169d39fb8ea9828f6ed8dbbeaa12594706d03bfd1638a912608a085fdd7a5", + "staking_output_value": 100000, + "staking_transaction_timelock_script_hex": "204000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafdad02e803b2", + "staking_transaction_unbonding_script_hex": "204000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafdad204852a5d3e79cfdee1bda4ea729e879c1db0f19230eadd3cb96d3cb1efa8d30faac", + "staking_transaction_slashing_script_hex": "204000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafdad2046542ccdcbde8a8c147c8d00f14d47f0d5c13c684d27497fc4610c7a4def15e5ad204852a5d3e79cfdee1bda4ea729e879c1db0f19230eadd3cb96d3cb1efa8d30faac", + "unbonding_transaction_hex": "020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff01d07e01000000000022512071f38cba0e3c0453eb34ac8f9a60805965e9500a9ab69724f636a00fcafc252f00000000", + "unbonding_transaction_time_lock_script_hex": "204000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafdad0164b2", + "unbonding_transaction_slashing_script_hex": "204000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafdad2046542ccdcbde8a8c147c8d00f14d47f0d5c13c684d27497fc4610c7a4def15e5ad204852a5d3e79cfdee1bda4ea729e879c1db0f19230eadd3cb96d3cb1efa8d30faac", + "op_return_script_hex": "6a4701020304004000bd2c8b975d351c5f3a42618aca31e07e2b253fcd571e9630540a3cb6eafd46542ccdcbde8a8c147c8d00f14d47f0d5c13c684d27497fc4610c7a4def15e503e8" + } + }, + { + "name": "1 finality key, 3/5 covenant committe, 1 staker key with op_return", + "parameters": { + "covenant_public_keys": [ + "02cc5c77da065c490a320834fdcf2c3da70ecd442054c90f874a1edb4669607b83", + "022f57b6d267043beda2deebab1187a67316121f1eac24047c16d1209c5e6cd0a5", + "03784bdab9a1c71ea51fa5904227e721681453e59d20af3d97485e79e5518bdfff", + "03f31cf8fb9ee1d9157e172d65b1bd00a0b54cee3906df13ced709bfd8d407e9a2", + "035c3e1bb7c6b475a9caeebcb09fab74546a9b8a364dd0ccede7e5aea5c5b12ed0" + ], + "covenant_quorum": 3, + "finality_provider_public_keys": [ + "03b5e37d93a8d04daee62838ac680ead407d7cbe0c858525781f8834495be0bce7" + ], + "staker_public_key": "03cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fe", + "staking_time": 10000, + "staking_value": 1000000, + "staking_tx_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "staking_output_index": 0, + "unbonding_tx_version": 2, + "unbonding_time": 50, + "unbonding_fee": 20000, + "magic_bytes": "01020304", + "network": "mainnet" + }, + "expected": { + "staking_output_pkscript_hex": "5120bbc6be1fff9cb4d93cb638f0fc9e5df7036c137b89c8baa762fb8637acdf3da7", + "staking_output_value": 1000000, + "staking_transaction_timelock_script_hex": "20cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fead021027b2", + "staking_transaction_unbonding_script_hex": "20cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fead202f57b6d267043beda2deebab1187a67316121f1eac24047c16d1209c5e6cd0a5ac205c3e1bb7c6b475a9caeebcb09fab74546a9b8a364dd0ccede7e5aea5c5b12ed0ba20784bdab9a1c71ea51fa5904227e721681453e59d20af3d97485e79e5518bdfffba20cc5c77da065c490a320834fdcf2c3da70ecd442054c90f874a1edb4669607b83ba20f31cf8fb9ee1d9157e172d65b1bd00a0b54cee3906df13ced709bfd8d407e9a2ba539c", + "staking_transaction_slashing_script_hex": "20cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fead20b5e37d93a8d04daee62838ac680ead407d7cbe0c858525781f8834495be0bce7ad202f57b6d267043beda2deebab1187a67316121f1eac24047c16d1209c5e6cd0a5ac205c3e1bb7c6b475a9caeebcb09fab74546a9b8a364dd0ccede7e5aea5c5b12ed0ba20784bdab9a1c71ea51fa5904227e721681453e59d20af3d97485e79e5518bdfffba20cc5c77da065c490a320834fdcf2c3da70ecd442054c90f874a1edb4669607b83ba20f31cf8fb9ee1d9157e172d65b1bd00a0b54cee3906df13ced709bfd8d407e9a2ba539c", + "unbonding_transaction_hex": "020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0120f40e0000000000225120d4ea23776e49e47df891d52a42a2ec389786aa3bdafa874b5e69df13070fb4bf00000000", + "unbonding_transaction_time_lock_script_hex": "20cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fead0132b2", + "unbonding_transaction_slashing_script_hex": "20cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257fead20b5e37d93a8d04daee62838ac680ead407d7cbe0c858525781f8834495be0bce7ad202f57b6d267043beda2deebab1187a67316121f1eac24047c16d1209c5e6cd0a5ac205c3e1bb7c6b475a9caeebcb09fab74546a9b8a364dd0ccede7e5aea5c5b12ed0ba20784bdab9a1c71ea51fa5904227e721681453e59d20af3d97485e79e5518bdfffba20cc5c77da065c490a320834fdcf2c3da70ecd442054c90f874a1edb4669607b83ba20f31cf8fb9ee1d9157e172d65b1bd00a0b54cee3906df13ced709bfd8d407e9a2ba539c", + "op_return_script_hex": "6a470102030400cc327c2a1ee1a70d7033bee61ed2e3e6ffc7c5f5d6c637c4f0d2ddfae8a257feb5e37d93a8d04daee62838ac680ead407d7cbe0c858525781f8834495be0bce72710" + } + }, + { + "name": "3 finality keys, 3/5 covenant committe, 1 staker key with no op_return", + "parameters": { + "covenant_public_keys": [ + "02042916c9cd52cfa146118c37b6b118f082bb50fb91da1c51b76dfc2100e66f00", + "03a2bfd2843357efda60fd26238b6affe6cbafa65d1f3cfbfb63ae3841d35887e6", + "035df1524dfc57fc1b0288ebac9b7abbcf5c61cfbfb8e4667ae0009445b04ecf22", + "03652ea9ac1c526218691e6b94769beaebbaedda080c5f1f036c239d5af69088b6", + "02dca4c9e5848db62e0f62e2c1cafca10f4464c10ae00bf579a8f7b5d81cd697f6" + ], + "covenant_quorum": 3, + "finality_provider_public_keys": [ + "0275e96ca4067b937f8e93bcb962523a1713c25d2af1a26f61034dd81f4e4687fe", + "0396c5c62af047a0839f8ea2b230315db93af25fa7074c71a2b95deeb47e507a63", + "034d4fb121fbe9f13ed7b55440fb9f3ad0f8bce8bd92589423b5f90d871db5142d" + ], + "staker_public_key": "037b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29", + "staking_time": 10000, + "staking_value": 1000000, + "staking_tx_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "staking_output_index": 0, + "unbonding_tx_version": 2, + "unbonding_time": 50, + "unbonding_fee": 20000, + "magic_bytes": "01020304", + "network": "mainnet" + }, + "expected": { + "staking_output_pkscript_hex": "51206136db5cccc1b9fca70164b3445020d6f6f8dd1428e78cef9111b295bd4eec89", + "staking_output_value": 1000000, + "staking_transaction_timelock_script_hex": "207b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29ad021027b2", + "staking_transaction_unbonding_script_hex": "207b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29ad20042916c9cd52cfa146118c37b6b118f082bb50fb91da1c51b76dfc2100e66f00ac205df1524dfc57fc1b0288ebac9b7abbcf5c61cfbfb8e4667ae0009445b04ecf22ba20652ea9ac1c526218691e6b94769beaebbaedda080c5f1f036c239d5af69088b6ba20a2bfd2843357efda60fd26238b6affe6cbafa65d1f3cfbfb63ae3841d35887e6ba20dca4c9e5848db62e0f62e2c1cafca10f4464c10ae00bf579a8f7b5d81cd697f6ba539c", + "staking_transaction_slashing_script_hex": "207b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29ad204d4fb121fbe9f13ed7b55440fb9f3ad0f8bce8bd92589423b5f90d871db5142dac2075e96ca4067b937f8e93bcb962523a1713c25d2af1a26f61034dd81f4e4687feba2096c5c62af047a0839f8ea2b230315db93af25fa7074c71a2b95deeb47e507a63ba519d20042916c9cd52cfa146118c37b6b118f082bb50fb91da1c51b76dfc2100e66f00ac205df1524dfc57fc1b0288ebac9b7abbcf5c61cfbfb8e4667ae0009445b04ecf22ba20652ea9ac1c526218691e6b94769beaebbaedda080c5f1f036c239d5af69088b6ba20a2bfd2843357efda60fd26238b6affe6cbafa65d1f3cfbfb63ae3841d35887e6ba20dca4c9e5848db62e0f62e2c1cafca10f4464c10ae00bf579a8f7b5d81cd697f6ba539c", + "unbonding_transaction_hex": "020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0120f40e0000000000225120a52e08ebd0db898e6a52870ca3e72a78391b799eac97a1675eccd416adace90e00000000", + "unbonding_transaction_time_lock_script_hex": "207b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29ad0132b2", + "unbonding_transaction_slashing_script_hex": "207b251c30f5bd7a29f3b1749d599c60f2bcdc11553e500a6c32e4075b80d5bd29ad204d4fb121fbe9f13ed7b55440fb9f3ad0f8bce8bd92589423b5f90d871db5142dac2075e96ca4067b937f8e93bcb962523a1713c25d2af1a26f61034dd81f4e4687feba2096c5c62af047a0839f8ea2b230315db93af25fa7074c71a2b95deeb47e507a63ba519d20042916c9cd52cfa146118c37b6b118f082bb50fb91da1c51b76dfc2100e66f00ac205df1524dfc57fc1b0288ebac9b7abbcf5c61cfbfb8e4667ae0009445b04ecf22ba20652ea9ac1c526218691e6b94769beaebbaedda080c5f1f036c239d5af69088b6ba20a2bfd2843357efda60fd26238b6affe6cbafa65d1f3cfbfb63ae3841d35887e6ba20dca4c9e5848db62e0f62e2c1cafca10f4464c10ae00bf579a8f7b5d81cd697f6ba539c", + "op_return_script_hex": "" + } + }, + { + "name": "1 finality keys, 7/9 covenant committe, 1 staker key with op_return", + "parameters": { + "covenant_public_keys": [ + "0287ed5bb2d036baf209eb49520327f6bd05285dabd30c97f239c3a69ff419950b", + "02ce45e9c7828b2f1b52f29076b0fbbac380db5e6a8318cb7718c99e0b3fe6228f", + "0354967fa36311ba41a19a725925a68053579122e7e833c5b76a7dde99eec8fb31", + "02cdf01d771c38b4ee3363daf4d33c25796adbade4da3f621e954fd1d2e40d7c1f", + "038a7f080c5629980a5f3ccbfb1ea8a1bc20e7ce0dccbfefe3f35620e69c589e63", + "03b2729d612586227170a2116d9f97e2728f7cdc5f1c2e8eb4c4acd35a143917fd", + "0357925d2886601e7d9cecc60352cf435111f429b3fc97be8704dbf1f0fe491089", + "0369769314404fb9c68cd5c77adb2a5837372c4d5e5ef5d564e8de98f886a1a13e", + "02792a29aeaaaa1bc69ed57612ef050b29345e6f987951b2e22fcb00195b3ae2d5" + ], + "covenant_quorum": 7, + "finality_provider_public_keys": [ + "03bc9d21a6400b831e1741056dd45aaeecd42f23fafdf3ea49b815e49ebb4f95fc" + ], + "staker_public_key": "03a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0", + "staking_time": 20000, + "staking_value": 10000000, + "staking_tx_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "staking_output_index": 0, + "unbonding_tx_version": 2, + "unbonding_time": 201, + "unbonding_fee": 50000, + "magic_bytes": "01020304", + "network": "mainnet" + }, + "expected": { + "staking_output_pkscript_hex": "51208b763bd20b8bca50c7bc059e3c7810471bfe30111f546bbbf4d879e437dd6ae2", + "staking_output_value": 10000000, + "staking_transaction_timelock_script_hex": "20a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0ad02204eb2", + "staking_transaction_unbonding_script_hex": "20a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0ad2054967fa36311ba41a19a725925a68053579122e7e833c5b76a7dde99eec8fb31ac2057925d2886601e7d9cecc60352cf435111f429b3fc97be8704dbf1f0fe491089ba2069769314404fb9c68cd5c77adb2a5837372c4d5e5ef5d564e8de98f886a1a13eba20792a29aeaaaa1bc69ed57612ef050b29345e6f987951b2e22fcb00195b3ae2d5ba2087ed5bb2d036baf209eb49520327f6bd05285dabd30c97f239c3a69ff419950bba208a7f080c5629980a5f3ccbfb1ea8a1bc20e7ce0dccbfefe3f35620e69c589e63ba20b2729d612586227170a2116d9f97e2728f7cdc5f1c2e8eb4c4acd35a143917fdba20cdf01d771c38b4ee3363daf4d33c25796adbade4da3f621e954fd1d2e40d7c1fba20ce45e9c7828b2f1b52f29076b0fbbac380db5e6a8318cb7718c99e0b3fe6228fba579c", + "staking_transaction_slashing_script_hex": "20a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0ad20bc9d21a6400b831e1741056dd45aaeecd42f23fafdf3ea49b815e49ebb4f95fcad2054967fa36311ba41a19a725925a68053579122e7e833c5b76a7dde99eec8fb31ac2057925d2886601e7d9cecc60352cf435111f429b3fc97be8704dbf1f0fe491089ba2069769314404fb9c68cd5c77adb2a5837372c4d5e5ef5d564e8de98f886a1a13eba20792a29aeaaaa1bc69ed57612ef050b29345e6f987951b2e22fcb00195b3ae2d5ba2087ed5bb2d036baf209eb49520327f6bd05285dabd30c97f239c3a69ff419950bba208a7f080c5629980a5f3ccbfb1ea8a1bc20e7ce0dccbfefe3f35620e69c589e63ba20b2729d612586227170a2116d9f97e2728f7cdc5f1c2e8eb4c4acd35a143917fdba20cdf01d771c38b4ee3363daf4d33c25796adbade4da3f621e954fd1d2e40d7c1fba20ce45e9c7828b2f1b52f29076b0fbbac380db5e6a8318cb7718c99e0b3fe6228fba579c", + "unbonding_transaction_hex": "020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0130d3970000000000225120bd14e11a13e473ed65a7233cd8ae5ccae670fedc9b50bb99c1a09b9cff669fc800000000", + "unbonding_transaction_time_lock_script_hex": "20a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0ad02c900b2", + "unbonding_transaction_slashing_script_hex": "20a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0ad20bc9d21a6400b831e1741056dd45aaeecd42f23fafdf3ea49b815e49ebb4f95fcad2054967fa36311ba41a19a725925a68053579122e7e833c5b76a7dde99eec8fb31ac2057925d2886601e7d9cecc60352cf435111f429b3fc97be8704dbf1f0fe491089ba2069769314404fb9c68cd5c77adb2a5837372c4d5e5ef5d564e8de98f886a1a13eba20792a29aeaaaa1bc69ed57612ef050b29345e6f987951b2e22fcb00195b3ae2d5ba2087ed5bb2d036baf209eb49520327f6bd05285dabd30c97f239c3a69ff419950bba208a7f080c5629980a5f3ccbfb1ea8a1bc20e7ce0dccbfefe3f35620e69c589e63ba20b2729d612586227170a2116d9f97e2728f7cdc5f1c2e8eb4c4acd35a143917fdba20cdf01d771c38b4ee3363daf4d33c25796adbade4da3f621e954fd1d2e40d7c1fba20ce45e9c7828b2f1b52f29076b0fbbac380db5e6a8318cb7718c99e0b3fe6228fba579c", + "op_return_script_hex": "6a470102030400a9200483d40c3c81a7a983a8f0a0de37955fbea587595b4bf8fcb878d857c0c0bc9d21a6400b831e1741056dd45aaeecd42f23fafdf3ea49b815e49ebb4f95fc4e20" + } + }, + { + "name": "10 finality keys, 18/20 covenant committe, 1 staker key with no op_return", + "parameters": { + "covenant_public_keys": [ + "02e3803a6ecff76daf35709c8484f382783d211970f22397d7a258f40ca3b46304", + "03378f464f4365136230d30c3ad7d6425457d6c0742ed7fefd1015f0040cc70769", + "03583c7fbf7450f8f78977b8c9f2981ff10676efefb6399ec925ba54eed7978a2e", + "021fccb5af3a431a928c32267e556f1ba256871f98428419fae1cce6e7b8356cb9", + "03243b84dd7a170a6e1edc32b22357b20f8365a4149a12ef1d340342701d535991", + "037947f704a584a804c91d07250239ec528300bd01dd3137770f7227309f63db0a", + "021e435d3bbab5fb0244c273e38d6f078bfe57a1bd151016ab5c4ac84457d724b3", + "039010f319cde80190717d96dd60823b8e05905a2da458c69f4de19d5c9226cca8", + "03db2bb56299fe3219ea5901198d1872f0523234d529a29fa912a76c9cb6d70db6", + "030f14729c14b6a9b292e7b5142fc5483d7c25196af1ef4b9722ea5821719e2c40", + "02dbf2c13d6e3b0a8ad7286966bd00164ca0a163b483d305df6b492119cbffbabb", + "03f399ff078d6d954a390f67989705ed21e575ccf43a1340ca8752cd1613ca7ce0", + "030feacb370b7fcfcdd5ee7a363d73fda02d596ce61fd00e308d0ab68a7b955f48", + "022367edcf01edd517d46c1b3cc3d40f5a28608e0313636dd09b0904799bccd635", + "03a63763c4100bacdb1c06e5e1ba5599e379a2e23553d56d2b1d0ee3c990bd1192", + "0364df415d63ef3ce23ddd639c4a5ec8fdbfa67254db91228ca77fbec9610367ae", + "03f6a33481886c7d5ed5429c3bb0a83dbdefafd6d140b22a87aa7081cf7073136c", + "0336612620ae82332e4f5da8d78d0d8a4ff7c8b09e88ee988b3dde18ef6a04c497", + "03e0647bb72f1b3d33d69f360d7e9f58f6a693d40b6ef58f49f140a212bf16931c", + "0339eca9e5cf04e22471d6cde649604e6fd0aae077cd5b1af9a1dc26e56d8502f3" + ], + "covenant_quorum": 18, + "finality_provider_public_keys": [ + "027bb40e3cb76545a71fafcb29738fb27b452c3176b41ffd614f7231b40ff5ce68", + "0378c5d7a263ab7e98e311c8d2d7305d13d78a014d4ae0603b427bb55cb42dbed1", + "03f1209d7248936f9ff2fa7b0ec97e5c0d26e4f41ad6de9f2e423128780da5dfec", + "0350eff2669c6d83f858937cd9229fc93ad57c10cc8d8cfb7ec9bc40e32a9f7ff2", + "03fe96402099f8387ce0ddef84bee2d0f869b35bb599a58b9aaec4a73db08dc490", + "0329f526a81bc92dd2ed8cf1682fc4ae5956987f3f6d3c0da71fbcf230c71781ff", + "03cca2d8aa1feb47ad4933154ef8196db229cfbba676607c3c0583397d65a1e4ee", + "02ae3c70699ae235ddebef85378a550f796723a6b961dcff1f33716d5dbb096a1e", + "03a7165ffc90d12c25187b75b2ebdcb57b1c759e357d655d8371cfb96dc4df2ecc", + "034bcfb4042e5d13286fcd3d481b81a61cdfc3715aaf7909c4ee93de49356cd0b4" + ], + "staker_public_key": "037aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5", + "staking_time": 65535, + "staking_value": 100000000, + "staking_tx_hash": "0000000000000000000000000000000000000000000000000000000000000000", + "staking_output_index": 0, + "unbonding_tx_version": 2, + "unbonding_time": 201, + "unbonding_fee": 100000, + "magic_bytes": "01020304", + "network": "mainnet" + }, + "expected": { + "staking_output_pkscript_hex": "51205c7f92282283bf913e9a1cf7659b574104b4ca10095cb4cd293d77664e9d6a2d", + "staking_output_value": 100000000, + "staking_transaction_timelock_script_hex": "207aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5ad03ffff00b2", + "staking_transaction_unbonding_script_hex": "207aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5ad200f14729c14b6a9b292e7b5142fc5483d7c25196af1ef4b9722ea5821719e2c40ac200feacb370b7fcfcdd5ee7a363d73fda02d596ce61fd00e308d0ab68a7b955f48ba201e435d3bbab5fb0244c273e38d6f078bfe57a1bd151016ab5c4ac84457d724b3ba201fccb5af3a431a928c32267e556f1ba256871f98428419fae1cce6e7b8356cb9ba202367edcf01edd517d46c1b3cc3d40f5a28608e0313636dd09b0904799bccd635ba20243b84dd7a170a6e1edc32b22357b20f8365a4149a12ef1d340342701d535991ba2036612620ae82332e4f5da8d78d0d8a4ff7c8b09e88ee988b3dde18ef6a04c497ba20378f464f4365136230d30c3ad7d6425457d6c0742ed7fefd1015f0040cc70769ba2039eca9e5cf04e22471d6cde649604e6fd0aae077cd5b1af9a1dc26e56d8502f3ba20583c7fbf7450f8f78977b8c9f2981ff10676efefb6399ec925ba54eed7978a2eba2064df415d63ef3ce23ddd639c4a5ec8fdbfa67254db91228ca77fbec9610367aeba207947f704a584a804c91d07250239ec528300bd01dd3137770f7227309f63db0aba209010f319cde80190717d96dd60823b8e05905a2da458c69f4de19d5c9226cca8ba20a63763c4100bacdb1c06e5e1ba5599e379a2e23553d56d2b1d0ee3c990bd1192ba20db2bb56299fe3219ea5901198d1872f0523234d529a29fa912a76c9cb6d70db6ba20dbf2c13d6e3b0a8ad7286966bd00164ca0a163b483d305df6b492119cbffbabbba20e0647bb72f1b3d33d69f360d7e9f58f6a693d40b6ef58f49f140a212bf16931cba20e3803a6ecff76daf35709c8484f382783d211970f22397d7a258f40ca3b46304ba20f399ff078d6d954a390f67989705ed21e575ccf43a1340ca8752cd1613ca7ce0ba20f6a33481886c7d5ed5429c3bb0a83dbdefafd6d140b22a87aa7081cf7073136cba01129c", + "staking_transaction_slashing_script_hex": "207aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5ad2029f526a81bc92dd2ed8cf1682fc4ae5956987f3f6d3c0da71fbcf230c71781ffac204bcfb4042e5d13286fcd3d481b81a61cdfc3715aaf7909c4ee93de49356cd0b4ba2050eff2669c6d83f858937cd9229fc93ad57c10cc8d8cfb7ec9bc40e32a9f7ff2ba2078c5d7a263ab7e98e311c8d2d7305d13d78a014d4ae0603b427bb55cb42dbed1ba207bb40e3cb76545a71fafcb29738fb27b452c3176b41ffd614f7231b40ff5ce68ba20a7165ffc90d12c25187b75b2ebdcb57b1c759e357d655d8371cfb96dc4df2eccba20ae3c70699ae235ddebef85378a550f796723a6b961dcff1f33716d5dbb096a1eba20cca2d8aa1feb47ad4933154ef8196db229cfbba676607c3c0583397d65a1e4eeba20f1209d7248936f9ff2fa7b0ec97e5c0d26e4f41ad6de9f2e423128780da5dfecba20fe96402099f8387ce0ddef84bee2d0f869b35bb599a58b9aaec4a73db08dc490ba519d200f14729c14b6a9b292e7b5142fc5483d7c25196af1ef4b9722ea5821719e2c40ac200feacb370b7fcfcdd5ee7a363d73fda02d596ce61fd00e308d0ab68a7b955f48ba201e435d3bbab5fb0244c273e38d6f078bfe57a1bd151016ab5c4ac84457d724b3ba201fccb5af3a431a928c32267e556f1ba256871f98428419fae1cce6e7b8356cb9ba202367edcf01edd517d46c1b3cc3d40f5a28608e0313636dd09b0904799bccd635ba20243b84dd7a170a6e1edc32b22357b20f8365a4149a12ef1d340342701d535991ba2036612620ae82332e4f5da8d78d0d8a4ff7c8b09e88ee988b3dde18ef6a04c497ba20378f464f4365136230d30c3ad7d6425457d6c0742ed7fefd1015f0040cc70769ba2039eca9e5cf04e22471d6cde649604e6fd0aae077cd5b1af9a1dc26e56d8502f3ba20583c7fbf7450f8f78977b8c9f2981ff10676efefb6399ec925ba54eed7978a2eba2064df415d63ef3ce23ddd639c4a5ec8fdbfa67254db91228ca77fbec9610367aeba207947f704a584a804c91d07250239ec528300bd01dd3137770f7227309f63db0aba209010f319cde80190717d96dd60823b8e05905a2da458c69f4de19d5c9226cca8ba20a63763c4100bacdb1c06e5e1ba5599e379a2e23553d56d2b1d0ee3c990bd1192ba20db2bb56299fe3219ea5901198d1872f0523234d529a29fa912a76c9cb6d70db6ba20dbf2c13d6e3b0a8ad7286966bd00164ca0a163b483d305df6b492119cbffbabbba20e0647bb72f1b3d33d69f360d7e9f58f6a693d40b6ef58f49f140a212bf16931cba20e3803a6ecff76daf35709c8484f382783d211970f22397d7a258f40ca3b46304ba20f399ff078d6d954a390f67989705ed21e575ccf43a1340ca8752cd1613ca7ce0ba20f6a33481886c7d5ed5429c3bb0a83dbdefafd6d140b22a87aa7081cf7073136cba01129c", + "unbonding_transaction_hex": "020000000100000000000000000000000000000000000000000000000000000000000000000000000000ffffffff01605af4050000000022512044b4c847be70ba60488426ae7c59a636dc952b8494fb2f01584c9f533cd4b07c00000000", + "unbonding_transaction_time_lock_script_hex": "207aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5ad02c900b2", + "unbonding_transaction_slashing_script_hex": "207aa0dafe26a7b663b679418f2c19fe7ea1215919051aa5ac76e4a9fbef2f33c5ad2029f526a81bc92dd2ed8cf1682fc4ae5956987f3f6d3c0da71fbcf230c71781ffac204bcfb4042e5d13286fcd3d481b81a61cdfc3715aaf7909c4ee93de49356cd0b4ba2050eff2669c6d83f858937cd9229fc93ad57c10cc8d8cfb7ec9bc40e32a9f7ff2ba2078c5d7a263ab7e98e311c8d2d7305d13d78a014d4ae0603b427bb55cb42dbed1ba207bb40e3cb76545a71fafcb29738fb27b452c3176b41ffd614f7231b40ff5ce68ba20a7165ffc90d12c25187b75b2ebdcb57b1c759e357d655d8371cfb96dc4df2eccba20ae3c70699ae235ddebef85378a550f796723a6b961dcff1f33716d5dbb096a1eba20cca2d8aa1feb47ad4933154ef8196db229cfbba676607c3c0583397d65a1e4eeba20f1209d7248936f9ff2fa7b0ec97e5c0d26e4f41ad6de9f2e423128780da5dfecba20fe96402099f8387ce0ddef84bee2d0f869b35bb599a58b9aaec4a73db08dc490ba519d200f14729c14b6a9b292e7b5142fc5483d7c25196af1ef4b9722ea5821719e2c40ac200feacb370b7fcfcdd5ee7a363d73fda02d596ce61fd00e308d0ab68a7b955f48ba201e435d3bbab5fb0244c273e38d6f078bfe57a1bd151016ab5c4ac84457d724b3ba201fccb5af3a431a928c32267e556f1ba256871f98428419fae1cce6e7b8356cb9ba202367edcf01edd517d46c1b3cc3d40f5a28608e0313636dd09b0904799bccd635ba20243b84dd7a170a6e1edc32b22357b20f8365a4149a12ef1d340342701d535991ba2036612620ae82332e4f5da8d78d0d8a4ff7c8b09e88ee988b3dde18ef6a04c497ba20378f464f4365136230d30c3ad7d6425457d6c0742ed7fefd1015f0040cc70769ba2039eca9e5cf04e22471d6cde649604e6fd0aae077cd5b1af9a1dc26e56d8502f3ba20583c7fbf7450f8f78977b8c9f2981ff10676efefb6399ec925ba54eed7978a2eba2064df415d63ef3ce23ddd639c4a5ec8fdbfa67254db91228ca77fbec9610367aeba207947f704a584a804c91d07250239ec528300bd01dd3137770f7227309f63db0aba209010f319cde80190717d96dd60823b8e05905a2da458c69f4de19d5c9226cca8ba20a63763c4100bacdb1c06e5e1ba5599e379a2e23553d56d2b1d0ee3c990bd1192ba20db2bb56299fe3219ea5901198d1872f0523234d529a29fa912a76c9cb6d70db6ba20dbf2c13d6e3b0a8ad7286966bd00164ca0a163b483d305df6b492119cbffbabbba20e0647bb72f1b3d33d69f360d7e9f58f6a693d40b6ef58f49f140a212bf16931cba20e3803a6ecff76daf35709c8484f382783d211970f22397d7a258f40ca3b46304ba20f399ff078d6d954a390f67989705ed21e575ccf43a1340ca8752cd1613ca7ce0ba20f6a33481886c7d5ed5429c3bb0a83dbdefafd6d140b22a87aa7081cf7073136cba01129c", + "op_return_script_hex": "" + } + } + ] +} From f19de7d0fcc4ea786a070a700a03d2cde3f57b7f Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 24 May 2024 19:54:07 +1000 Subject: [PATCH 088/119] finality: Merkle tree based public randomness commitment (#655) --- client/query/finality.go | 14 + crypto/eots/eots.go | 6 +- go.mod | 8 +- go.sum | 16 +- proto/babylon/finality/v1/finality.proto | 13 + proto/babylon/finality/v1/genesis.proto | 10 + proto/babylon/finality/v1/query.proto | 38 + proto/babylon/finality/v1/tx.proto | 20 +- test/e2e/btc_staking_e2e_test.go | 20 +- .../configurer/chain/commands_btcstaking.go | 29 +- .../configurer/chain/queries_btcstaking.go | 14 + testutil/datagen/finality.go | 62 +- types/btc_schnorr_pub_rand.go | 13 + x/finality/client/cli/query.go | 34 + x/finality/client/cli/tx.go | 59 +- x/finality/keeper/genesis.go | 40 +- x/finality/keeper/genesis_test.go | 22 +- x/finality/keeper/grpc_query.go | 34 + x/finality/keeper/grpc_query_test.go | 75 ++ x/finality/keeper/msg_server.go | 52 +- x/finality/keeper/msg_server_test.go | 41 +- x/finality/keeper/public_randomness.go | 93 +- x/finality/keeper/votes_bench_test.go | 5 +- x/finality/types/errors.go | 21 +- x/finality/types/finality.go | 30 + x/finality/types/finality.pb.go | 310 ++++- x/finality/types/genesis.pb.go | 364 +++++- x/finality/types/keys.go | 7 +- x/finality/types/msg.go | 59 +- x/finality/types/msg_test.go | 21 +- x/finality/types/query.pb.go | 1148 ++++++++++++++--- x/finality/types/query.pb.gw.go | 119 ++ x/finality/types/tx.pb.go | 301 +++-- 33 files changed, 2616 insertions(+), 482 deletions(-) diff --git a/client/query/finality.go b/client/query/finality.go index 18220c3ec..554705bc5 100644 --- a/client/query/finality.go +++ b/client/query/finality.go @@ -46,6 +46,20 @@ func (c *QueryClient) VotesAtHeight(height uint64) (*finalitytypes.QueryVotesAtH return resp, err } +func (c *QueryClient) ListPubRandCommit(fpBtcPkHex string, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListPubRandCommitResponse, error) { + var resp *finalitytypes.QueryListPubRandCommitResponse + err := c.QueryFinality(func(ctx context.Context, queryClient finalitytypes.QueryClient) error { + var err error + req := &finalitytypes.QueryListPubRandCommitRequest{ + FpBtcPkHex: fpBtcPkHex, + Pagination: pagination, + } + resp, err = queryClient.ListPubRandCommit(ctx, req) + return err + }) + + return resp, err +} // ListBlocks queries the Finality module to get blocks with a given status. func (c *QueryClient) ListBlocks(status finalitytypes.QueriedBlockStatus, pagination *sdkquerytypes.PageRequest) (*finalitytypes.QueryListBlocksResponse, error) { diff --git a/crypto/eots/eots.go b/crypto/eots/eots.go index 932051b46..5bb288980 100644 --- a/crypto/eots/eots.go +++ b/crypto/eots/eots.go @@ -33,13 +33,13 @@ func PubGen(k *PrivateKey) *PublicKey { // RandGen returns the value to be used as random value when signing, and the associated public value. func RandGen(randSource io.Reader) (*PrivateRand, *PublicRand, error) { - pk, err := KeyGen(randSource) + sk, err := KeyGen(randSource) if err != nil { return nil, nil, err } var j secp256k1.JacobianPoint - pk.PubKey().AsJacobian(&j) - return &pk.Key, &j.X, nil + sk.PubKey().AsJacobian(&j) + return &sk.Key, &j.X, nil } // hash function is used for hashing the message input for all functions of the library. diff --git a/go.mod b/go.mod index 2f9e1e457..c621851bf 100644 --- a/go.mod +++ b/go.mod @@ -125,10 +125,10 @@ require ( github.com/tendermint/go-amino v0.16.0 // indirect github.com/zondax/hid v0.9.2 // indirect go.etcd.io/bbolt v1.3.8 // indirect - golang.org/x/crypto v0.22.0 - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.23.0 + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect nhooyr.io/websocket v1.8.6 // indirect ) diff --git a/go.sum b/go.sum index 4b44e4b3c..3c67d3b12 100644 --- a/go.sum +++ b/go.sum @@ -1259,8 +1259,8 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1519,16 +1519,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1543,8 +1543,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index 5f2a3d159..04b6bd722 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -16,6 +16,19 @@ message IndexedBlock { bool finalized = 3; } +// PubRandCommit is a commitment to a series of public randomness +// currently, the commitment is a root of a Merkle tree that includes +// a series of public randomness +message PubRandCommit { + // start_height is the height of the first commitment + uint64 start_height = 1; + // num_pub_rand is the number of committed public randomness + uint64 num_pub_rand = 2; + // commitment is the value of the commitment + // currently, it is the root of the merkle tree constructed by the public randomness + bytes commitment = 3; +} + // Evidence is the evidence that a finality provider has signed finality // signatures with correct public randomness on two conflicting Babylon headers message Evidence { diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index 7c1b4c62f..9edc47c7c 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -19,6 +19,8 @@ message GenesisState { repeated VoteSig vote_sigs = 4; // public_randomness contains all the public randomness ever commited from the finality providers. repeated PublicRandomness public_randomness = 5; + // pub_rand_commit contains all the public randomness commitment ever commited from the finality providers. + repeated PubRandCommitWithPK pub_rand_commit = 6; } // VoteSig the vote of an finality provider @@ -41,4 +43,12 @@ message PublicRandomness { bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pub_rand is the public randomness the finality provider has committed to. bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; +} + +// PubRandCommitWithPK is the public randomness commitment with the finality provider's BTC public key +message PubRandCommitWithPK { + // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pub_rand_commit is the public randomness commitment + PubRandCommit pub_rand_commit = 2; } \ No newline at end of file diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index 47938c2bf..352ef2716 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -17,10 +17,19 @@ service Query { } // ListPublicRandomness is a range query for public randomness of a given finality provider + // NOTE: Babylon only has the knowledge of public randomness that is already revealed by + // finality providers, i.e., the finality provider alreayd provides a finality signature + // at the corresponding height + // TODO: remove public randomness storage? rpc ListPublicRandomness(QueryListPublicRandomnessRequest) returns (QueryListPublicRandomnessResponse) { option (google.api.http).get = "/babylon/finality/v1/finality_providers/{fp_btc_pk_hex}/public_randomness_list"; } + // ListPubRandCommit is a range query for public randomness commitments of a given finality provider + rpc ListPubRandCommit(QueryListPubRandCommitRequest) returns (QueryListPubRandCommitResponse) { + option (google.api.http).get = "/babylon/finality/v1/finality_providers/{fp_btc_pk_hex}/pub_rand_commit_list"; + } + // Block queries a block at a given height rpc Block(QueryBlockRequest) returns (QueryBlockResponse) { option (google.api.http).get = "/babylon/finality/v1/blocks/{height}"; @@ -77,6 +86,35 @@ message QueryListPublicRandomnessResponse { cosmos.base.query.v1beta1.PageResponse pagination = 2; } +// PubRandCommitResponse is the response type for a public randomness commitment +message PubRandCommitResponse { + // num_pub_rand is the number of committed public randomness + uint64 num_pub_rand = 1; + // commitment is the value of the commitment + bytes commitment = 2; +} + +// QueryListPubRandCommitRequest is the request type for the +// Query/ListPubRandCommit RPC method. +message QueryListPubRandCommitRequest { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider + string fp_btc_pk_hex = 1; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryListPubRandCommitResponse is the response type for the +// Query/ListPubRandCommit RPC method. +message QueryListPubRandCommitResponse { + // pub_rand_commit_map is the map where the key is the start height and the value + // is the public randomness commitment at this height for the given finality provider + map pub_rand_commit_map = 1; + + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + // QueriedBlockStatus is the status of blocks that the querier wants to query. enum QueriedBlockStatus { // NON_FINALIZED means the block is not finalised diff --git a/proto/babylon/finality/v1/tx.proto b/proto/babylon/finality/v1/tx.proto index 5059e91ac..c1ff68ea2 100644 --- a/proto/babylon/finality/v1/tx.proto +++ b/proto/babylon/finality/v1/tx.proto @@ -4,6 +4,7 @@ package babylon.finality.v1; option go_package = "github.com/babylonchain/babylon/x/finality/types"; import "gogoproto/gogo.proto"; +import "tendermint/crypto/proof.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/msg/v1/msg.proto"; import "babylon/finality/v1/params.proto"; @@ -30,14 +31,17 @@ message MsgCommitPubRandList { bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // start_height is the start block height of the list of public randomness uint64 start_height = 3; - // pub_rand_list is the list of public randomness - repeated bytes pub_rand_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; - // sig is the signature on (start_height || pub_rand_list) signed by + // num_pub_rand is the number of public randomness committed + uint64 num_pub_rand = 4; + // commitment is the commitment of these public randomness + // currently it's the root of the Merkle tree that includes these public randomness + bytes commitment = 5; + // sig is the signature on (start_height || num_pub_rand || commitment) signed by // SK corresponding to fp_btc_pk. This prevents others to commit public // randomness on behalf of fp_btc_pk // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts // the tx submitter to be the holder of fp_btc_pk. Decide this later - bytes sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; } // MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message message MsgCommitPubRandListResponse{} @@ -51,13 +55,17 @@ message MsgAddFinalitySig { bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // block_height is the height of the voted block uint64 block_height = 3; + // pub_rand is the public randomness committed at this height + bytes pub_rand = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + // proof is the proof that the given public randomness is committed under the commitment + tendermint.crypto.Proof proof = 5; // block_app_hash is the AppHash of the voted block - bytes block_app_hash = 4; + bytes block_app_hash = 6; // finality_sig is the finality signature to this block // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - bytes finality_sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; } // MsgAddFinalitySigResponse is the response to the MsgAddFinalitySig message message MsgAddFinalitySigResponse{} diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 04aa36010..cdd0a69da 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -347,23 +347,26 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat commit a number of public randomness since activatedHeight */ // commit public randomness list - srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, activatedHeight, 100) + numPubRand := uint64(100) + randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, fpBTCSK, activatedHeight, numPubRand) s.NoError(err) nonValidatorNode.CommitPubRandList( msgCommitPubRandList.FpBtcPk, msgCommitPubRandList.StartHeight, - msgCommitPubRandList.PubRandList, + msgCommitPubRandList.NumPubRand, + msgCommitPubRandList.Commitment, msgCommitPubRandList.Sig, ) // ensure public randomness list is eventually committed nonValidatorNode.WaitForNextBlock() - var pubRandMap map[uint64]*bbn.SchnorrPubRand + var prCommitMap map[uint64]*ftypes.PubRandCommitResponse s.Eventually(func() bool { - pubRandMap = nonValidatorNode.QueryListPublicRandomness(fp.BtcPk) - return len(pubRandMap) > 0 + prCommitMap = nonValidatorNode.QueryListPubRandCommit(fp.BtcPk) + return len(prCommitMap) > 0 }, time.Minute, time.Second*5) - s.Equal(pubRandMap[activatedHeight].MustMarshal(), msgCommitPubRandList.PubRandList[0].MustMarshal()) + s.Equal(prCommitMap[activatedHeight].NumPubRand, msgCommitPubRandList.NumPubRand) + s.Equal(prCommitMap[activatedHeight].Commitment, msgCommitPubRandList.Commitment) // no reward gauge for finality provider and delegation yet fpBabylonAddr := sdk.AccAddress(nonValidatorNode.SecretKey.PubKey().Address().Bytes()) @@ -381,13 +384,14 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) appHash := blockToVote.AppHash + idx := 0 msgToSign := append(sdk.Uint64ToBigEndian(activatedHeight), appHash...) // generate EOTS signature - sig, err := eots.Sign(fpBTCSK, srList[0], msgToSign) + sig, err := eots.Sign(fpBTCSK, randListInfo.SRList[idx], msgToSign) s.NoError(err) eotsSig := bbn.NewSchnorrEOTSSigFromModNScalar(sig) // submit finality signature - nonValidatorNode.AddFinalitySig(fp.BtcPk, activatedHeight, appHash, eotsSig) + nonValidatorNode.AddFinalitySig(fp.BtcPk, activatedHeight, &randListInfo.PRList[idx], *randListInfo.ProofList[idx].ToProto(), appHash, eotsSig) // ensure vote is eventually cast nonValidatorNode.WaitForNextBlock() diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index 7397af143..01ffa2558 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcd/wire" sdkmath "cosmossdk.io/math" + cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/stretchr/testify/require" @@ -133,7 +134,7 @@ func (n *NodeConfig) AddCovenantSigs(covPK *bbn.BIP340PubKey, stakingTxHash stri n.LogActionF("successfully added covenant signatures") } -func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight uint64, pubRandList []bbn.SchnorrPubRand, sig *bbn.BIP340Signature) { +func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight uint64, numPubrand uint64, commitment []byte, sig *bbn.BIP340Signature) { n.LogActionF("committing public randomness list") cmd := []string{"babylond", "tx", "finality", "commit-pubrand-list"} @@ -146,11 +147,13 @@ func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight ui startHeightStr := strconv.FormatUint(startHeight, 10) cmd = append(cmd, startHeightStr) - // add each pubrand to cmd - for _, pr := range pubRandList { - prHex := pr.ToHexStr() - cmd = append(cmd, prHex) - } + // add num_pub_rand to cmd + numPubRandStr := strconv.FormatUint(numPubrand, 10) + cmd = append(cmd, numPubRandStr) + + // add commitment to cmd + commitmentHex := hex.EncodeToString(commitment) + cmd = append(cmd, commitmentHex) // add sig to cmd sigHex := sig.ToHexStr() @@ -160,23 +163,27 @@ func (n *NodeConfig) CommitPubRandList(fpBTCPK *bbn.BIP340PubKey, startHeight ui cmd = append(cmd, "--from=val") // gas - cmd = append(cmd, "--gas=auto", "--gas-prices=1ubbn", "--gas-adjustment=1.3") + cmd = append(cmd, "--gas=500000") _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) n.LogActionF("successfully committed public randomness list") } -func (n *NodeConfig) AddFinalitySig(fpBTCPK *bbn.BIP340PubKey, blockHeight uint64, blockLch []byte, finalitySig *bbn.SchnorrEOTSSig) { +func (n *NodeConfig) AddFinalitySig(fpBTCPK *bbn.BIP340PubKey, blockHeight uint64, pubRand *bbn.SchnorrPubRand, proof cmtcrypto.Proof, appHash []byte, finalitySig *bbn.SchnorrEOTSSig) { n.LogActionF("add finality signature") fpBTCPKHex := fpBTCPK.MarshalHex() blockHeightStr := strconv.FormatUint(blockHeight, 10) - blockLchHex := hex.EncodeToString(blockLch) + pubRandHex := pubRand.MarshalHex() + proofBytes, err := proof.Marshal() + require.NoError(n.t, err) + proofHex := hex.EncodeToString(proofBytes) + appHashHex := hex.EncodeToString(appHash) finalitySigHex := finalitySig.ToHexStr() - cmd := []string{"babylond", "tx", "finality", "add-finality-sig", fpBTCPKHex, blockHeightStr, blockLchHex, finalitySigHex, "--from=val", "--gas=500000"} - _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) + cmd := []string{"babylond", "tx", "finality", "add-finality-sig", fpBTCPKHex, blockHeightStr, pubRandHex, proofHex, appHashHex, finalitySigHex, "--from=val", "--gas=500000"} + _, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) n.LogActionF("successfully added finality signature") } diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index a4153050d..824381c1d 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -94,6 +94,7 @@ func (n *NodeConfig) QueryActivatedHeight() uint64 { } // TODO: pagination support +// TODO: remove public randomness storage? func (n *NodeConfig) QueryListPublicRandomness(fpBTCPK *bbn.BIP340PubKey) map[uint64]*bbn.SchnorrPubRand { path := fmt.Sprintf("/babylon/finality/v1/finality_providers/%s/public_randomness_list", fpBTCPK.MarshalHex()) bz, err := n.QueryGRPCGateway(path, url.Values{}) @@ -106,6 +107,19 @@ func (n *NodeConfig) QueryListPublicRandomness(fpBTCPK *bbn.BIP340PubKey) map[ui return resp.PubRandMap } +// TODO: pagination support +func (n *NodeConfig) QueryListPubRandCommit(fpBTCPK *bbn.BIP340PubKey) map[uint64]*ftypes.PubRandCommitResponse { + path := fmt.Sprintf("/babylon/finality/v1/finality_providers/%s/pub_rand_commit_list", fpBTCPK.MarshalHex()) + bz, err := n.QueryGRPCGateway(path, url.Values{}) + require.NoError(n.t, err) + + var resp ftypes.QueryListPubRandCommitResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + require.NoError(n.t, err) + + return resp.PubRandCommitMap +} + func (n *NodeConfig) QueryVotesAtHeight(height uint64) []bbn.BIP340PubKey { path := fmt.Sprintf("/babylon/finality/v1/votes/%d", height) bz, err := n.QueryGRPCGateway(path, url.Values{}) diff --git a/testutil/datagen/finality.go b/testutil/datagen/finality.go index 73eae543b..9216dd6d0 100644 --- a/testutil/datagen/finality.go +++ b/testutil/datagen/finality.go @@ -8,26 +8,44 @@ import ( ftypes "github.com/babylonchain/babylon/x/finality/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" + "github.com/cometbft/cometbft/crypto/merkle" sdk "github.com/cosmos/cosmos-sdk/types" ) -func GenRandomPubRandList(r *rand.Rand, numPubRand uint64) ([]*eots.PrivateRand, []bbn.SchnorrPubRand, error) { +type RandListInfo struct { + SRList []*eots.PrivateRand + PRList []bbn.SchnorrPubRand + Commitment []byte + ProofList []*merkle.Proof +} + +func GenRandomPubRandList(r *rand.Rand, numPubRand uint64) (*RandListInfo, error) { + // generate a list of secret/public randomness srList := []*eots.PrivateRand{} prList := []bbn.SchnorrPubRand{} for i := uint64(0); i < numPubRand; i++ { eotsSR, eotsPR, err := eots.RandGen(r) if err != nil { - return nil, nil, err + return nil, err } pr := bbn.NewSchnorrPubRandFromFieldVal(eotsPR) srList = append(srList, eotsSR) prList = append(prList, *pr) } - return srList, prList, nil + + prByteList := [][]byte{} + for i := range prList { + prByteList = append(prByteList, prList[i]) + } + + // generate the commitment to these public randomness + commitment, proofList := merkle.ProofsFromByteSlices(prByteList) + + return &RandListInfo{srList, prList, commitment, proofList}, nil } -func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeight uint64, numPubRand uint64) ([]*eots.PrivateRand, *ftypes.MsgCommitPubRandList, error) { - srList, prList, err := GenRandomPubRandList(r, numPubRand) +func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeight uint64, numPubRand uint64) (*RandListInfo, *ftypes.MsgCommitPubRandList, error) { + randListInfo, err := GenRandomPubRandList(r, numPubRand) if err != nil { return nil, nil, err } @@ -36,7 +54,8 @@ func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeig Signer: GenRandomAccount().Address, FpBtcPk: bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()), StartHeight: startHeight, - PubRandList: prList, + NumPubRand: numPubRand, + Commitment: randListInfo.Commitment, } hash, err := msg.HashToSign() if err != nil { @@ -47,7 +66,36 @@ func GenRandomMsgCommitPubRandList(r *rand.Rand, sk *btcec.PrivateKey, startHeig return nil, nil, err } msg.Sig = bbn.NewBIP340SignatureFromBTCSig(schnorrSig) - return srList, msg, nil + return randListInfo, msg, nil +} + +func NewMsgAddFinalitySig( + signer string, + sk *btcec.PrivateKey, + startHeight uint64, + blockHeight uint64, + randListInfo *RandListInfo, + blockAppHash []byte, +) (*ftypes.MsgAddFinalitySig, error) { + idx := blockHeight - startHeight + + msg := &ftypes.MsgAddFinalitySig{ + Signer: signer, + FpBtcPk: bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()), + PubRand: &randListInfo.PRList[idx], + Proof: randListInfo.ProofList[idx].ToProto(), + BlockHeight: blockHeight, + BlockAppHash: blockAppHash, + FinalitySig: nil, + } + msgToSign := msg.MsgToSign() + sig, err := eots.Sign(sk, randListInfo.SRList[idx], msgToSign) + if err != nil { + return nil, err + } + msg.FinalitySig = bbn.NewSchnorrEOTSSigFromModNScalar(sig) + + return msg, nil } func GenRandomEvidence(r *rand.Rand, sk *btcec.PrivateKey, height uint64) (*ftypes.Evidence, error) { diff --git a/types/btc_schnorr_pub_rand.go b/types/btc_schnorr_pub_rand.go index be92231d2..154c6dee6 100644 --- a/types/btc_schnorr_pub_rand.go +++ b/types/btc_schnorr_pub_rand.go @@ -4,7 +4,9 @@ import ( "encoding/hex" "fmt" + "github.com/babylonchain/babylon/crypto/eots" "github.com/btcsuite/btcd/btcec/v2" + "github.com/decred/dcrd/dcrec/secp256k1/v4" ) type SchnorrPubRand []byte @@ -31,6 +33,13 @@ func NewSchnorrPubRandFromFieldVal(r *btcec.FieldVal) *SchnorrPubRand { return &pr } +func NewPubRandFromPrivRand(sr *eots.PrivateRand) *SchnorrPubRand { + sk := secp256k1.NewPrivateKey(sr) + var j secp256k1.JacobianPoint + sk.PubKey().AsJacobian(&j) + return NewSchnorrPubRandFromFieldVal(&j.X) +} + func (pr SchnorrPubRand) ToFieldVal() *btcec.FieldVal { var r btcec.FieldVal r.SetByteSlice(pr) @@ -45,6 +54,10 @@ func (pr SchnorrPubRand) Marshal() ([]byte, error) { return pr, nil } +func (pr SchnorrPubRand) MarshalHex() string { + return hex.EncodeToString(pr) +} + func (pr SchnorrPubRand) MustMarshal() []byte { prBytes, err := pr.Marshal() if err != nil { diff --git a/x/finality/client/cli/query.go b/x/finality/client/cli/query.go index 7198e450f..78ece2d87 100644 --- a/x/finality/client/cli/query.go +++ b/x/finality/client/cli/query.go @@ -30,6 +30,7 @@ func GetQueryCmd(queryRoute string) *cobra.Command { cmd.AddCommand(CmdQueryParams()) cmd.AddCommand(CmdListPublicRandomness()) + cmd.AddCommand(CmdListPubRandCommit()) cmd.AddCommand(CmdBlock()) cmd.AddCommand(CmdListBlocks()) cmd.AddCommand(CmdVotesAtHeight()) @@ -100,6 +101,39 @@ func CmdListPublicRandomness() *cobra.Command { return cmd } +func CmdListPubRandCommit() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-pub-rand-commit [fp_btc_pk_hex]", + Short: "list public randomness commitment of a given finality provider", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.ListPubRandCommit(cmd.Context(), &types.QueryListPubRandCommitRequest{ + FpBtcPkHex: args[0], + Pagination: pageReq, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "list-pub-rand-commit") + + return cmd +} + func CmdListBlocks() *cobra.Command { cmd := &cobra.Command{ Use: "list-blocks", diff --git a/x/finality/client/cli/tx.go b/x/finality/client/cli/tx.go index bf4b4178b..d1ed88abd 100644 --- a/x/finality/client/cli/tx.go +++ b/x/finality/client/cli/tx.go @@ -8,6 +8,7 @@ import ( bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" + cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -34,8 +35,8 @@ func GetTxCmd() *cobra.Command { func NewCommitPubRandListCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "commit-pubrand-list [fp_btc_pk] [start_height] [pub_rand1] [pub_rand2] ... [sig]", - Args: cobra.MinimumNArgs(4), + Use: "commit-pubrand-list [fp_btc_pk] [start_height] [num_pub_rand] [commitment] [sig]", + Args: cobra.ExactArgs(5), Short: "Commit a list of public randomness", Long: strings.TrimSpace( `Commit a list of public randomness.`, // TODO: example @@ -58,28 +59,28 @@ func NewCommitPubRandListCmd() *cobra.Command { return err } - // get signature - sig, err := bbn.NewBIP340SignatureFromHex(args[len(args)-1]) + numPubRand, err := strconv.ParseUint(args[2], 10, 64) if err != nil { return err } - // get pub rand list - pubRandHexList := args[2 : len(args)-1] - pubRandList := []bbn.SchnorrPubRand{} - for _, prHex := range pubRandHexList { - pr, err := bbn.NewSchnorrPubRandFromHex(prHex) - if err != nil { - return err - } - pubRandList = append(pubRandList, *pr) + commitment, err := hex.DecodeString(args[3]) + if err != nil { + return err + } + + // get signature + sig, err := bbn.NewBIP340SignatureFromHex(args[4]) + if err != nil { + return err } msg := types.MsgCommitPubRandList{ Signer: clientCtx.FromAddress.String(), FpBtcPk: fpBTCPK, StartHeight: startHeight, - PubRandList: pubRandList, + NumPubRand: numPubRand, + Commitment: commitment, Sig: sig, } @@ -94,8 +95,8 @@ func NewCommitPubRandListCmd() *cobra.Command { func NewAddFinalitySigCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "add-finality-sig [fp_btc_pk] [block_height] [block_app_hash] [finality_sig]", - Args: cobra.ExactArgs(4), + Use: "add-finality-sig [fp_btc_pk] [block_height] [pub_rand] [proof] [block_app_hash] [finality_sig]", + Args: cobra.ExactArgs(6), Short: "Add a finality signature", Long: strings.TrimSpace( `Add a finality signature.`, // TODO: example @@ -118,14 +119,30 @@ func NewAddFinalitySigCmd() *cobra.Command { return err } - // get block last commit hash - blockLch, err := hex.DecodeString(args[2]) + // get public randomness + pubRand, err := bbn.NewSchnorrPubRandFromHex(args[2]) + if err != nil { + return err + } + + // get proof + proofBytes, err := hex.DecodeString(args[3]) + if err != nil { + return err + } + var proof cmtcrypto.Proof + if err := clientCtx.Codec.Unmarshal(proofBytes, &proof); err != nil { + return err + } + + // get block app hash + appHash, err := hex.DecodeString(args[4]) if err != nil { return err } // get finality signature - finalitySig, err := bbn.NewSchnorrEOTSSigFromHex(args[3]) + finalitySig, err := bbn.NewSchnorrEOTSSigFromHex(args[5]) if err != nil { return err } @@ -134,7 +151,9 @@ func NewAddFinalitySigCmd() *cobra.Command { Signer: clientCtx.FromAddress.String(), FpBtcPk: fpBTCPK, BlockHeight: blockHeight, - BlockAppHash: blockLch, + PubRand: pubRand, + Proof: &proof, + BlockAppHash: appHash, FinalitySig: finalitySig, } diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index 57fcac889..d6e700640 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -25,7 +25,11 @@ func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { } for _, pubRand := range gs.PublicRandomness { - k.SetPubRandList(ctx, pubRand.FpBtcPk, pubRand.BlockHeight, []bbn.SchnorrPubRand{*pubRand.PubRand}) + k.SetPubRand(ctx, pubRand.FpBtcPk, pubRand.BlockHeight, *pubRand.PubRand) + } + + for _, prc := range gs.PubRandCommit { + k.SetPubRandCommit(ctx, prc.FpBtcPk, prc.PubRandCommit) } return k.SetParams(ctx, gs.Params) @@ -53,12 +57,18 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) return nil, err } + prCommit, err := k.exportPubRandCommit(ctx) + if err != nil { + return nil, err + } + return &types.GenesisState{ Params: k.GetParams(ctx), IndexedBlocks: blocks, Evidences: evidences, VoteSigs: voteSigs, PublicRandomness: pubRandomness, + PubRandCommit: prCommit, }, nil } @@ -160,6 +170,34 @@ func (k Keeper) publicRandomness(ctx context.Context) ([]*types.PublicRandomness return commtRandoms, nil } +// exportPubRandCommit iterates over all public randomness commitment on the store, +// parses the finality provider public key and the height from the iterator key +// and the commitment from the iterator value. +// This function has high resource consumption and should be only used on export genesis. +func (k Keeper) exportPubRandCommit(ctx context.Context) ([]*types.PubRandCommitWithPK, error) { + store := k.pubRandCommitStore(ctx) + iter := store.Iterator(nil, nil) + defer iter.Close() + + commtRandoms := make([]*types.PubRandCommitWithPK, 0) + for ; iter.Valid(); iter.Next() { + // key contains the fp and the block height + fpBTCPK, _, err := parsePubKeyAndBlkHeightFromStoreKey(iter.Key()) + if err != nil { + return nil, err + } + var prc types.PubRandCommit + k.cdc.MustUnmarshal(iter.Value(), &prc) + + commtRandoms = append(commtRandoms, &types.PubRandCommitWithPK{ + FpBtcPk: fpBTCPK, + PubRandCommit: &prc, + }) + } + + return commtRandoms, nil +} + // parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with // BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index d8768fec2..ce7e87bc9 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -21,13 +21,12 @@ func TestExportGenesis(t *testing.T) { fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) - srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + randListInfo, _, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) require.NoError(t, err) - sr := srList[startHeight+blkHeight] blockHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address - msgAddFinalitySig, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blkHeight, blockHash) + msgAddFinalitySig, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blkHeight, randListInfo, blockHash) require.NoError(t, err) allVotes := make([]*types.VoteSig, numPubRand) @@ -57,7 +56,7 @@ func TestExportGenesis(t *testing.T) { evidence := &types.Evidence{ FpBtcPk: fpBTCPK, BlockHeight: blkHeight, - PubRand: &msgCommitPubRandList.PubRandList[i], + PubRand: &randListInfo.PRList[i], ForkAppHash: msgAddFinalitySig.BlockAppHash, ForkFinalitySig: msgAddFinalitySig.FinalitySig, CanonicalAppHash: blockHash, @@ -66,9 +65,9 @@ func TestExportGenesis(t *testing.T) { k.SetEvidence(ctx, evidence) allEvidences[i] = evidence - // PubRandoms - pubRand := msgCommitPubRandList.PubRandList[i] - k.SetPubRandList(ctx, fpBTCPK, blkHeight, []bbn.SchnorrPubRand{pubRand}) + // public randomness + pubRand := randListInfo.PRList[i] + k.SetPubRand(ctx, fpBTCPK, blkHeight, pubRand) randomness := &types.PublicRandomness{ BlockHeight: blkHeight, FpBtcPk: fpBTCPK, @@ -79,6 +78,14 @@ func TestExportGenesis(t *testing.T) { // updates the block everytime to make sure something is different. blkHeight++ } + + prc := &types.PubRandCommit{ + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: randListInfo.Commitment, + } + k.SetPubRandCommit(ctx, fpBTCPK, prc) + require.Equal(t, len(allVotes), int(numPubRand)) require.Equal(t, len(allBlocks), int(numPubRand)) require.Equal(t, len(allEvidences), int(numPubRand)) @@ -92,4 +99,5 @@ func TestExportGenesis(t *testing.T) { require.Equal(t, allBlocks, gs.IndexedBlocks) require.Equal(t, allEvidences, gs.Evidences) require.Equal(t, allPublicRandomness, gs.PublicRandomness) + require.Equal(t, prc, gs.PubRandCommit[0].PubRandCommit) } diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index 6f867bb08..3b9a48a3f 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -20,6 +20,7 @@ var _ types.QueryServer = Keeper{} // ListPublicRandomness returns a list of public randomness committed by a given // finality provider +// TODO: remove public randomness storage? func (k Keeper) ListPublicRandomness(ctx context.Context, req *types.QueryListPublicRandomnessRequest) (*types.QueryListPublicRandomnessResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") @@ -53,6 +54,39 @@ func (k Keeper) ListPublicRandomness(ctx context.Context, req *types.QueryListPu return resp, nil } +// ListPubRandCommit returns a list of public randomness commitment by a given +// finality provider +func (k Keeper) ListPubRandCommit(ctx context.Context, req *types.QueryListPubRandCommitRequest) (*types.QueryListPubRandCommitResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } + + fpBTCPK, err := bbn.NewBIP340PubKeyFromHex(req.FpBtcPkHex) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "failed to unmarshal finality provider BTC PK hex: %v", err) + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + store := k.pubRandCommitFpStore(sdkCtx, fpBTCPK) + pubRandCommitMap := map[uint64]*types.PubRandCommitResponse{} + pageRes, err := query.Paginate(store, req.Pagination, func(key, value []byte) error { + height := sdk.BigEndianToUint64(key) + var prCommit types.PubRandCommit + k.cdc.MustUnmarshal(value, &prCommit) + pubRandCommitMap[height] = prCommit.ToResponse() + return nil + }) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + resp := &types.QueryListPubRandCommitResponse{ + PubRandCommitMap: pubRandCommitMap, + Pagination: pageRes, + } + return resp, nil +} + func (k Keeper) Block(ctx context.Context, req *types.QueryBlockRequest) (*types.QueryBlockResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index beeb99986..e756ead0a 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -4,13 +4,16 @@ import ( "math/rand" "testing" + "github.com/btcsuite/btcd/btcec/v2/schnorr" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" + "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" "github.com/babylonchain/babylon/testutil/datagen" testkeeper "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/finality/keeper" "github.com/babylonchain/babylon/x/finality/types" ) @@ -178,6 +181,78 @@ func FuzzVotesAtHeight(f *testing.F) { }) } +func FuzzListPubRandCommit(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // Setup keeper and context + bsKeeper := types.NewMockBTCStakingKeeper(ctrl) + fKeeper, ctx := testkeeper.FinalityKeeper(t, bsKeeper, nil) + ctx = sdk.UnwrapSDKContext(ctx) + ms := keeper.NewMsgServerImpl(*fKeeper) + + // set random BTC SK PK + sk, _, err := datagen.GenRandomBTCKeyPair(r) + bip340PK := bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()) + require.NoError(t, err) + + // register finality provider + fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, sk) + require.NoError(t, err) + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(fp, nil).AnyTimes() + bsKeeper.EXPECT().HasFinalityProvider(gomock.Any(), gomock.Eq(bip340PK.MustMarshal())).Return(true).AnyTimes() + + numPrCommitList := datagen.RandomInt(r, 10) + 1 + prCommitList := []*types.PubRandCommit{} + + // set a list of random public randomness commitment + startHeight := datagen.RandomInt(r, 10) + 1 + for i := uint64(0); i < numPrCommitList; i++ { + numPubRand := datagen.RandomInt(r, 10) + 100 + randListInfo, err := datagen.GenRandomPubRandList(r, numPubRand) + require.NoError(t, err) + prCommit := &types.PubRandCommit{ + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: randListInfo.Commitment, + } + msg := &types.MsgCommitPubRandList{ + Signer: datagen.GenRandomAccount().Address, + FpBtcPk: bip340PK, + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: prCommit.Commitment, + } + hash, err := msg.HashToSign() + require.NoError(t, err) + schnorrSig, err := schnorr.Sign(sk, hash) + require.NoError(t, err) + msg.Sig = bbn.NewBIP340SignatureFromBTCSig(schnorrSig) + _, err = ms.CommitPubRandList(ctx, msg) + require.NoError(t, err) + + prCommitList = append(prCommitList, prCommit) + + startHeight += numPubRand + } + + resp, err := fKeeper.ListPubRandCommit(ctx, &types.QueryListPubRandCommitRequest{ + FpBtcPkHex: bip340PK.MarshalHex(), + }) + require.NoError(t, err) + + for _, prCommit := range prCommitList { + prCommitResp, ok := resp.PubRandCommitMap[prCommit.StartHeight] + require.True(t, ok) + require.Equal(t, prCommitResp.NumPubRand, prCommit.NumPubRand) + require.Equal(t, prCommitResp.Commitment, prCommit.Commitment) + } + }) +} + func FuzzQueryEvidence(f *testing.F) { datagen.AddRandomSeedsToFuzzer(f, 10) f.Fuzz(func(t *testing.T, seed int64) { diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index f5b910389..d64f9ef7a 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -7,7 +7,6 @@ import ( "time" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/crypto/eots" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/babylonchain/babylon/x/finality/types" @@ -97,20 +96,19 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal return &types.MsgAddFinalitySigResponse{}, nil } - // ensure the finality provider has committed public randomness - pubRand, err := ms.GetPubRand(ctx, fpPK, req.BlockHeight) + // find the public randomness commitment for this height from this finality provider + prCommit, err := ms.GetPubRandCommitForHeight(ctx, req.FpBtcPk, req.BlockHeight) if err != nil { - return nil, types.ErrPubRandNotFound + return nil, err } - // verify EOTS signature w.r.t. public randomness - fpBTCPK, err := fpPK.ToBTCPK() - if err != nil { + // verify the finality signature message w.r.t. the public randomness commitment + // including the public randomness inclusion proof and the finality signature + if err := types.VerifyFinalitySig(req, prCommit); err != nil { return nil, err } - if err := eots.Verify(fpBTCPK, pubRand.ToFieldVal(), req.MsgToSign(), req.FinalitySig.ToModNScalar()); err != nil { - return nil, types.ErrInvalidFinalitySig.Wrapf("the EOTS signature is invalid: %v", err) - } + // the public randomness is good, set the public randomness + ms.SetPubRand(ctx, req.FpBtcPk, req.BlockHeight, *req.PubRand) // verify whether the voted block is a fork or not indexedBlock, err := ms.GetBlock(ctx, req.BlockHeight) @@ -124,7 +122,7 @@ func (ms msgServer) AddFinalitySig(goCtx context.Context, req *types.MsgAddFinal evidence := &types.Evidence{ FpBtcPk: req.FpBtcPk, BlockHeight: req.BlockHeight, - PubRand: pubRand, + PubRand: req.PubRand, CanonicalAppHash: indexedBlock.AppHash, CanonicalFinalitySig: nil, ForkAppHash: req.BlockAppHash, @@ -184,10 +182,11 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi // ensure the request contains enough number of public randomness minPubRand := ms.GetParams(ctx).MinPubRand - givenPubRand := len(req.PubRandList) - if uint64(givenPubRand) < minPubRand { - return nil, types.ErrTooFewPubRand.Wrapf("required minimum: %d, actual: %d", minPubRand, givenPubRand) + givenNumPubRand := req.NumPubRand + if givenNumPubRand < minPubRand { + return nil, types.ErrTooFewPubRand.Wrapf("required minimum: %d, actual: %d", minPubRand, givenNumPubRand) } + // TODO: ensure log_2(givenNumPubRand) is an integer? // ensure the finality provider is registered if req.FpBtcPk == nil { @@ -198,20 +197,27 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi return nil, bstypes.ErrFpNotFound.Wrapf("the finality provider with BTC PK %v is not registered", fpBTCPKBytes) } + prCommit := &types.PubRandCommit{ + StartHeight: req.StartHeight, + NumPubRand: req.NumPubRand, + Commitment: req.Commitment, + } + + // get last public randomness commitment + // TODO: allow committing public randomness earlier than existing ones? + lastPrCommit := ms.GetLastPubRandCommit(ctx, req.FpBtcPk) + // this finality provider has not commit any public randomness, // commit the given public randomness list and return - if ms.IsFirstPubRand(ctx, req.FpBtcPk) { - ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) + if lastPrCommit == nil { + ms.SetPubRandCommit(ctx, req.FpBtcPk, prCommit) return &types.MsgCommitPubRandListResponse{}, nil } // ensure height and req.StartHeight do not overlap, i.e., height < req.StartHeight - height, _, err := ms.GetLastPubRand(ctx, req.FpBtcPk) - if err != nil { - return nil, err - } - if height >= req.StartHeight { - return nil, types.ErrInvalidPubRand.Wrapf("the start height (%d) has overlap with the height of the highest public randomness (%d)", req.StartHeight, height) + lastPrHeightCommitted := lastPrCommit.EndHeight() + if req.StartHeight <= lastPrCommit.EndHeight() { + return nil, types.ErrInvalidPubRand.Wrapf("the start height (%d) has overlap with the height of the highest public randomness committed (%d)", req.StartHeight, lastPrHeightCommitted) } // verify signature over the list @@ -220,7 +226,7 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi } // all good, commit the given public randomness list - ms.SetPubRandList(ctx, req.FpBtcPk, req.StartHeight, req.PubRandList) + ms.SetPubRandCommit(ctx, req.FpBtcPk, prCommit) return &types.MsgCommitPubRandListResponse{}, nil } diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 275f0da8f..1401db82e 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -73,10 +73,8 @@ func FuzzCommitPubRandList(f *testing.F) { _, err = ms.CommitPubRandList(ctx, msg) require.NoError(t, err) // query last public randomness and assert - actualHeight, actualPubRand, err := fKeeper.GetLastPubRand(ctx, fpBTCPK) - require.NoError(t, err) - require.Equal(t, startHeight+numPubRand-1, actualHeight) - require.Equal(t, msg.PubRandList[len(msg.PubRandList)-1].MustMarshal(), actualPubRand.MustMarshal()) + lastPrCommit := fKeeper.GetLastPubRandCommit(ctx, fpBTCPK) + require.NotNil(t, lastPrCommit) // Case 4: commit a pubrand list with overlap of the existing pubrand in KVStore and it should fail overlappedStartHeight := startHeight + numPubRand - 1 - datagen.RandomInt(r, 5) @@ -91,11 +89,6 @@ func FuzzCommitPubRandList(f *testing.F) { require.NoError(t, err) _, err = ms.CommitPubRandList(ctx, msg) require.NoError(t, err) - // query last public randomness and assert - actualHeight, actualPubRand, err = fKeeper.GetLastPubRand(ctx, fpBTCPK) - require.NoError(t, err) - require.Equal(t, nonOverlappedStartHeight+numPubRand-1, actualHeight) - require.Equal(t, msg.PubRandList[len(msg.PubRandList)-1].MustMarshal(), actualPubRand.MustMarshal()) }) } @@ -123,17 +116,16 @@ func FuzzAddFinalitySig(f *testing.F) { // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) - srList, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) require.NoError(t, err) _, err = ms.CommitPubRandList(ctx, msgCommitPubRandList) require.NoError(t, err) // generate a vote - blockHeight := uint64(1) - sr, _ := srList[startHeight+blockHeight], msgCommitPubRandList.PubRandList[startHeight+blockHeight] - blockHash := datagen.GenRandomByteArray(r, 32) + blockHeight := startHeight + uint64(1) + blockAppHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address - msg, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blockHeight, blockHash) + msg, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, blockAppHash) require.NoError(t, err) // Case 1: fail if the finality provider does not have voting power @@ -157,7 +149,7 @@ func FuzzAddFinalitySig(f *testing.F) { // Case 3: successful if the finality provider has voting power and has not casted this vote yet // index this block first - ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: blockHash}) + ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: blockAppHash}) fKeeper.IndexBlock(ctx) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) // add vote and it should work @@ -175,8 +167,8 @@ func FuzzAddFinalitySig(f *testing.F) { require.NotNil(t, resp) // Case 5: the finality provider is slashed if it votes for a fork - blockHash2 := datagen.GenRandomByteArray(r, 32) - msg2, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, blockHeight, blockHash2) + blockAppHash2 := datagen.GenRandomByteArray(r, 32) + msg2, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, blockAppHash2) require.NoError(t, err) bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) // mock slashing interface @@ -203,7 +195,7 @@ func FuzzAddFinalitySig(f *testing.F) { require.True(t, btcSK.Key.Equals(&btcSK2.Key) || btcSK.Key.Negate().Equals(&btcSK2.Key)) require.Equal(t, btcSK.PubKey().SerializeCompressed()[1:], btcSK2.PubKey().SerializeCompressed()[1:]) - // Case 6: slashed finality proivder cannot vote + // Case 6: slashed finality provider cannot vote fp.SlashedBabylonHeight = blockHeight bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), gomock.Eq(fpBTCPKBytes)).Return(fp, nil).Times(1) _, err = ms.AddFinalitySig(ctx, msg) @@ -231,16 +223,15 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { // commit some public randomness startHeight := uint64(0) numPubRand := uint64(200) - srList, msgCommitPubRandList, err := + randListInfo, msgCommitPubRandList, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) require.NoError(t, err) _, err = ms.CommitPubRandList(ctx, msgCommitPubRandList) require.NoError(t, err) // set a block height of 1 and some random list - blockHeight := uint64(1) - sr, _ := srList[startHeight+blockHeight], - msgCommitPubRandList.PubRandList[startHeight+blockHeight] + blockHeight := startHeight + uint64(1) + // generate two random hashes, one for the canonical block and // one for a fork block canonicalHash := datagen.GenRandomByteArray(r, 32) @@ -253,8 +244,7 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { // (2) Vote for a different block at height 1, this will make us have // some "evidence" ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: forkHash}) - msg1, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, - blockHeight, forkHash) + msg1, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, forkHash) require.NoError(t, err) bsKeeper.EXPECT().GetVotingPower(gomock.Any(), @@ -265,8 +255,7 @@ func TestVoteForConflictingHashShouldRetrieveEvidenceAndSlash(t *testing.T) { _, err = ms.AddFinalitySig(ctx, msg1) require.NoError(t, err) // (3) Now vote for the canonical block at height 1. This should slash Finality provider - msg, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, - blockHeight, canonicalHash) + msg, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blockHeight, randListInfo, canonicalHash) ctx = ctx.WithHeaderInfo(header.Info{Height: int64(blockHeight), AppHash: canonicalHash}) require.NoError(t, err) bsKeeper.EXPECT().GetVotingPower(gomock.Any(), diff --git a/x/finality/keeper/public_randomness.go b/x/finality/keeper/public_randomness.go index e21e5a4e5..a46a630fd 100644 --- a/x/finality/keeper/public_randomness.go +++ b/x/finality/keeper/public_randomness.go @@ -12,21 +12,77 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// SetPubRandList sets a list of public randomness starting from a given startHeight -// for a given finality provider -func (k Keeper) SetPubRandList(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, startHeight uint64, pubRandList []bbn.SchnorrPubRand) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - cacheCtx, writeCache := sdkCtx.CacheContext() - - // write to a KV store cache - store := k.pubRandFpStore(cacheCtx, fpBtcPK) - for i, pr := range pubRandList { - height := startHeight + uint64(i) - store.Set(sdk.Uint64ToBigEndian(height), pr) +/* + Public randomness commitment storage +*/ + +// GetPubRandCommitForHeight finds the public randomness commitment that includes the given +// height for the given finality provider +func (k Keeper) GetPubRandCommitForHeight(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) (*types.PubRandCommit, error) { + store := k.pubRandCommitFpStore(ctx, fpBtcPK) + iter := store.ReverseIterator(nil, nil) + defer iter.Close() + + var prCommit types.PubRandCommit + for ; iter.Valid(); iter.Next() { + k.cdc.MustUnmarshal(iter.Value(), &prCommit) + if prCommit.IsInRange(height) { + return &prCommit, nil + } } + return nil, types.ErrPubRandNotFound +} + +// SetPubRandCommit adds the given public randomness commitment for the given public key +func (k Keeper) SetPubRandCommit(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, prCommit *types.PubRandCommit) { + store := k.pubRandCommitFpStore(ctx, fpBtcPK) + prcBytes := k.cdc.MustMarshal(prCommit) + store.Set(sdk.Uint64ToBigEndian(prCommit.StartHeight), prcBytes) +} + +// GetLastPubRandCommit retrieves the last public randomness commitment of the given finality provider +func (k Keeper) GetLastPubRandCommit(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) *types.PubRandCommit { + store := k.pubRandCommitFpStore(ctx, fpBtcPK) + iter := store.ReverseIterator(nil, nil) + defer iter.Close() - // atomically write the new public randomness back to KV store - writeCache() + if !iter.Valid() { + // this finality provider does not commit any randomness + return nil + } + + var prCommit types.PubRandCommit + k.cdc.MustUnmarshal(iter.Value(), &prCommit) + return &prCommit +} + +// pubRandCommitFpStore returns the KVStore of the commitment of public randomness +// prefix: PubRandKey +// key: (finality provider PK || block height of the commitment) +// value: PubRandCommit +func (k Keeper) pubRandCommitFpStore(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) prefix.Store { + store := k.pubRandCommitStore(ctx) + return prefix.NewStore(store, fpBtcPK.MustMarshal()) +} + +// pubRandCommitStore returns the KVStore of the public randomness commitments +// prefix: PubRandKey +// key: (prefix) +// value: PubRandCommit +func (k Keeper) pubRandCommitStore(ctx context.Context) prefix.Store { + storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + return prefix.NewStore(storeAdapter, types.PubRandCommitKey) +} + +/* + Public randomness storage + TODO: remove public randomness storage? +*/ + +// SetPubRand sets a public randomness at a given height for a given finality provider +func (k Keeper) SetPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64, pubRand bbn.SchnorrPubRand) { + store := k.pubRandFpStore(ctx, fpBtcPK) + store.Set(sdk.Uint64ToBigEndian(height), pubRand) } func (k Keeper) HasPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, height uint64) bool { @@ -43,18 +99,11 @@ func (k Keeper) GetPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey, heigh return bbn.NewSchnorrPubRand(prBytes) } -func (k Keeper) IsFirstPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) bool { - store := k.pubRandFpStore(ctx, fpBtcPK) - iter := store.ReverseIterator(nil, nil) - - // if the iterator is not valid, then this finality provider does not commit any randomness - return !iter.Valid() -} - // GetLastPubRand retrieves the last public randomness committed by the given finality provider func (k Keeper) GetLastPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) (uint64, *bbn.SchnorrPubRand, error) { store := k.pubRandFpStore(ctx, fpBtcPK) iter := store.ReverseIterator(nil, nil) + defer iter.Close() if !iter.Valid() { // this finality provider does not commit any randomness @@ -72,7 +121,7 @@ func (k Keeper) GetLastPubRand(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) ( // pubRandFpStore returns the KVStore of the public randomness // prefix: PubRandKey -// key: (finality provider || PK block height) +// key: (finality provider PK || block height) // value: PublicRandomness func (k Keeper) pubRandFpStore(ctx context.Context, fpBtcPK *bbn.BIP340PubKey) prefix.Store { prefixedStore := k.pubRandStore(ctx) diff --git a/x/finality/keeper/votes_bench_test.go b/x/finality/keeper/votes_bench_test.go index c22a6cba4..ec35ffcdc 100644 --- a/x/finality/keeper/votes_bench_test.go +++ b/x/finality/keeper/votes_bench_test.go @@ -42,7 +42,7 @@ func benchmarkAddFinalitySig(b *testing.B) { // commit enough public randomness // TODO: generalise commit public randomness to allow arbitrary benchtime - srList, msg, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, 0, 100000) + randListInfo, msg, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, 0, 100000) require.NoError(b, err) _, err = ms.CommitPubRandList(ctx, msg) require.NoError(b, err) @@ -68,10 +68,9 @@ func benchmarkAddFinalitySig(b *testing.B) { height := uint64(i) // generate a vote - sr := srList[height] blockHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address - msg, err := types.NewMsgAddFinalitySig(signer, btcSK, sr, height, blockHash) + msg, err := datagen.NewMsgAddFinalitySig(signer, btcSK, 0, height, randListInfo, blockHash) require.NoError(b, err) ctx = ctx.WithHeaderInfo(header.Info{Height: int64(height), AppHash: blockHash}) diff --git a/x/finality/types/errors.go b/x/finality/types/errors.go index b39e4ff37..ee10b27fb 100644 --- a/x/finality/types/errors.go +++ b/x/finality/types/errors.go @@ -6,14 +6,15 @@ import ( // x/finality module sentinel errors var ( - ErrBlockNotFound = errorsmod.Register(ModuleName, 1100, "Block is not found") - ErrVoteNotFound = errorsmod.Register(ModuleName, 1101, "vote is not found") - ErrHeightTooHigh = errorsmod.Register(ModuleName, 1102, "the chain has not reached the given height yet") - ErrPubRandNotFound = errorsmod.Register(ModuleName, 1103, "public randomness is not found") - ErrNoPubRandYet = errorsmod.Register(ModuleName, 1104, "the finality provider has not committed any public randomness yet") - ErrTooFewPubRand = errorsmod.Register(ModuleName, 1105, "the request contains too few public randomness") - ErrInvalidPubRand = errorsmod.Register(ModuleName, 1106, "the public randomness list is invalid") - ErrEvidenceNotFound = errorsmod.Register(ModuleName, 1107, "evidence is not found") - ErrInvalidFinalitySig = errorsmod.Register(ModuleName, 1108, "finality signature is not valid") - ErrNoSlashableEvidence = errorsmod.Register(ModuleName, 1109, "there is no slashable evidence") + ErrBlockNotFound = errorsmod.Register(ModuleName, 1100, "Block is not found") + ErrVoteNotFound = errorsmod.Register(ModuleName, 1101, "vote is not found") + ErrHeightTooHigh = errorsmod.Register(ModuleName, 1102, "the chain has not reached the given height yet") + ErrPubRandNotFound = errorsmod.Register(ModuleName, 1103, "public randomness is not found") + ErrPubRandCommitNotFound = errorsmod.Register(ModuleName, 1104, "public randomness commitment is not found") + ErrNoPubRandYet = errorsmod.Register(ModuleName, 1105, "the finality provider has not committed any public randomness yet") + ErrTooFewPubRand = errorsmod.Register(ModuleName, 1106, "the request contains too few public randomness") + ErrInvalidPubRand = errorsmod.Register(ModuleName, 1107, "the public randomness list is invalid") + ErrEvidenceNotFound = errorsmod.Register(ModuleName, 1108, "evidence is not found") + ErrInvalidFinalitySig = errorsmod.Register(ModuleName, 1109, "finality signature is not valid") + ErrNoSlashableEvidence = errorsmod.Register(ModuleName, 1110, "there is no slashable evidence") ) diff --git a/x/finality/types/finality.go b/x/finality/types/finality.go index 5e1380d1d..9c40441a9 100644 --- a/x/finality/types/finality.go +++ b/x/finality/types/finality.go @@ -9,6 +9,36 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +func (c *PubRandCommit) IsInRange(height uint64) bool { + start, end := c.Range() + return start <= height && height <= end +} + +func (c *PubRandCommit) GetIndex(height uint64) (uint64, error) { + start, end := c.Range() + if start <= height && height <= end { + return height - start, nil + } + return 0, ErrPubRandNotFound.Wrapf("the given height (%d) is not in range [%d, %d]", height, start, end) +} + +func (c *PubRandCommit) EndHeight() uint64 { + return c.StartHeight + c.NumPubRand - 1 +} + +// Range() returns the range of the heights that a public randomness is committed +// both values are inclusive +func (c *PubRandCommit) Range() (uint64, uint64) { + return c.StartHeight, c.EndHeight() +} + +func (c *PubRandCommit) ToResponse() *PubRandCommitResponse { + return &PubRandCommitResponse{ + NumPubRand: c.NumPubRand, + Commitment: c.Commitment, + } +} + // msgToSignForVote returns the message for an EOTS signature // The EOTS signature on a block will be (blockHeight || blockHash) func msgToSignForVote(blockHeight uint64, blockHash []byte) []byte { diff --git a/x/finality/types/finality.pb.go b/x/finality/types/finality.pb.go index 7f1ebb971..952152352 100644 --- a/x/finality/types/finality.pb.go +++ b/x/finality/types/finality.pb.go @@ -89,6 +89,73 @@ func (m *IndexedBlock) GetFinalized() bool { return false } +// PubRandCommit is a commitment to a series of public randomness +// currently, the commitment is a root of a Merkle tree that includes +// a series of public randomness +type PubRandCommit struct { + // start_height is the height of the first commitment + StartHeight uint64 `protobuf:"varint,1,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + // num_pub_rand is the number of committed public randomness + NumPubRand uint64 `protobuf:"varint,2,opt,name=num_pub_rand,json=numPubRand,proto3" json:"num_pub_rand,omitempty"` + // commitment is the value of the commitment + // currently, it is the root of the merkle tree constructed by the public randomness + Commitment []byte `protobuf:"bytes,3,opt,name=commitment,proto3" json:"commitment,omitempty"` +} + +func (m *PubRandCommit) Reset() { *m = PubRandCommit{} } +func (m *PubRandCommit) String() string { return proto.CompactTextString(m) } +func (*PubRandCommit) ProtoMessage() {} +func (*PubRandCommit) Descriptor() ([]byte, []int) { + return fileDescriptor_ca5b87e52e3e6d02, []int{1} +} +func (m *PubRandCommit) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PubRandCommit) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PubRandCommit.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 *PubRandCommit) XXX_Merge(src proto.Message) { + xxx_messageInfo_PubRandCommit.Merge(m, src) +} +func (m *PubRandCommit) XXX_Size() int { + return m.Size() +} +func (m *PubRandCommit) XXX_DiscardUnknown() { + xxx_messageInfo_PubRandCommit.DiscardUnknown(m) +} + +var xxx_messageInfo_PubRandCommit proto.InternalMessageInfo + +func (m *PubRandCommit) GetStartHeight() uint64 { + if m != nil { + return m.StartHeight + } + return 0 +} + +func (m *PubRandCommit) GetNumPubRand() uint64 { + if m != nil { + return m.NumPubRand + } + return 0 +} + +func (m *PubRandCommit) GetCommitment() []byte { + if m != nil { + return m.Commitment + } + return nil +} + // Evidence is the evidence that a finality provider has signed finality // signatures with correct public randomness on two conflicting Babylon headers type Evidence struct { @@ -116,7 +183,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_ca5b87e52e3e6d02, []int{1} + return fileDescriptor_ca5b87e52e3e6d02, []int{2} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -168,6 +235,7 @@ func (m *Evidence) GetForkAppHash() []byte { func init() { proto.RegisterType((*IndexedBlock)(nil), "babylon.finality.v1.IndexedBlock") + proto.RegisterType((*PubRandCommit)(nil), "babylon.finality.v1.PubRandCommit") proto.RegisterType((*Evidence)(nil), "babylon.finality.v1.Evidence") } @@ -176,34 +244,37 @@ func init() { } var fileDescriptor_ca5b87e52e3e6d02 = []byte{ - // 424 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x92, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0x87, 0x9b, 0x6d, 0xb4, 0x9d, 0x17, 0x04, 0x98, 0x69, 0x2a, 0x08, 0x65, 0xa5, 0xa7, 0x1e, - 0x50, 0xb3, 0xb1, 0x09, 0x71, 0x25, 0xd2, 0xd0, 0x06, 0x07, 0x2a, 0x87, 0x13, 0x17, 0xcb, 0x76, - 0xdc, 0xd8, 0x6a, 0xb1, 0xad, 0xfc, 0xa9, 0x16, 0x3e, 0x05, 0x1f, 0x8b, 0xe3, 0x8e, 0x68, 0x87, - 0x0a, 0xb5, 0xdf, 0x03, 0xa1, 0x38, 0x69, 0x02, 0x27, 0x10, 0xbb, 0xbd, 0x7e, 0xfd, 0xd3, 0xfb, - 0x3c, 0x7a, 0x6d, 0x30, 0xa2, 0x84, 0x16, 0x0b, 0xad, 0xfc, 0x99, 0x54, 0x64, 0x21, 0xb3, 0xc2, - 0x5f, 0x9e, 0x36, 0xf5, 0xc4, 0x24, 0x3a, 0xd3, 0xf0, 0x71, 0x9d, 0x99, 0x34, 0xfd, 0xe5, 0xe9, - 0xd3, 0xc3, 0x58, 0xc7, 0xda, 0xde, 0xfb, 0x65, 0x55, 0x45, 0x47, 0x18, 0xb8, 0x57, 0x2a, 0xe2, - 0xd7, 0x3c, 0x0a, 0x16, 0x9a, 0xcd, 0xe1, 0x11, 0xe8, 0x0a, 0x2e, 0x63, 0x91, 0x0d, 0x9c, 0xa1, - 0x33, 0xde, 0x43, 0xf5, 0x09, 0x3e, 0x01, 0x7d, 0x62, 0x0c, 0x16, 0x24, 0x15, 0x83, 0x9d, 0xa1, - 0x33, 0x76, 0x51, 0x8f, 0x18, 0x73, 0x49, 0x52, 0x01, 0x9f, 0x81, 0xfd, 0x8a, 0xf3, 0x85, 0x47, - 0x83, 0xdd, 0xa1, 0x33, 0xee, 0xa3, 0xb6, 0x31, 0xfa, 0xb9, 0x0b, 0xfa, 0x17, 0x4b, 0x19, 0x71, - 0xc5, 0x38, 0x44, 0x60, 0x7f, 0x66, 0x30, 0xcd, 0x18, 0x36, 0x73, 0x0b, 0x70, 0x83, 0x57, 0xb7, - 0xab, 0xe3, 0x97, 0xb1, 0xcc, 0x44, 0x4e, 0x27, 0x4c, 0x7f, 0xf6, 0x6b, 0x75, 0x26, 0x88, 0x54, - 0xdb, 0x83, 0x9f, 0x15, 0x86, 0xa7, 0x93, 0xe0, 0x6a, 0x7a, 0x76, 0x7e, 0x32, 0xcd, 0xe9, 0x7b, - 0x5e, 0xa0, 0xde, 0xcc, 0x04, 0x19, 0x9b, 0xce, 0xe1, 0x73, 0xe0, 0xd2, 0x52, 0x1d, 0xd7, 0xde, - 0x3b, 0xd6, 0xfb, 0xc0, 0xf6, 0x2e, 0x2b, 0xf9, 0x10, 0xf4, 0x4d, 0x4e, 0x71, 0x42, 0x54, 0x25, - 0xe8, 0x06, 0xaf, 0x6f, 0x57, 0xc7, 0xe7, 0xff, 0x46, 0x0d, 0x99, 0x50, 0x3a, 0x49, 0xa6, 0x39, - 0x45, 0x44, 0x45, 0xa8, 0x67, 0xaa, 0x02, 0xbe, 0x00, 0x90, 0x11, 0xa5, 0x95, 0x64, 0x64, 0x81, - 0x9b, 0xdd, 0xec, 0xd9, 0xdd, 0x3c, 0x6c, 0x6e, 0xde, 0xd4, 0x4b, 0x1a, 0x81, 0xfb, 0x33, 0x9d, - 0xcc, 0xdb, 0xe0, 0x3d, 0x1b, 0x3c, 0x28, 0x9b, 0xdb, 0x8c, 0x02, 0x47, 0xed, 0xc4, 0xed, 0xd3, - 0xe1, 0x54, 0xc6, 0x83, 0xee, 0x7f, 0x4a, 0x5f, 0x7c, 0xf8, 0x18, 0x86, 0x32, 0x46, 0x87, 0xcd, - 0xdc, 0xb7, 0xf5, 0xd8, 0x50, 0xc6, 0x30, 0x02, 0x8f, 0xac, 0xd3, 0x1f, 0xa8, 0xde, 0x1d, 0x51, - 0x0f, 0xca, 0x91, 0xbf, 0x51, 0x82, 0x77, 0xdf, 0xd6, 0x9e, 0x73, 0xb3, 0xf6, 0x9c, 0x1f, 0x6b, - 0xcf, 0xf9, 0xba, 0xf1, 0x3a, 0x37, 0x1b, 0xaf, 0xf3, 0x7d, 0xe3, 0x75, 0x3e, 0x9d, 0xfc, 0x0d, - 0x70, 0xdd, 0x7e, 0x72, 0xcb, 0xa2, 0x5d, 0xfb, 0x69, 0xcf, 0x7e, 0x05, 0x00, 0x00, 0xff, 0xff, - 0xac, 0x30, 0x4b, 0x66, 0x05, 0x03, 0x00, 0x00, + // 474 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x93, 0x41, 0x6f, 0xd3, 0x30, + 0x14, 0xc7, 0x1b, 0x56, 0xda, 0xee, 0x35, 0x13, 0x10, 0xa6, 0xa9, 0x20, 0x94, 0x95, 0x9e, 0x7a, + 0x40, 0xcd, 0xc6, 0x26, 0xc4, 0x95, 0xa0, 0xa1, 0x0d, 0x0e, 0x54, 0x0e, 0x27, 0x2e, 0x91, 0xe3, + 0xb8, 0x89, 0xd5, 0xc6, 0xb6, 0x12, 0xa7, 0x5a, 0xf9, 0x14, 0x7c, 0x2c, 0x8e, 0x3b, 0xa2, 0x1d, + 0x26, 0xd4, 0x7e, 0x0f, 0x84, 0xe2, 0xba, 0xe9, 0x76, 0x02, 0xb1, 0x9b, 0xfd, 0xf7, 0xd3, 0xff, + 0xf7, 0xfe, 0xcf, 0x36, 0x0c, 0x22, 0x1c, 0x2d, 0x66, 0x82, 0x7b, 0x13, 0xc6, 0xf1, 0x8c, 0xa9, + 0x85, 0x37, 0x3f, 0xae, 0xd7, 0x23, 0x99, 0x0b, 0x25, 0x9c, 0xa7, 0xa6, 0x66, 0x54, 0xeb, 0xf3, + 0xe3, 0xe7, 0xfb, 0x89, 0x48, 0x84, 0x3e, 0xf7, 0xaa, 0xd5, 0xba, 0x74, 0x10, 0x82, 0x7d, 0xc1, + 0x63, 0x7a, 0x49, 0x63, 0x7f, 0x26, 0xc8, 0xd4, 0x39, 0x80, 0x56, 0x4a, 0x59, 0x92, 0xaa, 0x9e, + 0xd5, 0xb7, 0x86, 0x4d, 0x64, 0x76, 0xce, 0x33, 0xe8, 0x60, 0x29, 0xc3, 0x14, 0x17, 0x69, 0xef, + 0x41, 0xdf, 0x1a, 0xda, 0xa8, 0x8d, 0xa5, 0x3c, 0xc7, 0x45, 0xea, 0xbc, 0x80, 0xdd, 0x35, 0xe7, + 0x1b, 0x8d, 0x7b, 0x3b, 0x7d, 0x6b, 0xd8, 0x41, 0x5b, 0x61, 0xa0, 0x60, 0x6f, 0x5c, 0x46, 0x08, + 0xf3, 0xf8, 0xbd, 0xc8, 0x32, 0xa6, 0x9c, 0x97, 0x60, 0x17, 0x0a, 0xe7, 0x2a, 0xbc, 0xc3, 0xe9, + 0x6a, 0xed, 0x7c, 0x0d, 0xeb, 0x83, 0xcd, 0xcb, 0x2c, 0x94, 0x65, 0x14, 0xe6, 0x98, 0xc7, 0x1a, + 0xd8, 0x44, 0xc0, 0xcb, 0xcc, 0x58, 0x39, 0x2e, 0x00, 0xd1, 0x76, 0x19, 0xe5, 0x4a, 0x43, 0x6d, + 0x74, 0x4b, 0x19, 0xfc, 0xde, 0x81, 0xce, 0xd9, 0x9c, 0xc5, 0x94, 0x13, 0xea, 0x20, 0xd8, 0x9d, + 0xc8, 0x30, 0x52, 0x24, 0x94, 0x53, 0x8d, 0xb3, 0xfd, 0x37, 0xd7, 0x37, 0x87, 0xaf, 0x13, 0xa6, + 0xd2, 0x32, 0x1a, 0x11, 0x91, 0x79, 0x66, 0x60, 0x24, 0xc5, 0x8c, 0x6f, 0x36, 0x9e, 0x5a, 0x48, + 0x5a, 0x8c, 0xfc, 0x8b, 0xf1, 0xc9, 0xe9, 0xd1, 0xb8, 0x8c, 0x3e, 0xd1, 0x05, 0x6a, 0x4f, 0xa4, + 0xaf, 0xc8, 0x78, 0x5a, 0xa5, 0x88, 0xaa, 0x81, 0x6d, 0x52, 0xac, 0x5b, 0xec, 0x6a, 0xcd, 0xa4, + 0x08, 0xa0, 0x53, 0x27, 0xd0, 0x1d, 0xfa, 0x6f, 0xaf, 0x6f, 0x0e, 0x4f, 0xff, 0x8d, 0x1a, 0x90, + 0x94, 0x8b, 0x3c, 0x37, 0x79, 0x51, 0x5b, 0x9a, 0xe0, 0xaf, 0xc0, 0x21, 0x98, 0x0b, 0xce, 0x08, + 0x9e, 0x85, 0xf5, 0x8d, 0x34, 0xf5, 0x00, 0x1e, 0xd7, 0x27, 0xef, 0xcc, 0xd5, 0x0c, 0x60, 0x6f, + 0x22, 0xf2, 0xe9, 0xb6, 0xf0, 0xa1, 0x2e, 0xec, 0x56, 0xe2, 0xa6, 0x86, 0xc3, 0xc1, 0xd6, 0x71, + 0xf3, 0x60, 0xc2, 0x82, 0x25, 0xbd, 0xd6, 0x7f, 0x36, 0x7d, 0xf6, 0xf9, 0x4b, 0x10, 0xb0, 0x04, + 0xed, 0xd7, 0xbe, 0x1f, 0x8c, 0x6d, 0xc0, 0x12, 0x27, 0x86, 0x27, 0xba, 0xa7, 0x3b, 0xa8, 0xf6, + 0x3d, 0x51, 0x8f, 0x2a, 0xcb, 0x5b, 0x14, 0xff, 0xe3, 0x8f, 0xa5, 0x6b, 0x5d, 0x2d, 0x5d, 0xeb, + 0xd7, 0xd2, 0xb5, 0xbe, 0xaf, 0xdc, 0xc6, 0xd5, 0xca, 0x6d, 0xfc, 0x5c, 0xb9, 0x8d, 0xaf, 0x47, + 0x7f, 0x03, 0x5c, 0x6e, 0xbf, 0x96, 0x66, 0x45, 0x2d, 0xfd, 0x55, 0x4e, 0xfe, 0x04, 0x00, 0x00, + 0xff, 0xff, 0xab, 0xc1, 0xba, 0xbe, 0x7b, 0x03, 0x00, 0x00, } func (m *IndexedBlock) Marshal() (dAtA []byte, err error) { @@ -251,6 +322,46 @@ func (m *IndexedBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PubRandCommit) 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 *PubRandCommit) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PubRandCommit) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Commitment) > 0 { + i -= len(m.Commitment) + copy(dAtA[i:], m.Commitment) + i = encodeVarintFinality(dAtA, i, uint64(len(m.Commitment))) + i-- + dAtA[i] = 0x1a + } + if m.NumPubRand != 0 { + i = encodeVarintFinality(dAtA, i, uint64(m.NumPubRand)) + i-- + dAtA[i] = 0x10 + } + if m.StartHeight != 0 { + i = encodeVarintFinality(dAtA, i, uint64(m.StartHeight)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *Evidence) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -371,6 +482,25 @@ func (m *IndexedBlock) Size() (n int) { return n } +func (m *PubRandCommit) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.StartHeight != 0 { + n += 1 + sovFinality(uint64(m.StartHeight)) + } + if m.NumPubRand != 0 { + n += 1 + sovFinality(uint64(m.NumPubRand)) + } + l = len(m.Commitment) + if l > 0 { + n += 1 + l + sovFinality(uint64(l)) + } + return n +} + func (m *Evidence) Size() (n int) { if m == nil { return 0 @@ -536,6 +666,128 @@ func (m *IndexedBlock) Unmarshal(dAtA []byte) error { } return nil } +func (m *PubRandCommit) 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 ErrIntOverflowFinality + } + 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: PubRandCommit: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubRandCommit: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) + } + m.StartHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartHeight |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumPubRand", wireType) + } + m.NumPubRand = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumPubRand |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commitment", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthFinality + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthFinality + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Commitment = append(m.Commitment[:0], dAtA[iNdEx:postIndex]...) + if m.Commitment == nil { + m.Commitment = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipFinality(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFinality + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Evidence) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 304c7855c..7663e230b 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -36,6 +36,8 @@ type GenesisState struct { VoteSigs []*VoteSig `protobuf:"bytes,4,rep,name=vote_sigs,json=voteSigs,proto3" json:"vote_sigs,omitempty"` // public_randomness contains all the public randomness ever commited from the finality providers. PublicRandomness []*PublicRandomness `protobuf:"bytes,5,rep,name=public_randomness,json=publicRandomness,proto3" json:"public_randomness,omitempty"` + // pub_rand_commit contains all the public randomness commitment ever commited from the finality providers. + PubRandCommit []*PubRandCommitWithPK `protobuf:"bytes,6,rep,name=pub_rand_commit,json=pubRandCommit,proto3" json:"pub_rand_commit,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -106,6 +108,13 @@ func (m *GenesisState) GetPublicRandomness() []*PublicRandomness { return nil } +func (m *GenesisState) GetPubRandCommit() []*PubRandCommitWithPK { + if m != nil { + return m.PubRandCommit + } + return nil +} + // VoteSig the vote of an finality provider // with the block of the vote, the finality provider btc public key and the vote signature. type VoteSig struct { @@ -208,47 +217,99 @@ func (m *PublicRandomness) GetBlockHeight() uint64 { return 0 } +// PubRandCommitWithPK is the public randomness commitment with the finality provider's BTC public key +type PubRandCommitWithPK struct { + // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // pub_rand_commit is the public randomness commitment + PubRandCommit *PubRandCommit `protobuf:"bytes,2,opt,name=pub_rand_commit,json=pubRandCommit,proto3" json:"pub_rand_commit,omitempty"` +} + +func (m *PubRandCommitWithPK) Reset() { *m = PubRandCommitWithPK{} } +func (m *PubRandCommitWithPK) String() string { return proto.CompactTextString(m) } +func (*PubRandCommitWithPK) ProtoMessage() {} +func (*PubRandCommitWithPK) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{3} +} +func (m *PubRandCommitWithPK) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PubRandCommitWithPK) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PubRandCommitWithPK.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 *PubRandCommitWithPK) XXX_Merge(src proto.Message) { + xxx_messageInfo_PubRandCommitWithPK.Merge(m, src) +} +func (m *PubRandCommitWithPK) XXX_Size() int { + return m.Size() +} +func (m *PubRandCommitWithPK) XXX_DiscardUnknown() { + xxx_messageInfo_PubRandCommitWithPK.DiscardUnknown(m) +} + +var xxx_messageInfo_PubRandCommitWithPK proto.InternalMessageInfo + +func (m *PubRandCommitWithPK) GetPubRandCommit() *PubRandCommit { + if m != nil { + return m.PubRandCommit + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "babylon.finality.v1.GenesisState") proto.RegisterType((*VoteSig)(nil), "babylon.finality.v1.VoteSig") proto.RegisterType((*PublicRandomness)(nil), "babylon.finality.v1.PublicRandomness") + proto.RegisterType((*PubRandCommitWithPK)(nil), "babylon.finality.v1.PubRandCommitWithPK") } func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 483 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x93, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0x87, 0x9b, 0xb6, 0xac, 0xab, 0x5b, 0xd0, 0x08, 0x1c, 0xa2, 0x02, 0xe9, 0x1f, 0x09, 0xa9, - 0xa7, 0x64, 0xeb, 0x26, 0xc4, 0xc4, 0x2d, 0xd2, 0xc4, 0x06, 0x07, 0x22, 0x07, 0x71, 0x80, 0x43, - 0x14, 0xa7, 0x6e, 0x62, 0xb5, 0xb5, 0xad, 0xd8, 0x89, 0xd6, 0x6f, 0xc1, 0xc7, 0xda, 0x71, 0x47, - 0x34, 0x89, 0x82, 0xda, 0x2f, 0x82, 0xe2, 0xa4, 0x1b, 0x9a, 0x22, 0x81, 0xb8, 0x70, 0xb3, 0x9d, - 0xe7, 0x7d, 0xfc, 0xbe, 0xbf, 0xc8, 0x60, 0x88, 0x02, 0xb4, 0x5a, 0x30, 0x6a, 0xcf, 0x08, 0x0d, - 0x16, 0x44, 0xae, 0xec, 0xec, 0xc8, 0x8e, 0x30, 0xc5, 0x82, 0x08, 0x8b, 0x27, 0x4c, 0x32, 0xfd, - 0x49, 0x89, 0x58, 0x3b, 0xc4, 0xca, 0x8e, 0x7a, 0x4f, 0x23, 0x16, 0x31, 0xf5, 0xdd, 0xce, 0x57, - 0x05, 0xda, 0x1b, 0x54, 0xd9, 0x78, 0x90, 0x04, 0xcb, 0x52, 0xd6, 0x1b, 0x55, 0x11, 0xb7, 0x62, - 0xc5, 0x8c, 0x7e, 0xd4, 0x41, 0xf7, 0x6d, 0xd1, 0x82, 0x27, 0x03, 0x89, 0xf5, 0x53, 0xb0, 0x57, - 0x48, 0x0c, 0x6d, 0xa0, 0x8d, 0x3b, 0x93, 0x67, 0x56, 0x45, 0x4b, 0x96, 0xab, 0x10, 0xa7, 0x79, - 0xb5, 0xee, 0xd7, 0x60, 0x59, 0xa0, 0x9f, 0x83, 0x47, 0x84, 0x4e, 0xf1, 0x25, 0x9e, 0xfa, 0x68, - 0xc1, 0xc2, 0xb9, 0x30, 0xea, 0x83, 0xc6, 0xb8, 0x33, 0x19, 0x56, 0x2a, 0x2e, 0x0a, 0xd4, 0xc9, - 0x49, 0xf8, 0x90, 0xfc, 0xb6, 0x13, 0xfa, 0x1b, 0xd0, 0xc6, 0x19, 0x99, 0x62, 0x1a, 0x62, 0x61, - 0x34, 0x94, 0xe4, 0x45, 0xa5, 0xe4, 0xac, 0xa4, 0xe0, 0x1d, 0xaf, 0x9f, 0x82, 0x76, 0xc6, 0x24, - 0xf6, 0x05, 0x89, 0x84, 0xd1, 0x54, 0xc5, 0xcf, 0x2b, 0x8b, 0x3f, 0x31, 0x89, 0x3d, 0x12, 0xc1, - 0xfd, 0xac, 0x58, 0x08, 0x1d, 0x82, 0xc7, 0x3c, 0x45, 0x0b, 0x12, 0xfa, 0x49, 0x40, 0xa7, 0x6c, - 0x49, 0xb1, 0x10, 0xc6, 0x03, 0xa5, 0x78, 0x59, 0x9d, 0x83, 0xa2, 0xe1, 0x2d, 0x0c, 0x0f, 0xf8, - 0xbd, 0x93, 0xd1, 0x77, 0x0d, 0xb4, 0xca, 0x9b, 0xf4, 0x21, 0xe8, 0xaa, 0x64, 0xfc, 0x18, 0x93, - 0x28, 0x96, 0x2a, 0xe2, 0x26, 0xec, 0xa8, 0xb3, 0x73, 0x75, 0xa4, 0x43, 0xd0, 0x9e, 0x71, 0x1f, - 0xc9, 0xd0, 0xe7, 0x73, 0xa3, 0x3e, 0xd0, 0xc6, 0x5d, 0xe7, 0xd5, 0xcd, 0xba, 0x3f, 0x89, 0x88, - 0x8c, 0x53, 0x64, 0x85, 0x6c, 0x69, 0x97, 0x8d, 0x84, 0x71, 0x40, 0xe8, 0x6e, 0x63, 0xcb, 0x15, - 0xc7, 0xc2, 0x72, 0x2e, 0xdc, 0xe3, 0x93, 0x43, 0x37, 0x45, 0xef, 0xf1, 0x0a, 0xb6, 0x66, 0xdc, - 0x91, 0xa1, 0x3b, 0xd7, 0xbf, 0x80, 0xee, 0xae, 0xe9, 0x3c, 0x15, 0xa3, 0xa1, 0xb4, 0xaf, 0x6f, - 0xd6, 0xfd, 0x93, 0xbf, 0xd3, 0x7a, 0x61, 0x4c, 0x59, 0x92, 0x9c, 0x7d, 0xf8, 0xe8, 0xe5, 0x81, - 0x75, 0x76, 0x36, 0x8f, 0x44, 0xa3, 0xb5, 0x06, 0x0e, 0xee, 0xc7, 0xf0, 0xbf, 0x06, 0xf5, 0xc0, - 0x3e, 0x4f, 0x91, 0xfa, 0x79, 0xff, 0x3c, 0xa4, 0x9b, 0xa2, 0x7c, 0x10, 0xd8, 0xe2, 0xc5, 0xc2, - 0x79, 0x77, 0xb5, 0x31, 0xb5, 0xeb, 0x8d, 0xa9, 0xfd, 0xdc, 0x98, 0xda, 0xd7, 0xad, 0x59, 0xbb, - 0xde, 0x9a, 0xb5, 0x6f, 0x5b, 0xb3, 0xf6, 0xf9, 0xf0, 0x4f, 0xe2, 0xcb, 0xbb, 0xa7, 0xa7, 0xee, - 0x40, 0x7b, 0xea, 0xd5, 0x1d, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x48, 0x67, 0xec, 0x5e, 0x0b, - 0x04, 0x00, 0x00, + // 544 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x94, 0x4d, 0x6f, 0xd3, 0x30, + 0x18, 0xc7, 0xeb, 0xb5, 0xb4, 0xab, 0xdb, 0xc1, 0xf0, 0x38, 0x44, 0x05, 0xd2, 0x36, 0x12, 0x52, + 0x4f, 0xc9, 0xd6, 0x4d, 0x88, 0x89, 0x5b, 0xd0, 0xc4, 0x5e, 0x0e, 0x44, 0x0e, 0x02, 0x09, 0x0e, + 0x51, 0x92, 0xba, 0x89, 0xd5, 0x36, 0xb6, 0x6a, 0xb7, 0x5a, 0xbf, 0x05, 0x5f, 0x85, 0x03, 0xdf, + 0x61, 0xc7, 0x1d, 0xd1, 0x24, 0x2a, 0xd4, 0x7e, 0x11, 0x54, 0x37, 0xdd, 0x46, 0x09, 0x1a, 0x42, + 0x48, 0xdc, 0xec, 0x27, 0xff, 0xe7, 0xa7, 0xff, 0xf3, 0x12, 0xc3, 0x66, 0xe0, 0x07, 0x93, 0x3e, + 0x4b, 0xac, 0x2e, 0x4d, 0xfc, 0x3e, 0x95, 0x13, 0x6b, 0xbc, 0x67, 0x45, 0x24, 0x21, 0x82, 0x0a, + 0x93, 0x0f, 0x99, 0x64, 0x68, 0x27, 0x95, 0x98, 0x2b, 0x89, 0x39, 0xde, 0xab, 0x3d, 0x8a, 0x58, + 0xc4, 0xd4, 0x77, 0x6b, 0x71, 0x5a, 0x4a, 0x6b, 0x8d, 0x2c, 0x1a, 0xf7, 0x87, 0xfe, 0x20, 0x85, + 0xd5, 0x8c, 0x2c, 0xc5, 0x35, 0x58, 0x69, 0x8c, 0xcf, 0x79, 0x58, 0x7d, 0xbd, 0xb4, 0xe0, 0x4a, + 0x5f, 0x12, 0x74, 0x08, 0x8b, 0x4b, 0x88, 0x06, 0x1a, 0xa0, 0x55, 0x69, 0x3f, 0x36, 0x33, 0x2c, + 0x99, 0x8e, 0x92, 0xd8, 0x85, 0x8b, 0x69, 0x3d, 0x87, 0xd3, 0x04, 0x74, 0x0c, 0xef, 0xd3, 0xa4, + 0x43, 0xce, 0x49, 0xc7, 0x0b, 0xfa, 0x2c, 0xec, 0x09, 0x6d, 0xa3, 0x91, 0x6f, 0x55, 0xda, 0xcd, + 0x4c, 0xc4, 0xc9, 0x52, 0x6a, 0x2f, 0x94, 0x78, 0x8b, 0xde, 0xba, 0x09, 0xf4, 0x12, 0x96, 0xc9, + 0x98, 0x76, 0x48, 0x12, 0x12, 0xa1, 0xe5, 0x15, 0xe4, 0x69, 0x26, 0xe4, 0x28, 0x55, 0xe1, 0x1b, + 0x3d, 0x3a, 0x84, 0xe5, 0x31, 0x93, 0xc4, 0x13, 0x34, 0x12, 0x5a, 0x41, 0x25, 0x3f, 0xc9, 0x4c, + 0x7e, 0xc7, 0x24, 0x71, 0x69, 0x84, 0x37, 0xc7, 0xcb, 0x83, 0x40, 0x18, 0x3e, 0xe4, 0xa3, 0xa0, + 0x4f, 0x43, 0x6f, 0xe8, 0x27, 0x1d, 0x36, 0x48, 0x88, 0x10, 0xda, 0x3d, 0x85, 0x78, 0x96, 0xdd, + 0x07, 0xa5, 0xc6, 0xd7, 0x62, 0xbc, 0xcd, 0xd7, 0x22, 0xc8, 0x81, 0x0f, 0xf8, 0x28, 0x50, 0x40, + 0x2f, 0x64, 0x83, 0x01, 0x95, 0x5a, 0x51, 0x11, 0x5b, 0xbf, 0x23, 0x2e, 0x92, 0x5f, 0x29, 0xe5, + 0x7b, 0x2a, 0x63, 0xe7, 0x0c, 0x6f, 0xf1, 0xdb, 0x41, 0xe3, 0x1b, 0x80, 0xa5, 0xd4, 0x3b, 0x6a, + 0xc2, 0xaa, 0xea, 0xb5, 0x17, 0x13, 0x1a, 0xc5, 0x52, 0x0d, 0xad, 0x80, 0x2b, 0x2a, 0x76, 0xac, + 0x42, 0x08, 0xc3, 0x72, 0x97, 0x7b, 0x81, 0x0c, 0x3d, 0xde, 0xd3, 0x36, 0x1a, 0xa0, 0x55, 0xb5, + 0x9f, 0x5f, 0x4d, 0xeb, 0xed, 0x88, 0xca, 0x78, 0x14, 0x98, 0x21, 0x1b, 0x58, 0xa9, 0x91, 0x30, + 0xf6, 0x69, 0xb2, 0xba, 0x58, 0x72, 0xc2, 0x89, 0x30, 0xed, 0x13, 0x67, 0xff, 0x60, 0xd7, 0x19, + 0x05, 0x67, 0x64, 0x82, 0x4b, 0x5d, 0x6e, 0xcb, 0xd0, 0xe9, 0xa1, 0x8f, 0xb0, 0xba, 0x32, 0xbd, + 0xe8, 0xb3, 0x96, 0x57, 0xd8, 0x17, 0x57, 0xd3, 0xfa, 0xc1, 0x9f, 0x61, 0xdd, 0x30, 0x4e, 0xd8, + 0x70, 0x78, 0xf4, 0xe6, 0xad, 0xbb, 0x18, 0x41, 0x65, 0x45, 0x73, 0x69, 0x64, 0x4c, 0x01, 0xdc, + 0x5e, 0x6f, 0xec, 0xff, 0x2a, 0xd4, 0x85, 0x9b, 0xab, 0xe9, 0xfd, 0x75, 0x91, 0xe9, 0x48, 0x71, + 0x29, 0x1d, 0xa3, 0xf1, 0x05, 0xc0, 0x9d, 0x8c, 0x39, 0xff, 0x5c, 0x00, 0xf8, 0x37, 0x05, 0x9c, + 0xfe, 0xba, 0x7e, 0x1b, 0xea, 0xc7, 0x36, 0xee, 0x5e, 0xbf, 0xb5, 0xc5, 0xb3, 0x4f, 0x2f, 0x66, + 0x3a, 0xb8, 0x9c, 0xe9, 0xe0, 0xfb, 0x4c, 0x07, 0x9f, 0xe6, 0x7a, 0xee, 0x72, 0xae, 0xe7, 0xbe, + 0xce, 0xf5, 0xdc, 0x87, 0xdd, 0xbb, 0x2c, 0x9e, 0xdf, 0x3c, 0x42, 0xca, 0x6d, 0x50, 0x54, 0xef, + 0xcf, 0xfe, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x48, 0xf9, 0xea, 0x15, 0x05, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -271,6 +332,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.PubRandCommit) > 0 { + for iNdEx := len(m.PubRandCommit) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PubRandCommit[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } if len(m.PublicRandomness) > 0 { for iNdEx := len(m.PublicRandomness) - 1; iNdEx >= 0; iNdEx-- { { @@ -444,6 +519,53 @@ func (m *PublicRandomness) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PubRandCommitWithPK) 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 *PubRandCommitWithPK) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PubRandCommitWithPK) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PubRandCommit != nil { + { + size, err := m.PubRandCommit.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -487,6 +609,12 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.PubRandCommit) > 0 { + for _, e := range m.PubRandCommit { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -530,6 +658,23 @@ func (m *PublicRandomness) Size() (n int) { return n } +func (m *PubRandCommitWithPK) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if m.PubRandCommit != nil { + l = m.PubRandCommit.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + func sovGenesis(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -734,6 +879,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRandCommit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PubRandCommit = append(m.PubRandCommit, &PubRandCommitWithPK{}) + if err := m.PubRandCommit[len(m.PubRandCommit)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -1033,6 +1212,127 @@ func (m *PublicRandomness) Unmarshal(dAtA []byte) error { } return nil } +func (m *PubRandCommitWithPK) 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 ErrIntOverflowGenesis + } + 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: PubRandCommitWithPK: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubRandCommitWithPK: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRandCommit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PubRandCommit == nil { + m.PubRandCommit = &PubRandCommit{} + } + if err := m.PubRandCommit.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 4e596001b..4198e6134 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -18,7 +18,8 @@ var ( BlockKey = []byte{0x01} // key prefix for blocks VoteKey = []byte{0x02} // key prefix for votes PubRandKey = []byte{0x03} // key prefix for public randomness - ParamsKey = []byte{0x04} // key prefix for the parameters - EvidenceKey = []byte{0x05} // key prefix for evidences - NextHeightToFinalizeKey = []byte{0x06} // key prefix for next height to finalise + PubRandCommitKey = []byte{0x04} // key prefix for commitment of public randomness + ParamsKey = []byte{0x05} // key prefix for the parameters + EvidenceKey = []byte{0x06} // key prefix for evidences + NextHeightToFinalizeKey = []byte{0x07} // key prefix for next height to finalise ) diff --git a/x/finality/types/msg.go b/x/finality/types/msg.go index ab86316a1..7a1757f27 100644 --- a/x/finality/types/msg.go +++ b/x/finality/types/msg.go @@ -4,8 +4,7 @@ import ( fmt "fmt" "github.com/babylonchain/babylon/crypto/eots" - bbn "github.com/babylonchain/babylon/types" - "github.com/btcsuite/btcd/btcec/v2" + "github.com/cometbft/cometbft/crypto/merkle" "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -17,48 +16,54 @@ var ( _ sdk.Msg = &MsgCommitPubRandList{} ) -func NewMsgAddFinalitySig(signer string, sk *btcec.PrivateKey, sr *eots.PrivateRand, blockHeight uint64, blockHash []byte) (*MsgAddFinalitySig, error) { - msg := &MsgAddFinalitySig{ - Signer: signer, - FpBtcPk: bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()), - BlockHeight: blockHeight, - BlockAppHash: blockHash, - } - msgToSign := msg.MsgToSign() - sig, err := eots.Sign(sk, sr, msgToSign) - if err != nil { - return nil, err - } - msg.FinalitySig = bbn.NewSchnorrEOTSSigFromModNScalar(sig) - - return msg, nil -} - func (m *MsgAddFinalitySig) MsgToSign() []byte { return msgToSignForVote(m.BlockHeight, m.BlockAppHash) } -func (m *MsgAddFinalitySig) VerifyEOTSSig(pubRand *bbn.SchnorrPubRand) error { +// VerifyFinalitySig verifies the finality signature message w.r.t. the +// public randomness commitment. The verification includes +// - verifying the proof of inclusion of the given public randomness +// - verifying the finality signature w.r.t. the given block height/hash +func VerifyFinalitySig(m *MsgAddFinalitySig, prCommit *PubRandCommit) error { + // verify the index of the public randomness + heightOfProof := prCommit.StartHeight + uint64(m.Proof.Index) + if m.BlockHeight != heightOfProof { + return ErrInvalidFinalitySig.Wrapf("the inclusion proof (for height %d) does not correspond to the given height (%d) in the message", heightOfProof, m.BlockHeight) + } + // verify the total number of randomness is same as in the commit + if uint64(m.Proof.Total) != prCommit.NumPubRand { + return ErrInvalidFinalitySig.Wrapf("the total number of public randomnesses in the proof (%d) does not match the number of public randomnesses committed (%d)", m.Proof.Total, prCommit.NumPubRand) + } + // verify the proof of inclusion for this public randomness + unwrappedProof, err := merkle.ProofFromProto(m.Proof) + if err != nil { + return ErrInvalidFinalitySig.Wrapf("failed to unwrap proof: %v", err) + } + if err := unwrappedProof.Verify(prCommit.Commitment, *m.PubRand); err != nil { + return ErrInvalidFinalitySig.Wrapf("the inclusion proof of the public randomness is invalid: %v", err) + } + + // public randomness is good, verify finality signature msgToSign := m.MsgToSign() pk, err := m.FpBtcPk.ToBTCPK() if err != nil { return err } - - return eots.Verify(pk, pubRand.ToFieldVal(), msgToSign, m.FinalitySig.ToModNScalar()) + return eots.Verify(pk, m.PubRand.ToFieldVal(), msgToSign, m.FinalitySig.ToModNScalar()) } -// HashToSign returns a 32-byte hash of (start_height || pub_rand_list) +// HashToSign returns a 32-byte hash of (start_height || num_pub_rand || commitment) // The signature in MsgCommitPubRandList will be on this hash func (m *MsgCommitPubRandList) HashToSign() ([]byte, error) { hasher := tmhash.New() if _, err := hasher.Write(sdk.Uint64ToBigEndian(m.StartHeight)); err != nil { return nil, err } - for _, pr := range m.PubRandList { - if _, err := hasher.Write(pr.MustMarshal()); err != nil { - return nil, err - } + if _, err := hasher.Write(sdk.Uint64ToBigEndian(m.NumPubRand)); err != nil { + return nil, err + } + if _, err := hasher.Write(m.Commitment); err != nil { + return nil, err } return hasher.Sum(nil), nil } diff --git a/x/finality/types/msg_test.go b/x/finality/types/msg_test.go index 9dafd9d14..1ea69b6fa 100644 --- a/x/finality/types/msg_test.go +++ b/x/finality/types/msg_test.go @@ -6,7 +6,6 @@ import ( "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" "github.com/stretchr/testify/require" ) @@ -19,17 +18,27 @@ func FuzzMsgAddFinalitySig(f *testing.F) { sk, err := eots.KeyGen(r) require.NoError(t, err) - sr, pr, err := eots.RandGen(r) + + numPubRand := uint64(100) + randListInfo, err := datagen.GenRandomPubRandList(r, numPubRand) require.NoError(t, err) - blockHeight := datagen.RandomInt(r, 10) + + startHeight := datagen.RandomInt(r, 10) + blockHeight := startHeight + datagen.RandomInt(r, 10) blockHash := datagen.GenRandomByteArray(r, 32) signer := datagen.GenRandomAccount().Address - msg, err := types.NewMsgAddFinalitySig(signer, sk, sr, blockHeight, blockHash) + msg, err := datagen.NewMsgAddFinalitySig(signer, sk, startHeight, blockHeight, randListInfo, blockHash) require.NoError(t, err) - // verify msg's EOTS sig against the given public randomness - err = msg.VerifyEOTSSig(bbn.NewSchnorrPubRandFromFieldVal(pr)) + prCommit := &types.PubRandCommit{ + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: randListInfo.Commitment, + } + + // verify the finality signature message + err = types.VerifyFinalitySig(msg, prCommit) require.NoError(t, err) }) } diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index a4b12e2ea..21f8290a8 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -252,6 +252,174 @@ func (m *QueryListPublicRandomnessResponse) GetPagination() *query.PageResponse return nil } +// PubRandCommitResponse is the response type for a public randomness commitment +type PubRandCommitResponse struct { + // num_pub_rand is the number of committed public randomness + NumPubRand uint64 `protobuf:"varint,1,opt,name=num_pub_rand,json=numPubRand,proto3" json:"num_pub_rand,omitempty"` + // commitment is the value of the commitment + Commitment []byte `protobuf:"bytes,2,opt,name=commitment,proto3" json:"commitment,omitempty"` +} + +func (m *PubRandCommitResponse) Reset() { *m = PubRandCommitResponse{} } +func (m *PubRandCommitResponse) String() string { return proto.CompactTextString(m) } +func (*PubRandCommitResponse) ProtoMessage() {} +func (*PubRandCommitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{4} +} +func (m *PubRandCommitResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PubRandCommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PubRandCommitResponse.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 *PubRandCommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_PubRandCommitResponse.Merge(m, src) +} +func (m *PubRandCommitResponse) XXX_Size() int { + return m.Size() +} +func (m *PubRandCommitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_PubRandCommitResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_PubRandCommitResponse proto.InternalMessageInfo + +func (m *PubRandCommitResponse) GetNumPubRand() uint64 { + if m != nil { + return m.NumPubRand + } + return 0 +} + +func (m *PubRandCommitResponse) GetCommitment() []byte { + if m != nil { + return m.Commitment + } + return nil +} + +// QueryListPubRandCommitRequest is the request type for the +// Query/ListPubRandCommit RPC method. +type QueryListPubRandCommitRequest struct { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK of the finality provider + FpBtcPkHex string `protobuf:"bytes,1,opt,name=fp_btc_pk_hex,json=fpBtcPkHex,proto3" json:"fp_btc_pk_hex,omitempty"` + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryListPubRandCommitRequest) Reset() { *m = QueryListPubRandCommitRequest{} } +func (m *QueryListPubRandCommitRequest) String() string { return proto.CompactTextString(m) } +func (*QueryListPubRandCommitRequest) ProtoMessage() {} +func (*QueryListPubRandCommitRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{5} +} +func (m *QueryListPubRandCommitRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryListPubRandCommitRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryListPubRandCommitRequest.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 *QueryListPubRandCommitRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryListPubRandCommitRequest.Merge(m, src) +} +func (m *QueryListPubRandCommitRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryListPubRandCommitRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryListPubRandCommitRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryListPubRandCommitRequest proto.InternalMessageInfo + +func (m *QueryListPubRandCommitRequest) GetFpBtcPkHex() string { + if m != nil { + return m.FpBtcPkHex + } + return "" +} + +func (m *QueryListPubRandCommitRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryListPubRandCommitResponse is the response type for the +// Query/ListPubRandCommit RPC method. +type QueryListPubRandCommitResponse struct { + // pub_rand_commit_map is the map where the key is the start height and the value + // is the public randomness commitment at this height for the given finality provider + PubRandCommitMap map[uint64]*PubRandCommitResponse `protobuf:"bytes,1,rep,name=pub_rand_commit_map,json=pubRandCommitMap,proto3" json:"pub_rand_commit_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryListPubRandCommitResponse) Reset() { *m = QueryListPubRandCommitResponse{} } +func (m *QueryListPubRandCommitResponse) String() string { return proto.CompactTextString(m) } +func (*QueryListPubRandCommitResponse) ProtoMessage() {} +func (*QueryListPubRandCommitResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{6} +} +func (m *QueryListPubRandCommitResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryListPubRandCommitResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryListPubRandCommitResponse.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 *QueryListPubRandCommitResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryListPubRandCommitResponse.Merge(m, src) +} +func (m *QueryListPubRandCommitResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryListPubRandCommitResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryListPubRandCommitResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryListPubRandCommitResponse proto.InternalMessageInfo + +func (m *QueryListPubRandCommitResponse) GetPubRandCommitMap() map[uint64]*PubRandCommitResponse { + if m != nil { + return m.PubRandCommitMap + } + return nil +} + +func (m *QueryListPubRandCommitResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + // QueryBlockRequest is the request type for the // Query/Block RPC method. type QueryBlockRequest struct { @@ -263,7 +431,7 @@ func (m *QueryBlockRequest) Reset() { *m = QueryBlockRequest{} } func (m *QueryBlockRequest) String() string { return proto.CompactTextString(m) } func (*QueryBlockRequest) ProtoMessage() {} func (*QueryBlockRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{4} + return fileDescriptor_32bddab77af6fdae, []int{7} } func (m *QueryBlockRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -310,7 +478,7 @@ func (m *QueryBlockResponse) Reset() { *m = QueryBlockResponse{} } func (m *QueryBlockResponse) String() string { return proto.CompactTextString(m) } func (*QueryBlockResponse) ProtoMessage() {} func (*QueryBlockResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{5} + return fileDescriptor_32bddab77af6fdae, []int{8} } func (m *QueryBlockResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -359,7 +527,7 @@ func (m *QueryListBlocksRequest) Reset() { *m = QueryListBlocksRequest{} func (m *QueryListBlocksRequest) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksRequest) ProtoMessage() {} func (*QueryListBlocksRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{6} + return fileDescriptor_32bddab77af6fdae, []int{9} } func (m *QueryListBlocksRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -415,7 +583,7 @@ func (m *QueryListBlocksResponse) Reset() { *m = QueryListBlocksResponse func (m *QueryListBlocksResponse) String() string { return proto.CompactTextString(m) } func (*QueryListBlocksResponse) ProtoMessage() {} func (*QueryListBlocksResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{7} + return fileDescriptor_32bddab77af6fdae, []int{10} } func (m *QueryListBlocksResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -469,7 +637,7 @@ func (m *QueryVotesAtHeightRequest) Reset() { *m = QueryVotesAtHeightReq func (m *QueryVotesAtHeightRequest) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightRequest) ProtoMessage() {} func (*QueryVotesAtHeightRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{8} + return fileDescriptor_32bddab77af6fdae, []int{11} } func (m *QueryVotesAtHeightRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -517,7 +685,7 @@ func (m *QueryVotesAtHeightResponse) Reset() { *m = QueryVotesAtHeightRe func (m *QueryVotesAtHeightResponse) String() string { return proto.CompactTextString(m) } func (*QueryVotesAtHeightResponse) ProtoMessage() {} func (*QueryVotesAtHeightResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{9} + return fileDescriptor_32bddab77af6fdae, []int{12} } func (m *QueryVotesAtHeightResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -558,7 +726,7 @@ func (m *QueryEvidenceRequest) Reset() { *m = QueryEvidenceRequest{} } func (m *QueryEvidenceRequest) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceRequest) ProtoMessage() {} func (*QueryEvidenceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{10} + return fileDescriptor_32bddab77af6fdae, []int{13} } func (m *QueryEvidenceRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -604,7 +772,7 @@ func (m *QueryEvidenceResponse) Reset() { *m = QueryEvidenceResponse{} } func (m *QueryEvidenceResponse) String() string { return proto.CompactTextString(m) } func (*QueryEvidenceResponse) ProtoMessage() {} func (*QueryEvidenceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{11} + return fileDescriptor_32bddab77af6fdae, []int{14} } func (m *QueryEvidenceResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -654,7 +822,7 @@ func (m *QueryListEvidencesRequest) Reset() { *m = QueryListEvidencesReq func (m *QueryListEvidencesRequest) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesRequest) ProtoMessage() {} func (*QueryListEvidencesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{12} + return fileDescriptor_32bddab77af6fdae, []int{15} } func (m *QueryListEvidencesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -710,7 +878,7 @@ func (m *QueryListEvidencesResponse) Reset() { *m = QueryListEvidencesRe func (m *QueryListEvidencesResponse) String() string { return proto.CompactTextString(m) } func (*QueryListEvidencesResponse) ProtoMessage() {} func (*QueryListEvidencesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_32bddab77af6fdae, []int{13} + return fileDescriptor_32bddab77af6fdae, []int{16} } func (m *QueryListEvidencesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -760,6 +928,10 @@ func init() { proto.RegisterType((*QueryListPublicRandomnessRequest)(nil), "babylon.finality.v1.QueryListPublicRandomnessRequest") proto.RegisterType((*QueryListPublicRandomnessResponse)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse") proto.RegisterMapType((map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse.PubRandMapEntry") + proto.RegisterType((*PubRandCommitResponse)(nil), "babylon.finality.v1.PubRandCommitResponse") + proto.RegisterType((*QueryListPubRandCommitRequest)(nil), "babylon.finality.v1.QueryListPubRandCommitRequest") + proto.RegisterType((*QueryListPubRandCommitResponse)(nil), "babylon.finality.v1.QueryListPubRandCommitResponse") + proto.RegisterMapType((map[uint64]*PubRandCommitResponse)(nil), "babylon.finality.v1.QueryListPubRandCommitResponse.PubRandCommitMapEntry") proto.RegisterType((*QueryBlockRequest)(nil), "babylon.finality.v1.QueryBlockRequest") proto.RegisterType((*QueryBlockResponse)(nil), "babylon.finality.v1.QueryBlockResponse") proto.RegisterType((*QueryListBlocksRequest)(nil), "babylon.finality.v1.QueryListBlocksRequest") @@ -775,72 +947,81 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 1028 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0x38, 0x8d, 0x9b, 0xbc, 0xc4, 0x90, 0x4e, 0x4d, 0x09, 0x2e, 0x75, 0x9c, 0x2d, 0x24, - 0x21, 0xa9, 0x76, 0x1b, 0xa7, 0x94, 0x16, 0x84, 0x4a, 0x2c, 0x12, 0x12, 0x68, 0x5d, 0xb3, 0x95, - 0x2a, 0xd1, 0x8b, 0x35, 0x6b, 0x4f, 0xec, 0x55, 0xec, 0x9d, 0xed, 0xee, 0xac, 0x15, 0xab, 0xaa, - 0x84, 0x38, 0xf4, 0x04, 0x12, 0x12, 0x17, 0x2e, 0x3d, 0xd0, 0x2b, 0xff, 0x48, 0x8f, 0x91, 0xb8, - 0xa0, 0x4a, 0x44, 0x28, 0xe1, 0xc6, 0x3f, 0x81, 0x76, 0x66, 0xd6, 0x8e, 0xc3, 0xfa, 0x47, 0xab, - 0xdc, 0xbc, 0x33, 0xef, 0xc7, 0xf7, 0xbe, 0xf7, 0xe6, 0x7b, 0x86, 0x79, 0x8b, 0x58, 0xed, 0x06, - 0x73, 0x8c, 0x5d, 0xdb, 0x21, 0x0d, 0x9b, 0xb7, 0x8d, 0xd6, 0x9a, 0xf1, 0x38, 0xa0, 0x5e, 0x5b, - 0x77, 0x3d, 0xc6, 0x19, 0xbe, 0xa8, 0x0c, 0xf4, 0xc8, 0x40, 0x6f, 0xad, 0x65, 0xd2, 0x35, 0x56, - 0x63, 0xe2, 0xde, 0x08, 0x7f, 0x49, 0xd3, 0xcc, 0xfb, 0x35, 0xc6, 0x6a, 0x0d, 0x6a, 0x10, 0xd7, - 0x36, 0x88, 0xe3, 0x30, 0x4e, 0xb8, 0xcd, 0x1c, 0x5f, 0xdd, 0xae, 0x54, 0x98, 0xdf, 0x64, 0xbe, - 0x61, 0x11, 0x9f, 0xca, 0x0c, 0x46, 0x6b, 0xcd, 0xa2, 0x9c, 0xac, 0x19, 0x2e, 0xa9, 0xd9, 0x8e, - 0x30, 0x56, 0xb6, 0xb9, 0x38, 0x54, 0x2e, 0xf1, 0x48, 0x33, 0x8a, 0xa6, 0xc5, 0x59, 0x74, 0x20, - 0x0a, 0x1b, 0x2d, 0x0d, 0xf8, 0xdb, 0x30, 0x4f, 0x49, 0x38, 0x9a, 0xf4, 0x71, 0x40, 0x7d, 0xae, - 0x95, 0xe0, 0x62, 0xcf, 0xa9, 0xef, 0x32, 0xc7, 0xa7, 0xf8, 0x36, 0x24, 0x65, 0x82, 0x39, 0x94, - 0x43, 0xcb, 0xd3, 0xf9, 0xcb, 0x7a, 0x4c, 0xe1, 0xba, 0x74, 0x2a, 0x9c, 0x7b, 0x79, 0x38, 0x3f, - 0x66, 0x2a, 0x07, 0xed, 0x27, 0x04, 0x39, 0x11, 0xf2, 0xae, 0xed, 0xf3, 0x52, 0x60, 0x35, 0xec, - 0x8a, 0x49, 0x9c, 0x2a, 0x6b, 0x3a, 0xd4, 0x8f, 0xd2, 0xe2, 0x05, 0x48, 0xed, 0xba, 0x65, 0x8b, - 0x57, 0xca, 0xee, 0x5e, 0xb9, 0x4e, 0xf7, 0x45, 0x9a, 0x29, 0x13, 0x76, 0xdd, 0x02, 0xaf, 0x94, - 0xf6, 0xb6, 0xe9, 0x3e, 0xde, 0x02, 0xe8, 0x32, 0x31, 0x97, 0x10, 0x30, 0x16, 0x75, 0x49, 0x9b, - 0x1e, 0xd2, 0xa6, 0xcb, 0xc6, 0x28, 0xda, 0xf4, 0x12, 0xa9, 0x51, 0x15, 0xde, 0x3c, 0xe1, 0xa9, - 0x1d, 0x24, 0x60, 0x61, 0x00, 0x1e, 0x55, 0xf0, 0x0b, 0x04, 0x33, 0x6e, 0x60, 0x95, 0x3d, 0xe2, - 0x54, 0xcb, 0x4d, 0xe2, 0xce, 0xa1, 0xdc, 0xf8, 0xf2, 0x74, 0x7e, 0x2b, 0xb6, 0xee, 0xa1, 0xe1, - 0xf4, 0x52, 0x60, 0x85, 0xa7, 0xf7, 0x88, 0xbb, 0xe9, 0x70, 0xaf, 0x5d, 0xb8, 0xf5, 0xea, 0x70, - 0xfe, 0x46, 0xcd, 0xe6, 0xf5, 0xc0, 0xd2, 0x2b, 0xac, 0x69, 0xa8, 0xa8, 0x95, 0x3a, 0xb1, 0x9d, - 0xe8, 0xc3, 0xe0, 0x6d, 0x97, 0xfa, 0xfa, 0x83, 0x4a, 0xdd, 0x61, 0x9e, 0xa7, 0x22, 0x98, 0xe0, - 0x76, 0x42, 0xe1, 0xaf, 0x62, 0x28, 0x59, 0x1a, 0x4a, 0x89, 0x84, 0x74, 0x92, 0x93, 0xcc, 0xe7, - 0xf0, 0xf6, 0x29, 0x84, 0x78, 0x16, 0xc6, 0xf7, 0x68, 0x5b, 0xf4, 0xe1, 0x9c, 0x19, 0xfe, 0xc4, - 0x69, 0x98, 0x68, 0x91, 0x46, 0x40, 0x45, 0xa2, 0x19, 0x53, 0x7e, 0x7c, 0x9a, 0xb8, 0x85, 0xb4, - 0x55, 0xb8, 0x20, 0x28, 0x28, 0x34, 0x58, 0x65, 0x2f, 0x6a, 0xe9, 0x25, 0x48, 0xd6, 0xa9, 0x5d, - 0xab, 0x73, 0x15, 0x43, 0x7d, 0x69, 0xf7, 0xd4, 0xdc, 0x29, 0x63, 0xc5, 0xf7, 0x27, 0x30, 0x61, - 0x85, 0x07, 0x6a, 0xbe, 0x16, 0x62, 0x79, 0xde, 0x71, 0xaa, 0x74, 0x9f, 0x56, 0xa5, 0xa7, 0xb4, - 0xd7, 0x7e, 0x43, 0x70, 0xa9, 0xc3, 0xbf, 0xb8, 0xe9, 0x0c, 0xd5, 0x1d, 0x48, 0xfa, 0x9c, 0xf0, - 0x40, 0x0e, 0xed, 0x5b, 0xf9, 0xa5, 0xbe, 0xcd, 0xb3, 0x55, 0xd0, 0x07, 0xc2, 0xdc, 0x54, 0x6e, - 0x67, 0x36, 0x72, 0xcf, 0x11, 0xbc, 0xfb, 0x3f, 0x8c, 0xdd, 0x97, 0x25, 0x0a, 0xf1, 0xd5, 0x84, - 0x8d, 0x50, 0xb9, 0x72, 0x38, 0xb3, 0xf6, 0x6b, 0xeb, 0xf0, 0x9e, 0x80, 0xf7, 0x90, 0x71, 0xea, - 0x6f, 0xf0, 0x6d, 0xd1, 0xa8, 0x61, 0x7d, 0x6c, 0x42, 0x26, 0xce, 0x49, 0x95, 0x75, 0x1f, 0xce, - 0xcb, 0xd7, 0x2c, 0xeb, 0x9a, 0x29, 0xdc, 0x7c, 0x75, 0x38, 0x9f, 0x1f, 0x6d, 0xe2, 0x0b, 0x3b, - 0xa5, 0xf5, 0x1b, 0xd7, 0x4b, 0x81, 0xf5, 0x0d, 0x6d, 0x9b, 0x49, 0x2b, 0x14, 0x00, 0x5f, 0xbb, - 0x0d, 0x69, 0x91, 0x6e, 0xb3, 0x65, 0x57, 0xa9, 0x53, 0xa1, 0xa3, 0x2b, 0x87, 0x66, 0xc2, 0x3b, - 0xa7, 0x5c, 0x3b, 0xdc, 0x4f, 0x52, 0x75, 0xa6, 0xe6, 0xee, 0x4a, 0x2c, 0xfb, 0x1d, 0xc7, 0x8e, - 0xb9, 0xf6, 0x0c, 0x29, 0xce, 0xc2, 0x96, 0x46, 0xf7, 0x27, 0xe4, 0x6c, 0xc6, 0xe7, 0xc4, 0xe3, - 0xe5, 0x1e, 0xe6, 0xa6, 0xc5, 0x99, 0x24, 0xea, 0xcc, 0x66, 0xeb, 0x05, 0x52, 0x7d, 0x38, 0x05, - 0x44, 0x95, 0xf8, 0x19, 0x4c, 0x45, 0x98, 0xa3, 0x09, 0x1b, 0x52, 0x63, 0xd7, 0xfe, 0xcc, 0x06, - 0x6c, 0xe5, 0x8e, 0x7c, 0xf3, 0xbd, 0xcf, 0x0c, 0x5f, 0x80, 0x54, 0xf1, 0x7e, 0xb1, 0xbc, 0xb5, - 0x53, 0xdc, 0xb8, 0xbb, 0xf3, 0x68, 0xf3, 0xcb, 0xd9, 0x31, 0x9c, 0x82, 0xa9, 0xee, 0x27, 0xc2, - 0xe7, 0x61, 0x7c, 0xa3, 0xf8, 0xdd, 0x6c, 0x22, 0xff, 0xef, 0x24, 0x4c, 0x88, 0x2a, 0xf1, 0xf7, - 0x08, 0x92, 0x72, 0xcf, 0xe0, 0xfe, 0xef, 0xb9, 0x77, 0xa9, 0x65, 0x96, 0x87, 0x1b, 0x4a, 0xd0, - 0xda, 0xd5, 0x1f, 0xfe, 0xf8, 0xe7, 0x97, 0xc4, 0x15, 0x7c, 0xd9, 0xe8, 0xbf, 0x63, 0xf1, 0x5f, - 0x08, 0xd2, 0x71, 0x6a, 0x8f, 0x3f, 0x7e, 0xdd, 0xed, 0x20, 0xe1, 0xdd, 0x7c, 0xb3, 0xa5, 0xa2, - 0x3d, 0x14, 0x60, 0x4b, 0xb8, 0x68, 0x0c, 0x5a, 0xf7, 0x65, 0xd7, 0x63, 0x61, 0x47, 0x3d, 0xdf, - 0x78, 0xd2, 0xf3, 0x52, 0x9e, 0x1a, 0xae, 0x88, 0x2c, 0x76, 0x9c, 0x0c, 0x5d, 0x6e, 0xd8, 0x3e, - 0xc7, 0xcf, 0x10, 0x4c, 0x88, 0x3e, 0xe1, 0xc5, 0xfe, 0xc8, 0x4e, 0x6a, 0x7d, 0x66, 0x69, 0xa8, - 0x9d, 0x82, 0x7c, 0x4d, 0x40, 0x5e, 0xc4, 0x1f, 0xc4, 0x42, 0x96, 0xba, 0x66, 0x3c, 0x91, 0xaf, - 0xe6, 0x29, 0xfe, 0x11, 0x01, 0x74, 0x25, 0x13, 0xaf, 0x0e, 0xe6, 0xa9, 0x47, 0xfc, 0x33, 0xd7, - 0x46, 0x33, 0x1e, 0xa9, 0xef, 0x4a, 0x6f, 0x9f, 0x23, 0x48, 0xf5, 0xa8, 0x1d, 0xd6, 0xfb, 0x27, - 0x89, 0xd3, 0xd2, 0x8c, 0x31, 0xb2, 0xbd, 0xc2, 0xb5, 0x2a, 0x70, 0x7d, 0x88, 0xaf, 0xc6, 0xe2, - 0x6a, 0x85, 0x3e, 0x5d, 0xba, 0x7e, 0x47, 0x30, 0x19, 0x3d, 0x63, 0xfc, 0x51, 0xff, 0x54, 0xa7, - 0x24, 0x34, 0xb3, 0x32, 0x8a, 0xa9, 0x02, 0xb4, 0x2d, 0x00, 0x15, 0xf0, 0x17, 0x6f, 0x3a, 0x73, - 0x91, 0xba, 0xe0, 0x5f, 0x11, 0xa4, 0x7a, 0x34, 0x6b, 0x10, 0x9b, 0x71, 0x2a, 0x3b, 0x88, 0xcd, - 0x58, 0x31, 0xd4, 0x16, 0x05, 0xf8, 0x1c, 0xce, 0xc6, 0x82, 0xef, 0xe8, 0x5e, 0xe1, 0xeb, 0x97, - 0x47, 0x59, 0x74, 0x70, 0x94, 0x45, 0x7f, 0x1f, 0x65, 0xd1, 0xcf, 0xc7, 0xd9, 0xb1, 0x83, 0xe3, - 0xec, 0xd8, 0x9f, 0xc7, 0xd9, 0xb1, 0x47, 0xd7, 0x87, 0x6d, 0xb0, 0xfd, 0x6e, 0x48, 0xb1, 0xcc, - 0xac, 0xa4, 0xf8, 0xb7, 0xbd, 0xfe, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x08, 0x51, 0x06, - 0x4b, 0x0c, 0x00, 0x00, + // 1170 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xcf, 0x38, 0x8d, 0xdb, 0xbc, 0x24, 0xdf, 0x6f, 0x32, 0x49, 0x4b, 0x70, 0x89, 0xe3, 0x6c, + 0x21, 0x09, 0x49, 0xb5, 0xdb, 0x38, 0xa5, 0xb4, 0x20, 0xd4, 0xc6, 0x90, 0x90, 0x40, 0xea, 0x9a, + 0x2d, 0xaa, 0xd4, 0x5e, 0xac, 0x5d, 0x67, 0x62, 0xaf, 0xe2, 0xdd, 0xd9, 0x7a, 0x67, 0xad, 0x58, + 0x55, 0x25, 0xc4, 0xa1, 0x07, 0x04, 0x12, 0x12, 0x17, 0x2e, 0x3d, 0xd0, 0x2b, 0xff, 0x04, 0xc7, + 0x1e, 0x23, 0xe0, 0x80, 0x2a, 0x11, 0xa1, 0x84, 0x3f, 0x04, 0x79, 0x66, 0xd6, 0xf6, 0x3a, 0xeb, + 0x1f, 0x0d, 0x11, 0x37, 0xef, 0xec, 0xfb, 0xf1, 0x79, 0x9f, 0xf7, 0xd9, 0xf7, 0xc6, 0x30, 0x6b, + 0x1a, 0x66, 0xad, 0x4c, 0x1d, 0x6d, 0xd7, 0x72, 0x8c, 0xb2, 0xc5, 0x6a, 0x5a, 0x75, 0x45, 0x7b, + 0xec, 0x93, 0x4a, 0x4d, 0x75, 0x2b, 0x94, 0x51, 0x3c, 0x29, 0x0d, 0xd4, 0xc0, 0x40, 0xad, 0xae, + 0x24, 0xa6, 0x8a, 0xb4, 0x48, 0xf9, 0x7b, 0xad, 0xfe, 0x4b, 0x98, 0x26, 0xde, 0x2a, 0x52, 0x5a, + 0x2c, 0x13, 0xcd, 0x70, 0x2d, 0xcd, 0x70, 0x1c, 0xca, 0x0c, 0x66, 0x51, 0xc7, 0x93, 0x6f, 0x97, + 0x0a, 0xd4, 0xb3, 0xa9, 0xa7, 0x99, 0x86, 0x47, 0x44, 0x06, 0xad, 0xba, 0x62, 0x12, 0x66, 0xac, + 0x68, 0xae, 0x51, 0xb4, 0x1c, 0x6e, 0x2c, 0x6d, 0x53, 0x51, 0xa8, 0x5c, 0xa3, 0x62, 0xd8, 0x41, + 0x34, 0x25, 0xca, 0xa2, 0x01, 0x91, 0xdb, 0x28, 0x53, 0x80, 0xbf, 0xa8, 0xe7, 0xc9, 0x71, 0x47, + 0x9d, 0x3c, 0xf6, 0x89, 0xc7, 0x94, 0x1c, 0x4c, 0x86, 0x4e, 0x3d, 0x97, 0x3a, 0x1e, 0xc1, 0xb7, + 0x20, 0x2e, 0x12, 0x4c, 0xa3, 0x14, 0x5a, 0x1c, 0x49, 0x5f, 0x56, 0x23, 0x0a, 0x57, 0x85, 0x53, + 0xe6, 0xdc, 0xcb, 0xc3, 0xd9, 0x01, 0x5d, 0x3a, 0x28, 0xdf, 0x21, 0x48, 0xf1, 0x90, 0xdb, 0x96, + 0xc7, 0x72, 0xbe, 0x59, 0xb6, 0x0a, 0xba, 0xe1, 0xec, 0x50, 0xdb, 0x21, 0x5e, 0x90, 0x16, 0xcf, + 0xc1, 0xd8, 0xae, 0x9b, 0x37, 0x59, 0x21, 0xef, 0xee, 0xe5, 0x4b, 0x64, 0x9f, 0xa7, 0x19, 0xd6, + 0x61, 0xd7, 0xcd, 0xb0, 0x42, 0x6e, 0x6f, 0x93, 0xec, 0xe3, 0x0d, 0x80, 0x26, 0x13, 0xd3, 0x31, + 0x0e, 0x63, 0x5e, 0x15, 0xb4, 0xa9, 0x75, 0xda, 0x54, 0xd1, 0x18, 0x49, 0x9b, 0x9a, 0x33, 0x8a, + 0x44, 0x86, 0xd7, 0x5b, 0x3c, 0x95, 0x83, 0x18, 0xcc, 0x75, 0xc1, 0x23, 0x0b, 0x7e, 0x81, 0x60, + 0xd4, 0xf5, 0xcd, 0x7c, 0xc5, 0x70, 0x76, 0xf2, 0xb6, 0xe1, 0x4e, 0xa3, 0xd4, 0xe0, 0xe2, 0x48, + 0x7a, 0x23, 0xb2, 0xee, 0x9e, 0xe1, 0xd4, 0x9c, 0x6f, 0xd6, 0x4f, 0xef, 0x1a, 0xee, 0xba, 0xc3, + 0x2a, 0xb5, 0xcc, 0xcd, 0x57, 0x87, 0xb3, 0xd7, 0x8b, 0x16, 0x2b, 0xf9, 0xa6, 0x5a, 0xa0, 0xb6, + 0x26, 0xa3, 0x16, 0x4a, 0x86, 0xe5, 0x04, 0x0f, 0x1a, 0xab, 0xb9, 0xc4, 0x53, 0xef, 0x17, 0x4a, + 0x0e, 0xad, 0x54, 0x64, 0x04, 0x1d, 0xdc, 0x46, 0x28, 0xfc, 0x69, 0x04, 0x25, 0x0b, 0x3d, 0x29, + 0x11, 0x90, 0x5a, 0x39, 0x49, 0x7c, 0x04, 0xff, 0x6f, 0x43, 0x88, 0xc7, 0x61, 0x70, 0x8f, 0xd4, + 0x78, 0x1f, 0xce, 0xe9, 0xf5, 0x9f, 0x78, 0x0a, 0x86, 0xaa, 0x46, 0xd9, 0x27, 0x3c, 0xd1, 0xa8, + 0x2e, 0x1e, 0x3e, 0x88, 0xdd, 0x44, 0xca, 0x43, 0xb8, 0x28, 0xdd, 0x3f, 0xa6, 0xb6, 0x6d, 0xb1, + 0x06, 0x8b, 0x29, 0x18, 0x75, 0x7c, 0x3b, 0x1f, 0x10, 0x29, 0xa3, 0x81, 0xe3, 0xdb, 0xd2, 0x1e, + 0x27, 0x01, 0x0a, 0xdc, 0xc7, 0x26, 0x0e, 0x93, 0x91, 0x5b, 0x4e, 0x94, 0x6f, 0x10, 0xcc, 0xb4, + 0xd2, 0xdb, 0x9a, 0xe4, 0x3f, 0x97, 0xce, 0xef, 0x31, 0x48, 0x76, 0x02, 0x23, 0x2b, 0xde, 0x87, + 0xc9, 0x86, 0x6c, 0x44, 0x19, 0x2d, 0xea, 0xd9, 0xea, 0xa9, 0x9e, 0x93, 0x11, 0xd5, 0xd0, 0x69, + 0xd0, 0x1e, 0x7d, 0xdc, 0x6d, 0x3b, 0x3e, 0x3b, 0x31, 0xd0, 0xb6, 0x6e, 0x76, 0x91, 0xc4, 0x9d, + 0x56, 0x49, 0x8c, 0xa4, 0x97, 0xa2, 0xa7, 0x42, 0x54, 0x59, 0xad, 0xf2, 0x59, 0x86, 0x09, 0xce, + 0x41, 0xa6, 0x4c, 0x0b, 0x7b, 0x41, 0x5b, 0x2f, 0x41, 0xbc, 0x44, 0xac, 0x62, 0x89, 0xc9, 0x7c, + 0xf2, 0x49, 0xb9, 0x2b, 0xc7, 0x96, 0x34, 0x96, 0xb4, 0xbf, 0x0f, 0x43, 0x66, 0xfd, 0x40, 0x8e, + 0xa7, 0xb9, 0x48, 0x20, 0x5b, 0xce, 0x0e, 0xd9, 0x27, 0x3b, 0xc2, 0x53, 0xd8, 0x2b, 0x3f, 0x21, + 0xb8, 0xd4, 0x68, 0x00, 0x7f, 0xd3, 0x98, 0x49, 0xb7, 0x21, 0xee, 0x31, 0x83, 0xf9, 0x62, 0xe6, + 0xfd, 0x2f, 0xbd, 0xd0, 0xb1, 0x7b, 0x96, 0x0c, 0x7a, 0x9f, 0x9b, 0xeb, 0xd2, 0xed, 0xcc, 0x64, + 0xf7, 0x1c, 0xc1, 0x1b, 0x27, 0x30, 0x36, 0x07, 0x33, 0x2f, 0xc4, 0x93, 0x12, 0xeb, 0xa3, 0x72, + 0xe9, 0x70, 0x66, 0x82, 0x51, 0x56, 0xe1, 0x4d, 0x0e, 0xef, 0x01, 0x65, 0xc4, 0x5b, 0x63, 0x9b, + 0xbc, 0x51, 0xbd, 0xfa, 0x68, 0x43, 0x22, 0xca, 0x49, 0x96, 0x75, 0x0f, 0xce, 0x8b, 0x2f, 0x5a, + 0xd4, 0x35, 0x9a, 0xb9, 0xf1, 0xea, 0x70, 0x36, 0xdd, 0xdf, 0xc0, 0xcc, 0x6c, 0xe5, 0x56, 0xaf, + 0x5f, 0xcb, 0xf9, 0xe6, 0xe7, 0xa4, 0xa6, 0xc7, 0xcd, 0xfa, 0x10, 0xf0, 0x94, 0x5b, 0x30, 0xc5, + 0xd3, 0xad, 0x57, 0xad, 0x1d, 0xe2, 0x14, 0x48, 0xff, 0xd3, 0x43, 0xd1, 0xe1, 0x62, 0x9b, 0x6b, + 0x83, 0xfb, 0x0b, 0x44, 0x9e, 0x49, 0xdd, 0xcd, 0x44, 0xb2, 0xdf, 0x70, 0x6c, 0x98, 0x2b, 0xcf, + 0x90, 0xe4, 0xac, 0xde, 0xd2, 0xe0, 0x7d, 0xcb, 0x36, 0x1c, 0xf5, 0x98, 0x51, 0x61, 0xf9, 0x10, + 0x73, 0x23, 0xfc, 0x4c, 0x10, 0x75, 0x66, 0xda, 0x7a, 0x81, 0x64, 0x1f, 0xda, 0x80, 0xc8, 0x12, + 0x3f, 0x84, 0xe1, 0x00, 0x73, 0xa0, 0xb0, 0x1e, 0x35, 0x36, 0xed, 0xcf, 0x4c, 0x60, 0x4b, 0xb7, + 0xc5, 0x37, 0x1f, 0xfe, 0xcc, 0xf0, 0x04, 0x8c, 0x65, 0xef, 0x65, 0xf3, 0x1b, 0x5b, 0xd9, 0xb5, + 0xed, 0xad, 0x47, 0xeb, 0x9f, 0x8c, 0x0f, 0xe0, 0x31, 0x18, 0x6e, 0x3e, 0x22, 0x7c, 0x1e, 0x06, + 0xd7, 0xb2, 0x0f, 0xc7, 0x63, 0xe9, 0x5f, 0x00, 0x86, 0x78, 0x95, 0xf8, 0x2b, 0x04, 0x71, 0x71, + 0x4d, 0xc1, 0x9d, 0xbf, 0xe7, 0xf0, 0x9d, 0x28, 0xb1, 0xd8, 0xdb, 0x50, 0x80, 0x56, 0xae, 0x7c, + 0xfd, 0xdb, 0xdf, 0x3f, 0xc4, 0x66, 0xf0, 0x65, 0xad, 0xf3, 0x15, 0x0d, 0xff, 0x89, 0x60, 0x2a, + 0xea, 0xb2, 0x80, 0xdf, 0x7b, 0xdd, 0xcb, 0x85, 0x80, 0x77, 0xe3, 0x74, 0x77, 0x12, 0xe5, 0x01, + 0x07, 0x9b, 0xc3, 0x59, 0xad, 0xdb, 0x6d, 0x31, 0xef, 0x56, 0x68, 0xbd, 0xa3, 0x15, 0x4f, 0x7b, + 0x12, 0xfa, 0x52, 0x9e, 0x6a, 0x2e, 0x8f, 0xcc, 0x77, 0x9d, 0x08, 0x9d, 0x2f, 0x5b, 0x1e, 0xc3, + 0xbf, 0x22, 0x98, 0x38, 0xb1, 0xce, 0x70, 0xfa, 0xb5, 0x76, 0x9f, 0xa8, 0x6c, 0xf5, 0x14, 0xfb, + 0x52, 0xf9, 0x92, 0x97, 0x95, 0xc5, 0xdb, 0xff, 0xa2, 0xac, 0xd0, 0xfe, 0xe6, 0x45, 0x3d, 0x43, + 0x30, 0xc4, 0xc5, 0x87, 0xe7, 0x3b, 0x83, 0x6a, 0x5d, 0x60, 0x89, 0x85, 0x9e, 0x76, 0x12, 0xf0, + 0x55, 0x0e, 0x78, 0x1e, 0xbf, 0x1d, 0x09, 0x58, 0x0c, 0x6b, 0xed, 0x89, 0x18, 0x05, 0x4f, 0xf1, + 0xb7, 0x08, 0xa0, 0xb9, 0x07, 0xf0, 0x72, 0x77, 0x8a, 0x42, 0x1b, 0x2d, 0x71, 0xb5, 0x3f, 0xe3, + 0xbe, 0xc4, 0x2c, 0x97, 0xc8, 0x73, 0x04, 0x63, 0xa1, 0x11, 0x8e, 0xd5, 0xce, 0x49, 0xa2, 0x16, + 0x44, 0x42, 0xeb, 0xdb, 0x5e, 0xe2, 0x5a, 0xe6, 0xb8, 0xde, 0xc1, 0x57, 0x22, 0x71, 0x55, 0xeb, + 0x3e, 0x4d, 0xba, 0x7e, 0x46, 0x70, 0x21, 0x98, 0x4d, 0xf8, 0xdd, 0xce, 0xa9, 0xda, 0xf6, 0x42, + 0x62, 0xa9, 0x1f, 0x53, 0x09, 0x68, 0x93, 0x03, 0xca, 0xe0, 0x3b, 0xa7, 0x55, 0x5c, 0x30, 0x32, + 0xf1, 0x8f, 0x08, 0xc6, 0x42, 0x83, 0xb8, 0x1b, 0x9b, 0x51, 0xab, 0xa3, 0x1b, 0x9b, 0x91, 0x13, + 0x5e, 0x99, 0xe7, 0xe0, 0x53, 0x38, 0x19, 0x09, 0xbe, 0x31, 0xcc, 0x33, 0x9f, 0xbd, 0x3c, 0x4a, + 0xa2, 0x83, 0xa3, 0x24, 0xfa, 0xeb, 0x28, 0x89, 0xbe, 0x3f, 0x4e, 0x0e, 0x1c, 0x1c, 0x27, 0x07, + 0xfe, 0x38, 0x4e, 0x0e, 0x3c, 0xba, 0xd6, 0x6b, 0x2d, 0xef, 0x37, 0x43, 0xf2, 0x0d, 0x6d, 0xc6, + 0xf9, 0x3f, 0xd0, 0xd5, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x4f, 0x9a, 0xb0, 0x5f, 0x0f, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -858,7 +1039,13 @@ type QueryClient interface { // Parameters queries the parameters of the module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) // ListPublicRandomness is a range query for public randomness of a given finality provider + // NOTE: Babylon only has the knowledge of public randomness that is already revealed by + // finality providers, i.e., the finality provider alreayd provides a finality signature + // at the corresponding height + // TODO: remove public randomness storage? ListPublicRandomness(ctx context.Context, in *QueryListPublicRandomnessRequest, opts ...grpc.CallOption) (*QueryListPublicRandomnessResponse, error) + // ListPubRandCommit is a range query for public randomness commitments of a given finality provider + ListPubRandCommit(ctx context.Context, in *QueryListPubRandCommitRequest, opts ...grpc.CallOption) (*QueryListPubRandCommitResponse, error) // Block queries a block at a given height Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -897,6 +1084,15 @@ func (c *queryClient) ListPublicRandomness(ctx context.Context, in *QueryListPub return out, nil } +func (c *queryClient) ListPubRandCommit(ctx context.Context, in *QueryListPubRandCommitRequest, opts ...grpc.CallOption) (*QueryListPubRandCommitResponse, error) { + out := new(QueryListPubRandCommitResponse) + err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/ListPubRandCommit", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) Block(ctx context.Context, in *QueryBlockRequest, opts ...grpc.CallOption) (*QueryBlockResponse, error) { out := new(QueryBlockResponse) err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/Block", in, out, opts...) @@ -947,7 +1143,13 @@ type QueryServer interface { // Parameters queries the parameters of the module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) // ListPublicRandomness is a range query for public randomness of a given finality provider + // NOTE: Babylon only has the knowledge of public randomness that is already revealed by + // finality providers, i.e., the finality provider alreayd provides a finality signature + // at the corresponding height + // TODO: remove public randomness storage? ListPublicRandomness(context.Context, *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) + // ListPubRandCommit is a range query for public randomness commitments of a given finality provider + ListPubRandCommit(context.Context, *QueryListPubRandCommitRequest) (*QueryListPubRandCommitResponse, error) // Block queries a block at a given height Block(context.Context, *QueryBlockRequest) (*QueryBlockResponse, error) // ListBlocks is a range query for blocks at a given status @@ -970,6 +1172,9 @@ func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsReq func (*UnimplementedQueryServer) ListPublicRandomness(ctx context.Context, req *QueryListPublicRandomnessRequest) (*QueryListPublicRandomnessResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListPublicRandomness not implemented") } +func (*UnimplementedQueryServer) ListPubRandCommit(ctx context.Context, req *QueryListPubRandCommitRequest) (*QueryListPubRandCommitResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListPubRandCommit not implemented") +} func (*UnimplementedQueryServer) Block(ctx context.Context, req *QueryBlockRequest) (*QueryBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Block not implemented") } @@ -1026,6 +1231,24 @@ func _Query_ListPublicRandomness_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Query_ListPubRandCommit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryListPubRandCommitRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ListPubRandCommit(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.finality.v1.Query/ListPubRandCommit", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ListPubRandCommit(ctx, req.(*QueryListPubRandCommitRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_Block_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryBlockRequest) if err := dec(in); err != nil { @@ -1128,6 +1351,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ListPublicRandomness", Handler: _Query_ListPublicRandomness_Handler, }, + { + MethodName: "ListPubRandCommit", + Handler: _Query_ListPubRandCommit_Handler, + }, { MethodName: "Block", Handler: _Query_Block_Handler, @@ -1310,7 +1537,7 @@ func (m *QueryListPublicRandomnessResponse) MarshalToSizedBuffer(dAtA []byte) (i return len(dAtA) - i, nil } -func (m *QueryBlockRequest) Marshal() (dAtA []byte, err error) { +func (m *PubRandCommitResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1320,60 +1547,32 @@ func (m *QueryBlockRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryBlockRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *PubRandCommitResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryBlockRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *PubRandCommitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Height != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + if len(m.Commitment) > 0 { + i -= len(m.Commitment) + copy(dAtA[i:], m.Commitment) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Commitment))) i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *QueryBlockResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err + dAtA[i] = 0x12 } - return dAtA[:n], nil -} - -func (m *QueryBlockResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *QueryBlockResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Block != nil { - { - size, err := m.Block.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } + if m.NumPubRand != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.NumPubRand)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func (m *QueryListBlocksRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryListPubRandCommitRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1383,12 +1582,12 @@ func (m *QueryListBlocksRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryListBlocksRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryListPubRandCommitRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryListBlocksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryListPubRandCommitRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1405,15 +1604,17 @@ func (m *QueryListBlocksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if m.Status != 0 { - i = encodeVarintQuery(dAtA, i, uint64(m.Status)) + if len(m.FpBtcPkHex) > 0 { + i -= len(m.FpBtcPkHex) + copy(dAtA[i:], m.FpBtcPkHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.FpBtcPkHex))) i-- - dAtA[i] = 0x8 + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *QueryListBlocksResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryListPubRandCommitResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1423,12 +1624,12 @@ func (m *QueryListBlocksResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryListBlocksResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryListPubRandCommitResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryListBlocksResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryListPubRandCommitResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1445,16 +1646,26 @@ func (m *QueryListBlocksResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if len(m.Blocks) > 0 { - for iNdEx := len(m.Blocks) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Blocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err + if len(m.PubRandCommitMap) > 0 { + for k := range m.PubRandCommitMap { + v := m.PubRandCommitMap[k] + baseI := i + if v != nil { + { + size, err := v.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 } + i = encodeVarintQuery(dAtA, i, uint64(k)) + i-- + dAtA[i] = 0x8 + i = encodeVarintQuery(dAtA, i, uint64(baseI-i)) i-- dAtA[i] = 0xa } @@ -1462,7 +1673,7 @@ func (m *QueryListBlocksResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *QueryVotesAtHeightRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryBlockRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1472,12 +1683,12 @@ func (m *QueryVotesAtHeightRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryVotesAtHeightRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryBlockRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryVotesAtHeightRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryBlockRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1490,7 +1701,7 @@ func (m *QueryVotesAtHeightRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro return len(dAtA) - i, nil } -func (m *QueryVotesAtHeightResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryBlockResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1500,34 +1711,32 @@ func (m *QueryVotesAtHeightResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryVotesAtHeightResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryBlockResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryVotesAtHeightResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryBlockResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.BtcPks) > 0 { - for iNdEx := len(m.BtcPks) - 1; iNdEx >= 0; iNdEx-- { - { - size := m.BtcPks[iNdEx].Size() - i -= size - if _, err := m.BtcPks[iNdEx].MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintQuery(dAtA, i, uint64(size)) + if m.Block != nil { + { + size, err := m.Block.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } - i-- - dAtA[i] = 0xa + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa } return len(dAtA) - i, nil } -func (m *QueryEvidenceRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryListBlocksRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1537,12 +1746,166 @@ func (m *QueryEvidenceRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryEvidenceRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryListBlocksRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryEvidenceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryListBlocksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Status != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryListBlocksResponse) 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 *QueryListBlocksResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryListBlocksResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Blocks) > 0 { + for iNdEx := len(m.Blocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Blocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryVotesAtHeightRequest) 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 *QueryVotesAtHeightRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryVotesAtHeightRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryVotesAtHeightResponse) 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 *QueryVotesAtHeightResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryVotesAtHeightResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BtcPks) > 0 { + for iNdEx := len(m.BtcPks) - 1; iNdEx >= 0; iNdEx-- { + { + size := m.BtcPks[iNdEx].Size() + i -= size + if _, err := m.BtcPks[iNdEx].MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryEvidenceRequest) 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 *QueryEvidenceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryEvidenceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1755,6 +2118,65 @@ func (m *QueryListPublicRandomnessResponse) Size() (n int) { return n } +func (m *PubRandCommitResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NumPubRand != 0 { + n += 1 + sovQuery(uint64(m.NumPubRand)) + } + l = len(m.Commitment) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryListPubRandCommitRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FpBtcPkHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryListPubRandCommitResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.PubRandCommitMap) > 0 { + for k, v := range m.PubRandCommitMap { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovQuery(uint64(l)) + } + mapEntrySize := 1 + sovQuery(uint64(k)) + l + n += mapEntrySize + 1 + sovQuery(uint64(mapEntrySize)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QueryBlockRequest) Size() (n int) { if m == nil { return 0 @@ -2362,6 +2784,428 @@ func (m *QueryListPublicRandomnessResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *PubRandCommitResponse) 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 ErrIntOverflowQuery + } + 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: PubRandCommitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubRandCommitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumPubRand", wireType) + } + m.NumPubRand = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumPubRand |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Commitment", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Commitment = append(m.Commitment[:0], dAtA[iNdEx:postIndex]...) + if m.Commitment == nil { + m.Commitment = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryListPubRandCommitRequest) 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 ErrIntOverflowQuery + } + 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: QueryListPubRandCommitRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryListPubRandCommitRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FpBtcPkHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryListPubRandCommitResponse) 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 ErrIntOverflowQuery + } + 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: QueryListPubRandCommitResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryListPubRandCommitResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRandCommitMap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PubRandCommitMap == nil { + m.PubRandCommitMap = make(map[uint64]*PubRandCommitResponse) + } + var mapkey uint64 + var mapvalue *PubRandCommitResponse + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLengthQuery + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLengthQuery + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &PubRandCommitResponse{} + if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.PubRandCommitMap[mapkey] = mapvalue + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *QueryBlockRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/query.pb.gw.go b/x/finality/types/query.pb.gw.go index 1d001a7a0..1309d501b 100644 --- a/x/finality/types/query.pb.gw.go +++ b/x/finality/types/query.pb.gw.go @@ -123,6 +123,78 @@ func local_request_Query_ListPublicRandomness_0(ctx context.Context, marshaler r } +var ( + filter_Query_ListPubRandCommit_0 = &utilities.DoubleArray{Encoding: map[string]int{"fp_btc_pk_hex": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_ListPubRandCommit_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryListPubRandCommitRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPubRandCommit_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListPubRandCommit(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ListPubRandCommit_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryListPubRandCommitRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ListPubRandCommit_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListPubRandCommit(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_Block_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryBlockRequest var metadata runtime.ServerMetadata @@ -409,6 +481,29 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_ListPubRandCommit_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ListPubRandCommit_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ListPubRandCommit_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -605,6 +700,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_ListPubRandCommit_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ListPubRandCommit_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ListPubRandCommit_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_Block_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -713,6 +828,8 @@ var ( pattern_Query_ListPublicRandomness_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "finality", "v1", "finality_providers", "fp_btc_pk_hex", "public_randomness_list"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_ListPubRandCommit_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "finality", "v1", "finality_providers", "fp_btc_pk_hex", "pub_rand_commit_list"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Block_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "finality", "v1", "blocks", "height"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ListBlocks_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "blocks"}, "", runtime.AssumeColonVerbOpt(false))) @@ -729,6 +846,8 @@ var ( forward_Query_ListPublicRandomness_0 = runtime.ForwardResponseMessage + forward_Query_ListPubRandCommit_0 = runtime.ForwardResponseMessage + forward_Query_Block_0 = runtime.ForwardResponseMessage forward_Query_ListBlocks_0 = runtime.ForwardResponseMessage diff --git a/x/finality/types/tx.pb.go b/x/finality/types/tx.pb.go index 9e717dc67..ae1564fc9 100644 --- a/x/finality/types/tx.pb.go +++ b/x/finality/types/tx.pb.go @@ -7,6 +7,7 @@ import ( context "context" fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" @@ -38,14 +39,17 @@ type MsgCommitPubRandList struct { FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // start_height is the start block height of the list of public randomness StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` - // pub_rand_list is the list of public randomness - PubRandList []github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,4,rep,name=pub_rand_list,json=pubRandList,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_list,omitempty"` - // sig is the signature on (start_height || pub_rand_list) signed by + // num_pub_rand is the number of public randomness committed + NumPubRand uint64 `protobuf:"varint,4,opt,name=num_pub_rand,json=numPubRand,proto3" json:"num_pub_rand,omitempty"` + // commitment is the commitment of these public randomness + // currently it's the root of the Merkle tree that includes these public randomness + Commitment []byte `protobuf:"bytes,5,opt,name=commitment,proto3" json:"commitment,omitempty"` + // sig is the signature on (start_height || num_pub_rand || commitment) signed by // SK corresponding to fp_btc_pk. This prevents others to commit public // randomness on behalf of fp_btc_pk // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts // the tx submitter to be the holder of fp_btc_pk. Decide this later - Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,5,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` + Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,6,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` } func (m *MsgCommitPubRandList) Reset() { *m = MsgCommitPubRandList{} } @@ -95,6 +99,20 @@ func (m *MsgCommitPubRandList) GetStartHeight() uint64 { return 0 } +func (m *MsgCommitPubRandList) GetNumPubRand() uint64 { + if m != nil { + return m.NumPubRand + } + return 0 +} + +func (m *MsgCommitPubRandList) GetCommitment() []byte { + if m != nil { + return m.Commitment + } + return nil +} + // MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message type MsgCommitPubRandListResponse struct { } @@ -139,13 +157,17 @@ type MsgAddFinalitySig struct { FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // block_height is the height of the voted block BlockHeight uint64 `protobuf:"varint,3,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` + // pub_rand is the public randomness committed at this height + PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,4,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` + // proof is the proof that the given public randomness is committed under the commitment + Proof *crypto.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` // block_app_hash is the AppHash of the voted block - BlockAppHash []byte `protobuf:"bytes,4,opt,name=block_app_hash,json=blockAppHash,proto3" json:"block_app_hash,omitempty"` + BlockAppHash []byte `protobuf:"bytes,6,opt,name=block_app_hash,json=blockAppHash,proto3" json:"block_app_hash,omitempty"` // finality_sig is the finality signature to this block // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - FinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,5,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` + FinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,7,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` } func (m *MsgAddFinalitySig) Reset() { *m = MsgAddFinalitySig{} } @@ -195,6 +217,13 @@ func (m *MsgAddFinalitySig) GetBlockHeight() uint64 { return 0 } +func (m *MsgAddFinalitySig) GetProof() *crypto.Proof { + if m != nil { + return m.Proof + } + return nil +} + func (m *MsgAddFinalitySig) GetBlockAppHash() []byte { if m != nil { return m.BlockAppHash @@ -348,48 +377,52 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/tx.proto", fileDescriptor_2dd6da066b6baf1d) } var fileDescriptor_2dd6da066b6baf1d = []byte{ - // 647 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xdf, 0x4e, 0x13, 0x4f, - 0x14, 0xee, 0xb6, 0x85, 0x5f, 0x98, 0xf6, 0x87, 0x61, 0x25, 0xb2, 0x14, 0xb2, 0xad, 0x0d, 0x31, - 0x95, 0xe8, 0x2e, 0xff, 0x24, 0xc2, 0x1d, 0x6b, 0x34, 0x28, 0x36, 0x36, 0x5b, 0xbd, 0x51, 0x93, - 0xcd, 0xec, 0x9f, 0xce, 0x4e, 0xe8, 0xee, 0x8c, 0x3b, 0x53, 0x42, 0xef, 0x8c, 0x4f, 0xe0, 0x85, - 0x0f, 0x42, 0x8c, 0x0f, 0xc1, 0x8d, 0x09, 0xf1, 0xca, 0x90, 0xd8, 0x18, 0xb8, 0xe0, 0x35, 0x4c, - 0x77, 0xa7, 0x14, 0x4a, 0x89, 0xe5, 0xc6, 0xbb, 0x3d, 0x73, 0xbe, 0x73, 0xbe, 0x39, 0xdf, 0x7c, - 0x67, 0xc1, 0xbc, 0x0d, 0xed, 0x76, 0x93, 0x84, 0x7a, 0x03, 0x87, 0xb0, 0x89, 0x79, 0x5b, 0xdf, - 0x5b, 0xd6, 0xf9, 0xbe, 0x46, 0x23, 0xc2, 0x89, 0x7c, 0x5b, 0x64, 0xb5, 0x5e, 0x56, 0xdb, 0x5b, - 0x2e, 0x4c, 0x23, 0x82, 0x48, 0x9c, 0xd7, 0xbb, 0x5f, 0x09, 0xb4, 0x30, 0xeb, 0x10, 0x16, 0x10, - 0x66, 0x25, 0x89, 0x24, 0x10, 0xa9, 0x99, 0x24, 0xd2, 0x03, 0x86, 0xba, 0xdd, 0x03, 0x86, 0x44, - 0xa2, 0x34, 0x8c, 0x9c, 0xc2, 0x08, 0x06, 0xa2, 0xb4, 0xfc, 0x2b, 0x0d, 0xa6, 0xab, 0x0c, 0x3d, - 0x21, 0x41, 0x80, 0x79, 0xad, 0x65, 0x9b, 0x30, 0x74, 0x5f, 0x62, 0xc6, 0xe5, 0x3b, 0x60, 0x9c, - 0x61, 0x14, 0x7a, 0x91, 0x22, 0x95, 0xa4, 0xca, 0x84, 0x29, 0x22, 0xd9, 0x04, 0x13, 0x0d, 0x6a, - 0xd9, 0xdc, 0xb1, 0xe8, 0xae, 0x92, 0x2e, 0x49, 0x95, 0xbc, 0xb1, 0x7e, 0xdc, 0x29, 0xae, 0x20, - 0xcc, 0xfd, 0x96, 0xad, 0x39, 0x24, 0xd0, 0x05, 0xa9, 0xe3, 0x43, 0x1c, 0xf6, 0x02, 0x9d, 0xb7, - 0xa9, 0xc7, 0x34, 0xe3, 0x79, 0x6d, 0x75, 0x6d, 0xa9, 0xd6, 0xb2, 0x77, 0xbc, 0xb6, 0xf9, 0x5f, - 0x83, 0x1a, 0xdc, 0xa9, 0xed, 0xca, 0x77, 0x41, 0x9e, 0x71, 0x18, 0x71, 0xcb, 0xf7, 0x30, 0xf2, - 0xb9, 0x92, 0x29, 0x49, 0x95, 0xac, 0x99, 0x8b, 0xcf, 0xb6, 0xe3, 0x23, 0xf9, 0x3d, 0xf8, 0x9f, - 0xb6, 0x6c, 0x2b, 0x82, 0xa1, 0x6b, 0x35, 0x31, 0xe3, 0x4a, 0xb6, 0x94, 0xa9, 0xe4, 0x8d, 0xc7, - 0xc7, 0x9d, 0xe2, 0xda, 0x68, 0xd4, 0x75, 0xc7, 0x0f, 0x49, 0x14, 0x89, 0x19, 0xcd, 0x1c, 0xbd, - 0x30, 0xec, 0x0e, 0xc8, 0x30, 0x8c, 0x94, 0xb1, 0x78, 0x9c, 0x8d, 0xe3, 0x4e, 0xf1, 0xd1, 0x4d, - 0xc6, 0xa9, 0x63, 0x14, 0x42, 0xde, 0x8a, 0x3c, 0xb3, 0xdb, 0x65, 0x33, 0xf7, 0xe9, 0xec, 0x60, - 0x51, 0xc8, 0x55, 0x56, 0xc1, 0xfc, 0x30, 0x79, 0x4d, 0x8f, 0x51, 0x12, 0x32, 0xaf, 0xfc, 0x35, - 0x0d, 0xa6, 0xaa, 0x0c, 0x6d, 0xb9, 0xee, 0x33, 0xf1, 0x44, 0x75, 0x8c, 0xfe, 0xb5, 0xf8, 0x76, - 0x93, 0x38, 0xbb, 0x03, 0xe2, 0xc7, 0x67, 0x42, 0xfc, 0x05, 0x30, 0x99, 0x40, 0x20, 0xa5, 0x96, - 0x0f, 0x99, 0xaf, 0x64, 0xbb, 0xdc, 0x66, 0x52, 0xb8, 0x45, 0xe9, 0x36, 0x64, 0xbe, 0xfc, 0x0e, - 0xe4, 0x7b, 0x36, 0xb3, 0xfa, 0x6a, 0xde, 0xfc, 0x85, 0x9e, 0xbe, 0x7a, 0x5d, 0xaf, 0x63, 0x64, - 0xe6, 0x1a, 0x7d, 0x45, 0x2e, 0x8b, 0x3a, 0x07, 0x66, 0xaf, 0x68, 0x76, 0xae, 0xe8, 0x17, 0x09, - 0xdc, 0xaa, 0x32, 0xf4, 0x86, 0xba, 0x90, 0x7b, 0xb5, 0xd8, 0xeb, 0xf2, 0x3a, 0x98, 0x80, 0x2d, - 0xee, 0x93, 0x08, 0xf3, 0x76, 0x22, 0xa9, 0xa1, 0xfc, 0xf8, 0xf6, 0x70, 0x5a, 0x6c, 0xd1, 0x96, - 0xeb, 0x46, 0x1e, 0x63, 0x75, 0x1e, 0xe1, 0x10, 0x99, 0x7d, 0xa8, 0xbc, 0x01, 0xc6, 0x93, 0x6d, - 0x89, 0xc5, 0xce, 0xad, 0xcc, 0x69, 0x43, 0xf6, 0x55, 0x4b, 0x48, 0x8c, 0xec, 0x61, 0xa7, 0x98, - 0x32, 0x45, 0xc1, 0xe6, 0x64, 0xf7, 0xc2, 0xfd, 0x56, 0xe5, 0x59, 0x30, 0x33, 0x70, 0xab, 0xde, - 0x8d, 0x57, 0xbe, 0xa7, 0x41, 0xa6, 0xca, 0x90, 0xfc, 0x01, 0x4c, 0x5d, 0xdd, 0xc3, 0xfb, 0x43, - 0x29, 0x87, 0x79, 0xaa, 0xb0, 0x3c, 0x32, 0xb4, 0x47, 0x2d, 0xfb, 0x60, 0x72, 0xc0, 0x7a, 0xf7, - 0xae, 0x6b, 0x72, 0x19, 0x57, 0xd0, 0x46, 0xc3, 0x9d, 0x33, 0xd9, 0x20, 0x7f, 0xe9, 0x49, 0x16, - 0xae, 0xab, 0xbf, 0x88, 0x2a, 0x3c, 0x18, 0x05, 0xd5, 0xe3, 0x28, 0x8c, 0x7d, 0x3c, 0x3b, 0x58, - 0x94, 0x8c, 0x17, 0x87, 0x27, 0xaa, 0x74, 0x74, 0xa2, 0x4a, 0xbf, 0x4f, 0x54, 0xe9, 0xf3, 0xa9, - 0x9a, 0x3a, 0x3a, 0x55, 0x53, 0x3f, 0x4f, 0xd5, 0xd4, 0xdb, 0xa5, 0xbf, 0x19, 0x71, 0xbf, 0xff, - 0xa7, 0x8c, 0x3d, 0x69, 0x8f, 0xc7, 0xbf, 0xc9, 0xd5, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe1, - 0x58, 0x48, 0x68, 0xc7, 0x05, 0x00, 0x00, + // 712 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x4f, 0x4f, 0x13, 0x4d, + 0x1c, 0xee, 0x52, 0x28, 0x2f, 0xd3, 0x86, 0x37, 0xec, 0x4b, 0x5e, 0x96, 0x82, 0xdb, 0xda, 0x10, + 0x83, 0x44, 0x77, 0xa1, 0x20, 0x11, 0x6e, 0xd4, 0x68, 0x50, 0x6c, 0x6c, 0xb6, 0x7a, 0xd1, 0xc3, + 0x66, 0xff, 0x75, 0x76, 0x02, 0x3b, 0x33, 0xee, 0xcc, 0x12, 0x7a, 0x33, 0x7e, 0x02, 0x0f, 0x7e, + 0x10, 0x0e, 0x26, 0x9e, 0xbd, 0x71, 0x31, 0x21, 0x9e, 0x0c, 0x87, 0xc6, 0xc0, 0x81, 0xaf, 0x61, + 0x76, 0x77, 0x4a, 0x29, 0x94, 0x58, 0x3d, 0x78, 0xdb, 0x99, 0xdf, 0x33, 0xf3, 0x3c, 0xfb, 0x7b, + 0x9e, 0xdf, 0x80, 0x79, 0xdb, 0xb2, 0xdb, 0x7b, 0x04, 0xeb, 0x2d, 0x84, 0xad, 0x3d, 0xc4, 0xdb, + 0xfa, 0xfe, 0x8a, 0xce, 0x0f, 0x34, 0x1a, 0x12, 0x4e, 0xe4, 0xff, 0x44, 0x55, 0xeb, 0x56, 0xb5, + 0xfd, 0x95, 0xe2, 0x34, 0x24, 0x90, 0x24, 0x75, 0x3d, 0xfe, 0x4a, 0xa1, 0xc5, 0x5b, 0xdc, 0xc3, + 0xae, 0x17, 0x06, 0x08, 0x73, 0xdd, 0x09, 0xdb, 0x94, 0x13, 0x9d, 0x86, 0x84, 0xb4, 0x44, 0x79, + 0xd6, 0x21, 0x2c, 0x20, 0xcc, 0x4c, 0xcf, 0xa5, 0x0b, 0x51, 0x9a, 0x49, 0x57, 0x7a, 0xc0, 0x60, + 0x4c, 0x1e, 0x30, 0x28, 0x0a, 0xe5, 0x41, 0xda, 0xa8, 0x15, 0x5a, 0x81, 0x38, 0x5a, 0xf9, 0x32, + 0x02, 0xa6, 0xeb, 0x0c, 0x3e, 0x22, 0x41, 0x80, 0x78, 0x23, 0xb2, 0x0d, 0x0b, 0xbb, 0xcf, 0x11, + 0xe3, 0xf2, 0xff, 0x20, 0xc7, 0x10, 0xc4, 0x5e, 0xa8, 0x48, 0x65, 0x69, 0x71, 0xc2, 0x10, 0x2b, + 0xd9, 0x00, 0x13, 0x2d, 0x6a, 0xda, 0xdc, 0x31, 0xe9, 0xae, 0x32, 0x52, 0x96, 0x16, 0x0b, 0xb5, + 0xf5, 0x93, 0x4e, 0xa9, 0x0a, 0x11, 0xf7, 0x23, 0x5b, 0x73, 0x48, 0xa0, 0x0b, 0x52, 0xc7, 0xb7, + 0x10, 0xee, 0x2e, 0x74, 0xde, 0xa6, 0x1e, 0xd3, 0x6a, 0x4f, 0x1b, 0xab, 0x6b, 0xcb, 0x8d, 0xc8, + 0xde, 0xf1, 0xda, 0xc6, 0x78, 0x8b, 0xd6, 0xb8, 0xd3, 0xd8, 0x95, 0x6f, 0x83, 0x02, 0xe3, 0x56, + 0xc8, 0x4d, 0xdf, 0x43, 0xd0, 0xe7, 0x4a, 0xb6, 0x2c, 0x2d, 0x8e, 0x1a, 0xf9, 0x64, 0x6f, 0x3b, + 0xd9, 0x92, 0xcb, 0xa0, 0x80, 0xa3, 0xc0, 0xa4, 0x91, 0x6d, 0x86, 0x16, 0x76, 0x95, 0xd1, 0x04, + 0x02, 0x70, 0x14, 0x08, 0xd1, 0xb2, 0x0a, 0x80, 0x93, 0xfc, 0x45, 0xe0, 0x61, 0xae, 0x8c, 0xc5, + 0xca, 0x8c, 0x4b, 0x3b, 0xf2, 0x0e, 0xc8, 0x32, 0x04, 0x95, 0x5c, 0x22, 0x79, 0xe3, 0xa4, 0x53, + 0x7a, 0xf0, 0x3b, 0x92, 0x9b, 0x08, 0x62, 0x8b, 0x47, 0xa1, 0x67, 0xc4, 0xb7, 0x6c, 0xe6, 0xdf, + 0x9f, 0x1f, 0x2e, 0x89, 0x96, 0x54, 0x54, 0x30, 0x3f, 0xa8, 0x85, 0x86, 0xc7, 0x28, 0xc1, 0xcc, + 0xab, 0x7c, 0xce, 0x82, 0xa9, 0x3a, 0x83, 0x5b, 0xae, 0xfb, 0x44, 0xd8, 0xd0, 0x44, 0xf0, 0x6f, + 0x37, 0xd8, 0xde, 0x23, 0xce, 0xee, 0x95, 0x06, 0x27, 0x7b, 0xa2, 0xc1, 0x4d, 0xf0, 0x4f, 0x5f, + 0x73, 0x0b, 0xb5, 0x87, 0x27, 0x9d, 0xd2, 0xda, 0x70, 0xac, 0x4d, 0xc7, 0xc7, 0x24, 0x0c, 0xc5, + 0xcf, 0x1b, 0xe3, 0x54, 0x78, 0xa2, 0x81, 0xb1, 0x24, 0xc2, 0x89, 0x1d, 0xf9, 0xaa, 0xa2, 0xf5, + 0x22, 0xae, 0xa5, 0x11, 0xd7, 0x1a, 0x71, 0xdd, 0x48, 0x61, 0xf2, 0x02, 0x98, 0x4c, 0x75, 0x5a, + 0x94, 0x9a, 0xbe, 0xc5, 0xfc, 0xd4, 0x2e, 0x23, 0x55, 0xbf, 0x45, 0xe9, 0xb6, 0xc5, 0x7c, 0xf9, + 0x0d, 0x28, 0x74, 0xf3, 0x6c, 0xc6, 0x96, 0x8e, 0xff, 0xa1, 0xdc, 0xc7, 0x2f, 0x5e, 0x36, 0x9b, + 0x08, 0x1a, 0xf9, 0x56, 0xcf, 0x96, 0x7e, 0x67, 0xe7, 0xc0, 0xec, 0x35, 0xe3, 0x2e, 0x6c, 0xfd, + 0x28, 0x81, 0x7f, 0xeb, 0x0c, 0xbe, 0xa2, 0xae, 0xc5, 0xbd, 0x46, 0x32, 0x54, 0xf2, 0x3a, 0x98, + 0xb0, 0x22, 0xee, 0x93, 0x10, 0xf1, 0x76, 0xea, 0x6b, 0x4d, 0xf9, 0xf6, 0xe9, 0xfe, 0xb4, 0x18, + 0xd7, 0x2d, 0xd7, 0x0d, 0x3d, 0xc6, 0x9a, 0x3c, 0x44, 0x18, 0x1a, 0x3d, 0xa8, 0xbc, 0x01, 0x72, + 0xe9, 0x58, 0x26, 0x8e, 0xe7, 0xab, 0x73, 0xda, 0x80, 0x77, 0x43, 0x4b, 0x49, 0x6a, 0xa3, 0x47, + 0x9d, 0x52, 0xc6, 0x10, 0x07, 0x36, 0x27, 0x63, 0xc1, 0xbd, 0xab, 0x2a, 0xb3, 0x60, 0xe6, 0x8a, + 0xaa, 0xae, 0xe2, 0xea, 0xd7, 0x11, 0x90, 0xad, 0x33, 0x28, 0xbf, 0x05, 0x53, 0xd7, 0x07, 0xfe, + 0xee, 0x40, 0xca, 0x41, 0xc1, 0x2e, 0xae, 0x0c, 0x0d, 0xed, 0x52, 0xcb, 0x3e, 0x98, 0xbc, 0x92, + 0xff, 0x3b, 0x37, 0x5d, 0xd2, 0x8f, 0x2b, 0x6a, 0xc3, 0xe1, 0x2e, 0x98, 0x6c, 0x50, 0xe8, 0xb3, + 0x64, 0xe1, 0xa6, 0xf3, 0x97, 0x51, 0xc5, 0x7b, 0xc3, 0xa0, 0xba, 0x1c, 0xc5, 0xb1, 0x77, 0xe7, + 0x87, 0x4b, 0x52, 0xed, 0xd9, 0xd1, 0xa9, 0x2a, 0x1d, 0x9f, 0xaa, 0xd2, 0x8f, 0x53, 0x55, 0xfa, + 0x70, 0xa6, 0x66, 0x8e, 0xcf, 0xd4, 0xcc, 0xf7, 0x33, 0x35, 0xf3, 0x7a, 0xf9, 0x57, 0x41, 0x3c, + 0xe8, 0x3d, 0xc9, 0x49, 0x26, 0xed, 0x5c, 0xf2, 0x1e, 0xaf, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0x95, 0x73, 0xec, 0x64, 0x4f, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -582,21 +615,19 @@ func (m *MsgCommitPubRandList) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x32 + } + if len(m.Commitment) > 0 { + i -= len(m.Commitment) + copy(dAtA[i:], m.Commitment) + i = encodeVarintTx(dAtA, i, uint64(len(m.Commitment))) + i-- dAtA[i] = 0x2a } - if len(m.PubRandList) > 0 { - for iNdEx := len(m.PubRandList) - 1; iNdEx >= 0; iNdEx-- { - { - size := m.PubRandList[iNdEx].Size() - i -= size - if _, err := m.PubRandList[iNdEx].MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } + if m.NumPubRand != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.NumPubRand)) + i-- + dAtA[i] = 0x20 } if m.StartHeight != 0 { i = encodeVarintTx(dAtA, i, uint64(m.StartHeight)) @@ -678,13 +709,37 @@ func (m *MsgAddFinalitySig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x3a } if len(m.BlockAppHash) > 0 { i -= len(m.BlockAppHash) copy(dAtA[i:], m.BlockAppHash) i = encodeVarintTx(dAtA, i, uint64(len(m.BlockAppHash))) i-- + dAtA[i] = 0x32 + } + if m.Proof != nil { + { + size, err := m.Proof.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.PubRand != nil { + { + size := m.PubRand.Size() + i -= size + if _, err := m.PubRand.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- dAtA[i] = 0x22 } if m.BlockHeight != 0 { @@ -828,11 +883,12 @@ func (m *MsgCommitPubRandList) Size() (n int) { if m.StartHeight != 0 { n += 1 + sovTx(uint64(m.StartHeight)) } - if len(m.PubRandList) > 0 { - for _, e := range m.PubRandList { - l = e.Size() - n += 1 + l + sovTx(uint64(l)) - } + if m.NumPubRand != 0 { + n += 1 + sovTx(uint64(m.NumPubRand)) + } + l = len(m.Commitment) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) } if m.Sig != nil { l = m.Sig.Size() @@ -867,6 +923,14 @@ func (m *MsgAddFinalitySig) Size() (n int) { if m.BlockHeight != 0 { n += 1 + sovTx(uint64(m.BlockHeight)) } + if m.PubRand != nil { + l = m.PubRand.Size() + n += 1 + l + sovTx(uint64(l)) + } + if m.Proof != nil { + l = m.Proof.Size() + n += 1 + l + sovTx(uint64(l)) + } l = len(m.BlockAppHash) if l > 0 { n += 1 + l + sovTx(uint64(l)) @@ -1033,8 +1097,27 @@ func (m *MsgCommitPubRandList) Unmarshal(dAtA []byte) error { } } case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumPubRand", wireType) + } + m.NumPubRand = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumPubRand |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PubRandList", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Commitment", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -1061,13 +1144,12 @@ func (m *MsgCommitPubRandList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrPubRand - m.PubRandList = append(m.PubRandList, v) - if err := m.PubRandList[len(m.PubRandList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err + m.Commitment = append(m.Commitment[:0], dAtA[iNdEx:postIndex]...) + if m.Commitment == nil { + m.Commitment = []byte{} } iNdEx = postIndex - case 5: + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Sig", wireType) } @@ -1289,6 +1371,77 @@ func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { } } case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PubRand", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.SchnorrPubRand + m.PubRand = &v + if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Proof", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Proof == nil { + m.Proof = &crypto.Proof{} + } + if err := m.Proof.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BlockAppHash", wireType) } @@ -1322,7 +1475,7 @@ func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { m.BlockAppHash = []byte{} } iNdEx = postIndex - case 5: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field FinalitySig", wireType) } From 2e0733e1eba4538aa9e47634f9295ffa685b36c8 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Fri, 31 May 2024 21:03:15 +1000 Subject: [PATCH 089/119] init --- x/finality/keeper/msg_server.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index d64f9ef7a..f0cd17b80 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -197,6 +197,11 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi return nil, bstypes.ErrFpNotFound.Wrapf("the finality provider with BTC PK %v is not registered", fpBTCPKBytes) } + // verify signature over the public randomness commitment + if err := req.VerifySig(); err != nil { + return nil, types.ErrInvalidPubRand.Wrapf("invalid signature over the public randomness list: %v", err) + } + prCommit := &types.PubRandCommit{ StartHeight: req.StartHeight, NumPubRand: req.NumPubRand, @@ -220,11 +225,6 @@ func (ms msgServer) CommitPubRandList(goCtx context.Context, req *types.MsgCommi return nil, types.ErrInvalidPubRand.Wrapf("the start height (%d) has overlap with the height of the highest public randomness committed (%d)", req.StartHeight, lastPrHeightCommitted) } - // verify signature over the list - if err := req.VerifySig(); err != nil { - return nil, types.ErrInvalidPubRand.Wrapf("invalid signature over the public randomness list: %v", err) - } - // all good, commit the given public randomness list ms.SetPubRandCommit(ctx, req.FpBtcPk, prCommit) return &types.MsgCommitPubRandListResponse{}, nil From 7be9d5c57afbe1948d5e19e956cfff5e4ddd55b5 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Wed, 5 Jun 2024 16:47:37 +1000 Subject: [PATCH 090/119] zoneconcierge: avoid querying historical state by generating proofs upon sealing epochs (#662) --- app/app.go | 2 +- .../zoneconcierge/v1/zoneconcierge.proto | 10 + .../btc_timestamping_phase2_hermes_test.go | 8 +- test/e2e/bytecode/babylon_contract.wasm | Bin 717442 -> 676910 bytes test/e2e/e2e_test.go | 14 +- x/checkpointing/keeper/hooks.go | 9 + x/checkpointing/keeper/keeper.go | 20 +- x/checkpointing/types/expected_keepers.go | 1 + x/checkpointing/types/hooks.go | 10 + x/epoching/keeper/hooks.go | 2 +- x/monitor/keeper/hooks.go | 4 + .../keeper/epoch_chain_info_indexer.go | 55 ++- .../keeper/epoch_chain_info_indexer_test.go | 3 +- x/zoneconcierge/keeper/epochs.go | 34 ++ x/zoneconcierge/keeper/grpc_query.go | 14 +- x/zoneconcierge/keeper/hooks.go | 17 +- .../keeper/ibc_packet_btc_timestamp.go | 32 +- x/zoneconcierge/types/keys.go | 1 + x/zoneconcierge/types/zoneconcierge.pb.go | 373 +++++++++++++++--- 19 files changed, 490 insertions(+), 119 deletions(-) diff --git a/app/app.go b/app/app.go index 1a04c324e..d83795c73 100644 --- a/app/app.go +++ b/app/app.go @@ -170,7 +170,7 @@ var ( // The last arguments can contain custom message handlers, and custom query handlers, // if we want to allow any custom callbacks // See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md - wasmCapabilities = []string{"iterator", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "babylon"} + wasmCapabilities = []string{"iterator", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "staking", "babylon"} // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string diff --git a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto index 992662484..47e316a0f 100644 --- a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto +++ b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto @@ -72,6 +72,16 @@ message ChainInfo { uint64 timestamped_headers_count = 4; } +// ChainInfoWithProof is the chain info with a proof that the latest header in +// the chain info is included in the epoch +message ChainInfoWithProof { + ChainInfo chain_info = 1; + // proof_header_in_epoch is an inclusion proof that the latest_header in chain_info + // is committed to `app_hash` of the sealer header of latest_header.babylon_epoch + // this field is optional + tendermint.crypto.ProofOps proof_header_in_epoch = 2; +} + // FinalizedChainInfo is the information of a CZ that is BTC-finalised message FinalizedChainInfo { // chain_id is the ID of the chain diff --git a/test/e2e/btc_timestamping_phase2_hermes_test.go b/test/e2e/btc_timestamping_phase2_hermes_test.go index 51490d369..1a9cf8945 100644 --- a/test/e2e/btc_timestamping_phase2_hermes_test.go +++ b/test/e2e/btc_timestamping_phase2_hermes_test.go @@ -120,7 +120,7 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes if err != nil { return false } - s.T().Logf("next sequence send at ZoneConcierge is %d", nextSequenceSendResp.NextSequenceSend) + babylonNode.LogActionF("next sequence send at ZoneConcierge is %d", nextSequenceSendResp.NextSequenceSend) return nextSequenceSendResp.NextSequenceSend >= endEpochNum-startEpochNum+1+1 }, time.Minute, time.Second*2) @@ -131,17 +131,17 @@ func (s *BTCTimestampingPhase2HermesTestSuite) Test1IbcCheckpointingPhase2Hermes if err != nil { return false } - s.T().Logf("next sequence receive at Babylon contract is %d", nextSequenceRecv.NextSequenceReceive) + czNode.LogActionF("next sequence receive at Babylon contract is %d", nextSequenceRecv.NextSequenceReceive) return nextSequenceRecv.NextSequenceReceive >= endEpochNum-startEpochNum+1+1 }, time.Minute, time.Second*2) - // Ensure the IBC packet acknowledgements (on chain B) are there + // Ensure the IBC packet acknowledgements (on chain B) are there and do not contain error nextSequence := nextSequenceRecv.NextSequenceReceive for seq := uint64(1); seq < nextSequence; seq++ { var seqResp *channeltypes.QueryPacketAcknowledgementResponse s.Eventually(func() bool { seqResp, err = czNode.QueryPacketAcknowledgement(czChannel.ChannelId, czChannel.PortId, seq) - s.T().Logf("acknowledgement resp of IBC packet #%d: %v, err: %v", seq, seqResp, err) + czNode.LogActionF("acknowledgement resp of IBC packet #%d: %v, err: %v", seq, seqResp, err) return err == nil }, time.Minute, time.Second*2) } diff --git a/test/e2e/bytecode/babylon_contract.wasm b/test/e2e/bytecode/babylon_contract.wasm index 546c200eb754ea571693d3b84996e73fb4c903fa..16075c9065de0d2dac3f5ab351c645669731687a 100644 GIT binary patch literal 676910 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%0DqDvEa&MA`<;3dm@IGx&t2@-E8|s!q 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�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 Z>u#bY1jGj~28}riI0g6uuzauE{{vDFJ`Vr@ literal 717442 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�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 z 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

=H5Xe?il3?<`QiE;2Qu(;SvTH3WJZ2%Kd)^on% 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 64 { + return ErrIntOverflowZoneconcierge + } + 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: ChainInfoWithProof: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ChainInfoWithProof: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChainInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowZoneconcierge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthZoneconcierge + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthZoneconcierge + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ChainInfo == nil { + m.ChainInfo = &ChainInfo{} + } + if err := m.ChainInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ProofHeaderInEpoch", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowZoneconcierge + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthZoneconcierge + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthZoneconcierge + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ProofHeaderInEpoch == nil { + m.ProofHeaderInEpoch = &crypto.ProofOps{} + } + if err := m.ProofHeaderInEpoch.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipZoneconcierge(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthZoneconcierge + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *FinalizedChainInfo) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 From 58c28046b75d3e1e6bd014ed34d7bea75665bf80 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 10 Jun 2024 08:54:48 -0300 Subject: [PATCH 091/119] chore: add gosec (#667) * feat: add gosec to makefile and config * fix: gosec G306 * fix: add err check * feat: add gosec to circle ci * fix: gosec G104 * fix: gosec G304 * fix: gosec G301 * chore: add RegisterQueryHandlerClient to no err check * chore: exclude test dir from gosec * chore: add nosec and fix G404 * fix: gosec G601 * chore: nosec does not work * chore: exclude rule for using math rand * chore: move independant functions from keeper.go and set emitTypedEventWithLog as private * chore: removed unused function that was using math/rand * chore: tie logger and emmit evt with log under keeper --- .circleci/config.yml | 13 ++++++++ Makefile | 13 ++++++++ app/test_helpers.go | 30 ------------------- app/utils.go | 2 +- .../cmd/genhelpers/set_btc_headers.go | 8 +++-- .../cmd/genhelpers/set_finality_providers.go | 8 +++-- crypto/eots/examples/btc-testnet-txs/main.go | 5 +++- gosec.json | 11 +++++++ privval/file.go | 2 ++ test/e2e/initialization/node/main.go | 2 +- types/retry/retry.go | 18 +++++++++-- x/btclightclient/keeper/keeper.go | 18 +++++++++-- x/btclightclient/keeper/triggers.go | 8 ++--- x/btcstaking/keeper/btc_delegations.go | 1 + x/checkpointing/client/cli/utils.go | 2 +- x/checkpointing/types/genesis.go | 3 +- 16 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 gosec.json diff --git a/.circleci/config.yml b/.circleci/config.yml index 97920cdec..085fe6388 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -33,6 +33,16 @@ jobs: name: Run tests command: | make test + gosec: + machine: + image: ubuntu-2204:2024.01.1 + resource_class: large + steps: + - checkout + - run: + name: Run gosec + command: make gosec + e2e-test: machine: image: ubuntu-2204:2024.01.1 @@ -126,6 +136,9 @@ workflows: lint: jobs: - lint + gosec: + jobs: + - gosec docker: jobs: - build_docker: diff --git a/Makefile b/Makefile index 38dfecbd8..e999358a5 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ PACKAGES_SIMTEST=$(shell go list ./... | grep '/simulation') COMMIT := $(shell git log -1 --format='%H') LEDGER_ENABLED ?= true BINDIR ?= $(GOPATH)/bin +PROJECT_NAME ?= babylon BUILDDIR ?= $(CURDIR)/build HTTPS_GIT := https://github.com/babylonchain/babylon.git DOCKER := $(shell which docker) @@ -340,6 +341,18 @@ format: find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/babylonchain/babylon .PHONY: format +############################################################################### +### Gosec ### +############################################################################### + +gosec: + $(DOCKER) run --rm -it -w /$(PROJECT_NAME)/ -v $(CURDIR):/$(PROJECT_NAME) securego/gosec -exclude-generated -exclude-dir=/$(PROJECT_NAME)/testutil -exclude-dir=/$(PROJECT_NAME)/test -conf /$(PROJECT_NAME)/gosec.json /$(PROJECT_NAME)/... + +gosec-local: + gosec -exclude-generated -exclude-dir=$(CURDIR)/testutil -exclude-dir=$(CURDIR)/test -conf $(CURDIR)/gosec.json $(CURDIR)/... + +.PHONY: gosec gosec-local + ############################################################################### ### Devdoc ### ############################################################################### diff --git a/app/test_helpers.go b/app/test_helpers.go index b71c69169..d2bdc4a58 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -2,7 +2,6 @@ package app import ( "encoding/json" - "math/rand" "os" "testing" "time" @@ -15,13 +14,10 @@ import ( tmjson "github.com/cometbft/cometbft/libs/json" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" - bam "github.com/cosmos/cosmos-sdk/baseapp" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" cosmosed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server/types" simsutils "github.com/cosmos/cosmos-sdk/testutil/sims" @@ -357,29 +353,3 @@ func initAccountWithCoins(app *BabylonApp, ctx sdk.Context, addr sdk.AccAddress, panic(err) } } - -// SignAndDeliverWithoutCommit signs and delivers a transaction. No commit -func SignAndDeliverWithoutCommit(t *testing.T, txCfg client.TxConfig, app *bam.BaseApp, msgs []sdk.Msg, fees sdk.Coins, chainID string, accNums, accSeqs []uint64, blockTime time.Time, priv ...cryptotypes.PrivKey) (*abci.ResponseFinalizeBlock, error) { - tx, err := simsutils.GenSignedMockTx( - rand.New(rand.NewSource(time.Now().UnixNano())), - txCfg, - msgs, - fees, - simsutils.DefaultGenTxGas, - chainID, - accNums, - accSeqs, - priv..., - ) - require.NoError(t, err) - - bz, err := txCfg.TxEncoder()(tx) - require.NoError(t, err) - - return app.FinalizeBlock(&abci.RequestFinalizeBlock{ - Height: app.LastBlockHeight() + 1, - Hash: app.LastCommitID().Hash, - Time: blockTime, - Txs: [][]byte{bz}, - }) -} diff --git a/app/utils.go b/app/utils.go index 8869582bf..2f2ccbf9c 100644 --- a/app/utils.go +++ b/app/utils.go @@ -89,7 +89,7 @@ func saveClientConfig(homePath string, cliConf *config.ClientConfig) error { // ensureConfigPath creates a directory configPath if it does not exist func ensureConfigPath(configPath string) error { - return os.MkdirAll(configPath, os.ModePerm) + return os.MkdirAll(filepath.Clean(configPath), 0750) } func writeConfigToFile(configFilePath string, config *config.ClientConfig) error { diff --git a/cmd/babylond/cmd/genhelpers/set_btc_headers.go b/cmd/babylond/cmd/genhelpers/set_btc_headers.go index 9110f5dab..63014c88a 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_headers.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_headers.go @@ -3,6 +3,7 @@ package genhelpers import ( "fmt" "os" + "path/filepath" cmtos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/client" @@ -103,11 +104,12 @@ Possible content of 'btc_headers.json' is } func getBtcLightGenStateFromFile(cdc codec.Codec, inputFilePath string) (*btclighttypes.GenesisState, error) { - if !cmtos.FileExists(inputFilePath) { - return nil, fmt.Errorf("input file %s does not exists", inputFilePath) + filePath := filepath.Clean(inputFilePath) + if !cmtos.FileExists(filePath) { + return nil, fmt.Errorf("input file %s does not exists", filePath) } - bz, err := os.ReadFile(inputFilePath) + bz, err := os.ReadFile(filePath) if err != nil { return nil, err } diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers.go b/cmd/babylond/cmd/genhelpers/set_finality_providers.go index 502d2ad41..5298130c2 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "os" + "path/filepath" btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" cmtos "github.com/cometbft/cometbft/libs/os" @@ -127,11 +128,12 @@ func replaceModOnGenesis( } func getBtcStakingGenStateFromFile(cdc codec.Codec, inputFilePath string) (*btcstktypes.GenesisState, error) { - if !cmtos.FileExists(inputFilePath) { - return nil, fmt.Errorf("input file %s does not exists", inputFilePath) + filePath := filepath.Clean(inputFilePath) + if !cmtos.FileExists(filePath) { + return nil, fmt.Errorf("input file %s does not exists", filePath) } - bz, err := os.ReadFile(inputFilePath) + bz, err := os.ReadFile(filePath) if err != nil { return nil, err } diff --git a/crypto/eots/examples/btc-testnet-txs/main.go b/crypto/eots/examples/btc-testnet-txs/main.go index 2ddec8443..4ee467e62 100644 --- a/crypto/eots/examples/btc-testnet-txs/main.go +++ b/crypto/eots/examples/btc-testnet-txs/main.go @@ -130,7 +130,10 @@ func generateTx(senderPk *eots.PrivateKey, amount int64, fees int64, rcvAddress recTx.TxIn[0].SignatureScript = scriptSig buf := bytes.NewBuffer(make([]byte, 0, recTx.SerializeSize())) - recTx.Serialize(buf) + err = recTx.Serialize(buf) + if err != nil { + return nil, "", err + } // verify transaction vm, err := txscript.NewEngine(rcvScript, recTx, 0, txscript.StandardVerifyFlags, nil, nil, amount, nil) diff --git a/gosec.json b/gosec.json new file mode 100644 index 000000000..cfa57cbd8 --- /dev/null +++ b/gosec.json @@ -0,0 +1,11 @@ +{ + "global": { + "nosec": "enabled", + "audit": "disabled" + }, + "G104": { + "wire": ["WriteVarString"], + "io": ["WriteString"], + "types": ["RegisterQueryHandlerClient"] + } +} \ No newline at end of file diff --git a/privval/file.go b/privval/file.go index deebd10da..691038593 100644 --- a/privval/file.go +++ b/privval/file.go @@ -119,6 +119,7 @@ func LoadWrappedFilePVEmptyState(keyFilePath, stateFilePath string) *WrappedFile // If loadState is true, we load from the stateFilePath. Otherwise, we use an empty LastSignState. func loadWrappedFilePV(keyFilePath, stateFilePath string, loadState bool) *WrappedFilePV { + keyFilePath = filepath.Clean(keyFilePath) keyJSONBytes, err := os.ReadFile(keyFilePath) if err != nil { cmtos.Exit(err.Error()) @@ -138,6 +139,7 @@ func loadWrappedFilePV(keyFilePath, stateFilePath string, loadState bool) *Wrapp pvState := privval.FilePVLastSignState{} if loadState { + stateFilePath := filepath.Clean(stateFilePath) stateJSONBytes, err := os.ReadFile(stateFilePath) if err != nil { cmtos.Exit(err.Error()) diff --git a/test/e2e/initialization/node/main.go b/test/e2e/initialization/node/main.go index 7ed274975..cfa43b6c5 100644 --- a/test/e2e/initialization/node/main.go +++ b/test/e2e/initialization/node/main.go @@ -63,7 +63,7 @@ func main() { panic("persistent peers are required, separated by commas") } - if err := os.MkdirAll(dataDir, 0o755); err != nil { + if err := os.MkdirAll(dataDir, 0750); err != nil { panic(err) } diff --git a/types/retry/retry.go b/types/retry/retry.go index ec0845c15..05cf78bcf 100644 --- a/types/retry/retry.go +++ b/types/retry/retry.go @@ -1,8 +1,9 @@ package retry import ( + "crypto/rand" "errors" - "math/rand" + "math/big" "time" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -50,6 +51,8 @@ func isExpectedErr(err error) bool { return false } +// Do executes a func with retry +// TODO: check if this is needed, because is not being used. func Do(sleep time.Duration, maxSleepTime time.Duration, retryableFunc func() error) error { if err := retryableFunc(); err != nil { if isUnrecoverableErr(err) { @@ -63,7 +66,10 @@ func Do(sleep time.Duration, maxSleepTime time.Duration, retryableFunc func() er } // Add some randomness to prevent thrashing - jitter := time.Duration(rand.Int63n(int64(sleep))) + jitter, err := randDuration(int64(sleep)) + if err != nil { + return err + } sleep = sleep + jitter/2 if sleep > maxSleepTime { @@ -78,3 +84,11 @@ func Do(sleep time.Duration, maxSleepTime time.Duration, retryableFunc func() er } return nil } + +func randDuration(maxNumber int64) (dur time.Duration, err error) { + randNumber, err := rand.Int(rand.Reader, big.NewInt(maxNumber)) + if err != nil { + return dur, err + } + return time.Duration(randNumber.Int64()), nil +} diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index 942734798..9cb0330bc 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -5,8 +5,8 @@ import ( "fmt" corestoretypes "cosmossdk.io/core/store" - "cosmossdk.io/log" + bbn "github.com/babylonchain/babylon/types" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" @@ -14,6 +14,7 @@ import ( "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + proto "github.com/cosmos/gogoproto/proto" ) type ( @@ -47,10 +48,23 @@ func NewKeeper( } } -func (k Keeper) Logger(ctx sdk.Context) log.Logger { +// Logger returns the logger with the key value of the current module. +func (Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } +// emitTypedEventWithLog emits an event and logs if it errors. +func (k Keeper) emitTypedEventWithLog(ctx context.Context, evt proto.Message) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + if err := sdkCtx.EventManager().EmitTypedEvent(evt); err != nil { + k.Logger(sdkCtx).Error( + "faied to emit event", + "type", evt.String(), + "reason", err.Error(), + ) + } +} + // SetHooks sets the btclightclient hooks func (k *Keeper) SetHooks(bh types.BTCLightClientHooks) *Keeper { if k.hooks != nil { diff --git a/x/btclightclient/keeper/triggers.go b/x/btclightclient/keeper/triggers.go index 8b9bdaea1..e01a102c9 100644 --- a/x/btclightclient/keeper/triggers.go +++ b/x/btclightclient/keeper/triggers.go @@ -2,27 +2,27 @@ package keeper import ( "context" + "github.com/babylonchain/babylon/x/btclightclient/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) func (k Keeper) triggerHeaderInserted(ctx context.Context, headerInfo *types.BTCHeaderInfo) { // Trigger AfterBTCHeaderInserted hook k.AfterBTCHeaderInserted(ctx, headerInfo) // Emit HeaderInserted event - sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&types.EventBTCHeaderInserted{Header: headerInfo}) //nolint:errcheck + k.emitTypedEventWithLog(ctx, &types.EventBTCHeaderInserted{Header: headerInfo}) } func (k Keeper) triggerRollBack(ctx context.Context, headerInfo *types.BTCHeaderInfo) { // Trigger AfterBTCRollBack hook k.AfterBTCRollBack(ctx, headerInfo) // Emit BTCRollBack event - sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&types.EventBTCRollBack{Header: headerInfo}) //nolint:errcheck + k.emitTypedEventWithLog(ctx, &types.EventBTCRollBack{Header: headerInfo}) } func (k Keeper) triggerRollForward(ctx context.Context, headerInfo *types.BTCHeaderInfo) { // Trigger AfterBTCRollForward hook k.AfterBTCRollForward(ctx, headerInfo) // Emit BTCRollForward event - sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&types.EventBTCRollForward{Header: headerInfo}) //nolint:errcheck + k.emitTypedEventWithLog(ctx, &types.EventBTCRollForward{Header: headerInfo}) } diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index beade47a1..9ebcb6bea 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -30,6 +30,7 @@ func (k Keeper) AddBTCDelegation(ctx sdk.Context, btcDel *types.BTCDelegation) e // for each finality provider the delegation restakes to, update its index for _, fpBTCPK := range btcDel.FpBtcPkList { + fpBTCPK := fpBTCPK // remove when update to go1.22 // get BTC delegation index under this finality provider btcDelIndex := k.getBTCDelegatorDelegationIndex(ctx, &fpBTCPK, btcDel.BtcPk) if btcDelIndex == nil { diff --git a/x/checkpointing/client/cli/utils.go b/x/checkpointing/client/cli/utils.go index 532435bf5..50d049123 100644 --- a/x/checkpointing/client/cli/utils.go +++ b/x/checkpointing/client/cli/utils.go @@ -56,7 +56,7 @@ func parseAndValidateValidatorJSON(cdc codec.Codec, path string) (validator, err MinSelfDelegation string `json:"min-self-delegation"` } - contents, err := os.ReadFile(path) + contents, err := os.ReadFile(filepath.Clean(path)) if err != nil { return validator{}, err } diff --git a/x/checkpointing/types/genesis.go b/x/checkpointing/types/genesis.go index 1ab34122e..bbe289ea9 100644 --- a/x/checkpointing/types/genesis.go +++ b/x/checkpointing/types/genesis.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "os" + "path/filepath" tmjson "github.com/cometbft/cometbft/libs/json" "github.com/cosmos/cosmos-sdk/codec" @@ -54,7 +55,7 @@ func NewGenesisKey(delAddr sdk.ValAddress, blsPubKey *bls12381.PublicKey, pop *P } func LoadGenesisKeyFromFile(filePath string) (*GenesisKey, error) { - genBlsJSONBytes, err := os.ReadFile(filePath) + genBlsJSONBytes, err := os.ReadFile(filepath.Clean(filePath)) if err != nil { return nil, err } From dcb63810fe27e66d2d5aed5a7f45e5801623b761 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 11 Jun 2024 13:12:00 +0200 Subject: [PATCH 092/119] Few fixes to script docs (#669) --- docs/staking-script.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/staking-script.md b/docs/staking-script.md index 1cc147ebb..c2cf564bf 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -142,7 +142,8 @@ The requirements for a valid slashing transaction are: unbonding output - it must have exactly two outputs, the first sending the slashed fraction of the funds to a burn address specified in the Babylon chain's parameters and the - second sending the remaining funds back to the BTC staker's address. + second sending the remaining funds to output which can be unlocked by staker + after the timelock - the fee for the slashing transactions must be larger than or equal to the minimal fee specified in Babylon's parameters @@ -190,7 +191,7 @@ before the timelock expires. It commits to a script of the form: ``` OP_CHECKSIGVERIFY - OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD + OP_CHECKSIG OP_CHECKSIGADD ... OP_CHECKSIGADD OP_NUMEQUAL ``` @@ -214,7 +215,7 @@ delegators in the case of double signing. It commits to a script: ``` OP_CHECKSIGVERIFY OP_CHECKSIGVERIFY - OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD + OP_CHECKSIG OP_CHECKSIGADD ... OP_CHECKSIGADD OP_NUMEQUAL ``` @@ -292,7 +293,7 @@ delegators in the case of double signing. It commits to a script: ``` OP_CHECKSIGVERIFY OP_CHECKSIGVERIFY - OP_CHECKSIGADD OP_CHECKSIGADD ... OP_CHECKSIGADD + OP_CHECKSIG OP_CHECKSIGADD ... OP_CHECKSIGADD OP_NUMEQUAL ``` From 7ecdfdeefc3763001e601c289599c119ad647625 Mon Sep 17 00:00:00 2001 From: lesterli Date: Thu, 13 Jun 2024 00:34:08 -0400 Subject: [PATCH 093/119] Update Makefile (#671) --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e999358a5..72eca733f 100644 --- a/Makefile +++ b/Makefile @@ -439,8 +439,9 @@ localnet-start-nodes: init-testnet-dirs # localnet-start will run a with 4 nodes with 4 nodes, a bitcoin instance, and a vigilante instance localnet-start: localnet-stop build-docker localnet-start-nodes -# localnet-stop will stop all localnets running +# localnet-stop will clean up and stop all localnets running localnet-stop: + rm -rf $(CURDIR)/.testnets docker-compose down build-test-wasm: From 013f733e95376b32b9cd82bac42d79fee8f21196 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Wed, 19 Jun 2024 07:38:49 -0300 Subject: [PATCH 094/119] feat: BTC multisig use `sdk.AccAddress` (#657) * chore: proto change without generating * chore: update proto structures for simplify PoP with staker address as signer * chore: removed bbn pk from tx input * chore: removed bbn pk and add check for staker addr to be valid address * chore: add check of PoP BTC for BIP340 * chore: add check of PoP BTC for BIP332 * chore: add check of PoP BTC for ECDSA * chore: partially fix tests * chore: remove pop from BTCdelegation * chore: remove PoP and babylon PK to add staker address directly in BTCDelegation * chore: add Event for new delegation * chore: generate proto of event and BTC del with staker * chore: remove bbn pk to use address * fix: remove changes from pb.go files * fix: use address instead of bbn pub key * chore: add test for popBTC validate basic * fix: bip322 verification and test * chore: add check and new PoP BTC for ECDSA * chore: remove new btc delegation event * chore: bring back PoP to BTCDelegation * chore: add back check for pop in btc delegation * chore: add back check for equal pop and staker addr in btc delegation * chore: add check for staker addr and nil pop * fix: lint remove unused import * fix: e2e test btc delegation * fix: add pop to random btc del * fix: add wallet name to export node * feat: add PoP BTC to check `sdk.AccAddress` (#659) * chore: removed bbn pk from tx input * chore: removed bbn pk and add check for staker addr to be valid address * chore: add check of PoP BTC for BIP340 * chore: add check of PoP BTC for BIP332 * chore: add check of PoP BTC for ECDSA * chore: partially fix tests * chore: remove pop from BTCdelegation * chore: generate proto of event and BTC del with staker * fix: use address instead of bbn pub key * chore: add test for popBTC validate basic * fix: bip322 verification and test * chore: add check and new PoP BTC for ECDSA * chore: add back check for pop in btc delegation * chore: add back check for equal pop and staker addr in btc delegation * chore: add check for staker addr and nil pop * fix: lint remove unused import * fix: e2e test btc delegation * fix: add pop to random btc del * fix: add wallet name to export node * chore: rename addrHex * chore: address pr comments to remove numbers of verifications, since there is only one * chore: add check for signature types in ProofOfPossessionBTC ValidateBasic * fix: test malfunction * chore: add staker address to BTC delegation response * chore: add e2e btc multisig test (#664) * fix: size of addr and add commands for multisig * chore: add test for multisig BTC delegation * chore: add e2e testing for multisig BTC delegation * chore: refactory e2e test * chore: use creation of random FP * fix: cache fp in first test * chore: test6 use cached finality provider * chore: remove check for pending delegation and only check multisig addr * chore: refactory creation of BTC delegation * chore: reduce node function to create BTC delegation * chore: reduce duplicated code * chore: simplified file paths references * fix: usage of cache FP * chore: add test for btc multisig feegrant (#670) * Few fixes to script docs (#669) * chore: add query to get all delegations * feat: add TxFeeGrant to commands * fix: comment in TxFeeGrant * chore: add e2e test to create BTC delegations with feeGrant --------- Co-authored-by: KonradStaniec * fix: misspell possesion to possession * chore: update send command * chore: testing feegrant * chore: add missing params for bank send looking output * chore: add e2e test checking feegrant with spend limits and type of message * chore: enable back other e2e testings for BTC staker * fix: combine outputs --------- Co-authored-by: KonradStaniec --- cmd/babylond/cmd/genhelpers/bls_add.go | 2 +- cmd/babylond/cmd/genhelpers/bls_create.go | 2 +- proto/babylon/btcstaking/v1/btcstaking.proto | 6 +- proto/babylon/btcstaking/v1/events.proto | 4 +- proto/babylon/btcstaking/v1/incentive.proto | 4 +- proto/babylon/btcstaking/v1/pop.proto | 11 + proto/babylon/btcstaking/v1/query.proto | 32 +- proto/babylon/btcstaking/v1/tx.proto | 36 +- test/e2e/btc_staking_e2e_test.go | 524 ++++++++++++++---- test/e2e/configurer/chain/commands.go | 147 ++++- .../configurer/chain/commands_btcstaking.go | 32 +- test/e2e/configurer/chain/node.go | 9 +- .../configurer/chain/queries_btcstaking.go | 11 + test/e2e/containers/containers.go | 6 +- test/e2e/initialization/config.go | 2 +- test/e2e/initialization/export.go | 1 + test/e2e/initialization/node.go | 1 + testutil/datagen/btcstaking.go | 22 +- testutil/datagen/incentive.go | 3 +- x/btcstaking/client/cli/tx.go | 43 +- x/btcstaking/keeper/genesis_test.go | 3 +- x/btcstaking/keeper/keeper_test.go | 17 +- x/btcstaking/keeper/msg_server.go | 9 +- x/btcstaking/keeper/msg_server_test.go | 15 +- x/btcstaking/types/btc_delegation.go | 9 +- x/btcstaking/types/btcstaking.pb.go | 206 ++++--- x/btcstaking/types/incentive.go | 4 +- x/btcstaking/types/incentive.pb.go | 113 ++-- x/btcstaking/types/msg.go | 8 +- x/btcstaking/types/pop.go | 275 +++++++-- x/btcstaking/types/pop.pb.go | 256 ++++++++- x/btcstaking/types/pop_test.go | 206 ++++++- x/btcstaking/types/query.go | 1 + x/btcstaking/types/query.pb.go | 379 +++++++------ x/btcstaking/types/tx.pb.go | 327 +++++------ 35 files changed, 1897 insertions(+), 829 deletions(-) diff --git a/cmd/babylond/cmd/genhelpers/bls_add.go b/cmd/babylond/cmd/genhelpers/bls_add.go index 70d0a9f91..8cae9f906 100644 --- a/cmd/babylond/cmd/genhelpers/bls_add.go +++ b/cmd/babylond/cmd/genhelpers/bls_add.go @@ -16,7 +16,7 @@ import ( "github.com/babylonchain/babylon/x/checkpointing/types" ) -// CmdAddBls CLI adds the BLS key file with proof of possesion into the genesis state. +// CmdAddBls CLI adds the BLS key file with proof of possession into the genesis state. func CmdAddBls(validator genutiltypes.MessageValidator) *cobra.Command { cmd := &cobra.Command{ Use: "add-bls [genesis_bls_file]", diff --git a/cmd/babylond/cmd/genhelpers/bls_create.go b/cmd/babylond/cmd/genhelpers/bls_create.go index e5f0ff0f8..5c041d738 100644 --- a/cmd/babylond/cmd/genhelpers/bls_create.go +++ b/cmd/babylond/cmd/genhelpers/bls_create.go @@ -14,7 +14,7 @@ import ( "github.com/babylonchain/babylon/privval" ) -// CmdCreateBls CLI command to create BLS file with proof of possesion. +// CmdCreateBls CLI command to create BLS file with proof of possession. func CmdCreateBls() *cobra.Command { cmd := &cobra.Command{ Use: "create-bls", diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 9f9778a5c..d1b70ef5a 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -56,13 +56,13 @@ message FinalityProviderWithMeta { // BTCDelegation defines a BTC delegation message BTCDelegation { - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - cosmos.crypto.secp256k1.PubKey babylon_pk = 1; + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 3; + ProofOfPossessionBTC pop = 3; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to // If there is more than 1 PKs, then this means the delegation is restaked diff --git a/proto/babylon/btcstaking/v1/events.proto b/proto/babylon/btcstaking/v1/events.proto index 6bf54f882..1de3137a6 100644 --- a/proto/babylon/btcstaking/v1/events.proto +++ b/proto/babylon/btcstaking/v1/events.proto @@ -14,7 +14,7 @@ message EventNewFinalityProvider { FinalityProvider fp = 1; } // - non-existing -> pending, which happens upon `MsgCreateBTCDelegation` // - pending -> active, which happens upon `MsgAddCovenantSigs` // - active -> unbonded, which happens upon `MsgBTCUndelegate` or upon staking tx timelock expires -message EventBTCDelegationStateUpdate { +message EventBTCDelegationStateUpdate { // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 1; @@ -22,7 +22,7 @@ message EventBTCDelegationStateUpdate { BTCDelegationStatus new_state = 2; } -// EventSelectiveSlashing is the event emitted when an adversarial +// EventSelectiveSlashing is the event emitted when an adversarial // finality provider selectively slashes a BTC delegation. This will // result in slashing of all BTC delegations under this finality provider. message EventSelectiveSlashing { diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index ad9efaa0b..314d5db1b 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -38,8 +38,8 @@ message BTCDelDistInfo { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // babylon_pk is the Babylon public key of the BTC delegation - cosmos.crypto.secp256k1.PubKey babylon_pk = 2; + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // staking_tx_hash is the staking tx hash of the BTC delegation string staking_tx_hash = 3; // voting_power is the voting power of the BTC delegation diff --git a/proto/babylon/btcstaking/v1/pop.proto b/proto/babylon/btcstaking/v1/pop.proto index fa3ae87d8..1856941d2 100644 --- a/proto/babylon/btcstaking/v1/pop.proto +++ b/proto/babylon/btcstaking/v1/pop.proto @@ -27,6 +27,17 @@ message ProofOfPossession { bytes btc_sig = 3; } +// ProofOfPossessionBTC is the proof of possession that a Babylon +// address and a Bitcoin secp256k1 secret key are held by the same +// person +message ProofOfPossessionBTC { + // btc_sig_type indicates the type of btc_sig in the pop + BTCSigType btc_sig_type = 1; + // btc_sig is the signature generated via sign(sk_btc, babylon_staker_address) + // the signature follows encoding in either BIP-340 spec or BIP-322 spec + bytes btc_sig = 2; +} + // BIP322Sig is a BIP-322 signature together with the address corresponding to // the signer message BIP322Sig { diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index e3f385b57..995984eba 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -244,46 +244,48 @@ message QueryBTCDelegationResponse { // BTCDelegationResponse is the client needed information from a BTCDelegation with the current status based on parameters. message BTCDelegationResponse { + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to - repeated bytes fp_btc_pk_list = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock - uint64 start_height = 3; + uint64 start_height = 4; // end_height is the end height of the BTC delegation // it is the end BTC height of the timelock - w - uint64 end_height = 4; + uint64 end_height = 5; // total_sat is the total amount of BTC stakes in this delegation // quantified in satoshi - uint64 total_sat = 5; + uint64 total_sat = 6; // staking_tx_hex is the hex string of staking tx - string staking_tx_hex = 6; + string staking_tx_hex = 7; // slashing_tx_hex is the hex string of slashing tx - string slashing_tx_hex = 7; + string slashing_tx_hex = 8; // delegator_slash_sig_hex is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk) as string hex. // It will be a part of the witness for the staking tx output. - string delegator_slash_sig_hex = 8; + string delegator_slash_sig_hex = 9; // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. - repeated CovenantAdaptorSignatures covenant_sigs = 9; + repeated CovenantAdaptorSignatures covenant_sigs = 10; // staking_output_idx is the index of the staking output in the staking tx - uint32 staking_output_idx = 10; + uint32 staking_output_idx = 11; // whether this delegation is active - bool active = 11; + bool active = 12; // descriptive status of current delegation. - string status_desc = 12; + string status_desc = 13; // unbonding_time used in unbonding output timelock path and in slashing transactions // change outputs - uint32 unbonding_time = 13; + uint32 unbonding_time = 14; // undelegation_response is the undelegation info of this delegation. - BTCUndelegationResponse undelegation_response = 14; + BTCUndelegationResponse undelegation_response = 15; // params version used to validate delegation - uint32 params_version = 15; + uint32 params_version = 16; } // BTCUndelegationResponse provides all necessary info about the undeleagation diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index 8d2d5a642..dcec9bc1a 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -80,50 +80,48 @@ message MsgEditFinalityProviderResponse {} // MsgCreateBTCDelegation is the message for creating a BTC delegation message MsgCreateBTCDelegation { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - cosmos.crypto.secp256k1.PubKey babylon_pk = 2; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 3; + option (cosmos.msg.v1.signer) = "staker_addr"; + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // pop is the proof of possession of btc_pk by the staker_addr. + ProofOfPossessionBTC pop = 2; // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - repeated bytes fp_btc_pk_list = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // staking_time is the time lock used in staking transaction - uint32 staking_time = 6; + uint32 staking_time = 5; // staking_value is the amount of satoshis locked in staking output - int64 staking_value = 7; + int64 staking_value = 6; // staking_tx is the staking tx along with the merkle proof of inclusion in btc block - babylon.btccheckpoint.v1.TransactionInfo staking_tx = 8; + babylon.btccheckpoint.v1.TransactionInfo staking_tx = 7; // slashing_tx is the slashing tx // Note that the tx itself does not contain signatures, which are off-chain. - bytes slashing_tx = 9 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + bytes slashing_tx = 8 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - bytes delegator_slashing_sig = 10 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output // - unbonding slashing transaction, change output // It must be smaller than math.MaxUInt16 and larger that max(MinUnbondingTime, CheckpointFinalizationTimeout) - uint32 unbonding_time = 11; + uint32 unbonding_time = 10; // fields related to unbonding transaction // unbonding_tx is a bitcoin unbonding transaction i.e transaction that spends // staking output and sends it to the unbonding output - bytes unbonding_tx = 12; + bytes unbonding_tx = 11; // unbonding_value is amount of satoshis locked in unbonding output. // NOTE: staking_value and unbonding_value could be different because of the difference between the fee for staking tx and that for unbonding - int64 unbonding_value = 13; + int64 unbonding_value = 12; // unbonding_slashing_tx is the slashing tx which slash unbonding contract // Note that the tx itself does not contain signatures, which are off-chain. - bytes unbonding_slashing_tx = 14 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + bytes unbonding_slashing_tx = 13 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - bytes delegator_unbonding_slashing_sig = 15 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; } // MsgCreateBTCDelegationResponse is the response for MsgCreateBTCDelegation message MsgCreateBTCDelegationResponse {} diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index cdd0a69da..9ff521a0c 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -2,6 +2,7 @@ package e2e import ( "encoding/hex" + "fmt" "math" "math/rand" "time" @@ -10,10 +11,14 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" + sdkmath "cosmossdk.io/math" + "cosmossdk.io/x/feegrant" + feegrantcli "cosmossdk.io/x/feegrant/client/cli" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/app/params" "github.com/babylonchain/babylon/crypto/eots" "github.com/babylonchain/babylon/test/e2e/configurer" "github.com/babylonchain/babylon/test/e2e/configurer/chain" @@ -31,7 +36,7 @@ var ( net = &chaincfg.SimNetParams // finality provider fpBTCSK, _, _ = datagen.GenRandomBTCKeyPair(r) - fp *bstypes.FinalityProvider + cacheFP *bstypes.FinalityProvider // BTC delegation delBTCSK, delBTCPK, _ = datagen.GenRandomBTCKeyPair(r) // covenant @@ -75,21 +80,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) - /* - create a random finality provider on Babylon - */ - // NOTE: we use the node's secret key as Babylon secret key for the finality provider - fp, err = datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, nonValidatorNode.SecretKey) - s.NoError(err) - nonValidatorNode.CreateFinalityProvider(fp.BabylonPk, fp.BtcPk, fp.Pop, fp.Description.Moniker, fp.Description.Identity, fp.Description.Website, fp.Description.SecurityContact, fp.Description.Details, fp.Commission) - - // wait for a block so that above txs take effect - nonValidatorNode.WaitForNextBlock() - - // query the existence of finality provider and assert equivalence - actualFps := nonValidatorNode.QueryFinalityProviders() - s.Len(actualFps, 1) - s.equalFinalityProviderResp(fp, actualFps[0]) + cacheFP = s.CreateRandomFP(nonValidatorNode) /* create a random BTC delegation under this finality provider @@ -100,88 +91,24 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { // minimal required unbonding time unbondingTime := uint16(initialization.BabylonBtcFinalizationPeriod) + 1 - // get covenant BTC PKs - covenantBTCPKs := []*btcec.PublicKey{} - for _, covenantPK := range params.CovenantPks { - covenantBTCPKs = append(covenantBTCPKs, covenantPK.MustToBTCPK()) - } - // NOTE: we use the node's secret key as Babylon secret key for the BTC delegation - delBabylonSK := nonValidatorNode.SecretKey - pop, err := bstypes.NewPoP(delBabylonSK, delBTCSK) + // NOTE: we use the node's address for the BTC delegation + stakerAddr := sdk.MustAccAddressFromBech32(nonValidatorNode.PublicAddress) + pop, err := bstypes.NewPoPBTC(stakerAddr, delBTCSK) s.NoError(err) + // generate staking tx and slashing tx stakingTimeBlocks := uint16(math.MaxUint16) - testStakingInfo := datagen.GenBTCStakingSlashingInfo( - r, - s.T(), - net, - delBTCSK, - []*btcec.PublicKey{fp.BtcPk.MustToBTCPK()}, - covenantBTCPKs, - covenantQuorum, - stakingTimeBlocks, - stakingValue, - params.SlashingAddress, - params.SlashingRate, - unbondingTime, - ) + testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP) - stakingMsgTx := testStakingInfo.StakingTx - stakingTxHash := stakingMsgTx.TxHash().String() - stakingSlashingPathInfo, err := testStakingInfo.StakingInfo.SlashingPathSpendInfo() - s.NoError(err) - - // generate proper delegator sig - delegatorSig, err := testStakingInfo.SlashingTx.Sign( - stakingMsgTx, - datagen.StakingOutIdx, - stakingSlashingPathInfo.GetPkScriptPath(), - delBTCSK, - ) - s.NoError(err) - - // submit staking tx to Bitcoin and get inclusion proof - currentBtcTipResp, err := nonValidatorNode.QueryTip() - s.NoError(err) - currentBtcTip, err := chain.ParseBTCHeaderInfoResponseToInfo(currentBtcTipResp) - s.NoError(err) - - blockWithStakingTx := datagen.CreateBlockWithTransaction(r, currentBtcTip.Header.ToBlockHeader(), stakingMsgTx) - nonValidatorNode.InsertHeader(&blockWithStakingTx.HeaderBytes) - // make block k-deep - for i := 0; i < initialization.BabylonBtcConfirmationPeriod; i++ { - nonValidatorNode.InsertNewEmptyBtcHeader(r) - } - stakingTxInfo := btcctypes.NewTransactionInfoFromSpvProof(blockWithStakingTx.SpvProof) - - // generate BTC undelegation stuff - stkTxHash := testStakingInfo.StakingTx.TxHash() - unbondingValue := stakingValue - datagen.UnbondingTxFee // TODO: parameterise fee - testUnbondingInfo := datagen.GenBTCUnbondingSlashingInfo( - r, - s.T(), - net, - delBTCSK, - []*btcec.PublicKey{fp.BtcPk.MustToBTCPK()}, - covenantBTCPKs, - covenantQuorum, - wire.NewOutPoint(&stkTxHash, datagen.StakingOutIdx), - stakingTimeBlocks, - unbondingValue, - params.SlashingAddress, - params.SlashingRate, - unbondingTime, - ) delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) s.NoError(err) // submit the message for creating BTC delegation nonValidatorNode.CreateBTCDelegation( - delBabylonSK.PubKey().(*secp256k1.PubKey), bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), pop, stakingTxInfo, - fp.BtcPk, + cacheFP.BtcPk, stakingTimeBlocks, btcutil.Amount(stakingValue), testStakingInfo.SlashingTx, @@ -189,15 +116,16 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { testUnbondingInfo.UnbondingTx, testUnbondingInfo.SlashingTx, uint16(unbondingTime), - btcutil.Amount(unbondingValue), + btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), delUnbondingSlashingSig, + nonValidatorNode.WalletName, + false, ) // wait for a block so that above txs take effect nonValidatorNode.WaitForNextBlock() - nonValidatorNode.WaitForNextBlock() - pendingDelSet := nonValidatorNode.QueryFinalityProviderDelegations(fp.BtcPk.MarshalHex()) + pendingDelSet := nonValidatorNode.QueryFinalityProviderDelegations(cacheFP.BtcPk.MarshalHex()) s.Len(pendingDelSet, 1) pendingDels := pendingDelSet[0] s.Len(pendingDels.Dels, 1) @@ -205,8 +133,9 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { s.Len(pendingDels.Dels[0].CovenantSigs, 0) // check delegation - delegation := nonValidatorNode.QueryBtcDelegation(stakingTxHash) + delegation := nonValidatorNode.QueryBtcDelegation(testStakingInfo.StakingTx.TxHash().String()) s.NotNil(delegation) + s.Equal(delegation.BtcDelegation.StakerAddr, nonValidatorNode.PublicAddress) } // Test2SubmitCovenantSignature is an end-to-end test for user @@ -218,7 +147,7 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { s.NoError(err) // get last BTC delegation - pendingDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(fp.BtcPk.MarshalHex()) + pendingDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(cacheFP.BtcPk.MarshalHex()) s.Len(pendingDelsSet, 1) pendingDels := pendingDelsSet[0] s.Len(pendingDels.Dels, 1) @@ -303,7 +232,7 @@ func (s *BTCStakingTestSuite) Test2SubmitCovenantSignature() { nonValidatorNode.WaitForNextBlock() // ensure the BTC delegation has covenant sigs now - activeDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(fp.BtcPk.MarshalHex()) + activeDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(cacheFP.BtcPk.MarshalHex()) s.Len(activeDelsSet, 1) activeDels, err := ParseRespsBTCDelToBTCDel(activeDelsSet[0]) @@ -362,7 +291,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat nonValidatorNode.WaitForNextBlock() var prCommitMap map[uint64]*ftypes.PubRandCommitResponse s.Eventually(func() bool { - prCommitMap = nonValidatorNode.QueryListPubRandCommit(fp.BtcPk) + prCommitMap = nonValidatorNode.QueryListPubRandCommit(cacheFP.BtcPk) return len(prCommitMap) > 0 }, time.Minute, time.Second*5) s.Equal(prCommitMap[activatedHeight].NumPubRand, msgCommitPubRandList.NumPubRand) @@ -391,7 +320,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat s.NoError(err) eotsSig := bbn.NewSchnorrEOTSSigFromModNScalar(sig) // submit finality signature - nonValidatorNode.AddFinalitySig(fp.BtcPk, activatedHeight, &randListInfo.PRList[idx], *randListInfo.ProofList[idx].ToProto(), appHash, eotsSig) + nonValidatorNode.AddFinalitySig(cacheFP.BtcPk, activatedHeight, &randListInfo.PRList[idx], *randListInfo.ProofList[idx].ToProto(), appHash, eotsSig) // ensure vote is eventually cast nonValidatorNode.WaitForNextBlock() @@ -401,7 +330,7 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat return len(votes) > 0 }, time.Minute, time.Second*5) s.Equal(1, len(votes)) - s.Equal(votes[0].MarshalHex(), fp.BtcPk.MarshalHex()) + s.Equal(votes[0].MarshalHex(), cacheFP.BtcPk.MarshalHex()) // once the vote is cast, ensure block is finalised finalizedBlock := nonValidatorNode.QueryIndexedBlock(activatedHeight) s.NotEmpty(finalizedBlock) @@ -493,7 +422,7 @@ func (s *BTCStakingTestSuite) Test5SubmitStakerUnbonding() { // wait for a block so that above txs take effect nonValidatorNode.WaitForNextBlock() - activeDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(fp.BtcPk.MarshalHex()) + activeDelsSet := nonValidatorNode.QueryFinalityProviderDelegations(cacheFP.BtcPk.MarshalHex()) s.Len(activeDelsSet, 1) activeDels := activeDelsSet[0] s.Len(activeDels.Dels, 1) @@ -529,6 +458,295 @@ func (s *BTCStakingTestSuite) Test5SubmitStakerUnbonding() { s.Equal(stakingTxHash, unbondDel.MustGetStakingTxHash()) } +// Test6MultisigBTCDelegation is an end-to-end test to create a BTC delegation +// with multisignature. It also utilizes the cacheFP populated at +// Test1CreateFinalityProviderAndDelegation. +func (s *BTCStakingTestSuite) Test6MultisigBTCDelegation() { + chainA := s.configurer.GetChainConfig(0) + chainA.WaitUntilHeight(1) + nonValidatorNode, err := chainA.GetNodeAtIndex(2) + s.NoError(err) + + w1, w2, wMultisig := "multisig-holder-1", "multisig-holder-2", "multisig-2of2" + + nonValidatorNode.KeysAdd(w1) + nonValidatorNode.KeysAdd(w2) + // creates and fund multisig + multisigAddr := nonValidatorNode.KeysAdd(wMultisig, []string{fmt.Sprintf("--multisig=%s,%s", w1, w2), "--multisig-threshold=2"}...) + nonValidatorNode.BankSendFromNode(multisigAddr, "100000ubbn") + + // create a random BTC delegation under the cached finality provider + // BTC staking params, BTC delegation key pairs and PoP + params := nonValidatorNode.QueryBTCStakingParams() + + // minimal required unbonding time + unbondingTime := uint16(initialization.BabylonBtcFinalizationPeriod) + 1 + + // NOTE: we use the multisig address for the BTC delegation + multisigStakerAddr := sdk.MustAccAddressFromBech32(multisigAddr) + pop, err := bstypes.NewPoPBTC(multisigStakerAddr, delBTCSK) + s.NoError(err) + + // generate staking tx and slashing tx + stakingTimeBlocks := uint16(math.MaxUint16) + testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, params, stakingTimeBlocks, cacheFP) + + delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) + s.NoError(err) + + // submit the message for only generate the Tx to create BTC delegation + jsonTx := nonValidatorNode.CreateBTCDelegation( + bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), + pop, + stakingTxInfo, + cacheFP.BtcPk, + stakingTimeBlocks, + btcutil.Amount(stakingValue), + testStakingInfo.SlashingTx, + delegatorSig, + testUnbondingInfo.UnbondingTx, + testUnbondingInfo.SlashingTx, + uint16(unbondingTime), + btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), + delUnbondingSlashingSig, + multisigAddr, + true, + ) + + // write the tx to a file + fullPathTxBTCDelegation := nonValidatorNode.WriteFile("tx.json", jsonTx) + // signs the tx with the 2 wallets and the multisig and broadcast the tx + nonValidatorNode.TxMultisignBroadcast(wMultisig, fullPathTxBTCDelegation, []string{w1, w2}) + + // wait for a block so that above txs take effect + nonValidatorNode.WaitForNextBlock() + + // check delegation with the multisig staker address exists. + delegation := nonValidatorNode.QueryBtcDelegation(testStakingInfo.StakingTx.TxHash().String()) + s.NotNil(delegation) + s.Equal(multisigAddr, delegation.BtcDelegation.StakerAddr) +} + +// Test7BTCDelegationFeeGrant is an end-to-end test to create a BTC delegation +// from a BTC delegator that does not have funds to pay for fees. It also +// utilizes the cacheFP populated at Test1CreateFinalityProviderAndDelegation. +func (s *BTCStakingTestSuite) Test7BTCDelegationFeeGrant() { + chainA := s.configurer.GetChainConfig(0) + chainA.WaitUntilHeight(1) + nonValidatorNode, err := chainA.GetNodeAtIndex(2) + s.NoError(err) + + wGratee, wGranter := "grantee", "granter" + feePayerAddr := sdk.MustAccAddressFromBech32(nonValidatorNode.KeysAdd(wGranter)) + granteeStakerAddr := sdk.MustAccAddressFromBech32(nonValidatorNode.KeysAdd(wGratee)) + + feePayerBalanceBeforeBTCDel := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(100000)) + fees := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(50000)) + + // fund the granter + nonValidatorNode.BankSendFromNode(feePayerAddr.String(), feePayerBalanceBeforeBTCDel.String()) + + // create a random BTC delegation under the cached finality provider + // BTC staking btcStkParams, BTC delegation key pairs and PoP + btcStkParams := nonValidatorNode.QueryBTCStakingParams() + + // minimal required unbonding time + unbondingTime := uint16(initialization.BabylonBtcFinalizationPeriod) + 1 + + // NOTE: we use the grantee staker address for the BTC delegation PoP + pop, err := bstypes.NewPoPBTC(granteeStakerAddr, delBTCSK) + s.NoError(err) + + // generate staking tx and slashing tx + stakingTimeBlocks := uint16(math.MaxUint16) - 5 + testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(nonValidatorNode, btcStkParams, stakingTimeBlocks, cacheFP) + + delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) + s.NoError(err) + + // conceive the fee grant from the payer to the staker. + nonValidatorNode.TxFeeGrant(feePayerAddr.String(), granteeStakerAddr.String(), fmt.Sprintf("--from=%s", wGranter)) + // wait for a block to take effect the fee grant tx. + nonValidatorNode.WaitForNextBlock() + + // staker should not have any balance. + stakerBalances, err := nonValidatorNode.QueryBalances(granteeStakerAddr.String()) + s.NoError(err) + s.True(stakerBalances.IsZero()) + + // submit the message to create BTC delegation + nonValidatorNode.CreateBTCDelegation( + bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), + pop, + stakingTxInfo, + cacheFP.BtcPk, + stakingTimeBlocks, + btcutil.Amount(stakingValue), + testStakingInfo.SlashingTx, + delegatorSig, + testUnbondingInfo.UnbondingTx, + testUnbondingInfo.SlashingTx, + uint16(unbondingTime), + btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), + delUnbondingSlashingSig, + wGratee, + false, + fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + fmt.Sprintf("--fees=%s", fees.String()), + ) + + // wait for a block so that above txs take effect + nonValidatorNode.WaitForNextBlock() + + // check the delegation was success. + delegation := nonValidatorNode.QueryBtcDelegation(testStakingInfo.StakingTx.TxHash().String()) + s.NotNil(delegation) + s.Equal(granteeStakerAddr.String(), delegation.BtcDelegation.StakerAddr) + + // verify the balances after the BTC delegation was submited + // the staker should continue to have zero as balance. + stakerBalances, err = nonValidatorNode.QueryBalances(granteeStakerAddr.String()) + s.NoError(err) + s.True(stakerBalances.IsZero()) + + // the fee payer should have the (feePayerBalanceBeforeBTCDel - fee) == currentBalance + feePayerBalances, err := nonValidatorNode.QueryBalances(feePayerAddr.String()) + s.NoError(err) + s.Equal(feePayerBalanceBeforeBTCDel.Sub(fees).String(), feePayerBalances.String()) +} + +// Test8BTCDelegationFeeGrantTyped is an end-to-end test to create a BTC delegation +// from a BTC delegator that does not have funds to pay for fees and explore scenarios +// to verify if the feeGrant is respected by the msg type and also spend limits. It also +// utilizes the cacheFP populated at Test1CreateFinalityProviderAndDelegation. +func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { + chainA := s.configurer.GetChainConfig(0) + chainA.WaitUntilHeight(1) + node, err := chainA.GetNodeAtIndex(2) + s.NoError(err) + + wGratee, wGranter := "staker", "feePayer" + feePayerAddr := sdk.MustAccAddressFromBech32(node.KeysAdd(wGranter)) + granteeStakerAddr := sdk.MustAccAddressFromBech32(node.KeysAdd(wGratee)) + + feePayerBalanceBeforeBTCDel := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(100000)) + stakerBalance := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(100)) + fees := sdk.NewCoin(params.DefaultBondDenom, sdkmath.NewInt(50000)) + + // fund the granter and the staker + node.BankSendFromNode(feePayerAddr.String(), feePayerBalanceBeforeBTCDel.String()) + node.BankSendFromNode(granteeStakerAddr.String(), stakerBalance.String()) + + // create a random BTC delegation under the cached finality provider + // BTC staking btcStkParams, BTC delegation key pairs and PoP + btcStkParams := node.QueryBTCStakingParams() + + // minimal required unbonding time + unbondingTime := uint16(initialization.BabylonBtcFinalizationPeriod) + 1 + + // NOTE: we use the grantee staker address for the BTC delegation PoP + pop, err := bstypes.NewPoPBTC(granteeStakerAddr, delBTCSK) + s.NoError(err) + + // generate staking tx and slashing tx + stakingTimeBlocks := uint16(math.MaxUint16) - 2 + testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig := s.BTCStakingUnbondSlashInfo(node, btcStkParams, stakingTimeBlocks, cacheFP) + + delUnbondingSlashingSig, err := testUnbondingInfo.GenDelSlashingTxSig(delBTCSK) + s.NoError(err) + + // conceive the fee grant from the payer to the staker only for one specific msg type. + node.TxFeeGrant( + feePayerAddr.String(), granteeStakerAddr.String(), + fmt.Sprintf("--from=%s", wGranter), + fmt.Sprintf("--%s=%s", feegrantcli.FlagSpendLimit, fees.String()), + fmt.Sprintf("--%s=%s", feegrantcli.FlagAllowedMsgs, sdk.MsgTypeURL(&bstypes.MsgCreateBTCDelegation{})), + ) + // wait for a block to take effect the fee grant tx. + node.WaitForNextBlock() + + // tries to create a send transaction putting the freegranter as feepayer, it should FAIL + // since we only gave grant for BTC delegation msgs. + outBuff, errBuff, err := node.BankSendOutput( + wGratee, node.PublicAddress, stakerBalance.String(), + fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + ) + outputStr := outBuff.String() + errBuff.String() + s.Require().Contains(outputStr, fmt.Sprintf("code: %d", feegrant.ErrMessageNotAllowed.ABCICode())) + s.Require().Contains(outputStr, feegrant.ErrMessageNotAllowed.Error()) + s.Nil(err) + + // staker should not have lost any balance. + stakerBalances, err := node.QueryBalances(granteeStakerAddr.String()) + s.Require().NoError(err) + s.Require().Equal(stakerBalance.String(), stakerBalances.String()) + + // submit the message to create BTC delegation using the fee grant + // but putting as fee more than the spend limit + // it should fail by exceeding the fee limit. + output := node.CreateBTCDelegation( + bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), + pop, + stakingTxInfo, + cacheFP.BtcPk, + stakingTimeBlocks, + btcutil.Amount(stakingValue), + testStakingInfo.SlashingTx, + delegatorSig, + testUnbondingInfo.UnbondingTx, + testUnbondingInfo.SlashingTx, + uint16(unbondingTime), + btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), + delUnbondingSlashingSig, + wGratee, + false, + fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + fmt.Sprintf("--fees=%s", fees.Add(stakerBalance).String()), + ) + s.Require().Contains(output, fmt.Sprintf("code: %d", feegrant.ErrFeeLimitExceeded.ABCICode())) + s.Require().Contains(output, feegrant.ErrFeeLimitExceeded.Error()) + + // submit the message to create BTC delegation using the fee grant at the max of spend limit + node.CreateBTCDelegation( + bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), + pop, + stakingTxInfo, + cacheFP.BtcPk, + stakingTimeBlocks, + btcutil.Amount(stakingValue), + testStakingInfo.SlashingTx, + delegatorSig, + testUnbondingInfo.UnbondingTx, + testUnbondingInfo.SlashingTx, + uint16(unbondingTime), + btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), + delUnbondingSlashingSig, + wGratee, + false, + fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + fmt.Sprintf("--fees=%s", fees.String()), + ) + + // wait for a block so that above txs take effect + node.WaitForNextBlock() + + // check the delegation was success. + delegation := node.QueryBtcDelegation(testStakingInfo.StakingTx.TxHash().String()) + s.NotNil(delegation) + s.Equal(granteeStakerAddr.String(), delegation.BtcDelegation.StakerAddr) + + // verify the balances after the BTC delegation was submited + // the staker should continue to have zero as balance. + stakerBalances, err = node.QueryBalances(granteeStakerAddr.String()) + s.NoError(err) + s.Equal(stakerBalance.String(), stakerBalances.String()) + + // the fee payer should have the (feePayerBalanceBeforeBTCDel - fee) == currentBalance + feePayerBalances, err := node.QueryBalances(feePayerAddr.String()) + s.NoError(err) + s.Equal(feePayerBalanceBeforeBTCDel.Sub(fees).String(), feePayerBalances.String()) +} + // ParseRespsBTCDelToBTCDel parses an BTC delegation response to BTC Delegation func ParseRespsBTCDelToBTCDel(resp *bstypes.BTCDelegatorDelegationsResponse) (btcDels *bstypes.BTCDelegatorDelegations, err error) { if resp == nil { @@ -566,8 +784,7 @@ func ParseRespBTCDelToBTCDel(resp *bstypes.BTCDelegationResponse) (btcDel *bstyp } btcDel = &bstypes.BTCDelegation{ - // missing BabylonPk, Pop - // these fields are not sent out to the client on BTCDelegationResponse + StakerAddr: resp.StakerAddr, BtcPk: resp.BtcPk, FpBtcPkList: resp.FpBtcPkList, StartHeight: resp.StartHeight, @@ -627,3 +844,110 @@ func (s *BTCStakingTestSuite) equalFinalityProviderResp(fp *bstypes.FinalityProv s.Equal(fp.SlashedBabylonHeight, fpResp.SlashedBabylonHeight) s.Equal(fp.SlashedBtcHeight, fpResp.SlashedBtcHeight) } + +// CreateRandomFP creates a random finality provider. +func (s *BTCStakingTestSuite) CreateRandomFP(node *chain.NodeConfig) (newFP *bstypes.FinalityProvider) { + newFP, err := datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, node.SecretKey) + s.NoError(err) + node.CreateFinalityProvider(newFP.BabylonPk, newFP.BtcPk, newFP.Pop, newFP.Description.Moniker, newFP.Description.Identity, newFP.Description.Website, newFP.Description.SecurityContact, newFP.Description.Details, newFP.Commission) + + // wait for a block so that above txs take effect + node.WaitForNextBlock() + + // query the existence of finality provider and assert equivalence + actualFps := node.QueryFinalityProviders() + s.Len(actualFps, 1) + s.equalFinalityProviderResp(newFP, actualFps[0]) + + return newFP +} + +// CovenantBTCPKs returns the covenantBTCPks as slice from parameters +func CovenantBTCPKs(params *bstypes.Params) []*btcec.PublicKey { + // get covenant BTC PKs + covenantBTCPKs := make([]*btcec.PublicKey, len(params.CovenantPks)) + for i, covenantPK := range params.CovenantPks { + covenantBTCPKs[i] = covenantPK.MustToBTCPK() + } + return covenantBTCPKs +} + +// BTCStakingUnbondSlashInfo generate BTC information to create BTC delegation. +func (s *BTCStakingTestSuite) BTCStakingUnbondSlashInfo( + node *chain.NodeConfig, + params *bstypes.Params, + stakingTimeBlocks uint16, + fp *bstypes.FinalityProvider, +) ( + testStakingInfo *datagen.TestStakingSlashingInfo, + stakingTxInfo *btcctypes.TransactionInfo, + testUnbondingInfo *datagen.TestUnbondingSlashingInfo, + delegatorSig *bbn.BIP340Signature, +) { + covenantBTCPKs := CovenantBTCPKs(params) + // minimal required unbonding time + unbondingTime := uint16(initialization.BabylonBtcFinalizationPeriod) + 1 + + testStakingInfo = datagen.GenBTCStakingSlashingInfo( + r, + s.T(), + net, + delBTCSK, + []*btcec.PublicKey{fp.BtcPk.MustToBTCPK()}, + covenantBTCPKs, + covenantQuorum, + stakingTimeBlocks, + stakingValue, + params.SlashingAddress, + params.SlashingRate, + unbondingTime, + ) + + // submit staking tx to Bitcoin and get inclusion proof + currentBtcTipResp, err := node.QueryTip() + s.NoError(err) + currentBtcTip, err := chain.ParseBTCHeaderInfoResponseToInfo(currentBtcTipResp) + s.NoError(err) + + stakingMsgTx := testStakingInfo.StakingTx + + blockWithStakingTx := datagen.CreateBlockWithTransaction(r, currentBtcTip.Header.ToBlockHeader(), stakingMsgTx) + node.InsertHeader(&blockWithStakingTx.HeaderBytes) + // make block k-deep + for i := 0; i < initialization.BabylonBtcConfirmationPeriod; i++ { + node.InsertNewEmptyBtcHeader(r) + } + stakingTxInfo = btcctypes.NewTransactionInfoFromSpvProof(blockWithStakingTx.SpvProof) + + // generate BTC undelegation stuff + stkTxHash := testStakingInfo.StakingTx.TxHash() + unbondingValue := stakingValue - datagen.UnbondingTxFee + testUnbondingInfo = datagen.GenBTCUnbondingSlashingInfo( + r, + s.T(), + net, + delBTCSK, + []*btcec.PublicKey{fp.BtcPk.MustToBTCPK()}, + covenantBTCPKs, + covenantQuorum, + wire.NewOutPoint(&stkTxHash, datagen.StakingOutIdx), + stakingTimeBlocks, + unbondingValue, + params.SlashingAddress, + params.SlashingRate, + unbondingTime, + ) + + stakingSlashingPathInfo, err := testStakingInfo.StakingInfo.SlashingPathSpendInfo() + s.NoError(err) + + delegatorSig, err = testStakingInfo.SlashingTx.Sign( + stakingMsgTx, + datagen.StakingOutIdx, + stakingSlashingPathInfo.GetPkScriptPath(), + delBTCSK, + ) + s.NoError(err) + + return testStakingInfo, stakingTxInfo, testUnbondingInfo, delegatorSig +} diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index cc316188f..8d8c59b1a 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -1,15 +1,19 @@ package chain import ( + "bytes" "encoding/hex" "encoding/json" "fmt" "math/rand" + "os" + "path/filepath" "regexp" "strings" "time" txformat "github.com/babylonchain/babylon/btctxformatter" + "github.com/babylonchain/babylon/test/e2e/containers" "github.com/babylonchain/babylon/test/e2e/initialization" "github.com/babylonchain/babylon/test/e2e/util" "github.com/babylonchain/babylon/testutil/datagen" @@ -23,15 +27,32 @@ import ( "github.com/stretchr/testify/require" ) +const ( + flagKeyringTest = "--keyring-backend=test" +) + func (n *NodeConfig) GetWallet(walletName string) string { n.LogActionF("retrieving wallet %s", walletName) - cmd := []string{"babylond", "keys", "show", walletName, "--keyring-backend=test"} + cmd := []string{"babylond", "keys", "show", walletName, flagKeyringTest, containers.FlagHome} outBuf, _, err := n.containerManager.ExecCmd(n.t, n.Name, cmd, "") require.NoError(n.t, err) - re := regexp.MustCompile("bbn(.{38})") + re := regexp.MustCompile("bbn(.{39})") + walletAddr := fmt.Sprintf("%s\n", re.FindString(outBuf.String())) + walletAddr = strings.TrimSuffix(walletAddr, "\n") + n.LogActionF("wallet %s found, wallet address - %s", walletName, walletAddr) + return walletAddr +} + +// KeysAdd creates a new key in the keyring +func (n *NodeConfig) KeysAdd(walletName string, overallFlags ...string) string { + n.LogActionF("adding new wallet %s", walletName) + cmd := []string{"babylond", "keys", "add", walletName, flagKeyringTest, containers.FlagHome} + outBuf, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") + require.NoError(n.t, err) + re := regexp.MustCompile("bbn(.{39})") walletAddr := fmt.Sprintf("%s\n", re.FindString(outBuf.String())) walletAddr = strings.TrimSuffix(walletAddr, "\n") - n.LogActionF("wallet %s found, waller address - %s", walletName, walletAddr) + n.LogActionF("wallet %s created, address - %s", walletName, walletAddr) return walletAddr } @@ -69,12 +90,27 @@ func (n *NodeConfig) FailIBCTransfer(from, recipient, amount string) { n.LogActionF("Failed to send IBC transfer (as expected)") } -func (n *NodeConfig) BankSend(amount string, sendAddress string, receiveAddress string) { - n.LogActionF("bank sending %s from address %s to %s", amount, sendAddress, receiveAddress) - cmd := []string{"babylond", "tx", "bank", "send", sendAddress, receiveAddress, amount, "--from=val"} - _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) +func (n *NodeConfig) BankSendFromNode(receiveAddress, amount string) { + n.BankSend(n.WalletName, receiveAddress, amount) +} + +func (n *NodeConfig) BankSend(fromWallet, to, amount string, overallFlags ...string) { + fromAddr := n.GetWallet(fromWallet) + n.LogActionF("bank sending %s from wallet %s to %s", amount, fromWallet, to) + cmd := []string{"babylond", "tx", "bank", "send", fromAddr, to, amount, fmt.Sprintf("--from=%s", fromWallet)} + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) require.NoError(n.t, err) - n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, sendAddress, receiveAddress) + n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, fromWallet, to) +} + +func (n *NodeConfig) BankSendOutput(fromWallet, to, amount string, overallFlags ...string) (out bytes.Buffer, errBuff bytes.Buffer, err error) { + fromAddr := n.GetWallet(fromWallet) + n.LogActionF("bank sending %s from wallet %s to %s", amount, fromWallet, to) + cmd := []string{ + "babylond", "tx", "bank", "send", fromAddr, to, amount, fmt.Sprintf("--from=%s", fromWallet), + n.FlagChainID(), "-b=sync", "--yes", "--keyring-backend=test", "--log_format=json", "--home=/home/babylon/babylondata", + } + return n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") } func (n *NodeConfig) SendHeaderHex(headerHex string) { @@ -235,6 +271,101 @@ func (n *NodeConfig) WithdrawReward(sType, from string) { n.LogActionF("successfully withdrawn") } +// TxMultisigSign sign a tx in a file with one wallet for a multisig address. +func (n *NodeConfig) TxMultisigSign(walletName, multisigAddr, txFileFullPath, fileName string, overallFlags ...string) (fullFilePathInContainer string) { + return n.TxSign(walletName, txFileFullPath, fileName, fmt.Sprintf("--multisig=%s", multisigAddr)) +} + +// TxSign sign a tx in a file with one wallet. +func (n *NodeConfig) TxSign(walletName, txFileFullPath, fileName string, overallFlags ...string) (fullFilePathInContainer string) { + n.LogActionF("wallet %s sign tx file %s", walletName, txFileFullPath) + cmd := []string{ + "babylond", "tx", "sign", txFileFullPath, + fmt.Sprintf("--from=%s", walletName), + n.FlagChainID(), flagKeyringTest, containers.FlagHome, + } + outBuf, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") + require.NoError(n.t, err) + + return n.WriteFile(fileName, outBuf.String()) +} + +// TxMultisign sign a tx in a file. +func (n *NodeConfig) TxMultisign(walletNameMultisig, txFileFullPath, outputFileName string, signedFiles []string, overallFlags ...string) (signedTxFilePath string) { + n.LogActionF("%s multisig tx file %s", walletNameMultisig, txFileFullPath) + cmd := []string{ + "babylond", "tx", "multisign", txFileFullPath, walletNameMultisig, + n.FlagChainID(), + flagKeyringTest, containers.FlagHome, + } + cmd = append(cmd, signedFiles...) + outBuf, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") + require.NoError(n.t, err) + + return n.WriteFile(outputFileName, outBuf.String()) +} + +// TxBroadcast broadcast a signed transaction to the chain. +func (n *NodeConfig) TxBroadcast(txSignedFileFullPath string, overallFlags ...string) { + n.LogActionF("broadcast tx file %s", txSignedFileFullPath) + cmd := []string{ + "babylond", "tx", "broadcast", txSignedFileFullPath, + n.FlagChainID(), + } + _, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") + require.NoError(n.t, err) +} + +// TxFeeGrant creates a fee grant tx. Which the granter is the one that will +// pay the fees for the grantee to submit txs for free. +func (n *NodeConfig) TxFeeGrant(granter, grantee string, overallFlags ...string) { + n.LogActionF("tx fee grant, granter: %s - grantee: %s", granter, grantee) + cmd := []string{ + "babylond", "tx", "feegrant", "grant", granter, grantee, + n.FlagChainID(), + } + _, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, append(cmd, overallFlags...)) + require.NoError(n.t, err) +} + +// TxSignBroadcast signs the tx from the wallet and broadcast to chain. +func (n *NodeConfig) TxSignBroadcast(walletName, txFileFullPath string) { + fileName := fmt.Sprintf("tx-signed-%s.json", walletName) + signedTxToBroadcast := n.TxSign(walletName, txFileFullPath, fileName) + n.TxBroadcast(signedTxToBroadcast) +} + +// TxMultisignBroadcast signs the tx from each wallet and the multisig and broadcast to chain. +func (n *NodeConfig) TxMultisignBroadcast(walletNameMultisig, txFileFullPath string, walleNameSigners []string) { + multisigAddr := n.GetWallet(walletNameMultisig) + + signedFiles := make([]string, len(walleNameSigners)) + for i, wName := range walleNameSigners { + fileName := fmt.Sprintf("tx-signed-%s.json", wName) + signedFiles[i] = n.TxMultisigSign(wName, multisigAddr, txFileFullPath, fileName) + } + + signedTxToBroadcast := n.TxMultisign(walletNameMultisig, txFileFullPath, "tx-multisigned.json", signedFiles) + n.TxBroadcast(signedTxToBroadcast) +} + +// WriteFile writes a new file in the config dir of the node where it is volume mounted to the +// babylon home inside the container and returns the full file path inside the container. +func (n *NodeConfig) WriteFile(fileName, content string) (fullFilePathInContainer string) { + b := bytes.NewBufferString(content) + fileFullPath := filepath.Join(n.ConfigDir, fileName) + + err := os.WriteFile(fileFullPath, b.Bytes(), 0644) + require.NoError(n.t, err) + + return filepath.Join(containers.BabylonHomePath, fileName) +} + +// FlagChainID returns the flag of the chainID. +func (n *NodeConfig) FlagChainID() string { + return fmt.Sprintf("--chain-id=%s", n.chainId) +} + // ParseBTCHeaderInfoResponseToInfo turns an BTCHeaderInfoResponse back to BTCHeaderInfo. func ParseBTCHeaderInfoResponseToInfo(r *blc.BTCHeaderInfoResponse) (*blc.BTCHeaderInfo, error) { header, err := bbn.NewBTCHeaderBytesFromHex(r.HeaderHex) diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index 01ffa2558..dbd713817 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -2,6 +2,7 @@ package chain import ( "encoding/hex" + "fmt" "strconv" "strings" @@ -16,6 +17,7 @@ import ( "github.com/stretchr/testify/require" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + "github.com/babylonchain/babylon/test/e2e/containers" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" @@ -43,9 +45,8 @@ func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK * } func (n *NodeConfig) CreateBTCDelegation( - babylonPK *secp256k1.PubKey, btcPk *bbn.BIP340PubKey, - pop *bstypes.ProofOfPossession, + pop *bstypes.ProofOfPossessionBTC, stakingTxInfo *btcctypes.TransactionInfo, fpPK *bbn.BIP340PubKey, stakingTimeBlocks uint16, @@ -57,14 +58,12 @@ func (n *NodeConfig) CreateBTCDelegation( unbondingTime uint16, unbondingValue btcutil.Amount, delUnbondingSlashingSig *bbn.BIP340Signature, -) { + fromWalletName string, + generateOnly bool, + overallFlags ...string, +) (outStr string) { n.LogActionF("creating BTC delegation") - // get babylon PK hex - babylonPKBytes, err := babylonPK.Marshal() - require.NoError(n.t, err) - babylonPKHex := hex.EncodeToString(babylonPKBytes) - btcPkHex := btcPk.MarshalHex() // get pop hex @@ -94,10 +93,23 @@ func (n *NodeConfig) CreateBTCDelegation( unbondingValueStr := sdkmath.NewInt(int64(unbondingValue)).String() delUnbondingSlashingSigHex := delUnbondingSlashingSig.ToHexStr() - cmd := []string{"babylond", "tx", "btcstaking", "create-btc-delegation", babylonPKHex, btcPkHex, popHex, stakingTxInfoHex, fpPKHex, stakingTimeString, stakingValueString, slashingTxHex, delegatorSigHex, unbondingTxHex, unbondingSlashingTxHex, unbondingTimeStr, unbondingValueStr, delUnbondingSlashingSigHex, "--from=val"} - _, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) + cmd := []string{ + "babylond", "tx", "btcstaking", "create-btc-delegation", + btcPkHex, popHex, stakingTxInfoHex, fpPKHex, stakingTimeString, stakingValueString, slashingTxHex, delegatorSigHex, unbondingTxHex, unbondingSlashingTxHex, unbondingTimeStr, unbondingValueStr, delUnbondingSlashingSigHex, + fmt.Sprintf("--from=%s", fromWalletName), containers.FlagHome, flagKeyringTest, + n.FlagChainID(), "--log_format=json", + } + + if generateOnly { + cmd = append(cmd, "--generate-only") + } else { + cmd = append(cmd, "-b=sync", "--yes") + } + + outBuff, _, err := n.containerManager.ExecCmd(n.t, n.Name, append(cmd, overallFlags...), "") require.NoError(n.t, err) n.LogActionF("successfully created BTC delegation") + return outBuff.String() } func (n *NodeConfig) AddCovenantSigs(covPK *bbn.BIP340PubKey, stakingTxHash string, slashingSigs [][]byte, unbondingSig *bbn.BIP340Signature, unbondingSlashingSigs [][]byte) { diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index 476db4573..8e185ec51 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -141,11 +141,16 @@ func (n *NodeConfig) WaitUntilBtcHeight(height uint64) { } func (n *NodeConfig) WaitForNextBlock() { + n.WaitForNextBlocks(1) +} + +func (n *NodeConfig) WaitForNextBlocks(numberOfBlocks uint64) { latest := n.LatestBlockNumber() + blockToWait := latest + numberOfBlocks n.WaitForCondition(func() bool { newLatest := n.LatestBlockNumber() - return newLatest > latest - }, fmt.Sprintf("Timed out waiting for next block. Current height is: %d", latest)) + return newLatest > blockToWait + }, fmt.Sprintf("Timed out waiting for block %d. Current height is: %d", latest, blockToWait)) } func (n *NodeConfig) extractOperatorAddressIfValidator() error { diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index 824381c1d..60be29f74 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -69,6 +69,17 @@ func (n *NodeConfig) QueryBtcDelegation(stakingTxHash string) *bstypes.QueryBTCD return &resp } +func (n *NodeConfig) QueryBtcDelegations() *bstypes.QueryBTCDelegationsResponse { + bz, err := n.QueryGRPCGateway("/babylon/btcstaking/v1/btc_delegations", url.Values{}) + require.NoError(n.t, err) + + var resp bstypes.QueryBTCDelegationsResponse + err = util.Cdc.UnmarshalJSON(bz, &resp) + require.NoError(n.t, err) + + return &resp +} + func (n *NodeConfig) QueryUnbondedDelegations() []*bstypes.BTCDelegationResponse { queryParams := url.Values{} queryParams.Add("status", fmt.Sprintf("%d", bstypes.BTCDelegationStatus_UNBONDED)) diff --git a/test/e2e/containers/containers.go b/test/e2e/containers/containers.go index 6195562e5..09782d7f1 100644 --- a/test/e2e/containers/containers.go +++ b/test/e2e/containers/containers.go @@ -21,6 +21,8 @@ const ( // The maximum number of times debug logs are printed to console // per CLI command. maxDebugLogsPerCommand = 3 + BabylonHomePath = "/home/babylon/babylondata" + FlagHome = "--home=" + BabylonHomePath ) var errRegex = regexp.MustCompile(`(E|e)rror`) @@ -256,11 +258,11 @@ func (m *Manager) RunNodeResource(chainId string, containerName, valCondifDir st Entrypoint: []string{ "sh", "-c", - "babylond start --home /home/babylon/babylondata", + "babylond start " + FlagHome, }, ExposedPorts: []string{"26656", "26657", "1317", "9090"}, Mounts: []string{ - fmt.Sprintf("%s/:/home/babylon/babylondata", valCondifDir), + fmt.Sprintf("%s/:%s", valCondifDir, BabylonHomePath), fmt.Sprintf("%s/bytecode:/bytecode", pwd), }, } diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index 418a86371..9e5f95a16 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -369,7 +369,7 @@ func updateCheckpointingGenesis(c *internalChain) func(*checkpointingtypes.Genes proofOfPossession, err := privval.BuildPoP(node.consensusKey.PrivKey, node.consensusKey.BlsPrivKey) if err != nil { - panic("It should be possible to build proof of possesion from validator private keys") + panic("It should be possible to build proof of possession from validator private keys") } valPubKey, err := cryptocodec.FromCmtPubKeyInterface(node.consensusKey.PubKey) diff --git a/test/e2e/initialization/export.go b/test/e2e/initialization/export.go index 1da2629ba..663250876 100644 --- a/test/e2e/initialization/export.go +++ b/test/e2e/initialization/export.go @@ -16,6 +16,7 @@ type Node struct { ConfigDir string `json:"configDir"` Mnemonic string `json:"mnemonic"` PublicAddress string `json:"publicAddress"` + WalletName string `json:"walletName"` SecretKey cryptotypes.PrivKey PublicKey []byte `json:"publicKey"` PeerId string `json:"peerId"` diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index 93dbb5da5..d2a8dc1bf 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -247,6 +247,7 @@ func (n *internalNode) export() *Node { ConfigDir: n.configDir(), Mnemonic: n.mnemonic, PublicAddress: addr.String(), + WalletName: n.keyInfo.Name, SecretKey: n.privateKey, PublicKey: pub.Bytes(), PeerId: n.peerId, diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 382df22cc..ab483d0e1 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -6,6 +6,7 @@ import ( "testing" sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" @@ -112,21 +113,8 @@ func GenRandomBTCDelegation( if err != nil { return nil, err } + staker := GenRandomAccount() - // BTC delegation Babylon key pairs - bbnSK, bbnPK, err := GenRandomSecp256k1KeyPair(r) - if err != nil { - return nil, err - } - secp256k1PK, ok := bbnPK.(*secp256k1.PubKey) - if !ok { - return nil, fmt.Errorf("failed to assert bbnPK to *secp256k1.PubKey") - } - // pop - pop, err := bstypes.NewPoP(bbnSK, delSK) - if err != nil { - return nil, err - } // staking/slashing tx stakingSlashingInfo := GenBTCStakingSlashingInfo( r, @@ -168,8 +156,12 @@ func GenRandomBTCDelegation( serializedStakingTx, err := bbn.SerializeBTCTx(stakingSlashingInfo.StakingTx) require.NoError(t, err) w := uint16(100) // TODO: parameterise w + + pop, err := bstypes.NewPoPBTC(sdk.MustAccAddressFromBech32(staker.Address), delSK) + require.NoError(t, err) + del := &bstypes.BTCDelegation{ - BabylonPk: secp256k1PK, + StakerAddr: staker.Address, BtcPk: delBTCPK, Pop: pop, FpBtcPkList: fpBTCPKs, diff --git a/testutil/datagen/incentive.go b/testutil/datagen/incentive.go index c6320860f..b970f1ca2 100644 --- a/testutil/datagen/incentive.go +++ b/testutil/datagen/incentive.go @@ -7,7 +7,6 @@ import ( btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" itypes "github.com/babylonchain/babylon/x/incentive/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -84,7 +83,7 @@ func GenRandomBTCDelDistInfo(r *rand.Rand) (*bstypes.BTCDelDistInfo, error) { } return &bstypes.BTCDelDistInfo{ BtcPk: btcPK, - BabylonPk: GenRandomAccount().GetPubKey().(*secp256k1.PubKey), + StakerAddr: GenRandomAccount().Address, VotingPower: RandomInt(r, 1000) + 1, }, nil } diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 9f0942dc0..cd0b532db 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -202,8 +202,8 @@ func NewEditFinalityProviderCmd() *cobra.Command { func NewCreateBTCDelegationCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-btc-delegation [babylon_pk] [btc_pk] [pop] [staking_tx_info] [fp_pk] [staking_time] [staking_value] [slashing_tx] [delegator_slashing_sig] [unbonding_tx] [unbonding_slashing_tx] [unbonding_time] [unbonding_value] [delegator_unbonding_slashing_sig]", - Args: cobra.ExactArgs(14), + Use: "create-btc-delegation [btc_pk] [pop_hex] [staking_tx_info] [fp_pk] [staking_time] [staking_value] [slashing_tx] [delegator_slashing_sig] [unbonding_tx] [unbonding_slashing_tx] [unbonding_time] [unbonding_value] [delegator_unbonding_slashing_sig]", + Args: cobra.ExactArgs(13), Short: "Create a BTC delegation", Long: strings.TrimSpace( `Create a BTC delegation.`, // TODO: example @@ -214,97 +214,86 @@ func NewCreateBTCDelegationCmd() *cobra.Command { return err } - // get Babylon PK - babylonPKBytes, err := hex.DecodeString(args[0]) - if err != nil { - return err - } - var babylonPK secp256k1.PubKey - if err := babylonPK.Unmarshal(babylonPKBytes); err != nil { - return err - } - // staker pk - btcPK, err := bbn.NewBIP340PubKeyFromHex(args[1]) + btcPK, err := bbn.NewBIP340PubKeyFromHex(args[0]) if err != nil { return err } // get PoP - pop, err := types.NewPoPFromHex(args[2]) + pop, err := types.NewPoPBTCFromHex(args[1]) if err != nil { return err } // get staking tx info - stakingTxInfo, err := btcctypes.NewTransactionInfoFromHex(args[3]) + stakingTxInfo, err := btcctypes.NewTransactionInfoFromHex(args[2]) if err != nil { return err } // TODO: Support multiple finality providers // get finality provider PK - fpPK, err := bbn.NewBIP340PubKeyFromHex(args[4]) + fpPK, err := bbn.NewBIP340PubKeyFromHex(args[3]) if err != nil { return err } // get staking time - stakingTime, err := parseLockTime(args[5]) + stakingTime, err := parseLockTime(args[4]) if err != nil { return err } - stakingValue, err := parseBtcAmount(args[6]) + stakingValue, err := parseBtcAmount(args[5]) if err != nil { return err } // get slashing tx - slashingTx, err := types.NewBTCSlashingTxFromHex(args[7]) + slashingTx, err := types.NewBTCSlashingTxFromHex(args[6]) if err != nil { return err } // get delegator sig on slashing tx - delegatorSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[8]) + delegatorSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[7]) if err != nil { return err } // get unbonding tx - _, unbondingTxBytes, err := bbn.NewBTCTxFromHex(args[9]) + _, unbondingTxBytes, err := bbn.NewBTCTxFromHex(args[8]) if err != nil { return err } // get unbonding slashing tx - unbondingSlashingTx, err := types.NewBTCSlashingTxFromHex(args[10]) + unbondingSlashingTx, err := types.NewBTCSlashingTxFromHex(args[9]) if err != nil { return err } // get staking time - unbondingTime, err := parseLockTime(args[11]) + unbondingTime, err := parseLockTime(args[10]) if err != nil { return err } - unbondingValue, err := parseBtcAmount(args[12]) + unbondingValue, err := parseBtcAmount(args[11]) if err != nil { return err } // get delegator sig on unbonding slashing tx - delegatorUnbondingSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[13]) + delegatorUnbondingSlashingSig, err := bbn.NewBIP340SignatureFromHex(args[12]) if err != nil { return err } msg := types.MsgCreateBTCDelegation{ - Signer: clientCtx.FromAddress.String(), - BabylonPk: &babylonPK, + StakerAddr: clientCtx.FromAddress.String(), BtcPk: btcPK, FpBtcPkList: []bbn.BIP340PubKey{*fpPK}, Pop: pop, diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go index 5c0eb2606..724591366 100644 --- a/x/btcstaking/keeper/genesis_test.go +++ b/x/btcstaking/keeper/genesis_test.go @@ -4,6 +4,7 @@ import ( "bytes" "math" "math/rand" + "strings" "testing" "github.com/babylonchain/babylon/testutil/datagen" @@ -140,7 +141,7 @@ func TestExportGenesis(t *testing.T) { correctDels := 0 for _, del := range btcDelegations { for _, gsdel := range gs.BtcDelegations { - if !bytes.Equal(del.BabylonPk.Address(), gsdel.BabylonPk.Address()) { + if !strings.EqualFold(del.StakerAddr, gsdel.StakerAddr) { continue } correctDels++ diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 6a2a5229e..fb1c8bff6 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -16,7 +16,6 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -176,12 +175,10 @@ func (h *Helper) CreateDelegationCustom( stakingTxHash := testStakingInfo.StakingTx.TxHash().String() // random signer - signer := datagen.GenRandomAccount().Address - // random Babylon SK - delBabylonSK, delBabylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - h.NoError(err) + staker := sdk.MustAccAddressFromBech32(datagen.GenRandomAccount().Address) + // PoP - pop, err := types.NewPoP(delBabylonSK, delSK) + pop, err := types.NewPoPBTC(staker, delSK) h.NoError(err) // generate staking tx info prevBlock, _ := datagen.GenRandomBtcdBlock(r, 0, nil) @@ -243,8 +240,7 @@ func (h *Helper) CreateDelegationCustom( // all good, construct and send MsgCreateBTCDelegation message fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpPK) msgCreateBTCDel := &types.MsgCreateBTCDelegation{ - Signer: signer, - BabylonPk: delBabylonPK.(*secp256k1.PubKey), + StakerAddr: staker.String(), BtcPk: stPk, FpBtcPkList: []bbn.BIP340PubKey{*fpBTCPK}, Pop: pop, @@ -366,7 +362,7 @@ func (h *Helper) GenerateCovenantSignaturesMessages( for i := 0; i < len(bsParams.CovenantPks); i++ { msgAddCovenantSig := &types.MsgAddCovenantSigs{ - Signer: msgCreateBTCDel.Signer, + Signer: msgCreateBTCDel.StakerAddr, Pk: covenantSlashingTxSigs[i].CovPk, StakingTxHash: stakingTxHash, SlashingTxSigs: covenantSlashingTxSigs[i].AdaptorSigs, @@ -422,7 +418,8 @@ func (h *Helper) GetDelegationAndCheckValues( ) *types.BTCDelegation { actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) h.NoError(err) - require.Equal(h.t, msgCreateBTCDel.BabylonPk, actualDel.BabylonPk) + // TODO: update pop in BTC delegation + require.Equal(h.t, msgCreateBTCDel.StakerAddr, actualDel.StakerAddr) require.Equal(h.t, msgCreateBTCDel.Pop, actualDel.Pop) require.Equal(h.t, msgCreateBTCDel.StakingTx.Transaction, actualDel.StakingTx) require.Equal(h.t, msgCreateBTCDel.SlashingTx, actualDel.SlashingTx) diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 1ba83c259..ea9be3b50 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -179,8 +179,13 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre // - is smaller than math.MaxUint16 (due to check in req.ValidateBasic()) validatedUnbondingTime := uint16(req.UnbondingTime) + stakerAddr, err := sdk.AccAddressFromBech32(req.StakerAddr) + if err != nil { + return nil, types.ErrInvalidStakingTx.Wrapf("invalid staker addr %s: %v", req.StakerAddr, err) + } + // verify proof of possession - if err := req.Pop.Verify(req.BabylonPk, req.BtcPk, ms.btcNet); err != nil { + if err := req.Pop.Verify(stakerAddr, req.BtcPk, ms.btcNet); err != nil { return nil, types.ErrInvalidProofOfPossession.Wrapf("error while validating proof of posession: %v", err) } @@ -315,7 +320,7 @@ func (ms msgServer) CreateBTCDelegation(goCtx context.Context, req *types.MsgCre // have voting power only when 1) its corresponding staking tx is k-deep, // and 2) it receives a covenant signature newBTCDel := &types.BTCDelegation{ - BabylonPk: req.BabylonPk, + StakerAddr: stakerAddr.String(), BtcPk: req.BtcPk, Pop: req.Pop, FpBtcPkList: req.FpBtcPkList, diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index d2324d789..c830f91f6 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -11,7 +11,6 @@ import ( sdkmath "cosmossdk.io/math" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/wire" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" @@ -172,7 +171,7 @@ func FuzzCreateBTCDelegation(f *testing.F) { // ensure consistency between the msg and the BTC delegation in DB actualDel, err := h.BTCStakingKeeper.GetBTCDelegation(h.Ctx, stakingTxHash) h.NoError(err) - require.Equal(h.t, msgCreateBTCDel.BabylonPk, actualDel.BabylonPk) + require.Equal(h.t, msgCreateBTCDel.StakerAddr, actualDel.StakerAddr) require.Equal(h.t, msgCreateBTCDel.Pop, actualDel.Pop) require.Equal(h.t, msgCreateBTCDel.StakingTx.Transaction, actualDel.StakingTx) require.Equal(h.t, msgCreateBTCDel.SlashingTx, actualDel.SlashingTx) @@ -587,13 +586,12 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { stakingMsgTx := testStakingInfo.StakingTx serializedStakingTx, err := bbn.SerializeBTCTx(stakingMsgTx) require.NoError(t, err) - // random signer - signer := datagen.GenRandomAccount().Address // random Babylon SK - delBabylonSK, delBabylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + acc := datagen.GenRandomAccount() + stakerAddr := sdk.MustAccAddressFromBech32(acc.Address) + // PoP - pop, err := types.NewPoP(delBabylonSK, delSK) + pop, err := types.NewPoPBTC(stakerAddr, delSK) require.NoError(t, err) // generate staking tx info prevBlock, _ := datagen.GenRandomBtcdBlock(r, 0, nil) @@ -643,8 +641,7 @@ func TestDoNotAllowDelegationWithoutFinalityProvider(t *testing.T) { // all good, construct and send MsgCreateBTCDelegation message fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(fpPK) msgCreateBTCDel := &types.MsgCreateBTCDelegation{ - Signer: signer, - BabylonPk: delBabylonPK.(*secp256k1.PubKey), + StakerAddr: stakerAddr.String(), FpBtcPkList: []bbn.BIP340PubKey{*fpBTCPK}, BtcPk: bbn.NewBIP340PubKeyFromBTCPK(delSK.PubKey()), Pop: pop, diff --git a/x/btcstaking/types/btc_delegation.go b/x/btcstaking/types/btc_delegation.go index 0d496965d..66a621751 100644 --- a/x/btcstaking/types/btc_delegation.go +++ b/x/btcstaking/types/btc_delegation.go @@ -5,6 +5,8 @@ import ( "fmt" math "math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/babylonchain/babylon/btcstaking" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" @@ -139,8 +141,8 @@ func (d *BTCDelegation) MustGetStakingTxHash() chainhash.Hash { } func (d *BTCDelegation) ValidateBasic() error { - if d.BabylonPk == nil { - return fmt.Errorf("empty Babylon public key") + if _, err := sdk.AccAddressFromBech32(d.StakerAddr); err != nil { + return fmt.Errorf("invalid staker address: %s - %w", d.StakerAddr, err) } if d.BtcPk == nil { return fmt.Errorf("empty BTC public key") @@ -168,9 +170,6 @@ func (d *BTCDelegation) ValidateBasic() error { if _, err := bbn.NewBTCTxFromBytes(d.StakingTx); err != nil { return err } - if err := d.Pop.ValidateBasic(); err != nil { - return err - } return nil } diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index 7decf89b8..f5bba85b5 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -242,13 +242,13 @@ func (m *FinalityProviderWithMeta) GetSlashedBtcHeight() uint64 { // BTCDelegation defines a BTC delegation type BTCDelegation struct { - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - BabylonPk *secp256k1.PubKey `protobuf:"bytes,1,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // staker_addr is the address to receive rewards from BTC delegation. + StakerAddr string `protobuf:"bytes,1,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,3,opt,name=pop,proto3" json:"pop,omitempty"` + Pop *ProofOfPossessionBTC `protobuf:"bytes,3,opt,name=pop,proto3" json:"pop,omitempty"` // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to // If there is more than 1 PKs, then this means the delegation is restaked @@ -321,14 +321,14 @@ func (m *BTCDelegation) XXX_DiscardUnknown() { var xxx_messageInfo_BTCDelegation proto.InternalMessageInfo -func (m *BTCDelegation) GetBabylonPk() *secp256k1.PubKey { +func (m *BTCDelegation) GetStakerAddr() string { if m != nil { - return m.BabylonPk + return m.StakerAddr } - return nil + return "" } -func (m *BTCDelegation) GetPop() *ProofOfPossession { +func (m *BTCDelegation) GetPop() *ProofOfPossessionBTC { if m != nil { return m.Pop } @@ -744,82 +744,85 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1197 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0xc5, - 0x17, 0xcf, 0xda, 0x8e, 0x53, 0x1f, 0xdb, 0x8d, 0x3b, 0x4d, 0xd3, 0x6d, 0xa3, 0x7f, 0x92, 0xbf, - 0x29, 0x95, 0x85, 0xa8, 0xdd, 0xa4, 0x1f, 0x02, 0x2e, 0x90, 0xea, 0x38, 0xa5, 0x51, 0xdb, 0xd4, - 0xac, 0x93, 0x22, 0x40, 0x62, 0x35, 0xde, 0x9d, 0xac, 0x57, 0xb6, 0x77, 0x96, 0x9d, 0xb1, 0xb1, - 0xdf, 0x80, 0x1b, 0x24, 0x6e, 0xb9, 0xe7, 0x11, 0x78, 0x06, 0xc4, 0x65, 0xc5, 0x0d, 0x28, 0x17, - 0x11, 0x6a, 0x1f, 0x80, 0x57, 0x40, 0x33, 0x3b, 0xfb, 0xe1, 0xb6, 0x29, 0xb4, 0xce, 0x9d, 0x67, - 0xce, 0x39, 0xbf, 0xf3, 0xf1, 0xfb, 0xf9, 0xcc, 0xc2, 0xf5, 0x2e, 0xee, 0x4e, 0x07, 0xd4, 0x6b, - 0x74, 0xb9, 0xc5, 0x38, 0xee, 0xbb, 0x9e, 0xd3, 0x18, 0x6f, 0xa5, 0x4e, 0x75, 0x3f, 0xa0, 0x9c, - 0xa2, 0x4b, 0xca, 0xaf, 0x9e, 0xb2, 0x8c, 0xb7, 0xae, 0xae, 0x38, 0xd4, 0xa1, 0xd2, 0xa3, 0x21, - 0x7e, 0x85, 0xce, 0x57, 0xaf, 0x58, 0x94, 0x0d, 0x29, 0x33, 0x43, 0x43, 0x78, 0x50, 0xa6, 0x6a, - 0x78, 0x6a, 0x58, 0xc1, 0xd4, 0xe7, 0xb4, 0xc1, 0x88, 0xe5, 0x6f, 0xdf, 0xb9, 0xdb, 0xdf, 0x6a, - 0xf4, 0xc9, 0x34, 0xf2, 0xb9, 0xa6, 0x7c, 0x92, 0x7a, 0xba, 0x84, 0xe3, 0xad, 0xc6, 0x4c, 0x45, - 0x57, 0x37, 0x5e, 0x5f, 0xb9, 0x4f, 0xfd, 0xd0, 0xa1, 0xfa, 0x47, 0x16, 0x2a, 0xf7, 0x5d, 0x0f, - 0x0f, 0x5c, 0x3e, 0x6d, 0x07, 0x74, 0xec, 0xda, 0x24, 0x40, 0xbb, 0x50, 0xb4, 0x09, 0xb3, 0x02, - 0xd7, 0xe7, 0x2e, 0xf5, 0x74, 0x6d, 0x53, 0xab, 0x15, 0xb7, 0xdf, 0xab, 0xab, 0x1a, 0x93, 0xce, - 0x64, 0xc6, 0x7a, 0x2b, 0x71, 0x35, 0xd2, 0x71, 0xe8, 0x31, 0x80, 0x45, 0x87, 0x43, 0x97, 0x31, - 0x81, 0x92, 0xd9, 0xd4, 0x6a, 0x85, 0xe6, 0x8d, 0xe3, 0x93, 0x8d, 0xb5, 0x10, 0x88, 0xd9, 0xfd, - 0xba, 0x4b, 0x1b, 0x43, 0xcc, 0x7b, 0xf5, 0x47, 0xc4, 0xc1, 0xd6, 0xb4, 0x45, 0xac, 0xdf, 0x7f, - 0xb9, 0x01, 0x2a, 0x4f, 0x8b, 0x58, 0x46, 0x0a, 0x00, 0x7d, 0x0a, 0xa0, 0xba, 0x31, 0xfd, 0xbe, - 0x9e, 0x95, 0x45, 0x6d, 0x44, 0x45, 0x85, 0xa3, 0xaa, 0xc7, 0xa3, 0xaa, 0xb7, 0x47, 0xdd, 0x87, - 0x64, 0x6a, 0x14, 0x54, 0x48, 0xbb, 0x8f, 0x1e, 0x43, 0xbe, 0xcb, 0x2d, 0x11, 0x9b, 0xdb, 0xd4, - 0x6a, 0xa5, 0xe6, 0xdd, 0xe3, 0x93, 0x8d, 0x6d, 0xc7, 0xe5, 0xbd, 0x51, 0xb7, 0x6e, 0xd1, 0x61, - 0x43, 0x79, 0x5a, 0x3d, 0xec, 0x7a, 0xd1, 0xa1, 0xc1, 0xa7, 0x3e, 0x61, 0xf5, 0xe6, 0x5e, 0xfb, - 0xd6, 0xed, 0x9b, 0x0a, 0x72, 0xb1, 0xcb, 0xad, 0x76, 0x1f, 0x7d, 0x02, 0x59, 0x9f, 0xfa, 0xfa, - 0xa2, 0xac, 0xa3, 0x56, 0x7f, 0x2d, 0xf5, 0xf5, 0x76, 0x40, 0xe9, 0xd1, 0x93, 0xa3, 0x36, 0x65, - 0x8c, 0xc8, 0x2e, 0x0c, 0x11, 0x84, 0x6e, 0xc3, 0x2a, 0x1b, 0x60, 0xd6, 0x23, 0xb6, 0x19, 0xb5, - 0xd4, 0x23, 0xae, 0xd3, 0xe3, 0x7a, 0x7e, 0x53, 0xab, 0xe5, 0x8c, 0x15, 0x65, 0x6d, 0x86, 0xc6, - 0x07, 0xd2, 0x86, 0x3e, 0x04, 0x14, 0x47, 0x71, 0x2b, 0x8a, 0x58, 0x92, 0x11, 0x95, 0x28, 0x82, - 0x5b, 0xa1, 0x77, 0xf5, 0xfb, 0x0c, 0xe8, 0x2f, 0x33, 0xfb, 0x85, 0xcb, 0x7b, 0x8f, 0x09, 0xc7, - 0xa9, 0x59, 0x68, 0x67, 0x31, 0x8b, 0x55, 0xc8, 0xab, 0x6a, 0x32, 0xb2, 0x1a, 0x75, 0x42, 0xff, - 0x87, 0xd2, 0x98, 0x72, 0xd7, 0x73, 0x4c, 0x9f, 0x7e, 0x47, 0x02, 0x49, 0x5a, 0xce, 0x28, 0x86, - 0x77, 0x6d, 0x71, 0xf5, 0x86, 0x51, 0xe4, 0xde, 0x7a, 0x14, 0x8b, 0xa7, 0x8c, 0xe2, 0xef, 0x3c, - 0x94, 0x9b, 0x07, 0x3b, 0x2d, 0x32, 0x20, 0x0e, 0xe6, 0xaf, 0x6a, 0x49, 0x9b, 0x43, 0x4b, 0x99, - 0x33, 0xd4, 0x52, 0xf6, 0x5d, 0xb4, 0xf4, 0x35, 0x9c, 0x3f, 0xf2, 0xcd, 0xb0, 0x1a, 0x73, 0xe0, - 0x32, 0x31, 0xb8, 0xec, 0x1c, 0x25, 0x15, 0x8f, 0xfc, 0xa6, 0x28, 0xea, 0x91, 0xcb, 0x24, 0x81, - 0x8c, 0xe3, 0x80, 0xcf, 0x4e, 0xb8, 0x28, 0xef, 0x14, 0x15, 0xff, 0x03, 0x20, 0x9e, 0x3d, 0xab, - 0xdf, 0x02, 0xf1, 0x6c, 0x65, 0x5e, 0x83, 0x02, 0xa7, 0x1c, 0x0f, 0x4c, 0x86, 0x23, 0xad, 0x9e, - 0x93, 0x17, 0x1d, 0x2c, 0x63, 0x55, 0x83, 0x26, 0x9f, 0xe8, 0xe7, 0xc4, 0x28, 0x8d, 0x82, 0xba, - 0x39, 0x98, 0x48, 0x96, 0x95, 0x99, 0x8e, 0xb8, 0x3f, 0xe2, 0xa6, 0x6b, 0x4f, 0xf4, 0xc2, 0xa6, - 0x56, 0x2b, 0x1b, 0x15, 0x65, 0x79, 0x22, 0x0d, 0x7b, 0xf6, 0x04, 0x6d, 0x43, 0x51, 0x32, 0xaf, - 0xd0, 0x40, 0x12, 0x73, 0xe1, 0xf8, 0x64, 0x43, 0x70, 0xdf, 0x51, 0x96, 0x83, 0x89, 0x01, 0x2c, - 0xfe, 0x8d, 0xbe, 0x81, 0xb2, 0x1d, 0xaa, 0x82, 0x06, 0x26, 0x73, 0x1d, 0xbd, 0x28, 0xa3, 0x3e, - 0x3e, 0x3e, 0xd9, 0xb8, 0xf3, 0x36, 0xb3, 0xeb, 0xb8, 0x8e, 0x87, 0xf9, 0x28, 0x20, 0x46, 0x29, - 0xc6, 0xeb, 0xb8, 0x0e, 0x3a, 0x84, 0xb2, 0x45, 0xc7, 0xc4, 0xc3, 0x1e, 0x17, 0xf0, 0x4c, 0x2f, - 0x6d, 0x66, 0x6b, 0xc5, 0xed, 0x9b, 0xa7, 0x50, 0xbc, 0xa3, 0x7c, 0xef, 0xd9, 0xd8, 0x0f, 0x11, - 0x42, 0x54, 0x66, 0x94, 0x22, 0x98, 0x8e, 0xeb, 0x30, 0xf4, 0x3e, 0x9c, 0x1f, 0x79, 0x5d, 0xea, - 0xd9, 0xb2, 0x57, 0x77, 0x48, 0xf4, 0xb2, 0x1c, 0x4a, 0x39, 0xbe, 0x3d, 0x70, 0x87, 0x04, 0x7d, - 0x0e, 0x15, 0xa1, 0x8b, 0x91, 0x67, 0xc7, 0xca, 0xd7, 0xcf, 0x4b, 0x8d, 0x5d, 0x3f, 0xa5, 0x80, - 0xe6, 0xc1, 0xce, 0x61, 0xca, 0xdb, 0x58, 0xee, 0x72, 0x2b, 0x7d, 0x21, 0x32, 0xfb, 0x38, 0xc0, - 0x43, 0x66, 0x8e, 0x49, 0x20, 0xf7, 0xfa, 0x72, 0x98, 0x39, 0xbc, 0x7d, 0x1a, 0x5e, 0x56, 0x7f, - 0xca, 0xc1, 0xf2, 0x4b, 0x58, 0x42, 0x4b, 0xa9, 0xa2, 0x27, 0xe1, 0xe6, 0x31, 0x8a, 0x49, 0xc9, - 0xaf, 0x50, 0x98, 0xf9, 0x2f, 0x14, 0x7e, 0x0b, 0x97, 0x13, 0x0a, 0x93, 0x04, 0x82, 0xcc, 0xec, - 0xbc, 0x64, 0x5e, 0x8a, 0x91, 0x0f, 0x23, 0x60, 0xc1, 0x2a, 0x85, 0xd5, 0x94, 0x6a, 0xa2, 0x82, - 0x45, 0xc6, 0xdc, 0xbc, 0x19, 0x57, 0x12, 0xf9, 0x28, 0x5c, 0x91, 0xf0, 0x08, 0x56, 0x13, 0x19, - 0xa5, 0xf2, 0x31, 0x7d, 0xf1, 0x1d, 0xf5, 0xb4, 0x12, 0xeb, 0x29, 0x49, 0xc3, 0x90, 0x05, 0x6b, - 0x71, 0x9e, 0x99, 0x51, 0x86, 0x8b, 0x25, 0x2f, 0x93, 0x5d, 0x3b, 0x25, 0x59, 0x8c, 0xbe, 0xe7, - 0x1d, 0x51, 0x43, 0x8f, 0x80, 0xd2, 0x93, 0x13, 0x3b, 0xa5, 0xda, 0x81, 0xcb, 0xc9, 0x32, 0xa6, - 0x41, 0xb2, 0x95, 0x19, 0xfa, 0x08, 0x72, 0x36, 0x19, 0x30, 0x5d, 0x7b, 0x63, 0xa2, 0x99, 0x55, - 0x6e, 0xc8, 0x88, 0xea, 0x3e, 0xac, 0xbd, 0x1e, 0x74, 0xcf, 0xb3, 0xc9, 0x04, 0x35, 0x60, 0x25, - 0x59, 0x34, 0x66, 0x0f, 0xb3, 0x5e, 0xd8, 0x91, 0x48, 0x54, 0x32, 0x2e, 0xc4, 0x2b, 0xe7, 0x01, - 0x66, 0x3d, 0x59, 0xe4, 0xcf, 0x1a, 0x94, 0x67, 0x1a, 0x42, 0xf7, 0x21, 0x33, 0xf7, 0x73, 0x99, - 0xf1, 0xfb, 0xe8, 0x21, 0x64, 0x85, 0x52, 0x32, 0xf3, 0x2a, 0x45, 0xa0, 0x54, 0x7f, 0xd0, 0xe0, - 0xca, 0xa9, 0x24, 0x8b, 0x57, 0xca, 0xa2, 0xe3, 0x33, 0x78, 0xe5, 0x2d, 0x3a, 0x6e, 0xf7, 0xc5, - 0x1f, 0x18, 0x87, 0x39, 0x42, 0xed, 0x65, 0xe4, 0xf0, 0x8a, 0x38, 0xce, 0xcb, 0xaa, 0xbf, 0x6a, - 0x70, 0xa5, 0x43, 0x06, 0xc4, 0xe2, 0xee, 0x98, 0x44, 0xd2, 0xda, 0x15, 0xdf, 0x1e, 0x9e, 0x45, - 0xd0, 0x75, 0x58, 0x7e, 0x89, 0x05, 0x59, 0x58, 0xc1, 0x28, 0xcf, 0x10, 0x80, 0x0c, 0x28, 0xc4, - 0x4f, 0xda, 0x9c, 0x0f, 0xec, 0x92, 0x7a, 0xcd, 0xd0, 0x0d, 0xb8, 0x18, 0x10, 0xa1, 0xc9, 0x80, - 0xd8, 0xa6, 0x42, 0x67, 0xe1, 0x67, 0x64, 0xc9, 0xa8, 0xc4, 0xa6, 0xfb, 0xc2, 0xbd, 0xd3, 0xff, - 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc3, 0x31, 0x1f, 0x31, 0x54, 0x84, 0xa5, 0xf6, 0xee, 0x7e, - 0x6b, 0x6f, 0xff, 0xb3, 0xca, 0x02, 0x02, 0xc8, 0xdf, 0xdb, 0x39, 0xd8, 0x7b, 0xba, 0x5b, 0xd1, - 0x50, 0x09, 0xce, 0x1d, 0xee, 0x37, 0x9f, 0xec, 0xb7, 0x76, 0x5b, 0x95, 0x0c, 0x5a, 0x82, 0xec, - 0xbd, 0xfd, 0x2f, 0x2b, 0xd9, 0xe6, 0xa3, 0xdf, 0x9e, 0xaf, 0x6b, 0xcf, 0x9e, 0xaf, 0x6b, 0x7f, - 0x3d, 0x5f, 0xd7, 0x7e, 0x7c, 0xb1, 0xbe, 0xf0, 0xec, 0xc5, 0xfa, 0xc2, 0x9f, 0x2f, 0xd6, 0x17, - 0xbe, 0xfa, 0xd7, 0x66, 0x26, 0xe9, 0x6f, 0x76, 0xd9, 0x59, 0x37, 0x2f, 0xbf, 0xd9, 0x6f, 0xfd, - 0x13, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xb8, 0x1f, 0xd2, 0x90, 0x0c, 0x00, 0x00, + // 1238 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x1b, 0xce, 0xda, 0x8e, 0x53, 0xbf, 0xb6, 0x1b, 0x77, 0x9a, 0xa6, 0xdb, 0x46, 0x5f, 0x92, 0xcf, + 0x94, 0xca, 0x02, 0x62, 0x37, 0xe9, 0x8f, 0x28, 0x12, 0x48, 0x71, 0x9c, 0xd2, 0xa8, 0x6d, 0x6a, + 0xd6, 0x4e, 0x11, 0x20, 0xb1, 0x1a, 0xef, 0x4e, 0xec, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, + 0x3b, 0xe0, 0x04, 0x89, 0x53, 0xce, 0xb9, 0x84, 0x5e, 0x03, 0xe2, 0xb0, 0xea, 0x09, 0x28, 0x07, + 0x11, 0x6a, 0x8f, 0xb9, 0x07, 0x34, 0x3f, 0x5e, 0xaf, 0x4b, 0x53, 0x5a, 0x92, 0x33, 0xcf, 0xfb, + 0xf3, 0xbc, 0x3f, 0xcf, 0xe3, 0x99, 0x85, 0xeb, 0x2d, 0xdc, 0x1a, 0xf7, 0xa8, 0x5f, 0x69, 0x71, + 0x87, 0x71, 0xdc, 0xf5, 0xfc, 0x76, 0x65, 0xb8, 0x19, 0x3b, 0x95, 0x83, 0x90, 0x72, 0x8a, 0x2e, + 0xe9, 0xb8, 0x72, 0xcc, 0x33, 0xdc, 0xbc, 0xba, 0xd4, 0xa6, 0x6d, 0x2a, 0x23, 0x2a, 0xe2, 0x97, + 0x0a, 0xbe, 0x7a, 0xc5, 0xa1, 0xac, 0x4f, 0x99, 0xad, 0x1c, 0xea, 0xa0, 0x5d, 0x45, 0x75, 0xaa, + 0x38, 0xe1, 0x38, 0xe0, 0xb4, 0xc2, 0x88, 0x13, 0x6c, 0xdd, 0xbe, 0xd3, 0xdd, 0xac, 0x74, 0xc9, + 0x78, 0x12, 0x73, 0x4d, 0xc7, 0x4c, 0xfb, 0x69, 0x11, 0x8e, 0x37, 0x2b, 0x33, 0x1d, 0x5d, 0x5d, + 0x7b, 0x7d, 0xe7, 0x01, 0x0d, 0x54, 0x40, 0xf1, 0xf7, 0x24, 0x14, 0xee, 0x79, 0x3e, 0xee, 0x79, + 0x7c, 0x5c, 0x0f, 0xe9, 0xd0, 0x73, 0x49, 0x88, 0x76, 0x21, 0xeb, 0x12, 0xe6, 0x84, 0x5e, 0xc0, + 0x3d, 0xea, 0x9b, 0xc6, 0xba, 0x51, 0xca, 0x6e, 0xbd, 0x57, 0xd6, 0x3d, 0x4e, 0x27, 0x93, 0x15, + 0xcb, 0xb5, 0x69, 0xa8, 0x15, 0xcf, 0x43, 0x8f, 0x00, 0x1c, 0xda, 0xef, 0x7b, 0x8c, 0x09, 0x94, + 0xc4, 0xba, 0x51, 0xca, 0x54, 0x37, 0x8e, 0x8e, 0xd7, 0x56, 0x14, 0x10, 0x73, 0xbb, 0x65, 0x8f, + 0x56, 0xfa, 0x98, 0x77, 0xca, 0x0f, 0x49, 0x1b, 0x3b, 0xe3, 0x1a, 0x71, 0x9e, 0x3f, 0xdd, 0x00, + 0x5d, 0xa7, 0x46, 0x1c, 0x2b, 0x06, 0x80, 0x3e, 0x03, 0xd0, 0xd3, 0xd8, 0x41, 0xd7, 0x4c, 0xca, + 0xa6, 0xd6, 0x26, 0x4d, 0xa9, 0x55, 0x95, 0xa3, 0x55, 0x95, 0xeb, 0x83, 0xd6, 0x03, 0x32, 0xb6, + 0x32, 0x3a, 0xa5, 0xde, 0x45, 0x8f, 0x20, 0xdd, 0xe2, 0x8e, 0xc8, 0x4d, 0xad, 0x1b, 0xa5, 0x5c, + 0xf5, 0xce, 0xd1, 0xf1, 0xda, 0x56, 0xdb, 0xe3, 0x9d, 0x41, 0xab, 0xec, 0xd0, 0x7e, 0x45, 0x47, + 0x3a, 0x1d, 0xec, 0xf9, 0x93, 0x43, 0x85, 0x8f, 0x03, 0xc2, 0xca, 0xd5, 0xbd, 0xfa, 0xcd, 0x5b, + 0x37, 0x34, 0xe4, 0x7c, 0x8b, 0x3b, 0xf5, 0x2e, 0xfa, 0x04, 0x92, 0x01, 0x0d, 0xcc, 0x79, 0xd9, + 0x47, 0xa9, 0xfc, 0x5a, 0xea, 0xcb, 0xf5, 0x90, 0xd2, 0xc3, 0xc7, 0x87, 0x75, 0xca, 0x18, 0x91, + 0x53, 0x58, 0x22, 0x09, 0xdd, 0x82, 0x65, 0xd6, 0xc3, 0xac, 0x43, 0x5c, 0x7b, 0x32, 0x52, 0x87, + 0x78, 0xed, 0x0e, 0x37, 0xd3, 0xeb, 0x46, 0x29, 0x65, 0x2d, 0x69, 0x6f, 0x55, 0x39, 0xef, 0x4b, + 0x1f, 0xfa, 0x08, 0x50, 0x94, 0xc5, 0x9d, 0x49, 0xc6, 0x82, 0xcc, 0x28, 0x4c, 0x32, 0xb8, 0xa3, + 0xa2, 0x8b, 0x3f, 0x24, 0xc0, 0x7c, 0x95, 0xd9, 0x2f, 0x3d, 0xde, 0x79, 0x44, 0x38, 0x8e, 0xed, + 0xc2, 0x38, 0x8b, 0x5d, 0x2c, 0x43, 0x5a, 0x77, 0x93, 0x90, 0xdd, 0xe8, 0x13, 0xfa, 0x3f, 0xe4, + 0x86, 0x94, 0x7b, 0x7e, 0xdb, 0x0e, 0xe8, 0xf7, 0x24, 0x94, 0xa4, 0xa5, 0xac, 0xac, 0xb2, 0xd5, + 0x85, 0xe9, 0x0d, 0xab, 0x48, 0xbd, 0xf3, 0x2a, 0xe6, 0x4f, 0x58, 0xc5, 0x5f, 0x69, 0xc8, 0x57, + 0x9b, 0x3b, 0x35, 0xd2, 0x23, 0x6d, 0x2c, 0xa5, 0x79, 0x17, 0xb2, 0x82, 0x25, 0x12, 0xda, 0xd8, + 0x75, 0x43, 0xb9, 0x84, 0x4c, 0xd5, 0x7c, 0xfe, 0x74, 0x63, 0x49, 0xeb, 0x69, 0xdb, 0x75, 0x43, + 0xc2, 0x58, 0x83, 0x87, 0x9e, 0xdf, 0xb6, 0x40, 0x05, 0x0b, 0x63, 0x6c, 0x75, 0x89, 0xb3, 0x58, + 0xdd, 0xa7, 0x4a, 0x46, 0x4a, 0xce, 0x1f, 0xbe, 0xad, 0x8c, 0xaa, 0xcd, 0x1d, 0xa5, 0xa4, 0x6f, + 0xe0, 0xfc, 0x61, 0x60, 0xab, 0x86, 0xec, 0x9e, 0xc7, 0xc4, 0xda, 0x92, 0xa7, 0xe8, 0x2a, 0x7b, + 0x18, 0x54, 0x45, 0x5f, 0x0f, 0x3d, 0x26, 0xe9, 0x63, 0x1c, 0x87, 0x7c, 0x76, 0xbf, 0x59, 0x69, + 0xd3, 0x44, 0xfc, 0x0f, 0x80, 0xf8, 0xee, 0xac, 0x7a, 0x33, 0xc4, 0x77, 0xb5, 0x7b, 0x05, 0x32, + 0x9c, 0x72, 0xdc, 0xb3, 0x19, 0x9e, 0x28, 0xf5, 0x9c, 0x34, 0x34, 0xb0, 0xcc, 0xd5, 0x33, 0xda, + 0x7c, 0x64, 0x9e, 0x13, 0xdb, 0xb4, 0x32, 0xda, 0xd2, 0x1c, 0x49, 0x8e, 0xb5, 0x9b, 0x0e, 0x78, + 0x30, 0xe0, 0xb6, 0xe7, 0x8e, 0xcc, 0xcc, 0xba, 0x51, 0xca, 0x5b, 0x05, 0xed, 0x79, 0x2c, 0x1d, + 0x7b, 0xee, 0x08, 0x6d, 0x41, 0x56, 0xf2, 0xae, 0xd1, 0x40, 0x72, 0x73, 0xe1, 0xe8, 0x78, 0x4d, + 0x30, 0xdf, 0xd0, 0x9e, 0xe6, 0xc8, 0x02, 0x16, 0xfd, 0x46, 0xdf, 0x42, 0xde, 0x55, 0x9a, 0xa0, + 0xa1, 0xcd, 0xbc, 0xb6, 0x99, 0x95, 0x59, 0x77, 0x8f, 0x8e, 0xd7, 0x6e, 0xbf, 0xcb, 0xee, 0x1a, + 0x5e, 0xdb, 0xc7, 0x7c, 0x10, 0x12, 0x2b, 0x17, 0xe1, 0x35, 0xbc, 0x36, 0x3a, 0x80, 0xbc, 0x43, + 0x87, 0xc4, 0xc7, 0x3e, 0x17, 0xf0, 0xcc, 0xcc, 0xad, 0x27, 0x4b, 0xd9, 0xad, 0x1b, 0x27, 0xb0, + 0xbc, 0xa3, 0x63, 0xb7, 0x5d, 0x1c, 0x28, 0x04, 0x85, 0xca, 0xac, 0xdc, 0x04, 0xa6, 0xe1, 0xb5, + 0x19, 0x7a, 0x1f, 0xce, 0x0f, 0xfc, 0x16, 0xf5, 0x5d, 0x39, 0xab, 0xd7, 0x27, 0x66, 0x5e, 0x2e, + 0x25, 0x1f, 0x59, 0x9b, 0x5e, 0x9f, 0xa0, 0x2f, 0xa0, 0x20, 0x74, 0x31, 0xf0, 0xdd, 0x48, 0xf7, + 0xe6, 0x79, 0x29, 0xb3, 0xeb, 0x27, 0x34, 0x50, 0x6d, 0xee, 0x1c, 0xc4, 0xa2, 0xad, 0xc5, 0x16, + 0x77, 0xe2, 0x06, 0x51, 0x39, 0xc0, 0x21, 0xee, 0x33, 0x7b, 0x48, 0x42, 0x79, 0xab, 0x2f, 0xaa, + 0xca, 0xca, 0xfa, 0x44, 0x19, 0x8b, 0x3f, 0xa7, 0x60, 0xf1, 0x15, 0x2c, 0xa1, 0xa5, 0x58, 0xd3, + 0x23, 0x75, 0xef, 0x58, 0xd9, 0x69, 0xcb, 0xff, 0xa0, 0x30, 0xf1, 0x36, 0x14, 0x7e, 0x07, 0x97, + 0xa7, 0x14, 0x4e, 0x0b, 0x08, 0x32, 0x93, 0xa7, 0x25, 0xf3, 0x52, 0x84, 0x7c, 0x30, 0x01, 0x16, + 0xac, 0x52, 0x58, 0x8e, 0xa9, 0x66, 0xd2, 0xb0, 0xa8, 0x98, 0x3a, 0x6d, 0xc5, 0xa5, 0xa9, 0x7c, + 0x34, 0xae, 0x28, 0x78, 0x08, 0xcb, 0x53, 0x19, 0xc5, 0xea, 0x31, 0x73, 0xfe, 0x3f, 0xea, 0x69, + 0x29, 0xd2, 0xd3, 0xb4, 0x0c, 0x43, 0x0e, 0xac, 0x44, 0x75, 0x66, 0x56, 0xa9, 0x2e, 0x96, 0xb4, + 0x2c, 0x76, 0xed, 0x84, 0x62, 0x11, 0xfa, 0x9e, 0x7f, 0x48, 0x2d, 0x73, 0x02, 0x14, 0xdf, 0x9c, + 0xb8, 0x53, 0x8a, 0x0d, 0xb8, 0x3c, 0xbd, 0x8a, 0x69, 0x38, 0xbd, 0x93, 0x19, 0xfa, 0x18, 0x52, + 0x2e, 0xe9, 0x31, 0xd3, 0x78, 0x63, 0xa1, 0x99, 0x8b, 0xdc, 0x92, 0x19, 0xc5, 0x7d, 0x58, 0x79, + 0x3d, 0xe8, 0x9e, 0xef, 0x92, 0x11, 0xaa, 0xc0, 0xd2, 0xf4, 0xa2, 0xb1, 0x3b, 0x98, 0x75, 0xd4, + 0x44, 0xa2, 0x50, 0xce, 0xba, 0x10, 0x5d, 0x39, 0xf7, 0x31, 0xeb, 0xc8, 0x26, 0x7f, 0x31, 0x20, + 0x3f, 0x33, 0x10, 0xba, 0x07, 0x89, 0x53, 0x3f, 0x96, 0x89, 0xa0, 0x8b, 0x1e, 0x40, 0x52, 0x28, + 0x25, 0x71, 0x5a, 0xa5, 0x08, 0x94, 0xe2, 0x8f, 0x06, 0x5c, 0x39, 0x91, 0x64, 0xf1, 0x50, 0x39, + 0x74, 0x78, 0x06, 0x6f, 0xbc, 0x43, 0x87, 0xf5, 0xae, 0xf8, 0x03, 0x63, 0x55, 0x43, 0x69, 0x2f, + 0x21, 0x97, 0x97, 0xc5, 0x51, 0x5d, 0x56, 0xfc, 0xd5, 0x80, 0x2b, 0x0d, 0xd2, 0x23, 0x0e, 0xf7, + 0x86, 0x64, 0x22, 0xad, 0x5d, 0xf1, 0xe5, 0xe1, 0x3b, 0x04, 0x5d, 0x87, 0xc5, 0x57, 0x58, 0x50, + 0xef, 0xae, 0x95, 0x9f, 0x21, 0x00, 0x59, 0x90, 0x89, 0x9e, 0xb4, 0x53, 0xbe, 0xb1, 0x0b, 0xfa, + 0x35, 0x43, 0x1b, 0x70, 0x31, 0x24, 0x42, 0x93, 0x21, 0x71, 0x6d, 0x8d, 0xce, 0xd4, 0x47, 0x64, + 0xce, 0x2a, 0x44, 0xae, 0x7b, 0x22, 0xbc, 0xd1, 0xfd, 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc1, + 0x31, 0x1f, 0x30, 0x94, 0x85, 0x85, 0xfa, 0xee, 0x7e, 0x6d, 0x6f, 0xff, 0xf3, 0xc2, 0x1c, 0x02, + 0x48, 0x6f, 0xef, 0x34, 0xf7, 0x9e, 0xec, 0x16, 0x0c, 0x94, 0x83, 0x73, 0x07, 0xfb, 0xd5, 0xc7, + 0xfb, 0xb5, 0xdd, 0x5a, 0x21, 0x81, 0x16, 0x20, 0xb9, 0xbd, 0xff, 0x55, 0x21, 0x59, 0x7d, 0xf8, + 0xdb, 0x8b, 0x55, 0xe3, 0xd9, 0x8b, 0x55, 0xe3, 0xcf, 0x17, 0xab, 0xc6, 0x4f, 0x2f, 0x57, 0xe7, + 0x9e, 0xbd, 0x5c, 0x9d, 0xfb, 0xe3, 0xe5, 0xea, 0xdc, 0xd7, 0xff, 0x3a, 0xcc, 0x28, 0xfe, 0xc5, + 0x2e, 0x27, 0x6b, 0xa5, 0xe5, 0x17, 0xfb, 0xcd, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa6, 0x40, + 0x45, 0xa7, 0x8e, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -1115,15 +1118,10 @@ func (m *BTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintBtcstaking(dAtA, i, uint64(size)) - } + if len(m.StakerAddr) > 0 { + i -= len(m.StakerAddr) + copy(dAtA[i:], m.StakerAddr) + i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.StakerAddr))) i-- dAtA[i] = 0xa } @@ -1510,8 +1508,8 @@ func (m *BTCDelegation) Size() (n int) { } var l int _ = l - if m.BabylonPk != nil { - l = m.BabylonPk.Size() + l = len(m.StakerAddr) + if l > 0 { n += 1 + l + sovBtcstaking(uint64(l)) } if m.BtcPk != nil { @@ -2160,9 +2158,9 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StakerAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowBtcstaking @@ -2172,27 +2170,23 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthBtcstaking } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthBtcstaking } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.StakerAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -2259,7 +2253,7 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Pop == nil { - m.Pop = &ProofOfPossession{} + m.Pop = &ProofOfPossessionBTC{} } if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 1f687ab16..3c8ebd5a0 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -87,7 +87,7 @@ func (v *FinalityProviderDistInfo) GetAddress() sdk.AccAddress { func (v *FinalityProviderDistInfo) AddBTCDel(btcDel *BTCDelegation) { btcDelDistInfo := &BTCDelDistInfo{ BtcPk: btcDel.BtcPk, - BabylonPk: btcDel.BabylonPk, + StakerAddr: btcDel.StakerAddr, StakingTxHash: btcDel.MustGetStakingTxHash().String(), VotingPower: btcDel.TotalSat, } @@ -107,5 +107,5 @@ func (v *FinalityProviderDistInfo) GetBTCDelPortion(d *BTCDelDistInfo) sdkmath.L } func (d *BTCDelDistInfo) GetAddress() sdk.AccAddress { - return sdk.AccAddress(d.BabylonPk.Address()) + return sdk.MustAccAddressFromBech32(d.StakerAddr) } diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index 601912c7c..2a96c2a0f 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -156,8 +156,8 @@ type BTCDelDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // babylon_pk is the Babylon public key of the BTC delegation - BabylonPk *secp256k1.PubKey `protobuf:"bytes,2,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // staker_addr is the address to receive rewards from BTC delegation. + StakerAddr string `protobuf:"bytes,2,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // staking_tx_hash is the staking tx hash of the BTC delegation StakingTxHash string `protobuf:"bytes,3,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` // voting_power is the voting power of the BTC delegation @@ -197,11 +197,11 @@ func (m *BTCDelDistInfo) XXX_DiscardUnknown() { var xxx_messageInfo_BTCDelDistInfo proto.InternalMessageInfo -func (m *BTCDelDistInfo) GetBabylonPk() *secp256k1.PubKey { +func (m *BTCDelDistInfo) GetStakerAddr() string { if m != nil { - return m.BabylonPk + return m.StakerAddr } - return nil + return "" } func (m *BTCDelDistInfo) GetStakingTxHash() string { @@ -229,39 +229,41 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 507 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0x9b, 0xee, 0x0f, 0xcc, 0x1d, 0xff, 0xa2, 0x21, 0x95, 0x21, 0xa5, 0xa5, 0xd2, 0x50, - 0x0f, 0xcc, 0xa6, 0x1d, 0xec, 0x88, 0x50, 0x16, 0x21, 0x26, 0x36, 0x29, 0x8a, 0x26, 0x0e, 0x1c, - 0x88, 0x1c, 0xd7, 0x4d, 0xac, 0x24, 0x76, 0x54, 0x7b, 0xa1, 0xf9, 0x16, 0x7c, 0x08, 0x3e, 0x02, - 0x1f, 0x82, 0xe3, 0xc4, 0x09, 0xed, 0x30, 0xa1, 0xf6, 0x82, 0xf8, 0x14, 0x28, 0x89, 0xd9, 0x0a, - 0x5a, 0xc5, 0x95, 0x5b, 0xde, 0x3c, 0xcf, 0xfb, 0xbe, 0x7e, 0x7e, 0x96, 0xc1, 0x4e, 0x80, 0x83, - 0x22, 0x11, 0x1c, 0x05, 0x8a, 0x48, 0x85, 0x63, 0xc6, 0x43, 0x94, 0x0f, 0x10, 0xe3, 0x84, 0x72, - 0xc5, 0x72, 0x0a, 0xb3, 0x89, 0x50, 0xc2, 0xbc, 0xaf, 0x6d, 0xf0, 0xca, 0x06, 0xf3, 0xc1, 0xf6, - 0x56, 0x28, 0x42, 0x51, 0x39, 0x50, 0xf9, 0x55, 0x9b, 0xb7, 0x1f, 0x10, 0x21, 0x53, 0x21, 0xfd, - 0x5a, 0xa8, 0x0b, 0x2d, 0xf5, 0xea, 0x0a, 0x91, 0x49, 0x91, 0x29, 0x81, 0x24, 0x25, 0xd9, 0xf0, - 0xf9, 0x7e, 0x3c, 0x40, 0x31, 0x2d, 0xb4, 0xa7, 0xf7, 0xc9, 0x00, 0x5b, 0x6f, 0x85, 0x62, 0x3c, - 0x74, 0xc5, 0x07, 0x3a, 0x71, 0x98, 0x54, 0x07, 0x98, 0x44, 0xd4, 0x7c, 0x02, 0x4c, 0x25, 0x14, - 0x4e, 0xfc, 0xbc, 0x52, 0xfd, 0xac, 0x94, 0xdb, 0x46, 0xd7, 0xe8, 0xaf, 0x7a, 0x77, 0x2b, 0x65, - 0xa1, 0xcd, 0x7c, 0x0f, 0xcc, 0x31, 0xe3, 0x38, 0x61, 0xaa, 0x28, 0x4f, 0x92, 0xb3, 0x11, 0x9d, - 0xc8, 0x76, 0xb3, 0xbb, 0xd2, 0x6f, 0x0d, 0x11, 0xbc, 0x36, 0x0f, 0x7c, 0xa5, 0x1b, 0x5c, 0xed, - 0x2f, 0x77, 0x1f, 0xf2, 0xb1, 0xf0, 0xee, 0x8d, 0xff, 0x52, 0x64, 0xef, 0x47, 0x13, 0xb4, 0x97, - 0xf9, 0xcd, 0x63, 0xb0, 0x1e, 0x28, 0xe2, 0x67, 0x71, 0x75, 0xbc, 0x4d, 0x7b, 0xff, 0xfc, 0xa2, - 0x33, 0x0c, 0x99, 0x8a, 0x4e, 0x03, 0x48, 0x44, 0x8a, 0xf4, 0x7a, 0x12, 0x61, 0xc6, 0x7f, 0x17, - 0x48, 0x15, 0x19, 0x95, 0xd0, 0x3e, 0x74, 0xf7, 0x9e, 0x3d, 0x75, 0x4f, 0x83, 0x37, 0xb4, 0xf0, - 0xd6, 0x02, 0x45, 0xdc, 0xd8, 0x7c, 0x01, 0x80, 0x36, 0x95, 0x23, 0x9b, 0x5d, 0xa3, 0xdf, 0x1a, - 0x76, 0xa0, 0x26, 0x5b, 0xb3, 0x84, 0x97, 0x2c, 0xa1, 0xee, 0xdd, 0xd0, 0x2d, 0x6e, 0x6c, 0x1e, - 0x03, 0x40, 0x44, 0x9a, 0x32, 0x29, 0x99, 0xe0, 0xed, 0x95, 0xae, 0xd1, 0xdf, 0xb0, 0x77, 0xcf, - 0x2f, 0x3a, 0x0f, 0xeb, 0x11, 0x72, 0x14, 0x43, 0x26, 0x50, 0x8a, 0x55, 0x04, 0x8f, 0x68, 0x88, - 0x49, 0xe1, 0x50, 0xf2, 0xf5, 0xf3, 0x2e, 0xd0, 0x1b, 0x1c, 0x4a, 0xbc, 0x85, 0x01, 0x4b, 0x2e, - 0x62, 0x75, 0xc9, 0x45, 0xbc, 0x04, 0x37, 0x4b, 0x16, 0x23, 0x9a, 0xc8, 0xf6, 0x5a, 0x85, 0x7f, - 0x67, 0x09, 0x7e, 0xfb, 0xe4, 0xc0, 0xa1, 0xc9, 0x25, 0xf4, 0x1b, 0x81, 0x22, 0x0e, 0x4d, 0x64, - 0xef, 0xa7, 0x01, 0x6e, 0xff, 0xa9, 0xfd, 0x6f, 0x80, 0x1f, 0x83, 0x3b, 0x3a, 0x87, 0xaf, 0xa6, - 0x7e, 0x84, 0x65, 0x54, 0x53, 0xf6, 0x6e, 0xe9, 0xdf, 0x27, 0xd3, 0xd7, 0x58, 0x46, 0xe6, 0x23, - 0xb0, 0x79, 0x0d, 0xb3, 0x56, 0x7e, 0x85, 0xcb, 0x3e, 0xfa, 0x32, 0xb3, 0x8c, 0xb3, 0x99, 0x65, - 0x7c, 0x9f, 0x59, 0xc6, 0xc7, 0xb9, 0xd5, 0x38, 0x9b, 0x5b, 0x8d, 0x6f, 0x73, 0xab, 0xf1, 0xee, - 0x9f, 0xf9, 0xa6, 0x8b, 0xaf, 0xb8, 0x0a, 0x1b, 0xac, 0x57, 0x6f, 0x6a, 0xef, 0x57, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x0c, 0xa8, 0xb2, 0x95, 0xe8, 0x03, 0x00, 0x00, + // 542 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xcf, 0x6e, 0xd3, 0x30, + 0x1c, 0xc7, 0x9b, 0xee, 0x0f, 0xd4, 0x1d, 0xff, 0xa2, 0x22, 0x85, 0x21, 0xa5, 0xa5, 0xd2, 0x50, + 0x0f, 0xd4, 0xa1, 0x1d, 0x4c, 0xe2, 0x82, 0x20, 0xab, 0x10, 0x13, 0x9b, 0x14, 0x85, 0x89, 0x03, + 0x07, 0x22, 0xc7, 0x71, 0x13, 0x2b, 0x69, 0x1c, 0xc5, 0x5e, 0x68, 0xde, 0x82, 0x87, 0xe0, 0x11, + 0xf6, 0x10, 0x1c, 0xa7, 0x9d, 0xd0, 0x0e, 0x13, 0x6a, 0x85, 0xc4, 0x63, 0xa0, 0x24, 0x66, 0x2b, + 0x68, 0x15, 0x97, 0xdd, 0xfc, 0xf3, 0xf7, 0xfb, 0xfb, 0xf7, 0xb1, 0x0c, 0xb6, 0x5c, 0xe4, 0xe6, + 0x11, 0x8b, 0x0d, 0x57, 0x60, 0x2e, 0x50, 0x48, 0x63, 0xdf, 0xc8, 0x06, 0x06, 0x8d, 0x31, 0x89, + 0x05, 0xcd, 0x08, 0x4c, 0x52, 0x26, 0x98, 0x7a, 0x5f, 0xda, 0xe0, 0xa5, 0x0d, 0x66, 0x83, 0xcd, + 0x96, 0xcf, 0x7c, 0x56, 0x3a, 0x8c, 0xe2, 0x54, 0x99, 0x37, 0x1f, 0x60, 0xc6, 0x27, 0x8c, 0x3b, + 0x95, 0x50, 0x05, 0x52, 0xea, 0x56, 0x91, 0x81, 0xd3, 0x3c, 0x11, 0xcc, 0xe0, 0x04, 0x27, 0xc3, + 0xe7, 0x3b, 0xe1, 0xc0, 0x08, 0x49, 0x2e, 0x3d, 0xdd, 0xaf, 0x0a, 0x68, 0x7d, 0x60, 0x82, 0xc6, + 0xbe, 0xc5, 0x3e, 0x93, 0x74, 0x44, 0xb9, 0xd8, 0x45, 0x38, 0x20, 0xea, 0x13, 0xa0, 0x0a, 0x26, + 0x50, 0xe4, 0x64, 0xa5, 0xea, 0x24, 0x85, 0xac, 0x29, 0x1d, 0xa5, 0xb7, 0x6a, 0xdf, 0x2d, 0x95, + 0x85, 0x34, 0xf5, 0x13, 0x50, 0xc7, 0x34, 0x46, 0x11, 0x15, 0x79, 0x31, 0x49, 0x46, 0x3d, 0x92, + 0x72, 0xad, 0xde, 0x59, 0xe9, 0x35, 0x87, 0x06, 0xbc, 0x72, 0x1f, 0xf8, 0x46, 0x26, 0x58, 0xd2, + 0x5f, 0xf4, 0xde, 0x8b, 0xc7, 0xcc, 0xbe, 0x37, 0xfe, 0x47, 0xe1, 0xdd, 0x5f, 0x75, 0xa0, 0x2d, + 0xf3, 0xab, 0x07, 0x60, 0xdd, 0x15, 0xd8, 0x49, 0xc2, 0x72, 0xbc, 0x0d, 0x73, 0xe7, 0xec, 0xbc, + 0x3d, 0xf4, 0xa9, 0x08, 0x8e, 0x5c, 0x88, 0xd9, 0xc4, 0x90, 0xed, 0x71, 0x80, 0x68, 0xfc, 0x27, + 0x30, 0x44, 0x9e, 0x10, 0x0e, 0xcd, 0x3d, 0x6b, 0xfb, 0xd9, 0x53, 0xeb, 0xc8, 0x7d, 0x47, 0x72, + 0x7b, 0xcd, 0x15, 0xd8, 0x0a, 0xd5, 0x97, 0x00, 0x48, 0x53, 0x51, 0xb2, 0xde, 0x51, 0x7a, 0xcd, + 0x61, 0x1b, 0x4a, 0xb2, 0x15, 0x4b, 0x78, 0xc1, 0x12, 0xca, 0xdc, 0x86, 0x4c, 0xb1, 0x42, 0xf5, + 0x00, 0x00, 0xcc, 0x26, 0x13, 0xca, 0x39, 0x65, 0xb1, 0xb6, 0xd2, 0x51, 0x7a, 0x0d, 0xb3, 0x7f, + 0x76, 0xde, 0x7e, 0x58, 0x95, 0xe0, 0x5e, 0x08, 0x29, 0x33, 0x26, 0x48, 0x04, 0x70, 0x9f, 0xf8, + 0x08, 0xe7, 0x23, 0x82, 0x4f, 0x8f, 0xfb, 0x40, 0x76, 0x18, 0x11, 0x6c, 0x2f, 0x14, 0x58, 0xf2, + 0x10, 0xab, 0x4b, 0x1e, 0xe2, 0x15, 0xb8, 0x59, 0xb0, 0xf0, 0x48, 0xc4, 0xb5, 0xb5, 0x12, 0xff, + 0xd6, 0x12, 0xfc, 0xe6, 0xe1, 0xee, 0x88, 0x44, 0x17, 0xd0, 0x6f, 0xb8, 0x02, 0x8f, 0x48, 0xc4, + 0xbb, 0x3f, 0x15, 0x70, 0xfb, 0x6f, 0xed, 0xba, 0x01, 0xbf, 0x00, 0xcd, 0x62, 0x0e, 0x92, 0x3a, + 0xc8, 0xf3, 0xd2, 0x92, 0x70, 0xc3, 0xd4, 0x4e, 0x8f, 0xfb, 0x2d, 0x89, 0xe0, 0xb5, 0xe7, 0xa5, + 0x84, 0xf3, 0xf7, 0x22, 0xa5, 0xb1, 0x6f, 0x83, 0xca, 0x5c, 0x5c, 0xaa, 0x8f, 0xc1, 0x1d, 0xb9, + 0x82, 0x23, 0xa6, 0x4e, 0x80, 0x78, 0x50, 0x01, 0xb6, 0x6f, 0xc9, 0xeb, 0xc3, 0xe9, 0x5b, 0xc4, + 0x03, 0xf5, 0x11, 0xd8, 0xb8, 0x02, 0x57, 0x33, 0xbb, 0x24, 0x65, 0xee, 0x7f, 0x9b, 0xe9, 0xca, + 0xc9, 0x4c, 0x57, 0x7e, 0xcc, 0x74, 0xe5, 0xcb, 0x5c, 0xaf, 0x9d, 0xcc, 0xf5, 0xda, 0xf7, 0xb9, + 0x5e, 0xfb, 0xf8, 0xdf, 0xd5, 0xa6, 0x8b, 0x1f, 0xb8, 0xdc, 0xd3, 0x5d, 0x2f, 0xbf, 0xd3, 0xf6, + 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0xba, 0x97, 0x72, 0xe3, 0x03, 0x00, 0x00, } func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { @@ -416,15 +418,10 @@ func (m *BTCDelDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintIncentive(dAtA, i, uint64(size)) - } + if len(m.StakerAddr) > 0 { + i -= len(m.StakerAddr) + copy(dAtA[i:], m.StakerAddr) + i = encodeVarintIncentive(dAtA, i, uint64(len(m.StakerAddr))) i-- dAtA[i] = 0x12 } @@ -512,8 +509,8 @@ func (m *BTCDelDistInfo) Size() (n int) { l = m.BtcPk.Size() n += 1 + l + sovIncentive(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() + l = len(m.StakerAddr) + if l > 0 { n += 1 + l + sovIncentive(uint64(l)) } l = len(m.StakingTxHash) @@ -911,9 +908,9 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StakerAddr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowIncentive @@ -923,27 +920,23 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthIncentive } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthIncentive } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.StakerAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index ba77caf15..9d2e86fe2 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -79,8 +79,8 @@ func (m *MsgEditFinalityProvider) ValidateBasic() error { } func (m *MsgCreateBTCDelegation) ValidateBasic() error { - if m.BabylonPk == nil { - return fmt.Errorf("empty Babylon public key") + if _, err := sdk.AccAddressFromBech32(m.StakerAddr); err != nil { + return fmt.Errorf("invalid staker addr %s: %w", m.StakerAddr, err) } if m.Pop == nil { return fmt.Errorf("empty proof of possession") @@ -110,10 +110,6 @@ func (m *MsgCreateBTCDelegation) ValidateBasic() error { return fmt.Errorf("invalid delegator slashing signature: %w", err) } - if _, err := sdk.AccAddressFromBech32(m.Signer); err != nil { - return err - } - // Check staking time is at most uint16 if m.StakingTime > math.MaxUint16 { return ErrInvalidStakingTx.Wrapf("invalid lock time: %d, max: %d", m.StakingTime, math.MaxUint16) diff --git a/x/btcstaking/types/pop.go b/x/btcstaking/types/pop.go index 1c0521661..75e457c6e 100644 --- a/x/btcstaking/types/pop.go +++ b/x/btcstaking/types/pop.go @@ -16,6 +16,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/cometbft/cometbft/crypto/tmhash" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) type checkStakerKey func(stakerKey *bbn.BIP340PubKey) error @@ -56,6 +57,28 @@ func NewPoP(babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKey) (*ProofOfPos return &pop, nil } +// NewPoPBTC generates a new proof of possession that sk_BTC and the address are held by the same person +// a proof of possession contains only one signature +// - pop.BtcSig = schnorr_sign(sk_BTC, bbnAddress) +func NewPoPBTC(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*ProofOfPossessionBTC, error) { + pop := ProofOfPossessionBTC{ + BtcSigType: BTCSigType_BIP340, // by default, we use BIP-340 encoding for BTC signature + } + + // generate pop.BtcSig = schnorr_sign(sk_BTC, hash(bbnAddress)) + // NOTE: *schnorr.Sign has to take the hash of the message. + // So we have to hash the address before signing + hash := tmhash.Sum(addr.Bytes()) + btcSig, err := schnorr.Sign(btcSK, hash) + if err != nil { + return nil, err + } + bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig) + pop.BtcSig = bip340Sig.MustMarshal() + + return &pop, nil +} + // NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format // a proof of possession contains two signatures: // - pop.BabylonSig = sign(sk_Babylon, pk_BTC) @@ -87,6 +110,27 @@ func NewPoPWithECDSABTCSig(babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKe return &pop, nil } +// NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format +// a proof of possession contains two signatures: +// - pop.BtcSig = ecdsa_sign(sk_BTC, addr) +func NewPoPBTCWithECDSABTCSig(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*ProofOfPossessionBTC, error) { + pop := ProofOfPossessionBTC{ + BtcSigType: BTCSigType_ECDSA, + } + + // generate pop.BtcSig = ecdsa_sign(sk_BTC, pop.BabylonSig) + // NOTE: ecdsa.Sign has to take the message as string. + // So we have to hex addr before signing + addrHex := hex.EncodeToString(addr.Bytes()) + btcSig, err := ecdsa.Sign(btcSK, addrHex) + if err != nil { + return nil, err + } + pop.BtcSig = btcSig + + return &pop, nil +} + func babylonSigToHexHash(babylonSig []byte) []byte { babylonSigHash := tmhash.Sum(babylonSig) babylonSigHashHex := hex.EncodeToString(babylonSigHash) @@ -118,12 +162,46 @@ func newPoPWithBIP322Sig[A btcutil.Address]( // ref: https://github.com/babylonchain/babylon/issues/433 bbnSigHashHexBytes := babylonSigToHexHash(pop.BabylonSig) + bip322SigEncoded, err := newBIP322Sig(bbnSigHashHexBytes, btcSK, net, bip322SignFn) + if err != nil { + return nil, err + } + pop.BtcSig = bip322SigEncoded + + return &pop, nil +} + +func newPoPBTCWithBIP322Sig[A btcutil.Address]( + addressToSign sdk.AccAddress, + btcSK *btcec.PrivateKey, + net *chaincfg.Params, + bip322SignFn bip322Sign[A], +) (*ProofOfPossessionBTC, error) { + pop := ProofOfPossessionBTC{ + BtcSigType: BTCSigType_BIP322, + } + + bip322SigEncoded, err := newBIP322Sig(tmhash.Sum(addressToSign.Bytes()), btcSK, net, bip322SignFn) + if err != nil { + return nil, err + } + pop.BtcSig = bip322SigEncoded + + return &pop, nil +} + +func newBIP322Sig[A btcutil.Address]( + msgToSign []byte, + btcSK *btcec.PrivateKey, + net *chaincfg.Params, + bip322SignFn bip322Sign[A], +) ([]byte, error) { + address, witnessSignture, err := bip322SignFn( - bbnSigHashHexBytes, + msgToSign, btcSK, net, ) - if err != nil { return nil, err } @@ -133,14 +211,7 @@ func newPoPWithBIP322Sig[A btcutil.Address]( Sig: witnessSignture, } - bip322SigEncoded, err := bip322Sig.Marshal() - - if err != nil { - return nil, err - } - pop.BtcSig = bip322SigEncoded - - return &pop, nil + return bip322Sig.Marshal() } func NewPoPWithBIP322P2WPKHSig( @@ -151,6 +222,16 @@ func NewPoPWithBIP322P2WPKHSig( return newPoPWithBIP322Sig(babylonSK, btcSK, net, bip322.SignWithP2WPKHAddress) } +// NewPoPBTCWithBIP322P2WPKHSig creates a proof of possession of type BIP322 +// that signs the address with the BTC secret key. +func NewPoPBTCWithBIP322P2WPKHSig( + addr sdk.AccAddress, + btcSK *btcec.PrivateKey, + net *chaincfg.Params, +) (*ProofOfPossessionBTC, error) { + return newPoPBTCWithBIP322Sig(addr, btcSK, net, bip322.SignWithP2WPKHAddress) +} + func NewPoPWithBIP322P2TRBIP86Sig( babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKey, @@ -171,6 +252,18 @@ func NewPoPFromHex(popHex string) (*ProofOfPossession, error) { return &pop, nil } +func NewPoPBTCFromHex(popHex string) (*ProofOfPossessionBTC, error) { + popBytes, err := hex.DecodeString(popHex) + if err != nil { + return nil, err + } + var pop ProofOfPossessionBTC + if err := pop.Unmarshal(popBytes); err != nil { + return nil, err + } + return &pop, nil +} + func (pop *ProofOfPossession) ToHexStr() (string, error) { popBytes, err := pop.Marshal() if err != nil { @@ -179,6 +272,14 @@ func (pop *ProofOfPossession) ToHexStr() (string, error) { return hex.EncodeToString(popBytes), nil } +func (pop *ProofOfPossessionBTC) ToHexStr() (string, error) { + popBytes, err := pop.Marshal() + if err != nil { + return "", err + } + return hex.EncodeToString(popBytes), nil +} + func (pop *ProofOfPossession) Verify(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { switch pop.BtcSigType { case BTCSigType_BIP340: @@ -192,16 +293,27 @@ func (pop *ProofOfPossession) Verify(babylonPK cryptotypes.PubKey, bip340PK *bbn } } -// VerifyBIP340 verifies the validity of PoP where Bitcoin signature is in BIP-340 -// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? -// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? -func (pop *ProofOfPossession) VerifyBIP340(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { - if pop.BtcSigType != BTCSigType_BIP340 { +// Verify that the BTC private key corresponding to the bip340PK signed the staker address +func (pop *ProofOfPossessionBTC) Verify(staker sdk.AccAddress, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { + switch pop.BtcSigType { + case BTCSigType_BIP340: + return pop.VerifyBIP340(staker, bip340PK) + case BTCSigType_BIP322: + return pop.VerifyBIP322(staker, bip340PK, net) + case BTCSigType_ECDSA: + return pop.VerifyECDSA(staker, bip340PK) + default: + return fmt.Errorf("invalid BTC signature type") + } +} + +// VerifyBIP340 if the BTC signature has signed the hash by the pair of bip340PK. +func VerifyBIP340(sigType BTCSigType, btcSigRaw []byte, bip340PK *bbn.BIP340PubKey, msg []byte) error { + if sigType != BTCSigType_BIP340 { return fmt.Errorf("the Bitcoin signature in this proof of possession is not using BIP-340 encoding") } - // rule 1: verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? - bip340Sig, err := bbn.NewBIP340Signature(pop.BtcSig) + bip340Sig, err := bbn.NewBIP340Signature(btcSigRaw) if err != nil { return err } @@ -213,13 +325,31 @@ func (pop *ProofOfPossession) VerifyBIP340(babylonPK cryptotypes.PubKey, bip340P if err != nil { return err } + // NOTE: btcSig.Verify has to take hash of the message. // So we have to hash babylonSig before verifying the signature - babylonSigHash := tmhash.Sum(pop.BabylonSig) - if !btcSig.Verify(babylonSigHash, btcPK) { + hash := tmhash.Sum(msg) + if !btcSig.Verify(hash, btcPK) { return fmt.Errorf("failed to verify pop.BtcSig") } + return nil +} + +// VerifyBIP340 verifies the validity of PoP where Bitcoin signature is in BIP-340 +// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=staker_addr)? +func (pop *ProofOfPossessionBTC) VerifyBIP340(stakerAddr sdk.AccAddress, bip340PK *bbn.BIP340PubKey) error { + return VerifyBIP340(pop.BtcSigType, pop.BtcSig, bip340PK, stakerAddr.Bytes()) +} + +// VerifyBIP340 verifies the validity of PoP where Bitcoin signature is in BIP-340 +// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? +// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? +func (pop *ProofOfPossession) VerifyBIP340(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { + if err := VerifyBIP340(pop.BtcSigType, pop.BtcSig, bip340PK, pop.BabylonSig); err != nil { + return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) + } + // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? if !babylonPK.VerifySignature(*bip340PK, pop.BabylonSig) { return fmt.Errorf("failed to verify pop.BabylonSig") @@ -361,31 +491,25 @@ func VerifyBIP322SigPop( // VerifyBIP322 verifies the validity of PoP where Bitcoin signature is in BIP-322 // after decoding pop.BtcSig to bip322Sig which contains sig and address, -// 1. verify whether bip322 pop signature where msg=pop.BabylonSig -// 2. verify(sig=pop.BabylonSig, pubkey=babylonPK, msg=bip340PK)? -func (pop *ProofOfPossession) VerifyBIP322(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { - if pop.BtcSigType != BTCSigType_BIP322 { +// verify whether bip322 pop signature where msg=signedMsg +func VerifyBIP322(sigType BTCSigType, btcSigRaw []byte, bip340PK *bbn.BIP340PubKey, signedMsg []byte, net *chaincfg.Params) error { + if sigType != BTCSigType_BIP322 { return fmt.Errorf("the Bitcoin signature in this proof of possession is not using BIP-322 encoding") } // unmarshal pop.BtcSig to bip322Sig var bip322Sig BIP322Sig - if err := bip322Sig.Unmarshal(pop.BtcSig); err != nil { + if err := bip322Sig.Unmarshal(btcSigRaw); err != nil { return nil } - // TODO: temporary solution for MVP purposes. - // Eventually we need to use tmhash.Sum(pop.BabylonSig) rather than bbnSigHashHexBytes - // ref: https://github.com/babylonchain/babylon/issues/433 - bbnSigHashHexBytes := babylonSigToHexHash(pop.BabylonSig) - btcKeyBytes, err := bip340PK.Marshal() if err != nil { return err } - // 1. Verify Bip322 proof of possession signature + // Verify Bip322 proof of possession signature if err := VerifyBIP322SigPop( - bbnSigHashHexBytes, + signedMsg, bip322Sig.Address, bip322Sig.Sig, btcKeyBytes, @@ -394,6 +518,22 @@ func (pop *ProofOfPossession) VerifyBIP322(babylonPK cryptotypes.PubKey, bip340P return err } + return nil +} + +// VerifyBIP322 verifies the validity of PoP where Bitcoin signature is in BIP-322 +// after decoding pop.BtcSig to bip322Sig which contains sig and address, +// 1. verify whether bip322 pop signature where msg=pop.BabylonSig +// 2. verify(sig=pop.BabylonSig, pubkey=babylonPK, msg=bip340PK)? +func (pop *ProofOfPossession) VerifyBIP322(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { + // TODO: temporary solution for MVP purposes. + // Eventually we need to use tmhash.Sum(pop.BabylonSig) rather than bbnSigHashHexBytes + // ref: https://github.com/babylonchain/babylon/issues/433 + bbnSigHashHexBytes := babylonSigToHexHash(pop.BabylonSig) + if err := VerifyBIP322(pop.BtcSigType, pop.BtcSig, bip340PK, bbnSigHashHexBytes, net); err != nil { + return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) + } + // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? if !babylonPK.VerifySignature(*bip340PK, pop.BabylonSig) { return fmt.Errorf("failed to verify pop.BabylonSig") @@ -402,24 +542,46 @@ func (pop *ProofOfPossession) VerifyBIP322(babylonPK cryptotypes.PubKey, bip340P return nil } +// VerifyBIP322 verifies the validity of PoP where Bitcoin signature is in BIP-322 +// after decoding pop.BtcSig to bip322Sig which contains sig and address, +// 1. verify whether bip322 pop signature where msg=pop.BabylonSig +// 2. verify(sig=pop.BabylonSig, pubkey=babylonPK, msg=bip340PK)? +func (pop *ProofOfPossessionBTC) VerifyBIP322(addr sdk.AccAddress, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { + msg := tmhash.Sum(addr.Bytes()) + if err := VerifyBIP322(pop.BtcSigType, pop.BtcSig, bip340PK, msg, net); err != nil { + return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) + } + return nil +} + // VerifyECDSA verifies the validity of PoP where Bitcoin signature is in ECDSA encoding -// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? -// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? -func (pop *ProofOfPossession) VerifyECDSA(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { - if pop.BtcSigType != BTCSigType_ECDSA { +// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=msg)? +func VerifyECDSA(sigType BTCSigType, btcSigRaw []byte, bip340PK *bbn.BIP340PubKey, msg []byte) error { + if sigType != BTCSigType_ECDSA { return fmt.Errorf("the Bitcoin signature in this proof of possession is not using ECDSA encoding") } - // rule 1: verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? + // rule 1: verify(sig=sig_btc, pubkey=pk_btc, msg=msg)? btcPK, err := bip340PK.ToBTCPK() if err != nil { return err } // NOTE: ecdsa.Verify has to take message as a string // So we have to hex BabylonSig before verifying the signature - bbnSigHex := hex.EncodeToString(pop.BabylonSig) - if err := ecdsa.Verify(btcPK, bbnSigHex, pop.BtcSig); err != nil { - return fmt.Errorf("failed to verify pop.BtcSig") + bbnSigHex := hex.EncodeToString(msg) + if err := ecdsa.Verify(btcPK, bbnSigHex, btcSigRaw); err != nil { + return fmt.Errorf("failed to verify btcSigRaw") + } + + return nil +} + +// VerifyECDSA verifies the validity of PoP where Bitcoin signature is in ECDSA encoding +// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? +// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? +func (pop *ProofOfPossession) VerifyECDSA(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { + if err := VerifyECDSA(pop.BtcSigType, pop.BtcSig, bip340PK, pop.BabylonSig); err != nil { + return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) } // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? @@ -430,6 +592,12 @@ func (pop *ProofOfPossession) VerifyECDSA(babylonPK cryptotypes.PubKey, bip340PK return nil } +// VerifyECDSA verifies the validity of PoP where Bitcoin signature is in ECDSA encoding +// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=addr)? +func (pop *ProofOfPossessionBTC) VerifyECDSA(addr sdk.AccAddress, bip340PK *bbn.BIP340PubKey) error { + return VerifyECDSA(pop.BtcSigType, pop.BtcSig, bip340PK, addr.Bytes()) +} + func (pop *ProofOfPossession) ValidateBasic() error { if len(pop.BabylonSig) == 0 { return fmt.Errorf("empty Babylon signature") @@ -440,3 +608,32 @@ func (pop *ProofOfPossession) ValidateBasic() error { return nil } + +// ValidateBasic checks if there is a BTC Signature. +func (pop *ProofOfPossessionBTC) ValidateBasic() error { + if pop.BtcSig == nil { + return fmt.Errorf("empty BTC signature") + } + + switch pop.BtcSigType { + case BTCSigType_BIP340: + _, err := bbn.NewBIP340Signature(pop.BtcSig) + if err != nil { + return fmt.Errorf("invalid BTC BIP340 signature: %w", err) + } + return nil + case BTCSigType_BIP322: + var bip322Sig BIP322Sig + if err := bip322Sig.Unmarshal(pop.BtcSig); err != nil { + return fmt.Errorf("invalid BTC BIP322 signature: %w", err) + } + return nil + case BTCSigType_ECDSA: + if len(pop.BtcSig) != 65 { // size of compact signature + return fmt.Errorf("invalid BTC ECDSA signature size") + } + return nil + default: + return fmt.Errorf("invalid BTC signature type") + } +} diff --git a/x/btcstaking/types/pop.pb.go b/x/btcstaking/types/pop.pb.go index 672a3f88a..bf7cbafa4 100644 --- a/x/btcstaking/types/pop.pb.go +++ b/x/btcstaking/types/pop.pb.go @@ -122,6 +122,64 @@ func (m *ProofOfPossession) GetBtcSig() []byte { return nil } +// ProofOfPossessionBTC is the proof of possession that a Babylon +// address and a Bitcoin secp256k1 secret key are held by the same +// person +type ProofOfPossessionBTC struct { + // btc_sig_type indicates the type of btc_sig in the pop + BtcSigType BTCSigType `protobuf:"varint,1,opt,name=btc_sig_type,json=btcSigType,proto3,enum=babylon.btcstaking.v1.BTCSigType" json:"btc_sig_type,omitempty"` + // btc_sig is the signature generated via sign(sk_btc, babylon_staker_address) + // the signature follows encoding in either BIP-340 spec or BIP-322 spec + BtcSig []byte `protobuf:"bytes,2,opt,name=btc_sig,json=btcSig,proto3" json:"btc_sig,omitempty"` +} + +func (m *ProofOfPossessionBTC) Reset() { *m = ProofOfPossessionBTC{} } +func (m *ProofOfPossessionBTC) String() string { return proto.CompactTextString(m) } +func (*ProofOfPossessionBTC) ProtoMessage() {} +func (*ProofOfPossessionBTC) Descriptor() ([]byte, []int) { + return fileDescriptor_9d6ceb088d9e9f3a, []int{1} +} +func (m *ProofOfPossessionBTC) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ProofOfPossessionBTC) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ProofOfPossessionBTC.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 *ProofOfPossessionBTC) XXX_Merge(src proto.Message) { + xxx_messageInfo_ProofOfPossessionBTC.Merge(m, src) +} +func (m *ProofOfPossessionBTC) XXX_Size() int { + return m.Size() +} +func (m *ProofOfPossessionBTC) XXX_DiscardUnknown() { + xxx_messageInfo_ProofOfPossessionBTC.DiscardUnknown(m) +} + +var xxx_messageInfo_ProofOfPossessionBTC proto.InternalMessageInfo + +func (m *ProofOfPossessionBTC) GetBtcSigType() BTCSigType { + if m != nil { + return m.BtcSigType + } + return BTCSigType_BIP340 +} + +func (m *ProofOfPossessionBTC) GetBtcSig() []byte { + if m != nil { + return m.BtcSig + } + return nil +} + // BIP322Sig is a BIP-322 signature together with the address corresponding to // the signer type BIP322Sig struct { @@ -135,7 +193,7 @@ func (m *BIP322Sig) Reset() { *m = BIP322Sig{} } func (m *BIP322Sig) String() string { return proto.CompactTextString(m) } func (*BIP322Sig) ProtoMessage() {} func (*BIP322Sig) Descriptor() ([]byte, []int) { - return fileDescriptor_9d6ceb088d9e9f3a, []int{1} + return fileDescriptor_9d6ceb088d9e9f3a, []int{2} } func (m *BIP322Sig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -181,32 +239,34 @@ func (m *BIP322Sig) GetSig() []byte { func init() { proto.RegisterEnum("babylon.btcstaking.v1.BTCSigType", BTCSigType_name, BTCSigType_value) proto.RegisterType((*ProofOfPossession)(nil), "babylon.btcstaking.v1.ProofOfPossession") + proto.RegisterType((*ProofOfPossessionBTC)(nil), "babylon.btcstaking.v1.ProofOfPossessionBTC") proto.RegisterType((*BIP322Sig)(nil), "babylon.btcstaking.v1.BIP322Sig") } func init() { proto.RegisterFile("babylon/btcstaking/v1/pop.proto", fileDescriptor_9d6ceb088d9e9f3a) } var fileDescriptor_9d6ceb088d9e9f3a = []byte{ - // 298 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4f, 0xc2, 0x30, - 0x1c, 0xc5, 0x57, 0x88, 0x10, 0xfe, 0x12, 0x33, 0x9b, 0x18, 0x77, 0x2a, 0xc8, 0x89, 0x78, 0x68, - 0xa5, 0x98, 0x78, 0x16, 0xf4, 0x60, 0x62, 0x22, 0x01, 0x4e, 0x5e, 0xc8, 0x3a, 0xc6, 0x68, 0xd4, - 0x75, 0xa1, 0x95, 0xc8, 0xb7, 0x30, 0x7e, 0x2a, 0x8f, 0x1c, 0x3d, 0x9a, 0xed, 0x8b, 0x98, 0xcd, - 0x2e, 0xf3, 0xe0, 0xed, 0xbd, 0xf6, 0xf5, 0xd7, 0x97, 0x07, 0x1d, 0xe1, 0x8b, 0xdd, 0xb3, 0x8a, - 0x99, 0x30, 0x81, 0x36, 0xfe, 0x93, 0x8c, 0x23, 0xb6, 0x1d, 0xb0, 0x44, 0x25, 0x34, 0xd9, 0x28, - 0xa3, 0xf0, 0x89, 0x0d, 0xd0, 0x2a, 0x40, 0xb7, 0x83, 0xde, 0x07, 0x82, 0xe3, 0xc9, 0x46, 0xa9, - 0xd5, 0xc3, 0x6a, 0xa2, 0xb4, 0x0e, 0xb5, 0x96, 0x2a, 0xc6, 0x63, 0x68, 0x0b, 0x13, 0x2c, 0xb4, - 0x8c, 0x16, 0x66, 0x97, 0x84, 0x1e, 0xea, 0xa2, 0xfe, 0x11, 0x3f, 0xa3, 0xff, 0x32, 0xe8, 0x68, - 0x3e, 0x9e, 0xc9, 0x68, 0xbe, 0x4b, 0xc2, 0x29, 0x08, 0x13, 0x58, 0x8d, 0x3b, 0x70, 0x68, 0xf3, - 0x39, 0xc8, 0xab, 0x75, 0x51, 0xbf, 0x3d, 0x05, 0x7b, 0x34, 0x93, 0x11, 0x3e, 0x85, 0xa6, 0xfd, - 0xc5, 0xab, 0x17, 0x97, 0x8d, 0xdf, 0xd7, 0xbd, 0x2b, 0x68, 0x8d, 0xee, 0x26, 0x43, 0xce, 0xf3, - 0x94, 0x07, 0x4d, 0x7f, 0xb9, 0xdc, 0x84, 0x5a, 0x17, 0x35, 0x5a, 0xd3, 0xd2, 0x62, 0x17, 0xea, - 0x15, 0x38, 0x97, 0xe7, 0x0c, 0xa0, 0x2a, 0x83, 0x01, 0x1a, 0x39, 0xe6, 0xf2, 0xc2, 0x75, 0x4a, - 0xcd, 0xb9, 0x8b, 0x70, 0x0b, 0x0e, 0x6e, 0xc7, 0x37, 0xb3, 0x6b, 0xb7, 0x36, 0xba, 0xff, 0x4c, - 0x09, 0xda, 0xa7, 0x04, 0x7d, 0xa7, 0x04, 0xbd, 0x67, 0xc4, 0xd9, 0x67, 0xc4, 0xf9, 0xca, 0x88, - 0xf3, 0xc8, 0x23, 0x69, 0xd6, 0xaf, 0x82, 0x06, 0xea, 0x85, 0xd9, 0xce, 0xc1, 0xda, 0x97, 0x71, - 0x69, 0xd8, 0xdb, 0xdf, 0xa9, 0xf3, 0x95, 0xb4, 0x68, 0x14, 0x53, 0x0f, 0x7f, 0x02, 0x00, 0x00, - 0xff, 0xff, 0x89, 0x18, 0xe3, 0x67, 0x8d, 0x01, 0x00, 0x00, + // 317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0x4a, 0x4c, 0xaa, + 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x2e, 0x2e, 0x49, 0xcc, 0xce, 0xcc, 0x4b, 0xd7, 0x2f, + 0x33, 0xd4, 0x2f, 0xc8, 0x2f, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x85, 0x2a, 0xd0, + 0x43, 0x28, 0xd0, 0x2b, 0x33, 0x54, 0x9a, 0xc4, 0xc8, 0x25, 0x18, 0x50, 0x94, 0x9f, 0x9f, 0xe6, + 0x9f, 0x16, 0x90, 0x5f, 0x5c, 0x9c, 0x5a, 0x5c, 0x9c, 0x99, 0x9f, 0x27, 0xe4, 0xcc, 0xc5, 0x93, + 0x54, 0x92, 0x1c, 0x5f, 0x9c, 0x99, 0x1e, 0x5f, 0x52, 0x59, 0x90, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, + 0xc1, 0x67, 0xa4, 0xa8, 0x87, 0xd5, 0x0c, 0x3d, 0xa7, 0x10, 0xe7, 0xe0, 0xcc, 0xf4, 0x90, 0xca, + 0x82, 0xd4, 0x20, 0xae, 0xa4, 0x92, 0x64, 0x28, 0x5b, 0x48, 0x9e, 0x8b, 0x1b, 0xaa, 0x1e, 0x64, + 0x90, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x17, 0x54, 0x28, 0x38, 0x33, 0x5d, 0x48, 0x9c, + 0x8b, 0x1d, 0x6a, 0x8b, 0x04, 0x33, 0x58, 0x92, 0x0d, 0xa2, 0x5b, 0xa9, 0x84, 0x4b, 0x04, 0xc3, + 0x4d, 0x4e, 0x21, 0xce, 0xd4, 0x71, 0x16, 0x92, 0xad, 0x4c, 0x28, 0xb6, 0x9a, 0x73, 0x71, 0x3a, + 0x79, 0x06, 0x18, 0x1b, 0x19, 0x81, 0xdc, 0x26, 0xc1, 0xc5, 0x9e, 0x98, 0x92, 0x52, 0x94, 0x5a, + 0x5c, 0x0c, 0xb6, 0x85, 0x33, 0x08, 0xc6, 0x15, 0x12, 0xe0, 0x62, 0x46, 0xe8, 0x05, 0x31, 0xb5, + 0xf4, 0xb9, 0xb8, 0x10, 0x76, 0x09, 0x71, 0x71, 0xb1, 0x81, 0x8c, 0x31, 0x31, 0x10, 0x60, 0x80, + 0xb1, 0x8d, 0x8c, 0x04, 0x18, 0x85, 0x38, 0xb9, 0x58, 0x5d, 0x9d, 0x5d, 0x82, 0x1d, 0x05, 0x98, + 0x9c, 0x7c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, + 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x28, 0x3d, 0xb3, + 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xea, 0xab, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, + 0x18, 0x47, 0xbf, 0x02, 0x39, 0x82, 0x41, 0x81, 0x50, 0x9c, 0xc4, 0x06, 0x8e, 0x60, 0x63, 0x40, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x71, 0x75, 0x81, 0xa6, 0x03, 0x02, 0x00, 0x00, } func (m *ProofOfPossession) Marshal() (dAtA []byte, err error) { @@ -251,6 +311,41 @@ func (m *ProofOfPossession) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *ProofOfPossessionBTC) 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 *ProofOfPossessionBTC) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ProofOfPossessionBTC) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.BtcSig) > 0 { + i -= len(m.BtcSig) + copy(dAtA[i:], m.BtcSig) + i = encodeVarintPop(dAtA, i, uint64(len(m.BtcSig))) + i-- + dAtA[i] = 0x12 + } + if m.BtcSigType != 0 { + i = encodeVarintPop(dAtA, i, uint64(m.BtcSigType)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *BIP322Sig) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -319,6 +414,22 @@ func (m *ProofOfPossession) Size() (n int) { return n } +func (m *ProofOfPossessionBTC) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BtcSigType != 0 { + n += 1 + sovPop(uint64(m.BtcSigType)) + } + l = len(m.BtcSig) + if l > 0 { + n += 1 + l + sovPop(uint64(l)) + } + return n +} + func (m *BIP322Sig) Size() (n int) { if m == nil { return 0 @@ -479,6 +590,109 @@ func (m *ProofOfPossession) Unmarshal(dAtA []byte) error { } return nil } +func (m *ProofOfPossessionBTC) 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 ErrIntOverflowPop + } + 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: ProofOfPossessionBTC: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ProofOfPossessionBTC: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcSigType", wireType) + } + m.BtcSigType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPop + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BtcSigType |= BTCSigType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BtcSig", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPop + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPop + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPop + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BtcSig = append(m.BtcSig[:0], dAtA[iNdEx:postIndex]...) + if m.BtcSig == nil { + m.BtcSig = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPop(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPop + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *BIP322Sig) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/btcstaking/types/pop_test.go b/x/btcstaking/types/pop_test.go index 34fa89d6f..c4f0e7f5e 100644 --- a/x/btcstaking/types/pop_test.go +++ b/x/btcstaking/types/pop_test.go @@ -1,18 +1,23 @@ package types_test import ( + "fmt" "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/stretchr/testify/require" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg" + "github.com/cometbft/cometbft/crypto/tmhash" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/btcstaking/types" ) var ( @@ -183,3 +188,196 @@ func FuzzPop_ValidBip322SigNotMatchingBip340PubKey(f *testing.F) { require.Error(t, err) }) } + +func TestPoPBTCValidateBasic(t *testing.T) { + r := rand.New(rand.NewSource(10)) + + btcSK, _, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + addrToSign := sdk.MustAccAddressFromBech32(datagen.GenRandomAccount().Address) + + popBip340, err := types.NewPoPBTC(addrToSign, btcSK) + require.NoError(t, err) + + popBip322, err := types.NewPoPBTCWithBIP322P2WPKHSig(addrToSign, btcSK, &chaincfg.MainNetParams) + require.NoError(t, err) + + popECDSA, err := types.NewPoPBTCWithECDSABTCSig(addrToSign, btcSK) + require.NoError(t, err) + + tcs := []struct { + title string + pop *types.ProofOfPossessionBTC + expErr error + }{ + { + "valid: BIP 340", + popBip340, + nil, + }, + { + "valid: BIP 322", + popBip322, + nil, + }, + { + "valid: ECDSA", + popECDSA, + nil, + }, + { + "invalid: nil sig", + &types.ProofOfPossessionBTC{}, + fmt.Errorf("empty BTC signature"), + }, + { + "invalid: BIP 340 - bad sig", + &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType_BIP340, + BtcSig: popBip322.BtcSig, + }, + fmt.Errorf("invalid BTC BIP340 signature: bytes cannot be converted to a *schnorr.Signature object"), + }, + { + "invalid: BIP 322 - bad sig", + &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType_BIP322, + BtcSig: []byte("ss"), + }, + fmt.Errorf("invalid BTC BIP322 signature: unexpected EOF"), + }, + { + "invalid: ECDSA - bad sig", + &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType_ECDSA, + BtcSig: popBip340.BtcSig, + }, + fmt.Errorf("invalid BTC ECDSA signature size"), + }, + } + + for _, tc := range tcs { + tc := tc + t.Run(tc.title, func(t *testing.T) { + actErr := tc.pop.ValidateBasic() + if tc.expErr != nil { + require.EqualError(t, actErr, tc.expErr.Error()) + return + } + require.NoError(t, actErr) + }) + } +} + +func TestPoPBTCVerify(t *testing.T) { + r := rand.New(rand.NewSource(10)) + + addrToSign := sdk.MustAccAddressFromBech32(datagen.GenRandomAccount().Address) + randomAddr := sdk.MustAccAddressFromBech32(datagen.GenRandomAccount().Address) + + // generate BTC key pair + btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + + netParams := &chaincfg.MainNetParams + + popBip340, err := types.NewPoPBTC(addrToSign, btcSK) + require.NoError(t, err) + + popBip322, err := types.NewPoPBTCWithBIP322P2WPKHSig(addrToSign, btcSK, netParams) + require.NoError(t, err) + + popECDSA, err := types.NewPoPBTCWithECDSABTCSig(addrToSign, btcSK) + require.NoError(t, err) + + tcs := []struct { + title string + staker sdk.AccAddress + btcPK *bbn.BIP340PubKey + pop *types.ProofOfPossessionBTC + expErr error + }{ + { + "valid: BIP340", + addrToSign, + bip340PK, + popBip340, + nil, + }, + { + "valid: BIP322", + addrToSign, + bip340PK, + popBip322, + nil, + }, + { + "valid: ECDSA", + addrToSign, + bip340PK, + popECDSA, + nil, + }, + { + "invalid: BIP340 - bad addr", + randomAddr, + bip340PK, + popBip340, + fmt.Errorf("failed to verify pop.BtcSig"), + }, + { + "invalid: BIP322 - bad addr", + randomAddr, + bip340PK, + popBip322, + fmt.Errorf("failed to verify possession of babylon sig by the BTC key: signature not empty on failed checksig"), + }, + { + "invalid: ECDSA - bad addr", + randomAddr, + bip340PK, + popECDSA, + fmt.Errorf("failed to verify btcSigRaw"), + }, + { + "invalid: SigType", + nil, + nil, + &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType(123), + }, + fmt.Errorf("invalid BTC signature type"), + }, + { + "invalid: nil sig", + randomAddr, + bip340PK, + &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType_BIP322, + BtcSig: nil, + }, + fmt.Errorf("failed to verify possession of babylon sig by the BTC key: cannot verfiy bip322 signature. One of the required parameters is empty"), + }, + { + "invalid: nil signed msg", + nil, + bip340PK, + popBip340, + fmt.Errorf("failed to verify pop.BtcSig"), + }, + } + + for _, tc := range tcs { + tc := tc + t.Run(tc.title, func(t *testing.T) { + actErr := tc.pop.Verify(tc.staker, tc.btcPK, netParams) + if tc.expErr != nil { + require.EqualError(t, actErr, tc.expErr.Error()) + return + } + require.NoError(t, actErr) + }) + } +} diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 1907483ff..a84af7070 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -7,6 +7,7 @@ import ( // NewBTCDelegationResponse returns a new delegation response structure. func NewBTCDelegationResponse(btcDel *BTCDelegation, status BTCDelegationStatus) (resp *BTCDelegationResponse) { resp = &BTCDelegationResponse{ + StakerAddr: btcDel.StakerAddr, BtcPk: btcDel.BtcPk, FpBtcPkList: btcDel.FpBtcPkList, StartHeight: btcDel.StartHeight, diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index ee5452bbb..767f3dbbc 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1156,46 +1156,48 @@ func (m *QueryBTCDelegationResponse) GetBtcDelegation() *BTCDelegationResponse { // BTCDelegationResponse is the client needed information from a BTCDelegation with the current status based on parameters. type BTCDelegationResponse struct { + // staker_addr is the address to receive rewards from BTC delegation. + StakerAddr string `protobuf:"bytes,1,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` + FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock - StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + StartHeight uint64 `protobuf:"varint,4,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` // end_height is the end height of the BTC delegation // it is the end BTC height of the timelock - w - EndHeight uint64 `protobuf:"varint,4,opt,name=end_height,json=endHeight,proto3" json:"end_height,omitempty"` + EndHeight uint64 `protobuf:"varint,5,opt,name=end_height,json=endHeight,proto3" json:"end_height,omitempty"` // total_sat is the total amount of BTC stakes in this delegation // quantified in satoshi - TotalSat uint64 `protobuf:"varint,5,opt,name=total_sat,json=totalSat,proto3" json:"total_sat,omitempty"` + TotalSat uint64 `protobuf:"varint,6,opt,name=total_sat,json=totalSat,proto3" json:"total_sat,omitempty"` // staking_tx_hex is the hex string of staking tx - StakingTxHex string `protobuf:"bytes,6,opt,name=staking_tx_hex,json=stakingTxHex,proto3" json:"staking_tx_hex,omitempty"` + StakingTxHex string `protobuf:"bytes,7,opt,name=staking_tx_hex,json=stakingTxHex,proto3" json:"staking_tx_hex,omitempty"` // slashing_tx_hex is the hex string of slashing tx - SlashingTxHex string `protobuf:"bytes,7,opt,name=slashing_tx_hex,json=slashingTxHex,proto3" json:"slashing_tx_hex,omitempty"` + SlashingTxHex string `protobuf:"bytes,8,opt,name=slashing_tx_hex,json=slashingTxHex,proto3" json:"slashing_tx_hex,omitempty"` // delegator_slash_sig_hex is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk) as string hex. // It will be a part of the witness for the staking tx output. - DelegatorSlashSigHex string `protobuf:"bytes,8,opt,name=delegator_slash_sig_hex,json=delegatorSlashSigHex,proto3" json:"delegator_slash_sig_hex,omitempty"` + DelegatorSlashSigHex string `protobuf:"bytes,9,opt,name=delegator_slash_sig_hex,json=delegatorSlashSigHex,proto3" json:"delegator_slash_sig_hex,omitempty"` // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. - CovenantSigs []*CovenantAdaptorSignatures `protobuf:"bytes,9,rep,name=covenant_sigs,json=covenantSigs,proto3" json:"covenant_sigs,omitempty"` + CovenantSigs []*CovenantAdaptorSignatures `protobuf:"bytes,10,rep,name=covenant_sigs,json=covenantSigs,proto3" json:"covenant_sigs,omitempty"` // staking_output_idx is the index of the staking output in the staking tx - StakingOutputIdx uint32 `protobuf:"varint,10,opt,name=staking_output_idx,json=stakingOutputIdx,proto3" json:"staking_output_idx,omitempty"` + StakingOutputIdx uint32 `protobuf:"varint,11,opt,name=staking_output_idx,json=stakingOutputIdx,proto3" json:"staking_output_idx,omitempty"` // whether this delegation is active - Active bool `protobuf:"varint,11,opt,name=active,proto3" json:"active,omitempty"` + Active bool `protobuf:"varint,12,opt,name=active,proto3" json:"active,omitempty"` // descriptive status of current delegation. - StatusDesc string `protobuf:"bytes,12,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` + StatusDesc string `protobuf:"bytes,13,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` // unbonding_time used in unbonding output timelock path and in slashing transactions // change outputs - UnbondingTime uint32 `protobuf:"varint,13,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` + UnbondingTime uint32 `protobuf:"varint,14,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` // undelegation_response is the undelegation info of this delegation. - UndelegationResponse *BTCUndelegationResponse `protobuf:"bytes,14,opt,name=undelegation_response,json=undelegationResponse,proto3" json:"undelegation_response,omitempty"` + UndelegationResponse *BTCUndelegationResponse `protobuf:"bytes,15,opt,name=undelegation_response,json=undelegationResponse,proto3" json:"undelegation_response,omitempty"` // params version used to validate delegation - ParamsVersion uint32 `protobuf:"varint,15,opt,name=params_version,json=paramsVersion,proto3" json:"params_version,omitempty"` + ParamsVersion uint32 `protobuf:"varint,16,opt,name=params_version,json=paramsVersion,proto3" json:"params_version,omitempty"` } func (m *BTCDelegationResponse) Reset() { *m = BTCDelegationResponse{} } @@ -1231,6 +1233,13 @@ func (m *BTCDelegationResponse) XXX_DiscardUnknown() { var xxx_messageInfo_BTCDelegationResponse proto.InternalMessageInfo +func (m *BTCDelegationResponse) GetStakerAddr() string { + if m != nil { + return m.StakerAddr + } + return "" +} + func (m *BTCDelegationResponse) GetStartHeight() uint64 { if m != nil { return m.StartHeight @@ -1611,124 +1620,127 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1869 bytes of a gzipped FileDescriptorProto + // 1906 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, - 0x19, 0x67, 0x92, 0x60, 0xc8, 0x97, 0x3f, 0x84, 0xb7, 0x01, 0x8c, 0x43, 0x62, 0x98, 0xb2, 0x10, - 0x58, 0x98, 0x21, 0x26, 0x50, 0x69, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, - 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x8a, 0x3d, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, - 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa1, 0xaa, 0xd4, 0x73, 0x2b, 0xf5, 0xd8, 0x3d, 0x55, - 0xea, 0x7d, 0x7b, 0x5b, 0x6d, 0x0f, 0xad, 0x38, 0xa0, 0x0a, 0xaa, 0x56, 0xaa, 0xd4, 0x6b, 0xcf, - 0xd5, 0xbc, 0xf7, 0xc6, 0x33, 0xb6, 0x67, 0x1c, 0x3b, 0xc9, 0xde, 0xe2, 0x79, 0xdf, 0xff, 0xef, - 0xf7, 0x7e, 0xef, 0xbd, 0x2f, 0x70, 0xa9, 0x62, 0x56, 0x3a, 0x0d, 0xe2, 0xea, 0x15, 0x66, 0x51, - 0x66, 0xee, 0x38, 0xae, 0xad, 0xef, 0xae, 0xe9, 0x2f, 0x5b, 0xd8, 0xef, 0x68, 0x9e, 0x4f, 0x18, - 0x41, 0x67, 0xa4, 0x88, 0x16, 0x89, 0x68, 0xbb, 0x6b, 0xb9, 0x45, 0x9b, 0xd8, 0x84, 0x4b, 0xe8, - 0xc1, 0x5f, 0x42, 0x38, 0x77, 0xc1, 0x26, 0xc4, 0x6e, 0x60, 0xdd, 0xf4, 0x1c, 0xdd, 0x74, 0x5d, - 0xc2, 0x4c, 0xe6, 0x10, 0x97, 0xca, 0xd5, 0xf3, 0x16, 0xa1, 0x4d, 0x42, 0xcb, 0x42, 0x4d, 0xfc, - 0x90, 0x4b, 0xaa, 0xf8, 0xa5, 0x5b, 0x7e, 0xc7, 0x63, 0x44, 0xa7, 0xd8, 0xf2, 0x0a, 0x77, 0xee, - 0xee, 0xac, 0xe9, 0x3b, 0xb8, 0x13, 0xca, 0x5c, 0x96, 0x32, 0x51, 0xa0, 0x15, 0xcc, 0xcc, 0xb5, - 0xf0, 0xb7, 0x94, 0xba, 0x2e, 0xa5, 0x2a, 0x26, 0xc5, 0x22, 0x91, 0xae, 0xa0, 0x67, 0xda, 0x8e, - 0xcb, 0x23, 0x0a, 0xbd, 0x26, 0xa7, 0xef, 0x99, 0xbe, 0xd9, 0x0c, 0xbd, 0x5e, 0x49, 0x96, 0x89, - 0x55, 0x43, 0xc8, 0xe5, 0x53, 0x6c, 0x11, 0x4f, 0x08, 0xa8, 0x8b, 0x80, 0xbe, 0x17, 0x84, 0x53, - 0xe2, 0xd6, 0x0d, 0xfc, 0xb2, 0x85, 0x29, 0x53, 0x0d, 0x78, 0xaf, 0xe7, 0x2b, 0xf5, 0x88, 0x4b, - 0x31, 0xfa, 0x08, 0x32, 0x22, 0x8a, 0xac, 0x72, 0x51, 0x59, 0x9d, 0x29, 0x2c, 0x6b, 0x89, 0x6d, - 0xd0, 0x84, 0x5a, 0x71, 0xea, 0xcb, 0x37, 0xf9, 0x63, 0x86, 0x54, 0x51, 0xbf, 0x0d, 0x4b, 0x31, - 0x9b, 0xc5, 0xce, 0xf7, 0xb1, 0x4f, 0x1d, 0xe2, 0x4a, 0x97, 0x28, 0x0b, 0x27, 0x76, 0xc5, 0x17, - 0x6e, 0x7c, 0xce, 0x08, 0x7f, 0xaa, 0x9f, 0xc3, 0x85, 0x64, 0xc5, 0xa3, 0x88, 0xca, 0x86, 0x65, - 0x6e, 0xfc, 0x13, 0xc7, 0x35, 0x1b, 0x0e, 0xeb, 0x94, 0x7c, 0xb2, 0xeb, 0x54, 0xb1, 0x1f, 0x96, - 0x02, 0x7d, 0x02, 0x10, 0x75, 0x48, 0x7a, 0xb8, 0xa2, 0x49, 0x98, 0x04, 0xed, 0xd4, 0x04, 0x2e, - 0x65, 0x3b, 0xb5, 0x92, 0x69, 0x63, 0xa9, 0x6b, 0xc4, 0x34, 0xd5, 0xbf, 0x28, 0xb0, 0x92, 0xe6, - 0x49, 0x26, 0xf2, 0x63, 0x40, 0x35, 0xb9, 0x18, 0xa0, 0x51, 0xac, 0x66, 0x95, 0x8b, 0x93, 0xab, - 0x33, 0x05, 0x3d, 0x25, 0xa9, 0x7e, 0x6b, 0xa1, 0x31, 0xe3, 0x74, 0xad, 0xdf, 0x0f, 0x7a, 0xd4, - 0x93, 0xca, 0x04, 0x4f, 0xe5, 0xea, 0xbe, 0xa9, 0x48, 0x7b, 0xf1, 0x5c, 0x36, 0x64, 0x47, 0x06, - 0x9d, 0x8b, 0x9a, 0x5d, 0x82, 0xb9, 0x9a, 0x57, 0xae, 0x30, 0xab, 0xec, 0xed, 0x94, 0xeb, 0xb8, - 0xcd, 0xcb, 0x36, 0x6d, 0x40, 0xcd, 0x2b, 0x32, 0xab, 0xb4, 0xf3, 0x18, 0xb7, 0xd5, 0xbd, 0x94, - 0xba, 0x77, 0x8b, 0xf1, 0x23, 0x38, 0x3d, 0x50, 0x0c, 0x59, 0xfe, 0xb1, 0x6b, 0xb1, 0xd0, 0x5f, - 0x0b, 0xf5, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xe2, 0xf3, 0x87, 0x9b, 0xb8, 0x81, 0x6d, 0x41, 0x09, - 0x61, 0x02, 0x45, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x80, 0xd4, 0x7c, 0xe1, 0x7a, 0x8a, 0xc7, 0x1e, - 0xed, 0x6d, 0xae, 0x61, 0x48, 0xcd, 0x3e, 0xe0, 0x4c, 0x1c, 0x18, 0x38, 0x7f, 0x56, 0xe4, 0xc6, - 0xe9, 0x0f, 0x55, 0x16, 0xea, 0x05, 0x9c, 0x0a, 0x2a, 0x5d, 0x8d, 0x96, 0x24, 0x64, 0x6e, 0x8c, - 0x12, 0x74, 0xb7, 0x46, 0xf3, 0x15, 0x66, 0xc5, 0xcc, 0x1f, 0x1d, 0x58, 0x6a, 0x70, 0x2d, 0xb1, - 0xd3, 0x25, 0xf2, 0x13, 0xec, 0x6f, 0xb0, 0xc7, 0xd8, 0xb1, 0xeb, 0x6c, 0x74, 0xe4, 0xa0, 0xb3, - 0x90, 0xa9, 0x73, 0x1d, 0x1e, 0xd4, 0x94, 0x21, 0x7f, 0xa9, 0xcf, 0xe0, 0xfa, 0x28, 0x7e, 0x64, - 0xd5, 0x2e, 0xc1, 0xec, 0x2e, 0x61, 0x8e, 0x6b, 0x97, 0xbd, 0x60, 0x9d, 0xfb, 0x99, 0x32, 0x66, - 0xc4, 0x37, 0xae, 0xa2, 0x6e, 0xc1, 0x6a, 0xa2, 0xc1, 0x87, 0x2d, 0xdf, 0xc7, 0x2e, 0xe3, 0x42, - 0x63, 0x20, 0x3e, 0xad, 0x0e, 0xbd, 0xe6, 0x64, 0x78, 0x51, 0x92, 0x4a, 0x3c, 0xc9, 0x81, 0xb0, - 0x27, 0x06, 0xc3, 0xfe, 0xb9, 0x02, 0x1f, 0x70, 0x47, 0x1b, 0x16, 0x73, 0x76, 0xf1, 0x00, 0xdd, - 0xf4, 0x97, 0x3c, 0xcd, 0xd5, 0x51, 0xe1, 0xf7, 0x6f, 0x0a, 0xdc, 0x18, 0x2d, 0x9e, 0x23, 0xa4, - 0xc1, 0x1f, 0x38, 0xac, 0xbe, 0x85, 0x99, 0xf9, 0x8d, 0xd2, 0xe0, 0xb2, 0xdc, 0x98, 0x3c, 0x31, - 0x93, 0xe1, 0x6a, 0x4f, 0x61, 0xd5, 0xbb, 0x92, 0x25, 0x07, 0x96, 0x87, 0xf7, 0x58, 0xfd, 0x95, - 0x02, 0x57, 0x13, 0x91, 0x92, 0x40, 0x54, 0x23, 0xec, 0x97, 0xa3, 0xea, 0xe3, 0xbf, 0x95, 0x94, - 0xfd, 0x90, 0x44, 0x4a, 0x3e, 0x9c, 0x8f, 0x91, 0x12, 0xf1, 0x13, 0xe8, 0xe9, 0xee, 0xbe, 0xf4, - 0x44, 0x92, 0x4c, 0x1b, 0xe7, 0x22, 0xa2, 0xea, 0x11, 0x38, 0xba, 0xbe, 0x7e, 0x0a, 0xe7, 0x07, - 0x09, 0x37, 0xac, 0xf8, 0x4d, 0x78, 0x4f, 0x06, 0x5b, 0x66, 0xed, 0x72, 0xdd, 0xa4, 0xf5, 0x58, - 0xdd, 0x17, 0xe4, 0xd2, 0xf3, 0xf6, 0x63, 0x93, 0xd6, 0x83, 0x5d, 0xff, 0x32, 0xe9, 0x9c, 0xe9, - 0x96, 0x69, 0x1b, 0xe6, 0x7b, 0xb9, 0x5b, 0x9e, 0x70, 0xe3, 0x51, 0xf7, 0x5c, 0x0f, 0x75, 0xab, - 0xbf, 0xce, 0xc0, 0x99, 0x64, 0x77, 0x5b, 0x90, 0x11, 0x50, 0xe1, 0x6e, 0x66, 0x8b, 0x77, 0x5f, - 0xbf, 0xc9, 0x17, 0x6c, 0x87, 0xd5, 0x5b, 0x15, 0xcd, 0x22, 0x4d, 0x5d, 0x3a, 0xb5, 0xea, 0xa6, - 0xe3, 0x86, 0x3f, 0x74, 0xd6, 0xf1, 0x30, 0xd5, 0x8a, 0x4f, 0x4a, 0xb7, 0xd7, 0x6f, 0x95, 0x5a, - 0x95, 0xcf, 0x70, 0xc7, 0x38, 0x5e, 0x09, 0xc0, 0x85, 0x3e, 0x87, 0xf9, 0x08, 0x7c, 0x0d, 0x87, - 0x06, 0x8c, 0x3c, 0x79, 0x08, 0xb3, 0x33, 0x12, 0xb5, 0x4f, 0x1d, 0x8e, 0xec, 0x59, 0xca, 0x4c, - 0x9f, 0x95, 0xe5, 0x1e, 0x99, 0x14, 0x4c, 0xc7, 0xbf, 0x89, 0x8d, 0x84, 0x96, 0x01, 0xb0, 0x5b, - 0x0d, 0x05, 0xa6, 0xb8, 0xc0, 0x34, 0x76, 0xe5, 0x3e, 0x43, 0x4b, 0x30, 0xcd, 0x08, 0x33, 0x1b, - 0x65, 0x6a, 0xb2, 0xec, 0x71, 0xbe, 0x7a, 0x92, 0x7f, 0xd8, 0x36, 0x19, 0xba, 0x0c, 0xf3, 0xf1, - 0x36, 0xe2, 0x76, 0x36, 0xc3, 0x3b, 0x38, 0x1b, 0x75, 0x10, 0xb7, 0xd1, 0x15, 0x38, 0x45, 0x1b, - 0x26, 0xad, 0xc7, 0xc4, 0x4e, 0x70, 0xb1, 0xb9, 0xf0, 0xb3, 0x90, 0xbb, 0x03, 0xe7, 0x22, 0xa8, - 0xf3, 0xa5, 0x32, 0x75, 0x6c, 0x2e, 0x7f, 0x92, 0xcb, 0x2f, 0x76, 0x97, 0xb7, 0x83, 0xd5, 0x6d, - 0xc7, 0x0e, 0xd4, 0x5e, 0xc0, 0x9c, 0x45, 0x76, 0xb1, 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0xd9, 0x69, - 0xbe, 0x33, 0x6e, 0xa5, 0x74, 0xff, 0xa1, 0x94, 0xdd, 0xa8, 0x9a, 0x5e, 0x60, 0xc9, 0xb1, 0x5d, - 0x93, 0xb5, 0x7c, 0x4c, 0x8d, 0xd9, 0xd0, 0xcc, 0xb6, 0x63, 0x53, 0x74, 0x03, 0x50, 0x98, 0x1b, - 0x69, 0x31, 0xaf, 0xc5, 0xca, 0x4e, 0xb5, 0x9d, 0x05, 0x7e, 0xab, 0x0e, 0x11, 0xfa, 0x8c, 0x2f, - 0x3c, 0xa9, 0xf2, 0xf3, 0xd4, 0xe4, 0xcc, 0x9c, 0x9d, 0xb9, 0xa8, 0xac, 0x9e, 0x34, 0xe4, 0x2f, - 0x94, 0x87, 0x19, 0x71, 0x93, 0x29, 0x57, 0x31, 0xb5, 0xb2, 0xb3, 0x82, 0x58, 0xc4, 0xa7, 0x4d, - 0x4c, 0x2d, 0xf4, 0x3e, 0xcc, 0xb7, 0xdc, 0x0a, 0x71, 0xab, 0xbc, 0x3a, 0x4e, 0x13, 0x67, 0xe7, - 0xb8, 0x8b, 0xb9, 0xee, 0xd7, 0xe7, 0x4e, 0x13, 0x23, 0x0b, 0xce, 0xb4, 0xdc, 0x08, 0xe1, 0x65, - 0x5f, 0xa2, 0x31, 0x3b, 0xcf, 0xa1, 0xae, 0xa5, 0x43, 0xfd, 0x45, 0x4c, 0xad, 0x0b, 0xf6, 0xc5, - 0x56, 0xc2, 0xd7, 0x20, 0x16, 0x71, 0xa1, 0x2f, 0x87, 0x8f, 0x88, 0x53, 0x22, 0x16, 0xf1, 0x55, - 0x3e, 0x19, 0xd4, 0x2f, 0x26, 0xe1, 0x5c, 0x8a, 0x61, 0xb4, 0x0a, 0x0b, 0xb1, 0x74, 0xda, 0xb1, - 0x5d, 0x1d, 0xa5, 0x29, 0xba, 0xfd, 0x5d, 0x58, 0x8a, 0xba, 0x1d, 0xe9, 0x84, 0x1d, 0x9f, 0xe0, - 0x4a, 0xd9, 0xae, 0xc8, 0x8b, 0x50, 0x42, 0x76, 0xdd, 0x82, 0xa5, 0x6e, 0xd7, 0x7b, 0xb5, 0xf9, - 0x1e, 0x9a, 0xe4, 0x18, 0xb8, 0x9c, 0x52, 0x96, 0x6e, 0xd3, 0x9f, 0xb8, 0x35, 0x62, 0x64, 0x43, - 0x43, 0x71, 0x1f, 0x7c, 0xfb, 0x24, 0x20, 0x77, 0x2a, 0x09, 0xb9, 0x1f, 0x41, 0xae, 0x0f, 0xb9, - 0xf1, 0x54, 0x8e, 0x73, 0x95, 0x73, 0xbd, 0xe0, 0x8d, 0x32, 0xa9, 0xc1, 0xd9, 0x08, 0xbf, 0x31, - 0x5d, 0x9a, 0xcd, 0x1c, 0x10, 0xc8, 0x8b, 0x5d, 0x20, 0x47, 0x9e, 0xa8, 0x6a, 0x41, 0x7e, 0x9f, - 0x53, 0x01, 0x3d, 0x80, 0xa9, 0x2a, 0x6e, 0x1c, 0xec, 0xea, 0xcb, 0x35, 0xd5, 0xdf, 0x4c, 0x41, - 0x36, 0xf5, 0x35, 0xf2, 0x31, 0xcc, 0x04, 0xbb, 0xc0, 0x77, 0xbc, 0x18, 0x4b, 0x7f, 0x2b, 0x3c, - 0x5c, 0x22, 0x0f, 0xe2, 0x64, 0xd9, 0x8c, 0x44, 0x8d, 0xb8, 0x1e, 0xda, 0x02, 0xb0, 0x48, 0xb3, - 0xe9, 0x50, 0x1a, 0x1e, 0x51, 0xd3, 0xc5, 0x9b, 0xaf, 0xdf, 0xe4, 0x97, 0x84, 0x21, 0x5a, 0xdd, - 0xd1, 0x1c, 0xa2, 0x37, 0x4d, 0x56, 0xd7, 0x9e, 0x62, 0xdb, 0xb4, 0x3a, 0x9b, 0xd8, 0xfa, 0xfa, - 0x8b, 0x9b, 0x20, 0xfd, 0x6c, 0x62, 0xcb, 0x88, 0x19, 0x40, 0xf7, 0x00, 0x64, 0x9e, 0x01, 0xa7, - 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0x68, 0xa1, 0x75, 0x87, 0x16, 0x9a, 0x64, 0xd9, 0x69, - 0xa9, 0x52, 0xda, 0x89, 0x9d, 0x07, 0x53, 0x47, 0x71, 0x1e, 0x7c, 0x08, 0x93, 0x1e, 0xf1, 0x38, - 0x68, 0x66, 0x0a, 0xab, 0x69, 0xaf, 0x70, 0x9f, 0x90, 0xda, 0xb3, 0x5a, 0x89, 0x50, 0x8a, 0x79, - 0x16, 0x46, 0xa0, 0x84, 0xd6, 0xe1, 0x2c, 0x47, 0x10, 0xae, 0x96, 0xc3, 0x94, 0x24, 0xaf, 0x67, - 0x38, 0x73, 0x2f, 0xca, 0xd5, 0xa2, 0x58, 0x94, 0x14, 0x1f, 0x30, 0x5d, 0xa8, 0xc5, 0xac, 0x50, - 0xe3, 0x04, 0xd7, 0x58, 0x08, 0x35, 0x98, 0x25, 0xa5, 0xa3, 0x0b, 0xd7, 0xc9, 0xa1, 0x97, 0xea, - 0xe9, 0x81, 0x4b, 0x75, 0xe1, 0xb7, 0xa7, 0xe1, 0x38, 0x3f, 0xc7, 0xd1, 0xcf, 0x14, 0xc8, 0x88, - 0x49, 0x02, 0xba, 0x96, 0x92, 0xe2, 0xe0, 0x40, 0x25, 0x77, 0x7d, 0x14, 0x51, 0x81, 0x35, 0xf5, - 0xfd, 0x9f, 0xfe, 0xf5, 0x9f, 0xbf, 0x9c, 0xc8, 0xa3, 0x65, 0x7d, 0xd8, 0x20, 0x08, 0xfd, 0x41, - 0x81, 0x53, 0x7d, 0x23, 0x11, 0x54, 0xd8, 0xdf, 0x4d, 0xff, 0xe0, 0x25, 0x77, 0x7b, 0x2c, 0x1d, - 0x19, 0xa3, 0xce, 0x63, 0xbc, 0x86, 0xae, 0x0e, 0x8d, 0x51, 0x7f, 0x25, 0xd9, 0x78, 0x0f, 0xfd, - 0x51, 0x81, 0xd3, 0x03, 0x57, 0x7f, 0xb4, 0x3e, 0xcc, 0x77, 0xda, 0x48, 0x26, 0x77, 0x67, 0x4c, - 0x2d, 0x19, 0xf3, 0x1a, 0x8f, 0xf9, 0x03, 0x74, 0x2d, 0x25, 0xe6, 0xc1, 0x47, 0x07, 0xfa, 0x5a, - 0x81, 0x85, 0x7e, 0x83, 0xe8, 0xf6, 0x38, 0xee, 0xc3, 0x98, 0xd7, 0xc7, 0x53, 0x92, 0x21, 0x6f, - 0xf3, 0x90, 0xb7, 0xd0, 0x67, 0x23, 0x87, 0xac, 0xbf, 0xea, 0x79, 0x0f, 0xec, 0x0d, 0x8a, 0xa0, - 0xdf, 0x29, 0x30, 0xdf, 0x3b, 0x4b, 0x40, 0x6b, 0xc3, 0xa2, 0x4b, 0x1c, 0x91, 0xe4, 0x0a, 0xe3, - 0xa8, 0xc8, 0x74, 0x34, 0x9e, 0xce, 0x2a, 0xba, 0xa2, 0xa7, 0x8e, 0x2f, 0xe3, 0x0f, 0x05, 0xf4, - 0x2f, 0x05, 0xf2, 0xfb, 0xbc, 0x1a, 0x51, 0x71, 0x58, 0x1c, 0xa3, 0x3d, 0x81, 0x73, 0x0f, 0x0f, - 0x65, 0x43, 0x26, 0xf7, 0x21, 0x4f, 0x6e, 0x1d, 0x15, 0xc6, 0xe8, 0x95, 0x20, 0xa0, 0x3d, 0xf4, - 0x3f, 0x05, 0x96, 0x87, 0xce, 0x2d, 0xd0, 0x83, 0x71, 0xf0, 0x93, 0x34, 0x5a, 0xc9, 0x6d, 0x1c, - 0xc2, 0x82, 0x4c, 0xb1, 0xc4, 0x53, 0xfc, 0x14, 0x3d, 0x3e, 0x38, 0x1c, 0x39, 0xc3, 0x46, 0x89, - 0xff, 0x47, 0x81, 0x0b, 0xc3, 0x06, 0x22, 0xe8, 0xfe, 0x38, 0x51, 0x27, 0x4c, 0x66, 0x72, 0x0f, - 0x0e, 0x6e, 0x40, 0x66, 0xfd, 0x88, 0x67, 0xbd, 0x81, 0xee, 0x1f, 0x32, 0x6b, 0xce, 0xd8, 0x7d, - 0xc3, 0x80, 0xe1, 0x8c, 0x9d, 0x3c, 0x58, 0x18, 0xce, 0xd8, 0x29, 0xd3, 0x86, 0x7d, 0x19, 0xdb, - 0x0c, 0xf5, 0xe4, 0x29, 0x8a, 0xfe, 0xab, 0xc0, 0xd2, 0x90, 0xa7, 0x3e, 0xba, 0x37, 0x4e, 0x61, - 0x13, 0x08, 0xe4, 0xfe, 0x81, 0xf5, 0x65, 0x46, 0x5b, 0x3c, 0xa3, 0x47, 0xe8, 0xe3, 0x83, 0xf7, - 0x25, 0x4e, 0x36, 0x7f, 0x52, 0x60, 0xae, 0x87, 0xb7, 0xd0, 0xad, 0x91, 0x29, 0x2e, 0xcc, 0x69, - 0x6d, 0x0c, 0x0d, 0x99, 0xc5, 0x26, 0xcf, 0xe2, 0x1e, 0xfa, 0xce, 0x68, 0x9c, 0xa8, 0xbf, 0x4a, - 0x98, 0x3e, 0xec, 0x15, 0x9f, 0x7e, 0xf9, 0x76, 0x45, 0xf9, 0xea, 0xed, 0x8a, 0xf2, 0x8f, 0xb7, - 0x2b, 0xca, 0x2f, 0xde, 0xad, 0x1c, 0xfb, 0xea, 0xdd, 0xca, 0xb1, 0xbf, 0xbf, 0x5b, 0x39, 0xf6, - 0xc3, 0x7d, 0xef, 0x73, 0xed, 0xb8, 0x43, 0x7e, 0xb9, 0xab, 0x64, 0xf8, 0xff, 0x86, 0x6e, 0xff, - 0x3f, 0x00, 0x00, 0xff, 0xff, 0xa8, 0x9b, 0xda, 0xbf, 0x89, 0x1b, 0x00, 0x00, + 0x19, 0x67, 0x92, 0x60, 0xc8, 0xe7, 0x24, 0x84, 0xb7, 0x01, 0x06, 0x87, 0xc4, 0x30, 0x65, 0x21, + 0xb0, 0xe0, 0x21, 0x26, 0x50, 0x75, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, + 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x4a, 0x3c, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, + 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa9, 0x52, 0xcf, 0xad, 0xd4, 0x63, 0x39, 0x55, 0xea, + 0x7d, 0x7b, 0x5b, 0xb1, 0x87, 0x56, 0x1c, 0x50, 0x05, 0x55, 0x2b, 0x55, 0xea, 0xb5, 0xe7, 0x6a, + 0xde, 0x7b, 0xe3, 0x19, 0xdb, 0x33, 0x8e, 0x1d, 0xd2, 0x5b, 0xfc, 0xde, 0xf7, 0xef, 0xf7, 0x7d, + 0xdf, 0xfb, 0xbd, 0x79, 0x5f, 0xe0, 0x42, 0xd5, 0xac, 0x76, 0x76, 0x88, 0xab, 0x57, 0x99, 0x45, + 0x99, 0xb9, 0xed, 0xb8, 0xb6, 0xbe, 0xbb, 0xaa, 0x3f, 0x6f, 0x61, 0xbf, 0x53, 0xf0, 0x7c, 0xc2, + 0x08, 0x3a, 0x25, 0x45, 0x0a, 0x91, 0x48, 0x61, 0x77, 0x35, 0xb7, 0x60, 0x13, 0x9b, 0x70, 0x09, + 0x3d, 0xf8, 0x4b, 0x08, 0xe7, 0xce, 0xd9, 0x84, 0xd8, 0x3b, 0x58, 0x37, 0x3d, 0x47, 0x37, 0x5d, + 0x97, 0x30, 0x93, 0x39, 0xc4, 0xa5, 0x72, 0xf7, 0xac, 0x45, 0x68, 0x93, 0xd0, 0x8a, 0x50, 0x13, + 0x3f, 0xe4, 0x96, 0x26, 0x7e, 0xe9, 0x96, 0xdf, 0xf1, 0x18, 0xd1, 0x29, 0xb6, 0xbc, 0xe2, 0xad, + 0xdb, 0xdb, 0xab, 0xfa, 0x36, 0xee, 0x84, 0x32, 0x17, 0xa5, 0x4c, 0x14, 0x68, 0x15, 0x33, 0x73, + 0x35, 0xfc, 0x2d, 0xa5, 0xae, 0x4a, 0xa9, 0xaa, 0x49, 0xb1, 0x00, 0xd2, 0x15, 0xf4, 0x4c, 0xdb, + 0x71, 0x79, 0x44, 0xa1, 0xd7, 0x64, 0xf8, 0x9e, 0xe9, 0x9b, 0xcd, 0xd0, 0xeb, 0xa5, 0x64, 0x99, + 0x58, 0x36, 0x84, 0x5c, 0x3e, 0xc5, 0x16, 0xf1, 0x84, 0x80, 0xb6, 0x00, 0xe8, 0xfb, 0x41, 0x38, + 0x65, 0x6e, 0xdd, 0xc0, 0xcf, 0x5b, 0x98, 0x32, 0xcd, 0x80, 0x0f, 0x7a, 0x56, 0xa9, 0x47, 0x5c, + 0x8a, 0xd1, 0x27, 0x90, 0x11, 0x51, 0xa8, 0xca, 0x79, 0x65, 0x25, 0x5b, 0x5c, 0x2a, 0x24, 0x96, + 0xa1, 0x20, 0xd4, 0x4a, 0x53, 0x5f, 0xbd, 0xc9, 0x1f, 0x31, 0xa4, 0x8a, 0xf6, 0x6d, 0x58, 0x8c, + 0xd9, 0x2c, 0x75, 0x7e, 0x80, 0x7d, 0xea, 0x10, 0x57, 0xba, 0x44, 0x2a, 0x1c, 0xdb, 0x15, 0x2b, + 0xdc, 0xf8, 0xac, 0x11, 0xfe, 0xd4, 0xbe, 0x84, 0x73, 0xc9, 0x8a, 0x87, 0x11, 0x95, 0x0d, 0x4b, + 0xdc, 0xf8, 0x67, 0x8e, 0x6b, 0xee, 0x38, 0xac, 0x53, 0xf6, 0xc9, 0xae, 0x53, 0xc3, 0x7e, 0x98, + 0x0a, 0xf4, 0x19, 0x40, 0x54, 0x21, 0xe9, 0xe1, 0x52, 0x41, 0xb6, 0x49, 0x50, 0xce, 0x82, 0xe8, + 0x4b, 0x59, 0xce, 0x42, 0xd9, 0xb4, 0xb1, 0xd4, 0x35, 0x62, 0x9a, 0xda, 0x5f, 0x14, 0x58, 0x4e, + 0xf3, 0x24, 0x81, 0xfc, 0x04, 0x50, 0x5d, 0x6e, 0x06, 0xdd, 0x28, 0x76, 0x55, 0xe5, 0xfc, 0xe4, + 0x4a, 0xb6, 0xa8, 0xa7, 0x80, 0xea, 0xb7, 0x16, 0x1a, 0x33, 0x4e, 0xd6, 0xfb, 0xfd, 0xa0, 0x07, + 0x3d, 0x50, 0x26, 0x38, 0x94, 0xcb, 0xfb, 0x42, 0x91, 0xf6, 0xe2, 0x58, 0xd6, 0x65, 0x45, 0x06, + 0x9d, 0x8b, 0x9c, 0x5d, 0x80, 0xd9, 0xba, 0x57, 0xa9, 0x32, 0xab, 0xe2, 0x6d, 0x57, 0x1a, 0xb8, + 0xcd, 0xd3, 0x36, 0x6d, 0x40, 0xdd, 0x2b, 0x31, 0xab, 0xbc, 0xfd, 0x10, 0xb7, 0xb5, 0xbd, 0x94, + 0xbc, 0x77, 0x93, 0xf1, 0x63, 0x38, 0x39, 0x90, 0x0c, 0x99, 0xfe, 0xb1, 0x73, 0x31, 0xdf, 0x9f, + 0x0b, 0xed, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xd2, 0xd3, 0xfb, 0x1b, 0x78, 0x07, 0xdb, 0x82, 0x12, + 0x42, 0x00, 0x25, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x68, 0xa9, 0xb9, 0xe2, 0xd5, 0x14, 0x8f, 0x3d, + 0xda, 0x5b, 0x5c, 0xc3, 0x90, 0x9a, 0x7d, 0x8d, 0x33, 0x71, 0xe0, 0xc6, 0xf9, 0xb3, 0x22, 0x0f, + 0x4e, 0x7f, 0xa8, 0x32, 0x51, 0xcf, 0xe0, 0x44, 0x90, 0xe9, 0x5a, 0xb4, 0x25, 0x5b, 0xe6, 0xda, + 0x28, 0x41, 0x77, 0x73, 0x34, 0x57, 0x65, 0x56, 0xcc, 0xfc, 0xe1, 0x35, 0x4b, 0x1d, 0xae, 0x24, + 0x56, 0xba, 0x4c, 0x7e, 0x8a, 0xfd, 0x75, 0xf6, 0x10, 0x3b, 0x76, 0x83, 0x8d, 0xde, 0x39, 0xe8, + 0x34, 0x64, 0x1a, 0x5c, 0x87, 0x07, 0x35, 0x65, 0xc8, 0x5f, 0xda, 0x13, 0xb8, 0x3a, 0x8a, 0x1f, + 0x99, 0xb5, 0x0b, 0x30, 0xb3, 0x4b, 0x98, 0xe3, 0xda, 0x15, 0x2f, 0xd8, 0xe7, 0x7e, 0xa6, 0x8c, + 0xac, 0x58, 0xe3, 0x2a, 0xda, 0x26, 0xac, 0x24, 0x1a, 0xbc, 0xdf, 0xf2, 0x7d, 0xec, 0x32, 0x2e, + 0x34, 0x46, 0xc7, 0xa7, 0xe5, 0xa1, 0xd7, 0x9c, 0x0c, 0x2f, 0x02, 0xa9, 0xc4, 0x41, 0x0e, 0x84, + 0x3d, 0x31, 0x18, 0xf6, 0x2f, 0x14, 0xf8, 0x88, 0x3b, 0x5a, 0xb7, 0x98, 0xb3, 0x8b, 0x07, 0xe8, + 0xa6, 0x3f, 0xe5, 0x69, 0xae, 0x0e, 0xab, 0x7f, 0xff, 0xaa, 0xc0, 0xb5, 0xd1, 0xe2, 0x39, 0x44, + 0x1a, 0xfc, 0xa1, 0xc3, 0x1a, 0x9b, 0x98, 0x99, 0xff, 0x57, 0x1a, 0x5c, 0x92, 0x07, 0x93, 0x03, + 0x33, 0x19, 0xae, 0xf5, 0x24, 0x56, 0xbb, 0x2d, 0x59, 0x72, 0x60, 0x7b, 0x78, 0x8d, 0xb5, 0x5f, + 0x2b, 0x70, 0x39, 0xb1, 0x53, 0x12, 0x88, 0x6a, 0x84, 0xf3, 0x72, 0x58, 0x75, 0xfc, 0x97, 0x92, + 0x72, 0x1e, 0x92, 0x48, 0xc9, 0x87, 0xb3, 0x31, 0x52, 0x22, 0x7e, 0x02, 0x3d, 0xdd, 0xde, 0x97, + 0x9e, 0x48, 0x92, 0x69, 0xe3, 0x4c, 0x44, 0x54, 0x3d, 0x02, 0x87, 0x57, 0xd7, 0xcf, 0xe1, 0xec, + 0x20, 0xe1, 0x86, 0x19, 0xbf, 0x0e, 0x1f, 0xc8, 0x60, 0x2b, 0xac, 0x5d, 0x69, 0x98, 0xb4, 0x11, + 0xcb, 0xfb, 0xbc, 0xdc, 0x7a, 0xda, 0x7e, 0x68, 0xd2, 0x46, 0x70, 0xea, 0x9f, 0x27, 0xdd, 0x33, + 0xdd, 0x34, 0x6d, 0xc1, 0x5c, 0x2f, 0x77, 0xcb, 0x1b, 0x6e, 0x3c, 0xea, 0x9e, 0xed, 0xa1, 0x6e, + 0xed, 0x9b, 0x0c, 0x9c, 0x4a, 0x76, 0xf7, 0x1d, 0xc8, 0x06, 0xc6, 0xb0, 0x5f, 0x31, 0x6b, 0x35, + 0xc1, 0x79, 0xd3, 0x25, 0xf5, 0xd5, 0xcb, 0xeb, 0x0b, 0x32, 0x4b, 0xeb, 0xb5, 0x9a, 0x8f, 0x29, + 0xdd, 0x62, 0xbe, 0xe3, 0xda, 0x06, 0x08, 0xe1, 0x60, 0x11, 0x6d, 0x42, 0x46, 0x74, 0x19, 0x4f, + 0xec, 0x4c, 0xe9, 0xf6, 0xeb, 0x37, 0xf9, 0xa2, 0xed, 0xb0, 0x46, 0xab, 0x5a, 0xb0, 0x48, 0x53, + 0x97, 0xf1, 0x5a, 0x0d, 0xd3, 0x71, 0xc3, 0x1f, 0x3a, 0xeb, 0x78, 0x98, 0x16, 0x4a, 0x8f, 0xca, + 0x37, 0xd7, 0x6e, 0x94, 0x5b, 0xd5, 0x2f, 0x70, 0xc7, 0x38, 0x5a, 0x0d, 0xfa, 0x12, 0x7d, 0x09, + 0x73, 0x51, 0xdf, 0xee, 0x38, 0x94, 0xa9, 0x93, 0xe7, 0x27, 0xdf, 0xc3, 0x6c, 0x56, 0x36, 0xfc, + 0x63, 0x87, 0x1f, 0x8a, 0x19, 0xca, 0x4c, 0x9f, 0x55, 0xe4, 0xf1, 0x9a, 0x12, 0x24, 0xc9, 0xd7, + 0xc4, 0x19, 0x44, 0x4b, 0x00, 0xd8, 0xad, 0x85, 0x02, 0x47, 0xb9, 0xc0, 0x34, 0x76, 0xe5, 0x11, + 0x45, 0x8b, 0x30, 0xcd, 0x08, 0x33, 0x77, 0x2a, 0xd4, 0x64, 0x6a, 0x86, 0xef, 0x1e, 0xe7, 0x0b, + 0x5b, 0x26, 0x43, 0x17, 0x61, 0x2e, 0xde, 0x01, 0xb8, 0xad, 0x1e, 0xe3, 0xc5, 0x9f, 0x89, 0x8a, + 0x8f, 0xdb, 0xe8, 0x12, 0x9c, 0xa0, 0x3b, 0x26, 0x6d, 0xc4, 0xc4, 0x8e, 0x73, 0xb1, 0xd9, 0x70, + 0x59, 0xc8, 0xdd, 0x82, 0x33, 0xd1, 0x29, 0xe1, 0x5b, 0x15, 0xea, 0xd8, 0x5c, 0x7e, 0x9a, 0xcb, + 0x2f, 0x74, 0xb7, 0xb7, 0x82, 0xdd, 0x2d, 0xc7, 0x0e, 0xd4, 0x9e, 0xc1, 0xac, 0x45, 0x76, 0xb1, + 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0x2a, 0xf0, 0x43, 0x75, 0x23, 0xa5, 0x71, 0xee, 0x4b, 0xd9, 0xf5, + 0x9a, 0xe9, 0x05, 0x96, 0x1c, 0xdb, 0x35, 0x59, 0xcb, 0xc7, 0xd4, 0x98, 0x09, 0xcd, 0x6c, 0x39, + 0x36, 0x45, 0xd7, 0x00, 0x85, 0xd8, 0x48, 0x8b, 0x79, 0x2d, 0x56, 0x71, 0x6a, 0x6d, 0x35, 0xcb, + 0x3f, 0xc8, 0xc3, 0xe6, 0x7e, 0xc2, 0x37, 0x1e, 0xd5, 0xf8, 0x55, 0x6c, 0x72, 0x52, 0x57, 0x67, + 0xce, 0x2b, 0x2b, 0xc7, 0x0d, 0xf9, 0x0b, 0xe5, 0x79, 0x9f, 0xb1, 0x16, 0xad, 0xd4, 0x30, 0xb5, + 0xd4, 0x59, 0xc1, 0x49, 0x62, 0x69, 0x03, 0x53, 0x0b, 0x7d, 0x08, 0x73, 0x2d, 0xb7, 0x4a, 0xdc, + 0x1a, 0xcf, 0x8e, 0xd3, 0xc4, 0xea, 0x1c, 0x77, 0x31, 0xdb, 0x5d, 0x7d, 0xea, 0x34, 0x31, 0xb2, + 0xe0, 0x54, 0xcb, 0x8d, 0x0e, 0x47, 0xc5, 0x97, 0x8d, 0xac, 0x9e, 0xe0, 0xa7, 0xa4, 0x90, 0x7e, + 0x4a, 0x9e, 0xc5, 0xd4, 0xba, 0xe7, 0x64, 0xa1, 0x95, 0xb0, 0x1a, 0xc4, 0x22, 0xde, 0x02, 0x95, + 0xf0, 0xfd, 0x31, 0x2f, 0x62, 0x11, 0xab, 0xf2, 0xb5, 0xa1, 0xbd, 0x9c, 0x84, 0x33, 0x29, 0x86, + 0xd1, 0x0a, 0xcc, 0xc7, 0xe0, 0xb4, 0x63, 0x84, 0x10, 0xc1, 0x14, 0xd5, 0xfe, 0x1e, 0x2c, 0x46, + 0xd5, 0x8e, 0x74, 0xc2, 0x8a, 0x4f, 0x70, 0x25, 0xb5, 0x2b, 0xf2, 0x2c, 0x94, 0x90, 0x55, 0xb7, + 0x60, 0xb1, 0x5b, 0xf5, 0x5e, 0xed, 0xee, 0x19, 0xca, 0x16, 0x2f, 0xa6, 0xa4, 0xa5, 0x5b, 0xf4, + 0x47, 0x6e, 0x9d, 0x18, 0x6a, 0x68, 0x28, 0xee, 0x83, 0x1f, 0x9f, 0x84, 0xce, 0x9d, 0x4a, 0xea, + 0xdc, 0x4f, 0x20, 0xd7, 0xd7, 0xb9, 0x71, 0x28, 0x47, 0xb9, 0xca, 0x99, 0xde, 0xe6, 0x8d, 0x90, + 0xd4, 0xe1, 0x74, 0xd4, 0xbf, 0x31, 0x5d, 0xaa, 0x66, 0x0e, 0xd8, 0xc8, 0x0b, 0xdd, 0x46, 0x8e, + 0x3c, 0x51, 0xcd, 0x82, 0xfc, 0x3e, 0x17, 0x0a, 0xba, 0x07, 0x53, 0x35, 0xbc, 0x73, 0xb0, 0xaf, + 0x66, 0xae, 0xa9, 0xfd, 0x66, 0x0a, 0xd4, 0xd4, 0x87, 0xcc, 0xa7, 0x90, 0x0d, 0x4e, 0x81, 0xef, + 0x78, 0x31, 0x82, 0xff, 0x56, 0x78, 0x2f, 0x45, 0x1e, 0xc4, 0xa5, 0xb4, 0x11, 0x89, 0x1a, 0x71, + 0x3d, 0xb4, 0x09, 0x60, 0x91, 0x66, 0xd3, 0xa1, 0x34, 0xbc, 0xdd, 0xa6, 0x4b, 0xd7, 0x5f, 0xbf, + 0xc9, 0x2f, 0x0a, 0x43, 0xb4, 0xb6, 0x5d, 0x70, 0x88, 0xde, 0x34, 0x59, 0xa3, 0xf0, 0x18, 0xdb, + 0xa6, 0xd5, 0xd9, 0xc0, 0xd6, 0xab, 0x97, 0xd7, 0x41, 0xfa, 0xd9, 0xc0, 0x96, 0x11, 0x33, 0x80, + 0xee, 0x00, 0x48, 0x9c, 0x01, 0xa7, 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0xde, 0x51, 0xe8, + 0xce, 0x3b, 0x0a, 0x92, 0x65, 0xa7, 0xa5, 0x4a, 0x79, 0x3b, 0x76, 0x1f, 0x4c, 0x1d, 0xc6, 0x7d, + 0xf0, 0x31, 0x4c, 0x7a, 0xc4, 0xe3, 0x4d, 0x93, 0x2d, 0xae, 0xa4, 0x3d, 0xe0, 0x7d, 0x42, 0xea, + 0x4f, 0xea, 0x65, 0x42, 0x29, 0xe6, 0x28, 0x8c, 0x40, 0x09, 0xad, 0xc1, 0x69, 0xde, 0x41, 0xb8, + 0x56, 0x09, 0x21, 0x49, 0x5e, 0x17, 0xcc, 0xbd, 0x20, 0x77, 0x4b, 0x62, 0x53, 0x52, 0x7c, 0xc0, + 0x74, 0xa1, 0x16, 0xb3, 0x42, 0x8d, 0x63, 0x5c, 0x63, 0x3e, 0xd4, 0x60, 0x96, 0x94, 0x8e, 0xbe, + 0xd5, 0x8e, 0x0f, 0xfd, 0x1e, 0x9f, 0x1e, 0xf8, 0x1e, 0x2f, 0xfe, 0xf6, 0x24, 0x1c, 0xe5, 0x9f, + 0x00, 0xe8, 0xe7, 0x0a, 0x64, 0xc4, 0x10, 0x02, 0x5d, 0x49, 0x81, 0x38, 0x38, 0x8b, 0xc9, 0x5d, + 0x1d, 0x45, 0x54, 0xf4, 0x9a, 0xf6, 0xe1, 0xcf, 0xbe, 0xf9, 0xc7, 0xaf, 0x26, 0xf2, 0x68, 0x49, + 0x1f, 0x36, 0x43, 0x42, 0x7f, 0x50, 0xe0, 0x44, 0xdf, 0x34, 0x05, 0x15, 0xf7, 0x77, 0xd3, 0x3f, + 0xb3, 0xc9, 0xdd, 0x1c, 0x4b, 0x47, 0xc6, 0xa8, 0xf3, 0x18, 0xaf, 0xa0, 0xcb, 0x43, 0x63, 0xd4, + 0x5f, 0x48, 0x36, 0xde, 0x43, 0x7f, 0x54, 0xe0, 0xe4, 0xc0, 0xab, 0x01, 0xad, 0x0d, 0xf3, 0x9d, + 0x36, 0xcd, 0xc9, 0xdd, 0x1a, 0x53, 0x4b, 0xc6, 0xbc, 0xca, 0x63, 0xfe, 0x08, 0x5d, 0x49, 0x89, + 0x79, 0xf0, 0xbd, 0x82, 0x5e, 0x29, 0x30, 0xdf, 0x6f, 0x10, 0xdd, 0x1c, 0xc7, 0x7d, 0x18, 0xf3, + 0xda, 0x78, 0x4a, 0x32, 0xe4, 0x2d, 0x1e, 0xf2, 0x26, 0xfa, 0x62, 0xe4, 0x90, 0xf5, 0x17, 0x3d, + 0x4f, 0x89, 0xbd, 0x41, 0x11, 0xf4, 0x3b, 0x05, 0xe6, 0x7a, 0xc7, 0x10, 0x68, 0x75, 0x58, 0x74, + 0x89, 0xd3, 0x95, 0x5c, 0x71, 0x1c, 0x15, 0x09, 0xa7, 0xc0, 0xe1, 0xac, 0xa0, 0x4b, 0x7a, 0xea, + 0xe4, 0x33, 0xfe, 0xc6, 0x40, 0xff, 0x54, 0x20, 0xbf, 0xcf, 0x83, 0x13, 0x95, 0x86, 0xc5, 0x31, + 0xda, 0xeb, 0x39, 0x77, 0xff, 0xbd, 0x6c, 0x48, 0x70, 0x1f, 0x73, 0x70, 0x6b, 0xa8, 0x38, 0x46, + 0xad, 0x04, 0x01, 0xed, 0xa1, 0xff, 0x2a, 0xb0, 0x34, 0x74, 0xe4, 0x81, 0xee, 0x8d, 0xd3, 0x3f, + 0x49, 0x53, 0x99, 0xdc, 0xfa, 0x7b, 0x58, 0x90, 0x10, 0xcb, 0x1c, 0xe2, 0xe7, 0xe8, 0xe1, 0xc1, + 0xdb, 0x91, 0x33, 0x6c, 0x04, 0xfc, 0xdf, 0x0a, 0x9c, 0x1b, 0x36, 0x4b, 0x41, 0x77, 0xc7, 0x89, + 0x3a, 0x61, 0xa8, 0x93, 0xbb, 0x77, 0x70, 0x03, 0x12, 0xf5, 0x03, 0x8e, 0x7a, 0x1d, 0xdd, 0x7d, + 0x4f, 0xd4, 0x9c, 0xb1, 0xfb, 0xe6, 0x08, 0xc3, 0x19, 0x3b, 0x79, 0x26, 0x31, 0x9c, 0xb1, 0x53, + 0x06, 0x15, 0xfb, 0x32, 0xb6, 0x19, 0xea, 0xc9, 0x5b, 0x14, 0xfd, 0x47, 0x81, 0xc5, 0x21, 0x53, + 0x02, 0x74, 0x67, 0x9c, 0xc4, 0x26, 0x10, 0xc8, 0xdd, 0x03, 0xeb, 0x4b, 0x44, 0x9b, 0x1c, 0xd1, + 0x03, 0xf4, 0xe9, 0xc1, 0xeb, 0x12, 0x27, 0x9b, 0x3f, 0x29, 0x30, 0xdb, 0xc3, 0x5b, 0xe8, 0xc6, + 0xc8, 0x14, 0x17, 0x62, 0x5a, 0x1d, 0x43, 0x43, 0xa2, 0xd8, 0xe0, 0x28, 0xee, 0xa0, 0xef, 0x8e, + 0xc6, 0x89, 0xfa, 0x8b, 0x84, 0xc1, 0xc5, 0x5e, 0xe9, 0xf1, 0x57, 0x6f, 0x97, 0x95, 0xaf, 0xdf, + 0x2e, 0x2b, 0x7f, 0x7f, 0xbb, 0xac, 0xfc, 0xf2, 0xdd, 0xf2, 0x91, 0xaf, 0xdf, 0x2d, 0x1f, 0xf9, + 0xdb, 0xbb, 0xe5, 0x23, 0x3f, 0xda, 0xf7, 0x7b, 0xae, 0x1d, 0x77, 0xc8, 0x3f, 0xee, 0xaa, 0x19, + 0xfe, 0x6f, 0xa5, 0x9b, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x80, 0xf7, 0x24, 0x06, 0xc4, 0x1b, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2995,7 +3007,9 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.ParamsVersion != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.ParamsVersion)) i-- - dAtA[i] = 0x78 + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 } if m.UndelegationResponse != nil { { @@ -3007,19 +3021,19 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x72 + dAtA[i] = 0x7a } if m.UnbondingTime != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.UnbondingTime)) i-- - dAtA[i] = 0x68 + dAtA[i] = 0x70 } if len(m.StatusDesc) > 0 { i -= len(m.StatusDesc) copy(dAtA[i:], m.StatusDesc) i = encodeVarintQuery(dAtA, i, uint64(len(m.StatusDesc))) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x6a } if m.Active { i-- @@ -3029,12 +3043,12 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0 } i-- - dAtA[i] = 0x58 + dAtA[i] = 0x60 } if m.StakingOutputIdx != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.StakingOutputIdx)) i-- - dAtA[i] = 0x50 + dAtA[i] = 0x58 } if len(m.CovenantSigs) > 0 { for iNdEx := len(m.CovenantSigs) - 1; iNdEx >= 0; iNdEx-- { @@ -3047,7 +3061,7 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x52 } } if len(m.DelegatorSlashSigHex) > 0 { @@ -3055,36 +3069,36 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.DelegatorSlashSigHex) i = encodeVarintQuery(dAtA, i, uint64(len(m.DelegatorSlashSigHex))) i-- - dAtA[i] = 0x42 + dAtA[i] = 0x4a } if len(m.SlashingTxHex) > 0 { i -= len(m.SlashingTxHex) copy(dAtA[i:], m.SlashingTxHex) i = encodeVarintQuery(dAtA, i, uint64(len(m.SlashingTxHex))) i-- - dAtA[i] = 0x3a + dAtA[i] = 0x42 } if len(m.StakingTxHex) > 0 { i -= len(m.StakingTxHex) copy(dAtA[i:], m.StakingTxHex) i = encodeVarintQuery(dAtA, i, uint64(len(m.StakingTxHex))) i-- - dAtA[i] = 0x32 + dAtA[i] = 0x3a } if m.TotalSat != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.TotalSat)) i-- - dAtA[i] = 0x28 + dAtA[i] = 0x30 } if m.EndHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.EndHeight)) i-- - dAtA[i] = 0x20 + dAtA[i] = 0x28 } if m.StartHeight != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.StartHeight)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x20 } if len(m.FpBtcPkList) > 0 { for iNdEx := len(m.FpBtcPkList) - 1; iNdEx >= 0; iNdEx-- { @@ -3097,7 +3111,7 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } } if m.BtcPk != nil { @@ -3110,6 +3124,13 @@ func (m *BTCDelegationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x12 + } + if len(m.StakerAddr) > 0 { + i -= len(m.StakerAddr) + copy(dAtA[i:], m.StakerAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.StakerAddr))) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -3661,6 +3682,10 @@ func (m *BTCDelegationResponse) Size() (n int) { } var l int _ = l + l = len(m.StakerAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } if m.BtcPk != nil { l = m.BtcPk.Size() n += 1 + l + sovQuery(uint64(l)) @@ -3716,7 +3741,7 @@ func (m *BTCDelegationResponse) Size() (n int) { n += 1 + l + sovQuery(uint64(l)) } if m.ParamsVersion != 0 { - n += 1 + sovQuery(uint64(m.ParamsVersion)) + n += 2 + sovQuery(uint64(m.ParamsVersion)) } return n } @@ -5824,6 +5849,38 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StakerAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.StakerAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) } @@ -5858,7 +5915,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkList", wireType) } @@ -5893,7 +5950,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) } @@ -5912,7 +5969,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 4: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field EndHeight", wireType) } @@ -5931,7 +5988,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 5: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field TotalSat", wireType) } @@ -5950,7 +6007,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 6: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StakingTxHex", wireType) } @@ -5982,7 +6039,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } m.StakingTxHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 7: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SlashingTxHex", wireType) } @@ -6014,7 +6071,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } m.SlashingTxHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 8: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DelegatorSlashSigHex", wireType) } @@ -6046,7 +6103,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } m.DelegatorSlashSigHex = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 9: + case 10: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field CovenantSigs", wireType) } @@ -6080,7 +6137,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 10: + case 11: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StakingOutputIdx", wireType) } @@ -6099,7 +6156,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 11: + case 12: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Active", wireType) } @@ -6119,7 +6176,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } } m.Active = bool(v != 0) - case 12: + case 13: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StatusDesc", wireType) } @@ -6151,7 +6208,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { } m.StatusDesc = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 13: + case 14: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTime", wireType) } @@ -6170,7 +6227,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { break } } - case 14: + case 15: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UndelegationResponse", wireType) } @@ -6206,7 +6263,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 15: + case 16: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field ParamsVersion", wireType) } diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index e1c979153..1b6326375 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -254,48 +254,47 @@ var xxx_messageInfo_MsgEditFinalityProviderResponse proto.InternalMessageInfo // MsgCreateBTCDelegation is the message for creating a BTC delegation type MsgCreateBTCDelegation struct { - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - BabylonPk *secp256k1.PubKey `protobuf:"bytes,2,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` - // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,3,opt,name=pop,proto3" json:"pop,omitempty"` + // staker_addr is the address to receive rewards from BTC delegation. + StakerAddr string `protobuf:"bytes,1,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` + // pop is the proof of possession of btc_pk by the staker_addr. + Pop *ProofOfPossessionBTC `protobuf:"bytes,2,opt,name=pop,proto3" json:"pop,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,5,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` + FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` // staking_time is the time lock used in staking transaction - StakingTime uint32 `protobuf:"varint,6,opt,name=staking_time,json=stakingTime,proto3" json:"staking_time,omitempty"` + StakingTime uint32 `protobuf:"varint,5,opt,name=staking_time,json=stakingTime,proto3" json:"staking_time,omitempty"` // staking_value is the amount of satoshis locked in staking output - StakingValue int64 `protobuf:"varint,7,opt,name=staking_value,json=stakingValue,proto3" json:"staking_value,omitempty"` + StakingValue int64 `protobuf:"varint,6,opt,name=staking_value,json=stakingValue,proto3" json:"staking_value,omitempty"` // staking_tx is the staking tx along with the merkle proof of inclusion in btc block - StakingTx *types1.TransactionInfo `protobuf:"bytes,8,opt,name=staking_tx,json=stakingTx,proto3" json:"staking_tx,omitempty"` + StakingTx *types1.TransactionInfo `protobuf:"bytes,7,opt,name=staking_tx,json=stakingTx,proto3" json:"staking_tx,omitempty"` // slashing_tx is the slashing tx // Note that the tx itself does not contain signatures, which are off-chain. - SlashingTx *BTCSlashingTx `protobuf:"bytes,9,opt,name=slashing_tx,json=slashingTx,proto3,customtype=BTCSlashingTx" json:"slashing_tx,omitempty"` + SlashingTx *BTCSlashingTx `protobuf:"bytes,8,opt,name=slashing_tx,json=slashingTx,proto3,customtype=BTCSlashingTx" json:"slashing_tx,omitempty"` // delegator_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - DelegatorSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,10,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` + DelegatorSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,9,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output // - unbonding slashing transaction, change output // It must be smaller than math.MaxUInt16 and larger that max(MinUnbondingTime, CheckpointFinalizationTimeout) - UnbondingTime uint32 `protobuf:"varint,11,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` + UnbondingTime uint32 `protobuf:"varint,10,opt,name=unbonding_time,json=unbondingTime,proto3" json:"unbonding_time,omitempty"` // fields related to unbonding transaction // unbonding_tx is a bitcoin unbonding transaction i.e transaction that spends // staking output and sends it to the unbonding output - UnbondingTx []byte `protobuf:"bytes,12,opt,name=unbonding_tx,json=unbondingTx,proto3" json:"unbonding_tx,omitempty"` + UnbondingTx []byte `protobuf:"bytes,11,opt,name=unbonding_tx,json=unbondingTx,proto3" json:"unbonding_tx,omitempty"` // unbonding_value is amount of satoshis locked in unbonding output. // NOTE: staking_value and unbonding_value could be different because of the difference between the fee for staking tx and that for unbonding - UnbondingValue int64 `protobuf:"varint,13,opt,name=unbonding_value,json=unbondingValue,proto3" json:"unbonding_value,omitempty"` + UnbondingValue int64 `protobuf:"varint,12,opt,name=unbonding_value,json=unbondingValue,proto3" json:"unbonding_value,omitempty"` // unbonding_slashing_tx is the slashing tx which slash unbonding contract // Note that the tx itself does not contain signatures, which are off-chain. - UnbondingSlashingTx *BTCSlashingTx `protobuf:"bytes,14,opt,name=unbonding_slashing_tx,json=unbondingSlashingTx,proto3,customtype=BTCSlashingTx" json:"unbonding_slashing_tx,omitempty"` + UnbondingSlashingTx *BTCSlashingTx `protobuf:"bytes,13,opt,name=unbonding_slashing_tx,json=unbondingSlashingTx,proto3,customtype=BTCSlashingTx" json:"unbonding_slashing_tx,omitempty"` // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - DelegatorUnbondingSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,15,opt,name=delegator_unbonding_slashing_sig,json=delegatorUnbondingSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_unbonding_slashing_sig,omitempty"` + DelegatorUnbondingSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,14,opt,name=delegator_unbonding_slashing_sig,json=delegatorUnbondingSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_unbonding_slashing_sig,omitempty"` } func (m *MsgCreateBTCDelegation) Reset() { *m = MsgCreateBTCDelegation{} } @@ -331,21 +330,14 @@ func (m *MsgCreateBTCDelegation) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateBTCDelegation proto.InternalMessageInfo -func (m *MsgCreateBTCDelegation) GetSigner() string { +func (m *MsgCreateBTCDelegation) GetStakerAddr() string { if m != nil { - return m.Signer + return m.StakerAddr } return "" } -func (m *MsgCreateBTCDelegation) GetBabylonPk() *secp256k1.PubKey { - if m != nil { - return m.BabylonPk - } - return nil -} - -func (m *MsgCreateBTCDelegation) GetPop() *ProofOfPossession { +func (m *MsgCreateBTCDelegation) GetPop() *ProofOfPossessionBTC { if m != nil { return m.Pop } @@ -870,88 +862,89 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1284 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0xdb, 0xc6, - 0x13, 0x35, 0x2d, 0x5b, 0xf9, 0x79, 0x64, 0xd9, 0xfe, 0x31, 0x8e, 0x43, 0xb3, 0x89, 0x24, 0x3b, - 0x69, 0xe2, 0x04, 0x35, 0x15, 0x3b, 0x8d, 0xd1, 0x26, 0x40, 0x81, 0xc8, 0x76, 0x90, 0xa0, 0x11, - 0x2a, 0x50, 0x76, 0x0f, 0xed, 0x41, 0xa0, 0xa8, 0x35, 0xb5, 0x90, 0xc4, 0x25, 0xb8, 0x6b, 0x41, - 0x42, 0x81, 0xa2, 0x08, 0x7a, 0x2d, 0xd0, 0x53, 0x0f, 0xbd, 0xf5, 0x1b, 0xe4, 0x90, 0x8f, 0xd0, - 0x43, 0x8e, 0x41, 0x4e, 0x85, 0x0b, 0x18, 0x45, 0x52, 0x20, 0x87, 0x9e, 0x7b, 0x2f, 0x48, 0x2e, - 0x97, 0xa4, 0x2a, 0x36, 0x76, 0x9c, 0x1b, 0x77, 0xf7, 0xcd, 0xcc, 0x9b, 0x37, 0xb3, 0x7f, 0x08, - 0x85, 0xa6, 0xd1, 0x1c, 0x76, 0x89, 0x5d, 0x6e, 0x32, 0x93, 0x32, 0xa3, 0x83, 0x6d, 0xab, 0xdc, - 0xdf, 0x28, 0xb3, 0x81, 0xe6, 0xb8, 0x84, 0x11, 0xf9, 0x02, 0x5f, 0xd7, 0xa2, 0x75, 0xad, 0xbf, - 0xa1, 0x2e, 0x5a, 0xc4, 0x22, 0x3e, 0xa2, 0xec, 0x7d, 0x05, 0x60, 0x75, 0xd9, 0x24, 0xb4, 0x47, - 0x68, 0x23, 0x58, 0x08, 0x06, 0x7c, 0xe9, 0x62, 0x30, 0x2a, 0xf7, 0xa8, 0xef, 0xbf, 0x47, 0x2d, - 0xbe, 0xb0, 0xca, 0x17, 0x4c, 0x77, 0xe8, 0x30, 0x52, 0xa6, 0xc8, 0x74, 0x36, 0xef, 0x6c, 0x75, - 0x36, 0xca, 0x1d, 0x34, 0x0c, 0x8d, 0x57, 0xc7, 0x93, 0x74, 0x0c, 0xd7, 0xe8, 0x85, 0x98, 0x8f, - 0x62, 0x18, 0xb3, 0x8d, 0xcc, 0x8e, 0x43, 0xb0, 0xcd, 0x3c, 0x58, 0x62, 0x82, 0xa3, 0xaf, 0xf2, - 0xa8, 0x91, 0xb7, 0x26, 0x62, 0xc6, 0x46, 0x38, 0xe6, 0xa8, 0x62, 0x4a, 0x5c, 0xe2, 0x04, 0x80, - 0xd5, 0x5f, 0x32, 0xb0, 0x5c, 0xa5, 0xd6, 0xb6, 0x8b, 0x0c, 0x86, 0x1e, 0x60, 0xdb, 0xe8, 0x62, - 0x36, 0xac, 0xb9, 0xa4, 0x8f, 0x5b, 0xc8, 0x95, 0x97, 0x20, 0x4b, 0xb1, 0x65, 0x23, 0x57, 0x91, - 0x4a, 0xd2, 0xda, 0x8c, 0xce, 0x47, 0xf2, 0x2e, 0xe4, 0x5a, 0x88, 0x9a, 0x2e, 0x76, 0x18, 0x26, - 0xb6, 0x32, 0x59, 0x92, 0xd6, 0x72, 0x9b, 0x57, 0x34, 0xae, 0x57, 0xa4, 0xb2, 0x4f, 0x49, 0xdb, - 0x89, 0xa0, 0x7a, 0xdc, 0x4e, 0xae, 0x02, 0x98, 0xa4, 0xd7, 0xc3, 0x94, 0x7a, 0x5e, 0x32, 0x5e, - 0x88, 0xca, 0xfa, 0xd1, 0x71, 0xf1, 0x83, 0xc0, 0x11, 0x6d, 0x75, 0x34, 0x4c, 0xca, 0x3d, 0x83, - 0xb5, 0xb5, 0xc7, 0xc8, 0x32, 0xcc, 0xe1, 0x0e, 0x32, 0x5f, 0x3e, 0x5b, 0x07, 0x1e, 0x67, 0x07, - 0x99, 0x7a, 0xcc, 0x81, 0xfc, 0x19, 0x00, 0x4f, 0xb7, 0xe1, 0x74, 0x94, 0x29, 0x9f, 0x54, 0x31, - 0x24, 0x15, 0x54, 0x47, 0x13, 0xd5, 0xd1, 0x6a, 0x87, 0xcd, 0xcf, 0xd1, 0x50, 0x9f, 0xe1, 0x26, - 0xb5, 0x8e, 0x5c, 0x85, 0x6c, 0x93, 0x99, 0x9e, 0xed, 0x74, 0x49, 0x5a, 0x9b, 0xad, 0x6c, 0x1d, - 0x1d, 0x17, 0x37, 0x2d, 0xcc, 0xda, 0x87, 0x4d, 0xcd, 0x24, 0xbd, 0x32, 0x47, 0x9a, 0x6d, 0x03, - 0xdb, 0xe1, 0xa0, 0xcc, 0x86, 0x0e, 0xa2, 0x5a, 0xe5, 0x51, 0xed, 0xf6, 0xc7, 0xb7, 0xb8, 0xcb, - 0xe9, 0x26, 0x33, 0x6b, 0x1d, 0xf9, 0x2e, 0x64, 0x1c, 0xe2, 0x28, 0x59, 0x9f, 0xc7, 0x9a, 0x36, - 0xb6, 0x0d, 0xb5, 0x9a, 0x4b, 0xc8, 0xc1, 0x17, 0x07, 0x35, 0x42, 0x29, 0xf2, 0xb3, 0xd0, 0x3d, - 0xa3, 0xbb, 0xb9, 0x27, 0x6f, 0x9e, 0xde, 0xe4, 0x6a, 0xaf, 0x5e, 0x81, 0x95, 0xd4, 0x12, 0xe9, - 0x88, 0x3a, 0xc4, 0xa6, 0x68, 0xf5, 0x2f, 0x09, 0x2e, 0x56, 0xa9, 0xb5, 0xdb, 0xc2, 0xec, 0xc4, - 0x65, 0xbc, 0x20, 0x12, 0xf6, 0x2a, 0x38, 0x1b, 0x12, 0x1f, 0xa9, 0x6e, 0xe6, 0xbd, 0x54, 0x77, - 0xea, 0x8c, 0xd5, 0x4d, 0x4a, 0xb2, 0x02, 0xc5, 0x94, 0x64, 0x85, 0x20, 0xbf, 0x9f, 0x83, 0x25, - 0x21, 0x5b, 0x65, 0x6f, 0x7b, 0x07, 0x75, 0x91, 0x65, 0xf8, 0xcc, 0xd2, 0xf4, 0x48, 0x36, 0xd0, - 0xe4, 0xa9, 0x1b, 0x88, 0x57, 0x3c, 0xf3, 0x0e, 0x15, 0x8f, 0x35, 0xdf, 0xd4, 0xfb, 0x68, 0xbe, - 0xaf, 0x61, 0xee, 0xc0, 0x69, 0x04, 0x1e, 0x1b, 0x5d, 0x4c, 0x99, 0x32, 0x5d, 0xca, 0x9c, 0xc1, - 0x6d, 0xee, 0xc0, 0xa9, 0x78, 0x8e, 0x1f, 0x63, 0xca, 0xe4, 0x15, 0x98, 0xe5, 0x09, 0x35, 0x18, - 0xee, 0x21, 0xbf, 0xc5, 0xf3, 0x7a, 0x8e, 0xcf, 0xed, 0xe1, 0x1e, 0x92, 0xaf, 0x40, 0x3e, 0x84, - 0xf4, 0x8d, 0xee, 0x21, 0x52, 0xce, 0x95, 0xa4, 0xb5, 0x8c, 0x1e, 0xda, 0x7d, 0xe9, 0xcd, 0xc9, - 0x0f, 0x01, 0x84, 0x9f, 0x81, 0xf2, 0x3f, 0x5f, 0xb6, 0x1b, 0x71, 0xd9, 0x62, 0xa7, 0x5e, 0x7f, - 0x43, 0xdb, 0x73, 0x0d, 0x9b, 0x1a, 0xa6, 0x57, 0xc2, 0x47, 0xf6, 0x01, 0xd1, 0x67, 0xc2, 0x80, - 0x03, 0x79, 0x13, 0x72, 0xb4, 0x6b, 0xd0, 0x36, 0x77, 0x35, 0xe3, 0x4b, 0xf8, 0xff, 0xa3, 0xe3, - 0x62, 0xbe, 0xb2, 0xb7, 0x5d, 0xe7, 0x2b, 0x7b, 0x03, 0x1d, 0xa8, 0xf8, 0x96, 0x09, 0x2c, 0xb5, - 0x82, 0x9e, 0x20, 0x6e, 0x43, 0x58, 0x53, 0x6c, 0x29, 0xe0, 0x9b, 0x7f, 0x7a, 0x74, 0x5c, 0xbc, - 0x73, 0x1a, 0xa9, 0xea, 0xd8, 0xb2, 0x0d, 0x76, 0xe8, 0x22, 0x7d, 0x51, 0x38, 0x0e, 0x63, 0xd7, - 0xb1, 0x25, 0x7f, 0x08, 0x73, 0x87, 0x76, 0x93, 0xd8, 0x2d, 0x21, 0x5c, 0xce, 0x17, 0x2e, 0x2f, - 0x66, 0x7d, 0xe9, 0x56, 0x60, 0x36, 0x06, 0x1b, 0x28, 0xb3, 0xfe, 0xde, 0xcc, 0x45, 0xa0, 0x81, - 0x7c, 0x1d, 0xe6, 0x23, 0x48, 0xa0, 0x6f, 0xde, 0xd7, 0x37, 0x0a, 0x10, 0x28, 0xbc, 0x0b, 0x17, - 0x22, 0x60, 0x5c, 0xa1, 0xb9, 0x34, 0x85, 0xce, 0x0b, 0x7c, 0x34, 0x29, 0x3f, 0x91, 0xa0, 0x14, - 0x69, 0x35, 0xc6, 0xa3, 0xa7, 0xda, 0xfc, 0x59, 0x55, 0xbb, 0x2c, 0x42, 0xec, 0x8f, 0x72, 0xa8, - 0x63, 0x2b, 0x79, 0x00, 0x94, 0xa0, 0x30, 0x7e, 0x73, 0x8b, 0xfd, 0xff, 0xf7, 0x24, 0xc8, 0x55, - 0x6a, 0xdd, 0x6f, 0xb5, 0xb6, 0x49, 0x1f, 0xd9, 0x86, 0xcd, 0xea, 0xd8, 0xa2, 0xa9, 0x7b, 0xff, - 0x01, 0x4c, 0x86, 0xe7, 0xe0, 0x3b, 0x6f, 0x92, 0x49, 0xa7, 0x23, 0x5f, 0x83, 0xf9, 0xa8, 0xa7, - 0x1b, 0x6d, 0x83, 0xb6, 0x83, 0x8b, 0x4d, 0xcf, 0x8b, 0x6e, 0x7d, 0x68, 0xd0, 0xb6, 0xbc, 0x06, - 0x0b, 0xb1, 0x7a, 0x78, 0x02, 0x52, 0x65, 0xca, 0xdb, 0xa2, 0xfa, 0x5c, 0xd4, 0xa3, 0x3e, 0x63, - 0x13, 0x16, 0xe2, 0xfd, 0xe0, 0x6b, 0x3d, 0x7d, 0x56, 0xad, 0xe7, 0x62, 0xed, 0xe4, 0xf5, 0xe6, - 0x3d, 0x50, 0x05, 0x9d, 0xd1, 0x68, 0x54, 0xc9, 0xfa, 0xc4, 0x2e, 0x86, 0x88, 0xfd, 0x84, 0x2d, - 0x4d, 0x56, 0xe6, 0x12, 0xa8, 0xff, 0x96, 0x5d, 0x54, 0xe5, 0x57, 0x09, 0x16, 0xaa, 0xd4, 0xaa, - 0xec, 0x6d, 0xef, 0xdb, 0xbc, 0xdc, 0x28, 0xb5, 0x26, 0x63, 0xb4, 0x9c, 0x1c, 0xa7, 0xe5, 0x38, - 0x85, 0x32, 0xef, 0x59, 0xa1, 0x64, 0x92, 0x2a, 0x28, 0xa3, 0x59, 0x88, 0x14, 0x7f, 0x96, 0xe0, - 0x52, 0x95, 0x5a, 0x75, 0xd4, 0x45, 0x26, 0xc3, 0x7d, 0x14, 0xf6, 0xf0, 0xae, 0x77, 0x3f, 0xd9, - 0xe6, 0xd9, 0xd3, 0x5d, 0x87, 0xf3, 0x2e, 0x32, 0x49, 0x1f, 0xb9, 0xa8, 0xd5, 0xe0, 0xa7, 0x3c, - 0xed, 0x04, 0x19, 0xeb, 0x0b, 0x62, 0xe9, 0x81, 0x77, 0x62, 0xd7, 0x3b, 0x49, 0xe2, 0xd7, 0xe0, - 0xea, 0x7f, 0x71, 0x13, 0x49, 0xfc, 0x24, 0xc1, 0x7c, 0x95, 0x5a, 0xfb, 0x4e, 0xcb, 0x60, 0xa8, - 0xe6, 0x3f, 0x53, 0xe5, 0x2d, 0x98, 0x31, 0x0e, 0x59, 0x9b, 0xb8, 0x98, 0x0d, 0x03, 0xea, 0x15, - 0xe5, 0xe5, 0xb3, 0xf5, 0x45, 0x7e, 0x41, 0xde, 0x6f, 0xb5, 0x5c, 0x44, 0x69, 0x9d, 0xb9, 0xd8, - 0xb6, 0xf4, 0x08, 0x2a, 0xdf, 0x83, 0x6c, 0xf0, 0xd0, 0xe5, 0x57, 0xea, 0xe5, 0xb4, 0x9b, 0xd1, - 0x07, 0x55, 0xa6, 0x9e, 0x1f, 0x17, 0x27, 0x74, 0x6e, 0x72, 0x77, 0xce, 0x63, 0x1f, 0x39, 0x5b, - 0x5d, 0xf6, 0x9f, 0x39, 0x71, 0x5e, 0x21, 0xe7, 0xcd, 0x3f, 0xb3, 0x90, 0xa9, 0x52, 0x4b, 0xfe, - 0x5e, 0x82, 0xa5, 0x94, 0x07, 0xed, 0xad, 0x94, 0xd0, 0xa9, 0xef, 0x2b, 0xf5, 0x93, 0xd3, 0x5a, - 0x84, 0x74, 0xe4, 0x6f, 0x61, 0x71, 0xec, 0x6b, 0x4c, 0x4b, 0xf7, 0x38, 0x0e, 0xaf, 0x6e, 0x9d, - 0x0e, 0x2f, 0xe2, 0x7f, 0x03, 0xe7, 0xc7, 0x3d, 0x7e, 0xd6, 0xdf, 0x96, 0x50, 0x02, 0xae, 0xde, - 0x39, 0x15, 0x5c, 0x04, 0x27, 0x30, 0x3f, 0x7a, 0xf2, 0xde, 0x48, 0xf7, 0x34, 0x02, 0x55, 0x37, - 0x4e, 0x0c, 0x15, 0x01, 0x31, 0xe4, 0x93, 0x87, 0xca, 0xf5, 0x74, 0x1f, 0x09, 0xa0, 0x5a, 0x3e, - 0x21, 0x50, 0x84, 0xfa, 0x41, 0x82, 0xe5, 0xf4, 0xdd, 0x7d, 0x3b, 0xdd, 0x5d, 0xaa, 0x91, 0x7a, - 0xef, 0x1d, 0x8c, 0x04, 0x9f, 0x03, 0x98, 0x4d, 0xec, 0xd3, 0x6b, 0xe9, 0xce, 0xe2, 0x38, 0x55, - 0x3b, 0x19, 0x2e, 0x8c, 0xa3, 0x4e, 0x7f, 0xf7, 0xe6, 0xe9, 0x4d, 0xa9, 0xf2, 0xf8, 0xf9, 0xab, - 0x82, 0xf4, 0xe2, 0x55, 0x41, 0xfa, 0xe3, 0x55, 0x41, 0xfa, 0xf1, 0x75, 0x61, 0xe2, 0xc5, 0xeb, - 0xc2, 0xc4, 0x6f, 0xaf, 0x0b, 0x13, 0x5f, 0xbd, 0xf5, 0xce, 0x1c, 0xc4, 0xff, 0x43, 0xfd, 0x63, - 0xb7, 0x99, 0xf5, 0xff, 0x43, 0x6f, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xd3, 0xc8, 0xf6, - 0xc7, 0x0f, 0x00, 0x00, + // 1300 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0x45, + 0x14, 0xce, 0xc6, 0x89, 0x4b, 0x9e, 0xe3, 0x24, 0x6c, 0xd3, 0xd4, 0x59, 0x5a, 0x3b, 0x71, 0x4b, + 0x9b, 0x16, 0xb2, 0x6e, 0x52, 0x1a, 0xd1, 0x54, 0x20, 0xd5, 0x49, 0xaa, 0x56, 0xd4, 0xc2, 0x5a, + 0x3b, 0x1c, 0xe0, 0x60, 0xad, 0x77, 0x27, 0xeb, 0x91, 0xed, 0x9d, 0xd5, 0xce, 0xc4, 0xb2, 0x85, + 0x84, 0x50, 0xc5, 0x15, 0x89, 0x13, 0x07, 0x6e, 0xfc, 0x07, 0x3d, 0xf4, 0x4f, 0x40, 0xa8, 0xc7, + 0xaa, 0x27, 0x94, 0x43, 0x84, 0x5a, 0xa4, 0x1e, 0x38, 0x73, 0x47, 0x3b, 0x3b, 0xfb, 0xc3, 0xc1, + 0x4b, 0x93, 0x26, 0x37, 0xef, 0xcc, 0xf7, 0xbe, 0xf7, 0xde, 0xf7, 0xde, 0x9b, 0x19, 0x43, 0xbe, + 0xa9, 0x37, 0x07, 0x1d, 0x62, 0x97, 0x9a, 0xcc, 0xa0, 0x4c, 0x6f, 0x63, 0xdb, 0x2a, 0xf5, 0xd6, + 0x4a, 0xac, 0xaf, 0x3a, 0x2e, 0x61, 0x44, 0xbe, 0x20, 0xf6, 0xd5, 0x68, 0x5f, 0xed, 0xad, 0x29, + 0xf3, 0x16, 0xb1, 0x08, 0x47, 0x94, 0xbc, 0x5f, 0x3e, 0x58, 0x59, 0x34, 0x08, 0xed, 0x12, 0xda, + 0xf0, 0x37, 0xfc, 0x0f, 0xb1, 0x75, 0xd1, 0xff, 0x2a, 0x75, 0x29, 0xe7, 0xef, 0x52, 0x4b, 0x6c, + 0x14, 0xc5, 0x86, 0xe1, 0x0e, 0x1c, 0x46, 0x4a, 0x14, 0x19, 0xce, 0xfa, 0x9d, 0x8d, 0xf6, 0x5a, + 0xa9, 0x8d, 0x06, 0x81, 0x71, 0x71, 0x74, 0x90, 0x8e, 0xee, 0xea, 0xdd, 0x00, 0xf3, 0x71, 0x0c, + 0x63, 0xb4, 0x90, 0xd1, 0x76, 0x08, 0xb6, 0x99, 0x07, 0x1b, 0x5a, 0x10, 0xe8, 0xab, 0xc2, 0x6b, + 0xc4, 0xd6, 0x44, 0x4c, 0x5f, 0x0b, 0xbe, 0x05, 0xaa, 0x90, 0xe0, 0x97, 0x38, 0x3e, 0xa0, 0xf8, + 0x6b, 0x0a, 0x16, 0x2b, 0xd4, 0xda, 0x72, 0x91, 0xce, 0xd0, 0x03, 0x6c, 0xeb, 0x1d, 0xcc, 0x06, + 0x55, 0x97, 0xf4, 0xb0, 0x89, 0x5c, 0x79, 0x01, 0xd2, 0x14, 0x5b, 0x36, 0x72, 0x73, 0xd2, 0x92, + 0xb4, 0x32, 0xa5, 0x89, 0x2f, 0x79, 0x07, 0x32, 0x26, 0xa2, 0x86, 0x8b, 0x1d, 0x86, 0x89, 0x9d, + 0x1b, 0x5f, 0x92, 0x56, 0x32, 0xeb, 0x57, 0x54, 0xa1, 0x57, 0xa4, 0x32, 0x0f, 0x49, 0xdd, 0x8e, + 0xa0, 0x5a, 0xdc, 0x4e, 0xae, 0x00, 0x18, 0xa4, 0xdb, 0xc5, 0x94, 0x7a, 0x2c, 0x29, 0xcf, 0x45, + 0x79, 0xf5, 0xe0, 0xb0, 0xf0, 0x81, 0x4f, 0x44, 0xcd, 0xb6, 0x8a, 0x49, 0xa9, 0xab, 0xb3, 0x96, + 0xfa, 0x18, 0x59, 0xba, 0x31, 0xd8, 0x46, 0xc6, 0xcb, 0x67, 0xab, 0x20, 0xfc, 0x6c, 0x23, 0x43, + 0x8b, 0x11, 0xc8, 0x9f, 0x03, 0x88, 0x74, 0x1b, 0x4e, 0x3b, 0x37, 0xc1, 0x83, 0x2a, 0x04, 0x41, + 0xf9, 0xd5, 0x51, 0xc3, 0xea, 0xa8, 0xd5, 0xfd, 0xe6, 0x17, 0x68, 0xa0, 0x4d, 0x09, 0x93, 0x6a, + 0x5b, 0xae, 0x40, 0xba, 0xc9, 0x0c, 0xcf, 0x76, 0x72, 0x49, 0x5a, 0x99, 0x2e, 0x6f, 0x1c, 0x1c, + 0x16, 0xd6, 0x2d, 0xcc, 0x5a, 0xfb, 0x4d, 0xd5, 0x20, 0xdd, 0x92, 0x40, 0x1a, 0x2d, 0x1d, 0xdb, + 0xc1, 0x47, 0x89, 0x0d, 0x1c, 0x44, 0xd5, 0xf2, 0xa3, 0xea, 0xed, 0x4f, 0x6e, 0x09, 0xca, 0xc9, + 0x26, 0x33, 0xaa, 0x6d, 0x79, 0x13, 0x52, 0x0e, 0x71, 0x72, 0x69, 0x1e, 0xc7, 0x8a, 0x3a, 0xb2, + 0x0d, 0xd5, 0xaa, 0x4b, 0xc8, 0xde, 0x97, 0x7b, 0x55, 0x42, 0x29, 0xe2, 0x59, 0x68, 0x9e, 0xd1, + 0x66, 0xe6, 0xc9, 0x9b, 0xa7, 0x37, 0x85, 0xda, 0xc5, 0x2b, 0xb0, 0x9c, 0x58, 0x22, 0x0d, 0x51, + 0x87, 0xd8, 0x14, 0x15, 0xff, 0x96, 0xe0, 0x62, 0x85, 0x5a, 0x3b, 0x26, 0x66, 0xc7, 0x2e, 0xe3, + 0x85, 0x30, 0x61, 0xaf, 0x82, 0xd3, 0x41, 0xe0, 0x47, 0xaa, 0x9b, 0x3a, 0x93, 0xea, 0x4e, 0x9c, + 0xb2, 0xba, 0xc3, 0x92, 0x2c, 0x43, 0x21, 0x21, 0xd9, 0x50, 0x90, 0xdf, 0xcf, 0xc1, 0x42, 0x28, + 0x5b, 0xb9, 0xbe, 0xb5, 0x8d, 0x3a, 0xc8, 0xd2, 0x79, 0x64, 0x77, 0x21, 0xe3, 0x65, 0x81, 0xdc, + 0x86, 0x6e, 0x9a, 0x42, 0x94, 0x72, 0xee, 0xe5, 0xb3, 0xd5, 0x79, 0xe1, 0xfb, 0xbe, 0x69, 0xba, + 0x88, 0xd2, 0x1a, 0x73, 0xb1, 0x6d, 0x69, 0xe0, 0x83, 0xbd, 0x45, 0xf9, 0x33, 0xbf, 0xa8, 0x7e, + 0xc7, 0x7f, 0x74, 0xdc, 0xa2, 0x96, 0xeb, 0x5b, 0xbc, 0xae, 0xb1, 0x16, 0x4b, 0x9d, 0x45, 0x8b, + 0x7d, 0x03, 0x33, 0x7b, 0x4e, 0xc3, 0x67, 0x6c, 0x74, 0x30, 0x65, 0xb9, 0x89, 0xa5, 0xd4, 0x29, + 0x68, 0x33, 0x7b, 0x4e, 0xd9, 0x23, 0x7e, 0x8c, 0x29, 0x93, 0x97, 0x61, 0x5a, 0xe4, 0xd4, 0x60, + 0xb8, 0x8b, 0xf8, 0x50, 0x64, 0xb5, 0x8c, 0x58, 0xab, 0xe3, 0x2e, 0x92, 0xaf, 0x40, 0x36, 0x80, + 0xf4, 0xf4, 0xce, 0x3e, 0xe2, 0xcd, 0x9e, 0xd2, 0x02, 0xbb, 0xaf, 0xbc, 0x35, 0xf9, 0x21, 0x40, + 0xc8, 0xd3, 0xcf, 0x9d, 0xe3, 0xca, 0xdd, 0x88, 0x2b, 0x17, 0x3b, 0xdb, 0x7a, 0x6b, 0x6a, 0xdd, + 0xd5, 0x6d, 0xaa, 0x1b, 0x5e, 0xa1, 0x1e, 0xd9, 0x7b, 0x44, 0x9b, 0x0a, 0x1c, 0xf6, 0xe5, 0x75, + 0xc8, 0xd0, 0x8e, 0x4e, 0x5b, 0x82, 0xea, 0x3d, 0x2e, 0xe1, 0xfb, 0x07, 0x87, 0x85, 0x6c, 0xb9, + 0xbe, 0x55, 0x13, 0x3b, 0xf5, 0xbe, 0x06, 0x34, 0xfc, 0x2d, 0x13, 0x58, 0x30, 0xfd, 0xca, 0x13, + 0xb7, 0x11, 0x5a, 0x53, 0x6c, 0xe5, 0xa6, 0xb8, 0xf9, 0xdd, 0x83, 0xc3, 0xc2, 0x9d, 0x93, 0x48, + 0x55, 0xc3, 0x96, 0xad, 0xb3, 0x7d, 0x17, 0x69, 0xf3, 0x21, 0x71, 0xe0, 0xbb, 0x86, 0x2d, 0xf9, + 0x43, 0x98, 0xd9, 0xb7, 0x9b, 0xc4, 0x36, 0x43, 0xe1, 0x80, 0x0b, 0x97, 0x0d, 0x57, 0xb9, 0x74, + 0xcb, 0x30, 0x1d, 0x83, 0xf5, 0x73, 0x19, 0x3e, 0x81, 0x99, 0x08, 0xd4, 0x97, 0xaf, 0xc3, 0x6c, + 0x04, 0xf1, 0xf5, 0x9d, 0xe6, 0xfa, 0x46, 0x0e, 0x7c, 0x85, 0x77, 0xe0, 0x42, 0x04, 0x8c, 0x2b, + 0x94, 0x4d, 0x52, 0xe8, 0x7c, 0x88, 0x8f, 0x16, 0xe5, 0x27, 0x12, 0x2c, 0x45, 0x5a, 0x8d, 0x60, + 0xf4, 0x54, 0x9b, 0x39, 0xad, 0x6a, 0x97, 0x43, 0x17, 0xbb, 0x47, 0x63, 0xa8, 0x61, 0x6b, 0x73, + 0xce, 0x1b, 0xf3, 0xf8, 0x78, 0x16, 0x97, 0x20, 0x3f, 0x7a, 0x8e, 0xc3, 0x51, 0xff, 0x67, 0x1c, + 0xe4, 0x0a, 0xb5, 0xee, 0x9b, 0xe6, 0x16, 0xe9, 0x21, 0x5b, 0xb7, 0x59, 0x0d, 0x5b, 0x34, 0xf1, + 0xd8, 0x7b, 0x00, 0xe3, 0xc1, 0x91, 0xf7, 0xce, 0x93, 0x32, 0xee, 0xb4, 0xe5, 0x6b, 0x30, 0x1b, + 0x35, 0x76, 0xa3, 0xa5, 0xd3, 0x96, 0x7f, 0x87, 0x69, 0xd9, 0xb0, 0x65, 0x1f, 0xea, 0xb4, 0x25, + 0xaf, 0xc0, 0x5c, 0xac, 0x28, 0x9e, 0x8a, 0xd4, 0x9f, 0x53, 0x6d, 0x26, 0x6a, 0x54, 0x1e, 0xb1, + 0x01, 0x73, 0xf1, 0xa6, 0xe0, 0x82, 0x4f, 0x9e, 0x56, 0xf0, 0x99, 0x58, 0x4f, 0x79, 0x0d, 0x7a, + 0x0f, 0x94, 0x30, 0x9c, 0xa3, 0xde, 0x68, 0x2e, 0xcd, 0x03, 0xbb, 0x18, 0x20, 0x76, 0x87, 0x6c, + 0xe9, 0xf0, 0x29, 0x7c, 0x09, 0x94, 0xff, 0xca, 0x1e, 0x56, 0xe5, 0x37, 0x09, 0xe6, 0x2a, 0xd4, + 0x2a, 0xd7, 0xb7, 0x76, 0x6d, 0x51, 0x73, 0x94, 0x58, 0x93, 0x11, 0x5a, 0x8e, 0x8f, 0xd2, 0x72, + 0x94, 0x42, 0xa9, 0x33, 0x56, 0x68, 0x38, 0x49, 0x05, 0x72, 0x47, 0xb3, 0x08, 0x53, 0xfc, 0x45, + 0x82, 0x4b, 0x15, 0x6a, 0xd5, 0x50, 0x07, 0x19, 0x0c, 0xf7, 0x50, 0xd0, 0xc8, 0x3b, 0xde, 0x55, + 0x64, 0x1b, 0xa7, 0x4f, 0x77, 0x15, 0xce, 0xbb, 0xc8, 0x20, 0x3d, 0xe4, 0x22, 0xb3, 0x21, 0x8e, + 0x7a, 0x2a, 0x2e, 0x0f, 0x6d, 0x2e, 0xdc, 0x7a, 0xe0, 0x1d, 0xdb, 0xb5, 0xf6, 0x70, 0xe0, 0xd7, + 0xe0, 0xea, 0xff, 0xc5, 0x16, 0x26, 0xf1, 0xb3, 0x04, 0xb3, 0x15, 0x6a, 0xed, 0x3a, 0xa6, 0xce, + 0x50, 0x95, 0xbf, 0x48, 0xe5, 0x0d, 0x98, 0xd2, 0xf7, 0x59, 0x8b, 0xb8, 0x98, 0x0d, 0xde, 0x7a, + 0x3f, 0x46, 0x50, 0xf9, 0x1e, 0xa4, 0xfd, 0x37, 0xad, 0xb8, 0x21, 0x2f, 0x27, 0xdd, 0x90, 0x1c, + 0x54, 0x9e, 0x78, 0x7e, 0x58, 0x18, 0xd3, 0x84, 0xc9, 0xe6, 0x8c, 0x17, 0x7d, 0x44, 0x56, 0x5c, + 0xe4, 0x2f, 0x9a, 0x78, 0x5c, 0x41, 0xcc, 0xeb, 0x7f, 0xa5, 0x21, 0x55, 0xa1, 0x96, 0xfc, 0x83, + 0x04, 0x0b, 0x09, 0x6f, 0xd7, 0x5b, 0x09, 0xae, 0x13, 0x9f, 0x52, 0xca, 0xa7, 0x27, 0xb5, 0x08, + 0xc2, 0x91, 0xbf, 0x83, 0xf9, 0x91, 0x0f, 0x2f, 0x35, 0x99, 0x71, 0x14, 0x5e, 0xd9, 0x38, 0x19, + 0x3e, 0xf4, 0xff, 0x2d, 0x9c, 0x1f, 0xf5, 0xce, 0x59, 0x7d, 0x5b, 0x42, 0x43, 0x70, 0xe5, 0xce, + 0x89, 0xe0, 0xa1, 0x73, 0x02, 0xb3, 0x47, 0x4f, 0xde, 0x1b, 0xc9, 0x4c, 0x47, 0xa0, 0xca, 0xda, + 0xb1, 0xa1, 0xa1, 0x43, 0x0c, 0xd9, 0xe1, 0x43, 0xe5, 0x7a, 0x32, 0xc7, 0x10, 0x50, 0x29, 0x1d, + 0x13, 0x18, 0xba, 0xfa, 0x51, 0x82, 0xc5, 0xe4, 0xe9, 0xbe, 0x9d, 0x4c, 0x97, 0x68, 0xa4, 0xdc, + 0x7b, 0x07, 0xa3, 0x30, 0x9e, 0x3d, 0x98, 0x1e, 0x9a, 0xd3, 0x6b, 0xc9, 0x64, 0x71, 0x9c, 0xa2, + 0x1e, 0x0f, 0x17, 0xf8, 0x51, 0x26, 0xbf, 0x7f, 0xf3, 0xf4, 0xa6, 0x54, 0x7e, 0xfc, 0xfc, 0x55, + 0x5e, 0x7a, 0xf1, 0x2a, 0x2f, 0xfd, 0xf9, 0x2a, 0x2f, 0xfd, 0xf4, 0x3a, 0x3f, 0xf6, 0xe2, 0x75, + 0x7e, 0xec, 0x8f, 0xd7, 0xf9, 0xb1, 0xaf, 0xdf, 0x7a, 0x67, 0xf6, 0xe3, 0x7f, 0x39, 0xf9, 0xb1, + 0xdb, 0x4c, 0xf3, 0xbf, 0x9c, 0xb7, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xdd, 0x49, 0xe6, + 0xb2, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1493,7 +1486,7 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x7a + dAtA[i] = 0x72 } if m.UnbondingSlashingTx != nil { { @@ -1505,24 +1498,24 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x72 + dAtA[i] = 0x6a } if m.UnbondingValue != 0 { i = encodeVarintTx(dAtA, i, uint64(m.UnbondingValue)) i-- - dAtA[i] = 0x68 + dAtA[i] = 0x60 } if len(m.UnbondingTx) > 0 { i -= len(m.UnbondingTx) copy(dAtA[i:], m.UnbondingTx) i = encodeVarintTx(dAtA, i, uint64(len(m.UnbondingTx))) i-- - dAtA[i] = 0x62 + dAtA[i] = 0x5a } if m.UnbondingTime != 0 { i = encodeVarintTx(dAtA, i, uint64(m.UnbondingTime)) i-- - dAtA[i] = 0x58 + dAtA[i] = 0x50 } if m.DelegatorSlashingSig != nil { { @@ -1534,7 +1527,7 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x52 + dAtA[i] = 0x4a } if m.SlashingTx != nil { { @@ -1546,7 +1539,7 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x4a + dAtA[i] = 0x42 } if m.StakingTx != nil { { @@ -1558,17 +1551,17 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x42 + dAtA[i] = 0x3a } if m.StakingValue != 0 { i = encodeVarintTx(dAtA, i, uint64(m.StakingValue)) i-- - dAtA[i] = 0x38 + dAtA[i] = 0x30 } if m.StakingTime != 0 { i = encodeVarintTx(dAtA, i, uint64(m.StakingTime)) i-- - dAtA[i] = 0x30 + dAtA[i] = 0x28 } if len(m.FpBtcPkList) > 0 { for iNdEx := len(m.FpBtcPkList) - 1; iNdEx >= 0; iNdEx-- { @@ -1581,7 +1574,7 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a + dAtA[i] = 0x22 } } if m.BtcPk != nil { @@ -1594,7 +1587,7 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x22 + dAtA[i] = 0x1a } if m.Pop != nil { { @@ -1606,24 +1599,12 @@ func (m *MsgCreateBTCDelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a - } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- dAtA[i] = 0x12 } - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + if len(m.StakerAddr) > 0 { + i -= len(m.StakerAddr) + copy(dAtA[i:], m.StakerAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.StakerAddr))) i-- dAtA[i] = 0xa } @@ -2050,14 +2031,10 @@ func (m *MsgCreateBTCDelegation) Size() (n int) { } var l int _ = l - l = len(m.Signer) + l = len(m.StakerAddr) if l > 0 { n += 1 + l + sovTx(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() - n += 1 + l + sovTx(uint64(l)) - } if m.Pop != nil { l = m.Pop.Size() n += 1 + l + sovTx(uint64(l)) @@ -2836,7 +2813,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field StakerAddr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2864,45 +2841,9 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = string(dAtA[iNdEx:postIndex]) + m.StakerAddr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pop", wireType) } @@ -2932,13 +2873,13 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Pop == nil { - m.Pop = &ProofOfPossession{} + m.Pop = &ProofOfPossessionBTC{} } if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 4: + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) } @@ -2973,7 +2914,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 5: + case 4: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkList", wireType) } @@ -3008,7 +2949,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StakingTime", wireType) } @@ -3027,7 +2968,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { break } } - case 7: + case 6: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field StakingValue", wireType) } @@ -3046,7 +2987,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { break } } - case 8: + case 7: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field StakingTx", wireType) } @@ -3082,7 +3023,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 9: + case 8: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field SlashingTx", wireType) } @@ -3117,7 +3058,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 10: + case 9: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DelegatorSlashingSig", wireType) } @@ -3152,7 +3093,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 11: + case 10: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTime", wireType) } @@ -3171,7 +3112,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { break } } - case 12: + case 11: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingTx", wireType) } @@ -3205,7 +3146,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { m.UnbondingTx = []byte{} } iNdEx = postIndex - case 13: + case 12: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingValue", wireType) } @@ -3224,7 +3165,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { break } } - case 14: + case 13: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field UnbondingSlashingTx", wireType) } @@ -3259,7 +3200,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 15: + case 14: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field DelegatorUnbondingSlashingSig", wireType) } From 4ca07923c3bd49b3c4d56143354a39c661ffe2ab Mon Sep 17 00:00:00 2001 From: Stan Zhang <32720167+jz448@users.noreply.github.com> Date: Fri, 21 Jun 2024 12:42:18 +0800 Subject: [PATCH 095/119] Fix a typo in x/zoneconcierge/README.md (#677) fixed a typo in x/zoneconcierge/README.md --- x/zoneconcierge/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/zoneconcierge/README.md b/x/zoneconcierge/README.md index e7040567b..d9dda333c 100644 --- a/x/zoneconcierge/README.md +++ b/x/zoneconcierge/README.md @@ -5,7 +5,7 @@ headers from other PoS blockchains. These BTC timestamps allow PoS blockchains integrating with Babylon to achieve Bitcoin security, i.e., forking the PoS blockchain is as hard as forking Bitcoin. The Zone Concierge module leverages the IBC protocol to receive PoS blockchains' headers and provide them with -succint and provable information about their timestamps. +succinct and provable information about their timestamps. There are two phases of integration for a PoS blockchain: From 3087e872145b83c340b4b119e9bd8f094859c775 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 25 Jun 2024 16:30:56 +0200 Subject: [PATCH 096/119] Tighten checks in CheckTransactions function (#680) * Tighten checks in CheckTransactions function * wrap errors --- btcstaking/staking.go | 20 +++++++++-- btcstaking/staking_test.go | 70 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/btcstaking/staking.go b/btcstaking/staking.go index 1fe4af286..d0c412f4a 100644 --- a/btcstaking/staking.go +++ b/btcstaking/staking.go @@ -6,6 +6,7 @@ import ( "fmt" sdkmath "cosmossdk.io/math" + "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" @@ -214,7 +215,7 @@ func IsSimpleTransfer(tx *wire.MsgTx) error { return nil } -// ValidateSlashingTx performs basic checks on a slashing transaction: +// validateSlashingTx performs basic checks on a slashing transaction: // - the slashing transaction is not nil. // - the slashing transaction has exactly one input. // - the slashing transaction is non-replaceable. @@ -225,7 +226,7 @@ func IsSimpleTransfer(tx *wire.MsgTx) error { // - neither of the outputs are considered dust. // // - the min fee for slashing tx is preserved -func ValidateSlashingTx( +func validateSlashingTx( slashingTx *wire.MsgTx, slashingAddress btcutil.Address, slashingRate sdkmath.LegacyDec, @@ -329,6 +330,7 @@ func ValidateSlashingTx( } // CheckTransactions validates all relevant data of slashing and funding transaction. +// - both transactions are valid from pov of BTC rules // - funding transaction has output committing to the provided script // - slashing transaction is valid // - slashing transaction input hash is pointing to funding transaction hash @@ -344,6 +346,18 @@ func CheckTransactions( slashingChangeLockTime uint16, net *chaincfg.Params, ) error { + if slashingTx == nil || fundingTransaction == nil { + return fmt.Errorf("slashing and funding transactions must not be nil") + } + + if err := blockchain.CheckTransactionSanity(btcutil.NewTx(slashingTx)); err != nil { + return fmt.Errorf("slashing transaction does not obey BTC rules: %w", err) + } + + if err := blockchain.CheckTransactionSanity(btcutil.NewTx(fundingTransaction)); err != nil { + return fmt.Errorf("funding transaction does not obey BTC rules: %w", err) + } + // Check if slashing tx min fee is valid if slashingTxMinFee <= 0 { return fmt.Errorf("slashing transaction min fee must be larger than 0") @@ -360,7 +374,7 @@ func CheckTransactions( stakingOutput := fundingTransaction.TxOut[fundingOutputIdx] // 3. Check if slashing transaction is valid - if err := ValidateSlashingTx( + if err := validateSlashingTx( slashingTx, slashingAddress, slashingRate, diff --git a/btcstaking/staking_test.go b/btcstaking/staking_test.go index 2937157fd..abbb8dbee 100644 --- a/btcstaking/staking_test.go +++ b/btcstaking/staking_test.go @@ -5,6 +5,7 @@ import ( "math" "math/rand" "testing" + "time" sdkmath "cosmossdk.io/math" "github.com/babylonchain/babylon/btcstaking" @@ -66,6 +67,12 @@ func FuzzGeneratingValidStakingSlashingTx(f *testing.F) { r := rand.New(rand.NewSource(seed)) // we do not care for inputs in staking tx stakingTx := wire.NewMsgTx(2) + bogusInputHashBytes := [32]byte{} + bogusInputHash, _ := chainhash.NewHash(bogusInputHashBytes[:]) + stakingTx.AddTxIn( + wire.NewTxIn(wire.NewOutPoint(bogusInputHash, 0), nil, nil), + ) + stakingOutputIdx := r.Intn(5) // always more outputs than stakingOutputIdx stakingTxNumOutputs := r.Intn(5) + 10 @@ -240,3 +247,66 @@ func FuzzGeneratingSignatureValidation(f *testing.F) { require.NoError(t, err) }) } + +func TestSlashingTxWithOverflowMustNotAccepted(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + // we do not care for inputs in staking tx + stakingTx := wire.NewMsgTx(2) + slashingLockTime := uint16(100) + minStakingValue := 10000 + minFee := 2000 + slashingRate := sdkmath.LegacyNewDecWithPrec(1000, 4) + sd := genValidStakingScriptData(t, r) + + info, err := btcstaking.BuildStakingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.FinalityProviderKey}, + []*btcec.PublicKey{sd.CovenantKey}, + 1, + sd.StakingTime, + btcutil.Amount(r.Intn(5000)+minStakingValue), + &chaincfg.MainNetParams, + ) + + require.NoError(t, err) + stakingTx.AddTxOut(info.StakingOutput) + bogusInputHashBytes := [32]byte{} + bogusInputHash, _ := chainhash.NewHash(bogusInputHashBytes[:]) + stakingTx.AddTxIn( + wire.NewTxIn(wire.NewOutPoint(bogusInputHash, 0), nil, nil), + ) + + slashingAddress, err := genRandomBTCAddress(r) + require.NoError(t, err) + + // Construct slashing transaction using the provided parameters + slashingTx, err := btcstaking.BuildSlashingTxFromStakingTxStrict( + stakingTx, + uint32(0), + slashingAddress, + sd.StakerKey, + slashingLockTime, + int64(minFee), + slashingRate, + &chaincfg.MainNetParams, + ) + require.NoError(t, err) + require.NotNil(t, slashingTx) + + slashingTx.TxOut[0].Value = math.MaxInt64 / 8 + slashingTx.TxOut[1].Value = math.MaxInt64 / 8 + + err = btcstaking.CheckTransactions( + slashingTx, + stakingTx, + uint32(0), + int64(minFee), + slashingRate, + slashingAddress, + sd.StakerKey, + slashingLockTime, + &chaincfg.MainNetParams, + ) + require.Error(t, err) + require.EqualError(t, err, "slashing transaction does not obey BTC rules: transaction output value of 1152921504606846975 is higher than max allowed value of 2.1e+15") +} From cd4c81b860bf2fbee2305a100c3eabe8508eb780 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 26 Jun 2024 12:15:08 +0200 Subject: [PATCH 097/119] Enforce that keys are unique in scripts (#679) * Enforce that keys are unique in scripts --- btcstaking/scripts_utils.go | 13 ++--- btcstaking/staking_test.go | 97 +++++++++++++++++++++++++++++++++++++ btcstaking/types.go | 57 +++++++++++++++++++--- docs/staking-script.md | 23 ++++++--- 4 files changed, 167 insertions(+), 23 deletions(-) diff --git a/btcstaking/scripts_utils.go b/btcstaking/scripts_utils.go index a21669fbc..1c815c1d2 100644 --- a/btcstaking/scripts_utils.go +++ b/btcstaking/scripts_utils.go @@ -55,9 +55,9 @@ func SortKeys(keys []*btcec.PublicKey) []*btcec.PublicKey { // prepareKeys prepares keys to be used in multisig script // Validates: -// - whether there are at lest 2 keys -// - whether there are no duplicate keys +// - whether there are at least 2 keys // returns copy of the slice of keys sorted lexicographically +// Note: It is up to the caller to ensure that the keys are unique func prepareKeysForMultisigScript(keys []*btcec.PublicKey) ([]*btcec.PublicKey, error) { if len(keys) < 2 { return nil, fmt.Errorf("cannot create multisig script with less than 2 keys") @@ -65,19 +65,14 @@ func prepareKeysForMultisigScript(keys []*btcec.PublicKey) ([]*btcec.PublicKey, sortedKeys := SortKeys(keys) - for i := 0; i < len(sortedKeys)-1; i++ { - if bytes.Equal(schnorr.SerializePubKey(sortedKeys[i]), schnorr.SerializePubKey(sortedKeys[i+1])) { - return nil, fmt.Errorf("duplicate key in list of keys") - } - } - return sortedKeys, nil } // buildMultiSigScript creates multisig script with given keys and signer threshold to // successfully execute script -// it validates whether provided keys are unique and the threshold is not greater than number of keys +// it validates whether threshold is not greater than number of keys // If there is only one key provided it will return single key sig script +// Note: It is up to the caller to ensure that the keys are unique func buildMultiSigScript( keys []*btcec.PublicKey, threshold uint32, diff --git a/btcstaking/staking_test.go b/btcstaking/staking_test.go index abbb8dbee..735ba99db 100644 --- a/btcstaking/staking_test.go +++ b/btcstaking/staking_test.go @@ -1,6 +1,7 @@ package btcstaking_test import ( + "errors" "fmt" "math" "math/rand" @@ -310,3 +311,99 @@ func TestSlashingTxWithOverflowMustNotAccepted(t *testing.T) { require.Error(t, err) require.EqualError(t, err, "slashing transaction does not obey BTC rules: transaction output value of 1152921504606846975 is higher than max allowed value of 2.1e+15") } + +func TestNotAllowStakerKeyToBeFinalityProviderKey(t *testing.T) { + r := rand.New(rand.NewSource(0)) + sd := genValidStakingScriptData(t, r) + + // Construct staking transaction using the provided parameters + stakingTx, err := btcstaking.BuildStakingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.StakerKey}, + []*btcec.PublicKey{sd.CovenantKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, stakingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) + + unbondingTx, err := btcstaking.BuildUnbondingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.StakerKey}, + []*btcec.PublicKey{sd.CovenantKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, unbondingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) +} + +func TestNotAllowStakerKeyToBeCovenantKey(t *testing.T) { + r := rand.New(rand.NewSource(0)) + sd := genValidStakingScriptData(t, r) + + // Construct staking transaction using the provided parameters + stakingTx, err := btcstaking.BuildStakingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.FinalityProviderKey}, + []*btcec.PublicKey{sd.StakerKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, stakingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) + + unbondingTx, err := btcstaking.BuildUnbondingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.FinalityProviderKey}, + []*btcec.PublicKey{sd.StakerKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, unbondingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) +} + +func TestNotAllowFinalityProviderKeysAsCovenantKeys(t *testing.T) { + r := rand.New(rand.NewSource(0)) + sd := genValidStakingScriptData(t, r) + + // Construct staking transaction using the provided parameters + stakingTx, err := btcstaking.BuildStakingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.FinalityProviderKey}, + []*btcec.PublicKey{sd.FinalityProviderKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, stakingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) + + unbondingTx, err := btcstaking.BuildUnbondingInfo( + sd.StakerKey, + []*btcec.PublicKey{sd.FinalityProviderKey}, + []*btcec.PublicKey{sd.FinalityProviderKey}, + 1, + sd.StakingTime, + btcutil.Amount(10000), + &chaincfg.MainNetParams, + ) + require.Nil(t, unbondingTx) + require.Error(t, err) + require.True(t, errors.Is(err, btcstaking.ErrDuplicatedKeyInScript)) +} diff --git a/btcstaking/types.go b/btcstaking/types.go index 331502a09..77d6bf0ef 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -24,7 +24,10 @@ const ( ) var ( - unspendableKeyPathKey = unspendableKeyPathInternalPubKeyInternal(unspendableKeyPath) + unspendableKeyPathKey = unspendableKeyPathInternalPubKeyInternal(unspendableKeyPath) + errBuildingStakingInfo = fmt.Errorf("error building staking info") + errBuildingUnbondingInfo = fmt.Errorf("error building unbonding info") + ErrDuplicatedKeyInScript = fmt.Errorf("duplicated key in script") ) func unspendableKeyPathInternalPubKeyInternal(keyHex string) btcec.PublicKey { @@ -267,6 +270,42 @@ type babylonScriptPaths struct { slashingPathScript []byte } +func keyToString(key *btcec.PublicKey) string { + return hex.EncodeToString(schnorr.SerializePubKey(key)) +} + +func checkForDuplicateKeys( + stakerKey *btcec.PublicKey, + fpKeys []*btcec.PublicKey, + covenantKeys []*btcec.PublicKey, +) error { + keyMap := make(map[string]struct{}) + + keyMap[keyToString(stakerKey)] = struct{}{} + + for _, key := range fpKeys { + keyStr := keyToString(key) + + if _, ok := keyMap[keyStr]; ok { + return fmt.Errorf("key: %s: %w", keyStr, ErrDuplicatedKeyInScript) + } + + keyMap[keyStr] = struct{}{} + } + + for _, key := range covenantKeys { + keyStr := keyToString(key) + + if _, ok := keyMap[keyStr]; ok { + return fmt.Errorf("key: %s: %w", keyStr, ErrDuplicatedKeyInScript) + } + + keyMap[keyStr] = struct{}{} + } + + return nil +} + func newBabylonScriptPaths( stakerKey *btcec.PublicKey, fpKeys []*btcec.PublicKey, @@ -278,6 +317,10 @@ func newBabylonScriptPaths( return nil, fmt.Errorf("staker key is nil") } + if err := checkForDuplicateKeys(stakerKey, fpKeys, covenantKeys); err != nil { + return nil, fmt.Errorf("error building scripts: %w", err) + } + timeLockPathScript, err := buildTimeLockScript(stakerKey, lockTime) if err != nil { @@ -353,7 +396,7 @@ func BuildStakingInfo( ) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingStakingInfo, err) } var unbondingPaths [][]byte @@ -371,13 +414,13 @@ func BuildStakingInfo( ) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingStakingInfo, err) } taprootPkScript, err := sh.taprootPkScript(net) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingStakingInfo, err) } stakingOutput := wire.NewTxOut(int64(stakingAmount), taprootPkScript) @@ -433,7 +476,7 @@ func BuildUnbondingInfo( ) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingUnbondingInfo, err) } var unbondingPaths [][]byte @@ -449,13 +492,13 @@ func BuildUnbondingInfo( ) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingUnbondingInfo, err) } taprootPkScript, err := sh.taprootPkScript(net) if err != nil { - return nil, err + return nil, fmt.Errorf("%s: %w", errBuildingUnbondingInfo, err) } unbondingOutput := wire.NewTxOut(int64(unbondingAmount), taprootPkScript) diff --git a/docs/staking-script.md b/docs/staking-script.md index c2cf564bf..9957bffb0 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -149,6 +149,15 @@ The requirements for a valid slashing transaction are: ## Staking and Unbonding output scripts +In the below scripts, there are three entities, each represented by BTC public +key: + +- `StakerPK` - BTC staker public key +- `FinalityProviderPk` - finality provider public key +- `CovenantPk1..CovenantPkN` - public keys of covenant committee members +There must be no duplicated public keys in created scripts. +For example, `StakerPK` must never be equal to `FinalityProviderPk` + ### Staking output The staking output is a taproot output which can only be spent through a script @@ -173,13 +182,13 @@ The timelock path locks the staker's Bitcoin for a pre-determined number of Bitcoin blocks. It commits to a script of the form: ``` - OP_CHECKSIGVERIFY OP_CHECKSEQUENCEVERIFY + OP_CHECKSIGVERIFY OP_CHECKSEQUENCEVERIFY ``` where: -- `` is the BTC staker's public key.. -- `` is the lockup period denoted in Bitcoin blocks. The +- `` is the BTC staker's public key.. +- `` is the lockup period denoted in Bitcoin blocks. The timelock comes into effect after the Bitcoin transaction has been included in a mined block. In essence, the script denotes that only the staker can unlock the funds after the timelock has passed. It must be lower than `65535`. @@ -197,7 +206,7 @@ before the timelock expires. It commits to a script of the form: where: -- `Staker_PK` is the BTC staker's public key +- `StakerPK` is the BTC staker's public key - `CovenantPk1..CovenantPkN` are the lexicographically sorted public keys of the current covenant committee recognized by the Babylon chain - `CovenantThreshold` is a Babylon parameter specifying the number of how many @@ -275,13 +284,13 @@ The timelock path locks the staker's Bitcoin for a pre-determined number of Bitcoin blocks. It commits to a script of the form: ``` - OP_CHECKSIGVERIFY OP_CHECKSEQUENCEVERIFY` + OP_CHECKSIGVERIFY OP_CHECKSEQUENCEVERIFY` ``` where: -- Staker_PK is btc staker public key -- Timelock_Blocks is unbonding time. It must be lower or equal 65535, but larger +- `` is btc staker public key +- `` is unbonding time. It must be lower or equal 65535, but larger than `max(MinUnbondingTime, CheckpointFinalizationTimeout)`. `MinUnbondingTime` and `CheckpointFinalizationTimeout` are Babylon parameters. From 9149d8a0987f2dc3c21ff29fb87cdcfc4563fcf4 Mon Sep 17 00:00:00 2001 From: Rafael Tenfen Date: Mon, 1 Jul 2024 10:10:10 -0300 Subject: [PATCH 098/119] chore: FP as signer addr (#678) * chore: set signer addr as finality provider * chore: proto gen fp signer changes * chore: update to use fp addr as signer * fix: unit test check * fix: lint, removed unused import * chore: remove unused PoP * chore: removed unused func * chore: add test for valid basic * chore: update description of PoP * chore: update to use fp addr instead of deriving from bbn SK * chore: update order of addr in finality provider * chore: update readme about btcstaking protos * chore: add send msg with signer to use in testings --- client/client/tx.go | 354 ++++++++++++++++++ proto/babylon/btcstaking/v1/btcstaking.proto | 14 +- proto/babylon/btcstaking/v1/incentive.proto | 5 +- proto/babylon/btcstaking/v1/pop.proto | 13 - proto/babylon/btcstaking/v1/query.proto | 10 +- proto/babylon/btcstaking/v1/tx.proto | 26 +- test/e2e/btc_staking_e2e_test.go | 16 +- .../configurer/chain/commands_btcstaking.go | 14 +- testutil/datagen/btcstaking.go | 20 +- testutil/helper/helper.go | 4 + x/btcstaking/README.md | 263 +++++++------ x/btcstaking/client/cli/tx.go | 24 +- x/btcstaking/keeper/bench_test.go | 3 +- x/btcstaking/keeper/genesis_test.go | 3 +- x/btcstaking/keeper/grpc_query_test.go | 2 +- x/btcstaking/keeper/incentive_test.go | 4 +- x/btcstaking/keeper/keeper_test.go | 5 +- x/btcstaking/keeper/msg_server.go | 19 +- x/btcstaking/keeper/msg_server_test.go | 14 +- x/btcstaking/types/btcstaking.go | 7 +- x/btcstaking/types/btcstaking.pb.go | 266 +++++++------ x/btcstaking/types/incentive.go | 4 +- x/btcstaking/types/incentive.pb.go | 114 +++--- x/btcstaking/types/msg.go | 13 +- x/btcstaking/types/msg_test.go | 181 +++++++++ x/btcstaking/types/pop.go | 221 +---------- x/btcstaking/types/pop.pb.go | 311 ++------------- x/btcstaking/types/pop_test.go | 84 ++--- x/btcstaking/types/query.go | 2 +- x/btcstaking/types/query.pb.go | 294 +++++++-------- x/btcstaking/types/tx.pb.go | 283 ++++++-------- 31 files changed, 1232 insertions(+), 1361 deletions(-) create mode 100644 x/btcstaking/types/msg_test.go diff --git a/client/client/tx.go b/client/client/tx.go index 52d5244f2..4bf35f9d7 100644 --- a/client/client/tx.go +++ b/client/client/tx.go @@ -5,11 +5,22 @@ import ( "fmt" "sync" + signingv1beta1 "cosmossdk.io/api/cosmos/tx/signing/v1beta1" "cosmossdk.io/errors" + txsigning "cosmossdk.io/x/tx/signing" "github.com/avast/retry-go/v4" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + abci "github.com/cometbft/cometbft/abci/types" + coretypes "github.com/cometbft/cometbft/rpc/core/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" + txtypes "github.com/cosmos/cosmos-sdk/types/tx" + "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/relayer/v2/relayer/chains/cosmos" pv "github.com/cosmos/relayer/v2/relayer/provider" "go.uber.org/zap" @@ -134,6 +145,343 @@ func (c *Client) ReliablySendMsgs(ctx context.Context, msgs []sdk.Msg, expectedE return rlyResp, nil } +// ReliablySendMsgsWithSigner reliably sends a list of messages to the chain. +// It utilizes the signer private key to sign all msgs +func (c *Client) ReliablySendMsgsWithSigner(ctx context.Context, signerAddr sdk.AccAddress, signerPvKey *secp256k1.PrivKey, msgs []sdk.Msg, expectedErrors []*errors.Error, unrecoverableErrors []*errors.Error) (*pv.RelayerTxResponse, error) { + var ( + rlyResp *pv.RelayerTxResponse + callbackErr error + wg sync.WaitGroup + ) + wg.Add(1) + + // convert message type + relayerMsgs := ToProviderMsgs(msgs) + + // TODO: consider using Babylon's retry package + if err := retry.Do(func() error { + _, sendMsgErr := c.SendMessageWithSigner(ctx, signerAddr, signerPvKey, relayerMsgs) + if sendMsgErr != nil { + if errorContained(sendMsgErr, unrecoverableErrors) { + c.logger.Error("unrecoverable err when submitting the tx, skip retrying", zap.Error(sendMsgErr)) + return retry.Unrecoverable(sendMsgErr) + } + if errorContained(sendMsgErr, expectedErrors) { + // this is necessary because if err is returned + // the callback function will not be executed so + // that the inside wg.Done will not be executed + wg.Done() + c.logger.Error("expected err when submitting the tx, skip retrying", zap.Error(sendMsgErr)) + return nil + } + return sendMsgErr + } + wg.Done() + return nil + }, retry.Context(ctx), rtyAtt, rtyDel, rtyErr, retry.OnRetry(func(n uint, err error) { + c.logger.Debug("retrying", zap.Uint("attemp", n+1), zap.Uint("max_attempts", rtyAttNum), zap.Error(err)) + })); err != nil { + return nil, err + } + + wg.Wait() + + if callbackErr != nil { + if errorContained(callbackErr, expectedErrors) { + return nil, nil + } + return nil, callbackErr + } + + if rlyResp == nil { + // this case could happen if the error within the retry is an expected error + return nil, nil + } + + if rlyResp.Code != 0 { + return rlyResp, fmt.Errorf("transaction failed with code: %d", rlyResp.Code) + } + + return rlyResp, nil +} + +func (c *Client) SendMessageWithSigner( + ctx context.Context, + signerAddr sdk.AccAddress, + signerPvKey *secp256k1.PrivKey, + relayerMsgs []pv.RelayerMessage, +) (result *coretypes.ResultBroadcastTx, err error) { + cMsgs := cosmos.CosmosMsgs(relayerMsgs...) + var ( + num, seq uint64 + ) + + cc := c.provider + cliCtx := client.Context{}.WithClient(cc.RPCClient). + WithInterfaceRegistry(cc.Cdc.InterfaceRegistry). + WithChainID(cc.PCfg.ChainID). + WithCodec(cc.Cdc.Marshaler). + WithFromAddress(signerAddr) + + txf := cc.TxFactory() + if err := retry.Do(func() error { + if err := txf.AccountRetriever().EnsureExists(cliCtx, signerAddr); err != nil { + return err + } + return err + }, rtyAtt, rtyDel, rtyErr); err != nil { + return nil, err + } + + initNum, initSeq := txf.AccountNumber(), txf.Sequence() + if initNum == 0 || initSeq == 0 { + if err := retry.Do(func() error { + num, seq, err = txf.AccountRetriever().GetAccountNumberSequence(cliCtx, signerAddr) + if err != nil { + return err + } + return err + }, rtyAtt, rtyDel, rtyErr); err != nil { + return nil, err + } + + if initNum == 0 { + txf = txf.WithAccountNumber(num) + } + + if initSeq == 0 { + txf = txf.WithSequence(seq) + } + } + + if cc.PCfg.MinGasAmount != 0 { + txf = txf.WithGas(cc.PCfg.MinGasAmount) + } + + if cc.PCfg.MaxGasAmount != 0 { + txf = txf.WithGas(cc.PCfg.MaxGasAmount) + } + txf, err = cc.SetWithExtensionOptions(txf) + if err != nil { + return nil, err + } + + //txf ready + _, adjusted, err := c.CalculateGas(ctx, txf, signerPvKey.PubKey(), cMsgs...) + if err != nil { + return nil, err + } + + // Set the gas amount on the transaction factory + txf = txf.WithGas(adjusted) + + // Build the transaction builder + txb, err := txf.BuildUnsignedTx(cMsgs...) + if err != nil { + return nil, err + } + + // Attach the signature to the transaction + // c.LogFailedTx(nil, err, msgs) + // Force encoding in the chain specific address + for _, msg := range cMsgs { + cc.Cdc.Marshaler.MustMarshalJSON(msg) + } + if err := Sign(ctx, txf, signerPvKey, txb, cc.Cdc.TxConfig.SignModeHandler(), false); err != nil { + return nil, err + } + + tx := txb.GetTx() + + // Generate the transaction bytes + txBytes, err := cc.Cdc.TxConfig.TxEncoder()(tx) + if err != nil { + return nil, err + } + + return cc.RPCClient.BroadcastTxSync(ctx, txBytes) +} + +// BuildSimTx creates an unsigned tx with an empty single signature and returns +// the encoded transaction or an error if the unsigned transaction cannot be built. +func BuildSimTx(pk cryptotypes.PubKey, txf tx.Factory, msgs ...sdk.Msg) ([]byte, error) { + txb, err := txf.BuildUnsignedTx(msgs...) + if err != nil { + return nil, err + } + + // Create an empty signature literal as the ante handler will populate with a + // sentinel pubkey. + sig := signing.SignatureV2{ + PubKey: pk, + Data: &signing.SingleSignatureData{ + SignMode: txf.SignMode(), + }, + Sequence: txf.Sequence(), + } + if err := txb.SetSignatures(sig); err != nil { + return nil, err + } + + protoProvider, ok := txb.(protoTxProvider) + if !ok { + return nil, fmt.Errorf("cannot simulate amino tx") + } + + simReq := txtypes.SimulateRequest{Tx: protoProvider.GetProtoTx()} + return simReq.Marshal() +} + +// CalculateGas simulates a tx to generate the appropriate gas settings before broadcasting a tx. +func (c *Client) CalculateGas(ctx context.Context, txf tx.Factory, signingPK cryptotypes.PubKey, msgs ...sdk.Msg) (txtypes.SimulateResponse, uint64, error) { + cc := c.provider + + var txBytes []byte + if err := retry.Do(func() error { + var err error + txBytes, err = BuildSimTx(signingPK, txf, msgs...) + if err != nil { + return err + } + return nil + }, retry.Context(ctx), rtyAtt, rtyDel, rtyErr); err != nil { + return txtypes.SimulateResponse{}, 0, err + } + + simQuery := abci.RequestQuery{ + Path: "/cosmos.tx.v1beta1.Service/Simulate", + Data: txBytes, + } + + var res abci.ResponseQuery + if err := retry.Do(func() error { + var err error + res, err = cc.QueryABCI(ctx, simQuery) + if err != nil { + return err + } + return nil + }, retry.Context(ctx), rtyAtt, rtyDel, rtyErr); err != nil { + return txtypes.SimulateResponse{}, 0, err + } + + var simRes txtypes.SimulateResponse + if err := simRes.Unmarshal(res.Value); err != nil { + return txtypes.SimulateResponse{}, 0, err + } + + gas, err := cc.AdjustEstimatedGas(simRes.GasInfo.GasUsed) + return simRes, gas, err +} + +// Sign signs a given tx with the private key. The bytes signed over are canconical. +// The resulting signature will be added to the transaction builder overwriting the previous +// ones if overwrite=true (otherwise, the signature will be appended). +// Signing a transaction with mutltiple signers in the DIRECT mode is not supprted and will +// return an error. +// An error is returned upon failure. +func Sign( + ctx context.Context, + txf tx.Factory, + signerPvKey *secp256k1.PrivKey, + txBuilder client.TxBuilder, + handlerMap *txsigning.HandlerMap, + overwriteSig bool, +) error { + var err error + signMode := txf.SignMode() + if signMode == signing.SignMode_SIGN_MODE_UNSPECIFIED { + // use the SignModeHandler's default mode if unspecified + signMode, err = authsigning.APISignModeToInternal(signingv1beta1.SignMode_SIGN_MODE_DIRECT_AUX) + if err != nil { + return err + } + } + + pubKey := signerPvKey.PubKey() + + signerData := authsigning.SignerData{ + ChainID: txf.ChainID(), + AccountNumber: txf.AccountNumber(), + Sequence: txf.Sequence(), + PubKey: pubKey, + Address: sdk.AccAddress(pubKey.Address()).String(), + } + + // For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on + // TxBuilder under the hood, and SignerInfos is needed to generated the + // sign bytes. This is the reason for setting SetSignatures here, with a + // nil signature. + // + // Note: this line is not needed for SIGN_MODE_LEGACY_AMINO, but putting it + // also doesn't affect its generated sign bytes, so for code's simplicity + // sake, we put it here. + sigData := signing.SingleSignatureData{ + SignMode: signMode, + Signature: nil, + } + sig := signing.SignatureV2{ + PubKey: pubKey, + Data: &sigData, + Sequence: txf.Sequence(), + } + + var prevSignatures []signing.SignatureV2 + if !overwriteSig { + prevSignatures, err = txBuilder.GetTx().GetSignaturesV2() + if err != nil { + return err + } + } + // Overwrite or append signer infos. + var sigs []signing.SignatureV2 + if overwriteSig { + sigs = []signing.SignatureV2{sig} + } else { + sigs = append(sigs, prevSignatures...) + sigs = append(sigs, sig) + } + if err := txBuilder.SetSignatures(sigs...); err != nil { + return err + } + + bytesToSign, err := authsigning.GetSignBytesAdapter(ctx, handlerMap, signMode, signerData, txBuilder.GetTx()) + if err != nil { + return err + } + + sigBytes, err := signerPvKey.Sign(bytesToSign) + if err != nil { + return err + } + + // Construct the SignatureV2 struct + sigData = signing.SingleSignatureData{ + SignMode: signMode, + Signature: sigBytes, + } + sig = signing.SignatureV2{ + PubKey: pubKey, + Data: &sigData, + Sequence: txf.Sequence(), + } + + if overwriteSig { + err = txBuilder.SetSignatures(sig) + } else { + prevSignatures = append(prevSignatures, sig) + err = txBuilder.SetSignatures(prevSignatures...) + } + + if err != nil { + return fmt.Errorf("unable to set signatures on payload: %w", err) + } + + // Run optional preprocessing if specified. By default, this is unset + // and will return nil. + return nil +} + // We do not expose ctx in our client calls, which means: // - we do not support cancellation of submitting messages // - the only timeout is the block inclusion timeout i.e block-timeout @@ -146,6 +494,12 @@ func (c *Client) InsertHeaders(ctx context.Context, msg *btclctypes.MsgInsertHea return c.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{}) } +// protoTxProvider is a type which can provide a proto transaction. It is a +// workaround to get access to the wrapper TxBuilder's method GetProtoTx(). +type protoTxProvider interface { + GetProtoTx() *txtypes.Tx +} + // TODO: implement necessary message invocations here // - MsgInconsistencyEvidence // - MsgStallingEvidence diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index d1b70ef5a..04757d74b 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -3,7 +3,6 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -import "cosmos/crypto/secp256k1/keys.proto"; import "cosmos/staking/v1beta1/staking.proto"; import "babylon/btcstaking/v1/pop.proto"; @@ -11,20 +10,21 @@ option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; // FinalityProvider defines a finality provider message FinalityProvider { + // addr is the bech32 address identifier of the finality provider. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // description defines the description terms for the finality provider. - cosmos.staking.v1beta1.Description description = 1; + cosmos.staking.v1beta1.Description description = 2; // commission defines the commission rate of the finality provider. - string commission = 2 [ + string commission = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 3; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 5; + // pop is the proof of possession of the btc_pk, where the BTC + // private key signs the bech32 bbn addr of the finality provider. + ProofOfPossessionBTC pop = 5; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index 314d5db1b..8072a5d44 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -3,7 +3,6 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -import "cosmos/crypto/secp256k1/keys.proto"; option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; @@ -20,8 +19,8 @@ message FinalityProviderDistInfo { // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // babylon_pk is the Babylon public key of the finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 2; + // addr is the address to receive commission from delegations. + string addr = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // commission defines the commission rate of finality provider string commission = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", diff --git a/proto/babylon/btcstaking/v1/pop.proto b/proto/babylon/btcstaking/v1/pop.proto index 1856941d2..4762d3c12 100644 --- a/proto/babylon/btcstaking/v1/pop.proto +++ b/proto/babylon/btcstaking/v1/pop.proto @@ -14,19 +14,6 @@ enum BTCSigType { ECDSA = 2; } -// ProofOfPossession is the proof of possession that a Babylon secp256k1 -// secret key and a Bitcoin secp256k1 secret key are held by the same -// person -message ProofOfPossession { - // btc_sig_type indicates the type of btc_sig in the pop - BTCSigType btc_sig_type = 1; - // babylon_sig is the signature generated via sign(sk_babylon, pk_btc) - bytes babylon_sig = 2; - // btc_sig is the signature generated via sign(sk_btc, babylon_sig) - // the signature follows encoding in either BIP-340 spec or BIP-322 spec - bytes btc_sig = 3; -} - // ProofOfPossessionBTC is the proof of possession that a Babylon // address and a Bitcoin secp256k1 secret key are held by the same // person diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 995984eba..91e3052ad 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -4,7 +4,6 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; import "cosmos_proto/cosmos.proto"; -import "cosmos/crypto/secp256k1/keys.proto"; import "cosmos/staking/v1beta1/staking.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btcstaking/v1/params.proto"; @@ -330,13 +329,14 @@ message FinalityProviderResponse { (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 3; + // addr is the address to receive commission from delegations. + string addr = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 5; + // pop is the proof of possession of the BTC_PK by the fp addr. + // Essentially is the signature where the BTC SK sigs the fp addr. + ProofOfPossessionBTC pop = 5; // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index dcec9bc1a..e2cdcbf6b 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -4,7 +4,6 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/msg/v1/msg.proto"; -import "cosmos/crypto/secp256k1/keys.proto"; import "babylon/btcstaking/v1/params.proto"; import "babylon/btccheckpoint/v1/btccheckpoint.proto"; import "cosmos/staking/v1beta1/staking.proto"; @@ -36,10 +35,10 @@ service Msg { // MsgCreateFinalityProvider is the message for creating a finality provider message MsgCreateFinalityProvider { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - + option (cosmos.msg.v1.signer) = "addr"; + // addr defines the address of the finality provider that will receive + // the commissions to all the delegations. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // description defines the description terms for the finality provider cosmos.staking.v1beta1.Description description = 2; // commission defines the commission rate of the finality provider @@ -47,26 +46,23 @@ message MsgCreateFinalityProvider { (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 4; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 6; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of btc_pk over the FP signer address. + ProofOfPossessionBTC pop = 5; } + // MsgCreateFinalityProviderResponse is the response for MsgCreateFinalityProvider message MsgCreateFinalityProviderResponse {} // MsgEditFinalityProvider is the message for editing an existing finality provider message MsgEditFinalityProvider { - option (cosmos.msg.v1.signer) = "signer"; - - // NOTE: this signer needs to correspond to babylon_pk of the finality provider - string signer = 1; + option (cosmos.msg.v1.signer) = "addr"; + // addr the address of the finality provider that whishes to edit his information. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited bytes btc_pk = 2; - // description defines the updated description terms for the finality provider cosmos.staking.v1beta1.Description description = 3; // commission defines the updated commission rate of the finality provider diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 9ff521a0c..538c58c01 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -80,7 +80,7 @@ func (s *BTCStakingTestSuite) Test1CreateFinalityProviderAndDelegation() { nonValidatorNode, err := chainA.GetNodeAtIndex(2) s.NoError(err) - cacheFP = s.CreateRandomFP(nonValidatorNode) + cacheFP = s.CreateNodeFP(nonValidatorNode) /* create a random BTC delegation under this finality provider @@ -838,18 +838,22 @@ func ParseRespBTCDelToBTCDel(resp *bstypes.BTCDelegationResponse) (btcDel *bstyp func (s *BTCStakingTestSuite) equalFinalityProviderResp(fp *bstypes.FinalityProvider, fpResp *bstypes.FinalityProviderResponse) { s.Equal(fp.Description, fpResp.Description) s.Equal(fp.Commission, fpResp.Commission) - s.Equal(fp.BabylonPk, fpResp.BabylonPk) + s.Equal(fp.Addr, fpResp.Addr) s.Equal(fp.BtcPk, fpResp.BtcPk) s.Equal(fp.Pop, fpResp.Pop) s.Equal(fp.SlashedBabylonHeight, fpResp.SlashedBabylonHeight) s.Equal(fp.SlashedBtcHeight, fpResp.SlashedBtcHeight) } -// CreateRandomFP creates a random finality provider. -func (s *BTCStakingTestSuite) CreateRandomFP(node *chain.NodeConfig) (newFP *bstypes.FinalityProvider) { - newFP, err := datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, node.SecretKey) +// CreateNodeFP creates a random finality provider. +func (s *BTCStakingTestSuite) CreateNodeFP(node *chain.NodeConfig) (newFP *bstypes.FinalityProvider) { + // the node is the new FP + nodeAddr, err := sdk.AccAddressFromBech32(node.PublicAddress) s.NoError(err) - node.CreateFinalityProvider(newFP.BabylonPk, newFP.BtcPk, newFP.Pop, newFP.Description.Moniker, newFP.Description.Identity, newFP.Description.Website, newFP.Description.SecurityContact, newFP.Description.Details, newFP.Commission) + + newFP, err = datagen.GenRandomFinalityProviderWithBTCBabylonSKs(r, fpBTCSK, nodeAddr) + s.NoError(err) + node.CreateFinalityProvider(newFP.Addr, newFP.BtcPk, newFP.Pop, newFP.Description.Moniker, newFP.Description.Identity, newFP.Description.Website, newFP.Description.SecurityContact, newFP.Description.Details, newFP.Commission) // wait for a block so that above txs take effect node.WaitForNextBlock() diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index dbd713817..f42041b7e 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -6,6 +6,8 @@ import ( "strconv" "strings" + "github.com/stretchr/testify/require" + "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -13,8 +15,6 @@ import ( sdkmath "cosmossdk.io/math" cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - "github.com/stretchr/testify/require" asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" "github.com/babylonchain/babylon/test/e2e/containers" @@ -23,13 +23,9 @@ import ( bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) -func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossession, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { +func (n *NodeConfig) CreateFinalityProvider(walletAddrOrName string, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossessionBTC, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { n.LogActionF("creating finality provider") - // get babylon PK hex - babylonPKBytes, err := babylonPK.Marshal() - require.NoError(n.t, err) - babylonPKHex := hex.EncodeToString(babylonPKBytes) // get BTC PK hex btcPKHex := btcPK.MarshalHex() // get pop hex @@ -37,7 +33,9 @@ func (n *NodeConfig) CreateFinalityProvider(babylonPK *secp256k1.PubKey, btcPK * require.NoError(n.t, err) cmd := []string{ - "babylond", "tx", "btcstaking", "create-finality-provider", babylonPKHex, btcPKHex, popHex, "--from=val", "--moniker", moniker, "--identity", identity, "--website", website, "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), + "babylond", "tx", "btcstaking", "create-finality-provider", btcPKHex, popHex, + fmt.Sprintf("--from=%s", walletAddrOrName), "--moniker", moniker, "--identity", identity, "--website", website, + "--security-contact", securityContract, "--details", details, "--commission-rate", commission.String(), } _, _, err = n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd) require.NoError(n.t, err) diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index ab483d0e1..810be2364 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -1,7 +1,6 @@ package datagen import ( - "fmt" "math/rand" "testing" @@ -13,8 +12,6 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" @@ -48,11 +45,7 @@ func CreateNFinalityProviders(r *rand.Rand, t *testing.T, n int) []*bstypes.Fina } func GenRandomFinalityProviderWithBTCSK(r *rand.Rand, btcSK *btcec.PrivateKey) (*bstypes.FinalityProvider, error) { - bbnSK, _, err := GenRandomSecp256k1KeyPair(r) - if err != nil { - return nil, err - } - return GenRandomFinalityProviderWithBTCBabylonSKs(r, btcSK, bbnSK) + return GenRandomFinalityProviderWithBTCBabylonSKs(r, btcSK, GenRandomAccount().GetAddress()) } func GenRandomCommission(r *rand.Rand) sdkmath.LegacyDec { @@ -63,7 +56,7 @@ func GenRandomDescription(r *rand.Rand) *stakingtypes.Description { return &stakingtypes.Description{Moniker: GenRandomHexStr(r, 10)} } -func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.PrivateKey, bbnSK cryptotypes.PrivKey) (*bstypes.FinalityProvider, error) { +func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.PrivateKey, fpAddr sdk.AccAddress) (*bstypes.FinalityProvider, error) { // commission commission := GenRandomCommission(r) // description @@ -71,21 +64,16 @@ func GenRandomFinalityProviderWithBTCBabylonSKs(r *rand.Rand, btcSK *btcec.Priva // key pairs btcPK := btcSK.PubKey() bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - bbnPK := bbnSK.PubKey() - secp256k1PK, ok := bbnPK.(*secp256k1.PubKey) - if !ok { - return nil, fmt.Errorf("failed to assert bbnPK to *secp256k1.PubKey") - } // pop - pop, err := bstypes.NewPoP(bbnSK, btcSK) + pop, err := bstypes.NewPoPBTC(fpAddr, btcSK) if err != nil { return nil, err } return &bstypes.FinalityProvider{ Description: description, Commission: &commission, - BabylonPk: secp256k1PK, BtcPk: bip340PK, + Addr: fpAddr.String(), Pop: pop, }, nil } diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index 494786f5f..7fd126be9 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -139,6 +139,10 @@ func (h *Helper) Error(err error) { require.Error(h.t, err) } +func (h *Helper) EqualError(err, expected error) { + require.EqualError(h.t, err, expected.Error()) +} + func (h *Helper) getExtendedVotesFromValSet( epochNum uint64, height uint64, diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index deb963b65..69d7d9932 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -157,33 +157,29 @@ finality provider. ```protobuf // FinalityProvider defines a finality provider message FinalityProvider { - // description defines the description terms for the finality provider. - cosmos.staking.v1beta1.Description description = 1; - // commission defines the commission rate of the finality provider. - string commission = 2 [ - (cosmos_proto.scalar) = "cosmos.Dec", - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" - ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 3; - // btc_pk is the Bitcoin secp256k1 PK of this finality provider - // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 5; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 6; - // registered_epoch is the epoch when this finality provider is registered - uint64 registered_epoch = 7; - // slashed_babylon_height indicates the Babylon height when - // the finality provider is slashed. - // if it's 0 then the finality provider is not slashed - uint64 slashed_babylon_height = 8; - // slashed_btc_height indicates the BTC height when - // the finality provider is slashed. - // if it's 0 then the finality provider is not slashed - uint64 slashed_btc_height = 9; + // addr is the bech32 address identifier of the finality provider. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // description defines the description terms for the finality provider. + cosmos.staking.v1beta1.Description description = 2; + // commission defines the commission rate of the finality provider. + string commission = 3 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" + ]; + // btc_pk is the Bitcoin secp256k1 PK of this finality provider + // the PK follows encoding in BIP-340 spec + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of the btc_pk, where the BTC + // private key signs the bech32 bbn addr of the finality provider. + ProofOfPossessionBTC pop = 5; + // slashed_babylon_height indicates the Babylon height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_babylon_height = 6; + // slashed_btc_height indicates the BTC height when + // the finality provider is slashed. + // if it's 0 then the finality provider is not slashed + uint64 slashed_btc_height = 7; } ``` @@ -201,80 +197,80 @@ submit a staking transaction to Bitcoin. ```protobuf // BTCDelegation defines a BTC delegation message BTCDelegation { - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - cosmos.crypto.secp256k1.PubKey babylon_pk = 1; - // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation - // the PK follows encoding in BIP-340 spec - bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 3; - // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that - // this BTC delegation delegates to - // If there is more than 1 PKs, then this means the delegation is restaked - // to multiple finality providers - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // start_height is the start BTC height of the BTC delegation - // it is the start BTC height of the timelock - uint64 start_height = 5; - // end_height is the end height of the BTC delegation - // it is the end BTC height of the timelock - w - uint64 end_height = 6; - // total_sat is the total amount of BTC stakes in this delegation - // quantified in satoshi - uint64 total_sat = 7; - // staking_tx is the staking tx - bytes staking_tx = 8; - // staking_output_idx is the index of the staking output in the staking tx - uint32 staking_output_idx = 9; - // slashing_tx is the slashing tx - // It is partially signed by SK corresponding to btc_pk, but not signed by - // finality provider or covenant yet. - bytes slashing_tx = 10 [ (gogoproto.customtype) = "BTCSlashingTx" ]; - // delegator_sig is the signature on the slashing tx - // by the delegator (i.e., SK corresponding to btc_pk). - // It will be a part of the witness for the staking tx output. - bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; - // covenant_sigs is a list of adaptor signatures on the slashing tx - // by each covenant member - // It will be a part of the witness for the staking tx output. - repeated CovenantAdaptorSignatures covenant_sigs = 12; - // unbonding_time describes how long the funds will be locked either in unbonding output - // or slashing change output - uint32 unbonding_time = 13; - // btc_undelegation is the information about the early unbonding path of the BTC delegation - BTCUndelegation btc_undelegation = 14; - // version of the params used to validate the delegation - uint32 params_version = 15; + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation + // the PK follows encoding in BIP-340 spec + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of babylon_pk and btc_pk + ProofOfPossessionBTC pop = 3; + // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that + // this BTC delegation delegates to + // If there is more than 1 PKs, then this means the delegation is restaked + // to multiple finality providers + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // start_height is the start BTC height of the BTC delegation + // it is the start BTC height of the timelock + uint64 start_height = 5; + // end_height is the end height of the BTC delegation + // it is the end BTC height of the timelock - w + uint64 end_height = 6; + // total_sat is the total amount of BTC stakes in this delegation + // quantified in satoshi + uint64 total_sat = 7; + // staking_tx is the staking tx + bytes staking_tx = 8; + // staking_output_idx is the index of the staking output in the staking tx + uint32 staking_output_idx = 9; + // slashing_tx is the slashing tx + // It is partially signed by SK corresponding to btc_pk, but not signed by + // finality provider or covenant yet. + bytes slashing_tx = 10 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + // delegator_sig is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It will be a part of the witness for the staking tx output. + bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + // covenant_sigs is a list of adaptor signatures on the slashing tx + // by each covenant member + // It will be a part of the witness for the staking tx output. + repeated CovenantAdaptorSignatures covenant_sigs = 12; + // unbonding_time describes how long the funds will be locked either in unbonding output + // or slashing change output + uint32 unbonding_time = 13; + // btc_undelegation is the information about the early unbonding path of the BTC delegation + BTCUndelegation btc_undelegation = 14; + // version of the params used to validate the delegation + uint32 params_version = 15; } // BTCUndelegation contains the information about the early unbonding path of the BTC delegation message BTCUndelegation { - // unbonding_tx is the transaction which will transfer the funds from staking - // output to unbonding output. Unbonding output will usually have lower timelock - // than staking output. - bytes unbonding_tx = 1; - // slashing_tx is the slashing tx for unbonding transactions - // It is partially signed by SK corresponding to btc_pk, but not signed by - // finality provider or covenant yet. - bytes slashing_tx = 2 [ (gogoproto.customtype) = "BTCSlashingTx" ]; - // delegator_unbonding_sig is the signature on the unbonding tx - // by the delegator (i.e., SK corresponding to btc_pk). - // It effectively proves that the delegator wants to unbond and thus - // Babylon will consider this BTC delegation unbonded. Delegator's BTC - // on Bitcoin will be unbonded after timelock - bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; - // delegator_slashing_sig is the signature on the slashing tx - // by the delegator (i.e., SK corresponding to btc_pk). - // It will be a part of the witness for the unbonding tx output. - bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; - // covenant_slashing_sigs is a list of adaptor signatures on the slashing tx - // by each covenant member - // It will be a part of the witness for the staking tx output. - repeated CovenantAdaptorSignatures covenant_slashing_sigs = 5; - // covenant_unbonding_sig_list is the list of signatures on the unbonding tx - // by covenant members - // It must be provided after processing undelegate message by Babylon - repeated SignatureInfo covenant_unbonding_sig_list = 6; + // unbonding_tx is the transaction which will transfer the funds from staking + // output to unbonding output. Unbonding output will usually have lower timelock + // than staking output. + bytes unbonding_tx = 1; + // slashing_tx is the slashing tx for unbonding transactions + // It is partially signed by SK corresponding to btc_pk, but not signed by + // finality provider or covenant yet. + bytes slashing_tx = 2 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + // delegator_unbonding_sig is the signature on the unbonding tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It effectively proves that the delegator wants to unbond and thus + // Babylon will consider this BTC delegation unbonded. Delegator's BTC + // on Bitcoin will be unbonded after timelock + bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + // delegator_slashing_sig is the signature on the slashing tx + // by the delegator (i.e., SK corresponding to btc_pk). + // It will be a part of the witness for the unbonding tx output. + bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + // covenant_slashing_sigs is a list of adaptor signatures on the slashing tx + // by each covenant member + // It will be a part of the witness for the staking tx output. + repeated CovenantAdaptorSignatures covenant_slashing_sigs = 5; + // covenant_unbonding_sig_list is the list of signatures on the unbonding tx + // by covenant members + // It must be provided after processing undelegate message by Babylon + repeated SignatureInfo covenant_unbonding_sig_list = 6; } ``` @@ -290,7 +286,7 @@ staking transaction hashes of the delegator's BTC delegations. ```protobuf // BTCDelegatorDelegationIndex is a list of staking tx hashes of BTC delegations from the same delegator. message BTCDelegatorDelegationIndex { - repeated bytes staking_tx_hash_list = 1; + repeated bytes staking_tx_hash_list = 1; } ``` @@ -359,11 +355,12 @@ provider. It is typically submitted by a finality provider via the [finality provider](https://github.com/babylonchain/finality-provider) program. ```protobuf +// MsgCreateFinalityProvider is the message for creating a finality provider message MsgCreateFinalityProvider { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - + option (cosmos.msg.v1.signer) = "addr"; + // addr defines the address of the finality provider that will receive + // the commissions to all the delegations. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // description defines the description terms for the finality provider cosmos.staking.v1beta1.Description description = 2; // commission defines the commission rate of the finality provider @@ -371,16 +368,11 @@ message MsgCreateFinalityProvider { (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec" ]; - // babylon_pk is the Babylon secp256k1 PK of this finality provider - cosmos.crypto.secp256k1.PubKey babylon_pk = 4; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 6; - // master_pub_rand is the master public randomness of the finality provider - // encoded as a base58 string - string master_pub_rand = 7; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // pop is the proof of possession of btc_pk over the FP signer address. + ProofOfPossessionBTC pop = 5; } ``` @@ -409,7 +401,7 @@ Upon `MsgCreateFinalityProvider`, a Babylon node will execute as follows: 1. Verify a [proof of possession](https://rist.tech.cornell.edu/papers/pkreg.pdf) indicating the - ownership of both the Babylon and Bitcoin secret keys. + ownership of the Bitcoin secret keys over the Babylon address. 2. Ensure the given commission rate is at least the `MinCommissionRate` in the parameters and at most 100%. 3. Ensure the finality provider does not exist already. @@ -428,13 +420,11 @@ provider. ```protobuf // MsgEditFinalityProvider is the message for editing an existing finality provider message MsgEditFinalityProvider { - option (cosmos.msg.v1.signer) = "signer"; - - // NOTE: this signer needs to correspond to babylon_pk of the finality provider - string signer = 1; + option (cosmos.msg.v1.signer) = "addr"; + // addr the address of the finality provider that whishes to edit his information. + string addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited bytes btc_pk = 2; - // description defines the updated description terms for the finality provider cosmos.staking.v1beta1.Description description = 3; // commission defines the updated commission rate of the finality provider @@ -452,8 +442,7 @@ Upon `MsgEditFinalityProvider`, a Babylon node will execute as follows: parameters and at most 100%. 3. Get the finality provider with the given `btc_pk` from the finality provider storage. -4. Ensure the address `signer` corresponds to the Babylon public key - `babylon_pk` in the finality provider. +4. Ensure the address `addr` matches to the address in the finality provider. 5. Change the `description` and `commission` in the finality provider to the values supplied in the message, and write back the finality provider to the finality provider storage. @@ -467,50 +456,48 @@ staker](https://github.com/babylonchain/btc-staker) program. ```protobuf // MsgCreateBTCDelegation is the message for creating a BTC delegation message MsgCreateBTCDelegation { - option (cosmos.msg.v1.signer) = "signer"; - - string signer = 1; - // babylon_pk is the Babylon secp256k1 PK of this BTC delegation - cosmos.crypto.secp256k1.PubKey babylon_pk = 2; - // pop is the proof of possession of babylon_pk and btc_pk - ProofOfPossession pop = 3; + option (cosmos.msg.v1.signer) = "staker_addr"; + // staker_addr is the address to receive rewards from BTC delegation. + string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // pop is the proof of possession of btc_pk by the staker_addr. + ProofOfPossessionBTC pop = 2; // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - repeated bytes fp_btc_pk_list = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // staking_time is the time lock used in staking transaction - uint32 staking_time = 6; + uint32 staking_time = 5; // staking_value is the amount of satoshis locked in staking output - int64 staking_value = 7; + int64 staking_value = 6; // staking_tx is the staking tx along with the merkle proof of inclusion in btc block - babylon.btccheckpoint.v1.TransactionInfo staking_tx = 8; + babylon.btccheckpoint.v1.TransactionInfo staking_tx = 7; // slashing_tx is the slashing tx // Note that the tx itself does not contain signatures, which are off-chain. - bytes slashing_tx = 9 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + bytes slashing_tx = 8 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - bytes delegator_slashing_sig = 10 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output // - unbonding slashing transaction, change output // It must be smaller than math.MaxUInt16 and larger that max(MinUnbondingTime, CheckpointFinalizationTimeout) - uint32 unbonding_time = 11; + uint32 unbonding_time = 10; // fields related to unbonding transaction // unbonding_tx is a bitcoin unbonding transaction i.e transaction that spends // staking output and sends it to the unbonding output - bytes unbonding_tx = 12; + bytes unbonding_tx = 11; // unbonding_value is amount of satoshis locked in unbonding output. // NOTE: staking_value and unbonding_value could be different because of the difference between the fee for staking tx and that for unbonding - int64 unbonding_value = 13; + int64 unbonding_value = 12; // unbonding_slashing_tx is the slashing tx which slash unbonding contract // Note that the tx itself does not contain signatures, which are off-chain. - bytes unbonding_slashing_tx = 14 [ (gogoproto.customtype) = "BTCSlashingTx" ]; + bytes unbonding_slashing_tx = 13 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - bytes delegator_unbonding_slashing_sig = 15 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; } ``` @@ -522,7 +509,7 @@ CheckpointFinalizationTimeout)`, where `MinUnbondingTime` and and BTC Checkpoint module, respectively. 2. Verify a [proof of possession](https://rist.tech.cornell.edu/papers/pkreg.pdf) indicating the - ownership of both the Babylon and Bitcoin secret keys. + ownership of the Bitcoin secret key over the Babylon staker address. 3. Ensure the finality providers that the bitcoins are delegated to are known to Babylon. 4. Verify the staking transaction and slashing transaction, including diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index cd0b532db..813e70a50 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -9,7 +9,6 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" @@ -52,8 +51,8 @@ func GetTxCmd() *cobra.Command { func NewCreateFinalityProviderCmd() *cobra.Command { cmd := &cobra.Command{ - Use: "create-finality-provider [babylon_pk] [btc_pk] [pop]", - Args: cobra.ExactArgs(3), + Use: "create-finality-provider [btc_pk] [pop]", + Args: cobra.ExactArgs(2), Short: "Create a finality provider", Long: strings.TrimSpace( `Create a finality provider.`, // TODO: example @@ -86,33 +85,22 @@ func NewCreateFinalityProviderCmd() *cobra.Command { return err } - // get Babylon PK - babylonPKBytes, err := hex.DecodeString(args[0]) - if err != nil { - return err - } - var babylonPK secp256k1.PubKey - if err := babylonPK.Unmarshal(babylonPKBytes); err != nil { - return err - } - // get BTC PK - btcPK, err := bbn.NewBIP340PubKeyFromHex(args[1]) + btcPK, err := bbn.NewBIP340PubKeyFromHex(args[0]) if err != nil { return err } // get PoP - pop, err := types.NewPoPFromHex(args[2]) + pop, err := types.NewPoPBTCFromHex(args[1]) if err != nil { return err } msg := types.MsgCreateFinalityProvider{ - Signer: clientCtx.FromAddress.String(), + Addr: clientCtx.FromAddress.String(), Description: &description, Commission: &rate, - BabylonPk: &babylonPK, BtcPk: btcPK, Pop: pop, } @@ -177,7 +165,7 @@ func NewEditFinalityProviderCmd() *cobra.Command { } msg := types.MsgEditFinalityProvider{ - Signer: clientCtx.FromAddress.String(), + Addr: clientCtx.FromAddress.String(), BtcPk: btcPK, Description: &description, Commission: &rate, diff --git a/x/btcstaking/keeper/bench_test.go b/x/btcstaking/keeper/bench_test.go index 405a9119f..9e217a7aa 100644 --- a/x/btcstaking/keeper/bench_test.go +++ b/x/btcstaking/keeper/bench_test.go @@ -36,10 +36,9 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) { fp, err := datagen.GenRandomFinalityProvider(r) h.NoError(err) msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, + Addr: fp.Addr, Description: fp.Description, Commission: fp.Commission, - BabylonPk: fp.BabylonPk, BtcPk: fp.BtcPk, Pop: fp.Pop, } diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go index 724591366..cbcc60ead 100644 --- a/x/btcstaking/keeper/genesis_test.go +++ b/x/btcstaking/keeper/genesis_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "bytes" "math" "math/rand" "strings" @@ -128,7 +127,7 @@ func TestExportGenesis(t *testing.T) { correctFps := 0 for _, fp := range fps { for _, gsfp := range gs.FinalityProviders { - if !bytes.Equal(fp.BabylonPk.Address(), gsfp.BabylonPk.Address()) { + if !strings.EqualFold(fp.Addr, gsfp.Addr) { continue } require.EqualValues(t, fp, gsfp) diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index 20095c1dc..661836a97 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -147,7 +147,7 @@ func FuzzFinalityProvider(f *testing.F) { // check keys from map matches those in returned response require.Equal(t, v.BtcPk.MarshalHex(), resp.FinalityProvider.BtcPk.MarshalHex()) - require.Equal(t, v.BabylonPk, resp.FinalityProvider.BabylonPk) + require.Equal(t, v.Addr, resp.FinalityProvider.Addr) } // check some random non-existing guy diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index 7adac41a6..d6d3999ac 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -38,7 +38,7 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { _, _, fp := h.CreateFinalityProvider(r) if i < numFpsWithVotingPower { // these finality providers will receive BTC delegations and have voting power - fpsWithVotingPowerMap[fp.BabylonPk.String()] = fp + fpsWithVotingPowerMap[fp.Addr] = fp } } @@ -74,7 +74,7 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { activeFPs := dc.GetActiveFinalityProviders(maxNumFps) for _, fpDistInfo := range activeFPs { require.Equal(t, fpDistInfo.TotalVotingPower, numBTCDels*stakingValue) - fp, ok := fpsWithVotingPowerMap[fpDistInfo.BabylonPk.String()] + fp, ok := fpsWithVotingPowerMap[fpDistInfo.Addr] require.True(t, ok) require.Equal(t, fpDistInfo.Commission, fp.Commission) require.Len(t, fpDistInfo.BtcDels, int(numBTCDels)) diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index fb1c8bff6..73e44aac0 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -116,7 +116,7 @@ func CreateFinalityProvider(r *rand.Rand, t *testing.T) *types.FinalityProvider return &types.FinalityProvider{ Description: fp.Description, Commission: fp.Commission, - BabylonPk: fp.BabylonPk, + Addr: fp.Addr, BtcPk: fp.BtcPk, Pop: fp.Pop, } @@ -128,10 +128,9 @@ func (h *Helper) CreateFinalityProvider(r *rand.Rand) (*btcec.PrivateKey, *btcec fp, err := datagen.GenRandomFinalityProviderWithBTCSK(r, fpSK) h.NoError(err) msgNewFp := types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, + Addr: fp.Addr, Description: fp.Description, Commission: fp.Commission, - BabylonPk: fp.BabylonPk, BtcPk: fp.BtcPk, Pop: fp.Pop, } diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index ea9be3b50..2a97b6662 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -3,6 +3,7 @@ package keeper import ( "context" "fmt" + "strings" "time" errorsmod "cosmossdk.io/errors" @@ -60,8 +61,13 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg return nil, status.Errorf(codes.InvalidArgument, "%v", err) } + fpAddr, err := sdk.AccAddressFromBech32(req.Addr) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid address %s: %v", req.Addr, err) + } + // verify proof of possession - if err := req.Pop.Verify(req.BabylonPk, req.BtcPk, ms.btcNet); err != nil { + if err := req.Pop.Verify(fpAddr, req.BtcPk, ms.btcNet); err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid proof of possession: %v", err) } @@ -84,7 +90,7 @@ func (ms msgServer) CreateFinalityProvider(goCtx context.Context, req *types.Msg fp := types.FinalityProvider{ Description: req.Description, Commission: req.Commission, - BabylonPk: req.BabylonPk, + Addr: fpAddr.String(), BtcPk: req.BtcPk, Pop: req.Pop, } @@ -116,15 +122,20 @@ func (ms msgServer) EditFinalityProvider(ctx context.Context, req *types.MsgEdit return nil, types.ErrCommissionGTMaxRate } + // TODO: check to index the finality provider by his address instead of the BTC pk // find the finality provider with the given BTC PK fp, err := ms.GetFinalityProvider(ctx, req.BtcPk) if err != nil { return nil, err } + fpAddr, err := sdk.AccAddressFromBech32(req.Addr) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid address %s: %v", req.Addr, err) + } + // ensure the signer corresponds to the finality provider's Babylon address - fpBabylonAddr := sdk.AccAddress(fp.BabylonPk.Address()) - if req.Signer != fpBabylonAddr.String() { + if !strings.EqualFold(fpAddr.String(), fp.Addr) { return nil, status.Errorf(codes.PermissionDenied, "the signer does not correspond to the finality provider's Babylon address") } diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index c830f91f6..5038d7d58 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -49,10 +49,9 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { fp, err := datagen.GenRandomFinalityProvider(r) require.NoError(t, err) msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, + Addr: fp.Addr, Description: fp.Description, Commission: fp.Commission, - BabylonPk: fp.BabylonPk, BtcPk: fp.BtcPk, Pop: fp.Pop, } @@ -70,10 +69,9 @@ func FuzzMsgCreateFinalityProvider(f *testing.F) { // duplicated finality providers should not pass for _, fp2 := range fps { msg := &types.MsgCreateFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, + Addr: fp2.Addr, Description: fp2.Description, Commission: fp2.Commission, - BabylonPk: fp2.BabylonPk, BtcPk: fp2.BtcPk, Pop: fp2.Pop, } @@ -94,7 +92,6 @@ func FuzzMsgEditFinalityProvider(f *testing.F) { // generate new finality provider fp, err := datagen.GenRandomFinalityProvider(r) - fpAddr := sdk.AccAddress(fp.BabylonPk.Address()) require.NoError(t, err) // insert the finality provider h.AddFinalityProvider(fp) @@ -107,7 +104,7 @@ func FuzzMsgEditFinalityProvider(f *testing.F) { // scenario 1: editing finality provider should succeed msg := &types.MsgEditFinalityProvider{ - Signer: fpAddr.String(), + Addr: fp.Addr, BtcPk: *fp.BtcPk, Description: newDescription, Commission: &newCommission, @@ -122,14 +119,15 @@ func FuzzMsgEditFinalityProvider(f *testing.F) { // scenario 2: message from an unauthorised signer should fail newCommission = datagen.GenRandomCommission(r) newDescription = datagen.GenRandomDescription(r) + invalidAddr := datagen.GenRandomAccount().Address msg = &types.MsgEditFinalityProvider{ - Signer: datagen.GenRandomAccount().Address, + Addr: invalidAddr, BtcPk: *fp.BtcPk, Description: newDescription, Commission: &newCommission, } _, err = msgSrvr.EditFinalityProvider(h.Ctx, msg) - h.Error(err) + h.EqualError(err, status.Errorf(codes.PermissionDenied, "the signer does not correspond to the finality provider's Babylon address")) errStatus := status.Convert(err) require.Equal(t, codes.PermissionDenied, errStatus.Code()) }) diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index bea07a683..7b5902178 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -8,6 +8,7 @@ import ( asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) func (fp *FinalityProvider) IsSlashed() bool { @@ -16,8 +17,8 @@ func (fp *FinalityProvider) IsSlashed() bool { func (fp *FinalityProvider) ValidateBasic() error { // ensure fields are non-empty and well-formatted - if fp.BabylonPk == nil { - return fmt.Errorf("empty Babylon public key") + if _, err := sdk.AccAddressFromBech32(fp.Addr); err != nil { + return fmt.Errorf("invalid finality provider address: %s - %w", fp.Addr, err) } if fp.BtcPk == nil { return fmt.Errorf("empty BTC public key") @@ -29,7 +30,7 @@ func (fp *FinalityProvider) ValidateBasic() error { return fmt.Errorf("empty proof of possession") } if err := fp.Pop.ValidateBasic(); err != nil { - return err + return fmt.Errorf("PoP is not valid: %w", err) } return nil diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index f5bba85b5..cd2d79f7e 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -8,7 +8,6 @@ import ( fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" _ "github.com/cosmos/cosmos-proto" - secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -71,17 +70,18 @@ func (BTCDelegationStatus) EnumDescriptor() ([]byte, []int) { // FinalityProvider defines a finality provider type FinalityProvider struct { + // addr is the bech32 address identifier of the finality provider. + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` // description defines the description terms for the finality provider. - Description *types.Description `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` + Description *types.Description `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // commission defines the commission rate of the finality provider. - Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` - // babylon_pk is the Babylon secp256k1 PK of this finality provider - BabylonPk *secp256k1.PubKey `protobuf:"bytes,3,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` + // pop is the proof of possession of the btc_pk, where the BTC + // private key signs the bech32 bbn addr of the finality provider. + Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed @@ -125,21 +125,21 @@ func (m *FinalityProvider) XXX_DiscardUnknown() { var xxx_messageInfo_FinalityProvider proto.InternalMessageInfo -func (m *FinalityProvider) GetDescription() *types.Description { +func (m *FinalityProvider) GetAddr() string { if m != nil { - return m.Description + return m.Addr } - return nil + return "" } -func (m *FinalityProvider) GetBabylonPk() *secp256k1.PubKey { +func (m *FinalityProvider) GetDescription() *types.Description { if m != nil { - return m.BabylonPk + return m.Description } return nil } -func (m *FinalityProvider) GetPop() *ProofOfPossession { +func (m *FinalityProvider) GetPop() *ProofOfPossessionBTC { if m != nil { return m.Pop } @@ -744,85 +744,82 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1238 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdd, 0x6e, 0x1b, 0x45, - 0x1b, 0xce, 0xda, 0x8e, 0x53, 0xbf, 0xb6, 0x1b, 0x77, 0x9a, 0xa6, 0xdb, 0x46, 0x5f, 0x92, 0xcf, - 0x94, 0xca, 0x02, 0x62, 0x37, 0xe9, 0x8f, 0x28, 0x12, 0x48, 0x71, 0x9c, 0xd2, 0xa8, 0x6d, 0x6a, - 0xd6, 0x4e, 0x11, 0x20, 0xb1, 0x1a, 0xef, 0x4e, 0xec, 0x95, 0xed, 0x9d, 0x65, 0x67, 0x6c, 0xec, - 0x3b, 0xe0, 0x04, 0x89, 0x53, 0xce, 0xb9, 0x84, 0x5e, 0x03, 0xe2, 0xb0, 0xea, 0x09, 0x28, 0x07, - 0x11, 0x6a, 0x8f, 0xb9, 0x07, 0x34, 0x3f, 0x5e, 0xaf, 0x4b, 0x53, 0x5a, 0x92, 0x33, 0xcf, 0xfb, - 0xf3, 0xbc, 0x3f, 0xcf, 0xe3, 0x99, 0x85, 0xeb, 0x2d, 0xdc, 0x1a, 0xf7, 0xa8, 0x5f, 0x69, 0x71, - 0x87, 0x71, 0xdc, 0xf5, 0xfc, 0x76, 0x65, 0xb8, 0x19, 0x3b, 0x95, 0x83, 0x90, 0x72, 0x8a, 0x2e, - 0xe9, 0xb8, 0x72, 0xcc, 0x33, 0xdc, 0xbc, 0xba, 0xd4, 0xa6, 0x6d, 0x2a, 0x23, 0x2a, 0xe2, 0x97, - 0x0a, 0xbe, 0x7a, 0xc5, 0xa1, 0xac, 0x4f, 0x99, 0xad, 0x1c, 0xea, 0xa0, 0x5d, 0x45, 0x75, 0xaa, - 0x38, 0xe1, 0x38, 0xe0, 0xb4, 0xc2, 0x88, 0x13, 0x6c, 0xdd, 0xbe, 0xd3, 0xdd, 0xac, 0x74, 0xc9, - 0x78, 0x12, 0x73, 0x4d, 0xc7, 0x4c, 0xfb, 0x69, 0x11, 0x8e, 0x37, 0x2b, 0x33, 0x1d, 0x5d, 0x5d, - 0x7b, 0x7d, 0xe7, 0x01, 0x0d, 0x54, 0x40, 0xf1, 0xf7, 0x24, 0x14, 0xee, 0x79, 0x3e, 0xee, 0x79, - 0x7c, 0x5c, 0x0f, 0xe9, 0xd0, 0x73, 0x49, 0x88, 0x76, 0x21, 0xeb, 0x12, 0xe6, 0x84, 0x5e, 0xc0, - 0x3d, 0xea, 0x9b, 0xc6, 0xba, 0x51, 0xca, 0x6e, 0xbd, 0x57, 0xd6, 0x3d, 0x4e, 0x27, 0x93, 0x15, - 0xcb, 0xb5, 0x69, 0xa8, 0x15, 0xcf, 0x43, 0x8f, 0x00, 0x1c, 0xda, 0xef, 0x7b, 0x8c, 0x09, 0x94, - 0xc4, 0xba, 0x51, 0xca, 0x54, 0x37, 0x8e, 0x8e, 0xd7, 0x56, 0x14, 0x10, 0x73, 0xbb, 0x65, 0x8f, - 0x56, 0xfa, 0x98, 0x77, 0xca, 0x0f, 0x49, 0x1b, 0x3b, 0xe3, 0x1a, 0x71, 0x9e, 0x3f, 0xdd, 0x00, - 0x5d, 0xa7, 0x46, 0x1c, 0x2b, 0x06, 0x80, 0x3e, 0x03, 0xd0, 0xd3, 0xd8, 0x41, 0xd7, 0x4c, 0xca, - 0xa6, 0xd6, 0x26, 0x4d, 0xa9, 0x55, 0x95, 0xa3, 0x55, 0x95, 0xeb, 0x83, 0xd6, 0x03, 0x32, 0xb6, - 0x32, 0x3a, 0xa5, 0xde, 0x45, 0x8f, 0x20, 0xdd, 0xe2, 0x8e, 0xc8, 0x4d, 0xad, 0x1b, 0xa5, 0x5c, - 0xf5, 0xce, 0xd1, 0xf1, 0xda, 0x56, 0xdb, 0xe3, 0x9d, 0x41, 0xab, 0xec, 0xd0, 0x7e, 0x45, 0x47, - 0x3a, 0x1d, 0xec, 0xf9, 0x93, 0x43, 0x85, 0x8f, 0x03, 0xc2, 0xca, 0xd5, 0xbd, 0xfa, 0xcd, 0x5b, - 0x37, 0x34, 0xe4, 0x7c, 0x8b, 0x3b, 0xf5, 0x2e, 0xfa, 0x04, 0x92, 0x01, 0x0d, 0xcc, 0x79, 0xd9, - 0x47, 0xa9, 0xfc, 0x5a, 0xea, 0xcb, 0xf5, 0x90, 0xd2, 0xc3, 0xc7, 0x87, 0x75, 0xca, 0x18, 0x91, - 0x53, 0x58, 0x22, 0x09, 0xdd, 0x82, 0x65, 0xd6, 0xc3, 0xac, 0x43, 0x5c, 0x7b, 0x32, 0x52, 0x87, - 0x78, 0xed, 0x0e, 0x37, 0xd3, 0xeb, 0x46, 0x29, 0x65, 0x2d, 0x69, 0x6f, 0x55, 0x39, 0xef, 0x4b, - 0x1f, 0xfa, 0x08, 0x50, 0x94, 0xc5, 0x9d, 0x49, 0xc6, 0x82, 0xcc, 0x28, 0x4c, 0x32, 0xb8, 0xa3, - 0xa2, 0x8b, 0x3f, 0x24, 0xc0, 0x7c, 0x95, 0xd9, 0x2f, 0x3d, 0xde, 0x79, 0x44, 0x38, 0x8e, 0xed, - 0xc2, 0x38, 0x8b, 0x5d, 0x2c, 0x43, 0x5a, 0x77, 0x93, 0x90, 0xdd, 0xe8, 0x13, 0xfa, 0x3f, 0xe4, - 0x86, 0x94, 0x7b, 0x7e, 0xdb, 0x0e, 0xe8, 0xf7, 0x24, 0x94, 0xa4, 0xa5, 0xac, 0xac, 0xb2, 0xd5, - 0x85, 0xe9, 0x0d, 0xab, 0x48, 0xbd, 0xf3, 0x2a, 0xe6, 0x4f, 0x58, 0xc5, 0x5f, 0x69, 0xc8, 0x57, - 0x9b, 0x3b, 0x35, 0xd2, 0x23, 0x6d, 0x2c, 0xa5, 0x79, 0x17, 0xb2, 0x82, 0x25, 0x12, 0xda, 0xd8, - 0x75, 0x43, 0xb9, 0x84, 0x4c, 0xd5, 0x7c, 0xfe, 0x74, 0x63, 0x49, 0xeb, 0x69, 0xdb, 0x75, 0x43, - 0xc2, 0x58, 0x83, 0x87, 0x9e, 0xdf, 0xb6, 0x40, 0x05, 0x0b, 0x63, 0x6c, 0x75, 0x89, 0xb3, 0x58, - 0xdd, 0xa7, 0x4a, 0x46, 0x4a, 0xce, 0x1f, 0xbe, 0xad, 0x8c, 0xaa, 0xcd, 0x1d, 0xa5, 0xa4, 0x6f, - 0xe0, 0xfc, 0x61, 0x60, 0xab, 0x86, 0xec, 0x9e, 0xc7, 0xc4, 0xda, 0x92, 0xa7, 0xe8, 0x2a, 0x7b, - 0x18, 0x54, 0x45, 0x5f, 0x0f, 0x3d, 0x26, 0xe9, 0x63, 0x1c, 0x87, 0x7c, 0x76, 0xbf, 0x59, 0x69, - 0xd3, 0x44, 0xfc, 0x0f, 0x80, 0xf8, 0xee, 0xac, 0x7a, 0x33, 0xc4, 0x77, 0xb5, 0x7b, 0x05, 0x32, - 0x9c, 0x72, 0xdc, 0xb3, 0x19, 0x9e, 0x28, 0xf5, 0x9c, 0x34, 0x34, 0xb0, 0xcc, 0xd5, 0x33, 0xda, - 0x7c, 0x64, 0x9e, 0x13, 0xdb, 0xb4, 0x32, 0xda, 0xd2, 0x1c, 0x49, 0x8e, 0xb5, 0x9b, 0x0e, 0x78, - 0x30, 0xe0, 0xb6, 0xe7, 0x8e, 0xcc, 0xcc, 0xba, 0x51, 0xca, 0x5b, 0x05, 0xed, 0x79, 0x2c, 0x1d, - 0x7b, 0xee, 0x08, 0x6d, 0x41, 0x56, 0xf2, 0xae, 0xd1, 0x40, 0x72, 0x73, 0xe1, 0xe8, 0x78, 0x4d, - 0x30, 0xdf, 0xd0, 0x9e, 0xe6, 0xc8, 0x02, 0x16, 0xfd, 0x46, 0xdf, 0x42, 0xde, 0x55, 0x9a, 0xa0, - 0xa1, 0xcd, 0xbc, 0xb6, 0x99, 0x95, 0x59, 0x77, 0x8f, 0x8e, 0xd7, 0x6e, 0xbf, 0xcb, 0xee, 0x1a, - 0x5e, 0xdb, 0xc7, 0x7c, 0x10, 0x12, 0x2b, 0x17, 0xe1, 0x35, 0xbc, 0x36, 0x3a, 0x80, 0xbc, 0x43, - 0x87, 0xc4, 0xc7, 0x3e, 0x17, 0xf0, 0xcc, 0xcc, 0xad, 0x27, 0x4b, 0xd9, 0xad, 0x1b, 0x27, 0xb0, - 0xbc, 0xa3, 0x63, 0xb7, 0x5d, 0x1c, 0x28, 0x04, 0x85, 0xca, 0xac, 0xdc, 0x04, 0xa6, 0xe1, 0xb5, - 0x19, 0x7a, 0x1f, 0xce, 0x0f, 0xfc, 0x16, 0xf5, 0x5d, 0x39, 0xab, 0xd7, 0x27, 0x66, 0x5e, 0x2e, - 0x25, 0x1f, 0x59, 0x9b, 0x5e, 0x9f, 0xa0, 0x2f, 0xa0, 0x20, 0x74, 0x31, 0xf0, 0xdd, 0x48, 0xf7, - 0xe6, 0x79, 0x29, 0xb3, 0xeb, 0x27, 0x34, 0x50, 0x6d, 0xee, 0x1c, 0xc4, 0xa2, 0xad, 0xc5, 0x16, - 0x77, 0xe2, 0x06, 0x51, 0x39, 0xc0, 0x21, 0xee, 0x33, 0x7b, 0x48, 0x42, 0x79, 0xab, 0x2f, 0xaa, - 0xca, 0xca, 0xfa, 0x44, 0x19, 0x8b, 0x3f, 0xa7, 0x60, 0xf1, 0x15, 0x2c, 0xa1, 0xa5, 0x58, 0xd3, - 0x23, 0x75, 0xef, 0x58, 0xd9, 0x69, 0xcb, 0xff, 0xa0, 0x30, 0xf1, 0x36, 0x14, 0x7e, 0x07, 0x97, - 0xa7, 0x14, 0x4e, 0x0b, 0x08, 0x32, 0x93, 0xa7, 0x25, 0xf3, 0x52, 0x84, 0x7c, 0x30, 0x01, 0x16, - 0xac, 0x52, 0x58, 0x8e, 0xa9, 0x66, 0xd2, 0xb0, 0xa8, 0x98, 0x3a, 0x6d, 0xc5, 0xa5, 0xa9, 0x7c, - 0x34, 0xae, 0x28, 0x78, 0x08, 0xcb, 0x53, 0x19, 0xc5, 0xea, 0x31, 0x73, 0xfe, 0x3f, 0xea, 0x69, - 0x29, 0xd2, 0xd3, 0xb4, 0x0c, 0x43, 0x0e, 0xac, 0x44, 0x75, 0x66, 0x56, 0xa9, 0x2e, 0x96, 0xb4, - 0x2c, 0x76, 0xed, 0x84, 0x62, 0x11, 0xfa, 0x9e, 0x7f, 0x48, 0x2d, 0x73, 0x02, 0x14, 0xdf, 0x9c, - 0xb8, 0x53, 0x8a, 0x0d, 0xb8, 0x3c, 0xbd, 0x8a, 0x69, 0x38, 0xbd, 0x93, 0x19, 0xfa, 0x18, 0x52, - 0x2e, 0xe9, 0x31, 0xd3, 0x78, 0x63, 0xa1, 0x99, 0x8b, 0xdc, 0x92, 0x19, 0xc5, 0x7d, 0x58, 0x79, - 0x3d, 0xe8, 0x9e, 0xef, 0x92, 0x11, 0xaa, 0xc0, 0xd2, 0xf4, 0xa2, 0xb1, 0x3b, 0x98, 0x75, 0xd4, - 0x44, 0xa2, 0x50, 0xce, 0xba, 0x10, 0x5d, 0x39, 0xf7, 0x31, 0xeb, 0xc8, 0x26, 0x7f, 0x31, 0x20, - 0x3f, 0x33, 0x10, 0xba, 0x07, 0x89, 0x53, 0x3f, 0x96, 0x89, 0xa0, 0x8b, 0x1e, 0x40, 0x52, 0x28, - 0x25, 0x71, 0x5a, 0xa5, 0x08, 0x94, 0xe2, 0x8f, 0x06, 0x5c, 0x39, 0x91, 0x64, 0xf1, 0x50, 0x39, - 0x74, 0x78, 0x06, 0x6f, 0xbc, 0x43, 0x87, 0xf5, 0xae, 0xf8, 0x03, 0x63, 0x55, 0x43, 0x69, 0x2f, - 0x21, 0x97, 0x97, 0xc5, 0x51, 0x5d, 0x56, 0xfc, 0xd5, 0x80, 0x2b, 0x0d, 0xd2, 0x23, 0x0e, 0xf7, - 0x86, 0x64, 0x22, 0xad, 0x5d, 0xf1, 0xe5, 0xe1, 0x3b, 0x04, 0x5d, 0x87, 0xc5, 0x57, 0x58, 0x50, - 0xef, 0xae, 0x95, 0x9f, 0x21, 0x00, 0x59, 0x90, 0x89, 0x9e, 0xb4, 0x53, 0xbe, 0xb1, 0x0b, 0xfa, - 0x35, 0x43, 0x1b, 0x70, 0x31, 0x24, 0x42, 0x93, 0x21, 0x71, 0x6d, 0x8d, 0xce, 0xd4, 0x47, 0x64, - 0xce, 0x2a, 0x44, 0xae, 0x7b, 0x22, 0xbc, 0xd1, 0xfd, 0x60, 0x17, 0x2e, 0xce, 0xc8, 0xac, 0xc1, - 0x31, 0x1f, 0x30, 0x94, 0x85, 0x85, 0xfa, 0xee, 0x7e, 0x6d, 0x6f, 0xff, 0xf3, 0xc2, 0x1c, 0x02, - 0x48, 0x6f, 0xef, 0x34, 0xf7, 0x9e, 0xec, 0x16, 0x0c, 0x94, 0x83, 0x73, 0x07, 0xfb, 0xd5, 0xc7, - 0xfb, 0xb5, 0xdd, 0x5a, 0x21, 0x81, 0x16, 0x20, 0xb9, 0xbd, 0xff, 0x55, 0x21, 0x59, 0x7d, 0xf8, - 0xdb, 0x8b, 0x55, 0xe3, 0xd9, 0x8b, 0x55, 0xe3, 0xcf, 0x17, 0xab, 0xc6, 0x4f, 0x2f, 0x57, 0xe7, - 0x9e, 0xbd, 0x5c, 0x9d, 0xfb, 0xe3, 0xe5, 0xea, 0xdc, 0xd7, 0xff, 0x3a, 0xcc, 0x28, 0xfe, 0xc5, - 0x2e, 0x27, 0x6b, 0xa5, 0xe5, 0x17, 0xfb, 0xcd, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa6, 0x40, - 0x45, 0xa7, 0x8e, 0x0c, 0x00, 0x00, + // 1191 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x13, 0xc7, + 0x1b, 0xce, 0xda, 0x8e, 0x43, 0x5e, 0xdb, 0xc4, 0x0c, 0x21, 0x2c, 0x44, 0xbf, 0x24, 0x3f, 0x97, + 0xa2, 0xa8, 0x25, 0x36, 0x04, 0x5a, 0x95, 0x43, 0x0f, 0x71, 0x1c, 0x4a, 0x04, 0x04, 0x77, 0xed, + 0x50, 0xb5, 0x95, 0xba, 0x1a, 0xef, 0x4e, 0xd6, 0x23, 0xdb, 0x3b, 0xdb, 0x9d, 0xb1, 0xeb, 0x7c, + 0x83, 0x5e, 0x2a, 0xf5, 0xda, 0x7b, 0x3f, 0x02, 0x9f, 0xa1, 0xe2, 0x88, 0x38, 0x55, 0x39, 0x44, + 0x15, 0x9c, 0xfb, 0x1d, 0xaa, 0x99, 0x59, 0xef, 0xae, 0x29, 0xa1, 0x40, 0x72, 0xf3, 0xbc, 0xff, + 0x9e, 0x77, 0xde, 0xe7, 0xf1, 0x3b, 0x0b, 0xd7, 0x3b, 0xb8, 0x73, 0xd8, 0x67, 0x7e, 0xad, 0x23, + 0x1c, 0x2e, 0x70, 0x8f, 0xfa, 0x5e, 0x6d, 0x74, 0x2b, 0x75, 0xaa, 0x06, 0x21, 0x13, 0x0c, 0x5d, + 0x8a, 0xe2, 0xaa, 0x29, 0xcf, 0xe8, 0xd6, 0xd5, 0x45, 0x8f, 0x79, 0x4c, 0x45, 0xd4, 0xe4, 0x2f, + 0x1d, 0x7c, 0xf5, 0x8a, 0xc3, 0xf8, 0x80, 0x71, 0x5b, 0x3b, 0xf4, 0x21, 0x72, 0x5d, 0xd3, 0xa7, + 0x5a, 0x82, 0xd5, 0x21, 0x02, 0xdf, 0xaa, 0x4d, 0xa1, 0x5d, 0x5d, 0x7d, 0x73, 0x57, 0x01, 0x0b, + 0x74, 0x40, 0xe5, 0x59, 0x16, 0xca, 0xf7, 0xa8, 0x8f, 0xfb, 0x54, 0x1c, 0x36, 0x43, 0x36, 0xa2, + 0x2e, 0x09, 0xd1, 0x0d, 0xc8, 0x61, 0xd7, 0x0d, 0x4d, 0x63, 0xcd, 0x58, 0x9f, 0xaf, 0x9b, 0x2f, + 0x9e, 0x6e, 0x2c, 0x46, 0xd8, 0x5b, 0xae, 0x1b, 0x12, 0xce, 0x5b, 0x22, 0xa4, 0xbe, 0x67, 0xa9, + 0x28, 0xb4, 0x03, 0x05, 0x97, 0x70, 0x27, 0xa4, 0x81, 0xa0, 0xcc, 0x37, 0x33, 0x6b, 0xc6, 0x7a, + 0x61, 0xf3, 0xa3, 0x6a, 0x94, 0x91, 0xdc, 0x51, 0xf5, 0x57, 0x6d, 0x24, 0xa1, 0x56, 0x3a, 0x0f, + 0x3d, 0x02, 0x70, 0xd8, 0x60, 0x40, 0x39, 0x97, 0x55, 0xb2, 0x0a, 0x7a, 0xe3, 0xe8, 0x78, 0x75, + 0x59, 0x17, 0xe2, 0x6e, 0xaf, 0x4a, 0x59, 0x6d, 0x80, 0x45, 0xb7, 0xfa, 0x90, 0x78, 0xd8, 0x39, + 0x6c, 0x10, 0xe7, 0xc5, 0xd3, 0x0d, 0x88, 0x70, 0x1a, 0xc4, 0xb1, 0x52, 0x05, 0xd0, 0x23, 0xc8, + 0x77, 0x84, 0x63, 0x07, 0x3d, 0x33, 0xb7, 0x66, 0xac, 0x17, 0xeb, 0x9f, 0x1f, 0x1d, 0xaf, 0x6e, + 0x7a, 0x54, 0x74, 0x87, 0x9d, 0xaa, 0xc3, 0x06, 0xb5, 0x68, 0x30, 0x4e, 0x17, 0x53, 0x7f, 0x72, + 0xa8, 0x89, 0xc3, 0x80, 0xf0, 0x6a, 0x7d, 0xb7, 0x79, 0xfb, 0xce, 0xcd, 0xe6, 0xb0, 0xf3, 0x80, + 0x1c, 0x5a, 0xb3, 0x1d, 0xe1, 0x34, 0x7b, 0xe8, 0x4b, 0xc8, 0x06, 0x2c, 0x30, 0x67, 0xd5, 0xe5, + 0x3e, 0xad, 0xbe, 0x91, 0xc4, 0x6a, 0x33, 0x64, 0xec, 0xe0, 0xf1, 0x41, 0x93, 0x71, 0x4e, 0x54, + 0x17, 0xf5, 0xf6, 0xb6, 0x25, 0xf3, 0xd0, 0x1d, 0x58, 0xe2, 0x7d, 0xcc, 0xbb, 0xc4, 0xb5, 0xa3, + 0x54, 0xbb, 0x4b, 0xa8, 0xd7, 0x15, 0x66, 0x7e, 0xcd, 0x58, 0xcf, 0x59, 0x8b, 0x91, 0xb7, 0xae, + 0x9d, 0xf7, 0x95, 0x0f, 0xdd, 0x00, 0x14, 0x67, 0x09, 0x67, 0x92, 0x31, 0xa7, 0x32, 0xca, 0x93, + 0x0c, 0xe1, 0xe8, 0xe8, 0xca, 0xcf, 0x19, 0x30, 0x5f, 0xa7, 0xf2, 0x1b, 0x2a, 0xba, 0x8f, 0x88, + 0xc0, 0xa9, 0x71, 0x18, 0x67, 0x31, 0x8e, 0x25, 0xc8, 0x47, 0xdd, 0x64, 0x54, 0x37, 0xd1, 0x09, + 0xfd, 0x1f, 0x8a, 0x23, 0x26, 0xa8, 0xef, 0xd9, 0x01, 0xfb, 0x89, 0x84, 0x8a, 0xc6, 0x9c, 0x55, + 0xd0, 0xb6, 0xa6, 0x34, 0xbd, 0x65, 0x14, 0xb9, 0xf7, 0x1e, 0xc5, 0xec, 0x09, 0xa3, 0xf8, 0x3b, + 0x0f, 0xa5, 0x7a, 0x7b, 0xbb, 0x41, 0xfa, 0xc4, 0xc3, 0x4a, 0x5d, 0x77, 0xa1, 0x20, 0x89, 0x22, + 0xa1, 0xfd, 0x4e, 0xca, 0x06, 0x1d, 0x2c, 0x8d, 0xa9, 0xd1, 0x65, 0xce, 0x50, 0x49, 0xd9, 0x0f, + 0x54, 0xd2, 0xf7, 0x70, 0xfe, 0x20, 0xb0, 0x75, 0x43, 0x76, 0x9f, 0x72, 0x39, 0xb6, 0xec, 0x29, + 0xba, 0x2a, 0x1c, 0x04, 0x75, 0xd9, 0xd7, 0x43, 0xca, 0x15, 0x7d, 0x5c, 0xe0, 0x50, 0x4c, 0xcf, + 0xb7, 0xa0, 0x6c, 0x11, 0x11, 0xff, 0x03, 0x20, 0xbe, 0x3b, 0xad, 0xde, 0x79, 0xe2, 0xbb, 0x91, + 0x7b, 0x19, 0xe6, 0x05, 0x13, 0xb8, 0x6f, 0x73, 0x3c, 0x51, 0xea, 0x39, 0x65, 0x68, 0x61, 0x95, + 0x1b, 0xdd, 0xd1, 0x16, 0x63, 0xf3, 0x9c, 0x9c, 0xa6, 0x35, 0x1f, 0x59, 0xda, 0x63, 0xc5, 0x71, + 0xe4, 0x66, 0x43, 0x11, 0x0c, 0x85, 0x4d, 0xdd, 0xb1, 0x39, 0xbf, 0x66, 0xac, 0x97, 0xac, 0x72, + 0xe4, 0x79, 0xac, 0x1c, 0xbb, 0xee, 0x18, 0x6d, 0x42, 0x41, 0xf1, 0x1e, 0x55, 0x03, 0xc5, 0xcd, + 0x85, 0xa3, 0xe3, 0x55, 0xc9, 0x7c, 0x2b, 0xf2, 0xb4, 0xc7, 0x16, 0xf0, 0xf8, 0x37, 0xfa, 0x01, + 0x4a, 0xae, 0xd6, 0x04, 0x0b, 0x6d, 0x4e, 0x3d, 0xb3, 0xa0, 0xb2, 0xee, 0x1e, 0x1d, 0xaf, 0x7e, + 0xf6, 0x3e, 0xb3, 0x6b, 0x51, 0xcf, 0xc7, 0x62, 0x18, 0x12, 0xab, 0x18, 0xd7, 0x6b, 0x51, 0x0f, + 0xed, 0x43, 0xc9, 0x61, 0x23, 0xe2, 0x63, 0x5f, 0xc8, 0xf2, 0xdc, 0x2c, 0xae, 0x65, 0xd7, 0x0b, + 0x9b, 0x37, 0x4f, 0x60, 0x79, 0x3b, 0x8a, 0xdd, 0x72, 0x71, 0xa0, 0x2b, 0xe8, 0xaa, 0xdc, 0x2a, + 0x4e, 0xca, 0xb4, 0xa8, 0xc7, 0xd1, 0xc7, 0x70, 0x7e, 0xe8, 0x77, 0x98, 0xef, 0xaa, 0xbb, 0xd2, + 0x01, 0x31, 0x4b, 0x6a, 0x28, 0xa5, 0xd8, 0xda, 0xa6, 0x03, 0x82, 0xbe, 0x86, 0xb2, 0xd4, 0xc5, + 0xd0, 0x77, 0x63, 0xdd, 0x9b, 0xe7, 0x95, 0xcc, 0xae, 0x9f, 0xd0, 0x40, 0xbd, 0xbd, 0xbd, 0x9f, + 0x8a, 0xb6, 0x16, 0x3a, 0xc2, 0x49, 0x1b, 0x24, 0x72, 0x80, 0x43, 0x3c, 0xe0, 0xf6, 0x88, 0x84, + 0x6a, 0x31, 0x2f, 0x68, 0x64, 0x6d, 0x7d, 0xa2, 0x8d, 0x95, 0xdf, 0x72, 0xb0, 0xf0, 0x5a, 0x2d, + 0xa9, 0xa5, 0x54, 0xd3, 0x63, 0xbd, 0x77, 0xac, 0x42, 0xd2, 0xf2, 0xbf, 0x28, 0xcc, 0xbc, 0x0b, + 0x85, 0x3f, 0xc2, 0xe5, 0x84, 0xc2, 0x04, 0x40, 0x92, 0x99, 0x3d, 0x2d, 0x99, 0x97, 0xe2, 0xca, + 0xfb, 0x93, 0xc2, 0x92, 0x55, 0x06, 0x4b, 0x29, 0xd5, 0x4c, 0x1a, 0x96, 0x88, 0xb9, 0xd3, 0x22, + 0x2e, 0x26, 0xf2, 0x89, 0xea, 0x4a, 0xc0, 0x03, 0x58, 0x4a, 0x64, 0x94, 0xc2, 0xe3, 0xe6, 0xec, + 0x07, 0xea, 0x69, 0x31, 0xd6, 0x53, 0x02, 0xc3, 0x91, 0x03, 0xcb, 0x31, 0xce, 0xd4, 0x28, 0xf5, + 0x62, 0xc9, 0x2b, 0xb0, 0x6b, 0x27, 0x80, 0xc5, 0xd5, 0x77, 0xfd, 0x03, 0x66, 0x99, 0x93, 0x42, + 0xe9, 0xc9, 0xc9, 0x9d, 0x52, 0x69, 0xc1, 0xe5, 0x64, 0x15, 0xb3, 0x30, 0xd9, 0xc9, 0x1c, 0x7d, + 0x01, 0x39, 0x97, 0xf4, 0xb9, 0x69, 0xbc, 0x15, 0x68, 0x6a, 0x91, 0x5b, 0x2a, 0xa3, 0xb2, 0x07, + 0xcb, 0x6f, 0x2e, 0xba, 0xeb, 0xbb, 0x64, 0x8c, 0x6a, 0xb0, 0x98, 0x2c, 0x1a, 0xbb, 0x8b, 0x79, + 0x57, 0xdf, 0x48, 0x02, 0x15, 0xad, 0x0b, 0xf1, 0xca, 0xb9, 0x8f, 0x79, 0x57, 0x35, 0xf9, 0xbb, + 0x01, 0xa5, 0xa9, 0x0b, 0xa1, 0x7b, 0x90, 0x39, 0xf5, 0x63, 0x99, 0x09, 0x7a, 0xe8, 0x01, 0x64, + 0xa5, 0x52, 0x32, 0xa7, 0x55, 0x8a, 0xac, 0x52, 0xf9, 0xc5, 0x80, 0x2b, 0x27, 0x92, 0x2c, 0x1f, + 0x2a, 0x87, 0x8d, 0xce, 0xe0, 0x8d, 0x77, 0xd8, 0xa8, 0xd9, 0x93, 0x7f, 0x60, 0xac, 0x31, 0xb4, + 0xf6, 0x32, 0x6a, 0x78, 0x05, 0x1c, 0xe3, 0xf2, 0xca, 0x1f, 0x06, 0x5c, 0x69, 0x91, 0x3e, 0x71, + 0x04, 0x1d, 0x91, 0x89, 0xb4, 0x76, 0xe4, 0x97, 0x87, 0xef, 0x10, 0x74, 0x1d, 0x16, 0x5e, 0x63, + 0x41, 0xbf, 0xbb, 0x56, 0x69, 0x8a, 0x00, 0x64, 0xc1, 0x7c, 0xfc, 0xa4, 0x9d, 0xf2, 0x8d, 0x9d, + 0x8b, 0x5e, 0x33, 0xb4, 0x01, 0x17, 0x43, 0x22, 0x35, 0x19, 0x12, 0xd7, 0x8e, 0xaa, 0xf3, 0x9e, + 0x5e, 0x11, 0x56, 0x39, 0x76, 0xdd, 0x93, 0xe1, 0xad, 0xde, 0x27, 0x3b, 0x70, 0x71, 0x4a, 0x66, + 0x2d, 0x81, 0xc5, 0x90, 0xa3, 0x02, 0xcc, 0x35, 0x77, 0xf6, 0x1a, 0xbb, 0x7b, 0x5f, 0x95, 0x67, + 0x10, 0x40, 0x7e, 0x6b, 0xbb, 0xbd, 0xfb, 0x64, 0xa7, 0x6c, 0xa0, 0x22, 0x9c, 0xdb, 0xdf, 0xab, + 0x3f, 0xde, 0x6b, 0xec, 0x34, 0xca, 0x19, 0x34, 0x07, 0xd9, 0xad, 0xbd, 0x6f, 0xcb, 0xd9, 0xfa, + 0xc3, 0x67, 0x2f, 0x57, 0x8c, 0xe7, 0x2f, 0x57, 0x8c, 0xbf, 0x5e, 0xae, 0x18, 0xbf, 0xbe, 0x5a, + 0x99, 0x79, 0xfe, 0x6a, 0x65, 0xe6, 0xcf, 0x57, 0x2b, 0x33, 0xdf, 0xfd, 0xe7, 0x65, 0xc6, 0xe9, + 0x4f, 0x74, 0x75, 0xb3, 0x4e, 0x5e, 0x7d, 0xa2, 0xdf, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, + 0xf5, 0x0c, 0xdf, 0x5b, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -879,18 +876,6 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintBtcstaking(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } if m.Commission != nil { { size := m.Commission.Size() @@ -901,7 +886,7 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintBtcstaking(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } if m.Description != nil { { @@ -913,6 +898,13 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintBtcstaking(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x12 + } + if len(m.Addr) > 0 { + i -= len(m.Addr) + copy(dAtA[i:], m.Addr) + i = encodeVarintBtcstaking(dAtA, i, uint64(len(m.Addr))) + i-- dAtA[i] = 0xa } return len(dAtA) - i, nil @@ -1448,6 +1440,10 @@ func (m *FinalityProvider) Size() (n int) { } var l int _ = l + l = len(m.Addr) + if l > 0 { + n += 1 + l + sovBtcstaking(uint64(l)) + } if m.Description != nil { l = m.Description.Size() n += 1 + l + sovBtcstaking(uint64(l)) @@ -1456,10 +1452,6 @@ func (m *FinalityProvider) Size() (n int) { l = m.Commission.Size() n += 1 + l + sovBtcstaking(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() - n += 1 + l + sovBtcstaking(uint64(l)) - } if m.BtcPk != nil { l = m.BtcPk.Size() n += 1 + l + sovBtcstaking(uint64(l)) @@ -1730,9 +1722,9 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowBtcstaking @@ -1742,33 +1734,29 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthBtcstaking } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthBtcstaking } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Description == nil { - m.Description = &types.Description{} - } - if err := m.Description.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Commission", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowBtcstaking @@ -1778,33 +1766,33 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthBtcstaking } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthBtcstaking } if postIndex > l { return io.ErrUnexpectedEOF } - var v cosmossdk_io_math.LegacyDec - m.Commission = &v - if err := m.Commission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if m.Description == nil { + m.Description = &types.Description{} + } + if err := m.Description.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Commission", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowBtcstaking @@ -1814,25 +1802,25 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthBtcstaking } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthBtcstaking } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + var v cosmossdk_io_math.LegacyDec + m.Commission = &v + if err := m.Commission.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1901,7 +1889,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Pop == nil { - m.Pop = &ProofOfPossession{} + m.Pop = &ProofOfPossessionBTC{} } if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 3c8ebd5a0..21292ca0d 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -73,7 +73,7 @@ func (dc *VotingPowerDistCache) GetFinalityProviderPortion(v *FinalityProviderDi func NewFinalityProviderDistInfo(fp *FinalityProvider) *FinalityProviderDistInfo { return &FinalityProviderDistInfo{ BtcPk: fp.BtcPk, - BabylonPk: fp.BabylonPk, + Addr: fp.Addr, Commission: fp.Commission, TotalVotingPower: 0, BtcDels: []*BTCDelDistInfo{}, @@ -81,7 +81,7 @@ func NewFinalityProviderDistInfo(fp *FinalityProvider) *FinalityProviderDistInfo } func (v *FinalityProviderDistInfo) GetAddress() sdk.AccAddress { - return sdk.AccAddress(v.BabylonPk.Address()) + return sdk.MustAccAddressFromBech32(v.Addr) } func (v *FinalityProviderDistInfo) AddBTCDel(btcDel *BTCDelegation) { diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index 2a96c2a0f..4eba382f5 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -8,7 +8,6 @@ import ( fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" _ "github.com/cosmos/cosmos-proto" - secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -87,8 +86,8 @@ type FinalityProviderDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // babylon_pk is the Babylon public key of the finality provider - BabylonPk *secp256k1.PubKey `protobuf:"bytes,2,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // addr is the address to receive commission from delegations. + Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` // commission defines the commission rate of finality provider Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` // total_voting_power is the total voting power of the finality provider @@ -130,11 +129,11 @@ func (m *FinalityProviderDistInfo) XXX_DiscardUnknown() { var xxx_messageInfo_FinalityProviderDistInfo proto.InternalMessageInfo -func (m *FinalityProviderDistInfo) GetBabylonPk() *secp256k1.PubKey { +func (m *FinalityProviderDistInfo) GetAddr() string { if m != nil { - return m.BabylonPk + return m.Addr } - return nil + return "" } func (m *FinalityProviderDistInfo) GetTotalVotingPower() uint64 { @@ -229,41 +228,39 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 542 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0xcf, 0x6e, 0xd3, 0x30, - 0x1c, 0xc7, 0x9b, 0xee, 0x0f, 0xd4, 0x1d, 0xff, 0xa2, 0x22, 0x85, 0x21, 0xa5, 0xa5, 0xd2, 0x50, - 0x0f, 0xd4, 0xa1, 0x1d, 0x4c, 0xe2, 0x82, 0x20, 0xab, 0x10, 0x13, 0x9b, 0x14, 0x85, 0x89, 0x03, - 0x07, 0x22, 0xc7, 0x71, 0x13, 0x2b, 0x69, 0x1c, 0xc5, 0x5e, 0x68, 0xde, 0x82, 0x87, 0xe0, 0x11, - 0xf6, 0x10, 0x1c, 0xa7, 0x9d, 0xd0, 0x0e, 0x13, 0x6a, 0x85, 0xc4, 0x63, 0xa0, 0x24, 0x66, 0x2b, - 0x68, 0x15, 0x97, 0xdd, 0xfc, 0xf3, 0xf7, 0xfb, 0xfb, 0xf7, 0xb1, 0x0c, 0xb6, 0x5c, 0xe4, 0xe6, - 0x11, 0x8b, 0x0d, 0x57, 0x60, 0x2e, 0x50, 0x48, 0x63, 0xdf, 0xc8, 0x06, 0x06, 0x8d, 0x31, 0x89, - 0x05, 0xcd, 0x08, 0x4c, 0x52, 0x26, 0x98, 0x7a, 0x5f, 0xda, 0xe0, 0xa5, 0x0d, 0x66, 0x83, 0xcd, - 0x96, 0xcf, 0x7c, 0x56, 0x3a, 0x8c, 0xe2, 0x54, 0x99, 0x37, 0x1f, 0x60, 0xc6, 0x27, 0x8c, 0x3b, - 0x95, 0x50, 0x05, 0x52, 0xea, 0x56, 0x91, 0x81, 0xd3, 0x3c, 0x11, 0xcc, 0xe0, 0x04, 0x27, 0xc3, - 0xe7, 0x3b, 0xe1, 0xc0, 0x08, 0x49, 0x2e, 0x3d, 0xdd, 0xaf, 0x0a, 0x68, 0x7d, 0x60, 0x82, 0xc6, - 0xbe, 0xc5, 0x3e, 0x93, 0x74, 0x44, 0xb9, 0xd8, 0x45, 0x38, 0x20, 0xea, 0x13, 0xa0, 0x0a, 0x26, - 0x50, 0xe4, 0x64, 0xa5, 0xea, 0x24, 0x85, 0xac, 0x29, 0x1d, 0xa5, 0xb7, 0x6a, 0xdf, 0x2d, 0x95, - 0x85, 0x34, 0xf5, 0x13, 0x50, 0xc7, 0x34, 0x46, 0x11, 0x15, 0x79, 0x31, 0x49, 0x46, 0x3d, 0x92, - 0x72, 0xad, 0xde, 0x59, 0xe9, 0x35, 0x87, 0x06, 0xbc, 0x72, 0x1f, 0xf8, 0x46, 0x26, 0x58, 0xd2, - 0x5f, 0xf4, 0xde, 0x8b, 0xc7, 0xcc, 0xbe, 0x37, 0xfe, 0x47, 0xe1, 0xdd, 0x5f, 0x75, 0xa0, 0x2d, - 0xf3, 0xab, 0x07, 0x60, 0xdd, 0x15, 0xd8, 0x49, 0xc2, 0x72, 0xbc, 0x0d, 0x73, 0xe7, 0xec, 0xbc, - 0x3d, 0xf4, 0xa9, 0x08, 0x8e, 0x5c, 0x88, 0xd9, 0xc4, 0x90, 0xed, 0x71, 0x80, 0x68, 0xfc, 0x27, - 0x30, 0x44, 0x9e, 0x10, 0x0e, 0xcd, 0x3d, 0x6b, 0xfb, 0xd9, 0x53, 0xeb, 0xc8, 0x7d, 0x47, 0x72, - 0x7b, 0xcd, 0x15, 0xd8, 0x0a, 0xd5, 0x97, 0x00, 0x48, 0x53, 0x51, 0xb2, 0xde, 0x51, 0x7a, 0xcd, - 0x61, 0x1b, 0x4a, 0xb2, 0x15, 0x4b, 0x78, 0xc1, 0x12, 0xca, 0xdc, 0x86, 0x4c, 0xb1, 0x42, 0xf5, - 0x00, 0x00, 0xcc, 0x26, 0x13, 0xca, 0x39, 0x65, 0xb1, 0xb6, 0xd2, 0x51, 0x7a, 0x0d, 0xb3, 0x7f, - 0x76, 0xde, 0x7e, 0x58, 0x95, 0xe0, 0x5e, 0x08, 0x29, 0x33, 0x26, 0x48, 0x04, 0x70, 0x9f, 0xf8, - 0x08, 0xe7, 0x23, 0x82, 0x4f, 0x8f, 0xfb, 0x40, 0x76, 0x18, 0x11, 0x6c, 0x2f, 0x14, 0x58, 0xf2, - 0x10, 0xab, 0x4b, 0x1e, 0xe2, 0x15, 0xb8, 0x59, 0xb0, 0xf0, 0x48, 0xc4, 0xb5, 0xb5, 0x12, 0xff, - 0xd6, 0x12, 0xfc, 0xe6, 0xe1, 0xee, 0x88, 0x44, 0x17, 0xd0, 0x6f, 0xb8, 0x02, 0x8f, 0x48, 0xc4, - 0xbb, 0x3f, 0x15, 0x70, 0xfb, 0x6f, 0xed, 0xba, 0x01, 0xbf, 0x00, 0xcd, 0x62, 0x0e, 0x92, 0x3a, - 0xc8, 0xf3, 0xd2, 0x92, 0x70, 0xc3, 0xd4, 0x4e, 0x8f, 0xfb, 0x2d, 0x89, 0xe0, 0xb5, 0xe7, 0xa5, - 0x84, 0xf3, 0xf7, 0x22, 0xa5, 0xb1, 0x6f, 0x83, 0xca, 0x5c, 0x5c, 0xaa, 0x8f, 0xc1, 0x1d, 0xb9, - 0x82, 0x23, 0xa6, 0x4e, 0x80, 0x78, 0x50, 0x01, 0xb6, 0x6f, 0xc9, 0xeb, 0xc3, 0xe9, 0x5b, 0xc4, - 0x03, 0xf5, 0x11, 0xd8, 0xb8, 0x02, 0x57, 0x33, 0xbb, 0x24, 0x65, 0xee, 0x7f, 0x9b, 0xe9, 0xca, - 0xc9, 0x4c, 0x57, 0x7e, 0xcc, 0x74, 0xe5, 0xcb, 0x5c, 0xaf, 0x9d, 0xcc, 0xf5, 0xda, 0xf7, 0xb9, - 0x5e, 0xfb, 0xf8, 0xdf, 0xd5, 0xa6, 0x8b, 0x1f, 0xb8, 0xdc, 0xd3, 0x5d, 0x2f, 0xbf, 0xd3, 0xf6, - 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x48, 0xba, 0x97, 0x72, 0xe3, 0x03, 0x00, 0x00, + // 502 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0x9b, 0xae, 0x1b, 0xe0, 0x8e, 0x7f, 0x56, 0x91, 0xc2, 0x90, 0xb2, 0x52, 0x69, 0xa8, + 0x87, 0x35, 0x61, 0x1b, 0x42, 0xe2, 0x06, 0x59, 0x84, 0x98, 0xd8, 0xa4, 0x28, 0x4c, 0x1c, 0x38, + 0x10, 0x39, 0x8e, 0x9b, 0x58, 0x4d, 0xec, 0x2a, 0xf6, 0x42, 0xf3, 0x2d, 0xf8, 0x10, 0x7c, 0x84, + 0x7d, 0x08, 0x8e, 0xd3, 0x0e, 0x08, 0xed, 0x30, 0xa1, 0x56, 0x7c, 0x0f, 0x14, 0x27, 0xb0, 0x82, + 0x5a, 0xc1, 0x81, 0x9b, 0xed, 0xe7, 0x79, 0xfd, 0xbe, 0xcf, 0x4f, 0x7a, 0xc1, 0x56, 0x80, 0x82, + 0x22, 0xe1, 0xcc, 0x0a, 0x24, 0x16, 0x12, 0x8d, 0x28, 0x8b, 0xac, 0x7c, 0xc7, 0xa2, 0x0c, 0x13, + 0x26, 0x69, 0x4e, 0xcc, 0x71, 0xc6, 0x25, 0x87, 0xf7, 0x6a, 0x9b, 0x79, 0x65, 0x33, 0xf3, 0x9d, + 0x8d, 0x4e, 0xc4, 0x23, 0xae, 0x1c, 0x56, 0x79, 0xaa, 0xcc, 0x1b, 0xf7, 0x31, 0x17, 0x29, 0x17, + 0x7e, 0x25, 0x54, 0x97, 0x4a, 0xea, 0x7d, 0xd2, 0x40, 0xe7, 0x2d, 0x97, 0x94, 0x45, 0x2e, 0xff, + 0x40, 0x32, 0x87, 0x0a, 0xb9, 0x8f, 0x70, 0x4c, 0xe0, 0x36, 0x80, 0x92, 0x4b, 0x94, 0xf8, 0xb9, + 0x52, 0xfd, 0x71, 0x29, 0xeb, 0x5a, 0x57, 0xeb, 0xb7, 0xbc, 0x3b, 0x4a, 0x99, 0x2b, 0x83, 0xef, + 0x01, 0x1c, 0x52, 0x86, 0x12, 0x2a, 0x8b, 0xb2, 0x4b, 0x4e, 0x43, 0x92, 0x09, 0xbd, 0xd9, 0x5d, + 0xe9, 0xb7, 0x77, 0x2d, 0x73, 0xe1, 0xac, 0xe6, 0xcb, 0xba, 0xc0, 0xad, 0xfd, 0x65, 0xef, 0x03, + 0x36, 0xe4, 0xde, 0xdd, 0xe1, 0x1f, 0x8a, 0xe8, 0x7d, 0x69, 0x02, 0x7d, 0x99, 0x1f, 0x1e, 0x81, + 0xb5, 0x40, 0x62, 0x7f, 0x3c, 0x52, 0xe3, 0xad, 0xdb, 0x4f, 0x2f, 0x2e, 0x37, 0x77, 0x23, 0x2a, + 0xe3, 0x93, 0xc0, 0xc4, 0x3c, 0xb5, 0xea, 0xf6, 0x38, 0x46, 0x94, 0xfd, 0xbc, 0x58, 0xb2, 0x18, + 0x13, 0x61, 0xda, 0x07, 0xee, 0xde, 0x93, 0xc7, 0xee, 0x49, 0xf0, 0x9a, 0x14, 0xde, 0x6a, 0x20, + 0xb1, 0x3b, 0x82, 0xdb, 0xa0, 0x85, 0xc2, 0x30, 0xd3, 0x9b, 0x5d, 0xad, 0x7f, 0xc3, 0xd6, 0xcf, + 0x4f, 0x07, 0x9d, 0x1a, 0xd9, 0x8b, 0x30, 0xcc, 0x88, 0x10, 0x6f, 0x64, 0x46, 0x59, 0xe4, 0x29, + 0x17, 0x3c, 0x02, 0x00, 0xf3, 0x34, 0xa5, 0x42, 0x50, 0xce, 0xf4, 0x15, 0x55, 0x33, 0xb8, 0xb8, + 0xdc, 0x7c, 0x50, 0xd5, 0x88, 0x70, 0x64, 0x52, 0x6e, 0xa5, 0x48, 0xc6, 0xe6, 0x21, 0x89, 0x10, + 0x2e, 0x1c, 0x82, 0xcf, 0x4f, 0x07, 0xa0, 0xfe, 0xd2, 0x21, 0xd8, 0x9b, 0xfb, 0x60, 0x09, 0xf6, + 0xd6, 0x12, 0xec, 0xcf, 0xc1, 0xf5, 0x32, 0x79, 0x48, 0x12, 0xa1, 0xaf, 0x2a, 0xd8, 0x5b, 0x4b, + 0x60, 0xdb, 0xc7, 0xfb, 0x0e, 0x49, 0x7e, 0x21, 0xbe, 0x16, 0x48, 0xec, 0x90, 0x44, 0xf4, 0xbe, + 0x6b, 0xe0, 0xd6, 0xef, 0xda, 0xff, 0xc6, 0xf9, 0x0c, 0xb4, 0xcb, 0x39, 0x48, 0xe6, 0xff, 0x13, + 0x55, 0x50, 0x99, 0xcb, 0x47, 0xf8, 0x08, 0xdc, 0xae, 0x23, 0xf8, 0x72, 0xe2, 0xc7, 0x48, 0xc4, + 0x15, 0x60, 0xef, 0x66, 0xfd, 0x7c, 0x3c, 0x79, 0x85, 0x44, 0x0c, 0x1f, 0x82, 0xf5, 0x05, 0xb8, + 0xda, 0xf9, 0x15, 0x29, 0xfb, 0xf0, 0xf3, 0xd4, 0xd0, 0xce, 0xa6, 0x86, 0xf6, 0x6d, 0x6a, 0x68, + 0x1f, 0x67, 0x46, 0xe3, 0x6c, 0x66, 0x34, 0xbe, 0xce, 0x8c, 0xc6, 0xbb, 0xbf, 0x46, 0x9b, 0xcc, + 0xaf, 0xa2, 0xca, 0x19, 0xac, 0xa9, 0xe5, 0xd9, 0xfb, 0x11, 0x00, 0x00, 0xff, 0xff, 0x42, 0x6b, + 0x62, 0xab, 0xad, 0x03, 0x00, 0x00, } func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { @@ -359,15 +356,10 @@ func (m *FinalityProviderDistInfo) MarshalToSizedBuffer(dAtA []byte) (int, error i-- dAtA[i] = 0x1a } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintIncentive(dAtA, i, uint64(size)) - } + if len(m.Addr) > 0 { + i -= len(m.Addr) + copy(dAtA[i:], m.Addr) + i = encodeVarintIncentive(dAtA, i, uint64(len(m.Addr))) i-- dAtA[i] = 0x12 } @@ -479,8 +471,8 @@ func (m *FinalityProviderDistInfo) Size() (n int) { l = m.BtcPk.Size() n += 1 + l + sovIncentive(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() + l = len(m.Addr) + if l > 0 { n += 1 + l + sovIncentive(uint64(l)) } if m.Commission != nil { @@ -698,9 +690,9 @@ func (m *FinalityProviderDistInfo) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowIncentive @@ -710,27 +702,23 @@ func (m *FinalityProviderDistInfo) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthIncentive } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthIncentive } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 2 { diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index 9d2e86fe2..8abc851e5 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -33,9 +33,6 @@ func (m *MsgCreateFinalityProvider) ValidateBasic() error { if _, err := m.Description.EnsureLength(); err != nil { return err } - if m.BabylonPk == nil { - return fmt.Errorf("empty Babylon public key") - } if m.BtcPk == nil { return fmt.Errorf("empty BTC public key") } @@ -45,14 +42,10 @@ func (m *MsgCreateFinalityProvider) ValidateBasic() error { if m.Pop == nil { return fmt.Errorf("empty proof of possession") } - if _, err := sdk.AccAddressFromBech32(m.Signer); err != nil { - return err + if _, err := sdk.AccAddressFromBech32(m.Addr); err != nil { + return fmt.Errorf("invalid FP addr: %s - %v", m.Addr, err) } - if err := m.Pop.ValidateBasic(); err != nil { - return err - } - - return nil + return m.Pop.ValidateBasic() } func (m *MsgEditFinalityProvider) ValidateBasic() error { diff --git a/x/btcstaking/types/msg_test.go b/x/btcstaking/types/msg_test.go new file mode 100644 index 000000000..c6f66678a --- /dev/null +++ b/x/btcstaking/types/msg_test.go @@ -0,0 +1,181 @@ +package types_test + +import ( + "fmt" + "math/rand" + "testing" + + "cosmossdk.io/errors" + "github.com/babylonchain/babylon/testutil/datagen" + bbntypes "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/btcstaking/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + stktypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" +) + +func TestMsgCreateFinalityProviderValidateBasic(t *testing.T) { + r := rand.New(rand.NewSource(10)) + randBigMoniker := datagen.GenRandomHexStr(r, 100) + + bigBtcPK := datagen.GenRandomByteArray(r, 100) + + fp, err := datagen.GenRandomFinalityProvider(r) + require.NoError(t, err) + + invalidAddr := "bbnbadaddr" + + tcs := []struct { + title string + msg *types.MsgCreateFinalityProvider + expErr error + }{ + { + "valid: msg create fp", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + nil, + }, + { + "invalid: empty commission", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: nil, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + fmt.Errorf("empty commission"), + }, + { + "invalid: empty description", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: nil, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + fmt.Errorf("empty description"), + }, + { + "invalid: empty moniker", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: &stktypes.Description{ + Moniker: "", + Identity: fp.Description.Identity, + Website: fp.Description.Website, + SecurityContact: fp.Description.SecurityContact, + Details: fp.Description.Details, + }, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + fmt.Errorf("empty moniker"), + }, + { + "invalid: big moniker", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: &stktypes.Description{ + Moniker: randBigMoniker, + Identity: fp.Description.Identity, + Website: fp.Description.Website, + SecurityContact: fp.Description.SecurityContact, + Details: fp.Description.Details, + }, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid moniker length; got: %d, max: %d", len(randBigMoniker), stktypes.MaxMonikerLength), + }, + { + "invalid: empty BTC pk", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: nil, + Pop: fp.Pop, + }, + fmt.Errorf("empty BTC public key"), + }, + { + "invalid: invalid BTC pk", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: (*bbntypes.BIP340PubKey)(&bigBtcPK), + Pop: fp.Pop, + }, + fmt.Errorf("invalid BTC public key: %v", fmt.Errorf("bad pubkey byte string size (want %v, have %v)", 32, len(bigBtcPK))), + }, + { + "invalid: empty PoP", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: nil, + }, + fmt.Errorf("empty proof of possession"), + }, + { + "invalid: empty PoP", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: nil, + }, + fmt.Errorf("empty proof of possession"), + }, + { + "invalid: bad addr", + &types.MsgCreateFinalityProvider{ + Addr: invalidAddr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: fp.Pop, + }, + fmt.Errorf("invalid FP addr: %s - %v", invalidAddr, fmt.Errorf("decoding bech32 failed: invalid separator index -1")), + }, + { + "invalid: bad PoP empty sig", + &types.MsgCreateFinalityProvider{ + Addr: fp.Addr, + Description: fp.Description, + Commission: fp.Commission, + BtcPk: fp.BtcPk, + Pop: &types.ProofOfPossessionBTC{ + BtcSig: nil, + }, + }, + fmt.Errorf("empty BTC signature"), + }, + } + + for _, tc := range tcs { + tc := tc + t.Run(tc.title, func(t *testing.T) { + actErr := tc.msg.ValidateBasic() + if tc.expErr != nil { + require.EqualError(t, actErr, tc.expErr.Error()) + return + } + require.NoError(t, actErr) + }) + } +} diff --git a/x/btcstaking/types/pop.go b/x/btcstaking/types/pop.go index 75e457c6e..dd5a562ae 100644 --- a/x/btcstaking/types/pop.go +++ b/x/btcstaking/types/pop.go @@ -15,7 +15,6 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/cometbft/cometbft/crypto/tmhash" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -25,38 +24,6 @@ type bip322Sign[A btcutil.Address] func(sg []byte, privKey *btcec.PrivateKey, net *chaincfg.Params) (A, []byte, error) -// NewPoP generates a new proof of possession that sk_Babylon and sk_BTC are held by the same person -// a proof of possession contains two signatures: -// - pop.BabylonSig = sign(sk_Babylon, pk_BTC) -// - pop.BtcSig = schnorr_sign(sk_BTC, pop.BabylonSig) -func NewPoP(babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKey) (*ProofOfPossession, error) { - pop := ProofOfPossession{ - BtcSigType: BTCSigType_BIP340, // by default, we use BIP-340 encoding for BTC signature - } - - // generate pop.BabylonSig = sign(sk_Babylon, pk_BTC) - btcPK := btcSK.PubKey() - bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - babylonSig, err := babylonSK.Sign(*bip340PK) - if err != nil { - return nil, err - } - pop.BabylonSig = babylonSig - - // generate pop.BtcSig = schnorr_sign(sk_BTC, pop.BabylonSig) - // NOTE: *schnorr.Sign has to take the hash of the message. - // So we have to hash babylonSig before signing - babylonSigHash := tmhash.Sum(pop.BabylonSig) - btcSig, err := schnorr.Sign(btcSK, babylonSigHash) - if err != nil { - return nil, err - } - bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig) - pop.BtcSig = bip340Sig.MustMarshal() - - return &pop, nil -} - // NewPoPBTC generates a new proof of possession that sk_BTC and the address are held by the same person // a proof of possession contains only one signature // - pop.BtcSig = schnorr_sign(sk_BTC, bbnAddress) @@ -79,37 +46,6 @@ func NewPoPBTC(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*ProofOfPossession return &pop, nil } -// NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format -// a proof of possession contains two signatures: -// - pop.BabylonSig = sign(sk_Babylon, pk_BTC) -// - pop.BtcSig = ecdsa_sign(sk_BTC, pop.BabylonSig) -func NewPoPWithECDSABTCSig(babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKey) (*ProofOfPossession, error) { - pop := ProofOfPossession{ - BtcSigType: BTCSigType_ECDSA, - } - - // generate pop.BabylonSig = sign(sk_Babylon, pk_BTC) - btcPK := btcSK.PubKey() - bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - babylonSig, err := babylonSK.Sign(*bip340PK) - if err != nil { - return nil, err - } - pop.BabylonSig = babylonSig - - // generate pop.BtcSig = ecdsa_sign(sk_BTC, pop.BabylonSig) - // NOTE: ecdsa.Sign has to take the message as string. - // So we have to hex babylonSig before signing - babylonSigHex := hex.EncodeToString(pop.BabylonSig) - btcSig, err := ecdsa.Sign(btcSK, babylonSigHex) - if err != nil { - return nil, err - } - pop.BtcSig = btcSig - - return &pop, nil -} - // NewPoPWithECDSABTCSig generates a new proof of possession where Bitcoin signature is in ECDSA format // a proof of possession contains two signatures: // - pop.BtcSig = ecdsa_sign(sk_BTC, addr) @@ -131,46 +67,6 @@ func NewPoPBTCWithECDSABTCSig(addr sdk.AccAddress, btcSK *btcec.PrivateKey) (*Pr return &pop, nil } -func babylonSigToHexHash(babylonSig []byte) []byte { - babylonSigHash := tmhash.Sum(babylonSig) - babylonSigHashHex := hex.EncodeToString(babylonSigHash) - babylonSigHashHexBytes := []byte(babylonSigHashHex) - return babylonSigHashHexBytes -} - -func newPoPWithBIP322Sig[A btcutil.Address]( - babylonSK cryptotypes.PrivKey, - btcSK *btcec.PrivateKey, - net *chaincfg.Params, - bip322SignFn bip322Sign[A], -) (*ProofOfPossession, error) { - pop := ProofOfPossession{ - BtcSigType: BTCSigType_BIP322, - } - - // generate pop.BabylonSig = sign(sk_Babylon, pk_BTC) - btcPK := btcSK.PubKey() - bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - babylonSig, err := babylonSK.Sign(*bip340PK) - if err != nil { - return nil, err - } - pop.BabylonSig = babylonSig - - // TODO: temporary solution for MVP purposes. - // Eventually we need to use tmhash.Sum(pop.BabylonSig) rather than bbnSigHashHexBytes - // ref: https://github.com/babylonchain/babylon/issues/433 - bbnSigHashHexBytes := babylonSigToHexHash(pop.BabylonSig) - - bip322SigEncoded, err := newBIP322Sig(bbnSigHashHexBytes, btcSK, net, bip322SignFn) - if err != nil { - return nil, err - } - pop.BtcSig = bip322SigEncoded - - return &pop, nil -} - func newPoPBTCWithBIP322Sig[A btcutil.Address]( addressToSign sdk.AccAddress, btcSK *btcec.PrivateKey, @@ -214,14 +110,6 @@ func newBIP322Sig[A btcutil.Address]( return bip322Sig.Marshal() } -func NewPoPWithBIP322P2WPKHSig( - babylonSK cryptotypes.PrivKey, - btcSK *btcec.PrivateKey, - net *chaincfg.Params, -) (*ProofOfPossession, error) { - return newPoPWithBIP322Sig(babylonSK, btcSK, net, bip322.SignWithP2WPKHAddress) -} - // NewPoPBTCWithBIP322P2WPKHSig creates a proof of possession of type BIP322 // that signs the address with the BTC secret key. func NewPoPBTCWithBIP322P2WPKHSig( @@ -232,26 +120,6 @@ func NewPoPBTCWithBIP322P2WPKHSig( return newPoPBTCWithBIP322Sig(addr, btcSK, net, bip322.SignWithP2WPKHAddress) } -func NewPoPWithBIP322P2TRBIP86Sig( - babylonSK cryptotypes.PrivKey, - btcSK *btcec.PrivateKey, - net *chaincfg.Params, -) (*ProofOfPossession, error) { - return newPoPWithBIP322Sig(babylonSK, btcSK, net, bip322.SignWithP2TrSpendAddress) -} - -func NewPoPFromHex(popHex string) (*ProofOfPossession, error) { - popBytes, err := hex.DecodeString(popHex) - if err != nil { - return nil, err - } - var pop ProofOfPossession - if err := pop.Unmarshal(popBytes); err != nil { - return nil, err - } - return &pop, nil -} - func NewPoPBTCFromHex(popHex string) (*ProofOfPossessionBTC, error) { popBytes, err := hex.DecodeString(popHex) if err != nil { @@ -264,14 +132,6 @@ func NewPoPBTCFromHex(popHex string) (*ProofOfPossessionBTC, error) { return &pop, nil } -func (pop *ProofOfPossession) ToHexStr() (string, error) { - popBytes, err := pop.Marshal() - if err != nil { - return "", err - } - return hex.EncodeToString(popBytes), nil -} - func (pop *ProofOfPossessionBTC) ToHexStr() (string, error) { popBytes, err := pop.Marshal() if err != nil { @@ -280,19 +140,6 @@ func (pop *ProofOfPossessionBTC) ToHexStr() (string, error) { return hex.EncodeToString(popBytes), nil } -func (pop *ProofOfPossession) Verify(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { - switch pop.BtcSigType { - case BTCSigType_BIP340: - return pop.VerifyBIP340(babylonPK, bip340PK) - case BTCSigType_BIP322: - return pop.VerifyBIP322(babylonPK, bip340PK, net) - case BTCSigType_ECDSA: - return pop.VerifyECDSA(babylonPK, bip340PK) - default: - return fmt.Errorf("invalid BTC signature type") - } -} - // Verify that the BTC private key corresponding to the bip340PK signed the staker address func (pop *ProofOfPossessionBTC) Verify(staker sdk.AccAddress, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { switch pop.BtcSigType { @@ -342,20 +189,12 @@ func (pop *ProofOfPossessionBTC) VerifyBIP340(stakerAddr sdk.AccAddress, bip340P return VerifyBIP340(pop.BtcSigType, pop.BtcSig, bip340PK, stakerAddr.Bytes()) } -// VerifyBIP340 verifies the validity of PoP where Bitcoin signature is in BIP-340 -// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? -// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? -func (pop *ProofOfPossession) VerifyBIP340(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { - if err := VerifyBIP340(pop.BtcSigType, pop.BtcSig, bip340PK, pop.BabylonSig); err != nil { - return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) - } - - // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? - if !babylonPK.VerifySignature(*bip340PK, pop.BabylonSig) { - return fmt.Errorf("failed to verify pop.BabylonSig") - } - - return nil +func NewPoPBTCWithBIP322P2TRBIP86Sig( + addrToSign sdk.AccAddress, + btcSK *btcec.PrivateKey, + net *chaincfg.Params, +) (*ProofOfPossessionBTC, error) { + return newPoPBTCWithBIP322Sig(addrToSign, btcSK, net, bip322.SignWithP2TrSpendAddress) } // isSupportedAddressAndWitness checks whether provided address and witness are @@ -521,27 +360,6 @@ func VerifyBIP322(sigType BTCSigType, btcSigRaw []byte, bip340PK *bbn.BIP340PubK return nil } -// VerifyBIP322 verifies the validity of PoP where Bitcoin signature is in BIP-322 -// after decoding pop.BtcSig to bip322Sig which contains sig and address, -// 1. verify whether bip322 pop signature where msg=pop.BabylonSig -// 2. verify(sig=pop.BabylonSig, pubkey=babylonPK, msg=bip340PK)? -func (pop *ProofOfPossession) VerifyBIP322(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey, net *chaincfg.Params) error { - // TODO: temporary solution for MVP purposes. - // Eventually we need to use tmhash.Sum(pop.BabylonSig) rather than bbnSigHashHexBytes - // ref: https://github.com/babylonchain/babylon/issues/433 - bbnSigHashHexBytes := babylonSigToHexHash(pop.BabylonSig) - if err := VerifyBIP322(pop.BtcSigType, pop.BtcSig, bip340PK, bbnSigHashHexBytes, net); err != nil { - return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) - } - - // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? - if !babylonPK.VerifySignature(*bip340PK, pop.BabylonSig) { - return fmt.Errorf("failed to verify pop.BabylonSig") - } - - return nil -} - // VerifyBIP322 verifies the validity of PoP where Bitcoin signature is in BIP-322 // after decoding pop.BtcSig to bip322Sig which contains sig and address, // 1. verify whether bip322 pop signature where msg=pop.BabylonSig @@ -576,39 +394,12 @@ func VerifyECDSA(sigType BTCSigType, btcSigRaw []byte, bip340PK *bbn.BIP340PubKe return nil } -// VerifyECDSA verifies the validity of PoP where Bitcoin signature is in ECDSA encoding -// 1. verify(sig=sig_btc, pubkey=pk_btc, msg=pop.BabylonSig)? -// 2. verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? -func (pop *ProofOfPossession) VerifyECDSA(babylonPK cryptotypes.PubKey, bip340PK *bbn.BIP340PubKey) error { - if err := VerifyECDSA(pop.BtcSigType, pop.BtcSig, bip340PK, pop.BabylonSig); err != nil { - return fmt.Errorf("failed to verify possession of babylon sig by the BTC key: %w", err) - } - - // rule 2: verify(sig=pop.BabylonSig, pubkey=pk_babylon, msg=pk_btc)? - if !babylonPK.VerifySignature(*bip340PK, pop.BabylonSig) { - return fmt.Errorf("failed to verify pop.BabylonSig") - } - - return nil -} - // VerifyECDSA verifies the validity of PoP where Bitcoin signature is in ECDSA encoding // 1. verify(sig=sig_btc, pubkey=pk_btc, msg=addr)? func (pop *ProofOfPossessionBTC) VerifyECDSA(addr sdk.AccAddress, bip340PK *bbn.BIP340PubKey) error { return VerifyECDSA(pop.BtcSigType, pop.BtcSig, bip340PK, addr.Bytes()) } -func (pop *ProofOfPossession) ValidateBasic() error { - if len(pop.BabylonSig) == 0 { - return fmt.Errorf("empty Babylon signature") - } - if pop.BtcSig == nil { - return fmt.Errorf("empty BTC signature") - } - - return nil -} - // ValidateBasic checks if there is a BTC Signature. func (pop *ProofOfPossessionBTC) ValidateBasic() error { if pop.BtcSig == nil { diff --git a/x/btcstaking/types/pop.pb.go b/x/btcstaking/types/pop.pb.go index bf7cbafa4..32bfca102 100644 --- a/x/btcstaking/types/pop.pb.go +++ b/x/btcstaking/types/pop.pb.go @@ -55,73 +55,6 @@ func (BTCSigType) EnumDescriptor() ([]byte, []int) { return fileDescriptor_9d6ceb088d9e9f3a, []int{0} } -// ProofOfPossession is the proof of possession that a Babylon secp256k1 -// secret key and a Bitcoin secp256k1 secret key are held by the same -// person -type ProofOfPossession struct { - // btc_sig_type indicates the type of btc_sig in the pop - BtcSigType BTCSigType `protobuf:"varint,1,opt,name=btc_sig_type,json=btcSigType,proto3,enum=babylon.btcstaking.v1.BTCSigType" json:"btc_sig_type,omitempty"` - // babylon_sig is the signature generated via sign(sk_babylon, pk_btc) - BabylonSig []byte `protobuf:"bytes,2,opt,name=babylon_sig,json=babylonSig,proto3" json:"babylon_sig,omitempty"` - // btc_sig is the signature generated via sign(sk_btc, babylon_sig) - // the signature follows encoding in either BIP-340 spec or BIP-322 spec - BtcSig []byte `protobuf:"bytes,3,opt,name=btc_sig,json=btcSig,proto3" json:"btc_sig,omitempty"` -} - -func (m *ProofOfPossession) Reset() { *m = ProofOfPossession{} } -func (m *ProofOfPossession) String() string { return proto.CompactTextString(m) } -func (*ProofOfPossession) ProtoMessage() {} -func (*ProofOfPossession) Descriptor() ([]byte, []int) { - return fileDescriptor_9d6ceb088d9e9f3a, []int{0} -} -func (m *ProofOfPossession) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *ProofOfPossession) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_ProofOfPossession.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 *ProofOfPossession) XXX_Merge(src proto.Message) { - xxx_messageInfo_ProofOfPossession.Merge(m, src) -} -func (m *ProofOfPossession) XXX_Size() int { - return m.Size() -} -func (m *ProofOfPossession) XXX_DiscardUnknown() { - xxx_messageInfo_ProofOfPossession.DiscardUnknown(m) -} - -var xxx_messageInfo_ProofOfPossession proto.InternalMessageInfo - -func (m *ProofOfPossession) GetBtcSigType() BTCSigType { - if m != nil { - return m.BtcSigType - } - return BTCSigType_BIP340 -} - -func (m *ProofOfPossession) GetBabylonSig() []byte { - if m != nil { - return m.BabylonSig - } - return nil -} - -func (m *ProofOfPossession) GetBtcSig() []byte { - if m != nil { - return m.BtcSig - } - return nil -} - // ProofOfPossessionBTC is the proof of possession that a Babylon // address and a Bitcoin secp256k1 secret key are held by the same // person @@ -137,7 +70,7 @@ func (m *ProofOfPossessionBTC) Reset() { *m = ProofOfPossessionBTC{} } func (m *ProofOfPossessionBTC) String() string { return proto.CompactTextString(m) } func (*ProofOfPossessionBTC) ProtoMessage() {} func (*ProofOfPossessionBTC) Descriptor() ([]byte, []int) { - return fileDescriptor_9d6ceb088d9e9f3a, []int{1} + return fileDescriptor_9d6ceb088d9e9f3a, []int{0} } func (m *ProofOfPossessionBTC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -193,7 +126,7 @@ func (m *BIP322Sig) Reset() { *m = BIP322Sig{} } func (m *BIP322Sig) String() string { return proto.CompactTextString(m) } func (*BIP322Sig) ProtoMessage() {} func (*BIP322Sig) Descriptor() ([]byte, []int) { - return fileDescriptor_9d6ceb088d9e9f3a, []int{2} + return fileDescriptor_9d6ceb088d9e9f3a, []int{1} } func (m *BIP322Sig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -238,7 +171,6 @@ func (m *BIP322Sig) GetSig() []byte { func init() { proto.RegisterEnum("babylon.btcstaking.v1.BTCSigType", BTCSigType_name, BTCSigType_value) - proto.RegisterType((*ProofOfPossession)(nil), "babylon.btcstaking.v1.ProofOfPossession") proto.RegisterType((*ProofOfPossessionBTC)(nil), "babylon.btcstaking.v1.ProofOfPossessionBTC") proto.RegisterType((*BIP322Sig)(nil), "babylon.btcstaking.v1.BIP322Sig") } @@ -246,69 +178,25 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/pop.proto", fileDescriptor_9d6ceb088d9e9f3a) } var fileDescriptor_9d6ceb088d9e9f3a = []byte{ - // 317 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0x4a, 0x4c, 0xaa, - 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x2e, 0x2e, 0x49, 0xcc, 0xce, 0xcc, 0x4b, 0xd7, 0x2f, - 0x33, 0xd4, 0x2f, 0xc8, 0x2f, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x85, 0x2a, 0xd0, - 0x43, 0x28, 0xd0, 0x2b, 0x33, 0x54, 0x9a, 0xc4, 0xc8, 0x25, 0x18, 0x50, 0x94, 0x9f, 0x9f, 0xe6, - 0x9f, 0x16, 0x90, 0x5f, 0x5c, 0x9c, 0x5a, 0x5c, 0x9c, 0x99, 0x9f, 0x27, 0xe4, 0xcc, 0xc5, 0x93, - 0x54, 0x92, 0x1c, 0x5f, 0x9c, 0x99, 0x1e, 0x5f, 0x52, 0x59, 0x90, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, - 0xc1, 0x67, 0xa4, 0xa8, 0x87, 0xd5, 0x0c, 0x3d, 0xa7, 0x10, 0xe7, 0xe0, 0xcc, 0xf4, 0x90, 0xca, - 0x82, 0xd4, 0x20, 0xae, 0xa4, 0x92, 0x64, 0x28, 0x5b, 0x48, 0x9e, 0x8b, 0x1b, 0xaa, 0x1e, 0x64, - 0x90, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x17, 0x54, 0x28, 0x38, 0x33, 0x5d, 0x48, 0x9c, - 0x8b, 0x1d, 0x6a, 0x8b, 0x04, 0x33, 0x58, 0x92, 0x0d, 0xa2, 0x5b, 0xa9, 0x84, 0x4b, 0x04, 0xc3, - 0x4d, 0x4e, 0x21, 0xce, 0xd4, 0x71, 0x16, 0x92, 0xad, 0x4c, 0x28, 0xb6, 0x9a, 0x73, 0x71, 0x3a, - 0x79, 0x06, 0x18, 0x1b, 0x19, 0x81, 0xdc, 0x26, 0xc1, 0xc5, 0x9e, 0x98, 0x92, 0x52, 0x94, 0x5a, - 0x5c, 0x0c, 0xb6, 0x85, 0x33, 0x08, 0xc6, 0x15, 0x12, 0xe0, 0x62, 0x46, 0xe8, 0x05, 0x31, 0xb5, - 0xf4, 0xb9, 0xb8, 0x10, 0x76, 0x09, 0x71, 0x71, 0xb1, 0x81, 0x8c, 0x31, 0x31, 0x10, 0x60, 0x80, - 0xb1, 0x8d, 0x8c, 0x04, 0x18, 0x85, 0x38, 0xb9, 0x58, 0x5d, 0x9d, 0x5d, 0x82, 0x1d, 0x05, 0x98, - 0x9c, 0x7c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, - 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x28, 0x3d, 0xb3, - 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, 0x3f, 0x57, 0x1f, 0xea, 0xab, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, - 0x18, 0x47, 0xbf, 0x02, 0x39, 0x82, 0x41, 0x81, 0x50, 0x9c, 0xc4, 0x06, 0x8e, 0x60, 0x63, 0x40, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x71, 0x75, 0x81, 0xa6, 0x03, 0x02, 0x00, 0x00, -} - -func (m *ProofOfPossession) 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 *ProofOfPossession) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *ProofOfPossession) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.BtcSig) > 0 { - i -= len(m.BtcSig) - copy(dAtA[i:], m.BtcSig) - i = encodeVarintPop(dAtA, i, uint64(len(m.BtcSig))) - i-- - dAtA[i] = 0x1a - } - if len(m.BabylonSig) > 0 { - i -= len(m.BabylonSig) - copy(dAtA[i:], m.BabylonSig) - i = encodeVarintPop(dAtA, i, uint64(len(m.BabylonSig))) - i-- - dAtA[i] = 0x12 - } - if m.BtcSigType != 0 { - i = encodeVarintPop(dAtA, i, uint64(m.BtcSigType)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil + // 285 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4b, 0xc3, 0x30, + 0x1c, 0xc5, 0x9b, 0x89, 0x1b, 0xfb, 0x33, 0xa4, 0x04, 0xc5, 0x9d, 0xe2, 0xdc, 0x69, 0x78, 0x48, + 0x5c, 0x26, 0x78, 0xb6, 0xd5, 0x83, 0x20, 0x38, 0xd6, 0x9e, 0xbc, 0x8c, 0xa6, 0xeb, 0xba, 0xa0, + 0x36, 0xa5, 0x89, 0xc3, 0x7e, 0x0b, 0x3f, 0x96, 0xc7, 0x1d, 0x3d, 0x4a, 0xfb, 0x45, 0xa4, 0xb3, + 0xa5, 0x1e, 0xbc, 0xbd, 0x47, 0x5e, 0xde, 0xe3, 0xff, 0x83, 0x33, 0x11, 0x88, 0xfc, 0x45, 0x25, + 0x4c, 0x98, 0x50, 0x9b, 0xe0, 0x59, 0x26, 0x31, 0xdb, 0x4e, 0x59, 0xaa, 0x52, 0x9a, 0x66, 0xca, + 0x28, 0x7c, 0x52, 0x07, 0x68, 0x1b, 0xa0, 0xdb, 0xe9, 0xd8, 0xc0, 0xf1, 0x3c, 0x53, 0x6a, 0xfd, + 0xb8, 0x9e, 0x2b, 0xad, 0x23, 0xad, 0xa5, 0x4a, 0x1c, 0xdf, 0xc5, 0x2e, 0x0c, 0x84, 0x09, 0x97, + 0x5a, 0xc6, 0x4b, 0x93, 0xa7, 0xd1, 0x10, 0x8d, 0xd0, 0xe4, 0x88, 0x9f, 0xd3, 0x7f, 0x5b, 0xa8, + 0xe3, 0xbb, 0x9e, 0x8c, 0xfd, 0x3c, 0x8d, 0x16, 0x20, 0x4c, 0x58, 0x6b, 0x7c, 0x0a, 0xbd, 0xba, + 0x64, 0xd8, 0x19, 0xa1, 0xc9, 0x60, 0xd1, 0xfd, 0x7d, 0x1c, 0x5f, 0x43, 0xdf, 0xb9, 0x9f, 0xcf, + 0x38, 0xf7, 0x64, 0x8c, 0x87, 0xd0, 0x0b, 0x56, 0xab, 0x2c, 0xd2, 0x7a, 0xbf, 0xd2, 0x5f, 0x34, + 0x16, 0xdb, 0x70, 0xd0, 0xfe, 0xad, 0xe4, 0x05, 0x03, 0x68, 0xb7, 0x30, 0x40, 0xb7, 0xaa, 0xb9, + 0xba, 0xb4, 0xad, 0x46, 0x73, 0x6e, 0x23, 0xdc, 0x87, 0xc3, 0x3b, 0xf7, 0xd6, 0xbb, 0xb1, 0x3b, + 0xce, 0xc3, 0x67, 0x41, 0xd0, 0xae, 0x20, 0xe8, 0xbb, 0x20, 0xe8, 0xa3, 0x24, 0xd6, 0xae, 0x24, + 0xd6, 0x57, 0x49, 0xac, 0x27, 0x1e, 0x4b, 0xb3, 0x79, 0x13, 0x34, 0x54, 0xaf, 0xac, 0xbe, 0x2a, + 0xdc, 0x04, 0x32, 0x69, 0x0c, 0x7b, 0xff, 0xcb, 0xb2, 0x82, 0xa0, 0x45, 0x77, 0xcf, 0x72, 0xf6, + 0x13, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x31, 0xf3, 0x97, 0x6e, 0x01, 0x00, 0x00, } func (m *ProofOfPossessionBTC) Marshal() (dAtA []byte, err error) { @@ -394,26 +282,6 @@ func encodeVarintPop(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *ProofOfPossession) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.BtcSigType != 0 { - n += 1 + sovPop(uint64(m.BtcSigType)) - } - l = len(m.BabylonSig) - if l > 0 { - n += 1 + l + sovPop(uint64(l)) - } - l = len(m.BtcSig) - if l > 0 { - n += 1 + l + sovPop(uint64(l)) - } - return n -} - func (m *ProofOfPossessionBTC) Size() (n int) { if m == nil { return 0 @@ -453,143 +321,6 @@ func sovPop(x uint64) (n int) { func sozPop(x uint64) (n int) { return sovPop(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *ProofOfPossession) 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 ErrIntOverflowPop - } - 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: ProofOfPossession: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: ProofOfPossession: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field BtcSigType", wireType) - } - m.BtcSigType = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPop - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.BtcSigType |= BTCSigType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonSig", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPop - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthPop - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthPop - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BabylonSig = append(m.BabylonSig[:0], dAtA[iNdEx:postIndex]...) - if m.BabylonSig == nil { - m.BabylonSig = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BtcSig", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPop - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthPop - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthPop - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.BtcSig = append(m.BtcSig[:0], dAtA[iNdEx:postIndex]...) - if m.BtcSig == nil { - m.BtcSig = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPop(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPop - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} func (m *ProofOfPossessionBTC) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/btcstaking/types/pop_test.go b/x/btcstaking/types/pop_test.go index c4f0e7f5e..dc58f6dfd 100644 --- a/x/btcstaking/types/pop_test.go +++ b/x/btcstaking/types/pop_test.go @@ -7,12 +7,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg" - "github.com/cometbft/cometbft/crypto/tmhash" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/babylonchain/babylon/testutil/datagen" @@ -24,35 +20,11 @@ var ( net = &chaincfg.TestNet3Params ) -func newInvalidBIP340PoP(r *rand.Rand, babylonSK cryptotypes.PrivKey, btcSK *btcec.PrivateKey) *types.ProofOfPossession { - pop := types.ProofOfPossession{} - - randomNum := datagen.RandomInt(r, 2) // 0 or 1 - - btcPK := btcSK.PubKey() - bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - babylonSig, err := babylonSK.Sign(*bip340PK) - if err != nil { - panic(err) - } - - var babylonSigHash []byte - if randomNum == 0 { - pop.BabylonSig = babylonSig // correct sig - babylonSigHash = datagen.GenRandomByteArray(r, 32) // fake sig hash - } else { - pop.BabylonSig = datagen.GenRandomByteArray(r, uint64(len(babylonSig))) // fake sig - babylonSigHash = tmhash.Sum(pop.BabylonSig) // correct sig hash - } - - btcSig, err := schnorr.Sign(btcSK, babylonSigHash) - if err != nil { - panic(err) +func newInvalidBIP340PoP(r *rand.Rand) *types.ProofOfPossessionBTC { + return &types.ProofOfPossessionBTC{ + BtcSigType: types.BTCSigType_BIP340, + BtcSig: datagen.GenRandomByteArray(r, 32), // fake sig hash } - bip340Sig := bbn.NewBIP340SignatureFromBTCSig(btcSig) - pop.BtcSig = bip340Sig.MustMarshal() - - return &pop } func FuzzPoP_BIP340(f *testing.F) { @@ -66,19 +38,17 @@ func FuzzPoP_BIP340(f *testing.F) { require.NoError(t, err) bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - // generate Babylon key pair - babylonSK, babylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + accAddr := datagen.GenRandomAccount().GetAddress() // generate and verify PoP, correct case - pop, err := types.NewPoP(babylonSK, btcSK) + pop, err := types.NewPoPBTC(accAddr, btcSK) require.NoError(t, err) - err = pop.VerifyBIP340(babylonPK, bip340PK) + err = pop.VerifyBIP340(accAddr, bip340PK) require.NoError(t, err) // generate and verify PoP, invalid case - invalidPoP := newInvalidBIP340PoP(r, babylonSK, btcSK) - err = invalidPoP.VerifyBIP340(babylonPK, bip340PK) + invalidPoP := newInvalidBIP340PoP(r) + err = invalidPoP.VerifyBIP340(accAddr, bip340PK) require.Error(t, err) }) } @@ -94,14 +64,12 @@ func FuzzPoP_ECDSA(f *testing.F) { require.NoError(t, err) bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - // generate Babylon key pair - babylonSK, babylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + accAddr := datagen.GenRandomAccount().GetAddress() // generate and verify PoP, correct case - pop, err := types.NewPoPWithECDSABTCSig(babylonSK, btcSK) + pop, err := types.NewPoPBTCWithECDSABTCSig(accAddr, btcSK) require.NoError(t, err) - err = pop.VerifyECDSA(babylonPK, bip340PK) + err = pop.VerifyECDSA(accAddr, bip340PK) require.NoError(t, err) }) } @@ -117,14 +85,12 @@ func FuzzPoP_BIP322_P2WPKH(f *testing.F) { require.NoError(t, err) bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - // generate Babylon key pair - babylonSK, babylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + accAddr := datagen.GenRandomAccount().GetAddress() // generate and verify PoP, correct case - pop, err := types.NewPoPWithBIP322P2WPKHSig(babylonSK, btcSK, net) + pop, err := types.NewPoPBTCWithBIP322P2WPKHSig(accAddr, btcSK, net) require.NoError(t, err) - err = pop.VerifyBIP322(babylonPK, bip340PK, net) + err = pop.VerifyBIP322(accAddr, bip340PK, net) require.NoError(t, err) }) } @@ -140,14 +106,12 @@ func FuzzPoP_BIP322_P2Tr_BIP86(f *testing.F) { require.NoError(t, err) bip340PK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - // generate Babylon key pair - babylonSK, babylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + accAddr := datagen.GenRandomAccount().GetAddress() // generate and verify PoP, correct case - pop, err := types.NewPoPWithBIP322P2TRBIP86Sig(babylonSK, btcSK, net) + pop, err := types.NewPoPBTCWithBIP322P2TRBIP86Sig(accAddr, btcSK, net) require.NoError(t, err) - err = pop.VerifyBIP322(babylonPK, bip340PK, net) + err = pop.VerifyBIP322(accAddr, bip340PK, net) require.NoError(t, err) }) } @@ -167,24 +131,22 @@ func FuzzPop_ValidBip322SigNotMatchingBip340PubKey(f *testing.F) { require.NoError(t, err) bip340PK1 := bbn.NewBIP340PubKeyFromBTCPK(btcPK1) - // generate Babylon key pair - babylonSK, babylonPK, err := datagen.GenRandomSecp256k1KeyPair(r) - require.NoError(t, err) + accAddr := datagen.GenRandomAccount().GetAddress() // generate valid bip322 P2WPKH pop - pop, err := types.NewPoPWithBIP322P2WPKHSig(babylonSK, btcSK, net) + pop, err := types.NewPoPBTCWithBIP322P2WPKHSig(accAddr, btcSK, net) require.NoError(t, err) // verify bip322 pop with incorrect staker key - err = pop.VerifyBIP322(babylonPK, bip340PK1, net) + err = pop.VerifyBIP322(accAddr, bip340PK1, net) require.Error(t, err) // generate valid bip322 P2Tr pop - pop, err = types.NewPoPWithBIP322P2TRBIP86Sig(babylonSK, btcSK, net) + pop, err = types.NewPoPBTCWithBIP322P2TRBIP86Sig(accAddr, btcSK, net) require.NoError(t, err) // verify bip322 pop with incorrect staker key - err = pop.VerifyBIP322(babylonPK, bip340PK1, net) + err = pop.VerifyBIP322(accAddr, bip340PK1, net) require.Error(t, err) }) } diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index a84af7070..717228035 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -61,7 +61,7 @@ func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPowe return &FinalityProviderResponse{ Description: f.Description, Commission: f.Commission, - BabylonPk: f.BabylonPk, + Addr: f.Addr, BtcPk: f.BtcPk, Pop: f.Pop, SlashedBabylonHeight: f.SlashedBabylonHeight, diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 767f3dbbc..ac26ddef0 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -9,7 +9,6 @@ import ( fmt "fmt" github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" _ "github.com/cosmos/cosmos-proto" - secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" query "github.com/cosmos/cosmos-sdk/types/query" types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" @@ -1485,13 +1484,14 @@ type FinalityProviderResponse struct { Description *types.Description `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` // commission defines the commission rate of the finality provider. Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,2,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` - // babylon_pk is the Babylon secp256k1 PK of this finality provider - BabylonPk *secp256k1.PubKey `protobuf:"bytes,3,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` + // addr is the address to receive commission from delegations. + Addr string `protobuf:"bytes,3,opt,name=addr,proto3" json:"addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` + // pop is the proof of possession of the BTC_PK by the fp addr. + // Essentially is the signature where the BTC SK sigs the fp addr. + Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` // slashed_babylon_height indicates the Babylon height when // the finality provider is slashed. // if it's 0 then the finality provider is not slashed @@ -1546,14 +1546,14 @@ func (m *FinalityProviderResponse) GetDescription() *types.Description { return nil } -func (m *FinalityProviderResponse) GetBabylonPk() *secp256k1.PubKey { +func (m *FinalityProviderResponse) GetAddr() string { if m != nil { - return m.BabylonPk + return m.Addr } - return nil + return "" } -func (m *FinalityProviderResponse) GetPop() *ProofOfPossession { +func (m *FinalityProviderResponse) GetPop() *ProofOfPossessionBTC { if m != nil { return m.Pop } @@ -1620,127 +1620,124 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1906 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4f, 0x6c, 0x13, 0xd9, - 0x19, 0x67, 0x92, 0x60, 0xc8, 0xe7, 0x24, 0x84, 0xb7, 0x01, 0x06, 0x87, 0xc4, 0x30, 0x65, 0x21, - 0xb0, 0xe0, 0x21, 0x26, 0x50, 0x75, 0xb7, 0x05, 0x62, 0xb2, 0x0b, 0xec, 0x12, 0xe1, 0x4e, 0xa0, - 0x95, 0xba, 0x55, 0xad, 0xf1, 0xf8, 0x79, 0x3c, 0x4a, 0x3c, 0x6f, 0x98, 0xf7, 0x9c, 0xda, 0x42, - 0xb9, 0xf4, 0xd0, 0x5b, 0xa5, 0x4a, 0xed, 0xa9, 0x52, 0xcf, 0xad, 0xd4, 0x63, 0x39, 0x55, 0xea, - 0x7d, 0x7b, 0x5b, 0xb1, 0x87, 0x56, 0x1c, 0x50, 0x05, 0x55, 0x2b, 0x55, 0xea, 0xb5, 0xe7, 0x6a, - 0xde, 0x7b, 0xe3, 0x19, 0xdb, 0x33, 0x8e, 0x1d, 0xd2, 0x5b, 0xfc, 0xde, 0xf7, 0xef, 0xf7, 0x7d, - 0xdf, 0xfb, 0xbd, 0x79, 0x5f, 0xe0, 0x42, 0xd5, 0xac, 0x76, 0x76, 0x88, 0xab, 0x57, 0x99, 0x45, - 0x99, 0xb9, 0xed, 0xb8, 0xb6, 0xbe, 0xbb, 0xaa, 0x3f, 0x6f, 0x61, 0xbf, 0x53, 0xf0, 0x7c, 0xc2, - 0x08, 0x3a, 0x25, 0x45, 0x0a, 0x91, 0x48, 0x61, 0x77, 0x35, 0xb7, 0x60, 0x13, 0x9b, 0x70, 0x09, - 0x3d, 0xf8, 0x4b, 0x08, 0xe7, 0xce, 0xd9, 0x84, 0xd8, 0x3b, 0x58, 0x37, 0x3d, 0x47, 0x37, 0x5d, - 0x97, 0x30, 0x93, 0x39, 0xc4, 0xa5, 0x72, 0xf7, 0xac, 0x45, 0x68, 0x93, 0xd0, 0x8a, 0x50, 0x13, - 0x3f, 0xe4, 0x96, 0x26, 0x7e, 0xe9, 0x96, 0xdf, 0xf1, 0x18, 0xd1, 0x29, 0xb6, 0xbc, 0xe2, 0xad, - 0xdb, 0xdb, 0xab, 0xfa, 0x36, 0xee, 0x84, 0x32, 0x17, 0xa5, 0x4c, 0x14, 0x68, 0x15, 0x33, 0x73, - 0x35, 0xfc, 0x2d, 0xa5, 0xae, 0x4a, 0xa9, 0xaa, 0x49, 0xb1, 0x00, 0xd2, 0x15, 0xf4, 0x4c, 0xdb, - 0x71, 0x79, 0x44, 0xa1, 0xd7, 0x64, 0xf8, 0x9e, 0xe9, 0x9b, 0xcd, 0xd0, 0xeb, 0xa5, 0x64, 0x99, - 0x58, 0x36, 0x84, 0x5c, 0x3e, 0xc5, 0x16, 0xf1, 0x84, 0x80, 0xb6, 0x00, 0xe8, 0xfb, 0x41, 0x38, - 0x65, 0x6e, 0xdd, 0xc0, 0xcf, 0x5b, 0x98, 0x32, 0xcd, 0x80, 0x0f, 0x7a, 0x56, 0xa9, 0x47, 0x5c, - 0x8a, 0xd1, 0x27, 0x90, 0x11, 0x51, 0xa8, 0xca, 0x79, 0x65, 0x25, 0x5b, 0x5c, 0x2a, 0x24, 0x96, - 0xa1, 0x20, 0xd4, 0x4a, 0x53, 0x5f, 0xbd, 0xc9, 0x1f, 0x31, 0xa4, 0x8a, 0xf6, 0x6d, 0x58, 0x8c, - 0xd9, 0x2c, 0x75, 0x7e, 0x80, 0x7d, 0xea, 0x10, 0x57, 0xba, 0x44, 0x2a, 0x1c, 0xdb, 0x15, 0x2b, - 0xdc, 0xf8, 0xac, 0x11, 0xfe, 0xd4, 0xbe, 0x84, 0x73, 0xc9, 0x8a, 0x87, 0x11, 0x95, 0x0d, 0x4b, - 0xdc, 0xf8, 0x67, 0x8e, 0x6b, 0xee, 0x38, 0xac, 0x53, 0xf6, 0xc9, 0xae, 0x53, 0xc3, 0x7e, 0x98, - 0x0a, 0xf4, 0x19, 0x40, 0x54, 0x21, 0xe9, 0xe1, 0x52, 0x41, 0xb6, 0x49, 0x50, 0xce, 0x82, 0xe8, - 0x4b, 0x59, 0xce, 0x42, 0xd9, 0xb4, 0xb1, 0xd4, 0x35, 0x62, 0x9a, 0xda, 0x5f, 0x14, 0x58, 0x4e, - 0xf3, 0x24, 0x81, 0xfc, 0x04, 0x50, 0x5d, 0x6e, 0x06, 0xdd, 0x28, 0x76, 0x55, 0xe5, 0xfc, 0xe4, - 0x4a, 0xb6, 0xa8, 0xa7, 0x80, 0xea, 0xb7, 0x16, 0x1a, 0x33, 0x4e, 0xd6, 0xfb, 0xfd, 0xa0, 0x07, - 0x3d, 0x50, 0x26, 0x38, 0x94, 0xcb, 0xfb, 0x42, 0x91, 0xf6, 0xe2, 0x58, 0xd6, 0x65, 0x45, 0x06, - 0x9d, 0x8b, 0x9c, 0x5d, 0x80, 0xd9, 0xba, 0x57, 0xa9, 0x32, 0xab, 0xe2, 0x6d, 0x57, 0x1a, 0xb8, - 0xcd, 0xd3, 0x36, 0x6d, 0x40, 0xdd, 0x2b, 0x31, 0xab, 0xbc, 0xfd, 0x10, 0xb7, 0xb5, 0xbd, 0x94, - 0xbc, 0x77, 0x93, 0xf1, 0x63, 0x38, 0x39, 0x90, 0x0c, 0x99, 0xfe, 0xb1, 0x73, 0x31, 0xdf, 0x9f, - 0x0b, 0xed, 0xf7, 0x0a, 0xe4, 0xb8, 0xff, 0xd2, 0xd3, 0xfb, 0x1b, 0x78, 0x07, 0xdb, 0x82, 0x12, - 0x42, 0x00, 0x25, 0xc8, 0x50, 0x66, 0xb2, 0x96, 0x68, 0xa9, 0xb9, 0xe2, 0xd5, 0x14, 0x8f, 0x3d, - 0xda, 0x5b, 0x5c, 0xc3, 0x90, 0x9a, 0x7d, 0x8d, 0x33, 0x71, 0xe0, 0xc6, 0xf9, 0xb3, 0x22, 0x0f, - 0x4e, 0x7f, 0xa8, 0x32, 0x51, 0xcf, 0xe0, 0x44, 0x90, 0xe9, 0x5a, 0xb4, 0x25, 0x5b, 0xe6, 0xda, - 0x28, 0x41, 0x77, 0x73, 0x34, 0x57, 0x65, 0x56, 0xcc, 0xfc, 0xe1, 0x35, 0x4b, 0x1d, 0xae, 0x24, - 0x56, 0xba, 0x4c, 0x7e, 0x8a, 0xfd, 0x75, 0xf6, 0x10, 0x3b, 0x76, 0x83, 0x8d, 0xde, 0x39, 0xe8, - 0x34, 0x64, 0x1a, 0x5c, 0x87, 0x07, 0x35, 0x65, 0xc8, 0x5f, 0xda, 0x13, 0xb8, 0x3a, 0x8a, 0x1f, - 0x99, 0xb5, 0x0b, 0x30, 0xb3, 0x4b, 0x98, 0xe3, 0xda, 0x15, 0x2f, 0xd8, 0xe7, 0x7e, 0xa6, 0x8c, - 0xac, 0x58, 0xe3, 0x2a, 0xda, 0x26, 0xac, 0x24, 0x1a, 0xbc, 0xdf, 0xf2, 0x7d, 0xec, 0x32, 0x2e, - 0x34, 0x46, 0xc7, 0xa7, 0xe5, 0xa1, 0xd7, 0x9c, 0x0c, 0x2f, 0x02, 0xa9, 0xc4, 0x41, 0x0e, 0x84, - 0x3d, 0x31, 0x18, 0xf6, 0x2f, 0x14, 0xf8, 0x88, 0x3b, 0x5a, 0xb7, 0x98, 0xb3, 0x8b, 0x07, 0xe8, - 0xa6, 0x3f, 0xe5, 0x69, 0xae, 0x0e, 0xab, 0x7f, 0xff, 0xaa, 0xc0, 0xb5, 0xd1, 0xe2, 0x39, 0x44, - 0x1a, 0xfc, 0xa1, 0xc3, 0x1a, 0x9b, 0x98, 0x99, 0xff, 0x57, 0x1a, 0x5c, 0x92, 0x07, 0x93, 0x03, - 0x33, 0x19, 0xae, 0xf5, 0x24, 0x56, 0xbb, 0x2d, 0x59, 0x72, 0x60, 0x7b, 0x78, 0x8d, 0xb5, 0x5f, - 0x2b, 0x70, 0x39, 0xb1, 0x53, 0x12, 0x88, 0x6a, 0x84, 0xf3, 0x72, 0x58, 0x75, 0xfc, 0x97, 0x92, - 0x72, 0x1e, 0x92, 0x48, 0xc9, 0x87, 0xb3, 0x31, 0x52, 0x22, 0x7e, 0x02, 0x3d, 0xdd, 0xde, 0x97, - 0x9e, 0x48, 0x92, 0x69, 0xe3, 0x4c, 0x44, 0x54, 0x3d, 0x02, 0x87, 0x57, 0xd7, 0xcf, 0xe1, 0xec, - 0x20, 0xe1, 0x86, 0x19, 0xbf, 0x0e, 0x1f, 0xc8, 0x60, 0x2b, 0xac, 0x5d, 0x69, 0x98, 0xb4, 0x11, - 0xcb, 0xfb, 0xbc, 0xdc, 0x7a, 0xda, 0x7e, 0x68, 0xd2, 0x46, 0x70, 0xea, 0x9f, 0x27, 0xdd, 0x33, - 0xdd, 0x34, 0x6d, 0xc1, 0x5c, 0x2f, 0x77, 0xcb, 0x1b, 0x6e, 0x3c, 0xea, 0x9e, 0xed, 0xa1, 0x6e, - 0xed, 0x9b, 0x0c, 0x9c, 0x4a, 0x76, 0xf7, 0x1d, 0xc8, 0x06, 0xc6, 0xb0, 0x5f, 0x31, 0x6b, 0x35, - 0xc1, 0x79, 0xd3, 0x25, 0xf5, 0xd5, 0xcb, 0xeb, 0x0b, 0x32, 0x4b, 0xeb, 0xb5, 0x9a, 0x8f, 0x29, - 0xdd, 0x62, 0xbe, 0xe3, 0xda, 0x06, 0x08, 0xe1, 0x60, 0x11, 0x6d, 0x42, 0x46, 0x74, 0x19, 0x4f, - 0xec, 0x4c, 0xe9, 0xf6, 0xeb, 0x37, 0xf9, 0xa2, 0xed, 0xb0, 0x46, 0xab, 0x5a, 0xb0, 0x48, 0x53, - 0x97, 0xf1, 0x5a, 0x0d, 0xd3, 0x71, 0xc3, 0x1f, 0x3a, 0xeb, 0x78, 0x98, 0x16, 0x4a, 0x8f, 0xca, - 0x37, 0xd7, 0x6e, 0x94, 0x5b, 0xd5, 0x2f, 0x70, 0xc7, 0x38, 0x5a, 0x0d, 0xfa, 0x12, 0x7d, 0x09, - 0x73, 0x51, 0xdf, 0xee, 0x38, 0x94, 0xa9, 0x93, 0xe7, 0x27, 0xdf, 0xc3, 0x6c, 0x56, 0x36, 0xfc, - 0x63, 0x87, 0x1f, 0x8a, 0x19, 0xca, 0x4c, 0x9f, 0x55, 0xe4, 0xf1, 0x9a, 0x12, 0x24, 0xc9, 0xd7, - 0xc4, 0x19, 0x44, 0x4b, 0x00, 0xd8, 0xad, 0x85, 0x02, 0x47, 0xb9, 0xc0, 0x34, 0x76, 0xe5, 0x11, - 0x45, 0x8b, 0x30, 0xcd, 0x08, 0x33, 0x77, 0x2a, 0xd4, 0x64, 0x6a, 0x86, 0xef, 0x1e, 0xe7, 0x0b, - 0x5b, 0x26, 0x43, 0x17, 0x61, 0x2e, 0xde, 0x01, 0xb8, 0xad, 0x1e, 0xe3, 0xc5, 0x9f, 0x89, 0x8a, - 0x8f, 0xdb, 0xe8, 0x12, 0x9c, 0xa0, 0x3b, 0x26, 0x6d, 0xc4, 0xc4, 0x8e, 0x73, 0xb1, 0xd9, 0x70, - 0x59, 0xc8, 0xdd, 0x82, 0x33, 0xd1, 0x29, 0xe1, 0x5b, 0x15, 0xea, 0xd8, 0x5c, 0x7e, 0x9a, 0xcb, - 0x2f, 0x74, 0xb7, 0xb7, 0x82, 0xdd, 0x2d, 0xc7, 0x0e, 0xd4, 0x9e, 0xc1, 0xac, 0x45, 0x76, 0xb1, - 0x6b, 0xba, 0x2c, 0x90, 0xa7, 0x2a, 0xf0, 0x43, 0x75, 0x23, 0xa5, 0x71, 0xee, 0x4b, 0xd9, 0xf5, - 0x9a, 0xe9, 0x05, 0x96, 0x1c, 0xdb, 0x35, 0x59, 0xcb, 0xc7, 0xd4, 0x98, 0x09, 0xcd, 0x6c, 0x39, - 0x36, 0x45, 0xd7, 0x00, 0x85, 0xd8, 0x48, 0x8b, 0x79, 0x2d, 0x56, 0x71, 0x6a, 0x6d, 0x35, 0xcb, - 0x3f, 0xc8, 0xc3, 0xe6, 0x7e, 0xc2, 0x37, 0x1e, 0xd5, 0xf8, 0x55, 0x6c, 0x72, 0x52, 0x57, 0x67, - 0xce, 0x2b, 0x2b, 0xc7, 0x0d, 0xf9, 0x0b, 0xe5, 0x79, 0x9f, 0xb1, 0x16, 0xad, 0xd4, 0x30, 0xb5, - 0xd4, 0x59, 0xc1, 0x49, 0x62, 0x69, 0x03, 0x53, 0x0b, 0x7d, 0x08, 0x73, 0x2d, 0xb7, 0x4a, 0xdc, - 0x1a, 0xcf, 0x8e, 0xd3, 0xc4, 0xea, 0x1c, 0x77, 0x31, 0xdb, 0x5d, 0x7d, 0xea, 0x34, 0x31, 0xb2, - 0xe0, 0x54, 0xcb, 0x8d, 0x0e, 0x47, 0xc5, 0x97, 0x8d, 0xac, 0x9e, 0xe0, 0xa7, 0xa4, 0x90, 0x7e, - 0x4a, 0x9e, 0xc5, 0xd4, 0xba, 0xe7, 0x64, 0xa1, 0x95, 0xb0, 0x1a, 0xc4, 0x22, 0xde, 0x02, 0x95, - 0xf0, 0xfd, 0x31, 0x2f, 0x62, 0x11, 0xab, 0xf2, 0xb5, 0xa1, 0xbd, 0x9c, 0x84, 0x33, 0x29, 0x86, - 0xd1, 0x0a, 0xcc, 0xc7, 0xe0, 0xb4, 0x63, 0x84, 0x10, 0xc1, 0x14, 0xd5, 0xfe, 0x1e, 0x2c, 0x46, - 0xd5, 0x8e, 0x74, 0xc2, 0x8a, 0x4f, 0x70, 0x25, 0xb5, 0x2b, 0xf2, 0x2c, 0x94, 0x90, 0x55, 0xb7, - 0x60, 0xb1, 0x5b, 0xf5, 0x5e, 0xed, 0xee, 0x19, 0xca, 0x16, 0x2f, 0xa6, 0xa4, 0xa5, 0x5b, 0xf4, - 0x47, 0x6e, 0x9d, 0x18, 0x6a, 0x68, 0x28, 0xee, 0x83, 0x1f, 0x9f, 0x84, 0xce, 0x9d, 0x4a, 0xea, - 0xdc, 0x4f, 0x20, 0xd7, 0xd7, 0xb9, 0x71, 0x28, 0x47, 0xb9, 0xca, 0x99, 0xde, 0xe6, 0x8d, 0x90, - 0xd4, 0xe1, 0x74, 0xd4, 0xbf, 0x31, 0x5d, 0xaa, 0x66, 0x0e, 0xd8, 0xc8, 0x0b, 0xdd, 0x46, 0x8e, - 0x3c, 0x51, 0xcd, 0x82, 0xfc, 0x3e, 0x17, 0x0a, 0xba, 0x07, 0x53, 0x35, 0xbc, 0x73, 0xb0, 0xaf, - 0x66, 0xae, 0xa9, 0xfd, 0x66, 0x0a, 0xd4, 0xd4, 0x87, 0xcc, 0xa7, 0x90, 0x0d, 0x4e, 0x81, 0xef, - 0x78, 0x31, 0x82, 0xff, 0x56, 0x78, 0x2f, 0x45, 0x1e, 0xc4, 0xa5, 0xb4, 0x11, 0x89, 0x1a, 0x71, - 0x3d, 0xb4, 0x09, 0x60, 0x91, 0x66, 0xd3, 0xa1, 0x34, 0xbc, 0xdd, 0xa6, 0x4b, 0xd7, 0x5f, 0xbf, - 0xc9, 0x2f, 0x0a, 0x43, 0xb4, 0xb6, 0x5d, 0x70, 0x88, 0xde, 0x34, 0x59, 0xa3, 0xf0, 0x18, 0xdb, - 0xa6, 0xd5, 0xd9, 0xc0, 0xd6, 0xab, 0x97, 0xd7, 0x41, 0xfa, 0xd9, 0xc0, 0x96, 0x11, 0x33, 0x80, - 0xee, 0x00, 0x48, 0x9c, 0x01, 0xa7, 0x4f, 0xf2, 0xa0, 0xf2, 0x61, 0x50, 0x62, 0xde, 0x51, 0xe8, - 0xce, 0x3b, 0x0a, 0x92, 0x65, 0xa7, 0xa5, 0x4a, 0x79, 0x3b, 0x76, 0x1f, 0x4c, 0x1d, 0xc6, 0x7d, - 0xf0, 0x31, 0x4c, 0x7a, 0xc4, 0xe3, 0x4d, 0x93, 0x2d, 0xae, 0xa4, 0x3d, 0xe0, 0x7d, 0x42, 0xea, - 0x4f, 0xea, 0x65, 0x42, 0x29, 0xe6, 0x28, 0x8c, 0x40, 0x09, 0xad, 0xc1, 0x69, 0xde, 0x41, 0xb8, - 0x56, 0x09, 0x21, 0x49, 0x5e, 0x17, 0xcc, 0xbd, 0x20, 0x77, 0x4b, 0x62, 0x53, 0x52, 0x7c, 0xc0, - 0x74, 0xa1, 0x16, 0xb3, 0x42, 0x8d, 0x63, 0x5c, 0x63, 0x3e, 0xd4, 0x60, 0x96, 0x94, 0x8e, 0xbe, - 0xd5, 0x8e, 0x0f, 0xfd, 0x1e, 0x9f, 0x1e, 0xf8, 0x1e, 0x2f, 0xfe, 0xf6, 0x24, 0x1c, 0xe5, 0x9f, - 0x00, 0xe8, 0xe7, 0x0a, 0x64, 0xc4, 0x10, 0x02, 0x5d, 0x49, 0x81, 0x38, 0x38, 0x8b, 0xc9, 0x5d, - 0x1d, 0x45, 0x54, 0xf4, 0x9a, 0xf6, 0xe1, 0xcf, 0xbe, 0xf9, 0xc7, 0xaf, 0x26, 0xf2, 0x68, 0x49, - 0x1f, 0x36, 0x43, 0x42, 0x7f, 0x50, 0xe0, 0x44, 0xdf, 0x34, 0x05, 0x15, 0xf7, 0x77, 0xd3, 0x3f, - 0xb3, 0xc9, 0xdd, 0x1c, 0x4b, 0x47, 0xc6, 0xa8, 0xf3, 0x18, 0xaf, 0xa0, 0xcb, 0x43, 0x63, 0xd4, - 0x5f, 0x48, 0x36, 0xde, 0x43, 0x7f, 0x54, 0xe0, 0xe4, 0xc0, 0xab, 0x01, 0xad, 0x0d, 0xf3, 0x9d, - 0x36, 0xcd, 0xc9, 0xdd, 0x1a, 0x53, 0x4b, 0xc6, 0xbc, 0xca, 0x63, 0xfe, 0x08, 0x5d, 0x49, 0x89, - 0x79, 0xf0, 0xbd, 0x82, 0x5e, 0x29, 0x30, 0xdf, 0x6f, 0x10, 0xdd, 0x1c, 0xc7, 0x7d, 0x18, 0xf3, - 0xda, 0x78, 0x4a, 0x32, 0xe4, 0x2d, 0x1e, 0xf2, 0x26, 0xfa, 0x62, 0xe4, 0x90, 0xf5, 0x17, 0x3d, - 0x4f, 0x89, 0xbd, 0x41, 0x11, 0xf4, 0x3b, 0x05, 0xe6, 0x7a, 0xc7, 0x10, 0x68, 0x75, 0x58, 0x74, - 0x89, 0xd3, 0x95, 0x5c, 0x71, 0x1c, 0x15, 0x09, 0xa7, 0xc0, 0xe1, 0xac, 0xa0, 0x4b, 0x7a, 0xea, - 0xe4, 0x33, 0xfe, 0xc6, 0x40, 0xff, 0x54, 0x20, 0xbf, 0xcf, 0x83, 0x13, 0x95, 0x86, 0xc5, 0x31, - 0xda, 0xeb, 0x39, 0x77, 0xff, 0xbd, 0x6c, 0x48, 0x70, 0x1f, 0x73, 0x70, 0x6b, 0xa8, 0x38, 0x46, - 0xad, 0x04, 0x01, 0xed, 0xa1, 0xff, 0x2a, 0xb0, 0x34, 0x74, 0xe4, 0x81, 0xee, 0x8d, 0xd3, 0x3f, - 0x49, 0x53, 0x99, 0xdc, 0xfa, 0x7b, 0x58, 0x90, 0x10, 0xcb, 0x1c, 0xe2, 0xe7, 0xe8, 0xe1, 0xc1, - 0xdb, 0x91, 0x33, 0x6c, 0x04, 0xfc, 0xdf, 0x0a, 0x9c, 0x1b, 0x36, 0x4b, 0x41, 0x77, 0xc7, 0x89, - 0x3a, 0x61, 0xa8, 0x93, 0xbb, 0x77, 0x70, 0x03, 0x12, 0xf5, 0x03, 0x8e, 0x7a, 0x1d, 0xdd, 0x7d, - 0x4f, 0xd4, 0x9c, 0xb1, 0xfb, 0xe6, 0x08, 0xc3, 0x19, 0x3b, 0x79, 0x26, 0x31, 0x9c, 0xb1, 0x53, - 0x06, 0x15, 0xfb, 0x32, 0xb6, 0x19, 0xea, 0xc9, 0x5b, 0x14, 0xfd, 0x47, 0x81, 0xc5, 0x21, 0x53, - 0x02, 0x74, 0x67, 0x9c, 0xc4, 0x26, 0x10, 0xc8, 0xdd, 0x03, 0xeb, 0x4b, 0x44, 0x9b, 0x1c, 0xd1, - 0x03, 0xf4, 0xe9, 0xc1, 0xeb, 0x12, 0x27, 0x9b, 0x3f, 0x29, 0x30, 0xdb, 0xc3, 0x5b, 0xe8, 0xc6, - 0xc8, 0x14, 0x17, 0x62, 0x5a, 0x1d, 0x43, 0x43, 0xa2, 0xd8, 0xe0, 0x28, 0xee, 0xa0, 0xef, 0x8e, - 0xc6, 0x89, 0xfa, 0x8b, 0x84, 0xc1, 0xc5, 0x5e, 0xe9, 0xf1, 0x57, 0x6f, 0x97, 0x95, 0xaf, 0xdf, - 0x2e, 0x2b, 0x7f, 0x7f, 0xbb, 0xac, 0xfc, 0xf2, 0xdd, 0xf2, 0x91, 0xaf, 0xdf, 0x2d, 0x1f, 0xf9, - 0xdb, 0xbb, 0xe5, 0x23, 0x3f, 0xda, 0xf7, 0x7b, 0xae, 0x1d, 0x77, 0xc8, 0x3f, 0xee, 0xaa, 0x19, - 0xfe, 0x6f, 0xa5, 0x9b, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x80, 0xf7, 0x24, 0x06, 0xc4, 0x1b, - 0x00, 0x00, + // 1870 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6c, 0xdb, 0xc8, + 0x19, 0x0e, 0x6d, 0x45, 0x89, 0x7f, 0xd9, 0x8e, 0x33, 0xeb, 0x24, 0x8c, 0x1c, 0xdb, 0x09, 0x9b, + 0x4d, 0x9c, 0x97, 0x18, 0x2b, 0xde, 0x14, 0xed, 0x76, 0x37, 0xb1, 0xec, 0xdd, 0x24, 0xbb, 0x31, + 0xa2, 0xd2, 0x49, 0x0b, 0x74, 0x8b, 0x12, 0x14, 0x39, 0xa2, 0x88, 0x58, 0x24, 0xc3, 0x19, 0xb9, + 0x32, 0x02, 0x5f, 0x7a, 0xe8, 0xa5, 0x28, 0x50, 0xa0, 0xbd, 0xf6, 0xdc, 0x02, 0x3d, 0x36, 0xa7, + 0x02, 0xbd, 0x6f, 0x6f, 0x8b, 0xec, 0xa1, 0xc5, 0x1e, 0x82, 0x22, 0x29, 0x5a, 0xa0, 0x40, 0xaf, + 0x3d, 0x17, 0x9c, 0x19, 0x8a, 0x94, 0x44, 0xea, 0x61, 0xbb, 0x37, 0x71, 0xe6, 0x7f, 0x3f, 0xbe, + 0x99, 0xf9, 0x05, 0x97, 0x6a, 0x46, 0x6d, 0x6f, 0xc7, 0x73, 0xd5, 0x1a, 0x35, 0x09, 0x35, 0x9e, + 0x3b, 0xae, 0xad, 0xee, 0xae, 0xaa, 0x2f, 0x5a, 0x38, 0xd8, 0x2b, 0xf9, 0x81, 0x47, 0x3d, 0x74, + 0x46, 0x90, 0x94, 0x62, 0x92, 0xd2, 0xee, 0x6a, 0x71, 0xde, 0xf6, 0x6c, 0x8f, 0x51, 0xa8, 0xe1, + 0x2f, 0x4e, 0x5c, 0xbc, 0x60, 0x7b, 0x9e, 0xbd, 0x83, 0x55, 0xc3, 0x77, 0x54, 0xc3, 0x75, 0x3d, + 0x6a, 0x50, 0xc7, 0x73, 0x89, 0xd8, 0x3d, 0x6f, 0x7a, 0xa4, 0xe9, 0x11, 0x9d, 0xb3, 0xf1, 0x0f, + 0xb1, 0x75, 0x99, 0x7f, 0xa9, 0xb1, 0x11, 0x35, 0x4c, 0x8d, 0xd5, 0xe8, 0x5b, 0x50, 0x5d, 0x17, + 0x54, 0x35, 0x83, 0x60, 0x6e, 0x64, 0x87, 0xd0, 0x37, 0x6c, 0xc7, 0x65, 0xda, 0x04, 0xad, 0x92, + 0xee, 0x9a, 0x6f, 0x04, 0x46, 0x33, 0xd2, 0x7a, 0x25, 0x9d, 0x26, 0xe1, 0x29, 0xa7, 0x5b, 0xce, + 0x90, 0xe5, 0xf9, 0x9c, 0x40, 0x99, 0x07, 0xf4, 0xfd, 0xd0, 0x9c, 0x2a, 0x93, 0xae, 0xe1, 0x17, + 0x2d, 0x4c, 0xa8, 0xa2, 0xc1, 0x7b, 0x5d, 0xab, 0xc4, 0xf7, 0x5c, 0x82, 0xd1, 0x87, 0x90, 0xe7, + 0x56, 0xc8, 0xd2, 0x45, 0x69, 0xa5, 0x50, 0x5e, 0x2c, 0xa5, 0x86, 0xb8, 0xc4, 0xd9, 0x2a, 0xb9, + 0x2f, 0xdf, 0x2c, 0x1f, 0xd3, 0x04, 0x8b, 0xf2, 0x6d, 0x58, 0x48, 0xc8, 0xac, 0xec, 0xfd, 0x00, + 0x07, 0xc4, 0xf1, 0x5c, 0xa1, 0x12, 0xc9, 0x70, 0x62, 0x97, 0xaf, 0x30, 0xe1, 0x33, 0x5a, 0xf4, + 0xa9, 0x7c, 0x01, 0x17, 0xd2, 0x19, 0x8f, 0xc2, 0x2a, 0x1b, 0x16, 0x99, 0xf0, 0x4f, 0x1d, 0xd7, + 0xd8, 0x71, 0xe8, 0x5e, 0x35, 0xf0, 0x76, 0x1d, 0x0b, 0x07, 0x51, 0x28, 0xd0, 0xa7, 0x00, 0x71, + 0x86, 0x84, 0x86, 0x2b, 0x25, 0x51, 0x02, 0x61, 0x3a, 0x4b, 0xbc, 0xe6, 0x44, 0x3a, 0x4b, 0x55, + 0xc3, 0xc6, 0x82, 0x57, 0x4b, 0x70, 0x2a, 0x7f, 0x91, 0x60, 0x29, 0x4b, 0x93, 0x70, 0xe4, 0x27, + 0x80, 0xea, 0x62, 0x33, 0xac, 0x34, 0xbe, 0x2b, 0x4b, 0x17, 0x27, 0x57, 0x0a, 0x65, 0x35, 0xc3, + 0xa9, 0x5e, 0x69, 0x91, 0x30, 0xed, 0x74, 0xbd, 0x57, 0x0f, 0x7a, 0xd0, 0xe5, 0xca, 0x04, 0x73, + 0xe5, 0xea, 0x50, 0x57, 0x84, 0xbc, 0xa4, 0x2f, 0xeb, 0x22, 0x23, 0xfd, 0xca, 0x79, 0xcc, 0x2e, + 0xc1, 0x4c, 0xdd, 0xd7, 0x6b, 0xd4, 0xd4, 0xfd, 0xe7, 0x7a, 0x03, 0xb7, 0x59, 0xd8, 0xa6, 0x34, + 0xa8, 0xfb, 0x15, 0x6a, 0x56, 0x9f, 0x3f, 0xc4, 0x6d, 0x65, 0x3f, 0x23, 0xee, 0x9d, 0x60, 0xfc, + 0x18, 0x4e, 0xf7, 0x05, 0x43, 0x84, 0x7f, 0xec, 0x58, 0xcc, 0xf5, 0xc6, 0x42, 0xf9, 0xbd, 0x04, + 0x45, 0xa6, 0xbf, 0xf2, 0x74, 0x63, 0x13, 0xef, 0x60, 0x9b, 0xb7, 0x7b, 0xe4, 0x40, 0x05, 0xf2, + 0x84, 0x1a, 0xb4, 0xc5, 0x4b, 0x6a, 0xb6, 0x7c, 0x3d, 0x43, 0x63, 0x17, 0xf7, 0x36, 0xe3, 0xd0, + 0x04, 0x67, 0x4f, 0xe1, 0x4c, 0x1c, 0xb8, 0x70, 0xfe, 0x2c, 0x89, 0xc6, 0xe9, 0x35, 0x55, 0x04, + 0xea, 0x19, 0x9c, 0x0a, 0x23, 0x6d, 0xc5, 0x5b, 0xa2, 0x64, 0x6e, 0x8e, 0x62, 0x74, 0x27, 0x46, + 0xb3, 0x35, 0x6a, 0x26, 0xc4, 0x1f, 0x5d, 0xb1, 0xd4, 0xe1, 0x5a, 0x6a, 0xa6, 0xab, 0xde, 0x4f, + 0x71, 0xb0, 0x4e, 0x1f, 0x62, 0xc7, 0x6e, 0xd0, 0xd1, 0x2b, 0x07, 0x9d, 0x85, 0x7c, 0x83, 0xf1, + 0x30, 0xa3, 0x72, 0x9a, 0xf8, 0x52, 0x9e, 0xc0, 0xf5, 0x51, 0xf4, 0x88, 0xa8, 0x5d, 0x82, 0xe9, + 0x5d, 0x8f, 0x3a, 0xae, 0xad, 0xfb, 0xe1, 0x3e, 0xd3, 0x93, 0xd3, 0x0a, 0x7c, 0x8d, 0xb1, 0x28, + 0x5b, 0xb0, 0x92, 0x2a, 0x70, 0xa3, 0x15, 0x04, 0xd8, 0xa5, 0x8c, 0x68, 0x8c, 0x8a, 0xcf, 0x8a, + 0x43, 0xb7, 0x38, 0x61, 0x5e, 0xec, 0xa4, 0x94, 0x74, 0xb2, 0xcf, 0xec, 0x89, 0x7e, 0xb3, 0x7f, + 0x29, 0xc1, 0x0d, 0xa6, 0x68, 0xdd, 0xa4, 0xce, 0x2e, 0xee, 0x83, 0x9b, 0xde, 0x90, 0x67, 0xa9, + 0x3a, 0xaa, 0xfa, 0xfd, 0xab, 0x04, 0x37, 0x47, 0xb3, 0xe7, 0x08, 0x61, 0xf0, 0x87, 0x0e, 0x6d, + 0x6c, 0x61, 0x6a, 0xfc, 0x5f, 0x61, 0x70, 0x51, 0x34, 0x26, 0x73, 0xcc, 0xa0, 0xd8, 0xea, 0x0a, + 0xac, 0x72, 0x57, 0xa0, 0x64, 0xdf, 0xf6, 0xe0, 0x1c, 0x2b, 0xbf, 0x91, 0xe0, 0x6a, 0x6a, 0xa5, + 0xa4, 0x00, 0xd5, 0x08, 0xfd, 0x72, 0x54, 0x79, 0xfc, 0x97, 0x94, 0xd1, 0x0f, 0x69, 0xa0, 0x14, + 0xc0, 0xf9, 0x04, 0x28, 0x79, 0x41, 0x0a, 0x3c, 0xdd, 0x1d, 0x0a, 0x4f, 0x5e, 0x9a, 0x68, 0xed, + 0x5c, 0x0c, 0x54, 0x5d, 0x04, 0x47, 0x97, 0xd7, 0xcf, 0xe0, 0x7c, 0x3f, 0xe0, 0x46, 0x11, 0xbf, + 0x05, 0xef, 0x09, 0x63, 0x75, 0xda, 0xd6, 0x1b, 0x06, 0x69, 0x24, 0xe2, 0x3e, 0x27, 0xb6, 0x9e, + 0xb6, 0x1f, 0x1a, 0xa4, 0x11, 0x76, 0xfd, 0x8b, 0xb4, 0x73, 0xa6, 0x13, 0xa6, 0x6d, 0x98, 0xed, + 0xc6, 0x6e, 0x71, 0xc2, 0x8d, 0x07, 0xdd, 0x33, 0x5d, 0xd0, 0xad, 0x7c, 0x9d, 0x87, 0x33, 0xe9, + 0xea, 0xbe, 0x03, 0x85, 0x50, 0x18, 0x0e, 0x74, 0xc3, 0xb2, 0x38, 0xe6, 0x4d, 0x55, 0xe4, 0xd7, + 0xaf, 0x6e, 0xcd, 0x8b, 0x28, 0xad, 0x5b, 0x56, 0x80, 0x09, 0xd9, 0xa6, 0x81, 0xe3, 0xda, 0x1a, + 0x70, 0xe2, 0x70, 0x11, 0x6d, 0x41, 0x9e, 0x57, 0x19, 0x0b, 0xec, 0x74, 0xe5, 0xee, 0x37, 0x6f, + 0x96, 0xcb, 0xb6, 0x43, 0x1b, 0xad, 0x5a, 0xc9, 0xf4, 0x9a, 0xaa, 0xb0, 0xd7, 0x6c, 0x18, 0x8e, + 0x1b, 0x7d, 0xa8, 0x74, 0xcf, 0xc7, 0xa4, 0x54, 0x79, 0x54, 0xbd, 0xb3, 0x76, 0xbb, 0xda, 0xaa, + 0x7d, 0x8e, 0xf7, 0xb4, 0xe3, 0xb5, 0xb0, 0x2e, 0xd1, 0x17, 0x30, 0x1b, 0xd7, 0xed, 0x8e, 0x43, + 0xa8, 0x3c, 0x79, 0x71, 0xf2, 0x10, 0x62, 0x0b, 0xa2, 0xe0, 0x1f, 0x3b, 0xac, 0x29, 0xa6, 0x09, + 0x35, 0x02, 0xaa, 0x8b, 0xf6, 0xca, 0x71, 0x90, 0x64, 0x6b, 0xbc, 0x07, 0xd1, 0x22, 0x00, 0x76, + 0xad, 0x88, 0xe0, 0x38, 0x23, 0x98, 0xc2, 0xae, 0x68, 0x51, 0xb4, 0x00, 0x53, 0xd4, 0xa3, 0xc6, + 0x8e, 0x4e, 0x0c, 0x2a, 0xe7, 0xd9, 0xee, 0x49, 0xb6, 0xb0, 0x6d, 0x50, 0x74, 0x19, 0x66, 0x93, + 0x15, 0x80, 0xdb, 0xf2, 0x09, 0x96, 0xfc, 0xe9, 0x38, 0xf9, 0xb8, 0x8d, 0xae, 0xc0, 0x29, 0xb2, + 0x63, 0x90, 0x46, 0x82, 0xec, 0x24, 0x23, 0x9b, 0x89, 0x96, 0x39, 0xdd, 0x07, 0x70, 0x2e, 0xee, + 0x12, 0xb6, 0xa5, 0x13, 0xc7, 0x66, 0xf4, 0x53, 0x8c, 0x7e, 0xbe, 0xb3, 0xbd, 0x1d, 0xee, 0x6e, + 0x3b, 0x76, 0xc8, 0xf6, 0x0c, 0x66, 0x4c, 0x6f, 0x17, 0xbb, 0x86, 0x4b, 0x43, 0x7a, 0x22, 0x03, + 0x6b, 0xaa, 0xdb, 0x19, 0x85, 0xb3, 0x21, 0x68, 0xd7, 0x2d, 0xc3, 0x0f, 0x25, 0x39, 0xb6, 0x6b, + 0xd0, 0x56, 0x80, 0x89, 0x36, 0x1d, 0x89, 0xd9, 0x76, 0x6c, 0x82, 0x6e, 0x02, 0x8a, 0x7c, 0xf3, + 0x5a, 0xd4, 0x6f, 0x51, 0xdd, 0xb1, 0xda, 0x72, 0x81, 0x5d, 0xc8, 0xa3, 0xe2, 0x7e, 0xc2, 0x36, + 0x1e, 0x59, 0xec, 0x28, 0x36, 0x18, 0xa8, 0xcb, 0xd3, 0x17, 0xa5, 0x95, 0x93, 0x9a, 0xf8, 0x42, + 0xcb, 0xac, 0xce, 0x68, 0x8b, 0xe8, 0x16, 0x26, 0xa6, 0x3c, 0xc3, 0x31, 0x89, 0x2f, 0x6d, 0x62, + 0x62, 0xa2, 0xf7, 0x61, 0xb6, 0xe5, 0xd6, 0x3c, 0xd7, 0x62, 0xd1, 0x71, 0x9a, 0x58, 0x9e, 0x65, + 0x2a, 0x66, 0x3a, 0xab, 0x4f, 0x9d, 0x26, 0x46, 0x26, 0x9c, 0x69, 0xb9, 0x71, 0x73, 0xe8, 0x81, + 0x28, 0x64, 0xf9, 0x14, 0xeb, 0x92, 0x52, 0x76, 0x97, 0x3c, 0x4b, 0xb0, 0x75, 0xfa, 0x64, 0xbe, + 0x95, 0xb2, 0x1a, 0xda, 0xc2, 0xdf, 0x02, 0x7a, 0xf4, 0xfe, 0x98, 0xe3, 0xb6, 0xf0, 0x55, 0xf1, + 0xda, 0x50, 0x5e, 0x4d, 0xc2, 0xb9, 0x0c, 0xc1, 0x68, 0x05, 0xe6, 0x12, 0xee, 0xb4, 0x13, 0x80, + 0x10, 0xbb, 0xc9, 0xb3, 0xfd, 0x11, 0x2c, 0xc4, 0xd9, 0x8e, 0x79, 0xa2, 0x8c, 0x4f, 0x30, 0x26, + 0xb9, 0x43, 0xf2, 0x2c, 0xa2, 0x10, 0x59, 0x37, 0x61, 0xa1, 0x93, 0xf5, 0x6e, 0xee, 0x4e, 0x0f, + 0x15, 0xca, 0x97, 0x33, 0xc2, 0xd2, 0x49, 0xfa, 0x23, 0xb7, 0xee, 0x69, 0x72, 0x24, 0x28, 0xa9, + 0x83, 0xb5, 0x4f, 0x4a, 0xe5, 0xe6, 0xd2, 0x2a, 0xf7, 0x43, 0x28, 0xf6, 0x54, 0x6e, 0xd2, 0x95, + 0xe3, 0x8c, 0xe5, 0x5c, 0x77, 0xf1, 0xc6, 0x9e, 0xd4, 0xe1, 0x6c, 0x5c, 0xbf, 0x09, 0x5e, 0x22, + 0xe7, 0x0f, 0x58, 0xc8, 0xf3, 0x9d, 0x42, 0x8e, 0x35, 0x11, 0xc5, 0x84, 0xe5, 0x21, 0x07, 0x0a, + 0xba, 0x0f, 0x39, 0x0b, 0xef, 0x1c, 0xec, 0xd6, 0xcc, 0x38, 0x95, 0x5f, 0xe4, 0x40, 0xce, 0x7c, + 0xc8, 0x7c, 0x02, 0x85, 0xb0, 0x0b, 0x02, 0xc7, 0x4f, 0x00, 0xfc, 0xb7, 0xa2, 0x73, 0x29, 0xd6, + 0xc0, 0x0f, 0xa5, 0xcd, 0x98, 0x54, 0x4b, 0xf2, 0xa1, 0x2d, 0x00, 0xd3, 0x6b, 0x36, 0x1d, 0x42, + 0xa2, 0xd3, 0x6d, 0xaa, 0x72, 0xeb, 0x9b, 0x37, 0xcb, 0x0b, 0x5c, 0x10, 0xb1, 0x9e, 0x97, 0x1c, + 0x4f, 0x6d, 0x1a, 0xb4, 0x51, 0x7a, 0x8c, 0x6d, 0xc3, 0xdc, 0xdb, 0xc4, 0xe6, 0xeb, 0x57, 0xb7, + 0x40, 0xe8, 0xd9, 0xc4, 0xa6, 0x96, 0x10, 0x80, 0x6e, 0x42, 0x8e, 0x9d, 0x01, 0x93, 0x43, 0xce, + 0x00, 0x46, 0x95, 0x40, 0xff, 0xdc, 0x51, 0xa0, 0xff, 0x47, 0x30, 0xe9, 0x7b, 0x3e, 0x2b, 0x91, + 0x42, 0xf9, 0x46, 0xd6, 0x73, 0x3d, 0xf0, 0xbc, 0xfa, 0x93, 0x7a, 0xd5, 0x23, 0x04, 0x33, 0x9b, + 0x2b, 0x4f, 0x37, 0xb4, 0x90, 0x0f, 0xad, 0xc1, 0x59, 0x56, 0x32, 0xd8, 0xd2, 0x05, 0x6b, 0x04, + 0xe4, 0x1c, 0xaa, 0xe7, 0xc5, 0x6e, 0x85, 0x6f, 0x0a, 0x4c, 0x0f, 0xa1, 0x2d, 0xe2, 0xa2, 0x66, + 0xc4, 0x71, 0x82, 0x71, 0xcc, 0x45, 0x1c, 0xd4, 0x14, 0xd4, 0xf1, 0xe5, 0xec, 0xe4, 0xc0, 0x0b, + 0xf8, 0x54, 0xdf, 0x05, 0xbc, 0xfc, 0xdb, 0xd3, 0x70, 0x9c, 0x9d, 0xf9, 0xe8, 0xe7, 0x12, 0xe4, + 0xf9, 0xd4, 0x01, 0x5d, 0xcb, 0xf0, 0xb2, 0x7f, 0xf8, 0x52, 0xbc, 0x3e, 0x0a, 0x29, 0x2f, 0x2e, + 0xe5, 0xfd, 0x9f, 0x7d, 0xfd, 0x8f, 0x5f, 0x4f, 0x2c, 0xa3, 0x45, 0x75, 0xd0, 0xd0, 0x08, 0xfd, + 0x41, 0x82, 0x53, 0x3d, 0xe3, 0x13, 0x54, 0x1e, 0xae, 0xa6, 0x77, 0x48, 0x53, 0xbc, 0x33, 0x16, + 0x8f, 0xb0, 0x51, 0x65, 0x36, 0x5e, 0x43, 0x57, 0x07, 0xda, 0xa8, 0xbe, 0x14, 0xf0, 0xbb, 0x8f, + 0xfe, 0x28, 0xc1, 0xe9, 0xbe, 0x67, 0x02, 0x5a, 0x1b, 0xa4, 0x3b, 0x6b, 0x7c, 0x53, 0xfc, 0x60, + 0x4c, 0x2e, 0x61, 0xf3, 0x2a, 0xb3, 0xf9, 0x06, 0xba, 0x96, 0x61, 0x73, 0xff, 0x03, 0x05, 0xbd, + 0x96, 0x60, 0xae, 0x57, 0x20, 0xba, 0x33, 0x8e, 0xfa, 0xc8, 0xe6, 0xb5, 0xf1, 0x98, 0x84, 0xc9, + 0xdb, 0xcc, 0xe4, 0x2d, 0xf4, 0xf9, 0xc8, 0x26, 0xab, 0x2f, 0xbb, 0xde, 0x0e, 0xfb, 0xfd, 0x24, + 0xe8, 0x77, 0x12, 0xcc, 0x76, 0xcf, 0x1d, 0xd0, 0xea, 0x20, 0xeb, 0x52, 0xc7, 0x29, 0xc5, 0xf2, + 0x38, 0x2c, 0xc2, 0x9d, 0x12, 0x73, 0x67, 0x05, 0x5d, 0x51, 0x33, 0x47, 0x9d, 0xc9, 0x47, 0x05, + 0xfa, 0xa7, 0x04, 0xcb, 0x43, 0x5e, 0x98, 0xa8, 0x32, 0xc8, 0x8e, 0xd1, 0x9e, 0xcb, 0xc5, 0x8d, + 0x43, 0xc9, 0x10, 0xce, 0x7d, 0x97, 0x39, 0xb7, 0x86, 0xca, 0x63, 0xe4, 0x8a, 0x03, 0xd0, 0x3e, + 0xfa, 0xaf, 0x04, 0x8b, 0x03, 0x67, 0x1c, 0xe8, 0xfe, 0x38, 0xf5, 0x93, 0x36, 0x86, 0x29, 0xae, + 0x1f, 0x42, 0x82, 0x70, 0xb1, 0xca, 0x5c, 0xfc, 0x0c, 0x3d, 0x3c, 0x78, 0x39, 0x32, 0x84, 0x8d, + 0x1d, 0xff, 0xb7, 0x04, 0x17, 0x06, 0x0d, 0x4f, 0xd0, 0xbd, 0x71, 0xac, 0x4e, 0x99, 0xe2, 0x14, + 0xef, 0x1f, 0x5c, 0x80, 0xf0, 0xfa, 0x01, 0xf3, 0x7a, 0x1d, 0xdd, 0x3b, 0xa4, 0xd7, 0x0c, 0xb1, + 0x7b, 0x06, 0x07, 0x83, 0x11, 0x3b, 0x7d, 0x08, 0x31, 0x18, 0xb1, 0x33, 0x26, 0x13, 0x43, 0x11, + 0xdb, 0x88, 0xf8, 0xc4, 0x29, 0x8a, 0xfe, 0x23, 0xc1, 0xc2, 0x80, 0xb1, 0x00, 0xfa, 0x78, 0x9c, + 0xc0, 0xa6, 0x00, 0xc8, 0xbd, 0x03, 0xf3, 0x0b, 0x8f, 0xb6, 0x98, 0x47, 0x0f, 0xd0, 0x27, 0x07, + 0xcf, 0x4b, 0x12, 0x6c, 0xfe, 0x24, 0xc1, 0x4c, 0x17, 0x6e, 0xa1, 0xdb, 0x23, 0x43, 0x5c, 0xe4, + 0xd3, 0xea, 0x18, 0x1c, 0xc2, 0x8b, 0x4d, 0xe6, 0xc5, 0xc7, 0xe8, 0x7b, 0xa3, 0x61, 0xa2, 0xfa, + 0x32, 0x65, 0x52, 0xb1, 0x5f, 0x79, 0xfc, 0xe5, 0xdb, 0x25, 0xe9, 0xab, 0xb7, 0x4b, 0xd2, 0xdf, + 0xdf, 0x2e, 0x49, 0xbf, 0x7a, 0xb7, 0x74, 0xec, 0xab, 0x77, 0x4b, 0xc7, 0xfe, 0xf6, 0x6e, 0xe9, + 0xd8, 0x8f, 0x86, 0x5e, 0xe9, 0xda, 0x49, 0x85, 0xec, 0x7e, 0x57, 0xcb, 0xb3, 0xff, 0x91, 0xee, + 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x92, 0xc6, 0x90, 0x35, 0x91, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3316,15 +3313,10 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error i-- dAtA[i] = 0x22 } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } + if len(m.Addr) > 0 { + i -= len(m.Addr) + copy(dAtA[i:], m.Addr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Addr))) i-- dAtA[i] = 0x1a } @@ -3812,8 +3804,8 @@ func (m *FinalityProviderResponse) Size() (n int) { l = m.Commission.Size() n += 1 + l + sovQuery(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() + l = len(m.Addr) + if l > 0 { n += 1 + l + sovQuery(uint64(l)) } if m.BtcPk != nil { @@ -6736,9 +6728,9 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -6748,27 +6740,23 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthQuery } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthQuery } if postIndex > l { return io.ErrUnexpectedEOF } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { @@ -6835,7 +6823,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Pop == nil { - m.Pop = &ProofOfPossession{} + m.Pop = &ProofOfPossessionBTC{} } if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index 1b6326375..b2f595e61 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -10,7 +10,6 @@ import ( github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" types1 "github.com/babylonchain/babylon/x/btccheckpoint/types" _ "github.com/cosmos/cosmos-proto" - secp256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" _ "github.com/cosmos/cosmos-sdk/types/msgservice" types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" @@ -37,18 +36,18 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgCreateFinalityProvider is the message for creating a finality provider type MsgCreateFinalityProvider struct { - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // addr defines the address of the finality provider that will receive + // the commissions to all the delegations. + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` // description defines the description terms for the finality provider Description *types.Description `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"` // commission defines the commission rate of the finality provider Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` - // babylon_pk is the Babylon secp256k1 PK of this finality provider - BabylonPk *secp256k1.PubKey `protobuf:"bytes,4,opt,name=babylon_pk,json=babylonPk,proto3" json:"babylon_pk,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,5,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` - // pop is the proof of possession of babylon_pk and btc_pk - Pop *ProofOfPossession `protobuf:"bytes,6,opt,name=pop,proto3" json:"pop,omitempty"` + BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + // pop is the proof of possession of btc_pk over the FP signer address. + Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` } func (m *MsgCreateFinalityProvider) Reset() { *m = MsgCreateFinalityProvider{} } @@ -84,9 +83,9 @@ func (m *MsgCreateFinalityProvider) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateFinalityProvider proto.InternalMessageInfo -func (m *MsgCreateFinalityProvider) GetSigner() string { +func (m *MsgCreateFinalityProvider) GetAddr() string { if m != nil { - return m.Signer + return m.Addr } return "" } @@ -98,14 +97,7 @@ func (m *MsgCreateFinalityProvider) GetDescription() *types.Description { return nil } -func (m *MsgCreateFinalityProvider) GetBabylonPk() *secp256k1.PubKey { - if m != nil { - return m.BabylonPk - } - return nil -} - -func (m *MsgCreateFinalityProvider) GetPop() *ProofOfPossession { +func (m *MsgCreateFinalityProvider) GetPop() *ProofOfPossessionBTC { if m != nil { return m.Pop } @@ -151,8 +143,8 @@ var xxx_messageInfo_MsgCreateFinalityProviderResponse proto.InternalMessageInfo // MsgEditFinalityProvider is the message for editing an existing finality provider type MsgEditFinalityProvider struct { - // NOTE: this signer needs to correspond to babylon_pk of the finality provider - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + // addr the address of the finality provider that whishes to edit his information. + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of the finality provider to be edited BtcPk []byte `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3" json:"btc_pk,omitempty"` // description defines the updated description terms for the finality provider @@ -194,9 +186,9 @@ func (m *MsgEditFinalityProvider) XXX_DiscardUnknown() { var xxx_messageInfo_MsgEditFinalityProvider proto.InternalMessageInfo -func (m *MsgEditFinalityProvider) GetSigner() string { +func (m *MsgEditFinalityProvider) GetAddr() string { if m != nil { - return m.Signer + return m.Addr } return "" } @@ -862,89 +854,86 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1300 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0x45, - 0x14, 0xce, 0xc6, 0x89, 0x4b, 0x9e, 0xe3, 0x24, 0x6c, 0xd3, 0xd4, 0x59, 0x5a, 0x3b, 0x71, 0x4b, - 0x9b, 0x16, 0xb2, 0x6e, 0x52, 0x1a, 0xd1, 0x54, 0x20, 0xd5, 0x49, 0xaa, 0x56, 0xd4, 0xc2, 0x5a, - 0x3b, 0x1c, 0xe0, 0x60, 0xad, 0x77, 0x27, 0xeb, 0x91, 0xed, 0x9d, 0xd5, 0xce, 0xc4, 0xb2, 0x85, - 0x84, 0x50, 0xc5, 0x15, 0x89, 0x13, 0x07, 0x6e, 0xfc, 0x07, 0x3d, 0xf4, 0x4f, 0x40, 0xa8, 0xc7, - 0xaa, 0x27, 0x94, 0x43, 0x84, 0x5a, 0xa4, 0x1e, 0x38, 0x73, 0x47, 0x3b, 0x3b, 0xfb, 0xc3, 0xc1, - 0x4b, 0x93, 0x26, 0x37, 0xef, 0xcc, 0xf7, 0xbe, 0xf7, 0xde, 0xf7, 0xde, 0x9b, 0x19, 0x43, 0xbe, - 0xa9, 0x37, 0x07, 0x1d, 0x62, 0x97, 0x9a, 0xcc, 0xa0, 0x4c, 0x6f, 0x63, 0xdb, 0x2a, 0xf5, 0xd6, - 0x4a, 0xac, 0xaf, 0x3a, 0x2e, 0x61, 0x44, 0xbe, 0x20, 0xf6, 0xd5, 0x68, 0x5f, 0xed, 0xad, 0x29, - 0xf3, 0x16, 0xb1, 0x08, 0x47, 0x94, 0xbc, 0x5f, 0x3e, 0x58, 0x59, 0x34, 0x08, 0xed, 0x12, 0xda, - 0xf0, 0x37, 0xfc, 0x0f, 0xb1, 0x75, 0xd1, 0xff, 0x2a, 0x75, 0x29, 0xe7, 0xef, 0x52, 0x4b, 0x6c, - 0x14, 0xc5, 0x86, 0xe1, 0x0e, 0x1c, 0x46, 0x4a, 0x14, 0x19, 0xce, 0xfa, 0x9d, 0x8d, 0xf6, 0x5a, - 0xa9, 0x8d, 0x06, 0x81, 0x71, 0x71, 0x74, 0x90, 0x8e, 0xee, 0xea, 0xdd, 0x00, 0xf3, 0x71, 0x0c, - 0x63, 0xb4, 0x90, 0xd1, 0x76, 0x08, 0xb6, 0x99, 0x07, 0x1b, 0x5a, 0x10, 0xe8, 0xab, 0xc2, 0x6b, - 0xc4, 0xd6, 0x44, 0x4c, 0x5f, 0x0b, 0xbe, 0x05, 0xaa, 0x90, 0xe0, 0x97, 0x38, 0x3e, 0xa0, 0xf8, - 0x6b, 0x0a, 0x16, 0x2b, 0xd4, 0xda, 0x72, 0x91, 0xce, 0xd0, 0x03, 0x6c, 0xeb, 0x1d, 0xcc, 0x06, - 0x55, 0x97, 0xf4, 0xb0, 0x89, 0x5c, 0x79, 0x01, 0xd2, 0x14, 0x5b, 0x36, 0x72, 0x73, 0xd2, 0x92, - 0xb4, 0x32, 0xa5, 0x89, 0x2f, 0x79, 0x07, 0x32, 0x26, 0xa2, 0x86, 0x8b, 0x1d, 0x86, 0x89, 0x9d, - 0x1b, 0x5f, 0x92, 0x56, 0x32, 0xeb, 0x57, 0x54, 0xa1, 0x57, 0xa4, 0x32, 0x0f, 0x49, 0xdd, 0x8e, - 0xa0, 0x5a, 0xdc, 0x4e, 0xae, 0x00, 0x18, 0xa4, 0xdb, 0xc5, 0x94, 0x7a, 0x2c, 0x29, 0xcf, 0x45, - 0x79, 0xf5, 0xe0, 0xb0, 0xf0, 0x81, 0x4f, 0x44, 0xcd, 0xb6, 0x8a, 0x49, 0xa9, 0xab, 0xb3, 0x96, - 0xfa, 0x18, 0x59, 0xba, 0x31, 0xd8, 0x46, 0xc6, 0xcb, 0x67, 0xab, 0x20, 0xfc, 0x6c, 0x23, 0x43, - 0x8b, 0x11, 0xc8, 0x9f, 0x03, 0x88, 0x74, 0x1b, 0x4e, 0x3b, 0x37, 0xc1, 0x83, 0x2a, 0x04, 0x41, - 0xf9, 0xd5, 0x51, 0xc3, 0xea, 0xa8, 0xd5, 0xfd, 0xe6, 0x17, 0x68, 0xa0, 0x4d, 0x09, 0x93, 0x6a, - 0x5b, 0xae, 0x40, 0xba, 0xc9, 0x0c, 0xcf, 0x76, 0x72, 0x49, 0x5a, 0x99, 0x2e, 0x6f, 0x1c, 0x1c, - 0x16, 0xd6, 0x2d, 0xcc, 0x5a, 0xfb, 0x4d, 0xd5, 0x20, 0xdd, 0x92, 0x40, 0x1a, 0x2d, 0x1d, 0xdb, - 0xc1, 0x47, 0x89, 0x0d, 0x1c, 0x44, 0xd5, 0xf2, 0xa3, 0xea, 0xed, 0x4f, 0x6e, 0x09, 0xca, 0xc9, - 0x26, 0x33, 0xaa, 0x6d, 0x79, 0x13, 0x52, 0x0e, 0x71, 0x72, 0x69, 0x1e, 0xc7, 0x8a, 0x3a, 0xb2, - 0x0d, 0xd5, 0xaa, 0x4b, 0xc8, 0xde, 0x97, 0x7b, 0x55, 0x42, 0x29, 0xe2, 0x59, 0x68, 0x9e, 0xd1, - 0x66, 0xe6, 0xc9, 0x9b, 0xa7, 0x37, 0x85, 0xda, 0xc5, 0x2b, 0xb0, 0x9c, 0x58, 0x22, 0x0d, 0x51, - 0x87, 0xd8, 0x14, 0x15, 0xff, 0x96, 0xe0, 0x62, 0x85, 0x5a, 0x3b, 0x26, 0x66, 0xc7, 0x2e, 0xe3, - 0x85, 0x30, 0x61, 0xaf, 0x82, 0xd3, 0x41, 0xe0, 0x47, 0xaa, 0x9b, 0x3a, 0x93, 0xea, 0x4e, 0x9c, - 0xb2, 0xba, 0xc3, 0x92, 0x2c, 0x43, 0x21, 0x21, 0xd9, 0x50, 0x90, 0xdf, 0xcf, 0xc1, 0x42, 0x28, - 0x5b, 0xb9, 0xbe, 0xb5, 0x8d, 0x3a, 0xc8, 0xd2, 0x79, 0x64, 0x77, 0x21, 0xe3, 0x65, 0x81, 0xdc, - 0x86, 0x6e, 0x9a, 0x42, 0x94, 0x72, 0xee, 0xe5, 0xb3, 0xd5, 0x79, 0xe1, 0xfb, 0xbe, 0x69, 0xba, - 0x88, 0xd2, 0x1a, 0x73, 0xb1, 0x6d, 0x69, 0xe0, 0x83, 0xbd, 0x45, 0xf9, 0x33, 0xbf, 0xa8, 0x7e, - 0xc7, 0x7f, 0x74, 0xdc, 0xa2, 0x96, 0xeb, 0x5b, 0xbc, 0xae, 0xb1, 0x16, 0x4b, 0x9d, 0x45, 0x8b, - 0x7d, 0x03, 0x33, 0x7b, 0x4e, 0xc3, 0x67, 0x6c, 0x74, 0x30, 0x65, 0xb9, 0x89, 0xa5, 0xd4, 0x29, - 0x68, 0x33, 0x7b, 0x4e, 0xd9, 0x23, 0x7e, 0x8c, 0x29, 0x93, 0x97, 0x61, 0x5a, 0xe4, 0xd4, 0x60, - 0xb8, 0x8b, 0xf8, 0x50, 0x64, 0xb5, 0x8c, 0x58, 0xab, 0xe3, 0x2e, 0x92, 0xaf, 0x40, 0x36, 0x80, - 0xf4, 0xf4, 0xce, 0x3e, 0xe2, 0xcd, 0x9e, 0xd2, 0x02, 0xbb, 0xaf, 0xbc, 0x35, 0xf9, 0x21, 0x40, - 0xc8, 0xd3, 0xcf, 0x9d, 0xe3, 0xca, 0xdd, 0x88, 0x2b, 0x17, 0x3b, 0xdb, 0x7a, 0x6b, 0x6a, 0xdd, - 0xd5, 0x6d, 0xaa, 0x1b, 0x5e, 0xa1, 0x1e, 0xd9, 0x7b, 0x44, 0x9b, 0x0a, 0x1c, 0xf6, 0xe5, 0x75, - 0xc8, 0xd0, 0x8e, 0x4e, 0x5b, 0x82, 0xea, 0x3d, 0x2e, 0xe1, 0xfb, 0x07, 0x87, 0x85, 0x6c, 0xb9, - 0xbe, 0x55, 0x13, 0x3b, 0xf5, 0xbe, 0x06, 0x34, 0xfc, 0x2d, 0x13, 0x58, 0x30, 0xfd, 0xca, 0x13, - 0xb7, 0x11, 0x5a, 0x53, 0x6c, 0xe5, 0xa6, 0xb8, 0xf9, 0xdd, 0x83, 0xc3, 0xc2, 0x9d, 0x93, 0x48, - 0x55, 0xc3, 0x96, 0xad, 0xb3, 0x7d, 0x17, 0x69, 0xf3, 0x21, 0x71, 0xe0, 0xbb, 0x86, 0x2d, 0xf9, - 0x43, 0x98, 0xd9, 0xb7, 0x9b, 0xc4, 0x36, 0x43, 0xe1, 0x80, 0x0b, 0x97, 0x0d, 0x57, 0xb9, 0x74, - 0xcb, 0x30, 0x1d, 0x83, 0xf5, 0x73, 0x19, 0x3e, 0x81, 0x99, 0x08, 0xd4, 0x97, 0xaf, 0xc3, 0x6c, - 0x04, 0xf1, 0xf5, 0x9d, 0xe6, 0xfa, 0x46, 0x0e, 0x7c, 0x85, 0x77, 0xe0, 0x42, 0x04, 0x8c, 0x2b, - 0x94, 0x4d, 0x52, 0xe8, 0x7c, 0x88, 0x8f, 0x16, 0xe5, 0x27, 0x12, 0x2c, 0x45, 0x5a, 0x8d, 0x60, - 0xf4, 0x54, 0x9b, 0x39, 0xad, 0x6a, 0x97, 0x43, 0x17, 0xbb, 0x47, 0x63, 0xa8, 0x61, 0x6b, 0x73, - 0xce, 0x1b, 0xf3, 0xf8, 0x78, 0x16, 0x97, 0x20, 0x3f, 0x7a, 0x8e, 0xc3, 0x51, 0xff, 0x67, 0x1c, - 0xe4, 0x0a, 0xb5, 0xee, 0x9b, 0xe6, 0x16, 0xe9, 0x21, 0x5b, 0xb7, 0x59, 0x0d, 0x5b, 0x34, 0xf1, - 0xd8, 0x7b, 0x00, 0xe3, 0xc1, 0x91, 0xf7, 0xce, 0x93, 0x32, 0xee, 0xb4, 0xe5, 0x6b, 0x30, 0x1b, - 0x35, 0x76, 0xa3, 0xa5, 0xd3, 0x96, 0x7f, 0x87, 0x69, 0xd9, 0xb0, 0x65, 0x1f, 0xea, 0xb4, 0x25, - 0xaf, 0xc0, 0x5c, 0xac, 0x28, 0x9e, 0x8a, 0xd4, 0x9f, 0x53, 0x6d, 0x26, 0x6a, 0x54, 0x1e, 0xb1, - 0x01, 0x73, 0xf1, 0xa6, 0xe0, 0x82, 0x4f, 0x9e, 0x56, 0xf0, 0x99, 0x58, 0x4f, 0x79, 0x0d, 0x7a, - 0x0f, 0x94, 0x30, 0x9c, 0xa3, 0xde, 0x68, 0x2e, 0xcd, 0x03, 0xbb, 0x18, 0x20, 0x76, 0x87, 0x6c, - 0xe9, 0xf0, 0x29, 0x7c, 0x09, 0x94, 0xff, 0xca, 0x1e, 0x56, 0xe5, 0x37, 0x09, 0xe6, 0x2a, 0xd4, - 0x2a, 0xd7, 0xb7, 0x76, 0x6d, 0x51, 0x73, 0x94, 0x58, 0x93, 0x11, 0x5a, 0x8e, 0x8f, 0xd2, 0x72, - 0x94, 0x42, 0xa9, 0x33, 0x56, 0x68, 0x38, 0x49, 0x05, 0x72, 0x47, 0xb3, 0x08, 0x53, 0xfc, 0x45, - 0x82, 0x4b, 0x15, 0x6a, 0xd5, 0x50, 0x07, 0x19, 0x0c, 0xf7, 0x50, 0xd0, 0xc8, 0x3b, 0xde, 0x55, - 0x64, 0x1b, 0xa7, 0x4f, 0x77, 0x15, 0xce, 0xbb, 0xc8, 0x20, 0x3d, 0xe4, 0x22, 0xb3, 0x21, 0x8e, - 0x7a, 0x2a, 0x2e, 0x0f, 0x6d, 0x2e, 0xdc, 0x7a, 0xe0, 0x1d, 0xdb, 0xb5, 0xf6, 0x70, 0xe0, 0xd7, - 0xe0, 0xea, 0xff, 0xc5, 0x16, 0x26, 0xf1, 0xb3, 0x04, 0xb3, 0x15, 0x6a, 0xed, 0x3a, 0xa6, 0xce, - 0x50, 0x95, 0xbf, 0x48, 0xe5, 0x0d, 0x98, 0xd2, 0xf7, 0x59, 0x8b, 0xb8, 0x98, 0x0d, 0xde, 0x7a, - 0x3f, 0x46, 0x50, 0xf9, 0x1e, 0xa4, 0xfd, 0x37, 0xad, 0xb8, 0x21, 0x2f, 0x27, 0xdd, 0x90, 0x1c, - 0x54, 0x9e, 0x78, 0x7e, 0x58, 0x18, 0xd3, 0x84, 0xc9, 0xe6, 0x8c, 0x17, 0x7d, 0x44, 0x56, 0x5c, - 0xe4, 0x2f, 0x9a, 0x78, 0x5c, 0x41, 0xcc, 0xeb, 0x7f, 0xa5, 0x21, 0x55, 0xa1, 0x96, 0xfc, 0x83, - 0x04, 0x0b, 0x09, 0x6f, 0xd7, 0x5b, 0x09, 0xae, 0x13, 0x9f, 0x52, 0xca, 0xa7, 0x27, 0xb5, 0x08, - 0xc2, 0x91, 0xbf, 0x83, 0xf9, 0x91, 0x0f, 0x2f, 0x35, 0x99, 0x71, 0x14, 0x5e, 0xd9, 0x38, 0x19, - 0x3e, 0xf4, 0xff, 0x2d, 0x9c, 0x1f, 0xf5, 0xce, 0x59, 0x7d, 0x5b, 0x42, 0x43, 0x70, 0xe5, 0xce, - 0x89, 0xe0, 0xa1, 0x73, 0x02, 0xb3, 0x47, 0x4f, 0xde, 0x1b, 0xc9, 0x4c, 0x47, 0xa0, 0xca, 0xda, - 0xb1, 0xa1, 0xa1, 0x43, 0x0c, 0xd9, 0xe1, 0x43, 0xe5, 0x7a, 0x32, 0xc7, 0x10, 0x50, 0x29, 0x1d, - 0x13, 0x18, 0xba, 0xfa, 0x51, 0x82, 0xc5, 0xe4, 0xe9, 0xbe, 0x9d, 0x4c, 0x97, 0x68, 0xa4, 0xdc, - 0x7b, 0x07, 0xa3, 0x30, 0x9e, 0x3d, 0x98, 0x1e, 0x9a, 0xd3, 0x6b, 0xc9, 0x64, 0x71, 0x9c, 0xa2, - 0x1e, 0x0f, 0x17, 0xf8, 0x51, 0x26, 0xbf, 0x7f, 0xf3, 0xf4, 0xa6, 0x54, 0x7e, 0xfc, 0xfc, 0x55, - 0x5e, 0x7a, 0xf1, 0x2a, 0x2f, 0xfd, 0xf9, 0x2a, 0x2f, 0xfd, 0xf4, 0x3a, 0x3f, 0xf6, 0xe2, 0x75, - 0x7e, 0xec, 0x8f, 0xd7, 0xf9, 0xb1, 0xaf, 0xdf, 0x7a, 0x67, 0xf6, 0xe3, 0x7f, 0x39, 0xf9, 0xb1, - 0xdb, 0x4c, 0xf3, 0xbf, 0x9c, 0xb7, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xf3, 0xdd, 0x49, 0xe6, - 0xb2, 0x0f, 0x00, 0x00, + // 1259 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x13, 0x47, + 0x14, 0xcf, 0xda, 0x89, 0x69, 0x9e, 0xe3, 0x24, 0x5d, 0x42, 0xd8, 0x6c, 0xc1, 0x76, 0x0c, 0x85, + 0x40, 0xc9, 0x9a, 0x84, 0x82, 0x4a, 0x50, 0x0f, 0x38, 0x09, 0x02, 0x15, 0xab, 0xd6, 0xda, 0xe9, + 0xa1, 0x3d, 0x58, 0xeb, 0xdd, 0xc9, 0x7a, 0x64, 0x7b, 0x67, 0xb5, 0x33, 0xb1, 0x1c, 0x55, 0xaa, + 0x2a, 0xd4, 0x6b, 0xa5, 0x9e, 0x7a, 0xe8, 0xa7, 0xe0, 0xc0, 0x47, 0xa8, 0x2a, 0x8e, 0x88, 0x53, + 0x95, 0x43, 0x54, 0x41, 0x25, 0x3e, 0x41, 0xa5, 0xde, 0x5a, 0xed, 0xec, 0x5f, 0xbb, 0xde, 0x92, + 0x60, 0x6e, 0xde, 0x99, 0xdf, 0xfb, 0xbd, 0xf7, 0x7e, 0xef, 0xbd, 0x99, 0x31, 0xe4, 0x5b, 0x5a, + 0xeb, 0xb0, 0x4b, 0xac, 0x72, 0x8b, 0xe9, 0x94, 0x69, 0x1d, 0x6c, 0x99, 0xe5, 0xfe, 0x46, 0x99, + 0x0d, 0x14, 0xdb, 0x21, 0x8c, 0x88, 0xe7, 0xfc, 0x7d, 0x25, 0xda, 0x57, 0xfa, 0x1b, 0xf2, 0x92, + 0x49, 0x4c, 0xc2, 0x11, 0x65, 0xf7, 0x97, 0x07, 0x96, 0x57, 0x74, 0x42, 0x7b, 0x84, 0x36, 0xbd, + 0x0d, 0xef, 0xc3, 0xdf, 0x3a, 0xef, 0x7d, 0x95, 0x7b, 0x94, 0xf3, 0xf7, 0xa8, 0xe9, 0x6f, 0x94, + 0xc6, 0x07, 0x60, 0x6b, 0x8e, 0xd6, 0x0b, 0x8c, 0x6f, 0xc4, 0x30, 0x7a, 0x1b, 0xe9, 0x1d, 0x9b, + 0x60, 0x8b, 0xb9, 0xb0, 0xa1, 0x05, 0x1f, 0x7d, 0xd9, 0x77, 0x15, 0xb1, 0xb5, 0x10, 0xd3, 0x36, + 0x82, 0x6f, 0x1f, 0x55, 0x48, 0xf0, 0x4b, 0x6c, 0x0f, 0x50, 0xfa, 0x3b, 0x05, 0x2b, 0x55, 0x6a, + 0x6e, 0x3b, 0x48, 0x63, 0xe8, 0x01, 0xb6, 0xb4, 0x2e, 0x66, 0x87, 0x35, 0x87, 0xf4, 0xb1, 0x81, + 0x1c, 0xf1, 0x06, 0x4c, 0x6b, 0x86, 0xe1, 0x48, 0x42, 0x51, 0x58, 0x9b, 0xad, 0x48, 0x2f, 0x9f, + 0xad, 0x2f, 0xf9, 0xf9, 0xde, 0x37, 0x0c, 0x07, 0x51, 0x5a, 0x67, 0x0e, 0xb6, 0x4c, 0x95, 0xa3, + 0xc4, 0x5d, 0xc8, 0x1a, 0x88, 0xea, 0x0e, 0xb6, 0x19, 0x26, 0x96, 0x94, 0x2a, 0x0a, 0x6b, 0xd9, + 0xcd, 0x4b, 0x8a, 0x6f, 0x11, 0xe9, 0xca, 0x03, 0x55, 0x76, 0x22, 0xa8, 0x1a, 0xb7, 0x13, 0xab, + 0x00, 0x3a, 0xe9, 0xf5, 0x30, 0xa5, 0x2e, 0x4b, 0x9a, 0xbb, 0x5e, 0x3f, 0x3a, 0x2e, 0x7c, 0xe4, + 0x11, 0x51, 0xa3, 0xa3, 0x60, 0x52, 0xee, 0x69, 0xac, 0xad, 0x3c, 0x46, 0xa6, 0xa6, 0x1f, 0xee, + 0x20, 0xfd, 0xe5, 0xb3, 0x75, 0xf0, 0xfd, 0xec, 0x20, 0x5d, 0x8d, 0x11, 0x88, 0x55, 0xc8, 0xb4, + 0x98, 0xde, 0xb4, 0x3b, 0xd2, 0x74, 0x51, 0x58, 0x9b, 0xab, 0xdc, 0x39, 0x3a, 0x2e, 0x6c, 0x9a, + 0x98, 0xb5, 0x0f, 0x5a, 0x8a, 0x4e, 0x7a, 0x65, 0x5f, 0x21, 0xbd, 0xad, 0x61, 0x2b, 0xf8, 0x28, + 0xb3, 0x43, 0x1b, 0x51, 0xa5, 0xf2, 0xa8, 0x76, 0xeb, 0xd3, 0x9b, 0xb5, 0x83, 0xd6, 0x17, 0xe8, + 0x50, 0x9d, 0x69, 0x31, 0xbd, 0xd6, 0x11, 0x3f, 0x87, 0xb4, 0x4d, 0x6c, 0x69, 0x86, 0x27, 0xf7, + 0x89, 0x32, 0xb6, 0x71, 0x94, 0x9a, 0x43, 0xc8, 0xfe, 0x97, 0xfb, 0x35, 0x42, 0x29, 0xe2, 0x51, + 0x54, 0x1a, 0xdb, 0xaa, 0x6b, 0xb7, 0x35, 0xfb, 0xe4, 0xcd, 0xd3, 0xeb, 0x5c, 0xae, 0xd2, 0x25, + 0x58, 0x4d, 0x54, 0x5e, 0x45, 0xd4, 0x26, 0x16, 0x45, 0xa5, 0x7f, 0x04, 0x38, 0x5f, 0xa5, 0xe6, + 0xae, 0x81, 0xd9, 0x84, 0xd5, 0x39, 0x17, 0xea, 0xe0, 0x16, 0x66, 0x2e, 0xc8, 0x67, 0xa4, 0x68, + 0xe9, 0xf7, 0x52, 0xb4, 0xe9, 0x09, 0x8b, 0x16, 0x97, 0x69, 0x15, 0x0a, 0x09, 0x02, 0x84, 0x22, + 0xfd, 0x76, 0x06, 0x96, 0x43, 0x29, 0x2b, 0x8d, 0xed, 0x1d, 0xd4, 0x45, 0xa6, 0xc6, 0xe3, 0xba, + 0x0b, 0x59, 0x37, 0x07, 0xe4, 0x34, 0x4f, 0x24, 0x15, 0x78, 0x60, 0x77, 0x31, 0xa8, 0x74, 0xea, + 0xdd, 0x2a, 0x1d, 0xeb, 0xbb, 0xf4, 0xfb, 0xe8, 0xbb, 0x6f, 0x60, 0x7e, 0xdf, 0x6e, 0x7a, 0x8c, + 0xcd, 0x2e, 0xa6, 0x4c, 0x9a, 0x2e, 0xa6, 0x27, 0xa0, 0xcd, 0xee, 0xdb, 0x15, 0x97, 0xf8, 0x31, + 0xa6, 0x4c, 0x5c, 0x85, 0x39, 0x3f, 0xa7, 0x26, 0xc3, 0x3d, 0xc4, 0xbb, 0x3b, 0xa7, 0x66, 0xfd, + 0xb5, 0x06, 0xee, 0x21, 0xf1, 0x12, 0xe4, 0x02, 0x48, 0x5f, 0xeb, 0x1e, 0x20, 0x29, 0x53, 0x14, + 0xd6, 0xd2, 0x6a, 0x60, 0xf7, 0x95, 0xbb, 0x26, 0x3e, 0x04, 0x08, 0x79, 0x06, 0xd2, 0x19, 0xae, + 0xdc, 0xb5, 0xb8, 0x72, 0xb1, 0x63, 0xac, 0xbf, 0xa1, 0x34, 0x1c, 0xcd, 0xa2, 0x9a, 0xee, 0x16, + 0xea, 0x91, 0xb5, 0x4f, 0xd4, 0xd9, 0xc0, 0xe1, 0x40, 0xdc, 0x84, 0x2c, 0xed, 0x6a, 0xb4, 0xed, + 0x53, 0x7d, 0xc0, 0x25, 0xfc, 0xf0, 0xe8, 0xb8, 0x90, 0xab, 0x34, 0xb6, 0xeb, 0xfe, 0x4e, 0x63, + 0xa0, 0x02, 0x0d, 0x7f, 0x8b, 0x04, 0x96, 0x0d, 0xaf, 0xf2, 0xc4, 0x69, 0x86, 0xd6, 0x14, 0x9b, + 0xd2, 0x2c, 0x37, 0xbf, 0x7b, 0x74, 0x5c, 0xb8, 0x7d, 0x1a, 0xa9, 0xea, 0xd8, 0xb4, 0x34, 0x76, + 0xe0, 0x20, 0x75, 0x29, 0x24, 0x0e, 0x7c, 0xd7, 0xb1, 0x29, 0x7e, 0x0c, 0xf3, 0x07, 0x56, 0x8b, + 0x58, 0x46, 0x28, 0x1c, 0x70, 0xe1, 0x72, 0xe1, 0x2a, 0x97, 0x6e, 0x15, 0xe6, 0x62, 0xb0, 0x81, + 0x94, 0xe5, 0xf3, 0x97, 0x8d, 0x40, 0x03, 0xf1, 0x2a, 0x2c, 0x44, 0x10, 0x4f, 0xdf, 0x39, 0xae, + 0x6f, 0xe4, 0xc0, 0x53, 0x78, 0x17, 0xce, 0x45, 0xc0, 0xb8, 0x42, 0xb9, 0x24, 0x85, 0xce, 0x86, + 0xf8, 0x68, 0x51, 0x7c, 0x22, 0x40, 0x31, 0xd2, 0x6a, 0x0c, 0xa3, 0xab, 0xda, 0xfc, 0xa4, 0xaa, + 0x5d, 0x0c, 0x5d, 0xec, 0x8d, 0xc6, 0x50, 0xc7, 0xe6, 0xd6, 0xa2, 0x3b, 0xe4, 0xf1, 0xf1, 0x2c, + 0x15, 0x21, 0x3f, 0x7e, 0x8e, 0xc3, 0x51, 0xff, 0x2b, 0x05, 0x62, 0x95, 0x9a, 0xf7, 0x0d, 0x63, + 0x9b, 0xf4, 0x91, 0xa5, 0x59, 0xac, 0x8e, 0x4d, 0x2a, 0x2e, 0x43, 0x86, 0x62, 0xd3, 0x42, 0xfe, + 0x84, 0xab, 0xfe, 0x97, 0xf8, 0x00, 0x52, 0xc1, 0x81, 0xf7, 0xce, 0x93, 0x92, 0xb2, 0x3b, 0xe2, + 0x15, 0x58, 0x88, 0x1a, 0xbb, 0xd9, 0xd6, 0x68, 0xdb, 0xbb, 0x98, 0xd4, 0x5c, 0xd8, 0xb2, 0x0f, + 0x35, 0xda, 0x16, 0xd7, 0x60, 0x31, 0x56, 0x14, 0x57, 0x45, 0xea, 0xcd, 0xa9, 0x3a, 0x1f, 0x35, + 0x2a, 0x8f, 0x58, 0x87, 0xc5, 0x78, 0x53, 0x70, 0xc1, 0x67, 0x26, 0x15, 0x7c, 0x3e, 0xd6, 0x53, + 0x6e, 0x83, 0xde, 0x03, 0x39, 0x0c, 0x67, 0xd4, 0x1b, 0x95, 0x32, 0x3c, 0xb0, 0xf3, 0x01, 0x62, + 0x6f, 0xc8, 0x96, 0x6e, 0x65, 0xdd, 0xf2, 0xf8, 0x42, 0x96, 0x2e, 0x80, 0xfc, 0x5f, 0xd9, 0xc3, + 0xaa, 0xfc, 0x2a, 0xc0, 0x62, 0x95, 0x9a, 0x95, 0xc6, 0xf6, 0x9e, 0xe5, 0xd7, 0x1c, 0x25, 0xd6, + 0x64, 0x8c, 0x96, 0xa9, 0x71, 0x5a, 0x8e, 0x53, 0x28, 0xfd, 0x9e, 0x15, 0x1a, 0x4e, 0x52, 0x06, + 0x69, 0x34, 0x8b, 0x30, 0xc5, 0x5f, 0x04, 0xb8, 0x50, 0xa5, 0x66, 0x1d, 0x75, 0x91, 0xce, 0x70, + 0x1f, 0x05, 0x8d, 0xbc, 0xeb, 0x5e, 0x45, 0x96, 0x3e, 0x79, 0xba, 0xeb, 0x70, 0xd6, 0x41, 0x3a, + 0xe9, 0x23, 0x07, 0x19, 0x4d, 0xff, 0xa8, 0xa7, 0xfe, 0xe5, 0xa1, 0x2e, 0x86, 0x5b, 0x0f, 0xdc, + 0x63, 0xbb, 0xde, 0x19, 0x0e, 0xfc, 0x0a, 0x5c, 0xfe, 0xbf, 0xd8, 0xc2, 0x24, 0x7e, 0x16, 0x60, + 0xa1, 0x4a, 0xcd, 0x3d, 0xdb, 0xd0, 0x18, 0xaa, 0xf1, 0xc7, 0xa7, 0x78, 0x07, 0x66, 0xb5, 0x03, + 0xd6, 0x26, 0x0e, 0x66, 0x87, 0x6f, 0xbd, 0x1f, 0x23, 0xa8, 0x78, 0x0f, 0x32, 0xde, 0xf3, 0xd5, + 0xbf, 0x21, 0x2f, 0x26, 0xdd, 0x90, 0x1c, 0x54, 0x99, 0x7e, 0x7e, 0x5c, 0x98, 0x52, 0x7d, 0x93, + 0xad, 0x79, 0x37, 0xfa, 0x88, 0xac, 0xb4, 0xc2, 0x5f, 0x39, 0xf1, 0xb8, 0x82, 0x98, 0x37, 0xff, + 0xcc, 0x40, 0xba, 0x4a, 0x4d, 0xf1, 0x07, 0x01, 0x96, 0x13, 0x9e, 0xa9, 0x37, 0x13, 0x5c, 0x27, + 0x3e, 0xaf, 0xe4, 0xcf, 0x4e, 0x6b, 0x11, 0x84, 0x23, 0x7e, 0x07, 0x4b, 0x63, 0x1f, 0x63, 0x4a, + 0x32, 0xe3, 0x38, 0xbc, 0x7c, 0xe7, 0x74, 0xf8, 0xd0, 0xff, 0xb7, 0x70, 0x76, 0xdc, 0x3b, 0x67, + 0xfd, 0x6d, 0x09, 0x0d, 0xc1, 0xe5, 0xdb, 0xa7, 0x82, 0x87, 0xce, 0x09, 0x2c, 0x8c, 0x9e, 0xbc, + 0xd7, 0x92, 0x99, 0x46, 0xa0, 0xf2, 0xc6, 0x89, 0xa1, 0xa1, 0x43, 0x0c, 0xb9, 0xe1, 0x43, 0xe5, + 0x6a, 0x32, 0xc7, 0x10, 0x50, 0x2e, 0x9f, 0x10, 0x18, 0xba, 0xfa, 0x51, 0x80, 0x95, 0xe4, 0xe9, + 0xbe, 0x95, 0x4c, 0x97, 0x68, 0x24, 0xdf, 0x7b, 0x07, 0xa3, 0x30, 0x9e, 0x7d, 0x98, 0x1b, 0x9a, + 0xd3, 0x2b, 0xc9, 0x64, 0x71, 0x9c, 0xac, 0x9c, 0x0c, 0x17, 0xf8, 0x91, 0x67, 0xbe, 0x7f, 0xf3, + 0xf4, 0xba, 0x50, 0x79, 0xfc, 0xfc, 0x55, 0x5e, 0x78, 0xf1, 0x2a, 0x2f, 0xfc, 0xf1, 0x2a, 0x2f, + 0xfc, 0xf4, 0x3a, 0x3f, 0xf5, 0xe2, 0x75, 0x7e, 0xea, 0xf7, 0xd7, 0xf9, 0xa9, 0xaf, 0xdf, 0x7a, + 0x67, 0x0e, 0xe2, 0xff, 0x2e, 0xf9, 0xb1, 0xdb, 0xca, 0xf0, 0x7f, 0x97, 0xb7, 0xfe, 0x0d, 0x00, + 0x00, 0xff, 0xff, 0xf6, 0xe9, 0xb3, 0x62, 0x79, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1289,7 +1278,7 @@ func (m *MsgCreateFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, erro i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x32 + dAtA[i] = 0x2a } if m.BtcPk != nil { { @@ -1301,18 +1290,6 @@ func (m *MsgCreateFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, erro i = encodeVarintTx(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x2a - } - if m.BabylonPk != nil { - { - size, err := m.BabylonPk.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTx(dAtA, i, uint64(size)) - } - i-- dAtA[i] = 0x22 } if m.Commission != nil { @@ -1339,10 +1316,10 @@ func (m *MsgCreateFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, erro i-- dAtA[i] = 0x12 } - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + if len(m.Addr) > 0 { + i -= len(m.Addr) + copy(dAtA[i:], m.Addr) + i = encodeVarintTx(dAtA, i, uint64(len(m.Addr))) i-- dAtA[i] = 0xa } @@ -1423,10 +1400,10 @@ func (m *MsgEditFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if len(m.Signer) > 0 { - i -= len(m.Signer) - copy(dAtA[i:], m.Signer) - i = encodeVarintTx(dAtA, i, uint64(len(m.Signer))) + if len(m.Addr) > 0 { + i -= len(m.Addr) + copy(dAtA[i:], m.Addr) + i = encodeVarintTx(dAtA, i, uint64(len(m.Addr))) i-- dAtA[i] = 0xa } @@ -1955,7 +1932,7 @@ func (m *MsgCreateFinalityProvider) Size() (n int) { } var l int _ = l - l = len(m.Signer) + l = len(m.Addr) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -1967,10 +1944,6 @@ func (m *MsgCreateFinalityProvider) Size() (n int) { l = m.Commission.Size() n += 1 + l + sovTx(uint64(l)) } - if m.BabylonPk != nil { - l = m.BabylonPk.Size() - n += 1 + l + sovTx(uint64(l)) - } if m.BtcPk != nil { l = m.BtcPk.Size() n += 1 + l + sovTx(uint64(l)) @@ -1997,7 +1970,7 @@ func (m *MsgEditFinalityProvider) Size() (n int) { } var l int _ = l - l = len(m.Signer) + l = len(m.Addr) if l > 0 { n += 1 + l + sovTx(uint64(l)) } @@ -2264,7 +2237,7 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2292,7 +2265,7 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = string(dAtA[iNdEx:postIndex]) + m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { @@ -2367,42 +2340,6 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { } iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field BabylonPk", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTx - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTx - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTx - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.BabylonPk == nil { - m.BabylonPk = &secp256k1.PubKey{} - } - if err := m.BabylonPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field BtcPk", wireType) } @@ -2437,7 +2374,7 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 6: + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pop", wireType) } @@ -2467,7 +2404,7 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.Pop == nil { - m.Pop = &ProofOfPossession{} + m.Pop = &ProofOfPossessionBTC{} } if err := m.Pop.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2575,7 +2512,7 @@ func (m *MsgEditFinalityProvider) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2603,7 +2540,7 @@ func (m *MsgEditFinalityProvider) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = string(dAtA[iNdEx:postIndex]) + m.Addr = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { From 416912aa80d1b4de9539ef17772f353edf9a2f7c Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Mon, 1 Jul 2024 15:40:54 +0200 Subject: [PATCH 099/119] bump btcd library (#685) --- btcstaking/staking_test.go | 2 +- go.mod | 3 ++- go.sum | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/btcstaking/staking_test.go b/btcstaking/staking_test.go index 735ba99db..8a02803f7 100644 --- a/btcstaking/staking_test.go +++ b/btcstaking/staking_test.go @@ -309,7 +309,7 @@ func TestSlashingTxWithOverflowMustNotAccepted(t *testing.T) { &chaincfg.MainNetParams, ) require.Error(t, err) - require.EqualError(t, err, "slashing transaction does not obey BTC rules: transaction output value of 1152921504606846975 is higher than max allowed value of 2.1e+15") + require.EqualError(t, err, "slashing transaction does not obey BTC rules: transaction output value is higher than max allowed value: 1152921504606846975 > 2.1e+15 ") } func TestNotAllowStakerKeyToBeFinalityProviderKey(t *testing.T) { diff --git a/go.mod b/go.mod index c621851bf..978f302be 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ module github.com/babylonchain/babylon require ( github.com/CosmWasm/wasmd v0.51.0 - github.com/btcsuite/btcd v0.24.0 + github.com/btcsuite/btcd v0.24.2 github.com/cometbft/cometbft v0.38.6 github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/cosmos/cosmos-sdk v0.50.6 @@ -227,6 +227,7 @@ require ( github.com/sirupsen/logrus v1.9.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/strangelove-ventures/cometbft-client v0.1.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tidwall/btree v1.7.0 // indirect github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/ulikunitz/xz v0.5.11 // indirect diff --git a/go.sum b/go.sum index 3c67d3b12..aac30481a 100644 --- a/go.sum +++ b/go.sum @@ -291,8 +291,8 @@ github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d/go.mod h1:f1iKL6Z github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= -github.com/btcsuite/btcd v0.24.0 h1:gL3uHE/IaFj6fcZSu03SvqPMSx7s/dPzfpG/atRwWdo= -github.com/btcsuite/btcd v0.24.0/go.mod h1:K4IDc1593s8jKXIF7yS7yCTSxrknB9z0STzc2j6XgE4= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= From 1c4a32e16e957c4dfaeea95712596ee3edea4e37 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 3 Jul 2024 15:43:44 +0200 Subject: [PATCH 100/119] Add command to print module sizes (#687) * Add command to print module sizes --- cmd/babylond/cmd/root.go | 1 + cmd/babylond/cmd/sizes_cmd.go | 178 ++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 cmd/babylond/cmd/sizes_cmd.go diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index 329be3354..f87c0afb5 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -189,6 +189,7 @@ func initRootCmd(rootCmd *cobra.Command, txConfig client.TxEncodingConfig, basic TestnetCmd(basicManager, banktypes.GenesisBalancesIterator{}), genhelpers.CmdGenHelpers(gentxModule.GenTxValidator), CreateBlsKeyCmd(), + ModuleSizeCmd(), debug.Cmd(), confixcmd.ConfigCommand(), ) diff --git a/cmd/babylond/cmd/sizes_cmd.go b/cmd/babylond/cmd/sizes_cmd.go new file mode 100644 index 000000000..800c77730 --- /dev/null +++ b/cmd/babylond/cmd/sizes_cmd.go @@ -0,0 +1,178 @@ +package cmd + +import ( + "cmp" + "fmt" + "path/filepath" + "regexp" + "slices" + "strings" + + dbm "github.com/cosmos/cosmos-db" + "github.com/spf13/cobra" + "golang.org/x/exp/maps" +) + +const ( + FlagPrintInterval = "print-interval" +) + +// r is a regular expression that matched the store key prefix +// we cannot use modules names direclty as sometimes module key != store key +// for example account module has store key "acc" and module key "auth" +var r, _ = regexp.Compile("s/k:[A-Za-z]+/") + +func OpenDB(dir string) (dbm.DB, error) { + fmt.Printf("Opening database at: %s\n", dir) + defer fmt.Printf("Opened database at: %s\n", dir) + + dir, err := filepath.Abs(dir) + if err != nil { + return nil, err + } + ext := filepath.Ext(dir) + if !strings.EqualFold(ext, ".db") { + return nil, fmt.Errorf("database directory must end with .db") + } + + directory := filepath.Dir(dir) + filename := filepath.Base(dir) + + name := strings.TrimSuffix(filename, ext) + db, err := dbm.NewGoLevelDB(name, directory, nil) + if err != nil { + return nil, err + } + return db, nil +} + +type ModuleStats struct { + ModuleKey string + NodeCount uint64 + TotalSizeBytes uint64 +} + +type GlobalStats struct { + TotalNodeCount uint64 + TotalSizeBytes uint64 + UnknownStoreKeyCount uint64 + UnknownStoreKeySize uint64 +} + +func extractStoreKey(fullKey string) string { + return r.FindString(fullKey) +} + +func printModuleStats(stats map[string]*ModuleStats, gs *GlobalStats) { + if len(stats) == 0 { + fmt.Printf("No module stats to report\n") + return + } + + statsSlice := maps.Values(stats) + + slices.SortStableFunc(statsSlice, func(a *ModuleStats, b *ModuleStats) int { + // sort from highest to lowest size + return -cmp.Compare(a.TotalSizeBytes, b.TotalSizeBytes) + }) + + fmt.Printf("****************** Printing module stats ******************\n") + fmt.Printf("Total number of nodes in db: %d\n", gs.TotalNodeCount) + fmt.Printf("Total size of database: %d bytes\n", gs.TotalSizeBytes) + fmt.Printf("Total number of unknown storekeys: %d\n", gs.UnknownStoreKeyCount) + fmt.Printf("Total size of unknown storekeys: %d bytes\n", gs.UnknownStoreKeySize) + fmt.Printf("Fraction of unknown storekeys: %.3f\n", float64(gs.UnknownStoreKeySize)/float64(gs.TotalSizeBytes)) + for _, v := range statsSlice { + fmt.Printf("Store key %s:\n", v.ModuleKey) + fmt.Printf("Number of tree state nodes: %d\n", v.NodeCount) + fmt.Printf("Total size of of module storage: %d bytes\n", v.TotalSizeBytes) + fmt.Printf("Fraction of total size: %.3f\n", float64(v.TotalSizeBytes)/float64(gs.TotalSizeBytes)) + } + fmt.Printf("****************** Printed stats for all Babylon modules ******************\n") +} + +func PrintDBStats(db dbm.DB, printInterval int) { + fmt.Printf("****************** Starting to iterate over whole database ******************\n") + storeKeyStats := make(map[string]*ModuleStats) + + gs := GlobalStats{} + + itr, err := db.Iterator(nil, nil) + if err != nil { + panic(err) + } + fmt.Printf("****************** Retrived database iterator ******************\n") + + defer itr.Close() + for ; itr.Valid(); itr.Next() { + gs.TotalNodeCount++ + if gs.TotalNodeCount%uint64(printInterval) == 0 { + printModuleStats(storeKeyStats, &gs) + } + + fullKey := itr.Key() + fullValue := itr.Value() + fullKeyString := string(fullKey) + keyValueSize := uint64(len(fullKey) + len(fullValue)) + extractedStoreKey := extractStoreKey(fullKeyString) + + if extractedStoreKey == "" { + gs.UnknownStoreKeyCount++ + gs.TotalSizeBytes += keyValueSize + gs.UnknownStoreKeySize += keyValueSize + continue + } + + if _, ok := storeKeyStats[extractedStoreKey]; !ok { + storeKeyStats[extractedStoreKey] = &ModuleStats{ + ModuleKey: extractedStoreKey, + } + } + + storeKeyStats[extractedStoreKey].NodeCount++ + storeKeyStats[extractedStoreKey].TotalSizeBytes += keyValueSize + gs.TotalSizeBytes += keyValueSize + } + + if err := itr.Error(); err != nil { + panic(err) + } + fmt.Printf("****************** Finished iterating over whole database ******************\n") + printModuleStats(storeKeyStats, &gs) +} + +func ModuleSizeCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "module-sizes [path-to-db]", + Short: "print sizes of each module in the database", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + d, err := cmd.Flags().GetInt(FlagPrintInterval) + + if err != nil { + return err + } + + if d <= 0 { + return fmt.Errorf("print interval must be greater than 0") + } + + pathToDB := args[0] + + db, err := OpenDB(pathToDB) + + if err != nil { + return err + } + defer db.Close() + + PrintDBStats(db, d) + + return nil + }, + } + + cmd.Flags().Int(FlagPrintInterval, 100000, "interval between printing databse stats") + + return cmd +} From de79e2e2fc406ff00c9aade60b9dcdb5baa0b511 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Fri, 5 Jul 2024 15:38:06 +0200 Subject: [PATCH 101/119] Add docs to public facing functions (#692) * Add docs to public facing functions --- btcstaking/types.go | 12 ++++++++++++ btcstaking/witness_utils.go | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/btcstaking/types.go b/btcstaking/types.go index 77d6bf0ef..95d6a9455 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -376,6 +376,12 @@ func newBabylonScriptPaths( }, nil } +// BuildStakingInfo builds all Babylon specific BTC scripts that must +// be committed to in the staking output. +// Returned `StakingInfo` object exposes methods to build spend info for each +// of the script spending paths which later must be included in the witness. +// It is up to the caller to verify whether parameters provided to this function +// obey parameters expected by Babylon chain. func BuildStakingInfo( stakerKey *btcec.PublicKey, fpKeys []*btcec.PublicKey, @@ -456,6 +462,12 @@ type UnbondingInfo struct { slashingPathLeafHash chainhash.Hash } +// BuildUnbondingInfo builds all Babylon specific BTC scripts that must +// be committed to in the unbonding output. +// Returned `UnbondingInfo` object exposes methods to build spend info for each +// of the script spending paths which later must be included in the witness. +// It is up to the caller to verify whether parameters provided to this function +// obey parameters expected by Babylon chain. func BuildUnbondingInfo( stakerKey *btcec.PublicKey, fpKeys []*btcec.PublicKey, diff --git a/btcstaking/witness_utils.go b/btcstaking/witness_utils.go index a733ab1e9..8e45f2f0a 100644 --- a/btcstaking/witness_utils.go +++ b/btcstaking/witness_utils.go @@ -17,7 +17,14 @@ func (si *SpendInfo) CreateTimeLockPathWitness(delegatorSig *schnorr.Signature) return CreateWitness(si, [][]byte{delegatorSig.Serialize()}) } -func (si *SpendInfo) CreateUnbondingPathWitness(covenantSigs []*schnorr.Signature, delegatorSig *schnorr.Signature) (wire.TxWitness, error) { +// CreateUnbondingPathWitness helper function to create a witness to spend +// transaction through the unbonding path. +// It is up to the caller to ensure that the amount of covenantSigs matches the +// expected quorum of covenenant members and the transaction has unbonding path. +func (si *SpendInfo) CreateUnbondingPathWitness( + covenantSigs []*schnorr.Signature, + delegatorSig *schnorr.Signature, +) (wire.TxWitness, error) { if si == nil { panic("cannot build witness without spend info") } @@ -46,7 +53,16 @@ func (si *SpendInfo) CreateUnbondingPathWitness(covenantSigs []*schnorr.Signatur return CreateWitness(si, witnessStack) } -func (si *SpendInfo) CreateSlashingPathWitness(covenantSigs []*schnorr.Signature, fpSigs []*schnorr.Signature, delegatorSig *schnorr.Signature) (wire.TxWitness, error) { +// CreateSlashingPathWitness helper function to create a witness to spend +// transaction through the slashing path. +// It is up to the caller to ensure that the amount of covenantSigs matches the +// expected quorum of covenenant members, the finality provider sigs respect the finality providers +// that the delegation belongs to, and the transaction has slashing path. +func (si *SpendInfo) CreateSlashingPathWitness( + covenantSigs []*schnorr.Signature, + fpSigs []*schnorr.Signature, + delegatorSig *schnorr.Signature, +) (wire.TxWitness, error) { if si == nil { panic("cannot build witness without spend info") } From d64ddc97d1c8b9f695b814b7b1b92ce133f2547b Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Tue, 9 Jul 2024 21:05:16 +0800 Subject: [PATCH 102/119] chore: Rename magic bytes to tag (#696) --- btcstaking/identifiable_staking.go | 76 ++++++++++++------------- btcstaking/identifiable_staking_test.go | 13 +++-- btcstaking/staking_testvectors_test.go | 19 ++++--- btcstaking/testvectors/vectors.json | 10 ++-- docs/transaction-impl-spec.md | 8 +-- 5 files changed, 64 insertions(+), 62 deletions(-) diff --git a/btcstaking/identifiable_staking.go b/btcstaking/identifiable_staking.go index cd28468c9..d75288dd5 100644 --- a/btcstaking/identifiable_staking.go +++ b/btcstaking/identifiable_staking.go @@ -16,9 +16,9 @@ import ( ) const ( - // length of magic prefix indentifying staking transactions - MagicBytesLen = 4 - // 4 bytes magic bytes + 1 byte version + 32 bytes staker public key + 32 bytes finality provider public key + 2 bytes staking time + // length of tag prefix indentifying staking transactions + TagLen = 4 + // 4 bytes tag + 1 byte version + 32 bytes staker public key + 32 bytes finality provider public key + 2 bytes staking time V0OpReturnDataSize = 71 v0OpReturnCreationErrMsg = "cannot create V0 op_return data" @@ -50,7 +50,7 @@ func uint16FromBytes(b []byte) (uint16, error) { // V0OpReturnData represents the data that is embedded in the OP_RETURN output // It marshalls to exactly 71 bytes type V0OpReturnData struct { - MagicBytes []byte + Tag []byte Version byte StakerPublicKey *XonlyPubKey FinalityProviderPublicKey *XonlyPubKey @@ -58,13 +58,13 @@ type V0OpReturnData struct { } func NewV0OpReturnData( - magicBytes []byte, + tag []byte, stakerPublicKey []byte, finalityProviderPublicKey []byte, stakingTime []byte, ) (*V0OpReturnData, error) { - if len(magicBytes) != MagicBytesLen { - return nil, fmt.Errorf("%s: invalid magic bytes length: %d, expected: %d", v0OpReturnCreationErrMsg, len(magicBytes), MagicBytesLen) + if len(tag) != TagLen { + return nil, fmt.Errorf("%s: invalid tag length: %d, expected: %d", v0OpReturnCreationErrMsg, len(tag), TagLen) } stakerKey, err := XOnlyPublicKeyFromBytes(stakerPublicKey) @@ -85,17 +85,17 @@ func NewV0OpReturnData( return nil, fmt.Errorf("%s:invalid staking time:%w", v0OpReturnCreationErrMsg, err) } - return NewV0OpReturnDataFromParsed(magicBytes, stakerKey.PubKey, fpKey.PubKey, stakingTimeValue) + return NewV0OpReturnDataFromParsed(tag, stakerKey.PubKey, fpKey.PubKey, stakingTimeValue) } func NewV0OpReturnDataFromParsed( - magicBytes []byte, + tag []byte, stakerPublicKey *btcec.PublicKey, finalityProviderPublicKey *btcec.PublicKey, stakingTime uint16, ) (*V0OpReturnData, error) { - if len(magicBytes) != MagicBytesLen { - return nil, fmt.Errorf("%s:invalid magic bytes length: %d, expected: %d", v0OpReturnCreationErrMsg, len(magicBytes), MagicBytesLen) + if len(tag) != TagLen { + return nil, fmt.Errorf("%s:invalid tag length: %d, expected: %d", v0OpReturnCreationErrMsg, len(tag), TagLen) } if stakerPublicKey == nil { @@ -107,7 +107,7 @@ func NewV0OpReturnDataFromParsed( } return &V0OpReturnData{ - MagicBytes: magicBytes, + Tag: tag, Version: 0, StakerPublicKey: &XonlyPubKey{stakerPublicKey}, FinalityProviderPublicKey: &XonlyPubKey{finalityProviderPublicKey}, @@ -119,18 +119,18 @@ func NewV0OpReturnDataFromBytes(b []byte) (*V0OpReturnData, error) { if len(b) != V0OpReturnDataSize { return nil, fmt.Errorf("invalid op return data length: %d, expected: %d", len(b), V0OpReturnDataSize) } - magicBytes := b[:MagicBytesLen] + tag := b[:TagLen] - version := b[MagicBytesLen] + version := b[TagLen] if version != 0 { return nil, fmt.Errorf("invalid op return version: %d, expected: %d", version, 0) } - stakerPublicKey := b[MagicBytesLen+1 : MagicBytesLen+1+schnorr.PubKeyBytesLen] - finalityProviderPublicKey := b[MagicBytesLen+1+schnorr.PubKeyBytesLen : MagicBytesLen+1+schnorr.PubKeyBytesLen*2] - stakingTime := b[MagicBytesLen+1+schnorr.PubKeyBytesLen*2:] - return NewV0OpReturnData(magicBytes, stakerPublicKey, finalityProviderPublicKey, stakingTime) + stakerPublicKey := b[TagLen+1 : TagLen+1+schnorr.PubKeyBytesLen] + finalityProviderPublicKey := b[TagLen+1+schnorr.PubKeyBytesLen : TagLen+1+schnorr.PubKeyBytesLen*2] + stakingTime := b[TagLen+1+schnorr.PubKeyBytesLen*2:] + return NewV0OpReturnData(tag, stakerPublicKey, finalityProviderPublicKey, stakingTime) } func getV0OpReturnBytes(out *wire.TxOut) ([]byte, error) { @@ -164,7 +164,7 @@ func NewV0OpReturnDataFromTxOutput(out *wire.TxOut) (*V0OpReturnData, error) { func (d *V0OpReturnData) Marshall() []byte { var data []byte - data = append(data, d.MagicBytes...) + data = append(data, d.Tag...) data = append(data, d.Version) data = append(data, d.StakerPublicKey.Marshall()...) data = append(data, d.FinalityProviderPublicKey.Marshall()...) @@ -182,7 +182,7 @@ func (d *V0OpReturnData) ToTxOutput() (*wire.TxOut, error) { // BuildV0IdentifiableStakingOutputs creates outputs which every staking transaction must have func BuildV0IdentifiableStakingOutputs( - magicBytes []byte, + tag []byte, stakerKey *btcec.PublicKey, fpKey *btcec.PublicKey, covenantKeys []*btcec.PublicKey, @@ -204,7 +204,7 @@ func BuildV0IdentifiableStakingOutputs( return nil, err } - opReturnData, err := NewV0OpReturnDataFromParsed(magicBytes, stakerKey, fpKey, stakingTime) + opReturnData, err := NewV0OpReturnDataFromParsed(tag, stakerKey, fpKey, stakingTime) if err != nil { return nil, err @@ -229,7 +229,7 @@ func BuildV0IdentifiableStakingOutputs( // BuildV0IdentifiableStakingOutputsAndTx creates outputs which every staking transaction must have and // returns the not-funded transaction with these outputs func BuildV0IdentifiableStakingOutputsAndTx( - magicBytes []byte, + tag []byte, stakerKey *btcec.PublicKey, fpKey *btcec.PublicKey, covenantKeys []*btcec.PublicKey, @@ -239,7 +239,7 @@ func BuildV0IdentifiableStakingOutputsAndTx( net *chaincfg.Params, ) (*IdentifiableStakingInfo, *wire.MsgTx, error) { info, err := BuildV0IdentifiableStakingOutputs( - magicBytes, + tag, stakerKey, fpKey, covenantKeys, @@ -344,7 +344,7 @@ func tryToGetStakingOutput(outputs []*wire.TxOut, stakingOutputPkScript []byte) // It does all necessary checks to ensure that the transaction is valid staking transaction. func ParseV0StakingTx( tx *wire.MsgTx, - expectedMagicBytes []byte, + expectedTag []byte, covenantKeys []*btcec.PublicKey, covenantQuorum uint32, net *chaincfg.Params, @@ -354,8 +354,8 @@ func ParseV0StakingTx( return nil, fmt.Errorf("nil tx") } - if len(expectedMagicBytes) != MagicBytesLen { - return nil, fmt.Errorf("invalid magic bytes length: %d, expected: %d", len(expectedMagicBytes), MagicBytesLen) + if len(expectedTag) != TagLen { + return nil, fmt.Errorf("invalid tag length: %d, expected: %d", len(expectedTag), TagLen) } if len(covenantKeys) == 0 { @@ -382,11 +382,11 @@ func ParseV0StakingTx( } // at this point we know that transaction has op return output which seems to match - // the expected shape. Check the magic bytes and version. - if !bytes.Equal(opReturnData.MagicBytes, expectedMagicBytes) { - return nil, fmt.Errorf("unexpected magic bytes: %s, expected: %s", - hex.EncodeToString(opReturnData.MagicBytes), - hex.EncodeToString(expectedMagicBytes), + // the expected shape. Check the tag and version. + if !bytes.Equal(opReturnData.Tag, expectedTag) { + return nil, fmt.Errorf("unexpected tag: %s, expected: %s", + hex.EncodeToString(opReturnData.Tag), + hex.EncodeToString(expectedTag), ) } @@ -434,11 +434,11 @@ func ParseV0StakingTx( // checks: // 1. Whether the transaction has at least 2 outputs // 2. have an op return output -// 3. op return output has expected magic bytes +// 3. op return output has expected tag // This function is much faster than ParseV0StakingTx, as it does not perform // all necessary checks. -func IsPossibleV0StakingTx(tx *wire.MsgTx, expectedMagicBytes []byte) bool { - if len(expectedMagicBytes) != MagicBytesLen { +func IsPossibleV0StakingTx(tx *wire.MsgTx, expectedTag []byte) bool { + if len(expectedTag) != TagLen { return false } @@ -457,18 +457,18 @@ func IsPossibleV0StakingTx(tx *wire.MsgTx, expectedMagicBytes []byte) bool { continue } - if !bytes.Equal(data[:MagicBytesLen], expectedMagicBytes) { - // this is not the op return output we are looking for as magic bytes do not match + if !bytes.Equal(data[:TagLen], expectedTag) { + // this is not the op return output we are looking for as tag do not match continue } - if data[MagicBytesLen] != 0 { + if data[TagLen] != 0 { // this is not the v0 op return output continue } if possibleStakingTx { - // this is second output that matches the magic bytes, we do not allow for multiple op return outputs + // this is second output that matches the tag, we do not allow for multiple op return outputs // so this is not a valid staking transaction return false } diff --git a/btcstaking/identifiable_staking_test.go b/btcstaking/identifiable_staking_test.go index fb714a7d4..6f790f8d8 100644 --- a/btcstaking/identifiable_staking_test.go +++ b/btcstaking/identifiable_staking_test.go @@ -7,12 +7,13 @@ import ( "github.com/babylonchain/babylon/btcstaking" - "github.com/babylonchain/babylon/testutil/datagen" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/testutil/datagen" ) func generateTxFromOutputs(r *rand.Rand, info *btcstaking.IdentifiableStakingInfo) (*wire.MsgTx, int, int) { @@ -47,13 +48,13 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { quroum := uint32(r.Intn(int(numCovenantKeys)) + 1) stakingAmount := btcutil.Amount(r.Int63n(1000000000) + 10000) stakingTime := uint16(r.Int31n(math.MaxUint16-1) + 1) - magicBytes := datagen.GenRandomByteArray(r, btcstaking.MagicBytesLen) + tag := datagen.GenRandomByteArray(r, btcstaking.TagLen) net := &chaincfg.MainNetParams sc := GenerateTestScenario(r, t, 1, numCovenantKeys, quroum, stakingAmount, stakingTime) outputs, err := btcstaking.BuildV0IdentifiableStakingOutputs( - magicBytes, + tag, sc.StakerKey.PubKey(), sc.FinalityProviderKeys[0].PubKey(), sc.CovenantPublicKeys(), @@ -70,11 +71,11 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { // ParseV0StakingTx and IsPossibleV0StakingTx should be consistent and recognize // the same tx as a valid staking tx - require.True(t, btcstaking.IsPossibleV0StakingTx(tx, magicBytes)) + require.True(t, btcstaking.IsPossibleV0StakingTx(tx, tag)) parsedTx, err := btcstaking.ParseV0StakingTx( tx, - magicBytes, + tag, sc.CovenantPublicKeys(), quroum, net, @@ -90,7 +91,7 @@ func FuzzGenerateAndParseValidV0StakingTransaction(f *testing.F) { require.Equal(t, outputs.OpReturnOutput.Value, parsedTx.OpReturnOutput.Value) require.Equal(t, opReturnOutputIdx, parsedTx.OpReturnOutputIdx) - require.Equal(t, magicBytes, parsedTx.OpReturnData.MagicBytes) + require.Equal(t, tag, parsedTx.OpReturnData.Tag) require.Equal(t, uint8(0), parsedTx.OpReturnData.Version) require.Equal(t, stakingTime, parsedTx.OpReturnData.StakingTime) diff --git a/btcstaking/staking_testvectors_test.go b/btcstaking/staking_testvectors_test.go index 52521e21b..2a60273f5 100644 --- a/btcstaking/staking_testvectors_test.go +++ b/btcstaking/staking_testvectors_test.go @@ -8,13 +8,14 @@ import ( "os" "testing" - "github.com/babylonchain/babylon/btcstaking" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/btcstaking" ) func getBtcNetworkParams(network string) (*chaincfg.Params, error) { @@ -86,7 +87,7 @@ type Parameters struct { UnbondingTxVersion int `json:"unbonding_tx_version"` UnbondingTime int `json:"unbonding_time"` UnbondingFee int `json:"unbonding_fee"` - MagicBytes string `json:"magic_bytes"` + Tag string `json:"tag"` Network string `json:"network"` } @@ -124,7 +125,7 @@ type ParsedParams struct { UnbondingTxVersion uint32 UnbondingTime uint16 UnbondingFee btcutil.Amount - MagicBytes []byte + Tag []byte Network *chaincfg.Params } @@ -139,7 +140,7 @@ func parseTestParams(t *testing.T, p *Parameters) (*ParsedParams, error) { return nil, err } - magicBytes, err := hex.DecodeString(p.MagicBytes) + tag, err := hex.DecodeString(p.Tag) if err != nil { return nil, err } @@ -161,7 +162,7 @@ func parseTestParams(t *testing.T, p *Parameters) (*ParsedParams, error) { UnbondingTxVersion: uint32(p.UnbondingTxVersion), UnbondingTime: uint16(p.UnbondingTime), UnbondingFee: btcutil.Amount(p.UnbondingFee), - MagicBytes: magicBytes, + Tag: tag, Network: network, }, nil } @@ -260,7 +261,7 @@ func TestVectorsCompatiblity(t *testing.T) { if tc.Expected.OpReturnScript != "" { data, err := btcstaking.NewV0OpReturnDataFromParsed( - parsedParams.MagicBytes, + parsedParams.Tag, parsedParams.StakerPublicKey, parsedParams.FinalityProviderPublicKeys[0], parsedParams.StakingTime, @@ -320,7 +321,7 @@ func GenerateTestCase( stakingTime int, unbondingTime int, unbondingFee int, - magicBytes []byte, + tag []byte, ) string { emptyHash := [32]byte{} eh, err := chainhash.NewHash(emptyHash[:]) @@ -379,7 +380,7 @@ func GenerateTestCase( // if there is more build op_return output if len(finalityKeys) == 1 { opInfo, err := btcstaking.BuildV0IdentifiableStakingOutputs( - magicBytes, + tag, keysToPubKeys(t, stakerKeys)[0], keysToPubKeys(t, finalityKeys)[0], keysToPubKeys(t, covenantKeys), @@ -404,7 +405,7 @@ func GenerateTestCase( UnbondingTxVersion: 2, UnbondingTime: unbondingTime, UnbondingFee: unbondingFee, - MagicBytes: hex.EncodeToString(magicBytes), + Tag: hex.EncodeToString(tag), Network: "mainnet", } diff --git a/btcstaking/testvectors/vectors.json b/btcstaking/testvectors/vectors.json index 0ca091df3..a3272abf5 100644 --- a/btcstaking/testvectors/vectors.json +++ b/btcstaking/testvectors/vectors.json @@ -18,7 +18,7 @@ "unbonding_tx_version": 2, "unbonding_time": 100, "unbonding_fee": 2000, - "magic_bytes": "01020304", + "tag": "01020304", "network": "mainnet" }, "expected": { @@ -55,7 +55,7 @@ "unbonding_tx_version": 2, "unbonding_time": 50, "unbonding_fee": 20000, - "magic_bytes": "01020304", + "tag": "01020304", "network": "mainnet" }, "expected": { @@ -94,7 +94,7 @@ "unbonding_tx_version": 2, "unbonding_time": 50, "unbonding_fee": 20000, - "magic_bytes": "01020304", + "tag": "01020304", "network": "mainnet" }, "expected": { @@ -135,7 +135,7 @@ "unbonding_tx_version": 2, "unbonding_time": 201, "unbonding_fee": 50000, - "magic_bytes": "01020304", + "tag": "01020304", "network": "mainnet" }, "expected": { @@ -196,7 +196,7 @@ "unbonding_tx_version": 2, "unbonding_time": 201, "unbonding_fee": 100000, - "magic_bytes": "01020304", + "tag": "01020304", "network": "mainnet" }, "expected": { diff --git a/docs/transaction-impl-spec.md b/docs/transaction-impl-spec.md index 17a3b2707..4cf55e823 100644 --- a/docs/transaction-impl-spec.md +++ b/docs/transaction-impl-spec.md @@ -81,7 +81,7 @@ Data in the OP_RETURN output is described by the following struct: ```go type V0OpReturnData struct { - MagicBytes []byte + Tag []byte Version byte StakerPublicKey []byte FinalityProviderPublicKey []byte @@ -91,7 +91,7 @@ type V0OpReturnData struct { The implementation of the struct can be found [here](../btcstaking/identifiable_staking.go?pain=1#L52) Fields description: -- `MagicBytes` - 4 bytes, tag which is used to identify the staking transaction +- `Tag` - 4 bytes, tag which is used to identify the staking transaction among other transactions in the Bitcoin ledger. It is specified in the `global_parameters.Tag` field. - `Version` - 1 byte, current version of the OP_RETURN output @@ -107,7 +107,7 @@ output in the staking transaction. This data is serialized as follows: ``` -SerializedStakingData = MagicBytes || Version || StakerPublicKey || FinalityProviderPublicKey || StakingTime +SerializedStakingData = Tag || Version || StakerPublicKey || FinalityProviderPublicKey || StakingTime ``` To transform this data into OP_RETURN data: @@ -166,7 +166,7 @@ function with the following signature: ```go func BuildV0IdentifiableStakingOutputsAndTx( - magicBytes []byte, + tag []byte, stakerKey *btcec.PublicKey, fpKey *btcec.PublicKey, covenantKeys []*btcec.PublicKey, From 22b9969c32e4ee58d48f047797036215a4d689b3 Mon Sep 17 00:00:00 2001 From: omahs <73983677+omahs@users.noreply.github.com> Date: Wed, 10 Jul 2024 11:23:15 +0200 Subject: [PATCH 103/119] chore: fix typos (#702) --- docs/run-node.md | 2 +- docs/staking-script.md | 6 +++--- x/epoching/README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/run-node.md b/docs/run-node.md index 8e1b1be41..b6b2f2a4b 100644 --- a/docs/run-node.md +++ b/docs/run-node.md @@ -44,7 +44,7 @@ The `gentxs` directory contains the genesis transactions. It contains transactions that assign bbn tokens to a single address that is defined for each node. -The `node0` directory contains the the following, +The `node0` directory contains the following, ```console $ ls .testnet/node0/babylond diff --git a/docs/staking-script.md b/docs/staking-script.md index 9957bffb0..23ff7bc7f 100644 --- a/docs/staking-script.md +++ b/docs/staking-script.md @@ -5,7 +5,7 @@ Babylon's BTC staking protocol turns Bitcoin into a staking asset with the aim to enhance the economic security of the Babylon chain. Bitcoin holders can stake their Bitcoin by locking them using a special transaction on the Bitcoin chain. -The locked Bitcoin contribute to Babylon chain's economic security and generate +The locked Bitcoin contributes to Babylon chain's economic security and generates yields for the Bitcoin stakers. The protocol has the following important properties: @@ -36,7 +36,7 @@ the Bitcoin Staker, and the other is called the Finality Provider. - **Bitcoin Staker**: A Bitcoin Staker is an entity identified by `` in staking scripts. Note that a staking transaction can be funded from -arbitrary UTXO, including those owned by multsig/MPC/threshold accounts. +arbitrary UTXO, including those owned by multisig/MPC/threshold accounts. Thus, `` is not necessarily the address of the source of the fund. Rather, it is the controller and beneficiary of the stake after its creation. - **Finality Provider**: A Finality Provider is the an entity that votes @@ -259,7 +259,7 @@ This leads to following system wide repercussions: unbonding transaction in this staking request. This staking request will become active only when `CovenantThreshold` signatures will be received by Babylon chain. Lack of `FinalityProviderPk` in unbonding path, means that after - delegation becomes active, staker can send unbodning transaction any time + delegation becomes active, staker can send unbonding transaction any time without asking finality provider for permission. - existence of `FinalityProviderPk` in slashing path, coupled with the fact that btc staker needs to provide pre-signed slashing transaction which needs to be diff --git a/x/epoching/README.md b/x/epoching/README.md index e557c8df8..0800dc108 100644 --- a/x/epoching/README.md +++ b/x/epoching/README.md @@ -350,7 +350,7 @@ module, and then inserts the message to the epoch message queue storage. ### MsgUpdateParams The `MsgUpdateParams` message is used for updating the module parameters for the -Epoching module. It can only be executed via a govenance proposal. +Epoching module. It can only be executed via a governance proposal. ```protobuf // MsgUpdateParams defines a message for updating Epoching module parameters. From beebc9c5d56786ab0ad37428e3d32559c666d526 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 12 Jul 2024 09:33:22 +0800 Subject: [PATCH 104/119] refactor: Extract public functions (#706) --- btcstaking/btcstaking_test.go | 72 +++++++++-------------------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/btcstaking/btcstaking_test.go b/btcstaking/btcstaking_test.go index 02bf5f612..fc41142aa 100644 --- a/btcstaking/btcstaking_test.go +++ b/btcstaking/btcstaking_test.go @@ -86,6 +86,18 @@ func (t *TestScenario) FinalityProviderPublicKeys() []*btcec.PublicKey { return finalityProviderPubKeys } +func createSpendStakeTx(amount btcutil.Amount) *wire.MsgTx { + spendStakeTx := wire.NewMsgTx(2) + spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) + spendStakeTx.AddTxOut( + &wire.TxOut{ + PkScript: []byte("doesn't matter"), + Value: int64(amount), + }, + ) + return spendStakeTx +} + func TestSpendingTimeLockPath(t *testing.T) { r := rand.New(rand.NewSource(time.Now().Unix())) scenario := GenerateTestScenario( @@ -110,15 +122,7 @@ func TestSpendingTimeLockPath(t *testing.T) { require.NoError(t, err) - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(scenario.StakingAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(scenario.StakingAmount.MulF64(0.5)) // to spend tx as staker, we need to set the sequence number to be >= stakingTimeBlocks spendStakeTx.TxIn[0].Sequence = uint32(scenario.StakingTime) @@ -248,15 +252,7 @@ func TestSpendingUnbondingPathCovenant35MultiSig(t *testing.T) { require.NoError(t, err) - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(scenario.StakingAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(scenario.StakingAmount.MulF64(0.5)) si, err := stakingInfo.UnbondingPathSpendInfo() require.NoError(t, err) @@ -326,15 +322,7 @@ func TestSpendingUnbondingPathSingleKeyCovenant(t *testing.T) { require.NoError(t, err) - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(scenario.StakingAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(scenario.StakingAmount.MulF64(0.5)) si, err := stakingInfo.UnbondingPathSpendInfo() require.NoError(t, err) @@ -398,15 +386,7 @@ func TestSpendingSlashingPathCovenant35MultiSig(t *testing.T) { require.NoError(t, err) - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(scenario.StakingAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(scenario.StakingAmount.MulF64(0.5)) si, err := stakingInfo.SlashingPathSpendInfo() require.NoError(t, err) @@ -484,15 +464,7 @@ func TestSpendingSlashingPathCovenant35MultiSigFinalityProviderRestaking(t *test require.NoError(t, err) - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(scenario.StakingAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(scenario.StakingAmount.MulF64(0.5)) si, err := stakingInfo.SlashingPathSpendInfo() require.NoError(t, err) @@ -553,15 +525,7 @@ func TestSpendingRelativeTimeLockScript(t *testing.T) { lockedAmount := btcutil.Amount(2 * 10e8) // to spend output with relative timelock transaction need to be version two or higher - spendStakeTx := wire.NewMsgTx(2) - spendStakeTx.AddTxIn(wire.NewTxIn(&wire.OutPoint{}, nil, nil)) - spendStakeTx.AddTxOut( - &wire.TxOut{ - PkScript: []byte("doesn't matter"), - // spend half of the staking amount - Value: int64(lockedAmount.MulF64(0.5)), - }, - ) + spendStakeTx := createSpendStakeTx(lockedAmount.MulF64(0.5)) tls, err := btcstaking.BuildRelativeTimelockTaprootScript( stakerPubKey, From 57800f8d2edca52c33eb6d1d7c46e5a2bbdc19f3 Mon Sep 17 00:00:00 2001 From: Stan Zhang <32720167+jz448@users.noreply.github.com> Date: Mon, 15 Jul 2024 09:27:31 +0800 Subject: [PATCH 105/119] Fix a typo in docs/run-node.md (#711) --- docs/run-node.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/run-node.md b/docs/run-node.md index b6b2f2a4b..e92eb4363 100644 --- a/docs/run-node.md +++ b/docs/run-node.md @@ -82,7 +82,7 @@ babylond --home .testnet/node{i}/babylond/ --chain-id \ query ``` -For example, in order to get the hashes maintained by the `btcligthclient` +For example, in order to get the hashes maintained by the `btclightclient` module: ```console From b3c5196f6f747b627809f678a3d9f1c62a3f7cd3 Mon Sep 17 00:00:00 2001 From: Abdullah Eryuzlu <24809834+aeryz@users.noreply.github.com> Date: Mon, 15 Jul 2024 12:16:26 +0300 Subject: [PATCH 106/119] Add `08-wasm` clients module (#695) * feat: add 08-wasm clients support Signed-off-by: aeryz * chore: bump ibc-go to v8.3.0 Signed-off-by: aeryz --------- Signed-off-by: aeryz --- app/app.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++------- go.mod | 9 +++++---- go.sum | 14 ++++++++------ 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/app/app.go b/app/app.go index d83795c73..7dc8e63d8 100644 --- a/app/app.go +++ b/app/app.go @@ -102,6 +102,9 @@ import ( "github.com/cosmos/ibc-go/modules/capability" capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + ibcwasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm" + ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" + ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" ibcfee "github.com/cosmos/ibc-go/v8/modules/apps/29-fee" ibcfeekeeper "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/keeper" ibcfeetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" @@ -166,12 +169,6 @@ const ( ) var ( - // TODO review possible capabilities - // The last arguments can contain custom message handlers, and custom query handlers, - // if we want to allow any custom callbacks - // See https://github.com/CosmWasm/cosmwasm/blob/main/docs/CAPABILITIES-BUILT-IN.md - wasmCapabilities = []string{"iterator", "stargate", "cosmwasm_1_1", "cosmwasm_1_2", "staking", "babylon"} - // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string // fee collector account, module accounts and their permissions @@ -246,6 +243,7 @@ type BabylonApp struct { IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly IBCFeeKeeper ibcfeekeeper.Keeper // for relayer incentivization - https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment TransferKeeper ibctransferkeeper.Keeper // for cross-chain fungible token transfers + IBCWasmKeeper ibcwasmkeeper.Keeper // for IBC wasm light clients ZoneConciergeKeeper zckeeper.Keeper // for cross-chain fungible token transfers // BTC staking related modules @@ -327,6 +325,7 @@ func NewBabylonApp( ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, + ibcwasmtypes.StoreKey, zctypes.StoreKey, // BTC staking related modules btcstakingtypes.StoreKey, @@ -734,11 +733,27 @@ func NewBabylonApp( app.GRPCQueryRouter(), homePath, wasmConfig, - wasmCapabilities, + WasmCapabilities(), authtypes.NewModuleAddress(govtypes.ModuleName).String(), wasmOpts..., ) + ibcWasmConfig := + ibcwasmtypes.WasmConfig{ + DataDir: filepath.Join(homePath, "ibc_08-wasm"), + SupportedCapabilities: WasmCapabilities(), + ContractDebugMode: false, + } + + app.IBCWasmKeeper = ibcwasmkeeper.NewKeeperWithConfig( + appCodec, + runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), + app.IBCKeeper.ClientKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ibcWasmConfig, + app.GRPCQueryRouter(), + ) + // Set legacy router for backwards compatibility with gov v1beta1 app.GovKeeper.SetLegacyRouter(govRouter) @@ -803,6 +818,7 @@ func NewBabylonApp( transfer.NewAppModule(app.TransferKeeper), ibcfee.NewAppModule(app.IBCFeeKeeper), ibctm.AppModule{}, + ibcwasm.NewAppModule(app.IBCWasmKeeper), // Babylon modules - btc timestamping epoching.NewAppModule(appCodec, app.EpochingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper), btclightclient.NewAppModule(appCodec, app.BTCLightClientKeeper), @@ -862,6 +878,7 @@ func NewBabylonApp( monitortypes.ModuleName, // IBC-related modules ibcexported.ModuleName, + ibcwasmtypes.ModuleName, ibctransfertypes.ModuleName, zctypes.ModuleName, ibcfeetypes.ModuleName, @@ -890,6 +907,7 @@ func NewBabylonApp( monitortypes.ModuleName, // IBC-related modules ibcexported.ModuleName, + ibcwasmtypes.ModuleName, ibctransfertypes.ModuleName, zctypes.ModuleName, ibcfeetypes.ModuleName, @@ -922,6 +940,7 @@ func NewBabylonApp( monitortypes.ModuleName, // IBC-related modules ibcexported.ModuleName, + ibcwasmtypes.ModuleName, ibctransfertypes.ModuleName, zctypes.ModuleName, ibcfeetypes.ModuleName, @@ -1028,6 +1047,13 @@ func NewBabylonApp( if err != nil { panic(fmt.Errorf("failed to register snapshot extension: %s", err)) } + + err = manager.RegisterExtensions( + ibcwasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.IBCWasmKeeper), + ) + if err != nil { + panic(fmt.Errorf("failed to register snapshot extension: %s", err)) + } } app.ScopedIBCKeeper = scopedIBCKeeper @@ -1296,3 +1322,20 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino return paramsKeeper } + +// Capabilities of the IBC wasm contracts +func WasmCapabilities() []string { + // The last arguments can contain custom message handlers, and custom query handlers, + // if we want to allow any custom callbacks + return []string{ + "iterator", + "staking", + "stargate", + "cosmwasm_1_1", + "cosmwasm_1_2", + "cosmwasm_1_3", + "cosmwasm_1_4", + "cosmwasm_2_0", + "babylon", + } +} diff --git a/go.mod b/go.mod index 978f302be..30fd3ecc6 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,10 @@ module github.com/babylonchain/babylon require ( github.com/CosmWasm/wasmd v0.51.0 github.com/btcsuite/btcd v0.24.2 - github.com/cometbft/cometbft v0.38.6 + github.com/cometbft/cometbft v0.38.7 github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/cosmos/cosmos-sdk v0.50.6 + github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.0.0-20240429153234-e1e6da7e4ead github.com/cosmos/relayer/v2 v2.5.1 github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 @@ -38,7 +39,7 @@ require ( cosmossdk.io/x/feegrant v0.1.0 cosmossdk.io/x/tx v0.13.3 cosmossdk.io/x/upgrade v0.1.1 - github.com/CosmWasm/wasmvm/v2 v2.0.0 + github.com/CosmWasm/wasmvm/v2 v2.0.1 github.com/avast/retry-go/v4 v4.5.1 github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d github.com/btcsuite/btcd/btcec/v2 v2.3.2 @@ -48,7 +49,7 @@ require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 github.com/cosmos/gogoproto v1.4.12 github.com/cosmos/ibc-go/modules/capability v1.0.0 - github.com/cosmos/ibc-go/v8 v8.0.0 + github.com/cosmos/ibc-go/v8 v8.3.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 github.com/docker/docker v23.0.8+incompatible github.com/golang/mock v1.6.0 @@ -60,6 +61,7 @@ require ( github.com/ory/dockertest/v3 v3.9.1 github.com/vulpine-io/io-test v1.0.0 go.uber.org/zap v1.26.0 + golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de ) @@ -242,7 +244,6 @@ require ( go.opentelemetry.io/otel/metric v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/oauth2 v0.18.0 // indirect diff --git a/go.sum b/go.sum index aac30481a..8dfff70fa 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CosmWasm/wasmd v0.51.0 h1:3A2o20RrdF7P1D3Xb+R7A/pHbbHWsYCDXrHLa7S0SC8= github.com/CosmWasm/wasmd v0.51.0/go.mod h1:7TSaj5HoolghujuVWeExqmcUKgpcYWEySGLSODbnnwY= -github.com/CosmWasm/wasmvm/v2 v2.0.0 h1:IqNCI2G0mvs7K6ej17/I28805rVqnu+Y1cWDqIdwb08= -github.com/CosmWasm/wasmvm/v2 v2.0.0/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck= +github.com/CosmWasm/wasmvm/v2 v2.0.1 h1:0YCQ7MKGNri7NFeRp75erPJXrqyCtH4gdc9jMstyMzk= +github.com/CosmWasm/wasmvm/v2 v2.0.1/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -378,8 +378,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk= -github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= +github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= +github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= @@ -415,8 +415,10 @@ github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= -github.com/cosmos/ibc-go/v8 v8.0.0/go.mod h1:C6IiJom0F3cIQCD5fKwVPDrDK9j/xTu563AWuOmXois= +github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.0.0-20240429153234-e1e6da7e4ead h1:QB50+AmrEVqFr2hzvIxMkICziWQ/uuebze0vNYKMnBg= +github.com/cosmos/ibc-go/modules/light-clients/08-wasm v0.0.0-20240429153234-e1e6da7e4ead/go.mod h1:AJeroAXnPKeFpD1AfEfjYBHGEWt5gBfzUjgs4SYn2ZY= +github.com/cosmos/ibc-go/v8 v8.3.0 h1:fdW2S7NjZYFhSwmCaFjjyDv80kI1ePOJDQmco4qrnD0= +github.com/cosmos/ibc-go/v8 v8.3.0/go.mod h1:izwHZvn9lKrBn8xWj0aXWut6HKcwHMPD3uyuvOJoPSA= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= From ab5129460681b4682f44ef66bdc764ba7060f7ff Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 16 Jul 2024 13:52:04 +0800 Subject: [PATCH 107/119] feat(gov): software upgrade governance proposal support (#705) * refactor: moving keepers to a new struct (#697) * upgrade: framework for writing software upgrade migration function (#703) * fix: execute `PreBlocker` for upgrade module (#707) * docstring for vanilla upgrade --- app/app.go | 750 +++++--------------------- app/export.go | 2 +- app/keepers/keepers.go | 630 ++++++++++++++++++++++ app/keepers/keys.go | 48 ++ app/{ => keepers}/utils.go | 2 +- app/test_helpers.go | 13 +- app/upgrades/README.md | 43 ++ app/upgrades/types.go | 48 ++ app/upgrades/vanilla/README.md | 4 + app/upgrades/vanilla/upgrades.go | 64 +++ app/upgrades/vanilla/upgrades_test.go | 105 ++++ cmd/babylond/cmd/root.go | 5 +- cmd/babylond/cmd/testnet.go | 4 +- test/e2e/initialization/init.go | 4 +- testutil/datagen/genesiskey.go | 12 +- testutil/helper/helper.go | 12 +- x/checkpointing/module.go | 3 +- x/checkpointing/proposal.go | 7 +- 18 files changed, 1096 insertions(+), 660 deletions(-) create mode 100644 app/keepers/keepers.go create mode 100644 app/keepers/keys.go rename app/{ => keepers}/utils.go (99%) create mode 100644 app/upgrades/README.md create mode 100644 app/upgrades/types.go create mode 100644 app/upgrades/vanilla/README.md create mode 100644 app/upgrades/vanilla/upgrades.go create mode 100644 app/upgrades/vanilla/upgrades_test.go diff --git a/app/app.go b/app/app.go index 7dc8e63d8..f6b806fe2 100644 --- a/app/app.go +++ b/app/app.go @@ -11,25 +11,21 @@ import ( reflectionv1 "cosmossdk.io/api/cosmos/reflection/v1" "cosmossdk.io/client/v2/autocli" "cosmossdk.io/core/appmodule" - errorsmod "cosmossdk.io/errors" "cosmossdk.io/log" - storetypes "cosmossdk.io/store/types" "cosmossdk.io/x/circuit" - circuitkeeper "cosmossdk.io/x/circuit/keeper" circuittypes "cosmossdk.io/x/circuit/types" "cosmossdk.io/x/evidence" - evidencekeeper "cosmossdk.io/x/evidence/keeper" evidencetypes "cosmossdk.io/x/evidence/types" "cosmossdk.io/x/feegrant" - feegrantkeeper "cosmossdk.io/x/feegrant/keeper" feegrantmodule "cosmossdk.io/x/feegrant/module" "cosmossdk.io/x/upgrade" - upgradekeeper "cosmossdk.io/x/upgrade/keeper" upgradetypes "cosmossdk.io/x/upgrade/types" wasmapp "github.com/CosmWasm/wasmd/app" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/babylonchain/babylon/app/upgrades" + bbn "github.com/babylonchain/babylon/types" abci "github.com/cometbft/cometbft/abci/types" cmtos "github.com/cometbft/cometbft/libs/os" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -49,102 +45,75 @@ import ( "github.com/cosmos/cosmos-sdk/std" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/types/msgservice" "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth/ante" authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" - authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/cosmos-sdk/x/auth/vesting" vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types" "github.com/cosmos/cosmos-sdk/x/authz" - authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module" "github.com/cosmos/cosmos-sdk/x/bank" - bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/cosmos-sdk/x/consensus" - consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" "github.com/cosmos/cosmos-sdk/x/crisis" - crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" distr "github.com/cosmos/cosmos-sdk/x/distribution" - distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/gov" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" "github.com/cosmos/cosmos-sdk/x/mint" - mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/cosmos/cosmos-sdk/x/params" paramsclient "github.com/cosmos/cosmos-sdk/x/params/client" - paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" - paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" "github.com/cosmos/cosmos-sdk/x/slashing" - slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" "github.com/cosmos/ibc-go/modules/capability" - capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" ibcwasm "github.com/cosmos/ibc-go/modules/light-clients/08-wasm" ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" ibcfee "github.com/cosmos/ibc-go/v8/modules/apps/29-fee" - ibcfeekeeper "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/keeper" ibcfeetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" "github.com/cosmos/ibc-go/v8/modules/apps/transfer" - ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" - ibc "github.com/cosmos/ibc-go/v8/modules/core" - porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" // ibc module puts types under `ibchost` rather than `ibctypes` + ibc "github.com/cosmos/ibc-go/v8/modules/core" // ibc module puts types under `ibchost` rather than `ibctypes` ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" - ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cast" + appkeepers "github.com/babylonchain/babylon/app/keepers" appparams "github.com/babylonchain/babylon/app/params" "github.com/babylonchain/babylon/client/docs" - bbn "github.com/babylonchain/babylon/types" - owasm "github.com/babylonchain/babylon/wasmbinding" "github.com/babylonchain/babylon/x/btccheckpoint" - btccheckpointkeeper "github.com/babylonchain/babylon/x/btccheckpoint/keeper" btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" "github.com/babylonchain/babylon/x/btclightclient" - btclightclientkeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking" - btcstakingkeeper "github.com/babylonchain/babylon/x/btcstaking/keeper" btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/babylonchain/babylon/x/checkpointing" - checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" "github.com/babylonchain/babylon/x/epoching" epochingkeeper "github.com/babylonchain/babylon/x/epoching/keeper" epochingtypes "github.com/babylonchain/babylon/x/epoching/types" "github.com/babylonchain/babylon/x/finality" - finalitykeeper "github.com/babylonchain/babylon/x/finality/keeper" finalitytypes "github.com/babylonchain/babylon/x/finality/types" "github.com/babylonchain/babylon/x/incentive" - incentivekeeper "github.com/babylonchain/babylon/x/incentive/keeper" incentivetypes "github.com/babylonchain/babylon/x/incentive/types" "github.com/babylonchain/babylon/x/monitor" - monitorkeeper "github.com/babylonchain/babylon/x/monitor/keeper" monitortypes "github.com/babylonchain/babylon/x/monitor/types" "github.com/babylonchain/babylon/x/zoneconcierge" zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" @@ -169,6 +138,9 @@ const ( ) var ( + // EmptyWasmOpts defines a type alias for a list of wasm options. + EmptyWasmOpts []wasmkeeper.Option + // DefaultNodeHome default home directories for the application daemon DefaultNodeHome string // fee collector account, module accounts and their permissions @@ -183,14 +155,22 @@ var ( ibcfeetypes.ModuleName: nil, incentivetypes.ModuleName: nil, // this line is needed to create an account for incentive module } -) -// Wasm related variables -var ( - // EmptyWasmOpts defines a type alias for a list of wasm options. - EmptyWasmOpts []wasmkeeper.Option + // software upgrades and forks + Upgrades = []upgrades.Upgrade{} + Forks = []upgrades.Fork{} ) +func init() { + // Note: If this changes, the home directory under x/checkpointing/client/cli/tx.go needs to change as well + userHomeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + + DefaultNodeHome = filepath.Join(userHomeDir, ".babylond") +} + var ( _ runtime.AppI = (*BabylonApp)(nil) _ servertypes.Application = (*BabylonApp)(nil) @@ -201,66 +181,14 @@ var ( // capabilities aren't needed for testing. type BabylonApp struct { *baseapp.BaseApp + *appkeepers.AppKeepers + legacyAmino *codec.LegacyAmino appCodec codec.Codec txConfig client.TxConfig interfaceRegistry types.InterfaceRegistry - - invCheckPeriod uint - - // keys to access the substores - keys map[string]*storetypes.KVStoreKey - tkeys map[string]*storetypes.TransientStoreKey - memKeys map[string]*storetypes.MemoryStoreKey - - // keepers - AccountKeeper authkeeper.AccountKeeper - BankKeeper bankkeeper.Keeper - CapabilityKeeper *capabilitykeeper.Keeper - StakingKeeper *stakingkeeper.Keeper - SlashingKeeper slashingkeeper.Keeper - MintKeeper mintkeeper.Keeper - DistrKeeper distrkeeper.Keeper - GovKeeper govkeeper.Keeper - CrisisKeeper *crisiskeeper.Keeper - UpgradeKeeper *upgradekeeper.Keeper - ParamsKeeper paramskeeper.Keeper - AuthzKeeper authzkeeper.Keeper - EvidenceKeeper evidencekeeper.Keeper - FeeGrantKeeper feegrantkeeper.Keeper - ConsensusParamsKeeper consensusparamkeeper.Keeper - CircuitKeeper circuitkeeper.Keeper - - // Babylon modules - EpochingKeeper epochingkeeper.Keeper - BTCLightClientKeeper btclightclientkeeper.Keeper - BtcCheckpointKeeper btccheckpointkeeper.Keeper - CheckpointingKeeper checkpointingkeeper.Keeper - MonitorKeeper monitorkeeper.Keeper - - // IBC-related modules - IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly - IBCFeeKeeper ibcfeekeeper.Keeper // for relayer incentivization - https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment - TransferKeeper ibctransferkeeper.Keeper // for cross-chain fungible token transfers - IBCWasmKeeper ibcwasmkeeper.Keeper // for IBC wasm light clients - ZoneConciergeKeeper zckeeper.Keeper // for cross-chain fungible token transfers - - // BTC staking related modules - BTCStakingKeeper btcstakingkeeper.Keeper - FinalityKeeper finalitykeeper.Keeper - - // wasm smart contract module - WasmKeeper wasmkeeper.Keeper - - // tokenomics-related modules - IncentiveKeeper incentivekeeper.Keeper - - // make scoped keepers public for test purposes - ScopedIBCKeeper capabilitykeeper.ScopedKeeper - ScopedTransferKeeper capabilitykeeper.ScopedKeeper - ScopedZoneConciergeKeeper capabilitykeeper.ScopedKeeper - ScopedWasmKeeper capabilitykeeper.ScopedKeeper + invCheckPeriod uint // the module manager ModuleManager *module.Manager @@ -273,20 +201,15 @@ type BabylonApp struct { configurator module.Configurator } -func init() { - // Note: If this changes, the home directory under x/checkpointing/client/cli/tx.go needs to change as well - userHomeDir, err := os.UserHomeDir() - if err != nil { - panic(err) - } - - DefaultNodeHome = filepath.Join(userHomeDir, ".babylond") -} - // NewBabylonApp returns a reference to an initialized BabylonApp. func NewBabylonApp( - logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool, - invCheckPeriod uint, privSigner *PrivSigner, + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + loadLatest bool, + skipUpgradeHeights map[int64]bool, + invCheckPeriod uint, + privSigner *appkeepers.PrivSigner, appOpts servertypes.AppOptions, wasmOpts []wasmkeeper.Option, baseAppOptions ...func(*baseapp.BaseApp), @@ -294,8 +217,6 @@ func NewBabylonApp( // we could also take it from global object which should be initialised in rootCmd // but this way it makes babylon app more testable btcConfig := bbn.ParseBtcOptionsFromConfig(appOpts) - powLimit := btcConfig.PowLimit() - btcNetParams := btcConfig.NetParams() homePath := cast.ToString(appOpts.Get(flags.FlagHome)) if homePath == "" { homePath = DefaultNodeHome @@ -309,477 +230,44 @@ func NewBabylonApp( std.RegisterLegacyAminoCodec(legacyAmino) std.RegisterInterfaces(interfaceRegistry) - keys := storetypes.NewKVStoreKeys( - authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, - minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, - govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, - evidencetypes.StoreKey, circuittypes.StoreKey, capabilitytypes.StoreKey, - authzkeeper.StoreKey, - // Babylon modules - epochingtypes.StoreKey, - btclightclienttypes.StoreKey, - btccheckpointtypes.StoreKey, - checkpointingtypes.StoreKey, - monitortypes.StoreKey, - // IBC-related modules - ibcexported.StoreKey, - ibctransfertypes.StoreKey, - ibcfeetypes.StoreKey, - ibcwasmtypes.StoreKey, - zctypes.StoreKey, - // BTC staking related modules - btcstakingtypes.StoreKey, - finalitytypes.StoreKey, - // WASM - wasmtypes.StoreKey, - // tokenomics-related modules - incentivetypes.StoreKey, - ) - accountKeeper := authkeeper.NewAccountKeeper( - appCodec, - runtime.NewKVStoreService(keys[authtypes.StoreKey]), - authtypes.ProtoBaseAccount, - maccPerms, - authcodec.NewBech32Codec(appparams.Bech32PrefixAccAddr), - appparams.Bech32PrefixAccAddr, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - bankKeeper := bankkeeper.NewBaseKeeper( - appCodec, - runtime.NewKVStoreService(keys[banktypes.StoreKey]), - accountKeeper, - BlockedAddresses(), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - logger, - ) - - stakingKeeper := stakingkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), - accountKeeper, - bankKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - authcodec.NewBech32Codec(appparams.Bech32PrefixValAddr), - authcodec.NewBech32Codec(appparams.Bech32PrefixConsAddr), - ) - - // NOTE: the epoching module has to be set before the chekpointing module, as the checkpointing module will have access to the epoching module - epochingKeeper := epochingkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[epochingtypes.StoreKey]), - bankKeeper, - stakingKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - checkpointingKeeper := checkpointingkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[checkpointingtypes.StoreKey]), - privSigner.WrappedPV, - epochingKeeper, - ) - - // set proposal extension - prepareOpt := func(bApp *baseapp.BaseApp) { - proposalHandler := checkpointing.NewProposalHandler( - logger, &checkpointingKeeper, bApp.Mempool(), bApp) - proposalHandler.SetHandlers(bApp) - } - baseAppOptions = append(baseAppOptions, prepareOpt) - - // set vote extension - voteExtOp := func(bApp *baseapp.BaseApp) { - voteExtHandler := checkpointing.NewVoteExtensionHandler(logger, &checkpointingKeeper) - voteExtHandler.SetHandlers(bApp) - } - baseAppOptions = append(baseAppOptions, voteExtOp) - bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...) bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetVersion(version.Version) bApp.SetInterfaceRegistry(interfaceRegistry) bApp.SetTxEncoder(txConfig.TxEncoder()) - tkeys := storetypes.NewTransientStoreKeys( - paramstypes.TStoreKey, btccheckpointtypes.TStoreKey) - // NOTE: The testingkey is just mounted for testing purposes. Actual applications should - // not include this key. - memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey") - - // register streaming services - if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil { - panic(err) + wasmConfig, err := wasm.ReadWasmConfig(appOpts) + if err != nil { + panic(fmt.Sprintf("error while reading wasm config: %s", err)) } app := &BabylonApp{ + AppKeepers: &appkeepers.AppKeepers{}, BaseApp: bApp, legacyAmino: legacyAmino, appCodec: appCodec, txConfig: txConfig, interfaceRegistry: interfaceRegistry, invCheckPeriod: invCheckPeriod, - keys: keys, - tkeys: tkeys, - memKeys: memKeys, } - app.ParamsKeeper = initParamsKeeper( - appCodec, - legacyAmino, - keys[paramstypes.StoreKey], - tkeys[paramstypes.TStoreKey], - ) - - app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - runtime.EventService{}, - ) - bApp.SetParamStore(app.ConsensusParamsKeeper.ParamsStore) - - app.CapabilityKeeper = capabilitykeeper.NewKeeper( - appCodec, - keys[capabilitytypes.StoreKey], - memKeys[capabilitytypes.MemStoreKey], - ) - - // grant capabilities for the ibc and ibc-transfer modules - scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) - scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) - scopedZoneConciergeKeeper := app.CapabilityKeeper.ScopeToModule(zctypes.ModuleName) - scopedWasmKeeper := app.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName) - - // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating - // their scoped modules in `NewApp` with `ScopeToModule` - app.CapabilityKeeper.Seal() - - // add keepers - app.AccountKeeper = accountKeeper - - app.BankKeeper = bankKeeper - - app.StakingKeeper = stakingKeeper - - app.CircuitKeeper = circuitkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[circuittypes.StoreKey]), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - app.AccountKeeper.AddressCodec(), - ) - app.BaseApp.SetCircuitBreaker(&app.CircuitKeeper) - - app.MintKeeper = mintkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[minttypes.StoreKey]), - app.StakingKeeper, - app.AccountKeeper, - app.BankKeeper, - authtypes.FeeCollectorName, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - app.DistrKeeper = distrkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[distrtypes.StoreKey]), - app.AccountKeeper, - app.BankKeeper, - app.StakingKeeper, - authtypes.FeeCollectorName, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - // set up incentive keeper - app.IncentiveKeeper = incentivekeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[incentivetypes.StoreKey]), - app.BankKeeper, - app.AccountKeeper, - &epochingKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - authtypes.FeeCollectorName, - ) - - app.SlashingKeeper = slashingkeeper.NewKeeper( - appCodec, - legacyAmino, - runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), - app.StakingKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - app.CrisisKeeper = crisiskeeper.NewKeeper( + app.AppKeepers.InitKeepers( + logger, appCodec, - runtime.NewKVStoreService(keys[crisistypes.StoreKey]), + &btcConfig, + encCfg, + bApp, + maccPerms, + homePath, invCheckPeriod, - app.BankKeeper, - authtypes.FeeCollectorName, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - app.AccountKeeper.AddressCodec(), - ) - - app.FeeGrantKeeper = feegrantkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[feegrant.StoreKey]), - app.AccountKeeper, - ) - // register the staking hooks - // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks - app.StakingKeeper.SetHooks( - stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks(), epochingKeeper.Hooks()), - ) - - // set the governance module account as the authority for conducting upgrades - app.UpgradeKeeper = upgradekeeper.NewKeeper( skipUpgradeHeights, - runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), - appCodec, - homePath, - app.BaseApp, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - app.AuthzKeeper = authzkeeper.NewKeeper( - runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), - appCodec, - app.MsgServiceRouter(), - app.AccountKeeper, - ) - - app.IBCKeeper = ibckeeper.NewKeeper( - appCodec, - keys[ibcexported.StoreKey], - app.GetSubspace(ibcexported.ModuleName), - app.StakingKeeper, - app.UpgradeKeeper, - scopedIBCKeeper, - // From 8.0.0 the IBC keeper requires an authority for the messages - // `MsgIBCSoftwareUpgrade` and `MsgRecoverClient` - // https://github.com/cosmos/ibc-go/releases/tag/v8.0.0 - // Gov is the proper authority for those types of messages - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - // register the proposal types - // Deprecated: Avoid adding new handlers, instead use the new proposal flow - // by granting the governance module the right to execute the message. - // See: https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/gov/spec/01_concepts.md#proposal-messages - // TODO: investigate how to migrate to new proposal flow - govRouter := govv1beta1.NewRouter() - govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). - AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)) - - // TODO: this should be a function parameter - govConfig := govtypes.DefaultConfig() - /* - Example of setting gov params: - govConfig.MaxMetadataLen = 10000 - */ - govKeeper := govkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[govtypes.StoreKey]), - app.AccountKeeper, - app.BankKeeper, - app.StakingKeeper, - app.DistrKeeper, - app.MsgServiceRouter(), - govConfig, - authtypes.NewModuleAddress(govtypes.ModuleName).String()) - - app.GovKeeper = *govKeeper.SetHooks( - govtypes.NewMultiGovHooks( - // register the governance hooks - ), - ) - - btclightclientKeeper := btclightclientkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[btclightclienttypes.StoreKey]), - btcConfig, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - btcCheckpointKeeper := btccheckpointkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[btccheckpointtypes.StoreKey]), - tkeys[btccheckpointtypes.TStoreKey], - &btclightclientKeeper, - &checkpointingKeeper, - &app.IncentiveKeeper, - &powLimit, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - // create querier for KVStore - storeQuerier, ok := app.CommitMultiStore().(storetypes.Queryable) - if !ok { - panic(errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries")) - } - - app.IBCFeeKeeper = ibcfeekeeper.NewKeeper( - appCodec, keys[ibcfeetypes.StoreKey], - app.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.PortKeeper, app.AccountKeeper, app.BankKeeper, - ) - - zcKeeper := zckeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[zctypes.StoreKey]), - app.IBCFeeKeeper, - app.IBCKeeper.ClientKeeper, - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.PortKeeper, - app.AccountKeeper, - app.BankKeeper, - &btclightclientKeeper, - &checkpointingKeeper, - &btcCheckpointKeeper, - epochingKeeper, - storeQuerier, - scopedZoneConciergeKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - app.ZoneConciergeKeeper = *zcKeeper - - // Create Transfer Keepers - app.TransferKeeper = ibctransferkeeper.NewKeeper( - appCodec, - keys[ibctransfertypes.StoreKey], - app.GetSubspace(ibctransfertypes.ModuleName), - app.IBCFeeKeeper, - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.PortKeeper, - app.AccountKeeper, - app.BankKeeper, - scopedTransferKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - app.MonitorKeeper = monitorkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[monitortypes.StoreKey]), - &btclightclientKeeper, - ) - - // add msgServiceRouter so that the epoching module can forward unwrapped messages to the staking module - epochingKeeper.SetMsgServiceRouter(app.BaseApp.MsgServiceRouter()) - // make ZoneConcierge and Monitor to subscribe to the epoching's hooks - app.EpochingKeeper = *epochingKeeper.SetHooks( - epochingtypes.NewMultiEpochingHooks(app.ZoneConciergeKeeper.Hooks(), app.MonitorKeeper.Hooks()), - ) - - // set up Checkpointing, BTCCheckpoint, and BTCLightclient keepers - app.CheckpointingKeeper = *checkpointingKeeper.SetHooks( - checkpointingtypes.NewMultiCheckpointingHooks(app.EpochingKeeper.Hooks(), app.ZoneConciergeKeeper.Hooks(), app.MonitorKeeper.Hooks()), - ) - app.BtcCheckpointKeeper = btcCheckpointKeeper - app.BTCLightClientKeeper = *btclightclientKeeper.SetHooks( - btclightclienttypes.NewMultiBTCLightClientHooks(app.BtcCheckpointKeeper.Hooks()), - ) - - // set up BTC staking keeper - app.BTCStakingKeeper = btcstakingkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]), - &btclightclientKeeper, - &btcCheckpointKeeper, - &checkpointingKeeper, - btcNetParams, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - // set up finality keeper - app.FinalityKeeper = finalitykeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[finalitytypes.StoreKey]), - app.BTCStakingKeeper, - app.IncentiveKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ) - - // create evidence keeper with router - evidenceKeeper := evidencekeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), - app.StakingKeeper, - app.SlashingKeeper, - app.AccountKeeper.AddressCodec(), - runtime.ProvideCometInfoService(), - ) - // If evidence needs to be handled for the app, set routes in router here and seal - app.EvidenceKeeper = *evidenceKeeper - - wasmConfig, err := wasm.ReadWasmConfig(appOpts) - if err != nil { - panic(fmt.Sprintf("error while reading wasm config: %s", err)) - } - - wasmOpts = append(owasm.RegisterCustomPlugins(&app.EpochingKeeper, &app.ZoneConciergeKeeper, &app.BTCLightClientKeeper), wasmOpts...) - - app.WasmKeeper = wasmkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[wasmtypes.StoreKey]), - app.AccountKeeper, - app.BankKeeper, - app.StakingKeeper, - distrkeeper.NewQuerier(app.DistrKeeper), - app.IBCFeeKeeper, - app.IBCKeeper.ChannelKeeper, - app.IBCKeeper.PortKeeper, - scopedWasmKeeper, - app.TransferKeeper, - app.MsgServiceRouter(), - app.GRPCQueryRouter(), - homePath, + privSigner, + appOpts, wasmConfig, - WasmCapabilities(), - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - wasmOpts..., - ) - - ibcWasmConfig := - ibcwasmtypes.WasmConfig{ - DataDir: filepath.Join(homePath, "ibc_08-wasm"), - SupportedCapabilities: WasmCapabilities(), - ContractDebugMode: false, - } - - app.IBCWasmKeeper = ibcwasmkeeper.NewKeeperWithConfig( - appCodec, - runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), - app.IBCKeeper.ClientKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), - ibcWasmConfig, - app.GRPCQueryRouter(), + wasmOpts, + BlockedAddresses(), ) - // Set legacy router for backwards compatibility with gov v1beta1 - app.GovKeeper.SetLegacyRouter(govRouter) - - // Create all supported IBC routes - var transferStack porttypes.IBCModule - transferStack = transfer.NewIBCModule(app.TransferKeeper) - transferStack = ibcfee.NewIBCMiddleware(transferStack, app.IBCFeeKeeper) - - var zoneConciergeStack porttypes.IBCModule - zoneConciergeStack = zoneconcierge.NewIBCModule(app.ZoneConciergeKeeper) - zoneConciergeStack = ibcfee.NewIBCMiddleware(zoneConciergeStack, app.IBCFeeKeeper) - - var wasmStack porttypes.IBCModule - wasmStack = wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCFeeKeeper) - wasmStack = ibcfee.NewIBCMiddleware(wasmStack, app.IBCFeeKeeper) - - // Create static IBC router, add ibc-transfer module route, then set and seal it - ibcRouter := porttypes.NewRouter(). - AddRoute(ibctransfertypes.ModuleName, transferStack). - AddRoute(zctypes.ModuleName, zoneConciergeStack). - AddRoute(wasmtypes.ModuleName, wasmStack) - - // Setting Router will finalize all routes by sealing router - // No more routes can be added - app.IBCKeeper.SetRouter(ibcRouter) - /**** Module Options ****/ // NOTE: we may consider parsing `appOpts` inside module constructors. For the moment @@ -959,8 +447,7 @@ func NewBabylonApp( app.ModuleManager.RegisterInvariants(app.CrisisKeeper) app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()) - err = app.ModuleManager.RegisterServices(app.configurator) - if err != nil { + if err := app.ModuleManager.RegisterServices(app.configurator); err != nil { panic(err) } @@ -987,9 +474,9 @@ func NewBabylonApp( app.sm.RegisterStoreDecoders() // initialize stores - app.MountKVStores(keys) - app.MountTransientStores(tkeys) - app.MountMemoryStores(memKeys) + app.MountKVStores(app.GetKVStoreKeys()) + app.MountTransientStores(app.GetTransientStoreKeys()) + app.MountMemoryStores(app.GetMemoryStoreKeys()) // initialize AnteHandler, which includes // - authAnteHandler @@ -1009,7 +496,7 @@ func NewBabylonApp( }, IBCKeeper: app.IBCKeeper, WasmConfig: &wasmConfig, - TXCounterStoreService: runtime.NewKVStoreService(keys[wasmtypes.StoreKey]), + TXCounterStoreService: runtime.NewKVStoreService(app.AppKeepers.GetKey(wasmtypes.StoreKey)), WasmKeeper: &app.WasmKeeper, CircuitKeeper: &app.CircuitKeeper, }, @@ -1025,8 +512,30 @@ func NewBabylonApp( NewBtcValidationDecorator(btcConfig, &app.BtcCheckpointKeeper), ) - // initialize BaseApp + // set proposal extension + proposalHandler := checkpointing.NewProposalHandler( + logger, &app.CheckpointingKeeper, bApp.Mempool(), bApp) + proposalHandler.SetHandlers(bApp) + + // set vote extension + voteExtHandler := checkpointing.NewVoteExtensionHandler(logger, &app.CheckpointingKeeper) + voteExtHandler.SetHandlers(bApp) + app.SetInitChainer(app.InitChainer) + app.SetPreBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + // execute the existing PreBlocker + res, err := app.PreBlocker(ctx, req) + if err != nil { + return res, err + } + // execute checkpointing module's PreBlocker + // NOTE: this does not change the consensus parameter in `res` + ckptPreBlocker := proposalHandler.PreBlocker() + if _, err := ckptPreBlocker(ctx, req); err != nil { + return res, err + } + return res, nil + }) app.SetBeginBlocker(app.BeginBlocker) app.SetEndBlocker(app.EndBlocker) app.SetAnteHandler(anteHandler) @@ -1056,11 +565,6 @@ func NewBabylonApp( } } - app.ScopedIBCKeeper = scopedIBCKeeper - app.ScopedZoneConciergeKeeper = scopedZoneConciergeKeeper - app.ScopedTransferKeeper = scopedTransferKeeper - app.ScopedWasmKeeper = scopedWasmKeeper - // At startup, after all modules have been registered, check that all proto // annotations are correct. protoFiles, err := proto.MergedRegistry() @@ -1074,6 +578,10 @@ func NewBabylonApp( _, _ = fmt.Fprintln(os.Stderr, err.Error()) } + // set upgrade handler and store loader for supporting software upgrade + app.setupUpgradeHandlers() + app.setupUpgradeStoreLoaders() + if loadLatest { if err := app.LoadLatestVersion(); err != nil { cmtos.Exit(err.Error()) @@ -1104,8 +612,19 @@ func (app *BabylonApp) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) return app.ModuleManager.PreBlock(ctx) } +// BeginBlockForks is intended to be ran in a chain upgrade. +func (app *BabylonApp) BeginBlockForks(ctx sdk.Context) { + for _, fork := range Forks { + if ctx.BlockHeight() == fork.UpgradeHeight { + fork.BeginForkLogic(ctx, app.AppKeepers) + return + } + } +} + // BeginBlocker application updates every begin block func (app *BabylonApp) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) { + app.BeginBlockForks(ctx) return app.ModuleManager.BeginBlock(ctx) } @@ -1182,35 +701,6 @@ func (app *BabylonApp) EncodingConfig() *appparams.EncodingConfig { } } -// GetKey returns the KVStoreKey for the provided store key. -// -// NOTE: This is solely to be used for testing purposes. -func (app *BabylonApp) GetKey(storeKey string) *storetypes.KVStoreKey { - return app.keys[storeKey] -} - -// GetTKey returns the TransientStoreKey for the provided store key. -// -// NOTE: This is solely to be used for testing purposes. -func (app *BabylonApp) GetTKey(storeKey string) *storetypes.TransientStoreKey { - return app.tkeys[storeKey] -} - -// GetMemKey returns the MemStoreKey for the provided mem key. -// -// NOTE: This is solely used for testing purposes. -func (app *BabylonApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { - return app.memKeys[storeKey] -} - -// GetSubspace returns a param subspace for a given module name. -// -// NOTE: This is solely to be used for testing purposes. -func (app *BabylonApp) GetSubspace(moduleName string) paramstypes.Subspace { - subspace, _ := app.ParamsKeeper.GetSubspace(moduleName) - return subspace -} - // SimulationManager implements the SimulationApp interface func (app *BabylonApp) SimulationManager() *module.SimulationManager { return app.sm @@ -1287,6 +777,39 @@ func (app *BabylonApp) AutoCliOpts() autocli.AppOptions { } } +// configure store loader that checks if version == upgradeHeight and applies store upgrades +func (app *BabylonApp) setupUpgradeStoreLoaders() { + upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if err != nil { + panic(fmt.Sprintf("failed to read upgrade info from disk %s", err)) + } + + if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + return + } + + for _, upgrade := range Upgrades { + if upgradeInfo.Name == upgrade.UpgradeName { + storeUpgrades := upgrade.StoreUpgrades + app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } + } +} + +func (app *BabylonApp) setupUpgradeHandlers() { + for _, upgrade := range Upgrades { + app.UpgradeKeeper.SetUpgradeHandler( + upgrade.UpgradeName, + upgrade.CreateUpgradeHandler( + app.ModuleManager, + app.configurator, + app.BaseApp, + app.AppKeepers, + ), + ) + } +} + // GetMaccPerms returns a copy of the module account permissions func GetMaccPerms() map[string][]string { dupMaccPerms := make(map[string][]string) @@ -1308,34 +831,3 @@ func BlockedAddresses() map[string]bool { return modAccAddrs } - -// initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { - paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - - // TODO: Only modules which did not migrate yet to new way of hanldling params - // are the IBC-related modules. Once they are migrated, we can remove this and - // whole usage of params module - paramsKeeper.Subspace(ibcexported.ModuleName) - paramsKeeper.Subspace(ibctransfertypes.ModuleName) - paramsKeeper.Subspace(zctypes.ModuleName) - - return paramsKeeper -} - -// Capabilities of the IBC wasm contracts -func WasmCapabilities() []string { - // The last arguments can contain custom message handlers, and custom query handlers, - // if we want to allow any custom callbacks - return []string{ - "iterator", - "staking", - "stargate", - "cosmwasm_1_1", - "cosmwasm_1_2", - "cosmwasm_1_3", - "cosmwasm_1_4", - "cosmwasm_2_0", - "babylon", - } -} diff --git a/app/export.go b/app/export.go index 105c96987..a83de8d0e 100644 --- a/app/export.go +++ b/app/export.go @@ -203,7 +203,7 @@ func (app *BabylonApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddr // Iterate through validators by power descending, reset bond heights, and // update bond intra-tx counters. - store := ctx.KVStore(app.keys[stakingtypes.StoreKey]) + store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey)) iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey) for ; iter.Valid(); iter.Next() { diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go new file mode 100644 index 000000000..15628ee78 --- /dev/null +++ b/app/keepers/keepers.go @@ -0,0 +1,630 @@ +package keepers + +import ( + "path/filepath" + + errorsmod "cosmossdk.io/errors" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + circuitkeeper "cosmossdk.io/x/circuit/keeper" + circuittypes "cosmossdk.io/x/circuit/types" + evidencekeeper "cosmossdk.io/x/evidence/keeper" + evidencetypes "cosmossdk.io/x/evidence/types" + "cosmossdk.io/x/feegrant" + feegrantkeeper "cosmossdk.io/x/feegrant/keeper" + upgradekeeper "cosmossdk.io/x/upgrade/keeper" + upgradetypes "cosmossdk.io/x/upgrade/types" + "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/runtime" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" + consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" + crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" + crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" + 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" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1" + mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" + "github.com/cosmos/cosmos-sdk/x/params" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal" + slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper" + slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" + capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" + ibcwasmkeeper "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/keeper" + ibcwasmtypes "github.com/cosmos/ibc-go/modules/light-clients/08-wasm/types" + ibcfee "github.com/cosmos/ibc-go/v8/modules/apps/29-fee" + ibcfeekeeper "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/keeper" + ibcfeetypes "github.com/cosmos/ibc-go/v8/modules/apps/29-fee/types" + "github.com/cosmos/ibc-go/v8/modules/apps/transfer" + ibctransferkeeper "github.com/cosmos/ibc-go/v8/modules/apps/transfer/keeper" + ibctransfertypes "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" // ibc module puts types under `ibchost` rather than `ibctypes` + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" + + appparams "github.com/babylonchain/babylon/app/params" + bbn "github.com/babylonchain/babylon/types" + owasm "github.com/babylonchain/babylon/wasmbinding" + btccheckpointkeeper "github.com/babylonchain/babylon/x/btccheckpoint/keeper" + btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + btclightclientkeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" + btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" + btcstakingkeeper "github.com/babylonchain/babylon/x/btcstaking/keeper" + btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" + checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + epochingkeeper "github.com/babylonchain/babylon/x/epoching/keeper" + epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + finalitykeeper "github.com/babylonchain/babylon/x/finality/keeper" + finalitytypes "github.com/babylonchain/babylon/x/finality/types" + incentivekeeper "github.com/babylonchain/babylon/x/incentive/keeper" + incentivetypes "github.com/babylonchain/babylon/x/incentive/types" + monitorkeeper "github.com/babylonchain/babylon/x/monitor/keeper" + monitortypes "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonchain/babylon/x/zoneconcierge" + zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" + zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" +) + +// Capabilities of the IBC wasm contracts +func WasmCapabilities() []string { + // The last arguments can contain custom message handlers, and custom query handlers, + // if we want to allow any custom callbacks + return []string{ + "iterator", + "staking", + "stargate", + "cosmwasm_1_1", + "cosmwasm_1_2", + "cosmwasm_1_3", + "cosmwasm_1_4", + "cosmwasm_2_0", + "babylon", + } +} + +type AppKeepers struct { + // keepers + AccountKeeper authkeeper.AccountKeeper + BankKeeper bankkeeper.Keeper + CapabilityKeeper *capabilitykeeper.Keeper + StakingKeeper *stakingkeeper.Keeper + SlashingKeeper slashingkeeper.Keeper + MintKeeper mintkeeper.Keeper + DistrKeeper distrkeeper.Keeper + GovKeeper govkeeper.Keeper + CrisisKeeper *crisiskeeper.Keeper + UpgradeKeeper *upgradekeeper.Keeper + ParamsKeeper paramskeeper.Keeper + AuthzKeeper authzkeeper.Keeper + EvidenceKeeper evidencekeeper.Keeper + FeeGrantKeeper feegrantkeeper.Keeper + ConsensusParamsKeeper consensusparamkeeper.Keeper + CircuitKeeper circuitkeeper.Keeper + + // Babylon modules + EpochingKeeper epochingkeeper.Keeper + BTCLightClientKeeper btclightclientkeeper.Keeper + BtcCheckpointKeeper btccheckpointkeeper.Keeper + CheckpointingKeeper checkpointingkeeper.Keeper + MonitorKeeper monitorkeeper.Keeper + + // IBC-related modules + IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly + IBCFeeKeeper ibcfeekeeper.Keeper // for relayer incentivization - https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment + TransferKeeper ibctransferkeeper.Keeper // for cross-chain fungible token transfers + IBCWasmKeeper ibcwasmkeeper.Keeper // for IBC wasm light clients + ZoneConciergeKeeper zckeeper.Keeper // for cross-chain fungible token transfers + + // BTC staking related modules + BTCStakingKeeper btcstakingkeeper.Keeper + FinalityKeeper finalitykeeper.Keeper + + // wasm smart contract module + WasmKeeper wasmkeeper.Keeper + + // tokenomics-related modules + IncentiveKeeper incentivekeeper.Keeper + + // make scoped keepers public for test purposes + ScopedIBCKeeper capabilitykeeper.ScopedKeeper + ScopedTransferKeeper capabilitykeeper.ScopedKeeper + ScopedZoneConciergeKeeper capabilitykeeper.ScopedKeeper + ScopedWasmKeeper capabilitykeeper.ScopedKeeper + + // keys to access the substores + keys map[string]*storetypes.KVStoreKey + tkeys map[string]*storetypes.TransientStoreKey + memKeys map[string]*storetypes.MemoryStoreKey +} + +func (ak *AppKeepers) InitKeepers( + logger log.Logger, + appCodec codec.Codec, + btcConfig *bbn.BtcConfig, + encodingConfig *appparams.EncodingConfig, + bApp *baseapp.BaseApp, + maccPerms map[string][]string, + homePath string, + invCheckPeriod uint, + skipUpgradeHeights map[int64]bool, + privSigner *PrivSigner, + appOpts servertypes.AppOptions, + wasmConfig wasmtypes.WasmConfig, + wasmOpts []wasmkeeper.Option, + blockedAddress map[string]bool, +) { + powLimit := btcConfig.PowLimit() + btcNetParams := btcConfig.NetParams() + + // set persistent store keys + keys := storetypes.NewKVStoreKeys( + authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey, crisistypes.StoreKey, + minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey, + govtypes.StoreKey, paramstypes.StoreKey, consensusparamtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, + evidencetypes.StoreKey, circuittypes.StoreKey, capabilitytypes.StoreKey, + authzkeeper.StoreKey, + // Babylon modules + epochingtypes.StoreKey, + btclightclienttypes.StoreKey, + btccheckpointtypes.StoreKey, + checkpointingtypes.StoreKey, + monitortypes.StoreKey, + // IBC-related modules + ibcexported.StoreKey, + ibctransfertypes.StoreKey, + ibcfeetypes.StoreKey, + ibcwasmtypes.StoreKey, + zctypes.StoreKey, + // BTC staking related modules + btcstakingtypes.StoreKey, + finalitytypes.StoreKey, + // WASM + wasmtypes.StoreKey, + // tokenomics-related modules + incentivetypes.StoreKey, + ) + ak.keys = keys + + // set transient store keys + ak.tkeys = storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, btccheckpointtypes.TStoreKey) + + // set memory store keys + // NOTE: The testingkey is just mounted for testing purposes. Actual applications should + // not include this key. + ak.memKeys = storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey") + + accountKeeper := authkeeper.NewAccountKeeper( + appCodec, + runtime.NewKVStoreService(keys[authtypes.StoreKey]), + authtypes.ProtoBaseAccount, + maccPerms, + authcodec.NewBech32Codec(appparams.Bech32PrefixAccAddr), + appparams.Bech32PrefixAccAddr, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + bankKeeper := bankkeeper.NewBaseKeeper( + appCodec, + runtime.NewKVStoreService(keys[banktypes.StoreKey]), + accountKeeper, + blockedAddress, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + logger, + ) + + stakingKeeper := stakingkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), + accountKeeper, + bankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authcodec.NewBech32Codec(appparams.Bech32PrefixValAddr), + authcodec.NewBech32Codec(appparams.Bech32PrefixConsAddr), + ) + + // NOTE: the epoching module has to be set before the chekpointing module, as the checkpointing module will have access to the epoching module + epochingKeeper := epochingkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[epochingtypes.StoreKey]), + bankKeeper, + stakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + checkpointingKeeper := checkpointingkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[checkpointingtypes.StoreKey]), + privSigner.WrappedPV, + epochingKeeper, + ) + + // register streaming services + if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil { + panic(err) + } + + ak.ParamsKeeper = initParamsKeeper( + appCodec, + encodingConfig.Amino, + keys[paramstypes.StoreKey], + ak.tkeys[paramstypes.TStoreKey], + ) + + ak.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + runtime.EventService{}, + ) + bApp.SetParamStore(ak.ConsensusParamsKeeper.ParamsStore) + + ak.CapabilityKeeper = capabilitykeeper.NewKeeper( + appCodec, + keys[capabilitytypes.StoreKey], + ak.memKeys[capabilitytypes.MemStoreKey], + ) + + // grant capabilities for the ibc and ibc-transfer modules + scopedIBCKeeper := ak.CapabilityKeeper.ScopeToModule(ibcexported.ModuleName) + scopedTransferKeeper := ak.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + scopedZoneConciergeKeeper := ak.CapabilityKeeper.ScopeToModule(zctypes.ModuleName) + scopedWasmKeeper := ak.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName) + + // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating + // their scoped modules in `NewApp` with `ScopeToModule` + ak.CapabilityKeeper.Seal() + + // add keepers + ak.AccountKeeper = accountKeeper + + ak.BankKeeper = bankKeeper + + ak.StakingKeeper = stakingKeeper + + ak.CircuitKeeper = circuitkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[circuittypes.StoreKey]), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ak.AccountKeeper.AddressCodec(), + ) + bApp.SetCircuitBreaker(&ak.CircuitKeeper) + + ak.MintKeeper = mintkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[minttypes.StoreKey]), + ak.StakingKeeper, + ak.AccountKeeper, + ak.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + ak.DistrKeeper = distrkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[distrtypes.StoreKey]), + ak.AccountKeeper, + ak.BankKeeper, + ak.StakingKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // set up incentive keeper + ak.IncentiveKeeper = incentivekeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[incentivetypes.StoreKey]), + ak.BankKeeper, + ak.AccountKeeper, + &epochingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + authtypes.FeeCollectorName, + ) + + ak.SlashingKeeper = slashingkeeper.NewKeeper( + appCodec, + encodingConfig.Amino, + runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), + ak.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + ak.CrisisKeeper = crisiskeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[crisistypes.StoreKey]), + invCheckPeriod, + ak.BankKeeper, + authtypes.FeeCollectorName, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ak.AccountKeeper.AddressCodec(), + ) + + ak.FeeGrantKeeper = feegrantkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[feegrant.StoreKey]), + ak.AccountKeeper, + ) + // register the staking hooks + // NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks + ak.StakingKeeper.SetHooks( + stakingtypes.NewMultiStakingHooks(ak.DistrKeeper.Hooks(), ak.SlashingKeeper.Hooks(), epochingKeeper.Hooks()), + ) + + // set the governance module account as the authority for conducting upgrades + ak.UpgradeKeeper = upgradekeeper.NewKeeper( + skipUpgradeHeights, + runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), + appCodec, + homePath, + bApp, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + ak.AuthzKeeper = authzkeeper.NewKeeper( + runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), + appCodec, + bApp.MsgServiceRouter(), + ak.AccountKeeper, + ) + + ak.IBCKeeper = ibckeeper.NewKeeper( + appCodec, + keys[ibcexported.StoreKey], + ak.GetSubspace(ibcexported.ModuleName), + ak.StakingKeeper, + ak.UpgradeKeeper, + scopedIBCKeeper, + // From 8.0.0 the IBC keeper requires an authority for the messages + // `MsgIBCSoftwareUpgrade` and `MsgRecoverClient` + // https://github.com/cosmos/ibc-go/releases/tag/v8.0.0 + // Gov is the proper authority for those types of messages + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // register the proposal types + // Deprecated: Avoid adding new handlers, instead use the new proposal flow + // by granting the governance module the right to execute the message. + // See: https://github.com/cosmos/cosmos-sdk/blob/release/v0.46.x/x/gov/spec/01_concepts.md#proposal-messages + // TODO: investigate how to migrate to new proposal flow + govRouter := govv1beta1.NewRouter() + govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler). + AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(ak.ParamsKeeper)) + + // TODO: this should be a function parameter + govConfig := govtypes.DefaultConfig() + /* + Example of setting gov params: + govConfig.MaxMetadataLen = 10000 + */ + govKeeper := govkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[govtypes.StoreKey]), + ak.AccountKeeper, + ak.BankKeeper, + ak.StakingKeeper, + ak.DistrKeeper, + bApp.MsgServiceRouter(), + govConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String()) + + ak.GovKeeper = *govKeeper.SetHooks( + govtypes.NewMultiGovHooks( + // register the governance hooks + ), + ) + + btclightclientKeeper := btclightclientkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[btclightclienttypes.StoreKey]), + *btcConfig, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + btcCheckpointKeeper := btccheckpointkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[btccheckpointtypes.StoreKey]), + ak.tkeys[btccheckpointtypes.TStoreKey], + &btclightclientKeeper, + &checkpointingKeeper, + &ak.IncentiveKeeper, + &powLimit, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // create querier for KVStore + storeQuerier, ok := bApp.CommitMultiStore().(storetypes.Queryable) + if !ok { + panic(errorsmod.Wrap(sdkerrors.ErrUnknownRequest, "multistore doesn't support queries")) + } + + ak.IBCFeeKeeper = ibcfeekeeper.NewKeeper( + appCodec, keys[ibcfeetypes.StoreKey], + ak.IBCKeeper.ChannelKeeper, // may be replaced with IBC middleware + ak.IBCKeeper.ChannelKeeper, + ak.IBCKeeper.PortKeeper, ak.AccountKeeper, ak.BankKeeper, + ) + + zcKeeper := zckeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[zctypes.StoreKey]), + ak.IBCFeeKeeper, + ak.IBCKeeper.ClientKeeper, + ak.IBCKeeper.ChannelKeeper, + ak.IBCKeeper.PortKeeper, + ak.AccountKeeper, + ak.BankKeeper, + &btclightclientKeeper, + &checkpointingKeeper, + &btcCheckpointKeeper, + epochingKeeper, + storeQuerier, + scopedZoneConciergeKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + ak.ZoneConciergeKeeper = *zcKeeper + + // Create Transfer Keepers + ak.TransferKeeper = ibctransferkeeper.NewKeeper( + appCodec, + keys[ibctransfertypes.StoreKey], + ak.GetSubspace(ibctransfertypes.ModuleName), + ak.IBCFeeKeeper, + ak.IBCKeeper.ChannelKeeper, + ak.IBCKeeper.PortKeeper, + ak.AccountKeeper, + ak.BankKeeper, + scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + ak.MonitorKeeper = monitorkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[monitortypes.StoreKey]), + &btclightclientKeeper, + ) + + // add msgServiceRouter so that the epoching module can forward unwrapped messages to the staking module + epochingKeeper.SetMsgServiceRouter(bApp.MsgServiceRouter()) + // make ZoneConcierge and Monitor to subscribe to the epoching's hooks + ak.EpochingKeeper = *epochingKeeper.SetHooks( + epochingtypes.NewMultiEpochingHooks(ak.ZoneConciergeKeeper.Hooks(), ak.MonitorKeeper.Hooks()), + ) + + // set up Checkpointing, BTCCheckpoint, and BTCLightclient keepers + ak.CheckpointingKeeper = *checkpointingKeeper.SetHooks( + checkpointingtypes.NewMultiCheckpointingHooks(ak.EpochingKeeper.Hooks(), ak.ZoneConciergeKeeper.Hooks(), ak.MonitorKeeper.Hooks()), + ) + ak.BtcCheckpointKeeper = btcCheckpointKeeper + ak.BTCLightClientKeeper = *btclightclientKeeper.SetHooks( + btclightclienttypes.NewMultiBTCLightClientHooks(ak.BtcCheckpointKeeper.Hooks()), + ) + + // set up BTC staking keeper + ak.BTCStakingKeeper = btcstakingkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]), + &btclightclientKeeper, + &btcCheckpointKeeper, + &checkpointingKeeper, + btcNetParams, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + // set up finality keeper + ak.FinalityKeeper = finalitykeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[finalitytypes.StoreKey]), + ak.BTCStakingKeeper, + ak.IncentiveKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ) + + // create evidence keeper with router + evidenceKeeper := evidencekeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[evidencetypes.StoreKey]), + ak.StakingKeeper, + ak.SlashingKeeper, + ak.AccountKeeper.AddressCodec(), + runtime.ProvideCometInfoService(), + ) + // If evidence needs to be handled for the app, set routes in router here and seal + ak.EvidenceKeeper = *evidenceKeeper + + wasmOpts = append(owasm.RegisterCustomPlugins(&ak.EpochingKeeper, &ak.ZoneConciergeKeeper, &ak.BTCLightClientKeeper), wasmOpts...) + + ak.WasmKeeper = wasmkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[wasmtypes.StoreKey]), + ak.AccountKeeper, + ak.BankKeeper, + ak.StakingKeeper, + distrkeeper.NewQuerier(ak.DistrKeeper), + ak.IBCFeeKeeper, + ak.IBCKeeper.ChannelKeeper, + ak.IBCKeeper.PortKeeper, + scopedWasmKeeper, + ak.TransferKeeper, + bApp.MsgServiceRouter(), + bApp.GRPCQueryRouter(), + homePath, + wasmConfig, + WasmCapabilities(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + wasmOpts..., + ) + + ibcWasmConfig := + ibcwasmtypes.WasmConfig{ + DataDir: filepath.Join(homePath, "ibc_08-wasm"), + SupportedCapabilities: WasmCapabilities(), + ContractDebugMode: false, + } + + ak.IBCWasmKeeper = ibcwasmkeeper.NewKeeperWithConfig( + appCodec, + runtime.NewKVStoreService(keys[ibcwasmtypes.StoreKey]), + ak.IBCKeeper.ClientKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + ibcWasmConfig, + bApp.GRPCQueryRouter(), + ) + + // Set legacy router for backwards compatibility with gov v1beta1 + ak.GovKeeper.SetLegacyRouter(govRouter) + + // Create all supported IBC routes + var transferStack porttypes.IBCModule + transferStack = transfer.NewIBCModule(ak.TransferKeeper) + transferStack = ibcfee.NewIBCMiddleware(transferStack, ak.IBCFeeKeeper) + + var zoneConciergeStack porttypes.IBCModule + zoneConciergeStack = zoneconcierge.NewIBCModule(ak.ZoneConciergeKeeper) + zoneConciergeStack = ibcfee.NewIBCMiddleware(zoneConciergeStack, ak.IBCFeeKeeper) + + var wasmStack porttypes.IBCModule + wasmStack = wasm.NewIBCHandler(ak.WasmKeeper, ak.IBCKeeper.ChannelKeeper, ak.IBCFeeKeeper) + wasmStack = ibcfee.NewIBCMiddleware(wasmStack, ak.IBCFeeKeeper) + + // Create static IBC router, add ibc-transfer module route, then set and seal it + ibcRouter := porttypes.NewRouter(). + AddRoute(ibctransfertypes.ModuleName, transferStack). + AddRoute(zctypes.ModuleName, zoneConciergeStack). + AddRoute(wasmtypes.ModuleName, wasmStack) + + // Setting Router will finalize all routes by sealing router + // No more routes can be added + ak.IBCKeeper.SetRouter(ibcRouter) +} + +// initParamsKeeper init params keeper and its subspaces +func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { + paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) + + // TODO: Only modules which did not migrate yet to new way of hanldling params + // are the IBC-related modules. Once they are migrated, we can remove this and + // whole usage of params module + paramsKeeper.Subspace(ibcexported.ModuleName) + paramsKeeper.Subspace(ibctransfertypes.ModuleName) + paramsKeeper.Subspace(zctypes.ModuleName) + + return paramsKeeper +} diff --git a/app/keepers/keys.go b/app/keepers/keys.go new file mode 100644 index 000000000..c01bf564c --- /dev/null +++ b/app/keepers/keys.go @@ -0,0 +1,48 @@ +package keepers + +import ( + storetypes "cosmossdk.io/store/types" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +// GetSubspace gets existing substore from keeper. +func (appKeepers *AppKeepers) GetSubspace(moduleName string) paramstypes.Subspace { + subspace, _ := appKeepers.ParamsKeeper.GetSubspace(moduleName) + return subspace +} + +// GetKVStoreKey gets KV Store keys. +func (appKeepers *AppKeepers) GetKVStoreKeys() map[string]*storetypes.KVStoreKey { + return appKeepers.keys +} + +// GetTransientStoreKey gets Transient Store keys. +func (appKeepers *AppKeepers) GetTransientStoreKeys() map[string]*storetypes.TransientStoreKey { + return appKeepers.tkeys +} + +// GetMemoryStoreKey get memory Store keys. +func (appKeepers *AppKeepers) GetMemoryStoreKeys() map[string]*storetypes.MemoryStoreKey { + return appKeepers.memKeys +} + +// GetKey returns the KVStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (appKeepers *AppKeepers) GetKey(storeKey string) *storetypes.KVStoreKey { + return appKeepers.keys[storeKey] +} + +// GetTKey returns the TransientStoreKey for the provided store key. +// +// NOTE: This is solely to be used for testing purposes. +func (appKeepers *AppKeepers) GetTKey(storeKey string) *storetypes.TransientStoreKey { + return appKeepers.tkeys[storeKey] +} + +// GetMemKey returns the MemStoreKey for the provided mem key. +// +// NOTE: This is solely used for testing purposes. +func (appKeepers *AppKeepers) GetMemKey(storeKey string) *storetypes.MemoryStoreKey { + return appKeepers.memKeys[storeKey] +} diff --git a/app/utils.go b/app/keepers/utils.go similarity index 99% rename from app/utils.go rename to app/keepers/utils.go index 2f2ccbf9c..121f3531f 100644 --- a/app/utils.go +++ b/app/keepers/utils.go @@ -1,4 +1,4 @@ -package app +package keepers import ( "bytes" diff --git a/app/test_helpers.go b/app/test_helpers.go index d2bdc4a58..d8dfea5ef 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -30,6 +30,7 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/stretchr/testify/require" + appkeepers "github.com/babylonchain/babylon/app/keepers" appparams "github.com/babylonchain/babylon/app/params" "github.com/babylonchain/babylon/crypto/bls12381" "github.com/babylonchain/babylon/privval" @@ -46,7 +47,7 @@ type SetupOptions struct { AppOpts types.AppOptions } -func setup(t *testing.T, ps *PrivSigner, withGenesis bool, invCheckPeriod uint) (*BabylonApp, GenesisState) { +func setup(t *testing.T, ps *appkeepers.PrivSigner, withGenesis bool, invCheckPeriod uint) (*BabylonApp, GenesisState) { db := dbm.NewMemDB() nodeHome := t.TempDir() @@ -80,7 +81,7 @@ func setup(t *testing.T, ps *PrivSigner, withGenesis bool, invCheckPeriod uint) // Created Babylon application will have one validator with hardcoed amount of tokens. // This is necessary as from cosmos-sdk 0.46 it is required that there is at least // one validator in validator set during InitGenesis abci call - https://github.com/cosmos/cosmos-sdk/pull/9697 -func NewBabylonAppWithCustomOptions(t *testing.T, isCheckTx bool, privSigner *PrivSigner, options SetupOptions) *BabylonApp { +func NewBabylonAppWithCustomOptions(t *testing.T, isCheckTx bool, privSigner *appkeepers.PrivSigner, options SetupOptions) *BabylonApp { t.Helper() // create validator set with single validator valKeys, err := privval.NewValidatorKeys(ed25519.GenPrivKey(), bls12381.GenPrivKey()) @@ -245,7 +246,7 @@ func Setup(t *testing.T, isCheckTx bool) *BabylonApp { } // SetupTestPrivSigner sets up a PrivSigner for testing -func SetupTestPrivSigner() (*PrivSigner, error) { +func SetupTestPrivSigner() (*appkeepers.PrivSigner, error) { // Create a temporary node directory nodeDir, err := ioutils.TempDir("", "tmp-signer") if err != nil { @@ -254,7 +255,7 @@ func SetupTestPrivSigner() (*PrivSigner, error) { defer func() { _ = os.RemoveAll(nodeDir) }() - privSigner, _ := InitPrivSigner(nodeDir) + privSigner, _ := appkeepers.InitPrivSigner(nodeDir) return privSigner, nil } @@ -263,7 +264,7 @@ func SetupTestPrivSigner() (*PrivSigner, error) { // of one consensus engine unit (10^6) in the default token of the babylon app from first genesis // account. A Nop logger is set in BabylonApp. // Note that the privSigner should be the 0th item of valSet -func SetupWithGenesisValSet(t *testing.T, valSet []*checkpointingtypes.GenesisKey, privSigner *PrivSigner, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *BabylonApp { +func SetupWithGenesisValSet(t *testing.T, valSet []*checkpointingtypes.GenesisKey, privSigner *appkeepers.PrivSigner, genAccs []authtypes.GenesisAccount, balances ...banktypes.Balance) *BabylonApp { t.Helper() app, genesisState := setup(t, privSigner, true, 5) genesisState = genesisStateWithValSet(t, app, genesisState, valSet, genAccs, balances...) @@ -296,7 +297,7 @@ func SetupWithGenesisValSet(t *testing.T, valSet []*checkpointingtypes.GenesisKe return app } -func GenesisKeyFromPrivSigner(ps *PrivSigner) (*checkpointingtypes.GenesisKey, error) { +func GenesisKeyFromPrivSigner(ps *appkeepers.PrivSigner) (*checkpointingtypes.GenesisKey, error) { valKeys, err := privval.NewValidatorKeys(ps.WrappedPV.GetValPrivKey(), ps.WrappedPV.GetBlsPrivKey()) if err != nil { return nil, err diff --git a/app/upgrades/README.md b/app/upgrades/README.md new file mode 100644 index 000000000..e7e799a56 --- /dev/null +++ b/app/upgrades/README.md @@ -0,0 +1,43 @@ +# Babylon Upgrades + +This folder contains sub-folders for every babylon upgrade. (Both state +migrations, and hard forks) It also defines upgrade & hard fork structs, +that each upgrade implements. These then get included in the application +app.go to run the upgrade. + +The code is adapted from [Osmosis](https://github.com/osmosis-labs/osmosis/blob/68d546d94acbf1aa99d6b514cb66b2b40afff4a4/app/upgrades). + +## Version History + +TODO + +## Upgrade types + +There are two upgrade types exposed, `Upgrade` and `Fork`. An `Upgrade` +defines an upgrade that is to be acted upon by state migrations from the +SDK `x/upgrade` module. A `Fork` defines a hard fork that changes some +logic at a block height. If the goal is to have a new binary be +compatible with the old binary prior to the upgrade height, as is the +case for all babylon `Fork`s, then all logic changes must be +height-gated or in the `BeginForkLogic` code. + +```go +type Upgrade struct { + // Upgrade version name, for the upgrade handler, e.g. `v7` + UpgradeName string + // Function that creates an upgrade handler + CreateUpgradeHandler func(mm *module.Manager, configurator module.Configurator, keepers *keepers.AppKeepers) upgradetypes.UpgradeHandler + // Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed. + StoreUpgrades store.StoreUpgrades +} + +type Fork struct { + // Upgrade version name, for the upgrade handler, e.g. `v7` + UpgradeName string + // height the upgrade occurs at + UpgradeHeight int64 + + // Function that runs some custom state transition code at the beginning of a fork. + BeginForkLogic func(ctx sdk.Context, keepers *keepers.AppKeepers) +} +``` diff --git a/app/upgrades/types.go b/app/upgrades/types.go new file mode 100644 index 000000000..8f143c8e1 --- /dev/null +++ b/app/upgrades/types.go @@ -0,0 +1,48 @@ +package upgrades + +import ( + store "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + + "github.com/babylonchain/babylon/app/keepers" +) + +// BaseAppParamManager defines an interrace that BaseApp is expected to fulfill +// that allows upgrade handlers to modify BaseApp parameters. +type BaseAppParamManager interface { + GetConsensusParams(ctx sdk.Context) tmproto.ConsensusParams + StoreConsensusParams(ctx sdk.Context, cp tmproto.ConsensusParams) error +} + +// Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal +// must have written, in order for the state migration to go smoothly. +// An upgrade must implement this struct, and then set it in the app.go. +// The app.go will then define the handler. +type Upgrade struct { + // Upgrade version name, for the upgrade handler, e.g. `v7` + UpgradeName string + + // CreateUpgradeHandler defines the function that creates an upgrade handler + CreateUpgradeHandler func(*module.Manager, module.Configurator, BaseAppParamManager, *keepers.AppKeepers) upgradetypes.UpgradeHandler + + // Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed. + StoreUpgrades store.StoreUpgrades +} + +// Fork defines a struct containing the requisite fields for a non-software upgrade proposal +// Hard Fork at a given height to implement. +// There is one time code that can be added for the start of the Fork, in `BeginForkLogic`. +// Any other change in the code should be height-gated, if the goal is to have old and new binaries +// to be compatible prior to the upgrade height. +type Fork struct { + // Upgrade version name, for the upgrade handler, e.g. `v7` + UpgradeName string + // height the upgrade occurs at + UpgradeHeight int64 + + // Function that runs some custom state transition code at the beginning of a fork. + BeginForkLogic func(ctx sdk.Context, keepers *keepers.AppKeepers) +} diff --git a/app/upgrades/vanilla/README.md b/app/upgrades/vanilla/README.md new file mode 100644 index 000000000..3909ea3f3 --- /dev/null +++ b/app/upgrades/vanilla/README.md @@ -0,0 +1,4 @@ +# vanilla + +This folder contains a vanilla software upgrade for testing purposes. +DO NOT USE IN PRODUCTION! diff --git a/app/upgrades/vanilla/upgrades.go b/app/upgrades/vanilla/upgrades.go new file mode 100644 index 000000000..1cc0c9060 --- /dev/null +++ b/app/upgrades/vanilla/upgrades.go @@ -0,0 +1,64 @@ +// This code is only for testing purposes. +// DO NOT USE IN PRODUCTION! + +package vanilla + +import ( + "context" + + store "cosmossdk.io/store/types" + upgradetypes "cosmossdk.io/x/upgrade/types" + "github.com/babylonchain/babylon/app/keepers" + "github.com/babylonchain/babylon/app/upgrades" + bbn "github.com/babylonchain/babylon/types" + btcstakingkeeper "github.com/babylonchain/babylon/x/btcstaking/keeper" + bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/btcsuite/btcd/btcec/v2" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" +) + +var Upgrade = upgrades.Upgrade{ + UpgradeName: "vanilla", + CreateUpgradeHandler: CreateUpgradeHandler, + StoreUpgrades: store.StoreUpgrades{}, +} + +func CreateUpgradeHandler( + mm *module.Manager, + cfg module.Configurator, + _ upgrades.BaseAppParamManager, + keepers *keepers.AppKeepers, +) upgradetypes.UpgradeHandler { + return func(context context.Context, _plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + + ctx := sdk.UnwrapSDKContext(context) + + propVanilla(ctx, &keepers.AccountKeeper, &keepers.BTCStakingKeeper) + + return mm.RunMigrations(ctx, cfg, fromVM) + } +} + +func propVanilla( + ctx sdk.Context, + accountKeeper *authkeeper.AccountKeeper, + bsKeeper *btcstakingkeeper.Keeper, +) { + // remove an account + allAccounts := accountKeeper.GetAllAccounts(ctx) + accountKeeper.RemoveAccount(ctx, allAccounts[len(allAccounts)-1]) + + // insert a FP + sk, err := btcec.NewPrivateKey() + if err != nil { + panic(err) + } + btcPK := bbn.NewBIP340PubKeyFromBTCPK(sk.PubKey()) + fp := &bstypes.FinalityProvider{ + Addr: allAccounts[0].GetAddress().String(), + BtcPk: btcPK, + } + bsKeeper.SetFinalityProvider(ctx, fp) +} diff --git a/app/upgrades/vanilla/upgrades_test.go b/app/upgrades/vanilla/upgrades_test.go new file mode 100644 index 000000000..fba069c7f --- /dev/null +++ b/app/upgrades/vanilla/upgrades_test.go @@ -0,0 +1,105 @@ +package vanilla_test + +import ( + "fmt" + "testing" + "time" + + "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/header" + "cosmossdk.io/x/upgrade" + upgradetypes "cosmossdk.io/x/upgrade/types" + "github.com/babylonchain/babylon/app" + v1 "github.com/babylonchain/babylon/app/upgrades/vanilla" + bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/suite" +) + +const ( + DummyUpgradeHeight = 5 +) + +type UpgradeTestSuite struct { + suite.Suite + + ctx sdk.Context + app *app.BabylonApp + preModule appmodule.HasPreBlocker +} + +func (s *UpgradeTestSuite) SetupTest() { + // add the upgrade plan + app.Upgrades = append(app.Upgrades, v1.Upgrade) + + // set up app + s.app = app.Setup(s.T(), false) + s.ctx = s.app.BaseApp.NewContextLegacy(false, tmproto.Header{Height: 1, ChainID: "babylon-1", Time: time.Now().UTC()}) + s.preModule = upgrade.NewAppModule(s.app.UpgradeKeeper, s.app.AccountKeeper.AddressCodec()) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(UpgradeTestSuite)) +} + +func (s *UpgradeTestSuite) TestUpgradePayments() { + oldAcctNum := 0 + + testCases := []struct { + msg string + pre_update func() + update func() + post_update func() + expPass bool + }{ + { + "Test vanilla software upgrade gov prop", + func() { + allAccounts := s.app.AccountKeeper.GetAllAccounts(s.ctx) + oldAcctNum = len(allAccounts) + }, + func() { + // inject upgrade plan + s.ctx = s.ctx.WithBlockHeight(DummyUpgradeHeight - 1) + plan := upgradetypes.Plan{Name: v1.Upgrade.UpgradeName, Height: DummyUpgradeHeight} + err := s.app.UpgradeKeeper.ScheduleUpgrade(s.ctx, plan) + s.NoError(err) + + // ensure upgrade plan exists + actualPlan, err := s.app.UpgradeKeeper.GetUpgradePlan(s.ctx) + s.NoError(err) + s.Equal(plan, actualPlan) + + // execute upgrade + s.ctx = s.ctx.WithHeaderInfo(header.Info{Height: DummyUpgradeHeight, Time: s.ctx.BlockTime().Add(time.Second)}).WithBlockHeight(DummyUpgradeHeight) + s.NotPanics(func() { + _, err := s.preModule.PreBlock(s.ctx) + s.NoError(err) + }) + }, + func() { + // ensure the account is removed + allAccounts := s.app.AccountKeeper.GetAllAccounts(s.ctx) + newAcctNum := len(allAccounts) + s.Equal(newAcctNum, oldAcctNum-1) + + // ensure finality provider is inserted + resp, err := s.app.BTCStakingKeeper.FinalityProviders(s.ctx, &bstypes.QueryFinalityProvidersRequest{}) + s.NoError(err) + s.Len(resp.FinalityProviders, 1) + }, + true, + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("Case %s", tc.msg), func() { + s.SetupTest() // reset + + tc.pre_update() + tc.update() + tc.post_update() + }) + } +} diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index f87c0afb5..bab90741e 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -8,6 +8,7 @@ import ( confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + appkeepers "github.com/babylonchain/babylon/app/keepers" cmtcfg "github.com/cometbft/cometbft/config" cmtcli "github.com/cometbft/cometbft/libs/cli" dbm "github.com/cosmos/cosmos-db" @@ -274,7 +275,7 @@ func newApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts serverty } homeDir := cast.ToString(appOpts.Get(flags.FlagHome)) - privSigner, err := app.InitPrivSigner(homeDir) + privSigner, err := appkeepers.InitPrivSigner(homeDir) if err != nil { panic(err) } @@ -313,7 +314,7 @@ func appExport( return servertypes.ExportedApp{}, errors.New("application home not set") } - privSigner, err := app.InitPrivSigner(homePath) + privSigner, err := appkeepers.InitPrivSigner(homePath) if err != nil { panic(err) } diff --git a/cmd/babylond/cmd/testnet.go b/cmd/babylond/cmd/testnet.go index 13886c348..8ac343ea6 100644 --- a/cmd/babylond/cmd/testnet.go +++ b/cmd/babylond/cmd/testnet.go @@ -11,6 +11,7 @@ import ( "time" "cosmossdk.io/math" + appkeepers "github.com/babylonchain/babylon/app/keepers" cmtconfig "github.com/cometbft/cometbft/config" cmtos "github.com/cometbft/cometbft/libs/os" cmttime "github.com/cometbft/cometbft/types/time" @@ -35,7 +36,6 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/app" appparams "github.com/babylonchain/babylon/app/params" "github.com/babylonchain/babylon/privval" "github.com/babylonchain/babylon/testutil/datagen" @@ -321,7 +321,7 @@ func InitTestnet( srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config/app.toml"), babylonConfig) // create and save client config - if _, err = app.CreateClientConfig(chainID, keyringBackend, nodeDir); err != nil { + if _, err = appkeepers.CreateClientConfig(chainID, keyringBackend, nodeDir); err != nil { return err } } diff --git a/test/e2e/initialization/init.go b/test/e2e/initialization/init.go index 8dc02cee4..0a4f2b62b 100644 --- a/test/e2e/initialization/init.go +++ b/test/e2e/initialization/init.go @@ -6,7 +6,7 @@ import ( "path/filepath" "time" - "github.com/babylonchain/babylon/app" + appkeepers "github.com/babylonchain/babylon/app/keepers" "github.com/babylonchain/babylon/test/e2e/util" ) @@ -42,7 +42,7 @@ func InitChain(id, dataDir string, nodeConfigs []*NodeConfig, votingPeriod, expe } for _, node := range chain.nodes { - _, _ = app.CreateClientConfig(node.chain.chainMeta.Id, "test", node.configDir()) + _, _ = appkeepers.CreateClientConfig(node.chain.chainMeta.Id, "test", node.configDir()) } return chain.export(), nil diff --git a/testutil/datagen/genesiskey.go b/testutil/datagen/genesiskey.go index 3b15e14ad..aff771d1b 100644 --- a/testutil/datagen/genesiskey.go +++ b/testutil/datagen/genesiskey.go @@ -1,6 +1,11 @@ package datagen import ( + "github.com/babylonchain/babylon/app" + appkeepers "github.com/babylonchain/babylon/app/keepers" + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/privval" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" cmtcrypto "github.com/cometbft/cometbft/crypto" cmted25519 "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/crypto/codec" @@ -8,11 +13,6 @@ import ( cosmosed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" - - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" ) type GenesisValidators struct { @@ -88,7 +88,7 @@ func GenesisValidatorSet(numVals int) (*GenesisValidators, error) { // GenesisValidatorSetWithPrivSigner generates a set with `numVals` genesis validators // along with the privSigner, which will be in the 0th position of the return validator set -func GenesisValidatorSetWithPrivSigner(numVals int) (*GenesisValidators, *app.PrivSigner, error) { +func GenesisValidatorSetWithPrivSigner(numVals int) (*GenesisValidators, *appkeepers.PrivSigner, error) { ps, err := app.SetupTestPrivSigner() if err != nil { return nil, nil, err diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index 7fd126be9..2a0390e09 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -7,16 +7,16 @@ import ( "testing" "cosmossdk.io/core/header" + appkeepers "github.com/babylonchain/babylon/app/keepers" + "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonchain/babylon/testutil/datagen" + checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" abci "github.com/cometbft/cometbft/abci/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" cosmosed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" protoio "github.com/cosmos/gogoproto/io" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - "cosmossdk.io/math" "github.com/cosmos/gogoproto/proto" "github.com/stretchr/testify/require" @@ -56,7 +56,7 @@ func NewHelper(t *testing.T) *Helper { // NewHelperWithValSet is same as NewHelper, except that it creates a set of validators // the privSigner is the 0th validator in valSet -func NewHelperWithValSet(t *testing.T, valSet *datagen.GenesisValidators, privSigner *app.PrivSigner) *Helper { +func NewHelperWithValSet(t *testing.T, valSet *datagen.GenesisValidators, privSigner *appkeepers.PrivSigner) *Helper { // generate the genesis account signerPubKey := privSigner.WrappedPV.Key.PubKey acc := authtypes.NewBaseAccount(signerPubKey.Address().Bytes(), &cosmosed.PubKey{Key: signerPubKey.Bytes()}, 0, 0) @@ -94,7 +94,7 @@ func NewHelperWithValSet(t *testing.T, valSet *datagen.GenesisValidators, privSi // NewHelperWithValSetNoSigner is same as NewHelperWithValSet, except that the privSigner is not // included in the validator set -func NewHelperWithValSetNoSigner(t *testing.T, valSet *datagen.GenesisValidators, privSigner *app.PrivSigner) *Helper { +func NewHelperWithValSetNoSigner(t *testing.T, valSet *datagen.GenesisValidators, privSigner *appkeepers.PrivSigner) *Helper { // generate the genesis account signerPubKey := privSigner.WrappedPV.Key.PubKey acc := authtypes.NewBaseAccount(signerPubKey.Address().Bytes(), &cosmosed.PubKey{Key: signerPubKey.Bytes()}, 0, 0) diff --git a/x/checkpointing/module.go b/x/checkpointing/module.go index 5e4bf3184..7e5cb77cc 100644 --- a/x/checkpointing/module.go +++ b/x/checkpointing/module.go @@ -2,10 +2,11 @@ package checkpointing import ( "context" - "cosmossdk.io/core/appmodule" "encoding/json" "fmt" + "cosmossdk.io/core/appmodule" + "github.com/gorilla/mux" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/spf13/cobra" diff --git a/x/checkpointing/proposal.go b/x/checkpointing/proposal.go index c4c0bb437..b9d3a3696 100644 --- a/x/checkpointing/proposal.go +++ b/x/checkpointing/proposal.go @@ -45,7 +45,6 @@ func NewProposalHandler( func (h *ProposalHandler) SetHandlers(bApp *baseapp.BaseApp) { bApp.SetPrepareProposal(h.PrepareProposal()) bApp.SetProcessProposal(h.ProcessProposal()) - bApp.SetPreBlocker(h.PreBlocker()) } // PrepareProposal examines the vote extensions from the previous block, accumulates @@ -329,14 +328,14 @@ func (h *ProposalHandler) ProcessProposal() sdk.ProcessProposalHandler { } } -// PreBlocker extracts the checkpoint from the injected tx and stores it in -// the application +// PreBlocker extracts the checkpoint from the injected tx and stores it in the application // no more validation is needed as it is already done in ProcessProposal +// NOTE: this is appended to the existing PreBlocker in BabylonApp at app.go func (h *ProposalHandler) PreBlocker() sdk.PreBlocker { return func(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { - k := h.ckptKeeper res := &sdk.ResponsePreBlock{} + k := h.ckptKeeper epoch := k.GetEpoch(ctx) // BLS signatures are sent in the last block of the previous epoch, // so they should be aggregated in the first block of the new epoch From f05669b55bb0a98647cfcb0a782e0ff8c4145f92 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Tue, 16 Jul 2024 08:21:10 +0200 Subject: [PATCH 108/119] Disable flaky e2e test (#713) Disable flaky test --- test/e2e/btc_staking_e2e_test.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index 538c58c01..d8d85a5e4 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -667,19 +667,21 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { // tries to create a send transaction putting the freegranter as feepayer, it should FAIL // since we only gave grant for BTC delegation msgs. - outBuff, errBuff, err := node.BankSendOutput( - wGratee, node.PublicAddress, stakerBalance.String(), - fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), - ) - outputStr := outBuff.String() + errBuff.String() - s.Require().Contains(outputStr, fmt.Sprintf("code: %d", feegrant.ErrMessageNotAllowed.ABCICode())) - s.Require().Contains(outputStr, feegrant.ErrMessageNotAllowed.Error()) - s.Nil(err) - - // staker should not have lost any balance. - stakerBalances, err := node.QueryBalances(granteeStakerAddr.String()) - s.Require().NoError(err) - s.Require().Equal(stakerBalance.String(), stakerBalances.String()) + // TODO: Uncomment the next lines when issue: https://github.com/babylonchain/babylon/issues/693 + // is fixed on cosmos-sdk side + // outBuff, errBuff, err := node.BankSendOutput( + // wGratee, node.PublicAddress, stakerBalance.String(), + // fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + // ) + // outputStr := outBuff.String() + errBuff.String() + // s.Require().Contains(outputStr, fmt.Sprintf("code: %d", feegrant.ErrMessageNotAllowed.ABCICode())) + // s.Require().Contains(outputStr, feegrant.ErrMessageNotAllowed.Error()) + // s.Nil(err) + + // // staker should not have lost any balance. + // stakerBalances, err := node.QueryBalances(granteeStakerAddr.String()) + // s.Require().NoError(err) + // s.Require().Equal(stakerBalance.String(), stakerBalances.String()) // submit the message to create BTC delegation using the fee grant // but putting as fee more than the spend limit @@ -737,7 +739,7 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { // verify the balances after the BTC delegation was submited // the staker should continue to have zero as balance. - stakerBalances, err = node.QueryBalances(granteeStakerAddr.String()) + stakerBalances, err := node.QueryBalances(granteeStakerAddr.String()) s.NoError(err) s.Equal(stakerBalance.String(), stakerBalances.String()) From 5bc646e5faafd19dcae34035c11391380c6a2ea8 Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Tue, 16 Jul 2024 14:34:25 +0800 Subject: [PATCH 109/119] feat(inactivity): Identify inactive finality providers (#682) * feat: Add finality provider signing info (#614) * feat(jailing): Identify inactivity upon EndBlocker (#681) * feat(Inactivity): Add LivenessDelay to finality params and logic for reverting inactive flag (#689) --- app/app.go | 5 +- app/keepers/keepers.go | 3 + go.mod | 4 +- proto/babylon/btcstaking/v1/btcstaking.proto | 4 + proto/babylon/btcstaking/v1/query.proto | 2 + proto/babylon/finality/v1/finality.proto | 12 + proto/babylon/finality/v1/params.proto | 20 +- .../configurer/chain/queries_btcstaking.go | 3 +- .../mocks/checkpointing_expected_keepers.go | 29 +- x/btcstaking/keeper/finality_providers.go | 24 +- x/btcstaking/keeper/hooks.go | 39 +++ x/btcstaking/keeper/incentive_test.go | 7 +- x/btcstaking/keeper/keeper.go | 18 +- x/btcstaking/keeper/keeper_test.go | 19 +- x/btcstaking/keeper/power_dist_change.go | 14 +- x/btcstaking/types/btcstaking.go | 5 + x/btcstaking/types/btcstaking.pb.go | 235 ++++++++----- x/btcstaking/types/expected_keepers.go | 4 + x/btcstaking/types/hooks.go | 26 ++ x/btcstaking/types/incentive.go | 37 ++- x/btcstaking/types/mocked_keepers.go | 37 +++ x/btcstaking/types/query.pb.go | 273 ++++++++------- x/finality/abci.go | 17 +- x/finality/keeper/hooks.go | 41 +++ x/finality/keeper/keeper.go | 39 ++- x/finality/keeper/liveness.go | 187 +++++++++++ x/finality/keeper/liveness_test.go | 90 +++++ x/finality/keeper/params.go | 1 + x/finality/keeper/signing_info.go | 103 ++++++ x/finality/types/expected_keepers.go | 10 + x/finality/types/finality.pb.go | 313 ++++++++++++++++-- x/finality/types/genesis_test.go | 7 +- x/finality/types/hooks.go | 26 ++ x/finality/types/keys.go | 52 ++- x/finality/types/mocked_keepers.go | 105 +++++- x/finality/types/params.go | 100 +++++- x/finality/types/params.pb.go | 163 ++++++++- x/finality/types/signing_info.go | 28 ++ 38 files changed, 1790 insertions(+), 312 deletions(-) create mode 100644 x/btcstaking/keeper/hooks.go create mode 100644 x/btcstaking/types/hooks.go create mode 100644 x/finality/keeper/hooks.go create mode 100644 x/finality/keeper/liveness.go create mode 100644 x/finality/keeper/liveness_test.go create mode 100644 x/finality/keeper/signing_info.go create mode 100644 x/finality/types/hooks.go create mode 100644 x/finality/types/signing_info.go diff --git a/app/app.go b/app/app.go index f6b806fe2..67b0b7800 100644 --- a/app/app.go +++ b/app/app.go @@ -24,8 +24,6 @@ import ( "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - "github.com/babylonchain/babylon/app/upgrades" - bbn "github.com/babylonchain/babylon/types" abci "github.com/cometbft/cometbft/abci/types" cmtos "github.com/cometbft/cometbft/libs/os" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" @@ -95,6 +93,9 @@ import ( ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cast" + "github.com/babylonchain/babylon/app/upgrades" + bbn "github.com/babylonchain/babylon/types" + appkeepers "github.com/babylonchain/babylon/app/keepers" appparams "github.com/babylonchain/babylon/app/params" "github.com/babylonchain/babylon/client/docs" diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 15628ee78..64c0baa14 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -528,6 +528,7 @@ func (ak *AppKeepers) InitKeepers( btcNetParams, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + // set up finality keeper ak.FinalityKeeper = finalitykeeper.NewKeeper( appCodec, @@ -536,6 +537,8 @@ func (ak *AppKeepers) InitKeepers( ak.IncentiveKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) + ak.BTCStakingKeeper = *ak.BTCStakingKeeper.SetHooks(btcstakingtypes.NewMultiBtcStakingHooks(ak.FinalityKeeper.Hooks())) + ak.FinalityKeeper = *ak.FinalityKeeper.SetHooks(finalitytypes.NewMultiFinalityHooks(ak.BTCStakingKeeper.Hooks())) // create evidence keeper with router evidenceKeeper := evidencekeeper.NewKeeper( diff --git a/go.mod b/go.mod index 30fd3ecc6..98badadb7 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( require ( cosmossdk.io/api v0.7.4 cosmossdk.io/client/v2 v2.0.0-beta.1 + cosmossdk.io/collections v0.4.0 cosmossdk.io/core v0.11.0 cosmossdk.io/depinject v1.0.0-alpha.4 cosmossdk.io/errors v1.0.1 @@ -41,6 +42,7 @@ require ( cosmossdk.io/x/upgrade v0.1.1 github.com/CosmWasm/wasmvm/v2 v2.0.1 github.com/avast/retry-go/v4 v4.5.1 + github.com/bits-and-blooms/bitset v1.10.0 github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/btcsuite/btcd/btcutil v1.1.5 @@ -141,7 +143,6 @@ require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.36.0 // indirect - cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/x/nft v0.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect @@ -152,7 +153,6 @@ require ( github.com/aead/siphash v1.0.1 // indirect github.com/aws/aws-sdk-go v1.44.312 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 04757d74b..091555f19 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -33,6 +33,8 @@ message FinalityProvider { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed uint64 slashed_btc_height = 7; + // inactive defines whether the finality provider is detected inactive + bool inactive = 8; } // FinalityProviderWithMeta wraps the FinalityProvider with metadata. @@ -52,6 +54,8 @@ message FinalityProviderWithMeta { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed uint64 slashed_btc_height = 5; + // inactive defines whether the finality provider is detected inactive + bool inactive = 6; } // BTCDelegation defines a BTC delegation diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 91e3052ad..9a48e212c 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -349,4 +349,6 @@ message FinalityProviderResponse { uint64 height = 8; // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 9; + // inactive defines whether the finality provider is detected inactive + bool inactive = 10; } diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index 04b6bd722..c833f5fc6 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -51,3 +51,15 @@ message Evidence { // where finality signature is an EOTS signature bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; } + +// FinalityProviderSigningInfo defines a finality provider's signing info for monitoring their +// liveness activity. +message FinalityProviderSigningInfo { + // fp_btc_pk is the BTC PK of the finality provider that casts this vote + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // start_height is the block height at which finality provider become active + int64 start_height = 2; + // missed_blocks_counter defines a counter to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + int64 missed_blocks_counter = 3; +} diff --git a/proto/babylon/finality/v1/params.proto b/proto/babylon/finality/v1/params.proto index c5dce2cc9..8645a61e0 100644 --- a/proto/babylon/finality/v1/params.proto +++ b/proto/babylon/finality/v1/params.proto @@ -2,14 +2,28 @@ syntax = "proto3"; package babylon.finality.v1; import "gogoproto/gogo.proto"; +import "amino/amino.proto"; +import "cosmos_proto/cosmos.proto"; option go_package = "github.com/babylonchain/babylon/x/finality/types"; // Params defines the parameters for the module. message Params { option (gogoproto.goproto_stringer) = false; - - // min_pub_rand is the minimum number of public randomness each + // signed_blocks_window defines the size of the sliding window for tracking finality provider liveness + int64 signed_blocks_window = 1; + // finality_sig_timeout defines how much time (in terms of blocks) finality providers have to cast a finality + // vote before being judged as missing their voting turn on the given block + int64 finality_sig_timeout = 2; + // min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign + // within the sliding window to avoid being detected as inactive + bytes min_signed_per_window = 3 [ + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false, + (amino.dont_omitempty) = true + ]; + // min_pub_rand is the minimum number of public randomness each // message should commit - uint64 min_pub_rand = 1; + uint64 min_pub_rand = 4; } diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index 60be29f74..8e3cec5e0 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -4,11 +4,12 @@ import ( "fmt" "net/url" + "github.com/stretchr/testify/require" + "github.com/babylonchain/babylon/test/e2e/util" bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ftypes "github.com/babylonchain/babylon/x/finality/types" - "github.com/stretchr/testify/require" ) func (n *NodeConfig) QueryBTCStakingParams() *bstypes.Params { diff --git a/testutil/mocks/checkpointing_expected_keepers.go b/testutil/mocks/checkpointing_expected_keepers.go index 409a1071b..80f0345f2 100644 --- a/testutil/mocks/checkpointing_expected_keepers.go +++ b/testutil/mocks/checkpointing_expected_keepers.go @@ -65,21 +65,6 @@ func (mr *MockEpochingKeeperMockRecorder) EnqueueMsg(ctx, msg interface{}) *gomo return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnqueueMsg", reflect.TypeOf((*MockEpochingKeeper)(nil).EnqueueMsg), ctx, msg) } -// GetAppHash mocks base method. -func (m *MockEpochingKeeper) GetAppHash(ctx context.Context, height uint64) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAppHash", ctx, height) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAppHash indicates an expected call of GetAppHash. -func (mr *MockEpochingKeeperMockRecorder) GetAppHash(ctx, height interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAppHash", reflect.TypeOf((*MockEpochingKeeper)(nil).GetAppHash), ctx, height) -} - // GetEpoch mocks base method. func (m *MockEpochingKeeper) GetEpoch(ctx context.Context) *types0.Epoch { m.ctrl.T.Helper() @@ -229,3 +214,17 @@ func (mr *MockCheckpointingHooksMockRecorder) AfterRawCheckpointForgotten(ctx, c mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterRawCheckpointForgotten", reflect.TypeOf((*MockCheckpointingHooks)(nil).AfterRawCheckpointForgotten), ctx, ckpt) } + +// AfterRawCheckpointSealed mocks base method. +func (m *MockCheckpointingHooks) AfterRawCheckpointSealed(ctx context.Context, epoch uint64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterRawCheckpointSealed", ctx, epoch) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterRawCheckpointSealed indicates an expected call of AfterRawCheckpointSealed. +func (mr *MockCheckpointingHooksMockRecorder) AfterRawCheckpointSealed(ctx, epoch interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterRawCheckpointSealed", reflect.TypeOf((*MockCheckpointingHooks)(nil).AfterRawCheckpointSealed), ctx, epoch) +} diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index 6b2a4960f..5b2c38d52 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -5,9 +5,10 @@ import ( "fmt" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/x/btcstaking/types" ) // SetFinalityProvider adds the given finality provider to KVStore @@ -66,6 +67,27 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error return nil } +// RevertInactiveFinalityProvider sets the Inactive flag of the given finality provider +// to false +func (k Keeper) RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error { + // ensure finality provider exists + fp, err := k.GetFinalityProvider(ctx, fpBTCPK) + if err != nil { + return err + } + + // ignore the finality provider is already slashed + // or detected as inactive + if fp.IsSlashed() || fp.IsInactive() { + return nil + } + + fp.Inactive = false + k.SetFinalityProvider(ctx, fp) + + return nil +} + // finalityProviderStore returns the KVStore of the finality provider set // prefix: FinalityProviderKey // key: Bitcoin secp256k1 PK diff --git a/x/btcstaking/keeper/hooks.go b/x/btcstaking/keeper/hooks.go new file mode 100644 index 000000000..137af32ba --- /dev/null +++ b/x/btcstaking/keeper/hooks.go @@ -0,0 +1,39 @@ +package keeper + +import ( + "context" + "fmt" + + bbntypes "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/finality/types" +) + +var _ types.FinalityHooks = Hooks{} + +// Hooks wrapper struct for BTC staking keeper +type Hooks struct { + k Keeper +} + +// Return the finality hooks +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} + +// AfterInactiveFinalityProviderDetected updates the status of the given finality provider to `inactive` +func (h Hooks) AfterInactiveFinalityProviderDetected(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { + fp, err := h.k.GetFinalityProvider(ctx, fpPk.MustMarshal()) + if err != nil { + return err + } + + if fp.IsInactive() { + return fmt.Errorf("the finality provider %s is already detected as inactive", fpPk.MarshalHex()) + } + + fp.Inactive = true + + h.k.SetFinalityProvider(ctx, fp) + + return nil +} diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index d6d3999ac..ec60f11c1 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -4,11 +4,12 @@ import ( "math/rand" "testing" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonchain/babylon/testutil/datagen" btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) func FuzzRecordVotingPowerDistCache(f *testing.F) { @@ -71,7 +72,7 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) { require.NotNil(t, dc) require.Equal(t, dc.TotalVotingPower, numFpsWithVotingPower*numBTCDels*stakingValue) maxNumFps := h.BTCStakingKeeper.GetParams(h.Ctx).MaxActiveFinalityProviders - activeFPs := dc.GetActiveFinalityProviders(maxNumFps) + activeFPs := dc.GetActiveFinalityProviderSet(maxNumFps) for _, fpDistInfo := range activeFPs { require.Equal(t, fpDistInfo.TotalVotingPower, numBTCDels*stakingValue) fp, ok := fpsWithVotingPowerMap[fpDistInfo.Addr] diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 6c0b9ca68..56d1ac41f 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -7,10 +7,11 @@ import ( corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/log" - "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/x/btcstaking/types" ) type ( @@ -22,6 +23,8 @@ type ( btccKeeper types.BtcCheckpointKeeper ckptKeeper types.CheckpointingKeeper + hooks types.BtcStakingHooks + btcNet *chaincfg.Params // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. @@ -48,11 +51,24 @@ func NewKeeper( btccKeeper: btccKeeper, ckptKeeper: ckptKeeper, + hooks: nil, + btcNet: btcNet, authority: authority, } } +// SetHooks sets the BTC staking hooks +func (k *Keeper) SetHooks(sh types.BtcStakingHooks) *Keeper { + if k.hooks != nil { + panic("cannot set BTC staking hooks twice") + } + + k.hooks = sh + + return k +} + func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) } diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 73e44aac0..49da3cdaf 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -6,6 +6,13 @@ import ( "cosmossdk.io/core/header" sdkmath "cosmossdk.io/math" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/wire" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" @@ -13,12 +20,6 @@ import ( btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" "github.com/babylonchain/babylon/x/btcstaking/keeper" "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/chaincfg" - "github.com/btcsuite/btcd/wire" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/require" ) var ( @@ -33,6 +34,7 @@ type Helper struct { BTCLightClientKeeper *types.MockBTCLightClientKeeper BTCCheckpointKeeper *types.MockBtcCheckpointKeeper CheckpointingKeeper *types.MockCheckpointingKeeper + BTCStakingHooks *types.MockBtcStakingHooks MsgServer types.MsgServer Net *chaincfg.Params } @@ -42,6 +44,11 @@ func NewHelper(t testing.TB, btclcKeeper *types.MockBTCLightClientKeeper, btccKe ctx = ctx.WithHeaderInfo(header.Info{Height: 1}) msgSrvr := keeper.NewMsgServerImpl(*k) + ctrl := gomock.NewController(t) + mockedHooks := types.NewMockBtcStakingHooks(ctrl) + mockedHooks.EXPECT().AfterFinalityProviderActivated(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + k.SetHooks(mockedHooks) + return &Helper{ t: t, Ctx: ctx, diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index 1f0ff4de2..0d6aa3e2c 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -2,14 +2,16 @@ package keeper import ( "context" + "fmt" "sort" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcutil" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" + + bbn "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/btcstaking/types" ) /* power distribution update */ @@ -54,6 +56,14 @@ func (k Keeper) UpdatePowerDist(ctx context.Context) { // to construct the new distribution newDc := k.ProcessAllPowerDistUpdateEvents(ctx, dc, events, maxActiveFps) + // find newly bonded finality providers and execute the hooks + newBondedFinalityProviders := newDc.FindNewActiveFinalityProviders(dc, maxActiveFps) + for _, fp := range newBondedFinalityProviders { + if err := k.hooks.AfterFinalityProviderActivated(ctx, fp.BtcPk); err != nil { + panic(fmt.Errorf("failed to execute after finality provider %s bonded", fp.BtcPk.MarshalHex())) + } + } + // record voting power and cache for this height k.recordVotingPowerAndCache(ctx, newDc, maxActiveFps) // record metrics diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 7b5902178..818382fe9 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -5,6 +5,7 @@ import ( "sort" "cosmossdk.io/math" + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" @@ -15,6 +16,10 @@ func (fp *FinalityProvider) IsSlashed() bool { return fp.SlashedBabylonHeight > 0 } +func (fp *FinalityProvider) IsInactive() bool { + return fp.Inactive +} + func (fp *FinalityProvider) ValidateBasic() error { // ensure fields are non-empty and well-formatted if _, err := sdk.AccAddressFromBech32(fp.Addr); err != nil { diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index cd2d79f7e..62a796b6a 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -90,6 +90,8 @@ type FinalityProvider struct { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + // inactive defines whether the finality provider is detected inactive + Inactive bool `protobuf:"varint,8,opt,name=inactive,proto3" json:"inactive,omitempty"` } func (m *FinalityProvider) Reset() { *m = FinalityProvider{} } @@ -160,6 +162,13 @@ func (m *FinalityProvider) GetSlashedBtcHeight() uint64 { return 0 } +func (m *FinalityProvider) GetInactive() bool { + if m != nil { + return m.Inactive + } + return false +} + // FinalityProviderWithMeta wraps the FinalityProvider with metadata. type FinalityProviderWithMeta struct { // btc_pk is the Bitcoin secp256k1 PK of thisfinality provider @@ -177,6 +186,8 @@ type FinalityProviderWithMeta struct { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed SlashedBtcHeight uint64 `protobuf:"varint,5,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` + // inactive defines whether the finality provider is detected inactive + Inactive bool `protobuf:"varint,6,opt,name=inactive,proto3" json:"inactive,omitempty"` } func (m *FinalityProviderWithMeta) Reset() { *m = FinalityProviderWithMeta{} } @@ -240,6 +251,13 @@ func (m *FinalityProviderWithMeta) GetSlashedBtcHeight() uint64 { return 0 } +func (m *FinalityProviderWithMeta) GetInactive() bool { + if m != nil { + return m.Inactive + } + return false +} + // BTCDelegation defines a BTC delegation type BTCDelegation struct { // staker_addr is the address to receive rewards from BTC delegation. @@ -744,82 +762,83 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1191 bytes of a gzipped FileDescriptorProto + // 1209 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x13, 0xc7, - 0x1b, 0xce, 0xda, 0x8e, 0x43, 0x5e, 0xdb, 0xc4, 0x0c, 0x21, 0x2c, 0x44, 0xbf, 0x24, 0x3f, 0x97, - 0xa2, 0xa8, 0x25, 0x36, 0x04, 0x5a, 0x95, 0x43, 0x0f, 0x71, 0x1c, 0x4a, 0x04, 0x04, 0x77, 0xed, - 0x50, 0xb5, 0x95, 0xba, 0x1a, 0xef, 0x4e, 0xd6, 0x23, 0xdb, 0x3b, 0xdb, 0x9d, 0xb1, 0xeb, 0x7c, - 0x83, 0x5e, 0x2a, 0xf5, 0xda, 0x7b, 0x3f, 0x02, 0x9f, 0xa1, 0xe2, 0x88, 0x38, 0x55, 0x39, 0x44, - 0x15, 0x9c, 0xfb, 0x1d, 0xaa, 0x99, 0x59, 0xef, 0xae, 0x29, 0xa1, 0x40, 0x72, 0xf3, 0xbc, 0xff, - 0x9e, 0x77, 0xde, 0xe7, 0xf1, 0x3b, 0x0b, 0xd7, 0x3b, 0xb8, 0x73, 0xd8, 0x67, 0x7e, 0xad, 0x23, - 0x1c, 0x2e, 0x70, 0x8f, 0xfa, 0x5e, 0x6d, 0x74, 0x2b, 0x75, 0xaa, 0x06, 0x21, 0x13, 0x0c, 0x5d, - 0x8a, 0xe2, 0xaa, 0x29, 0xcf, 0xe8, 0xd6, 0xd5, 0x45, 0x8f, 0x79, 0x4c, 0x45, 0xd4, 0xe4, 0x2f, - 0x1d, 0x7c, 0xf5, 0x8a, 0xc3, 0xf8, 0x80, 0x71, 0x5b, 0x3b, 0xf4, 0x21, 0x72, 0x5d, 0xd3, 0xa7, - 0x5a, 0x82, 0xd5, 0x21, 0x02, 0xdf, 0xaa, 0x4d, 0xa1, 0x5d, 0x5d, 0x7d, 0x73, 0x57, 0x01, 0x0b, - 0x74, 0x40, 0xe5, 0x59, 0x16, 0xca, 0xf7, 0xa8, 0x8f, 0xfb, 0x54, 0x1c, 0x36, 0x43, 0x36, 0xa2, - 0x2e, 0x09, 0xd1, 0x0d, 0xc8, 0x61, 0xd7, 0x0d, 0x4d, 0x63, 0xcd, 0x58, 0x9f, 0xaf, 0x9b, 0x2f, - 0x9e, 0x6e, 0x2c, 0x46, 0xd8, 0x5b, 0xae, 0x1b, 0x12, 0xce, 0x5b, 0x22, 0xa4, 0xbe, 0x67, 0xa9, - 0x28, 0xb4, 0x03, 0x05, 0x97, 0x70, 0x27, 0xa4, 0x81, 0xa0, 0xcc, 0x37, 0x33, 0x6b, 0xc6, 0x7a, - 0x61, 0xf3, 0xa3, 0x6a, 0x94, 0x91, 0xdc, 0x51, 0xf5, 0x57, 0x6d, 0x24, 0xa1, 0x56, 0x3a, 0x0f, - 0x3d, 0x02, 0x70, 0xd8, 0x60, 0x40, 0x39, 0x97, 0x55, 0xb2, 0x0a, 0x7a, 0xe3, 0xe8, 0x78, 0x75, - 0x59, 0x17, 0xe2, 0x6e, 0xaf, 0x4a, 0x59, 0x6d, 0x80, 0x45, 0xb7, 0xfa, 0x90, 0x78, 0xd8, 0x39, - 0x6c, 0x10, 0xe7, 0xc5, 0xd3, 0x0d, 0x88, 0x70, 0x1a, 0xc4, 0xb1, 0x52, 0x05, 0xd0, 0x23, 0xc8, - 0x77, 0x84, 0x63, 0x07, 0x3d, 0x33, 0xb7, 0x66, 0xac, 0x17, 0xeb, 0x9f, 0x1f, 0x1d, 0xaf, 0x6e, - 0x7a, 0x54, 0x74, 0x87, 0x9d, 0xaa, 0xc3, 0x06, 0xb5, 0x68, 0x30, 0x4e, 0x17, 0x53, 0x7f, 0x72, - 0xa8, 0x89, 0xc3, 0x80, 0xf0, 0x6a, 0x7d, 0xb7, 0x79, 0xfb, 0xce, 0xcd, 0xe6, 0xb0, 0xf3, 0x80, - 0x1c, 0x5a, 0xb3, 0x1d, 0xe1, 0x34, 0x7b, 0xe8, 0x4b, 0xc8, 0x06, 0x2c, 0x30, 0x67, 0xd5, 0xe5, - 0x3e, 0xad, 0xbe, 0x91, 0xc4, 0x6a, 0x33, 0x64, 0xec, 0xe0, 0xf1, 0x41, 0x93, 0x71, 0x4e, 0x54, - 0x17, 0xf5, 0xf6, 0xb6, 0x25, 0xf3, 0xd0, 0x1d, 0x58, 0xe2, 0x7d, 0xcc, 0xbb, 0xc4, 0xb5, 0xa3, - 0x54, 0xbb, 0x4b, 0xa8, 0xd7, 0x15, 0x66, 0x7e, 0xcd, 0x58, 0xcf, 0x59, 0x8b, 0x91, 0xb7, 0xae, - 0x9d, 0xf7, 0x95, 0x0f, 0xdd, 0x00, 0x14, 0x67, 0x09, 0x67, 0x92, 0x31, 0xa7, 0x32, 0xca, 0x93, - 0x0c, 0xe1, 0xe8, 0xe8, 0xca, 0xcf, 0x19, 0x30, 0x5f, 0xa7, 0xf2, 0x1b, 0x2a, 0xba, 0x8f, 0x88, - 0xc0, 0xa9, 0x71, 0x18, 0x67, 0x31, 0x8e, 0x25, 0xc8, 0x47, 0xdd, 0x64, 0x54, 0x37, 0xd1, 0x09, - 0xfd, 0x1f, 0x8a, 0x23, 0x26, 0xa8, 0xef, 0xd9, 0x01, 0xfb, 0x89, 0x84, 0x8a, 0xc6, 0x9c, 0x55, - 0xd0, 0xb6, 0xa6, 0x34, 0xbd, 0x65, 0x14, 0xb9, 0xf7, 0x1e, 0xc5, 0xec, 0x09, 0xa3, 0xf8, 0x3b, - 0x0f, 0xa5, 0x7a, 0x7b, 0xbb, 0x41, 0xfa, 0xc4, 0xc3, 0x4a, 0x5d, 0x77, 0xa1, 0x20, 0x89, 0x22, - 0xa1, 0xfd, 0x4e, 0xca, 0x06, 0x1d, 0x2c, 0x8d, 0xa9, 0xd1, 0x65, 0xce, 0x50, 0x49, 0xd9, 0x0f, - 0x54, 0xd2, 0xf7, 0x70, 0xfe, 0x20, 0xb0, 0x75, 0x43, 0x76, 0x9f, 0x72, 0x39, 0xb6, 0xec, 0x29, - 0xba, 0x2a, 0x1c, 0x04, 0x75, 0xd9, 0xd7, 0x43, 0xca, 0x15, 0x7d, 0x5c, 0xe0, 0x50, 0x4c, 0xcf, - 0xb7, 0xa0, 0x6c, 0x11, 0x11, 0xff, 0x03, 0x20, 0xbe, 0x3b, 0xad, 0xde, 0x79, 0xe2, 0xbb, 0x91, - 0x7b, 0x19, 0xe6, 0x05, 0x13, 0xb8, 0x6f, 0x73, 0x3c, 0x51, 0xea, 0x39, 0x65, 0x68, 0x61, 0x95, - 0x1b, 0xdd, 0xd1, 0x16, 0x63, 0xf3, 0x9c, 0x9c, 0xa6, 0x35, 0x1f, 0x59, 0xda, 0x63, 0xc5, 0x71, - 0xe4, 0x66, 0x43, 0x11, 0x0c, 0x85, 0x4d, 0xdd, 0xb1, 0x39, 0xbf, 0x66, 0xac, 0x97, 0xac, 0x72, - 0xe4, 0x79, 0xac, 0x1c, 0xbb, 0xee, 0x18, 0x6d, 0x42, 0x41, 0xf1, 0x1e, 0x55, 0x03, 0xc5, 0xcd, - 0x85, 0xa3, 0xe3, 0x55, 0xc9, 0x7c, 0x2b, 0xf2, 0xb4, 0xc7, 0x16, 0xf0, 0xf8, 0x37, 0xfa, 0x01, - 0x4a, 0xae, 0xd6, 0x04, 0x0b, 0x6d, 0x4e, 0x3d, 0xb3, 0xa0, 0xb2, 0xee, 0x1e, 0x1d, 0xaf, 0x7e, - 0xf6, 0x3e, 0xb3, 0x6b, 0x51, 0xcf, 0xc7, 0x62, 0x18, 0x12, 0xab, 0x18, 0xd7, 0x6b, 0x51, 0x0f, - 0xed, 0x43, 0xc9, 0x61, 0x23, 0xe2, 0x63, 0x5f, 0xc8, 0xf2, 0xdc, 0x2c, 0xae, 0x65, 0xd7, 0x0b, - 0x9b, 0x37, 0x4f, 0x60, 0x79, 0x3b, 0x8a, 0xdd, 0x72, 0x71, 0xa0, 0x2b, 0xe8, 0xaa, 0xdc, 0x2a, - 0x4e, 0xca, 0xb4, 0xa8, 0xc7, 0xd1, 0xc7, 0x70, 0x7e, 0xe8, 0x77, 0x98, 0xef, 0xaa, 0xbb, 0xd2, - 0x01, 0x31, 0x4b, 0x6a, 0x28, 0xa5, 0xd8, 0xda, 0xa6, 0x03, 0x82, 0xbe, 0x86, 0xb2, 0xd4, 0xc5, - 0xd0, 0x77, 0x63, 0xdd, 0x9b, 0xe7, 0x95, 0xcc, 0xae, 0x9f, 0xd0, 0x40, 0xbd, 0xbd, 0xbd, 0x9f, - 0x8a, 0xb6, 0x16, 0x3a, 0xc2, 0x49, 0x1b, 0x24, 0x72, 0x80, 0x43, 0x3c, 0xe0, 0xf6, 0x88, 0x84, - 0x6a, 0x31, 0x2f, 0x68, 0x64, 0x6d, 0x7d, 0xa2, 0x8d, 0x95, 0xdf, 0x72, 0xb0, 0xf0, 0x5a, 0x2d, - 0xa9, 0xa5, 0x54, 0xd3, 0x63, 0xbd, 0x77, 0xac, 0x42, 0xd2, 0xf2, 0xbf, 0x28, 0xcc, 0xbc, 0x0b, - 0x85, 0x3f, 0xc2, 0xe5, 0x84, 0xc2, 0x04, 0x40, 0x92, 0x99, 0x3d, 0x2d, 0x99, 0x97, 0xe2, 0xca, - 0xfb, 0x93, 0xc2, 0x92, 0x55, 0x06, 0x4b, 0x29, 0xd5, 0x4c, 0x1a, 0x96, 0x88, 0xb9, 0xd3, 0x22, - 0x2e, 0x26, 0xf2, 0x89, 0xea, 0x4a, 0xc0, 0x03, 0x58, 0x4a, 0x64, 0x94, 0xc2, 0xe3, 0xe6, 0xec, - 0x07, 0xea, 0x69, 0x31, 0xd6, 0x53, 0x02, 0xc3, 0x91, 0x03, 0xcb, 0x31, 0xce, 0xd4, 0x28, 0xf5, - 0x62, 0xc9, 0x2b, 0xb0, 0x6b, 0x27, 0x80, 0xc5, 0xd5, 0x77, 0xfd, 0x03, 0x66, 0x99, 0x93, 0x42, - 0xe9, 0xc9, 0xc9, 0x9d, 0x52, 0x69, 0xc1, 0xe5, 0x64, 0x15, 0xb3, 0x30, 0xd9, 0xc9, 0x1c, 0x7d, - 0x01, 0x39, 0x97, 0xf4, 0xb9, 0x69, 0xbc, 0x15, 0x68, 0x6a, 0x91, 0x5b, 0x2a, 0xa3, 0xb2, 0x07, - 0xcb, 0x6f, 0x2e, 0xba, 0xeb, 0xbb, 0x64, 0x8c, 0x6a, 0xb0, 0x98, 0x2c, 0x1a, 0xbb, 0x8b, 0x79, - 0x57, 0xdf, 0x48, 0x02, 0x15, 0xad, 0x0b, 0xf1, 0xca, 0xb9, 0x8f, 0x79, 0x57, 0x35, 0xf9, 0xbb, - 0x01, 0xa5, 0xa9, 0x0b, 0xa1, 0x7b, 0x90, 0x39, 0xf5, 0x63, 0x99, 0x09, 0x7a, 0xe8, 0x01, 0x64, - 0xa5, 0x52, 0x32, 0xa7, 0x55, 0x8a, 0xac, 0x52, 0xf9, 0xc5, 0x80, 0x2b, 0x27, 0x92, 0x2c, 0x1f, - 0x2a, 0x87, 0x8d, 0xce, 0xe0, 0x8d, 0x77, 0xd8, 0xa8, 0xd9, 0x93, 0x7f, 0x60, 0xac, 0x31, 0xb4, - 0xf6, 0x32, 0x6a, 0x78, 0x05, 0x1c, 0xe3, 0xf2, 0xca, 0x1f, 0x06, 0x5c, 0x69, 0x91, 0x3e, 0x71, - 0x04, 0x1d, 0x91, 0x89, 0xb4, 0x76, 0xe4, 0x97, 0x87, 0xef, 0x10, 0x74, 0x1d, 0x16, 0x5e, 0x63, - 0x41, 0xbf, 0xbb, 0x56, 0x69, 0x8a, 0x00, 0x64, 0xc1, 0x7c, 0xfc, 0xa4, 0x9d, 0xf2, 0x8d, 0x9d, - 0x8b, 0x5e, 0x33, 0xb4, 0x01, 0x17, 0x43, 0x22, 0x35, 0x19, 0x12, 0xd7, 0x8e, 0xaa, 0xf3, 0x9e, - 0x5e, 0x11, 0x56, 0x39, 0x76, 0xdd, 0x93, 0xe1, 0xad, 0xde, 0x27, 0x3b, 0x70, 0x71, 0x4a, 0x66, - 0x2d, 0x81, 0xc5, 0x90, 0xa3, 0x02, 0xcc, 0x35, 0x77, 0xf6, 0x1a, 0xbb, 0x7b, 0x5f, 0x95, 0x67, - 0x10, 0x40, 0x7e, 0x6b, 0xbb, 0xbd, 0xfb, 0x64, 0xa7, 0x6c, 0xa0, 0x22, 0x9c, 0xdb, 0xdf, 0xab, - 0x3f, 0xde, 0x6b, 0xec, 0x34, 0xca, 0x19, 0x34, 0x07, 0xd9, 0xad, 0xbd, 0x6f, 0xcb, 0xd9, 0xfa, - 0xc3, 0x67, 0x2f, 0x57, 0x8c, 0xe7, 0x2f, 0x57, 0x8c, 0xbf, 0x5e, 0xae, 0x18, 0xbf, 0xbe, 0x5a, - 0x99, 0x79, 0xfe, 0x6a, 0x65, 0xe6, 0xcf, 0x57, 0x2b, 0x33, 0xdf, 0xfd, 0xe7, 0x65, 0xc6, 0xe9, - 0x4f, 0x74, 0x75, 0xb3, 0x4e, 0x5e, 0x7d, 0xa2, 0xdf, 0xfe, 0x27, 0x00, 0x00, 0xff, 0xff, 0xc9, - 0xf5, 0x0c, 0xdf, 0x5b, 0x0c, 0x00, 0x00, + 0x1b, 0xce, 0xda, 0x8e, 0x93, 0xbc, 0xb6, 0x89, 0x19, 0x42, 0x58, 0x12, 0xfd, 0x12, 0xff, 0x5c, + 0x8a, 0xac, 0x96, 0xd8, 0x10, 0x68, 0x55, 0x0e, 0x3d, 0xc4, 0x71, 0x28, 0x11, 0x10, 0xdc, 0xb5, + 0x43, 0xd5, 0x56, 0xea, 0x6a, 0xbc, 0x3b, 0x59, 0x8f, 0x6c, 0xef, 0x6c, 0x77, 0xc6, 0xae, 0xf3, + 0x21, 0x2a, 0xf5, 0xda, 0x3b, 0x1f, 0x81, 0xcf, 0x50, 0xf5, 0x88, 0x38, 0x55, 0x39, 0x44, 0x15, + 0xf4, 0xda, 0xef, 0x50, 0xcd, 0xec, 0x7a, 0x77, 0x9d, 0x12, 0x0a, 0x98, 0x9b, 0xe7, 0xfd, 0xf7, + 0xbc, 0xf3, 0x3e, 0x8f, 0xdf, 0x59, 0xb8, 0xde, 0xc1, 0x9d, 0xe3, 0x3e, 0x73, 0x6b, 0x1d, 0x61, + 0x71, 0x81, 0x7b, 0xd4, 0x75, 0x6a, 0xa3, 0x5b, 0x89, 0x53, 0xd5, 0xf3, 0x99, 0x60, 0xe8, 0x72, + 0x18, 0x57, 0x4d, 0x78, 0x46, 0xb7, 0xd6, 0x56, 0x1c, 0xe6, 0x30, 0x15, 0x51, 0x93, 0xbf, 0x82, + 0xe0, 0xb5, 0xab, 0x16, 0xe3, 0x03, 0xc6, 0xcd, 0xc0, 0x11, 0x1c, 0x42, 0xd7, 0xb5, 0xe0, 0x54, + 0x8b, 0xb1, 0x3a, 0x44, 0xe0, 0x5b, 0xb5, 0x29, 0xb4, 0xb5, 0xcd, 0xd7, 0x77, 0xe5, 0x31, 0x2f, + 0x08, 0x28, 0xff, 0x95, 0x86, 0xe2, 0x3d, 0xea, 0xe2, 0x3e, 0x15, 0xc7, 0x4d, 0x9f, 0x8d, 0xa8, + 0x4d, 0x7c, 0x74, 0x03, 0x32, 0xd8, 0xb6, 0x7d, 0x5d, 0x2b, 0x69, 0x95, 0xa5, 0xba, 0xfe, 0xe2, + 0xd9, 0xd6, 0x4a, 0x88, 0xbd, 0x63, 0xdb, 0x3e, 0xe1, 0xbc, 0x25, 0x7c, 0xea, 0x3a, 0x86, 0x8a, + 0x42, 0x7b, 0x90, 0xb3, 0x09, 0xb7, 0x7c, 0xea, 0x09, 0xca, 0x5c, 0x3d, 0x55, 0xd2, 0x2a, 0xb9, + 0xed, 0x8f, 0xaa, 0x61, 0x46, 0x7c, 0x47, 0xd5, 0x5f, 0xb5, 0x11, 0x87, 0x1a, 0xc9, 0x3c, 0xf4, + 0x08, 0xc0, 0x62, 0x83, 0x01, 0xe5, 0x5c, 0x56, 0x49, 0x2b, 0xe8, 0xad, 0x93, 0xd3, 0xcd, 0xf5, + 0xa0, 0x10, 0xb7, 0x7b, 0x55, 0xca, 0x6a, 0x03, 0x2c, 0xba, 0xd5, 0x87, 0xc4, 0xc1, 0xd6, 0x71, + 0x83, 0x58, 0x2f, 0x9e, 0x6d, 0x41, 0x88, 0xd3, 0x20, 0x96, 0x91, 0x28, 0x80, 0x1e, 0x41, 0xb6, + 0x23, 0x2c, 0xd3, 0xeb, 0xe9, 0x99, 0x92, 0x56, 0xc9, 0xd7, 0x3f, 0x3f, 0x39, 0xdd, 0xdc, 0x76, + 0xa8, 0xe8, 0x0e, 0x3b, 0x55, 0x8b, 0x0d, 0x6a, 0xe1, 0x60, 0xac, 0x2e, 0xa6, 0xee, 0xe4, 0x50, + 0x13, 0xc7, 0x1e, 0xe1, 0xd5, 0xfa, 0x7e, 0xf3, 0xf6, 0x9d, 0x9b, 0xcd, 0x61, 0xe7, 0x01, 0x39, + 0x36, 0xe6, 0x3b, 0xc2, 0x6a, 0xf6, 0xd0, 0x97, 0x90, 0xf6, 0x98, 0xa7, 0xcf, 0xab, 0xcb, 0x7d, + 0x5a, 0x7d, 0x2d, 0x89, 0xd5, 0xa6, 0xcf, 0xd8, 0xd1, 0xe3, 0xa3, 0x26, 0xe3, 0x9c, 0xa8, 0x2e, + 0xea, 0xed, 0x5d, 0x43, 0xe6, 0xa1, 0x3b, 0xb0, 0xca, 0xfb, 0x98, 0x77, 0x89, 0x6d, 0x86, 0xa9, + 0x66, 0x97, 0x50, 0xa7, 0x2b, 0xf4, 0x6c, 0x49, 0xab, 0x64, 0x8c, 0x95, 0xd0, 0x5b, 0x0f, 0x9c, + 0xf7, 0x95, 0x0f, 0xdd, 0x00, 0x14, 0x65, 0x09, 0x6b, 0x92, 0xb1, 0xa0, 0x32, 0x8a, 0x93, 0x0c, + 0x61, 0x85, 0xd1, 0x6b, 0xb0, 0x48, 0x5d, 0x6c, 0x09, 0x3a, 0x22, 0xfa, 0x62, 0x49, 0xab, 0x2c, + 0x1a, 0xd1, 0xb9, 0xfc, 0x34, 0x05, 0xfa, 0x59, 0x9a, 0xbf, 0xa1, 0xa2, 0xfb, 0x88, 0x08, 0x9c, + 0x18, 0x95, 0xf6, 0x21, 0x46, 0xb5, 0x0a, 0xd9, 0xb0, 0xd3, 0x94, 0xea, 0x34, 0x3c, 0xa1, 0xff, + 0x43, 0x7e, 0xc4, 0x04, 0x75, 0x1d, 0xd3, 0x63, 0x3f, 0x11, 0x5f, 0x51, 0x9c, 0x31, 0x72, 0x81, + 0xad, 0x29, 0x4d, 0x6f, 0x18, 0x53, 0xe6, 0x9d, 0xc7, 0x34, 0xff, 0x16, 0x63, 0xca, 0x9e, 0x19, + 0xd3, 0xdf, 0x59, 0x28, 0xd4, 0xdb, 0xbb, 0x0d, 0xd2, 0x27, 0x0e, 0x56, 0xaa, 0xbc, 0x0b, 0x39, + 0x49, 0x30, 0xf1, 0xcd, 0xb7, 0xfa, 0x47, 0x40, 0x10, 0x2c, 0x8d, 0x89, 0xb1, 0xa6, 0x3e, 0xa0, + 0x02, 0xd3, 0xef, 0xa9, 0xc0, 0xef, 0xe1, 0xc2, 0x91, 0x67, 0x06, 0x0d, 0x99, 0x7d, 0xca, 0xe5, + 0x48, 0xd3, 0x33, 0x74, 0x95, 0x3b, 0xf2, 0xea, 0xb2, 0xaf, 0x87, 0x94, 0x2b, 0x6a, 0xb9, 0xc0, + 0xbe, 0x98, 0x9e, 0x7d, 0x4e, 0xd9, 0xc2, 0xb1, 0xff, 0x0f, 0x80, 0xb8, 0xf6, 0xb4, 0xea, 0x97, + 0x88, 0x6b, 0x87, 0xee, 0x75, 0x58, 0x12, 0x4c, 0xe0, 0xbe, 0xc9, 0xf1, 0x44, 0xe1, 0x8b, 0xca, + 0xd0, 0xc2, 0x2a, 0x37, 0xbc, 0xa3, 0x29, 0xc6, 0x4a, 0xdb, 0x79, 0x63, 0x29, 0xb4, 0xb4, 0xc7, + 0x8a, 0xff, 0xd0, 0xcd, 0x86, 0xc2, 0x1b, 0x0a, 0x93, 0xda, 0x63, 0x7d, 0xa9, 0xa4, 0x55, 0x0a, + 0x46, 0x31, 0xf4, 0x3c, 0x56, 0x8e, 0x7d, 0x7b, 0x8c, 0xb6, 0x21, 0xa7, 0x34, 0x11, 0x56, 0x03, + 0xc5, 0xcd, 0xc5, 0x93, 0xd3, 0x4d, 0xc9, 0x7c, 0x2b, 0xf4, 0xb4, 0xc7, 0x06, 0xf0, 0xe8, 0x37, + 0xfa, 0x01, 0x0a, 0x76, 0xa0, 0x09, 0xe6, 0x9b, 0x9c, 0x3a, 0x7a, 0x4e, 0x65, 0xdd, 0x3d, 0x39, + 0xdd, 0xfc, 0xec, 0x5d, 0x66, 0xd7, 0xa2, 0x8e, 0x8b, 0xc5, 0xd0, 0x27, 0x46, 0x3e, 0xaa, 0xd7, + 0xa2, 0x0e, 0x3a, 0x84, 0x82, 0xc5, 0x46, 0xc4, 0xc5, 0xae, 0x90, 0xe5, 0xb9, 0x9e, 0x2f, 0xa5, + 0x2b, 0xb9, 0xed, 0x9b, 0xe7, 0xb0, 0xbc, 0x1b, 0xc6, 0xee, 0xd8, 0xd8, 0x0b, 0x2a, 0x04, 0x55, + 0xb9, 0x91, 0x9f, 0x94, 0x69, 0x51, 0x87, 0xa3, 0x8f, 0xe1, 0xc2, 0xd0, 0xed, 0x30, 0xd7, 0x56, + 0x77, 0xa5, 0x03, 0xa2, 0x17, 0xd4, 0x50, 0x0a, 0x91, 0xb5, 0x4d, 0x07, 0x04, 0x7d, 0x0d, 0x45, + 0xa9, 0x8b, 0xa1, 0x6b, 0x47, 0xba, 0xd7, 0x2f, 0x28, 0x99, 0x5d, 0x3f, 0xa7, 0x81, 0x7a, 0x7b, + 0xf7, 0x30, 0x11, 0x6d, 0x2c, 0x77, 0x84, 0x95, 0x34, 0x48, 0x64, 0x0f, 0xfb, 0x78, 0xc0, 0xcd, + 0x11, 0xf1, 0xd5, 0x42, 0x5f, 0x0e, 0x90, 0x03, 0xeb, 0x93, 0xc0, 0x58, 0xfe, 0x35, 0x03, 0xcb, + 0x67, 0x6a, 0x49, 0x2d, 0x25, 0x9a, 0x1e, 0x07, 0x3b, 0xc9, 0xc8, 0xc5, 0x2d, 0xff, 0x8b, 0xc2, + 0xd4, 0xdb, 0x50, 0xf8, 0x23, 0x5c, 0x89, 0x29, 0x8c, 0x01, 0x24, 0x99, 0xe9, 0x59, 0xc9, 0xbc, + 0x1c, 0x55, 0x3e, 0x9c, 0x14, 0x96, 0xac, 0x32, 0x58, 0x4d, 0xa8, 0x66, 0xd2, 0xb0, 0x44, 0xcc, + 0xcc, 0x8a, 0xb8, 0x12, 0xcb, 0x27, 0xac, 0x2b, 0x01, 0x8f, 0x60, 0x35, 0x96, 0x51, 0x02, 0x8f, + 0xeb, 0xf3, 0xef, 0xa9, 0xa7, 0x95, 0x48, 0x4f, 0x31, 0x0c, 0x47, 0x16, 0xac, 0x47, 0x38, 0x53, + 0xa3, 0x0c, 0x16, 0x4b, 0x56, 0x81, 0x5d, 0x3b, 0x07, 0x2c, 0xaa, 0xbe, 0xef, 0x1e, 0x31, 0x43, + 0x9f, 0x14, 0x4a, 0x4e, 0x4e, 0xee, 0x94, 0x72, 0x0b, 0xae, 0xc4, 0xab, 0x98, 0xf9, 0xf1, 0x4e, + 0xe6, 0xe8, 0x0b, 0xc8, 0xd8, 0xa4, 0xcf, 0x75, 0xed, 0x8d, 0x40, 0x53, 0x8b, 0xdc, 0x50, 0x19, + 0xe5, 0x03, 0x58, 0x7f, 0x7d, 0xd1, 0x7d, 0xd7, 0x26, 0x63, 0x54, 0x83, 0x95, 0x78, 0xd1, 0x98, + 0x5d, 0xcc, 0xbb, 0xc1, 0x8d, 0x24, 0x50, 0xde, 0xb8, 0x18, 0xad, 0x9c, 0xfb, 0x98, 0x77, 0x55, + 0x93, 0x4f, 0x35, 0x28, 0x4c, 0x5d, 0x08, 0xdd, 0x83, 0xd4, 0xcc, 0x0f, 0x69, 0xca, 0xeb, 0xa1, + 0x07, 0x90, 0x96, 0x4a, 0x49, 0xcd, 0xaa, 0x14, 0x59, 0xa5, 0xfc, 0xb3, 0x06, 0x57, 0xcf, 0x25, + 0x59, 0x3e, 0x54, 0x16, 0x1b, 0x7d, 0x80, 0xf7, 0xdf, 0x62, 0xa3, 0x66, 0x4f, 0xfe, 0x81, 0x71, + 0x80, 0x11, 0x68, 0x2f, 0xa5, 0x86, 0x97, 0xc3, 0x11, 0x2e, 0x2f, 0xff, 0xa6, 0xc1, 0xd5, 0x16, + 0xe9, 0x13, 0xf5, 0xea, 0x4e, 0xa4, 0xb5, 0x27, 0xbf, 0x4a, 0x5c, 0x8b, 0xa0, 0xeb, 0xb0, 0x7c, + 0x86, 0x85, 0xe0, 0xdd, 0x35, 0x0a, 0x53, 0x04, 0x20, 0x03, 0x96, 0xa2, 0x27, 0x6d, 0xc6, 0x37, + 0x76, 0x21, 0x7c, 0xcd, 0xd0, 0x16, 0x5c, 0xf2, 0x89, 0xd4, 0xa4, 0x4f, 0x6c, 0x33, 0xac, 0xce, + 0x7b, 0xc1, 0x8a, 0x30, 0x8a, 0x91, 0xeb, 0x9e, 0x0c, 0x6f, 0xf5, 0x3e, 0xd9, 0x83, 0x4b, 0x53, + 0x32, 0x6b, 0x09, 0x2c, 0x86, 0x1c, 0xe5, 0x60, 0xa1, 0xb9, 0x77, 0xd0, 0xd8, 0x3f, 0xf8, 0xaa, + 0x38, 0x87, 0x00, 0xb2, 0x3b, 0xbb, 0xed, 0xfd, 0x27, 0x7b, 0x45, 0x0d, 0xe5, 0x61, 0xf1, 0xf0, + 0xa0, 0xfe, 0xf8, 0xa0, 0xb1, 0xd7, 0x28, 0xa6, 0xd0, 0x02, 0xa4, 0x77, 0x0e, 0xbe, 0x2d, 0xa6, + 0xeb, 0x0f, 0x7f, 0x7f, 0xb9, 0xa1, 0x3d, 0x7f, 0xb9, 0xa1, 0xfd, 0xf9, 0x72, 0x43, 0xfb, 0xe5, + 0xd5, 0xc6, 0xdc, 0xf3, 0x57, 0x1b, 0x73, 0x7f, 0xbc, 0xda, 0x98, 0xfb, 0xee, 0x3f, 0x2f, 0x33, + 0x4e, 0x7e, 0xda, 0xab, 0x9b, 0x75, 0xb2, 0xea, 0xd3, 0xfe, 0xf6, 0x3f, 0x01, 0x00, 0x00, 0xff, + 0xff, 0xbc, 0xeb, 0x0e, 0xfb, 0x93, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -842,6 +861,16 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Inactive { + i-- + if m.Inactive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- @@ -930,6 +959,16 @@ func (m *FinalityProviderWithMeta) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if m.Inactive { + i-- + if m.Inactive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if m.SlashedBtcHeight != 0 { i = encodeVarintBtcstaking(dAtA, i, uint64(m.SlashedBtcHeight)) i-- @@ -1466,6 +1505,9 @@ func (m *FinalityProvider) Size() (n int) { if m.SlashedBtcHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBtcHeight)) } + if m.Inactive { + n += 2 + } return n } @@ -1491,6 +1533,9 @@ func (m *FinalityProviderWithMeta) Size() (n int) { if m.SlashedBtcHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBtcHeight)) } + if m.Inactive { + n += 2 + } return n } @@ -1933,6 +1978,26 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { break } } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Inactive = bool(v != 0) default: iNdEx = preIndex skippy, err := skipBtcstaking(dAtA[iNdEx:]) @@ -2094,6 +2159,26 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowBtcstaking + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Inactive = bool(v != 0) default: iNdEx = preIndex skippy, err := skipBtcstaking(dAtA[iNdEx:]) diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index 2f8b0428d..c36571416 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -25,3 +25,7 @@ type CheckpointingKeeper interface { GetEpoch(ctx context.Context) *etypes.Epoch GetLastFinalizedEpoch(ctx context.Context) uint64 } + +type BtcStakingHooks interface { + AfterFinalityProviderActivated(ctx context.Context, fpPk *bbn.BIP340PubKey) error +} diff --git a/x/btcstaking/types/hooks.go b/x/btcstaking/types/hooks.go new file mode 100644 index 000000000..450ef8c26 --- /dev/null +++ b/x/btcstaking/types/hooks.go @@ -0,0 +1,26 @@ +package types + +import ( + "context" + + "github.com/babylonchain/babylon/types" +) + +// combine multiple BTC staking hooks, all hook functions are run in array sequence +var _ BtcStakingHooks = &MultiBtcStakingHooks{} + +type MultiBtcStakingHooks []BtcStakingHooks + +func NewMultiBtcStakingHooks(hooks ...BtcStakingHooks) MultiBtcStakingHooks { + return hooks +} + +func (h MultiBtcStakingHooks) AfterFinalityProviderActivated(ctx context.Context, btcPk *types.BIP340PubKey) error { + for i := range h { + if err := h[i].AfterFinalityProviderActivated(ctx, btcPk); err != nil { + return err + } + } + + return nil +} diff --git a/x/btcstaking/types/incentive.go b/x/btcstaking/types/incentive.go index 21292ca0d..7dd020896 100644 --- a/x/btcstaking/types/incentive.go +++ b/x/btcstaking/types/incentive.go @@ -20,6 +20,21 @@ func (dc *VotingPowerDistCache) AddFinalityProviderDistInfo(v *FinalityProviderD dc.FinalityProviders = append(dc.FinalityProviders, v) } +func (dc *VotingPowerDistCache) FindNewActiveFinalityProviders(prevDc *VotingPowerDistCache, maxActiveFPs uint32) []*FinalityProviderDistInfo { + activeFps := dc.GetActiveFinalityProviderSet(maxActiveFPs) + prevActiveFps := prevDc.GetActiveFinalityProviderSet(maxActiveFPs) + newActiveFps := make([]*FinalityProviderDistInfo, 0) + + for pk, fp := range activeFps { + _, exists := prevActiveFps[pk] + if !exists { + newActiveFps = append(newActiveFps, fp) + } + } + + return newActiveFps +} + // ApplyActiveFinalityProviders sorts all finality providers, counts the total voting // power of top N finality providers, and records them in cache func (dc *VotingPowerDistCache) ApplyActiveFinalityProviders(maxActiveFPs uint32) { @@ -38,22 +53,30 @@ func (dc *VotingPowerDistCache) GetNumActiveFPs(maxActiveFPs uint32) uint32 { return min(maxActiveFPs, uint32(len(dc.FinalityProviders))) } -// GetActiveFinalityProviders returns the list of active finality providers +// GetActiveFinalityProviderSet returns a set of active finality providers +// keyed by the hex string of the finality provider's BTC public key // i.e., top N of them in terms of voting power -func (dc *VotingPowerDistCache) GetActiveFinalityProviders(maxActiveFPs uint32) []*FinalityProviderDistInfo { +func (dc *VotingPowerDistCache) GetActiveFinalityProviderSet(maxActiveFPs uint32) map[string]*FinalityProviderDistInfo { numActiveFPs := dc.GetNumActiveFPs(maxActiveFPs) - return dc.FinalityProviders[:numActiveFPs] + + activeFps := make(map[string]*FinalityProviderDistInfo) + + for _, fp := range dc.FinalityProviders[:numActiveFPs] { + activeFps[fp.BtcPk.MarshalHex()] = fp + } + + return activeFps } // FilterVotedDistCache filters out a voting power distribution cache // with finality providers that have voted according to a map of given // voters, and their total voted power. func (dc *VotingPowerDistCache) FilterVotedDistCache(maxActiveFPs uint32, voterBTCPKs map[string]struct{}) *VotingPowerDistCache { - activeFPs := dc.GetActiveFinalityProviders(maxActiveFPs) - filteredFps := []*FinalityProviderDistInfo{} + activeFPs := dc.GetActiveFinalityProviderSet(maxActiveFPs) + var filteredFps []*FinalityProviderDistInfo totalVotingPower := uint64(0) - for _, v := range activeFPs { - if _, ok := voterBTCPKs[v.BtcPk.MarshalHex()]; ok { + for k, v := range activeFPs { + if _, ok := voterBTCPKs[k]; ok { filteredFps = append(filteredFps, v) totalVotingPower += v.TotalVotingPower } diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index 4211211d8..e3a42ecb0 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -182,3 +182,40 @@ func (mr *MockCheckpointingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interfa mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastFinalizedEpoch", reflect.TypeOf((*MockCheckpointingKeeper)(nil).GetLastFinalizedEpoch), ctx) } + +// MockBtcStakingHooks is a mock of BtcStakingHooks interface. +type MockBtcStakingHooks struct { + ctrl *gomock.Controller + recorder *MockBtcStakingHooksMockRecorder +} + +// MockBtcStakingHooksMockRecorder is the mock recorder for MockBtcStakingHooks. +type MockBtcStakingHooksMockRecorder struct { + mock *MockBtcStakingHooks +} + +// NewMockBtcStakingHooks creates a new mock instance. +func NewMockBtcStakingHooks(ctrl *gomock.Controller) *MockBtcStakingHooks { + mock := &MockBtcStakingHooks{ctrl: ctrl} + mock.recorder = &MockBtcStakingHooksMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBtcStakingHooks) EXPECT() *MockBtcStakingHooksMockRecorder { + return m.recorder +} + +// AfterFinalityProviderActivated mocks base method. +func (m *MockBtcStakingHooks) AfterFinalityProviderActivated(ctx context.Context, fpPk *types.BIP340PubKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterFinalityProviderActivated", ctx, fpPk) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterFinalityProviderActivated indicates an expected call of AfterFinalityProviderActivated. +func (mr *MockBtcStakingHooksMockRecorder) AfterFinalityProviderActivated(ctx, fpPk interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterFinalityProviderActivated", reflect.TypeOf((*MockBtcStakingHooks)(nil).AfterFinalityProviderActivated), ctx, fpPk) +} diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index ac26ddef0..88a252b59 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1504,6 +1504,8 @@ type FinalityProviderResponse struct { Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height VotingPower uint64 `protobuf:"varint,9,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` + // inactive defines whether the finality provider is detected inactive + Inactive bool `protobuf:"varint,10,opt,name=inactive,proto3" json:"inactive,omitempty"` } func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } @@ -1588,6 +1590,13 @@ func (m *FinalityProviderResponse) GetVotingPower() uint64 { return 0 } +func (m *FinalityProviderResponse) GetInactive() bool { + if m != nil { + return m.Inactive + } + return false +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "babylon.btcstaking.v1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "babylon.btcstaking.v1.QueryParamsResponse") @@ -1620,124 +1629,125 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1870 bytes of a gzipped FileDescriptorProto + // 1881 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6c, 0xdb, 0xc8, - 0x19, 0x0e, 0x6d, 0x45, 0x89, 0x7f, 0xd9, 0x8e, 0x33, 0xeb, 0x24, 0x8c, 0x1c, 0xdb, 0x09, 0x9b, + 0x19, 0x0e, 0x6d, 0x45, 0xb1, 0x7f, 0xd9, 0x8e, 0x33, 0xeb, 0x24, 0x8c, 0x1c, 0xdb, 0x09, 0x9b, 0x4d, 0x9c, 0x97, 0x18, 0x2b, 0xde, 0x14, 0xed, 0x76, 0x37, 0xb1, 0xec, 0xdd, 0x24, 0xbb, 0x31, 0xa2, 0xd2, 0x49, 0x0b, 0x74, 0x8b, 0x12, 0x14, 0x39, 0xa2, 0x88, 0x58, 0x24, 0xc3, 0x19, 0xb9, - 0x32, 0x02, 0x5f, 0x7a, 0xe8, 0xa5, 0x28, 0x50, 0xa0, 0xbd, 0xf6, 0xdc, 0x02, 0x3d, 0x36, 0xa7, - 0x02, 0xbd, 0x6f, 0x6f, 0x8b, 0xec, 0xa1, 0xc5, 0x1e, 0x82, 0x22, 0x29, 0x5a, 0xa0, 0x40, 0xaf, - 0x3d, 0x17, 0x9c, 0x19, 0x8a, 0x94, 0x44, 0xea, 0x61, 0xbb, 0x37, 0x71, 0xe6, 0x7f, 0x3f, 0xbe, - 0x99, 0xf9, 0x05, 0x97, 0x6a, 0x46, 0x6d, 0x6f, 0xc7, 0x73, 0xd5, 0x1a, 0x35, 0x09, 0x35, 0x9e, - 0x3b, 0xae, 0xad, 0xee, 0xae, 0xaa, 0x2f, 0x5a, 0x38, 0xd8, 0x2b, 0xf9, 0x81, 0x47, 0x3d, 0x74, - 0x46, 0x90, 0x94, 0x62, 0x92, 0xd2, 0xee, 0x6a, 0x71, 0xde, 0xf6, 0x6c, 0x8f, 0x51, 0xa8, 0xe1, - 0x2f, 0x4e, 0x5c, 0xbc, 0x60, 0x7b, 0x9e, 0xbd, 0x83, 0x55, 0xc3, 0x77, 0x54, 0xc3, 0x75, 0x3d, - 0x6a, 0x50, 0xc7, 0x73, 0x89, 0xd8, 0x3d, 0x6f, 0x7a, 0xa4, 0xe9, 0x11, 0x9d, 0xb3, 0xf1, 0x0f, - 0xb1, 0x75, 0x99, 0x7f, 0xa9, 0xb1, 0x11, 0x35, 0x4c, 0x8d, 0xd5, 0xe8, 0x5b, 0x50, 0x5d, 0x17, - 0x54, 0x35, 0x83, 0x60, 0x6e, 0x64, 0x87, 0xd0, 0x37, 0x6c, 0xc7, 0x65, 0xda, 0x04, 0xad, 0x92, - 0xee, 0x9a, 0x6f, 0x04, 0x46, 0x33, 0xd2, 0x7a, 0x25, 0x9d, 0x26, 0xe1, 0x29, 0xa7, 0x5b, 0xce, - 0x90, 0xe5, 0xf9, 0x9c, 0x40, 0x99, 0x07, 0xf4, 0xfd, 0xd0, 0x9c, 0x2a, 0x93, 0xae, 0xe1, 0x17, - 0x2d, 0x4c, 0xa8, 0xa2, 0xc1, 0x7b, 0x5d, 0xab, 0xc4, 0xf7, 0x5c, 0x82, 0xd1, 0x87, 0x90, 0xe7, - 0x56, 0xc8, 0xd2, 0x45, 0x69, 0xa5, 0x50, 0x5e, 0x2c, 0xa5, 0x86, 0xb8, 0xc4, 0xd9, 0x2a, 0xb9, - 0x2f, 0xdf, 0x2c, 0x1f, 0xd3, 0x04, 0x8b, 0xf2, 0x6d, 0x58, 0x48, 0xc8, 0xac, 0xec, 0xfd, 0x00, - 0x07, 0xc4, 0xf1, 0x5c, 0xa1, 0x12, 0xc9, 0x70, 0x62, 0x97, 0xaf, 0x30, 0xe1, 0x33, 0x5a, 0xf4, - 0xa9, 0x7c, 0x01, 0x17, 0xd2, 0x19, 0x8f, 0xc2, 0x2a, 0x1b, 0x16, 0x99, 0xf0, 0x4f, 0x1d, 0xd7, - 0xd8, 0x71, 0xe8, 0x5e, 0x35, 0xf0, 0x76, 0x1d, 0x0b, 0x07, 0x51, 0x28, 0xd0, 0xa7, 0x00, 0x71, - 0x86, 0x84, 0x86, 0x2b, 0x25, 0x51, 0x02, 0x61, 0x3a, 0x4b, 0xbc, 0xe6, 0x44, 0x3a, 0x4b, 0x55, - 0xc3, 0xc6, 0x82, 0x57, 0x4b, 0x70, 0x2a, 0x7f, 0x91, 0x60, 0x29, 0x4b, 0x93, 0x70, 0xe4, 0x27, - 0x80, 0xea, 0x62, 0x33, 0xac, 0x34, 0xbe, 0x2b, 0x4b, 0x17, 0x27, 0x57, 0x0a, 0x65, 0x35, 0xc3, - 0xa9, 0x5e, 0x69, 0x91, 0x30, 0xed, 0x74, 0xbd, 0x57, 0x0f, 0x7a, 0xd0, 0xe5, 0xca, 0x04, 0x73, - 0xe5, 0xea, 0x50, 0x57, 0x84, 0xbc, 0xa4, 0x2f, 0xeb, 0x22, 0x23, 0xfd, 0xca, 0x79, 0xcc, 0x2e, - 0xc1, 0x4c, 0xdd, 0xd7, 0x6b, 0xd4, 0xd4, 0xfd, 0xe7, 0x7a, 0x03, 0xb7, 0x59, 0xd8, 0xa6, 0x34, - 0xa8, 0xfb, 0x15, 0x6a, 0x56, 0x9f, 0x3f, 0xc4, 0x6d, 0x65, 0x3f, 0x23, 0xee, 0x9d, 0x60, 0xfc, - 0x18, 0x4e, 0xf7, 0x05, 0x43, 0x84, 0x7f, 0xec, 0x58, 0xcc, 0xf5, 0xc6, 0x42, 0xf9, 0xbd, 0x04, - 0x45, 0xa6, 0xbf, 0xf2, 0x74, 0x63, 0x13, 0xef, 0x60, 0x9b, 0xb7, 0x7b, 0xe4, 0x40, 0x05, 0xf2, - 0x84, 0x1a, 0xb4, 0xc5, 0x4b, 0x6a, 0xb6, 0x7c, 0x3d, 0x43, 0x63, 0x17, 0xf7, 0x36, 0xe3, 0xd0, - 0x04, 0x67, 0x4f, 0xe1, 0x4c, 0x1c, 0xb8, 0x70, 0xfe, 0x2c, 0x89, 0xc6, 0xe9, 0x35, 0x55, 0x04, - 0xea, 0x19, 0x9c, 0x0a, 0x23, 0x6d, 0xc5, 0x5b, 0xa2, 0x64, 0x6e, 0x8e, 0x62, 0x74, 0x27, 0x46, - 0xb3, 0x35, 0x6a, 0x26, 0xc4, 0x1f, 0x5d, 0xb1, 0xd4, 0xe1, 0x5a, 0x6a, 0xa6, 0xab, 0xde, 0x4f, - 0x71, 0xb0, 0x4e, 0x1f, 0x62, 0xc7, 0x6e, 0xd0, 0xd1, 0x2b, 0x07, 0x9d, 0x85, 0x7c, 0x83, 0xf1, - 0x30, 0xa3, 0x72, 0x9a, 0xf8, 0x52, 0x9e, 0xc0, 0xf5, 0x51, 0xf4, 0x88, 0xa8, 0x5d, 0x82, 0xe9, - 0x5d, 0x8f, 0x3a, 0xae, 0xad, 0xfb, 0xe1, 0x3e, 0xd3, 0x93, 0xd3, 0x0a, 0x7c, 0x8d, 0xb1, 0x28, - 0x5b, 0xb0, 0x92, 0x2a, 0x70, 0xa3, 0x15, 0x04, 0xd8, 0xa5, 0x8c, 0x68, 0x8c, 0x8a, 0xcf, 0x8a, - 0x43, 0xb7, 0x38, 0x61, 0x5e, 0xec, 0xa4, 0x94, 0x74, 0xb2, 0xcf, 0xec, 0x89, 0x7e, 0xb3, 0x7f, - 0x29, 0xc1, 0x0d, 0xa6, 0x68, 0xdd, 0xa4, 0xce, 0x2e, 0xee, 0x83, 0x9b, 0xde, 0x90, 0x67, 0xa9, - 0x3a, 0xaa, 0xfa, 0xfd, 0xab, 0x04, 0x37, 0x47, 0xb3, 0xe7, 0x08, 0x61, 0xf0, 0x87, 0x0e, 0x6d, - 0x6c, 0x61, 0x6a, 0xfc, 0x5f, 0x61, 0x70, 0x51, 0x34, 0x26, 0x73, 0xcc, 0xa0, 0xd8, 0xea, 0x0a, - 0xac, 0x72, 0x57, 0xa0, 0x64, 0xdf, 0xf6, 0xe0, 0x1c, 0x2b, 0xbf, 0x91, 0xe0, 0x6a, 0x6a, 0xa5, - 0xa4, 0x00, 0xd5, 0x08, 0xfd, 0x72, 0x54, 0x79, 0xfc, 0x97, 0x94, 0xd1, 0x0f, 0x69, 0xa0, 0x14, - 0xc0, 0xf9, 0x04, 0x28, 0x79, 0x41, 0x0a, 0x3c, 0xdd, 0x1d, 0x0a, 0x4f, 0x5e, 0x9a, 0x68, 0xed, - 0x5c, 0x0c, 0x54, 0x5d, 0x04, 0x47, 0x97, 0xd7, 0xcf, 0xe0, 0x7c, 0x3f, 0xe0, 0x46, 0x11, 0xbf, - 0x05, 0xef, 0x09, 0x63, 0x75, 0xda, 0xd6, 0x1b, 0x06, 0x69, 0x24, 0xe2, 0x3e, 0x27, 0xb6, 0x9e, - 0xb6, 0x1f, 0x1a, 0xa4, 0x11, 0x76, 0xfd, 0x8b, 0xb4, 0x73, 0xa6, 0x13, 0xa6, 0x6d, 0x98, 0xed, - 0xc6, 0x6e, 0x71, 0xc2, 0x8d, 0x07, 0xdd, 0x33, 0x5d, 0xd0, 0xad, 0x7c, 0x9d, 0x87, 0x33, 0xe9, - 0xea, 0xbe, 0x03, 0x85, 0x50, 0x18, 0x0e, 0x74, 0xc3, 0xb2, 0x38, 0xe6, 0x4d, 0x55, 0xe4, 0xd7, - 0xaf, 0x6e, 0xcd, 0x8b, 0x28, 0xad, 0x5b, 0x56, 0x80, 0x09, 0xd9, 0xa6, 0x81, 0xe3, 0xda, 0x1a, - 0x70, 0xe2, 0x70, 0x11, 0x6d, 0x41, 0x9e, 0x57, 0x19, 0x0b, 0xec, 0x74, 0xe5, 0xee, 0x37, 0x6f, - 0x96, 0xcb, 0xb6, 0x43, 0x1b, 0xad, 0x5a, 0xc9, 0xf4, 0x9a, 0xaa, 0xb0, 0xd7, 0x6c, 0x18, 0x8e, - 0x1b, 0x7d, 0xa8, 0x74, 0xcf, 0xc7, 0xa4, 0x54, 0x79, 0x54, 0xbd, 0xb3, 0x76, 0xbb, 0xda, 0xaa, - 0x7d, 0x8e, 0xf7, 0xb4, 0xe3, 0xb5, 0xb0, 0x2e, 0xd1, 0x17, 0x30, 0x1b, 0xd7, 0xed, 0x8e, 0x43, - 0xa8, 0x3c, 0x79, 0x71, 0xf2, 0x10, 0x62, 0x0b, 0xa2, 0xe0, 0x1f, 0x3b, 0xac, 0x29, 0xa6, 0x09, - 0x35, 0x02, 0xaa, 0x8b, 0xf6, 0xca, 0x71, 0x90, 0x64, 0x6b, 0xbc, 0x07, 0xd1, 0x22, 0x00, 0x76, - 0xad, 0x88, 0xe0, 0x38, 0x23, 0x98, 0xc2, 0xae, 0x68, 0x51, 0xb4, 0x00, 0x53, 0xd4, 0xa3, 0xc6, - 0x8e, 0x4e, 0x0c, 0x2a, 0xe7, 0xd9, 0xee, 0x49, 0xb6, 0xb0, 0x6d, 0x50, 0x74, 0x19, 0x66, 0x93, - 0x15, 0x80, 0xdb, 0xf2, 0x09, 0x96, 0xfc, 0xe9, 0x38, 0xf9, 0xb8, 0x8d, 0xae, 0xc0, 0x29, 0xb2, - 0x63, 0x90, 0x46, 0x82, 0xec, 0x24, 0x23, 0x9b, 0x89, 0x96, 0x39, 0xdd, 0x07, 0x70, 0x2e, 0xee, - 0x12, 0xb6, 0xa5, 0x13, 0xc7, 0x66, 0xf4, 0x53, 0x8c, 0x7e, 0xbe, 0xb3, 0xbd, 0x1d, 0xee, 0x6e, - 0x3b, 0x76, 0xc8, 0xf6, 0x0c, 0x66, 0x4c, 0x6f, 0x17, 0xbb, 0x86, 0x4b, 0x43, 0x7a, 0x22, 0x03, - 0x6b, 0xaa, 0xdb, 0x19, 0x85, 0xb3, 0x21, 0x68, 0xd7, 0x2d, 0xc3, 0x0f, 0x25, 0x39, 0xb6, 0x6b, - 0xd0, 0x56, 0x80, 0x89, 0x36, 0x1d, 0x89, 0xd9, 0x76, 0x6c, 0x82, 0x6e, 0x02, 0x8a, 0x7c, 0xf3, - 0x5a, 0xd4, 0x6f, 0x51, 0xdd, 0xb1, 0xda, 0x72, 0x81, 0x5d, 0xc8, 0xa3, 0xe2, 0x7e, 0xc2, 0x36, - 0x1e, 0x59, 0xec, 0x28, 0x36, 0x18, 0xa8, 0xcb, 0xd3, 0x17, 0xa5, 0x95, 0x93, 0x9a, 0xf8, 0x42, - 0xcb, 0xac, 0xce, 0x68, 0x8b, 0xe8, 0x16, 0x26, 0xa6, 0x3c, 0xc3, 0x31, 0x89, 0x2f, 0x6d, 0x62, - 0x62, 0xa2, 0xf7, 0x61, 0xb6, 0xe5, 0xd6, 0x3c, 0xd7, 0x62, 0xd1, 0x71, 0x9a, 0x58, 0x9e, 0x65, - 0x2a, 0x66, 0x3a, 0xab, 0x4f, 0x9d, 0x26, 0x46, 0x26, 0x9c, 0x69, 0xb9, 0x71, 0x73, 0xe8, 0x81, - 0x28, 0x64, 0xf9, 0x14, 0xeb, 0x92, 0x52, 0x76, 0x97, 0x3c, 0x4b, 0xb0, 0x75, 0xfa, 0x64, 0xbe, - 0x95, 0xb2, 0x1a, 0xda, 0xc2, 0xdf, 0x02, 0x7a, 0xf4, 0xfe, 0x98, 0xe3, 0xb6, 0xf0, 0x55, 0xf1, - 0xda, 0x50, 0x5e, 0x4d, 0xc2, 0xb9, 0x0c, 0xc1, 0x68, 0x05, 0xe6, 0x12, 0xee, 0xb4, 0x13, 0x80, - 0x10, 0xbb, 0xc9, 0xb3, 0xfd, 0x11, 0x2c, 0xc4, 0xd9, 0x8e, 0x79, 0xa2, 0x8c, 0x4f, 0x30, 0x26, - 0xb9, 0x43, 0xf2, 0x2c, 0xa2, 0x10, 0x59, 0x37, 0x61, 0xa1, 0x93, 0xf5, 0x6e, 0xee, 0x4e, 0x0f, - 0x15, 0xca, 0x97, 0x33, 0xc2, 0xd2, 0x49, 0xfa, 0x23, 0xb7, 0xee, 0x69, 0x72, 0x24, 0x28, 0xa9, - 0x83, 0xb5, 0x4f, 0x4a, 0xe5, 0xe6, 0xd2, 0x2a, 0xf7, 0x43, 0x28, 0xf6, 0x54, 0x6e, 0xd2, 0x95, - 0xe3, 0x8c, 0xe5, 0x5c, 0x77, 0xf1, 0xc6, 0x9e, 0xd4, 0xe1, 0x6c, 0x5c, 0xbf, 0x09, 0x5e, 0x22, - 0xe7, 0x0f, 0x58, 0xc8, 0xf3, 0x9d, 0x42, 0x8e, 0x35, 0x11, 0xc5, 0x84, 0xe5, 0x21, 0x07, 0x0a, - 0xba, 0x0f, 0x39, 0x0b, 0xef, 0x1c, 0xec, 0xd6, 0xcc, 0x38, 0x95, 0x5f, 0xe4, 0x40, 0xce, 0x7c, - 0xc8, 0x7c, 0x02, 0x85, 0xb0, 0x0b, 0x02, 0xc7, 0x4f, 0x00, 0xfc, 0xb7, 0xa2, 0x73, 0x29, 0xd6, - 0xc0, 0x0f, 0xa5, 0xcd, 0x98, 0x54, 0x4b, 0xf2, 0xa1, 0x2d, 0x00, 0xd3, 0x6b, 0x36, 0x1d, 0x42, - 0xa2, 0xd3, 0x6d, 0xaa, 0x72, 0xeb, 0x9b, 0x37, 0xcb, 0x0b, 0x5c, 0x10, 0xb1, 0x9e, 0x97, 0x1c, - 0x4f, 0x6d, 0x1a, 0xb4, 0x51, 0x7a, 0x8c, 0x6d, 0xc3, 0xdc, 0xdb, 0xc4, 0xe6, 0xeb, 0x57, 0xb7, - 0x40, 0xe8, 0xd9, 0xc4, 0xa6, 0x96, 0x10, 0x80, 0x6e, 0x42, 0x8e, 0x9d, 0x01, 0x93, 0x43, 0xce, - 0x00, 0x46, 0x95, 0x40, 0xff, 0xdc, 0x51, 0xa0, 0xff, 0x47, 0x30, 0xe9, 0x7b, 0x3e, 0x2b, 0x91, - 0x42, 0xf9, 0x46, 0xd6, 0x73, 0x3d, 0xf0, 0xbc, 0xfa, 0x93, 0x7a, 0xd5, 0x23, 0x04, 0x33, 0x9b, - 0x2b, 0x4f, 0x37, 0xb4, 0x90, 0x0f, 0xad, 0xc1, 0x59, 0x56, 0x32, 0xd8, 0xd2, 0x05, 0x6b, 0x04, - 0xe4, 0x1c, 0xaa, 0xe7, 0xc5, 0x6e, 0x85, 0x6f, 0x0a, 0x4c, 0x0f, 0xa1, 0x2d, 0xe2, 0xa2, 0x66, - 0xc4, 0x71, 0x82, 0x71, 0xcc, 0x45, 0x1c, 0xd4, 0x14, 0xd4, 0xf1, 0xe5, 0xec, 0xe4, 0xc0, 0x0b, - 0xf8, 0x54, 0xdf, 0x05, 0xbc, 0xfc, 0xdb, 0xd3, 0x70, 0x9c, 0x9d, 0xf9, 0xe8, 0xe7, 0x12, 0xe4, - 0xf9, 0xd4, 0x01, 0x5d, 0xcb, 0xf0, 0xb2, 0x7f, 0xf8, 0x52, 0xbc, 0x3e, 0x0a, 0x29, 0x2f, 0x2e, - 0xe5, 0xfd, 0x9f, 0x7d, 0xfd, 0x8f, 0x5f, 0x4f, 0x2c, 0xa3, 0x45, 0x75, 0xd0, 0xd0, 0x08, 0xfd, - 0x41, 0x82, 0x53, 0x3d, 0xe3, 0x13, 0x54, 0x1e, 0xae, 0xa6, 0x77, 0x48, 0x53, 0xbc, 0x33, 0x16, - 0x8f, 0xb0, 0x51, 0x65, 0x36, 0x5e, 0x43, 0x57, 0x07, 0xda, 0xa8, 0xbe, 0x14, 0xf0, 0xbb, 0x8f, - 0xfe, 0x28, 0xc1, 0xe9, 0xbe, 0x67, 0x02, 0x5a, 0x1b, 0xa4, 0x3b, 0x6b, 0x7c, 0x53, 0xfc, 0x60, - 0x4c, 0x2e, 0x61, 0xf3, 0x2a, 0xb3, 0xf9, 0x06, 0xba, 0x96, 0x61, 0x73, 0xff, 0x03, 0x05, 0xbd, - 0x96, 0x60, 0xae, 0x57, 0x20, 0xba, 0x33, 0x8e, 0xfa, 0xc8, 0xe6, 0xb5, 0xf1, 0x98, 0x84, 0xc9, - 0xdb, 0xcc, 0xe4, 0x2d, 0xf4, 0xf9, 0xc8, 0x26, 0xab, 0x2f, 0xbb, 0xde, 0x0e, 0xfb, 0xfd, 0x24, - 0xe8, 0x77, 0x12, 0xcc, 0x76, 0xcf, 0x1d, 0xd0, 0xea, 0x20, 0xeb, 0x52, 0xc7, 0x29, 0xc5, 0xf2, - 0x38, 0x2c, 0xc2, 0x9d, 0x12, 0x73, 0x67, 0x05, 0x5d, 0x51, 0x33, 0x47, 0x9d, 0xc9, 0x47, 0x05, - 0xfa, 0xa7, 0x04, 0xcb, 0x43, 0x5e, 0x98, 0xa8, 0x32, 0xc8, 0x8e, 0xd1, 0x9e, 0xcb, 0xc5, 0x8d, - 0x43, 0xc9, 0x10, 0xce, 0x7d, 0x97, 0x39, 0xb7, 0x86, 0xca, 0x63, 0xe4, 0x8a, 0x03, 0xd0, 0x3e, - 0xfa, 0xaf, 0x04, 0x8b, 0x03, 0x67, 0x1c, 0xe8, 0xfe, 0x38, 0xf5, 0x93, 0x36, 0x86, 0x29, 0xae, - 0x1f, 0x42, 0x82, 0x70, 0xb1, 0xca, 0x5c, 0xfc, 0x0c, 0x3d, 0x3c, 0x78, 0x39, 0x32, 0x84, 0x8d, - 0x1d, 0xff, 0xb7, 0x04, 0x17, 0x06, 0x0d, 0x4f, 0xd0, 0xbd, 0x71, 0xac, 0x4e, 0x99, 0xe2, 0x14, - 0xef, 0x1f, 0x5c, 0x80, 0xf0, 0xfa, 0x01, 0xf3, 0x7a, 0x1d, 0xdd, 0x3b, 0xa4, 0xd7, 0x0c, 0xb1, - 0x7b, 0x06, 0x07, 0x83, 0x11, 0x3b, 0x7d, 0x08, 0x31, 0x18, 0xb1, 0x33, 0x26, 0x13, 0x43, 0x11, - 0xdb, 0x88, 0xf8, 0xc4, 0x29, 0x8a, 0xfe, 0x23, 0xc1, 0xc2, 0x80, 0xb1, 0x00, 0xfa, 0x78, 0x9c, - 0xc0, 0xa6, 0x00, 0xc8, 0xbd, 0x03, 0xf3, 0x0b, 0x8f, 0xb6, 0x98, 0x47, 0x0f, 0xd0, 0x27, 0x07, - 0xcf, 0x4b, 0x12, 0x6c, 0xfe, 0x24, 0xc1, 0x4c, 0x17, 0x6e, 0xa1, 0xdb, 0x23, 0x43, 0x5c, 0xe4, - 0xd3, 0xea, 0x18, 0x1c, 0xc2, 0x8b, 0x4d, 0xe6, 0xc5, 0xc7, 0xe8, 0x7b, 0xa3, 0x61, 0xa2, 0xfa, - 0x32, 0x65, 0x52, 0xb1, 0x5f, 0x79, 0xfc, 0xe5, 0xdb, 0x25, 0xe9, 0xab, 0xb7, 0x4b, 0xd2, 0xdf, - 0xdf, 0x2e, 0x49, 0xbf, 0x7a, 0xb7, 0x74, 0xec, 0xab, 0x77, 0x4b, 0xc7, 0xfe, 0xf6, 0x6e, 0xe9, - 0xd8, 0x8f, 0x86, 0x5e, 0xe9, 0xda, 0x49, 0x85, 0xec, 0x7e, 0x57, 0xcb, 0xb3, 0xff, 0x91, 0xee, - 0xfc, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x92, 0xc6, 0x90, 0x35, 0x91, 0x1b, 0x00, 0x00, + 0x32, 0x02, 0x5f, 0x7a, 0xe8, 0xad, 0x40, 0x81, 0xf6, 0xda, 0xf3, 0x16, 0xe8, 0xb1, 0x39, 0x15, + 0xe8, 0x7d, 0x7b, 0x5b, 0x64, 0x0f, 0x2d, 0xf6, 0x10, 0x14, 0x49, 0xd1, 0x02, 0x05, 0x7a, 0xed, + 0xb9, 0xe0, 0xcc, 0x50, 0xa4, 0x24, 0x52, 0x0f, 0xc7, 0xbd, 0x89, 0x33, 0xff, 0xfb, 0xf1, 0xcd, + 0xcc, 0x2f, 0xb8, 0x58, 0x33, 0x6a, 0xfb, 0xbb, 0x9e, 0xab, 0xd6, 0xa8, 0x49, 0xa8, 0xf1, 0xcc, + 0x71, 0x6d, 0x75, 0x6f, 0x4d, 0x7d, 0xde, 0xc2, 0xc1, 0x7e, 0xc9, 0x0f, 0x3c, 0xea, 0xa1, 0xd3, + 0x82, 0xa4, 0x14, 0x93, 0x94, 0xf6, 0xd6, 0x8a, 0x0b, 0xb6, 0x67, 0x7b, 0x8c, 0x42, 0x0d, 0x7f, + 0x71, 0xe2, 0xe2, 0x79, 0xdb, 0xf3, 0xec, 0x5d, 0xac, 0x1a, 0xbe, 0xa3, 0x1a, 0xae, 0xeb, 0x51, + 0x83, 0x3a, 0x9e, 0x4b, 0xc4, 0xee, 0x39, 0xd3, 0x23, 0x4d, 0x8f, 0xe8, 0x9c, 0x8d, 0x7f, 0x88, + 0xad, 0x4b, 0xfc, 0x4b, 0x8d, 0x8d, 0xa8, 0x61, 0x6a, 0xac, 0x45, 0xdf, 0x82, 0xea, 0x9a, 0xa0, + 0xaa, 0x19, 0x04, 0x73, 0x23, 0x3b, 0x84, 0xbe, 0x61, 0x3b, 0x2e, 0xd3, 0x26, 0x68, 0x95, 0x74, + 0xd7, 0x7c, 0x23, 0x30, 0x9a, 0x91, 0xd6, 0xcb, 0xe9, 0x34, 0x09, 0x4f, 0x39, 0xdd, 0x4a, 0x86, + 0x2c, 0xcf, 0xe7, 0x04, 0xca, 0x02, 0xa0, 0x1f, 0x86, 0xe6, 0x54, 0x99, 0x74, 0x0d, 0x3f, 0x6f, + 0x61, 0x42, 0x15, 0x0d, 0xde, 0xeb, 0x5a, 0x25, 0xbe, 0xe7, 0x12, 0x8c, 0x3e, 0x84, 0x3c, 0xb7, + 0x42, 0x96, 0x2e, 0x48, 0xab, 0x85, 0xf2, 0x52, 0x29, 0x35, 0xc4, 0x25, 0xce, 0x56, 0xc9, 0x7d, + 0xf5, 0x7a, 0xe5, 0x98, 0x26, 0x58, 0x94, 0xef, 0xc2, 0x62, 0x42, 0x66, 0x65, 0xff, 0x47, 0x38, + 0x20, 0x8e, 0xe7, 0x0a, 0x95, 0x48, 0x86, 0x13, 0x7b, 0x7c, 0x85, 0x09, 0x9f, 0xd5, 0xa2, 0x4f, + 0xe5, 0x0b, 0x38, 0x9f, 0xce, 0x78, 0x14, 0x56, 0xd9, 0xb0, 0xc4, 0x84, 0x7f, 0xea, 0xb8, 0xc6, + 0xae, 0x43, 0xf7, 0xab, 0x81, 0xb7, 0xe7, 0x58, 0x38, 0x88, 0x42, 0x81, 0x3e, 0x05, 0x88, 0x33, + 0x24, 0x34, 0x5c, 0x2e, 0x89, 0x12, 0x08, 0xd3, 0x59, 0xe2, 0x35, 0x27, 0xd2, 0x59, 0xaa, 0x1a, + 0x36, 0x16, 0xbc, 0x5a, 0x82, 0x53, 0xf9, 0x8b, 0x04, 0xcb, 0x59, 0x9a, 0x84, 0x23, 0x3f, 0x03, + 0x54, 0x17, 0x9b, 0x61, 0xa5, 0xf1, 0x5d, 0x59, 0xba, 0x30, 0xb9, 0x5a, 0x28, 0xab, 0x19, 0x4e, + 0xf5, 0x4a, 0x8b, 0x84, 0x69, 0xa7, 0xea, 0xbd, 0x7a, 0xd0, 0xfd, 0x2e, 0x57, 0x26, 0x98, 0x2b, + 0x57, 0x86, 0xba, 0x22, 0xe4, 0x25, 0x7d, 0xd9, 0x10, 0x19, 0xe9, 0x57, 0xce, 0x63, 0x76, 0x11, + 0x66, 0xeb, 0xbe, 0x5e, 0xa3, 0xa6, 0xee, 0x3f, 0xd3, 0x1b, 0xb8, 0xcd, 0xc2, 0x36, 0xad, 0x41, + 0xdd, 0xaf, 0x50, 0xb3, 0xfa, 0xec, 0x01, 0x6e, 0x2b, 0x07, 0x19, 0x71, 0xef, 0x04, 0xe3, 0xa7, + 0x70, 0xaa, 0x2f, 0x18, 0x22, 0xfc, 0x63, 0xc7, 0x62, 0xbe, 0x37, 0x16, 0xca, 0xef, 0x25, 0x28, + 0x32, 0xfd, 0x95, 0x27, 0x9b, 0x5b, 0x78, 0x17, 0xdb, 0xbc, 0xdd, 0x23, 0x07, 0x2a, 0x90, 0x27, + 0xd4, 0xa0, 0x2d, 0x5e, 0x52, 0x73, 0xe5, 0x6b, 0x19, 0x1a, 0xbb, 0xb8, 0x77, 0x18, 0x87, 0x26, + 0x38, 0x7b, 0x0a, 0x67, 0xe2, 0xd0, 0x85, 0xf3, 0x67, 0x49, 0x34, 0x4e, 0xaf, 0xa9, 0x22, 0x50, + 0x4f, 0xe1, 0x64, 0x18, 0x69, 0x2b, 0xde, 0x12, 0x25, 0x73, 0x63, 0x14, 0xa3, 0x3b, 0x31, 0x9a, + 0xab, 0x51, 0x33, 0x21, 0xfe, 0xe8, 0x8a, 0xa5, 0x0e, 0x57, 0x53, 0x33, 0x5d, 0xf5, 0x7e, 0x8e, + 0x83, 0x0d, 0xfa, 0x00, 0x3b, 0x76, 0x83, 0x8e, 0x5e, 0x39, 0xe8, 0x0c, 0xe4, 0x1b, 0x8c, 0x87, + 0x19, 0x95, 0xd3, 0xc4, 0x97, 0xf2, 0x18, 0xae, 0x8d, 0xa2, 0x47, 0x44, 0xed, 0x22, 0xcc, 0xec, + 0x79, 0xd4, 0x71, 0x6d, 0xdd, 0x0f, 0xf7, 0x99, 0x9e, 0x9c, 0x56, 0xe0, 0x6b, 0x8c, 0x45, 0xd9, + 0x86, 0xd5, 0x54, 0x81, 0x9b, 0xad, 0x20, 0xc0, 0x2e, 0x65, 0x44, 0x63, 0x54, 0x7c, 0x56, 0x1c, + 0xba, 0xc5, 0x09, 0xf3, 0x62, 0x27, 0xa5, 0xa4, 0x93, 0x7d, 0x66, 0x4f, 0xf4, 0x9b, 0xfd, 0x2b, + 0x09, 0xae, 0x33, 0x45, 0x1b, 0x26, 0x75, 0xf6, 0x70, 0x1f, 0xdc, 0xf4, 0x86, 0x3c, 0x4b, 0xd5, + 0x51, 0xd5, 0xef, 0x5f, 0x25, 0xb8, 0x31, 0x9a, 0x3d, 0x47, 0x08, 0x83, 0x3f, 0x76, 0x68, 0x63, + 0x1b, 0x53, 0xe3, 0xff, 0x0a, 0x83, 0x4b, 0xa2, 0x31, 0x99, 0x63, 0x06, 0xc5, 0x56, 0x57, 0x60, + 0x95, 0x3b, 0x02, 0x25, 0xfb, 0xb6, 0x07, 0xe7, 0x58, 0xf9, 0xad, 0x04, 0x57, 0x52, 0x2b, 0x25, + 0x05, 0xa8, 0x46, 0xe8, 0x97, 0xa3, 0xca, 0xe3, 0xbf, 0xa4, 0x8c, 0x7e, 0x48, 0x03, 0xa5, 0x00, + 0xce, 0x25, 0x40, 0xc9, 0x0b, 0x52, 0xe0, 0xe9, 0xce, 0x50, 0x78, 0xf2, 0xd2, 0x44, 0x6b, 0x67, + 0x63, 0xa0, 0xea, 0x22, 0x38, 0xba, 0xbc, 0x7e, 0x06, 0xe7, 0xfa, 0x01, 0x37, 0x8a, 0xf8, 0x4d, + 0x78, 0x4f, 0x18, 0xab, 0xd3, 0xb6, 0xde, 0x30, 0x48, 0x23, 0x11, 0xf7, 0x79, 0xb1, 0xf5, 0xa4, + 0xfd, 0xc0, 0x20, 0x8d, 0xb0, 0xeb, 0x9f, 0xa7, 0x9d, 0x33, 0x9d, 0x30, 0xed, 0xc0, 0x5c, 0x37, + 0x76, 0x8b, 0x13, 0x6e, 0x3c, 0xe8, 0x9e, 0xed, 0x82, 0x6e, 0xe5, 0x9b, 0x3c, 0x9c, 0x4e, 0x57, + 0xf7, 0x3d, 0x28, 0x84, 0xc2, 0x70, 0xa0, 0x1b, 0x96, 0xc5, 0x31, 0x6f, 0xba, 0x22, 0xbf, 0x7a, + 0x79, 0x73, 0x41, 0x44, 0x69, 0xc3, 0xb2, 0x02, 0x4c, 0xc8, 0x0e, 0x0d, 0x1c, 0xd7, 0xd6, 0x80, + 0x13, 0x87, 0x8b, 0x68, 0x1b, 0xf2, 0xbc, 0xca, 0x58, 0x60, 0x67, 0x2a, 0x77, 0xbe, 0x7d, 0xbd, + 0x52, 0xb6, 0x1d, 0xda, 0x68, 0xd5, 0x4a, 0xa6, 0xd7, 0x54, 0x85, 0xbd, 0x66, 0xc3, 0x70, 0xdc, + 0xe8, 0x43, 0xa5, 0xfb, 0x3e, 0x26, 0xa5, 0xca, 0xc3, 0xea, 0xed, 0xf5, 0x5b, 0xd5, 0x56, 0xed, + 0x73, 0xbc, 0xaf, 0x1d, 0xaf, 0x85, 0x75, 0x89, 0xbe, 0x80, 0xb9, 0xb8, 0x6e, 0x77, 0x1d, 0x42, + 0xe5, 0xc9, 0x0b, 0x93, 0xef, 0x20, 0xb6, 0x20, 0x0a, 0xfe, 0x91, 0xc3, 0x9a, 0x62, 0x86, 0x50, + 0x23, 0xa0, 0xba, 0x68, 0xaf, 0x1c, 0x07, 0x49, 0xb6, 0xc6, 0x7b, 0x10, 0x2d, 0x01, 0x60, 0xd7, + 0x8a, 0x08, 0x8e, 0x33, 0x82, 0x69, 0xec, 0x8a, 0x16, 0x45, 0x8b, 0x30, 0x4d, 0x3d, 0x6a, 0xec, + 0xea, 0xc4, 0xa0, 0x72, 0x9e, 0xed, 0x4e, 0xb1, 0x85, 0x1d, 0x83, 0xa2, 0x4b, 0x30, 0x97, 0xac, + 0x00, 0xdc, 0x96, 0x4f, 0xb0, 0xe4, 0xcf, 0xc4, 0xc9, 0xc7, 0x6d, 0x74, 0x19, 0x4e, 0x92, 0x5d, + 0x83, 0x34, 0x12, 0x64, 0x53, 0x8c, 0x6c, 0x36, 0x5a, 0xe6, 0x74, 0x1f, 0xc0, 0xd9, 0xb8, 0x4b, + 0xd8, 0x96, 0x4e, 0x1c, 0x9b, 0xd1, 0x4f, 0x33, 0xfa, 0x85, 0xce, 0xf6, 0x4e, 0xb8, 0xbb, 0xe3, + 0xd8, 0x21, 0xdb, 0x53, 0x98, 0x35, 0xbd, 0x3d, 0xec, 0x1a, 0x2e, 0x0d, 0xe9, 0x89, 0x0c, 0xac, + 0xa9, 0x6e, 0x65, 0x14, 0xce, 0xa6, 0xa0, 0xdd, 0xb0, 0x0c, 0x3f, 0x94, 0xe4, 0xd8, 0xae, 0x41, + 0x5b, 0x01, 0x26, 0xda, 0x4c, 0x24, 0x66, 0xc7, 0xb1, 0x09, 0xba, 0x01, 0x28, 0xf2, 0xcd, 0x6b, + 0x51, 0xbf, 0x45, 0x75, 0xc7, 0x6a, 0xcb, 0x05, 0x76, 0x21, 0x8f, 0x8a, 0xfb, 0x31, 0xdb, 0x78, + 0x68, 0xb1, 0xa3, 0xd8, 0x60, 0xa0, 0x2e, 0xcf, 0x5c, 0x90, 0x56, 0xa7, 0x34, 0xf1, 0x85, 0x56, + 0x58, 0x9d, 0xd1, 0x16, 0xd1, 0x2d, 0x4c, 0x4c, 0x79, 0x96, 0x63, 0x12, 0x5f, 0xda, 0xc2, 0xc4, + 0x44, 0xef, 0xc3, 0x5c, 0xcb, 0xad, 0x79, 0xae, 0xc5, 0xa2, 0xe3, 0x34, 0xb1, 0x3c, 0xc7, 0x54, + 0xcc, 0x76, 0x56, 0x9f, 0x38, 0x4d, 0x8c, 0x4c, 0x38, 0xdd, 0x72, 0xe3, 0xe6, 0xd0, 0x03, 0x51, + 0xc8, 0xf2, 0x49, 0xd6, 0x25, 0xa5, 0xec, 0x2e, 0x79, 0x9a, 0x60, 0xeb, 0xf4, 0xc9, 0x42, 0x2b, + 0x65, 0x35, 0xb4, 0x85, 0xbf, 0x05, 0xf4, 0xe8, 0xfd, 0x31, 0xcf, 0x6d, 0xe1, 0xab, 0xe2, 0xb5, + 0xa1, 0xbc, 0x9c, 0x84, 0xb3, 0x19, 0x82, 0xd1, 0x2a, 0xcc, 0x27, 0xdc, 0x69, 0x27, 0x00, 0x21, + 0x76, 0x93, 0x67, 0xfb, 0x23, 0x58, 0x8c, 0xb3, 0x1d, 0xf3, 0x44, 0x19, 0x9f, 0x60, 0x4c, 0x72, + 0x87, 0xe4, 0x69, 0x44, 0x21, 0xb2, 0x6e, 0xc2, 0x62, 0x27, 0xeb, 0xdd, 0xdc, 0x9d, 0x1e, 0x2a, + 0x94, 0x2f, 0x65, 0x84, 0xa5, 0x93, 0xf4, 0x87, 0x6e, 0xdd, 0xd3, 0xe4, 0x48, 0x50, 0x52, 0x07, + 0x6b, 0x9f, 0x94, 0xca, 0xcd, 0xa5, 0x55, 0xee, 0x87, 0x50, 0xec, 0xa9, 0xdc, 0xa4, 0x2b, 0xc7, + 0x19, 0xcb, 0xd9, 0xee, 0xe2, 0x8d, 0x3d, 0xa9, 0xc3, 0x99, 0xb8, 0x7e, 0x13, 0xbc, 0x44, 0xce, + 0x1f, 0xb2, 0x90, 0x17, 0x3a, 0x85, 0x1c, 0x6b, 0x22, 0x8a, 0x09, 0x2b, 0x43, 0x0e, 0x14, 0x74, + 0x0f, 0x72, 0x16, 0xde, 0x3d, 0xdc, 0xad, 0x99, 0x71, 0x2a, 0x5f, 0xe6, 0x40, 0xce, 0x7c, 0xc8, + 0x7c, 0x02, 0x85, 0xb0, 0x0b, 0x02, 0xc7, 0x4f, 0x00, 0xfc, 0x77, 0xa2, 0x73, 0x29, 0xd6, 0xc0, + 0x0f, 0xa5, 0xad, 0x98, 0x54, 0x4b, 0xf2, 0xa1, 0x6d, 0x00, 0xd3, 0x6b, 0x36, 0x1d, 0x42, 0xa2, + 0xd3, 0x6d, 0xba, 0x72, 0xf3, 0xdb, 0xd7, 0x2b, 0x8b, 0x5c, 0x10, 0xb1, 0x9e, 0x95, 0x1c, 0x4f, + 0x6d, 0x1a, 0xb4, 0x51, 0x7a, 0x84, 0x6d, 0xc3, 0xdc, 0xdf, 0xc2, 0xe6, 0xab, 0x97, 0x37, 0x41, + 0xe8, 0xd9, 0xc2, 0xa6, 0x96, 0x10, 0x80, 0x6e, 0x40, 0x8e, 0x9d, 0x01, 0x93, 0x43, 0xce, 0x00, + 0x46, 0x95, 0x40, 0xff, 0xdc, 0x51, 0xa0, 0xff, 0x47, 0x30, 0xe9, 0x7b, 0x3e, 0x2b, 0x91, 0x42, + 0xf9, 0x7a, 0xd6, 0x73, 0x3d, 0xf0, 0xbc, 0xfa, 0xe3, 0x7a, 0xd5, 0x23, 0x04, 0x33, 0x9b, 0x2b, + 0x4f, 0x36, 0xb5, 0x90, 0x0f, 0xad, 0xc3, 0x19, 0x56, 0x32, 0xd8, 0xd2, 0x05, 0x6b, 0x04, 0xe4, + 0x1c, 0xaa, 0x17, 0xc4, 0x6e, 0x85, 0x6f, 0x0a, 0x4c, 0x0f, 0xa1, 0x2d, 0xe2, 0xa2, 0x66, 0xc4, + 0x71, 0x82, 0x71, 0xcc, 0x47, 0x1c, 0xd4, 0x14, 0xd4, 0xf1, 0xe5, 0x6c, 0x6a, 0xe0, 0x05, 0x7c, + 0xba, 0xef, 0x02, 0x8e, 0x8a, 0x30, 0xe5, 0xb8, 0x02, 0x17, 0x81, 0xe1, 0x62, 0xe7, 0xbb, 0xfc, + 0xbb, 0x53, 0x70, 0x9c, 0xdd, 0x07, 0xd0, 0x2f, 0x25, 0xc8, 0xf3, 0x89, 0x04, 0xba, 0x9a, 0x11, + 0x81, 0xfe, 0xc1, 0x4c, 0xf1, 0xda, 0x28, 0xa4, 0xbc, 0xf0, 0x94, 0xf7, 0x7f, 0xf1, 0xcd, 0x3f, + 0x7e, 0x33, 0xb1, 0x82, 0x96, 0xd4, 0x41, 0x03, 0x25, 0xf4, 0x07, 0x09, 0x4e, 0xf6, 0x8c, 0x56, + 0x50, 0x79, 0xb8, 0x9a, 0xde, 0x01, 0x4e, 0xf1, 0xf6, 0x58, 0x3c, 0xc2, 0x46, 0x95, 0xd9, 0x78, + 0x15, 0x5d, 0x19, 0x68, 0xa3, 0xfa, 0x42, 0x40, 0xf3, 0x01, 0xfa, 0xa3, 0x04, 0xa7, 0xfa, 0x9e, + 0x10, 0x68, 0x7d, 0x90, 0xee, 0xac, 0xd1, 0x4e, 0xf1, 0x83, 0x31, 0xb9, 0x84, 0xcd, 0x6b, 0xcc, + 0xe6, 0xeb, 0xe8, 0x6a, 0x86, 0xcd, 0xfd, 0x8f, 0x17, 0xf4, 0x4a, 0x82, 0xf9, 0x5e, 0x81, 0xe8, + 0xf6, 0x38, 0xea, 0x23, 0x9b, 0xd7, 0xc7, 0x63, 0x12, 0x26, 0xef, 0x30, 0x93, 0xb7, 0xd1, 0xe7, + 0x23, 0x9b, 0xac, 0xbe, 0xe8, 0x7a, 0x57, 0x1c, 0xf4, 0x93, 0xa0, 0x2f, 0x25, 0x98, 0xeb, 0x9e, + 0x49, 0xa0, 0xb5, 0x41, 0xd6, 0xa5, 0x8e, 0x5a, 0x8a, 0xe5, 0x71, 0x58, 0x84, 0x3b, 0x25, 0xe6, + 0xce, 0x2a, 0xba, 0xac, 0x66, 0x8e, 0x41, 0x93, 0x0f, 0x0e, 0xf4, 0x4f, 0x09, 0x56, 0x86, 0xbc, + 0x3e, 0x51, 0x65, 0x90, 0x1d, 0xa3, 0x3d, 0xa5, 0x8b, 0x9b, 0xef, 0x24, 0x43, 0x38, 0xf7, 0x7d, + 0xe6, 0xdc, 0x3a, 0x2a, 0x8f, 0x91, 0x2b, 0x0e, 0x4e, 0x07, 0xe8, 0xbf, 0x12, 0x2c, 0x0d, 0x9c, + 0x7f, 0xa0, 0x7b, 0xe3, 0xd4, 0x4f, 0xda, 0x88, 0xa6, 0xb8, 0xf1, 0x0e, 0x12, 0x84, 0x8b, 0x55, + 0xe6, 0xe2, 0x67, 0xe8, 0xc1, 0xe1, 0xcb, 0x91, 0xa1, 0x6f, 0xec, 0xf8, 0xbf, 0x25, 0x38, 0x3f, + 0x68, 0xb0, 0x82, 0xee, 0x8e, 0x63, 0x75, 0xca, 0x84, 0xa7, 0x78, 0xef, 0xf0, 0x02, 0x84, 0xd7, + 0xf7, 0x99, 0xd7, 0x1b, 0xe8, 0xee, 0x3b, 0x7a, 0xcd, 0x10, 0xbb, 0x67, 0xa8, 0x30, 0x18, 0xb1, + 0xd3, 0x07, 0x14, 0x83, 0x11, 0x3b, 0x63, 0x6a, 0x31, 0x14, 0xb1, 0x8d, 0x88, 0x4f, 0x9c, 0xb0, + 0xe8, 0x3f, 0x12, 0x2c, 0x0e, 0x18, 0x19, 0xa0, 0x8f, 0xc7, 0x09, 0x6c, 0x0a, 0x80, 0xdc, 0x3d, + 0x34, 0xbf, 0xf0, 0x68, 0x9b, 0x79, 0x74, 0x1f, 0x7d, 0x72, 0xf8, 0xbc, 0x24, 0xc1, 0xe6, 0x4f, + 0x12, 0xcc, 0x76, 0xe1, 0x16, 0xba, 0x35, 0x32, 0xc4, 0x45, 0x3e, 0xad, 0x8d, 0xc1, 0x21, 0xbc, + 0xd8, 0x62, 0x5e, 0x7c, 0x8c, 0x7e, 0x30, 0x1a, 0x26, 0xaa, 0x2f, 0x52, 0xa6, 0x18, 0x07, 0x95, + 0x47, 0x5f, 0xbd, 0x59, 0x96, 0xbe, 0x7e, 0xb3, 0x2c, 0xfd, 0xfd, 0xcd, 0xb2, 0xf4, 0xeb, 0xb7, + 0xcb, 0xc7, 0xbe, 0x7e, 0xbb, 0x7c, 0xec, 0x6f, 0x6f, 0x97, 0x8f, 0xfd, 0x64, 0xe8, 0x75, 0xaf, + 0x9d, 0x54, 0xc8, 0xee, 0x7e, 0xb5, 0x3c, 0xfb, 0x8f, 0xe9, 0xf6, 0xff, 0x02, 0x00, 0x00, 0xff, + 0xff, 0x9d, 0x96, 0x10, 0xe8, 0xad, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3269,6 +3279,16 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l + if m.Inactive { + i-- + if m.Inactive { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } if m.VotingPower != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.VotingPower)) i-- @@ -3828,6 +3848,9 @@ func (m *FinalityProviderResponse) Size() (n int) { if m.VotingPower != 0 { n += 1 + sovQuery(uint64(m.VotingPower)) } + if m.Inactive { + n += 2 + } return n } @@ -6905,6 +6928,26 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Inactive = bool(v != 0) default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/finality/abci.go b/x/finality/abci.go index facf59d75..f69fac165 100644 --- a/x/finality/abci.go +++ b/x/finality/abci.go @@ -4,10 +4,12 @@ import ( "context" "time" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/x/finality/keeper" + "github.com/babylonchain/babylon/x/finality/types" ) func BeginBlocker(ctx context.Context, k keeper.Keeper) error { @@ -25,6 +27,17 @@ func EndBlocker(ctx context.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, e k.IndexBlock(ctx) // tally all non-finalised blocks k.TallyBlocks(ctx) + + // detect inactive finality providers if there are any + // heightToExamine is determined by the current height - params.FinalitySigTimeout + // which indicates that finality providers have up to `params.FinalitySigTimeout` blocks + // to send votes on the height to be examined as whether `missed` or not (1 or 0 of a + // bit in a bit array of size params.SignedBlocksWindow) + // once this height is judged as `missed`, the judgement is irreversible + heightToExamine := sdk.UnwrapSDKContext(ctx).HeaderInfo().Height - k.GetParams(ctx).FinalitySigTimeout + if heightToExamine >= 1 { + k.HandleLiveness(ctx, heightToExamine) + } } return []abci.ValidatorUpdate{}, nil diff --git a/x/finality/keeper/hooks.go b/x/finality/keeper/hooks.go new file mode 100644 index 000000000..8d18422c7 --- /dev/null +++ b/x/finality/keeper/hooks.go @@ -0,0 +1,41 @@ +package keeper + +import ( + "context" + "errors" + + "cosmossdk.io/collections" + sdk "github.com/cosmos/cosmos-sdk/types" + + bbntypes "github.com/babylonchain/babylon/types" + "github.com/babylonchain/babylon/x/finality/types" +) + +var _ types.BtcStakingHooks = Hooks{} + +// Hooks wrapper struct for finality keeper +type Hooks struct { + k Keeper +} + +// Return the BTC staking hooks +func (k Keeper) Hooks() Hooks { + return Hooks{k} +} + +// AfterFinalityProviderActivated updates the signing info start height or create a new signing info +func (h Hooks) AfterFinalityProviderActivated(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { + signingInfo, err := h.k.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + sdkCtx := sdk.UnwrapSDKContext(ctx) + if err == nil { + signingInfo.StartHeight = sdkCtx.BlockHeight() + } else if errors.Is(err, collections.ErrNotFound) { + signingInfo = types.NewFinalityProviderSigningInfo( + fpPk, + sdkCtx.BlockHeight(), + 0, + ) + } + + return h.k.FinalityProviderSigningTracker.Set(ctx, fpPk.MustMarshal(), signingInfo) +} diff --git a/x/finality/keeper/keeper.go b/x/finality/keeper/keeper.go index 590d54eee..8b131d070 100644 --- a/x/finality/keeper/keeper.go +++ b/x/finality/keeper/keeper.go @@ -4,8 +4,8 @@ import ( "context" "fmt" + "cosmossdk.io/collections" corestoretypes "cosmossdk.io/core/store" - "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -23,24 +23,57 @@ type ( // the address capable of executing a MsgUpdateParams message. Typically, this // should be the x/gov module account. authority string + + hooks types.FinalityHooks + + // FinalityProviderSigningTracker key: BIP340PubKey bytes | value: FinalityProviderSigningInfo + FinalityProviderSigningTracker collections.Map[[]byte, types.FinalityProviderSigningInfo] + // FinalityProviderMissedBlockBitmap key: BIP340PubKey bytes | value: byte key for a finality provider's missed block bitmap chunk + FinalityProviderMissedBlockBitmap collections.Map[collections.Pair[[]byte, uint64], []byte] } ) func NewKeeper( cdc codec.BinaryCodec, storeService corestoretypes.KVStoreService, - btctakingKeeper types.BTCStakingKeeper, + btcstakingKeeper types.BTCStakingKeeper, incentiveKeeper types.IncentiveKeeper, authority string, ) Keeper { + sb := collections.NewSchemaBuilder(storeService) return Keeper{ cdc: cdc, storeService: storeService, - BTCStakingKeeper: btctakingKeeper, + BTCStakingKeeper: btcstakingKeeper, IncentiveKeeper: incentiveKeeper, authority: authority, + FinalityProviderSigningTracker: collections.NewMap( + sb, + types.FinalityProviderSigningInfoKeyPrefix, + "finality_provider_signing_info", + collections.BytesKey, + codec.CollValue[types.FinalityProviderSigningInfo](cdc), + ), + FinalityProviderMissedBlockBitmap: collections.NewMap( + sb, + types.FinalityProviderMissedBlockBitmapKeyPrefix, + "finality_provider_missed_block_bitmap", + collections.PairKeyCodec(collections.BytesKey, collections.Uint64Key), + collections.BytesValue, + ), + } +} + +// SetHooks sets the finality hooks +func (k *Keeper) SetHooks(sh types.FinalityHooks) *Keeper { + if k.hooks != nil { + panic("cannot set finality hooks twice") } + + k.hooks = sh + + return k } func (k Keeper) Logger(ctx sdk.Context) log.Logger { diff --git a/x/finality/keeper/liveness.go b/x/finality/keeper/liveness.go new file mode 100644 index 000000000..f4da183e0 --- /dev/null +++ b/x/finality/keeper/liveness.go @@ -0,0 +1,187 @@ +package keeper + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/babylonchain/babylon/types" + finalitytypes "github.com/babylonchain/babylon/x/finality/types" +) + +// HandleLiveness handles liveness of each active finality provider for a given height +// including identifying inactive finality providers and applying punishment +func (k Keeper) HandleLiveness(ctx context.Context, height int64) { + // get all the active finality providers for the height + fpSet := k.BTCStakingKeeper.GetVotingPowerTable(ctx, uint64(height)) + // get all the voters for the height + voterBTCPKs := k.GetVoters(ctx, uint64(height)) + + // Iterate over all the finality providers which *should* have signed this block + // store whether or not they have actually signed it, identify inactive + // ones, and apply punishment + for fpPkHex := range fpSet { + fpPk, err := types.NewBIP340PubKeyFromHex(fpPkHex) + if err != nil { + panic(fmt.Errorf("invalid finality provider public key %s: %w", fpPkHex, err)) + } + + _, ok := voterBTCPKs[fpPkHex] + missed := !ok + + err = k.HandleFinalityProviderLiveness(ctx, fpPk, missed, height) + if err != nil { + panic(fmt.Errorf("failed to handle liveness of finality provider %s: %w", fpPkHex, err)) + } + } +} + +// HandleFinalityProviderLiveness updates the voting history of the given finality provider and +// detect inactive the finality provider if the number of missed block is reached to the threshold in a +// sliding window +func (k Keeper) HandleFinalityProviderLiveness(ctx context.Context, fpPk *types.BIP340PubKey, missed bool, height int64) error { + params := k.GetParams(ctx) + fp, err := k.BTCStakingKeeper.GetFinalityProvider(ctx, fpPk.MustMarshal()) + if err != nil { + return err + } + + // don't update missed blocks when finality provider is already detected slashed + if fp.IsSlashed() { + return nil + } + + updated, signInfo, err := k.updateSigningInfo(ctx, fpPk, missed, height) + if err != nil { + return err + } + + signedBlocksWindow := params.SignedBlocksWindow + minSignedPerWindow := params.MinSignedPerWindowInt() + + sdkCtx := sdk.UnwrapSDKContext(ctx) + if missed { + // TODO emit event + + k.Logger(sdkCtx).Debug( + "absent finality provider", + "height", height, + "public_key", fpPk.MarshalHex(), + "missed", signInfo.MissedBlocksCounter, + "threshold", minSignedPerWindow, + ) + } + + minHeight := signInfo.StartHeight + signedBlocksWindow + maxMissed := signedBlocksWindow - minSignedPerWindow + + // if we are past the minimum height and the finality provider has missed too many blocks, punish them + if height > minHeight && signInfo.MissedBlocksCounter > maxMissed { + updated = true + // TODO emit event + + // Inactivity detected + err = k.hooks.AfterInactiveFinalityProviderDetected(ctx, fpPk) + if err != nil { + return err + } + + k.Logger(sdkCtx).Info( + "detected inactive finality provider", + "height", height, + "public_key", fpPk.MarshalHex(), + ) + } else if fp.IsInactive() { + updated = true + // TODO emit event + + // change the Inactive flag of the finality provider to false + err = k.BTCStakingKeeper.RevertInactiveFinalityProvider(ctx, fpPk.MustMarshal()) + if err != nil { + return fmt.Errorf("failed to revert inactive finality provider %s: %w", fpPk.MarshalHex(), err) + } + + k.Logger(sdkCtx).Info( + "reverted inactive finality provider", + "height", height, + "public_key", fpPk.MarshalHex(), + ) + } + + // Set the updated signing info + if updated { + return k.FinalityProviderSigningTracker.Set(ctx, fpPk.MustMarshal(), *signInfo) + } + + return nil +} + +func (k Keeper) updateSigningInfo( + ctx context.Context, + fpPk *types.BIP340PubKey, + missed bool, + height int64, +) (bool, *finalitytypes.FinalityProviderSigningInfo, error) { + params := k.GetParams(ctx) + // fetch signing info + signInfo, err := k.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + if err != nil { + return false, nil, err + } + + signedBlocksWindow := params.SignedBlocksWindow + + // Compute the relative index, so we count the blocks the finality provider *should* + // have signed. We will also use the 0-value default signing info if not present. + // The index is in the range [0, SignedBlocksWindow) + // and is used to see if a finality provider signed a block at the given height, which + // is represented by a bit in the bitmap. + // The finality provider start height should get mapped to index 0, so we computed index as: + // (height - startHeight) % signedBlocksWindow + // + // NOTE: There is subtle different behavior between genesis finality provider and non-genesis + // finality providers. + // A genesis finality provider will start at index 0, whereas a non-genesis finality provider's + // startHeight will be the block they become active for, but the first block they vote on will be + // one later. (And thus their first vote is at index 1) + if signInfo.StartHeight > height { + return false, nil, fmt.Errorf("invalid state, the finality provider signing info has start height %d, which is greater than the current height %d", + signInfo.StartHeight, height) + } + index := (height - signInfo.StartHeight) % signedBlocksWindow + + // determine if the finality provider signed the previous block + previous, err := k.GetMissedBlockBitmapValue(ctx, fpPk, index) + if err != nil { + return false, nil, fmt.Errorf("failed to get the finality provider's bitmap value: %w", err) + } + + modifiedSignInfo := false + switch { + case !previous && missed: + // Bitmap value has changed from not missed to missed, so we flip the bit + // and increment the counter. + if err := k.SetMissedBlockBitmapValue(ctx, fpPk, index, true); err != nil { + return false, nil, err + } + + signInfo.IncrementMissedBlocksCounter() + modifiedSignInfo = true + + case previous && !missed: + // Bitmap value has changed from missed to not missed, so we flip the bit + // and decrement the counter. + if err := k.SetMissedBlockBitmapValue(ctx, fpPk, index, false); err != nil { + return false, nil, err + } + + signInfo.DecrementMissedBlocksCounter() + modifiedSignInfo = true + + default: + // bitmap value at this index has not changed, no need to update counter + } + + return modifiedSignInfo, &signInfo, nil +} diff --git a/x/finality/keeper/liveness_test.go b/x/finality/keeper/liveness_test.go new file mode 100644 index 000000000..4f110b442 --- /dev/null +++ b/x/finality/keeper/liveness_test.go @@ -0,0 +1,90 @@ +package keeper_test + +import ( + "math/rand" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/testutil/datagen" + keepertest "github.com/babylonchain/babylon/testutil/keeper" + bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonchain/babylon/x/finality/types" +) + +func FuzzHandleLiveness(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + bsKeeper := types.NewMockBTCStakingKeeper(ctrl) + bsKeeper.EXPECT().GetParams(gomock.Any()).Return(bstypes.Params{MaxActiveFinalityProviders: 100}).AnyTimes() + iKeeper := types.NewMockIncentiveKeeper(ctrl) + fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) + + mockedHooks := types.NewMockFinalityHooks(ctrl) + mockedHooks.EXPECT().AfterInactiveFinalityProviderDetected(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + fKeeper.SetHooks(mockedHooks) + + params := fKeeper.GetParams(ctx) + fpPk, err := datagen.GenRandomBIP340PubKey(r) + require.NoError(t, err) + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(&bstypes.FinalityProvider{Inactive: false}, nil).AnyTimes() + signingInfo := types.NewFinalityProviderSigningInfo( + fpPk, + 1, + 0, + ) + err = fKeeper.FinalityProviderSigningTracker.Set(ctx, fpPk.MustMarshal(), signingInfo) + require.NoError(t, err) + + // activate BTC staking protocol at a random height + activatedHeight := int64(datagen.RandomInt(r, 10) + 1) + + // for signed blocks, mark the finality provider as having signed + height := activatedHeight + for ; height < activatedHeight+params.SignedBlocksWindow; height++ { + err := fKeeper.HandleFinalityProviderLiveness(ctx, fpPk, false, height) + require.NoError(t, err) + } + signingInfo, err = fKeeper.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + require.NoError(t, err) + require.Equal(t, int64(0), signingInfo.MissedBlocksCounter) + + minSignedPerWindow := params.MinSignedPerWindowInt() + maxMissed := params.SignedBlocksWindow - minSignedPerWindow + // for blocks up to the inactivity boundary, mark the finality provider as having not signed + inactiveDetectedHeight := height + maxMissed + 1 + for ; height < inactiveDetectedHeight; height++ { + err := fKeeper.HandleFinalityProviderLiveness(ctx, fpPk, true, height) + require.NoError(t, err) + signingInfo, err = fKeeper.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + require.NoError(t, err) + if height < inactiveDetectedHeight-1 { + require.GreaterOrEqual(t, maxMissed, signingInfo.MissedBlocksCounter) + } else { + require.Less(t, maxMissed, signingInfo.MissedBlocksCounter) + } + } + + // perform heights that not missed, expect the inactive is reverted + bsKeeper.EXPECT().RevertInactiveFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(nil).AnyTimes() + inactiveRevertedHeight := height + maxMissed + for ; height < inactiveRevertedHeight; height++ { + err := fKeeper.HandleFinalityProviderLiveness(ctx, fpPk, false, height) + require.NoError(t, err) + signingInfo, err = fKeeper.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + require.NoError(t, err) + if height < inactiveRevertedHeight-1 { + require.Less(t, maxMissed, signingInfo.MissedBlocksCounter) + } else { + // the inactive fp is reverted + require.Equal(t, maxMissed, signingInfo.MissedBlocksCounter) + } + } + }) +} diff --git a/x/finality/keeper/params.go b/x/finality/keeper/params.go index 2b0d78a79..15241fefc 100644 --- a/x/finality/keeper/params.go +++ b/x/finality/keeper/params.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "github.com/babylonchain/babylon/x/finality/types" ) diff --git a/x/finality/keeper/signing_info.go b/x/finality/keeper/signing_info.go new file mode 100644 index 000000000..262687a13 --- /dev/null +++ b/x/finality/keeper/signing_info.go @@ -0,0 +1,103 @@ +package keeper + +import ( + "context" + "errors" + + "cosmossdk.io/collections" + errorsmod "cosmossdk.io/errors" + "github.com/bits-and-blooms/bitset" + "github.com/cosmos/cosmos-sdk/x/slashing/types" + + bbntypes "github.com/babylonchain/babylon/types" + finalitytypes "github.com/babylonchain/babylon/x/finality/types" +) + +// GetMissedBlockBitmapValue returns true if a finality provider missed signing +// a block at the given index and false otherwise. The index provided is assumed +// to be the index in the range [0, SignedBlocksWindow), which represents the bitmap +// where each bit represents a height, and is determined by the finality provider's +// IndexOffset modulo SignedBlocksWindow. This index is used to fetch the chunk +// in the bitmap and the relative bit in that chunk. +func (k Keeper) GetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BIP340PubKey, index int64) (bool, error) { + // get the chunk or "word" in the logical bitmap + chunkIndex := index / finalitytypes.MissedBlockBitmapChunkSize + + bs := bitset.New(uint(finalitytypes.MissedBlockBitmapChunkSize)) + chunk, err := k.getMissedBlockBitmapChunk(ctx, fpPk, chunkIndex) + if err != nil { + return false, errorsmod.Wrapf(err, "failed to get bitmap chunk; index: %d", index) + } + + if chunk != nil { + if err := bs.UnmarshalBinary(chunk); err != nil { + return false, errorsmod.Wrapf(err, "failed to decode bitmap chunk; index: %d", index) + } + } + + // get the bit position in the chunk of the logical bitmap, where Test() + // checks if the bit is set. + bitIndex := index % types.MissedBlockBitmapChunkSize + return bs.Test(uint(bitIndex)), nil +} + +// SetMissedBlockBitmapValue sets, i.e. flips, a bit in the validator's missed +// block bitmap. When missed=true, the bit is set, otherwise it set to zero. The +// index provided is assumed to be the index in the range [0, SignedBlocksWindow), +// which represents the bitmap where each bit represents a height, and is +// determined by the validator's IndexOffset modulo SignedBlocksWindow. This +// index is used to fetch the chunk in the bitmap and the relative bit in that +// chunk. +func (k Keeper) SetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BIP340PubKey, index int64, missed bool) error { + // get the chunk or "word" in the logical bitmap + chunkIndex := index / types.MissedBlockBitmapChunkSize + + bs := bitset.New(uint(types.MissedBlockBitmapChunkSize)) + chunk, err := k.getMissedBlockBitmapChunk(ctx, fpPk, chunkIndex) + if err != nil { + return errorsmod.Wrapf(err, "failed to get bitmap chunk; index: %d", index) + } + + if chunk != nil { + if err := bs.UnmarshalBinary(chunk); err != nil { + return errorsmod.Wrapf(err, "failed to decode bitmap chunk; index: %d", index) + } + } + + // get the bit position in the chunk of the logical bitmap + bitIndex := uint(index % types.MissedBlockBitmapChunkSize) + if missed { + bs.Set(bitIndex) + } else { + bs.Clear(bitIndex) + } + + updatedChunk, err := bs.MarshalBinary() + if err != nil { + return errorsmod.Wrapf(err, "failed to encode bitmap chunk; index: %d", index) + } + + return k.SetMissedBlockBitmapChunk(ctx, fpPk, chunkIndex, updatedChunk) +} + +// DeleteMissedBlockBitmap removes a validator's missed block bitmap from state. +func (k Keeper) DeleteMissedBlockBitmap(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { + rng := collections.NewPrefixedPairRange[[]byte, uint64](fpPk.MustMarshal()) + return k.FinalityProviderMissedBlockBitmap.Clear(ctx, rng) +} + +// SetMissedBlockBitmapChunk sets the bitmap chunk at the given chunk index for +// a validator's missed block signing window. +func (k Keeper) SetMissedBlockBitmapChunk(ctx context.Context, fpPk *bbntypes.BIP340PubKey, chunkIndex int64, chunk []byte) error { + return k.FinalityProviderMissedBlockBitmap.Set(ctx, collections.Join(fpPk.MustMarshal(), uint64(chunkIndex)), chunk) +} + +// getMissedBlockBitmapChunk gets the bitmap chunk at the given chunk index for +// a finality provider's missed block signing window. +func (k Keeper) getMissedBlockBitmapChunk(ctx context.Context, fpPk *bbntypes.BIP340PubKey, chunkIndex int64) ([]byte, error) { + chunk, err := k.FinalityProviderMissedBlockBitmap.Get(ctx, collections.Join(fpPk.MustMarshal(), uint64(chunkIndex))) + if err != nil && !errors.Is(err, collections.ErrNotFound) { + return nil, err + } + return chunk, nil +} diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index cbf8d2072..291683a28 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -3,6 +3,7 @@ package types import ( "context" + bbn "github.com/babylonchain/babylon/types" bstypes "github.com/babylonchain/babylon/x/btcstaking/types" ) @@ -17,9 +18,18 @@ type BTCStakingKeeper interface { GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) RemoveVotingPowerDistCache(ctx context.Context, height uint64) GetLastFinalizedEpoch(ctx context.Context) uint64 + RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error } // IncentiveKeeper defines the expected interface needed to distribute rewards. type IncentiveKeeper interface { RewardBTCStaking(ctx context.Context, height uint64, filteredDc *bstypes.VotingPowerDistCache) } + +type BtcStakingHooks interface { + AfterFinalityProviderActivated(ctx context.Context, btcPk *bbn.BIP340PubKey) error +} + +type FinalityHooks interface { + AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *bbn.BIP340PubKey) error +} diff --git a/x/finality/types/finality.pb.go b/x/finality/types/finality.pb.go index 952152352..466fe2bd9 100644 --- a/x/finality/types/finality.pb.go +++ b/x/finality/types/finality.pb.go @@ -233,10 +233,70 @@ func (m *Evidence) GetForkAppHash() []byte { return nil } +// FinalityProviderSigningInfo defines a finality provider's signing info for monitoring their +// liveness activity. +type FinalityProviderSigningInfo struct { + // fp_btc_pk is the BTC PK of the finality provider that casts this vote + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // start_height is the block height at which finality provider become active + StartHeight int64 `protobuf:"varint,2,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + // missed_blocks_counter defines a counter to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + MissedBlocksCounter int64 `protobuf:"varint,3,opt,name=missed_blocks_counter,json=missedBlocksCounter,proto3" json:"missed_blocks_counter,omitempty"` +} + +func (m *FinalityProviderSigningInfo) Reset() { *m = FinalityProviderSigningInfo{} } +func (m *FinalityProviderSigningInfo) String() string { return proto.CompactTextString(m) } +func (*FinalityProviderSigningInfo) ProtoMessage() {} +func (*FinalityProviderSigningInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_ca5b87e52e3e6d02, []int{3} +} +func (m *FinalityProviderSigningInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FinalityProviderSigningInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FinalityProviderSigningInfo.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 *FinalityProviderSigningInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinalityProviderSigningInfo.Merge(m, src) +} +func (m *FinalityProviderSigningInfo) XXX_Size() int { + return m.Size() +} +func (m *FinalityProviderSigningInfo) XXX_DiscardUnknown() { + xxx_messageInfo_FinalityProviderSigningInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_FinalityProviderSigningInfo proto.InternalMessageInfo + +func (m *FinalityProviderSigningInfo) GetStartHeight() int64 { + if m != nil { + return m.StartHeight + } + return 0 +} + +func (m *FinalityProviderSigningInfo) GetMissedBlocksCounter() int64 { + if m != nil { + return m.MissedBlocksCounter + } + return 0 +} + func init() { proto.RegisterType((*IndexedBlock)(nil), "babylon.finality.v1.IndexedBlock") proto.RegisterType((*PubRandCommit)(nil), "babylon.finality.v1.PubRandCommit") proto.RegisterType((*Evidence)(nil), "babylon.finality.v1.Evidence") + proto.RegisterType((*FinalityProviderSigningInfo)(nil), "babylon.finality.v1.FinalityProviderSigningInfo") } func init() { @@ -244,37 +304,41 @@ func init() { } var fileDescriptor_ca5b87e52e3e6d02 = []byte{ - // 474 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x93, 0x41, 0x6f, 0xd3, 0x30, - 0x14, 0xc7, 0x1b, 0x56, 0xda, 0xee, 0x35, 0x13, 0x10, 0xa6, 0xa9, 0x20, 0x94, 0x95, 0x9e, 0x7a, - 0x40, 0xcd, 0xc6, 0x26, 0xc4, 0x95, 0xa0, 0xa1, 0x0d, 0x0e, 0x54, 0x0e, 0x27, 0x2e, 0x91, 0xe3, - 0xb8, 0x89, 0xd5, 0xc6, 0xb6, 0x12, 0xa7, 0x5a, 0xf9, 0x14, 0x7c, 0x2c, 0x8e, 0x3b, 0xa2, 0x1d, - 0x26, 0xd4, 0x7e, 0x0f, 0x84, 0xe2, 0xba, 0xe9, 0x76, 0x02, 0xb1, 0x9b, 0xfd, 0xf7, 0xd3, 0xff, - 0xf7, 0xfe, 0xcf, 0x36, 0x0c, 0x22, 0x1c, 0x2d, 0x66, 0x82, 0x7b, 0x13, 0xc6, 0xf1, 0x8c, 0xa9, - 0x85, 0x37, 0x3f, 0xae, 0xd7, 0x23, 0x99, 0x0b, 0x25, 0x9c, 0xa7, 0xa6, 0x66, 0x54, 0xeb, 0xf3, - 0xe3, 0xe7, 0xfb, 0x89, 0x48, 0x84, 0x3e, 0xf7, 0xaa, 0xd5, 0xba, 0x74, 0x10, 0x82, 0x7d, 0xc1, - 0x63, 0x7a, 0x49, 0x63, 0x7f, 0x26, 0xc8, 0xd4, 0x39, 0x80, 0x56, 0x4a, 0x59, 0x92, 0xaa, 0x9e, - 0xd5, 0xb7, 0x86, 0x4d, 0x64, 0x76, 0xce, 0x33, 0xe8, 0x60, 0x29, 0xc3, 0x14, 0x17, 0x69, 0xef, - 0x41, 0xdf, 0x1a, 0xda, 0xa8, 0x8d, 0xa5, 0x3c, 0xc7, 0x45, 0xea, 0xbc, 0x80, 0xdd, 0x35, 0xe7, - 0x1b, 0x8d, 0x7b, 0x3b, 0x7d, 0x6b, 0xd8, 0x41, 0x5b, 0x61, 0xa0, 0x60, 0x6f, 0x5c, 0x46, 0x08, - 0xf3, 0xf8, 0xbd, 0xc8, 0x32, 0xa6, 0x9c, 0x97, 0x60, 0x17, 0x0a, 0xe7, 0x2a, 0xbc, 0xc3, 0xe9, - 0x6a, 0xed, 0x7c, 0x0d, 0xeb, 0x83, 0xcd, 0xcb, 0x2c, 0x94, 0x65, 0x14, 0xe6, 0x98, 0xc7, 0x1a, - 0xd8, 0x44, 0xc0, 0xcb, 0xcc, 0x58, 0x39, 0x2e, 0x00, 0xd1, 0x76, 0x19, 0xe5, 0x4a, 0x43, 0x6d, - 0x74, 0x4b, 0x19, 0xfc, 0xde, 0x81, 0xce, 0xd9, 0x9c, 0xc5, 0x94, 0x13, 0xea, 0x20, 0xd8, 0x9d, - 0xc8, 0x30, 0x52, 0x24, 0x94, 0x53, 0x8d, 0xb3, 0xfd, 0x37, 0xd7, 0x37, 0x87, 0xaf, 0x13, 0xa6, - 0xd2, 0x32, 0x1a, 0x11, 0x91, 0x79, 0x66, 0x60, 0x24, 0xc5, 0x8c, 0x6f, 0x36, 0x9e, 0x5a, 0x48, - 0x5a, 0x8c, 0xfc, 0x8b, 0xf1, 0xc9, 0xe9, 0xd1, 0xb8, 0x8c, 0x3e, 0xd1, 0x05, 0x6a, 0x4f, 0xa4, - 0xaf, 0xc8, 0x78, 0x5a, 0xa5, 0x88, 0xaa, 0x81, 0x6d, 0x52, 0xac, 0x5b, 0xec, 0x6a, 0xcd, 0xa4, - 0x08, 0xa0, 0x53, 0x27, 0xd0, 0x1d, 0xfa, 0x6f, 0xaf, 0x6f, 0x0e, 0x4f, 0xff, 0x8d, 0x1a, 0x90, - 0x94, 0x8b, 0x3c, 0x37, 0x79, 0x51, 0x5b, 0x9a, 0xe0, 0xaf, 0xc0, 0x21, 0x98, 0x0b, 0xce, 0x08, - 0x9e, 0x85, 0xf5, 0x8d, 0x34, 0xf5, 0x00, 0x1e, 0xd7, 0x27, 0xef, 0xcc, 0xd5, 0x0c, 0x60, 0x6f, - 0x22, 0xf2, 0xe9, 0xb6, 0xf0, 0xa1, 0x2e, 0xec, 0x56, 0xe2, 0xa6, 0x86, 0xc3, 0xc1, 0xd6, 0x71, - 0xf3, 0x60, 0xc2, 0x82, 0x25, 0xbd, 0xd6, 0x7f, 0x36, 0x7d, 0xf6, 0xf9, 0x4b, 0x10, 0xb0, 0x04, - 0xed, 0xd7, 0xbe, 0x1f, 0x8c, 0x6d, 0xc0, 0x12, 0x27, 0x86, 0x27, 0xba, 0xa7, 0x3b, 0xa8, 0xf6, - 0x3d, 0x51, 0x8f, 0x2a, 0xcb, 0x5b, 0x14, 0xff, 0xe3, 0x8f, 0xa5, 0x6b, 0x5d, 0x2d, 0x5d, 0xeb, - 0xd7, 0xd2, 0xb5, 0xbe, 0xaf, 0xdc, 0xc6, 0xd5, 0xca, 0x6d, 0xfc, 0x5c, 0xb9, 0x8d, 0xaf, 0x47, - 0x7f, 0x03, 0x5c, 0x6e, 0xbf, 0x96, 0x66, 0x45, 0x2d, 0xfd, 0x55, 0x4e, 0xfe, 0x04, 0x00, 0x00, - 0xff, 0xff, 0xab, 0xc1, 0xba, 0xbe, 0x7b, 0x03, 0x00, 0x00, + // 533 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x30, + 0x18, 0x6e, 0x68, 0x69, 0x3b, 0x37, 0x13, 0x90, 0x8d, 0xa9, 0x7c, 0x28, 0x2b, 0x39, 0xf5, 0x80, + 0xda, 0x7d, 0x09, 0x71, 0x25, 0xd3, 0xd0, 0x0a, 0x07, 0x2a, 0x87, 0x13, 0x17, 0xcb, 0x71, 0xdc, + 0xc4, 0x6a, 0x63, 0x5b, 0x89, 0x53, 0xad, 0xfc, 0x0a, 0x7e, 0xd6, 0x8e, 0x3b, 0xa2, 0x1d, 0x26, + 0xd4, 0xfe, 0x0f, 0x84, 0xe2, 0xa4, 0xe9, 0x7a, 0x02, 0x81, 0xb8, 0xc5, 0xef, 0xfb, 0xea, 0xf9, + 0x78, 0xfd, 0x38, 0xc0, 0xf1, 0xb1, 0xbf, 0x98, 0x09, 0x3e, 0x9c, 0x30, 0x8e, 0x67, 0x4c, 0x2d, + 0x86, 0xf3, 0xe3, 0xea, 0x7b, 0x20, 0x13, 0xa1, 0x84, 0xb5, 0x57, 0xce, 0x0c, 0xaa, 0xfa, 0xfc, + 0xf8, 0xf9, 0x7e, 0x28, 0x42, 0xa1, 0xfb, 0xc3, 0xfc, 0xab, 0x18, 0x75, 0x10, 0x30, 0x47, 0x3c, + 0xa0, 0x57, 0x34, 0x70, 0x67, 0x82, 0x4c, 0xad, 0x03, 0xd0, 0x8c, 0x28, 0x0b, 0x23, 0xd5, 0x35, + 0x7a, 0x46, 0xbf, 0x01, 0xcb, 0x93, 0xf5, 0x0c, 0xb4, 0xb1, 0x94, 0x28, 0xc2, 0x69, 0xd4, 0x7d, + 0xd0, 0x33, 0xfa, 0x26, 0x6c, 0x61, 0x29, 0x2f, 0x71, 0x1a, 0x59, 0x2f, 0xc1, 0x4e, 0xc1, 0xf3, + 0x95, 0x06, 0xdd, 0x7a, 0xcf, 0xe8, 0xb7, 0xe1, 0xa6, 0xe0, 0x28, 0xb0, 0x3b, 0xce, 0x7c, 0x88, + 0x79, 0x70, 0x2e, 0xe2, 0x98, 0x29, 0xeb, 0x15, 0x30, 0x53, 0x85, 0x13, 0x85, 0xb6, 0x78, 0x3a, + 0xba, 0x76, 0x59, 0x90, 0xf5, 0x80, 0xc9, 0xb3, 0x18, 0xc9, 0xcc, 0x47, 0x09, 0xe6, 0x81, 0x26, + 0x6c, 0x40, 0xc0, 0xb3, 0xb8, 0x84, 0xb2, 0x6c, 0x00, 0x88, 0x86, 0x8b, 0x29, 0x57, 0x9a, 0xd4, + 0x84, 0xf7, 0x2a, 0xce, 0xcf, 0x3a, 0x68, 0x5f, 0xcc, 0x59, 0x40, 0x39, 0xa1, 0x16, 0x04, 0x3b, + 0x13, 0x89, 0x7c, 0x45, 0x90, 0x9c, 0x6a, 0x3a, 0xd3, 0x7d, 0x73, 0x7b, 0x77, 0x78, 0x12, 0x32, + 0x15, 0x65, 0xfe, 0x80, 0x88, 0x78, 0x58, 0x2e, 0x8c, 0x44, 0x98, 0xf1, 0xf5, 0x61, 0xa8, 0x16, + 0x92, 0xa6, 0x03, 0x77, 0x34, 0x3e, 0x3d, 0x3b, 0x1a, 0x67, 0xfe, 0x47, 0xba, 0x80, 0xad, 0x89, + 0x74, 0x15, 0x19, 0x4f, 0x73, 0x17, 0x7e, 0xbe, 0xb0, 0xb5, 0x8b, 0x42, 0x62, 0x47, 0xd7, 0x4a, + 0x17, 0x1e, 0x68, 0x57, 0x0e, 0xb4, 0x42, 0xf7, 0xed, 0xed, 0xdd, 0xe1, 0xd9, 0x9f, 0xb1, 0x7a, + 0x24, 0xe2, 0x22, 0x49, 0x4a, 0xbf, 0xb0, 0x25, 0x4b, 0xe3, 0xaf, 0x81, 0x45, 0x30, 0x17, 0x9c, + 0x11, 0x3c, 0x43, 0xd5, 0x8d, 0x34, 0xf4, 0x02, 0x1e, 0x57, 0x9d, 0x77, 0xe5, 0xd5, 0x38, 0x60, + 0x77, 0x22, 0x92, 0xe9, 0x66, 0xf0, 0xa1, 0x1e, 0xec, 0xe4, 0xc5, 0xf5, 0x0c, 0x07, 0x07, 0x1b, + 0xc4, 0x75, 0x60, 0x50, 0xca, 0xc2, 0x6e, 0xf3, 0x2f, 0x45, 0x5f, 0x7c, 0xfa, 0xec, 0x79, 0x2c, + 0x84, 0xfb, 0x15, 0xee, 0xfb, 0x12, 0xd6, 0x63, 0xa1, 0x15, 0x80, 0x27, 0x5a, 0xd3, 0x16, 0x55, + 0xeb, 0x1f, 0xa9, 0x1e, 0xe5, 0x90, 0xf7, 0x58, 0x9c, 0x6b, 0x03, 0xbc, 0x58, 0x9f, 0xc7, 0x89, + 0xc8, 0xa3, 0x90, 0x78, 0x2c, 0xe4, 0x8c, 0x87, 0x23, 0x3e, 0x11, 0xff, 0x2b, 0x13, 0x5b, 0xc9, + 0xce, 0x33, 0x51, 0xdf, 0x4e, 0xf6, 0x09, 0x78, 0x1a, 0xb3, 0x34, 0xa5, 0x01, 0xd2, 0x49, 0x49, + 0x11, 0x11, 0x19, 0x57, 0x34, 0xd1, 0x01, 0xa9, 0xc3, 0xbd, 0xa2, 0xa9, 0x9f, 0x62, 0x7a, 0x5e, + 0xb4, 0xdc, 0x0f, 0xd7, 0x4b, 0xdb, 0xb8, 0x59, 0xda, 0xc6, 0x8f, 0xa5, 0x6d, 0x7c, 0x5b, 0xd9, + 0xb5, 0x9b, 0x95, 0x5d, 0xfb, 0xbe, 0xb2, 0x6b, 0x5f, 0x8e, 0x7e, 0xa7, 0xf6, 0x6a, 0xf3, 0x97, + 0xd0, 0xc2, 0xfd, 0xa6, 0x7e, 0xf5, 0xa7, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x32, 0x14, + 0xff, 0x46, 0x04, 0x00, 0x00, } func (m *IndexedBlock) Marshal() (dAtA []byte, err error) { @@ -452,6 +516,51 @@ func (m *Evidence) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *FinalityProviderSigningInfo) 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 *FinalityProviderSigningInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FinalityProviderSigningInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.MissedBlocksCounter != 0 { + i = encodeVarintFinality(dAtA, i, uint64(m.MissedBlocksCounter)) + i-- + dAtA[i] = 0x18 + } + if m.StartHeight != 0 { + i = encodeVarintFinality(dAtA, i, uint64(m.StartHeight)) + i-- + dAtA[i] = 0x10 + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintFinality(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintFinality(dAtA []byte, offset int, v uint64) int { offset -= sovFinality(v) base := offset @@ -537,6 +646,25 @@ func (m *Evidence) Size() (n int) { return n } +func (m *FinalityProviderSigningInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovFinality(uint64(l)) + } + if m.StartHeight != 0 { + n += 1 + sovFinality(uint64(m.StartHeight)) + } + if m.MissedBlocksCounter != 0 { + n += 1 + sovFinality(uint64(m.MissedBlocksCounter)) + } + return n +} + func sovFinality(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1065,6 +1193,129 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { } return nil } +func (m *FinalityProviderSigningInfo) 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 ErrIntOverflowFinality + } + 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: FinalityProviderSigningInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FinalityProviderSigningInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthFinality + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthFinality + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) + } + m.StartHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MissedBlocksCounter", wireType) + } + m.MissedBlocksCounter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowFinality + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MissedBlocksCounter |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipFinality(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthFinality + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipFinality(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/genesis_test.go b/x/finality/types/genesis_test.go index 97dbf25c2..00b8b7c3e 100644 --- a/x/finality/types/genesis_test.go +++ b/x/finality/types/genesis_test.go @@ -3,8 +3,9 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/finality/types" "github.com/stretchr/testify/require" + + "github.com/babylonchain/babylon/x/finality/types" ) func TestGenesisState_Validate(t *testing.T) { @@ -19,13 +20,13 @@ func TestGenesisState_Validate(t *testing.T) { valid: true, }, { - desc: "valid genesis state", + desc: "invalid genesis state", genState: &types.GenesisState{ Params: types.Params{ MinPubRand: 200, }, }, - valid: true, + valid: false, }, } for _, tc := range tests { diff --git a/x/finality/types/hooks.go b/x/finality/types/hooks.go new file mode 100644 index 000000000..093f51180 --- /dev/null +++ b/x/finality/types/hooks.go @@ -0,0 +1,26 @@ +package types + +import ( + "context" + + "github.com/babylonchain/babylon/types" +) + +// combine multiple finality hooks, all hook functions are run in array sequence +var _ FinalityHooks = &MultiFinalityHooks{} + +type MultiFinalityHooks []FinalityHooks + +func NewMultiFinalityHooks(hooks ...FinalityHooks) MultiFinalityHooks { + return hooks +} + +func (h MultiFinalityHooks) AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { + for i := range h { + if err := h[i].AfterInactiveFinalityProviderDetected(ctx, btcPk); err != nil { + return err + } + } + + return nil +} diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 4198e6134..532809c4b 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -1,5 +1,12 @@ package types +import ( + "cosmossdk.io/collections" + "github.com/cosmos/cosmos-sdk/types/address" + + "github.com/babylonchain/babylon/types" +) + const ( // ModuleName defines the module name ModuleName = "finality" @@ -12,14 +19,45 @@ const ( // MemStoreKey defines the in-memory store key MemStoreKey = "mem_finality" + + // MissedBlockBitmapChunkSize defines the chunk size, in number of bits, of a + // finality provider missed block bitmap. Chunks are used to reduce the storage and + // write overhead of IAVL nodes. The total size of the bitmap is roughly in + // the range [0, SignedBlocksWindow) where each bit represents a block. A + // finality provider's IndexOffset modulo the SignedBlocksWindow is used to retrieve + // the chunk in that bitmap range. Once the chunk is retrieved, the same index + // is used to check or flip a bit, where if a bit is set, it indicates the + // finality provider missed that block. + // + // For a bitmap of N items, i.e. a finality provider's signed block window, the amount + // of write complexity per write with a factor of f being the overhead of + // IAVL being un-optimized, i.e. 2-4, is as follows: + // + // ChunkSize + (f * 256 ) + 256 * log_2(N / ChunkSize) + // + // As for the storage overhead, with the same factor f, it is as follows: + // (N - 256) + (N / ChunkSize) * (512 * f) + MissedBlockBitmapChunkSize = 1024 // 2^10 bits ) var ( - BlockKey = []byte{0x01} // key prefix for blocks - VoteKey = []byte{0x02} // key prefix for votes - PubRandKey = []byte{0x03} // key prefix for public randomness - PubRandCommitKey = []byte{0x04} // key prefix for commitment of public randomness - ParamsKey = []byte{0x05} // key prefix for the parameters - EvidenceKey = []byte{0x06} // key prefix for evidences - NextHeightToFinalizeKey = []byte{0x07} // key prefix for next height to finalise + BlockKey = []byte{0x01} // key prefix for blocks + VoteKey = []byte{0x02} // key prefix for votes + PubRandKey = []byte{0x03} // key prefix for public randomness + PubRandCommitKey = []byte{0x04} // key prefix for commitment of public randomness + ParamsKey = []byte{0x05} // key prefix for the parameters + EvidenceKey = []byte{0x06} // key prefix for evidences + NextHeightToFinalizeKey = []byte{0x07} // key prefix for next height to finalise + FinalityProviderSigningInfoKeyPrefix = collections.NewPrefix(8) // key prefix for signing info + FinalityProviderMissedBlockBitmapKeyPrefix = collections.NewPrefix(9) // key prefix for missed block bitmap ) + +// FinalityProviderSigningInfoKey - stored by finality provider public key in BIP340 +func FinalityProviderSigningInfoKey(pk *types.BIP340PubKey) []byte { + return append(FinalityProviderSigningInfoKeyPrefix, address.MustLengthPrefix(pk.MustMarshal())...) +} + +// FinalityProviderMissedBlockBitmapKey - stored by finality provider public key in BIP340 +func FinalityProviderMissedBlockBitmapKey(pk *types.BIP340PubKey) []byte { + return append(FinalityProviderMissedBlockBitmapKeyPrefix, address.MustLengthPrefix(pk.MustMarshal())...) +} diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index ecef9983e..fad540139 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -8,7 +8,8 @@ import ( context "context" reflect "reflect" - types "github.com/babylonchain/babylon/x/btcstaking/types" + types "github.com/babylonchain/babylon/types" + types0 "github.com/babylonchain/babylon/x/btcstaking/types" gomock "github.com/golang/mock/gomock" ) @@ -51,10 +52,10 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetBTCStakingActivatedHeight(ctx int } // GetFinalityProvider mocks base method. -func (m *MockBTCStakingKeeper) GetFinalityProvider(ctx context.Context, fpBTCPK []byte) (*types.FinalityProvider, error) { +func (m *MockBTCStakingKeeper) GetFinalityProvider(ctx context.Context, fpBTCPK []byte) (*types0.FinalityProvider, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetFinalityProvider", ctx, fpBTCPK) - ret0, _ := ret[0].(*types.FinalityProvider) + ret0, _ := ret[0].(*types0.FinalityProvider) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -80,10 +81,10 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetLastFinalizedEpoch(ctx interface{ } // GetParams mocks base method. -func (m *MockBTCStakingKeeper) GetParams(ctx context.Context) types.Params { +func (m *MockBTCStakingKeeper) GetParams(ctx context.Context) types0.Params { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetParams", ctx) - ret0, _ := ret[0].(types.Params) + ret0, _ := ret[0].(types0.Params) return ret0 } @@ -108,10 +109,10 @@ func (mr *MockBTCStakingKeeperMockRecorder) GetVotingPower(ctx, fpBTCPK, height } // GetVotingPowerDistCache mocks base method. -func (m *MockBTCStakingKeeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types.VotingPowerDistCache, error) { +func (m *MockBTCStakingKeeper) GetVotingPowerDistCache(ctx context.Context, height uint64) (*types0.VotingPowerDistCache, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetVotingPowerDistCache", ctx, height) - ret0, _ := ret[0].(*types.VotingPowerDistCache) + ret0, _ := ret[0].(*types0.VotingPowerDistCache) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -162,6 +163,20 @@ func (mr *MockBTCStakingKeeperMockRecorder) RemoveVotingPowerDistCache(ctx, heig return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveVotingPowerDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RemoveVotingPowerDistCache), ctx, height) } +// RevertInactiveFinalityProvider mocks base method. +func (m *MockBTCStakingKeeper) RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RevertInactiveFinalityProvider", ctx, fpBTCPK) + ret0, _ := ret[0].(error) + return ret0 +} + +// RevertInactiveFinalityProvider indicates an expected call of RevertInactiveFinalityProvider. +func (mr *MockBTCStakingKeeperMockRecorder) RevertInactiveFinalityProvider(ctx, fpBTCPK interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertInactiveFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RevertInactiveFinalityProvider), ctx, fpBTCPK) +} + // SlashFinalityProvider mocks base method. func (m *MockBTCStakingKeeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error { m.ctrl.T.Helper() @@ -200,7 +215,7 @@ func (m *MockIncentiveKeeper) EXPECT() *MockIncentiveKeeperMockRecorder { } // RewardBTCStaking mocks base method. -func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, filteredDc *types.VotingPowerDistCache) { +func (m *MockIncentiveKeeper) RewardBTCStaking(ctx context.Context, height uint64, filteredDc *types0.VotingPowerDistCache) { m.ctrl.T.Helper() m.ctrl.Call(m, "RewardBTCStaking", ctx, height, filteredDc) } @@ -210,3 +225,77 @@ func (mr *MockIncentiveKeeperMockRecorder) RewardBTCStaking(ctx, height, filtere mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RewardBTCStaking", reflect.TypeOf((*MockIncentiveKeeper)(nil).RewardBTCStaking), ctx, height, filteredDc) } + +// MockBtcStakingHooks is a mock of BtcStakingHooks interface. +type MockBtcStakingHooks struct { + ctrl *gomock.Controller + recorder *MockBtcStakingHooksMockRecorder +} + +// MockBtcStakingHooksMockRecorder is the mock recorder for MockBtcStakingHooks. +type MockBtcStakingHooksMockRecorder struct { + mock *MockBtcStakingHooks +} + +// NewMockBtcStakingHooks creates a new mock instance. +func NewMockBtcStakingHooks(ctrl *gomock.Controller) *MockBtcStakingHooks { + mock := &MockBtcStakingHooks{ctrl: ctrl} + mock.recorder = &MockBtcStakingHooksMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBtcStakingHooks) EXPECT() *MockBtcStakingHooksMockRecorder { + return m.recorder +} + +// AfterFinalityProviderActivated mocks base method. +func (m *MockBtcStakingHooks) AfterFinalityProviderActivated(ctx context.Context, btcPk *types.BIP340PubKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterFinalityProviderActivated", ctx, btcPk) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterFinalityProviderActivated indicates an expected call of AfterFinalityProviderActivated. +func (mr *MockBtcStakingHooksMockRecorder) AfterFinalityProviderActivated(ctx, btcPk interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterFinalityProviderActivated", reflect.TypeOf((*MockBtcStakingHooks)(nil).AfterFinalityProviderActivated), ctx, btcPk) +} + +// MockFinalityHooks is a mock of FinalityHooks interface. +type MockFinalityHooks struct { + ctrl *gomock.Controller + recorder *MockFinalityHooksMockRecorder +} + +// MockFinalityHooksMockRecorder is the mock recorder for MockFinalityHooks. +type MockFinalityHooksMockRecorder struct { + mock *MockFinalityHooks +} + +// NewMockFinalityHooks creates a new mock instance. +func NewMockFinalityHooks(ctrl *gomock.Controller) *MockFinalityHooks { + mock := &MockFinalityHooks{ctrl: ctrl} + mock.recorder = &MockFinalityHooksMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFinalityHooks) EXPECT() *MockFinalityHooksMockRecorder { + return m.recorder +} + +// AfterInactiveFinalityProviderDetected mocks base method. +func (m *MockFinalityHooks) AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AfterInactiveFinalityProviderDetected", ctx, btcPk) + ret0, _ := ret[0].(error) + return ret0 +} + +// AfterInactiveFinalityProviderDetected indicates an expected call of AfterInactiveFinalityProviderDetected. +func (mr *MockFinalityHooksMockRecorder) AfterInactiveFinalityProviderDetected(ctx, btcPk interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterInactiveFinalityProviderDetected", reflect.TypeOf((*MockFinalityHooks)(nil).AfterInactiveFinalityProviderDetected), ctx, btcPk) +} diff --git a/x/finality/types/params.go b/x/finality/types/params.go index 437a4e662..a936e17a5 100644 --- a/x/finality/types/params.go +++ b/x/finality/types/params.go @@ -3,21 +3,31 @@ package types import ( "fmt" + "cosmossdk.io/math" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" "gopkg.in/yaml.v2" ) -var _ paramtypes.ParamSet = (*Params)(nil) +// Default parameter namespace +const ( + DefaultSignedBlocksWindow = int64(100) + DefaultMinPubRand = 100 + DefaultFinalitySigTimeout = 3 +) -// ParamKeyTable the param key table for launch module -func ParamKeyTable() paramtypes.KeyTable { - return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) -} +var ( + DefaultMinSignedPerWindow = math.LegacyNewDecWithPrec(5, 1) +) + +var _ paramtypes.ParamSet = (*Params)(nil) // DefaultParams returns a default set of parameters func DefaultParams() Params { return Params{ - MinPubRand: 100, + FinalitySigTimeout: DefaultFinalitySigTimeout, + SignedBlocksWindow: DefaultSignedBlocksWindow, + MinSignedPerWindow: DefaultMinSignedPerWindow, + MinPubRand: DefaultMinPubRand, } } @@ -33,16 +43,84 @@ func validateMinPubRand(minPubRand uint64) error { return nil } -// Validate validates the set of params +// String implements the Stringer interface. +func (p Params) String() string { + out, _ := yaml.Marshal(p) + return string(out) +} + +// Validate validates the params func (p Params) Validate() error { + if err := validateSignedBlocksWindow(p.SignedBlocksWindow); err != nil { + return err + } + + if err := validateFinalitySigTimeout(p.FinalitySigTimeout); err != nil { + return err + } + + if err := validateMinSignedPerWindow(p.MinSignedPerWindow); err != nil { + return err + } + if err := validateMinPubRand(p.MinPubRand); err != nil { return err } + return nil } -// String implements the Stringer interface. -func (p Params) String() string { - out, _ := yaml.Marshal(p) - return string(out) +func validateSignedBlocksWindow(i interface{}) error { + v, ok := i.(int64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v <= 0 { + return fmt.Errorf("signed blocks window must be positive: %d", v) + } + + return nil +} + +func validateFinalitySigTimeout(i interface{}) error { + v, ok := i.(int64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v <= 0 { + return fmt.Errorf("finality vote delay must be positive: %d", v) + } + + return nil +} + +func validateMinSignedPerWindow(i interface{}) error { + v, ok := i.(math.LegacyDec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v.IsNil() { + return fmt.Errorf("min signed per window cannot be nil: %s", v) + } + if v.IsNegative() { + return fmt.Errorf("min signed per window cannot be negative: %s", v) + } + if v.GT(math.LegacyOneDec()) { + return fmt.Errorf("min signed per window too large: %s", v) + } + + return nil +} + +// MinSignedPerWindowInt returns min signed per window as an integer (vs the decimal in the param) +func (p *Params) MinSignedPerWindowInt() int64 { + signedBlocksWindow := p.SignedBlocksWindow + minSignedPerWindow := p.MinSignedPerWindow + + // NOTE: RoundInt64 will never panic as minSignedPerWindow is + // less than 1. + return minSignedPerWindow.MulInt64(signedBlocksWindow).RoundInt64() } diff --git a/x/finality/types/params.pb.go b/x/finality/types/params.pb.go index fe81592df..4080a8b37 100644 --- a/x/finality/types/params.pb.go +++ b/x/finality/types/params.pb.go @@ -4,7 +4,10 @@ package types import ( + cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -25,9 +28,17 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { + // signed_blocks_window defines the size of the sliding window for tracking finality provider liveness + SignedBlocksWindow int64 `protobuf:"varint,1,opt,name=signed_blocks_window,json=signedBlocksWindow,proto3" json:"signed_blocks_window,omitempty"` + // finality_sig_timeout defines how much time (in terms of blocks) finality providers have to cast a finality + // vote before being judged as missing their voting turn on the given block + FinalitySigTimeout int64 `protobuf:"varint,2,opt,name=finality_sig_timeout,json=finalitySigTimeout,proto3" json:"finality_sig_timeout,omitempty"` + // min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign + // within the sliding window to avoid being detected as inactive + MinSignedPerWindow cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=min_signed_per_window,json=minSignedPerWindow,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_signed_per_window"` // min_pub_rand is the minimum number of public randomness each // message should commit - MinPubRand uint64 `protobuf:"varint,1,opt,name=min_pub_rand,json=minPubRand,proto3" json:"min_pub_rand,omitempty"` + MinPubRand uint64 `protobuf:"varint,4,opt,name=min_pub_rand,json=minPubRand,proto3" json:"min_pub_rand,omitempty"` } func (m *Params) Reset() { *m = Params{} } @@ -62,6 +73,20 @@ func (m *Params) XXX_DiscardUnknown() { var xxx_messageInfo_Params proto.InternalMessageInfo +func (m *Params) GetSignedBlocksWindow() int64 { + if m != nil { + return m.SignedBlocksWindow + } + return 0 +} + +func (m *Params) GetFinalitySigTimeout() int64 { + if m != nil { + return m.FinalitySigTimeout + } + return 0 +} + func (m *Params) GetMinPubRand() uint64 { if m != nil { return m.MinPubRand @@ -76,19 +101,30 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/params.proto", fileDescriptor_25539c9a61c72ee9) } var fileDescriptor_25539c9a61c72ee9 = []byte{ - // 192 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, - 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, - 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, - 0xd0, 0x83, 0xa9, 0xd0, 0x2b, 0x33, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0xcb, 0xeb, 0x83, - 0x58, 0x10, 0xa5, 0x4a, 0x06, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x42, 0x0a, 0x5c, 0x3c, 0xb9, 0x99, - 0x79, 0xf1, 0x05, 0xa5, 0x49, 0xf1, 0x45, 0x89, 0x79, 0x29, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x2c, - 0x41, 0x5c, 0xb9, 0x99, 0x79, 0x01, 0xa5, 0x49, 0x41, 0x89, 0x79, 0x29, 0x56, 0x2c, 0x33, 0x16, - 0xc8, 0x33, 0x38, 0x79, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, - 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x41, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0x05, 0xc9, 0x19, 0x89, - 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0xc2, 0xc9, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, - 0x47, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x3d, 0x78, 0xb7, 0xd3, 0x00, 0x00, 0x00, + // 359 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x91, 0x31, 0x4b, 0xfb, 0x40, + 0x18, 0xc6, 0x73, 0xff, 0x96, 0x0e, 0xa1, 0xcb, 0x3f, 0x56, 0xa8, 0x15, 0xd2, 0xe0, 0x54, 0x04, + 0x73, 0x2d, 0x82, 0x83, 0x63, 0xe9, 0x24, 0x0e, 0x25, 0x15, 0x04, 0x97, 0x70, 0x49, 0xce, 0xf4, + 0xa5, 0xbd, 0xbb, 0x90, 0x4b, 0x5a, 0xf3, 0x2d, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0xfc, 0x10, 0x1d, + 0x8b, 0x93, 0x38, 0x14, 0x69, 0x07, 0x3f, 0x86, 0xd2, 0xbb, 0x04, 0x97, 0xe3, 0xde, 0xfb, 0x3d, + 0xef, 0x3d, 0xcf, 0xbd, 0x67, 0x3a, 0x01, 0x09, 0x8a, 0xb9, 0xe0, 0xf8, 0x1e, 0x38, 0x99, 0x43, + 0x56, 0xe0, 0xc5, 0x00, 0x27, 0x24, 0x25, 0x4c, 0xba, 0x49, 0x2a, 0x32, 0x61, 0x1d, 0x94, 0x0a, + 0xb7, 0x52, 0xb8, 0x8b, 0x41, 0xa7, 0x15, 0x8b, 0x58, 0x28, 0x8e, 0xf7, 0x3b, 0x2d, 0xed, 0xfc, + 0x27, 0x0c, 0xb8, 0xc0, 0x6a, 0x2d, 0x8f, 0x8e, 0x42, 0x21, 0x99, 0x90, 0xbe, 0xd6, 0xea, 0x42, + 0xa3, 0x93, 0x1f, 0x64, 0x36, 0xc6, 0xca, 0xc9, 0xea, 0x9b, 0x2d, 0x09, 0x31, 0xa7, 0x91, 0x1f, + 0xcc, 0x45, 0x38, 0x93, 0xfe, 0x12, 0x78, 0x24, 0x96, 0x6d, 0xe4, 0xa0, 0x5e, 0xcd, 0xb3, 0x34, + 0x1b, 0x2a, 0x74, 0xab, 0xc8, 0xbe, 0xa3, 0xca, 0xe3, 0x4b, 0x88, 0xfd, 0x0c, 0x18, 0x15, 0x79, + 0xd6, 0xfe, 0xa7, 0x3b, 0x2a, 0x36, 0x81, 0xf8, 0x46, 0x13, 0x0b, 0xcc, 0x43, 0x06, 0xdc, 0x2f, + 0x7d, 0x12, 0x9a, 0x56, 0x26, 0x35, 0x07, 0xf5, 0x9a, 0xc3, 0x8b, 0xd5, 0xa6, 0x6b, 0x7c, 0x6e, + 0xba, 0xc7, 0x3a, 0xa3, 0x8c, 0x66, 0x2e, 0x08, 0xcc, 0x48, 0x36, 0x75, 0xaf, 0x69, 0x4c, 0xc2, + 0x62, 0x44, 0xc3, 0xf7, 0xb7, 0x33, 0xb3, 0x7c, 0xc2, 0x88, 0x86, 0x2f, 0xdf, 0xaf, 0xa7, 0xc8, + 0xb3, 0x18, 0xf0, 0x89, 0xba, 0x73, 0x4c, 0xd3, 0x32, 0x9c, 0x63, 0x36, 0xf7, 0x56, 0x49, 0x1e, + 0xf8, 0x29, 0xe1, 0x51, 0xbb, 0xee, 0xa0, 0x5e, 0xdd, 0x33, 0x19, 0xf0, 0x71, 0x1e, 0x78, 0x84, + 0x47, 0x97, 0xf5, 0xa7, 0xe7, 0xae, 0x31, 0xbc, 0x5a, 0x6d, 0x6d, 0xb4, 0xde, 0xda, 0xe8, 0x6b, + 0x6b, 0xa3, 0xc7, 0x9d, 0x6d, 0xac, 0x77, 0xb6, 0xf1, 0xb1, 0xb3, 0x8d, 0xbb, 0x7e, 0x0c, 0xd9, + 0x34, 0x0f, 0xdc, 0x50, 0x30, 0x5c, 0xce, 0x3f, 0x9c, 0x12, 0xe0, 0x55, 0x81, 0x1f, 0xfe, 0x3e, + 0x2c, 0x2b, 0x12, 0x2a, 0x83, 0x86, 0x1a, 0xea, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb0, + 0x39, 0x84, 0xbb, 0xd1, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -114,6 +150,26 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { if m.MinPubRand != 0 { i = encodeVarintParams(dAtA, i, uint64(m.MinPubRand)) i-- + dAtA[i] = 0x20 + } + { + size := m.MinSignedPerWindow.Size() + i -= size + if _, err := m.MinSignedPerWindow.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if m.FinalitySigTimeout != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.FinalitySigTimeout)) + i-- + dAtA[i] = 0x10 + } + if m.SignedBlocksWindow != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.SignedBlocksWindow)) + i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil @@ -136,6 +192,14 @@ func (m *Params) Size() (n int) { } var l int _ = l + if m.SignedBlocksWindow != 0 { + n += 1 + sovParams(uint64(m.SignedBlocksWindow)) + } + if m.FinalitySigTimeout != 0 { + n += 1 + sovParams(uint64(m.FinalitySigTimeout)) + } + l = m.MinSignedPerWindow.Size() + n += 1 + l + sovParams(uint64(l)) if m.MinPubRand != 0 { n += 1 + sovParams(uint64(m.MinPubRand)) } @@ -178,6 +242,77 @@ func (m *Params) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SignedBlocksWindow", wireType) + } + m.SignedBlocksWindow = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SignedBlocksWindow |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field FinalitySigTimeout", wireType) + } + m.FinalitySigTimeout = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.FinalitySigTimeout |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinSignedPerWindow", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthParams + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MinSignedPerWindow.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field MinPubRand", wireType) } diff --git a/x/finality/types/signing_info.go b/x/finality/types/signing_info.go new file mode 100644 index 000000000..9d0f41b90 --- /dev/null +++ b/x/finality/types/signing_info.go @@ -0,0 +1,28 @@ +package types + +import ( + bbntypes "github.com/babylonchain/babylon/types" +) + +// NewFinalityProviderSigningInfo creates a new FinalityProviderSigningInfo instance +func NewFinalityProviderSigningInfo( + fpPk *bbntypes.BIP340PubKey, startHeight, missedBlocksCounter int64, +) FinalityProviderSigningInfo { + return FinalityProviderSigningInfo{ + FpBtcPk: fpPk, + StartHeight: startHeight, + MissedBlocksCounter: missedBlocksCounter, + } +} + +func (si *FinalityProviderSigningInfo) IncrementMissedBlocksCounter() { + si.MissedBlocksCounter++ +} + +func (si *FinalityProviderSigningInfo) DecrementMissedBlocksCounter() { + si.MissedBlocksCounter-- +} + +func (si *FinalityProviderSigningInfo) ResetMissedBlocksCounter() { + si.MissedBlocksCounter = 0 +} From 20e67406300945d14338aa4f89053cd08c20fe71 Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Wed, 17 Jul 2024 14:42:50 +0800 Subject: [PATCH 110/119] chore(inactivity): Rename `inactive` flag to `sluggish`, add queries, events, and metrics (#714) --- proto/babylon/btcstaking/v1/btcstaking.proto | 8 +- proto/babylon/btcstaking/v1/query.proto | 4 +- proto/babylon/finality/v1/events.proto | 14 + proto/babylon/finality/v1/params.proto | 2 +- proto/babylon/finality/v1/query.proto | 39 + x/btcstaking/keeper/finality_providers.go | 10 +- x/btcstaking/keeper/hooks.go | 10 +- x/btcstaking/types/btcstaking.go | 7 +- x/btcstaking/types/btcstaking.pb.go | 136 +-- x/btcstaking/types/query.go | 1 + x/btcstaking/types/query.pb.go | 222 ++-- x/finality/README.md | 75 +- x/finality/abci.go | 2 +- x/finality/keeper/grpc_query.go | 48 + x/finality/keeper/grpc_query_test.go | 71 ++ x/finality/keeper/liveness.go | 55 +- x/finality/keeper/liveness_test.go | 22 +- x/finality/types/events.go | 10 + x/finality/types/events.pb.go | 363 +++++- x/finality/types/expected_keepers.go | 4 +- x/finality/types/hooks.go | 4 +- x/finality/types/metrics.go | 35 +- x/finality/types/mocked_keepers.go | 24 +- x/finality/types/params.pb.go | 2 +- x/finality/types/query.pb.go | 1127 +++++++++++++++--- x/finality/types/query.pb.gw.go | 184 +++ 26 files changed, 2085 insertions(+), 394 deletions(-) diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index 091555f19..e8fcc14de 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -33,8 +33,8 @@ message FinalityProvider { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed uint64 slashed_btc_height = 7; - // inactive defines whether the finality provider is detected inactive - bool inactive = 8; + // sluggish defines whether the finality provider is detected sluggish + bool sluggish = 8; } // FinalityProviderWithMeta wraps the FinalityProvider with metadata. @@ -54,8 +54,8 @@ message FinalityProviderWithMeta { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed uint64 slashed_btc_height = 5; - // inactive defines whether the finality provider is detected inactive - bool inactive = 6; + // sluggish defines whether the finality provider is detected sluggish + bool sluggish = 6; } // BTCDelegation defines a BTC delegation diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 9a48e212c..5b4417568 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -349,6 +349,6 @@ message FinalityProviderResponse { uint64 height = 8; // voting_power is the voting power of this finality provider at the given height uint64 voting_power = 9; - // inactive defines whether the finality provider is detected inactive - bool inactive = 10; + // sluggish defines whether the finality provider is detected sluggish + bool sluggish = 10; } diff --git a/proto/babylon/finality/v1/events.proto b/proto/babylon/finality/v1/events.proto index 61d7f6d5e..436456dea 100644 --- a/proto/babylon/finality/v1/events.proto +++ b/proto/babylon/finality/v1/events.proto @@ -11,3 +11,17 @@ message EventSlashedFinalityProvider { // evidence is the evidence that the finality provider double signs Evidence evidence = 1; } + +// EventSluggishFinalityProviderDetected is the event emitted when a finality provider is +// detected as sluggish +message EventSluggishFinalityProviderDetected { + // public_key is the BTC public key of the finality provider + string public_key = 1; +} + +// EventSluggishFinalityProviderReverted is the event emitted when a sluggish finality +// provider is no longer considered sluggish +message EventSluggishFinalityProviderReverted { + // public_key is the BTC public key of the finality provider + string public_key = 1; +} diff --git a/proto/babylon/finality/v1/params.proto b/proto/babylon/finality/v1/params.proto index 8645a61e0..67751c58d 100644 --- a/proto/babylon/finality/v1/params.proto +++ b/proto/babylon/finality/v1/params.proto @@ -16,7 +16,7 @@ message Params { // vote before being judged as missing their voting turn on the given block int64 finality_sig_timeout = 2; // min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign - // within the sliding window to avoid being detected as inactive + // within the sliding window to avoid being detected as sluggish bytes min_signed_per_window = 3 [ (cosmos_proto.scalar) = "cosmos.Dec", (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index 352ef2716..270834f72 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -54,6 +54,16 @@ service Query { rpc ListEvidences(QueryListEvidencesRequest) returns (QueryListEvidencesResponse) { option (google.api.http).get = "/babylon/finality/v1/evidences"; } + + // SigningInfo queries the signing info of given finality provider BTC public key + rpc SigningInfo(QuerySigningInfoRequest) returns (QuerySigningInfoResponse) { + option (google.api.http).get = "/babylon/finality/v1/signing_infos/{fp_btc_pk_hex}"; + } + + // SigningInfos queries the signing info of all the active finality providers + rpc SigningInfos(QuerySigningInfosRequest) returns (QuerySigningInfosResponse) { + option (google.api.http).get = "/babylon/finality/v1/signing_infos"; + } } // QueryParamsRequest is request type for the Query/Params RPC method. @@ -208,3 +218,32 @@ message QueryListEvidencesResponse { // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } + +// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC +// method +message QuerySigningInfoRequest { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK + // (in BIP340 format) of the finality provider + string fp_btc_pk_hex = 1; +} + +// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC +// method +message QuerySigningInfoResponse { + // fp_signing_info is the signing info of requested finality provider BTC public key + FinalityProviderSigningInfo fp_signing_info = 1 [(gogoproto.nullable) = false]; +} + +// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC +// method +message QuerySigningInfosRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC +// method +message QuerySigningInfosResponse { + // info is the signing info of all finality providers with signing info + repeated FinalityProviderSigningInfo fp_signing_infos = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index 5b2c38d52..b978dda34 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -67,9 +67,9 @@ func (k Keeper) SlashFinalityProvider(ctx context.Context, fpBTCPK []byte) error return nil } -// RevertInactiveFinalityProvider sets the Inactive flag of the given finality provider +// RevertSluggishFinalityProvider sets the Sluggish flag of the given finality provider // to false -func (k Keeper) RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error { +func (k Keeper) RevertSluggishFinalityProvider(ctx context.Context, fpBTCPK []byte) error { // ensure finality provider exists fp, err := k.GetFinalityProvider(ctx, fpBTCPK) if err != nil { @@ -77,12 +77,12 @@ func (k Keeper) RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []by } // ignore the finality provider is already slashed - // or detected as inactive - if fp.IsSlashed() || fp.IsInactive() { + // or detected as sluggish + if fp.IsSlashed() || fp.IsSluggish() { return nil } - fp.Inactive = false + fp.Sluggish = false k.SetFinalityProvider(ctx, fp) return nil diff --git a/x/btcstaking/keeper/hooks.go b/x/btcstaking/keeper/hooks.go index 137af32ba..1ae540dc9 100644 --- a/x/btcstaking/keeper/hooks.go +++ b/x/btcstaking/keeper/hooks.go @@ -20,18 +20,18 @@ func (k Keeper) Hooks() Hooks { return Hooks{k} } -// AfterInactiveFinalityProviderDetected updates the status of the given finality provider to `inactive` -func (h Hooks) AfterInactiveFinalityProviderDetected(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { +// AfterSluggishFinalityProviderDetected updates the status of the given finality provider to `sluggish` +func (h Hooks) AfterSluggishFinalityProviderDetected(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { fp, err := h.k.GetFinalityProvider(ctx, fpPk.MustMarshal()) if err != nil { return err } - if fp.IsInactive() { - return fmt.Errorf("the finality provider %s is already detected as inactive", fpPk.MarshalHex()) + if fp.IsSluggish() { + return fmt.Errorf("the finality provider %s is already detected as sluggish", fpPk.MarshalHex()) } - fp.Inactive = true + fp.Sluggish = true h.k.SetFinalityProvider(ctx, fp) diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 818382fe9..8f22d7838 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -6,18 +6,19 @@ import ( "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) func (fp *FinalityProvider) IsSlashed() bool { return fp.SlashedBabylonHeight > 0 } -func (fp *FinalityProvider) IsInactive() bool { - return fp.Inactive +func (fp *FinalityProvider) IsSluggish() bool { + return fp.Sluggish } func (fp *FinalityProvider) ValidateBasic() error { diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index 62a796b6a..5fd7ae838 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -90,8 +90,8 @@ type FinalityProvider struct { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed SlashedBtcHeight uint64 `protobuf:"varint,7,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` - // inactive defines whether the finality provider is detected inactive - Inactive bool `protobuf:"varint,8,opt,name=inactive,proto3" json:"inactive,omitempty"` + // sluggish defines whether the finality provider is detected sluggish + Sluggish bool `protobuf:"varint,8,opt,name=sluggish,proto3" json:"sluggish,omitempty"` } func (m *FinalityProvider) Reset() { *m = FinalityProvider{} } @@ -162,9 +162,9 @@ func (m *FinalityProvider) GetSlashedBtcHeight() uint64 { return 0 } -func (m *FinalityProvider) GetInactive() bool { +func (m *FinalityProvider) GetSluggish() bool { if m != nil { - return m.Inactive + return m.Sluggish } return false } @@ -186,8 +186,8 @@ type FinalityProviderWithMeta struct { // the finality provider is slashed. // if it's 0 then the finality provider is not slashed SlashedBtcHeight uint64 `protobuf:"varint,5,opt,name=slashed_btc_height,json=slashedBtcHeight,proto3" json:"slashed_btc_height,omitempty"` - // inactive defines whether the finality provider is detected inactive - Inactive bool `protobuf:"varint,6,opt,name=inactive,proto3" json:"inactive,omitempty"` + // sluggish defines whether the finality provider is detected sluggish + Sluggish bool `protobuf:"varint,6,opt,name=sluggish,proto3" json:"sluggish,omitempty"` } func (m *FinalityProviderWithMeta) Reset() { *m = FinalityProviderWithMeta{} } @@ -251,9 +251,9 @@ func (m *FinalityProviderWithMeta) GetSlashedBtcHeight() uint64 { return 0 } -func (m *FinalityProviderWithMeta) GetInactive() bool { +func (m *FinalityProviderWithMeta) GetSluggish() bool { if m != nil { - return m.Inactive + return m.Sluggish } return false } @@ -762,7 +762,7 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1209 bytes of a gzipped FileDescriptorProto + // 1210 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x13, 0xc7, 0x1b, 0xce, 0xda, 0x8e, 0x93, 0xbc, 0xb6, 0x89, 0x19, 0x42, 0x58, 0x12, 0xfd, 0x12, 0xff, 0x5c, 0x8a, 0xac, 0x96, 0xd8, 0x10, 0x68, 0x55, 0x0e, 0x3d, 0xc4, 0x71, 0x28, 0x11, 0x10, 0xdc, 0xb5, @@ -790,55 +790,55 @@ var fileDescriptor_3851ae95ccfaf7db = []byte{ 0xea, 0xed, 0x5d, 0x43, 0xe6, 0xa1, 0x3b, 0xb0, 0xca, 0xfb, 0x98, 0x77, 0x89, 0x6d, 0x86, 0xa9, 0x66, 0x97, 0x50, 0xa7, 0x2b, 0xf4, 0x6c, 0x49, 0xab, 0x64, 0x8c, 0x95, 0xd0, 0x5b, 0x0f, 0x9c, 0xf7, 0x95, 0x0f, 0xdd, 0x00, 0x14, 0x65, 0x09, 0x6b, 0x92, 0xb1, 0xa0, 0x32, 0x8a, 0x93, 0x0c, - 0x61, 0x85, 0xd1, 0x6b, 0xb0, 0x48, 0x5d, 0x6c, 0x09, 0x3a, 0x22, 0xfa, 0x62, 0x49, 0xab, 0x2c, - 0x1a, 0xd1, 0xb9, 0xfc, 0x34, 0x05, 0xfa, 0x59, 0x9a, 0xbf, 0xa1, 0xa2, 0xfb, 0x88, 0x08, 0x9c, - 0x18, 0x95, 0xf6, 0x21, 0x46, 0xb5, 0x0a, 0xd9, 0xb0, 0xd3, 0x94, 0xea, 0x34, 0x3c, 0xa1, 0xff, - 0x43, 0x7e, 0xc4, 0x04, 0x75, 0x1d, 0xd3, 0x63, 0x3f, 0x11, 0x5f, 0x51, 0x9c, 0x31, 0x72, 0x81, - 0xad, 0x29, 0x4d, 0x6f, 0x18, 0x53, 0xe6, 0x9d, 0xc7, 0x34, 0xff, 0x16, 0x63, 0xca, 0x9e, 0x19, - 0xd3, 0xdf, 0x59, 0x28, 0xd4, 0xdb, 0xbb, 0x0d, 0xd2, 0x27, 0x0e, 0x56, 0xaa, 0xbc, 0x0b, 0x39, - 0x49, 0x30, 0xf1, 0xcd, 0xb7, 0xfa, 0x47, 0x40, 0x10, 0x2c, 0x8d, 0x89, 0xb1, 0xa6, 0x3e, 0xa0, - 0x02, 0xd3, 0xef, 0xa9, 0xc0, 0xef, 0xe1, 0xc2, 0x91, 0x67, 0x06, 0x0d, 0x99, 0x7d, 0xca, 0xe5, - 0x48, 0xd3, 0x33, 0x74, 0x95, 0x3b, 0xf2, 0xea, 0xb2, 0xaf, 0x87, 0x94, 0x2b, 0x6a, 0xb9, 0xc0, - 0xbe, 0x98, 0x9e, 0x7d, 0x4e, 0xd9, 0xc2, 0xb1, 0xff, 0x0f, 0x80, 0xb8, 0xf6, 0xb4, 0xea, 0x97, - 0x88, 0x6b, 0x87, 0xee, 0x75, 0x58, 0x12, 0x4c, 0xe0, 0xbe, 0xc9, 0xf1, 0x44, 0xe1, 0x8b, 0xca, - 0xd0, 0xc2, 0x2a, 0x37, 0xbc, 0xa3, 0x29, 0xc6, 0x4a, 0xdb, 0x79, 0x63, 0x29, 0xb4, 0xb4, 0xc7, - 0x8a, 0xff, 0xd0, 0xcd, 0x86, 0xc2, 0x1b, 0x0a, 0x93, 0xda, 0x63, 0x7d, 0xa9, 0xa4, 0x55, 0x0a, - 0x46, 0x31, 0xf4, 0x3c, 0x56, 0x8e, 0x7d, 0x7b, 0x8c, 0xb6, 0x21, 0xa7, 0x34, 0x11, 0x56, 0x03, - 0xc5, 0xcd, 0xc5, 0x93, 0xd3, 0x4d, 0xc9, 0x7c, 0x2b, 0xf4, 0xb4, 0xc7, 0x06, 0xf0, 0xe8, 0x37, - 0xfa, 0x01, 0x0a, 0x76, 0xa0, 0x09, 0xe6, 0x9b, 0x9c, 0x3a, 0x7a, 0x4e, 0x65, 0xdd, 0x3d, 0x39, - 0xdd, 0xfc, 0xec, 0x5d, 0x66, 0xd7, 0xa2, 0x8e, 0x8b, 0xc5, 0xd0, 0x27, 0x46, 0x3e, 0xaa, 0xd7, - 0xa2, 0x0e, 0x3a, 0x84, 0x82, 0xc5, 0x46, 0xc4, 0xc5, 0xae, 0x90, 0xe5, 0xb9, 0x9e, 0x2f, 0xa5, - 0x2b, 0xb9, 0xed, 0x9b, 0xe7, 0xb0, 0xbc, 0x1b, 0xc6, 0xee, 0xd8, 0xd8, 0x0b, 0x2a, 0x04, 0x55, - 0xb9, 0x91, 0x9f, 0x94, 0x69, 0x51, 0x87, 0xa3, 0x8f, 0xe1, 0xc2, 0xd0, 0xed, 0x30, 0xd7, 0x56, - 0x77, 0xa5, 0x03, 0xa2, 0x17, 0xd4, 0x50, 0x0a, 0x91, 0xb5, 0x4d, 0x07, 0x04, 0x7d, 0x0d, 0x45, - 0xa9, 0x8b, 0xa1, 0x6b, 0x47, 0xba, 0xd7, 0x2f, 0x28, 0x99, 0x5d, 0x3f, 0xa7, 0x81, 0x7a, 0x7b, - 0xf7, 0x30, 0x11, 0x6d, 0x2c, 0x77, 0x84, 0x95, 0x34, 0x48, 0x64, 0x0f, 0xfb, 0x78, 0xc0, 0xcd, - 0x11, 0xf1, 0xd5, 0x42, 0x5f, 0x0e, 0x90, 0x03, 0xeb, 0x93, 0xc0, 0x58, 0xfe, 0x35, 0x03, 0xcb, - 0x67, 0x6a, 0x49, 0x2d, 0x25, 0x9a, 0x1e, 0x07, 0x3b, 0xc9, 0xc8, 0xc5, 0x2d, 0xff, 0x8b, 0xc2, - 0xd4, 0xdb, 0x50, 0xf8, 0x23, 0x5c, 0x89, 0x29, 0x8c, 0x01, 0x24, 0x99, 0xe9, 0x59, 0xc9, 0xbc, - 0x1c, 0x55, 0x3e, 0x9c, 0x14, 0x96, 0xac, 0x32, 0x58, 0x4d, 0xa8, 0x66, 0xd2, 0xb0, 0x44, 0xcc, - 0xcc, 0x8a, 0xb8, 0x12, 0xcb, 0x27, 0xac, 0x2b, 0x01, 0x8f, 0x60, 0x35, 0x96, 0x51, 0x02, 0x8f, - 0xeb, 0xf3, 0xef, 0xa9, 0xa7, 0x95, 0x48, 0x4f, 0x31, 0x0c, 0x47, 0x16, 0xac, 0x47, 0x38, 0x53, - 0xa3, 0x0c, 0x16, 0x4b, 0x56, 0x81, 0x5d, 0x3b, 0x07, 0x2c, 0xaa, 0xbe, 0xef, 0x1e, 0x31, 0x43, - 0x9f, 0x14, 0x4a, 0x4e, 0x4e, 0xee, 0x94, 0x72, 0x0b, 0xae, 0xc4, 0xab, 0x98, 0xf9, 0xf1, 0x4e, - 0xe6, 0xe8, 0x0b, 0xc8, 0xd8, 0xa4, 0xcf, 0x75, 0xed, 0x8d, 0x40, 0x53, 0x8b, 0xdc, 0x50, 0x19, - 0xe5, 0x03, 0x58, 0x7f, 0x7d, 0xd1, 0x7d, 0xd7, 0x26, 0x63, 0x54, 0x83, 0x95, 0x78, 0xd1, 0x98, - 0x5d, 0xcc, 0xbb, 0xc1, 0x8d, 0x24, 0x50, 0xde, 0xb8, 0x18, 0xad, 0x9c, 0xfb, 0x98, 0x77, 0x55, - 0x93, 0x4f, 0x35, 0x28, 0x4c, 0x5d, 0x08, 0xdd, 0x83, 0xd4, 0xcc, 0x0f, 0x69, 0xca, 0xeb, 0xa1, - 0x07, 0x90, 0x96, 0x4a, 0x49, 0xcd, 0xaa, 0x14, 0x59, 0xa5, 0xfc, 0xb3, 0x06, 0x57, 0xcf, 0x25, - 0x59, 0x3e, 0x54, 0x16, 0x1b, 0x7d, 0x80, 0xf7, 0xdf, 0x62, 0xa3, 0x66, 0x4f, 0xfe, 0x81, 0x71, - 0x80, 0x11, 0x68, 0x2f, 0xa5, 0x86, 0x97, 0xc3, 0x11, 0x2e, 0x2f, 0xff, 0xa6, 0xc1, 0xd5, 0x16, - 0xe9, 0x13, 0xf5, 0xea, 0x4e, 0xa4, 0xb5, 0x27, 0xbf, 0x4a, 0x5c, 0x8b, 0xa0, 0xeb, 0xb0, 0x7c, - 0x86, 0x85, 0xe0, 0xdd, 0x35, 0x0a, 0x53, 0x04, 0x20, 0x03, 0x96, 0xa2, 0x27, 0x6d, 0xc6, 0x37, - 0x76, 0x21, 0x7c, 0xcd, 0xd0, 0x16, 0x5c, 0xf2, 0x89, 0xd4, 0xa4, 0x4f, 0x6c, 0x33, 0xac, 0xce, - 0x7b, 0xc1, 0x8a, 0x30, 0x8a, 0x91, 0xeb, 0x9e, 0x0c, 0x6f, 0xf5, 0x3e, 0xd9, 0x83, 0x4b, 0x53, - 0x32, 0x6b, 0x09, 0x2c, 0x86, 0x1c, 0xe5, 0x60, 0xa1, 0xb9, 0x77, 0xd0, 0xd8, 0x3f, 0xf8, 0xaa, - 0x38, 0x87, 0x00, 0xb2, 0x3b, 0xbb, 0xed, 0xfd, 0x27, 0x7b, 0x45, 0x0d, 0xe5, 0x61, 0xf1, 0xf0, - 0xa0, 0xfe, 0xf8, 0xa0, 0xb1, 0xd7, 0x28, 0xa6, 0xd0, 0x02, 0xa4, 0x77, 0x0e, 0xbe, 0x2d, 0xa6, - 0xeb, 0x0f, 0x7f, 0x7f, 0xb9, 0xa1, 0x3d, 0x7f, 0xb9, 0xa1, 0xfd, 0xf9, 0x72, 0x43, 0xfb, 0xe5, - 0xd5, 0xc6, 0xdc, 0xf3, 0x57, 0x1b, 0x73, 0x7f, 0xbc, 0xda, 0x98, 0xfb, 0xee, 0x3f, 0x2f, 0x33, - 0x4e, 0x7e, 0xda, 0xab, 0x9b, 0x75, 0xb2, 0xea, 0xd3, 0xfe, 0xf6, 0x3f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xbc, 0xeb, 0x0e, 0xfb, 0x93, 0x0c, 0x00, 0x00, + 0x61, 0x85, 0xd1, 0x6b, 0xb0, 0xc8, 0xfb, 0x43, 0xc7, 0xa1, 0xbc, 0xab, 0x2f, 0x96, 0xb4, 0xca, + 0xa2, 0x11, 0x9d, 0xcb, 0x4f, 0x53, 0xa0, 0x9f, 0xa5, 0xf9, 0x1b, 0x2a, 0xba, 0x8f, 0x88, 0xc0, + 0x89, 0x51, 0x69, 0x1f, 0x62, 0x54, 0xab, 0x90, 0x0d, 0x3b, 0x4d, 0xa9, 0x4e, 0xc3, 0x13, 0xfa, + 0x3f, 0xe4, 0x47, 0x4c, 0x50, 0xd7, 0x31, 0x3d, 0xf6, 0x13, 0xf1, 0x15, 0xc5, 0x19, 0x23, 0x17, + 0xd8, 0x9a, 0xd2, 0xf4, 0x86, 0x31, 0x65, 0xde, 0x79, 0x4c, 0xf3, 0x6f, 0x31, 0xa6, 0xec, 0x99, + 0x31, 0xfd, 0x9d, 0x85, 0x42, 0xbd, 0xbd, 0xdb, 0x20, 0x7d, 0xe2, 0x60, 0xa5, 0xca, 0xbb, 0x90, + 0x93, 0x04, 0x13, 0xdf, 0x7c, 0xab, 0x7f, 0x04, 0x04, 0xc1, 0xd2, 0x98, 0x18, 0x6b, 0xea, 0x03, + 0x2a, 0x30, 0xfd, 0x9e, 0x0a, 0xfc, 0x1e, 0x2e, 0x1c, 0x79, 0x66, 0xd0, 0x90, 0xd9, 0xa7, 0x5c, + 0x8e, 0x34, 0x3d, 0x43, 0x57, 0xb9, 0x23, 0xaf, 0x2e, 0xfb, 0x7a, 0x48, 0xb9, 0xa2, 0x96, 0x0b, + 0xec, 0x8b, 0xe9, 0xd9, 0xe7, 0x94, 0x2d, 0x1c, 0xfb, 0xff, 0x00, 0x88, 0x6b, 0x4f, 0xab, 0x7e, + 0x89, 0xb8, 0x76, 0xe8, 0x5e, 0x87, 0x25, 0xc1, 0x04, 0xee, 0x9b, 0x1c, 0x4f, 0x14, 0xbe, 0xa8, + 0x0c, 0x2d, 0xac, 0x72, 0xc3, 0x3b, 0x9a, 0x62, 0xac, 0xb4, 0x9d, 0x37, 0x96, 0x42, 0x4b, 0x7b, + 0xac, 0xf8, 0x0f, 0xdd, 0x6c, 0x28, 0xbc, 0xa1, 0x30, 0xa9, 0x3d, 0xd6, 0x97, 0x4a, 0x5a, 0xa5, + 0x60, 0x14, 0x43, 0xcf, 0x63, 0xe5, 0xd8, 0xb7, 0xc7, 0x68, 0x1b, 0x72, 0x4a, 0x13, 0x61, 0x35, + 0x50, 0xdc, 0x5c, 0x3c, 0x39, 0xdd, 0x94, 0xcc, 0xb7, 0x42, 0x4f, 0x7b, 0x6c, 0x00, 0x8f, 0x7e, + 0xa3, 0x1f, 0xa0, 0x60, 0x07, 0x9a, 0x60, 0xbe, 0xc9, 0xa9, 0xa3, 0xe7, 0x54, 0xd6, 0xdd, 0x93, + 0xd3, 0xcd, 0xcf, 0xde, 0x65, 0x76, 0x2d, 0xea, 0xb8, 0x58, 0x0c, 0x7d, 0x62, 0xe4, 0xa3, 0x7a, + 0x2d, 0xea, 0xa0, 0x43, 0x28, 0x58, 0x6c, 0x44, 0x5c, 0xec, 0x0a, 0x59, 0x9e, 0xeb, 0xf9, 0x52, + 0xba, 0x92, 0xdb, 0xbe, 0x79, 0x0e, 0xcb, 0xbb, 0x61, 0xec, 0x8e, 0x8d, 0xbd, 0xa0, 0x42, 0x50, + 0x95, 0x1b, 0xf9, 0x49, 0x99, 0x16, 0x75, 0x38, 0xfa, 0x18, 0x2e, 0x0c, 0xdd, 0x0e, 0x73, 0x6d, + 0x75, 0x57, 0x3a, 0x20, 0x7a, 0x41, 0x0d, 0xa5, 0x10, 0x59, 0xdb, 0x74, 0x40, 0xd0, 0xd7, 0x50, + 0x94, 0xba, 0x18, 0xba, 0x76, 0xa4, 0x7b, 0xfd, 0x82, 0x92, 0xd9, 0xf5, 0x73, 0x1a, 0xa8, 0xb7, + 0x77, 0x0f, 0x13, 0xd1, 0xc6, 0x72, 0x47, 0x58, 0x49, 0x83, 0x44, 0xf6, 0xb0, 0x8f, 0x07, 0xdc, + 0x1c, 0x11, 0x5f, 0x2d, 0xf4, 0xe5, 0x00, 0x39, 0xb0, 0x3e, 0x09, 0x8c, 0xe5, 0x5f, 0x33, 0xb0, + 0x7c, 0xa6, 0x96, 0xd4, 0x52, 0xa2, 0xe9, 0x71, 0xb0, 0x93, 0x8c, 0x5c, 0xdc, 0xf2, 0xbf, 0x28, + 0x4c, 0xbd, 0x0d, 0x85, 0x3f, 0xc2, 0x95, 0x98, 0xc2, 0x18, 0x40, 0x92, 0x99, 0x9e, 0x95, 0xcc, + 0xcb, 0x51, 0xe5, 0xc3, 0x49, 0x61, 0xc9, 0x2a, 0x83, 0xd5, 0x84, 0x6a, 0x26, 0x0d, 0x4b, 0xc4, + 0xcc, 0xac, 0x88, 0x2b, 0xb1, 0x7c, 0xc2, 0xba, 0x12, 0xf0, 0x08, 0x56, 0x63, 0x19, 0x25, 0xf0, + 0xb8, 0x3e, 0xff, 0x9e, 0x7a, 0x5a, 0x89, 0xf4, 0x14, 0xc3, 0x70, 0x64, 0xc1, 0x7a, 0x84, 0x33, + 0x35, 0xca, 0x60, 0xb1, 0x64, 0x15, 0xd8, 0xb5, 0x73, 0xc0, 0xa2, 0xea, 0xfb, 0xee, 0x11, 0x33, + 0xf4, 0x49, 0xa1, 0xe4, 0xe4, 0xe4, 0x4e, 0x29, 0xb7, 0xe0, 0x4a, 0xbc, 0x8a, 0x99, 0x1f, 0xef, + 0x64, 0x8e, 0xbe, 0x80, 0x8c, 0x4d, 0xfa, 0x5c, 0xd7, 0xde, 0x08, 0x34, 0xb5, 0xc8, 0x0d, 0x95, + 0x51, 0x3e, 0x80, 0xf5, 0xd7, 0x17, 0xdd, 0x77, 0x6d, 0x32, 0x46, 0x35, 0x58, 0x89, 0x17, 0x8d, + 0xd9, 0xc5, 0xbc, 0x1b, 0xdc, 0x48, 0x02, 0xe5, 0x8d, 0x8b, 0xd1, 0xca, 0xb9, 0x8f, 0x79, 0x57, + 0x35, 0xf9, 0x54, 0x83, 0xc2, 0xd4, 0x85, 0xd0, 0x3d, 0x48, 0xcd, 0xfc, 0x90, 0xa6, 0xbc, 0x1e, + 0x7a, 0x00, 0x69, 0xa9, 0x94, 0xd4, 0xac, 0x4a, 0x91, 0x55, 0xca, 0x3f, 0x6b, 0x70, 0xf5, 0x5c, + 0x92, 0xe5, 0x43, 0x65, 0xb1, 0xd1, 0x07, 0x78, 0xff, 0x2d, 0x36, 0x6a, 0xf6, 0xe4, 0x1f, 0x18, + 0x07, 0x18, 0x81, 0xf6, 0x52, 0x6a, 0x78, 0x39, 0x1c, 0xe1, 0xf2, 0xf2, 0x6f, 0x1a, 0x5c, 0x6d, + 0x91, 0x3e, 0xb1, 0x04, 0x1d, 0x91, 0x89, 0xb4, 0xf6, 0xe4, 0x57, 0x89, 0x6b, 0x11, 0x74, 0x1d, + 0x96, 0xcf, 0xb0, 0x10, 0xbc, 0xbb, 0x46, 0x61, 0x8a, 0x00, 0x64, 0xc0, 0x52, 0xf4, 0xa4, 0xcd, + 0xf8, 0xc6, 0x2e, 0x84, 0xaf, 0x19, 0xda, 0x82, 0x4b, 0x3e, 0x91, 0x9a, 0xf4, 0x89, 0x6d, 0x86, + 0xd5, 0x79, 0x2f, 0x58, 0x11, 0x46, 0x31, 0x72, 0xdd, 0x93, 0xe1, 0xad, 0xde, 0x27, 0x7b, 0x70, + 0x69, 0x4a, 0x66, 0x2d, 0x81, 0xc5, 0x90, 0xa3, 0x1c, 0x2c, 0x34, 0xf7, 0x0e, 0x1a, 0xfb, 0x07, + 0x5f, 0x15, 0xe7, 0x10, 0x40, 0x76, 0x67, 0xb7, 0xbd, 0xff, 0x64, 0xaf, 0xa8, 0xa1, 0x3c, 0x2c, + 0x1e, 0x1e, 0xd4, 0x1f, 0x1f, 0x34, 0xf6, 0x1a, 0xc5, 0x14, 0x5a, 0x80, 0xf4, 0xce, 0xc1, 0xb7, + 0xc5, 0x74, 0xfd, 0xe1, 0xef, 0x2f, 0x37, 0xb4, 0xe7, 0x2f, 0x37, 0xb4, 0x3f, 0x5f, 0x6e, 0x68, + 0xbf, 0xbc, 0xda, 0x98, 0x7b, 0xfe, 0x6a, 0x63, 0xee, 0x8f, 0x57, 0x1b, 0x73, 0xdf, 0xfd, 0xe7, + 0x65, 0xc6, 0xc9, 0x4f, 0x7b, 0x75, 0xb3, 0x4e, 0x56, 0x7d, 0xda, 0xdf, 0xfe, 0x27, 0x00, 0x00, + 0xff, 0xff, 0xbf, 0xab, 0xbe, 0x1d, 0x93, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -861,9 +861,9 @@ func (m *FinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if m.Inactive { + if m.Sluggish { i-- - if m.Inactive { + if m.Sluggish { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -959,9 +959,9 @@ func (m *FinalityProviderWithMeta) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l - if m.Inactive { + if m.Sluggish { i-- - if m.Inactive { + if m.Sluggish { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -1505,7 +1505,7 @@ func (m *FinalityProvider) Size() (n int) { if m.SlashedBtcHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBtcHeight)) } - if m.Inactive { + if m.Sluggish { n += 2 } return n @@ -1533,7 +1533,7 @@ func (m *FinalityProviderWithMeta) Size() (n int) { if m.SlashedBtcHeight != 0 { n += 1 + sovBtcstaking(uint64(m.SlashedBtcHeight)) } - if m.Inactive { + if m.Sluggish { n += 2 } return n @@ -1980,7 +1980,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { } case 8: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sluggish", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -1997,7 +1997,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { break } } - m.Inactive = bool(v != 0) + m.Sluggish = bool(v != 0) default: iNdEx = preIndex skippy, err := skipBtcstaking(dAtA[iNdEx:]) @@ -2161,7 +2161,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { } case 6: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sluggish", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -2178,7 +2178,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { break } } - m.Inactive = bool(v != 0) + m.Sluggish = bool(v != 0) default: iNdEx = preIndex skippy, err := skipBtcstaking(dAtA[iNdEx:]) diff --git a/x/btcstaking/types/query.go b/x/btcstaking/types/query.go index 717228035..1caecf29e 100644 --- a/x/btcstaking/types/query.go +++ b/x/btcstaking/types/query.go @@ -66,6 +66,7 @@ func NewFinalityProviderResponse(f *FinalityProvider, bbnBlockHeight, votingPowe Pop: f.Pop, SlashedBabylonHeight: f.SlashedBabylonHeight, SlashedBtcHeight: f.SlashedBtcHeight, + Sluggish: f.Sluggish, Height: bbnBlockHeight, VotingPower: votingPower, } diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 88a252b59..369f69ab9 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -1504,8 +1504,8 @@ type FinalityProviderResponse struct { Height uint64 `protobuf:"varint,8,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height VotingPower uint64 `protobuf:"varint,9,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` - // inactive defines whether the finality provider is detected inactive - Inactive bool `protobuf:"varint,10,opt,name=inactive,proto3" json:"inactive,omitempty"` + // sluggish defines whether the finality provider is detected sluggish + Sluggish bool `protobuf:"varint,10,opt,name=sluggish,proto3" json:"sluggish,omitempty"` } func (m *FinalityProviderResponse) Reset() { *m = FinalityProviderResponse{} } @@ -1590,9 +1590,9 @@ func (m *FinalityProviderResponse) GetVotingPower() uint64 { return 0 } -func (m *FinalityProviderResponse) GetInactive() bool { +func (m *FinalityProviderResponse) GetSluggish() bool { if m != nil { - return m.Inactive + return m.Sluggish } return false } @@ -1629,125 +1629,125 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1881 bytes of a gzipped FileDescriptorProto + // 1884 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6c, 0xdb, 0xc8, 0x19, 0x0e, 0x6d, 0x45, 0xb1, 0x7f, 0xd9, 0x8e, 0x33, 0xeb, 0x24, 0x8c, 0x1c, 0xdb, 0x09, 0x9b, 0x4d, 0x9c, 0x97, 0x18, 0x2b, 0xde, 0x14, 0xed, 0x76, 0x37, 0xb1, 0xec, 0xdd, 0x24, 0xbb, 0x31, - 0xa2, 0xd2, 0x49, 0x0b, 0x74, 0x8b, 0x12, 0x14, 0x39, 0xa2, 0x88, 0x58, 0x24, 0xc3, 0x19, 0xb9, + 0xa2, 0xd2, 0x49, 0x0b, 0x74, 0x8b, 0x12, 0x14, 0x39, 0xa2, 0x88, 0xc8, 0x24, 0xc3, 0x19, 0xb9, 0x32, 0x02, 0x5f, 0x7a, 0xe8, 0xad, 0x40, 0x81, 0xf6, 0xda, 0xf3, 0x16, 0xe8, 0xb1, 0x39, 0x15, 0xe8, 0x7d, 0x7b, 0x5b, 0x64, 0x0f, 0x2d, 0xf6, 0x10, 0x14, 0x49, 0xd1, 0x02, 0x05, 0x7a, 0xed, 0xb9, 0xe0, 0xcc, 0x50, 0xa4, 0x24, 0x52, 0x0f, 0xc7, 0xbd, 0x89, 0x33, 0xff, 0xfb, 0xf1, 0xcd, - 0xcc, 0x2f, 0xb8, 0x58, 0x33, 0x6a, 0xfb, 0xbb, 0x9e, 0xab, 0xd6, 0xa8, 0x49, 0xa8, 0xf1, 0xcc, - 0x71, 0x6d, 0x75, 0x6f, 0x4d, 0x7d, 0xde, 0xc2, 0xc1, 0x7e, 0xc9, 0x0f, 0x3c, 0xea, 0xa1, 0xd3, - 0x82, 0xa4, 0x14, 0x93, 0x94, 0xf6, 0xd6, 0x8a, 0x0b, 0xb6, 0x67, 0x7b, 0x8c, 0x42, 0x0d, 0x7f, - 0x71, 0xe2, 0xe2, 0x79, 0xdb, 0xf3, 0xec, 0x5d, 0xac, 0x1a, 0xbe, 0xa3, 0x1a, 0xae, 0xeb, 0x51, - 0x83, 0x3a, 0x9e, 0x4b, 0xc4, 0xee, 0x39, 0xd3, 0x23, 0x4d, 0x8f, 0xe8, 0x9c, 0x8d, 0x7f, 0x88, - 0xad, 0x4b, 0xfc, 0x4b, 0x8d, 0x8d, 0xa8, 0x61, 0x6a, 0xac, 0x45, 0xdf, 0x82, 0xea, 0x9a, 0xa0, - 0xaa, 0x19, 0x04, 0x73, 0x23, 0x3b, 0x84, 0xbe, 0x61, 0x3b, 0x2e, 0xd3, 0x26, 0x68, 0x95, 0x74, - 0xd7, 0x7c, 0x23, 0x30, 0x9a, 0x91, 0xd6, 0xcb, 0xe9, 0x34, 0x09, 0x4f, 0x39, 0xdd, 0x4a, 0x86, + 0xcc, 0x2f, 0xb8, 0x58, 0x33, 0x6a, 0xfb, 0x4d, 0xcf, 0x55, 0x6b, 0xd4, 0x24, 0xd4, 0x78, 0xe6, + 0xb8, 0xb6, 0xba, 0xb7, 0xa6, 0x3e, 0x6f, 0xe1, 0x60, 0xbf, 0xe4, 0x07, 0x1e, 0xf5, 0xd0, 0x69, + 0x41, 0x52, 0x8a, 0x49, 0x4a, 0x7b, 0x6b, 0xc5, 0x05, 0xdb, 0xb3, 0x3d, 0x46, 0xa1, 0x86, 0xbf, + 0x38, 0x71, 0xf1, 0xbc, 0xed, 0x79, 0x76, 0x13, 0xab, 0x86, 0xef, 0xa8, 0x86, 0xeb, 0x7a, 0xd4, + 0xa0, 0x8e, 0xe7, 0x12, 0xb1, 0x7b, 0xce, 0xf4, 0xc8, 0xae, 0x47, 0x74, 0xce, 0xc6, 0x3f, 0xc4, + 0xd6, 0x25, 0xfe, 0xa5, 0xc6, 0x46, 0xd4, 0x30, 0x35, 0xd6, 0xa2, 0x6f, 0x41, 0x75, 0x4d, 0x50, + 0xd5, 0x0c, 0x82, 0xb9, 0x91, 0x1d, 0x42, 0xdf, 0xb0, 0x1d, 0x97, 0x69, 0x13, 0xb4, 0x4a, 0xba, + 0x6b, 0xbe, 0x11, 0x18, 0xbb, 0x91, 0xd6, 0xcb, 0xe9, 0x34, 0x09, 0x4f, 0x39, 0xdd, 0x4a, 0x86, 0x2c, 0xcf, 0xe7, 0x04, 0xca, 0x02, 0xa0, 0x1f, 0x86, 0xe6, 0x54, 0x99, 0x74, 0x0d, 0x3f, 0x6f, 0x61, 0x42, 0x15, 0x0d, 0xde, 0xeb, 0x5a, 0x25, 0xbe, 0xe7, 0x12, 0x8c, 0x3e, 0x84, 0x3c, 0xb7, 0x42, 0x96, 0x2e, 0x48, 0xab, 0x85, 0xf2, 0x52, 0x29, 0x35, 0xc4, 0x25, 0xce, 0x56, 0xc9, 0x7d, 0xf5, 0x7a, 0xe5, 0x98, 0x26, 0x58, 0x94, 0xef, 0xc2, 0x62, 0x42, 0x66, 0x65, 0xff, 0x47, 0x38, 0x20, 0x8e, 0xe7, 0x0a, 0x95, 0x48, 0x86, 0x13, 0x7b, 0x7c, 0x85, 0x09, 0x9f, 0xd5, 0xa2, 0x4f, - 0xe5, 0x0b, 0x38, 0x9f, 0xce, 0x78, 0x14, 0x56, 0xd9, 0xb0, 0xc4, 0x84, 0x7f, 0xea, 0xb8, 0xc6, - 0xae, 0x43, 0xf7, 0xab, 0x81, 0xb7, 0xe7, 0x58, 0x38, 0x88, 0x42, 0x81, 0x3e, 0x05, 0x88, 0x33, - 0x24, 0x34, 0x5c, 0x2e, 0x89, 0x12, 0x08, 0xd3, 0x59, 0xe2, 0x35, 0x27, 0xd2, 0x59, 0xaa, 0x1a, - 0x36, 0x16, 0xbc, 0x5a, 0x82, 0x53, 0xf9, 0x8b, 0x04, 0xcb, 0x59, 0x9a, 0x84, 0x23, 0x3f, 0x03, - 0x54, 0x17, 0x9b, 0x61, 0xa5, 0xf1, 0x5d, 0x59, 0xba, 0x30, 0xb9, 0x5a, 0x28, 0xab, 0x19, 0x4e, - 0xf5, 0x4a, 0x8b, 0x84, 0x69, 0xa7, 0xea, 0xbd, 0x7a, 0xd0, 0xfd, 0x2e, 0x57, 0x26, 0x98, 0x2b, - 0x57, 0x86, 0xba, 0x22, 0xe4, 0x25, 0x7d, 0xd9, 0x10, 0x19, 0xe9, 0x57, 0xce, 0x63, 0x76, 0x11, - 0x66, 0xeb, 0xbe, 0x5e, 0xa3, 0xa6, 0xee, 0x3f, 0xd3, 0x1b, 0xb8, 0xcd, 0xc2, 0x36, 0xad, 0x41, - 0xdd, 0xaf, 0x50, 0xb3, 0xfa, 0xec, 0x01, 0x6e, 0x2b, 0x07, 0x19, 0x71, 0xef, 0x04, 0xe3, 0xa7, - 0x70, 0xaa, 0x2f, 0x18, 0x22, 0xfc, 0x63, 0xc7, 0x62, 0xbe, 0x37, 0x16, 0xca, 0xef, 0x25, 0x28, - 0x32, 0xfd, 0x95, 0x27, 0x9b, 0x5b, 0x78, 0x17, 0xdb, 0xbc, 0xdd, 0x23, 0x07, 0x2a, 0x90, 0x27, - 0xd4, 0xa0, 0x2d, 0x5e, 0x52, 0x73, 0xe5, 0x6b, 0x19, 0x1a, 0xbb, 0xb8, 0x77, 0x18, 0x87, 0x26, - 0x38, 0x7b, 0x0a, 0x67, 0xe2, 0xd0, 0x85, 0xf3, 0x67, 0x49, 0x34, 0x4e, 0xaf, 0xa9, 0x22, 0x50, - 0x4f, 0xe1, 0x64, 0x18, 0x69, 0x2b, 0xde, 0x12, 0x25, 0x73, 0x63, 0x14, 0xa3, 0x3b, 0x31, 0x9a, - 0xab, 0x51, 0x33, 0x21, 0xfe, 0xe8, 0x8a, 0xa5, 0x0e, 0x57, 0x53, 0x33, 0x5d, 0xf5, 0x7e, 0x8e, - 0x83, 0x0d, 0xfa, 0x00, 0x3b, 0x76, 0x83, 0x8e, 0x5e, 0x39, 0xe8, 0x0c, 0xe4, 0x1b, 0x8c, 0x87, - 0x19, 0x95, 0xd3, 0xc4, 0x97, 0xf2, 0x18, 0xae, 0x8d, 0xa2, 0x47, 0x44, 0xed, 0x22, 0xcc, 0xec, - 0x79, 0xd4, 0x71, 0x6d, 0xdd, 0x0f, 0xf7, 0x99, 0x9e, 0x9c, 0x56, 0xe0, 0x6b, 0x8c, 0x45, 0xd9, - 0x86, 0xd5, 0x54, 0x81, 0x9b, 0xad, 0x20, 0xc0, 0x2e, 0x65, 0x44, 0x63, 0x54, 0x7c, 0x56, 0x1c, - 0xba, 0xc5, 0x09, 0xf3, 0x62, 0x27, 0xa5, 0xa4, 0x93, 0x7d, 0x66, 0x4f, 0xf4, 0x9b, 0xfd, 0x2b, - 0x09, 0xae, 0x33, 0x45, 0x1b, 0x26, 0x75, 0xf6, 0x70, 0x1f, 0xdc, 0xf4, 0x86, 0x3c, 0x4b, 0xd5, - 0x51, 0xd5, 0xef, 0x5f, 0x25, 0xb8, 0x31, 0x9a, 0x3d, 0x47, 0x08, 0x83, 0x3f, 0x76, 0x68, 0x63, - 0x1b, 0x53, 0xe3, 0xff, 0x0a, 0x83, 0x4b, 0xa2, 0x31, 0x99, 0x63, 0x06, 0xc5, 0x56, 0x57, 0x60, - 0x95, 0x3b, 0x02, 0x25, 0xfb, 0xb6, 0x07, 0xe7, 0x58, 0xf9, 0xad, 0x04, 0x57, 0x52, 0x2b, 0x25, - 0x05, 0xa8, 0x46, 0xe8, 0x97, 0xa3, 0xca, 0xe3, 0xbf, 0xa4, 0x8c, 0x7e, 0x48, 0x03, 0xa5, 0x00, - 0xce, 0x25, 0x40, 0xc9, 0x0b, 0x52, 0xe0, 0xe9, 0xce, 0x50, 0x78, 0xf2, 0xd2, 0x44, 0x6b, 0x67, - 0x63, 0xa0, 0xea, 0x22, 0x38, 0xba, 0xbc, 0x7e, 0x06, 0xe7, 0xfa, 0x01, 0x37, 0x8a, 0xf8, 0x4d, - 0x78, 0x4f, 0x18, 0xab, 0xd3, 0xb6, 0xde, 0x30, 0x48, 0x23, 0x11, 0xf7, 0x79, 0xb1, 0xf5, 0xa4, - 0xfd, 0xc0, 0x20, 0x8d, 0xb0, 0xeb, 0x9f, 0xa7, 0x9d, 0x33, 0x9d, 0x30, 0xed, 0xc0, 0x5c, 0x37, - 0x76, 0x8b, 0x13, 0x6e, 0x3c, 0xe8, 0x9e, 0xed, 0x82, 0x6e, 0xe5, 0x9b, 0x3c, 0x9c, 0x4e, 0x57, - 0xf7, 0x3d, 0x28, 0x84, 0xc2, 0x70, 0xa0, 0x1b, 0x96, 0xc5, 0x31, 0x6f, 0xba, 0x22, 0xbf, 0x7a, - 0x79, 0x73, 0x41, 0x44, 0x69, 0xc3, 0xb2, 0x02, 0x4c, 0xc8, 0x0e, 0x0d, 0x1c, 0xd7, 0xd6, 0x80, - 0x13, 0x87, 0x8b, 0x68, 0x1b, 0xf2, 0xbc, 0xca, 0x58, 0x60, 0x67, 0x2a, 0x77, 0xbe, 0x7d, 0xbd, - 0x52, 0xb6, 0x1d, 0xda, 0x68, 0xd5, 0x4a, 0xa6, 0xd7, 0x54, 0x85, 0xbd, 0x66, 0xc3, 0x70, 0xdc, - 0xe8, 0x43, 0xa5, 0xfb, 0x3e, 0x26, 0xa5, 0xca, 0xc3, 0xea, 0xed, 0xf5, 0x5b, 0xd5, 0x56, 0xed, - 0x73, 0xbc, 0xaf, 0x1d, 0xaf, 0x85, 0x75, 0x89, 0xbe, 0x80, 0xb9, 0xb8, 0x6e, 0x77, 0x1d, 0x42, - 0xe5, 0xc9, 0x0b, 0x93, 0xef, 0x20, 0xb6, 0x20, 0x0a, 0xfe, 0x91, 0xc3, 0x9a, 0x62, 0x86, 0x50, - 0x23, 0xa0, 0xba, 0x68, 0xaf, 0x1c, 0x07, 0x49, 0xb6, 0xc6, 0x7b, 0x10, 0x2d, 0x01, 0x60, 0xd7, - 0x8a, 0x08, 0x8e, 0x33, 0x82, 0x69, 0xec, 0x8a, 0x16, 0x45, 0x8b, 0x30, 0x4d, 0x3d, 0x6a, 0xec, - 0xea, 0xc4, 0xa0, 0x72, 0x9e, 0xed, 0x4e, 0xb1, 0x85, 0x1d, 0x83, 0xa2, 0x4b, 0x30, 0x97, 0xac, - 0x00, 0xdc, 0x96, 0x4f, 0xb0, 0xe4, 0xcf, 0xc4, 0xc9, 0xc7, 0x6d, 0x74, 0x19, 0x4e, 0x92, 0x5d, - 0x83, 0x34, 0x12, 0x64, 0x53, 0x8c, 0x6c, 0x36, 0x5a, 0xe6, 0x74, 0x1f, 0xc0, 0xd9, 0xb8, 0x4b, - 0xd8, 0x96, 0x4e, 0x1c, 0x9b, 0xd1, 0x4f, 0x33, 0xfa, 0x85, 0xce, 0xf6, 0x4e, 0xb8, 0xbb, 0xe3, - 0xd8, 0x21, 0xdb, 0x53, 0x98, 0x35, 0xbd, 0x3d, 0xec, 0x1a, 0x2e, 0x0d, 0xe9, 0x89, 0x0c, 0xac, - 0xa9, 0x6e, 0x65, 0x14, 0xce, 0xa6, 0xa0, 0xdd, 0xb0, 0x0c, 0x3f, 0x94, 0xe4, 0xd8, 0xae, 0x41, - 0x5b, 0x01, 0x26, 0xda, 0x4c, 0x24, 0x66, 0xc7, 0xb1, 0x09, 0xba, 0x01, 0x28, 0xf2, 0xcd, 0x6b, - 0x51, 0xbf, 0x45, 0x75, 0xc7, 0x6a, 0xcb, 0x05, 0x76, 0x21, 0x8f, 0x8a, 0xfb, 0x31, 0xdb, 0x78, - 0x68, 0xb1, 0xa3, 0xd8, 0x60, 0xa0, 0x2e, 0xcf, 0x5c, 0x90, 0x56, 0xa7, 0x34, 0xf1, 0x85, 0x56, - 0x58, 0x9d, 0xd1, 0x16, 0xd1, 0x2d, 0x4c, 0x4c, 0x79, 0x96, 0x63, 0x12, 0x5f, 0xda, 0xc2, 0xc4, - 0x44, 0xef, 0xc3, 0x5c, 0xcb, 0xad, 0x79, 0xae, 0xc5, 0xa2, 0xe3, 0x34, 0xb1, 0x3c, 0xc7, 0x54, - 0xcc, 0x76, 0x56, 0x9f, 0x38, 0x4d, 0x8c, 0x4c, 0x38, 0xdd, 0x72, 0xe3, 0xe6, 0xd0, 0x03, 0x51, - 0xc8, 0xf2, 0x49, 0xd6, 0x25, 0xa5, 0xec, 0x2e, 0x79, 0x9a, 0x60, 0xeb, 0xf4, 0xc9, 0x42, 0x2b, - 0x65, 0x35, 0xb4, 0x85, 0xbf, 0x05, 0xf4, 0xe8, 0xfd, 0x31, 0xcf, 0x6d, 0xe1, 0xab, 0xe2, 0xb5, - 0xa1, 0xbc, 0x9c, 0x84, 0xb3, 0x19, 0x82, 0xd1, 0x2a, 0xcc, 0x27, 0xdc, 0x69, 0x27, 0x00, 0x21, - 0x76, 0x93, 0x67, 0xfb, 0x23, 0x58, 0x8c, 0xb3, 0x1d, 0xf3, 0x44, 0x19, 0x9f, 0x60, 0x4c, 0x72, - 0x87, 0xe4, 0x69, 0x44, 0x21, 0xb2, 0x6e, 0xc2, 0x62, 0x27, 0xeb, 0xdd, 0xdc, 0x9d, 0x1e, 0x2a, - 0x94, 0x2f, 0x65, 0x84, 0xa5, 0x93, 0xf4, 0x87, 0x6e, 0xdd, 0xd3, 0xe4, 0x48, 0x50, 0x52, 0x07, - 0x6b, 0x9f, 0x94, 0xca, 0xcd, 0xa5, 0x55, 0xee, 0x87, 0x50, 0xec, 0xa9, 0xdc, 0xa4, 0x2b, 0xc7, - 0x19, 0xcb, 0xd9, 0xee, 0xe2, 0x8d, 0x3d, 0xa9, 0xc3, 0x99, 0xb8, 0x7e, 0x13, 0xbc, 0x44, 0xce, - 0x1f, 0xb2, 0x90, 0x17, 0x3a, 0x85, 0x1c, 0x6b, 0x22, 0x8a, 0x09, 0x2b, 0x43, 0x0e, 0x14, 0x74, - 0x0f, 0x72, 0x16, 0xde, 0x3d, 0xdc, 0xad, 0x99, 0x71, 0x2a, 0x5f, 0xe6, 0x40, 0xce, 0x7c, 0xc8, - 0x7c, 0x02, 0x85, 0xb0, 0x0b, 0x02, 0xc7, 0x4f, 0x00, 0xfc, 0x77, 0xa2, 0x73, 0x29, 0xd6, 0xc0, - 0x0f, 0xa5, 0xad, 0x98, 0x54, 0x4b, 0xf2, 0xa1, 0x6d, 0x00, 0xd3, 0x6b, 0x36, 0x1d, 0x42, 0xa2, - 0xd3, 0x6d, 0xba, 0x72, 0xf3, 0xdb, 0xd7, 0x2b, 0x8b, 0x5c, 0x10, 0xb1, 0x9e, 0x95, 0x1c, 0x4f, - 0x6d, 0x1a, 0xb4, 0x51, 0x7a, 0x84, 0x6d, 0xc3, 0xdc, 0xdf, 0xc2, 0xe6, 0xab, 0x97, 0x37, 0x41, + 0xe5, 0x0b, 0x38, 0x9f, 0xce, 0x78, 0x14, 0x56, 0xd9, 0xb0, 0xc4, 0x84, 0x7f, 0xea, 0xb8, 0x46, + 0xd3, 0xa1, 0xfb, 0xd5, 0xc0, 0xdb, 0x73, 0x2c, 0x1c, 0x44, 0xa1, 0x40, 0x9f, 0x02, 0xc4, 0x19, + 0x12, 0x1a, 0x2e, 0x97, 0x44, 0x09, 0x84, 0xe9, 0x2c, 0xf1, 0x9a, 0x13, 0xe9, 0x2c, 0x55, 0x0d, + 0x1b, 0x0b, 0x5e, 0x2d, 0xc1, 0xa9, 0xfc, 0x45, 0x82, 0xe5, 0x2c, 0x4d, 0xc2, 0x91, 0x9f, 0x01, + 0xaa, 0x8b, 0xcd, 0xb0, 0xd2, 0xf8, 0xae, 0x2c, 0x5d, 0x98, 0x5c, 0x2d, 0x94, 0xd5, 0x0c, 0xa7, + 0x7a, 0xa5, 0x45, 0xc2, 0xb4, 0x53, 0xf5, 0x5e, 0x3d, 0xe8, 0x7e, 0x97, 0x2b, 0x13, 0xcc, 0x95, + 0x2b, 0x43, 0x5d, 0x11, 0xf2, 0x92, 0xbe, 0x6c, 0x88, 0x8c, 0xf4, 0x2b, 0xe7, 0x31, 0xbb, 0x08, + 0xb3, 0x75, 0x5f, 0xaf, 0x51, 0x53, 0xf7, 0x9f, 0xe9, 0x0d, 0xdc, 0x66, 0x61, 0x9b, 0xd6, 0xa0, + 0xee, 0x57, 0xa8, 0x59, 0x7d, 0xf6, 0x00, 0xb7, 0x95, 0x83, 0x8c, 0xb8, 0x77, 0x82, 0xf1, 0x53, + 0x38, 0xd5, 0x17, 0x0c, 0x11, 0xfe, 0xb1, 0x63, 0x31, 0xdf, 0x1b, 0x0b, 0xe5, 0xf7, 0x12, 0x14, + 0x99, 0xfe, 0xca, 0x93, 0xcd, 0x2d, 0xdc, 0xc4, 0x36, 0x6f, 0xf7, 0xc8, 0x81, 0x0a, 0xe4, 0x09, + 0x35, 0x68, 0x8b, 0x97, 0xd4, 0x5c, 0xf9, 0x5a, 0x86, 0xc6, 0x2e, 0xee, 0x1d, 0xc6, 0xa1, 0x09, + 0xce, 0x9e, 0xc2, 0x99, 0x38, 0x74, 0xe1, 0xfc, 0x59, 0x12, 0x8d, 0xd3, 0x6b, 0xaa, 0x08, 0xd4, + 0x53, 0x38, 0x19, 0x46, 0xda, 0x8a, 0xb7, 0x44, 0xc9, 0xdc, 0x18, 0xc5, 0xe8, 0x4e, 0x8c, 0xe6, + 0x6a, 0xd4, 0x4c, 0x88, 0x3f, 0xba, 0x62, 0xa9, 0xc3, 0xd5, 0xd4, 0x4c, 0x57, 0xbd, 0x9f, 0xe3, + 0x60, 0x83, 0x3e, 0xc0, 0x8e, 0xdd, 0xa0, 0xa3, 0x57, 0x0e, 0x3a, 0x03, 0xf9, 0x06, 0xe3, 0x61, + 0x46, 0xe5, 0x34, 0xf1, 0xa5, 0x3c, 0x86, 0x6b, 0xa3, 0xe8, 0x11, 0x51, 0xbb, 0x08, 0x33, 0x7b, + 0x1e, 0x75, 0x5c, 0x5b, 0xf7, 0xc3, 0x7d, 0xa6, 0x27, 0xa7, 0x15, 0xf8, 0x1a, 0x63, 0x51, 0xb6, + 0x61, 0x35, 0x55, 0xe0, 0x66, 0x2b, 0x08, 0xb0, 0x4b, 0x19, 0xd1, 0x18, 0x15, 0x9f, 0x15, 0x87, + 0x6e, 0x71, 0xc2, 0xbc, 0xd8, 0x49, 0x29, 0xe9, 0x64, 0x9f, 0xd9, 0x13, 0xfd, 0x66, 0xff, 0x4a, + 0x82, 0xeb, 0x4c, 0xd1, 0x86, 0x49, 0x9d, 0x3d, 0xdc, 0x07, 0x37, 0xbd, 0x21, 0xcf, 0x52, 0x75, + 0x54, 0xf5, 0xfb, 0x57, 0x09, 0x6e, 0x8c, 0x66, 0xcf, 0x11, 0xc2, 0xe0, 0x8f, 0x1d, 0xda, 0xd8, + 0xc6, 0xd4, 0xf8, 0xbf, 0xc2, 0xe0, 0x92, 0x68, 0x4c, 0xe6, 0x98, 0x41, 0xb1, 0xd5, 0x15, 0x58, + 0xe5, 0x8e, 0x40, 0xc9, 0xbe, 0xed, 0xc1, 0x39, 0x56, 0x7e, 0x2b, 0xc1, 0x95, 0xd4, 0x4a, 0x49, + 0x01, 0xaa, 0x11, 0xfa, 0xe5, 0xa8, 0xf2, 0xf8, 0x2f, 0x29, 0xa3, 0x1f, 0xd2, 0x40, 0x29, 0x80, + 0x73, 0x09, 0x50, 0xf2, 0x82, 0x14, 0x78, 0xba, 0x33, 0x14, 0x9e, 0xbc, 0x34, 0xd1, 0xda, 0xd9, + 0x18, 0xa8, 0xba, 0x08, 0x8e, 0x2e, 0xaf, 0x9f, 0xc1, 0xb9, 0x7e, 0xc0, 0x8d, 0x22, 0x7e, 0x13, + 0xde, 0x13, 0xc6, 0xea, 0xb4, 0xad, 0x37, 0x0c, 0xd2, 0x48, 0xc4, 0x7d, 0x5e, 0x6c, 0x3d, 0x69, + 0x3f, 0x30, 0x48, 0x23, 0xec, 0xfa, 0xe7, 0x69, 0xe7, 0x4c, 0x27, 0x4c, 0x3b, 0x30, 0xd7, 0x8d, + 0xdd, 0xe2, 0x84, 0x1b, 0x0f, 0xba, 0x67, 0xbb, 0xa0, 0x5b, 0xf9, 0x26, 0x0f, 0xa7, 0xd3, 0xd5, + 0x7d, 0x0f, 0x0a, 0xa1, 0x30, 0x1c, 0xe8, 0x86, 0x65, 0x71, 0xcc, 0x9b, 0xae, 0xc8, 0xaf, 0x5e, + 0xde, 0x5c, 0x10, 0x51, 0xda, 0xb0, 0xac, 0x00, 0x13, 0xb2, 0x43, 0x03, 0xc7, 0xb5, 0x35, 0xe0, + 0xc4, 0xe1, 0x22, 0xda, 0x86, 0x3c, 0xaf, 0x32, 0x16, 0xd8, 0x99, 0xca, 0x9d, 0x6f, 0x5f, 0xaf, + 0x94, 0x6d, 0x87, 0x36, 0x5a, 0xb5, 0x92, 0xe9, 0xed, 0xaa, 0xc2, 0x5e, 0xb3, 0x61, 0x38, 0x6e, + 0xf4, 0xa1, 0xd2, 0x7d, 0x1f, 0x93, 0x52, 0xe5, 0x61, 0xf5, 0xf6, 0xfa, 0xad, 0x6a, 0xab, 0xf6, + 0x39, 0xde, 0xd7, 0x8e, 0xd7, 0xc2, 0xba, 0x44, 0x5f, 0xc0, 0x5c, 0x5c, 0xb7, 0x4d, 0x87, 0x50, + 0x79, 0xf2, 0xc2, 0xe4, 0x3b, 0x88, 0x2d, 0x88, 0x82, 0x7f, 0xe4, 0xb0, 0xa6, 0x98, 0x21, 0xd4, + 0x08, 0xa8, 0x2e, 0xda, 0x2b, 0xc7, 0x41, 0x92, 0xad, 0xf1, 0x1e, 0x44, 0x4b, 0x00, 0xd8, 0xb5, + 0x22, 0x82, 0xe3, 0x8c, 0x60, 0x1a, 0xbb, 0xa2, 0x45, 0xd1, 0x22, 0x4c, 0x53, 0x8f, 0x1a, 0x4d, + 0x9d, 0x18, 0x54, 0xce, 0xb3, 0xdd, 0x29, 0xb6, 0xb0, 0x63, 0x50, 0x74, 0x09, 0xe6, 0x92, 0x15, + 0x80, 0xdb, 0xf2, 0x09, 0x96, 0xfc, 0x99, 0x38, 0xf9, 0xb8, 0x8d, 0x2e, 0xc3, 0x49, 0xd2, 0x34, + 0x48, 0x23, 0x41, 0x36, 0xc5, 0xc8, 0x66, 0xa3, 0x65, 0x4e, 0xf7, 0x01, 0x9c, 0x8d, 0xbb, 0x84, + 0x6d, 0xe9, 0xc4, 0xb1, 0x19, 0xfd, 0x34, 0xa3, 0x5f, 0xe8, 0x6c, 0xef, 0x84, 0xbb, 0x3b, 0x8e, + 0x1d, 0xb2, 0x3d, 0x85, 0x59, 0xd3, 0xdb, 0xc3, 0xae, 0xe1, 0xd2, 0x90, 0x9e, 0xc8, 0xc0, 0x9a, + 0xea, 0x56, 0x46, 0xe1, 0x6c, 0x0a, 0xda, 0x0d, 0xcb, 0xf0, 0x43, 0x49, 0x8e, 0xed, 0x1a, 0xb4, + 0x15, 0x60, 0xa2, 0xcd, 0x44, 0x62, 0x76, 0x1c, 0x9b, 0xa0, 0x1b, 0x80, 0x22, 0xdf, 0xbc, 0x16, + 0xf5, 0x5b, 0x54, 0x77, 0xac, 0xb6, 0x5c, 0x60, 0x17, 0xf2, 0xa8, 0xb8, 0x1f, 0xb3, 0x8d, 0x87, + 0x16, 0x3b, 0x8a, 0x0d, 0x06, 0xea, 0xf2, 0xcc, 0x05, 0x69, 0x75, 0x4a, 0x13, 0x5f, 0x68, 0x85, + 0xd5, 0x19, 0x6d, 0x11, 0xdd, 0xc2, 0xc4, 0x94, 0x67, 0x39, 0x26, 0xf1, 0xa5, 0x2d, 0x4c, 0x4c, + 0xf4, 0x3e, 0xcc, 0xb5, 0xdc, 0x9a, 0xe7, 0x5a, 0x2c, 0x3a, 0xce, 0x2e, 0x96, 0xe7, 0x98, 0x8a, + 0xd9, 0xce, 0xea, 0x13, 0x67, 0x17, 0x23, 0x13, 0x4e, 0xb7, 0xdc, 0xb8, 0x39, 0xf4, 0x40, 0x14, + 0xb2, 0x7c, 0x92, 0x75, 0x49, 0x29, 0xbb, 0x4b, 0x9e, 0x26, 0xd8, 0x3a, 0x7d, 0xb2, 0xd0, 0x4a, + 0x59, 0x0d, 0x6d, 0xe1, 0x6f, 0x01, 0x3d, 0x7a, 0x7f, 0xcc, 0x73, 0x5b, 0xf8, 0xaa, 0x78, 0x6d, + 0x28, 0x2f, 0x27, 0xe1, 0x6c, 0x86, 0x60, 0xb4, 0x0a, 0xf3, 0x09, 0x77, 0xda, 0x09, 0x40, 0x88, + 0xdd, 0xe4, 0xd9, 0xfe, 0x08, 0x16, 0xe3, 0x6c, 0xc7, 0x3c, 0x51, 0xc6, 0x27, 0x18, 0x93, 0xdc, + 0x21, 0x79, 0x1a, 0x51, 0x88, 0xac, 0x9b, 0xb0, 0xd8, 0xc9, 0x7a, 0x37, 0x77, 0xa7, 0x87, 0x0a, + 0xe5, 0x4b, 0x19, 0x61, 0xe9, 0x24, 0xfd, 0xa1, 0x5b, 0xf7, 0x34, 0x39, 0x12, 0x94, 0xd4, 0xc1, + 0xda, 0x27, 0xa5, 0x72, 0x73, 0x69, 0x95, 0xfb, 0x21, 0x14, 0x7b, 0x2a, 0x37, 0xe9, 0xca, 0x71, + 0xc6, 0x72, 0xb6, 0xbb, 0x78, 0x63, 0x4f, 0xea, 0x70, 0x26, 0xae, 0xdf, 0x04, 0x2f, 0x91, 0xf3, + 0x87, 0x2c, 0xe4, 0x85, 0x4e, 0x21, 0xc7, 0x9a, 0x88, 0x62, 0xc2, 0xca, 0x90, 0x03, 0x05, 0xdd, + 0x83, 0x9c, 0x85, 0x9b, 0x87, 0xbb, 0x35, 0x33, 0x4e, 0xe5, 0xcb, 0x1c, 0xc8, 0x99, 0x0f, 0x99, + 0x4f, 0xa0, 0x10, 0x76, 0x41, 0xe0, 0xf8, 0x09, 0x80, 0xff, 0x4e, 0x74, 0x2e, 0xc5, 0x1a, 0xf8, + 0xa1, 0xb4, 0x15, 0x93, 0x6a, 0x49, 0x3e, 0xb4, 0x0d, 0x60, 0x7a, 0xbb, 0xbb, 0x0e, 0x21, 0xd1, + 0xe9, 0x36, 0x5d, 0xb9, 0xf9, 0xed, 0xeb, 0x95, 0x45, 0x2e, 0x88, 0x58, 0xcf, 0x4a, 0x8e, 0xa7, + 0xee, 0x1a, 0xb4, 0x51, 0x7a, 0x84, 0x6d, 0xc3, 0xdc, 0xdf, 0xc2, 0xe6, 0xab, 0x97, 0x37, 0x41, 0xe8, 0xd9, 0xc2, 0xa6, 0x96, 0x10, 0x80, 0x6e, 0x40, 0x8e, 0x9d, 0x01, 0x93, 0x43, 0xce, 0x00, 0x46, 0x95, 0x40, 0xff, 0xdc, 0x51, 0xa0, 0xff, 0x47, 0x30, 0xe9, 0x7b, 0x3e, 0x2b, 0x91, 0x42, 0xf9, 0x7a, 0xd6, 0x73, 0x3d, 0xf0, 0xbc, 0xfa, 0xe3, 0x7a, 0xd5, 0x23, 0x04, 0x33, 0x9b, 0x2b, 0x4f, 0x36, 0xb5, 0x90, 0x0f, 0xad, 0xc3, 0x19, 0x56, 0x32, 0xd8, 0xd2, 0x05, 0x6b, 0x04, 0xe4, 0x1c, 0xaa, 0x17, 0xc4, 0x6e, 0x85, 0x6f, 0x0a, 0x4c, 0x0f, 0xa1, 0x2d, 0xe2, 0xa2, 0x66, 0xc4, 0x71, 0x82, 0x71, 0xcc, 0x47, 0x1c, 0xd4, 0x14, 0xd4, 0xf1, 0xe5, 0x6c, 0x6a, 0xe0, 0x05, 0x7c, - 0xba, 0xef, 0x02, 0x8e, 0x8a, 0x30, 0xe5, 0xb8, 0x02, 0x17, 0x81, 0xe1, 0x62, 0xe7, 0xbb, 0xfc, - 0xbb, 0x53, 0x70, 0x9c, 0xdd, 0x07, 0xd0, 0x2f, 0x25, 0xc8, 0xf3, 0x89, 0x04, 0xba, 0x9a, 0x11, - 0x81, 0xfe, 0xc1, 0x4c, 0xf1, 0xda, 0x28, 0xa4, 0xbc, 0xf0, 0x94, 0xf7, 0x7f, 0xf1, 0xcd, 0x3f, - 0x7e, 0x33, 0xb1, 0x82, 0x96, 0xd4, 0x41, 0x03, 0x25, 0xf4, 0x07, 0x09, 0x4e, 0xf6, 0x8c, 0x56, - 0x50, 0x79, 0xb8, 0x9a, 0xde, 0x01, 0x4e, 0xf1, 0xf6, 0x58, 0x3c, 0xc2, 0x46, 0x95, 0xd9, 0x78, - 0x15, 0x5d, 0x19, 0x68, 0xa3, 0xfa, 0x42, 0x40, 0xf3, 0x01, 0xfa, 0xa3, 0x04, 0xa7, 0xfa, 0x9e, - 0x10, 0x68, 0x7d, 0x90, 0xee, 0xac, 0xd1, 0x4e, 0xf1, 0x83, 0x31, 0xb9, 0x84, 0xcd, 0x6b, 0xcc, - 0xe6, 0xeb, 0xe8, 0x6a, 0x86, 0xcd, 0xfd, 0x8f, 0x17, 0xf4, 0x4a, 0x82, 0xf9, 0x5e, 0x81, 0xe8, - 0xf6, 0x38, 0xea, 0x23, 0x9b, 0xd7, 0xc7, 0x63, 0x12, 0x26, 0xef, 0x30, 0x93, 0xb7, 0xd1, 0xe7, - 0x23, 0x9b, 0xac, 0xbe, 0xe8, 0x7a, 0x57, 0x1c, 0xf4, 0x93, 0xa0, 0x2f, 0x25, 0x98, 0xeb, 0x9e, - 0x49, 0xa0, 0xb5, 0x41, 0xd6, 0xa5, 0x8e, 0x5a, 0x8a, 0xe5, 0x71, 0x58, 0x84, 0x3b, 0x25, 0xe6, - 0xce, 0x2a, 0xba, 0xac, 0x66, 0x8e, 0x41, 0x93, 0x0f, 0x0e, 0xf4, 0x4f, 0x09, 0x56, 0x86, 0xbc, - 0x3e, 0x51, 0x65, 0x90, 0x1d, 0xa3, 0x3d, 0xa5, 0x8b, 0x9b, 0xef, 0x24, 0x43, 0x38, 0xf7, 0x7d, - 0xe6, 0xdc, 0x3a, 0x2a, 0x8f, 0x91, 0x2b, 0x0e, 0x4e, 0x07, 0xe8, 0xbf, 0x12, 0x2c, 0x0d, 0x9c, - 0x7f, 0xa0, 0x7b, 0xe3, 0xd4, 0x4f, 0xda, 0x88, 0xa6, 0xb8, 0xf1, 0x0e, 0x12, 0x84, 0x8b, 0x55, - 0xe6, 0xe2, 0x67, 0xe8, 0xc1, 0xe1, 0xcb, 0x91, 0xa1, 0x6f, 0xec, 0xf8, 0xbf, 0x25, 0x38, 0x3f, - 0x68, 0xb0, 0x82, 0xee, 0x8e, 0x63, 0x75, 0xca, 0x84, 0xa7, 0x78, 0xef, 0xf0, 0x02, 0x84, 0xd7, - 0xf7, 0x99, 0xd7, 0x1b, 0xe8, 0xee, 0x3b, 0x7a, 0xcd, 0x10, 0xbb, 0x67, 0xa8, 0x30, 0x18, 0xb1, - 0xd3, 0x07, 0x14, 0x83, 0x11, 0x3b, 0x63, 0x6a, 0x31, 0x14, 0xb1, 0x8d, 0x88, 0x4f, 0x9c, 0xb0, - 0xe8, 0x3f, 0x12, 0x2c, 0x0e, 0x18, 0x19, 0xa0, 0x8f, 0xc7, 0x09, 0x6c, 0x0a, 0x80, 0xdc, 0x3d, - 0x34, 0xbf, 0xf0, 0x68, 0x9b, 0x79, 0x74, 0x1f, 0x7d, 0x72, 0xf8, 0xbc, 0x24, 0xc1, 0xe6, 0x4f, - 0x12, 0xcc, 0x76, 0xe1, 0x16, 0xba, 0x35, 0x32, 0xc4, 0x45, 0x3e, 0xad, 0x8d, 0xc1, 0x21, 0xbc, - 0xd8, 0x62, 0x5e, 0x7c, 0x8c, 0x7e, 0x30, 0x1a, 0x26, 0xaa, 0x2f, 0x52, 0xa6, 0x18, 0x07, 0x95, - 0x47, 0x5f, 0xbd, 0x59, 0x96, 0xbe, 0x7e, 0xb3, 0x2c, 0xfd, 0xfd, 0xcd, 0xb2, 0xf4, 0xeb, 0xb7, - 0xcb, 0xc7, 0xbe, 0x7e, 0xbb, 0x7c, 0xec, 0x6f, 0x6f, 0x97, 0x8f, 0xfd, 0x64, 0xe8, 0x75, 0xaf, - 0x9d, 0x54, 0xc8, 0xee, 0x7e, 0xb5, 0x3c, 0xfb, 0x8f, 0xe9, 0xf6, 0xff, 0x02, 0x00, 0x00, 0xff, - 0xff, 0x9d, 0x96, 0x10, 0xe8, 0xad, 0x1b, 0x00, 0x00, + 0xba, 0xef, 0x02, 0x8e, 0x8a, 0x30, 0x45, 0x9a, 0x2d, 0xdb, 0x76, 0x48, 0x43, 0x06, 0x86, 0x8b, + 0x9d, 0xef, 0xf2, 0xef, 0x4e, 0xc1, 0x71, 0x76, 0x1f, 0x40, 0xbf, 0x94, 0x20, 0xcf, 0x27, 0x12, + 0xe8, 0x6a, 0x46, 0x04, 0xfa, 0x07, 0x33, 0xc5, 0x6b, 0xa3, 0x90, 0xf2, 0xc2, 0x53, 0xde, 0xff, + 0xc5, 0x37, 0xff, 0xf8, 0xcd, 0xc4, 0x0a, 0x5a, 0x52, 0x07, 0x0d, 0x94, 0xd0, 0x1f, 0x24, 0x38, + 0xd9, 0x33, 0x5a, 0x41, 0xe5, 0xe1, 0x6a, 0x7a, 0x07, 0x38, 0xc5, 0xdb, 0x63, 0xf1, 0x08, 0x1b, + 0x55, 0x66, 0xe3, 0x55, 0x74, 0x65, 0xa0, 0x8d, 0xea, 0x0b, 0x01, 0xcd, 0x07, 0xe8, 0x8f, 0x12, + 0x9c, 0xea, 0x7b, 0x42, 0xa0, 0xf5, 0x41, 0xba, 0xb3, 0x46, 0x3b, 0xc5, 0x0f, 0xc6, 0xe4, 0x12, + 0x36, 0xaf, 0x31, 0x9b, 0xaf, 0xa3, 0xab, 0x19, 0x36, 0xf7, 0x3f, 0x5e, 0xd0, 0x2b, 0x09, 0xe6, + 0x7b, 0x05, 0xa2, 0xdb, 0xe3, 0xa8, 0x8f, 0x6c, 0x5e, 0x1f, 0x8f, 0x49, 0x98, 0xbc, 0xc3, 0x4c, + 0xde, 0x46, 0x9f, 0x8f, 0x6c, 0xb2, 0xfa, 0xa2, 0xeb, 0x5d, 0x71, 0xd0, 0x4f, 0x82, 0xbe, 0x94, + 0x60, 0xae, 0x7b, 0x26, 0x81, 0xd6, 0x06, 0x59, 0x97, 0x3a, 0x6a, 0x29, 0x96, 0xc7, 0x61, 0x11, + 0xee, 0x94, 0x98, 0x3b, 0xab, 0xe8, 0xb2, 0x9a, 0x39, 0x06, 0x4d, 0x3e, 0x38, 0xd0, 0x3f, 0x25, + 0x58, 0x19, 0xf2, 0xfa, 0x44, 0x95, 0x41, 0x76, 0x8c, 0xf6, 0x94, 0x2e, 0x6e, 0xbe, 0x93, 0x0c, + 0xe1, 0xdc, 0xf7, 0x99, 0x73, 0xeb, 0xa8, 0x3c, 0x46, 0xae, 0x38, 0x38, 0x1d, 0xa0, 0xff, 0x4a, + 0xb0, 0x34, 0x70, 0xfe, 0x81, 0xee, 0x8d, 0x53, 0x3f, 0x69, 0x23, 0x9a, 0xe2, 0xc6, 0x3b, 0x48, + 0x10, 0x2e, 0x56, 0x99, 0x8b, 0x9f, 0xa1, 0x07, 0x87, 0x2f, 0x47, 0x86, 0xbe, 0xb1, 0xe3, 0xff, + 0x96, 0xe0, 0xfc, 0xa0, 0xc1, 0x0a, 0xba, 0x3b, 0x8e, 0xd5, 0x29, 0x13, 0x9e, 0xe2, 0xbd, 0xc3, + 0x0b, 0x10, 0x5e, 0xdf, 0x67, 0x5e, 0x6f, 0xa0, 0xbb, 0xef, 0xe8, 0x35, 0x43, 0xec, 0x9e, 0xa1, + 0xc2, 0x60, 0xc4, 0x4e, 0x1f, 0x50, 0x0c, 0x46, 0xec, 0x8c, 0xa9, 0xc5, 0x50, 0xc4, 0x36, 0x22, + 0x3e, 0x71, 0xc2, 0xa2, 0xff, 0x48, 0xb0, 0x38, 0x60, 0x64, 0x80, 0x3e, 0x1e, 0x27, 0xb0, 0x29, + 0x00, 0x72, 0xf7, 0xd0, 0xfc, 0xc2, 0xa3, 0x6d, 0xe6, 0xd1, 0x7d, 0xf4, 0xc9, 0xe1, 0xf3, 0x92, + 0x04, 0x9b, 0x3f, 0x49, 0x30, 0xdb, 0x85, 0x5b, 0xe8, 0xd6, 0xc8, 0x10, 0x17, 0xf9, 0xb4, 0x36, + 0x06, 0x87, 0xf0, 0x62, 0x8b, 0x79, 0xf1, 0x31, 0xfa, 0xc1, 0x68, 0x98, 0xa8, 0xbe, 0x48, 0x99, + 0x62, 0x1c, 0x54, 0x1e, 0x7d, 0xf5, 0x66, 0x59, 0xfa, 0xfa, 0xcd, 0xb2, 0xf4, 0xf7, 0x37, 0xcb, + 0xd2, 0xaf, 0xdf, 0x2e, 0x1f, 0xfb, 0xfa, 0xed, 0xf2, 0xb1, 0xbf, 0xbd, 0x5d, 0x3e, 0xf6, 0x93, + 0xa1, 0xd7, 0xbd, 0x76, 0x52, 0x21, 0xbb, 0xfb, 0xd5, 0xf2, 0xec, 0x3f, 0xa6, 0xdb, 0xff, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0x33, 0x28, 0x24, 0xee, 0xad, 0x1b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3279,9 +3279,9 @@ func (m *FinalityProviderResponse) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l - if m.Inactive { + if m.Sluggish { i-- - if m.Inactive { + if m.Sluggish { dAtA[i] = 1 } else { dAtA[i] = 0 @@ -3848,7 +3848,7 @@ func (m *FinalityProviderResponse) Size() (n int) { if m.VotingPower != 0 { n += 1 + sovQuery(uint64(m.VotingPower)) } - if m.Inactive { + if m.Sluggish { n += 2 } return n @@ -6930,7 +6930,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { } case 10: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Inactive", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Sluggish", wireType) } var v int for shift := uint(0); ; shift += 7 { @@ -6947,7 +6947,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { break } } - m.Inactive = bool(v != 0) + m.Sluggish = bool(v != 0) default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) diff --git a/x/finality/README.md b/x/finality/README.md index f8c63a4b0..2f8954dcf 100644 --- a/x/finality/README.md +++ b/x/finality/README.md @@ -10,7 +10,8 @@ finalization status of blocks, and identifying equivocating finality providers in the finalization rounds. This includes: - handling requests for submitting finality votes from finality providers; -- maintaining the finalization status of blocks; and +- maintaining the finalization status of blocks; +- identifying sluggish finality providers; and - maintaining equivocation evidences of culpable finality providers. ## Table of contents @@ -179,6 +180,58 @@ message Evidence { } ``` +### Signing info tracker + +Information about finality providers' voting histories is tracked through +`FinalityProviderSigningInfo`. It is indexed in the store as follows: + +- `FinalityProviderSigningTracker: BTCPublicKey -> ProtoBuffer + (FinalityProviderSigningInfo)` + +- FinalityProviderMissedBlockBitmap: `BTCPublicKey -> VarInt(didMiss)` (varint + is a number encoding format) + +The first mapping allows us to easily look at the recent signing info for a +finality provider based on its public key, while the second mapping +(`MissedBlocksBitArray`) acts as a bit-array of size `SignedBlocksWindow` +that tells us if the finality provider missed the block for a given index in +the bit-array. The index in the bit-array is given as little-endian uint64. +The result is a varint that takes on 0 or 1, where 0 indicates the finality +provider did not miss (did sign) the corresponding block, and 1 indicates +they missed the block (did not sign). + +Note that the `MissedBlocksBitArray` is not explicitly initialized up-front. +Keys are added as the first `SignedBlocksWindow` blocks +for a newly active finality provider. The `SignedBlocksWindow` parameter +defines the size (number of blocks) of the sliding window used to track +finality provider liveness. + +The information stored for tracking finality provider liveness is as follows: + +```protobuf +// FinalityProviderSigningInfo defines a finality provider's signing info +// for monitoring their liveness activity. +message FinalityProviderSigningInfo { + // fp_btc_pk is the BTC PK of the finality provider that casts this finality + // signature + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // start_height is the block height at which finality provider become active + int64 start_height = 2; + // missed_blocks_counter defines a counter to avoid unnecessary array reads. + // Note that `Sum(MissedBlocksBitArray)` always equals `MissedBlocksCounter`. + int64 missed_blocks_counter = 3; +} +``` + +Note that the value of `missed_blocks_counter` in the +`FinalityProviderSigningInfo` is the same as the summed value of the +corresponding missed block bitmap. This is to avoid unnecessary bitmap reads. +Also note that the judgement of whether a finality signature is `missed` or not +is irreversible. + +The two maps will be updated upon `BeginBlock` which will be described in a +later section. + ## Messages The Finality module handles the following messages from finality providers. The @@ -285,11 +338,12 @@ been >=1 active BTC delegations)*: distribute rewards to the voted finality providers and their BTC delegations. Otherwise, none of the subsequent blocks shall be finalized and the loop breaks here. +3. Update the finality provider's voting history and label it to `sluggish` + if the number of block it has missed has passed the parameterized threshold. ## Events -The Finality module defines the `EventSlashedFinalityProvider` event. It is -emitted when a finality provider is slashed due to equivocation. +The Finality module defines the following events. ```protobuf // EventSlashedFinalityProvider is the event emitted when a finality provider is slashed @@ -298,6 +352,21 @@ message EventSlashedFinalityProvider { // evidence is the evidence that the finality provider double signs Evidence evidence = 1; } + +// EventSluggishFinalityProviderDetected is the event emitted when a finality provider is +// detected as sluggish +message EventSluggishFinalityProviderDetected { +// public_key is the BTC public key of the finality provider +string public_key = 1; +} + +// EventSluggishFinalityProviderReverted is the event emitted when a sluggish finality +// provider is no longer considered sluggish +message EventSluggishFinalityProviderReverted { +// public_key is the BTC public key of the finality provider +string public_key = 1; +} + ``` ## Queries diff --git a/x/finality/abci.go b/x/finality/abci.go index f69fac165..1b62dac38 100644 --- a/x/finality/abci.go +++ b/x/finality/abci.go @@ -28,7 +28,7 @@ func EndBlocker(ctx context.Context, k keeper.Keeper) ([]abci.ValidatorUpdate, e // tally all non-finalised blocks k.TallyBlocks(ctx) - // detect inactive finality providers if there are any + // detect sluggish finality providers if there are any // heightToExamine is determined by the current height - params.FinalitySigTimeout // which indicates that finality providers have up to `params.FinalitySigTimeout` blocks // to send votes on the height to be examined as whether `missed` or not (1 or 0 of a diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index 3b9a48a3f..5f38bba40 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -225,3 +225,51 @@ func (k Keeper) ListEvidences(ctx context.Context, req *types.QueryListEvidences } return resp, nil } + +// SigningInfo returns signing-info of a specific finality provider. +func (k Keeper) SigningInfo(ctx context.Context, req *types.QuerySigningInfoRequest) (*types.QuerySigningInfoResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + if req.FpBtcPkHex == "" { + return nil, status.Errorf(codes.InvalidArgument, "empty finality provider public key") + } + + fpPk, err := bbn.NewBIP340PubKeyFromHex(req.FpBtcPkHex) + if err != nil { + return nil, status.Errorf(codes.InvalidArgument, "invalid finality provider public key") + } + + signingInfo, err := k.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) + if err != nil { + return nil, status.Errorf(codes.NotFound, "SigningInfo not found for the finality provider %s", req.FpBtcPkHex) + } + + return &types.QuerySigningInfoResponse{FpSigningInfo: signingInfo}, nil +} + +// SigningInfos returns signing-infos of all finality providers. +func (k Keeper) SigningInfos(ctx context.Context, req *types.QuerySigningInfosRequest) (*types.QuerySigningInfosResponse, error) { + if req == nil { + return nil, status.Errorf(codes.InvalidArgument, "empty request") + } + + store := k.storeService.OpenKVStore(ctx) + var signInfos []types.FinalityProviderSigningInfo + + signingInfoStore := prefix.NewStore(runtime.KVStoreAdapter(store), types.FinalityProviderSigningInfoKeyPrefix) + pageRes, err := query.Paginate(signingInfoStore, req.Pagination, func(key, value []byte) error { + var info types.FinalityProviderSigningInfo + err := k.cdc.Unmarshal(value, &info) + if err != nil { + return err + } + signInfos = append(signInfos, info) + return nil + }) + if err != nil { + return nil, err + } + return &types.QuerySigningInfosResponse{FpSigningInfos: signInfos, Pagination: pageRes}, nil +} diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index e756ead0a..e4a360197 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" "math/rand" "testing" @@ -363,3 +364,73 @@ func FuzzListEvidences(f *testing.F) { } }) } + +func FuzzSigningInfo(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + + // Setup keeper and context + fKeeper, ctx := testkeeper.FinalityKeeper(t, nil, nil) + ctx = sdk.UnwrapSDKContext(ctx) + + // generate a random list of signing info + numSigningInfo := datagen.RandomInt(r, 100) + 10 + + fpSigningInfos := map[string]*types.FinalityProviderSigningInfo{} + fpPks := make([]string, 0) + for i := uint64(0); i < numSigningInfo; i++ { + // random key pair + fpPk, err := datagen.GenRandomBIP340PubKey(r) + require.NoError(t, err) + fpPks = append(fpPks, fpPk.MarshalHex()) + + // random height and missed block counter + height := int64(datagen.RandomInt(r, 100) + 1) + missedBlockCounter := int64(datagen.RandomInt(r, 100) + 1) + + // create signing info and add it to map and finality keeper + signingInfo := types.NewFinalityProviderSigningInfo(fpPk, height, missedBlockCounter) + err = fKeeper.FinalityProviderSigningTracker.Set(ctx, fpPk.MustMarshal(), signingInfo) + require.NoError(t, err) + fpSigningInfos[fpPk.MarshalHex()] = &signingInfo + } + + // perform queries for signing info of a given finality provider + for i := uint64(0); i < numSigningInfo; i++ { + fpPk := fpPks[i] + req := &types.QuerySigningInfoRequest{FpBtcPkHex: fpPk} + resp, err := fKeeper.SigningInfo(ctx, req) + require.NoError(t, err) + require.Equal(t, fpSigningInfos[fpPk].StartHeight, resp.FpSigningInfo.StartHeight) + require.Equal(t, fpSigningInfos[fpPk].MissedBlocksCounter, resp.FpSigningInfo.MissedBlocksCounter) + require.Equal(t, fpPk, resp.FpSigningInfo.FpBtcPk.MarshalHex()) + } + + // perform a query for signing info of non-exist finality provider + nonExistFpPk, err := datagen.GenRandomBIP340PubKey(r) + require.NoError(t, err) + require.NoError(t, err) + invalidReq := &types.QuerySigningInfoRequest{FpBtcPkHex: nonExistFpPk.MarshalHex()} + _, err = fKeeper.SigningInfo(ctx, invalidReq) + require.Contains(t, err.Error(), fmt.Sprintf("SigningInfo not found for the finality provider %s", nonExistFpPk.MarshalHex())) + + // perform a query for signing infos of all the finality providers + limit := datagen.RandomInt(r, int(numSigningInfo)) + 1 + req := &types.QuerySigningInfosRequest{ + Pagination: &query.PageRequest{ + CountTotal: true, + Limit: limit, + }, + } + resp, err := fKeeper.SigningInfos(ctx, req) + require.NoError(t, err) + require.LessOrEqual(t, len(resp.FpSigningInfos), int(limit)) // check if pagination takes effect + require.EqualValues(t, resp.Pagination.Total, numSigningInfo) // ensure evidences before startHeight are not included + for _, si := range resp.FpSigningInfos { + require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].MissedBlocksCounter, si.MissedBlocksCounter) + require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].FpBtcPk.MarshalHex(), si.FpBtcPk.MarshalHex()) + require.Equal(t, fpSigningInfos[si.FpBtcPk.MarshalHex()].StartHeight, si.StartHeight) + } + }) +} diff --git a/x/finality/keeper/liveness.go b/x/finality/keeper/liveness.go index f4da183e0..ae2fbb5db 100644 --- a/x/finality/keeper/liveness.go +++ b/x/finality/keeper/liveness.go @@ -11,7 +11,7 @@ import ( ) // HandleLiveness handles liveness of each active finality provider for a given height -// including identifying inactive finality providers and applying punishment +// including identifying sluggish finality providers and applying punishment (TBD) func (k Keeper) HandleLiveness(ctx context.Context, height int64) { // get all the active finality providers for the height fpSet := k.BTCStakingKeeper.GetVotingPowerTable(ctx, uint64(height)) @@ -19,8 +19,8 @@ func (k Keeper) HandleLiveness(ctx context.Context, height int64) { voterBTCPKs := k.GetVoters(ctx, uint64(height)) // Iterate over all the finality providers which *should* have signed this block - // store whether or not they have actually signed it, identify inactive - // ones, and apply punishment + // store whether or not they have actually signed it, identify sluggish + // ones, and apply punishment (TBD) for fpPkHex := range fpSet { fpPk, err := types.NewBIP340PubKeyFromHex(fpPkHex) if err != nil { @@ -38,7 +38,7 @@ func (k Keeper) HandleLiveness(ctx context.Context, height int64) { } // HandleFinalityProviderLiveness updates the voting history of the given finality provider and -// detect inactive the finality provider if the number of missed block is reached to the threshold in a +// detect sluggish the finality provider if the number of missed block is reached to the threshold in a // sliding window func (k Keeper) HandleFinalityProviderLiveness(ctx context.Context, fpPk *types.BIP340PubKey, missed bool, height int64) error { params := k.GetParams(ctx) @@ -62,8 +62,6 @@ func (k Keeper) HandleFinalityProviderLiveness(ctx context.Context, fpPk *types. sdkCtx := sdk.UnwrapSDKContext(ctx) if missed { - // TODO emit event - k.Logger(sdkCtx).Debug( "absent finality provider", "height", height, @@ -79,34 +77,51 @@ func (k Keeper) HandleFinalityProviderLiveness(ctx context.Context, fpPk *types. // if we are past the minimum height and the finality provider has missed too many blocks, punish them if height > minHeight && signInfo.MissedBlocksCounter > maxMissed { updated = true - // TODO emit event + + k.Logger(sdkCtx).Info( + "detected sluggish finality provider", + "height", height, + "public_key", fpPk.MarshalHex(), + "missed_count", signInfo.MissedBlocksCounter, + "threshold", minSignedPerWindow, + "window_size", signedBlocksWindow, + ) // Inactivity detected - err = k.hooks.AfterInactiveFinalityProviderDetected(ctx, fpPk) + err = k.hooks.AfterSluggishFinalityProviderDetected(ctx, fpPk) if err != nil { return err } + if err := sdkCtx.EventManager().EmitTypedEvent( + finalitytypes.NewEventSluggishFinalityProviderDetected(fpPk), + ); err != nil { + panic(fmt.Errorf("failed to emit sluggish finality provider detected event for height %d: %w", height, err)) + } + + finalitytypes.IncrementSluggishFinalityProviderCounter() + } else if fp.IsSluggish() { + updated = true + k.Logger(sdkCtx).Info( - "detected inactive finality provider", + "reverted sluggish finality provider", "height", height, "public_key", fpPk.MarshalHex(), ) - } else if fp.IsInactive() { - updated = true - // TODO emit event - // change the Inactive flag of the finality provider to false - err = k.BTCStakingKeeper.RevertInactiveFinalityProvider(ctx, fpPk.MustMarshal()) + // change the sluggish flag of the finality provider to false + err = k.BTCStakingKeeper.RevertSluggishFinalityProvider(ctx, fpPk.MustMarshal()) if err != nil { - return fmt.Errorf("failed to revert inactive finality provider %s: %w", fpPk.MarshalHex(), err) + return fmt.Errorf("failed to revert sluggish finality provider %s: %w", fpPk.MarshalHex(), err) } - k.Logger(sdkCtx).Info( - "reverted inactive finality provider", - "height", height, - "public_key", fpPk.MarshalHex(), - ) + if err := sdkCtx.EventManager().EmitTypedEvent( + finalitytypes.NewEventSluggishFinalityProviderReverted(fpPk), + ); err != nil { + panic(fmt.Errorf("failed to emit sluggish finality provider reverted event for height %d: %w", height, err)) + } + + finalitytypes.DecrementSluggishFinalityProviderCounter() } // Set the updated signing info diff --git a/x/finality/keeper/liveness_test.go b/x/finality/keeper/liveness_test.go index 4f110b442..563cba5ee 100644 --- a/x/finality/keeper/liveness_test.go +++ b/x/finality/keeper/liveness_test.go @@ -27,13 +27,13 @@ func FuzzHandleLiveness(f *testing.F) { fKeeper, ctx := keepertest.FinalityKeeper(t, bsKeeper, iKeeper) mockedHooks := types.NewMockFinalityHooks(ctrl) - mockedHooks.EXPECT().AfterInactiveFinalityProviderDetected(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() + mockedHooks.EXPECT().AfterSluggishFinalityProviderDetected(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() fKeeper.SetHooks(mockedHooks) params := fKeeper.GetParams(ctx) fpPk, err := datagen.GenRandomBIP340PubKey(r) require.NoError(t, err) - bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(&bstypes.FinalityProvider{Inactive: false}, nil).AnyTimes() + bsKeeper.EXPECT().GetFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(&bstypes.FinalityProvider{Sluggish: false}, nil).AnyTimes() signingInfo := types.NewFinalityProviderSigningInfo( fpPk, 1, @@ -58,31 +58,31 @@ func FuzzHandleLiveness(f *testing.F) { minSignedPerWindow := params.MinSignedPerWindowInt() maxMissed := params.SignedBlocksWindow - minSignedPerWindow // for blocks up to the inactivity boundary, mark the finality provider as having not signed - inactiveDetectedHeight := height + maxMissed + 1 - for ; height < inactiveDetectedHeight; height++ { + sluggishDetectedHeight := height + maxMissed + 1 + for ; height < sluggishDetectedHeight; height++ { err := fKeeper.HandleFinalityProviderLiveness(ctx, fpPk, true, height) require.NoError(t, err) signingInfo, err = fKeeper.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) require.NoError(t, err) - if height < inactiveDetectedHeight-1 { + if height < sluggishDetectedHeight-1 { require.GreaterOrEqual(t, maxMissed, signingInfo.MissedBlocksCounter) } else { require.Less(t, maxMissed, signingInfo.MissedBlocksCounter) } } - // perform heights that not missed, expect the inactive is reverted - bsKeeper.EXPECT().RevertInactiveFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(nil).AnyTimes() - inactiveRevertedHeight := height + maxMissed - for ; height < inactiveRevertedHeight; height++ { + // perform heights that not missed, expect the sluggish is reverted + bsKeeper.EXPECT().RevertSluggishFinalityProvider(gomock.Any(), fpPk.MustMarshal()).Return(nil).AnyTimes() + sluggishRevertedHeight := height + maxMissed + for ; height < sluggishRevertedHeight; height++ { err := fKeeper.HandleFinalityProviderLiveness(ctx, fpPk, false, height) require.NoError(t, err) signingInfo, err = fKeeper.FinalityProviderSigningTracker.Get(ctx, fpPk.MustMarshal()) require.NoError(t, err) - if height < inactiveRevertedHeight-1 { + if height < sluggishRevertedHeight-1 { require.Less(t, maxMissed, signingInfo.MissedBlocksCounter) } else { - // the inactive fp is reverted + // the sluggish fp is reverted require.Equal(t, maxMissed, signingInfo.MissedBlocksCounter) } } diff --git a/x/finality/types/events.go b/x/finality/types/events.go index 6d452f5d0..6e16582b4 100644 --- a/x/finality/types/events.go +++ b/x/finality/types/events.go @@ -1,7 +1,17 @@ package types +import "github.com/babylonchain/babylon/types" + func NewEventSlashedFinalityProvider(evidence *Evidence) *EventSlashedFinalityProvider { return &EventSlashedFinalityProvider{ Evidence: evidence, } } + +func NewEventSluggishFinalityProviderDetected(fpPk *types.BIP340PubKey) *EventSluggishFinalityProviderDetected { + return &EventSluggishFinalityProviderDetected{PublicKey: fpPk.MarshalHex()} +} + +func NewEventSluggishFinalityProviderReverted(fpPk *types.BIP340PubKey) *EventSluggishFinalityProviderReverted { + return &EventSluggishFinalityProviderReverted{PublicKey: fpPk.MarshalHex()} +} diff --git a/x/finality/types/events.pb.go b/x/finality/types/events.pb.go index 2a19e5f20..1f7fdd4b7 100644 --- a/x/finality/types/events.pb.go +++ b/x/finality/types/events.pb.go @@ -69,14 +69,110 @@ func (m *EventSlashedFinalityProvider) GetEvidence() *Evidence { return nil } +// EventSluggishFinalityProviderDetected is the event emitted when a finality provider is +// detected as sluggish +type EventSluggishFinalityProviderDetected struct { + // public_key is the BTC public key of the finality provider + PublicKey string `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (m *EventSluggishFinalityProviderDetected) Reset() { *m = EventSluggishFinalityProviderDetected{} } +func (m *EventSluggishFinalityProviderDetected) String() string { return proto.CompactTextString(m) } +func (*EventSluggishFinalityProviderDetected) ProtoMessage() {} +func (*EventSluggishFinalityProviderDetected) Descriptor() ([]byte, []int) { + return fileDescriptor_c34c03aae5e3e6bf, []int{1} +} +func (m *EventSluggishFinalityProviderDetected) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventSluggishFinalityProviderDetected) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventSluggishFinalityProviderDetected.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 *EventSluggishFinalityProviderDetected) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventSluggishFinalityProviderDetected.Merge(m, src) +} +func (m *EventSluggishFinalityProviderDetected) XXX_Size() int { + return m.Size() +} +func (m *EventSluggishFinalityProviderDetected) XXX_DiscardUnknown() { + xxx_messageInfo_EventSluggishFinalityProviderDetected.DiscardUnknown(m) +} + +var xxx_messageInfo_EventSluggishFinalityProviderDetected proto.InternalMessageInfo + +func (m *EventSluggishFinalityProviderDetected) GetPublicKey() string { + if m != nil { + return m.PublicKey + } + return "" +} + +// EventSluggishFinalityProviderReverted is the event emitted when a sluggish finality +// provider is no longer considered sluggish +type EventSluggishFinalityProviderReverted struct { + // public_key is the BTC public key of the finality provider + PublicKey string `protobuf:"bytes,1,opt,name=public_key,json=publicKey,proto3" json:"public_key,omitempty"` +} + +func (m *EventSluggishFinalityProviderReverted) Reset() { *m = EventSluggishFinalityProviderReverted{} } +func (m *EventSluggishFinalityProviderReverted) String() string { return proto.CompactTextString(m) } +func (*EventSluggishFinalityProviderReverted) ProtoMessage() {} +func (*EventSluggishFinalityProviderReverted) Descriptor() ([]byte, []int) { + return fileDescriptor_c34c03aae5e3e6bf, []int{2} +} +func (m *EventSluggishFinalityProviderReverted) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *EventSluggishFinalityProviderReverted) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_EventSluggishFinalityProviderReverted.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 *EventSluggishFinalityProviderReverted) XXX_Merge(src proto.Message) { + xxx_messageInfo_EventSluggishFinalityProviderReverted.Merge(m, src) +} +func (m *EventSluggishFinalityProviderReverted) XXX_Size() int { + return m.Size() +} +func (m *EventSluggishFinalityProviderReverted) XXX_DiscardUnknown() { + xxx_messageInfo_EventSluggishFinalityProviderReverted.DiscardUnknown(m) +} + +var xxx_messageInfo_EventSluggishFinalityProviderReverted proto.InternalMessageInfo + +func (m *EventSluggishFinalityProviderReverted) GetPublicKey() string { + if m != nil { + return m.PublicKey + } + return "" +} + func init() { proto.RegisterType((*EventSlashedFinalityProvider)(nil), "babylon.finality.v1.EventSlashedFinalityProvider") + proto.RegisterType((*EventSluggishFinalityProviderDetected)(nil), "babylon.finality.v1.EventSluggishFinalityProviderDetected") + proto.RegisterType((*EventSluggishFinalityProviderReverted)(nil), "babylon.finality.v1.EventSluggishFinalityProviderReverted") } func init() { proto.RegisterFile("babylon/finality/v1/events.proto", fileDescriptor_c34c03aae5e3e6bf) } var fileDescriptor_c34c03aae5e3e6bf = []byte{ - // 193 bytes of a gzipped FileDescriptorProto + // 250 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, @@ -84,12 +180,15 @@ var fileDescriptor_c34c03aae5e3e6bf = []byte{ 0x92, 0x4b, 0xc6, 0x15, 0x64, 0x50, 0x70, 0x4e, 0x62, 0x71, 0x46, 0x6a, 0x8a, 0x1b, 0x54, 0x36, 0xa0, 0x28, 0xbf, 0x2c, 0x33, 0x25, 0xb5, 0x48, 0xc8, 0x92, 0x8b, 0x23, 0x15, 0xc4, 0xca, 0x4b, 0x4e, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd5, 0xc3, 0x62, 0x97, 0x9e, 0x2b, 0x54, - 0x51, 0x10, 0x5c, 0xb9, 0x93, 0xd7, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, - 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, - 0x19, 0xa4, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x0d, 0x4b, 0xce, - 0x48, 0xcc, 0xcc, 0x83, 0x71, 0xf4, 0x2b, 0x10, 0x4e, 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, - 0x03, 0xbb, 0xd6, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x4e, 0xb5, 0x88, 0x0a, 0x01, 0x00, - 0x00, + 0x51, 0x10, 0x5c, 0xb9, 0x92, 0x1b, 0x97, 0x2a, 0xd4, 0xe8, 0xd2, 0xf4, 0xf4, 0xcc, 0xe2, 0x0c, + 0x74, 0xb3, 0x5d, 0x52, 0x4b, 0x52, 0x93, 0x4b, 0x52, 0x53, 0x84, 0x64, 0xb9, 0xb8, 0x0a, 0x4a, + 0x93, 0x72, 0x32, 0x93, 0xe3, 0xb3, 0x53, 0x2b, 0xc1, 0xb6, 0x70, 0x06, 0x71, 0x42, 0x44, 0xbc, + 0x53, 0x2b, 0x09, 0x9a, 0x13, 0x94, 0x5a, 0x96, 0x5a, 0x44, 0xd8, 0x1c, 0x27, 0xaf, 0x13, 0x8f, + 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, + 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x7a, 0x2e, 0x39, 0x23, 0x31, 0x33, 0x0f, 0xc6, 0xd1, 0xaf, 0x40, + 0x04, 0x61, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xf4, 0x8c, 0x01, 0x01, 0x00, 0x00, + 0xff, 0xff, 0x62, 0xf7, 0x2c, 0xf5, 0x9a, 0x01, 0x00, 0x00, } func (m *EventSlashedFinalityProvider) Marshal() (dAtA []byte, err error) { @@ -127,6 +226,66 @@ func (m *EventSlashedFinalityProvider) MarshalToSizedBuffer(dAtA []byte) (int, e return len(dAtA) - i, nil } +func (m *EventSluggishFinalityProviderDetected) 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 *EventSluggishFinalityProviderDetected) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventSluggishFinalityProviderDetected) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PublicKey) > 0 { + i -= len(m.PublicKey) + copy(dAtA[i:], m.PublicKey) + i = encodeVarintEvents(dAtA, i, uint64(len(m.PublicKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *EventSluggishFinalityProviderReverted) 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 *EventSluggishFinalityProviderReverted) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *EventSluggishFinalityProviderReverted) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.PublicKey) > 0 { + i -= len(m.PublicKey) + copy(dAtA[i:], m.PublicKey) + i = encodeVarintEvents(dAtA, i, uint64(len(m.PublicKey))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintEvents(dAtA []byte, offset int, v uint64) int { offset -= sovEvents(v) base := offset @@ -151,6 +310,32 @@ func (m *EventSlashedFinalityProvider) Size() (n int) { return n } +func (m *EventSluggishFinalityProviderDetected) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + return n +} + +func (m *EventSluggishFinalityProviderReverted) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovEvents(uint64(l)) + } + return n +} + func sovEvents(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -243,6 +428,170 @@ func (m *EventSlashedFinalityProvider) Unmarshal(dAtA []byte) error { } return nil } +func (m *EventSluggishFinalityProviderDetected) 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 ErrIntOverflowEvents + } + 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: EventSluggishFinalityProviderDetected: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSluggishFinalityProviderDetected: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EventSluggishFinalityProviderReverted) 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 ErrIntOverflowEvents + } + 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: EventSluggishFinalityProviderReverted: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EventSluggishFinalityProviderReverted: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowEvents + } + 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 ErrInvalidLengthEvents + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthEvents + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipEvents(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthEvents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipEvents(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index 291683a28..1be3bdab0 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -18,7 +18,7 @@ type BTCStakingKeeper interface { GetVotingPowerDistCache(ctx context.Context, height uint64) (*bstypes.VotingPowerDistCache, error) RemoveVotingPowerDistCache(ctx context.Context, height uint64) GetLastFinalizedEpoch(ctx context.Context) uint64 - RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error + RevertSluggishFinalityProvider(ctx context.Context, fpBTCPK []byte) error } // IncentiveKeeper defines the expected interface needed to distribute rewards. @@ -31,5 +31,5 @@ type BtcStakingHooks interface { } type FinalityHooks interface { - AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *bbn.BIP340PubKey) error + AfterSluggishFinalityProviderDetected(ctx context.Context, btcPk *bbn.BIP340PubKey) error } diff --git a/x/finality/types/hooks.go b/x/finality/types/hooks.go index 093f51180..743c6dabc 100644 --- a/x/finality/types/hooks.go +++ b/x/finality/types/hooks.go @@ -15,9 +15,9 @@ func NewMultiFinalityHooks(hooks ...FinalityHooks) MultiFinalityHooks { return hooks } -func (h MultiFinalityHooks) AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { +func (h MultiFinalityHooks) AfterSluggishFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { for i := range h { - if err := h[i].AfterInactiveFinalityProviderDetected(ctx, btcPk); err != nil { + if err := h[i].AfterSluggishFinalityProviderDetected(ctx, btcPk); err != nil { return err } } diff --git a/x/finality/types/metrics.go b/x/finality/types/metrics.go index 84c131add..2c8d89ae2 100644 --- a/x/finality/types/metrics.go +++ b/x/finality/types/metrics.go @@ -11,14 +11,21 @@ const ( MetricsKeyAddFinalitySig = "add_finality_sig" ) -// Metrics for monitoring block finalization status const ( + /* Metrics for monitoring block finalization status */ + // MetricsKeyLastHeight is the key of the gauge recording the last height // of the ledger MetricsKeyLastHeight = "last_height" // MetricsKeyLastFinalizedHeight is the key of the gauge recording the // last height finalized by finality providers MetricsKeyLastFinalizedHeight = "last_finalized_height" + + /* Metrics for monitoring finality provider liveness */ + + // MetricsKeySluggishFinalityProviderCounter is the number of finality providers + // that are being labeled as sluggish + MetricsKeySluggishFinalityProviderCounter = "sluggish_finality_provider_counter" ) // RecordLastHeight records the last height. It is triggered upon `IndexBlock` @@ -32,7 +39,7 @@ func RecordLastHeight(height uint64) { ) } -// RecordLastHeight records the last finalized height. It is triggered upon +// RecordLastFinalizedHeight records the last finalized height. It is triggered upon // finalizing a block becomes finalized func RecordLastFinalizedHeight(height uint64) { keys := []string{MetricsKeyLastFinalizedHeight} @@ -43,3 +50,27 @@ func RecordLastFinalizedHeight(height uint64) { labels, ) } + +// IncrementSluggishFinalityProviderCounter increments the counter for the sluggish +// finality providers +func IncrementSluggishFinalityProviderCounter() { + keys := []string{MetricsKeySluggishFinalityProviderCounter} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.IncrCounterWithLabels( + keys, + 1, + labels, + ) +} + +// DecrementSluggishFinalityProviderCounter increments the counter for the sluggish +// finality providers +func DecrementSluggishFinalityProviderCounter() { + keys := []string{MetricsKeySluggishFinalityProviderCounter} + labels := []metrics.Label{telemetry.NewLabel(telemetry.MetricLabelNameModule, ModuleName)} + telemetry.IncrCounterWithLabels( + keys, + -1, + labels, + ) +} diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index fad540139..157edc91e 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -163,18 +163,18 @@ func (mr *MockBTCStakingKeeperMockRecorder) RemoveVotingPowerDistCache(ctx, heig return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveVotingPowerDistCache", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RemoveVotingPowerDistCache), ctx, height) } -// RevertInactiveFinalityProvider mocks base method. -func (m *MockBTCStakingKeeper) RevertInactiveFinalityProvider(ctx context.Context, fpBTCPK []byte) error { +// RevertSluggishFinalityProvider mocks base method. +func (m *MockBTCStakingKeeper) RevertSluggishFinalityProvider(ctx context.Context, fpBTCPK []byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RevertInactiveFinalityProvider", ctx, fpBTCPK) + ret := m.ctrl.Call(m, "RevertSluggishFinalityProvider", ctx, fpBTCPK) ret0, _ := ret[0].(error) return ret0 } -// RevertInactiveFinalityProvider indicates an expected call of RevertInactiveFinalityProvider. -func (mr *MockBTCStakingKeeperMockRecorder) RevertInactiveFinalityProvider(ctx, fpBTCPK interface{}) *gomock.Call { +// RevertSluggishFinalityProvider indicates an expected call of RevertSluggishFinalityProvider. +func (mr *MockBTCStakingKeeperMockRecorder) RevertSluggishFinalityProvider(ctx, fpBTCPK interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertInactiveFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RevertInactiveFinalityProvider), ctx, fpBTCPK) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertSluggishFinalityProvider", reflect.TypeOf((*MockBTCStakingKeeper)(nil).RevertSluggishFinalityProvider), ctx, fpBTCPK) } // SlashFinalityProvider mocks base method. @@ -286,16 +286,16 @@ func (m *MockFinalityHooks) EXPECT() *MockFinalityHooksMockRecorder { return m.recorder } -// AfterInactiveFinalityProviderDetected mocks base method. -func (m *MockFinalityHooks) AfterInactiveFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { +// AfterSluggishFinalityProviderDetected mocks base method. +func (m *MockFinalityHooks) AfterSluggishFinalityProviderDetected(ctx context.Context, btcPk *types.BIP340PubKey) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AfterInactiveFinalityProviderDetected", ctx, btcPk) + ret := m.ctrl.Call(m, "AfterSluggishFinalityProviderDetected", ctx, btcPk) ret0, _ := ret[0].(error) return ret0 } -// AfterInactiveFinalityProviderDetected indicates an expected call of AfterInactiveFinalityProviderDetected. -func (mr *MockFinalityHooksMockRecorder) AfterInactiveFinalityProviderDetected(ctx, btcPk interface{}) *gomock.Call { +// AfterSluggishFinalityProviderDetected indicates an expected call of AfterSluggishFinalityProviderDetected. +func (mr *MockFinalityHooksMockRecorder) AfterSluggishFinalityProviderDetected(ctx, btcPk interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterInactiveFinalityProviderDetected", reflect.TypeOf((*MockFinalityHooks)(nil).AfterInactiveFinalityProviderDetected), ctx, btcPk) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AfterSluggishFinalityProviderDetected", reflect.TypeOf((*MockFinalityHooks)(nil).AfterSluggishFinalityProviderDetected), ctx, btcPk) } diff --git a/x/finality/types/params.pb.go b/x/finality/types/params.pb.go index 4080a8b37..cd6131dc4 100644 --- a/x/finality/types/params.pb.go +++ b/x/finality/types/params.pb.go @@ -34,7 +34,7 @@ type Params struct { // vote before being judged as missing their voting turn on the given block FinalitySigTimeout int64 `protobuf:"varint,2,opt,name=finality_sig_timeout,json=finalitySigTimeout,proto3" json:"finality_sig_timeout,omitempty"` // min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign - // within the sliding window to avoid being detected as inactive + // within the sliding window to avoid being detected as sluggish MinSignedPerWindow cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=min_signed_per_window,json=minSignedPerWindow,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"min_signed_per_window"` // min_pub_rand is the minimum number of public randomness each // message should commit diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index 21f8290a8..1f4648346 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -921,6 +921,202 @@ func (m *QueryListEvidencesResponse) GetPagination() *query.PageResponse { return nil } +// QuerySigningInfoRequest is the request type for the Query/SigningInfo RPC +// method +type QuerySigningInfoRequest struct { + // fp_btc_pk_hex is the hex str of Bitcoin secp256k1 PK + // (in BIP340 format) of the finality provider + FpBtcPkHex string `protobuf:"bytes,1,opt,name=fp_btc_pk_hex,json=fpBtcPkHex,proto3" json:"fp_btc_pk_hex,omitempty"` +} + +func (m *QuerySigningInfoRequest) Reset() { *m = QuerySigningInfoRequest{} } +func (m *QuerySigningInfoRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySigningInfoRequest) ProtoMessage() {} +func (*QuerySigningInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{17} +} +func (m *QuerySigningInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySigningInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySigningInfoRequest.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 *QuerySigningInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySigningInfoRequest.Merge(m, src) +} +func (m *QuerySigningInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySigningInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySigningInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySigningInfoRequest proto.InternalMessageInfo + +func (m *QuerySigningInfoRequest) GetFpBtcPkHex() string { + if m != nil { + return m.FpBtcPkHex + } + return "" +} + +// QuerySigningInfoResponse is the response type for the Query/SigningInfo RPC +// method +type QuerySigningInfoResponse struct { + // fp_signing_info is the signing info of requested finality provider BTC public key + FpSigningInfo FinalityProviderSigningInfo `protobuf:"bytes,1,opt,name=fp_signing_info,json=fpSigningInfo,proto3" json:"fp_signing_info"` +} + +func (m *QuerySigningInfoResponse) Reset() { *m = QuerySigningInfoResponse{} } +func (m *QuerySigningInfoResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySigningInfoResponse) ProtoMessage() {} +func (*QuerySigningInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{18} +} +func (m *QuerySigningInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySigningInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySigningInfoResponse.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 *QuerySigningInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySigningInfoResponse.Merge(m, src) +} +func (m *QuerySigningInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySigningInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySigningInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySigningInfoResponse proto.InternalMessageInfo + +func (m *QuerySigningInfoResponse) GetFpSigningInfo() FinalityProviderSigningInfo { + if m != nil { + return m.FpSigningInfo + } + return FinalityProviderSigningInfo{} +} + +// QuerySigningInfosRequest is the request type for the Query/SigningInfos RPC +// method +type QuerySigningInfosRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySigningInfosRequest) Reset() { *m = QuerySigningInfosRequest{} } +func (m *QuerySigningInfosRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySigningInfosRequest) ProtoMessage() {} +func (*QuerySigningInfosRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{19} +} +func (m *QuerySigningInfosRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySigningInfosRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySigningInfosRequest.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 *QuerySigningInfosRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySigningInfosRequest.Merge(m, src) +} +func (m *QuerySigningInfosRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySigningInfosRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySigningInfosRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySigningInfosRequest proto.InternalMessageInfo + +func (m *QuerySigningInfosRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QuerySigningInfosResponse is the response type for the Query/SigningInfos RPC +// method +type QuerySigningInfosResponse struct { + // info is the signing info of all finality providers with signing info + FpSigningInfos []FinalityProviderSigningInfo `protobuf:"bytes,1,rep,name=fp_signing_infos,json=fpSigningInfos,proto3" json:"fp_signing_infos"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySigningInfosResponse) Reset() { *m = QuerySigningInfosResponse{} } +func (m *QuerySigningInfosResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySigningInfosResponse) ProtoMessage() {} +func (*QuerySigningInfosResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_32bddab77af6fdae, []int{20} +} +func (m *QuerySigningInfosResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySigningInfosResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySigningInfosResponse.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 *QuerySigningInfosResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySigningInfosResponse.Merge(m, src) +} +func (m *QuerySigningInfosResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySigningInfosResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySigningInfosResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySigningInfosResponse proto.InternalMessageInfo + +func (m *QuerySigningInfosResponse) GetFpSigningInfos() []FinalityProviderSigningInfo { + if m != nil { + return m.FpSigningInfos + } + return nil +} + +func (m *QuerySigningInfosResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + func init() { proto.RegisterEnum("babylon.finality.v1.QueriedBlockStatus", QueriedBlockStatus_name, QueriedBlockStatus_value) proto.RegisterType((*QueryParamsRequest)(nil), "babylon.finality.v1.QueryParamsRequest") @@ -942,86 +1138,99 @@ func init() { proto.RegisterType((*QueryEvidenceResponse)(nil), "babylon.finality.v1.QueryEvidenceResponse") proto.RegisterType((*QueryListEvidencesRequest)(nil), "babylon.finality.v1.QueryListEvidencesRequest") proto.RegisterType((*QueryListEvidencesResponse)(nil), "babylon.finality.v1.QueryListEvidencesResponse") + proto.RegisterType((*QuerySigningInfoRequest)(nil), "babylon.finality.v1.QuerySigningInfoRequest") + proto.RegisterType((*QuerySigningInfoResponse)(nil), "babylon.finality.v1.QuerySigningInfoResponse") + proto.RegisterType((*QuerySigningInfosRequest)(nil), "babylon.finality.v1.QuerySigningInfosRequest") + proto.RegisterType((*QuerySigningInfosResponse)(nil), "babylon.finality.v1.QuerySigningInfosResponse") } func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 1170 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xcf, 0x38, 0x8d, 0xdb, 0xbc, 0x24, 0xdf, 0x6f, 0x32, 0x49, 0x4b, 0x70, 0x89, 0xe3, 0x6c, - 0x21, 0x09, 0x49, 0xb5, 0xdb, 0x38, 0xa5, 0xb4, 0x20, 0xd4, 0xc6, 0x90, 0x90, 0x40, 0xea, 0x9a, - 0x2d, 0xaa, 0xd4, 0x5e, 0xac, 0x5d, 0x67, 0x62, 0xaf, 0xe2, 0xdd, 0xd9, 0x7a, 0x67, 0xad, 0x58, - 0x55, 0x25, 0xc4, 0xa1, 0x07, 0x04, 0x12, 0x12, 0x17, 0x2e, 0x3d, 0xd0, 0x2b, 0xff, 0x04, 0xc7, - 0x1e, 0x23, 0xe0, 0x80, 0x2a, 0x11, 0xa1, 0x84, 0x3f, 0x04, 0x79, 0x66, 0xd6, 0xf6, 0x3a, 0xeb, - 0x1f, 0x0d, 0x11, 0x37, 0xef, 0xec, 0xfb, 0xf1, 0x79, 0x9f, 0xf7, 0xd9, 0xf7, 0xc6, 0x30, 0x6b, - 0x1a, 0x66, 0xad, 0x4c, 0x1d, 0x6d, 0xd7, 0x72, 0x8c, 0xb2, 0xc5, 0x6a, 0x5a, 0x75, 0x45, 0x7b, - 0xec, 0x93, 0x4a, 0x4d, 0x75, 0x2b, 0x94, 0x51, 0x3c, 0x29, 0x0d, 0xd4, 0xc0, 0x40, 0xad, 0xae, - 0x24, 0xa6, 0x8a, 0xb4, 0x48, 0xf9, 0x7b, 0xad, 0xfe, 0x4b, 0x98, 0x26, 0xde, 0x2a, 0x52, 0x5a, - 0x2c, 0x13, 0xcd, 0x70, 0x2d, 0xcd, 0x70, 0x1c, 0xca, 0x0c, 0x66, 0x51, 0xc7, 0x93, 0x6f, 0x97, - 0x0a, 0xd4, 0xb3, 0xa9, 0xa7, 0x99, 0x86, 0x47, 0x44, 0x06, 0xad, 0xba, 0x62, 0x12, 0x66, 0xac, - 0x68, 0xae, 0x51, 0xb4, 0x1c, 0x6e, 0x2c, 0x6d, 0x53, 0x51, 0xa8, 0x5c, 0xa3, 0x62, 0xd8, 0x41, - 0x34, 0x25, 0xca, 0xa2, 0x01, 0x91, 0xdb, 0x28, 0x53, 0x80, 0xbf, 0xa8, 0xe7, 0xc9, 0x71, 0x47, - 0x9d, 0x3c, 0xf6, 0x89, 0xc7, 0x94, 0x1c, 0x4c, 0x86, 0x4e, 0x3d, 0x97, 0x3a, 0x1e, 0xc1, 0xb7, - 0x20, 0x2e, 0x12, 0x4c, 0xa3, 0x14, 0x5a, 0x1c, 0x49, 0x5f, 0x56, 0x23, 0x0a, 0x57, 0x85, 0x53, - 0xe6, 0xdc, 0xcb, 0xc3, 0xd9, 0x01, 0x5d, 0x3a, 0x28, 0xdf, 0x21, 0x48, 0xf1, 0x90, 0xdb, 0x96, - 0xc7, 0x72, 0xbe, 0x59, 0xb6, 0x0a, 0xba, 0xe1, 0xec, 0x50, 0xdb, 0x21, 0x5e, 0x90, 0x16, 0xcf, - 0xc1, 0xd8, 0xae, 0x9b, 0x37, 0x59, 0x21, 0xef, 0xee, 0xe5, 0x4b, 0x64, 0x9f, 0xa7, 0x19, 0xd6, - 0x61, 0xd7, 0xcd, 0xb0, 0x42, 0x6e, 0x6f, 0x93, 0xec, 0xe3, 0x0d, 0x80, 0x26, 0x13, 0xd3, 0x31, - 0x0e, 0x63, 0x5e, 0x15, 0xb4, 0xa9, 0x75, 0xda, 0x54, 0xd1, 0x18, 0x49, 0x9b, 0x9a, 0x33, 0x8a, - 0x44, 0x86, 0xd7, 0x5b, 0x3c, 0x95, 0x83, 0x18, 0xcc, 0x75, 0xc1, 0x23, 0x0b, 0x7e, 0x81, 0x60, - 0xd4, 0xf5, 0xcd, 0x7c, 0xc5, 0x70, 0x76, 0xf2, 0xb6, 0xe1, 0x4e, 0xa3, 0xd4, 0xe0, 0xe2, 0x48, - 0x7a, 0x23, 0xb2, 0xee, 0x9e, 0xe1, 0xd4, 0x9c, 0x6f, 0xd6, 0x4f, 0xef, 0x1a, 0xee, 0xba, 0xc3, - 0x2a, 0xb5, 0xcc, 0xcd, 0x57, 0x87, 0xb3, 0xd7, 0x8b, 0x16, 0x2b, 0xf9, 0xa6, 0x5a, 0xa0, 0xb6, - 0x26, 0xa3, 0x16, 0x4a, 0x86, 0xe5, 0x04, 0x0f, 0x1a, 0xab, 0xb9, 0xc4, 0x53, 0xef, 0x17, 0x4a, - 0x0e, 0xad, 0x54, 0x64, 0x04, 0x1d, 0xdc, 0x46, 0x28, 0xfc, 0x69, 0x04, 0x25, 0x0b, 0x3d, 0x29, - 0x11, 0x90, 0x5a, 0x39, 0x49, 0x7c, 0x04, 0xff, 0x6f, 0x43, 0x88, 0xc7, 0x61, 0x70, 0x8f, 0xd4, - 0x78, 0x1f, 0xce, 0xe9, 0xf5, 0x9f, 0x78, 0x0a, 0x86, 0xaa, 0x46, 0xd9, 0x27, 0x3c, 0xd1, 0xa8, - 0x2e, 0x1e, 0x3e, 0x88, 0xdd, 0x44, 0xca, 0x43, 0xb8, 0x28, 0xdd, 0x3f, 0xa6, 0xb6, 0x6d, 0xb1, - 0x06, 0x8b, 0x29, 0x18, 0x75, 0x7c, 0x3b, 0x1f, 0x10, 0x29, 0xa3, 0x81, 0xe3, 0xdb, 0xd2, 0x1e, - 0x27, 0x01, 0x0a, 0xdc, 0xc7, 0x26, 0x0e, 0x93, 0x91, 0x5b, 0x4e, 0x94, 0x6f, 0x10, 0xcc, 0xb4, - 0xd2, 0xdb, 0x9a, 0xe4, 0x3f, 0x97, 0xce, 0xef, 0x31, 0x48, 0x76, 0x02, 0x23, 0x2b, 0xde, 0x87, - 0xc9, 0x86, 0x6c, 0x44, 0x19, 0x2d, 0xea, 0xd9, 0xea, 0xa9, 0x9e, 0x93, 0x11, 0xd5, 0xd0, 0x69, - 0xd0, 0x1e, 0x7d, 0xdc, 0x6d, 0x3b, 0x3e, 0x3b, 0x31, 0xd0, 0xb6, 0x6e, 0x76, 0x91, 0xc4, 0x9d, - 0x56, 0x49, 0x8c, 0xa4, 0x97, 0xa2, 0xa7, 0x42, 0x54, 0x59, 0xad, 0xf2, 0x59, 0x86, 0x09, 0xce, - 0x41, 0xa6, 0x4c, 0x0b, 0x7b, 0x41, 0x5b, 0x2f, 0x41, 0xbc, 0x44, 0xac, 0x62, 0x89, 0xc9, 0x7c, - 0xf2, 0x49, 0xb9, 0x2b, 0xc7, 0x96, 0x34, 0x96, 0xb4, 0xbf, 0x0f, 0x43, 0x66, 0xfd, 0x40, 0x8e, - 0xa7, 0xb9, 0x48, 0x20, 0x5b, 0xce, 0x0e, 0xd9, 0x27, 0x3b, 0xc2, 0x53, 0xd8, 0x2b, 0x3f, 0x21, - 0xb8, 0xd4, 0x68, 0x00, 0x7f, 0xd3, 0x98, 0x49, 0xb7, 0x21, 0xee, 0x31, 0x83, 0xf9, 0x62, 0xe6, - 0xfd, 0x2f, 0xbd, 0xd0, 0xb1, 0x7b, 0x96, 0x0c, 0x7a, 0x9f, 0x9b, 0xeb, 0xd2, 0xed, 0xcc, 0x64, - 0xf7, 0x1c, 0xc1, 0x1b, 0x27, 0x30, 0x36, 0x07, 0x33, 0x2f, 0xc4, 0x93, 0x12, 0xeb, 0xa3, 0x72, - 0xe9, 0x70, 0x66, 0x82, 0x51, 0x56, 0xe1, 0x4d, 0x0e, 0xef, 0x01, 0x65, 0xc4, 0x5b, 0x63, 0x9b, - 0xbc, 0x51, 0xbd, 0xfa, 0x68, 0x43, 0x22, 0xca, 0x49, 0x96, 0x75, 0x0f, 0xce, 0x8b, 0x2f, 0x5a, - 0xd4, 0x35, 0x9a, 0xb9, 0xf1, 0xea, 0x70, 0x36, 0xdd, 0xdf, 0xc0, 0xcc, 0x6c, 0xe5, 0x56, 0xaf, - 0x5f, 0xcb, 0xf9, 0xe6, 0xe7, 0xa4, 0xa6, 0xc7, 0xcd, 0xfa, 0x10, 0xf0, 0x94, 0x5b, 0x30, 0xc5, - 0xd3, 0xad, 0x57, 0xad, 0x1d, 0xe2, 0x14, 0x48, 0xff, 0xd3, 0x43, 0xd1, 0xe1, 0x62, 0x9b, 0x6b, - 0x83, 0xfb, 0x0b, 0x44, 0x9e, 0x49, 0xdd, 0xcd, 0x44, 0xb2, 0xdf, 0x70, 0x6c, 0x98, 0x2b, 0xcf, - 0x90, 0xe4, 0xac, 0xde, 0xd2, 0xe0, 0x7d, 0xcb, 0x36, 0x1c, 0xf5, 0x98, 0x51, 0x61, 0xf9, 0x10, - 0x73, 0x23, 0xfc, 0x4c, 0x10, 0x75, 0x66, 0xda, 0x7a, 0x81, 0x64, 0x1f, 0xda, 0x80, 0xc8, 0x12, - 0x3f, 0x84, 0xe1, 0x00, 0x73, 0xa0, 0xb0, 0x1e, 0x35, 0x36, 0xed, 0xcf, 0x4c, 0x60, 0x4b, 0xb7, - 0xc5, 0x37, 0x1f, 0xfe, 0xcc, 0xf0, 0x04, 0x8c, 0x65, 0xef, 0x65, 0xf3, 0x1b, 0x5b, 0xd9, 0xb5, - 0xed, 0xad, 0x47, 0xeb, 0x9f, 0x8c, 0x0f, 0xe0, 0x31, 0x18, 0x6e, 0x3e, 0x22, 0x7c, 0x1e, 0x06, - 0xd7, 0xb2, 0x0f, 0xc7, 0x63, 0xe9, 0x5f, 0x00, 0x86, 0x78, 0x95, 0xf8, 0x2b, 0x04, 0x71, 0x71, - 0x4d, 0xc1, 0x9d, 0xbf, 0xe7, 0xf0, 0x9d, 0x28, 0xb1, 0xd8, 0xdb, 0x50, 0x80, 0x56, 0xae, 0x7c, - 0xfd, 0xdb, 0xdf, 0x3f, 0xc4, 0x66, 0xf0, 0x65, 0xad, 0xf3, 0x15, 0x0d, 0xff, 0x89, 0x60, 0x2a, - 0xea, 0xb2, 0x80, 0xdf, 0x7b, 0xdd, 0xcb, 0x85, 0x80, 0x77, 0xe3, 0x74, 0x77, 0x12, 0xe5, 0x01, - 0x07, 0x9b, 0xc3, 0x59, 0xad, 0xdb, 0x6d, 0x31, 0xef, 0x56, 0x68, 0xbd, 0xa3, 0x15, 0x4f, 0x7b, - 0x12, 0xfa, 0x52, 0x9e, 0x6a, 0x2e, 0x8f, 0xcc, 0x77, 0x9d, 0x08, 0x9d, 0x2f, 0x5b, 0x1e, 0xc3, - 0xbf, 0x22, 0x98, 0x38, 0xb1, 0xce, 0x70, 0xfa, 0xb5, 0x76, 0x9f, 0xa8, 0x6c, 0xf5, 0x14, 0xfb, - 0x52, 0xf9, 0x92, 0x97, 0x95, 0xc5, 0xdb, 0xff, 0xa2, 0xac, 0xd0, 0xfe, 0xe6, 0x45, 0x3d, 0x43, - 0x30, 0xc4, 0xc5, 0x87, 0xe7, 0x3b, 0x83, 0x6a, 0x5d, 0x60, 0x89, 0x85, 0x9e, 0x76, 0x12, 0xf0, - 0x55, 0x0e, 0x78, 0x1e, 0xbf, 0x1d, 0x09, 0x58, 0x0c, 0x6b, 0xed, 0x89, 0x18, 0x05, 0x4f, 0xf1, - 0xb7, 0x08, 0xa0, 0xb9, 0x07, 0xf0, 0x72, 0x77, 0x8a, 0x42, 0x1b, 0x2d, 0x71, 0xb5, 0x3f, 0xe3, - 0xbe, 0xc4, 0x2c, 0x97, 0xc8, 0x73, 0x04, 0x63, 0xa1, 0x11, 0x8e, 0xd5, 0xce, 0x49, 0xa2, 0x16, - 0x44, 0x42, 0xeb, 0xdb, 0x5e, 0xe2, 0x5a, 0xe6, 0xb8, 0xde, 0xc1, 0x57, 0x22, 0x71, 0x55, 0xeb, - 0x3e, 0x4d, 0xba, 0x7e, 0x46, 0x70, 0x21, 0x98, 0x4d, 0xf8, 0xdd, 0xce, 0xa9, 0xda, 0xf6, 0x42, - 0x62, 0xa9, 0x1f, 0x53, 0x09, 0x68, 0x93, 0x03, 0xca, 0xe0, 0x3b, 0xa7, 0x55, 0x5c, 0x30, 0x32, - 0xf1, 0x8f, 0x08, 0xc6, 0x42, 0x83, 0xb8, 0x1b, 0x9b, 0x51, 0xab, 0xa3, 0x1b, 0x9b, 0x91, 0x13, - 0x5e, 0x99, 0xe7, 0xe0, 0x53, 0x38, 0x19, 0x09, 0xbe, 0x31, 0xcc, 0x33, 0x9f, 0xbd, 0x3c, 0x4a, - 0xa2, 0x83, 0xa3, 0x24, 0xfa, 0xeb, 0x28, 0x89, 0xbe, 0x3f, 0x4e, 0x0e, 0x1c, 0x1c, 0x27, 0x07, - 0xfe, 0x38, 0x4e, 0x0e, 0x3c, 0xba, 0xd6, 0x6b, 0x2d, 0xef, 0x37, 0x43, 0xf2, 0x0d, 0x6d, 0xc6, - 0xf9, 0x3f, 0xd0, 0xd5, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x4f, 0x9a, 0xb0, 0x5f, 0x0f, - 0x00, 0x00, + // 1317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdf, 0x6f, 0xdb, 0xd4, + 0x17, 0xef, 0xcd, 0xd6, 0x6c, 0x3b, 0x4d, 0xb6, 0xee, 0xae, 0xdb, 0xb7, 0xdf, 0x8c, 0xa5, 0x99, + 0x37, 0xda, 0xd2, 0x0e, 0xbb, 0x4d, 0xcb, 0xd8, 0x06, 0x68, 0x6b, 0xa0, 0xa5, 0x81, 0x2e, 0x0b, + 0x2e, 0x9a, 0xb4, 0x3d, 0x60, 0xec, 0xf4, 0x26, 0xb1, 0x9a, 0xd8, 0x5e, 0xec, 0x44, 0x0d, 0xd3, + 0x24, 0x84, 0xc4, 0x1e, 0x10, 0x48, 0x48, 0xbc, 0xc0, 0xc3, 0x1e, 0xd8, 0x03, 0x2f, 0xfc, 0x1f, + 0x68, 0x8f, 0x15, 0xf0, 0x80, 0x26, 0x51, 0xa1, 0x96, 0x3f, 0x04, 0xe5, 0xde, 0xeb, 0xc4, 0x4e, + 0x9c, 0x1f, 0x2d, 0x11, 0x6f, 0xf6, 0xf5, 0xf9, 0xf1, 0xf9, 0x7c, 0xce, 0xc9, 0xb9, 0xa7, 0x85, + 0x29, 0x4d, 0xd5, 0xea, 0x25, 0xd3, 0x90, 0xf2, 0xba, 0xa1, 0x96, 0x74, 0xa7, 0x2e, 0xd5, 0x16, + 0xa5, 0x47, 0x55, 0x52, 0xa9, 0x8b, 0x56, 0xc5, 0x74, 0x4c, 0x7c, 0x8e, 0x1b, 0x88, 0xae, 0x81, + 0x58, 0x5b, 0x8c, 0x4d, 0x14, 0xcc, 0x82, 0x49, 0xbf, 0x4b, 0x8d, 0x27, 0x66, 0x1a, 0x7b, 0xa5, + 0x60, 0x9a, 0x85, 0x12, 0x91, 0x54, 0x4b, 0x97, 0x54, 0xc3, 0x30, 0x1d, 0xd5, 0xd1, 0x4d, 0xc3, + 0xe6, 0x5f, 0xe7, 0x72, 0xa6, 0x5d, 0x36, 0x6d, 0x49, 0x53, 0x6d, 0xc2, 0x32, 0x48, 0xb5, 0x45, + 0x8d, 0x38, 0xea, 0xa2, 0x64, 0xa9, 0x05, 0xdd, 0xa0, 0xc6, 0xdc, 0x36, 0x11, 0x84, 0xca, 0x52, + 0x2b, 0x6a, 0xd9, 0x8d, 0x26, 0x04, 0x59, 0x34, 0x21, 0x52, 0x1b, 0x61, 0x02, 0xf0, 0x47, 0x8d, + 0x3c, 0x59, 0xea, 0x28, 0x93, 0x47, 0x55, 0x62, 0x3b, 0x42, 0x16, 0xce, 0xf9, 0x4e, 0x6d, 0xcb, + 0x34, 0x6c, 0x82, 0x6f, 0x42, 0x98, 0x25, 0x98, 0x44, 0x09, 0x34, 0x3b, 0x96, 0xbc, 0x28, 0x06, + 0x10, 0x17, 0x99, 0x53, 0xea, 0xf8, 0x8b, 0xbd, 0xa9, 0x11, 0x99, 0x3b, 0x08, 0xdf, 0x20, 0x48, + 0xd0, 0x90, 0x1b, 0xba, 0xed, 0x64, 0xab, 0x5a, 0x49, 0xcf, 0xc9, 0xaa, 0xb1, 0x65, 0x96, 0x0d, + 0x62, 0xbb, 0x69, 0xf1, 0x65, 0x88, 0xe6, 0x2d, 0x45, 0x73, 0x72, 0x8a, 0xb5, 0xad, 0x14, 0xc9, + 0x0e, 0x4d, 0x73, 0x4a, 0x86, 0xbc, 0x95, 0x72, 0x72, 0xd9, 0xed, 0x75, 0xb2, 0x83, 0xd7, 0x00, + 0x5a, 0x4a, 0x4c, 0x86, 0x28, 0x8c, 0x69, 0x91, 0xc9, 0x26, 0x36, 0x64, 0x13, 0x59, 0x61, 0xb8, + 0x6c, 0x62, 0x56, 0x2d, 0x10, 0x1e, 0x5e, 0xf6, 0x78, 0x0a, 0xbb, 0x21, 0xb8, 0xdc, 0x03, 0x0f, + 0x27, 0xfc, 0x1c, 0x41, 0xc4, 0xaa, 0x6a, 0x4a, 0x45, 0x35, 0xb6, 0x94, 0xb2, 0x6a, 0x4d, 0xa2, + 0xc4, 0xb1, 0xd9, 0xb1, 0xe4, 0x5a, 0x20, 0xef, 0xbe, 0xe1, 0xc4, 0x6c, 0x55, 0x6b, 0x9c, 0xde, + 0x55, 0xad, 0x55, 0xc3, 0xa9, 0xd4, 0x53, 0x37, 0x5e, 0xee, 0x4d, 0x2d, 0x17, 0x74, 0xa7, 0x58, + 0xd5, 0xc4, 0x9c, 0x59, 0x96, 0x78, 0xd4, 0x5c, 0x51, 0xd5, 0x0d, 0xf7, 0x45, 0x72, 0xea, 0x16, + 0xb1, 0xc5, 0xcd, 0x5c, 0xd1, 0x30, 0x2b, 0x15, 0x1e, 0x41, 0x06, 0xab, 0x19, 0x0a, 0xbf, 0x1f, + 0x20, 0xc9, 0x4c, 0x5f, 0x49, 0x18, 0x24, 0xaf, 0x26, 0xb1, 0x77, 0xe0, 0x4c, 0x1b, 0x42, 0x3c, + 0x0e, 0xc7, 0xb6, 0x49, 0x9d, 0xd6, 0xe1, 0xb8, 0xdc, 0x78, 0xc4, 0x13, 0x30, 0x5a, 0x53, 0x4b, + 0x55, 0x42, 0x13, 0x45, 0x64, 0xf6, 0x72, 0x2b, 0x74, 0x03, 0x09, 0x0f, 0xe0, 0x3c, 0x77, 0x7f, + 0xd7, 0x2c, 0x97, 0x75, 0xa7, 0xa9, 0x62, 0x02, 0x22, 0x46, 0xb5, 0xac, 0xb8, 0x42, 0xf2, 0x68, + 0x60, 0x54, 0xcb, 0xdc, 0x1e, 0xc7, 0x01, 0x72, 0xd4, 0xa7, 0x4c, 0x0c, 0x87, 0x47, 0xf6, 0x9c, + 0x08, 0x5f, 0x21, 0xb8, 0xe4, 0x95, 0xd7, 0x9b, 0xe4, 0x3f, 0x6f, 0x9d, 0xdf, 0x43, 0x10, 0xef, + 0x06, 0x86, 0x33, 0xde, 0x81, 0x73, 0xcd, 0xb6, 0x61, 0x34, 0x3c, 0xdd, 0x93, 0xee, 0xdb, 0x3d, + 0x9d, 0x11, 0x45, 0xdf, 0xa9, 0x5b, 0x1e, 0x79, 0xdc, 0x6a, 0x3b, 0x1e, 0x5e, 0x33, 0x98, 0x6d, + 0xd5, 0xec, 0xd1, 0x12, 0x77, 0xbc, 0x2d, 0x31, 0x96, 0x9c, 0x0b, 0x9e, 0x0a, 0x41, 0xb4, 0xbc, + 0xed, 0x33, 0x0f, 0x67, 0xa9, 0x06, 0xa9, 0x92, 0x99, 0xdb, 0x76, 0xcb, 0x7a, 0x01, 0xc2, 0x45, + 0xa2, 0x17, 0x8a, 0x0e, 0xcf, 0xc7, 0xdf, 0x84, 0xbb, 0x7c, 0x6c, 0x71, 0x63, 0x2e, 0xfb, 0x9b, + 0x30, 0xaa, 0x35, 0x0e, 0xf8, 0x78, 0xba, 0x1c, 0x08, 0x24, 0x6d, 0x6c, 0x91, 0x1d, 0xb2, 0xc5, + 0x3c, 0x99, 0xbd, 0xf0, 0x23, 0x82, 0x0b, 0xcd, 0x02, 0xd0, 0x2f, 0xcd, 0x99, 0x74, 0x1b, 0xc2, + 0xb6, 0xa3, 0x3a, 0x55, 0x36, 0xf3, 0x4e, 0x27, 0x67, 0xba, 0x56, 0x4f, 0xe7, 0x41, 0x37, 0xa9, + 0xb9, 0xcc, 0xdd, 0x86, 0xd6, 0x76, 0xcf, 0x10, 0xfc, 0xaf, 0x03, 0x63, 0x6b, 0x30, 0x53, 0x22, + 0x36, 0x6f, 0xb1, 0x01, 0x98, 0x73, 0x87, 0xa1, 0x35, 0x8c, 0xb0, 0x04, 0xff, 0xa7, 0xf0, 0xee, + 0x9b, 0x0e, 0xb1, 0x57, 0x9c, 0x75, 0x5a, 0xa8, 0x7e, 0x75, 0x2c, 0x43, 0x2c, 0xc8, 0x89, 0xd3, + 0xba, 0x07, 0x27, 0xd8, 0x2f, 0x9a, 0xf1, 0x8a, 0xa4, 0xae, 0xbf, 0xdc, 0x9b, 0x4a, 0x0e, 0x36, + 0x30, 0x53, 0xe9, 0xec, 0xd2, 0xf2, 0x42, 0xb6, 0xaa, 0x7d, 0x48, 0xea, 0x72, 0x58, 0x6b, 0x0c, + 0x01, 0x5b, 0xb8, 0x09, 0x13, 0x34, 0xdd, 0x6a, 0x4d, 0xdf, 0x22, 0x46, 0x8e, 0x0c, 0x3e, 0x3d, + 0x04, 0x19, 0xce, 0xb7, 0xb9, 0x36, 0xb5, 0x3f, 0x49, 0xf8, 0x19, 0xef, 0xbb, 0x4b, 0x81, 0xea, + 0x37, 0x1d, 0x9b, 0xe6, 0xc2, 0x53, 0xc4, 0x35, 0x6b, 0x94, 0xd4, 0xfd, 0xee, 0xb9, 0x0d, 0x23, + 0xb6, 0xa3, 0x56, 0x1c, 0xc5, 0xa7, 0xdc, 0x18, 0x3d, 0x63, 0x42, 0x0d, 0xad, 0xb7, 0x9e, 0x23, + 0x5e, 0x87, 0x36, 0x20, 0x9c, 0xe2, 0x5b, 0x70, 0xca, 0xc5, 0xec, 0x76, 0x58, 0x1f, 0x8e, 0x2d, + 0xfb, 0xe1, 0x35, 0xd8, 0xdb, 0xbc, 0xff, 0x37, 0xf5, 0x82, 0xa1, 0x1b, 0x85, 0xb4, 0x91, 0x37, + 0x0f, 0x51, 0xbf, 0xcf, 0x60, 0xb2, 0xd3, 0x9b, 0xf3, 0xfb, 0x04, 0xce, 0xe4, 0x2d, 0xc5, 0x66, + 0x5f, 0x14, 0xdd, 0xc8, 0x9b, 0xbc, 0x92, 0x0b, 0x81, 0x2c, 0xd7, 0xf8, 0x73, 0xb6, 0x62, 0x36, + 0x58, 0x56, 0x3c, 0x21, 0xf9, 0xd6, 0x13, 0xcd, 0x5b, 0x9e, 0x43, 0x41, 0xeb, 0xcc, 0xdd, 0xac, + 0xb2, 0xbf, 0x84, 0xe8, 0xc8, 0x25, 0xfc, 0xc5, 0xed, 0x25, 0x7f, 0x12, 0xce, 0xf0, 0x53, 0x18, + 0x6f, 0x63, 0xe8, 0x16, 0xf2, 0xa8, 0x14, 0x4f, 0xfb, 0x28, 0x0e, 0xaf, 0xcc, 0x73, 0xb7, 0xd9, + 0x68, 0xf7, 0x4f, 0x53, 0x7c, 0x16, 0xa2, 0x99, 0x7b, 0x19, 0x65, 0x2d, 0x9d, 0x59, 0xd9, 0x48, + 0x3f, 0x5c, 0x7d, 0x6f, 0x7c, 0x04, 0x47, 0xe1, 0x54, 0xeb, 0x15, 0xe1, 0x13, 0x70, 0x6c, 0x25, + 0xf3, 0x60, 0x3c, 0x94, 0xfc, 0x32, 0x0a, 0xa3, 0x54, 0x09, 0xfc, 0x39, 0x82, 0x30, 0xdb, 0x46, + 0x71, 0xf7, 0xb1, 0xed, 0x5f, 0x7d, 0x63, 0xb3, 0xfd, 0x0d, 0x19, 0x68, 0xe1, 0xca, 0x17, 0xbf, + 0xfd, 0xfd, 0x5d, 0xe8, 0x12, 0xbe, 0x28, 0x75, 0xdf, 0xc4, 0xf1, 0x9f, 0x08, 0x26, 0x82, 0x76, + 0x42, 0xfc, 0xc6, 0x61, 0x77, 0x48, 0x06, 0xef, 0xfa, 0xd1, 0x56, 0x4f, 0xe1, 0x3e, 0x05, 0x9b, + 0xc5, 0x19, 0xa9, 0xd7, 0x1f, 0x05, 0x8a, 0xc5, 0xeb, 0x6d, 0x4b, 0x8f, 0x7d, 0x3f, 0xa8, 0x27, + 0x92, 0x45, 0x23, 0xd3, 0x95, 0x86, 0x85, 0x56, 0x4a, 0xba, 0xed, 0xe0, 0x5f, 0x11, 0x9c, 0xed, + 0xd8, 0x5a, 0x70, 0xf2, 0x50, 0x2b, 0x0e, 0x63, 0xb6, 0x74, 0x84, 0xb5, 0x48, 0xf8, 0x98, 0xd2, + 0xca, 0xe0, 0x8d, 0x7f, 0x41, 0xcb, 0xb7, 0xa6, 0x51, 0x52, 0x4f, 0x11, 0x8c, 0xd2, 0xe6, 0xc3, + 0xd3, 0xdd, 0x41, 0x79, 0xf7, 0x94, 0xd8, 0x4c, 0x5f, 0x3b, 0x0e, 0xf8, 0x1a, 0x05, 0x3c, 0x8d, + 0xaf, 0x06, 0x02, 0x66, 0x77, 0xb2, 0xf4, 0x98, 0x4d, 0xfc, 0x27, 0xf8, 0x6b, 0x04, 0xd0, 0xba, + 0xee, 0xf1, 0x7c, 0x6f, 0x89, 0x7c, 0x8b, 0x4b, 0xec, 0xda, 0x60, 0xc6, 0x03, 0x35, 0x33, 0xdf, + 0x15, 0x9e, 0x21, 0x88, 0xfa, 0x6e, 0x6a, 0x2c, 0x76, 0x4f, 0x12, 0xb4, 0x07, 0xc4, 0xa4, 0x81, + 0xed, 0x39, 0xae, 0x79, 0x8a, 0xeb, 0x55, 0x7c, 0x25, 0x10, 0x57, 0xad, 0xe1, 0xd3, 0x92, 0xeb, + 0x67, 0x04, 0x27, 0xdd, 0x2b, 0x08, 0xbf, 0xd6, 0x3d, 0x55, 0xdb, 0xf5, 0x1f, 0x9b, 0x1b, 0xc4, + 0x94, 0x03, 0x5a, 0xa7, 0x80, 0x52, 0xf8, 0xce, 0x51, 0x3b, 0xce, 0xbd, 0x19, 0xf1, 0xf7, 0x08, + 0xa2, 0xbe, 0xfb, 0xb6, 0x97, 0x9a, 0x41, 0x1b, 0x42, 0x2f, 0x35, 0x03, 0x2f, 0x72, 0x61, 0x9a, + 0x82, 0x4f, 0xe0, 0x78, 0x20, 0xf8, 0xd6, 0x9d, 0xfd, 0x13, 0x82, 0x31, 0xcf, 0x74, 0xc7, 0x3d, + 0x7a, 0xa9, 0xf3, 0x36, 0x8e, 0xbd, 0x3e, 0xa0, 0x35, 0x07, 0x75, 0x8b, 0x82, 0x5a, 0xc6, 0xc9, + 0x40, 0x50, 0xbe, 0x3b, 0xab, 0x5d, 0x4c, 0xfc, 0x03, 0x82, 0x88, 0xef, 0x1a, 0x1a, 0x2c, 0x77, + 0x53, 0x41, 0x71, 0x50, 0x73, 0x8e, 0x75, 0x8e, 0x62, 0xbd, 0x8a, 0x85, 0xfe, 0x58, 0x53, 0x1f, + 0xbc, 0xd8, 0x8f, 0xa3, 0xdd, 0xfd, 0x38, 0xfa, 0x6b, 0x3f, 0x8e, 0xbe, 0x3d, 0x88, 0x8f, 0xec, + 0x1e, 0xc4, 0x47, 0xfe, 0x38, 0x88, 0x8f, 0x3c, 0x5c, 0xe8, 0xb7, 0xc2, 0xee, 0xb4, 0xc2, 0xd2, + 0x6d, 0x56, 0x0b, 0xd3, 0xff, 0xd6, 0x2c, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0x75, 0xb1, 0x13, + 0x1f, 0x8b, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1056,6 +1265,10 @@ type QueryClient interface { Evidence(ctx context.Context, in *QueryEvidenceRequest, opts ...grpc.CallOption) (*QueryEvidenceResponse, error) // ListEvidences queries is a range query for evidences ListEvidences(ctx context.Context, in *QueryListEvidencesRequest, opts ...grpc.CallOption) (*QueryListEvidencesResponse, error) + // SigningInfo queries the signing info of given finality provider BTC public key + SigningInfo(ctx context.Context, in *QuerySigningInfoRequest, opts ...grpc.CallOption) (*QuerySigningInfoResponse, error) + // SigningInfos queries the signing info of all the active finality providers + SigningInfos(ctx context.Context, in *QuerySigningInfosRequest, opts ...grpc.CallOption) (*QuerySigningInfosResponse, error) } type queryClient struct { @@ -1138,6 +1351,24 @@ func (c *queryClient) ListEvidences(ctx context.Context, in *QueryListEvidencesR return out, nil } +func (c *queryClient) SigningInfo(ctx context.Context, in *QuerySigningInfoRequest, opts ...grpc.CallOption) (*QuerySigningInfoResponse, error) { + out := new(QuerySigningInfoResponse) + err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/SigningInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) SigningInfos(ctx context.Context, in *QuerySigningInfosRequest, opts ...grpc.CallOption) (*QuerySigningInfosResponse, error) { + out := new(QuerySigningInfosResponse) + err := c.cc.Invoke(ctx, "/babylon.finality.v1.Query/SigningInfos", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Parameters queries the parameters of the module. @@ -1160,6 +1391,10 @@ type QueryServer interface { Evidence(context.Context, *QueryEvidenceRequest) (*QueryEvidenceResponse, error) // ListEvidences queries is a range query for evidences ListEvidences(context.Context, *QueryListEvidencesRequest) (*QueryListEvidencesResponse, error) + // SigningInfo queries the signing info of given finality provider BTC public key + SigningInfo(context.Context, *QuerySigningInfoRequest) (*QuerySigningInfoResponse, error) + // SigningInfos queries the signing info of all the active finality providers + SigningInfos(context.Context, *QuerySigningInfosRequest) (*QuerySigningInfosResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -1190,6 +1425,12 @@ func (*UnimplementedQueryServer) Evidence(ctx context.Context, req *QueryEvidenc func (*UnimplementedQueryServer) ListEvidences(ctx context.Context, req *QueryListEvidencesRequest) (*QueryListEvidencesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ListEvidences not implemented") } +func (*UnimplementedQueryServer) SigningInfo(ctx context.Context, req *QuerySigningInfoRequest) (*QuerySigningInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SigningInfo not implemented") +} +func (*UnimplementedQueryServer) SigningInfos(ctx context.Context, req *QuerySigningInfosRequest) (*QuerySigningInfosResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SigningInfos not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -1339,6 +1580,42 @@ func _Query_ListEvidences_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Query_SigningInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySigningInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).SigningInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.finality.v1.Query/SigningInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).SigningInfo(ctx, req.(*QuerySigningInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_SigningInfos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySigningInfosRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).SigningInfos(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/babylon.finality.v1.Query/SigningInfos", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).SigningInfos(ctx, req.(*QuerySigningInfosRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "babylon.finality.v1.Query", HandlerType: (*QueryServer)(nil), @@ -1375,6 +1652,14 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "ListEvidences", Handler: _Query_ListEvidences_Handler, }, + { + MethodName: "SigningInfo", + Handler: _Query_SigningInfo_Handler, + }, + { + MethodName: "SigningInfos", + Handler: _Query_SigningInfos_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "babylon/finality/v1/query.proto", @@ -2044,82 +2329,229 @@ func (m *QueryListEvidencesResponse) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } -func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { - offset -= sovQuery(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *QueryParamsRequest) Size() (n int) { - if m == nil { - return 0 +func (m *QuerySigningInfoRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - var l int - _ = l - return n + return dAtA[:n], nil } -func (m *QueryParamsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = m.Params.Size() - n += 1 + l + sovQuery(uint64(l)) - return n +func (m *QuerySigningInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryListPublicRandomnessRequest) Size() (n int) { - if m == nil { - return 0 - } +func (m *QuerySigningInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - l = len(m.FpBtcPkHex) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + if len(m.FpBtcPkHex) > 0 { + i -= len(m.FpBtcPkHex) + copy(dAtA[i:], m.FpBtcPkHex) + i = encodeVarintQuery(dAtA, i, uint64(len(m.FpBtcPkHex))) + i-- + dAtA[i] = 0xa } - return n + return len(dAtA) - i, nil } -func (m *QueryListPublicRandomnessResponse) Size() (n int) { - if m == nil { - return 0 +func (m *QuerySigningInfoResponse) 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 *QuerySigningInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySigningInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if len(m.PubRandMap) > 0 { - for k, v := range m.PubRandMap { - _ = k - _ = v - l = 0 - if v != nil { - l = v.Size() - l += 1 + sovQuery(uint64(l)) - } - mapEntrySize := 1 + sovQuery(uint64(k)) + l - n += mapEntrySize + 1 + sovQuery(uint64(mapEntrySize)) + { + size, err := m.FpSigningInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } - return n + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil } -func (m *PubRandCommitResponse) Size() (n int) { - if m == nil { +func (m *QuerySigningInfosRequest) 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 *QuerySigningInfosRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySigningInfosRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySigningInfosResponse) 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 *QuerySigningInfosResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySigningInfosResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.FpSigningInfos) > 0 { + for iNdEx := len(m.FpSigningInfos) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.FpSigningInfos[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryListPublicRandomnessRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FpBtcPkHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryListPublicRandomnessResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.PubRandMap) > 0 { + for k, v := range m.PubRandMap { + _ = k + _ = v + l = 0 + if v != nil { + l = v.Size() + l += 1 + sovQuery(uint64(l)) + } + mapEntrySize := 1 + sovQuery(uint64(k)) + l + n += mapEntrySize + 1 + sovQuery(uint64(mapEntrySize)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *PubRandCommitResponse) Size() (n int) { + if m == nil { return 0 } var l int @@ -2325,6 +2757,62 @@ func (m *QueryListEvidencesResponse) Size() (n int) { return n } +func (m *QuerySigningInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FpBtcPkHex) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySigningInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.FpSigningInfo.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QuerySigningInfosRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySigningInfosResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.FpSigningInfos) > 0 { + for _, e := range m.FpSigningInfos { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -4133,6 +4621,377 @@ func (m *QueryListEvidencesResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QuerySigningInfoRequest) 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 ErrIntOverflowQuery + } + 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: QuerySigningInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySigningInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPkHex", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FpBtcPkHex = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySigningInfoResponse) 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 ErrIntOverflowQuery + } + 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: QuerySigningInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySigningInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpSigningInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.FpSigningInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySigningInfosRequest) 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 ErrIntOverflowQuery + } + 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: QuerySigningInfosRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySigningInfosRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySigningInfosResponse) 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 ErrIntOverflowQuery + } + 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: QuerySigningInfosResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySigningInfosResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpSigningInfos", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FpSigningInfos = append(m.FpSigningInfos, FinalityProviderSigningInfo{}) + if err := m.FpSigningInfos[len(m.FpSigningInfos)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/finality/types/query.pb.gw.go b/x/finality/types/query.pb.gw.go index 1309d501b..6211809d2 100644 --- a/x/finality/types/query.pb.gw.go +++ b/x/finality/types/query.pb.gw.go @@ -429,6 +429,96 @@ func local_request_Query_ListEvidences_0(ctx context.Context, marshaler runtime. } +func request_Query_SigningInfo_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySigningInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + msg, err := client.SigningInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_SigningInfo_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySigningInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["fp_btc_pk_hex"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "fp_btc_pk_hex") + } + + protoReq.FpBtcPkHex, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "fp_btc_pk_hex", err) + } + + msg, err := server.SigningInfo(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_SigningInfos_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_SigningInfos_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySigningInfosRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_SigningInfos_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SigningInfos(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_SigningInfos_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySigningInfosRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_SigningInfos_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SigningInfos(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -619,6 +709,52 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_SigningInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_SigningInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SigningInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_SigningInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_SigningInfos_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SigningInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -820,6 +956,46 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_SigningInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_SigningInfo_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SigningInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_SigningInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_SigningInfos_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SigningInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -839,6 +1015,10 @@ var ( pattern_Query_Evidence_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 2, 5}, []string{"babylon", "finality", "v1", "finality_providers", "fp_btc_pk_hex", "evidence"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_ListEvidences_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "evidences"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_SigningInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"babylon", "finality", "v1", "signing_infos", "fp_btc_pk_hex"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_SigningInfos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"babylon", "finality", "v1", "signing_infos"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -857,4 +1037,8 @@ var ( forward_Query_Evidence_0 = runtime.ForwardResponseMessage forward_Query_ListEvidences_0 = runtime.ForwardResponseMessage + + forward_Query_SigningInfo_0 = runtime.ForwardResponseMessage + + forward_Query_SigningInfos_0 = runtime.ForwardResponseMessage ) From bc209828fa1504d07e210bca5db45b57f9b43797 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 17 Jul 2024 09:40:47 +0200 Subject: [PATCH 111/119] Improve extracting data from op_return + add tests (#716) * Improve extracting data from op_return + add tests * remove unused constant --- x/btccheckpoint/types/btcutils.go | 71 +++++++++------- x/btccheckpoint/types/btcutils_test.go | 110 +++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 31 deletions(-) diff --git a/x/btccheckpoint/types/btcutils.go b/x/btccheckpoint/types/btcutils.go index 37670301f..9fc55702c 100644 --- a/x/btccheckpoint/types/btcutils.go +++ b/x/btccheckpoint/types/btcutils.go @@ -13,18 +13,6 @@ import ( "github.com/btcsuite/btcd/txscript" ) -const ( - // 1 byte for OP_RETURN opcode - // 1 byte for OP_DATAXX, or 2 bytes for OP_PUSHDATA1 opcode - // max 80 bytes of application specific data - // This stems from the fact that if data in op_return is less than 75 bytes - // one of OP_DATAXX opcodes is used (https://wiki.bitcoinsv.io/index.php/Pushdata_Opcodes#Opcodes_1-75_.280x01_-_0x4B.29) - // but if data in op_return is between 76 and 80bytes, OP_PUSHDATA1 needs to be used - // in which 1 byte indicates op code itself and 1 byte indicates how many bytes - // are pushed onto stack (https://wiki.bitcoinsv.io/index.php/Pushdata_Opcodes#OP_PUSHDATA1_.2876_or_0x4C.29) - maxOpReturnPkScriptSize = 83 -) - // ParsedProof represent semantically valid: // - Bitcoin Header // - Bitcoin Header hash @@ -204,32 +192,49 @@ func verify(tx *btcutil.Tx, merkleRoot *chainhash.Hash, intermediateNodes []byte return bytes.Equal(current[:], root) } -func ExtractOpReturnData(tx *btcutil.Tx) []byte { +// ExtractStandardOpReturnData extract OP_RETURN data from transaction OP_RETURN +// output. +// If OP_RETURN output is not standard it will be ignored. If there is more than +// one output with OP_RETURN, error will be returned. +func ExtractStandardOpReturnData(tx *btcutil.Tx) ([]byte, error) { msgTx := tx.MsgTx() opReturnData := []byte{} + var opReturnCounter = 0 + for _, output := range msgTx.TxOut { - pkScript := output.PkScript - pkScriptLen := len(pkScript) - // valid op return script will have at least 2 bytes - // - fisrt byte should be OP_RETURN marker - // - second byte should indicate how many bytes there are in opreturn script - if pkScriptLen > 1 && - pkScriptLen <= maxOpReturnPkScriptSize && - pkScript[0] == txscript.OP_RETURN { - - // if this is OP_PUSHDATA1, we need to drop first 3 bytes as those are related + script := output.PkScript + + if !txscript.IsNullData(script) { + // not a standard op_return, we do not care about this output + continue + } + // At this point we know: + // - script is not empty + // - script is valid looking op_return + // - with at most 80bytes of data + opReturnCounter++ + + if opReturnCounter > 1 { + return nil, fmt.Errorf("transaction has more than one OP_RETURN output") + } + + if len(script) == 1 { + // just op_return op code + continue + } + + if script[1] == txscript.OP_PUSHDATA1 { + // we need to drop first 3 bytes as those are related // to script iteslf i.e OP_RETURN + OP_PUSHDATA1 + len of bytes - if pkScript[1] == txscript.OP_PUSHDATA1 { - opReturnData = append(opReturnData, pkScript[3:]...) - } else { - // this should be one of OP_DATAXX opcodes we drop first 2 bytes - opReturnData = append(opReturnData, pkScript[2:]...) - } + opReturnData = append(opReturnData, script[3:]...) + } else { + // this should be one of OP_DATAXX opcodes we drop first 2 bytes + opReturnData = append(opReturnData, script[2:]...) } } - return opReturnData + return opReturnData, nil } func ParseTransaction(bytes []byte) (*btcutil.Tx, error) { @@ -276,7 +281,11 @@ func ParseProof( return nil, fmt.Errorf("header failed validation due to failed proof") } - opReturnData := ExtractOpReturnData(tx) + opReturnData, err := ExtractStandardOpReturnData(tx) + + if err != nil { + return nil, err + } if len(opReturnData) == 0 { return nil, fmt.Errorf("provided transaction should provide op return data") diff --git a/x/btccheckpoint/types/btcutils_test.go b/x/btccheckpoint/types/btcutils_test.go index 576929eea..803750dd4 100644 --- a/x/btccheckpoint/types/btcutils_test.go +++ b/x/btccheckpoint/types/btcutils_test.go @@ -3,12 +3,19 @@ package types_test import ( "bytes" "encoding/hex" + "math/rand" "testing" + "time" + "github.com/babylonchain/babylon/testutil/datagen" bbn "github.com/babylonchain/babylon/types" btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/btcsuite/btcd/btcutil" btcchaincfg "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/stretchr/testify/require" ) // Sanity test checking mostly btcd code, that we can realy parse bitcoin transaction @@ -164,3 +171,106 @@ func TestParsingCorrectBtcProofs(t *testing.T) { } } } + +func buildOpReturnOutput(t *testing.T, r *rand.Rand, dataLen int) *wire.TxOut { + data := datagen.GenRandomByteArray(r, uint64(dataLen)) + pkscript, err := txscript.NewScriptBuilder().AddOp(txscript.OP_RETURN).AddData(data).Script() + require.NoError(t, err) + + return wire.NewTxOut(0, pkscript) +} + +func TestExtractingOpReturn(t *testing.T) { + tests := []struct { + name string + buildTxFn func(t *testing.T, r *rand.Rand) *btcutil.Tx + expectedDatalen int + returnsErr bool + }{ + { + name: "transaction with 1 op_return output containing 80 bytes of data", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + tx.AddTxOut(buildOpReturnOutput(t, r, 80)) + return btcutil.NewTx(tx) + }, + expectedDatalen: 80, + returnsErr: false, + }, + { + name: "transaction with 1 op_return output containing 81 bytes of data", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + tx.AddTxOut(buildOpReturnOutput(t, r, 81)) + return btcutil.NewTx(tx) + }, + expectedDatalen: 0, + returnsErr: false, + }, + { + name: "transaction with 1 op_return output containing 0 bytes of data", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + tx.AddTxOut(buildOpReturnOutput(t, r, 0)) + return btcutil.NewTx(tx) + }, + expectedDatalen: 0, + returnsErr: false, + }, + { + name: "transaction with 2 op_return outputs", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + tx.AddTxOut(buildOpReturnOutput(t, r, 1)) + tx.AddTxOut(buildOpReturnOutput(t, r, 2)) + return btcutil.NewTx(tx) + }, + expectedDatalen: 0, + returnsErr: true, + }, + { + name: "transaction with 1 op_return output containing 80 bytes of data, but with invalid OP_PUSHDATA2 opcode", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + output := buildOpReturnOutput(t, r, 80) + // change valid txscript.OP_PUSHDATA1 to invalid txscript.OP_PUSHDATA2. + // This op code is invalid because it pushes less than 255 bytes of data + output.PkScript[1] = txscript.OP_PUSHDATA2 + tx.AddTxOut(output) + return btcutil.NewTx(tx) + }, + expectedDatalen: 0, + returnsErr: false, + }, + { + name: "transaction with 1 op_return output containing 80 bytes of data, but with invalid OP_PUSHDATA4 opcode", + buildTxFn: func(t *testing.T, r *rand.Rand) *btcutil.Tx { + tx := wire.NewMsgTx(wire.TxVersion) + output := buildOpReturnOutput(t, r, 80) + // change valid txscript.OP_PUSHDATA1 to invalid txscript.OP_PUSHDATA2. + // This op code is invalid because it pushes less than 255 bytes of data + output.PkScript[1] = txscript.OP_PUSHDATA4 + tx.AddTxOut(output) + return btcutil.NewTx(tx) + }, + expectedDatalen: 0, + returnsErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := rand.New(rand.NewSource(time.Now().Unix())) + tx := tt.buildTxFn(t, r) + data, err := btcctypes.ExtractStandardOpReturnData(tx) + if tt.returnsErr { + require.Error(t, err) + require.Nil(t, data) + } else { + require.NoError(t, err) + require.NotNil(t, data) + require.Equal(t, tt.expectedDatalen, len(data)) + } + }) + } +} From 6193496a29cedb6dede2fcff94b5f746e23078db Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 17 Jul 2024 10:51:03 +0200 Subject: [PATCH 112/119] Add cometbft to run-node docs (#718) --- docs/run-node.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/run-node.md b/docs/run-node.md index e92eb4363..fe4cdf534 100644 --- a/docs/run-node.md +++ b/docs/run-node.md @@ -139,6 +139,11 @@ $ ls .testnets gentxs node0 node1 node2 node3 ``` +## Running node in Production + +When running the Babylon node in a production setting, operators should adhere to  +[CometBFT Guidelines](https://docs.cometbft.com/v0.38/core/running-in-production) + ## Testing ```console From 135c23a999f732091ef3bbc466691e33150d8225 Mon Sep 17 00:00:00 2001 From: KonradStaniec Date: Wed, 17 Jul 2024 15:09:51 +0200 Subject: [PATCH 113/119] Disable failure scenario in feegranttyped test (#719) --- test/e2e/btc_staking_e2e_test.go | 43 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index d8d85a5e4..e76a83c11 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -14,7 +14,6 @@ import ( "github.com/stretchr/testify/suite" sdkmath "cosmossdk.io/math" - "cosmossdk.io/x/feegrant" feegrantcli "cosmossdk.io/x/feegrant/client/cli" sdk "github.com/cosmos/cosmos-sdk/types" @@ -686,27 +685,27 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { // submit the message to create BTC delegation using the fee grant // but putting as fee more than the spend limit // it should fail by exceeding the fee limit. - output := node.CreateBTCDelegation( - bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), - pop, - stakingTxInfo, - cacheFP.BtcPk, - stakingTimeBlocks, - btcutil.Amount(stakingValue), - testStakingInfo.SlashingTx, - delegatorSig, - testUnbondingInfo.UnbondingTx, - testUnbondingInfo.SlashingTx, - uint16(unbondingTime), - btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), - delUnbondingSlashingSig, - wGratee, - false, - fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), - fmt.Sprintf("--fees=%s", fees.Add(stakerBalance).String()), - ) - s.Require().Contains(output, fmt.Sprintf("code: %d", feegrant.ErrFeeLimitExceeded.ABCICode())) - s.Require().Contains(output, feegrant.ErrFeeLimitExceeded.Error()) + // output := node.CreateBTCDelegation( + // bbn.NewBIP340PubKeyFromBTCPK(delBTCPK), + // pop, + // stakingTxInfo, + // cacheFP.BtcPk, + // stakingTimeBlocks, + // btcutil.Amount(stakingValue), + // testStakingInfo.SlashingTx, + // delegatorSig, + // testUnbondingInfo.UnbondingTx, + // testUnbondingInfo.SlashingTx, + // uint16(unbondingTime), + // btcutil.Amount(testUnbondingInfo.UnbondingInfo.UnbondingOutput.Value), + // delUnbondingSlashingSig, + // wGratee, + // false, + // fmt.Sprintf("--fee-granter=%s", feePayerAddr.String()), + // fmt.Sprintf("--fees=%s", fees.Add(stakerBalance).String()), + // ) + // s.Require().Contains(output, fmt.Sprintf("code: %d", feegrant.ErrFeeLimitExceeded.ABCICode())) + // s.Require().Contains(output, feegrant.ErrFeeLimitExceeded.Error()) // submit the message to create BTC delegation using the fee grant at the max of spend limit node.CreateBTCDelegation( From 66d213148a023393ecfe7a59ccefb16d32a7b116 Mon Sep 17 00:00:00 2001 From: Cirrus Gai Date: Fri, 19 Jul 2024 13:25:12 +0800 Subject: [PATCH 114/119] chore(inactivity): Add `SigningInfo` and `MissedBlock` to `x/finality` genesis state (#720) --- proto/babylon/finality/v1/genesis.proto | 33 +- x/finality/keeper/genesis.go | 58 +- x/finality/keeper/genesis_test.go | 201 +++--- x/finality/keeper/signing_info.go | 64 +- x/finality/types/genesis.pb.go | 898 ++++++++++++++++++++++-- 5 files changed, 1108 insertions(+), 146 deletions(-) diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index 9edc47c7c..af3ef6cd6 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -21,6 +21,12 @@ message GenesisState { repeated PublicRandomness public_randomness = 5; // pub_rand_commit contains all the public randomness commitment ever commited from the finality providers. repeated PubRandCommitWithPK pub_rand_commit = 6; + // signing_infos represents a map between finality provider public key and their + // signing infos. + repeated SigningInfo signing_infos = 7 [(gogoproto.nullable) = false]; + // missed_blocks represents a map between finality provider public key and their + // missed blocks. + repeated FinalityProviderMissedBlocks missed_blocks = 8 [(gogoproto.nullable) = false]; } // VoteSig the vote of an finality provider @@ -51,4 +57,29 @@ message PubRandCommitWithPK { bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; // pub_rand_commit is the public randomness commitment PubRandCommit pub_rand_commit = 2; -} \ No newline at end of file +} + +// SigningInfo stores finality provider signing info of corresponding BTC public key. +message SigningInfo { + // fp_btc_pk is the BTC PK of the finality provider + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // fp_signing_info represents the signing info of this finality provider. + FinalityProviderSigningInfo fp_signing_info = 2 [(gogoproto.nullable) = false]; +} + +// FinalityProviderMissedBlocks contains array of missed blocks of corresponding +// BTC public key. +message FinalityProviderMissedBlocks { + // fp_btc_pk is the BTC PK of the finality provider + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + // missed_blocks is an array of missed blocks by the finality provider. + repeated MissedBlock missed_blocks = 2 [(gogoproto.nullable) = false]; +} + +// MissedBlock contains height and missed status as boolean. +message MissedBlock { + // index is the height at which the block was missed. + int64 index = 1; + // missed is the missed status. + bool missed = 2; +} diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index d6e700640..9a70531cb 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -4,10 +4,11 @@ import ( "context" "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + btcstk "github.com/babylonchain/babylon/btcstaking" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" - sdk "github.com/cosmos/cosmos-sdk/types" ) // InitGenesis initializes the keeper state from a provided initial genesis state. @@ -32,6 +33,21 @@ func (k Keeper) InitGenesis(ctx context.Context, gs types.GenesisState) error { k.SetPubRandCommit(ctx, prc.FpBtcPk, prc.PubRandCommit) } + for _, info := range gs.SigningInfos { + err := k.FinalityProviderSigningTracker.Set(ctx, info.FpBtcPk.MustMarshal(), info.FpSigningInfo) + if err != nil { + return err + } + } + + for _, array := range gs.MissedBlocks { + for _, missed := range array.MissedBlocks { + if err := k.SetMissedBlockBitmapValue(ctx, array.FpBtcPk, missed.Index, missed.Missed); err != nil { + return err + } + } + } + return k.SetParams(ctx, gs.Params) } @@ -62,6 +78,11 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) return nil, err } + signingInfos, missedBlocks, err := k.signingInfosAndMissedBlock(ctx) + if err != nil { + return nil, err + } + return &types.GenesisState{ Params: k.GetParams(ctx), IndexedBlocks: blocks, @@ -69,6 +90,8 @@ func (k Keeper) ExportGenesis(ctx context.Context) (*types.GenesisState, error) VoteSigs: voteSigs, PublicRandomness: pubRandomness, PubRandCommit: prCommit, + SigningInfos: signingInfos, + MissedBlocks: missedBlocks, }, nil } @@ -198,6 +221,39 @@ func (k Keeper) exportPubRandCommit(ctx context.Context) ([]*types.PubRandCommit return commtRandoms, nil } +func (k Keeper) signingInfosAndMissedBlock(ctx context.Context) ([]types.SigningInfo, []types.FinalityProviderMissedBlocks, error) { + signingInfos := make([]types.SigningInfo, 0) + missedBlocks := make([]types.FinalityProviderMissedBlocks, 0) + err := k.FinalityProviderSigningTracker.Walk(ctx, nil, func(fpPkBytes []byte, info types.FinalityProviderSigningInfo) (stop bool, err error) { + fpPk, err := bbn.NewBIP340PubKey(fpPkBytes) + if err != nil { + return true, err + } + + signingInfos = append(signingInfos, types.SigningInfo{ + FpBtcPk: fpPk, + FpSigningInfo: info, + }) + + localMissedBlocks, err := k.GetFinalityProviderMissedBlocks(ctx, fpPk) + if err != nil { + return true, err + } + + missedBlocks = append(missedBlocks, types.FinalityProviderMissedBlocks{ + FpBtcPk: fpPk, + MissedBlocks: localMissedBlocks, + }) + + return false, nil + }) + if err != nil { + return nil, nil, err + } + + return signingInfos, missedBlocks, nil +} + // parsePubKeyAndBlkHeightFromStoreKey expects to receive a key with // BIP340PubKey(fpBTCPK) || BigEndianUint64(blkHeight) func parsePubKeyAndBlkHeightFromStoreKey(key []byte) (fpBTCPK *bbn.BIP340PubKey, blkHeight uint64, err error) { diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index ce7e87bc9..bbec05549 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -4,100 +4,129 @@ import ( "math/rand" "testing" + "github.com/stretchr/testify/require" + "github.com/babylonchain/babylon/testutil/datagen" keepertest "github.com/babylonchain/babylon/testutil/keeper" bbn "github.com/babylonchain/babylon/types" "github.com/babylonchain/babylon/x/finality/types" - "github.com/stretchr/testify/require" ) -func TestExportGenesis(t *testing.T) { - k, ctx := keepertest.FinalityKeeper(t, nil, nil) - - r := rand.New(rand.NewSource(10)) - btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) - require.NoError(t, err) - - fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) - blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) - - randListInfo, _, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) - require.NoError(t, err) - - blockHash := datagen.GenRandomByteArray(r, 32) - signer := datagen.GenRandomAccount().Address - msgAddFinalitySig, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blkHeight, randListInfo, blockHash) - require.NoError(t, err) - - allVotes := make([]*types.VoteSig, numPubRand) - allBlocks := make([]*types.IndexedBlock, numPubRand) - allEvidences := make([]*types.Evidence, numPubRand) - allPublicRandomness := make([]*types.PublicRandomness, numPubRand) - for i := 0; i < int(numPubRand); i++ { - // Votes - vt := &types.VoteSig{ - FpBtcPk: fpBTCPK, - BlockHeight: blkHeight, - FinalitySig: msgAddFinalitySig.FinalitySig, +func FuzzTestExportGenesis(f *testing.F) { + datagen.AddRandomSeedsToFuzzer(f, 10) + f.Fuzz(func(t *testing.T, seed int64) { + r := rand.New(rand.NewSource(seed)) + k, ctx := keepertest.FinalityKeeper(t, nil, nil) + + btcSK, btcPK, err := datagen.GenRandomBTCKeyPair(r) + require.NoError(t, err) + + fpBTCPK := bbn.NewBIP340PubKeyFromBTCPK(btcPK) + blkHeight, startHeight, numPubRand := uint64(1), uint64(0), uint64(5) + + randListInfo, _, err := datagen.GenRandomMsgCommitPubRandList(r, btcSK, startHeight, numPubRand) + require.NoError(t, err) + + blockHash := datagen.GenRandomByteArray(r, 32) + signer := datagen.GenRandomAccount().Address + msgAddFinalitySig, err := datagen.NewMsgAddFinalitySig(signer, btcSK, startHeight, blkHeight, randListInfo, blockHash) + require.NoError(t, err) + + allVotes := make([]*types.VoteSig, numPubRand) + allBlocks := make([]*types.IndexedBlock, numPubRand) + allEvidences := make([]*types.Evidence, numPubRand) + allPublicRandomness := make([]*types.PublicRandomness, numPubRand) + for i := 0; i < int(numPubRand); i++ { + // Votes + vt := &types.VoteSig{ + FpBtcPk: fpBTCPK, + BlockHeight: blkHeight, + FinalitySig: msgAddFinalitySig.FinalitySig, + } + k.SetSig(ctx, vt.BlockHeight, vt.FpBtcPk, vt.FinalitySig) + allVotes[i] = vt + + // Blocks + blk := &types.IndexedBlock{ + Height: blkHeight, + AppHash: blockHash, + Finalized: i%2 == 0, + } + k.SetBlock(ctx, blk) + allBlocks[i] = blk + + // Evidences + evidence := &types.Evidence{ + FpBtcPk: fpBTCPK, + BlockHeight: blkHeight, + PubRand: &randListInfo.PRList[i], + ForkAppHash: msgAddFinalitySig.BlockAppHash, + ForkFinalitySig: msgAddFinalitySig.FinalitySig, + CanonicalAppHash: blockHash, + CanonicalFinalitySig: msgAddFinalitySig.FinalitySig, + } + k.SetEvidence(ctx, evidence) + allEvidences[i] = evidence + + // public randomness + pubRand := randListInfo.PRList[i] + k.SetPubRand(ctx, fpBTCPK, blkHeight, pubRand) + randomness := &types.PublicRandomness{ + BlockHeight: blkHeight, + FpBtcPk: fpBTCPK, + PubRand: &pubRand, + } + allPublicRandomness[i] = randomness + + // updates the block everytime to make sure something is different. + blkHeight++ } - k.SetSig(ctx, vt.BlockHeight, vt.FpBtcPk, vt.FinalitySig) - allVotes[i] = vt - - // Blocks - blk := &types.IndexedBlock{ - Height: blkHeight, - AppHash: blockHash, - Finalized: i%2 == 0, + + prc := &types.PubRandCommit{ + StartHeight: startHeight, + NumPubRand: numPubRand, + Commitment: randListInfo.Commitment, } - k.SetBlock(ctx, blk) - allBlocks[i] = blk - - // Evidences - evidence := &types.Evidence{ - FpBtcPk: fpBTCPK, - BlockHeight: blkHeight, - PubRand: &randListInfo.PRList[i], - ForkAppHash: msgAddFinalitySig.BlockAppHash, - ForkFinalitySig: msgAddFinalitySig.FinalitySig, - CanonicalAppHash: blockHash, - CanonicalFinalitySig: msgAddFinalitySig.FinalitySig, + k.SetPubRandCommit(ctx, fpBTCPK, prc) + + numSigningInfo := datagen.RandomInt(r, 100) + 10 + fpSigningInfos := map[string]*types.FinalityProviderSigningInfo{} + fpPks := make([]string, 0) + for i := uint64(0); i < numSigningInfo; i++ { + // random key pair + fpPk, err := datagen.GenRandomBIP340PubKey(r) + require.NoError(t, err) + fpPks = append(fpPks, fpPk.MarshalHex()) + + // random height and missed block counter + height := int64(datagen.RandomInt(r, 100) + 1) + missedBlockCounter := int64(datagen.RandomInt(r, 100) + 1) + + // create signing info and add it to map and finality keeper + signingInfo := types.NewFinalityProviderSigningInfo(fpPk, height, missedBlockCounter) + err = k.FinalityProviderSigningTracker.Set(ctx, fpPk.MustMarshal(), signingInfo) + require.NoError(t, err) + fpSigningInfos[fpPk.MarshalHex()] = &signingInfo } - k.SetEvidence(ctx, evidence) - allEvidences[i] = evidence - - // public randomness - pubRand := randListInfo.PRList[i] - k.SetPubRand(ctx, fpBTCPK, blkHeight, pubRand) - randomness := &types.PublicRandomness{ - BlockHeight: blkHeight, - FpBtcPk: fpBTCPK, - PubRand: &pubRand, + + require.Equal(t, len(allVotes), int(numPubRand)) + require.Equal(t, len(allBlocks), int(numPubRand)) + require.Equal(t, len(allEvidences), int(numPubRand)) + require.Equal(t, len(allPublicRandomness), int(numPubRand)) + + gs, err := k.ExportGenesis(ctx) + require.NoError(t, err) + require.Equal(t, k.GetParams(ctx), gs.Params) + + require.Equal(t, allVotes, gs.VoteSigs) + require.Equal(t, allBlocks, gs.IndexedBlocks) + require.Equal(t, allEvidences, gs.Evidences) + require.Equal(t, allPublicRandomness, gs.PublicRandomness) + require.Equal(t, prc, gs.PubRandCommit[0].PubRandCommit) + require.Equal(t, len(fpPks), len(gs.SigningInfos)) + for _, info := range gs.SigningInfos { + require.Equal(t, fpSigningInfos[info.FpBtcPk.MarshalHex()].MissedBlocksCounter, info.FpSigningInfo.MissedBlocksCounter) + require.Equal(t, fpSigningInfos[info.FpBtcPk.MarshalHex()].StartHeight, info.FpSigningInfo.StartHeight) } - allPublicRandomness[i] = randomness - - // updates the block everytime to make sure something is different. - blkHeight++ - } - - prc := &types.PubRandCommit{ - StartHeight: startHeight, - NumPubRand: numPubRand, - Commitment: randListInfo.Commitment, - } - k.SetPubRandCommit(ctx, fpBTCPK, prc) - - require.Equal(t, len(allVotes), int(numPubRand)) - require.Equal(t, len(allBlocks), int(numPubRand)) - require.Equal(t, len(allEvidences), int(numPubRand)) - require.Equal(t, len(allPublicRandomness), int(numPubRand)) - - gs, err := k.ExportGenesis(ctx) - require.NoError(t, err) - require.Equal(t, k.GetParams(ctx), gs.Params) - - require.Equal(t, allVotes, gs.VoteSigs) - require.Equal(t, allBlocks, gs.IndexedBlocks) - require.Equal(t, allEvidences, gs.Evidences) - require.Equal(t, allPublicRandomness, gs.PublicRandomness) - require.Equal(t, prc, gs.PubRandCommit[0].PubRandCommit) + }) } diff --git a/x/finality/keeper/signing_info.go b/x/finality/keeper/signing_info.go index 262687a13..80d80cc82 100644 --- a/x/finality/keeper/signing_info.go +++ b/x/finality/keeper/signing_info.go @@ -7,7 +7,6 @@ import ( "cosmossdk.io/collections" errorsmod "cosmossdk.io/errors" "github.com/bits-and-blooms/bitset" - "github.com/cosmos/cosmos-sdk/x/slashing/types" bbntypes "github.com/babylonchain/babylon/types" finalitytypes "github.com/babylonchain/babylon/x/finality/types" @@ -37,22 +36,22 @@ func (k Keeper) GetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BI // get the bit position in the chunk of the logical bitmap, where Test() // checks if the bit is set. - bitIndex := index % types.MissedBlockBitmapChunkSize + bitIndex := index % finalitytypes.MissedBlockBitmapChunkSize return bs.Test(uint(bitIndex)), nil } -// SetMissedBlockBitmapValue sets, i.e. flips, a bit in the validator's missed +// SetMissedBlockBitmapValue sets, i.e. flips, a bit in the finality provider's missed // block bitmap. When missed=true, the bit is set, otherwise it set to zero. The // index provided is assumed to be the index in the range [0, SignedBlocksWindow), // which represents the bitmap where each bit represents a height, and is -// determined by the validator's IndexOffset modulo SignedBlocksWindow. This +// determined by the finality provider's IndexOffset modulo SignedBlocksWindow. This // index is used to fetch the chunk in the bitmap and the relative bit in that // chunk. func (k Keeper) SetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BIP340PubKey, index int64, missed bool) error { // get the chunk or "word" in the logical bitmap - chunkIndex := index / types.MissedBlockBitmapChunkSize + chunkIndex := index / finalitytypes.MissedBlockBitmapChunkSize - bs := bitset.New(uint(types.MissedBlockBitmapChunkSize)) + bs := bitset.New(uint(finalitytypes.MissedBlockBitmapChunkSize)) chunk, err := k.getMissedBlockBitmapChunk(ctx, fpPk, chunkIndex) if err != nil { return errorsmod.Wrapf(err, "failed to get bitmap chunk; index: %d", index) @@ -65,7 +64,7 @@ func (k Keeper) SetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BI } // get the bit position in the chunk of the logical bitmap - bitIndex := uint(index % types.MissedBlockBitmapChunkSize) + bitIndex := uint(index % finalitytypes.MissedBlockBitmapChunkSize) if missed { bs.Set(bitIndex) } else { @@ -80,14 +79,61 @@ func (k Keeper) SetMissedBlockBitmapValue(ctx context.Context, fpPk *bbntypes.BI return k.SetMissedBlockBitmapChunk(ctx, fpPk, chunkIndex, updatedChunk) } -// DeleteMissedBlockBitmap removes a validator's missed block bitmap from state. +// GetFinalityProviderMissedBlocks returns array of missed blocks for given finality provider. +// Adapted from +// https://github.com/cosmos/cosmos-sdk/blob/f499bbf2138b171d6e5396a37df7699952e76bf3/x/slashing/keeper/signing_info.go#L224 +func (k Keeper) GetFinalityProviderMissedBlocks(ctx context.Context, fpPk *bbntypes.BIP340PubKey) ([]finalitytypes.MissedBlock, error) { + signedBlocksWindow := k.GetParams(ctx).SignedBlocksWindow + + missedBlocks := make([]finalitytypes.MissedBlock, 0, signedBlocksWindow) + err := k.IterateMissedBlockBitmap(ctx, fpPk, func(index int64, missed bool) (stop bool) { + if missed { + missedBlocks = append(missedBlocks, finalitytypes.MissedBlock{Index: index, Missed: missed}) + } + + return false + }) + + return missedBlocks, err +} + +// IterateMissedBlockBitmap iterates over a finality provider's signed blocks window +// bitmap and performs a callback function on each index, i.e. block height, in +// the range [0, SignedBlocksWindow). +// Note: A callback will only be executed over all bitmap chunks that exist in +// state. +// Adapted from +// https://github.com/cosmos/cosmos-sdk/blob/f499bbf2138b171d6e5396a37df7699952e76bf3/x/slashing/keeper/signing_info.go#L202 +func (k Keeper) IterateMissedBlockBitmap(ctx context.Context, fpPk *bbntypes.BIP340PubKey, cb func(index int64, missed bool) (stop bool)) error { + var index int64 + rng := collections.NewPrefixedPairRange[[]byte, uint64](fpPk.MustMarshal()) + return k.FinalityProviderMissedBlockBitmap.Walk(ctx, rng, func(key collections.Pair[[]byte, uint64], value []byte) (bool, error) { + bs := bitset.New(uint(finalitytypes.MissedBlockBitmapChunkSize)) + + if err := bs.UnmarshalBinary(value); err != nil { + return true, errorsmod.Wrapf(err, "failed to decode bitmap chunk; index: %v", key) + } + + for i := uint(0); i < finalitytypes.MissedBlockBitmapChunkSize; i++ { + // execute the callback, where Test() returns true if the bit is set + if cb(index, bs.Test(i)) { + break + } + + index++ + } + return false, nil + }) +} + +// DeleteMissedBlockBitmap removes a finality provider's missed block bitmap from state. func (k Keeper) DeleteMissedBlockBitmap(ctx context.Context, fpPk *bbntypes.BIP340PubKey) error { rng := collections.NewPrefixedPairRange[[]byte, uint64](fpPk.MustMarshal()) return k.FinalityProviderMissedBlockBitmap.Clear(ctx, rng) } // SetMissedBlockBitmapChunk sets the bitmap chunk at the given chunk index for -// a validator's missed block signing window. +// a finality provider's missed block signing window. func (k Keeper) SetMissedBlockBitmapChunk(ctx context.Context, fpPk *bbntypes.BIP340PubKey, chunkIndex int64, chunk []byte) error { return k.FinalityProviderMissedBlockBitmap.Set(ctx, collections.Join(fpPk.MustMarshal(), uint64(chunkIndex)), chunk) } diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 7663e230b..596eaf57b 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -38,6 +38,12 @@ type GenesisState struct { PublicRandomness []*PublicRandomness `protobuf:"bytes,5,rep,name=public_randomness,json=publicRandomness,proto3" json:"public_randomness,omitempty"` // pub_rand_commit contains all the public randomness commitment ever commited from the finality providers. PubRandCommit []*PubRandCommitWithPK `protobuf:"bytes,6,rep,name=pub_rand_commit,json=pubRandCommit,proto3" json:"pub_rand_commit,omitempty"` + // signing_infos represents a map between finality provider public key and their + // signing infos. + SigningInfos []SigningInfo `protobuf:"bytes,7,rep,name=signing_infos,json=signingInfos,proto3" json:"signing_infos"` + // missed_blocks represents a map between finality provider public key and their + // missed blocks. + MissedBlocks []FinalityProviderMissedBlocks `protobuf:"bytes,8,rep,name=missed_blocks,json=missedBlocks,proto3" json:"missed_blocks"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -115,6 +121,20 @@ func (m *GenesisState) GetPubRandCommit() []*PubRandCommitWithPK { return nil } +func (m *GenesisState) GetSigningInfos() []SigningInfo { + if m != nil { + return m.SigningInfos + } + return nil +} + +func (m *GenesisState) GetMissedBlocks() []FinalityProviderMissedBlocks { + if m != nil { + return m.MissedBlocks + } + return nil +} + // VoteSig the vote of an finality provider // with the block of the vote, the finality provider btc public key and the vote signature. type VoteSig struct { @@ -265,51 +285,216 @@ func (m *PubRandCommitWithPK) GetPubRandCommit() *PubRandCommit { return nil } +// SigningInfo stores finality provider signing info of corresponding BTC public key. +type SigningInfo struct { + // fp_btc_pk is the BTC PK of the finality provider + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // fp_signing_info represents the signing info of this finality provider. + FpSigningInfo FinalityProviderSigningInfo `protobuf:"bytes,2,opt,name=fp_signing_info,json=fpSigningInfo,proto3" json:"fp_signing_info"` +} + +func (m *SigningInfo) Reset() { *m = SigningInfo{} } +func (m *SigningInfo) String() string { return proto.CompactTextString(m) } +func (*SigningInfo) ProtoMessage() {} +func (*SigningInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{4} +} +func (m *SigningInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SigningInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SigningInfo.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 *SigningInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_SigningInfo.Merge(m, src) +} +func (m *SigningInfo) XXX_Size() int { + return m.Size() +} +func (m *SigningInfo) XXX_DiscardUnknown() { + xxx_messageInfo_SigningInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_SigningInfo proto.InternalMessageInfo + +func (m *SigningInfo) GetFpSigningInfo() FinalityProviderSigningInfo { + if m != nil { + return m.FpSigningInfo + } + return FinalityProviderSigningInfo{} +} + +// FinalityProviderMissedBlocks contains array of missed blocks of corresponding +// BTC public key. +type FinalityProviderMissedBlocks struct { + // fp_btc_pk is the BTC PK of the finality provider + FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + // missed_blocks is an array of missed blocks by the finality provider. + MissedBlocks []MissedBlock `protobuf:"bytes,2,rep,name=missed_blocks,json=missedBlocks,proto3" json:"missed_blocks"` +} + +func (m *FinalityProviderMissedBlocks) Reset() { *m = FinalityProviderMissedBlocks{} } +func (m *FinalityProviderMissedBlocks) String() string { return proto.CompactTextString(m) } +func (*FinalityProviderMissedBlocks) ProtoMessage() {} +func (*FinalityProviderMissedBlocks) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{5} +} +func (m *FinalityProviderMissedBlocks) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *FinalityProviderMissedBlocks) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_FinalityProviderMissedBlocks.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 *FinalityProviderMissedBlocks) XXX_Merge(src proto.Message) { + xxx_messageInfo_FinalityProviderMissedBlocks.Merge(m, src) +} +func (m *FinalityProviderMissedBlocks) XXX_Size() int { + return m.Size() +} +func (m *FinalityProviderMissedBlocks) XXX_DiscardUnknown() { + xxx_messageInfo_FinalityProviderMissedBlocks.DiscardUnknown(m) +} + +var xxx_messageInfo_FinalityProviderMissedBlocks proto.InternalMessageInfo + +func (m *FinalityProviderMissedBlocks) GetMissedBlocks() []MissedBlock { + if m != nil { + return m.MissedBlocks + } + return nil +} + +// MissedBlock contains height and missed status as boolean. +type MissedBlock struct { + // index is the height at which the block was missed. + Index int64 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + // missed is the missed status. + Missed bool `protobuf:"varint,2,opt,name=missed,proto3" json:"missed,omitempty"` +} + +func (m *MissedBlock) Reset() { *m = MissedBlock{} } +func (m *MissedBlock) String() string { return proto.CompactTextString(m) } +func (*MissedBlock) ProtoMessage() {} +func (*MissedBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_52dc577f74d797d1, []int{6} +} +func (m *MissedBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MissedBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MissedBlock.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 *MissedBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_MissedBlock.Merge(m, src) +} +func (m *MissedBlock) XXX_Size() int { + return m.Size() +} +func (m *MissedBlock) XXX_DiscardUnknown() { + xxx_messageInfo_MissedBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_MissedBlock proto.InternalMessageInfo + +func (m *MissedBlock) GetIndex() int64 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *MissedBlock) GetMissed() bool { + if m != nil { + return m.Missed + } + return false +} + func init() { proto.RegisterType((*GenesisState)(nil), "babylon.finality.v1.GenesisState") proto.RegisterType((*VoteSig)(nil), "babylon.finality.v1.VoteSig") proto.RegisterType((*PublicRandomness)(nil), "babylon.finality.v1.PublicRandomness") proto.RegisterType((*PubRandCommitWithPK)(nil), "babylon.finality.v1.PubRandCommitWithPK") + proto.RegisterType((*SigningInfo)(nil), "babylon.finality.v1.SigningInfo") + proto.RegisterType((*FinalityProviderMissedBlocks)(nil), "babylon.finality.v1.FinalityProviderMissedBlocks") + proto.RegisterType((*MissedBlock)(nil), "babylon.finality.v1.MissedBlock") } func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 544 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x94, 0x4d, 0x6f, 0xd3, 0x30, - 0x18, 0xc7, 0xeb, 0xb5, 0xb4, 0xab, 0xdb, 0xc1, 0xf0, 0x38, 0x44, 0x05, 0xd2, 0x36, 0x12, 0x52, - 0x4f, 0xc9, 0xd6, 0x4d, 0x88, 0x89, 0x5b, 0xd0, 0xc4, 0x5e, 0x0e, 0x44, 0x0e, 0x02, 0x09, 0x0e, - 0x51, 0x92, 0xba, 0x89, 0xd5, 0x36, 0xb6, 0x6a, 0xb7, 0x5a, 0xbf, 0x05, 0x5f, 0x85, 0x03, 0xdf, - 0x61, 0xc7, 0x1d, 0xd1, 0x24, 0x2a, 0xd4, 0x7e, 0x11, 0x54, 0x37, 0xdd, 0x46, 0x09, 0x1a, 0x42, - 0x48, 0xdc, 0xec, 0x27, 0xff, 0xe7, 0xa7, 0xff, 0xf3, 0x12, 0xc3, 0x66, 0xe0, 0x07, 0x93, 0x3e, - 0x4b, 0xac, 0x2e, 0x4d, 0xfc, 0x3e, 0x95, 0x13, 0x6b, 0xbc, 0x67, 0x45, 0x24, 0x21, 0x82, 0x0a, - 0x93, 0x0f, 0x99, 0x64, 0x68, 0x27, 0x95, 0x98, 0x2b, 0x89, 0x39, 0xde, 0xab, 0x3d, 0x8a, 0x58, - 0xc4, 0xd4, 0x77, 0x6b, 0x71, 0x5a, 0x4a, 0x6b, 0x8d, 0x2c, 0x1a, 0xf7, 0x87, 0xfe, 0x20, 0x85, - 0xd5, 0x8c, 0x2c, 0xc5, 0x35, 0x58, 0x69, 0x8c, 0xcf, 0x79, 0x58, 0x7d, 0xbd, 0xb4, 0xe0, 0x4a, - 0x5f, 0x12, 0x74, 0x08, 0x8b, 0x4b, 0x88, 0x06, 0x1a, 0xa0, 0x55, 0x69, 0x3f, 0x36, 0x33, 0x2c, - 0x99, 0x8e, 0x92, 0xd8, 0x85, 0x8b, 0x69, 0x3d, 0x87, 0xd3, 0x04, 0x74, 0x0c, 0xef, 0xd3, 0xa4, - 0x43, 0xce, 0x49, 0xc7, 0x0b, 0xfa, 0x2c, 0xec, 0x09, 0x6d, 0xa3, 0x91, 0x6f, 0x55, 0xda, 0xcd, - 0x4c, 0xc4, 0xc9, 0x52, 0x6a, 0x2f, 0x94, 0x78, 0x8b, 0xde, 0xba, 0x09, 0xf4, 0x12, 0x96, 0xc9, - 0x98, 0x76, 0x48, 0x12, 0x12, 0xa1, 0xe5, 0x15, 0xe4, 0x69, 0x26, 0xe4, 0x28, 0x55, 0xe1, 0x1b, - 0x3d, 0x3a, 0x84, 0xe5, 0x31, 0x93, 0xc4, 0x13, 0x34, 0x12, 0x5a, 0x41, 0x25, 0x3f, 0xc9, 0x4c, - 0x7e, 0xc7, 0x24, 0x71, 0x69, 0x84, 0x37, 0xc7, 0xcb, 0x83, 0x40, 0x18, 0x3e, 0xe4, 0xa3, 0xa0, - 0x4f, 0x43, 0x6f, 0xe8, 0x27, 0x1d, 0x36, 0x48, 0x88, 0x10, 0xda, 0x3d, 0x85, 0x78, 0x96, 0xdd, - 0x07, 0xa5, 0xc6, 0xd7, 0x62, 0xbc, 0xcd, 0xd7, 0x22, 0xc8, 0x81, 0x0f, 0xf8, 0x28, 0x50, 0x40, - 0x2f, 0x64, 0x83, 0x01, 0x95, 0x5a, 0x51, 0x11, 0x5b, 0xbf, 0x23, 0x2e, 0x92, 0x5f, 0x29, 0xe5, - 0x7b, 0x2a, 0x63, 0xe7, 0x0c, 0x6f, 0xf1, 0xdb, 0x41, 0xe3, 0x1b, 0x80, 0xa5, 0xd4, 0x3b, 0x6a, - 0xc2, 0xaa, 0xea, 0xb5, 0x17, 0x13, 0x1a, 0xc5, 0x52, 0x0d, 0xad, 0x80, 0x2b, 0x2a, 0x76, 0xac, - 0x42, 0x08, 0xc3, 0x72, 0x97, 0x7b, 0x81, 0x0c, 0x3d, 0xde, 0xd3, 0x36, 0x1a, 0xa0, 0x55, 0xb5, - 0x9f, 0x5f, 0x4d, 0xeb, 0xed, 0x88, 0xca, 0x78, 0x14, 0x98, 0x21, 0x1b, 0x58, 0xa9, 0x91, 0x30, - 0xf6, 0x69, 0xb2, 0xba, 0x58, 0x72, 0xc2, 0x89, 0x30, 0xed, 0x13, 0x67, 0xff, 0x60, 0xd7, 0x19, - 0x05, 0x67, 0x64, 0x82, 0x4b, 0x5d, 0x6e, 0xcb, 0xd0, 0xe9, 0xa1, 0x8f, 0xb0, 0xba, 0x32, 0xbd, - 0xe8, 0xb3, 0x96, 0x57, 0xd8, 0x17, 0x57, 0xd3, 0xfa, 0xc1, 0x9f, 0x61, 0xdd, 0x30, 0x4e, 0xd8, - 0x70, 0x78, 0xf4, 0xe6, 0xad, 0xbb, 0x18, 0x41, 0x65, 0x45, 0x73, 0x69, 0x64, 0x4c, 0x01, 0xdc, - 0x5e, 0x6f, 0xec, 0xff, 0x2a, 0xd4, 0x85, 0x9b, 0xab, 0xe9, 0xfd, 0x75, 0x91, 0xe9, 0x48, 0x71, - 0x29, 0x1d, 0xa3, 0xf1, 0x05, 0xc0, 0x9d, 0x8c, 0x39, 0xff, 0x5c, 0x00, 0xf8, 0x37, 0x05, 0x9c, - 0xfe, 0xba, 0x7e, 0x1b, 0xea, 0xc7, 0x36, 0xee, 0x5e, 0xbf, 0xb5, 0xc5, 0xb3, 0x4f, 0x2f, 0x66, - 0x3a, 0xb8, 0x9c, 0xe9, 0xe0, 0xfb, 0x4c, 0x07, 0x9f, 0xe6, 0x7a, 0xee, 0x72, 0xae, 0xe7, 0xbe, - 0xce, 0xf5, 0xdc, 0x87, 0xdd, 0xbb, 0x2c, 0x9e, 0xdf, 0x3c, 0x42, 0xca, 0x6d, 0x50, 0x54, 0xef, - 0xcf, 0xfe, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x48, 0xf9, 0xea, 0x15, 0x05, 0x00, 0x00, + // 689 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0x5f, 0x6b, 0xdb, 0x3c, + 0x14, 0xc6, 0xe3, 0x24, 0x4d, 0x52, 0x25, 0x79, 0xdb, 0x57, 0x2d, 0x2f, 0xa6, 0x6f, 0x97, 0xa6, + 0x86, 0x41, 0xae, 0x9c, 0xfe, 0x63, 0xac, 0xf4, 0x2e, 0xa3, 0x5b, 0xdb, 0x30, 0x66, 0xe4, 0xb1, + 0xc1, 0x36, 0x66, 0x6c, 0x47, 0x76, 0x44, 0x63, 0xcb, 0x58, 0x4a, 0x68, 0xbe, 0xc5, 0xbe, 0xcc, + 0xae, 0xc7, 0xee, 0x7a, 0xd9, 0xcb, 0x51, 0xb6, 0x30, 0xda, 0x2f, 0x32, 0x22, 0x3b, 0x8d, 0x97, + 0x7a, 0x6d, 0x19, 0x2b, 0xbb, 0x93, 0x4e, 0x9e, 0xf3, 0xcb, 0x39, 0xd2, 0x73, 0x64, 0xb0, 0x6e, + 0x99, 0xd6, 0xb0, 0x47, 0xfd, 0xa6, 0x43, 0x7c, 0xb3, 0x47, 0xf8, 0xb0, 0x39, 0xd8, 0x6c, 0xba, + 0xd8, 0xc7, 0x8c, 0x30, 0x35, 0x08, 0x29, 0xa7, 0x70, 0x29, 0x96, 0xa8, 0x13, 0x89, 0x3a, 0xd8, + 0x5c, 0x59, 0x76, 0xa9, 0x4b, 0xc5, 0xef, 0xcd, 0xf1, 0x2a, 0x92, 0xae, 0xd4, 0xd3, 0x68, 0x81, + 0x19, 0x9a, 0x5e, 0x0c, 0x5b, 0x51, 0xd2, 0x14, 0x57, 0x60, 0xa1, 0x51, 0xbe, 0xe6, 0x41, 0xe5, + 0x59, 0x54, 0x82, 0xce, 0x4d, 0x8e, 0xe1, 0x2e, 0x28, 0x44, 0x10, 0x59, 0xaa, 0x4b, 0x8d, 0xf2, + 0xd6, 0xff, 0x6a, 0x4a, 0x49, 0xaa, 0x26, 0x24, 0xad, 0xfc, 0xe9, 0x68, 0x2d, 0x83, 0xe2, 0x04, + 0x78, 0x00, 0xfe, 0x21, 0x7e, 0x07, 0x9f, 0xe0, 0x8e, 0x61, 0xf5, 0xa8, 0x7d, 0xcc, 0xe4, 0x6c, + 0x3d, 0xd7, 0x28, 0x6f, 0xad, 0xa7, 0x22, 0x0e, 0x23, 0x69, 0x6b, 0xac, 0x44, 0x55, 0x92, 0xd8, + 0x31, 0xb8, 0x07, 0xe6, 0xf1, 0x80, 0x74, 0xb0, 0x6f, 0x63, 0x26, 0xe7, 0x04, 0xe4, 0x41, 0x2a, + 0x64, 0x3f, 0x56, 0xa1, 0xa9, 0x1e, 0xee, 0x82, 0xf9, 0x01, 0xe5, 0xd8, 0x60, 0xc4, 0x65, 0x72, + 0x5e, 0x24, 0xaf, 0xa6, 0x26, 0xbf, 0xa2, 0x1c, 0xeb, 0xc4, 0x45, 0xa5, 0x41, 0xb4, 0x60, 0x10, + 0x81, 0x7f, 0x83, 0xbe, 0xd5, 0x23, 0xb6, 0x11, 0x9a, 0x7e, 0x87, 0x7a, 0x3e, 0x66, 0x4c, 0x9e, + 0x13, 0x88, 0x87, 0xe9, 0xe7, 0x20, 0xd4, 0xe8, 0x4a, 0x8c, 0x16, 0x83, 0x99, 0x08, 0xd4, 0xc0, + 0x42, 0xd0, 0xb7, 0x04, 0xd0, 0xb0, 0xa9, 0xe7, 0x11, 0x2e, 0x17, 0x04, 0xb1, 0xf1, 0x2b, 0xe2, + 0x38, 0xf9, 0x89, 0x50, 0xbe, 0x26, 0xbc, 0xab, 0xb5, 0x51, 0x35, 0x48, 0x06, 0x61, 0x1b, 0x54, + 0x19, 0x71, 0x7d, 0xe2, 0xbb, 0x06, 0xf1, 0x1d, 0xca, 0xe4, 0xa2, 0xe0, 0xd5, 0x53, 0x79, 0x7a, + 0xa4, 0x3c, 0xf4, 0x1d, 0x1a, 0x5f, 0x57, 0x85, 0x4d, 0x43, 0x0c, 0xbe, 0x03, 0x55, 0x8f, 0x30, + 0x36, 0xbd, 0xb3, 0x92, 0x80, 0x6d, 0xa6, 0xc2, 0x9e, 0xc6, 0x6b, 0x2d, 0xa4, 0xe3, 0xe3, 0x0e, + 0x9f, 0x8b, 0xcc, 0xe8, 0xd2, 0x26, 0x74, 0x2f, 0x11, 0x53, 0xbe, 0x49, 0xa0, 0x18, 0x1f, 0x33, + 0x5c, 0x07, 0x15, 0xf1, 0x17, 0x46, 0x17, 0x13, 0xb7, 0xcb, 0x85, 0xbf, 0xf2, 0xa8, 0x2c, 0x62, + 0x07, 0x22, 0x04, 0x11, 0x98, 0x77, 0x02, 0xc3, 0xe2, 0xb6, 0x11, 0x1c, 0xcb, 0xd9, 0xba, 0xd4, + 0xa8, 0xb4, 0x1e, 0x9d, 0x8f, 0xd6, 0xb6, 0x5c, 0xc2, 0xbb, 0x7d, 0x4b, 0xb5, 0xa9, 0xd7, 0x8c, + 0xcb, 0xb2, 0xbb, 0x26, 0xf1, 0x27, 0x9b, 0x26, 0x1f, 0x06, 0x98, 0xa9, 0xad, 0x43, 0x6d, 0x7b, + 0x67, 0x43, 0xeb, 0x5b, 0x6d, 0x3c, 0x44, 0x45, 0x27, 0x68, 0x71, 0x5b, 0x3b, 0x86, 0x6f, 0x41, + 0x65, 0xd2, 0xc2, 0xd8, 0x12, 0x72, 0x4e, 0x60, 0x1f, 0x9f, 0x8f, 0xd6, 0x76, 0xee, 0x86, 0xd5, + 0xed, 0xae, 0x4f, 0xc3, 0x70, 0xff, 0xc5, 0x4b, 0x7d, 0xec, 0x96, 0xf2, 0x84, 0xa6, 0x13, 0x57, + 0x19, 0x49, 0x60, 0x71, 0xd6, 0x03, 0x7f, 0xab, 0x51, 0x1d, 0x94, 0x26, 0x46, 0xfb, 0xed, 0x26, + 0x63, 0xf7, 0xa1, 0x62, 0xec, 0x38, 0xe5, 0xa3, 0x04, 0x96, 0x52, 0x2c, 0xf9, 0x73, 0x03, 0xd2, + 0x9f, 0x69, 0xe0, 0xe8, 0xfa, 0xa4, 0x64, 0xc5, 0x1b, 0xa4, 0xdc, 0x3e, 0x29, 0x33, 0x33, 0xa2, + 0x7c, 0x96, 0x40, 0x39, 0x61, 0xfd, 0x7b, 0xa9, 0xf7, 0x3d, 0x58, 0x70, 0x02, 0x23, 0x39, 0x8a, + 0x71, 0xbd, 0x1b, 0x77, 0x1a, 0x9e, 0xeb, 0x93, 0x59, 0x75, 0x82, 0x44, 0x50, 0xf9, 0x24, 0x81, + 0xd5, 0x9b, 0x26, 0xee, 0x5e, 0x9a, 0x6a, 0xcf, 0xbe, 0x07, 0xd9, 0x1b, 0x1e, 0x97, 0x44, 0x35, + 0xa9, 0xe3, 0xbf, 0x07, 0xca, 0x09, 0x09, 0x5c, 0x06, 0x73, 0xe2, 0x9d, 0x17, 0xb5, 0xe6, 0x50, + 0xb4, 0x81, 0xff, 0x81, 0x42, 0x94, 0x24, 0x4e, 0xaf, 0x84, 0xe2, 0x5d, 0xeb, 0xe8, 0xf4, 0xa2, + 0x26, 0x9d, 0x5d, 0xd4, 0xa4, 0xef, 0x17, 0x35, 0xe9, 0xc3, 0x65, 0x2d, 0x73, 0x76, 0x59, 0xcb, + 0x7c, 0xb9, 0xac, 0x65, 0xde, 0x6c, 0xdc, 0xd6, 0xe0, 0xc9, 0xf4, 0x93, 0x27, 0x7a, 0xb5, 0x0a, + 0xe2, 0x6b, 0xb7, 0xfd, 0x23, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x93, 0x7e, 0xf6, 0x83, 0x07, 0x00, + 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -332,6 +517,34 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.MissedBlocks) > 0 { + for iNdEx := len(m.MissedBlocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MissedBlocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.SigningInfos) > 0 { + for iNdEx := len(m.SigningInfos) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SigningInfos[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } if len(m.PubRandCommit) > 0 { for iNdEx := len(m.PubRandCommit) - 1; iNdEx >= 0; iNdEx-- { { @@ -566,6 +779,138 @@ func (m *PubRandCommitWithPK) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SigningInfo) 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 *SigningInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SigningInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.FpSigningInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *FinalityProviderMissedBlocks) 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 *FinalityProviderMissedBlocks) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *FinalityProviderMissedBlocks) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.MissedBlocks) > 0 { + for iNdEx := len(m.MissedBlocks) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.MissedBlocks[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.FpBtcPk != nil { + { + size := m.FpBtcPk.Size() + i -= size + if _, err := m.FpBtcPk.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MissedBlock) 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 *MissedBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MissedBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Missed { + i-- + if m.Missed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.Index != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { offset -= sovGenesis(v) base := offset @@ -615,6 +960,18 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.SigningInfos) > 0 { + for _, e := range m.SigningInfos { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.MissedBlocks) > 0 { + for _, e := range m.MissedBlocks { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -675,21 +1032,70 @@ func (m *PubRandCommitWithPK) Size() (n int) { return n } -func sovGenesis(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozGenesis(x uint64) (n int) { - return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +func (m *SigningInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + l = m.FpSigningInfo.Size() + n += 1 + l + sovGenesis(uint64(l)) + return n } -func (m *GenesisState) 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 ErrIntOverflowGenesis + +func (m *FinalityProviderMissedBlocks) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.FpBtcPk != nil { + l = m.FpBtcPk.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + if len(m.MissedBlocks) > 0 { + for _, e := range m.MissedBlocks { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *MissedBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != 0 { + n += 1 + sovGenesis(uint64(m.Index)) + } + if m.Missed { + n += 2 + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis } if iNdEx >= l { return io.ErrUnexpectedEOF @@ -913,6 +1319,74 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SigningInfos", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SigningInfos = append(m.SigningInfos, SigningInfo{}) + if err := m.SigningInfos[len(m.SigningInfos)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MissedBlocks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MissedBlocks = append(m.MissedBlocks, FinalityProviderMissedBlocks{}) + if err := m.MissedBlocks[len(m.MissedBlocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -1333,6 +1807,332 @@ func (m *PubRandCommitWithPK) Unmarshal(dAtA []byte) error { } return nil } +func (m *SigningInfo) 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 ErrIntOverflowGenesis + } + 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: SigningInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SigningInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpSigningInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.FpSigningInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *FinalityProviderMissedBlocks) 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 ErrIntOverflowGenesis + } + 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: FinalityProviderMissedBlocks: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: FinalityProviderMissedBlocks: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FpBtcPk", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_babylonchain_babylon_types.BIP340PubKey + m.FpBtcPk = &v + if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MissedBlocks", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MissedBlocks = append(m.MissedBlocks, MissedBlock{}) + if err := m.MissedBlocks[len(m.MissedBlocks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MissedBlock) 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 ErrIntOverflowGenesis + } + 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: MissedBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MissedBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Missed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Missed = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipGenesis(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 From a33a3344bb44bde2f3374d3cbf919abb942c341a Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 23 Jul 2024 17:17:37 +0800 Subject: [PATCH 115/119] epoching: query CLIs for epoching module (#726) --- x/checkpointing/client/cli/query.go | 4 +- x/epoching/client/cli/query.go | 222 +++++++++++++++++++++++++- x/epoching/client/cli/query_params.go | 34 ---- 3 files changed, 216 insertions(+), 44 deletions(-) delete mode 100644 x/epoching/client/cli/query_params.go diff --git a/x/checkpointing/client/cli/query.go b/x/checkpointing/client/cli/query.go index 5b1184ad6..d26a5bb07 100644 --- a/x/checkpointing/client/cli/query.go +++ b/x/checkpointing/client/cli/query.go @@ -80,12 +80,12 @@ func CmdRawCheckpoint() *cobra.Command { queryClient := types.NewQueryClient(clientCtx) - epoch_num, err := strconv.ParseUint(args[0], 10, 64) + epochNum, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return err } - params := types.NewQueryRawCheckpointRequest(epoch_num) + params := types.NewQueryRawCheckpointRequest(epochNum) res, err := queryClient.RawCheckpoint(context.Background(), params) if err != nil { return err diff --git a/x/epoching/client/cli/query.go b/x/epoching/client/cli/query.go index 3818f48cb..34c439cb6 100644 --- a/x/epoching/client/cli/query.go +++ b/x/epoching/client/cli/query.go @@ -1,16 +1,14 @@ package cli import ( + "context" "fmt" - // "strings" - - "github.com/spf13/cobra" - - "github.com/cosmos/cosmos-sdk/client" - // "github.com/cosmos/cosmos-sdk/client/flags" - // sdk "github.com/cosmos/cosmos-sdk/types" + "strconv" "github.com/babylonchain/babylon/x/epoching/types" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" ) // GetQueryCmd returns the cli query commands for this module @@ -24,7 +22,215 @@ func GetQueryCmd(queryRoute string) *cobra.Command { RunE: client.ValidateCmd, } - cmd.AddCommand(CmdQueryParams()) + cmd.AddCommand( + CmdQueryParams(), + CmdQueryEpochInfo(), + CmdQueryEpochsInfo(), + CmdQueryEpochMsgs(), + CmdQueryEpochValidators(), + ) + + return cmd +} + +func CmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "shows the parameters of the module", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdQueryEpochInfo() *cobra.Command { + cmd := &cobra.Command{ + Use: "epoch [epoch_number]", + Short: "shows the information of the current epoch, or the given epoch if specified", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + epochNum, err := getEpoch(queryClient, args) + if err != nil { + return err + } + + res, err := queryClient.EpochInfo( + context.Background(), + &types.QueryEpochInfoRequest{ + EpochNum: epochNum, + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) return cmd } + +func CmdQueryEpochsInfo() *cobra.Command { + cmd := &cobra.Command{ + Use: "epochs", + Short: "shows the information of epochs according to the pagination parameters", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.EpochsInfo( + context.Background(), + &types.QueryEpochsInfoRequest{ + Pagination: pageReq, + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "epochs") + + return cmd +} + +func CmdQueryEpochMsgs() *cobra.Command { + cmd := &cobra.Command{ + Use: "epoch-msgs [epoch_number]", + Short: "shows the messages that will be executed at the end of the current epoch, or the given epoch if specified", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + epochNum, err := getEpoch(queryClient, args) + if err != nil { + return err + } + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.EpochMsgs( + context.Background(), + &types.QueryEpochMsgsRequest{ + EpochNum: epochNum, + Pagination: pageReq, + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "epoch-msgs") + + return cmd +} + +func CmdQueryEpochValidators() *cobra.Command { + cmd := &cobra.Command{ + Use: "epoch-validators [epoch_number]", + Short: "shows the validators of the current epoch, or the given epoch if specified", + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + epochNum, err := getEpoch(queryClient, args) + if err != nil { + return err + } + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.EpochValSet( + context.Background(), + &types.QueryEpochValSetRequest{ + EpochNum: epochNum, + Pagination: pageReq, + }, + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "epoch-validators") + + return cmd +} + +func getEpoch(queryClient types.QueryClient, args []string) (uint64, error) { + var ( + epochNum uint64 + err error + ) + + if len(args) == 0 { + // get the current epoch number + res, err := queryClient.CurrentEpoch( + context.Background(), + &types.QueryCurrentEpochRequest{}, + ) + if err != nil { + return 0, err + } + epochNum = res.CurrentEpoch + } else { + // get the given epoch number + epochNum, err = strconv.ParseUint(args[0], 10, 64) + if err != nil { + return 0, err + } + } + + return epochNum, nil +} diff --git a/x/epoching/client/cli/query_params.go b/x/epoching/client/cli/query_params.go deleted file mode 100644 index d6446d918..000000000 --- a/x/epoching/client/cli/query_params.go +++ /dev/null @@ -1,34 +0,0 @@ -package cli - -import ( - "context" - - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/epoching/types" -) - -func CmdQueryParams() *cobra.Command { - cmd := &cobra.Command{ - Use: "params", - Short: "shows the parameters of the module", - Args: cobra.NoArgs, - RunE: func(cmd *cobra.Command, args []string) error { - clientCtx := client.GetClientContextFromCmd(cmd) - - queryClient := types.NewQueryClient(clientCtx) - - res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) - if err != nil { - return err - } - - return clientCtx.PrintProto(res) - }, - } - - flags.AddQueryFlagsToCmd(cmd) - - return cmd -} From d9d78f2d54c923a3b28592c8c7454b22a39a0ec7 Mon Sep 17 00:00:00 2001 From: hiepmai-babylonchain <167088365+hiepmai-babylonchain@users.noreply.github.com> Date: Thu, 25 Jul 2024 08:44:28 +0700 Subject: [PATCH 116/119] feat: Add github actions (#708) --- .circleci/config.yml | 157 ---------------------------------- .github/workflows/ci.yml | 24 ++++++ .github/workflows/publish.yml | 28 ++++++ 3 files changed, 52 insertions(+), 157 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/publish.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 085fe6388..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,157 +0,0 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. -# See: https://circleci.com/docs/2.0/configuration-reference -version: 2.1 - -orbs: - aws-ecr: circleci/aws-ecr@8.2.1 - go: circleci/go@1.9.0 - - -jobs: - build-test: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - go/install: - version: "1.21.4" - - checkout - - run: - name: Print Go environment - command: "go env" - - add_ssh_keys - - go/load-cache: - key: go-mod-v6-{{ checksum "go.sum" }} - - go/mod-download - - go/save-cache: - key: go-mod-v6-{{ checksum "go.sum" }} - path: "/home/circleci/.go_workspace/pkg/mod" - - run: - name: Build babylond - command: make build - - run: - name: Run tests - command: | - make test - gosec: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - checkout - - run: - name: Run gosec - command: make gosec - - e2e-test: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - go/install: - version: "1.21.4" - - checkout - - run: - name: Print Go environment - command: "go env" - - add_ssh_keys - - run: - name: Run e2e tests - no_output_timeout: 20m - command: | - sudo ln -s /usr/local/go/bin/go /usr/bin/go - sudo make test-e2e - lint: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - go/install: - version: "1.21.4" - - checkout - - add_ssh_keys - - run: - name: Lint proto files - command: make proto-lint - - run: - name: Lint - command: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.55.2 - ./bin/golangci-lint run - - build_docker: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - checkout - - add_ssh_keys - - aws-ecr/build-image: - push-image: false - dockerfile: Dockerfile - path: ./contrib/images/babylond/ - build-path: ./ - tag: "$CIRCLE_SHA1,$CIRCLE_TAG" - repo: "babylond" - - run: - name: Save Docker image to export it to workspace - command: | - docker save $(docker image ls --format '{{.Repository}}:{{.Tag}}') > /tmp/babylond.tar - - persist_to_workspace: - root: /tmp - paths: - - babylond.tar - - push_docker: - machine: - image: ubuntu-2204:2024.01.1 - resource_class: large - steps: - - attach_workspace: - at: /tmp - - run: - name: Load Docker image from workspace - command: | - docker load -i /tmp/babylond.tar - - aws-ecr/ecr-login: - aws-access-key-id: AWS_ACCESS_KEY_ID - aws-secret-access-key: AWS_SECRET_ACCESS_KEY - region: "$AWS_REGION" - - aws-ecr/push-image: - registry-id: AWS_ECR_REGISTRY_ID - region: "$AWS_REGION" - repo: "babylond" - tag: "$CIRCLE_SHA1,$CIRCLE_TAG" - -# Invoke jobs via workflows -# See: https://circleci.com/docs/2.0/configuration-reference/#workflows -workflows: - version: 2 - build-test: - jobs: - - build-test - e2e-test: - jobs: - - e2e-test - lint: - jobs: - - lint - gosec: - jobs: - - gosec - docker: - jobs: - - build_docker: - filters: - tags: - only: /.*/ - - push_docker: - requires: - - build_docker - filters: - tags: - only: /.*/ - branches: - only: - - main - - dev diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..859d3b1cf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: ci + +on: + push: + branches: + - '**' + +jobs: + lint_test: + uses: babylonchain/.github/.github/workflows/reusable_go_lint_test.yml@v0.1.0 + with: + run-unit-tests: true + run-integration-tests: true + run-lint: true + integration-tests-command: | + sudo make test-e2e + + docker_pipeline: + uses: babylonchain/.github/.github/workflows/reusable_docker_pipeline.yml@v0.1.0 + secrets: inherit + with: + publish: false + dockerfile: ./contrib/images/babylond/Dockerfile + repoName: babylond \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..38d5df4bf --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: docker_publish + +on: + push: + branches: + - 'main' + - 'dev' + tags: + - '*' + +jobs: + lint_test: + uses: babylonchain/.github/.github/workflows/reusable_go_lint_test.yml@v0.1.0 + with: + run-unit-tests: true + run-integration-tests: true + run-lint: true + integration-tests-command: | + sudo make test-e2e + + docker_pipeline: + uses: babylonchain/.github/.github/workflows/reusable_docker_pipeline.yml@v0.1.0 + needs: ["lint_test"] + secrets: inherit + with: + publish: true + dockerfile: ./contrib/images/babylond/Dockerfile + repoName: babylond \ No newline at end of file From 679b49a63171c879da52ce6de90b2ad9019e1239 Mon Sep 17 00:00:00 2001 From: caseylove Date: Thu, 25 Jul 2024 14:43:23 +0800 Subject: [PATCH 117/119] chore: add `help` target to Makefile to display the usage of all targets (#728) --- Makefile | 70 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/Makefile b/Makefile index 72eca733f..f70e4c026 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,10 @@ ifneq (,$(UPCOMING_TAG)) upcoming_tag := --upcoming-tag $(UPCOMING_TAG) endif -all: tools build lint test +help: ## Print this help message + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +all: tools build lint test ## Run build, lint, and test # The below include contains the tools and runsim targets. # TODO: Fix following make file so it will work on linux @@ -140,8 +143,8 @@ BUILD_TARGETS := build install PACKAGES_E2E=$(shell go list ./... | grep '/e2e') -build: BUILD_ARGS=-o $(BUILDDIR)/ -build-linux: +build: BUILD_ARGS=-o $(BUILDDIR)/ ## Build babylond binary +build-linux: ## Build babylond linux version binary GOOS=linux GOARCH=$(if $(findstring aarch64,$(shell uname -m)) || $(findstring arm64,$(shell uname -m)),arm64,amd64) LEDGER_ENABLED=false $(MAKE) build $(BUILD_TARGETS): go.sum $(BUILDDIR)/ @@ -154,7 +157,7 @@ $(BUILDDIR)/: mockgen_cmd=go run github.com/golang/mock/mockgen@v1.6.0 -mocks: $(MOCKS_DIR) +mocks: $(MOCKS_DIR) ## Generate mock objects for testing $(mockgen_cmd) -source=x/checkpointing/types/expected_keepers.go -package mocks -destination testutil/mocks/checkpointing_expected_keepers.go $(mockgen_cmd) -source=x/checkpointing/keeper/bls_signer.go -package mocks -destination testutil/mocks/bls_signer.go $(mockgen_cmd) -source=x/zoneconcierge/types/expected_keepers.go -package types -destination x/zoneconcierge/types/mocked_keepers.go @@ -166,8 +169,8 @@ mocks: $(MOCKS_DIR) $(MOCKS_DIR): mkdir -p $(MOCKS_DIR) -distclean: clean tools-clean -clean: +distclean: clean tools-clean ## Remove all files generated by builds and remove all installed tools +clean: ## Remove all files generated by builds rm -rf \ $(BUILDDIR)/ \ artifacts/ \ @@ -191,7 +194,7 @@ go.sum: go.mod # This builds a docs site for each branch/tag in `./docs/versions` # and copies each site to a version prefixed path. The last entry inside # the `versions` file will be the default root index.html. -build-docs: diagrams +build-docs: diagrams ## Builds a docs site @cd client/docs && \ while read -r branch path_prefix; do \ (git checkout $${branch} && npm install && VUEPRESS_BASE="/$${path_prefix}/" npm run build) ; \ @@ -205,8 +208,8 @@ build-docs: diagrams ### Tests & Simulation ### ############################################################################### -test: test-unit -test-all: test-unit test-ledger-mock test-race test-cover +test: test-unit ## Run unit tests +test-all: test-unit test-ledger-mock test-race test-cover ## Run all tests TEST_PACKAGES=./... TEST_TARGETS := test-unit test-unit-amino test-unit-proto test-ledger-mock test-race test-ledger test-race test-cover @@ -322,10 +325,10 @@ containerMarkdownLintFix=babylon-markdownlint-fix golangci_lint_cmd=go run github.com/golangci/golangci-lint/cmd/golangci-lint -lint: lint-go +lint: lint-go ## Run go linter @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLint}$$"; then docker start -a $(containerMarkdownLint); else docker run --name $(containerMarkdownLint) -i -v "$(CURDIR):/work" $(markdownLintImage); fi -lint-fix: +lint-fix: ## Run go linter and fix reported issues $(golangci_lint_cmd) run --fix --out-format=tab --issues-exit-code=0 @if docker ps -a --format '{{.Names}}' | grep -Eq "^${containerMarkdownLintFix}$$"; then docker start -a $(containerMarkdownLintFix); else docker run --name $(containerMarkdownLintFix) -i -v "$(CURDIR):/work" $(markdownLintImage) . --fix; fi @@ -335,7 +338,7 @@ lint-go: .PHONY: lint lint-fix -format: +format: ## Run code formater find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs gofmt -w -s find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs misspell -w find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/babylonchain/babylon @@ -345,10 +348,10 @@ format: ### Gosec ### ############################################################################### -gosec: +gosec: ## Run security checks $(DOCKER) run --rm -it -w /$(PROJECT_NAME)/ -v $(CURDIR):/$(PROJECT_NAME) securego/gosec -exclude-generated -exclude-dir=/$(PROJECT_NAME)/testutil -exclude-dir=/$(PROJECT_NAME)/test -conf /$(PROJECT_NAME)/gosec.json /$(PROJECT_NAME)/... -gosec-local: +gosec-local: ## Run local security checkss gosec -exclude-generated -exclude-dir=$(CURDIR)/testutil -exclude-dir=$(CURDIR)/test -conf $(CURDIR)/gosec.json $(CURDIR)/... .PHONY: gosec gosec-local @@ -359,22 +362,22 @@ gosec-local: DEVDOC_SAVE = docker commit `docker ps -a -n 1 -q` devdoc:local -devdoc-init: +devdoc-init: ## Initialize documentation $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonchain/babylon" -w "/go/src/github.com/babylonchain/babylon" tendermint/devdoc echo # TODO make this safer $(call DEVDOC_SAVE) -devdoc: +devdoc: ## Generate documentation $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonchain/babylon" -w "/go/src/github.com/babylonchain/babylon" devdoc:local bash -devdoc-save: +devdoc-save: ## Save documentation changes # TODO make this safer $(call DEVDOC_SAVE) -devdoc-clean: +devdoc-clean: ## Clean up documentation artifacts docker rmi -f $$(docker images -f "dangling=true" -q) -devdoc-update: +devdoc-update: ## Update documentation tools docker pull tendermint/devdoc .PHONY: devdoc devdoc-clean devdoc-init devdoc-save devdoc-update @@ -387,20 +390,20 @@ protoVer=0.14.0 protoImageName=ghcr.io/cosmos/proto-builder:$(protoVer) protoImage=$(DOCKER) run --rm -v $(CURDIR):/workspace --workdir /workspace $(protoImageName) -proto-all: proto-gen proto-swagger-gen +proto-all: proto-gen proto-swagger-gen ## Generate all protobuf related files -proto-gen: +proto-gen: ## Generate protobuf files @echo "Generating Protobuf files" @$(protoImage) sh ./proto/scripts/protocgen.sh -proto-swagger-gen: +proto-swagger-gen: ## Generate Swagger files from protobuf @echo "Generating Protobuf Swagger" @$(protoImage) sh ./proto/scripts/protoc-swagger-gen.sh -proto-format: +proto-format: ## Format protobuf files @$(protoImage) find ./ -name "*.proto" -exec clang-format -i {} \; -proto-lint: +proto-lint: ## Lint protobuf files @$(protoImage) buf lint --error-format=json .PHONY: proto-gen proto-swagger-gen proto-format prot-lint @@ -409,10 +412,10 @@ proto-lint: ### Docker ### ############################################################################### -build-docker: +build-docker: ## Build babylond Docker image $(MAKE) -C contrib/images babylond -build-cosmos-relayer-docker: +build-cosmos-relayer-docker: ## Build Docker image for the Cosmos relayer $(MAKE) -C contrib/images cosmos-relayer .PHONY: build-docker build-cosmos-relayer-docker @@ -421,8 +424,7 @@ build-cosmos-relayer-docker: ### Localnet ### ############################################################################### -# init-testnet-dirs will create a ./.testnets directory containing configuration for 4 Babylon nodes -init-testnet-dirs: +init-testnet-dirs: ## Initialize directories for testnet, creates a ./.testnets directory containing configuration for 4 Babylon nodes # need to create the dir before hand so that the docker container has write access to the `.testnets` dir # regardless of the user it uses mkdir -p $(CURDIR)/.testnets && chmod o+w $(CURDIR)/.testnets @@ -432,19 +434,17 @@ init-testnet-dirs: --chain-id chain-test --btc-confirmation-depth 2 --additional-sender-account true \ --epoch-interval 5 -# localnet-start-nodes will boot the nodes described in the docker-compose.yml file -localnet-start-nodes: init-testnet-dirs +localnet-start-nodes: init-testnet-dirs ## Boot the nodes described in the docker-compose.yml file docker-compose up -d -# localnet-start will run a with 4 nodes with 4 nodes, a bitcoin instance, and a vigilante instance -localnet-start: localnet-stop build-docker localnet-start-nodes +localnet-start: localnet-stop build-docker localnet-start-nodes ## Run with 4 nodes, a bitcoin instance, and a vigilante instance # localnet-stop will clean up and stop all localnets running localnet-stop: rm -rf $(CURDIR)/.testnets docker-compose down -build-test-wasm: +build-test-wasm: ## Build WASM bindings for testing docker run --rm -v "$(WASM_DIR)":/code \ --mount type=volume,source="$(WASM_DIR_BASE_NAME)_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ @@ -461,10 +461,10 @@ localnet-start \ localnet-stop .PHONY: diagrams -diagrams: +diagrams: ## Generate diagrams for documentation $(MAKE) -C client/docs/diagrams .PHONY: update-changelog -update-changelog: +update-changelog: ## Update the project changelog @echo ./scripts/update_changelog.sh $(since_tag) $(upcoming_tag) ./scripts/update_changelog.sh $(since_tag) $(upcoming_tag) From 5f8af8ced17d24f3f0c6172293cd37fb3d055807 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Mon, 29 Jul 2024 22:37:13 +0800 Subject: [PATCH 118/119] rename BabylonLabs dependencies (#1) Rename BabylonChain to BabylonLabs --------- Co-authored-by: KonradStaniec --- .github/workflows/publish.yml | 10 +- CHANGELOG.md | 830 +++++++++--------- LICENSE | 6 +- Makefile | 10 +- SECURITY.md | 2 +- app/ante_btc_validation_decorator.go | 8 +- app/app.go | 52 +- app/encoding.go | 4 +- app/keepers/keepers.go | 44 +- app/keepers/utils.go | 2 +- app/test_helpers.go | 12 +- app/upgrades/types.go | 2 +- app/upgrades/vanilla/upgrades.go | 10 +- app/upgrades/vanilla/upgrades_test.go | 6 +- btcstaking/btcstaking_test.go | 4 +- btcstaking/identifiable_staking_test.go | 4 +- btcstaking/staking.go | 2 +- btcstaking/staking_test.go | 4 +- btcstaking/staking_testvectors_test.go | 2 +- btcstaking/staking_utils_test.go | 6 +- btcstaking/types.go | 2 +- client/client/client.go | 6 +- client/client/keys.go | 2 +- client/client/keys_test.go | 8 +- client/client/tx.go | 4 +- client/config/babylon_config.go | 2 +- client/config/babylon_query_config_test.go | 2 +- client/docs/swagger-ui/swagger.yaml | 2 +- client/query/btccheckpoint.go | 2 +- client/query/btclightclient.go | 2 +- client/query/btcstaking.go | 2 +- client/query/checkpointing.go | 2 +- client/query/client.go | 2 +- client/query/epoching.go | 2 +- client/query/finality.go | 2 +- client/query/incentive.go | 2 +- client/query/monitor.go | 2 +- client/query/zoneconcierge.go | 2 +- cmd/babylond/cmd/cmd_test.go | 4 +- cmd/babylond/cmd/create_bls_key.go | 8 +- cmd/babylond/cmd/custom_babylon_config.go | 2 +- cmd/babylond/cmd/flags.go | 8 +- cmd/babylond/cmd/genaccounts_test.go | 4 +- cmd/babylond/cmd/genesis.go | 16 +- cmd/babylond/cmd/genhelpers/bls_add.go | 2 +- cmd/babylond/cmd/genhelpers/bls_add_test.go | 12 +- cmd/babylond/cmd/genhelpers/bls_create.go | 4 +- .../cmd/genhelpers/bls_create_test.go | 8 +- .../cmd/genhelpers/set_btc_delegations.go | 2 +- .../genhelpers/set_btc_delegations_test.go | 12 +- .../cmd/genhelpers/set_btc_headers.go | 2 +- .../cmd/genhelpers/set_btc_headers_test.go | 8 +- .../cmd/genhelpers/set_finality_providers.go | 2 +- .../genhelpers/set_finality_providers_test.go | 8 +- cmd/babylond/cmd/root.go | 8 +- cmd/babylond/cmd/testnet.go | 12 +- cmd/babylond/cmd/testnet_test.go | 2 +- cmd/babylond/cmd/validate_genesis.go | 2 +- cmd/babylond/cmd/validate_genesis_test.go | 6 +- cmd/babylond/main.go | 6 +- contrib/images/Makefile | 10 +- contrib/images/babylond/Dockerfile | 12 +- crypto/bip322/bip322_test.go | 4 +- crypto/ecdsa/ecdsa_test.go | 2 +- crypto/eots/eots_test.go | 4 +- crypto/eots/examples/btc-testnet-txs/main.go | 2 +- crypto/schnorr-adaptor-signature/keys_test.go | 2 +- crypto/schnorr-adaptor-signature/sig_test.go | 2 +- docker-compose.yml | 8 +- docs/architecture.md | 4 +- docs/transaction-impl-spec.md | 2 +- go.mod | 2 +- privval/file.go | 4 +- privval/types.go | 4 +- .../btccheckpoint/v1/btccheckpoint.proto | 8 +- proto/babylon/btccheckpoint/v1/genesis.proto | 2 +- proto/babylon/btccheckpoint/v1/params.proto | 2 +- proto/babylon/btccheckpoint/v1/query.proto | 2 +- proto/babylon/btccheckpoint/v1/tx.proto | 2 +- .../btclightclient/v1/btclightclient.proto | 6 +- proto/babylon/btclightclient/v1/event.proto | 2 +- proto/babylon/btclightclient/v1/genesis.proto | 2 +- proto/babylon/btclightclient/v1/params.proto | 2 +- proto/babylon/btclightclient/v1/query.proto | 8 +- proto/babylon/btclightclient/v1/tx.proto | 4 +- proto/babylon/btcstaking/v1/btcstaking.proto | 24 +- proto/babylon/btcstaking/v1/events.proto | 4 +- proto/babylon/btcstaking/v1/genesis.proto | 8 +- proto/babylon/btcstaking/v1/incentive.proto | 6 +- proto/babylon/btcstaking/v1/params.proto | 4 +- proto/babylon/btcstaking/v1/pop.proto | 2 +- proto/babylon/btcstaking/v1/query.proto | 8 +- proto/babylon/btcstaking/v1/tx.proto | 18 +- proto/babylon/checkpointing/v1/bls_key.proto | 8 +- .../babylon/checkpointing/v1/checkpoint.proto | 8 +- proto/babylon/checkpointing/v1/events.proto | 2 +- proto/babylon/checkpointing/v1/genesis.proto | 2 +- proto/babylon/checkpointing/v1/query.proto | 6 +- proto/babylon/checkpointing/v1/tx.proto | 2 +- proto/babylon/epoching/v1/epoching.proto | 2 +- proto/babylon/epoching/v1/events.proto | 2 +- proto/babylon/epoching/v1/genesis.proto | 2 +- proto/babylon/epoching/v1/params.proto | 2 +- proto/babylon/epoching/v1/query.proto | 2 +- proto/babylon/epoching/v1/tx.proto | 2 +- proto/babylon/finality/v1/events.proto | 2 +- proto/babylon/finality/v1/finality.proto | 12 +- proto/babylon/finality/v1/genesis.proto | 16 +- proto/babylon/finality/v1/params.proto | 2 +- proto/babylon/finality/v1/query.proto | 6 +- proto/babylon/finality/v1/tx.proto | 12 +- proto/babylon/incentive/genesis.proto | 2 +- proto/babylon/incentive/incentive.proto | 2 +- proto/babylon/incentive/params.proto | 2 +- proto/babylon/incentive/query.proto | 2 +- proto/babylon/incentive/tx.proto | 2 +- proto/babylon/monitor/v1/genesis.proto | 2 +- proto/babylon/monitor/v1/query.proto | 2 +- proto/babylon/zoneconcierge/v1/genesis.proto | 2 +- proto/babylon/zoneconcierge/v1/packet.proto | 2 +- proto/babylon/zoneconcierge/v1/params.proto | 2 +- proto/babylon/zoneconcierge/v1/query.proto | 2 +- proto/babylon/zoneconcierge/v1/tx.proto | 2 +- .../zoneconcierge/v1/zoneconcierge.proto | 2 +- proto/scripts/protocgen.sh | 2 +- test/e2e/README.md | 2 +- test/e2e/btc_staking_e2e_test.go | 24 +- test/e2e/btc_timestamping_e2e_test.go | 10 +- .../btc_timestamping_phase2_hermes_test.go | 6 +- test/e2e/btc_timestamping_phase2_rly_test.go | 6 +- test/e2e/bytecode/README.md | 2 +- test/e2e/configurer/base.go | 12 +- test/e2e/configurer/chain/chain.go | 6 +- test/e2e/configurer/chain/commands.go | 18 +- .../configurer/chain/commands_btcstaking.go | 10 +- test/e2e/configurer/chain/node.go | 4 +- test/e2e/configurer/chain/queries.go | 12 +- .../configurer/chain/queries_btcstaking.go | 8 +- test/e2e/configurer/chain/queries_ibc.go | 2 +- .../e2e/configurer/chain/queries_incentive.go | 4 +- test/e2e/configurer/current.go | 6 +- test/e2e/configurer/factory.go | 8 +- test/e2e/containers/config.go | 4 +- test/e2e/ibc_transfer_e2e_test.go | 4 +- test/e2e/initialization/chain/main.go | 2 +- test/e2e/initialization/config.go | 12 +- test/e2e/initialization/init.go | 4 +- test/e2e/initialization/init_test.go | 2 +- test/e2e/initialization/node.go | 12 +- test/e2e/initialization/node/main.go | 2 +- test/e2e/initialization/util.go | 2 +- test/e2e/scripts/download_release.sh | 7 +- test/e2e/util/codec.go | 4 +- testutil/datagen/account_balance.go | 2 +- testutil/datagen/btc_address_test.go | 2 +- testutil/datagen/btc_blockchain.go | 2 +- testutil/datagen/btc_header_chain.go | 4 +- testutil/datagen/btc_header_info.go | 6 +- testutil/datagen/btc_schnorr.go | 2 +- testutil/datagen/btc_transaction.go | 6 +- testutil/datagen/btcstaking.go | 6 +- testutil/datagen/covenant.go | 8 +- testutil/datagen/epoching.go | 2 +- testutil/datagen/finality.go | 6 +- testutil/datagen/genesiskey.go | 10 +- testutil/datagen/incentive.go | 6 +- testutil/datagen/init_val.go | 4 +- testutil/datagen/raw_checkpoint.go | 6 +- testutil/datagen/tendermint.go | 2 +- testutil/datagen/val_set.go | 6 +- testutil/datagen/vote_ext.go | 2 +- testutil/helper/gen_blocks.go | 2 +- testutil/helper/helper.go | 18 +- testutil/keeper/btccheckpoint.go | 4 +- testutil/keeper/btclightclient.go | 8 +- testutil/keeper/btcstaking.go | 4 +- testutil/keeper/checkpointing.go | 4 +- testutil/keeper/epoching.go | 4 +- testutil/keeper/finality.go | 4 +- testutil/keeper/incentive.go | 4 +- testutil/keeper/zoneconcierge.go | 4 +- testutil/mocks/bls_signer.go | 2 +- .../mocks/checkpointing_expected_keepers.go | 4 +- testutil/mocks/proposal_keeper.go | 6 +- types/btc_header_bytes_test.go | 4 +- types/btc_header_hash_bytes_test.go | 4 +- types/btc_schnorr_eots_test.go | 4 +- types/btc_schnorr_pk_test.go | 4 +- types/btc_schnorr_pub_rand.go | 2 +- types/btc_schnorr_pub_rand_test.go | 4 +- types/btc_schnorr_sig_test.go | 4 +- types/btcutils_test.go | 2 +- types/retry/retry.go | 6 +- wasmbinding/bindings/utils.go | 2 +- wasmbinding/test/custom_query_test.go | 6 +- wasmbinding/wasm.go | 10 +- x/btccheckpoint/abci.go | 2 +- x/btccheckpoint/client/cli/query.go | 2 +- x/btccheckpoint/client/cli/query_params.go | 2 +- x/btccheckpoint/client/cli/tx.go | 2 +- x/btccheckpoint/genesis.go | 4 +- x/btccheckpoint/genesis_test.go | 6 +- x/btccheckpoint/keeper/grpc_query.go | 2 +- x/btccheckpoint/keeper/grpc_query_params.go | 2 +- .../keeper/grpc_query_params_test.go | 4 +- x/btccheckpoint/keeper/grpc_query_test.go | 4 +- x/btccheckpoint/keeper/hooks.go | 4 +- x/btccheckpoint/keeper/incentive.go | 2 +- x/btccheckpoint/keeper/keeper.go | 6 +- x/btccheckpoint/keeper/keeper_test.go | 4 +- x/btccheckpoint/keeper/msg_server.go | 2 +- x/btccheckpoint/keeper/msg_server_test.go | 10 +- x/btccheckpoint/keeper/params.go | 2 +- x/btccheckpoint/keeper/params_test.go | 4 +- x/btccheckpoint/keeper/submissions.go | 4 +- x/btccheckpoint/module.go | 6 +- x/btccheckpoint/types/btccheckpoint.pb.go | 120 +-- x/btccheckpoint/types/btcutils.go | 2 +- x/btccheckpoint/types/btcutils_test.go | 6 +- x/btccheckpoint/types/expected_keepers.go | 4 +- x/btccheckpoint/types/genesis.pb.go | 12 +- x/btccheckpoint/types/genesis_test.go | 2 +- x/btccheckpoint/types/mock_keepers.go | 4 +- x/btccheckpoint/types/msgs.go | 2 +- x/btccheckpoint/types/params.go | 2 +- x/btccheckpoint/types/params.pb.go | 12 +- x/btccheckpoint/types/params_test.go | 2 +- x/btccheckpoint/types/query.pb.go | 120 +-- x/btccheckpoint/types/tx.pb.go | 12 +- x/btccheckpoint/types/types.go | 4 +- x/btclightclient/README.md | 6 +- x/btclightclient/client/cli/query.go | 2 +- x/btclightclient/client/cli/tx.go | 2 +- x/btclightclient/genesis.go | 4 +- x/btclightclient/genesis_test.go | 14 +- x/btclightclient/keeper/base_btc_header.go | 2 +- .../keeper/base_btc_header_test.go | 4 +- x/btclightclient/keeper/grpc_query.go | 4 +- x/btclightclient/keeper/grpc_query_test.go | 8 +- x/btclightclient/keeper/hooks.go | 2 +- x/btclightclient/keeper/keeper.go | 4 +- x/btclightclient/keeper/keeper_test.go | 8 +- x/btclightclient/keeper/msg_server.go | 2 +- x/btclightclient/keeper/msg_server_test.go | 8 +- x/btclightclient/keeper/params.go | 2 +- x/btclightclient/keeper/params_test.go | 4 +- x/btclightclient/keeper/state.go | 4 +- x/btclightclient/keeper/state_test.go | 8 +- x/btclightclient/keeper/triggers.go | 2 +- x/btclightclient/keeper/utils.go | 2 +- x/btclightclient/keeper/utils_test.go | 4 +- x/btclightclient/module.go | 6 +- x/btclightclient/types/btc_header_info.go | 2 +- .../types/btc_header_info_test.go | 6 +- x/btclightclient/types/btc_light_client.go | 2 +- x/btclightclient/types/btclightclient.pb.go | 44 +- x/btclightclient/types/event.pb.go | 12 +- x/btclightclient/types/genesis.go | 2 +- x/btclightclient/types/genesis.pb.go | 13 +- x/btclightclient/types/genesis_test.go | 2 +- x/btclightclient/types/keys.go | 2 +- x/btclightclient/types/keys_test.go | 6 +- x/btclightclient/types/msgs.go | 2 +- x/btclightclient/types/msgs_test.go | 6 +- x/btclightclient/types/params.pb.go | 12 +- x/btclightclient/types/querier.go | 2 +- x/btclightclient/types/querier_test.go | 6 +- x/btclightclient/types/query.pb.go | 130 +-- x/btclightclient/types/tx.pb.go | 50 +- x/btclightclient/types/work.go | 2 +- x/btclightclient/types/work_test.go | 4 +- x/btcstaking/README.md | 34 +- x/btcstaking/abci.go | 4 +- x/btcstaking/client/cli/query.go | 2 +- x/btcstaking/client/cli/query_params.go | 2 +- x/btcstaking/client/cli/tx.go | 8 +- x/btcstaking/genesis.go | 4 +- x/btcstaking/genesis_test.go | 8 +- x/btcstaking/keeper/bench_test.go | 8 +- x/btcstaking/keeper/btc_delegations.go | 6 +- x/btcstaking/keeper/btc_delegators.go | 4 +- x/btcstaking/keeper/btc_height_index.go | 2 +- x/btcstaking/keeper/btc_height_index_test.go | 8 +- x/btcstaking/keeper/finality_providers.go | 2 +- x/btcstaking/keeper/genesis.go | 6 +- x/btcstaking/keeper/genesis_test.go | 8 +- x/btcstaking/keeper/grpc_query.go | 4 +- x/btcstaking/keeper/grpc_query_test.go | 12 +- x/btcstaking/keeper/hooks.go | 4 +- x/btcstaking/keeper/incentive.go | 2 +- x/btcstaking/keeper/incentive_test.go | 6 +- x/btcstaking/keeper/keeper.go | 2 +- x/btcstaking/keeper/keeper_test.go | 14 +- x/btcstaking/keeper/msg_server.go | 6 +- x/btcstaking/keeper/msg_server_test.go | 14 +- x/btcstaking/keeper/params.go | 2 +- x/btcstaking/keeper/params_test.go | 6 +- x/btcstaking/keeper/power_dist_change.go | 4 +- x/btcstaking/keeper/power_dist_change_test.go | 6 +- x/btcstaking/keeper/query.go | 2 +- x/btcstaking/keeper/query_params.go | 2 +- x/btcstaking/keeper/query_params_test.go | 4 +- x/btcstaking/keeper/voting_power_table.go | 4 +- .../keeper/voting_power_table_test.go | 6 +- x/btcstaking/module.go | 6 +- x/btcstaking/types/btc_delegation.go | 6 +- x/btcstaking/types/btc_delegation_test.go | 10 +- x/btcstaking/types/btc_slashing_tx.go | 6 +- x/btcstaking/types/btc_slashing_tx_test.go | 10 +- x/btcstaking/types/btc_undelegation.go | 4 +- x/btcstaking/types/btc_undelegation_test.go | 10 +- x/btcstaking/types/btcstaking.go | 6 +- x/btcstaking/types/btcstaking.pb.go | 200 ++--- x/btcstaking/types/events.go | 2 +- x/btcstaking/types/events.pb.go | 67 +- x/btcstaking/types/expected_keepers.go | 8 +- x/btcstaking/types/genesis.pb.go | 102 +-- x/btcstaking/types/genesis_test.go | 2 +- x/btcstaking/types/hooks.go | 2 +- x/btcstaking/types/incentive.pb.go | 72 +- x/btcstaking/types/mocked_keepers.go | 8 +- x/btcstaking/types/msg.go | 4 +- x/btcstaking/types/msg_test.go | 6 +- x/btcstaking/types/params.go | 4 +- x/btcstaking/types/params.pb.go | 74 +- x/btcstaking/types/pop.go | 6 +- x/btcstaking/types/pop.pb.go | 38 +- x/btcstaking/types/pop_test.go | 6 +- x/btcstaking/types/query.pb.go | 249 +++--- x/btcstaking/types/tx.pb.go | 196 ++--- x/checkpointing/README.md | 6 +- x/checkpointing/abci.go | 4 +- x/checkpointing/client/cli/query.go | 2 +- x/checkpointing/client/cli/tx.go | 4 +- x/checkpointing/client/cli/tx_test.go | 10 +- x/checkpointing/client/cli/utils.go | 4 +- x/checkpointing/genesis.go | 4 +- x/checkpointing/genesis_test.go | 10 +- x/checkpointing/keeper/bls_signer.go | 4 +- x/checkpointing/keeper/bls_signer_test.go | 4 +- x/checkpointing/keeper/ckpt_state.go | 2 +- x/checkpointing/keeper/genesis_bls.go | 2 +- x/checkpointing/keeper/grpc_query_bls.go | 2 +- x/checkpointing/keeper/grpc_query_bls_test.go | 10 +- .../keeper/grpc_query_checkpoint.go | 2 +- .../keeper/grpc_query_checkpoint_test.go | 12 +- x/checkpointing/keeper/hooks.go | 2 +- x/checkpointing/keeper/keeper.go | 8 +- x/checkpointing/keeper/keeper_test.go | 12 +- x/checkpointing/keeper/msg_server.go | 4 +- x/checkpointing/keeper/msg_server_test.go | 18 +- x/checkpointing/keeper/registration_state.go | 4 +- x/checkpointing/keeper/val_bls_set.go | 2 +- x/checkpointing/keeper/val_bls_set_test.go | 10 +- x/checkpointing/module.go | 6 +- x/checkpointing/proposal.go | 2 +- x/checkpointing/proposal_expected_keeper.go | 6 +- x/checkpointing/proposal_test.go | 14 +- x/checkpointing/types/bls_key.pb.go | 82 +- x/checkpointing/types/checkpoint.pb.go | 126 +-- x/checkpointing/types/events.pb.go | 40 +- x/checkpointing/types/expected_keepers.go | 2 +- x/checkpointing/types/genesis.go | 2 +- x/checkpointing/types/genesis.pb.go | 44 +- x/checkpointing/types/keys.go | 2 +- x/checkpointing/types/msgs.go | 2 +- x/checkpointing/types/msgs_test.go | 8 +- x/checkpointing/types/pop.go | 2 +- x/checkpointing/types/pop_test.go | 4 +- x/checkpointing/types/query.pb.go | 172 ++-- x/checkpointing/types/tx.pb.go | 48 +- x/checkpointing/types/types.go | 6 +- x/checkpointing/types/types_test.go | 6 +- x/checkpointing/types/utils.go | 4 +- x/checkpointing/types/val_bls_set.go | 2 +- x/checkpointing/vote_ext.go | 4 +- x/checkpointing/vote_ext_test.go | 6 +- x/epoching/abci.go | 4 +- x/epoching/client/cli/query.go | 2 +- x/epoching/client/cli/tx.go | 4 +- x/epoching/genesis.go | 4 +- x/epoching/genesis_test.go | 6 +- .../keeper/drop_validator_msg_decorator.go | 2 +- x/epoching/keeper/epoch_msg_queue.go | 2 +- x/epoching/keeper/epoch_msg_queue_test.go | 8 +- x/epoching/keeper/epoch_slashed_val_set.go | 2 +- .../keeper/epoch_slashed_val_set_test.go | 6 +- x/epoching/keeper/epoch_val_set.go | 2 +- x/epoching/keeper/epoch_val_set_test.go | 4 +- x/epoching/keeper/epochs.go | 2 +- x/epoching/keeper/epochs_test.go | 4 +- x/epoching/keeper/grpc_query.go | 2 +- x/epoching/keeper/grpc_query_test.go | 6 +- x/epoching/keeper/hooks.go | 4 +- x/epoching/keeper/keeper.go | 2 +- x/epoching/keeper/keeper_test.go | 4 +- x/epoching/keeper/lifecycle_delegation.go | 2 +- x/epoching/keeper/lifecycle_validator.go | 2 +- x/epoching/keeper/modified_staking.go | 2 +- x/epoching/keeper/msg_server.go | 2 +- x/epoching/keeper/msg_server_test.go | 4 +- x/epoching/keeper/params.go | 2 +- x/epoching/keeper/params_test.go | 4 +- x/epoching/keeper/staking_functions.go | 2 +- x/epoching/module.go | 6 +- x/epoching/types/epoching.pb.go | 110 +-- x/epoching/types/epoching_test.go | 4 +- x/epoching/types/events.pb.go | 84 +- x/epoching/types/genesis.pb.go | 12 +- x/epoching/types/genesis_test.go | 8 +- x/epoching/types/msg_test.go | 4 +- x/epoching/types/params.pb.go | 12 +- x/epoching/types/params_test.go | 2 +- x/epoching/types/query.pb.go | 176 ++-- x/epoching/types/tx.pb.go | 76 +- x/epoching/types/validator_test.go | 2 +- x/finality/README.md | 12 +- x/finality/abci.go | 4 +- x/finality/client/cli/query.go | 2 +- x/finality/client/cli/query_params.go | 2 +- x/finality/client/cli/tx.go | 4 +- x/finality/genesis.go | 4 +- x/finality/genesis_test.go | 8 +- x/finality/keeper/evidence.go | 4 +- x/finality/keeper/genesis.go | 6 +- x/finality/keeper/genesis_test.go | 8 +- x/finality/keeper/grpc_query.go | 4 +- x/finality/keeper/grpc_query_test.go | 10 +- x/finality/keeper/hooks.go | 4 +- x/finality/keeper/indexed_blocks.go | 2 +- x/finality/keeper/keeper.go | 2 +- x/finality/keeper/liveness.go | 4 +- x/finality/keeper/liveness_test.go | 8 +- x/finality/keeper/msg_server.go | 6 +- x/finality/keeper/msg_server_test.go | 12 +- x/finality/keeper/params.go | 2 +- x/finality/keeper/params_test.go | 4 +- x/finality/keeper/public_randomness.go | 4 +- x/finality/keeper/query.go | 2 +- x/finality/keeper/query_params.go | 2 +- x/finality/keeper/query_params_test.go | 4 +- x/finality/keeper/signing_info.go | 4 +- x/finality/keeper/tallying.go | 2 +- x/finality/keeper/tallying_bench_test.go | 10 +- x/finality/keeper/tallying_test.go | 12 +- x/finality/keeper/votes.go | 4 +- x/finality/keeper/votes_bench_test.go | 10 +- x/finality/module.go | 6 +- x/finality/types/events.go | 2 +- x/finality/types/events.pb.go | 12 +- x/finality/types/expected_keepers.go | 4 +- x/finality/types/finality.go | 2 +- x/finality/types/finality.pb.go | 90 +- x/finality/types/genesis.pb.go | 120 +-- x/finality/types/genesis_test.go | 2 +- x/finality/types/hooks.go | 2 +- x/finality/types/keys.go | 2 +- x/finality/types/mocked_keepers.go | 4 +- x/finality/types/msg.go | 2 +- x/finality/types/msg_test.go | 6 +- x/finality/types/params.pb.go | 48 +- x/finality/types/query.pb.go | 184 ++-- x/finality/types/signing_info.go | 2 +- x/finality/types/tx.pb.go | 114 +-- x/incentive/abci.go | 4 +- x/incentive/client/cli/query.go | 2 +- x/incentive/client/cli/query_params.go | 2 +- x/incentive/client/cli/tx.go | 2 +- x/incentive/genesis.go | 4 +- x/incentive/genesis_test.go | 8 +- x/incentive/keeper/btc_staking_gauge.go | 4 +- x/incentive/keeper/btc_staking_gauge_test.go | 6 +- x/incentive/keeper/btc_timestamping_gauge.go | 4 +- .../keeper/btc_timestamping_gauge_test.go | 6 +- x/incentive/keeper/grpc_query.go | 2 +- x/incentive/keeper/grpc_query_test.go | 6 +- x/incentive/keeper/intercept_fee_collector.go | 2 +- .../keeper/intercept_fee_collector_test.go | 8 +- x/incentive/keeper/keeper.go | 2 +- x/incentive/keeper/msg_server.go | 2 +- x/incentive/keeper/msg_server_test.go | 8 +- x/incentive/keeper/params.go | 2 +- x/incentive/keeper/params_test.go | 4 +- x/incentive/keeper/query_params.go | 2 +- x/incentive/keeper/query_params_test.go | 4 +- x/incentive/keeper/reward_gauge.go | 2 +- x/incentive/keeper/reward_gauge_test.go | 2 +- x/incentive/module.go | 6 +- x/incentive/types/expected_keepers.go | 2 +- x/incentive/types/genesis.pb.go | 12 +- x/incentive/types/genesis_test.go | 2 +- x/incentive/types/incentive.pb.go | 10 +- x/incentive/types/mocked_keepers.go | 2 +- x/incentive/types/params.pb.go | 12 +- x/incentive/types/query.pb.go | 76 +- x/incentive/types/tx.pb.go | 62 +- x/monitor/client/cli/query.go | 2 +- x/monitor/client/cli/tx.go | 2 +- x/monitor/genesis.go | 4 +- x/monitor/genesis_test.go | 6 +- x/monitor/keeper/grpc_query.go | 2 +- x/monitor/keeper/grpc_query_test.go | 14 +- x/monitor/keeper/hooks.go | 4 +- x/monitor/keeper/keeper.go | 4 +- x/monitor/module.go | 6 +- x/monitor/types/expected_keepers.go | 2 +- x/monitor/types/genesis.pb.go | 13 +- x/monitor/types/genesis_test.go | 2 +- x/monitor/types/keys.go | 2 +- x/monitor/types/query.pb.go | 54 +- x/zoneconcierge/README.md | 2 +- x/zoneconcierge/abci.go | 4 +- x/zoneconcierge/client/cli/query.go | 2 +- x/zoneconcierge/client/cli/tx.go | 2 +- x/zoneconcierge/genesis.go | 4 +- x/zoneconcierge/genesis_test.go | 8 +- .../keeper/canonical_chain_indexer.go | 2 +- .../keeper/canonical_chain_indexer_test.go | 4 +- x/zoneconcierge/keeper/chain_info_indexer.go | 2 +- .../keeper/epoch_chain_info_indexer.go | 4 +- .../keeper/epoch_chain_info_indexer_test.go | 4 +- x/zoneconcierge/keeper/epochs.go | 4 +- x/zoneconcierge/keeper/fork_indexer.go | 2 +- x/zoneconcierge/keeper/fork_indexer_test.go | 4 +- x/zoneconcierge/keeper/grpc_query.go | 4 +- x/zoneconcierge/keeper/grpc_query_test.go | 14 +- x/zoneconcierge/keeper/header_handler.go | 2 +- x/zoneconcierge/keeper/hooks.go | 6 +- .../keeper/ibc_header_decorator.go | 2 +- x/zoneconcierge/keeper/ibc_packet.go | 2 +- .../keeper/ibc_packet_btc_timestamp.go | 12 +- .../keeper/ibc_packet_btc_timestamp_test.go | 8 +- x/zoneconcierge/keeper/keeper.go | 2 +- x/zoneconcierge/keeper/keeper_test.go | 4 +- x/zoneconcierge/keeper/msg_server.go | 2 +- x/zoneconcierge/keeper/params.go | 2 +- x/zoneconcierge/keeper/params_test.go | 4 +- x/zoneconcierge/keeper/proof_btc_timestamp.go | 8 +- .../keeper/proof_btc_timestamp_test.go | 14 +- x/zoneconcierge/module.go | 6 +- x/zoneconcierge/module_ibc.go | 4 +- x/zoneconcierge/types/btc_timestamp.go | 14 +- x/zoneconcierge/types/btc_timestamp_test.go | 14 +- x/zoneconcierge/types/expected_keepers.go | 10 +- x/zoneconcierge/types/genesis.pb.go | 12 +- x/zoneconcierge/types/genesis_test.go | 2 +- x/zoneconcierge/types/mocked_keepers.go | 10 +- x/zoneconcierge/types/packet.pb.go | 64 +- x/zoneconcierge/types/params.pb.go | 12 +- x/zoneconcierge/types/params_test.go | 2 +- x/zoneconcierge/types/query.pb.go | 156 ++-- x/zoneconcierge/types/tx.pb.go | 12 +- x/zoneconcierge/types/zoneconcierge.pb.go | 132 +-- 553 files changed, 3529 insertions(+), 3522 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 38d5df4bf..b5c3cdb81 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,22 +7,22 @@ on: - 'dev' tags: - '*' - + jobs: lint_test: - uses: babylonchain/.github/.github/workflows/reusable_go_lint_test.yml@v0.1.0 + uses: babylonlabs-io/.github/.github/workflows/reusable_go_lint_test.yml@v0.1.0 with: run-unit-tests: true run-integration-tests: true run-lint: true integration-tests-command: | sudo make test-e2e - + docker_pipeline: - uses: babylonchain/.github/.github/workflows/reusable_docker_pipeline.yml@v0.1.0 + uses: babylonlabs-io/.github/.github/workflows/reusable_docker_pipeline.yml@v0.1.0 needs: ["lint_test"] secrets: inherit with: publish: true dockerfile: ./contrib/images/babylond/Dockerfile - repoName: babylond \ No newline at end of file + repoName: babylond diff --git a/CHANGELOG.md b/CHANGELOG.md index 1793be5f2..54dbc9709 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,529 +1,529 @@ # Changelog -## [v0.8.0](https://github.com/babylonchain/babylon/tree/v0.8.0) (2024-02-08) +## [v0.8.0](https://github.com/babylonlabs-io/babylon/tree/v0.8.0) (2024-02-08) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.8.0-rc.0...v0.8.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.8.0-rc.0...v0.8.0) -## [v0.8.0-rc.0](https://github.com/babylonchain/babylon/tree/v0.8.0-rc.0) (2024-01-22) +## [v0.8.0-rc.0](https://github.com/babylonlabs-io/babylon/tree/v0.8.0-rc.0) (2024-01-22) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.2...v0.8.0-rc.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.7.2...v0.8.0-rc.0) **Closed issues:** -- Dead Link in the Git "Joining the testnet" [\#406](https://github.com/babylonchain/babylon/issues/406) -- Broken link for testnet in the main README.md [\#403](https://github.com/babylonchain/babylon/issues/403) -- Random failure when running integration test [\#319](https://github.com/babylonchain/babylon/issues/319) -- Refactor BLS signer to load gas settings during initiation [\#311](https://github.com/babylonchain/babylon/issues/311) -- Random CI failure on QueryFinalizedChainInfo [\#288](https://github.com/babylonchain/babylon/issues/288) +- Dead Link in the Git "Joining the testnet" [\#406](https://github.com/babylonlabs-io/babylon/issues/406) +- Broken link for testnet in the main README.md [\#403](https://github.com/babylonlabs-io/babylon/issues/403) +- Random failure when running integration test [\#319](https://github.com/babylonlabs-io/babylon/issues/319) +- Refactor BLS signer to load gas settings during initiation [\#311](https://github.com/babylonlabs-io/babylon/issues/311) +- Random CI failure on QueryFinalizedChainInfo [\#288](https://github.com/babylonlabs-io/babylon/issues/288) **Merged pull requests:** -- chore: add parameter sections for module docs [\#418](https://github.com/babylonchain/babylon/pull/418) ([SebastianElvis](https://github.com/SebastianElvis)) -- doc: documentation for the epoching module [\#416](https://github.com/babylonchain/babylon/pull/416) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: making zoneconcierge resilient against long BTC reorg \(again\) [\#413](https://github.com/babylonchain/babylon/pull/413) ([SebastianElvis](https://github.com/SebastianElvis)) -- BTC Staking [\#409](https://github.com/babylonchain/babylon/pull/409) ([vitsalis](https://github.com/vitsalis)) -- Fix typos [\#405](https://github.com/babylonchain/babylon/pull/405) ([AtomicInnovation321](https://github.com/AtomicInnovation321)) -- Updated testnet link [\#404](https://github.com/babylonchain/babylon/pull/404) ([kunallimaye](https://github.com/kunallimaye)) -- README: updating discord link [\#402](https://github.com/babylonchain/babylon/pull/402) ([GakiBash](https://github.com/GakiBash)) -- README: Add medium link [\#400](https://github.com/babylonchain/babylon/pull/400) ([EdwardFanfan](https://github.com/EdwardFanfan)) -- Bump comet bft [\#399](https://github.com/babylonchain/babylon/pull/399) ([KonradStaniec](https://github.com/KonradStaniec)) -- hotfix: Barberry upgrade [\#398](https://github.com/babylonchain/babylon/pull/398) ([vitsalis](https://github.com/vitsalis)) -- Bump wasmd to stable [\#396](https://github.com/babylonchain/babylon/pull/396) ([KonradStaniec](https://github.com/KonradStaniec)) -- hotfix: fixing marshaling of MsgWrappedCreateValidator [\#394](https://github.com/babylonchain/babylon/pull/394) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: adding a flag for retrieving proofs of a FinalizedChainInfo [\#391](https://github.com/babylonchain/babylon/pull/391) ([SebastianElvis](https://github.com/SebastianElvis)) -- e2e: merge integration tests with e2e tests [\#390](https://github.com/babylonchain/babylon/pull/390) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: add parameter sections for module docs [\#418](https://github.com/babylonlabs-io/babylon/pull/418) ([SebastianElvis](https://github.com/SebastianElvis)) +- doc: documentation for the epoching module [\#416](https://github.com/babylonlabs-io/babylon/pull/416) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: making zoneconcierge resilient against long BTC reorg \(again\) [\#413](https://github.com/babylonlabs-io/babylon/pull/413) ([SebastianElvis](https://github.com/SebastianElvis)) +- BTC Staking [\#409](https://github.com/babylonlabs-io/babylon/pull/409) ([vitsalis](https://github.com/vitsalis)) +- Fix typos [\#405](https://github.com/babylonlabs-io/babylon/pull/405) ([AtomicInnovation321](https://github.com/AtomicInnovation321)) +- Updated testnet link [\#404](https://github.com/babylonlabs-io/babylon/pull/404) ([kunallimaye](https://github.com/kunallimaye)) +- README: updating discord link [\#402](https://github.com/babylonlabs-io/babylon/pull/402) ([GakiBash](https://github.com/GakiBash)) +- README: Add medium link [\#400](https://github.com/babylonlabs-io/babylon/pull/400) ([EdwardFanfan](https://github.com/EdwardFanfan)) +- Bump comet bft [\#399](https://github.com/babylonlabs-io/babylon/pull/399) ([KonradStaniec](https://github.com/KonradStaniec)) +- hotfix: Barberry upgrade [\#398](https://github.com/babylonlabs-io/babylon/pull/398) ([vitsalis](https://github.com/vitsalis)) +- Bump wasmd to stable [\#396](https://github.com/babylonlabs-io/babylon/pull/396) ([KonradStaniec](https://github.com/KonradStaniec)) +- hotfix: fixing marshaling of MsgWrappedCreateValidator [\#394](https://github.com/babylonlabs-io/babylon/pull/394) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: adding a flag for retrieving proofs of a FinalizedChainInfo [\#391](https://github.com/babylonlabs-io/babylon/pull/391) ([SebastianElvis](https://github.com/SebastianElvis)) +- e2e: merge integration tests with e2e tests [\#390](https://github.com/babylonlabs-io/babylon/pull/390) ([SebastianElvis](https://github.com/SebastianElvis)) -## [v0.7.2](https://github.com/babylonchain/babylon/tree/v0.7.2) (2023-06-10) +## [v0.7.2](https://github.com/babylonlabs-io/babylon/tree/v0.7.2) (2023-06-10) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.1...v0.7.2) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.7.1...v0.7.2) -## [v0.7.1](https://github.com/babylonchain/babylon/tree/v0.7.1) (2023-05-30) +## [v0.7.1](https://github.com/babylonlabs-io/babylon/tree/v0.7.1) (2023-05-30) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.7.0...v0.7.1) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.7.0...v0.7.1) **Closed issues:** -- zoneconcierge: parameterise timeout for IBC packets [\#207](https://github.com/babylonchain/babylon/issues/207) +- zoneconcierge: parameterise timeout for IBC packets [\#207](https://github.com/babylonlabs-io/babylon/issues/207) **Merged pull requests:** -- hotfix: fixing marshaling of `MsgWrappedCreateValidator` [\#393](https://github.com/babylonchain/babylon/pull/393) ([SebastianElvis](https://github.com/SebastianElvis)) +- hotfix: fixing marshaling of `MsgWrappedCreateValidator` [\#393](https://github.com/babylonlabs-io/babylon/pull/393) ([SebastianElvis](https://github.com/SebastianElvis)) -## [v0.7.0](https://github.com/babylonchain/babylon/tree/v0.7.0) (2023-05-26) +## [v0.7.0](https://github.com/babylonlabs-io/babylon/tree/v0.7.0) (2023-05-26) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0...v0.7.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.6.0...v0.7.0) **Closed issues:** -- Nil hooks [\#214](https://github.com/babylonchain/babylon/issues/214) +- Nil hooks [\#214](https://github.com/babylonlabs-io/babylon/issues/214) **Merged pull requests:** -- Release v0.7.0 [\#388](https://github.com/babylonchain/babylon/pull/388) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge: adding header timestamp to IndexedHeader [\#387](https://github.com/babylonchain/babylon/pull/387) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: parameterise timeout for IBC packets [\#386](https://github.com/babylonchain/babylon/pull/386) ([SebastianElvis](https://github.com/SebastianElvis)) -- CI: Push images for dev branch commits [\#385](https://github.com/babylonchain/babylon/pull/385) ([filippos47](https://github.com/filippos47)) -- dockerfile: opt out version when building [\#384](https://github.com/babylonchain/babylon/pull/384) ([SebastianElvis](https://github.com/SebastianElvis)) -- Use fee module [\#383](https://github.com/babylonchain/babylon/pull/383) ([KonradStaniec](https://github.com/KonradStaniec)) -- Bump vulnerable docker/distribution [\#382](https://github.com/babylonchain/babylon/pull/382) ([vitsalis](https://github.com/vitsalis)) -- Bump wasmd to rc2 [\#381](https://github.com/babylonchain/babylon/pull/381) ([KonradStaniec](https://github.com/KonradStaniec)) -- Add wasm e2e test [\#380](https://github.com/babylonchain/babylon/pull/380) ([KonradStaniec](https://github.com/KonradStaniec)) -- phase2: IBC packet and logic [\#368](https://github.com/babylonchain/babylon/pull/368) ([SebastianElvis](https://github.com/SebastianElvis)) +- Release v0.7.0 [\#388](https://github.com/babylonlabs-io/babylon/pull/388) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: adding header timestamp to IndexedHeader [\#387](https://github.com/babylonlabs-io/babylon/pull/387) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: parameterise timeout for IBC packets [\#386](https://github.com/babylonlabs-io/babylon/pull/386) ([SebastianElvis](https://github.com/SebastianElvis)) +- CI: Push images for dev branch commits [\#385](https://github.com/babylonlabs-io/babylon/pull/385) ([filippos47](https://github.com/filippos47)) +- dockerfile: opt out version when building [\#384](https://github.com/babylonlabs-io/babylon/pull/384) ([SebastianElvis](https://github.com/SebastianElvis)) +- Use fee module [\#383](https://github.com/babylonlabs-io/babylon/pull/383) ([KonradStaniec](https://github.com/KonradStaniec)) +- Bump vulnerable docker/distribution [\#382](https://github.com/babylonlabs-io/babylon/pull/382) ([vitsalis](https://github.com/vitsalis)) +- Bump wasmd to rc2 [\#381](https://github.com/babylonlabs-io/babylon/pull/381) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add wasm e2e test [\#380](https://github.com/babylonlabs-io/babylon/pull/380) ([KonradStaniec](https://github.com/KonradStaniec)) +- phase2: IBC packet and logic [\#368](https://github.com/babylonlabs-io/babylon/pull/368) ([SebastianElvis](https://github.com/SebastianElvis)) -## [v0.6.0](https://github.com/babylonchain/babylon/tree/v0.6.0) (2023-05-10) +## [v0.6.0](https://github.com/babylonlabs-io/babylon/tree/v0.6.0) (2023-05-10) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0rc0...v0.6.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.6.0rc0...v0.6.0) **Merged pull requests:** -- Release v0.6.0 [\#379](https://github.com/babylonchain/babylon/pull/379) ([vitsalis](https://github.com/vitsalis)) -- Fix non-determinism in integration test [\#377](https://github.com/babylonchain/babylon/pull/377) ([KonradStaniec](https://github.com/KonradStaniec)) -- Fix consensus version in our custom modules [\#376](https://github.com/babylonchain/babylon/pull/376) ([KonradStaniec](https://github.com/KonradStaniec)) -- Add fuzz test for epoch finalization/confirmation [\#375](https://github.com/babylonchain/babylon/pull/375) ([KonradStaniec](https://github.com/KonradStaniec)) +- Release v0.6.0 [\#379](https://github.com/babylonlabs-io/babylon/pull/379) ([vitsalis](https://github.com/vitsalis)) +- Fix non-determinism in integration test [\#377](https://github.com/babylonlabs-io/babylon/pull/377) ([KonradStaniec](https://github.com/KonradStaniec)) +- Fix consensus version in our custom modules [\#376](https://github.com/babylonlabs-io/babylon/pull/376) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add fuzz test for epoch finalization/confirmation [\#375](https://github.com/babylonlabs-io/babylon/pull/375) ([KonradStaniec](https://github.com/KonradStaniec)) -## [v0.6.0rc0](https://github.com/babylonchain/babylon/tree/v0.6.0rc0) (2023-05-04) +## [v0.6.0rc0](https://github.com/babylonlabs-io/babylon/tree/v0.6.0rc0) (2023-05-04) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.6.0-rc0...v0.6.0rc0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.6.0-rc0...v0.6.0rc0) -## [v0.6.0-rc0](https://github.com/babylonchain/babylon/tree/v0.6.0-rc0) (2023-05-04) +## [v0.6.0-rc0](https://github.com/babylonlabs-io/babylon/tree/v0.6.0-rc0) (2023-05-04) -[Full Changelog](https://github.com/babylonchain/babylon/compare/devnet...v0.6.0-rc0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/devnet...v0.6.0-rc0) **Merged pull requests:** -- use tagged branch in test contract [\#374](https://github.com/babylonchain/babylon/pull/374) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Reduce default number of tests from 100 to 10 [\#373](https://github.com/babylonchain/babylon/pull/373) ([vitsalis](https://github.com/vitsalis)) -- feat: new rpc RawCheckpoints [\#372](https://github.com/babylonchain/babylon/pull/372) ([gusin13](https://github.com/gusin13)) -- chore: circleci: Use image with go 1.20.3 installed [\#371](https://github.com/babylonchain/babylon/pull/371) ([vitsalis](https://github.com/vitsalis)) -- Improve btccheckpointinfo rpc [\#370](https://github.com/babylonchain/babylon/pull/370) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: Add support for multiple chain ids in EpochChainsInfo API [\#369](https://github.com/babylonchain/babylon/pull/369) ([gusin13](https://github.com/gusin13)) -- Fix bug in submission btc info [\#367](https://github.com/babylonchain/babylon/pull/367) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Bump Cosmos SDK to v0.47.2 and minor bug fix [\#366](https://github.com/babylonchain/babylon/pull/366) ([vitsalis](https://github.com/vitsalis)) -- feat: support multiple chain ids in FinalizedChainsInfo [\#365](https://github.com/babylonchain/babylon/pull/365) ([gusin13](https://github.com/gusin13)) -- chore: Update runc and docker dependencies due to security alerts [\#364](https://github.com/babylonchain/babylon/pull/364) ([vitsalis](https://github.com/vitsalis)) -- chore: Replace deprecated `rand.Seed` with dedicated datagen random generators [\#363](https://github.com/babylonchain/babylon/pull/363) ([vitsalis](https://github.com/vitsalis)) -- feat: support multiple chain ids in zoneconcierge chains info api [\#362](https://github.com/babylonchain/babylon/pull/362) ([gusin13](https://github.com/gusin13)) -- Add last block height to finalized epoch info [\#361](https://github.com/babylonchain/babylon/pull/361) ([KonradStaniec](https://github.com/KonradStaniec)) -- Version bumps [\#358](https://github.com/babylonchain/babylon/pull/358) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: Make testnet command produce addresses bound to the host IP [\#357](https://github.com/babylonchain/babylon/pull/357) ([vitsalis](https://github.com/vitsalis)) -- Move checkpoint tag to params [\#356](https://github.com/babylonchain/babylon/pull/356) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Use more descriptive error message for using wrapped transactions [\#355](https://github.com/babylonchain/babylon/pull/355) ([vitsalis](https://github.com/vitsalis)) -- chore: Enable building docker image with unpushed changes [\#354](https://github.com/babylonchain/babylon/pull/354) ([vitsalis](https://github.com/vitsalis)) -- Handle btc related wasm queries [\#353](https://github.com/babylonchain/babylon/pull/353) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: fix query height in `ProveEpochSealed` [\#352](https://github.com/babylonchain/babylon/pull/352) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: fixing the bug in generating proof of sealed epoch [\#351](https://github.com/babylonchain/babylon/pull/351) ([SebastianElvis](https://github.com/SebastianElvis)) -- testnet: Add flag for time between blocks [\#134](https://github.com/babylonchain/babylon/pull/134) ([vitsalis](https://github.com/vitsalis)) - -## [devnet](https://github.com/babylonchain/babylon/tree/devnet) (2023-04-17) - -[Full Changelog](https://github.com/babylonchain/babylon/compare/test...devnet) +- use tagged branch in test contract [\#374](https://github.com/babylonlabs-io/babylon/pull/374) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Reduce default number of tests from 100 to 10 [\#373](https://github.com/babylonlabs-io/babylon/pull/373) ([vitsalis](https://github.com/vitsalis)) +- feat: new rpc RawCheckpoints [\#372](https://github.com/babylonlabs-io/babylon/pull/372) ([gusin13](https://github.com/gusin13)) +- chore: circleci: Use image with go 1.20.3 installed [\#371](https://github.com/babylonlabs-io/babylon/pull/371) ([vitsalis](https://github.com/vitsalis)) +- Improve btccheckpointinfo rpc [\#370](https://github.com/babylonlabs-io/babylon/pull/370) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add support for multiple chain ids in EpochChainsInfo API [\#369](https://github.com/babylonlabs-io/babylon/pull/369) ([gusin13](https://github.com/gusin13)) +- Fix bug in submission btc info [\#367](https://github.com/babylonlabs-io/babylon/pull/367) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Bump Cosmos SDK to v0.47.2 and minor bug fix [\#366](https://github.com/babylonlabs-io/babylon/pull/366) ([vitsalis](https://github.com/vitsalis)) +- feat: support multiple chain ids in FinalizedChainsInfo [\#365](https://github.com/babylonlabs-io/babylon/pull/365) ([gusin13](https://github.com/gusin13)) +- chore: Update runc and docker dependencies due to security alerts [\#364](https://github.com/babylonlabs-io/babylon/pull/364) ([vitsalis](https://github.com/vitsalis)) +- chore: Replace deprecated `rand.Seed` with dedicated datagen random generators [\#363](https://github.com/babylonlabs-io/babylon/pull/363) ([vitsalis](https://github.com/vitsalis)) +- feat: support multiple chain ids in zoneconcierge chains info api [\#362](https://github.com/babylonlabs-io/babylon/pull/362) ([gusin13](https://github.com/gusin13)) +- Add last block height to finalized epoch info [\#361](https://github.com/babylonlabs-io/babylon/pull/361) ([KonradStaniec](https://github.com/KonradStaniec)) +- Version bumps [\#358](https://github.com/babylonlabs-io/babylon/pull/358) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Make testnet command produce addresses bound to the host IP [\#357](https://github.com/babylonlabs-io/babylon/pull/357) ([vitsalis](https://github.com/vitsalis)) +- Move checkpoint tag to params [\#356](https://github.com/babylonlabs-io/babylon/pull/356) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Use more descriptive error message for using wrapped transactions [\#355](https://github.com/babylonlabs-io/babylon/pull/355) ([vitsalis](https://github.com/vitsalis)) +- chore: Enable building docker image with unpushed changes [\#354](https://github.com/babylonlabs-io/babylon/pull/354) ([vitsalis](https://github.com/vitsalis)) +- Handle btc related wasm queries [\#353](https://github.com/babylonlabs-io/babylon/pull/353) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: fix query height in `ProveEpochSealed` [\#352](https://github.com/babylonlabs-io/babylon/pull/352) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: fixing the bug in generating proof of sealed epoch [\#351](https://github.com/babylonlabs-io/babylon/pull/351) ([SebastianElvis](https://github.com/SebastianElvis)) +- testnet: Add flag for time between blocks [\#134](https://github.com/babylonlabs-io/babylon/pull/134) ([vitsalis](https://github.com/vitsalis)) + +## [devnet](https://github.com/babylonlabs-io/babylon/tree/devnet) (2023-04-17) + +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/test...devnet) **Breaking changes:** -- fix gas cost of insert header [\#309](https://github.com/babylonchain/babylon/pull/309) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix gas cost of insert header [\#309](https://github.com/babylonlabs-io/babylon/pull/309) ([KonradStaniec](https://github.com/KonradStaniec)) **Closed issues:** -- Remove `handler.go` from modules [\#336](https://github.com/babylonchain/babylon/issues/336) +- Remove `handler.go` from modules [\#336](https://github.com/babylonlabs-io/babylon/issues/336) **Merged pull requests:** -- Add support for querying for latest finalized epoch [\#350](https://github.com/babylonchain/babylon/pull/350) ([KonradStaniec](https://github.com/KonradStaniec)) -- Use block gas limit when defining genesis [\#349](https://github.com/babylonchain/babylon/pull/349) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: Use the account specified in app.toml to sign BLS transactions [\#348](https://github.com/babylonchain/babylon/pull/348) ([vitsalis](https://github.com/vitsalis)) -- Custom bindings for smart contracts [\#347](https://github.com/babylonchain/babylon/pull/347) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: Make e2e tests work with new docker image [\#345](https://github.com/babylonchain/babylon/pull/345) ([vitsalis](https://github.com/vitsalis)) -- Migrate epoching and btccheckpointing module to new way of handling params [\#344](https://github.com/babylonchain/babylon/pull/344) ([KonradStaniec](https://github.com/KonradStaniec)) -- Feature/lint proto ci [\#343](https://github.com/babylonchain/babylon/pull/343) ([KonradStaniec](https://github.com/KonradStaniec)) -- Re-enable e2e tests [\#342](https://github.com/babylonchain/babylon/pull/342) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Parallelize CircleCI lint build [\#341](https://github.com/babylonchain/babylon/pull/341) ([vitsalis](https://github.com/vitsalis)) -- docker: Refactor to a lightweight unified image [\#340](https://github.com/babylonchain/babylon/pull/340) ([danbryan](https://github.com/danbryan)) -- chore: set up OpenAPI [\#339](https://github.com/babylonchain/babylon/pull/339) ([fadeev](https://github.com/fadeev)) -- refactor: remove `handler.go` files from modules [\#337](https://github.com/babylonchain/babylon/pull/337) ([fadeev](https://github.com/fadeev)) -- Cleanup params in Babylon custom modules. [\#334](https://github.com/babylonchain/babylon/pull/334) ([KonradStaniec](https://github.com/KonradStaniec)) -- zoneconcierge: moving extended client keeper to Babylon repo [\#333](https://github.com/babylonchain/babylon/pull/333) ([SebastianElvis](https://github.com/SebastianElvis)) -- Use new version for our fork of ibc go [\#332](https://github.com/babylonchain/babylon/pull/332) ([KonradStaniec](https://github.com/KonradStaniec)) -- proto: fix proto-linter comments for epoching/zoneconcierge [\#331](https://github.com/babylonchain/babylon/pull/331) ([SebastianElvis](https://github.com/SebastianElvis)) -- Fix proto linter comments in btccheckpoint and monitor [\#330](https://github.com/babylonchain/babylon/pull/330) ([KonradStaniec](https://github.com/KonradStaniec)) -- proto-lint: Add comments to btclightclient and checkpointing proto files [\#329](https://github.com/babylonchain/babylon/pull/329) ([vitsalis](https://github.com/vitsalis)) -- CI: Build and push Docker image to ECR [\#328](https://github.com/babylonchain/babylon/pull/328) ([filippos47](https://github.com/filippos47)) -- Bump cosmos-sdk to stable version [\#327](https://github.com/babylonchain/babylon/pull/327) ([KonradStaniec](https://github.com/KonradStaniec)) -- Integrate wasmd [\#324](https://github.com/babylonchain/babylon/pull/324) ([KonradStaniec](https://github.com/KonradStaniec)) -- Migrate to comet bft [\#323](https://github.com/babylonchain/babylon/pull/323) ([KonradStaniec](https://github.com/KonradStaniec)) -- Update protobuf generation [\#322](https://github.com/babylonchain/babylon/pull/322) ([KonradStaniec](https://github.com/KonradStaniec)) -- Use cosmos v47 [\#320](https://github.com/babylonchain/babylon/pull/320) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Add balance check before inserting MsgWrappedCreateValidator into the epoch message queue [\#318](https://github.com/babylonchain/babylon/pull/318) ([gitferry](https://github.com/gitferry)) -- checkpointing: stateless checks on `MsgCreateValidator` [\#316](https://github.com/babylonchain/babylon/pull/316) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Add fuzz test of addBlsSig [\#313](https://github.com/babylonchain/babylon/pull/313) ([gitferry](https://github.com/gitferry)) -- btccheckpoint: Add information about transactions to BTCCheckpointInfo [\#312](https://github.com/babylonchain/babylon/pull/312) ([vitsalis](https://github.com/vitsalis)) -- chore: Keep a single encoding config in the application [\#308](https://github.com/babylonchain/babylon/pull/308) ([gitferry](https://github.com/gitferry)) -- feat: Checkpointing/Add fee estimation in sending BLS-sig tx [\#307](https://github.com/babylonchain/babylon/pull/307) ([gitferry](https://github.com/gitferry)) -- prepare-genesis cmd: Add flags related to inflation [\#306](https://github.com/babylonchain/babylon/pull/306) ([vitsalis](https://github.com/vitsalis)) -- fix: remove `start_epoch` and `end_epoch` parameters in APIs [\#305](https://github.com/babylonchain/babylon/pull/305) ([SebastianElvis](https://github.com/SebastianElvis)) -- Fix whitespace for Make 4.3 [\#303](https://github.com/babylonchain/babylon/pull/303) ([freshe4qa](https://github.com/freshe4qa)) - -## [test](https://github.com/babylonchain/babylon/tree/test) (2023-03-17) - -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.5.0...test) +- Add support for querying for latest finalized epoch [\#350](https://github.com/babylonlabs-io/babylon/pull/350) ([KonradStaniec](https://github.com/KonradStaniec)) +- Use block gas limit when defining genesis [\#349](https://github.com/babylonlabs-io/babylon/pull/349) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Use the account specified in app.toml to sign BLS transactions [\#348](https://github.com/babylonlabs-io/babylon/pull/348) ([vitsalis](https://github.com/vitsalis)) +- Custom bindings for smart contracts [\#347](https://github.com/babylonlabs-io/babylon/pull/347) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: Make e2e tests work with new docker image [\#345](https://github.com/babylonlabs-io/babylon/pull/345) ([vitsalis](https://github.com/vitsalis)) +- Migrate epoching and btccheckpointing module to new way of handling params [\#344](https://github.com/babylonlabs-io/babylon/pull/344) ([KonradStaniec](https://github.com/KonradStaniec)) +- Feature/lint proto ci [\#343](https://github.com/babylonlabs-io/babylon/pull/343) ([KonradStaniec](https://github.com/KonradStaniec)) +- Re-enable e2e tests [\#342](https://github.com/babylonlabs-io/babylon/pull/342) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Parallelize CircleCI lint build [\#341](https://github.com/babylonlabs-io/babylon/pull/341) ([vitsalis](https://github.com/vitsalis)) +- docker: Refactor to a lightweight unified image [\#340](https://github.com/babylonlabs-io/babylon/pull/340) ([danbryan](https://github.com/danbryan)) +- chore: set up OpenAPI [\#339](https://github.com/babylonlabs-io/babylon/pull/339) ([fadeev](https://github.com/fadeev)) +- refactor: remove `handler.go` files from modules [\#337](https://github.com/babylonlabs-io/babylon/pull/337) ([fadeev](https://github.com/fadeev)) +- Cleanup params in Babylon custom modules. [\#334](https://github.com/babylonlabs-io/babylon/pull/334) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: moving extended client keeper to Babylon repo [\#333](https://github.com/babylonlabs-io/babylon/pull/333) ([SebastianElvis](https://github.com/SebastianElvis)) +- Use new version for our fork of ibc go [\#332](https://github.com/babylonlabs-io/babylon/pull/332) ([KonradStaniec](https://github.com/KonradStaniec)) +- proto: fix proto-linter comments for epoching/zoneconcierge [\#331](https://github.com/babylonlabs-io/babylon/pull/331) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix proto linter comments in btccheckpoint and monitor [\#330](https://github.com/babylonlabs-io/babylon/pull/330) ([KonradStaniec](https://github.com/KonradStaniec)) +- proto-lint: Add comments to btclightclient and checkpointing proto files [\#329](https://github.com/babylonlabs-io/babylon/pull/329) ([vitsalis](https://github.com/vitsalis)) +- CI: Build and push Docker image to ECR [\#328](https://github.com/babylonlabs-io/babylon/pull/328) ([filippos47](https://github.com/filippos47)) +- Bump cosmos-sdk to stable version [\#327](https://github.com/babylonlabs-io/babylon/pull/327) ([KonradStaniec](https://github.com/KonradStaniec)) +- Integrate wasmd [\#324](https://github.com/babylonlabs-io/babylon/pull/324) ([KonradStaniec](https://github.com/KonradStaniec)) +- Migrate to comet bft [\#323](https://github.com/babylonlabs-io/babylon/pull/323) ([KonradStaniec](https://github.com/KonradStaniec)) +- Update protobuf generation [\#322](https://github.com/babylonlabs-io/babylon/pull/322) ([KonradStaniec](https://github.com/KonradStaniec)) +- Use cosmos v47 [\#320](https://github.com/babylonlabs-io/babylon/pull/320) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Add balance check before inserting MsgWrappedCreateValidator into the epoch message queue [\#318](https://github.com/babylonlabs-io/babylon/pull/318) ([gitferry](https://github.com/gitferry)) +- checkpointing: stateless checks on `MsgCreateValidator` [\#316](https://github.com/babylonlabs-io/babylon/pull/316) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Add fuzz test of addBlsSig [\#313](https://github.com/babylonlabs-io/babylon/pull/313) ([gitferry](https://github.com/gitferry)) +- btccheckpoint: Add information about transactions to BTCCheckpointInfo [\#312](https://github.com/babylonlabs-io/babylon/pull/312) ([vitsalis](https://github.com/vitsalis)) +- chore: Keep a single encoding config in the application [\#308](https://github.com/babylonlabs-io/babylon/pull/308) ([gitferry](https://github.com/gitferry)) +- feat: Checkpointing/Add fee estimation in sending BLS-sig tx [\#307](https://github.com/babylonlabs-io/babylon/pull/307) ([gitferry](https://github.com/gitferry)) +- prepare-genesis cmd: Add flags related to inflation [\#306](https://github.com/babylonlabs-io/babylon/pull/306) ([vitsalis](https://github.com/vitsalis)) +- fix: remove `start_epoch` and `end_epoch` parameters in APIs [\#305](https://github.com/babylonlabs-io/babylon/pull/305) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix whitespace for Make 4.3 [\#303](https://github.com/babylonlabs-io/babylon/pull/303) ([freshe4qa](https://github.com/freshe4qa)) + +## [test](https://github.com/babylonlabs-io/babylon/tree/test) (2023-03-17) + +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.5.0...test) **Implemented enhancements:** -- Fees as a parameter for the BlsSig transaction [\#168](https://github.com/babylonchain/babylon/issues/168) +- Fees as a parameter for the BlsSig transaction [\#168](https://github.com/babylonlabs-io/babylon/issues/168) **Fixed bugs:** -- flaky Test: `TestRawCheckpointWithMeta_Accumulate4` [\#124](https://github.com/babylonchain/babylon/issues/124) +- flaky Test: `TestRawCheckpointWithMeta_Accumulate4` [\#124](https://github.com/babylonlabs-io/babylon/issues/124) **Closed issues:** -- Use proto linter and formatter [\#321](https://github.com/babylonchain/babylon/issues/321) -- Lack of balance check before inserting MsgWrappedCreateValidator into the message queue [\#317](https://github.com/babylonchain/babylon/issues/317) -- Duplicate txs queued in the same epoch show inconsistent execution result [\#314](https://github.com/babylonchain/babylon/issues/314) -- Redundant pagination parameters in API [\#304](https://github.com/babylonchain/babylon/issues/304) -- Chain died on block 621 [\#302](https://github.com/babylonchain/babylon/issues/302) -- Add test for adding a BLS-sig transaction [\#279](https://github.com/babylonchain/babylon/issues/279) -- Add logs to show the submitter of each BLS-sig transaction [\#278](https://github.com/babylonchain/babylon/issues/278) -- zoneconcierge: API for querying submitted/confirmed chain info [\#212](https://github.com/babylonchain/babylon/issues/212) -- Validators should stop submitting BLS-sigs when they are syncing [\#182](https://github.com/babylonchain/babylon/issues/182) -- Accept encoding config in `InitPrivSigner` function instead of creating it. [\#174](https://github.com/babylonchain/babylon/issues/174) -- Improving Undelegating Requests and Lifecycle [\#159](https://github.com/babylonchain/babylon/issues/159) +- Use proto linter and formatter [\#321](https://github.com/babylonlabs-io/babylon/issues/321) +- Lack of balance check before inserting MsgWrappedCreateValidator into the message queue [\#317](https://github.com/babylonlabs-io/babylon/issues/317) +- Duplicate txs queued in the same epoch show inconsistent execution result [\#314](https://github.com/babylonlabs-io/babylon/issues/314) +- Redundant pagination parameters in API [\#304](https://github.com/babylonlabs-io/babylon/issues/304) +- Chain died on block 621 [\#302](https://github.com/babylonlabs-io/babylon/issues/302) +- Add test for adding a BLS-sig transaction [\#279](https://github.com/babylonlabs-io/babylon/issues/279) +- Add logs to show the submitter of each BLS-sig transaction [\#278](https://github.com/babylonlabs-io/babylon/issues/278) +- zoneconcierge: API for querying submitted/confirmed chain info [\#212](https://github.com/babylonlabs-io/babylon/issues/212) +- Validators should stop submitting BLS-sigs when they are syncing [\#182](https://github.com/babylonlabs-io/babylon/issues/182) +- Accept encoding config in `InitPrivSigner` function instead of creating it. [\#174](https://github.com/babylonlabs-io/babylon/issues/174) +- Improving Undelegating Requests and Lifecycle [\#159](https://github.com/babylonlabs-io/babylon/issues/159) -## [v0.5.0](https://github.com/babylonchain/babylon/tree/v0.5.0) (2023-02-03) +## [v0.5.0](https://github.com/babylonlabs-io/babylon/tree/v0.5.0) (2023-02-03) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.4.0...v0.5.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.4.0...v0.5.0) **Breaking changes:** -- Improve btc checkpoint data model [\#284](https://github.com/babylonchain/babylon/pull/284) ([KonradStaniec](https://github.com/KonradStaniec)) +- Improve btc checkpoint data model [\#284](https://github.com/babylonlabs-io/babylon/pull/284) ([KonradStaniec](https://github.com/KonradStaniec)) **Fixed bugs:** -- Fix vulnerability when processing bls sig transactions [\#287](https://github.com/babylonchain/babylon/pull/287) ([KonradStaniec](https://github.com/KonradStaniec)) +- Fix vulnerability when processing bls sig transactions [\#287](https://github.com/babylonlabs-io/babylon/pull/287) ([KonradStaniec](https://github.com/KonradStaniec)) **Closed issues:** -- Error results in RawCheckpointList [\#280](https://github.com/babylonchain/babylon/issues/280) -- Creating a validator after the chain has been running for a while leads to the validator never becoming bonded. [\#275](https://github.com/babylonchain/babylon/issues/275) -- Flaky zoneconcierge test [\#251](https://github.com/babylonchain/babylon/issues/251) -- go 1.19 [\#227](https://github.com/babylonchain/babylon/issues/227) +- Error results in RawCheckpointList [\#280](https://github.com/babylonlabs-io/babylon/issues/280) +- Creating a validator after the chain has been running for a while leads to the validator never becoming bonded. [\#275](https://github.com/babylonlabs-io/babylon/issues/275) +- Flaky zoneconcierge test [\#251](https://github.com/babylonlabs-io/babylon/issues/251) +- go 1.19 [\#227](https://github.com/babylonlabs-io/babylon/issues/227) **Merged pull requests:** -- Release v0.5.0 [\#301](https://github.com/babylonchain/babylon/pull/301) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge API: pagtinating chain IDs API [\#300](https://github.com/babylonchain/babylon/pull/300) ([SebastianElvis](https://github.com/SebastianElvis)) -- Fix: Monitor/fix reported checkpoint BTC height query bugs [\#299](https://github.com/babylonchain/babylon/pull/299) ([gitferry](https://github.com/gitferry)) -- Add Apache 2.0 licence [\#298](https://github.com/babylonchain/babylon/pull/298) ([vitsalis](https://github.com/vitsalis)) -- Clean and split up README [\#297](https://github.com/babylonchain/babylon/pull/297) ([vitsalis](https://github.com/vitsalis)) -- fix: add BLST\_PORTABLE flag before build instruction [\#295](https://github.com/babylonchain/babylon/pull/295) ([vitsalis](https://github.com/vitsalis)) -- btccheckpoint API: enriching existing APIs with `BTCCheckpointInfo` [\#294](https://github.com/babylonchain/babylon/pull/294) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Remove checkpointing spec [\#293](https://github.com/babylonchain/babylon/pull/293) ([gitferry](https://github.com/gitferry)) -- API: add parameters to range queries and improve outputs [\#292](https://github.com/babylonchain/babylon/pull/292) ([SebastianElvis](https://github.com/SebastianElvis)) -- btccheckpoint API: range query for BTC checkpoints [\#291](https://github.com/babylonchain/babylon/pull/291) ([SebastianElvis](https://github.com/SebastianElvis)) -- btccheckpoint API: add hash to `BtcCheckpointHeightAndHash` API [\#290](https://github.com/babylonchain/babylon/pull/290) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: range query for epochs [\#289](https://github.com/babylonchain/babylon/pull/289) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Monitor/Add new KV and query for checkpoint reported btc height [\#286](https://github.com/babylonchain/babylon/pull/286) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: proper initialisation for chain info [\#285](https://github.com/babylonchain/babylon/pull/285) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: API/Fix checkpoint list total error [\#283](https://github.com/babylonchain/babylon/pull/283) ([gitferry](https://github.com/gitferry)) -- fix: Fix pagination error of RawCheckpointList [\#282](https://github.com/babylonchain/babylon/pull/282) ([gitferry](https://github.com/gitferry)) -- Bump btcd versions to fix 2 consensus issues [\#281](https://github.com/babylonchain/babylon/pull/281) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: add HTTP URL for LastCheckpointWithStatusRequest [\#277](https://github.com/babylonchain/babylon/pull/277) ([gitferry](https://github.com/gitferry)) -- epoching/checkpointing: fuzz test for validators with zero voting power [\#276](https://github.com/babylonchain/babylon/pull/276) ([SebastianElvis](https://github.com/SebastianElvis)) -- Add simple monitor module [\#274](https://github.com/babylonchain/babylon/pull/274) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: checkpointing: Do not make the `home` flag a required one and unmarshall PubKey \(\#271\) [\#271](https://github.com/babylonchain/babylon/pull/271) ([vitsalis](https://github.com/vitsalis)) -- Fix: Increase gas in e2e test [\#270](https://github.com/babylonchain/babylon/pull/270) ([KonradStaniec](https://github.com/KonradStaniec)) -- Add integration test for zoneconcierge checkpointing [\#269](https://github.com/babylonchain/babylon/pull/269) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: refactor `FinalizedChainInfo` API [\#268](https://github.com/babylonchain/babylon/pull/268) ([SebastianElvis](https://github.com/SebastianElvis)) -- checkpointing API: add checkpoint lifecycle in `RawCheckpointWithMeta` [\#267](https://github.com/babylonchain/babylon/pull/267) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge API: find header and fork headers at a given height [\#266](https://github.com/babylonchain/babylon/pull/266) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge API: find the BTC-finalised chain info before specific CZ height [\#264](https://github.com/babylonchain/babylon/pull/264) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge API: adding total number of timestamped headers to chainInfo [\#263](https://github.com/babylonchain/babylon/pull/263) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: API for querying headers in a given epoch [\#261](https://github.com/babylonchain/babylon/pull/261) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: API for querying the chain info of a given epoch [\#260](https://github.com/babylonchain/babylon/pull/260) ([SebastianElvis](https://github.com/SebastianElvis)) -- add e2e test to CI [\#259](https://github.com/babylonchain/babylon/pull/259) ([KonradStaniec](https://github.com/KonradStaniec)) -- Bump golang to 1.19 [\#257](https://github.com/babylonchain/babylon/pull/257) ([KonradStaniec](https://github.com/KonradStaniec)) -- zoneconcierge: fix flaky test `FuzzProofEpochSealed_BLSSig` [\#256](https://github.com/babylonchain/babylon/pull/256) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: ignore out-of-order headers in ZoneConcierge [\#255](https://github.com/babylonchain/babylon/pull/255) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: API for listing the last checkpointed headers [\#254](https://github.com/babylonchain/babylon/pull/254) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add new query for the last checkpoint with a given status [\#253](https://github.com/babylonchain/babylon/pull/253) ([gitferry](https://github.com/gitferry)) - -## [v0.4.0](https://github.com/babylonchain/babylon/tree/v0.4.0) (2022-12-20) - -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.3.0...v0.4.0) +- Release v0.5.0 [\#301](https://github.com/babylonlabs-io/babylon/pull/301) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge API: pagtinating chain IDs API [\#300](https://github.com/babylonlabs-io/babylon/pull/300) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix: Monitor/fix reported checkpoint BTC height query bugs [\#299](https://github.com/babylonlabs-io/babylon/pull/299) ([gitferry](https://github.com/gitferry)) +- Add Apache 2.0 licence [\#298](https://github.com/babylonlabs-io/babylon/pull/298) ([vitsalis](https://github.com/vitsalis)) +- Clean and split up README [\#297](https://github.com/babylonlabs-io/babylon/pull/297) ([vitsalis](https://github.com/vitsalis)) +- fix: add BLST\_PORTABLE flag before build instruction [\#295](https://github.com/babylonlabs-io/babylon/pull/295) ([vitsalis](https://github.com/vitsalis)) +- btccheckpoint API: enriching existing APIs with `BTCCheckpointInfo` [\#294](https://github.com/babylonlabs-io/babylon/pull/294) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Remove checkpointing spec [\#293](https://github.com/babylonlabs-io/babylon/pull/293) ([gitferry](https://github.com/gitferry)) +- API: add parameters to range queries and improve outputs [\#292](https://github.com/babylonlabs-io/babylon/pull/292) ([SebastianElvis](https://github.com/SebastianElvis)) +- btccheckpoint API: range query for BTC checkpoints [\#291](https://github.com/babylonlabs-io/babylon/pull/291) ([SebastianElvis](https://github.com/SebastianElvis)) +- btccheckpoint API: add hash to `BtcCheckpointHeightAndHash` API [\#290](https://github.com/babylonlabs-io/babylon/pull/290) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: range query for epochs [\#289](https://github.com/babylonlabs-io/babylon/pull/289) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Monitor/Add new KV and query for checkpoint reported btc height [\#286](https://github.com/babylonlabs-io/babylon/pull/286) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proper initialisation for chain info [\#285](https://github.com/babylonlabs-io/babylon/pull/285) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: API/Fix checkpoint list total error [\#283](https://github.com/babylonlabs-io/babylon/pull/283) ([gitferry](https://github.com/gitferry)) +- fix: Fix pagination error of RawCheckpointList [\#282](https://github.com/babylonlabs-io/babylon/pull/282) ([gitferry](https://github.com/gitferry)) +- Bump btcd versions to fix 2 consensus issues [\#281](https://github.com/babylonlabs-io/babylon/pull/281) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: add HTTP URL for LastCheckpointWithStatusRequest [\#277](https://github.com/babylonlabs-io/babylon/pull/277) ([gitferry](https://github.com/gitferry)) +- epoching/checkpointing: fuzz test for validators with zero voting power [\#276](https://github.com/babylonlabs-io/babylon/pull/276) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add simple monitor module [\#274](https://github.com/babylonlabs-io/babylon/pull/274) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: checkpointing: Do not make the `home` flag a required one and unmarshall PubKey \(\#271\) [\#271](https://github.com/babylonlabs-io/babylon/pull/271) ([vitsalis](https://github.com/vitsalis)) +- Fix: Increase gas in e2e test [\#270](https://github.com/babylonlabs-io/babylon/pull/270) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add integration test for zoneconcierge checkpointing [\#269](https://github.com/babylonlabs-io/babylon/pull/269) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: refactor `FinalizedChainInfo` API [\#268](https://github.com/babylonlabs-io/babylon/pull/268) ([SebastianElvis](https://github.com/SebastianElvis)) +- checkpointing API: add checkpoint lifecycle in `RawCheckpointWithMeta` [\#267](https://github.com/babylonlabs-io/babylon/pull/267) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: find header and fork headers at a given height [\#266](https://github.com/babylonlabs-io/babylon/pull/266) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: find the BTC-finalised chain info before specific CZ height [\#264](https://github.com/babylonlabs-io/babylon/pull/264) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge API: adding total number of timestamped headers to chainInfo [\#263](https://github.com/babylonlabs-io/babylon/pull/263) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for querying headers in a given epoch [\#261](https://github.com/babylonlabs-io/babylon/pull/261) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for querying the chain info of a given epoch [\#260](https://github.com/babylonlabs-io/babylon/pull/260) ([SebastianElvis](https://github.com/SebastianElvis)) +- add e2e test to CI [\#259](https://github.com/babylonlabs-io/babylon/pull/259) ([KonradStaniec](https://github.com/KonradStaniec)) +- Bump golang to 1.19 [\#257](https://github.com/babylonlabs-io/babylon/pull/257) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: fix flaky test `FuzzProofEpochSealed_BLSSig` [\#256](https://github.com/babylonlabs-io/babylon/pull/256) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: ignore out-of-order headers in ZoneConcierge [\#255](https://github.com/babylonlabs-io/babylon/pull/255) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for listing the last checkpointed headers [\#254](https://github.com/babylonlabs-io/babylon/pull/254) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add new query for the last checkpoint with a given status [\#253](https://github.com/babylonlabs-io/babylon/pull/253) ([gitferry](https://github.com/gitferry)) + +## [v0.4.0](https://github.com/babylonlabs-io/babylon/tree/v0.4.0) (2022-12-20) + +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.3.0...v0.4.0) **Closed issues:** -- epoching: excessive `absent validator` logs during simulation [\#75](https://github.com/babylonchain/babylon/issues/75) +- epoching: excessive `absent validator` logs during simulation [\#75](https://github.com/babylonlabs-io/babylon/issues/75) **Merged pull requests:** -- Release v0.4.0 [\#252](https://github.com/babylonchain/babylon/pull/252) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge: typos and rename filenames [\#250](https://github.com/babylonchain/babylon/pull/250) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Introduce more control over home directory name for localnet [\#249](https://github.com/babylonchain/babylon/pull/249) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge/epoching: proof that a header is in an epoch [\#248](https://github.com/babylonchain/babylon/pull/248) ([SebastianElvis](https://github.com/SebastianElvis)) -- Add e2e testing framework based on Osmosis [\#247](https://github.com/babylonchain/babylon/pull/247) ([KonradStaniec](https://github.com/KonradStaniec)) -- zoneconcierge: verifier for `ProofEpochSubmitted` [\#246](https://github.com/babylonchain/babylon/pull/246) ([SebastianElvis](https://github.com/SebastianElvis)) -- Add versioning based on Git names for the executable [\#245](https://github.com/babylonchain/babylon/pull/245) ([vitsalis](https://github.com/vitsalis)) -- Fix: Resolve linting errors [\#244](https://github.com/babylonchain/babylon/pull/244) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge: query inclusion proofs and add them to `ProofEpochSealed` [\#243](https://github.com/babylonchain/babylon/pull/243) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add kv for validator BLS key set [\#242](https://github.com/babylonchain/babylon/pull/242) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: verifying BLS multisig in `ProofEpochSealed` [\#241](https://github.com/babylonchain/babylon/pull/241) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Unify bitmap length [\#240](https://github.com/babylonchain/babylon/pull/240) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: enriching `SubmissionData` to store BTCSpvProof [\#239](https://github.com/babylonchain/babylon/pull/239) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Move functionalities from the verifier [\#238](https://github.com/babylonchain/babylon/pull/238) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: proof of a sealed epoch and make proof generation optional [\#237](https://github.com/babylonchain/babylon/pull/237) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: API for querying the validator set of a given epoch [\#236](https://github.com/babylonchain/babylon/pull/236) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add voting power to BLS key set API [\#235](https://github.com/babylonchain/babylon/pull/235) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: proof that a tx is in a block [\#234](https://github.com/babylonchain/babylon/pull/234) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: repurpose heartbeat mechanism to a generic function [\#233](https://github.com/babylonchain/babylon/pull/233) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add bls pubkey set api [\#232](https://github.com/babylonchain/babylon/pull/232) ([gitferry](https://github.com/gitferry)) -- golangci-lint [\#222](https://github.com/babylonchain/babylon/pull/222) ([faddat](https://github.com/faddat)) - -## [v0.3.0](https://github.com/babylonchain/babylon/tree/v0.3.0) (2022-11-30) - -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.2.0...v0.3.0) +- Release v0.4.0 [\#252](https://github.com/babylonlabs-io/babylon/pull/252) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: typos and rename filenames [\#250](https://github.com/babylonlabs-io/babylon/pull/250) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Introduce more control over home directory name for localnet [\#249](https://github.com/babylonlabs-io/babylon/pull/249) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge/epoching: proof that a header is in an epoch [\#248](https://github.com/babylonlabs-io/babylon/pull/248) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add e2e testing framework based on Osmosis [\#247](https://github.com/babylonlabs-io/babylon/pull/247) ([KonradStaniec](https://github.com/KonradStaniec)) +- zoneconcierge: verifier for `ProofEpochSubmitted` [\#246](https://github.com/babylonlabs-io/babylon/pull/246) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add versioning based on Git names for the executable [\#245](https://github.com/babylonlabs-io/babylon/pull/245) ([vitsalis](https://github.com/vitsalis)) +- Fix: Resolve linting errors [\#244](https://github.com/babylonlabs-io/babylon/pull/244) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: query inclusion proofs and add them to `ProofEpochSealed` [\#243](https://github.com/babylonlabs-io/babylon/pull/243) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add kv for validator BLS key set [\#242](https://github.com/babylonlabs-io/babylon/pull/242) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: verifying BLS multisig in `ProofEpochSealed` [\#241](https://github.com/babylonlabs-io/babylon/pull/241) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Unify bitmap length [\#240](https://github.com/babylonlabs-io/babylon/pull/240) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: enriching `SubmissionData` to store BTCSpvProof [\#239](https://github.com/babylonlabs-io/babylon/pull/239) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Move functionalities from the verifier [\#238](https://github.com/babylonlabs-io/babylon/pull/238) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proof of a sealed epoch and make proof generation optional [\#237](https://github.com/babylonlabs-io/babylon/pull/237) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: API for querying the validator set of a given epoch [\#236](https://github.com/babylonlabs-io/babylon/pull/236) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add voting power to BLS key set API [\#235](https://github.com/babylonlabs-io/babylon/pull/235) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: proof that a tx is in a block [\#234](https://github.com/babylonlabs-io/babylon/pull/234) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: repurpose heartbeat mechanism to a generic function [\#233](https://github.com/babylonlabs-io/babylon/pull/233) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add bls pubkey set api [\#232](https://github.com/babylonlabs-io/babylon/pull/232) ([gitferry](https://github.com/gitferry)) +- golangci-lint [\#222](https://github.com/babylonlabs-io/babylon/pull/222) ([faddat](https://github.com/faddat)) + +## [v0.3.0](https://github.com/babylonlabs-io/babylon/tree/v0.3.0) (2022-11-30) + +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.2.0...v0.3.0) **Breaking changes:** -- Submission pruning improvements [\#204](https://github.com/babylonchain/babylon/pull/204) ([KonradStaniec](https://github.com/KonradStaniec)) +- Submission pruning improvements [\#204](https://github.com/babylonlabs-io/babylon/pull/204) ([KonradStaniec](https://github.com/KonradStaniec)) **Closed issues:** -- zoneconcierge: Chain info indexer snapshots the latest chain info for each epoch even without any relayer [\#220](https://github.com/babylonchain/babylon/issues/220) +- zoneconcierge: Chain info indexer snapshots the latest chain info for each epoch even without any relayer [\#220](https://github.com/babylonlabs-io/babylon/issues/220) **Merged pull requests:** -- Release v0.3.0 [\#231](https://github.com/babylonchain/babylon/pull/231) ([vitsalis](https://github.com/vitsalis)) -- doc: update swagger yml file [\#230](https://github.com/babylonchain/babylon/pull/230) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: Update verification rule for btc raw checkpoints [\#229](https://github.com/babylonchain/babylon/pull/229) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: API route [\#228](https://github.com/babylonchain/babylon/pull/228) ([SebastianElvis](https://github.com/SebastianElvis)) -- Bump protogen cosmos [\#226](https://github.com/babylonchain/babylon/pull/226) ([vitsalis](https://github.com/vitsalis)) -- chore: Remove starport references [\#225](https://github.com/babylonchain/babylon/pull/225) ([faddat](https://github.com/faddat)) -- bump ledger and cosmos-proto [\#223](https://github.com/babylonchain/babylon/pull/223) ([faddat](https://github.com/faddat)) -- zoneconcierge: find the earliest epoch that finalised a chain info for the API [\#221](https://github.com/babylonchain/babylon/pull/221) ([SebastianElvis](https://github.com/SebastianElvis)) -- bump deps [\#218](https://github.com/babylonchain/babylon/pull/218) ([faddat](https://github.com/faddat)) -- fix: fixed marshaling issue when enqueueing CreateValidator message and added tests [\#215](https://github.com/babylonchain/babylon/pull/215) ([gitferry](https://github.com/gitferry)) +- Release v0.3.0 [\#231](https://github.com/babylonlabs-io/babylon/pull/231) ([vitsalis](https://github.com/vitsalis)) +- doc: update swagger yml file [\#230](https://github.com/babylonlabs-io/babylon/pull/230) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Update verification rule for btc raw checkpoints [\#229](https://github.com/babylonlabs-io/babylon/pull/229) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: API route [\#228](https://github.com/babylonlabs-io/babylon/pull/228) ([SebastianElvis](https://github.com/SebastianElvis)) +- Bump protogen cosmos [\#226](https://github.com/babylonlabs-io/babylon/pull/226) ([vitsalis](https://github.com/vitsalis)) +- chore: Remove starport references [\#225](https://github.com/babylonlabs-io/babylon/pull/225) ([faddat](https://github.com/faddat)) +- bump ledger and cosmos-proto [\#223](https://github.com/babylonlabs-io/babylon/pull/223) ([faddat](https://github.com/faddat)) +- zoneconcierge: find the earliest epoch that finalised a chain info for the API [\#221](https://github.com/babylonlabs-io/babylon/pull/221) ([SebastianElvis](https://github.com/SebastianElvis)) +- bump deps [\#218](https://github.com/babylonlabs-io/babylon/pull/218) ([faddat](https://github.com/faddat)) +- fix: fixed marshaling issue when enqueueing CreateValidator message and added tests [\#215](https://github.com/babylonlabs-io/babylon/pull/215) ([gitferry](https://github.com/gitferry)) -## [v0.2.0](https://github.com/babylonchain/babylon/tree/v0.2.0) (2022-11-23) +## [v0.2.0](https://github.com/babylonlabs-io/babylon/tree/v0.2.0) (2022-11-23) -[Full Changelog](https://github.com/babylonchain/babylon/compare/v0.1.0...v0.2.0) +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/v0.1.0...v0.2.0) **Fixed bugs:** -- Concurrent issue when sending BLS-sig tx in a gorouting [\#197](https://github.com/babylonchain/babylon/issues/197) +- Concurrent issue when sending BLS-sig tx in a gorouting [\#197](https://github.com/babylonlabs-io/babylon/issues/197) **Closed issues:** -- Make FromName an attribute in app.toml [\#188](https://github.com/babylonchain/babylon/issues/188) -- Add correspondence check for genesis BLS keys and genesis txs [\#180](https://github.com/babylonchain/babylon/issues/180) +- Make FromName an attribute in app.toml [\#188](https://github.com/babylonlabs-io/babylon/issues/188) +- Add correspondence check for genesis BLS keys and genesis txs [\#180](https://github.com/babylonlabs-io/babylon/issues/180) **Merged pull requests:** -- Release v0.2.0 [\#217](https://github.com/babylonchain/babylon/pull/217) ([vitsalis](https://github.com/vitsalis)) -- hotfix: fixing the hook issue in `app.go` [\#213](https://github.com/babylonchain/babylon/pull/213) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: debugging API `ChainInfo` [\#211](https://github.com/babylonchain/babylon/pull/211) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: add checkpoint info and epoch info to `FinalizedChainInfo` API [\#210](https://github.com/babylonchain/babylon/pull/210) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: restrict the used port for IBC [\#209](https://github.com/babylonchain/babylon/pull/209) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: Use better short description for the babylond executable [\#208](https://github.com/babylonchain/babylon/pull/208) ([vitsalis](https://github.com/vitsalis)) -- IBC: bug fixes for creating IBC channels [\#206](https://github.com/babylonchain/babylon/pull/206) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: API for listing all chain IDs [\#205](https://github.com/babylonchain/babylon/pull/205) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: fuzz tests for various indexers [\#203](https://github.com/babylonchain/babylon/pull/203) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: Resolved concurrency issue when sending BLS-sig txs [\#202](https://github.com/babylonchain/babylon/pull/202) ([gitferry](https://github.com/gitferry)) -- zoneconcierge: track latest BTC-finalised header and add the query [\#201](https://github.com/babylonchain/babylon/pull/201) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: subscribe to checkpointing/epoching's hooks, and add a new hooks [\#200](https://github.com/babylonchain/babylon/pull/200) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Add signer key name into app custom config [\#199](https://github.com/babylonchain/babylon/pull/199) ([gitferry](https://github.com/gitferry)) -- feat: Introduce swagger docs for RPC queries [\#198](https://github.com/babylonchain/babylon/pull/198) ([vitsalis](https://github.com/vitsalis)) -- feat: Add genesis time on genesis parameters [\#196](https://github.com/babylonchain/babylon/pull/196) ([vitsalis](https://github.com/vitsalis)) -- zoneconcierge: heartbeat IBC packet to keep relayer awake [\#195](https://github.com/babylonchain/babylon/pull/195) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: test infra for IBC and vanilla tests [\#193](https://github.com/babylonchain/babylon/pull/193) ([SebastianElvis](https://github.com/SebastianElvis)) -- Add changelog [\#192](https://github.com/babylonchain/babylon/pull/192) ([KonradStaniec](https://github.com/KonradStaniec)) -- datagen: add datagen functions for testing reporter [\#190](https://github.com/babylonchain/babylon/pull/190) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: hook onto the light client and index headers/forks [\#189](https://github.com/babylonchain/babylon/pull/189) ([SebastianElvis](https://github.com/SebastianElvis)) -- zoneconcierge: replace IBC-Go with Babylon's fork, and implement DB schemas [\#184](https://github.com/babylonchain/babylon/pull/184) ([SebastianElvis](https://github.com/SebastianElvis)) - -## [v0.1.0](https://github.com/babylonchain/babylon/tree/v0.1.0) (2022-11-05) - -[Full Changelog](https://github.com/babylonchain/babylon/compare/b1645c9eea6511069c0b2ad0328d794018450eac...v0.1.0) +- Release v0.2.0 [\#217](https://github.com/babylonlabs-io/babylon/pull/217) ([vitsalis](https://github.com/vitsalis)) +- hotfix: fixing the hook issue in `app.go` [\#213](https://github.com/babylonlabs-io/babylon/pull/213) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: debugging API `ChainInfo` [\#211](https://github.com/babylonlabs-io/babylon/pull/211) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: add checkpoint info and epoch info to `FinalizedChainInfo` API [\#210](https://github.com/babylonlabs-io/babylon/pull/210) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: restrict the used port for IBC [\#209](https://github.com/babylonlabs-io/babylon/pull/209) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Use better short description for the babylond executable [\#208](https://github.com/babylonlabs-io/babylon/pull/208) ([vitsalis](https://github.com/vitsalis)) +- IBC: bug fixes for creating IBC channels [\#206](https://github.com/babylonlabs-io/babylon/pull/206) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: API for listing all chain IDs [\#205](https://github.com/babylonlabs-io/babylon/pull/205) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: fuzz tests for various indexers [\#203](https://github.com/babylonlabs-io/babylon/pull/203) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Resolved concurrency issue when sending BLS-sig txs [\#202](https://github.com/babylonlabs-io/babylon/pull/202) ([gitferry](https://github.com/gitferry)) +- zoneconcierge: track latest BTC-finalised header and add the query [\#201](https://github.com/babylonlabs-io/babylon/pull/201) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: subscribe to checkpointing/epoching's hooks, and add a new hooks [\#200](https://github.com/babylonlabs-io/babylon/pull/200) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Add signer key name into app custom config [\#199](https://github.com/babylonlabs-io/babylon/pull/199) ([gitferry](https://github.com/gitferry)) +- feat: Introduce swagger docs for RPC queries [\#198](https://github.com/babylonlabs-io/babylon/pull/198) ([vitsalis](https://github.com/vitsalis)) +- feat: Add genesis time on genesis parameters [\#196](https://github.com/babylonlabs-io/babylon/pull/196) ([vitsalis](https://github.com/vitsalis)) +- zoneconcierge: heartbeat IBC packet to keep relayer awake [\#195](https://github.com/babylonlabs-io/babylon/pull/195) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: test infra for IBC and vanilla tests [\#193](https://github.com/babylonlabs-io/babylon/pull/193) ([SebastianElvis](https://github.com/SebastianElvis)) +- Add changelog [\#192](https://github.com/babylonlabs-io/babylon/pull/192) ([KonradStaniec](https://github.com/KonradStaniec)) +- datagen: add datagen functions for testing reporter [\#190](https://github.com/babylonlabs-io/babylon/pull/190) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: hook onto the light client and index headers/forks [\#189](https://github.com/babylonlabs-io/babylon/pull/189) ([SebastianElvis](https://github.com/SebastianElvis)) +- zoneconcierge: replace IBC-Go with Babylon's fork, and implement DB schemas [\#184](https://github.com/babylonlabs-io/babylon/pull/184) ([SebastianElvis](https://github.com/SebastianElvis)) + +## [v0.1.0](https://github.com/babylonlabs-io/babylon/tree/v0.1.0) (2022-11-05) + +[Full Changelog](https://github.com/babylonlabs-io/babylon/compare/b1645c9eea6511069c0b2ad0328d794018450eac...v0.1.0) **Implemented enhancements:** -- Checkpointing: remove hardcoded FlagFee [\#160](https://github.com/babylonchain/babylon/issues/160) -- Proper coin denomination for testnet [\#139](https://github.com/babylonchain/babylon/issues/139) -- chore: bump Cosmos SDK dependency to `v0.46.0` [\#93](https://github.com/babylonchain/babylon/issues/93) -- btclightclient: Store BTCHeaderInfo objects instead of BTCHeaderBytes objects [\#57](https://github.com/babylonchain/babylon/issues/57) +- Checkpointing: remove hardcoded FlagFee [\#160](https://github.com/babylonlabs-io/babylon/issues/160) +- Proper coin denomination for testnet [\#139](https://github.com/babylonlabs-io/babylon/issues/139) +- chore: bump Cosmos SDK dependency to `v0.46.0` [\#93](https://github.com/babylonlabs-io/babylon/issues/93) +- btclightclient: Store BTCHeaderInfo objects instead of BTCHeaderBytes objects [\#57](https://github.com/babylonlabs-io/babylon/issues/57) **Fixed bugs:** -- bug: Transaction submission panics due to unavailability of BTC config [\#117](https://github.com/babylonchain/babylon/issues/117) -- epoching: simulation panicked with error message `panic: no delegation distribution info` [\#74](https://github.com/babylonchain/babylon/issues/74) -- Epoching AnteHandler rejects genesis staking transactions [\#36](https://github.com/babylonchain/babylon/issues/36) -- Fix handling duplicated submissions [\#163](https://github.com/babylonchain/babylon/pull/163) ([KonradStaniec](https://github.com/KonradStaniec)) +- bug: Transaction submission panics due to unavailability of BTC config [\#117](https://github.com/babylonlabs-io/babylon/issues/117) +- epoching: simulation panicked with error message `panic: no delegation distribution info` [\#74](https://github.com/babylonlabs-io/babylon/issues/74) +- Epoching AnteHandler rejects genesis staking transactions [\#36](https://github.com/babylonlabs-io/babylon/issues/36) +- Fix handling duplicated submissions [\#163](https://github.com/babylonlabs-io/babylon/pull/163) ([KonradStaniec](https://github.com/KonradStaniec)) **Closed issues:** -- Improve sending of bls transaction by checkpointing module. [\#155](https://github.com/babylonchain/babylon/issues/155) -- Checkpointing: random BLS-sig transactions are not executed successfully [\#141](https://github.com/babylonchain/babylon/issues/141) -- Fix integration test and blssigner denominations [\#137](https://github.com/babylonchain/babylon/issues/137) -- Errors prompted by the static analyser in `x/btclightclient` [\#9](https://github.com/babylonchain/babylon/issues/9) +- Improve sending of bls transaction by checkpointing module. [\#155](https://github.com/babylonlabs-io/babylon/issues/155) +- Checkpointing: random BLS-sig transactions are not executed successfully [\#141](https://github.com/babylonlabs-io/babylon/issues/141) +- Fix integration test and blssigner denominations [\#137](https://github.com/babylonlabs-io/babylon/issues/137) +- Errors prompted by the static analyser in `x/btclightclient` [\#9](https://github.com/babylonlabs-io/babylon/issues/9) **Merged pull requests:** -- Release v0.1.0 [\#191](https://github.com/babylonchain/babylon/pull/191) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: add validate-genesis cmd [\#187](https://github.com/babylonchain/babylon/pull/187) ([gitferry](https://github.com/gitferry)) -- chore: add correspondence check against gentx when adding genesis BLS keys [\#186](https://github.com/babylonchain/babylon/pull/186) ([gitferry](https://github.com/gitferry)) -- chore: regtest support [\#185](https://github.com/babylonchain/babylon/pull/185) ([SebastianElvis](https://github.com/SebastianElvis)) -- Implement ADR-01 [\#183](https://github.com/babylonchain/babylon/pull/183) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: Upgrade proto generation Docker image and script [\#181](https://github.com/babylonchain/babylon/pull/181) ([vitsalis](https://github.com/vitsalis)) -- Fix accepting submission [\#179](https://github.com/babylonchain/babylon/pull/179) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: add add-genesis-bls cmd [\#178](https://github.com/babylonchain/babylon/pull/178) ([gitferry](https://github.com/gitferry)) -- fix: CI failed after merging \#175 [\#177](https://github.com/babylonchain/babylon/pull/177) ([gitferry](https://github.com/gitferry)) -- ibc: vanilla IBC module [\#176](https://github.com/babylonchain/babylon/pull/176) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: add create-genesis-bls cmd [\#175](https://github.com/babylonchain/babylon/pull/175) ([gitferry](https://github.com/gitferry)) -- Bump cosmos sdk [\#173](https://github.com/babylonchain/babylon/pull/173) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: Add prepare-genesis command [\#172](https://github.com/babylonchain/babylon/pull/172) ([vitsalis](https://github.com/vitsalis)) -- Refactor submission bitcoin status [\#170](https://github.com/babylonchain/babylon/pull/170) ([KonradStaniec](https://github.com/KonradStaniec)) -- Validate btc objects in ante-handler [\#169](https://github.com/babylonchain/babylon/pull/169) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: Use \(u\)bbn bond denominations [\#167](https://github.com/babylonchain/babylon/pull/167) ([vitsalis](https://github.com/vitsalis)) -- feat: checkpointing/improve the sending of BLS-sig tx [\#166](https://github.com/babylonchain/babylon/pull/166) ([gitferry](https://github.com/gitferry)) -- feat: checkpointing/implement WrappedCreateValidator cli [\#165](https://github.com/babylonchain/babylon/pull/165) ([gitferry](https://github.com/gitferry)) -- Move retry module from Vigilante to BBN [\#164](https://github.com/babylonchain/babylon/pull/164) ([gusin13](https://github.com/gusin13)) -- feat: checkpointing/add create-bls-key cli [\#162](https://github.com/babylonchain/babylon/pull/162) ([gitferry](https://github.com/gitferry)) -- chore: checkpointing/refactor validate basic [\#161](https://github.com/babylonchain/babylon/pull/161) ([gitferry](https://github.com/gitferry)) -- Query to get submissions for given epoch [\#158](https://github.com/babylonchain/babylon/pull/158) ([KonradStaniec](https://github.com/KonradStaniec)) -- Functionality for building custom mainnet tags [\#157](https://github.com/babylonchain/babylon/pull/157) ([vitsalis](https://github.com/vitsalis)) -- Improve integration tests [\#156](https://github.com/babylonchain/babylon/pull/156) ([KonradStaniec](https://github.com/KonradStaniec)) -- epoching: fix error of `unexpected validator in unbonding queue` [\#154](https://github.com/babylonchain/babylon/pull/154) ([SebastianElvis](https://github.com/SebastianElvis)) -- Fix ancestry error [\#153](https://github.com/babylonchain/babylon/pull/153) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: fix error msg typo of btccheckpoint [\#151](https://github.com/babylonchain/babylon/pull/151) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching/checkpointing: checkpoint-assisted unbonding [\#150](https://github.com/babylonchain/babylon/pull/150) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: Allow minimum work headers for a testnet/simnet [\#148](https://github.com/babylonchain/babylon/pull/148) ([vitsalis](https://github.com/vitsalis)) -- Add test for checkpoint submissions and state change [\#147](https://github.com/babylonchain/babylon/pull/147) ([KonradStaniec](https://github.com/KonradStaniec)) -- fix: fixed decoder for checkpoint [\#146](https://github.com/babylonchain/babylon/pull/146) ([gitferry](https://github.com/gitferry)) -- epoching: add delegator address to events [\#145](https://github.com/babylonchain/babylon/pull/145) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: checkpointing/add logs for checkpoint status change [\#144](https://github.com/babylonchain/babylon/pull/144) ([gitferry](https://github.com/gitferry)) -- epoching: delegation lifecycle [\#143](https://github.com/babylonchain/babylon/pull/143) ([SebastianElvis](https://github.com/SebastianElvis)) -- Relax tx formatter rules [\#142](https://github.com/babylonchain/babylon/pull/142) ([KonradStaniec](https://github.com/KonradStaniec)) -- epoching: bugfix of `LatestEpochMsgs` API [\#140](https://github.com/babylonchain/babylon/pull/140) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: CLI for delegating/undelegating/redelegating requests [\#138](https://github.com/babylonchain/babylon/pull/138) ([SebastianElvis](https://github.com/SebastianElvis)) -- Revert: testnet: denom of gas price \#133 [\#136](https://github.com/babylonchain/babylon/pull/136) ([vitsalis](https://github.com/vitsalis)) -- bitcoinsim: Remove it from the repository [\#135](https://github.com/babylonchain/babylon/pull/135) ([vitsalis](https://github.com/vitsalis)) -- testnet: denom of gas price [\#133](https://github.com/babylonchain/babylon/pull/133) ([SebastianElvis](https://github.com/SebastianElvis)) -- btclightclient: create temporary method for Contains request with bytes parameter [\#132](https://github.com/babylonchain/babylon/pull/132) ([SebastianElvis](https://github.com/SebastianElvis)) -- btclightclient: Add BaseHeader query [\#130](https://github.com/babylonchain/babylon/pull/130) ([vitsalis](https://github.com/vitsalis)) -- Remove full stack deployment and irrelevant files [\#129](https://github.com/babylonchain/babylon/pull/129) ([vitsalis](https://github.com/vitsalis)) -- testnet: Add CLI args for specifying btccheckpoint and staking genesis params [\#128](https://github.com/babylonchain/babylon/pull/128) ([vitsalis](https://github.com/vitsalis)) -- Add extending btc light client chain in tests [\#127](https://github.com/babylonchain/babylon/pull/127) ([KonradStaniec](https://github.com/KonradStaniec)) -- chore: checkpointing/refactor bls-signer [\#126](https://github.com/babylonchain/babylon/pull/126) ([gitferry](https://github.com/gitferry)) -- fix: Re-introduce localnet start to enable integration tests [\#125](https://github.com/babylonchain/babylon/pull/125) ([vitsalis](https://github.com/vitsalis)) -- docker: Include vigilantes and explorer in the localnet deployment [\#123](https://github.com/babylonchain/babylon/pull/123) ([vitsalis](https://github.com/vitsalis)) -- fix: checkpointing/query epoch status count bug [\#122](https://github.com/babylonchain/babylon/pull/122) ([gitferry](https://github.com/gitferry)) -- Fixes initialisation bug [\#121](https://github.com/babylonchain/babylon/pull/121) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: checkpointing/integrate bls-sig tx into the message flow [\#120](https://github.com/babylonchain/babylon/pull/120) ([gitferry](https://github.com/gitferry)) -- epoching API: add epoch msg range queries and add timestamp to validator lifecycle [\#119](https://github.com/babylonchain/babylon/pull/119) ([SebastianElvis](https://github.com/SebastianElvis)) -- fix: bls-sig accumulating bug and added tests [\#118](https://github.com/babylonchain/babylon/pull/118) ([gitferry](https://github.com/gitferry)) -- epoching API: add timestamp to queued messages [\#116](https://github.com/babylonchain/babylon/pull/116) ([SebastianElvis](https://github.com/SebastianElvis)) -- Parameterize genesis and config through testnet command flags [\#115](https://github.com/babylonchain/babylon/pull/115) ([vitsalis](https://github.com/vitsalis)) -- Add custom query [\#114](https://github.com/babylonchain/babylon/pull/114) ([KonradStaniec](https://github.com/KonradStaniec)) -- btccheckpoint: make kDeep/wDeep as system parameters [\#113](https://github.com/babylonchain/babylon/pull/113) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: checkpointing/add typed events [\#112](https://github.com/babylonchain/babylon/pull/112) ([gitferry](https://github.com/gitferry)) -- feat: checkpointing/ add queries about epoch status [\#111](https://github.com/babylonchain/babylon/pull/111) ([gitferry](https://github.com/gitferry)) -- chore: BLS signer refactor [\#110](https://github.com/babylonchain/babylon/pull/110) ([gitferry](https://github.com/gitferry)) -- epoching API: validator lifecycle [\#109](https://github.com/babylonchain/babylon/pull/109) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: API: epoch\_msgs/{epoch\_num} -\> all events during this epoch [\#108](https://github.com/babylonchain/babylon/pull/108) ([SebastianElvis](https://github.com/SebastianElvis)) -- btcutils: refactor for vigilante [\#107](https://github.com/babylonchain/babylon/pull/107) ([SebastianElvis](https://github.com/SebastianElvis)) -- chore: Replace all instances of bbl with bbn [\#106](https://github.com/babylonchain/babylon/pull/106) ([vitsalis](https://github.com/vitsalis)) -- Add babylon app config [\#105](https://github.com/babylonchain/babylon/pull/105) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: checkpointing/implement BLS signer [\#104](https://github.com/babylonchain/babylon/pull/104) ([gitferry](https://github.com/gitferry)) -- Add parsing correct format in btccheckpoint [\#102](https://github.com/babylonchain/babylon/pull/102) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: add genesis state for checkpointing [\#101](https://github.com/babylonchain/babylon/pull/101) ([gitferry](https://github.com/gitferry)) -- Add fuzz tests to formatter [\#100](https://github.com/babylonchain/babylon/pull/100) ([KonradStaniec](https://github.com/KonradStaniec)) -- Fix: checkpointing/epoch growth bug [\#99](https://github.com/babylonchain/babylon/pull/99) ([gitferry](https://github.com/gitferry)) -- chore: replace bbl with bbn and gitignore [\#98](https://github.com/babylonchain/babylon/pull/98) ([SebastianElvis](https://github.com/SebastianElvis)) -- FIX: checkpointing/changed PoP by signing BLS public key [\#97](https://github.com/babylonchain/babylon/pull/97) ([gitferry](https://github.com/gitferry)) -- Add initial implementation of tx formatter [\#96](https://github.com/babylonchain/babylon/pull/96) ([KonradStaniec](https://github.com/KonradStaniec)) -- BM-102: Single BTC node in docker producing blocks [\#95](https://github.com/babylonchain/babylon/pull/95) ([aakoshh](https://github.com/aakoshh)) -- Add initial test checking progress [\#94](https://github.com/babylonchain/babylon/pull/94) ([KonradStaniec](https://github.com/KonradStaniec)) -- Add tests to ci [\#90](https://github.com/babylonchain/babylon/pull/90) ([KonradStaniec](https://github.com/KonradStaniec)) -- FIX: Add checkpoint query with status [\#89](https://github.com/babylonchain/babylon/pull/89) ([gitferry](https://github.com/gitferry)) -- enable gRPC gateway routes for rest queries [\#88](https://github.com/babylonchain/babylon/pull/88) ([toliujiayi](https://github.com/toliujiayi)) -- Wire app without mocks [\#87](https://github.com/babylonchain/babylon/pull/87) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: implement bls key generation [\#86](https://github.com/babylonchain/babylon/pull/86) ([gitferry](https://github.com/gitferry)) -- Add integration tests [\#85](https://github.com/babylonchain/babylon/pull/85) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: checkpointing/implement checkpoint verification and keeper tests [\#84](https://github.com/babylonchain/babylon/pull/84) ([gitferry](https://github.com/gitferry)) -- Add btccheckpoit unit tests [\#83](https://github.com/babylonchain/babylon/pull/83) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: btclightclient: Add BTCHeaderInserted event [\#82](https://github.com/babylonchain/babylon/pull/82) ([vitsalis](https://github.com/vitsalis)) -- fix: Remove WASM config from application configuration [\#81](https://github.com/babylonchain/babylon/pull/81) ([vitsalis](https://github.com/vitsalis)) -- epoching: smaller epoch interval in simulation [\#80](https://github.com/babylonchain/babylon/pull/80) ([SebastianElvis](https://github.com/SebastianElvis)) -- FIX: Use a caching multistore in delayed staking message handler [\#79](https://github.com/babylonchain/babylon/pull/79) ([aakoshh](https://github.com/aakoshh)) -- feat: checkpointing/implement cli [\#78](https://github.com/babylonchain/babylon/pull/78) ([gitferry](https://github.com/gitferry)) -- fix: Add installation instructions and executable reference [\#77](https://github.com/babylonchain/babylon/pull/77) ([vitsalis](https://github.com/vitsalis)) -- chore: issue templates [\#76](https://github.com/babylonchain/babylon/pull/76) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Register msg server for all modules & instructions for tx submission [\#73](https://github.com/babylonchain/babylon/pull/73) ([vitsalis](https://github.com/vitsalis)) -- feat: btclightclient: Refactor keepers based on needs of btcheckpoint module [\#72](https://github.com/babylonchain/babylon/pull/72) ([vitsalis](https://github.com/vitsalis)) -- simulation: vanilla simulation tests [\#71](https://github.com/babylonchain/babylon/pull/71) ([SebastianElvis](https://github.com/SebastianElvis)) -- Implement core btc handling logic [\#70](https://github.com/babylonchain/babylon/pull/70) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: btclightclient: gRPC query fuzz tests [\#69](https://github.com/babylonchain/babylon/pull/69) ([vitsalis](https://github.com/vitsalis)) -- epoching: simulation infra for integration testing [\#68](https://github.com/babylonchain/babylon/pull/68) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: btclightclient: Add keeper fuzz tests [\#67](https://github.com/babylonchain/babylon/pull/67) ([vitsalis](https://github.com/vitsalis)) -- epoching: fuzz tests on epoched undelegations and redelegations [\#66](https://github.com/babylonchain/babylon/pull/66) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: refactor test infra, mock messages and sample fuzz tests [\#65](https://github.com/babylonchain/babylon/pull/65) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: fuzz tests for slashed validator set [\#64](https://github.com/babylonchain/babylon/pull/64) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: replace deprecated `EmitEvent` APIs with `EmitTypedEvent` ones [\#63](https://github.com/babylonchain/babylon/pull/63) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: btclightclient HeadersState keeper fuzz tests [\#61](https://github.com/babylonchain/babylon/pull/61) ([vitsalis](https://github.com/vitsalis)) -- epoching: more test infra and some fuzz tests on keeper functionalities [\#60](https://github.com/babylonchain/babylon/pull/60) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: checkpointing/aggregate BLS signatures [\#59](https://github.com/babylonchain/babylon/pull/59) ([gitferry](https://github.com/gitferry)) -- feat: btclightclient: Abstract the usage of btcd types and store BTCHeaderInfo objects [\#58](https://github.com/babylonchain/babylon/pull/58) ([vitsalis](https://github.com/vitsalis)) -- feat: Replace BTC types unit tests with fuzz tests [\#56](https://github.com/babylonchain/babylon/pull/56) ([vitsalis](https://github.com/vitsalis)) -- feat: Create datagen testutil for common random generation functions [\#55](https://github.com/babylonchain/babylon/pull/55) ([vitsalis](https://github.com/vitsalis)) -- epoching: wrapper type `Epoch` and simplify code using this type [\#54](https://github.com/babylonchain/babylon/pull/54) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add btclightclient events and hooks [\#53](https://github.com/babylonchain/babylon/pull/53) ([vitsalis](https://github.com/vitsalis)) -- feat: add raw checkpoint creation [\#52](https://github.com/babylonchain/babylon/pull/52) ([gitferry](https://github.com/gitferry)) -- feat: Add accumulattive PoW functionality to btclightclient [\#51](https://github.com/babylonchain/babylon/pull/51) ([vitsalis](https://github.com/vitsalis)) -- btclightclient: Cleanup codebase and add descriptive comments [\#50](https://github.com/babylonchain/babylon/pull/50) ([vitsalis](https://github.com/vitsalis)) -- Update go to 1.18 in README [\#49](https://github.com/babylonchain/babylon/pull/49) ([vitsalis](https://github.com/vitsalis)) -- Upgrade to go 1.18 [\#48](https://github.com/babylonchain/babylon/pull/48) ([vitsalis](https://github.com/vitsalis)) -- feat: define checkpointing registration proto and state [\#46](https://github.com/babylonchain/babylon/pull/46) ([gitferry](https://github.com/gitferry)) -- BM-60: Database schema ER diagram [\#45](https://github.com/babylonchain/babylon/pull/45) ([aakoshh](https://github.com/aakoshh)) -- Revert "feat: CI: Generate a single block in build check " [\#44](https://github.com/babylonchain/babylon/pull/44) ([vitsalis](https://github.com/vitsalis)) -- Btccheckpoint oracle schema and processing [\#43](https://github.com/babylonchain/babylon/pull/43) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: Fuzz and unit tests for btclightclient types [\#42](https://github.com/babylonchain/babylon/pull/42) ([vitsalis](https://github.com/vitsalis)) -- epoching: fix genesis, param and bootstrapping [\#41](https://github.com/babylonchain/babylon/pull/41) ([SebastianElvis](https://github.com/SebastianElvis)) -- feat: Add unit tests for ValidateHeader of btcutils [\#40](https://github.com/babylonchain/babylon/pull/40) ([vitsalis](https://github.com/vitsalis)) -- feat: Add unit tests for BTCHeaderHashBytes and BTCHeaderBytes types [\#39](https://github.com/babylonchain/babylon/pull/39) ([vitsalis](https://github.com/vitsalis)) -- Add building, testing, and testnet instructions on README [\#38](https://github.com/babylonchain/babylon/pull/38) ([vitsalis](https://github.com/vitsalis)) -- feat: CI: Generate a single block in build check [\#37](https://github.com/babylonchain/babylon/pull/37) ([vitsalis](https://github.com/vitsalis)) -- epoching: event and hook upon a certain threshold amount of slashed voting power [\#35](https://github.com/babylonchain/babylon/pull/35) ([SebastianElvis](https://github.com/SebastianElvis)) -- doc: add BLS key registration spec [\#34](https://github.com/babylonchain/babylon/pull/34) ([gitferry](https://github.com/gitferry)) -- feat: add hooks, events, and error types to the checkpointing module [\#33](https://github.com/babylonchain/babylon/pull/33) ([gitferry](https://github.com/gitferry)) -- epoching: state transition upon `BeginBlock` and `EndBlock` [\#32](https://github.com/babylonchain/babylon/pull/32) ([SebastianElvis](https://github.com/SebastianElvis)) -- Handle insert checkpoint [\#31](https://github.com/babylonchain/babylon/pull/31) ([KonradStaniec](https://github.com/KonradStaniec)) -- feat: Add btclightclient chain query [\#30](https://github.com/babylonchain/babylon/pull/30) ([vitsalis](https://github.com/vitsalis)) -- feat: Implement BTCHeaderBytes and BTCHeaderHashBytes types [\#29](https://github.com/babylonchain/babylon/pull/29) ([vitsalis](https://github.com/vitsalis)) -- epoching: copy/paste necessary code from staking/evidence/slashing and make modifications [\#28](https://github.com/babylonchain/babylon/pull/28) ([SebastianElvis](https://github.com/SebastianElvis)) -- checkpointing: add keeper and core state [\#27](https://github.com/babylonchain/babylon/pull/27) ([gitferry](https://github.com/gitferry)) -- FIX: btclightclient: Properly convert the input of contains to bytes [\#26](https://github.com/babylonchain/babylon/pull/26) ([vitsalis](https://github.com/vitsalis)) -- BM-32: Update diagrams for out-of-sequence checkpoint handling [\#25](https://github.com/babylonchain/babylon/pull/25) ([aakoshh](https://github.com/aakoshh)) -- FIX\(localnet\): Redirect babylond stderr to stdout [\#24](https://github.com/babylonchain/babylon/pull/24) ([vitsalis](https://github.com/vitsalis)) -- BM-31: Add CircleCI pipeline for building and testing [\#23](https://github.com/babylonchain/babylon/pull/23) ([vitsalis](https://github.com/vitsalis)) -- FIX: Failing btclightclient tests, remove unneeded ones, clean up [\#22](https://github.com/babylonchain/babylon/pull/22) ([vitsalis](https://github.com/vitsalis)) -- FIX: Replace 'unimplemented' AnteHandler panic with comment [\#21](https://github.com/babylonchain/babylon/pull/21) ([vitsalis](https://github.com/vitsalis)) -- FIX: Implement Msg interface for MsgInsertBTCSpvProof [\#20](https://github.com/babylonchain/babylon/pull/20) ([vitsalis](https://github.com/vitsalis)) -- epoching: keeper functions, queries, and testing infra [\#19](https://github.com/babylonchain/babylon/pull/19) ([SebastianElvis](https://github.com/SebastianElvis)) -- epoching: Wrapped messages and AnteHandler implementation [\#18](https://github.com/babylonchain/babylon/pull/18) ([SebastianElvis](https://github.com/SebastianElvis)) -- FIX: Stringer in RawCheckpoint and correct checkpointing module ModuleName [\#17](https://github.com/babylonchain/babylon/pull/17) ([vitsalis](https://github.com/vitsalis)) -- BM-16: feat\(epoching\): add AnteHandler `DropValidatorMsgDecorator` [\#15](https://github.com/babylonchain/babylon/pull/15) ([SebastianElvis](https://github.com/SebastianElvis)) -- BM-13: feat\(epoching\): add hooks, events and keeper functions [\#14](https://github.com/babylonchain/babylon/pull/14) ([SebastianElvis](https://github.com/SebastianElvis)) -- BM-10: Basic btcheaderoracle module [\#13](https://github.com/babylonchain/babylon/pull/13) ([vitsalis](https://github.com/vitsalis)) -- BM-17: Add basic functianalities of bls crypto [\#12](https://github.com/babylonchain/babylon/pull/12) ([gitferry](https://github.com/gitferry)) -- FIX: Resolve inconsistent BTCLightClientKeeper name [\#11](https://github.com/babylonchain/babylon/pull/11) ([vitsalis](https://github.com/vitsalis)) -- BM-15: feat\(epoching\): add protobuf messages [\#10](https://github.com/babylonchain/babylon/pull/10) ([SebastianElvis](https://github.com/SebastianElvis)) -- BM-6: Initial proposal for btc checkpoint message [\#8](https://github.com/babylonchain/babylon/pull/8) ([KonradStaniec](https://github.com/KonradStaniec)) -- FIX: Do not modify go.mod when generating proto files [\#7](https://github.com/babylonchain/babylon/pull/7) ([vitsalis](https://github.com/vitsalis)) -- BM-5: feat\(btc light client\): BTC Light Client module setup [\#6](https://github.com/babylonchain/babylon/pull/6) ([vitsalis](https://github.com/vitsalis)) -- BM-2: feat\(checkpointing\): init checkpointing module and define proto types [\#5](https://github.com/babylonchain/babylon/pull/5) ([gitferry](https://github.com/gitferry)) -- BM-6: Add initial scaffold for rawcheckpoint module [\#4](https://github.com/babylonchain/babylon/pull/4) ([KonradStaniec](https://github.com/KonradStaniec)) -- FIX: Add script that downloads third party proto dependencies [\#3](https://github.com/babylonchain/babylon/pull/3) ([vitsalis](https://github.com/vitsalis)) -- BM-3: feat\(epoching\): Epoching module setup [\#2](https://github.com/babylonchain/babylon/pull/2) ([SebastianElvis](https://github.com/SebastianElvis)) -- BM-4: Add docs/diagrams with a Makefile and a test. [\#1](https://github.com/babylonchain/babylon/pull/1) ([aakoshh](https://github.com/aakoshh)) +- Release v0.1.0 [\#191](https://github.com/babylonlabs-io/babylon/pull/191) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add validate-genesis cmd [\#187](https://github.com/babylonlabs-io/babylon/pull/187) ([gitferry](https://github.com/gitferry)) +- chore: add correspondence check against gentx when adding genesis BLS keys [\#186](https://github.com/babylonlabs-io/babylon/pull/186) ([gitferry](https://github.com/gitferry)) +- chore: regtest support [\#185](https://github.com/babylonlabs-io/babylon/pull/185) ([SebastianElvis](https://github.com/SebastianElvis)) +- Implement ADR-01 [\#183](https://github.com/babylonlabs-io/babylon/pull/183) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: Upgrade proto generation Docker image and script [\#181](https://github.com/babylonlabs-io/babylon/pull/181) ([vitsalis](https://github.com/vitsalis)) +- Fix accepting submission [\#179](https://github.com/babylonlabs-io/babylon/pull/179) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add add-genesis-bls cmd [\#178](https://github.com/babylonlabs-io/babylon/pull/178) ([gitferry](https://github.com/gitferry)) +- fix: CI failed after merging \#175 [\#177](https://github.com/babylonlabs-io/babylon/pull/177) ([gitferry](https://github.com/gitferry)) +- ibc: vanilla IBC module [\#176](https://github.com/babylonlabs-io/babylon/pull/176) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: add create-genesis-bls cmd [\#175](https://github.com/babylonlabs-io/babylon/pull/175) ([gitferry](https://github.com/gitferry)) +- Bump cosmos sdk [\#173](https://github.com/babylonlabs-io/babylon/pull/173) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add prepare-genesis command [\#172](https://github.com/babylonlabs-io/babylon/pull/172) ([vitsalis](https://github.com/vitsalis)) +- Refactor submission bitcoin status [\#170](https://github.com/babylonlabs-io/babylon/pull/170) ([KonradStaniec](https://github.com/KonradStaniec)) +- Validate btc objects in ante-handler [\#169](https://github.com/babylonlabs-io/babylon/pull/169) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Use \(u\)bbn bond denominations [\#167](https://github.com/babylonlabs-io/babylon/pull/167) ([vitsalis](https://github.com/vitsalis)) +- feat: checkpointing/improve the sending of BLS-sig tx [\#166](https://github.com/babylonlabs-io/babylon/pull/166) ([gitferry](https://github.com/gitferry)) +- feat: checkpointing/implement WrappedCreateValidator cli [\#165](https://github.com/babylonlabs-io/babylon/pull/165) ([gitferry](https://github.com/gitferry)) +- Move retry module from Vigilante to BBN [\#164](https://github.com/babylonlabs-io/babylon/pull/164) ([gusin13](https://github.com/gusin13)) +- feat: checkpointing/add create-bls-key cli [\#162](https://github.com/babylonlabs-io/babylon/pull/162) ([gitferry](https://github.com/gitferry)) +- chore: checkpointing/refactor validate basic [\#161](https://github.com/babylonlabs-io/babylon/pull/161) ([gitferry](https://github.com/gitferry)) +- Query to get submissions for given epoch [\#158](https://github.com/babylonlabs-io/babylon/pull/158) ([KonradStaniec](https://github.com/KonradStaniec)) +- Functionality for building custom mainnet tags [\#157](https://github.com/babylonlabs-io/babylon/pull/157) ([vitsalis](https://github.com/vitsalis)) +- Improve integration tests [\#156](https://github.com/babylonlabs-io/babylon/pull/156) ([KonradStaniec](https://github.com/KonradStaniec)) +- epoching: fix error of `unexpected validator in unbonding queue` [\#154](https://github.com/babylonlabs-io/babylon/pull/154) ([SebastianElvis](https://github.com/SebastianElvis)) +- Fix ancestry error [\#153](https://github.com/babylonlabs-io/babylon/pull/153) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: fix error msg typo of btccheckpoint [\#151](https://github.com/babylonlabs-io/babylon/pull/151) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching/checkpointing: checkpoint-assisted unbonding [\#150](https://github.com/babylonlabs-io/babylon/pull/150) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: Allow minimum work headers for a testnet/simnet [\#148](https://github.com/babylonlabs-io/babylon/pull/148) ([vitsalis](https://github.com/vitsalis)) +- Add test for checkpoint submissions and state change [\#147](https://github.com/babylonlabs-io/babylon/pull/147) ([KonradStaniec](https://github.com/KonradStaniec)) +- fix: fixed decoder for checkpoint [\#146](https://github.com/babylonlabs-io/babylon/pull/146) ([gitferry](https://github.com/gitferry)) +- epoching: add delegator address to events [\#145](https://github.com/babylonlabs-io/babylon/pull/145) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: checkpointing/add logs for checkpoint status change [\#144](https://github.com/babylonlabs-io/babylon/pull/144) ([gitferry](https://github.com/gitferry)) +- epoching: delegation lifecycle [\#143](https://github.com/babylonlabs-io/babylon/pull/143) ([SebastianElvis](https://github.com/SebastianElvis)) +- Relax tx formatter rules [\#142](https://github.com/babylonlabs-io/babylon/pull/142) ([KonradStaniec](https://github.com/KonradStaniec)) +- epoching: bugfix of `LatestEpochMsgs` API [\#140](https://github.com/babylonlabs-io/babylon/pull/140) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: CLI for delegating/undelegating/redelegating requests [\#138](https://github.com/babylonlabs-io/babylon/pull/138) ([SebastianElvis](https://github.com/SebastianElvis)) +- Revert: testnet: denom of gas price \#133 [\#136](https://github.com/babylonlabs-io/babylon/pull/136) ([vitsalis](https://github.com/vitsalis)) +- bitcoinsim: Remove it from the repository [\#135](https://github.com/babylonlabs-io/babylon/pull/135) ([vitsalis](https://github.com/vitsalis)) +- testnet: denom of gas price [\#133](https://github.com/babylonlabs-io/babylon/pull/133) ([SebastianElvis](https://github.com/SebastianElvis)) +- btclightclient: create temporary method for Contains request with bytes parameter [\#132](https://github.com/babylonlabs-io/babylon/pull/132) ([SebastianElvis](https://github.com/SebastianElvis)) +- btclightclient: Add BaseHeader query [\#130](https://github.com/babylonlabs-io/babylon/pull/130) ([vitsalis](https://github.com/vitsalis)) +- Remove full stack deployment and irrelevant files [\#129](https://github.com/babylonlabs-io/babylon/pull/129) ([vitsalis](https://github.com/vitsalis)) +- testnet: Add CLI args for specifying btccheckpoint and staking genesis params [\#128](https://github.com/babylonlabs-io/babylon/pull/128) ([vitsalis](https://github.com/vitsalis)) +- Add extending btc light client chain in tests [\#127](https://github.com/babylonlabs-io/babylon/pull/127) ([KonradStaniec](https://github.com/KonradStaniec)) +- chore: checkpointing/refactor bls-signer [\#126](https://github.com/babylonlabs-io/babylon/pull/126) ([gitferry](https://github.com/gitferry)) +- fix: Re-introduce localnet start to enable integration tests [\#125](https://github.com/babylonlabs-io/babylon/pull/125) ([vitsalis](https://github.com/vitsalis)) +- docker: Include vigilantes and explorer in the localnet deployment [\#123](https://github.com/babylonlabs-io/babylon/pull/123) ([vitsalis](https://github.com/vitsalis)) +- fix: checkpointing/query epoch status count bug [\#122](https://github.com/babylonlabs-io/babylon/pull/122) ([gitferry](https://github.com/gitferry)) +- Fixes initialisation bug [\#121](https://github.com/babylonlabs-io/babylon/pull/121) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/integrate bls-sig tx into the message flow [\#120](https://github.com/babylonlabs-io/babylon/pull/120) ([gitferry](https://github.com/gitferry)) +- epoching API: add epoch msg range queries and add timestamp to validator lifecycle [\#119](https://github.com/babylonlabs-io/babylon/pull/119) ([SebastianElvis](https://github.com/SebastianElvis)) +- fix: bls-sig accumulating bug and added tests [\#118](https://github.com/babylonlabs-io/babylon/pull/118) ([gitferry](https://github.com/gitferry)) +- epoching API: add timestamp to queued messages [\#116](https://github.com/babylonlabs-io/babylon/pull/116) ([SebastianElvis](https://github.com/SebastianElvis)) +- Parameterize genesis and config through testnet command flags [\#115](https://github.com/babylonlabs-io/babylon/pull/115) ([vitsalis](https://github.com/vitsalis)) +- Add custom query [\#114](https://github.com/babylonlabs-io/babylon/pull/114) ([KonradStaniec](https://github.com/KonradStaniec)) +- btccheckpoint: make kDeep/wDeep as system parameters [\#113](https://github.com/babylonlabs-io/babylon/pull/113) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: checkpointing/add typed events [\#112](https://github.com/babylonlabs-io/babylon/pull/112) ([gitferry](https://github.com/gitferry)) +- feat: checkpointing/ add queries about epoch status [\#111](https://github.com/babylonlabs-io/babylon/pull/111) ([gitferry](https://github.com/gitferry)) +- chore: BLS signer refactor [\#110](https://github.com/babylonlabs-io/babylon/pull/110) ([gitferry](https://github.com/gitferry)) +- epoching API: validator lifecycle [\#109](https://github.com/babylonlabs-io/babylon/pull/109) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: API: epoch\_msgs/{epoch\_num} -\> all events during this epoch [\#108](https://github.com/babylonlabs-io/babylon/pull/108) ([SebastianElvis](https://github.com/SebastianElvis)) +- btcutils: refactor for vigilante [\#107](https://github.com/babylonlabs-io/babylon/pull/107) ([SebastianElvis](https://github.com/SebastianElvis)) +- chore: Replace all instances of bbl with bbn [\#106](https://github.com/babylonlabs-io/babylon/pull/106) ([vitsalis](https://github.com/vitsalis)) +- Add babylon app config [\#105](https://github.com/babylonlabs-io/babylon/pull/105) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/implement BLS signer [\#104](https://github.com/babylonlabs-io/babylon/pull/104) ([gitferry](https://github.com/gitferry)) +- Add parsing correct format in btccheckpoint [\#102](https://github.com/babylonlabs-io/babylon/pull/102) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: add genesis state for checkpointing [\#101](https://github.com/babylonlabs-io/babylon/pull/101) ([gitferry](https://github.com/gitferry)) +- Add fuzz tests to formatter [\#100](https://github.com/babylonlabs-io/babylon/pull/100) ([KonradStaniec](https://github.com/KonradStaniec)) +- Fix: checkpointing/epoch growth bug [\#99](https://github.com/babylonlabs-io/babylon/pull/99) ([gitferry](https://github.com/gitferry)) +- chore: replace bbl with bbn and gitignore [\#98](https://github.com/babylonlabs-io/babylon/pull/98) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: checkpointing/changed PoP by signing BLS public key [\#97](https://github.com/babylonlabs-io/babylon/pull/97) ([gitferry](https://github.com/gitferry)) +- Add initial implementation of tx formatter [\#96](https://github.com/babylonlabs-io/babylon/pull/96) ([KonradStaniec](https://github.com/KonradStaniec)) +- BM-102: Single BTC node in docker producing blocks [\#95](https://github.com/babylonlabs-io/babylon/pull/95) ([aakoshh](https://github.com/aakoshh)) +- Add initial test checking progress [\#94](https://github.com/babylonlabs-io/babylon/pull/94) ([KonradStaniec](https://github.com/KonradStaniec)) +- Add tests to ci [\#90](https://github.com/babylonlabs-io/babylon/pull/90) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Add checkpoint query with status [\#89](https://github.com/babylonlabs-io/babylon/pull/89) ([gitferry](https://github.com/gitferry)) +- enable gRPC gateway routes for rest queries [\#88](https://github.com/babylonlabs-io/babylon/pull/88) ([toliujiayi](https://github.com/toliujiayi)) +- Wire app without mocks [\#87](https://github.com/babylonlabs-io/babylon/pull/87) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: implement bls key generation [\#86](https://github.com/babylonlabs-io/babylon/pull/86) ([gitferry](https://github.com/gitferry)) +- Add integration tests [\#85](https://github.com/babylonlabs-io/babylon/pull/85) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: checkpointing/implement checkpoint verification and keeper tests [\#84](https://github.com/babylonlabs-io/babylon/pull/84) ([gitferry](https://github.com/gitferry)) +- Add btccheckpoit unit tests [\#83](https://github.com/babylonlabs-io/babylon/pull/83) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: btclightclient: Add BTCHeaderInserted event [\#82](https://github.com/babylonlabs-io/babylon/pull/82) ([vitsalis](https://github.com/vitsalis)) +- fix: Remove WASM config from application configuration [\#81](https://github.com/babylonlabs-io/babylon/pull/81) ([vitsalis](https://github.com/vitsalis)) +- epoching: smaller epoch interval in simulation [\#80](https://github.com/babylonlabs-io/babylon/pull/80) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: Use a caching multistore in delayed staking message handler [\#79](https://github.com/babylonlabs-io/babylon/pull/79) ([aakoshh](https://github.com/aakoshh)) +- feat: checkpointing/implement cli [\#78](https://github.com/babylonlabs-io/babylon/pull/78) ([gitferry](https://github.com/gitferry)) +- fix: Add installation instructions and executable reference [\#77](https://github.com/babylonlabs-io/babylon/pull/77) ([vitsalis](https://github.com/vitsalis)) +- chore: issue templates [\#76](https://github.com/babylonlabs-io/babylon/pull/76) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Register msg server for all modules & instructions for tx submission [\#73](https://github.com/babylonlabs-io/babylon/pull/73) ([vitsalis](https://github.com/vitsalis)) +- feat: btclightclient: Refactor keepers based on needs of btcheckpoint module [\#72](https://github.com/babylonlabs-io/babylon/pull/72) ([vitsalis](https://github.com/vitsalis)) +- simulation: vanilla simulation tests [\#71](https://github.com/babylonlabs-io/babylon/pull/71) ([SebastianElvis](https://github.com/SebastianElvis)) +- Implement core btc handling logic [\#70](https://github.com/babylonlabs-io/babylon/pull/70) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: btclightclient: gRPC query fuzz tests [\#69](https://github.com/babylonlabs-io/babylon/pull/69) ([vitsalis](https://github.com/vitsalis)) +- epoching: simulation infra for integration testing [\#68](https://github.com/babylonlabs-io/babylon/pull/68) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: btclightclient: Add keeper fuzz tests [\#67](https://github.com/babylonlabs-io/babylon/pull/67) ([vitsalis](https://github.com/vitsalis)) +- epoching: fuzz tests on epoched undelegations and redelegations [\#66](https://github.com/babylonlabs-io/babylon/pull/66) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: refactor test infra, mock messages and sample fuzz tests [\#65](https://github.com/babylonlabs-io/babylon/pull/65) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: fuzz tests for slashed validator set [\#64](https://github.com/babylonlabs-io/babylon/pull/64) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: replace deprecated `EmitEvent` APIs with `EmitTypedEvent` ones [\#63](https://github.com/babylonlabs-io/babylon/pull/63) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: btclightclient HeadersState keeper fuzz tests [\#61](https://github.com/babylonlabs-io/babylon/pull/61) ([vitsalis](https://github.com/vitsalis)) +- epoching: more test infra and some fuzz tests on keeper functionalities [\#60](https://github.com/babylonlabs-io/babylon/pull/60) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: checkpointing/aggregate BLS signatures [\#59](https://github.com/babylonlabs-io/babylon/pull/59) ([gitferry](https://github.com/gitferry)) +- feat: btclightclient: Abstract the usage of btcd types and store BTCHeaderInfo objects [\#58](https://github.com/babylonlabs-io/babylon/pull/58) ([vitsalis](https://github.com/vitsalis)) +- feat: Replace BTC types unit tests with fuzz tests [\#56](https://github.com/babylonlabs-io/babylon/pull/56) ([vitsalis](https://github.com/vitsalis)) +- feat: Create datagen testutil for common random generation functions [\#55](https://github.com/babylonlabs-io/babylon/pull/55) ([vitsalis](https://github.com/vitsalis)) +- epoching: wrapper type `Epoch` and simplify code using this type [\#54](https://github.com/babylonlabs-io/babylon/pull/54) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add btclightclient events and hooks [\#53](https://github.com/babylonlabs-io/babylon/pull/53) ([vitsalis](https://github.com/vitsalis)) +- feat: add raw checkpoint creation [\#52](https://github.com/babylonlabs-io/babylon/pull/52) ([gitferry](https://github.com/gitferry)) +- feat: Add accumulattive PoW functionality to btclightclient [\#51](https://github.com/babylonlabs-io/babylon/pull/51) ([vitsalis](https://github.com/vitsalis)) +- btclightclient: Cleanup codebase and add descriptive comments [\#50](https://github.com/babylonlabs-io/babylon/pull/50) ([vitsalis](https://github.com/vitsalis)) +- Update go to 1.18 in README [\#49](https://github.com/babylonlabs-io/babylon/pull/49) ([vitsalis](https://github.com/vitsalis)) +- Upgrade to go 1.18 [\#48](https://github.com/babylonlabs-io/babylon/pull/48) ([vitsalis](https://github.com/vitsalis)) +- feat: define checkpointing registration proto and state [\#46](https://github.com/babylonlabs-io/babylon/pull/46) ([gitferry](https://github.com/gitferry)) +- BM-60: Database schema ER diagram [\#45](https://github.com/babylonlabs-io/babylon/pull/45) ([aakoshh](https://github.com/aakoshh)) +- Revert "feat: CI: Generate a single block in build check " [\#44](https://github.com/babylonlabs-io/babylon/pull/44) ([vitsalis](https://github.com/vitsalis)) +- Btccheckpoint oracle schema and processing [\#43](https://github.com/babylonlabs-io/babylon/pull/43) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Fuzz and unit tests for btclightclient types [\#42](https://github.com/babylonlabs-io/babylon/pull/42) ([vitsalis](https://github.com/vitsalis)) +- epoching: fix genesis, param and bootstrapping [\#41](https://github.com/babylonlabs-io/babylon/pull/41) ([SebastianElvis](https://github.com/SebastianElvis)) +- feat: Add unit tests for ValidateHeader of btcutils [\#40](https://github.com/babylonlabs-io/babylon/pull/40) ([vitsalis](https://github.com/vitsalis)) +- feat: Add unit tests for BTCHeaderHashBytes and BTCHeaderBytes types [\#39](https://github.com/babylonlabs-io/babylon/pull/39) ([vitsalis](https://github.com/vitsalis)) +- Add building, testing, and testnet instructions on README [\#38](https://github.com/babylonlabs-io/babylon/pull/38) ([vitsalis](https://github.com/vitsalis)) +- feat: CI: Generate a single block in build check [\#37](https://github.com/babylonlabs-io/babylon/pull/37) ([vitsalis](https://github.com/vitsalis)) +- epoching: event and hook upon a certain threshold amount of slashed voting power [\#35](https://github.com/babylonlabs-io/babylon/pull/35) ([SebastianElvis](https://github.com/SebastianElvis)) +- doc: add BLS key registration spec [\#34](https://github.com/babylonlabs-io/babylon/pull/34) ([gitferry](https://github.com/gitferry)) +- feat: add hooks, events, and error types to the checkpointing module [\#33](https://github.com/babylonlabs-io/babylon/pull/33) ([gitferry](https://github.com/gitferry)) +- epoching: state transition upon `BeginBlock` and `EndBlock` [\#32](https://github.com/babylonlabs-io/babylon/pull/32) ([SebastianElvis](https://github.com/SebastianElvis)) +- Handle insert checkpoint [\#31](https://github.com/babylonlabs-io/babylon/pull/31) ([KonradStaniec](https://github.com/KonradStaniec)) +- feat: Add btclightclient chain query [\#30](https://github.com/babylonlabs-io/babylon/pull/30) ([vitsalis](https://github.com/vitsalis)) +- feat: Implement BTCHeaderBytes and BTCHeaderHashBytes types [\#29](https://github.com/babylonlabs-io/babylon/pull/29) ([vitsalis](https://github.com/vitsalis)) +- epoching: copy/paste necessary code from staking/evidence/slashing and make modifications [\#28](https://github.com/babylonlabs-io/babylon/pull/28) ([SebastianElvis](https://github.com/SebastianElvis)) +- checkpointing: add keeper and core state [\#27](https://github.com/babylonlabs-io/babylon/pull/27) ([gitferry](https://github.com/gitferry)) +- FIX: btclightclient: Properly convert the input of contains to bytes [\#26](https://github.com/babylonlabs-io/babylon/pull/26) ([vitsalis](https://github.com/vitsalis)) +- BM-32: Update diagrams for out-of-sequence checkpoint handling [\#25](https://github.com/babylonlabs-io/babylon/pull/25) ([aakoshh](https://github.com/aakoshh)) +- FIX\(localnet\): Redirect babylond stderr to stdout [\#24](https://github.com/babylonlabs-io/babylon/pull/24) ([vitsalis](https://github.com/vitsalis)) +- BM-31: Add CircleCI pipeline for building and testing [\#23](https://github.com/babylonlabs-io/babylon/pull/23) ([vitsalis](https://github.com/vitsalis)) +- FIX: Failing btclightclient tests, remove unneeded ones, clean up [\#22](https://github.com/babylonlabs-io/babylon/pull/22) ([vitsalis](https://github.com/vitsalis)) +- FIX: Replace 'unimplemented' AnteHandler panic with comment [\#21](https://github.com/babylonlabs-io/babylon/pull/21) ([vitsalis](https://github.com/vitsalis)) +- FIX: Implement Msg interface for MsgInsertBTCSpvProof [\#20](https://github.com/babylonlabs-io/babylon/pull/20) ([vitsalis](https://github.com/vitsalis)) +- epoching: keeper functions, queries, and testing infra [\#19](https://github.com/babylonlabs-io/babylon/pull/19) ([SebastianElvis](https://github.com/SebastianElvis)) +- epoching: Wrapped messages and AnteHandler implementation [\#18](https://github.com/babylonlabs-io/babylon/pull/18) ([SebastianElvis](https://github.com/SebastianElvis)) +- FIX: Stringer in RawCheckpoint and correct checkpointing module ModuleName [\#17](https://github.com/babylonlabs-io/babylon/pull/17) ([vitsalis](https://github.com/vitsalis)) +- BM-16: feat\(epoching\): add AnteHandler `DropValidatorMsgDecorator` [\#15](https://github.com/babylonlabs-io/babylon/pull/15) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-13: feat\(epoching\): add hooks, events and keeper functions [\#14](https://github.com/babylonlabs-io/babylon/pull/14) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-10: Basic btcheaderoracle module [\#13](https://github.com/babylonlabs-io/babylon/pull/13) ([vitsalis](https://github.com/vitsalis)) +- BM-17: Add basic functianalities of bls crypto [\#12](https://github.com/babylonlabs-io/babylon/pull/12) ([gitferry](https://github.com/gitferry)) +- FIX: Resolve inconsistent BTCLightClientKeeper name [\#11](https://github.com/babylonlabs-io/babylon/pull/11) ([vitsalis](https://github.com/vitsalis)) +- BM-15: feat\(epoching\): add protobuf messages [\#10](https://github.com/babylonlabs-io/babylon/pull/10) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-6: Initial proposal for btc checkpoint message [\#8](https://github.com/babylonlabs-io/babylon/pull/8) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Do not modify go.mod when generating proto files [\#7](https://github.com/babylonlabs-io/babylon/pull/7) ([vitsalis](https://github.com/vitsalis)) +- BM-5: feat\(btc light client\): BTC Light Client module setup [\#6](https://github.com/babylonlabs-io/babylon/pull/6) ([vitsalis](https://github.com/vitsalis)) +- BM-2: feat\(checkpointing\): init checkpointing module and define proto types [\#5](https://github.com/babylonlabs-io/babylon/pull/5) ([gitferry](https://github.com/gitferry)) +- BM-6: Add initial scaffold for rawcheckpoint module [\#4](https://github.com/babylonlabs-io/babylon/pull/4) ([KonradStaniec](https://github.com/KonradStaniec)) +- FIX: Add script that downloads third party proto dependencies [\#3](https://github.com/babylonlabs-io/babylon/pull/3) ([vitsalis](https://github.com/vitsalis)) +- BM-3: feat\(epoching\): Epoching module setup [\#2](https://github.com/babylonlabs-io/babylon/pull/2) ([SebastianElvis](https://github.com/SebastianElvis)) +- BM-4: Add docs/diagrams with a Makefile and a test. [\#1](https://github.com/babylonlabs-io/babylon/pull/1) ([aakoshh](https://github.com/aakoshh)) diff --git a/LICENSE b/LICENSE index 45ff37b20..d08b6069f 100644 --- a/LICENSE +++ b/LICENSE @@ -8,14 +8,14 @@ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. Parameters -Licensor: Babylonchain, Inc. +Licensor: BabylonLabs, Ltd. Licensed Work: Babylon - The Licensed Work is (c) 2023 Babylonchain, Inc. + The Licensed Work is (c) 2023 BabylonLabs, Ltd. Additional Use Grant: None. -Change Date: 2027-01-20 (January 20th, 2027] +Change Date: 2027-01-20 (January 20th, 2027) Change License: Apache 2.0 diff --git a/Makefile b/Makefile index f70e4c026..4c8db9052 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ LEDGER_ENABLED ?= true BINDIR ?= $(GOPATH)/bin PROJECT_NAME ?= babylon BUILDDIR ?= $(CURDIR)/build -HTTPS_GIT := https://github.com/babylonchain/babylon.git +HTTPS_GIT := https://github.com/babylonlabs-io/babylon.git DOCKER := $(shell which docker) SIMAPP = ./simapp @@ -341,7 +341,7 @@ lint-go: format: ## Run code formater find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs gofmt -w -s find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs misspell -w - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/babylonchain/babylon + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/docs/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/babylonlabs-io/babylon .PHONY: format ############################################################################### @@ -363,12 +363,12 @@ gosec-local: ## Run local security checkss DEVDOC_SAVE = docker commit `docker ps -a -n 1 -q` devdoc:local devdoc-init: ## Initialize documentation - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonchain/babylon" -w "/go/src/github.com/babylonchain/babylon" tendermint/devdoc echo + $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonlabs-io/babylon" -w "/go/src/github.com/babylonlabs-io/babylon" tendermint/devdoc echo # TODO make this safer $(call DEVDOC_SAVE) devdoc: ## Generate documentation - $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonchain/babylon" -w "/go/src/github.com/babylonchain/babylon" devdoc:local bash + $(DOCKER) run -it -v "$(CURDIR):/go/src/github.com/babylonlabs-io/babylon" -w "/go/src/github.com/babylonlabs-io/babylon" devdoc:local bash devdoc-save: ## Save documentation changes # TODO make this safer @@ -428,7 +428,7 @@ init-testnet-dirs: ## Initialize directories for testnet, creates a ./.testnets # need to create the dir before hand so that the docker container has write access to the `.testnets` dir # regardless of the user it uses mkdir -p $(CURDIR)/.testnets && chmod o+w $(CURDIR)/.testnets - $(DOCKER) run --rm -v $(CURDIR)/.testnets:/home/babylon/.testnets:Z babylonchain/babylond \ + $(DOCKER) run --rm -v $(CURDIR)/.testnets:/home/babylon/.testnets:Z babylonlabs-io/babylond \ babylond testnet init-files --v 4 -o /home/babylon/.testnets \ --starting-ip-address 192.168.10.2 --keyring-backend=test \ --chain-id chain-test --btc-confirmation-depth 2 --additional-sender-account true \ diff --git a/SECURITY.md b/SECURITY.md index e30d358d5..ee8c3febf 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -25,7 +25,7 @@ Send your detailed vulnerability report to `security@babylonchain.io`. ### 2. GitHub Private Vulnerability Reporting -Utilize [GitHub's Private Vulnerability Reporting](https://github.com/babylonchain/babylon/security/advisories/new) +Utilize [GitHub's Private Vulnerability Reporting](https://github.com/babylonlabs-io/babylon/security/advisories/new) for confidential disclosure. ## Submit Vulnerability Report diff --git a/app/ante_btc_validation_decorator.go b/app/ante_btc_validation_decorator.go index 46a003bb1..8e5febfb8 100644 --- a/app/ante_btc_validation_decorator.go +++ b/app/ante_btc_validation_decorator.go @@ -1,10 +1,10 @@ package app import ( - bbn "github.com/babylonchain/babylon/types" - btccheckpointkeeper "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclightclient "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + btccheckpointkeeper "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclightclient "github.com/babylonlabs-io/babylon/x/btclightclient/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/app/app.go b/app/app.go index 67b0b7800..541bcd8d3 100644 --- a/app/app.go +++ b/app/app.go @@ -93,32 +93,32 @@ import ( ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/spf13/cast" - "github.com/babylonchain/babylon/app/upgrades" - bbn "github.com/babylonchain/babylon/types" - - appkeepers "github.com/babylonchain/babylon/app/keepers" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/client/docs" - "github.com/babylonchain/babylon/x/btccheckpoint" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - "github.com/babylonchain/babylon/x/btclightclient" - btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking" - btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/checkpointing" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - "github.com/babylonchain/babylon/x/epoching" - epochingkeeper "github.com/babylonchain/babylon/x/epoching/keeper" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/finality" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" - "github.com/babylonchain/babylon/x/incentive" - incentivetypes "github.com/babylonchain/babylon/x/incentive/types" - "github.com/babylonchain/babylon/x/monitor" - monitortypes "github.com/babylonchain/babylon/x/monitor/types" - "github.com/babylonchain/babylon/x/zoneconcierge" - zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/app/upgrades" + bbn "github.com/babylonlabs-io/babylon/types" + + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/client/docs" + "github.com/babylonlabs-io/babylon/x/btccheckpoint" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btclightclient" + btclightclienttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking" + btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/checkpointing" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/epoching" + epochingkeeper "github.com/babylonlabs-io/babylon/x/epoching/keeper" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/finality" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/incentive" + incentivetypes "github.com/babylonlabs-io/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/monitor" + monitortypes "github.com/babylonlabs-io/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge" + zckeeper "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) const ( diff --git a/app/encoding.go b/app/encoding.go index 0ae2e5a9f..57a5b6cf5 100644 --- a/app/encoding.go +++ b/app/encoding.go @@ -9,8 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" simsutils "github.com/cosmos/cosmos-sdk/testutil/sims" - appparams "github.com/babylonchain/babylon/app/params" - bbn "github.com/babylonchain/babylon/types" + appparams "github.com/babylonlabs-io/babylon/app/params" + bbn "github.com/babylonlabs-io/babylon/types" ) // TmpAppOptions returns an app option with tmp dir and btc network diff --git a/app/keepers/keepers.go b/app/keepers/keepers.go index 64c0baa14..74174a608 100644 --- a/app/keepers/keepers.go +++ b/app/keepers/keepers.go @@ -61,28 +61,28 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" ibckeeper "github.com/cosmos/ibc-go/v8/modules/core/keeper" - appparams "github.com/babylonchain/babylon/app/params" - bbn "github.com/babylonchain/babylon/types" - owasm "github.com/babylonchain/babylon/wasmbinding" - btccheckpointkeeper "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclightclientkeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" - btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" - btcstakingkeeper "github.com/babylonchain/babylon/x/btcstaking/keeper" - btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" - checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingkeeper "github.com/babylonchain/babylon/x/epoching/keeper" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - finalitykeeper "github.com/babylonchain/babylon/x/finality/keeper" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" - incentivekeeper "github.com/babylonchain/babylon/x/incentive/keeper" - incentivetypes "github.com/babylonchain/babylon/x/incentive/types" - monitorkeeper "github.com/babylonchain/babylon/x/monitor/keeper" - monitortypes "github.com/babylonchain/babylon/x/monitor/types" - "github.com/babylonchain/babylon/x/zoneconcierge" - zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + appparams "github.com/babylonlabs-io/babylon/app/params" + bbn "github.com/babylonlabs-io/babylon/types" + owasm "github.com/babylonlabs-io/babylon/wasmbinding" + btccheckpointkeeper "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclightclientkeeper "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + btclightclienttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + btcstakingkeeper "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + checkpointingkeeper "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingkeeper "github.com/babylonlabs-io/babylon/x/epoching/keeper" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + finalitykeeper "github.com/babylonlabs-io/babylon/x/finality/keeper" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" + incentivekeeper "github.com/babylonlabs-io/babylon/x/incentive/keeper" + incentivetypes "github.com/babylonlabs-io/babylon/x/incentive/types" + monitorkeeper "github.com/babylonlabs-io/babylon/x/monitor/keeper" + monitortypes "github.com/babylonlabs-io/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge" + zckeeper "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // Capabilities of the IBC wasm contracts diff --git a/app/keepers/utils.go b/app/keepers/utils.go index 121f3531f..7efe4b78a 100644 --- a/app/keepers/utils.go +++ b/app/keepers/utils.go @@ -11,7 +11,7 @@ import ( cmtos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/client/config" - "github.com/babylonchain/babylon/privval" + "github.com/babylonlabs-io/babylon/privval" ) const defaultConfigTemplate = `# This is a TOML config file. diff --git a/app/test_helpers.go b/app/test_helpers.go index d8dfea5ef..08ff94d76 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -30,12 +30,12 @@ import ( "github.com/docker/docker/pkg/ioutils" "github.com/stretchr/testify/require" - appkeepers "github.com/babylonchain/babylon/app/keepers" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - bbn "github.com/babylonchain/babylon/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + bbn "github.com/babylonlabs-io/babylon/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // SetupOptions defines arguments that are passed into `Simapp` constructor. diff --git a/app/upgrades/types.go b/app/upgrades/types.go index 8f143c8e1..15fa8ae05 100644 --- a/app/upgrades/types.go +++ b/app/upgrades/types.go @@ -7,7 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/babylonchain/babylon/app/keepers" + "github.com/babylonlabs-io/babylon/app/keepers" ) // BaseAppParamManager defines an interrace that BaseApp is expected to fulfill diff --git a/app/upgrades/vanilla/upgrades.go b/app/upgrades/vanilla/upgrades.go index 1cc0c9060..35d546958 100644 --- a/app/upgrades/vanilla/upgrades.go +++ b/app/upgrades/vanilla/upgrades.go @@ -8,11 +8,11 @@ import ( store "cosmossdk.io/store/types" upgradetypes "cosmossdk.io/x/upgrade/types" - "github.com/babylonchain/babylon/app/keepers" - "github.com/babylonchain/babylon/app/upgrades" - bbn "github.com/babylonchain/babylon/types" - btcstakingkeeper "github.com/babylonchain/babylon/x/btcstaking/keeper" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/app/keepers" + "github.com/babylonlabs-io/babylon/app/upgrades" + bbn "github.com/babylonlabs-io/babylon/types" + btcstakingkeeper "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" diff --git a/app/upgrades/vanilla/upgrades_test.go b/app/upgrades/vanilla/upgrades_test.go index fba069c7f..19511629f 100644 --- a/app/upgrades/vanilla/upgrades_test.go +++ b/app/upgrades/vanilla/upgrades_test.go @@ -9,9 +9,9 @@ import ( "cosmossdk.io/core/header" "cosmossdk.io/x/upgrade" upgradetypes "cosmossdk.io/x/upgrade/types" - "github.com/babylonchain/babylon/app" - v1 "github.com/babylonchain/babylon/app/upgrades/vanilla" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/app" + v1 "github.com/babylonlabs-io/babylon/app/upgrades/vanilla" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" tmproto "github.com/cometbft/cometbft/proto/tendermint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" diff --git a/btcstaking/btcstaking_test.go b/btcstaking/btcstaking_test.go index fc41142aa..940a4aace 100644 --- a/btcstaking/btcstaking_test.go +++ b/btcstaking/btcstaking_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/btcstaking" - btctest "github.com/babylonchain/babylon/testutil/bitcoin" + "github.com/babylonlabs-io/babylon/btcstaking" + btctest "github.com/babylonlabs-io/babylon/testutil/bitcoin" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" diff --git a/btcstaking/identifiable_staking_test.go b/btcstaking/identifiable_staking_test.go index 6f790f8d8..96692735b 100644 --- a/btcstaking/identifiable_staking_test.go +++ b/btcstaking/identifiable_staking_test.go @@ -5,7 +5,7 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonlabs-io/babylon/btcstaking" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" @@ -13,7 +13,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" ) func generateTxFromOutputs(r *rand.Rand, info *btcstaking.IdentifiableStakingInfo) (*wire.MsgTx, int, int) { diff --git a/btcstaking/staking.go b/btcstaking/staking.go index d0c412f4a..d82cb0f2a 100644 --- a/btcstaking/staking.go +++ b/btcstaking/staking.go @@ -15,7 +15,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" ) // buildSlashingTxFromOutpoint builds a valid slashing transaction by creating a new Bitcoin transaction that slashes a portion diff --git a/btcstaking/staking_test.go b/btcstaking/staking_test.go index 8a02803f7..b54c97c95 100644 --- a/btcstaking/staking_test.go +++ b/btcstaking/staking_test.go @@ -9,8 +9,8 @@ import ( "time" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/btcstaking" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/btcstaking" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" diff --git a/btcstaking/staking_testvectors_test.go b/btcstaking/staking_testvectors_test.go index 2a60273f5..b8e3613b7 100644 --- a/btcstaking/staking_testvectors_test.go +++ b/btcstaking/staking_testvectors_test.go @@ -15,7 +15,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonlabs-io/babylon/btcstaking" ) func getBtcNetworkParams(network string) (*chaincfg.Params, error) { diff --git a/btcstaking/staking_utils_test.go b/btcstaking/staking_utils_test.go index e286ad05e..7cb2da873 100644 --- a/btcstaking/staking_utils_test.go +++ b/btcstaking/staking_utils_test.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/btcstaking" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btcstaking" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/stretchr/testify/require" ) diff --git a/btcstaking/types.go b/btcstaking/types.go index 95d6a9455..d6dc68f8c 100644 --- a/btcstaking/types.go +++ b/btcstaking/types.go @@ -13,7 +13,7 @@ import ( "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/client/client/client.go b/client/client/client.go index 14b84fc15..e641c96bc 100644 --- a/client/client/client.go +++ b/client/client/client.go @@ -4,9 +4,9 @@ import ( "context" "time" - bbn "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/client/config" - "github.com/babylonchain/babylon/client/query" + bbn "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/client/config" + "github.com/babylonlabs-io/babylon/client/query" rpchttp "github.com/cometbft/cometbft/rpc/client/http" "github.com/cosmos/relayer/v2/relayer/chains/cosmos" "go.uber.org/zap" diff --git a/client/client/keys.go b/client/client/keys.go index baf6b7bac..2974ccbde 100644 --- a/client/client/keys.go +++ b/client/client/keys.go @@ -28,7 +28,7 @@ func (c *Client) GetKeyring() keyring.Keyring { // the file system lock, in order to remain thread-safe when multiple concurrent // relayers are running on the same machine and accessing the same keyring // adapted from -// https://github.com/babylonchain/babylon-relayer/blob/f962d0940832a8f84f747c5d9cbc67bc1b156386/bbnrelayer/utils.go#L212 +// https://github.com/babylonlabs-io/babylon-relayer/blob/f962d0940832a8f84f747c5d9cbc67bc1b156386/bbnrelayer/utils.go#L212 func (c *Client) accessKeyWithLock(accessFunc func()) error { // use lock file to guard concurrent access to the keyring lockFilePath := path.Join(c.provider.PCfg.KeyDirectory, "keys.lock") diff --git a/client/client/keys_test.go b/client/client/keys_test.go index 5b1a716ec..4192b87ab 100644 --- a/client/client/keys_test.go +++ b/client/client/keys_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - bbn "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/client/client" - "github.com/babylonchain/babylon/client/config" - "github.com/babylonchain/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/client/client" + "github.com/babylonlabs-io/babylon/client/config" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/stretchr/testify/require" diff --git a/client/client/tx.go b/client/client/tx.go index 4bf35f9d7..f3bac897e 100644 --- a/client/client/tx.go +++ b/client/client/tx.go @@ -9,8 +9,8 @@ import ( "cosmossdk.io/errors" txsigning "cosmossdk.io/x/tx/signing" "github.com/avast/retry-go/v4" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" abci "github.com/cometbft/cometbft/abci/types" coretypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/cosmos/cosmos-sdk/client" diff --git a/client/config/babylon_config.go b/client/config/babylon_config.go index a332e2633..680e5fb1a 100644 --- a/client/config/babylon_config.go +++ b/client/config/babylon_config.go @@ -84,7 +84,7 @@ func DefaultBabylonConfig() BabylonConfig { } // defaultBabylonHome returns the default Babylon node directory, which is $HOME/.babylond -// copied from https://github.com/babylonchain/babylon/blob/648b804bc492ded2cb826ba261d7164b4614d78a/app/app.go#L205-L210 +// copied from https://github.com/babylonlabs-io/babylon/blob/648b804bc492ded2cb826ba261d7164b4614d78a/app/app.go#L205-L210 func defaultBabylonHome() string { userHomeDir, err := os.UserHomeDir() if err != nil { diff --git a/client/config/babylon_query_config_test.go b/client/config/babylon_query_config_test.go index ba758a1ae..18c9ac2e5 100644 --- a/client/config/babylon_query_config_test.go +++ b/client/config/babylon_query_config_test.go @@ -3,7 +3,7 @@ package config_test import ( "testing" - "github.com/babylonchain/babylon/client/config" + "github.com/babylonlabs-io/babylon/client/config" "github.com/stretchr/testify/require" ) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 3fa9bac6e..00e83b140 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -615,7 +615,7 @@ paths: summary: |- ContainsBytes is a temporary method that checks whether a hash is maintained by the module. - See discussion at https://github.com/babylonchain/babylon/pull/132 + See discussion at https://github.com/babylonlabs-io/babylon/pull/132 for more details. operationId: ContainsBytes responses: diff --git a/client/query/btccheckpoint.go b/client/query/btccheckpoint.go index 974dbe7ef..c5947cd68 100644 --- a/client/query/btccheckpoint.go +++ b/client/query/btccheckpoint.go @@ -3,7 +3,7 @@ package query import ( "context" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/client/query/btclightclient.go b/client/query/btclightclient.go index a20e0c19d..3c400c631 100644 --- a/client/query/btclightclient.go +++ b/client/query/btclightclient.go @@ -3,7 +3,7 @@ package query import ( "context" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" diff --git a/client/query/btcstaking.go b/client/query/btcstaking.go index 4a9b17e68..04250fd3d 100644 --- a/client/query/btcstaking.go +++ b/client/query/btcstaking.go @@ -3,7 +3,7 @@ package query import ( "context" - btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" + btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/client/query/checkpointing.go b/client/query/checkpointing.go index 50afba26c..58466b5bf 100644 --- a/client/query/checkpointing.go +++ b/client/query/checkpointing.go @@ -3,7 +3,7 @@ package query import ( "context" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/client/query/client.go b/client/query/client.go index 17c60e98d..4a41f4fd9 100644 --- a/client/query/client.go +++ b/client/query/client.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" - "github.com/babylonchain/babylon/client/config" + "github.com/babylonlabs-io/babylon/client/config" rpcclient "github.com/cometbft/cometbft/rpc/client" "github.com/cosmos/cosmos-sdk/client" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" diff --git a/client/query/epoching.go b/client/query/epoching.go index a94743737..ec6dc792e 100644 --- a/client/query/epoching.go +++ b/client/query/epoching.go @@ -3,7 +3,7 @@ package query import ( "context" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/client/query/finality.go b/client/query/finality.go index 554705bc5..2db05d281 100644 --- a/client/query/finality.go +++ b/client/query/finality.go @@ -3,7 +3,7 @@ package query import ( "context" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/client/query/incentive.go b/client/query/incentive.go index fe45356a1..6031578c6 100644 --- a/client/query/incentive.go +++ b/client/query/incentive.go @@ -3,7 +3,7 @@ package query import ( "context" - incentivetypes "github.com/babylonchain/babylon/x/incentive/types" + incentivetypes "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/client" ) diff --git a/client/query/monitor.go b/client/query/monitor.go index 3ca35f95d..d08597e51 100644 --- a/client/query/monitor.go +++ b/client/query/monitor.go @@ -3,7 +3,7 @@ package query import ( "context" - monitortypes "github.com/babylonchain/babylon/x/monitor/types" + monitortypes "github.com/babylonlabs-io/babylon/x/monitor/types" "github.com/cosmos/cosmos-sdk/client" ) diff --git a/client/query/zoneconcierge.go b/client/query/zoneconcierge.go index 95f3c5331..6639d5207 100644 --- a/client/query/zoneconcierge.go +++ b/client/query/zoneconcierge.go @@ -3,7 +3,7 @@ package query import ( "context" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/client" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/cmd/babylond/cmd/cmd_test.go b/cmd/babylond/cmd/cmd_test.go index f00b10994..ddebd4ac7 100644 --- a/cmd/babylond/cmd/cmd_test.go +++ b/cmd/babylond/cmd/cmd_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" ) diff --git a/cmd/babylond/cmd/create_bls_key.go b/cmd/babylond/cmd/create_bls_key.go index ab402874e..37e4f4be4 100644 --- a/cmd/babylond/cmd/create_bls_key.go +++ b/cmd/babylond/cmd/create_bls_key.go @@ -12,10 +12,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/app" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" + "github.com/babylonlabs-io/babylon/app" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" ) func CreateBlsKeyCmd() *cobra.Command { diff --git a/cmd/babylond/cmd/custom_babylon_config.go b/cmd/babylond/cmd/custom_babylon_config.go index c90ec3210..055f6069f 100644 --- a/cmd/babylond/cmd/custom_babylon_config.go +++ b/cmd/babylond/cmd/custom_babylon_config.go @@ -4,7 +4,7 @@ import ( wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" serverconfig "github.com/cosmos/cosmos-sdk/server/config" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" ) type BtcConfig struct { diff --git a/cmd/babylond/cmd/flags.go b/cmd/babylond/cmd/flags.go index 3d154b980..65713599a 100644 --- a/cmd/babylond/cmd/flags.go +++ b/cmd/babylond/cmd/flags.go @@ -10,10 +10,10 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - babylonApp "github.com/babylonchain/babylon/app" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btcltypes "github.com/babylonchain/babylon/x/btclightclient/types" - btcstypes "github.com/babylonchain/babylon/x/btcstaking/types" + babylonApp "github.com/babylonlabs-io/babylon/app" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btcltypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + btcstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) const ( diff --git a/cmd/babylond/cmd/genaccounts_test.go b/cmd/babylond/cmd/genaccounts_test.go index 0142009a1..0ea1ba566 100644 --- a/cmd/babylond/cmd/genaccounts_test.go +++ b/cmd/babylond/cmd/genaccounts_test.go @@ -3,7 +3,7 @@ package cmd_test import ( "context" "fmt" - "github.com/babylonchain/babylon/app" + "github.com/babylonlabs-io/babylon/app" "testing" "github.com/cosmos/cosmos-sdk/crypto/hd" @@ -22,7 +22,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" - bbncmd "github.com/babylonchain/babylon/cmd/babylond/cmd" + bbncmd "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" ) var testMbm = module.NewBasicManager(genutil.AppModuleBasic{}) diff --git a/cmd/babylond/cmd/genesis.go b/cmd/babylond/cmd/genesis.go index 8d7d6cb93..23a6d7dad 100644 --- a/cmd/babylond/cmd/genesis.go +++ b/cmd/babylond/cmd/genesis.go @@ -7,8 +7,8 @@ import ( sdkmath "cosmossdk.io/math" - btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" + btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" comettypes "github.com/cometbft/cometbft/types" "github.com/cosmos/cosmos-sdk/client" @@ -29,12 +29,12 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - appparams "github.com/babylonchain/babylon/app/params" - bbn "github.com/babylonchain/babylon/types" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + appparams "github.com/babylonlabs-io/babylon/app/params" + bbn "github.com/babylonlabs-io/babylon/types" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclightclienttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) func PrepareGenesisCmd(defaultNodeHome string, mbm module.BasicManager) *cobra.Command { diff --git a/cmd/babylond/cmd/genhelpers/bls_add.go b/cmd/babylond/cmd/genhelpers/bls_add.go index 8cae9f906..c8ca06a36 100644 --- a/cmd/babylond/cmd/genhelpers/bls_add.go +++ b/cmd/babylond/cmd/genhelpers/bls_add.go @@ -13,7 +13,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // CmdAddBls CLI adds the BLS key file with proof of possession into the genesis state. diff --git a/cmd/babylond/cmd/genhelpers/bls_add_test.go b/cmd/babylond/cmd/genhelpers/bls_add_test.go index ce5e42545..949b5dd14 100644 --- a/cmd/babylond/cmd/genhelpers/bls_add_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_add_test.go @@ -30,12 +30,12 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/testutil/cli" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/testutil/cli" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func newConfig() depinject.Config { diff --git a/cmd/babylond/cmd/genhelpers/bls_create.go b/cmd/babylond/cmd/genhelpers/bls_create.go index 5c041d738..ac1ab7882 100644 --- a/cmd/babylond/cmd/genhelpers/bls_create.go +++ b/cmd/babylond/cmd/genhelpers/bls_create.go @@ -10,8 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/privval" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/privval" ) // CmdCreateBls CLI command to create BLS file with proof of possession. diff --git a/cmd/babylond/cmd/genhelpers/bls_create_test.go b/cmd/babylond/cmd/genhelpers/bls_create_test.go index 259709372..c036794ac 100644 --- a/cmd/babylond/cmd/genhelpers/bls_create_test.go +++ b/cmd/babylond/cmd/genhelpers/bls_create_test.go @@ -22,10 +22,10 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func Test_CmdCreateBls(t *testing.T) { diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations.go index 15427d573..c4b1f2e28 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_delegations.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations.go @@ -3,7 +3,7 @@ package genhelpers import ( "fmt" - btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/x/genutil" diff --git a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go index a12401389..ccaa5a4bd 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_delegations_test.go @@ -9,12 +9,12 @@ import ( "testing" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/helper" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg" "github.com/cosmos/cosmos-sdk/client" genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" diff --git a/cmd/babylond/cmd/genhelpers/set_btc_headers.go b/cmd/babylond/cmd/genhelpers/set_btc_headers.go index 63014c88a..db30b2f04 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_headers.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_headers.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - btclighttypes "github.com/babylonchain/babylon/x/btclightclient/types" + btclighttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/spf13/cobra" ) diff --git a/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go b/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go index 3659ec232..023c87553 100644 --- a/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go +++ b/cmd/babylond/cmd/genhelpers/set_btc_headers_test.go @@ -8,10 +8,10 @@ import ( "path/filepath" "testing" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" - btclighttypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/helper" + btclighttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/client" genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers.go b/cmd/babylond/cmd/genhelpers/set_finality_providers.go index 5298130c2..b5a8cf40f 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers.go @@ -6,7 +6,7 @@ import ( "os" "path/filepath" - btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" cmtos "github.com/cometbft/cometbft/libs/os" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" diff --git a/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go index d3a97909a..bd3776a78 100644 --- a/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go +++ b/cmd/babylond/cmd/genhelpers/set_finality_providers_test.go @@ -8,10 +8,10 @@ import ( "path/filepath" "testing" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" - btcstktypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/helper" + btcstktypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cometbft/cometbft/libs/tempfile" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" diff --git a/cmd/babylond/cmd/root.go b/cmd/babylond/cmd/root.go index bab90741e..efc9304c1 100644 --- a/cmd/babylond/cmd/root.go +++ b/cmd/babylond/cmd/root.go @@ -8,7 +8,7 @@ import ( confixcmd "cosmossdk.io/tools/confix/cmd" "github.com/CosmWasm/wasmd/x/wasm" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - appkeepers "github.com/babylonchain/babylon/app/keepers" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" cmtcfg "github.com/cometbft/cometbft/config" cmtcli "github.com/cometbft/cometbft/libs/cli" dbm "github.com/cosmos/cosmos-db" @@ -40,9 +40,9 @@ import ( "github.com/spf13/cast" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/cmd/babylond/cmd/genhelpers" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd/genhelpers" ) // NewRootCmd creates a new root command for babylond. It is called once in the diff --git a/cmd/babylond/cmd/testnet.go b/cmd/babylond/cmd/testnet.go index 8ac343ea6..aff015cb5 100644 --- a/cmd/babylond/cmd/testnet.go +++ b/cmd/babylond/cmd/testnet.go @@ -11,7 +11,7 @@ import ( "time" "cosmossdk.io/math" - appkeepers "github.com/babylonchain/babylon/app/keepers" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" cmtconfig "github.com/cometbft/cometbft/config" cmtos "github.com/cometbft/cometbft/libs/os" cmttime "github.com/cometbft/cometbft/types/time" @@ -36,11 +36,11 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) var ( diff --git a/cmd/babylond/cmd/testnet_test.go b/cmd/babylond/cmd/testnet_test.go index 551f0326d..f379b1357 100644 --- a/cmd/babylond/cmd/testnet_test.go +++ b/cmd/babylond/cmd/testnet_test.go @@ -17,7 +17,7 @@ import ( "github.com/spf13/viper" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" + "github.com/babylonlabs-io/babylon/app" ) func Test_TestnetCmd(t *testing.T) { diff --git a/cmd/babylond/cmd/validate_genesis.go b/cmd/babylond/cmd/validate_genesis.go index 61fba3f17..f9ba0c0fc 100644 --- a/cmd/babylond/cmd/validate_genesis.go +++ b/cmd/babylond/cmd/validate_genesis.go @@ -13,7 +13,7 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) const chainUpgradeGuide = "https://github.com/cosmos/cosmos-sdk/blob/a51aa517c46c70df04a06f586c67fb765e45322a/UPGRADING.md" diff --git a/cmd/babylond/cmd/validate_genesis_test.go b/cmd/babylond/cmd/validate_genesis_test.go index 017f50b7e..1248d596d 100644 --- a/cmd/babylond/cmd/validate_genesis_test.go +++ b/cmd/babylond/cmd/validate_genesis_test.go @@ -8,7 +8,7 @@ import ( dbm "github.com/cosmos/cosmos-db" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/x/genutil" "github.com/spf13/viper" @@ -22,8 +22,8 @@ import ( genutiltest "github.com/cosmos/cosmos-sdk/x/genutil/client/testutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" ) func TestCheckCorrespondence(t *testing.T) { diff --git a/cmd/babylond/main.go b/cmd/babylond/main.go index 338f0cb45..7b323f60d 100644 --- a/cmd/babylond/main.go +++ b/cmd/babylond/main.go @@ -4,11 +4,11 @@ import ( "cosmossdk.io/log" "os" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" - "github.com/babylonchain/babylon/app/params" + "github.com/babylonlabs-io/babylon/app/params" ) func main() { diff --git a/contrib/images/Makefile b/contrib/images/Makefile index 3b9d0818e..67e2fc470 100644 --- a/contrib/images/Makefile +++ b/contrib/images/Makefile @@ -3,18 +3,18 @@ RELAYER_TAG := $(shell grep '^ENV RELAYER_TAG' cosmos-relayer/Dockerfile | cut - all: babylond cosmos-relayer babylond: babylond-rmi - docker build --tag babylonchain/babylond -f babylond/Dockerfile \ + docker build --tag babylonlabs-io/babylond -f babylond/Dockerfile \ $(shell git rev-parse --show-toplevel) babylond-rmi: - docker rmi babylonchain/babylond 2>/dev/null; true + docker rmi babylonlabs-io/babylond 2>/dev/null; true cosmos-relayer: cosmos-relayer-rmi - docker build --tag babylonchain/cosmos-relayer:${RELAYER_TAG} -f cosmos-relayer/Dockerfile \ + docker build --tag babylonlabs-io/cosmos-relayer:${RELAYER_TAG} -f cosmos-relayer/Dockerfile \ $(shell git rev-parse --show-toplevel)/contrib/images/cosmos-relayer - docker tag babylonchain/cosmos-relayer:${RELAYER_TAG} babylonchain/cosmos-relayer:latest + docker tag babylonlabs-io/cosmos-relayer:${RELAYER_TAG} babylonlabs-io/cosmos-relayer:latest cosmos-relayer-rmi: - docker rmi babylonchain/cosmos-relayer 2>/dev/null; true + docker rmi babylonlabs-io/cosmos-relayer 2>/dev/null; true .PHONY: all babylond cosmos-relayer babylond-rmi cosmos-relayer-rmi diff --git a/contrib/images/babylond/Dockerfile b/contrib/images/babylond/Dockerfile index 2e8add214..d4e8957fb 100644 --- a/contrib/images/babylond/Dockerfile +++ b/contrib/images/babylond/Dockerfile @@ -15,12 +15,12 @@ ARG COSMOS_BUILD_OPTIONS="" RUN apt-get update && apt-get install -y make git bash gcc curl jq # Build -WORKDIR /go/src/github.com/babylonchain/babylon +WORKDIR /go/src/github.com/babylonlabs-io/babylon # First cache dependencies -COPY go.mod go.sum /go/src/github.com/babylonchain/babylon/ +COPY go.mod go.sum /go/src/github.com/babylonlabs-io/babylon/ RUN go mod download # Then copy everything else -COPY ./ /go/src/github.com/babylonchain/babylon/ +COPY ./ /go/src/github.com/babylonlabs-io/babylon/ # If version is set, then checkout this version RUN if [ -n "${VERSION}" ]; then \ git checkout -f ${VERSION}; \ @@ -38,11 +38,11 @@ RUN addgroup --gid 1137 --system babylon && adduser --uid 1137 --gid 1137 --syst RUN apt-get update && apt-get install -y bash curl jq wget # Label should match your github repo -LABEL org.opencontainers.image.source="https://github.com/babylonchain/babylond:${VERSION}" +LABEL org.opencontainers.image.source="https://github.com/babylonlabs-io/babylond:${VERSION}" # Install libraries # Cosmwasm - Download correct libwasmvm version -COPY --from=build-env /go/src/github.com/babylonchain/babylon/go.mod /tmp +COPY --from=build-env /go/src/github.com/babylonlabs-io/babylon/go.mod /tmp RUN WASMVM_VERSION=$(grep github.com/CosmWasm/wasmvm /tmp/go.mod | cut -d' ' -f2) && \ wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm.$(uname -m).so \ -O /lib/libwasmvm.$(uname -m).so && \ @@ -51,7 +51,7 @@ RUN WASMVM_VERSION=$(grep github.com/CosmWasm/wasmvm /tmp/go.mod | cut -d' ' -f2 sha256sum /lib/libwasmvm.$(uname -m).so | grep $(cat /tmp/checksums.txt | grep libwasmvm.$(uname -m) | cut -d ' ' -f 1) RUN rm -f /tmp/go.mod -COPY --from=build-env /go/src/github.com/babylonchain/babylon/build/babylond /bin/babylond +COPY --from=build-env /go/src/github.com/babylonlabs-io/babylon/build/babylond /bin/babylond # Set home directory and user WORKDIR /home/babylon diff --git a/crypto/bip322/bip322_test.go b/crypto/bip322/bip322_test.go index 22b4f5a13..bbf4d3697 100644 --- a/crypto/bip322/bip322_test.go +++ b/crypto/bip322/bip322_test.go @@ -6,8 +6,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/crypto/bip322" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/crypto/bip322" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" diff --git a/crypto/ecdsa/ecdsa_test.go b/crypto/ecdsa/ecdsa_test.go index 836e49f8a..473eee42c 100644 --- a/crypto/ecdsa/ecdsa_test.go +++ b/crypto/ecdsa/ecdsa_test.go @@ -6,7 +6,7 @@ import ( "encoding/hex" "testing" - "github.com/babylonchain/babylon/crypto/ecdsa" + "github.com/babylonlabs-io/babylon/crypto/ecdsa" "github.com/btcsuite/btcd/btcec/v2" "github.com/stretchr/testify/require" ) diff --git a/crypto/eots/eots_test.go b/crypto/eots/eots_test.go index 91865b4d0..4ff6ab156 100644 --- a/crypto/eots/eots_test.go +++ b/crypto/eots/eots_test.go @@ -6,8 +6,8 @@ import ( mathrand "math/rand" "testing" - "github.com/babylonchain/babylon/crypto/eots" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/stretchr/testify/require" "github.com/vulpine-io/io-test/v1/pkg/iotest" diff --git a/crypto/eots/examples/btc-testnet-txs/main.go b/crypto/eots/examples/btc-testnet-txs/main.go index 4ee467e62..766da8d01 100644 --- a/crypto/eots/examples/btc-testnet-txs/main.go +++ b/crypto/eots/examples/btc-testnet-txs/main.go @@ -8,7 +8,7 @@ import ( "fmt" "os" - "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/crypto/eots" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/crypto/schnorr-adaptor-signature/keys_test.go b/crypto/schnorr-adaptor-signature/keys_test.go index dcc1bcdf8..92b8aee7b 100644 --- a/crypto/schnorr-adaptor-signature/keys_test.go +++ b/crypto/schnorr-adaptor-signature/keys_test.go @@ -3,7 +3,7 @@ package schnorr_adaptor_signature_test import ( "testing" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" "github.com/stretchr/testify/require" ) diff --git a/crypto/schnorr-adaptor-signature/sig_test.go b/crypto/schnorr-adaptor-signature/sig_test.go index 34ee6cd49..83cb49eba 100644 --- a/crypto/schnorr-adaptor-signature/sig_test.go +++ b/crypto/schnorr-adaptor-signature/sig_test.go @@ -7,7 +7,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/stretchr/testify/require" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" ) func FuzzEncSignAndEncVerify(f *testing.F) { diff --git a/docker-compose.yml b/docker-compose.yml index 8b40cf1fa..b92576e3f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: "3" services: babylondnode0: container_name: babylondnode0 - image: "babylonchain/babylond" + image: "babylonlabs-io/babylond" command: > babylond --home /babylondhome start --log_format 'plain' 2>&1 | tee /babylondhome/babylond.log cap_add: @@ -23,7 +23,7 @@ services: babylondnode1: container_name: babylondnode1 - image: "babylonchain/babylond" + image: "babylonlabs-io/babylond" command: > babylond --home /babylondhome start --log_format 'plain' 2>&1 | tee /babylondhome/babylond.log cap_add: @@ -43,7 +43,7 @@ services: babylondnode2: container_name: babylondnode2 - image: "babylonchain/babylond" + image: "babylonlabs-io/babylond" environment: - LOG=${LOG:-babylond.log} command: > @@ -65,7 +65,7 @@ services: babylondnode3: container_name: babylondnode3 - image: "babylonchain/babylond" + image: "babylonlabs-io/babylond" environment: - LOG=${LOG:-babylond.log} command: > diff --git a/docs/architecture.md b/docs/architecture.md index 329e8ec01..ca2f56160 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -210,14 +210,14 @@ this function. Most notably: - [Cosmos Relayer](https://github.com/cosmos/relayer): A fully functional relayer written in Go. -- [Babylon Relayer](https://github.com/babylonchain/babylon-relayer/): +- [Babylon Relayer](https://github.com/babylonlabs-io/babylon-relayer/): A wrapper of the Cosmos Relayer that can maintain a one-way IBC connection. It is recommended to be used when the Consumer Zone does not deploy the Babylon smart contract. - [Hermes Relayer](https://github.com/informalsystems/hermes): A fully functional relayer written in Rust. -### [Babylon Contract](https://github.com/babylonchain/babylon-contract) +### [Babylon Contract](https://github.com/babylonlabs-io/babylon-contract) A [CosmWasm](https://cosmwasm.com/) smart contract intended for deployment in a Consumer Zone. diff --git a/docs/transaction-impl-spec.md b/docs/transaction-impl-spec.md index 4cf55e823..d21a45caf 100644 --- a/docs/transaction-impl-spec.md +++ b/docs/transaction-impl-spec.md @@ -259,7 +259,7 @@ timelock script, the following function could be implemented ```go import ( // Babylon btc staking library - "github.com/babylonchain/babylon/btcstaking" + "github.com/babylonlabs-io/babylon/btcstaking" ) func buildTimelockScriptAndControlBlock( diff --git a/go.mod b/go.mod index 98badadb7..e8ba3e373 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ go 1.21 -module github.com/babylonchain/babylon +module github.com/babylonlabs-io/babylon require ( github.com/CosmWasm/wasmd v0.51.0 diff --git a/privval/file.go b/privval/file.go index 691038593..ebfac1314 100644 --- a/privval/file.go +++ b/privval/file.go @@ -17,8 +17,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/crypto/bls12381" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // copied from github.com/cometbft/cometbft/privval/file.go" diff --git a/privval/types.go b/privval/types.go index 17ed68fcf..be2a302f4 100644 --- a/privval/types.go +++ b/privval/types.go @@ -5,8 +5,8 @@ import ( cmtcrypto "github.com/cometbft/cometbft/crypto" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) type ValidatorKeys struct { diff --git a/proto/babylon/btccheckpoint/v1/btccheckpoint.proto b/proto/babylon/btccheckpoint/v1/btccheckpoint.proto index 8bfef61d6..70b3b5aeb 100644 --- a/proto/babylon/btccheckpoint/v1/btccheckpoint.proto +++ b/proto/babylon/btccheckpoint/v1/btccheckpoint.proto @@ -3,7 +3,7 @@ package babylon.btccheckpoint.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"; // Consider we have a Merkle tree with following structure: // ROOT @@ -36,7 +36,7 @@ message BTCSpvProof { // Should have exactly 80 bytes bytes confirming_btc_header = 4 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" ]; } // Each provided OP_RETURN transaction can be identified by hash of block in @@ -45,7 +45,7 @@ message TransactionKey { uint32 index = 1; bytes hash = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; } // Checkpoint can be composed from multiple transactions, so to identify whole @@ -143,7 +143,7 @@ message BTCCheckpointInfo { // youngest block of best submission bytes best_submission_btc_block_hash = 3 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; // the BTC checkpoint transactions of the best submission repeated TransactionInfo best_submission_transactions = 4; // list of vigilantes' addresses of the best submission diff --git a/proto/babylon/btccheckpoint/v1/genesis.proto b/proto/babylon/btccheckpoint/v1/genesis.proto index 49097c360..4d1187126 100644 --- a/proto/babylon/btccheckpoint/v1/genesis.proto +++ b/proto/babylon/btccheckpoint/v1/genesis.proto @@ -4,7 +4,7 @@ package babylon.btccheckpoint.v1; import "gogoproto/gogo.proto"; import "babylon/btccheckpoint/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"; // GenesisState defines the btccheckpoint module's genesis state. message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/proto/babylon/btccheckpoint/v1/params.proto b/proto/babylon/btccheckpoint/v1/params.proto index 20ed5e6ee..3315aa03d 100644 --- a/proto/babylon/btccheckpoint/v1/params.proto +++ b/proto/babylon/btccheckpoint/v1/params.proto @@ -3,7 +3,7 @@ package babylon.btccheckpoint.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"; // Params defines the parameters for the module. message Params { diff --git a/proto/babylon/btccheckpoint/v1/query.proto b/proto/babylon/btccheckpoint/v1/query.proto index 9fc55b2c8..d7ee344ef 100644 --- a/proto/babylon/btccheckpoint/v1/query.proto +++ b/proto/babylon/btccheckpoint/v1/query.proto @@ -7,7 +7,7 @@ import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btccheckpoint/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/babylon/btccheckpoint/v1/tx.proto b/proto/babylon/btccheckpoint/v1/tx.proto index 38fb5a173..9664ea79c 100644 --- a/proto/babylon/btccheckpoint/v1/tx.proto +++ b/proto/babylon/btccheckpoint/v1/tx.proto @@ -7,7 +7,7 @@ import "cosmos/msg/v1/msg.proto"; import "babylon/btccheckpoint/v1/params.proto"; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/btccheckpoint/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/babylon/btclightclient/v1/btclightclient.proto b/proto/babylon/btclightclient/v1/btclightclient.proto index f5300706c..d38314f3d 100644 --- a/proto/babylon/btclightclient/v1/btclightclient.proto +++ b/proto/babylon/btclightclient/v1/btclightclient.proto @@ -3,7 +3,7 @@ package babylon.btclightclient.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // BTCHeaderInfo is a structure that contains all relevant information about a // BTC header @@ -16,10 +16,10 @@ option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; message BTCHeaderInfo { bytes header = 1 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" ]; bytes hash = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; uint64 height = 3; bytes work = 4 [ (gogoproto.customtype) = "cosmossdk.io/math.Uint" ]; diff --git a/proto/babylon/btclightclient/v1/event.proto b/proto/babylon/btclightclient/v1/event.proto index 4b1a3a0af..4e29ad384 100644 --- a/proto/babylon/btclightclient/v1/event.proto +++ b/proto/babylon/btclightclient/v1/event.proto @@ -3,7 +3,7 @@ package babylon.btclightclient.v1; import "babylon/btclightclient/v1/btclightclient.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // The header included in the event is the block in the history // of the current mainchain to which we are rolling back to. diff --git a/proto/babylon/btclightclient/v1/genesis.proto b/proto/babylon/btclightclient/v1/genesis.proto index 4d747e3f7..2ed0d830b 100644 --- a/proto/babylon/btclightclient/v1/genesis.proto +++ b/proto/babylon/btclightclient/v1/genesis.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "babylon/btclightclient/v1/btclightclient.proto"; import "babylon/btclightclient/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // GenesisState defines the btclightclient module's genesis state. message GenesisState { diff --git a/proto/babylon/btclightclient/v1/params.proto b/proto/babylon/btclightclient/v1/params.proto index ea0f0c709..7ca7c5757 100644 --- a/proto/babylon/btclightclient/v1/params.proto +++ b/proto/babylon/btclightclient/v1/params.proto @@ -4,7 +4,7 @@ package babylon.btclightclient.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // Params defines the parameters for the module. message Params { diff --git a/proto/babylon/btclightclient/v1/query.proto b/proto/babylon/btclightclient/v1/query.proto index 60ae07cc2..51ea46cf1 100644 --- a/proto/babylon/btclightclient/v1/query.proto +++ b/proto/babylon/btclightclient/v1/query.proto @@ -7,7 +7,7 @@ import "google/api/annotations.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/btclightclient/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // Query defines the gRPC querier service. service Query { @@ -28,7 +28,7 @@ service Query { // ContainsBytes is a temporary method that // checks whether a hash is maintained by the module. - // See discussion at https://github.com/babylonchain/babylon/pull/132 + // See discussion at https://github.com/babylonlabs-io/babylon/pull/132 // for more details. rpc ContainsBytes(QueryContainsBytesRequest) returns (QueryContainsBytesResponse) { @@ -77,7 +77,7 @@ message QueryHashesRequest { message QueryHashesResponse { repeated bytes hashes = 1 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -86,7 +86,7 @@ message QueryHashesResponse { message QueryContainsRequest { bytes hash = 1 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; } // QueryContainsResponse is response type for the Query/Contains RPC method. diff --git a/proto/babylon/btclightclient/v1/tx.proto b/proto/babylon/btclightclient/v1/tx.proto index 1c884ba87..421508712 100644 --- a/proto/babylon/btclightclient/v1/tx.proto +++ b/proto/babylon/btclightclient/v1/tx.proto @@ -6,7 +6,7 @@ import "cosmos/msg/v1/msg.proto"; import "babylon/btclightclient/v1/params.proto"; import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/babylonchain/babylon/x/btclightclient/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btclightclient/types"; // Msg defines the Msg service. service Msg { @@ -26,7 +26,7 @@ message MsgInsertHeaders { string signer = 1; repeated bytes headers = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" ]; } // MsgInsertHeadersResponse defines the response for the InsertHeaders transaction message MsgInsertHeadersResponse {} diff --git a/proto/babylon/btcstaking/v1/btcstaking.proto b/proto/babylon/btcstaking/v1/btcstaking.proto index e8fcc14de..183694036 100644 --- a/proto/babylon/btcstaking/v1/btcstaking.proto +++ b/proto/babylon/btcstaking/v1/btcstaking.proto @@ -6,7 +6,7 @@ import "cosmos_proto/cosmos.proto"; import "cosmos/staking/v1beta1/staking.proto"; import "babylon/btcstaking/v1/pop.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // FinalityProvider defines a finality provider message FinalityProvider { @@ -21,7 +21,7 @@ message FinalityProvider { ]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of the btc_pk, where the BTC // private key signs the bech32 bbn addr of the finality provider. ProofOfPossessionBTC pop = 5; @@ -41,7 +41,7 @@ message FinalityProvider { message FinalityProviderWithMeta { // btc_pk is the Bitcoin secp256k1 PK of thisfinality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // height is the queried Babylon height uint64 height = 2; // voting_power is the voting power of this finality provider at the given height @@ -64,14 +64,14 @@ message BTCDelegation { string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossessionBTC pop = 3; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to // If there is more than 1 PKs, then this means the delegation is restaked // to multiple finality providers - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock uint64 start_height = 5; @@ -92,7 +92,7 @@ message BTCDelegation { // delegator_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. - bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -121,11 +121,11 @@ message BTCUndelegation { // It effectively proves that the delegator wants to unbond and thus // Babylon will consider this BTC delegation unbonded. Delegator's BTC // on Bitcoin will be unbonded after timelock - bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // delegator_slashing_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the unbonding tx output. - bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // covenant_slashing_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -165,15 +165,15 @@ enum BTCDelegationStatus { // SignatureInfo is a BIP-340 signature together with its signer's BIP-340 PK message SignatureInfo { - bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; - bytes sig = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes sig = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } // CovenantAdaptorSignatures is a list adaptor signatures signed by the // covenant with different finality provider's public keys as encryption keys message CovenantAdaptorSignatures { // cov_pk is the public key of the covenant emulator, used as the public key of the adaptor signature - bytes cov_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes cov_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // adaptor_sigs is a list of adaptor signatures, each encrypted by a restaked BTC finality provider's public key repeated bytes adaptor_sigs = 2; } @@ -190,7 +190,7 @@ message SelectiveSlashingEvidence { string staking_tx_hash = 1; // fp_btc_pk is the BTC PK of the finality provider who // launches the selective slashing offence - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // recovered_fp_btc_sk is the finality provider's BTC SK recovered from // the covenant adaptor/Schnorr signature pair. It is the consequence // of selective slashing. diff --git a/proto/babylon/btcstaking/v1/events.proto b/proto/babylon/btcstaking/v1/events.proto index 1de3137a6..a8d4fb3e4 100644 --- a/proto/babylon/btcstaking/v1/events.proto +++ b/proto/babylon/btcstaking/v1/events.proto @@ -4,7 +4,7 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "babylon/btcstaking/v1/btcstaking.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // EventNewFinalityProvider is the event emitted when a finality provider is created message EventNewFinalityProvider { FinalityProvider fp = 1; } @@ -37,7 +37,7 @@ message EventPowerDistUpdate { // is slashed // TODO: unify with existing slashing events message EventSlashedFinalityProvider { - bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; } // ev is the event that affects voting power distribution diff --git a/proto/babylon/btcstaking/v1/genesis.proto b/proto/babylon/btcstaking/v1/genesis.proto index bc8529454..2e5d5966e 100644 --- a/proto/babylon/btcstaking/v1/genesis.proto +++ b/proto/babylon/btcstaking/v1/genesis.proto @@ -7,7 +7,7 @@ import "babylon/btcstaking/v1/btcstaking.proto"; import "babylon/btcstaking/v1/incentive.proto"; import "babylon/btcstaking/v1/events.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // GenesisState defines the btcstaking module's genesis state. message GenesisState { @@ -36,7 +36,7 @@ message VotingPowerFP { // block_height is the height of the block the voting power was stored. uint64 block_height = 1; // fp_btc_pk the finality provider btc public key. - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // voting_power is the power of the finality provider at this specific block height. uint64 voting_power = 3; } @@ -62,9 +62,9 @@ message BTCDelegator { // idx the btc delegator index. BTCDelegatorDelegationIndex idx = 1; // fp_btc_pk the finality provider btc public key. - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // del_btc_pk the delegator btc public key. - bytes del_btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes del_btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; } // EventIndex contains the event and its index. diff --git a/proto/babylon/btcstaking/v1/incentive.proto b/proto/babylon/btcstaking/v1/incentive.proto index 8072a5d44..7dcde01f8 100644 --- a/proto/babylon/btcstaking/v1/incentive.proto +++ b/proto/babylon/btcstaking/v1/incentive.proto @@ -4,7 +4,7 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // VotingPowerDistCache is the cache for voting power distribution of finality providers // and their BTC delegations at a height @@ -18,7 +18,7 @@ message VotingPowerDistCache { message FinalityProviderDistInfo { // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // addr is the address to receive commission from delegations. string addr = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // commission defines the commission rate of finality provider @@ -36,7 +36,7 @@ message FinalityProviderDistInfo { message BTCDelDistInfo { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // staker_addr is the address to receive rewards from BTC delegation. string staker_addr = 2 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // staking_tx_hash is the staking tx hash of the BTC delegation diff --git a/proto/babylon/btcstaking/v1/params.proto b/proto/babylon/btcstaking/v1/params.proto index d705a3c1f..5746ffb25 100644 --- a/proto/babylon/btcstaking/v1/params.proto +++ b/proto/babylon/btcstaking/v1/params.proto @@ -4,7 +4,7 @@ package babylon.btcstaking.v1; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // Params defines the parameters for the module. message Params { @@ -12,7 +12,7 @@ message Params { // covenant_pks is the list of public keys held by the covenant committee // each PK follows encoding in BIP-340 spec on Bitcoin - repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // covenant_quorum is the minimum number of signatures needed for the covenant // multisignature uint32 covenant_quorum = 2; diff --git a/proto/babylon/btcstaking/v1/pop.proto b/proto/babylon/btcstaking/v1/pop.proto index 4762d3c12..316bb1df7 100644 --- a/proto/babylon/btcstaking/v1/pop.proto +++ b/proto/babylon/btcstaking/v1/pop.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package babylon.btcstaking.v1; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // BTCSigType indicates the type of btc_sig in a pop enum BTCSigType { diff --git a/proto/babylon/btcstaking/v1/query.proto b/proto/babylon/btcstaking/v1/query.proto index 5b4417568..3f9aabe51 100644 --- a/proto/babylon/btcstaking/v1/query.proto +++ b/proto/babylon/btcstaking/v1/query.proto @@ -10,7 +10,7 @@ import "babylon/btcstaking/v1/params.proto"; import "babylon/btcstaking/v1/btcstaking.proto"; import "babylon/btcstaking/v1/pop.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // Query defines the gRPC querier service. service Query { @@ -247,10 +247,10 @@ message BTCDelegationResponse { string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to - repeated bytes fp_btc_pk_list = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock uint64 start_height = 4; @@ -333,7 +333,7 @@ message FinalityProviderResponse { string addr = 3 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of the BTC_PK by the fp addr. // Essentially is the signature where the BTC SK sigs the fp addr. ProofOfPossessionBTC pop = 5; diff --git a/proto/babylon/btcstaking/v1/tx.proto b/proto/babylon/btcstaking/v1/tx.proto index e2cdcbf6b..61500d480 100644 --- a/proto/babylon/btcstaking/v1/tx.proto +++ b/proto/babylon/btcstaking/v1/tx.proto @@ -9,7 +9,7 @@ import "babylon/btccheckpoint/v1/btccheckpoint.proto"; import "cosmos/staking/v1beta1/staking.proto"; import "babylon/btcstaking/v1/pop.proto"; -option go_package = "github.com/babylonchain/babylon/x/btcstaking/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/btcstaking/types"; // Msg defines the Msg service. // TODO: handle unbonding tx with full witness @@ -48,7 +48,7 @@ message MsgCreateFinalityProvider { ]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of btc_pk over the FP signer address. ProofOfPossessionBTC pop = 5; } @@ -82,10 +82,10 @@ message MsgCreateBTCDelegation { // pop is the proof of possession of btc_pk by the staker_addr. ProofOfPossessionBTC pop = 2; // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // staking_time is the time lock used in staking transaction uint32 staking_time = 5; // staking_value is the amount of satoshis locked in staking output @@ -99,7 +99,7 @@ message MsgCreateBTCDelegation { // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output @@ -117,7 +117,7 @@ message MsgCreateBTCDelegation { // Note that the tx itself does not contain signatures, which are off-chain. bytes unbonding_slashing_tx = 13 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } // MsgCreateBTCDelegationResponse is the response for MsgCreateBTCDelegation message MsgCreateBTCDelegationResponse {} @@ -128,7 +128,7 @@ message MsgAddCovenantSigs { string signer = 1; // pk is the BTC public key of the covenant member - bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 3; @@ -138,7 +138,7 @@ message MsgAddCovenantSigs { repeated bytes slashing_tx_sigs = 4; // unbonding_tx_sig is the signature of the covenant on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - bytes unbonding_tx_sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes unbonding_tx_sig = 5 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // slashing_unbonding_tx_sigs is a list of adaptor signatures of the covenant // on slashing tx corresponding to unbonding tx submitted to babylon // the order of sigs should respect the order of finality providers @@ -160,7 +160,7 @@ message MsgBTCUndelegate { string staking_tx_hash = 2; // unbonding_tx_sig is the signature of the staker on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - bytes unbonding_tx_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes unbonding_tx_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } // MsgBTCUndelegateResponse is the response for MsgBTCUndelegate message MsgBTCUndelegateResponse {} diff --git a/proto/babylon/checkpointing/v1/bls_key.proto b/proto/babylon/checkpointing/v1/bls_key.proto index 4ea1363c5..912f9dd63 100644 --- a/proto/babylon/checkpointing/v1/bls_key.proto +++ b/proto/babylon/checkpointing/v1/bls_key.proto @@ -3,14 +3,14 @@ package babylon.checkpointing.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // BlsKey wraps BLS public key with PoP message BlsKey { // pubkey is the BLS public key of a validator bytes pubkey = 1 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.PublicKey" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" ]; // pop is the proof-of-possession of the BLS key ProofOfPossession pop = 2; @@ -26,7 +26,7 @@ message ProofOfPossession { // ed25519_sig) bytes bls_sig = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } // ValidatorWithBLSSet defines a set of validators with their BLS public keys @@ -58,5 +58,5 @@ message VoteExtension { // bls_sig is the BLS signature bytes bls_sig = 6 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } diff --git a/proto/babylon/checkpointing/v1/checkpoint.proto b/proto/babylon/checkpointing/v1/checkpoint.proto index 208a191d4..309447a7a 100644 --- a/proto/babylon/checkpointing/v1/checkpoint.proto +++ b/proto/babylon/checkpointing/v1/checkpoint.proto @@ -5,7 +5,7 @@ import "google/protobuf/timestamp.proto"; import "gogoproto/gogo.proto"; import "tendermint/abci/types.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // RawCheckpoint wraps the BLS multi sig with metadata message RawCheckpoint { @@ -22,7 +22,7 @@ message RawCheckpoint { // sigs bytes bls_multi_sig = 4 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } // RawCheckpointWithMeta wraps the raw checkpoint with metadata. @@ -35,7 +35,7 @@ message RawCheckpointWithMeta { // bls_aggr_pk defines the aggregated BLS public key bytes bls_aggr_pk = 3 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.PublicKey" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" ]; // power_sum defines the accumulated voting power for the checkpoint uint64 power_sum = 4; // lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -94,7 +94,7 @@ message BlsSig { bytes block_hash = 2 [ (gogoproto.customtype) = "BlockHash" ]; bytes bls_sig = 3 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; // can't find cosmos_proto.scalar when compiling due to cosmos v0.45.4 does // not support scalar string signer_address = 4 [(cosmos_proto.scalar) = // "cosmos.AddressString"] diff --git a/proto/babylon/checkpointing/v1/events.proto b/proto/babylon/checkpointing/v1/events.proto index 4e170c058..090888b0a 100644 --- a/proto/babylon/checkpointing/v1/events.proto +++ b/proto/babylon/checkpointing/v1/events.proto @@ -3,7 +3,7 @@ package babylon.checkpointing.v1; import "babylon/checkpointing/v1/checkpoint.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // EventCheckpointAccumulating is emitted when a checkpoint reaches the // `Accumulating` state. diff --git a/proto/babylon/checkpointing/v1/genesis.proto b/proto/babylon/checkpointing/v1/genesis.proto index dd65d5017..dd96841a2 100644 --- a/proto/babylon/checkpointing/v1/genesis.proto +++ b/proto/babylon/checkpointing/v1/genesis.proto @@ -4,7 +4,7 @@ package babylon.checkpointing.v1; import "cosmos/crypto/ed25519/keys.proto"; import "babylon/checkpointing/v1/bls_key.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // GenesisState defines the checkpointing module's genesis state. message GenesisState { diff --git a/proto/babylon/checkpointing/v1/query.proto b/proto/babylon/checkpointing/v1/query.proto index a7ee01e16..74c9853f7 100644 --- a/proto/babylon/checkpointing/v1/query.proto +++ b/proto/babylon/checkpointing/v1/query.proto @@ -8,7 +8,7 @@ import "babylon/checkpointing/v1/bls_key.proto"; import "babylon/checkpointing/v1/checkpoint.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // Query defines the gRPC querier service. service Query { @@ -177,7 +177,7 @@ message RawCheckpointResponse { // bls_multi_sig defines the multi sig that is aggregated from individual BLS // sigs bytes bls_multi_sig = 4 [ - (gogoproto.customtype) = "github.com/babylonchain/babylon/crypto/bls12381.Signature" + (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } @@ -205,7 +205,7 @@ message RawCheckpointWithMetaResponse { // bls_aggr_pk defines the aggregated BLS public key bytes bls_aggr_pk = 4 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.PublicKey" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" ]; // power_sum defines the accumulated voting power for the checkpoint uint64 power_sum = 5; // lifecycle defines the lifecycle of this checkpoint, i.e., each state diff --git a/proto/babylon/checkpointing/v1/tx.proto b/proto/babylon/checkpointing/v1/tx.proto index bfc00666e..14709eee3 100644 --- a/proto/babylon/checkpointing/v1/tx.proto +++ b/proto/babylon/checkpointing/v1/tx.proto @@ -6,7 +6,7 @@ import "babylon/checkpointing/v1/bls_key.proto"; import "cosmos/staking/v1beta1/tx.proto"; import "cosmos/msg/v1/msg.proto"; -option go_package = "github.com/babylonchain/babylon/x/checkpointing/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/checkpointing/types"; // Msg defines the checkpointing Msg service. service Msg { diff --git a/proto/babylon/epoching/v1/epoching.proto b/proto/babylon/epoching/v1/epoching.proto index 79e579119..a7f90c4a1 100644 --- a/proto/babylon/epoching/v1/epoching.proto +++ b/proto/babylon/epoching/v1/epoching.proto @@ -6,7 +6,7 @@ import "gogoproto/gogo.proto"; import "cosmos/staking/v1beta1/tx.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // Epoch is a structure that contains the metadata of an epoch message Epoch { diff --git a/proto/babylon/epoching/v1/events.proto b/proto/babylon/epoching/v1/events.proto index f41c527e3..79e0dfae2 100644 --- a/proto/babylon/epoching/v1/events.proto +++ b/proto/babylon/epoching/v1/events.proto @@ -3,7 +3,7 @@ package babylon.epoching.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // EventBeginEpoch is the event emitted when an epoch has started message EventBeginEpoch { uint64 epoch_number = 1; } diff --git a/proto/babylon/epoching/v1/genesis.proto b/proto/babylon/epoching/v1/genesis.proto index eea522cba..f9c44d5b5 100644 --- a/proto/babylon/epoching/v1/genesis.proto +++ b/proto/babylon/epoching/v1/genesis.proto @@ -4,7 +4,7 @@ package babylon.epoching.v1; import "gogoproto/gogo.proto"; import "babylon/epoching/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // GenesisState defines the epoching module's genesis state. message GenesisState { Params params = 1 [ (gogoproto.nullable) = false ]; } diff --git a/proto/babylon/epoching/v1/params.proto b/proto/babylon/epoching/v1/params.proto index a9ce9a531..b315f37ca 100644 --- a/proto/babylon/epoching/v1/params.proto +++ b/proto/babylon/epoching/v1/params.proto @@ -3,7 +3,7 @@ package babylon.epoching.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // Params defines the parameters for the module. message Params { diff --git a/proto/babylon/epoching/v1/query.proto b/proto/babylon/epoching/v1/query.proto index e86999302..7243da42c 100644 --- a/proto/babylon/epoching/v1/query.proto +++ b/proto/babylon/epoching/v1/query.proto @@ -8,7 +8,7 @@ import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/epoching/v1/params.proto"; import "babylon/epoching/v1/epoching.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/babylon/epoching/v1/tx.proto b/proto/babylon/epoching/v1/tx.proto index 47f24da33..2157dea0c 100644 --- a/proto/babylon/epoching/v1/tx.proto +++ b/proto/babylon/epoching/v1/tx.proto @@ -8,7 +8,7 @@ import "babylon/epoching/v1/params.proto"; import "cosmos_proto/cosmos.proto"; import "cosmos/msg/v1/msg.proto"; -option go_package = "github.com/babylonchain/babylon/x/epoching/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/epoching/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/babylon/finality/v1/events.proto b/proto/babylon/finality/v1/events.proto index 436456dea..1c2fe0947 100644 --- a/proto/babylon/finality/v1/events.proto +++ b/proto/babylon/finality/v1/events.proto @@ -3,7 +3,7 @@ package babylon.finality.v1; import "babylon/finality/v1/finality.proto"; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; // EventSlashedFinalityProvider is the event emitted when a finality provider is slashed // due to signing two conflicting blocks diff --git a/proto/babylon/finality/v1/finality.proto b/proto/babylon/finality/v1/finality.proto index c833f5fc6..f6f56f6d9 100644 --- a/proto/babylon/finality/v1/finality.proto +++ b/proto/babylon/finality/v1/finality.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package babylon.finality.v1; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; import "gogoproto/gogo.proto"; @@ -33,11 +33,11 @@ message PubRandCommit { // signatures with correct public randomness on two conflicting Babylon headers message Evidence { // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // block_height is the height of the conflicting blocks uint64 block_height = 2; // pub_rand is the public randomness the finality provider has committed to - bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrPubRand" ]; // canonical_app_hash is the AppHash of the canonical block bytes canonical_app_hash = 4; // fork_app_hash is the AppHash of the fork block @@ -46,17 +46,17 @@ message Evidence { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - bytes canonical_finality_sig = 6 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes canonical_finality_sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; // fork_finality_sig is the finality signature to the fork block // where finality signature is an EOTS signature - bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; } // FinalityProviderSigningInfo defines a finality provider's signing info for monitoring their // liveness activity. message FinalityProviderSigningInfo { // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the block height at which finality provider become active int64 start_height = 2; // missed_blocks_counter defines a counter to avoid unnecessary array reads. diff --git a/proto/babylon/finality/v1/genesis.proto b/proto/babylon/finality/v1/genesis.proto index af3ef6cd6..4e40c9bd0 100644 --- a/proto/babylon/finality/v1/genesis.proto +++ b/proto/babylon/finality/v1/genesis.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "babylon/finality/v1/params.proto"; import "babylon/finality/v1/finality.proto"; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; // GenesisState defines the finality module's genesis state. message GenesisState { @@ -35,10 +35,10 @@ message VoteSig { // block_height is the height of the voted block. uint64 block_height = 1; // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // finality_sig is the finality signature to this block // where finality signature is an EOTS signature, i.e. - bytes finality_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes finality_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; } // PublicRandomness the block height and public randomness that the finality provider has submitted. @@ -46,15 +46,15 @@ message PublicRandomness { // block_height is the height of block which the finality provider submited public randomness. uint64 block_height = 1; // fp_btc_pk is the BTC PK of the finality provider that casts this vote. - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pub_rand is the public randomness the finality provider has committed to. - bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + bytes pub_rand = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrPubRand" ]; } // PubRandCommitWithPK is the public randomness commitment with the finality provider's BTC public key message PubRandCommitWithPK { // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pub_rand_commit is the public randomness commitment PubRandCommit pub_rand_commit = 2; } @@ -62,7 +62,7 @@ message PubRandCommitWithPK { // SigningInfo stores finality provider signing info of corresponding BTC public key. message SigningInfo { // fp_btc_pk is the BTC PK of the finality provider - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // fp_signing_info represents the signing info of this finality provider. FinalityProviderSigningInfo fp_signing_info = 2 [(gogoproto.nullable) = false]; } @@ -71,7 +71,7 @@ message SigningInfo { // BTC public key. message FinalityProviderMissedBlocks { // fp_btc_pk is the BTC PK of the finality provider - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // missed_blocks is an array of missed blocks by the finality provider. repeated MissedBlock missed_blocks = 2 [(gogoproto.nullable) = false]; } diff --git a/proto/babylon/finality/v1/params.proto b/proto/babylon/finality/v1/params.proto index 67751c58d..875497283 100644 --- a/proto/babylon/finality/v1/params.proto +++ b/proto/babylon/finality/v1/params.proto @@ -5,7 +5,7 @@ import "gogoproto/gogo.proto"; import "amino/amino.proto"; import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; // Params defines the parameters for the module. message Params { diff --git a/proto/babylon/finality/v1/query.proto b/proto/babylon/finality/v1/query.proto index 270834f72..7b6c9fb0b 100644 --- a/proto/babylon/finality/v1/query.proto +++ b/proto/babylon/finality/v1/query.proto @@ -7,7 +7,7 @@ import "cosmos/base/query/v1beta1/pagination.proto"; import "babylon/finality/v1/params.proto"; import "babylon/finality/v1/finality.proto"; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; // Query defines the gRPC querier service. service Query { @@ -90,7 +90,7 @@ message QueryListPublicRandomnessRequest { message QueryListPublicRandomnessResponse { // pub_rand_map is the map where the key is the height and the value // is the public randomness at this height for the given finality provider - map pub_rand_map = 1 [(gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + map pub_rand_map = 1 [(gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrPubRand" ]; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; @@ -181,7 +181,7 @@ message QueryVotesAtHeightRequest { message QueryVotesAtHeightResponse { // btc_pk is the Bitcoin secp256k1 PK of finality providers who have signed the block at given height. // the PK follows encoding in BIP-340 spec - repeated bytes btc_pks = 1 [(gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey"]; + repeated bytes btc_pks = 1 [(gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey"]; } // QueryEvidenceRequest is the request type for the diff --git a/proto/babylon/finality/v1/tx.proto b/proto/babylon/finality/v1/tx.proto index c1ff68ea2..fd46f9f3a 100644 --- a/proto/babylon/finality/v1/tx.proto +++ b/proto/babylon/finality/v1/tx.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package babylon.finality.v1; -option go_package = "github.com/babylonchain/babylon/x/finality/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/finality/types"; import "gogoproto/gogo.proto"; import "tendermint/crypto/proof.proto"; @@ -28,7 +28,7 @@ message MsgCommitPubRandList { string signer = 1; // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the start block height of the list of public randomness uint64 start_height = 3; // num_pub_rand is the number of public randomness committed @@ -41,7 +41,7 @@ message MsgCommitPubRandList { // randomness on behalf of fp_btc_pk // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts // the tx submitter to be the holder of fp_btc_pk. Decide this later - bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } // MsgCommitPubRandListResponse is the response to the MsgCommitPubRandList message message MsgCommitPubRandListResponse{} @@ -52,11 +52,11 @@ message MsgAddFinalitySig { string signer = 1; // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // block_height is the height of the voted block uint64 block_height = 3; // pub_rand is the public randomness committed at this height - bytes pub_rand = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrPubRand" ]; + bytes pub_rand = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrPubRand" ]; // proof is the proof that the given public randomness is committed under the commitment tendermint.crypto.Proof proof = 5; // block_app_hash is the AppHash of the voted block @@ -65,7 +65,7 @@ message MsgAddFinalitySig { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - bytes finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; } // MsgAddFinalitySigResponse is the response to the MsgAddFinalitySig message message MsgAddFinalitySigResponse{} diff --git a/proto/babylon/incentive/genesis.proto b/proto/babylon/incentive/genesis.proto index 04f82d21a..efe84b06f 100644 --- a/proto/babylon/incentive/genesis.proto +++ b/proto/babylon/incentive/genesis.proto @@ -4,7 +4,7 @@ package babylon.incentive; import "gogoproto/gogo.proto"; import "babylon/incentive/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/incentive/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/incentive/types"; // GenesisState defines the incentive module's genesis state. message GenesisState { diff --git a/proto/babylon/incentive/incentive.proto b/proto/babylon/incentive/incentive.proto index ccc4c3a6c..1e606919f 100644 --- a/proto/babylon/incentive/incentive.proto +++ b/proto/babylon/incentive/incentive.proto @@ -4,7 +4,7 @@ package babylon.incentive; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -option go_package = "github.com/babylonchain/babylon/x/incentive/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/incentive/types"; // Gauge is an object that stores rewards to be distributed // code adapted from https://github.com/osmosis-labs/osmosis/blob/v18.0.0/proto/osmosis/incentives/gauge.proto diff --git a/proto/babylon/incentive/params.proto b/proto/babylon/incentive/params.proto index c576cb9a4..8f5f6d54a 100644 --- a/proto/babylon/incentive/params.proto +++ b/proto/babylon/incentive/params.proto @@ -4,7 +4,7 @@ package babylon.incentive; import "gogoproto/gogo.proto"; import "cosmos_proto/cosmos.proto"; -option go_package = "github.com/babylonchain/babylon/x/incentive/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/incentive/types"; // Params defines the parameters for the module, including portions of rewards // distributed to each type of stakeholder. Note that sum of the portions should diff --git a/proto/babylon/incentive/query.proto b/proto/babylon/incentive/query.proto index 1239786e1..f31a511cb 100644 --- a/proto/babylon/incentive/query.proto +++ b/proto/babylon/incentive/query.proto @@ -6,7 +6,7 @@ import "google/api/annotations.proto"; import "babylon/incentive/params.proto"; import "babylon/incentive/incentive.proto"; -option go_package = "github.com/babylonchain/babylon/x/incentive/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/incentive/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/babylon/incentive/tx.proto b/proto/babylon/incentive/tx.proto index 965147bd5..13810102e 100644 --- a/proto/babylon/incentive/tx.proto +++ b/proto/babylon/incentive/tx.proto @@ -7,7 +7,7 @@ import "cosmos/msg/v1/msg.proto"; import "cosmos/base/v1beta1/coin.proto"; import "babylon/incentive/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/incentive/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/incentive/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/babylon/monitor/v1/genesis.proto b/proto/babylon/monitor/v1/genesis.proto index 66a259f15..b1e60078d 100644 --- a/proto/babylon/monitor/v1/genesis.proto +++ b/proto/babylon/monitor/v1/genesis.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package babylon.monitor.v1; -option go_package = "github.com/babylonchain/babylon/x/monitor/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/monitor/types"; // GenesisState defines the monitor module's genesis state. message GenesisState {} diff --git a/proto/babylon/monitor/v1/query.proto b/proto/babylon/monitor/v1/query.proto index 622305a34..c77bfc8f2 100644 --- a/proto/babylon/monitor/v1/query.proto +++ b/proto/babylon/monitor/v1/query.proto @@ -3,7 +3,7 @@ package babylon.monitor.v1; import "google/api/annotations.proto"; -option go_package = "github.com/babylonchain/babylon/x/monitor/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/monitor/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/babylon/zoneconcierge/v1/genesis.proto b/proto/babylon/zoneconcierge/v1/genesis.proto index 468fa02eb..8277e9e8a 100644 --- a/proto/babylon/zoneconcierge/v1/genesis.proto +++ b/proto/babylon/zoneconcierge/v1/genesis.proto @@ -4,7 +4,7 @@ package babylon.zoneconcierge.v1; import "gogoproto/gogo.proto"; import "babylon/zoneconcierge/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // GenesisState defines the zoneconcierge module's genesis state. message GenesisState { diff --git a/proto/babylon/zoneconcierge/v1/packet.proto b/proto/babylon/zoneconcierge/v1/packet.proto index a9b4ef163..9576b951c 100644 --- a/proto/babylon/zoneconcierge/v1/packet.proto +++ b/proto/babylon/zoneconcierge/v1/packet.proto @@ -7,7 +7,7 @@ import "babylon/btclightclient/v1/btclightclient.proto"; import "babylon/epoching/v1/epoching.proto"; import "babylon/zoneconcierge/v1/zoneconcierge.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // ZoneconciergePacketData is the message that defines the IBC packets of // ZoneConcierge diff --git a/proto/babylon/zoneconcierge/v1/params.proto b/proto/babylon/zoneconcierge/v1/params.proto index bb3e23738..48fa6c9e5 100644 --- a/proto/babylon/zoneconcierge/v1/params.proto +++ b/proto/babylon/zoneconcierge/v1/params.proto @@ -3,7 +3,7 @@ package babylon.zoneconcierge.v1; import "gogoproto/gogo.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // Params defines the parameters for the module. message Params { diff --git a/proto/babylon/zoneconcierge/v1/query.proto b/proto/babylon/zoneconcierge/v1/query.proto index aa65a805f..690ab0182 100644 --- a/proto/babylon/zoneconcierge/v1/query.proto +++ b/proto/babylon/zoneconcierge/v1/query.proto @@ -10,7 +10,7 @@ import "babylon/epoching/v1/epoching.proto"; import "babylon/zoneconcierge/v1/zoneconcierge.proto"; import "babylon/zoneconcierge/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // Query defines the gRPC querier service. service Query { diff --git a/proto/babylon/zoneconcierge/v1/tx.proto b/proto/babylon/zoneconcierge/v1/tx.proto index 105a29107..5e94ee9f4 100644 --- a/proto/babylon/zoneconcierge/v1/tx.proto +++ b/proto/babylon/zoneconcierge/v1/tx.proto @@ -7,7 +7,7 @@ import "cosmos_proto/cosmos.proto"; import "cosmos/msg/v1/msg.proto"; import "babylon/zoneconcierge/v1/params.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // Msg defines the Msg service. service Msg { diff --git a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto index 47e316a0f..b6c1dde8c 100644 --- a/proto/babylon/zoneconcierge/v1/zoneconcierge.proto +++ b/proto/babylon/zoneconcierge/v1/zoneconcierge.proto @@ -10,7 +10,7 @@ import "babylon/checkpointing/v1/checkpoint.proto"; import "babylon/epoching/v1/epoching.proto"; import "babylon/btclightclient/v1/btclightclient.proto"; -option go_package = "github.com/babylonchain/babylon/x/zoneconcierge/types"; +option go_package = "github.com/babylonlabs-io/babylon/x/zoneconcierge/types"; // IndexedHeader is the metadata of a CZ header message IndexedHeader { diff --git a/proto/scripts/protocgen.sh b/proto/scripts/protocgen.sh index 9cbce2e51..a61d0e936 100755 --- a/proto/scripts/protocgen.sh +++ b/proto/scripts/protocgen.sh @@ -16,7 +16,7 @@ done cd .. # move proto files to the right places -cp -r github.com/babylonchain/babylon/* ./ +cp -r github.com/babylonlabs-io/babylon/* ./ rm -rf github.com go mod tidy -compat=1.21 diff --git a/test/e2e/README.md b/test/e2e/README.md index d29a6539a..dacd487f7 100644 --- a/test/e2e/README.md +++ b/test/e2e/README.md @@ -9,7 +9,7 @@ approach. ### Wasm contract used for e2e testing -Wasm contract located in `bytecode/babylon_contract.wasm` is compiled from most recent commit `main` branch - https://github.com/babylonchain/babylon-contract +Wasm contract located in `bytecode/babylon_contract.wasm` is compiled from most recent commit `main` branch - https://github.com/babylonlabs-io/babylon-contract This contract uses feature specific to Babylon, through Babylon bindings library. diff --git a/test/e2e/btc_staking_e2e_test.go b/test/e2e/btc_staking_e2e_test.go index e76a83c11..d4bcf2775 100644 --- a/test/e2e/btc_staking_e2e_test.go +++ b/test/e2e/btc_staking_e2e_test.go @@ -17,17 +17,17 @@ import ( feegrantcli "cosmossdk.io/x/feegrant/client/cli" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/crypto/eots" - "github.com/babylonchain/babylon/test/e2e/configurer" - "github.com/babylonchain/babylon/test/e2e/configurer/chain" - "github.com/babylonchain/babylon/test/e2e/initialization" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - ftypes "github.com/babylonchain/babylon/x/finality/types" - itypes "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/test/e2e/configurer" + "github.com/babylonlabs-io/babylon/test/e2e/configurer/chain" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + ftypes "github.com/babylonlabs-io/babylon/x/finality/types" + itypes "github.com/babylonlabs-io/babylon/x/incentive/types" ) var ( @@ -666,7 +666,7 @@ func (s *BTCStakingTestSuite) Test8BTCDelegationFeeGrantTyped() { // tries to create a send transaction putting the freegranter as feepayer, it should FAIL // since we only gave grant for BTC delegation msgs. - // TODO: Uncomment the next lines when issue: https://github.com/babylonchain/babylon/issues/693 + // TODO: Uncomment the next lines when issue: https://github.com/babylonlabs-io/babylon/issues/693 // is fixed on cosmos-sdk side // outBuff, errBuff, err := node.BankSendOutput( // wGratee, node.PublicAddress, stakerBalance.String(), diff --git a/test/e2e/btc_timestamping_e2e_test.go b/test/e2e/btc_timestamping_e2e_test.go index db447f5d5..6b8282311 100644 --- a/test/e2e/btc_timestamping_e2e_test.go +++ b/test/e2e/btc_timestamping_e2e_test.go @@ -8,11 +8,11 @@ import ( "strconv" "time" - "github.com/babylonchain/babylon/test/e2e/configurer" - "github.com/babylonchain/babylon/test/e2e/initialization" - bbn "github.com/babylonchain/babylon/types" - ct "github.com/babylonchain/babylon/x/checkpointing/types" - itypes "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/test/e2e/configurer" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + bbn "github.com/babylonlabs-io/babylon/types" + ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" + itypes "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" ) diff --git a/test/e2e/btc_timestamping_phase2_hermes_test.go b/test/e2e/btc_timestamping_phase2_hermes_test.go index 1a9cf8945..cfae910f4 100644 --- a/test/e2e/btc_timestamping_phase2_hermes_test.go +++ b/test/e2e/btc_timestamping_phase2_hermes_test.go @@ -3,9 +3,9 @@ package e2e import ( "time" - "github.com/babylonchain/babylon/test/e2e/configurer" - "github.com/babylonchain/babylon/test/e2e/initialization" - ct "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/test/e2e/configurer" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/types/query" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "github.com/stretchr/testify/suite" diff --git a/test/e2e/btc_timestamping_phase2_rly_test.go b/test/e2e/btc_timestamping_phase2_rly_test.go index 8bc1e5352..091eabc06 100644 --- a/test/e2e/btc_timestamping_phase2_rly_test.go +++ b/test/e2e/btc_timestamping_phase2_rly_test.go @@ -3,9 +3,9 @@ package e2e import ( "time" - "github.com/babylonchain/babylon/test/e2e/configurer" - "github.com/babylonchain/babylon/test/e2e/initialization" - ct "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/test/e2e/configurer" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/types/query" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" "github.com/stretchr/testify/suite" diff --git a/test/e2e/bytecode/README.md b/test/e2e/bytecode/README.md index e0926f743..0655fa11f 100644 --- a/test/e2e/bytecode/README.md +++ b/test/e2e/bytecode/README.md @@ -1 +1 @@ -Contract built from https://github.com/babylonchain/babylon-contract/tree/main/contracts +Contract built from https://github.com/babylonlabs-io/babylon-contract/tree/main/contracts diff --git a/test/e2e/configurer/base.go b/test/e2e/configurer/base.go index 6744fff94..302fd8ca9 100644 --- a/test/e2e/configurer/base.go +++ b/test/e2e/configurer/base.go @@ -12,12 +12,12 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/test/e2e/configurer/chain" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" - "github.com/babylonchain/babylon/test/e2e/util" - "github.com/babylonchain/babylon/types" - types2 "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/test/e2e/configurer/chain" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/util" + "github.com/babylonlabs-io/babylon/types" + types2 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/test/e2e/configurer/chain/chain.go b/test/e2e/configurer/chain/chain.go index 4d5e1ec03..a6d92dc3f 100644 --- a/test/e2e/configurer/chain/chain.go +++ b/test/e2e/configurer/chain/chain.go @@ -10,9 +10,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/test/e2e/configurer/config" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/configurer/config" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) type Config struct { diff --git a/test/e2e/configurer/chain/commands.go b/test/e2e/configurer/chain/commands.go index 8d8c59b1a..36155d45c 100644 --- a/test/e2e/configurer/chain/commands.go +++ b/test/e2e/configurer/chain/commands.go @@ -12,15 +12,15 @@ import ( "strings" "time" - txformat "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" - "github.com/babylonchain/babylon/test/e2e/util" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - blc "github.com/babylonchain/babylon/x/btclightclient/types" - cttypes "github.com/babylonchain/babylon/x/checkpointing/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/util" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + blc "github.com/babylonlabs-io/babylon/x/btclightclient/types" + cttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/bech32" sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query" diff --git a/test/e2e/configurer/chain/commands_btcstaking.go b/test/e2e/configurer/chain/commands_btcstaking.go index f42041b7e..f7586d812 100644 --- a/test/e2e/configurer/chain/commands_btcstaking.go +++ b/test/e2e/configurer/chain/commands_btcstaking.go @@ -16,11 +16,11 @@ import ( sdkmath "cosmossdk.io/math" cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - "github.com/babylonchain/babylon/test/e2e/containers" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func (n *NodeConfig) CreateFinalityProvider(walletAddrOrName string, btcPK *bbn.BIP340PubKey, pop *bstypes.ProofOfPossessionBTC, moniker, identity, website, securityContract, details string, commission *sdkmath.LegacyDec) { diff --git a/test/e2e/configurer/chain/node.go b/test/e2e/configurer/chain/node.go index 8e185ec51..f849ac5ab 100644 --- a/test/e2e/configurer/chain/node.go +++ b/test/e2e/configurer/chain/node.go @@ -13,8 +13,8 @@ import ( coretypes "github.com/cometbft/cometbft/rpc/core/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) type NodeConfig struct { diff --git a/test/e2e/configurer/chain/queries.go b/test/e2e/configurer/chain/queries.go index c0bb049f8..ff4ae0302 100644 --- a/test/e2e/configurer/chain/queries.go +++ b/test/e2e/configurer/chain/queries.go @@ -21,12 +21,12 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/test/e2e/util" - blc "github.com/babylonchain/babylon/x/btclightclient/types" - ct "github.com/babylonchain/babylon/x/checkpointing/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" - mtypes "github.com/babylonchain/babylon/x/monitor/types" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/test/e2e/util" + blc "github.com/babylonlabs-io/babylon/x/btclightclient/types" + ct "github.com/babylonlabs-io/babylon/x/checkpointing/types" + etypes "github.com/babylonlabs-io/babylon/x/epoching/types" + mtypes "github.com/babylonlabs-io/babylon/x/monitor/types" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func (n *NodeConfig) QueryGRPCGateway(path string, queryParams url.Values) ([]byte, error) { diff --git a/test/e2e/configurer/chain/queries_btcstaking.go b/test/e2e/configurer/chain/queries_btcstaking.go index 8e3cec5e0..f7a735c8f 100644 --- a/test/e2e/configurer/chain/queries_btcstaking.go +++ b/test/e2e/configurer/chain/queries_btcstaking.go @@ -6,10 +6,10 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/test/e2e/util" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - ftypes "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/test/e2e/util" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + ftypes "github.com/babylonlabs-io/babylon/x/finality/types" ) func (n *NodeConfig) QueryBTCStakingParams() *bstypes.Params { diff --git a/test/e2e/configurer/chain/queries_ibc.go b/test/e2e/configurer/chain/queries_ibc.go index 621f5867c..f5889b229 100644 --- a/test/e2e/configurer/chain/queries_ibc.go +++ b/test/e2e/configurer/chain/queries_ibc.go @@ -4,7 +4,7 @@ import ( "fmt" "net/url" - "github.com/babylonchain/babylon/test/e2e/util" + "github.com/babylonlabs-io/babylon/test/e2e/util" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) diff --git a/test/e2e/configurer/chain/queries_incentive.go b/test/e2e/configurer/chain/queries_incentive.go index 9416d9866..152c42352 100644 --- a/test/e2e/configurer/chain/queries_incentive.go +++ b/test/e2e/configurer/chain/queries_incentive.go @@ -4,8 +4,8 @@ import ( "fmt" "net/url" - "github.com/babylonchain/babylon/test/e2e/util" - incentivetypes "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/test/e2e/util" + incentivetypes "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) diff --git a/test/e2e/configurer/current.go b/test/e2e/configurer/current.go index 32572e12e..ca2c26ae6 100644 --- a/test/e2e/configurer/current.go +++ b/test/e2e/configurer/current.go @@ -5,9 +5,9 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/test/e2e/configurer/chain" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/configurer/chain" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) type CurrentBranchConfigurer struct { diff --git a/test/e2e/configurer/factory.go b/test/e2e/configurer/factory.go index bcac549e5..a04a834cd 100644 --- a/test/e2e/configurer/factory.go +++ b/test/e2e/configurer/factory.go @@ -3,10 +3,10 @@ package configurer import ( "testing" - "github.com/babylonchain/babylon/test/e2e/configurer/chain" - "github.com/babylonchain/babylon/test/e2e/containers" - "github.com/babylonchain/babylon/test/e2e/initialization" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/test/e2e/configurer/chain" + "github.com/babylonlabs-io/babylon/test/e2e/containers" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) diff --git a/test/e2e/containers/config.go b/test/e2e/containers/config.go index 964367871..9f15dcb1c 100644 --- a/test/e2e/containers/config.go +++ b/test/e2e/containers/config.go @@ -10,14 +10,14 @@ type ImageConfig struct { //nolint:deadcode const ( // name of babylon container produced by running `make localnet-build-env` - BabylonContainerName = "babylonchain/babylond" + BabylonContainerName = "babylonlabs-io/babylond" hermesRelayerRepository = "informalsystems/hermes" hermesRelayerTag = "v1.8.2" // Built using the `build-cosmos-relayer-docker` target on an Intel (amd64) machine and pushed to ECR cosmosRelayerRepository = "public.ecr.aws/t9e9i3h0/cosmos-relayer" // TODO: Replace with version tag once we have a working version - cosmosRelayerTag = "main" + cosmosRelayerTag = "main" ) // NewImageConfig returns ImageConfig needed for running e2e test. diff --git a/test/e2e/ibc_transfer_e2e_test.go b/test/e2e/ibc_transfer_e2e_test.go index 8f1848c54..c1521a467 100644 --- a/test/e2e/ibc_transfer_e2e_test.go +++ b/test/e2e/ibc_transfer_e2e_test.go @@ -3,8 +3,8 @@ package e2e import ( "time" - "github.com/babylonchain/babylon/test/e2e/configurer" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/configurer" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/suite" ) diff --git a/test/e2e/initialization/chain/main.go b/test/e2e/initialization/chain/main.go index 074b7968f..6d22e8e78 100644 --- a/test/e2e/initialization/chain/main.go +++ b/test/e2e/initialization/chain/main.go @@ -7,7 +7,7 @@ import ( "os" "time" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) func main() { diff --git a/test/e2e/initialization/config.go b/test/e2e/initialization/config.go index 9e5f95a16..3e7119ae0 100644 --- a/test/e2e/initialization/config.go +++ b/test/e2e/initialization/config.go @@ -21,13 +21,13 @@ import ( staketypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/gogoproto/proto" - "github.com/babylonchain/babylon/privval" - bbn "github.com/babylonchain/babylon/types" - btccheckpointtypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - blctypes "github.com/babylonchain/babylon/x/btclightclient/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/privval" + bbn "github.com/babylonlabs-io/babylon/types" + btccheckpointtypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + blctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" - "github.com/babylonchain/babylon/test/e2e/util" + "github.com/babylonlabs-io/babylon/test/e2e/util" ) // NodeConfig is a confiuration for the node supplied from the test runner diff --git a/test/e2e/initialization/init.go b/test/e2e/initialization/init.go index 0a4f2b62b..94e8ca3e5 100644 --- a/test/e2e/initialization/init.go +++ b/test/e2e/initialization/init.go @@ -6,8 +6,8 @@ import ( "path/filepath" "time" - appkeepers "github.com/babylonchain/babylon/app/keepers" - "github.com/babylonchain/babylon/test/e2e/util" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" + "github.com/babylonlabs-io/babylon/test/e2e/util" ) func InitChain(id, dataDir string, nodeConfigs []*NodeConfig, votingPeriod, expeditedVotingPeriod time.Duration, forkHeight int) (*Chain, error) { diff --git a/test/e2e/initialization/init_test.go b/test/e2e/initialization/init_test.go index cdebd2ef1..8d21b1b4d 100644 --- a/test/e2e/initialization/init_test.go +++ b/test/e2e/initialization/init_test.go @@ -13,7 +13,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) const forkHeight = 10 diff --git a/test/e2e/initialization/node.go b/test/e2e/initialization/node.go index d2a8dc1bf..4346e7b31 100644 --- a/test/e2e/initialization/node.go +++ b/test/e2e/initialization/node.go @@ -31,12 +31,12 @@ import ( "github.com/cosmos/go-bip39" "github.com/spf13/viper" - babylonApp "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/cmd/babylond/cmd" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/test/e2e/util" - bbn "github.com/babylonchain/babylon/types" + babylonApp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/cmd/babylond/cmd" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/test/e2e/util" + bbn "github.com/babylonlabs-io/babylon/types" ) type internalNode struct { diff --git a/test/e2e/initialization/node/main.go b/test/e2e/initialization/node/main.go index cfa43b6c5..3a3a0a858 100644 --- a/test/e2e/initialization/node/main.go +++ b/test/e2e/initialization/node/main.go @@ -7,7 +7,7 @@ import ( "strings" "time" - "github.com/babylonchain/babylon/test/e2e/initialization" + "github.com/babylonlabs-io/babylon/test/e2e/initialization" ) func main() { diff --git a/test/e2e/initialization/util.go b/test/e2e/initialization/util.go index 3346f2b5d..fbcc6714a 100644 --- a/test/e2e/initialization/util.go +++ b/test/e2e/initialization/util.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec/unknownproto" sdktx "github.com/cosmos/cosmos-sdk/types/tx" - "github.com/babylonchain/babylon/test/e2e/util" + "github.com/babylonlabs-io/babylon/test/e2e/util" ) func decodeTx(txBytes []byte) (*sdktx.Tx, error) { diff --git a/test/e2e/scripts/download_release.sh b/test/e2e/scripts/download_release.sh index 77e35985d..060dcb1d3 100755 --- a/test/e2e/scripts/download_release.sh +++ b/test/e2e/scripts/download_release.sh @@ -2,7 +2,7 @@ set -o nounset -o pipefail command -v shellcheck >/dev/null && shellcheck "$0" -OWNER="babylonchain" +OWNER="babylonlabs-io" REPO="babylon-contract" CONTRACT="babylon_contract" OUTPUT_FOLDER="$(dirname "$0")/../bytecode" @@ -20,7 +20,10 @@ GH_TAGS="$GH_REPO/releases/tags/$TAG" AUTH="Authorization: token $GITHUB_API_TOKEN" # Validate token -curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; } +curl -o /dev/null -sH "$AUTH" $GH_REPO || { + echo "Error: Invalid repo, token or network issue!" + exit 1 +} # Read asset tags RESPONSE=$(curl -sH "$AUTH" "$GH_TAGS") diff --git a/test/e2e/util/codec.go b/test/e2e/util/codec.go index fd633f711..3e078ffdc 100644 --- a/test/e2e/util/codec.go +++ b/test/e2e/util/codec.go @@ -1,8 +1,8 @@ package util import ( - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/app/params" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/app/params" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" diff --git a/testutil/datagen/account_balance.go b/testutil/datagen/account_balance.go index 5530ecea5..d748c2939 100644 --- a/testutil/datagen/account_balance.go +++ b/testutil/datagen/account_balance.go @@ -2,7 +2,7 @@ package datagen import ( sdkmath "cosmossdk.io/math" - appparams "github.com/babylonchain/babylon/app/params" + appparams "github.com/babylonlabs-io/babylon/app/params" sec256k1 "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" diff --git a/testutil/datagen/btc_address_test.go b/testutil/datagen/btc_address_test.go index b1da6d13e..8a560c66e 100644 --- a/testutil/datagen/btc_address_test.go +++ b/testutil/datagen/btc_address_test.go @@ -4,7 +4,7 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" "github.com/stretchr/testify/require" diff --git a/testutil/datagen/btc_blockchain.go b/testutil/datagen/btc_blockchain.go index 1beb797cd..3e3ee42ec 100644 --- a/testutil/datagen/btc_blockchain.go +++ b/testutil/datagen/btc_blockchain.go @@ -4,7 +4,7 @@ import ( "math/big" "math/rand" - "github.com/babylonchain/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/btctxformatter" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/testutil/datagen/btc_header_chain.go b/testutil/datagen/btc_header_chain.go index 339fef508..e28421ef3 100644 --- a/testutil/datagen/btc_header_chain.go +++ b/testutil/datagen/btc_header_chain.go @@ -4,8 +4,8 @@ import ( "math/rand" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" ) diff --git a/testutil/datagen/btc_header_info.go b/testutil/datagen/btc_header_info.go index d8a773acf..91230a1dd 100644 --- a/testutil/datagen/btc_header_info.go +++ b/testutil/datagen/btc_header_info.go @@ -8,9 +8,9 @@ import ( "time" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" - btclightclientk "github.com/babylonchain/babylon/x/btclightclient/keeper" - btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + btclightclientk "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + btclightclienttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/testutil/datagen/btc_schnorr.go b/testutil/datagen/btc_schnorr.go index 1eec8d047..3068d0923 100644 --- a/testutil/datagen/btc_schnorr.go +++ b/testutil/datagen/btc_schnorr.go @@ -3,7 +3,7 @@ package datagen import ( "math/rand" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/decred/dcrd/dcrec/secp256k1/v4" ) diff --git a/testutil/datagen/btc_transaction.go b/testutil/datagen/btc_transaction.go index 9bcdad7f9..ae6a58947 100644 --- a/testutil/datagen/btc_transaction.go +++ b/testutil/datagen/btc_transaction.go @@ -17,9 +17,9 @@ import ( "github.com/btcsuite/btcd/wire" sdk "github.com/cosmos/cosmos-sdk/types" - txformat "github.com/babylonchain/babylon/btctxformatter" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) var ( diff --git a/testutil/datagen/btcstaking.go b/testutil/datagen/btcstaking.go index 810be2364..ed2ed828a 100644 --- a/testutil/datagen/btcstaking.go +++ b/testutil/datagen/btcstaking.go @@ -15,9 +15,9 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) const ( diff --git a/testutil/datagen/covenant.go b/testutil/datagen/covenant.go index 9961b5055..03f2944ac 100644 --- a/testutil/datagen/covenant.go +++ b/testutil/datagen/covenant.go @@ -1,10 +1,10 @@ package datagen import ( - "github.com/babylonchain/babylon/btcstaking" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/btcstaking" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/wire" diff --git a/testutil/datagen/epoching.go b/testutil/datagen/epoching.go index 6cec642f1..3e4dc40b3 100644 --- a/testutil/datagen/epoching.go +++ b/testutil/datagen/epoching.go @@ -3,7 +3,7 @@ package datagen import ( "math/rand" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) // getFirstBlockHeight returns the height of the first block of a given epoch and epoch interval diff --git a/testutil/datagen/finality.go b/testutil/datagen/finality.go index 9216dd6d0..ad6a6f12e 100644 --- a/testutil/datagen/finality.go +++ b/testutil/datagen/finality.go @@ -3,9 +3,9 @@ package datagen import ( "math/rand" - "github.com/babylonchain/babylon/crypto/eots" - bbn "github.com/babylonchain/babylon/types" - ftypes "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/crypto/eots" + bbn "github.com/babylonlabs-io/babylon/types" + ftypes "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/cometbft/cometbft/crypto/merkle" diff --git a/testutil/datagen/genesiskey.go b/testutil/datagen/genesiskey.go index aff771d1b..77bffb8af 100644 --- a/testutil/datagen/genesiskey.go +++ b/testutil/datagen/genesiskey.go @@ -1,11 +1,11 @@ package datagen import ( - "github.com/babylonchain/babylon/app" - appkeepers "github.com/babylonchain/babylon/app/keepers" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/app" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" cmtcrypto "github.com/cometbft/cometbft/crypto" cmted25519 "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/crypto/codec" diff --git a/testutil/datagen/incentive.go b/testutil/datagen/incentive.go index b970f1ca2..2cd0e10b6 100644 --- a/testutil/datagen/incentive.go +++ b/testutil/datagen/incentive.go @@ -4,9 +4,9 @@ import ( "math/rand" sdkmath "cosmossdk.io/math" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - itypes "github.com/babylonchain/babylon/x/incentive/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + itypes "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/testutil/datagen/init_val.go b/testutil/datagen/init_val.go index 5870ca8cf..46e883b46 100644 --- a/testutil/datagen/init_val.go +++ b/testutil/datagen/init_val.go @@ -11,8 +11,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/go-bip39" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" ) // InitializeNodeValidatorFiles creates private validator and p2p configuration files. diff --git a/testutil/datagen/raw_checkpoint.go b/testutil/datagen/raw_checkpoint.go index 88512ab0f..cc6d8d80a 100644 --- a/testutil/datagen/raw_checkpoint.go +++ b/testutil/datagen/raw_checkpoint.go @@ -5,9 +5,9 @@ import ( "github.com/boljen/go-bitmap" - txformat "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) const ( diff --git a/testutil/datagen/tendermint.go b/testutil/datagen/tendermint.go index cea24c2e5..c09368739 100644 --- a/testutil/datagen/tendermint.go +++ b/testutil/datagen/tendermint.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func GenRandomTMHeader(r *rand.Rand, chainID string, height uint64) *cmtproto.Header { diff --git a/testutil/datagen/val_set.go b/testutil/datagen/val_set.go index 8c55f9bec..b98429e29 100644 --- a/testutil/datagen/val_set.go +++ b/testutil/datagen/val_set.go @@ -5,9 +5,9 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/crypto/bls12381" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) func GenRandomValSet(n int) epochingtypes.ValidatorSet { diff --git a/testutil/datagen/vote_ext.go b/testutil/datagen/vote_ext.go index 1f0e35f8d..f33917204 100644 --- a/testutil/datagen/vote_ext.go +++ b/testutil/datagen/vote_ext.go @@ -5,7 +5,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func GenRandomVoteExtension( diff --git a/testutil/helper/gen_blocks.go b/testutil/helper/gen_blocks.go index def52b924..edb3b54d8 100644 --- a/testutil/helper/gen_blocks.go +++ b/testutil/helper/gen_blocks.go @@ -15,7 +15,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" ) // adapted from https://github.com/cosmos/cosmos-sdk/blob/v0.50.6/baseapp/abci_utils_test.go diff --git a/testutil/helper/helper.go b/testutil/helper/helper.go index 2a0390e09..6ae1de0d9 100644 --- a/testutil/helper/helper.go +++ b/testutil/helper/helper.go @@ -7,10 +7,10 @@ import ( "testing" "cosmossdk.io/core/header" - appkeepers "github.com/babylonchain/babylon/app/keepers" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + appkeepers "github.com/babylonlabs-io/babylon/app/keepers" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/testutil/datagen" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" abci "github.com/cometbft/cometbft/abci/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/cosmos-sdk/baseapp" @@ -26,11 +26,11 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/babylonchain/babylon/app" - appparams "github.com/babylonchain/babylon/app/params" - btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/epoching/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/app" + appparams "github.com/babylonlabs-io/babylon/app/params" + btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/epoching/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // Helper is a structure which wraps the entire app and exposes functionalities for testing the epoching module diff --git a/testutil/keeper/btccheckpoint.go b/testutil/keeper/btccheckpoint.go index 528c059f5..9049041af 100644 --- a/testutil/keeper/btccheckpoint.go +++ b/testutil/keeper/btccheckpoint.go @@ -19,8 +19,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) func NewBTCCheckpointKeeper( diff --git a/testutil/keeper/btclightclient.go b/testutil/keeper/btclightclient.go index 484c275ee..ebacf965e 100644 --- a/testutil/keeper/btclightclient.go +++ b/testutil/keeper/btclightclient.go @@ -20,10 +20,10 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - bapp "github.com/babylonchain/babylon/app" - bbn "github.com/babylonchain/babylon/types" - btclightclientk "github.com/babylonchain/babylon/x/btclightclient/keeper" - btclightclientt "github.com/babylonchain/babylon/x/btclightclient/types" + bapp "github.com/babylonlabs-io/babylon/app" + bbn "github.com/babylonlabs-io/babylon/types" + btclightclientk "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + btclightclientt "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) func BTCLightClientKeeper(t testing.TB) (*btclightclientk.Keeper, sdk.Context) { diff --git a/testutil/keeper/btcstaking.go b/testutil/keeper/btcstaking.go index 4402aa477..fd00fbf7f 100644 --- a/testutil/keeper/btcstaking.go +++ b/testutil/keeper/btcstaking.go @@ -19,8 +19,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func BTCStakingKeeper( diff --git a/testutil/keeper/checkpointing.go b/testutil/keeper/checkpointing.go index 9014c328d..f9ec59271 100644 --- a/testutil/keeper/checkpointing.go +++ b/testutil/keeper/checkpointing.go @@ -16,8 +16,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func CheckpointingKeeper(t testing.TB, ek types.EpochingKeeper, signer keeper.BlsSigner) (*keeper.Keeper, sdk.Context, *codec.ProtoCodec) { diff --git a/testutil/keeper/epoching.go b/testutil/keeper/epoching.go index 902a11593..716761886 100644 --- a/testutil/keeper/epoching.go +++ b/testutil/keeper/epoching.go @@ -18,8 +18,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/epoching/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) func EpochingKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { diff --git a/testutil/keeper/finality.go b/testutil/keeper/finality.go index 83b6ce264..fc15a866e 100644 --- a/testutil/keeper/finality.go +++ b/testutil/keeper/finality.go @@ -18,8 +18,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types.IncentiveKeeper) (*keeper.Keeper, sdk.Context) { diff --git a/testutil/keeper/incentive.go b/testutil/keeper/incentive.go index f5a23be90..2a6d2017b 100644 --- a/testutil/keeper/incentive.go +++ b/testutil/keeper/incentive.go @@ -18,8 +18,8 @@ import ( govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/incentive/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" ) func IncentiveKeeper(t testing.TB, bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper, epochingKeeper types.EpochingKeeper) (*keeper.Keeper, sdk.Context) { diff --git a/testutil/keeper/zoneconcierge.go b/testutil/keeper/zoneconcierge.go index 1c5478db4..30ed2679e 100644 --- a/testutil/keeper/zoneconcierge.go +++ b/testutil/keeper/zoneconcierge.go @@ -23,8 +23,8 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // zoneconciergeChannelKeeper is a stub of ChannelKeeper diff --git a/testutil/mocks/bls_signer.go b/testutil/mocks/bls_signer.go index 094e5b89c..c59a2fcd7 100644 --- a/testutil/mocks/bls_signer.go +++ b/testutil/mocks/bls_signer.go @@ -7,7 +7,7 @@ package mocks import ( reflect "reflect" - bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + bls12381 "github.com/babylonlabs-io/babylon/crypto/bls12381" crypto "github.com/cometbft/cometbft/crypto" types "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" diff --git a/testutil/mocks/checkpointing_expected_keepers.go b/testutil/mocks/checkpointing_expected_keepers.go index 80f0345f2..c4975364a 100644 --- a/testutil/mocks/checkpointing_expected_keepers.go +++ b/testutil/mocks/checkpointing_expected_keepers.go @@ -8,8 +8,8 @@ import ( context "context" reflect "reflect" - types "github.com/babylonchain/babylon/x/checkpointing/types" - types0 "github.com/babylonchain/babylon/x/epoching/types" + types "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types0 "github.com/babylonlabs-io/babylon/x/epoching/types" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" types1 "github.com/cosmos/cosmos-sdk/types" types2 "github.com/cosmos/cosmos-sdk/x/staking/types" diff --git a/testutil/mocks/proposal_keeper.go b/testutil/mocks/proposal_keeper.go index 89becc9ea..0afdfeab4 100644 --- a/testutil/mocks/proposal_keeper.go +++ b/testutil/mocks/proposal_keeper.go @@ -8,9 +8,9 @@ import ( context "context" reflect "reflect" - bls12381 "github.com/babylonchain/babylon/crypto/bls12381" - types "github.com/babylonchain/babylon/x/checkpointing/types" - types0 "github.com/babylonchain/babylon/x/epoching/types" + bls12381 "github.com/babylonlabs-io/babylon/crypto/bls12381" + types "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types0 "github.com/babylonlabs-io/babylon/x/epoching/types" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" types1 "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" diff --git a/types/btc_header_bytes_test.go b/types/btc_header_bytes_test.go index df0b00dcd..7e2eb638e 100644 --- a/types/btc_header_bytes_test.go +++ b/types/btc_header_bytes_test.go @@ -6,8 +6,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" ) func FuzzBTCHeaderBytesBytesOps(f *testing.F) { diff --git a/types/btc_header_hash_bytes_test.go b/types/btc_header_hash_bytes_test.go index 83305e969..ba7367821 100644 --- a/types/btc_header_hash_bytes_test.go +++ b/types/btc_header_hash_bytes_test.go @@ -6,8 +6,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/chaincfg/chainhash" ) diff --git a/types/btc_schnorr_eots_test.go b/types/btc_schnorr_eots_test.go index d6fe38575..27e6397f9 100644 --- a/types/btc_schnorr_eots_test.go +++ b/types/btc_schnorr_eots_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/stretchr/testify/require" ) diff --git a/types/btc_schnorr_pk_test.go b/types/btc_schnorr_pk_test.go index 6daf60629..3efbb125e 100644 --- a/types/btc_schnorr_pk_test.go +++ b/types/btc_schnorr_pk_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" "github.com/stretchr/testify/require" ) diff --git a/types/btc_schnorr_pub_rand.go b/types/btc_schnorr_pub_rand.go index 154c6dee6..6cbe4b8d3 100644 --- a/types/btc_schnorr_pub_rand.go +++ b/types/btc_schnorr_pub_rand.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "fmt" - "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/crypto/eots" "github.com/btcsuite/btcd/btcec/v2" "github.com/decred/dcrd/dcrec/secp256k1/v4" ) diff --git a/types/btc_schnorr_pub_rand_test.go b/types/btc_schnorr_pub_rand_test.go index 06e22387e..a1fc3966c 100644 --- a/types/btc_schnorr_pub_rand_test.go +++ b/types/btc_schnorr_pub_rand_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/stretchr/testify/require" ) diff --git a/types/btc_schnorr_sig_test.go b/types/btc_schnorr_sig_test.go index c8a7f2ad8..68a001937 100644 --- a/types/btc_schnorr_sig_test.go +++ b/types/btc_schnorr_sig_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/stretchr/testify/require" ) diff --git a/types/btcutils_test.go b/types/btcutils_test.go index e9890b0a7..7bd100a53 100644 --- a/types/btcutils_test.go +++ b/types/btcutils_test.go @@ -1,7 +1,7 @@ package types_test import ( - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" btcchaincfg "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/suite" diff --git a/types/retry/retry.go b/types/retry/retry.go index 05cf78bcf..e193a83a9 100644 --- a/types/retry/retry.go +++ b/types/retry/retry.go @@ -6,9 +6,9 @@ import ( "math/big" "time" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // unrecoverableErrors is a list of errors which are unsafe and should not be retried. diff --git a/wasmbinding/bindings/utils.go b/wasmbinding/bindings/utils.go index a4c278cd9..51eb450fa 100644 --- a/wasmbinding/bindings/utils.go +++ b/wasmbinding/bindings/utils.go @@ -1,7 +1,7 @@ package bindings import ( - lcTypes "github.com/babylonchain/babylon/x/btclightclient/types" + lcTypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) // AsBtcBlockHeaderInfo translates BTCHeaderInfo to BtcBlockHeaderInfo diff --git a/wasmbinding/test/custom_query_test.go b/wasmbinding/test/custom_query_test.go index 6237edaf6..a21d9c04d 100644 --- a/wasmbinding/test/custom_query_test.go +++ b/wasmbinding/test/custom_query_test.go @@ -19,9 +19,9 @@ import ( minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/wasmbinding/bindings" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/wasmbinding/bindings" ) // TODO consider doing it by enviromental variables as currently it may fail on some diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index 3dbdbb7e6..8896e0ec0 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -7,11 +7,11 @@ import ( errorsmod "cosmossdk.io/errors" wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" wasmvmtypes "github.com/CosmWasm/wasmvm/v2/types" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/wasmbinding/bindings" - lcKeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" - epochingkeeper "github.com/babylonchain/babylon/x/epoching/keeper" - zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/wasmbinding/bindings" + lcKeeper "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + epochingkeeper "github.com/babylonlabs-io/babylon/x/epoching/keeper" + zckeeper "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btccheckpoint/abci.go b/x/btccheckpoint/abci.go index 2307557f2..cb5579985 100644 --- a/x/btccheckpoint/abci.go +++ b/x/btccheckpoint/abci.go @@ -2,7 +2,7 @@ package btccheckpoint import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/keeper" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" ) // EndBlocker checks if during block execution btc light client head had been diff --git a/x/btccheckpoint/client/cli/query.go b/x/btccheckpoint/client/cli/query.go index 07d645da6..43124c93c 100644 --- a/x/btccheckpoint/client/cli/query.go +++ b/x/btccheckpoint/client/cli/query.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/btccheckpoint/client/cli/query_params.go b/x/btccheckpoint/client/cli/query_params.go index 3519dc58a..0dc96de8b 100644 --- a/x/btccheckpoint/client/cli/query_params.go +++ b/x/btccheckpoint/client/cli/query_params.go @@ -3,7 +3,7 @@ package cli import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" diff --git a/x/btccheckpoint/client/cli/tx.go b/x/btccheckpoint/client/cli/tx.go index 9d9f5b608..d463dd636 100644 --- a/x/btccheckpoint/client/cli/tx.go +++ b/x/btccheckpoint/client/cli/tx.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" // "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) // GetTxCmd returns the transaction commands for this module diff --git a/x/btccheckpoint/genesis.go b/x/btccheckpoint/genesis.go index 7b55f84a0..1b66e2251 100644 --- a/x/btccheckpoint/genesis.go +++ b/x/btccheckpoint/genesis.go @@ -2,8 +2,8 @@ package btccheckpoint import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) // InitGenesis initializes the capability module's state from a provided genesis diff --git a/x/btccheckpoint/genesis_test.go b/x/btccheckpoint/genesis_test.go index 5266094df..62b36760c 100644 --- a/x/btccheckpoint/genesis_test.go +++ b/x/btccheckpoint/genesis_test.go @@ -3,11 +3,11 @@ package btccheckpoint_test import ( "testing" - "github.com/babylonchain/babylon/x/btccheckpoint" + "github.com/babylonlabs-io/babylon/x/btccheckpoint" "github.com/stretchr/testify/require" - simapp "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + simapp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) func TestExportGenesis(t *testing.T) { diff --git a/x/btccheckpoint/keeper/grpc_query.go b/x/btccheckpoint/keeper/grpc_query.go index 81986aea5..2ee4ad676 100644 --- a/x/btccheckpoint/keeper/grpc_query.go +++ b/x/btccheckpoint/keeper/grpc_query.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" diff --git a/x/btccheckpoint/keeper/grpc_query_params.go b/x/btccheckpoint/keeper/grpc_query_params.go index 630c5e454..63923bf96 100644 --- a/x/btccheckpoint/keeper/grpc_query_params.go +++ b/x/btccheckpoint/keeper/grpc_query_params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/btccheckpoint/keeper/grpc_query_params_test.go b/x/btccheckpoint/keeper/grpc_query_params_test.go index b9db61836..9624ef04a 100644 --- a/x/btccheckpoint/keeper/grpc_query_params_test.go +++ b/x/btccheckpoint/keeper/grpc_query_params_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/x/btccheckpoint/keeper/grpc_query_test.go b/x/btccheckpoint/keeper/grpc_query_test.go index b9917de18..f1b32d76d 100644 --- a/x/btccheckpoint/keeper/grpc_query_test.go +++ b/x/btccheckpoint/keeper/grpc_query_test.go @@ -9,8 +9,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - dg "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + dg "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) func TestBtcCheckpointInfo(t *testing.T) { diff --git a/x/btccheckpoint/keeper/hooks.go b/x/btccheckpoint/keeper/hooks.go index 3fd096a46..9dfbef441 100644 --- a/x/btccheckpoint/keeper/hooks.go +++ b/x/btccheckpoint/keeper/hooks.go @@ -2,8 +2,8 @@ package keeper import ( "context" - ltypes "github.com/babylonchain/babylon/x/btclightclient/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" + ltypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + etypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) // HandledHooks Helper interface to ensure Hooks implements diff --git a/x/btccheckpoint/keeper/incentive.go b/x/btccheckpoint/keeper/incentive.go index 36c17f035..259af1ae4 100644 --- a/x/btccheckpoint/keeper/incentive.go +++ b/x/btccheckpoint/keeper/incentive.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) // rewardBTCTimestamping finds the (submitter, reporter) pairs of all submissions at the diff --git a/x/btccheckpoint/keeper/keeper.go b/x/btccheckpoint/keeper/keeper.go index 7f01dad7a..9d345cebd 100644 --- a/x/btccheckpoint/keeper/keeper.go +++ b/x/btccheckpoint/keeper/keeper.go @@ -11,9 +11,9 @@ import ( "cosmossdk.io/log" "cosmossdk.io/store/prefix" - txformat "github.com/babylonchain/babylon/btctxformatter" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btccheckpoint/keeper/keeper_test.go b/x/btccheckpoint/keeper/keeper_test.go index 5eed1abd6..5ed112659 100644 --- a/x/btccheckpoint/keeper/keeper_test.go +++ b/x/btccheckpoint/keeper/keeper_test.go @@ -5,8 +5,8 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/x/btccheckpoint/keeper/msg_server.go b/x/btccheckpoint/keeper/msg_server.go index 17480a698..d2cc65310 100644 --- a/x/btccheckpoint/keeper/msg_server.go +++ b/x/btccheckpoint/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( "context" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) diff --git a/x/btccheckpoint/keeper/msg_server_test.go b/x/btccheckpoint/keeper/msg_server_test.go index 651eedb7d..c74e939c7 100644 --- a/x/btccheckpoint/keeper/msg_server_test.go +++ b/x/btccheckpoint/keeper/msg_server_test.go @@ -8,11 +8,11 @@ import ( "testing" "time" - dg "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - bkeeper "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + dg "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + bkeeper "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/btcsuite/btcd/chaincfg" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" diff --git a/x/btccheckpoint/keeper/params.go b/x/btccheckpoint/keeper/params.go index a4333facb..c1fa0d068 100644 --- a/x/btccheckpoint/keeper/params.go +++ b/x/btccheckpoint/keeper/params.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) // SetParams sets the x/btccheckpoint module parameters. diff --git a/x/btccheckpoint/keeper/params_test.go b/x/btccheckpoint/keeper/params_test.go index 444e46eb9..08b049012 100644 --- a/x/btccheckpoint/keeper/params_test.go +++ b/x/btccheckpoint/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/x/btccheckpoint/keeper/submissions.go b/x/btccheckpoint/keeper/submissions.go index bcdb3e8c9..5e3f99b89 100644 --- a/x/btccheckpoint/keeper/submissions.go +++ b/x/btccheckpoint/keeper/submissions.go @@ -7,8 +7,8 @@ import ( "math" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) func (k Keeper) HasSubmission(ctx context.Context, sk types.SubmissionKey) bool { diff --git a/x/btccheckpoint/module.go b/x/btccheckpoint/module.go index 40db44228..47b73657c 100644 --- a/x/btccheckpoint/module.go +++ b/x/btccheckpoint/module.go @@ -12,9 +12,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/btccheckpoint/client/cli" - "github.com/babylonchain/babylon/x/btccheckpoint/keeper" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/client/cli" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/keeper" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/btccheckpoint/types/btccheckpoint.pb.go b/x/btccheckpoint/types/btccheckpoint.pb.go index 1f1882d7a..4e9ac7678 100644 --- a/x/btccheckpoint/types/btccheckpoint.pb.go +++ b/x/btccheckpoint/types/btccheckpoint.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -90,7 +90,7 @@ type BTCSpvProof struct { MerkleNodes []byte `protobuf:"bytes,3,opt,name=merkle_nodes,json=merkleNodes,proto3" json:"merkle_nodes,omitempty"` // Valid btc header which confirms btc_transaction. // Should have exactly 80 bytes - ConfirmingBtcHeader *github_com_babylonchain_babylon_types.BTCHeaderBytes `protobuf:"bytes,4,opt,name=confirming_btc_header,json=confirmingBtcHeader,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderBytes" json:"confirming_btc_header,omitempty"` + ConfirmingBtcHeader *github_com_babylonlabs_io_babylon_types.BTCHeaderBytes `protobuf:"bytes,4,opt,name=confirming_btc_header,json=confirmingBtcHeader,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" json:"confirming_btc_header,omitempty"` } func (m *BTCSpvProof) Reset() { *m = BTCSpvProof{} } @@ -150,8 +150,8 @@ func (m *BTCSpvProof) GetMerkleNodes() []byte { // Each provided OP_RETURN transaction can be identified by hash of block in // which transaction was included and transaction index in the block type TransactionKey struct { - Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` - Hash *github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,2,opt,name=hash,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + Hash *github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,2,opt,name=hash,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` } func (m *TransactionKey) Reset() { *m = TransactionKey{} } @@ -516,7 +516,7 @@ type BTCCheckpointInfo struct { BestSubmissionBtcBlockHeight uint64 `protobuf:"varint,2,opt,name=best_submission_btc_block_height,json=bestSubmissionBtcBlockHeight,proto3" json:"best_submission_btc_block_height,omitempty"` // hash of the btc block which determines checkpoint btc block height i.e. // youngest block of best submission - BestSubmissionBtcBlockHash *github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,3,opt,name=best_submission_btc_block_hash,json=bestSubmissionBtcBlockHash,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"best_submission_btc_block_hash,omitempty"` + BestSubmissionBtcBlockHash *github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,3,opt,name=best_submission_btc_block_hash,json=bestSubmissionBtcBlockHash,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" json:"best_submission_btc_block_hash,omitempty"` // the BTC checkpoint transactions of the best submission BestSubmissionTransactions []*TransactionInfo `protobuf:"bytes,4,rep,name=best_submission_transactions,json=bestSubmissionTransactions,proto3" json:"best_submission_transactions,omitempty"` // list of vigilantes' addresses of the best submission @@ -601,58 +601,58 @@ func init() { } var fileDescriptor_e096cac78d49b0a6 = []byte{ - // 814 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x8f, 0x22, 0x45, - 0x14, 0xa7, 0xa0, 0x67, 0x5d, 0x0a, 0x86, 0x1d, 0x8b, 0x59, 0xd3, 0x21, 0x93, 0x5e, 0xb6, 0x4d, - 0x5c, 0xd6, 0x28, 0x64, 0x47, 0x4d, 0x36, 0xae, 0x97, 0x69, 0x3e, 0x02, 0xd9, 0x5d, 0x98, 0x34, - 0xbd, 0x1e, 0xf6, 0x60, 0xa7, 0xbb, 0x29, 0xe8, 0x0a, 0xd0, 0x45, 0xba, 0x0a, 0x02, 0x9e, 0xf4, - 0x60, 0x62, 0x3c, 0x19, 0xef, 0x9e, 0xfc, 0x67, 0x3c, 0x78, 0xd8, 0xa3, 0xd9, 0xc3, 0xc4, 0xcc, - 0xfc, 0x07, 0x5e, 0xbd, 0x98, 0xaa, 0xee, 0xe1, 0x6b, 0x06, 0x95, 0xc4, 0x1b, 0xef, 0xd5, 0xef, - 0x7d, 0xfc, 0x7e, 0xef, 0x3d, 0x1a, 0x7e, 0xe4, 0x3a, 0xee, 0x62, 0x44, 0x83, 0x8a, 0xcb, 0x3d, - 0xcf, 0xc7, 0xde, 0x70, 0x42, 0x49, 0xc0, 0x2b, 0xb3, 0x27, 0x9b, 0x8e, 0xf2, 0x24, 0xa4, 0x9c, - 0x22, 0x35, 0x46, 0x97, 0x37, 0x1f, 0x67, 0x4f, 0x0a, 0xc7, 0x03, 0x3a, 0xa0, 0x12, 0x54, 0x11, - 0xbf, 0x22, 0xbc, 0xfe, 0x17, 0x80, 0x19, 0xc3, 0xaa, 0x76, 0x27, 0xb3, 0xf3, 0x90, 0xd2, 0x3e, - 0x7a, 0x04, 0xef, 0xb9, 0xdc, 0xb3, 0x79, 0xe8, 0x04, 0xcc, 0xf1, 0x38, 0xa1, 0x81, 0x0a, 0x8a, - 0xa0, 0x94, 0x35, 0x73, 0x2e, 0xf7, 0xac, 0x95, 0x17, 0x9d, 0xc2, 0xfb, 0x5b, 0x40, 0x9b, 0x04, - 0x3d, 0x3c, 0x57, 0x93, 0x45, 0x50, 0x3a, 0x34, 0xf3, 0x9b, 0xf0, 0x96, 0x78, 0x42, 0x0f, 0x61, - 0x76, 0x8c, 0xc3, 0xe1, 0x08, 0xdb, 0x01, 0xed, 0x61, 0xa6, 0xa6, 0x64, 0xe6, 0x4c, 0xe4, 0x6b, - 0x0b, 0x17, 0x1a, 0xc1, 0xfb, 0x1e, 0x0d, 0xfa, 0x24, 0x1c, 0x93, 0x60, 0x60, 0x8b, 0x0a, 0x3e, - 0x76, 0x7a, 0x38, 0x54, 0x15, 0x81, 0x35, 0x9e, 0xbe, 0xbd, 0x78, 0xf0, 0xe9, 0x80, 0x70, 0x7f, - 0xea, 0x96, 0x3d, 0x3a, 0xae, 0xc4, 0x6c, 0x3d, 0xdf, 0x21, 0xc1, 0xb5, 0x51, 0xe1, 0x8b, 0x09, - 0x66, 0x65, 0xc3, 0xaa, 0x36, 0x65, 0xa8, 0xb1, 0xe0, 0x98, 0x99, 0xf9, 0x55, 0x5a, 0x83, 0x7b, - 0xd1, 0x8b, 0x3e, 0x87, 0xb9, 0xb5, 0x26, 0x9f, 0xe3, 0x05, 0x3a, 0x86, 0x07, 0x11, 0x0d, 0x20, - 0x69, 0x44, 0x06, 0x3a, 0x87, 0x8a, 0xef, 0x30, 0x5f, 0x72, 0xcb, 0x1a, 0x5f, 0xbc, 0xbd, 0x78, - 0xf0, 0x74, 0xcf, 0x26, 0x9a, 0x0e, 0xf3, 0xa3, 0x46, 0x64, 0x26, 0xfd, 0x39, 0x3c, 0xec, 0x4e, - 0xdd, 0x31, 0x61, 0x2c, 0x2e, 0xfc, 0x39, 0x4c, 0x0d, 0xf1, 0x42, 0x05, 0xc5, 0x54, 0x29, 0x73, - 0x5a, 0x2a, 0xef, 0x1a, 0x63, 0x79, 0xb3, 0x5f, 0x53, 0x04, 0xe9, 0xdf, 0x01, 0x78, 0x6f, 0x43, - 0xec, 0x3e, 0x5d, 0xe5, 0x03, 0x7b, 0xe7, 0x43, 0x45, 0x98, 0x59, 0x5f, 0x80, 0x64, 0x34, 0xa6, - 0x35, 0x97, 0x90, 0x69, 0x22, 0xf6, 0x25, 0x1e, 0x61, 0x64, 0xe8, 0xbf, 0x01, 0x98, 0x5b, 0xb1, - 0xaa, 0x39, 0xdc, 0x41, 0x5f, 0xc1, 0xfc, 0x8c, 0x0c, 0xc8, 0xc8, 0x09, 0x38, 0xb6, 0x9d, 0x5e, - 0x2f, 0xc4, 0x8c, 0x61, 0x16, 0xb7, 0xf5, 0xf1, 0xee, 0xb6, 0xaa, 0x4b, 0xeb, 0xec, 0x3a, 0xc8, - 0x44, 0xcb, 0x4c, 0x4b, 0x1f, 0xaa, 0xc1, 0xbb, 0x7c, 0xce, 0x6c, 0x12, 0xf4, 0xa9, 0x9a, 0x94, - 0xda, 0x3d, 0xfe, 0x4f, 0x5c, 0x85, 0x46, 0xe6, 0x3b, 0x7c, 0xce, 0xa4, 0x58, 0xc7, 0xf0, 0x00, - 0x4f, 0xa8, 0xe7, 0x4b, 0x3a, 0x8a, 0x19, 0x19, 0x42, 0xd6, 0x74, 0x5d, 0xfc, 0x92, 0x4c, 0x9e, - 0x41, 0x65, 0x88, 0x17, 0x2c, 0x9e, 0xd0, 0xa3, 0xdd, 0x55, 0x36, 0xe6, 0x6a, 0xca, 0x20, 0xf4, - 0x0c, 0xde, 0x61, 0xdc, 0xe1, 0x53, 0x26, 0xc5, 0xcc, 0x9d, 0xbe, 0xbf, 0x3b, 0xdc, 0xe0, 0x5e, - 0x57, 0x42, 0xcd, 0x38, 0x44, 0xef, 0xc0, 0xfc, 0x2d, 0x72, 0xa0, 0x13, 0x98, 0x66, 0xa2, 0x14, - 0xe7, 0x38, 0x8c, 0x8f, 0x74, 0xe5, 0x40, 0x05, 0x78, 0x37, 0xc4, 0x13, 0x1a, 0x8a, 0xc7, 0x68, - 0x80, 0x4b, 0x5b, 0xff, 0x33, 0x05, 0xdf, 0x35, 0xac, 0xea, 0x2a, 0xa9, 0x14, 0xe1, 0x21, 0xcc, - 0x4a, 0xde, 0x76, 0x30, 0x1d, 0xbb, 0x71, 0x4a, 0xc5, 0xcc, 0x48, 0x5f, 0x5b, 0xba, 0x50, 0x03, - 0x16, 0x5d, 0xcc, 0xb8, 0xcd, 0x96, 0x14, 0xe5, 0x89, 0xba, 0x23, 0xea, 0x0d, 0x6d, 0x1f, 0x93, - 0x81, 0xcf, 0x65, 0x31, 0xc5, 0x3c, 0x11, 0xb8, 0x95, 0x12, 0x06, 0xf7, 0x0c, 0x01, 0x6a, 0x4a, - 0x0c, 0xfa, 0x06, 0x40, 0xed, 0x1f, 0x12, 0x89, 0x53, 0x4b, 0xfd, 0x0f, 0xa7, 0x56, 0xd8, 0xd1, - 0x84, 0xc3, 0x7c, 0x34, 0x84, 0x27, 0xdb, 0x1d, 0xac, 0x2d, 0x38, 0x53, 0x95, 0x7d, 0x97, 0x69, - 0xab, 0xd8, 0xda, 0x33, 0x43, 0xdf, 0x02, 0xf8, 0xc1, 0x76, 0xb5, 0x1b, 0x67, 0x61, 0x8f, 0x08, - 0xe3, 0xea, 0x81, 0xac, 0xbb, 0xe7, 0x65, 0xe8, 0x9b, 0xb5, 0xbf, 0xdc, 0xba, 0x93, 0x17, 0x84, - 0xf1, 0x0f, 0x7f, 0x02, 0x30, 0xbd, 0xdc, 0x2d, 0xf4, 0x18, 0xbe, 0x57, 0x3f, 0xef, 0x54, 0x9b, - 0x76, 0xd7, 0x3a, 0xb3, 0x5e, 0x75, 0xed, 0xee, 0x2b, 0xe3, 0x65, 0xcb, 0xb2, 0xea, 0xb5, 0xa3, - 0x44, 0xe1, 0xf0, 0x87, 0x9f, 0x8b, 0xe9, 0x6e, 0xbc, 0x49, 0xbd, 0x1b, 0xd0, 0x6a, 0xa7, 0xdd, - 0x68, 0x99, 0x2f, 0xeb, 0xb5, 0x23, 0x10, 0x41, 0xab, 0xd1, 0x3f, 0xeb, 0x2d, 0xd0, 0x46, 0xab, - 0x7d, 0xf6, 0xa2, 0xf5, 0xba, 0x5e, 0x3b, 0x4a, 0x46, 0xd0, 0x06, 0x09, 0x9c, 0x11, 0xf9, 0x1a, - 0xf7, 0x0a, 0xca, 0xf7, 0xbf, 0x68, 0x09, 0xa3, 0xf3, 0xeb, 0xa5, 0x06, 0xde, 0x5c, 0x6a, 0xe0, - 0x8f, 0x4b, 0x0d, 0xfc, 0x78, 0xa5, 0x25, 0xde, 0x5c, 0x69, 0x89, 0xdf, 0xaf, 0xb4, 0xc4, 0xeb, - 0xcf, 0xfe, 0x6d, 0xea, 0xf3, 0xad, 0x0f, 0xa2, 0xdc, 0x02, 0xf7, 0x8e, 0xfc, 0xac, 0x7d, 0xf2, - 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x55, 0x92, 0x5f, 0x36, 0x07, 0x00, 0x00, + // 816 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcd, 0x8b, 0xdb, 0x46, + 0x14, 0xf7, 0xd8, 0xda, 0x34, 0x1e, 0x7b, 0x9d, 0xed, 0x78, 0x53, 0x84, 0x59, 0x14, 0x47, 0x85, + 0xc6, 0x29, 0x8d, 0x4d, 0xb6, 0xd0, 0xc2, 0x06, 0x0a, 0x2b, 0x7f, 0x60, 0x93, 0xc4, 0x9b, 0xca, + 0x4a, 0x0f, 0x39, 0x54, 0x48, 0xf2, 0xd8, 0x1a, 0x6c, 0x6b, 0x8c, 0x66, 0x6c, 0xec, 0xdc, 0x5a, + 0x28, 0x94, 0x9e, 0x4a, 0xef, 0x3d, 0xf5, 0x9f, 0xe9, 0xa1, 0x87, 0x1c, 0xcb, 0x1e, 0x96, 0xb2, + 0xfb, 0x2f, 0xf4, 0x5a, 0x28, 0x33, 0xd2, 0xfa, 0x6b, 0xd7, 0x6d, 0x0d, 0xbd, 0xf9, 0xbd, 0xf9, + 0xbd, 0x8f, 0xdf, 0xef, 0xbd, 0x67, 0xc1, 0x4f, 0x5c, 0xc7, 0x9d, 0x0f, 0x69, 0x50, 0x71, 0xb9, + 0xe7, 0xf9, 0xd8, 0x1b, 0x8c, 0x29, 0x09, 0x78, 0x65, 0xfa, 0x74, 0xdd, 0x51, 0x1e, 0x87, 0x94, + 0x53, 0xa4, 0xc6, 0xe8, 0xf2, 0xfa, 0xe3, 0xf4, 0x69, 0xe1, 0xb0, 0x4f, 0xfb, 0x54, 0x82, 0x2a, + 0xe2, 0x57, 0x84, 0xd7, 0xff, 0x02, 0x30, 0x63, 0x58, 0xd5, 0xce, 0x78, 0xfa, 0x2a, 0xa4, 0xb4, + 0x87, 0x1e, 0xc1, 0x7b, 0x2e, 0xf7, 0x6c, 0x1e, 0x3a, 0x01, 0x73, 0x3c, 0x4e, 0x68, 0xa0, 0x82, + 0x22, 0x28, 0x65, 0xcd, 0x9c, 0xcb, 0x3d, 0x6b, 0xe9, 0x45, 0xc7, 0xf0, 0xfe, 0x06, 0xd0, 0x26, + 0x41, 0x17, 0xcf, 0xd4, 0x64, 0x11, 0x94, 0xf6, 0xcd, 0xfc, 0x3a, 0xbc, 0x25, 0x9e, 0xd0, 0x43, + 0x98, 0x1d, 0xe1, 0x70, 0x30, 0xc4, 0x76, 0x40, 0xbb, 0x98, 0xa9, 0x29, 0x99, 0x39, 0x13, 0xf9, + 0xda, 0xc2, 0x85, 0x02, 0x78, 0xdf, 0xa3, 0x41, 0x8f, 0x84, 0x23, 0x12, 0xf4, 0x6d, 0x51, 0xc1, + 0xc7, 0x4e, 0x17, 0x87, 0xaa, 0x22, 0xb0, 0xc6, 0xc9, 0xf9, 0xc5, 0x83, 0xcf, 0xfa, 0x84, 0xfb, + 0x13, 0xb7, 0xec, 0xd1, 0x51, 0x25, 0x66, 0x3b, 0x74, 0x5c, 0xf6, 0x84, 0xd0, 0x6b, 0xb3, 0xc2, + 0xe7, 0x63, 0xcc, 0xca, 0x86, 0x55, 0x6d, 0xca, 0x60, 0x63, 0xce, 0x31, 0x33, 0xf3, 0xcb, 0xc4, + 0x06, 0xf7, 0xa2, 0x17, 0xfd, 0x2d, 0xcc, 0xad, 0xb4, 0xf9, 0x1c, 0xcf, 0xd1, 0x21, 0xdc, 0x8b, + 0x88, 0x00, 0x49, 0x24, 0x32, 0x90, 0x09, 0x15, 0xdf, 0x61, 0xbe, 0x64, 0x97, 0x35, 0xbe, 0x38, + 0xbf, 0x78, 0x70, 0xb2, 0x73, 0x1b, 0x4d, 0x87, 0xf9, 0x51, 0x2b, 0x32, 0x97, 0xfe, 0x1c, 0xee, + 0x77, 0x26, 0xee, 0x88, 0x30, 0x16, 0x97, 0x3e, 0x81, 0xa9, 0x01, 0x9e, 0xab, 0xa0, 0x98, 0x2a, + 0x65, 0x8e, 0x4b, 0xe5, 0x6d, 0xa3, 0x2c, 0xaf, 0x77, 0x6c, 0x8a, 0x20, 0xfd, 0x3b, 0x00, 0xef, + 0xad, 0x09, 0xde, 0xa3, 0xcb, 0x7c, 0x60, 0xe7, 0x7c, 0xa8, 0x08, 0x33, 0xab, 0x4b, 0x90, 0x8c, + 0x46, 0xb5, 0xe2, 0x12, 0x42, 0x8d, 0xc5, 0xce, 0xc4, 0x63, 0x8c, 0x0c, 0xfd, 0x37, 0x00, 0x73, + 0x4b, 0x56, 0x35, 0x87, 0x3b, 0xe8, 0x6b, 0x98, 0x9f, 0x92, 0x3e, 0x19, 0x3a, 0x01, 0xc7, 0xb6, + 0xd3, 0xed, 0x86, 0x98, 0x31, 0xcc, 0xe2, 0xb6, 0x9e, 0x6c, 0x6f, 0xab, 0xba, 0xb0, 0x4e, 0xaf, + 0x83, 0x4c, 0xb4, 0xc8, 0xb4, 0xf0, 0xa1, 0x1a, 0xbc, 0xcb, 0x67, 0xcc, 0x26, 0x41, 0x8f, 0xaa, + 0x49, 0xa9, 0xdd, 0xe3, 0xff, 0xc4, 0x55, 0x68, 0x64, 0xbe, 0xc7, 0x67, 0x4c, 0x8a, 0x75, 0x08, + 0xf7, 0xf0, 0x98, 0x7a, 0xbe, 0xa4, 0xa3, 0x98, 0x91, 0x21, 0x64, 0x4d, 0xd7, 0xc5, 0x2f, 0xc9, + 0xe4, 0x19, 0x54, 0x06, 0x78, 0xce, 0xe2, 0x09, 0x3d, 0xda, 0x5e, 0x65, 0x6d, 0xae, 0xa6, 0x0c, + 0x42, 0xcf, 0xe0, 0x1d, 0xc6, 0x1d, 0x3e, 0x61, 0x52, 0xcc, 0xdc, 0xf1, 0x87, 0xdb, 0xc3, 0x0d, + 0xee, 0x75, 0x24, 0xd4, 0x8c, 0x43, 0xf4, 0x33, 0x98, 0xbf, 0x45, 0x0e, 0x74, 0x04, 0xd3, 0x4c, + 0x94, 0xe2, 0x1c, 0x87, 0xf1, 0xa1, 0x2e, 0x1d, 0xa8, 0x00, 0xef, 0x86, 0x78, 0x4c, 0x43, 0xf1, + 0x18, 0x0d, 0x70, 0x61, 0xeb, 0x7f, 0xa6, 0xe0, 0xfb, 0x86, 0x55, 0x5d, 0x26, 0x95, 0x22, 0x3c, + 0x84, 0x59, 0xc9, 0xdb, 0x0e, 0x26, 0x23, 0x37, 0x4e, 0xa9, 0x98, 0x19, 0xe9, 0x6b, 0x4b, 0x17, + 0x6a, 0xc0, 0xa2, 0x8b, 0x19, 0xb7, 0xd9, 0x82, 0xa2, 0x3c, 0x53, 0x77, 0x48, 0xbd, 0x81, 0xed, + 0x63, 0xd2, 0xf7, 0xb9, 0x2c, 0xa6, 0x98, 0x47, 0x02, 0xb7, 0x54, 0xc2, 0xe0, 0x9e, 0x21, 0x40, + 0x4d, 0x89, 0x41, 0xdf, 0x02, 0xa8, 0xfd, 0x43, 0x22, 0x71, 0x6c, 0xa9, 0xff, 0xe5, 0xd8, 0x0a, + 0x5b, 0xda, 0x70, 0x98, 0x8f, 0x06, 0xf0, 0x68, 0xb3, 0x87, 0x95, 0x15, 0x67, 0xaa, 0xb2, 0xeb, + 0x3a, 0x6d, 0x14, 0x5b, 0x79, 0x66, 0xe8, 0x1b, 0x00, 0x3f, 0xda, 0xac, 0x76, 0xe3, 0x30, 0xec, + 0x21, 0x61, 0x5c, 0xdd, 0x93, 0x75, 0x77, 0xbc, 0x0d, 0x7d, 0xbd, 0xf6, 0x57, 0x1b, 0x97, 0xf2, + 0x82, 0x30, 0xfe, 0xf1, 0x4f, 0x00, 0xa6, 0x17, 0xdb, 0x85, 0x1e, 0xc3, 0x0f, 0xea, 0xaf, 0xce, + 0xaa, 0x4d, 0xbb, 0x63, 0x9d, 0x5a, 0xaf, 0x3b, 0x76, 0xe7, 0xb5, 0xf1, 0xb2, 0x65, 0x59, 0xf5, + 0xda, 0x41, 0xa2, 0xb0, 0xff, 0xc3, 0xcf, 0xc5, 0x74, 0x27, 0xde, 0xa5, 0xee, 0x0d, 0x68, 0xf5, + 0xac, 0xdd, 0x68, 0x99, 0x2f, 0xeb, 0xb5, 0x03, 0x10, 0x41, 0xab, 0xd1, 0xbf, 0xeb, 0x2d, 0xd0, + 0x46, 0xab, 0x7d, 0xfa, 0xa2, 0xf5, 0xa6, 0x5e, 0x3b, 0x48, 0x46, 0xd0, 0x06, 0x09, 0x9c, 0x21, + 0x79, 0x8b, 0xbb, 0x05, 0xe5, 0xfb, 0x5f, 0xb4, 0x84, 0xf1, 0xe5, 0xaf, 0x97, 0x1a, 0x78, 0x77, + 0xa9, 0x81, 0x3f, 0x2e, 0x35, 0xf0, 0xe3, 0x95, 0x96, 0x78, 0x77, 0xa5, 0x25, 0x7e, 0xbf, 0xd2, + 0x12, 0x6f, 0x3e, 0xff, 0xf7, 0xb9, 0xcf, 0x36, 0x3e, 0x8c, 0x72, 0x0f, 0xdc, 0x3b, 0xf2, 0xf3, + 0xf6, 0xe9, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x35, 0x29, 0x9d, 0x36, 0x3e, 0x07, 0x00, 0x00, } func (m *BTCSpvProof) Marshal() (dAtA []byte, err error) { @@ -1367,7 +1367,7 @@ func (m *BTCSpvProof) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderBytes m.ConfirmingBtcHeader = &v if err := m.ConfirmingBtcHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1471,7 +1471,7 @@ func (m *TransactionKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderHashBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes m.Hash = &v if err := m.Hash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2192,7 +2192,7 @@ func (m *BTCCheckpointInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderHashBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes m.BestSubmissionBtcBlockHash = &v if err := m.BestSubmissionBtcBlockHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btccheckpoint/types/btcutils.go b/x/btccheckpoint/types/btcutils.go index 9fc55702c..b03d476ae 100644 --- a/x/btccheckpoint/types/btcutils.go +++ b/x/btccheckpoint/types/btcutils.go @@ -6,7 +6,7 @@ import ( "fmt" "math/big" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/x/btccheckpoint/types/btcutils_test.go b/x/btccheckpoint/types/btcutils_test.go index 803750dd4..405b7bde3 100644 --- a/x/btccheckpoint/types/btcutils_test.go +++ b/x/btccheckpoint/types/btcutils_test.go @@ -7,9 +7,9 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/btcsuite/btcd/btcutil" btcchaincfg "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/x/btccheckpoint/types/expected_keepers.go b/x/btccheckpoint/types/expected_keepers.go index 1d9da3675..324fccefc 100644 --- a/x/btccheckpoint/types/expected_keepers.go +++ b/x/btccheckpoint/types/expected_keepers.go @@ -2,8 +2,8 @@ package types import ( "context" - txformat "github.com/babylonchain/babylon/btctxformatter" - bbn "github.com/babylonchain/babylon/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + bbn "github.com/babylonlabs-io/babylon/types" ) type BTCLightClientKeeper interface { diff --git a/x/btccheckpoint/types/genesis.pb.go b/x/btccheckpoint/types/genesis.pb.go index a99ce5d8d..804cc55d5 100644 --- a/x/btccheckpoint/types/genesis.pb.go +++ b/x/btccheckpoint/types/genesis.pb.go @@ -77,7 +77,7 @@ func init() { } var fileDescriptor_9776220697c13f63 = []byte{ - // 205 bytes of a gzipped FileDescriptorProto + // 207 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4b, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x4e, 0xce, 0x48, 0x4d, 0xce, 0x2e, 0xc8, 0xcf, 0xcc, 0x2b, 0xd1, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, @@ -86,11 +86,11 @@ var fileDescriptor_9776220697c13f63 = []byte{ 0x28, 0x31, 0x17, 0x6a, 0xac, 0x92, 0x1f, 0x17, 0x8f, 0x3b, 0xc4, 0x9e, 0xe0, 0x92, 0xc4, 0x92, 0x54, 0x21, 0x3b, 0x2e, 0x36, 0x88, 0xbc, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0x82, 0x1e, 0x2e, 0x7b, 0xf5, 0x02, 0xc0, 0xea, 0x9c, 0x58, 0x4e, 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x72, - 0xf2, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, - 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xd3, 0xf4, 0xcc, 0x92, - 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, 0x99, 0xc9, 0x19, 0x89, 0x99, 0x79, 0x30, - 0x8e, 0x7e, 0x05, 0x9a, 0x53, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0xee, 0x34, 0x06, - 0x04, 0x00, 0x00, 0xff, 0xff, 0x60, 0x50, 0x97, 0x1e, 0x28, 0x01, 0x00, 0x00, + 0x0a, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, + 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xf3, 0xf4, 0xcc, 0x92, + 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, 0x99, 0x39, 0x89, 0x49, 0xc5, 0xba, 0x99, + 0xf9, 0x30, 0xae, 0x7e, 0x05, 0x9a, 0x63, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x2e, + 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xa9, 0x6b, 0x00, 0x2a, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/btccheckpoint/types/genesis_test.go b/x/btccheckpoint/types/genesis_test.go index 068fd4e15..aa5c98b5d 100644 --- a/x/btccheckpoint/types/genesis_test.go +++ b/x/btccheckpoint/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/x/btccheckpoint/types/mock_keepers.go b/x/btccheckpoint/types/mock_keepers.go index 3d533d24f..8d58c3dc3 100644 --- a/x/btccheckpoint/types/mock_keepers.go +++ b/x/btccheckpoint/types/mock_keepers.go @@ -4,8 +4,8 @@ import ( "context" "errors" - txformat "github.com/babylonchain/babylon/btctxformatter" - bbn "github.com/babylonchain/babylon/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + bbn "github.com/babylonlabs-io/babylon/types" ) type MockBTCLightClientKeeper struct { diff --git a/x/btccheckpoint/types/msgs.go b/x/btccheckpoint/types/msgs.go index 312f7cc68..ee645c24e 100644 --- a/x/btccheckpoint/types/msgs.go +++ b/x/btccheckpoint/types/msgs.go @@ -5,7 +5,7 @@ import ( fmt "fmt" "math/big" - txformat "github.com/babylonchain/babylon/btctxformatter" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) diff --git a/x/btccheckpoint/types/params.go b/x/btccheckpoint/types/params.go index 6a72e6e32..68b62f4b7 100644 --- a/x/btccheckpoint/types/params.go +++ b/x/btccheckpoint/types/params.go @@ -4,7 +4,7 @@ import ( "encoding/hex" "fmt" - txformat "github.com/babylonchain/babylon/btctxformatter" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" ) const ( diff --git a/x/btccheckpoint/types/params.pb.go b/x/btccheckpoint/types/params.pb.go index 4f6d10a6c..a2f432d08 100644 --- a/x/btccheckpoint/types/params.pb.go +++ b/x/btccheckpoint/types/params.pb.go @@ -104,7 +104,7 @@ func init() { } var fileDescriptor_5445a19005ae983c = []byte{ - // 306 bytes of a gzipped FileDescriptorProto + // 308 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x4e, 0xce, 0x48, 0x4d, 0xce, 0x2e, 0xc8, 0xcf, 0xcc, 0x2b, 0xd1, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, @@ -119,12 +119,12 @@ var fileDescriptor_5445a19005ae983c = []byte{ 0xa5, 0x20, 0x59, 0x84, 0x0a, 0x37, 0x24, 0x05, 0x21, 0x10, 0x79, 0x21, 0x07, 0x2e, 0x3e, 0x24, 0x23, 0x4a, 0x12, 0xd3, 0x25, 0x98, 0x15, 0x18, 0x35, 0x38, 0x9d, 0x24, 0x3f, 0xdd, 0x93, 0x17, 0xc5, 0xb0, 0xa2, 0x24, 0x31, 0x5d, 0x29, 0x88, 0x17, 0x21, 0x10, 0x92, 0x98, 0x6e, 0xc5, 0xf2, - 0x62, 0x81, 0x3c, 0xa3, 0x93, 0xff, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, + 0x62, 0x81, 0x3c, 0xa3, 0x53, 0xe0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, - 0x99, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x03, 0x3d, 0x39, - 0x23, 0x31, 0x33, 0x0f, 0xc6, 0xd1, 0xaf, 0x40, 0x8b, 0xaa, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, - 0x36, 0x70, 0xb8, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x78, 0xcb, 0x81, 0xd0, 0x01, - 0x00, 0x00, + 0x99, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x03, 0x3d, 0x27, + 0x31, 0xa9, 0x58, 0x37, 0x33, 0x1f, 0xc6, 0xd5, 0xaf, 0x40, 0x8b, 0xac, 0x92, 0xca, 0x82, 0xd4, + 0xe2, 0x24, 0x36, 0x70, 0xc8, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x82, 0xde, 0x0b, + 0xd2, 0x01, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/btccheckpoint/types/params_test.go b/x/btccheckpoint/types/params_test.go index e22e25245..a534b9a0a 100644 --- a/x/btccheckpoint/types/params_test.go +++ b/x/btccheckpoint/types/params_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" "github.com/stretchr/testify/require" ) diff --git a/x/btccheckpoint/types/query.pb.go b/x/btccheckpoint/types/query.pb.go index 05ce91205..88a83251e 100644 --- a/x/btccheckpoint/types/query.pb.go +++ b/x/btccheckpoint/types/query.pb.go @@ -720,67 +720,67 @@ func init() { } var fileDescriptor_6b9a2f46ada7d854 = []byte{ - // 949 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x41, 0x6f, 0xdc, 0x44, - 0x14, 0x8e, 0x37, 0x4e, 0x94, 0x7d, 0x69, 0xa1, 0x9d, 0x2e, 0x62, 0xb3, 0x09, 0xdb, 0xad, 0xd5, - 0xa6, 0x11, 0x22, 0xb6, 0xb6, 0xa1, 0x2d, 0x15, 0x08, 0x89, 0x8d, 0x68, 0xa9, 0x40, 0x10, 0xdc, - 0xc0, 0x81, 0x8b, 0x35, 0xf6, 0x4e, 0xec, 0x51, 0x76, 0x3d, 0xae, 0x67, 0x36, 0xca, 0xaa, 0xe2, + // 950 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x41, 0x6f, 0x1b, 0x45, + 0x14, 0xce, 0x3a, 0x9b, 0x28, 0x7e, 0x69, 0xa1, 0x9d, 0x1a, 0xe1, 0x38, 0xc1, 0x75, 0x57, 0x6d, + 0x1a, 0x21, 0xbc, 0x2b, 0x37, 0xd0, 0x50, 0x81, 0x90, 0x70, 0x44, 0x4b, 0x05, 0x42, 0xe9, 0x36, + 0x70, 0xe0, 0xb2, 0x9a, 0x5d, 0x4f, 0xd6, 0xa3, 0xd8, 0x3b, 0xdb, 0x9d, 0x71, 0x14, 0xab, 0xe2, 0xc2, 0x0d, 0x71, 0x00, 0x89, 0xbf, 0xc1, 0x11, 0x6e, 0x08, 0x89, 0x03, 0x52, 0x25, 0x2e, 0x15, - 0x5c, 0x38, 0x21, 0x94, 0xf0, 0x43, 0x2a, 0xcf, 0xcc, 0xae, 0xbd, 0x9b, 0xb8, 0x9b, 0xf4, 0xb6, - 0xf6, 0x7c, 0xdf, 0xf7, 0xbe, 0xf9, 0xde, 0x8b, 0x5f, 0xe0, 0xba, 0x8f, 0xfd, 0x61, 0x8f, 0xc5, - 0x8e, 0x2f, 0x82, 0x20, 0x22, 0xc1, 0x7e, 0xc2, 0x68, 0x2c, 0x9c, 0x83, 0xb6, 0xf3, 0x78, 0x40, - 0xd2, 0xa1, 0x9d, 0xa4, 0x4c, 0x30, 0x54, 0xd7, 0x28, 0x7b, 0x02, 0x65, 0x1f, 0xb4, 0x1b, 0xb5, - 0x90, 0x85, 0x4c, 0x82, 0x9c, 0xec, 0x97, 0xc2, 0x37, 0x56, 0x02, 0xc6, 0xfb, 0x8c, 0x7b, 0xea, - 0x40, 0x3d, 0xe8, 0xa3, 0xb5, 0x90, 0xb1, 0xb0, 0x47, 0x1c, 0x9c, 0x50, 0x07, 0xc7, 0x31, 0x13, - 0x58, 0x50, 0x16, 0x8f, 0x4e, 0xdf, 0x54, 0x58, 0xc7, 0xc7, 0x9c, 0x28, 0x07, 0xce, 0x41, 0xdb, - 0x27, 0x02, 0xb7, 0x9d, 0x04, 0x87, 0x34, 0x96, 0x60, 0x8d, 0xbd, 0x51, 0x6a, 0x3d, 0xc1, 0x29, - 0xee, 0x6b, 0x49, 0xab, 0x06, 0xe8, 0xf3, 0x4c, 0x68, 0x47, 0xbe, 0x74, 0xc9, 0xe3, 0x01, 0xe1, - 0xc2, 0xfa, 0x02, 0xae, 0x4c, 0xbc, 0xe5, 0x09, 0x8b, 0x39, 0x41, 0xef, 0xc3, 0xa2, 0x22, 0xd7, - 0x8d, 0x96, 0xb1, 0xb1, 0x7c, 0xab, 0x65, 0x97, 0xdd, 0xdc, 0x56, 0xcc, 0x8e, 0xf9, 0xf4, 0xdf, - 0xab, 0x73, 0xae, 0x66, 0x59, 0xef, 0xc1, 0x1b, 0x52, 0xb6, 0x23, 0x82, 0xed, 0x31, 0xfa, 0x61, - 0xbc, 0xc7, 0x74, 0x5d, 0xb4, 0x0a, 0x55, 0x92, 0xb0, 0x20, 0xf2, 0xe2, 0x41, 0x5f, 0xd6, 0x30, - 0xdd, 0x25, 0xf9, 0xe2, 0xd3, 0x41, 0xdf, 0xa2, 0xd0, 0x2c, 0x63, 0x6b, 0x7f, 0x0f, 0xc0, 0xa4, - 0xf1, 0x1e, 0xd3, 0xee, 0xb6, 0xca, 0xdd, 0x75, 0x76, 0xb7, 0x4f, 0x97, 0x70, 0xa5, 0x80, 0x15, - 0x9d, 0x56, 0x8a, 0x17, 0x9d, 0xde, 0x07, 0xc8, 0x23, 0xd7, 0x05, 0xd7, 0x6d, 0xdd, 0xcb, 0xac, - 0x3f, 0xb6, 0x9a, 0x10, 0xdd, 0x1f, 0x7b, 0x07, 0x87, 0x44, 0x73, 0xdd, 0x02, 0xd3, 0xfa, 0xd5, - 0x80, 0xab, 0xa5, 0xa5, 0xf4, 0xb5, 0x76, 0xa0, 0x9a, 0xb9, 0xf2, 0x7a, 0x94, 0x8b, 0xba, 0xd1, - 0x9a, 0x7f, 0xd9, 0xbb, 0x2d, 0x65, 0x2a, 0x9f, 0x50, 0x2e, 0xd0, 0x83, 0x09, 0xf7, 0x15, 0xe9, - 0xfe, 0xe6, 0x4c, 0xf7, 0x5a, 0xa6, 0x68, 0xff, 0x5d, 0x58, 0x93, 0xee, 0x3f, 0xcc, 0x9a, 0xf4, - 0x68, 0xe0, 0xf7, 0x29, 0xe7, 0xd9, 0xc0, 0x9e, 0xa9, 0xa1, 0x5d, 0x3d, 0x0e, 0x27, 0xc9, 0xfa, - 0xe2, 0xdb, 0x60, 0xee, 0x93, 0x21, 0xd7, 0x77, 0x76, 0xca, 0xef, 0x9c, 0x93, 0x3f, 0x26, 0xc3, - 0xbc, 0x97, 0x19, 0xd9, 0xfa, 0x73, 0x1e, 0x56, 0x4a, 0x33, 0x41, 0xd7, 0xe0, 0xc2, 0xd8, 0xa0, - 0x4f, 0x52, 0xed, 0x71, 0x79, 0xe4, 0xd1, 0x27, 0x29, 0xba, 0x0f, 0x2d, 0x9f, 0x70, 0xe1, 0xf1, - 0x71, 0x11, 0xcf, 0x17, 0x81, 0xe7, 0xf7, 0x58, 0xb0, 0xef, 0x45, 0x84, 0x86, 0x91, 0x90, 0x11, - 0x9a, 0xee, 0x5a, 0x86, 0xcb, 0xbd, 0x74, 0x44, 0xd0, 0xc9, 0x40, 0x1f, 0x49, 0x0c, 0xea, 0x40, - 0xf3, 0x05, 0x3a, 0x98, 0x47, 0xf5, 0xf9, 0x96, 0xb1, 0x51, 0x75, 0x1b, 0x25, 0x2a, 0x98, 0x47, - 0x88, 0xc3, 0xda, 0xb4, 0x86, 0x48, 0x71, 0xcc, 0x71, 0x20, 0xbf, 0x13, 0x75, 0x53, 0x26, 0xd5, - 0x2e, 0x4f, 0x6a, 0x37, 0x47, 0x4f, 0xcc, 0xc6, 0x54, 0xd1, 0x02, 0x8c, 0xa3, 0x6f, 0x0d, 0x58, - 0x9f, 0xae, 0x7a, 0x40, 0x43, 0xda, 0xc3, 0xb1, 0x20, 0x1e, 0xee, 0x76, 0x53, 0xc2, 0xb9, 0x9a, - 0xce, 0x05, 0x59, 0xff, 0x76, 0x79, 0xfd, 0xbc, 0x0d, 0x1f, 0x28, 0x1e, 0x19, 0xb7, 0xdb, 0xb5, - 0x26, 0x3d, 0x7c, 0x39, 0x2a, 0xa1, 0x91, 0xd9, 0xe4, 0x5a, 0x4f, 0xe0, 0xf5, 0x92, 0x2b, 0xa0, - 0x1a, 0x2c, 0xd0, 0xb8, 0x4b, 0x0e, 0x65, 0x0f, 0x2f, 0xba, 0xea, 0x01, 0x21, 0x30, 0x65, 0xb6, - 0x15, 0x99, 0xad, 0xfc, 0x8d, 0x5a, 0xb0, 0x5c, 0x48, 0x4d, 0xc7, 0x5e, 0x7c, 0x95, 0x69, 0x25, - 0x29, 0x63, 0x7b, 0x75, 0x53, 0x9e, 0xa9, 0x07, 0xeb, 0x3b, 0x03, 0x56, 0x5f, 0x70, 0x01, 0x74, - 0x07, 0xaa, 0x32, 0x22, 0x21, 0xf4, 0x24, 0x55, 0x3b, 0xf5, 0xbf, 0x7e, 0xde, 0xac, 0xe9, 0x3f, - 0x2c, 0x4d, 0x78, 0x24, 0x52, 0x1a, 0x87, 0x6e, 0x0e, 0x45, 0x6f, 0xc3, 0x52, 0x4a, 0x12, 0x96, - 0x66, 0xb4, 0xca, 0x0c, 0xda, 0x18, 0x69, 0xfd, 0x61, 0xc0, 0x6b, 0xa7, 0x0e, 0x3e, 0xda, 0x84, - 0x2b, 0x7b, 0x34, 0xe5, 0xc2, 0x13, 0x87, 0xc5, 0xf1, 0x92, 0x8e, 0xdc, 0x4b, 0xf2, 0x68, 0xf7, - 0x30, 0x1f, 0xaa, 0xeb, 0xf0, 0xca, 0x18, 0xae, 0x12, 0xac, 0xc8, 0x04, 0x2f, 0x68, 0xe4, 0x43, - 0x19, 0xa4, 0x03, 0x35, 0x4e, 0x02, 0x16, 0x77, 0xa7, 0x54, 0x55, 0x7a, 0x97, 0xd5, 0x59, 0x51, - 0x76, 0x1d, 0x5e, 0xcd, 0x09, 0x4a, 0xd7, 0x94, 0xba, 0x17, 0x47, 0x58, 0x29, 0x7c, 0xeb, 0xf7, - 0x05, 0x58, 0x90, 0xdf, 0x01, 0xf4, 0xbd, 0x01, 0x8b, 0x6a, 0x71, 0xa0, 0xb7, 0xca, 0x47, 0xe8, - 0xe4, 0xbe, 0x6a, 0x6c, 0x9e, 0x11, 0xad, 0xf2, 0xb1, 0x36, 0xbe, 0xf9, 0xfb, 0xff, 0x1f, 0x2b, - 0x16, 0x6a, 0x39, 0x33, 0x96, 0x24, 0xfa, 0xc5, 0x80, 0xcb, 0x27, 0xf6, 0x0d, 0xba, 0x3b, 0xa3, - 0x5c, 0xd9, 0x7e, 0x6b, 0xbc, 0x73, 0x7e, 0xa2, 0xb6, 0xbc, 0x29, 0x2d, 0xdf, 0x44, 0x37, 0xca, - 0x2d, 0x3f, 0x19, 0x7f, 0xc8, 0xbe, 0x46, 0x3f, 0x19, 0x80, 0x4e, 0x6e, 0x14, 0x74, 0xae, 0xfa, - 0xc5, 0x7d, 0xd7, 0xb8, 0xf7, 0x12, 0x4c, 0x6d, 0xfd, 0x9a, 0xb4, 0xbe, 0x8a, 0x56, 0x4a, 0xad, - 0xa3, 0xdf, 0x0c, 0xb8, 0x34, 0xbd, 0x05, 0xd0, 0x9d, 0x19, 0x25, 0x4b, 0x76, 0x4e, 0xe3, 0xee, - 0xb9, 0x79, 0xda, 0xe8, 0x3d, 0x69, 0x74, 0x0b, 0xb5, 0xcf, 0x94, 0xb1, 0x93, 0x7f, 0x0d, 0x79, - 0xe7, 0xb3, 0xa7, 0x47, 0x4d, 0xe3, 0xd9, 0x51, 0xd3, 0xf8, 0xef, 0xa8, 0x69, 0xfc, 0x70, 0xdc, - 0x9c, 0x7b, 0x76, 0xdc, 0x9c, 0xfb, 0xe7, 0xb8, 0x39, 0xf7, 0xd5, 0xed, 0x90, 0x8a, 0x68, 0xe0, - 0xdb, 0x01, 0xeb, 0x8f, 0x64, 0x83, 0x08, 0xd3, 0x78, 0x5c, 0xe3, 0x70, 0xaa, 0x8a, 0x18, 0x26, - 0x84, 0xfb, 0x8b, 0xf2, 0xdf, 0xb3, 0xad, 0xe7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x07, 0x9f, 0x31, - 0x97, 0x82, 0x0a, 0x00, 0x00, + 0x5c, 0x38, 0x21, 0x94, 0xf0, 0x43, 0xd0, 0xce, 0x8c, 0xbd, 0x6b, 0x3b, 0x5b, 0x27, 0xbd, 0x79, + 0x77, 0xbe, 0xef, 0x7b, 0xdf, 0x7c, 0xef, 0x65, 0x5f, 0xe0, 0xa6, 0x8f, 0xfd, 0x61, 0x8f, 0x45, + 0x8e, 0x2f, 0x82, 0xa0, 0x4b, 0x82, 0xc3, 0x98, 0xd1, 0x48, 0x38, 0x47, 0x2d, 0xe7, 0xc9, 0x80, + 0x24, 0x43, 0x3b, 0x4e, 0x98, 0x60, 0xa8, 0xaa, 0x51, 0xf6, 0x04, 0xca, 0x3e, 0x6a, 0xd5, 0x2a, + 0x21, 0x0b, 0x99, 0x04, 0x39, 0xe9, 0x2f, 0x85, 0xaf, 0xad, 0x05, 0x8c, 0xf7, 0x19, 0xf7, 0xd4, + 0x81, 0x7a, 0xd0, 0x47, 0x1b, 0x21, 0x63, 0x61, 0x8f, 0x38, 0x38, 0xa6, 0x0e, 0x8e, 0x22, 0x26, + 0xb0, 0xa0, 0x2c, 0x1a, 0x9d, 0xbe, 0xa9, 0xb0, 0x8e, 0x8f, 0x39, 0x51, 0x0e, 0x9c, 0xa3, 0x96, + 0x4f, 0x04, 0x6e, 0x39, 0x31, 0x0e, 0x69, 0x24, 0xc1, 0x1a, 0x7b, 0xab, 0xd0, 0x7a, 0x8c, 0x13, + 0xdc, 0xd7, 0x92, 0x56, 0x05, 0xd0, 0xa3, 0x54, 0x68, 0x4f, 0xbe, 0x74, 0xc9, 0x93, 0x01, 0xe1, + 0xc2, 0xfa, 0x1c, 0xae, 0x4d, 0xbc, 0xe5, 0x31, 0x8b, 0x38, 0x41, 0x1f, 0xc0, 0xb2, 0x22, 0x57, + 0x8d, 0x86, 0xb1, 0xb5, 0x7a, 0xa7, 0x61, 0x17, 0xdd, 0xdc, 0x56, 0xcc, 0xb6, 0xf9, 0xec, 0x9f, + 0xeb, 0x0b, 0xae, 0x66, 0x59, 0xef, 0xc3, 0x1b, 0x52, 0xb6, 0x2d, 0x82, 0xdd, 0x31, 0xfa, 0x61, + 0x74, 0xc0, 0x74, 0x5d, 0xb4, 0x0e, 0x65, 0x12, 0xb3, 0xa0, 0xeb, 0x45, 0x83, 0xbe, 0xac, 0x61, + 0xba, 0x2b, 0xf2, 0xc5, 0x67, 0x83, 0xbe, 0x45, 0xa1, 0x5e, 0xc4, 0xd6, 0xfe, 0x1e, 0x80, 0x49, + 0xa3, 0x03, 0xa6, 0xdd, 0x6d, 0x17, 0xbb, 0x6b, 0xef, 0xef, 0x9e, 0x2d, 0xe1, 0x4a, 0x01, 0xab, + 0x7b, 0x56, 0x29, 0x9e, 0x77, 0x7a, 0x1f, 0x20, 0x8b, 0x5c, 0x17, 0xdc, 0xb4, 0x75, 0x2f, 0xd3, + 0xfe, 0xd8, 0x6a, 0x42, 0x74, 0x7f, 0xec, 0x3d, 0x1c, 0x12, 0xcd, 0x75, 0x73, 0x4c, 0xeb, 0x17, + 0x03, 0xae, 0x17, 0x96, 0xd2, 0xd7, 0xda, 0x83, 0x72, 0xea, 0xca, 0xeb, 0x51, 0x2e, 0xaa, 0x46, + 0x63, 0xf1, 0x65, 0xef, 0xb6, 0x92, 0xaa, 0x7c, 0x4a, 0xb9, 0x40, 0x0f, 0x26, 0xdc, 0x97, 0xa4, + 0xfb, 0xdb, 0x73, 0xdd, 0x6b, 0x99, 0xbc, 0xfd, 0xf7, 0x60, 0x43, 0xba, 0xff, 0x28, 0x6d, 0xd2, + 0xe3, 0x81, 0xdf, 0xa7, 0x9c, 0xa7, 0x03, 0x7b, 0xae, 0x86, 0x76, 0xf4, 0x38, 0xcc, 0x92, 0xf5, + 0xc5, 0x77, 0xc1, 0x3c, 0x24, 0x43, 0xae, 0xef, 0xec, 0x14, 0xdf, 0x39, 0x23, 0x7f, 0x42, 0x86, + 0x59, 0x2f, 0x53, 0xb2, 0xf5, 0xc7, 0x22, 0xac, 0x15, 0x66, 0x82, 0x6e, 0xc0, 0xa5, 0xb1, 0x41, + 0x9f, 0x24, 0xda, 0xe3, 0xea, 0xc8, 0xa3, 0x4f, 0x12, 0x74, 0x1f, 0x1a, 0x3e, 0xe1, 0xc2, 0xe3, + 0xe3, 0x22, 0x9e, 0x2f, 0x02, 0xcf, 0xef, 0xb1, 0xe0, 0xd0, 0xeb, 0x12, 0x1a, 0x76, 0x85, 0x8c, + 0xd0, 0x74, 0x37, 0x52, 0x5c, 0xe6, 0xa5, 0x2d, 0x82, 0x76, 0x0a, 0xfa, 0x58, 0x62, 0x50, 0x1b, + 0xea, 0x2f, 0xd0, 0xc1, 0xbc, 0x5b, 0x5d, 0x6c, 0x18, 0x5b, 0x65, 0xb7, 0x56, 0xa0, 0x82, 0x79, + 0x17, 0x71, 0xd8, 0x98, 0xd6, 0x10, 0x09, 0x8e, 0x38, 0x0e, 0xe4, 0x77, 0xa2, 0x6a, 0xca, 0xa4, + 0x5a, 0xc5, 0x49, 0xed, 0x67, 0xe8, 0x89, 0xd9, 0x98, 0x2a, 0x9a, 0x83, 0x71, 0xf4, 0x8d, 0x01, + 0x9b, 0xd3, 0x55, 0x8f, 0x68, 0x48, 0x7b, 0x38, 0x12, 0xc4, 0xc3, 0x9d, 0x4e, 0x42, 0x38, 0x57, + 0xd3, 0xb9, 0x24, 0xeb, 0xbf, 0x53, 0x5c, 0x3f, 0x6b, 0xc3, 0x87, 0x8a, 0x47, 0xc6, 0xed, 0x76, + 0xad, 0x49, 0x0f, 0x5f, 0x8c, 0x4a, 0x68, 0x64, 0x3a, 0xb9, 0xd6, 0x53, 0x78, 0xbd, 0xe0, 0x0a, + 0xa8, 0x02, 0x4b, 0x34, 0xea, 0x90, 0x63, 0xd9, 0xc3, 0xcb, 0xae, 0x7a, 0x40, 0x08, 0x4c, 0x99, + 0x6d, 0x49, 0x66, 0x2b, 0x7f, 0xa3, 0x06, 0xac, 0xe6, 0x52, 0xd3, 0xb1, 0xe7, 0x5f, 0xa5, 0x5a, + 0x71, 0xc2, 0xd8, 0x41, 0xd5, 0x94, 0x67, 0xea, 0xc1, 0xfa, 0xd6, 0x80, 0xf5, 0x17, 0x5c, 0x00, + 0xdd, 0x85, 0xb2, 0x8c, 0x48, 0x08, 0x3d, 0x49, 0xe5, 0x76, 0xf5, 0xcf, 0x9f, 0x9a, 0x15, 0xfd, + 0x87, 0xa5, 0x09, 0x8f, 0x45, 0x42, 0xa3, 0xd0, 0xcd, 0xa0, 0xe8, 0x6d, 0x58, 0x49, 0x48, 0xcc, + 0x92, 0x94, 0x56, 0x9a, 0x43, 0x1b, 0x23, 0xad, 0xdf, 0x0d, 0x78, 0xed, 0xcc, 0xc1, 0x47, 0x4d, + 0xb8, 0x76, 0x40, 0x13, 0x2e, 0x3c, 0x71, 0x9c, 0x1f, 0x2f, 0xe9, 0xc8, 0xbd, 0x22, 0x8f, 0xf6, + 0x8f, 0xb3, 0xa1, 0xba, 0x09, 0xaf, 0x8c, 0xe1, 0x2a, 0xc1, 0x92, 0x4c, 0xf0, 0x92, 0x46, 0x3e, + 0x94, 0x41, 0x3a, 0x50, 0xe1, 0x24, 0x60, 0x51, 0x67, 0x4a, 0x55, 0xa5, 0x77, 0x55, 0x9d, 0xe5, + 0x65, 0x37, 0xe1, 0xd5, 0x8c, 0xa0, 0x74, 0x4d, 0xa9, 0x7b, 0x79, 0x84, 0x95, 0xc2, 0x77, 0x7e, + 0x5b, 0x82, 0x25, 0xf9, 0x1d, 0x40, 0xdf, 0x19, 0xb0, 0xac, 0x16, 0x07, 0x7a, 0xab, 0x78, 0x84, + 0x66, 0xf7, 0x55, 0xad, 0x79, 0x4e, 0xb4, 0xca, 0xc7, 0xda, 0xfa, 0xfa, 0xaf, 0xff, 0x7e, 0x28, + 0x59, 0xa8, 0xe1, 0xcc, 0x59, 0x92, 0xe8, 0x67, 0x03, 0xae, 0xce, 0xec, 0x1b, 0xb4, 0x33, 0xa7, + 0x5c, 0xd1, 0x7e, 0xab, 0xbd, 0x7b, 0x71, 0xa2, 0xb6, 0xdc, 0x94, 0x96, 0x6f, 0xa3, 0x5b, 0xc5, + 0x96, 0x9f, 0x8e, 0x3f, 0x64, 0x5f, 0xa1, 0x1f, 0x0d, 0x40, 0xb3, 0x1b, 0x05, 0x5d, 0xa8, 0x7e, + 0x7e, 0xdf, 0xd5, 0xee, 0xbd, 0x04, 0x53, 0x5b, 0xbf, 0x21, 0xad, 0xaf, 0xa3, 0xb5, 0x42, 0xeb, + 0xe8, 0x57, 0x03, 0xae, 0x4c, 0x6f, 0x01, 0x74, 0x77, 0x4e, 0xc9, 0x82, 0x9d, 0x53, 0xdb, 0xb9, + 0x30, 0x4f, 0x1b, 0xbd, 0x27, 0x8d, 0x6e, 0xa3, 0xd6, 0xb9, 0x32, 0x76, 0xb2, 0xaf, 0x21, 0x6f, + 0x3f, 0x7a, 0x76, 0x52, 0x37, 0x9e, 0x9f, 0xd4, 0x8d, 0x7f, 0x4f, 0xea, 0xc6, 0xf7, 0xa7, 0xf5, + 0x85, 0xe7, 0xa7, 0xf5, 0x85, 0xbf, 0x4f, 0xeb, 0x0b, 0x5f, 0xee, 0x84, 0x54, 0x74, 0x07, 0xbe, + 0x1d, 0xb0, 0xfe, 0x48, 0xb6, 0x87, 0x7d, 0xde, 0xa4, 0x6c, 0x5c, 0xe5, 0x78, 0xaa, 0x8e, 0x18, + 0xc6, 0x84, 0xfb, 0xcb, 0xf2, 0x1f, 0xb4, 0xed, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x12, 0x02, + 0x0c, 0x21, 0x84, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/btccheckpoint/types/tx.pb.go b/x/btccheckpoint/types/tx.pb.go index f02e60b7d..3e3f75258 100644 --- a/x/btccheckpoint/types/tx.pb.go +++ b/x/btccheckpoint/types/tx.pb.go @@ -229,7 +229,7 @@ func init() { func init() { proto.RegisterFile("babylon/btccheckpoint/v1/tx.proto", fileDescriptor_69a562325f8b35c5) } var fileDescriptor_69a562325f8b35c5 = []byte{ - // 439 bytes of a gzipped FileDescriptorProto + // 441 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0x4e, 0xce, 0x48, 0x4d, 0xce, 0x2e, 0xc8, 0xcf, 0xcc, 0x2b, 0xd1, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, @@ -252,12 +252,12 @@ var fileDescriptor_69a562325f8b35c5 = []byte{ 0xcd, 0x69, 0x30, 0x67, 0x1b, 0x7d, 0x67, 0xe4, 0x62, 0xf6, 0x2d, 0x4e, 0x17, 0xaa, 0xe6, 0x12, 0xc4, 0x0c, 0x60, 0x3d, 0xdc, 0xf6, 0x62, 0x0b, 0x0b, 0x29, 0x33, 0xd2, 0xd4, 0xc3, 0x1c, 0x21, 0x94, 0xc3, 0xc5, 0x83, 0x12, 0x6e, 0x9a, 0x78, 0xcd, 0x41, 0x56, 0x2a, 0x65, 0x48, 0xb4, 0x52, - 0x98, 0x6d, 0x52, 0xac, 0x0d, 0xcf, 0x37, 0x68, 0x31, 0x3a, 0xf9, 0x9f, 0x78, 0x24, 0xc7, 0x78, + 0x98, 0x6d, 0x52, 0xac, 0x0d, 0xcf, 0x37, 0x68, 0x31, 0x3a, 0x05, 0x9e, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, - 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x69, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, - 0xae, 0x3e, 0xd4, 0xf4, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, 0x18, 0x47, 0xbf, 0x02, 0x2d, 0x1d, 0x97, - 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x93, 0xab, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x00, - 0x2e, 0x80, 0x63, 0x8c, 0x03, 0x00, 0x00, + 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x79, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, + 0xae, 0x3e, 0xd4, 0xf4, 0x9c, 0xc4, 0xa4, 0x62, 0xdd, 0xcc, 0x7c, 0x18, 0x57, 0xbf, 0x02, 0x2d, + 0x25, 0x97, 0x54, 0x16, 0xa4, 0x16, 0x27, 0xb1, 0x81, 0x13, 0xac, 0x31, 0x20, 0x00, 0x00, 0xff, + 0xff, 0x7e, 0xe3, 0x2b, 0xd2, 0x8e, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/btccheckpoint/types/types.go b/x/btccheckpoint/types/types.go index fa7423a56..e70846158 100644 --- a/x/btccheckpoint/types/types.go +++ b/x/btccheckpoint/types/types.go @@ -5,8 +5,8 @@ import ( "fmt" "math/big" - "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/README.md b/x/btclightclient/README.md index 65609d6f1..7b7134b97 100644 --- a/x/btclightclient/README.md +++ b/x/btclightclient/README.md @@ -115,10 +115,10 @@ which contains the BTC header along with some metadata. message BTCHeaderInfo { bytes header = 1 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" ]; bytes hash = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderHashBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ]; uint64 height = 3; bytes work = 4 [ (gogoproto.customtype) = "cosmossdk.io/math.Uint" ]; @@ -153,7 +153,7 @@ message MsgInsertHeaders { string signer = 1; repeated bytes headers = 2 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/types.BTCHeaderBytes" ]; + "github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" ]; } ``` diff --git a/x/btclightclient/client/cli/query.go b/x/btclightclient/client/cli/query.go index 17faccb2b..fa956d287 100644 --- a/x/btclightclient/client/cli/query.go +++ b/x/btclightclient/client/cli/query.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" diff --git a/x/btclightclient/client/cli/tx.go b/x/btclightclient/client/cli/tx.go index bcf27f541..d2e20d367 100644 --- a/x/btclightclient/client/cli/tx.go +++ b/x/btclightclient/client/cli/tx.go @@ -3,7 +3,7 @@ package cli import ( "fmt" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" diff --git a/x/btclightclient/genesis.go b/x/btclightclient/genesis.go index 81d2f3ff5..a87edd838 100644 --- a/x/btclightclient/genesis.go +++ b/x/btclightclient/genesis.go @@ -3,8 +3,8 @@ package btclightclient import ( "context" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) // InitGenesis initializes the capability module's state from a provided genesis diff --git a/x/btclightclient/genesis_test.go b/x/btclightclient/genesis_test.go index a91066e4f..98ffd13a4 100644 --- a/x/btclightclient/genesis_test.go +++ b/x/btclightclient/genesis_test.go @@ -5,13 +5,13 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" - thelper "github.com/babylonchain/babylon/testutil/helper" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/btclightclient" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + thelper "github.com/babylonlabs-io/babylon/testutil/helper" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/btclightclient" + "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cometbft/cometbft/crypto/secp256k1" "github.com/stretchr/testify/require" diff --git a/x/btclightclient/keeper/base_btc_header.go b/x/btclightclient/keeper/base_btc_header.go index 6c860a512..b1d98710c 100644 --- a/x/btclightclient/keeper/base_btc_header.go +++ b/x/btclightclient/keeper/base_btc_header.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) func (k Keeper) GetBaseBTCHeader(ctx context.Context) *types.BTCHeaderInfo { diff --git a/x/btclightclient/keeper/base_btc_header_test.go b/x/btclightclient/keeper/base_btc_header_test.go index 8fa2eca7f..b6e94f81b 100644 --- a/x/btclightclient/keeper/base_btc_header_test.go +++ b/x/btclightclient/keeper/base_btc_header_test.go @@ -1,8 +1,8 @@ package keeper_test import ( - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/keeper" "math/rand" "testing" ) diff --git a/x/btclightclient/keeper/grpc_query.go b/x/btclightclient/keeper/grpc_query.go index 567c51b19..91d3792e8 100644 --- a/x/btclightclient/keeper/grpc_query.go +++ b/x/btclightclient/keeper/grpc_query.go @@ -3,8 +3,8 @@ package keeper import ( "context" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" diff --git a/x/btclightclient/keeper/grpc_query_test.go b/x/btclightclient/keeper/grpc_query_test.go index 1d2829614..6a6fed783 100644 --- a/x/btclightclient/keeper/grpc_query_test.go +++ b/x/btclightclient/keeper/grpc_query_test.go @@ -4,12 +4,12 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/cosmos/cosmos-sdk/types/query" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) func FuzzHashesQuery(f *testing.F) { diff --git a/x/btclightclient/keeper/hooks.go b/x/btclightclient/keeper/hooks.go index 17ff31d24..076b15da0 100644 --- a/x/btclightclient/keeper/hooks.go +++ b/x/btclightclient/keeper/hooks.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) // Implements BTCLightClientHooks interface diff --git a/x/btclightclient/keeper/keeper.go b/x/btclightclient/keeper/keeper.go index 9cb0330bc..64b7508ba 100644 --- a/x/btclightclient/keeper/keeper.go +++ b/x/btclightclient/keeper/keeper.go @@ -7,11 +7,11 @@ import ( corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/log" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" proto "github.com/cosmos/gogoproto/proto" diff --git a/x/btclightclient/keeper/keeper_test.go b/x/btclightclient/keeper/keeper_test.go index 93e1ff905..90ddeaa96 100644 --- a/x/btclightclient/keeper/keeper_test.go +++ b/x/btclightclient/keeper/keeper_test.go @@ -6,12 +6,12 @@ import ( "testing" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/chaincfg" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/keeper/msg_server.go b/x/btclightclient/keeper/msg_server.go index cd8fff632..90de17942 100644 --- a/x/btclightclient/keeper/msg_server.go +++ b/x/btclightclient/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( "context" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) diff --git a/x/btclightclient/keeper/msg_server_test.go b/x/btclightclient/keeper/msg_server_test.go index 8d9bd3735..343b6859a 100644 --- a/x/btclightclient/keeper/msg_server_test.go +++ b/x/btclightclient/keeper/msg_server_test.go @@ -6,12 +6,12 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/stretchr/testify/require" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/keeper/params.go b/x/btclightclient/keeper/params.go index bd68dd5d6..4e2847d13 100644 --- a/x/btclightclient/keeper/params.go +++ b/x/btclightclient/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) // SetParams sets the x/btclightclient module parameters. diff --git a/x/btclightclient/keeper/params_test.go b/x/btclightclient/keeper/params_test.go index 4dc68b70f..15129bd3a 100644 --- a/x/btclightclient/keeper/params_test.go +++ b/x/btclightclient/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/keeper/state.go b/x/btclightclient/keeper/state.go index 27c869cea..55ddb4e71 100644 --- a/x/btclightclient/keeper/state.go +++ b/x/btclightclient/keeper/state.go @@ -8,8 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/keeper/state_test.go b/x/btclightclient/keeper/state_test.go index eb1e3c892..10d5e34e8 100644 --- a/x/btclightclient/keeper/state_test.go +++ b/x/btclightclient/keeper/state_test.go @@ -4,11 +4,11 @@ import ( "math/rand" "testing" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/keeper/triggers.go b/x/btclightclient/keeper/triggers.go index e01a102c9..15f91f0b6 100644 --- a/x/btclightclient/keeper/triggers.go +++ b/x/btclightclient/keeper/triggers.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) func (k Keeper) triggerHeaderInserted(ctx context.Context, headerInfo *types.BTCHeaderInfo) { diff --git a/x/btclightclient/keeper/utils.go b/x/btclightclient/keeper/utils.go index 55d353cbf..9cc340ab4 100644 --- a/x/btclightclient/keeper/utils.go +++ b/x/btclightclient/keeper/utils.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/codec" ) diff --git a/x/btclightclient/keeper/utils_test.go b/x/btclightclient/keeper/utils_test.go index ec1131655..cbf1a3421 100644 --- a/x/btclightclient/keeper/utils_test.go +++ b/x/btclightclient/keeper/utils_test.go @@ -6,8 +6,8 @@ import ( "testing" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" diff --git a/x/btclightclient/module.go b/x/btclightclient/module.go index 6c6982d4a..74957909b 100644 --- a/x/btclightclient/module.go +++ b/x/btclightclient/module.go @@ -12,9 +12,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/btclightclient/client/cli" - "github.com/babylonchain/babylon/x/btclightclient/keeper" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/client/cli" + "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/btclightclient/types/btc_header_info.go b/x/btclightclient/types/btc_header_info.go index 17f6a1517..2cfdb00f6 100644 --- a/x/btclightclient/types/btc_header_info.go +++ b/x/btclightclient/types/btc_header_info.go @@ -5,7 +5,7 @@ import ( "fmt" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" ) func NewBTCHeaderInfo(header *bbn.BTCHeaderBytes, headerHash *bbn.BTCHeaderHashBytes, height uint64, work *sdkmath.Uint) *BTCHeaderInfo { diff --git a/x/btclightclient/types/btc_header_info_test.go b/x/btclightclient/types/btc_header_info_test.go index f0afe81cd..10bea02f1 100644 --- a/x/btclightclient/types/btc_header_info_test.go +++ b/x/btclightclient/types/btc_header_info_test.go @@ -9,9 +9,9 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/types/btc_light_client.go b/x/btclightclient/types/btc_light_client.go index dbbd19204..69440383f 100644 --- a/x/btclightclient/types/btc_light_client.go +++ b/x/btclightclient/types/btc_light_client.go @@ -5,7 +5,7 @@ import ( "time" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" diff --git a/x/btclightclient/types/btclightclient.pb.go b/x/btclightclient/types/btclightclient.pb.go index dd50ff83e..5384959e7 100644 --- a/x/btclightclient/types/btclightclient.pb.go +++ b/x/btclightclient/types/btclightclient.pb.go @@ -6,7 +6,7 @@ package types import ( cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -34,10 +34,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // to the header Bits field // and the total work of the header. type BTCHeaderInfo struct { - Header *github_com_babylonchain_babylon_types.BTCHeaderBytes `protobuf:"bytes,1,opt,name=header,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderBytes" json:"header,omitempty"` - Hash *github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,2,opt,name=hash,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` - Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` - Work *cosmossdk_io_math.Uint `protobuf:"bytes,4,opt,name=work,proto3,customtype=cosmossdk.io/math.Uint" json:"work,omitempty"` + Header *github_com_babylonlabs_io_babylon_types.BTCHeaderBytes `protobuf:"bytes,1,opt,name=header,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" json:"header,omitempty"` + Hash *github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,2,opt,name=hash,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` + Height uint64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` + Work *cosmossdk_io_math.Uint `protobuf:"bytes,4,opt,name=work,proto3,customtype=cosmossdk.io/math.Uint" json:"work,omitempty"` } func (m *BTCHeaderInfo) Reset() { *m = BTCHeaderInfo{} } @@ -89,25 +89,25 @@ func init() { } var fileDescriptor_84bf438d909b681d = []byte{ - // 282 bytes of a gzipped FileDescriptorProto + // 284 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4b, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0x68, 0x22, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x92, 0x50, 0xf5, 0x7a, 0x68, 0xb2, 0x65, 0x86, 0x52, 0x22, 0xe9, 0xf9, 0xe9, 0xf9, 0x60, 0x55, 0xfa, 0x20, 0x16, 0x44, - 0x83, 0xd2, 0x6f, 0x46, 0x2e, 0x5e, 0xa7, 0x10, 0x67, 0x8f, 0xd4, 0xc4, 0x94, 0xd4, 0x22, 0xcf, - 0xbc, 0xb4, 0x7c, 0xa1, 0x00, 0x2e, 0xb6, 0x0c, 0x30, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, 0xc7, - 0xc9, 0xe2, 0xd6, 0x3d, 0x79, 0x93, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, - 0x7d, 0xa8, 0x0d, 0xc9, 0x19, 0x89, 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x49, 0x65, 0x41, 0x6a, 0xb1, - 0x1e, 0xdc, 0x20, 0xa7, 0xca, 0x92, 0xd4, 0xe2, 0x20, 0xa8, 0x39, 0x42, 0x01, 0x5c, 0x2c, 0x19, - 0x89, 0xc5, 0x19, 0x12, 0x4c, 0x60, 0xf3, 0x6c, 0x6e, 0xdd, 0x93, 0xb7, 0x20, 0xd1, 0x3c, 0x8f, - 0xc4, 0xe2, 0x0c, 0x88, 0x99, 0x60, 0x93, 0x84, 0xc4, 0x40, 0x6e, 0x04, 0x79, 0x4f, 0x82, 0x59, - 0x81, 0x51, 0x83, 0x25, 0x08, 0xca, 0x13, 0xd2, 0xe3, 0x62, 0x29, 0xcf, 0x2f, 0xca, 0x96, 0x60, - 0x01, 0xdb, 0x24, 0x75, 0xeb, 0x9e, 0xbc, 0x58, 0x72, 0x7e, 0x71, 0x6e, 0x7e, 0x71, 0x71, 0x4a, - 0xb6, 0x5e, 0x66, 0xbe, 0x7e, 0x6e, 0x62, 0x49, 0x86, 0x5e, 0x68, 0x66, 0x5e, 0x49, 0x10, 0x58, - 0x9d, 0x53, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, - 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x99, 0x11, 0x72, - 0x61, 0x05, 0x7a, 0x94, 0x80, 0x9d, 0x9c, 0xc4, 0x06, 0x0e, 0x56, 0x63, 0x40, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x13, 0xc6, 0x69, 0x40, 0xb9, 0x01, 0x00, 0x00, + 0x83, 0xd2, 0x7f, 0x46, 0x2e, 0x5e, 0xa7, 0x10, 0x67, 0x8f, 0xd4, 0xc4, 0x94, 0xd4, 0x22, 0xcf, + 0xbc, 0xb4, 0x7c, 0xa1, 0x20, 0x2e, 0xb6, 0x0c, 0x30, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, 0xc7, + 0xc9, 0xea, 0xd6, 0x3d, 0x79, 0xb3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, + 0x7d, 0xa8, 0x0d, 0x39, 0x89, 0x49, 0xc5, 0xba, 0x99, 0xf9, 0x30, 0xae, 0x7e, 0x49, 0x65, 0x41, + 0x6a, 0xb1, 0x1e, 0xdc, 0x28, 0xa7, 0xca, 0x92, 0xd4, 0xe2, 0x20, 0xa8, 0x49, 0x42, 0x41, 0x5c, + 0x2c, 0x19, 0x89, 0xc5, 0x19, 0x12, 0x4c, 0x60, 0x13, 0xed, 0x6e, 0xdd, 0x93, 0xb7, 0x22, 0xd9, + 0x44, 0x8f, 0xc4, 0xe2, 0x0c, 0x88, 0xa9, 0x60, 0xb3, 0x84, 0xc4, 0x40, 0xee, 0x04, 0x79, 0x51, + 0x82, 0x59, 0x81, 0x51, 0x83, 0x25, 0x08, 0xca, 0x13, 0xd2, 0xe3, 0x62, 0x29, 0xcf, 0x2f, 0xca, + 0x96, 0x60, 0x01, 0xdb, 0x25, 0x75, 0xeb, 0x9e, 0xbc, 0x58, 0x72, 0x7e, 0x71, 0x6e, 0x7e, 0x71, + 0x71, 0x4a, 0xb6, 0x5e, 0x66, 0xbe, 0x7e, 0x6e, 0x62, 0x49, 0x86, 0x5e, 0x68, 0x66, 0x5e, 0x49, + 0x10, 0x58, 0x9d, 0x53, 0xd0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, + 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0x59, + 0x10, 0x76, 0x63, 0x05, 0x7a, 0xc4, 0x80, 0x1d, 0x9d, 0xc4, 0x06, 0x0e, 0x5c, 0x63, 0x40, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x93, 0x3f, 0xdd, 0x6c, 0xbf, 0x01, 0x00, 0x00, } func (m *BTCHeaderInfo) Marshal() (dAtA []byte, err error) { @@ -273,7 +273,7 @@ func (m *BTCHeaderInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderBytes m.Header = &v if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -308,7 +308,7 @@ func (m *BTCHeaderInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderHashBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes m.Hash = &v if err := m.Hash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btclightclient/types/event.pb.go b/x/btclightclient/types/event.pb.go index 71f8fcda3..aa0587758 100644 --- a/x/btclightclient/types/event.pb.go +++ b/x/btclightclient/types/event.pb.go @@ -176,7 +176,7 @@ func init() { } var fileDescriptor_519f2d655b639c5a = []byte{ - // 228 bytes of a gzipped FileDescriptorProto + // 230 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0xfa, 0xa9, 0x65, 0xa9, 0x79, 0x25, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, @@ -186,12 +186,12 @@ var fileDescriptor_519f2d655b639c5a = []byte{ 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x0d, 0x3d, 0x9c, 0xf6, 0xe9, 0x39, 0x85, 0x38, 0x7b, 0x80, 0xd5, 0x7a, 0xe6, 0xa5, 0xe5, 0x07, 0x41, 0xf5, 0x29, 0x85, 0x73, 0x09, 0x23, 0x9b, 0xea, 0x96, 0x5f, 0x54, 0x9e, 0x58, 0x94, 0x42, 0x05, 0x83, 0xa3, 0xb8, 0xc4, 0x60, 0x06, 0xc3, 0x64, 0x8b, 0x53, - 0x8b, 0x4a, 0x52, 0xa9, 0x60, 0xb6, 0x53, 0xc0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, + 0x8b, 0x4a, 0x52, 0xa9, 0x60, 0xb6, 0x53, 0xd0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, - 0x31, 0x44, 0x99, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x4d, - 0x4d, 0xce, 0x48, 0xcc, 0xcc, 0x83, 0x71, 0xf4, 0x2b, 0xd0, 0x83, 0xbb, 0xa4, 0xb2, 0x20, 0xb5, - 0x38, 0x89, 0x0d, 0x1c, 0xc6, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16, 0x0b, 0x33, 0xea, - 0xd7, 0x01, 0x00, 0x00, + 0x31, 0x44, 0x59, 0xa4, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x4d, + 0xcd, 0x49, 0x4c, 0x2a, 0xd6, 0xcd, 0xcc, 0x87, 0x71, 0xf5, 0x2b, 0xd0, 0x03, 0xbc, 0xa4, 0xb2, + 0x20, 0xb5, 0x38, 0x89, 0x0d, 0x1c, 0xca, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xba, 0x96, + 0x2b, 0x51, 0xd9, 0x01, 0x00, 0x00, } func (m *EventBTCRollBack) Marshal() (dAtA []byte, err error) { diff --git a/x/btclightclient/types/genesis.go b/x/btclightclient/types/genesis.go index 8cd976143..13835fa2b 100644 --- a/x/btclightclient/types/genesis.go +++ b/x/btclightclient/types/genesis.go @@ -5,7 +5,7 @@ import ( "errors" "fmt" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/chaincfg" "github.com/cosmos/cosmos-sdk/codec" diff --git a/x/btclightclient/types/genesis.pb.go b/x/btclightclient/types/genesis.pb.go index df669279a..cabb6090e 100644 --- a/x/btclightclient/types/genesis.pb.go +++ b/x/btclightclient/types/genesis.pb.go @@ -85,7 +85,7 @@ func init() { } var fileDescriptor_4f95902e4096217a = []byte{ - // 256 bytes of a gzipped FileDescriptorProto + // 258 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4f, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0xfa, 0xe9, 0xa9, 0x79, 0xa9, 0xc5, 0x99, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, @@ -97,11 +97,12 @@ var fileDescriptor_4f95902e4096217a = []byte{ 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0xda, 0x84, 0x3c, 0xb9, 0xb8, 0x93, 0x4a, 0x92, 0xe3, 0x33, 0x52, 0x13, 0x53, 0x52, 0x8b, 0x8a, 0x25, 0x98, 0x14, 0x98, 0x35, 0xb8, 0x8d, 0x34, 0xf0, 0x98, 0xe2, 0x14, 0xe2, 0xec, 0x01, 0x56, 0xec, 0x99, 0x97, 0x96, 0x1f, 0xc4, 0x95, 0x54, 0x92, 0x0c, - 0xe1, 0x16, 0x3b, 0x05, 0x9c, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, - 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x59, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xe4, 0xe4, 0x8c, 0xc4, - 0xcc, 0x3c, 0x18, 0x47, 0xbf, 0x02, 0xdd, 0xe3, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0x60, - 0x5f, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xed, 0x4f, 0xca, 0x25, 0xa9, 0x01, 0x00, 0x00, + 0xe1, 0x16, 0x3b, 0x05, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, + 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x45, + 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x3e, 0xd4, 0xe4, 0x9c, 0xc4, 0xa4, + 0x62, 0xdd, 0xcc, 0x7c, 0x18, 0x57, 0xbf, 0x02, 0xdd, 0xeb, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, + 0x6c, 0x60, 0x7f, 0x1b, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0xbc, 0xe4, 0xd2, 0xd7, 0xab, 0x01, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/btclightclient/types/genesis_test.go b/x/btclightclient/types/genesis_test.go index 29695c129..3d64269ce 100644 --- a/x/btclightclient/types/genesis_test.go +++ b/x/btclightclient/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/types/keys.go b/x/btclightclient/types/keys.go index b0844f440..4761c2be8 100644 --- a/x/btclightclient/types/keys.go +++ b/x/btclightclient/types/keys.go @@ -1,7 +1,7 @@ package types import ( - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/types/keys_test.go b/x/btclightclient/types/keys_test.go index e075a6c4e..e7095b95c 100644 --- a/x/btclightclient/types/keys_test.go +++ b/x/btclightclient/types/keys_test.go @@ -5,9 +5,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/types/msgs.go b/x/btclightclient/types/msgs.go index 038b9ac8c..7b6bfbdd8 100644 --- a/x/btclightclient/types/msgs.go +++ b/x/btclightclient/types/msgs.go @@ -5,7 +5,7 @@ import ( "fmt" "math/big" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btclightclient/types/msgs_test.go b/x/btclightclient/types/msgs_test.go index a55240fa0..9a4766fd8 100644 --- a/x/btclightclient/types/msgs_test.go +++ b/x/btclightclient/types/msgs_test.go @@ -7,9 +7,9 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) diff --git a/x/btclightclient/types/params.pb.go b/x/btclightclient/types/params.pb.go index bdd917254..483235b12 100644 --- a/x/btclightclient/types/params.pb.go +++ b/x/btclightclient/types/params.pb.go @@ -79,7 +79,7 @@ func init() { } var fileDescriptor_1e4c5f7a17079e1f = []byte{ - // 211 bytes of a gzipped FileDescriptorProto + // 213 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4b, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0xfa, 0x05, 0x89, 0x45, 0x89, 0xb9, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, @@ -88,12 +88,12 @@ var fileDescriptor_1e4c5f7a17079e1f = []byte{ 0x5c, 0x92, 0x99, 0x79, 0xc5, 0xa9, 0x45, 0x25, 0xf1, 0x19, 0xa9, 0x89, 0x29, 0xa9, 0x45, 0xc5, 0xf1, 0x89, 0x39, 0x39, 0xf9, 0xe5, 0xf1, 0x39, 0x99, 0xc5, 0x25, 0x12, 0x8c, 0x0a, 0xcc, 0x1a, 0x9c, 0x41, 0x62, 0x10, 0x05, 0x1e, 0x10, 0x79, 0x47, 0x90, 0xb4, 0x4f, 0x66, 0x71, 0x89, 0x15, - 0xcb, 0x8b, 0x05, 0xf2, 0x8c, 0x4e, 0x01, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, + 0xcb, 0x8b, 0x05, 0xf2, 0x8c, 0x4e, 0x41, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, - 0x10, 0x65, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0x75, 0x60, - 0x72, 0x46, 0x62, 0x66, 0x1e, 0x8c, 0xa3, 0x5f, 0x81, 0xee, 0xaf, 0x92, 0xca, 0x82, 0xd4, 0xe2, - 0x24, 0x36, 0xb0, 0x1b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x30, 0xe4, 0x07, 0x29, 0xfe, - 0x00, 0x00, 0x00, + 0x10, 0x65, 0x91, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x0f, 0x75, 0x60, + 0x4e, 0x62, 0x52, 0xb1, 0x6e, 0x66, 0x3e, 0x8c, 0xab, 0x5f, 0x81, 0xee, 0xb3, 0x92, 0xca, 0x82, + 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x2b, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x43, 0x29, 0x40, + 0xa2, 0x00, 0x01, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/btclightclient/types/querier.go b/x/btclightclient/types/querier.go index a35893026..6636f1eff 100644 --- a/x/btclightclient/types/querier.go +++ b/x/btclightclient/types/querier.go @@ -1,7 +1,7 @@ package types import ( - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/x/btclightclient/types/querier_test.go b/x/btclightclient/types/querier_test.go index 5a23c0c12..a60c514fd 100644 --- a/x/btclightclient/types/querier_test.go +++ b/x/btclightclient/types/querier_test.go @@ -5,9 +5,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/types/query" ) diff --git a/x/btclightclient/types/query.pb.go b/x/btclightclient/types/query.pb.go index 6148e7143..b8eb8bb97 100644 --- a/x/btclightclient/types/query.pb.go +++ b/x/btclightclient/types/query.pb.go @@ -7,7 +7,7 @@ import ( context "context" cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" @@ -164,8 +164,8 @@ func (m *QueryHashesRequest) GetPagination() *query.PageRequest { // QueryHashesResponse is response type for the Query/Hashes RPC method. type QueryHashesResponse struct { - Hashes []github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,1,rep,name=hashes,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"hashes,omitempty"` - Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` + Hashes []github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,1,rep,name=hashes,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" json:"hashes,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } func (m *QueryHashesResponse) Reset() { *m = QueryHashesResponse{} } @@ -211,7 +211,7 @@ func (m *QueryHashesResponse) GetPagination() *query.PageResponse { // QueryContainsRequest is request type for the Query/Contains RPC method. // It involves checking whether a hash is maintained by the module. type QueryContainsRequest struct { - Hash *github_com_babylonchain_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` + Hash *github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes `protobuf:"bytes,1,opt,name=hash,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" json:"hash,omitempty"` } func (m *QueryContainsRequest) Reset() { *m = QueryContainsRequest{} } @@ -836,65 +836,65 @@ func init() { } var fileDescriptor_3961270631e52721 = []byte{ - // 920 bytes of a gzipped FileDescriptorProto + // 924 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0xcf, 0x6f, 0x1b, 0x45, 0x14, 0xc7, 0x33, 0x89, 0xeb, 0x26, 0x2f, 0x20, 0x60, 0x48, 0x83, 0xb3, 0x02, 0x27, 0xdd, 0x92, - 0x1f, 0x4d, 0xf1, 0x4e, 0x9c, 0x00, 0xea, 0x01, 0x09, 0xe1, 0x20, 0x30, 0x48, 0x48, 0xc6, 0x32, - 0x1c, 0x50, 0xa5, 0x68, 0xec, 0x0c, 0xbb, 0xab, 0xc6, 0x3b, 0x5b, 0xef, 0x26, 0xc4, 0x42, 0x5c, - 0x38, 0x70, 0x46, 0x70, 0xe3, 0xc0, 0x81, 0x0b, 0x17, 0xe0, 0xd4, 0x3f, 0xa2, 0xc7, 0x0a, 0x2e, - 0xa8, 0x87, 0x08, 0x25, 0xfc, 0x11, 0x1c, 0xd1, 0xcc, 0xbc, 0xb5, 0xbd, 0x76, 0xea, 0xb5, 0xd5, - 0x5c, 0xa2, 0xcc, 0xcc, 0x7b, 0xef, 0xfb, 0x79, 0xcf, 0xb3, 0xdf, 0x5d, 0x58, 0x6f, 0xf2, 0x66, - 0xf7, 0x48, 0x06, 0xac, 0x19, 0xb7, 0x8e, 0x7c, 0xd7, 0x53, 0x7f, 0x45, 0x10, 0xb3, 0x93, 0x32, - 0x7b, 0x70, 0x2c, 0x3a, 0x5d, 0x27, 0xec, 0xc8, 0x58, 0xd2, 0x15, 0x0c, 0x73, 0xd2, 0x61, 0xce, - 0x49, 0xd9, 0x5a, 0x72, 0xa5, 0x2b, 0x75, 0x14, 0x53, 0xff, 0x99, 0x04, 0x6b, 0xa5, 0x25, 0xa3, - 0xb6, 0x8c, 0x0e, 0xcc, 0x81, 0x59, 0xe0, 0xd1, 0xab, 0xae, 0x94, 0xee, 0x91, 0x60, 0x3c, 0xf4, - 0x19, 0x0f, 0x02, 0x19, 0xf3, 0xd8, 0x97, 0x41, 0x72, 0xba, 0x6d, 0x62, 0x59, 0x93, 0x47, 0xc2, - 0x20, 0xb0, 0x93, 0x72, 0x53, 0xc4, 0xbc, 0xcc, 0x42, 0xee, 0xfa, 0x81, 0x0e, 0xc6, 0xd8, 0x8d, - 0xa7, 0xc3, 0x87, 0xbc, 0xc3, 0xdb, 0x58, 0xd3, 0x5e, 0x02, 0xfa, 0xa9, 0xaa, 0x54, 0xd3, 0x9b, - 0x75, 0xf1, 0xe0, 0x58, 0x44, 0xb1, 0xfd, 0x39, 0xbc, 0x9c, 0xda, 0x8d, 0x42, 0x19, 0x44, 0x82, - 0xbe, 0x0b, 0x79, 0x93, 0x5c, 0x20, 0x6b, 0x64, 0x6b, 0x71, 0xf7, 0xa6, 0xf3, 0xd4, 0xde, 0x1d, - 0x93, 0x5a, 0xc9, 0x3d, 0x3a, 0x5b, 0x9d, 0xa9, 0x63, 0x9a, 0x7d, 0x0f, 0xd5, 0xaa, 0x3c, 0xf2, - 0x44, 0xa2, 0x46, 0x3f, 0x00, 0xe8, 0xf3, 0x63, 0xe9, 0x0d, 0x07, 0x07, 0xa3, 0x9a, 0x75, 0xcc, - 0xbc, 0xb1, 0x59, 0xa7, 0xc6, 0x5d, 0x81, 0xb9, 0xf5, 0x81, 0x4c, 0xfb, 0x21, 0x41, 0xec, 0xa4, - 0x3c, 0x62, 0x37, 0x20, 0xef, 0xe9, 0x9d, 0x02, 0x59, 0x9b, 0xdb, 0x7a, 0xae, 0xf2, 0xce, 0x93, - 0xb3, 0xd5, 0xbb, 0xae, 0x1f, 0x7b, 0xc7, 0x4d, 0xa7, 0x25, 0xdb, 0x0c, 0x9b, 0x68, 0x79, 0xdc, - 0x0f, 0x92, 0x05, 0x8b, 0xbb, 0xa1, 0x88, 0x9c, 0x4a, 0x63, 0xbf, 0x2a, 0xf8, 0xa1, 0xe8, 0xa8, - 0x92, 0x95, 0x6e, 0x2c, 0xa2, 0x3a, 0xd6, 0xa2, 0x1f, 0xa6, 0xa8, 0x67, 0x35, 0xf5, 0x66, 0x26, - 0xb5, 0x41, 0x4a, 0x61, 0x7b, 0xb0, 0xa4, 0xa9, 0xf7, 0x65, 0x10, 0x73, 0x3f, 0xe8, 0x8d, 0xa5, - 0x06, 0x39, 0x25, 0xa5, 0x07, 0xf2, 0xac, 0xd0, 0xba, 0x92, 0xbd, 0x07, 0x37, 0x86, 0x94, 0x70, - 0x42, 0x16, 0xcc, 0xb7, 0x70, 0x4f, 0xcb, 0xcd, 0xd7, 0x7b, 0x6b, 0x9b, 0xc1, 0x4a, 0x2a, 0xc9, - 0x14, 0x44, 0x46, 0x3a, 0xc8, 0x88, 0x2a, 0x77, 0xc1, 0xba, 0x2c, 0x61, 0x02, 0xa9, 0x03, 0xe4, - 0xfb, 0x84, 0xfb, 0xc1, 0xbe, 0x6a, 0xec, 0xaa, 0x6f, 0xc8, 0xef, 0x04, 0x96, 0x87, 0x15, 0x90, - 0xeb, 0x63, 0xb8, 0xee, 0xe9, 0xa1, 0x99, 0x5b, 0xb2, 0xb8, 0xbb, 0x33, 0xe6, 0x72, 0xf7, 0x26, - 0xfc, 0x51, 0xf0, 0xa5, 0xec, 0xfd, 0xa8, 0x49, 0x81, 0xab, 0xbb, 0x1a, 0x2f, 0xc1, 0x0b, 0x1a, - 0xb7, 0xe1, 0x87, 0xc9, 0xa3, 0x79, 0x0f, 0x5e, 0xec, 0x6f, 0x21, 0x7b, 0x15, 0xf2, 0x46, 0x1a, - 0x47, 0x33, 0x3d, 0x3a, 0xe6, 0xdb, 0x05, 0x9c, 0x4f, 0x85, 0x47, 0xc2, 0x84, 0x25, 0xba, 0x2d, - 0x78, 0x65, 0xe4, 0xe4, 0xca, 0xe5, 0x4b, 0x28, 0x62, 0x42, 0xde, 0x17, 0x61, 0xec, 0x5d, 0x76, - 0xd3, 0x16, 0xf0, 0xa6, 0xed, 0x40, 0x61, 0x34, 0x1c, 0xa1, 0x96, 0xe0, 0xda, 0xa1, 0xda, 0xd0, - 0x09, 0xb9, 0xba, 0x59, 0xd8, 0xbf, 0x11, 0xb8, 0x71, 0x29, 0x02, 0x7d, 0x0d, 0xc0, 0x40, 0x1c, - 0x78, 0xe2, 0x14, 0x55, 0x16, 0xcc, 0x4e, 0x55, 0x9c, 0xd2, 0x15, 0x98, 0x57, 0x92, 0xfa, 0x70, - 0x56, 0x1f, 0x5e, 0x57, 0x6b, 0x75, 0xb4, 0xac, 0xda, 0x57, 0x5d, 0x16, 0xe6, 0xb4, 0x14, 0xae, - 0xe8, 0x7b, 0x90, 0xfb, 0x4a, 0x76, 0xee, 0x17, 0x72, 0x2a, 0xbc, 0x52, 0x52, 0x46, 0xf8, 0xe4, - 0x6c, 0x75, 0xd9, 0x5c, 0x83, 0xe8, 0xf0, 0xbe, 0xe3, 0x4b, 0xd6, 0xe6, 0xb1, 0xe7, 0x7c, 0xe6, - 0x07, 0xf1, 0x9f, 0x0f, 0x4b, 0x8b, 0x78, 0x41, 0xd4, 0xb2, 0xae, 0x53, 0x77, 0xff, 0x5b, 0x80, - 0x6b, 0xba, 0x43, 0xfa, 0x03, 0x81, 0xbc, 0xb1, 0x54, 0x5a, 0x1a, 0x33, 0xde, 0x51, 0x2f, 0xb7, - 0x9c, 0x49, 0xc3, 0xcd, 0x20, 0xec, 0xdb, 0xdf, 0xfe, 0xf5, 0xef, 0x8f, 0xb3, 0xb7, 0xe8, 0x4d, - 0x96, 0xf5, 0x0a, 0xd1, 0x50, 0xc6, 0x6b, 0xb3, 0xa1, 0x52, 0x96, 0x9f, 0x0d, 0x95, 0xb6, 0xf0, - 0x89, 0xa0, 0xd0, 0x97, 0x7f, 0x22, 0x30, 0x9f, 0x58, 0x0f, 0x65, 0x59, 0x3a, 0x43, 0xa6, 0x6b, - 0xed, 0x4c, 0x9e, 0x80, 0x68, 0x77, 0x34, 0xda, 0x3a, 0xbd, 0x35, 0x06, 0x2d, 0x71, 0x38, 0xfa, - 0x07, 0x81, 0xe7, 0x53, 0xbe, 0x48, 0xdf, 0x9c, 0x54, 0x70, 0xd0, 0x77, 0xad, 0xb7, 0xa6, 0xcc, - 0x42, 0xd6, 0x1d, 0xcd, 0xba, 0x4d, 0xb7, 0x26, 0x60, 0x35, 0x78, 0x3f, 0x13, 0x58, 0xe8, 0x99, - 0x25, 0xcd, 0x9c, 0xce, 0xb0, 0x73, 0x5b, 0xe5, 0x29, 0x32, 0x10, 0xf2, 0x0d, 0x0d, 0xb9, 0x41, - 0x5f, 0x1f, 0x03, 0xd9, 0xe6, 0xbe, 0x79, 0xf5, 0xd1, 0xef, 0x08, 0xcc, 0x35, 0xfc, 0x90, 0x6e, - 0x67, 0x09, 0xf5, 0x3d, 0xd4, 0xba, 0x33, 0x51, 0x2c, 0xe2, 0x6c, 0x68, 0x9c, 0x35, 0x5a, 0x1c, - 0x83, 0x13, 0xfb, 0x21, 0xfd, 0x85, 0x00, 0xf4, 0xcd, 0x91, 0x66, 0x36, 0x3e, 0x62, 0xb1, 0xd6, - 0xee, 0x34, 0x29, 0x48, 0x57, 0xd2, 0x74, 0x9b, 0x74, 0x7d, 0x0c, 0x9d, 0x7a, 0xe3, 0x18, 0x27, - 0xa3, 0xbf, 0x12, 0x58, 0x1c, 0x70, 0x4b, 0x9a, 0x29, 0x39, 0xea, 0xc4, 0xd6, 0xde, 0x54, 0x39, - 0xc8, 0xc9, 0x34, 0xe7, 0x6d, 0xba, 0x39, 0x86, 0x53, 0x5b, 0x34, 0xfb, 0x5a, 0x3d, 0xc7, 0xdf, - 0x54, 0x6a, 0x8f, 0xce, 0x8b, 0xe4, 0xf1, 0x79, 0x91, 0xfc, 0x73, 0x5e, 0x24, 0xdf, 0x5f, 0x14, - 0x67, 0x1e, 0x5f, 0x14, 0x67, 0xfe, 0xbe, 0x28, 0xce, 0x7c, 0xf1, 0x76, 0xd6, 0x57, 0xd0, 0xe9, - 0x70, 0x6d, 0xfd, 0x59, 0xd4, 0xcc, 0xeb, 0x2f, 0xde, 0xbd, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, - 0x93, 0xd5, 0xc3, 0x8e, 0xd8, 0x0b, 0x00, 0x00, + 0x1f, 0x4d, 0xf1, 0x4e, 0x9c, 0x80, 0x54, 0x71, 0x00, 0xe1, 0x20, 0x08, 0x48, 0x48, 0x65, 0x15, + 0x7a, 0x40, 0x95, 0xa2, 0x59, 0x67, 0xd8, 0x5d, 0x1a, 0xef, 0x6c, 0xbd, 0x9b, 0x90, 0x08, 0x71, + 0xe1, 0xc0, 0x19, 0xc1, 0x8d, 0x03, 0x07, 0x2e, 0x5c, 0x80, 0x13, 0xe2, 0x6f, 0xe8, 0xb1, 0x82, + 0x0b, 0xea, 0x21, 0x42, 0x09, 0x7f, 0x04, 0x47, 0x34, 0x33, 0x6f, 0x6d, 0xaf, 0x9d, 0x7a, 0x6d, + 0x35, 0x97, 0x28, 0x33, 0xf3, 0xde, 0xfb, 0x7e, 0xe6, 0xf9, 0xed, 0x77, 0x17, 0x96, 0x3d, 0xee, + 0x9d, 0x1c, 0xc8, 0x88, 0x79, 0x69, 0xf3, 0x20, 0xf4, 0x03, 0xf5, 0x57, 0x44, 0x29, 0x3b, 0xaa, + 0xb3, 0x07, 0x87, 0xa2, 0x7d, 0xe2, 0xc4, 0x6d, 0x99, 0x4a, 0xba, 0x80, 0x61, 0x4e, 0x3e, 0xcc, + 0x39, 0xaa, 0x5b, 0x73, 0xbe, 0xf4, 0xa5, 0x8e, 0x62, 0xea, 0x3f, 0x93, 0x60, 0x2d, 0x34, 0x65, + 0xd2, 0x92, 0xc9, 0x9e, 0x39, 0x30, 0x0b, 0x3c, 0x7a, 0xd9, 0x97, 0xd2, 0x3f, 0x10, 0x8c, 0xc7, + 0x21, 0xe3, 0x51, 0x24, 0x53, 0x9e, 0x86, 0x32, 0xca, 0x4e, 0xd7, 0x4d, 0x2c, 0xf3, 0x78, 0x22, + 0x0c, 0x02, 0x3b, 0xaa, 0x7b, 0x22, 0xe5, 0x75, 0x16, 0x73, 0x3f, 0x8c, 0x74, 0x30, 0xc6, 0xae, + 0x3c, 0x19, 0x3e, 0xe6, 0x6d, 0xde, 0xc2, 0x9a, 0xf6, 0x1c, 0xd0, 0x8f, 0x55, 0xa5, 0x3b, 0x7a, + 0xd3, 0x15, 0x0f, 0x0e, 0x45, 0x92, 0xda, 0x77, 0xe1, 0xc5, 0xdc, 0x6e, 0x12, 0xcb, 0x28, 0x11, + 0xf4, 0x6d, 0x28, 0x9b, 0xe4, 0x0a, 0x59, 0x22, 0x6b, 0xb3, 0x9b, 0xd7, 0x9d, 0x27, 0xde, 0xdd, + 0x31, 0xa9, 0x8d, 0xd2, 0xc3, 0xd3, 0xc5, 0x09, 0x17, 0xd3, 0xec, 0x7b, 0xa8, 0xb6, 0xc3, 0x93, + 0x40, 0x64, 0x6a, 0xf4, 0x3d, 0x80, 0x2e, 0x3f, 0x96, 0x5e, 0x71, 0xb0, 0x31, 0xea, 0xb2, 0x8e, + 0xe9, 0x37, 0x5e, 0xd6, 0xb9, 0xc3, 0x7d, 0x81, 0xb9, 0x6e, 0x4f, 0xa6, 0xfd, 0x07, 0x41, 0xec, + 0xac, 0x3c, 0x62, 0xdf, 0x85, 0x72, 0xa0, 0x77, 0x2a, 0x64, 0x69, 0x6a, 0xed, 0x99, 0xc6, 0x5b, + 0x8f, 0x4f, 0x17, 0xdf, 0xf4, 0xc3, 0x34, 0x38, 0xf4, 0x9c, 0xa6, 0x6c, 0x31, 0xbc, 0xc4, 0x01, + 0xf7, 0x92, 0x5a, 0x28, 0xb3, 0x25, 0x4b, 0x4f, 0x62, 0x91, 0x38, 0x8d, 0xdd, 0xed, 0x1d, 0xc1, + 0xf7, 0x45, 0x5b, 0x15, 0x6d, 0x9c, 0xa4, 0x22, 0x71, 0xb1, 0x1a, 0x7d, 0x3f, 0xc7, 0x3d, 0xa9, + 0xb9, 0x57, 0x0b, 0xb9, 0x0d, 0x54, 0x0e, 0xfc, 0x73, 0x98, 0xd3, 0xdc, 0xdb, 0x32, 0x4a, 0x79, + 0x18, 0x75, 0x1a, 0xe3, 0x42, 0x49, 0x49, 0xe9, 0x96, 0x3c, 0x3d, 0xb6, 0xae, 0x65, 0x6f, 0xc1, + 0xb5, 0x3e, 0x2d, 0xec, 0x92, 0x05, 0xd3, 0x4d, 0xdc, 0xd3, 0x82, 0xd3, 0x6e, 0x67, 0x6d, 0x33, + 0x58, 0xc8, 0x25, 0x99, 0x82, 0x48, 0x49, 0x7b, 0x29, 0x51, 0xe5, 0x36, 0x58, 0x17, 0x25, 0x8c, + 0x20, 0xb5, 0x87, 0x7c, 0x1f, 0xf1, 0x30, 0xda, 0x0e, 0x78, 0x18, 0x5d, 0xf6, 0x94, 0xfc, 0x4a, + 0x60, 0xbe, 0x5f, 0x01, 0xb9, 0x3e, 0x84, 0xab, 0x81, 0x6e, 0x9a, 0x99, 0x94, 0xd9, 0xcd, 0x8d, + 0x21, 0x03, 0xde, 0xe9, 0xf0, 0x07, 0xd1, 0x67, 0xb2, 0xf3, 0xb3, 0x66, 0x05, 0x2e, 0x6f, 0x38, + 0x5e, 0x80, 0xe7, 0x34, 0xee, 0x6e, 0x18, 0x67, 0x8f, 0xe7, 0x3d, 0x78, 0xbe, 0xbb, 0x85, 0xec, + 0x3b, 0x50, 0x36, 0xd2, 0xd8, 0x9a, 0xf1, 0xd1, 0x31, 0xdf, 0xae, 0x60, 0x7f, 0x1a, 0x3c, 0x11, + 0x26, 0x2c, 0xd3, 0x6d, 0xc2, 0x4b, 0x03, 0x27, 0x97, 0x2e, 0x5f, 0x43, 0x11, 0x13, 0xf2, 0xae, + 0x88, 0xd3, 0xe0, 0xa2, 0x49, 0x9b, 0xc1, 0x49, 0xdb, 0x80, 0xca, 0x60, 0x38, 0x42, 0xcd, 0xc1, + 0x95, 0x7d, 0xb5, 0xa1, 0x13, 0x4a, 0xae, 0x59, 0xd8, 0xbf, 0x10, 0xb8, 0x76, 0x21, 0x02, 0x7d, + 0x05, 0xc0, 0x40, 0xec, 0x05, 0xe2, 0x18, 0x55, 0x66, 0xcc, 0xce, 0x8e, 0x38, 0xa6, 0x0b, 0x30, + 0xad, 0x24, 0xf5, 0xe1, 0xa4, 0x3e, 0xbc, 0xaa, 0xd6, 0xea, 0x68, 0x5e, 0x5d, 0x5f, 0xdd, 0xb2, + 0x32, 0xa5, 0xa5, 0x70, 0x45, 0xdf, 0x81, 0xd2, 0x17, 0xb2, 0x7d, 0xbf, 0x52, 0x52, 0xe1, 0x8d, + 0x9a, 0x32, 0xc3, 0xc7, 0xa7, 0x8b, 0xf3, 0x66, 0x0c, 0x92, 0xfd, 0xfb, 0x4e, 0x28, 0x59, 0x8b, + 0xa7, 0x81, 0xf3, 0x49, 0x18, 0xa5, 0x7f, 0xfe, 0x5e, 0x9b, 0xc5, 0x01, 0x51, 0x4b, 0x57, 0xa7, + 0x6e, 0xfe, 0x37, 0x03, 0x57, 0xf4, 0x0d, 0xe9, 0x77, 0x04, 0xca, 0xc6, 0x56, 0x69, 0x6d, 0x48, + 0x7b, 0x07, 0xfd, 0xdc, 0x72, 0x46, 0x0d, 0x37, 0x8d, 0xb0, 0x6f, 0x7e, 0xfd, 0xd7, 0xbf, 0xdf, + 0x4f, 0xde, 0xa0, 0xd7, 0x59, 0xd1, 0x6b, 0x44, 0x43, 0x19, 0xbf, 0x2d, 0x86, 0xca, 0xd9, 0x7e, + 0x31, 0x54, 0xde, 0xc6, 0x47, 0x82, 0x42, 0x67, 0xfe, 0x81, 0xc0, 0x74, 0x66, 0x3d, 0x94, 0x15, + 0xe9, 0xf4, 0xd9, 0xae, 0xb5, 0x31, 0x7a, 0x02, 0xa2, 0xdd, 0xd2, 0x68, 0xcb, 0xf4, 0xc6, 0x10, + 0xb4, 0xcc, 0xe1, 0xe8, 0x6f, 0x04, 0x9e, 0xcd, 0xf9, 0x22, 0x7d, 0x7d, 0x54, 0xc1, 0x5e, 0xdf, + 0xb5, 0xde, 0x18, 0x33, 0x0b, 0x59, 0x37, 0x34, 0xeb, 0x3a, 0x5d, 0x1b, 0x81, 0xd5, 0xe0, 0xfd, + 0x48, 0x60, 0xa6, 0x63, 0x96, 0xb4, 0xb0, 0x3b, 0xfd, 0xce, 0x6d, 0xd5, 0xc7, 0xc8, 0x40, 0xc8, + 0xd7, 0x34, 0xe4, 0x0a, 0x7d, 0x75, 0x08, 0x64, 0x8b, 0x87, 0x51, 0x53, 0x23, 0x7d, 0x43, 0x60, + 0x6a, 0x37, 0x8c, 0xe9, 0x7a, 0x91, 0x50, 0xd7, 0x43, 0xad, 0x5b, 0x23, 0xc5, 0x22, 0xce, 0x8a, + 0xc6, 0x59, 0xa2, 0xd5, 0x21, 0x38, 0x69, 0x18, 0xd3, 0x9f, 0x08, 0x40, 0xd7, 0x1c, 0x69, 0xe1, + 0xc5, 0x07, 0x2c, 0xd6, 0xda, 0x1c, 0x27, 0x05, 0xe9, 0x6a, 0x9a, 0x6e, 0x95, 0x2e, 0x0f, 0xa1, + 0x53, 0x6f, 0x1c, 0xe3, 0x64, 0xf4, 0x67, 0x02, 0xb3, 0x3d, 0x6e, 0x49, 0x0b, 0x25, 0x07, 0x9d, + 0xd8, 0xda, 0x1a, 0x2b, 0x07, 0x39, 0x99, 0xe6, 0xbc, 0x49, 0x57, 0x87, 0x70, 0x6a, 0x8b, 0x66, + 0x5f, 0xaa, 0xe7, 0xf8, 0xab, 0x86, 0xfb, 0xf0, 0xac, 0x4a, 0x1e, 0x9d, 0x55, 0xc9, 0x3f, 0x67, + 0x55, 0xf2, 0xed, 0x79, 0x75, 0xe2, 0xd1, 0x79, 0x75, 0xe2, 0xef, 0xf3, 0xea, 0xc4, 0xa7, 0xb7, + 0x8b, 0xbf, 0x83, 0x8e, 0xfb, 0xab, 0xeb, 0x0f, 0x23, 0xaf, 0xac, 0xbf, 0x7b, 0xb7, 0xfe, 0x0f, + 0x00, 0x00, 0xff, 0xff, 0x10, 0x5c, 0x80, 0x4f, 0xde, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -917,7 +917,7 @@ type QueryClient interface { Contains(ctx context.Context, in *QueryContainsRequest, opts ...grpc.CallOption) (*QueryContainsResponse, error) // ContainsBytes is a temporary method that // checks whether a hash is maintained by the module. - // See discussion at https://github.com/babylonchain/babylon/pull/132 + // See discussion at https://github.com/babylonlabs-io/babylon/pull/132 // for more details. ContainsBytes(ctx context.Context, in *QueryContainsBytesRequest, opts ...grpc.CallOption) (*QueryContainsBytesResponse, error) // MainChain returns the canonical chain @@ -1022,7 +1022,7 @@ type QueryServer interface { Contains(context.Context, *QueryContainsRequest) (*QueryContainsResponse, error) // ContainsBytes is a temporary method that // checks whether a hash is maintained by the module. - // See discussion at https://github.com/babylonchain/babylon/pull/132 + // See discussion at https://github.com/babylonlabs-io/babylon/pull/132 // for more details. ContainsBytes(context.Context, *QueryContainsBytesRequest) (*QueryContainsBytesResponse, error) // MainChain returns the canonical chain @@ -2355,7 +2355,7 @@ func (m *QueryHashesResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderHashBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes m.Hashes = append(m.Hashes, v) if err := m.Hashes[len(m.Hashes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2476,7 +2476,7 @@ func (m *QueryContainsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderHashBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderHashBytes m.Hash = &v if err := m.Hash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btclightclient/types/tx.pb.go b/x/btclightclient/types/tx.pb.go index 3f22f09f1..4527a6b07 100644 --- a/x/btclightclient/types/tx.pb.go +++ b/x/btclightclient/types/tx.pb.go @@ -6,7 +6,7 @@ package types import ( context "context" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" @@ -33,8 +33,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // MsgInsertHeaders defines the message for multiple incoming header bytes type MsgInsertHeaders struct { - Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` - Headers []github_com_babylonchain_babylon_types.BTCHeaderBytes `protobuf:"bytes,2,rep,name=headers,proto3,customtype=github.com/babylonchain/babylon/types.BTCHeaderBytes" json:"headers,omitempty"` + Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` + Headers []github_com_babylonlabs_io_babylon_types.BTCHeaderBytes `protobuf:"bytes,2,rep,name=headers,proto3,customtype=github.com/babylonlabs-io/babylon/types.BTCHeaderBytes" json:"headers,omitempty"` } func (m *MsgInsertHeaders) Reset() { *m = MsgInsertHeaders{} } @@ -223,35 +223,35 @@ func init() { } var fileDescriptor_5f638eee60234021 = []byte{ - // 443 bytes of a gzipped FileDescriptorProto + // 445 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2a, 0x49, 0xce, 0xc9, 0x4c, 0xcf, 0x00, 0x91, 0xa9, 0x79, 0x25, 0xfa, 0x65, 0x86, 0xfa, 0x25, 0x15, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x92, 0x50, 0x35, 0x7a, 0xa8, 0x6a, 0xf4, 0xca, 0x0c, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xaa, 0xf4, 0x41, 0x2c, 0x88, 0x06, 0x29, 0xf1, 0xe4, 0xfc, 0xe2, 0xdc, 0xfc, 0x62, 0xfd, 0xdc, 0xe2, 0x74, 0x90, 0x41, 0xb9, 0xc5, 0xe9, 0x50, 0x09, 0x35, 0xdc, 0xb6, 0x15, 0x24, 0x16, 0x25, 0xe6, 0x16, 0x43, - 0xd5, 0x49, 0x42, 0x0c, 0x88, 0x87, 0x98, 0x0c, 0xe1, 0x40, 0xa4, 0x94, 0xba, 0x19, 0xb9, 0x04, + 0xd5, 0x49, 0x42, 0x0c, 0x88, 0x87, 0x98, 0x0c, 0xe1, 0x40, 0xa4, 0x94, 0x7a, 0x19, 0xb9, 0x04, 0x7c, 0x8b, 0xd3, 0x3d, 0xf3, 0x8a, 0x53, 0x8b, 0x4a, 0x3c, 0x52, 0x13, 0x53, 0x52, 0x8b, 0x8a, 0x85, 0xc4, 0xb8, 0xd8, 0x8a, 0x33, 0xd3, 0xf3, 0x52, 0x8b, 0x24, 0x18, 0x15, 0x18, 0x35, 0x38, - 0x83, 0xa0, 0x3c, 0xa1, 0x20, 0x2e, 0xf6, 0x0c, 0x88, 0x12, 0x09, 0x26, 0x05, 0x66, 0x0d, 0x1e, - 0x27, 0x8b, 0x5b, 0xf7, 0xe4, 0x4d, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, - 0xf5, 0xa1, 0xee, 0x49, 0xce, 0x48, 0xcc, 0xcc, 0x83, 0x71, 0xf4, 0x4b, 0x2a, 0x0b, 0x52, 0x8b, - 0xf5, 0x9c, 0x42, 0x9c, 0x21, 0xc6, 0x3b, 0x55, 0x96, 0xa4, 0x16, 0x07, 0xc1, 0x0c, 0xb2, 0xe2, - 0x6e, 0x7a, 0xbe, 0x41, 0x0b, 0x6a, 0x81, 0x92, 0x14, 0x97, 0x04, 0xba, 0x63, 0x82, 0x52, 0x8b, - 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x95, 0x66, 0x31, 0x72, 0xf1, 0xfb, 0x16, 0xa7, 0x87, 0x16, 0xa4, - 0x24, 0x96, 0xa4, 0x06, 0x80, 0xbd, 0x27, 0x64, 0xc6, 0xc5, 0x99, 0x58, 0x5a, 0x92, 0x91, 0x5f, - 0x94, 0x59, 0x52, 0x09, 0x71, 0xab, 0x93, 0xc4, 0xa5, 0x2d, 0xba, 0x22, 0x50, 0x2f, 0x3a, 0xa6, - 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, 0x21, 0x94, 0x0a, 0xd9, - 0x73, 0xb1, 0x41, 0x02, 0x48, 0x82, 0x49, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x51, 0x0f, 0x67, 0x9c, - 0xe8, 0x41, 0xac, 0x72, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xcd, 0x8a, 0x0f, 0xe4, - 0x6a, 0x84, 0x81, 0x4a, 0x92, 0x5c, 0xe2, 0x68, 0x6e, 0x83, 0xb9, 0xdb, 0xe8, 0x23, 0x23, 0x17, - 0xb3, 0x6f, 0x71, 0xba, 0x50, 0x31, 0x17, 0x2f, 0x6a, 0x28, 0x6b, 0xe3, 0xb1, 0x14, 0x3d, 0x14, - 0xa4, 0x8c, 0x49, 0x50, 0x0c, 0x0f, 0x32, 0x06, 0xa1, 0x3c, 0x2e, 0x1e, 0x94, 0x00, 0xd3, 0xc2, - 0x6f, 0x0c, 0xb2, 0x5a, 0x29, 0x23, 0xe2, 0xd5, 0xc2, 0x6c, 0x94, 0x62, 0x6d, 0x78, 0xbe, 0x41, - 0x8b, 0xd1, 0x29, 0xe0, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, - 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xcc, 0x08, - 0xa5, 0x96, 0x0a, 0xf4, 0xc4, 0x0c, 0x4e, 0x3e, 0x49, 0x6c, 0xe0, 0xe4, 0x6a, 0x0c, 0x08, 0x00, - 0x00, 0xff, 0xff, 0x64, 0x60, 0x2a, 0x32, 0x61, 0x03, 0x00, 0x00, + 0x83, 0xa0, 0x3c, 0xa1, 0x10, 0x2e, 0xf6, 0x0c, 0x88, 0x12, 0x09, 0x26, 0x05, 0x66, 0x0d, 0x1e, + 0x27, 0xab, 0x5b, 0xf7, 0xe4, 0xcd, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, + 0xf5, 0xa1, 0xee, 0xc9, 0x49, 0x4c, 0x2a, 0xd6, 0xcd, 0xcc, 0x87, 0x71, 0xf5, 0x4b, 0x2a, 0x0b, + 0x52, 0x8b, 0xf5, 0x9c, 0x42, 0x9c, 0x21, 0x16, 0x38, 0x55, 0x96, 0xa4, 0x16, 0x07, 0xc1, 0x8c, + 0xb2, 0xe2, 0x6e, 0x7a, 0xbe, 0x41, 0x0b, 0x6a, 0x85, 0x92, 0x14, 0x97, 0x04, 0xba, 0x73, 0x82, + 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x95, 0x66, 0x31, 0x72, 0xf1, 0xfb, 0x16, 0xa7, 0x87, + 0x16, 0xa4, 0x24, 0x96, 0xa4, 0x06, 0x80, 0x3d, 0x28, 0x64, 0xc6, 0xc5, 0x99, 0x58, 0x5a, 0x92, + 0x91, 0x5f, 0x94, 0x59, 0x52, 0x09, 0x71, 0xad, 0x93, 0xc4, 0xa5, 0x2d, 0xba, 0x22, 0x50, 0x4f, + 0x3a, 0xa6, 0xa4, 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, 0x21, 0x94, + 0x0a, 0xd9, 0x73, 0xb1, 0x41, 0x82, 0x48, 0x82, 0x49, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x51, 0x0f, + 0x67, 0xac, 0xe8, 0x41, 0xac, 0x72, 0x62, 0x39, 0x71, 0x4f, 0x9e, 0x21, 0x08, 0xaa, 0xcd, 0x8a, + 0x0f, 0xe4, 0x6a, 0x84, 0x81, 0x4a, 0x92, 0x5c, 0xe2, 0x68, 0x6e, 0x83, 0xb9, 0xdb, 0xe8, 0x23, + 0x23, 0x17, 0xb3, 0x6f, 0x71, 0xba, 0x50, 0x31, 0x17, 0x2f, 0x6a, 0x38, 0x6b, 0xe3, 0xb1, 0x14, + 0x3d, 0x14, 0xa4, 0x8c, 0x49, 0x50, 0x0c, 0x0f, 0x32, 0x06, 0xa1, 0x3c, 0x2e, 0x1e, 0x94, 0x00, + 0xd3, 0xc2, 0x6f, 0x0c, 0xb2, 0x5a, 0x29, 0x23, 0xe2, 0xd5, 0xc2, 0x6c, 0x94, 0x62, 0x6d, 0x78, + 0xbe, 0x41, 0x8b, 0xd1, 0x29, 0xe8, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, + 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, + 0x2c, 0x08, 0xa7, 0x97, 0x0a, 0xf4, 0x04, 0x0d, 0x4e, 0x40, 0x49, 0x6c, 0xe0, 0x24, 0x6b, 0x0c, + 0x08, 0x00, 0x00, 0xff, 0xff, 0x7a, 0xa1, 0x1d, 0x4d, 0x65, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -663,7 +663,7 @@ func (m *MsgInsertHeaders) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BTCHeaderBytes + var v github_com_babylonlabs_io_babylon_types.BTCHeaderBytes m.Headers = append(m.Headers, v) if err := m.Headers[len(m.Headers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btclightclient/types/work.go b/x/btclightclient/types/work.go index b5ef4148a..3dadf9c1d 100644 --- a/x/btclightclient/types/work.go +++ b/x/btclightclient/types/work.go @@ -2,7 +2,7 @@ package types import ( sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/wire" ) diff --git a/x/btclightclient/types/work_test.go b/x/btclightclient/types/work_test.go index a68410244..efed2a5ce 100644 --- a/x/btclightclient/types/work_test.go +++ b/x/btclightclient/types/work_test.go @@ -2,8 +2,8 @@ package types_test import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/btclightclient/types" "math/rand" "testing" ) diff --git a/x/btcstaking/README.md b/x/btcstaking/README.md index 69d7d9932..b07b297d5 100644 --- a/x/btcstaking/README.md +++ b/x/btcstaking/README.md @@ -105,7 +105,7 @@ message Params { // covenant_pks is the list of public keys held by the covenant committee // each PK follows encoding in BIP-340 spec on Bitcoin - repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // covenant_quorum is the minimum number of signatures needed for the covenant // multisignature uint32 covenant_quorum = 2; @@ -168,7 +168,7 @@ message FinalityProvider { ]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of the btc_pk, where the BTC // private key signs the bech32 bbn addr of the finality provider. ProofOfPossessionBTC pop = 5; @@ -201,14 +201,14 @@ message BTCDelegation { string staker_addr = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of babylon_pk and btc_pk ProofOfPossessionBTC pop = 3; // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to // If there is more than 1 PKs, then this means the delegation is restaked // to multiple finality providers - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock uint64 start_height = 5; @@ -229,7 +229,7 @@ message BTCDelegation { // delegator_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. - bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_sig = 11 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -258,11 +258,11 @@ message BTCUndelegation { // It effectively proves that the delegator wants to unbond and thus // Babylon will consider this BTC delegation unbonded. Delegator's BTC // on Bitcoin will be unbonded after timelock - bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // delegator_slashing_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the unbonding tx output. - bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // covenant_slashing_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -310,7 +310,7 @@ message Params { // covenant_pks is the list of public keys held by the covenant committee // each PK follows encoding in BIP-340 spec on Bitcoin - repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // covenant_quorum is the minimum number of signatures needed for the covenant // multisignature uint32 covenant_quorum = 2; @@ -370,7 +370,7 @@ message MsgCreateFinalityProvider { ]; // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // pop is the proof of possession of btc_pk over the FP signer address. ProofOfPossessionBTC pop = 5; } @@ -462,10 +462,10 @@ message MsgCreateBTCDelegation { // pop is the proof of possession of btc_pk by the staker_addr. ProofOfPossessionBTC pop = 2; // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // staking_time is the time lock used in staking transaction uint32 staking_time = 5; // staking_value is the amount of satoshis locked in staking output @@ -479,7 +479,7 @@ message MsgCreateBTCDelegation { // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 9 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output @@ -497,7 +497,7 @@ message MsgCreateBTCDelegation { // Note that the tx itself does not contain signatures, which are off-chain. bytes unbonding_slashing_tx = 13 [ (gogoproto.customtype) = "BTCSlashingTx" ]; // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_slashing_sig = 14 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } ``` @@ -555,7 +555,7 @@ message MsgAddCovenantSigs { string signer = 1; // pk is the BTC public key of the covenant member - bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 3; @@ -565,7 +565,7 @@ message MsgAddCovenantSigs { repeated bytes slashing_tx_sigs = 4; // unbonding_tx_sig is the signature of the covenant on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - bytes unbonding_tx_sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes unbonding_tx_sig = 5 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; // slashing_unbonding_tx_sigs is a list of adaptor signatures of the covenant // on slashing tx corresponding to unbonding tx submitted to babylon // the order of sigs should respect the order of finality providers @@ -607,7 +607,7 @@ message MsgBTCUndelegate { string staking_tx_hash = 2; // unbonding_tx_sig is the signature of the staker on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - bytes unbonding_tx_sig = 3 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340Signature" ]; + bytes unbonding_tx_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; } ``` @@ -746,7 +746,7 @@ message EventPowerDistUpdate { // is slashed // TODO: unify with existing slashing events message EventSlashedFinalityProvider { - bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; } // ev is the event that affects voting power distribution diff --git a/x/btcstaking/abci.go b/x/btcstaking/abci.go index b81a4cc7c..210f3ad0d 100644 --- a/x/btcstaking/abci.go +++ b/x/btcstaking/abci.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/telemetry" ) diff --git a/x/btcstaking/client/cli/query.go b/x/btcstaking/client/cli/query.go index 3f5ba70a9..7f3b19126 100644 --- a/x/btcstaking/client/cli/query.go +++ b/x/btcstaking/client/cli/query.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" ) diff --git a/x/btcstaking/client/cli/query_params.go b/x/btcstaking/client/cli/query_params.go index 1672274c1..bec7606ae 100644 --- a/x/btcstaking/client/cli/query_params.go +++ b/x/btcstaking/client/cli/query_params.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func CmdQueryParams() *cobra.Command { diff --git a/x/btcstaking/client/cli/tx.go b/x/btcstaking/client/cli/tx.go index 813e70a50..7ce982784 100644 --- a/x/btcstaking/client/cli/tx.go +++ b/x/btcstaking/client/cli/tx.go @@ -12,10 +12,10 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/spf13/cobra" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) const ( diff --git a/x/btcstaking/genesis.go b/x/btcstaking/genesis.go index 4b89af9ff..5d37bec53 100644 --- a/x/btcstaking/genesis.go +++ b/x/btcstaking/genesis.go @@ -3,8 +3,8 @@ package btcstaking import ( "context" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) // InitGenesis initializes the module's state from a provided genesis state. diff --git a/x/btcstaking/genesis_test.go b/x/btcstaking/genesis_test.go index 357ccfe0d..dc034bdf3 100644 --- a/x/btcstaking/genesis_test.go +++ b/x/btcstaking/genesis_test.go @@ -3,10 +3,10 @@ package btcstaking_test import ( "testing" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/btcstaking" - "github.com/babylonchain/babylon/x/btcstaking/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/btcstaking" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/keeper/bench_test.go b/x/btcstaking/keeper/bench_test.go index 9e217a7aa..27fe36b65 100644 --- a/x/btcstaking/keeper/bench_test.go +++ b/x/btcstaking/keeper/bench_test.go @@ -8,10 +8,10 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - bsmodule "github.com/babylonchain/babylon/x/btcstaking" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + bsmodule "github.com/babylonlabs-io/babylon/x/btcstaking" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/golang/mock/gomock" ) diff --git a/x/btcstaking/keeper/btc_delegations.go b/x/btcstaking/keeper/btc_delegations.go index 9ebcb6bea..4e98d1a81 100644 --- a/x/btcstaking/keeper/btc_delegations.go +++ b/x/btcstaking/keeper/btc_delegations.go @@ -5,9 +5,9 @@ import ( "fmt" "cosmossdk.io/store/prefix" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/btcstaking/keeper/btc_delegators.go b/x/btcstaking/keeper/btc_delegators.go index a8023166a..550a899fa 100644 --- a/x/btcstaking/keeper/btc_delegators.go +++ b/x/btcstaking/keeper/btc_delegators.go @@ -8,8 +8,8 @@ import ( "cosmossdk.io/store/prefix" "github.com/btcsuite/btcd/chaincfg/chainhash" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) // getBTCDelegatorDelegationIndex gets the BTC delegation index with a given BTC PK under a given finality provider diff --git a/x/btcstaking/keeper/btc_height_index.go b/x/btcstaking/keeper/btc_height_index.go index 60b3ce84f..1f7adcc64 100644 --- a/x/btcstaking/keeper/btc_height_index.go +++ b/x/btcstaking/keeper/btc_height_index.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btcstaking/keeper/btc_height_index_test.go b/x/btcstaking/keeper/btc_height_index_test.go index 819e92dd3..a40b5d4d3 100644 --- a/x/btcstaking/keeper/btc_height_index_test.go +++ b/x/btcstaking/keeper/btc_height_index_test.go @@ -4,10 +4,10 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/keeper/finality_providers.go b/x/btcstaking/keeper/finality_providers.go index b978dda34..f590ffc94 100644 --- a/x/btcstaking/keeper/finality_providers.go +++ b/x/btcstaking/keeper/finality_providers.go @@ -8,7 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) // SetFinalityProvider adds the given finality provider to KVStore diff --git a/x/btcstaking/keeper/genesis.go b/x/btcstaking/keeper/genesis.go index 211329c43..1e4a59a58 100644 --- a/x/btcstaking/keeper/genesis.go +++ b/x/btcstaking/keeper/genesis.go @@ -4,9 +4,9 @@ import ( "context" "fmt" - btcstk "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + btcstk "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btcstaking/keeper/genesis_test.go b/x/btcstaking/keeper/genesis_test.go index cbcc60ead..f9d5e7d0f 100644 --- a/x/btcstaking/keeper/genesis_test.go +++ b/x/btcstaking/keeper/genesis_test.go @@ -6,10 +6,10 @@ import ( "strings" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" - btclightclientt "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/helper" + btclightclientt "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/keeper/grpc_query.go b/x/btcstaking/keeper/grpc_query.go index f687cdb36..714515ebe 100644 --- a/x/btcstaking/keeper/grpc_query.go +++ b/x/btcstaking/keeper/grpc_query.go @@ -11,8 +11,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/btcstaking/keeper/grpc_query_test.go b/x/btcstaking/keeper/grpc_query_test.go index 661836a97..af2b03d47 100644 --- a/x/btcstaking/keeper/grpc_query_test.go +++ b/x/btcstaking/keeper/grpc_query_test.go @@ -12,12 +12,12 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func FuzzActivatedHeight(f *testing.F) { diff --git a/x/btcstaking/keeper/hooks.go b/x/btcstaking/keeper/hooks.go index 1ae540dc9..c7283e95a 100644 --- a/x/btcstaking/keeper/hooks.go +++ b/x/btcstaking/keeper/hooks.go @@ -4,8 +4,8 @@ import ( "context" "fmt" - bbntypes "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbntypes "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) var _ types.FinalityHooks = Hooks{} diff --git a/x/btcstaking/keeper/incentive.go b/x/btcstaking/keeper/incentive.go index d55135281..ac65638b9 100644 --- a/x/btcstaking/keeper/incentive.go +++ b/x/btcstaking/keeper/incentive.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btcstaking/keeper/incentive_test.go b/x/btcstaking/keeper/incentive_test.go index ec60f11c1..ea7d699d5 100644 --- a/x/btcstaking/keeper/incentive_test.go +++ b/x/btcstaking/keeper/incentive_test.go @@ -7,9 +7,9 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func FuzzRecordVotingPowerDistCache(f *testing.F) { diff --git a/x/btcstaking/keeper/keeper.go b/x/btcstaking/keeper/keeper.go index 56d1ac41f..5a992423a 100644 --- a/x/btcstaking/keeper/keeper.go +++ b/x/btcstaking/keeper/keeper.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) type ( diff --git a/x/btcstaking/keeper/keeper_test.go b/x/btcstaking/keeper/keeper_test.go index 49da3cdaf..1ce64721e 100644 --- a/x/btcstaking/keeper/keeper_test.go +++ b/x/btcstaking/keeper/keeper_test.go @@ -13,13 +13,13 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) var ( diff --git a/x/btcstaking/keeper/msg_server.go b/x/btcstaking/keeper/msg_server.go index 2a97b6662..a1617d9ed 100644 --- a/x/btcstaking/keeper/msg_server.go +++ b/x/btcstaking/keeper/msg_server.go @@ -8,9 +8,9 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/wire" diff --git a/x/btcstaking/keeper/msg_server_test.go b/x/btcstaking/keeper/msg_server_test.go index 5038d7d58..24d2b2cec 100644 --- a/x/btcstaking/keeper/msg_server_test.go +++ b/x/btcstaking/keeper/msg_server_test.go @@ -17,13 +17,13 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func FuzzMsgCreateFinalityProvider(f *testing.F) { diff --git a/x/btcstaking/keeper/params.go b/x/btcstaking/keeper/params.go index 4a9978c7a..0f47ba169 100644 --- a/x/btcstaking/keeper/params.go +++ b/x/btcstaking/keeper/params.go @@ -7,7 +7,7 @@ import ( "cosmossdk.io/math" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/runtime" ) diff --git a/x/btcstaking/keeper/params_test.go b/x/btcstaking/keeper/params_test.go index 18056c153..58f8500f4 100644 --- a/x/btcstaking/keeper/params_test.go +++ b/x/btcstaking/keeper/params_test.go @@ -5,9 +5,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/keeper/power_dist_change.go b/x/btcstaking/keeper/power_dist_change.go index 0d6aa3e2c..bde774ce7 100644 --- a/x/btcstaking/keeper/power_dist_change.go +++ b/x/btcstaking/keeper/power_dist_change.go @@ -10,8 +10,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) /* power distribution update */ diff --git a/x/btcstaking/keeper/power_dist_change_test.go b/x/btcstaking/keeper/power_dist_change_test.go index da4ec9502..65320c5df 100644 --- a/x/btcstaking/keeper/power_dist_change_test.go +++ b/x/btcstaking/keeper/power_dist_change_test.go @@ -4,9 +4,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" diff --git a/x/btcstaking/keeper/query.go b/x/btcstaking/keeper/query.go index 7a46601f8..ae817f28f 100644 --- a/x/btcstaking/keeper/query.go +++ b/x/btcstaking/keeper/query.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/btcstaking/keeper/query_params.go b/x/btcstaking/keeper/query_params.go index 51e391d52..eed444b02 100644 --- a/x/btcstaking/keeper/query_params.go +++ b/x/btcstaking/keeper/query_params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/btcstaking/keeper/query_params_test.go b/x/btcstaking/keeper/query_params_test.go index fefd0ae45..6d0239d0b 100644 --- a/x/btcstaking/keeper/query_params_test.go +++ b/x/btcstaking/keeper/query_params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/keeper/voting_power_table.go b/x/btcstaking/keeper/voting_power_table.go index 7b5297c5e..f7abc715b 100644 --- a/x/btcstaking/keeper/voting_power_table.go +++ b/x/btcstaking/keeper/voting_power_table.go @@ -7,8 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btcstaking/keeper/voting_power_table_test.go b/x/btcstaking/keeper/voting_power_table_test.go index 82ac32e6d..a8c743afe 100644 --- a/x/btcstaking/keeper/voting_power_table_test.go +++ b/x/btcstaking/keeper/voting_power_table_test.go @@ -5,9 +5,9 @@ import ( "sort" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/module.go b/x/btcstaking/module.go index a415eee5a..e8e431b76 100644 --- a/x/btcstaking/module.go +++ b/x/btcstaking/module.go @@ -11,9 +11,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/btcstaking/client/cli" - "github.com/babylonchain/babylon/x/btcstaking/keeper" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/client/cli" + "github.com/babylonlabs-io/babylon/x/btcstaking/keeper" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/btcstaking/types/btc_delegation.go b/x/btcstaking/types/btc_delegation.go index 66a621751..b17ef18ee 100644 --- a/x/btcstaking/types/btc_delegation.go +++ b/x/btcstaking/types/btc_delegation.go @@ -7,9 +7,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/btcstaking" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btcstaking" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" diff --git a/x/btcstaking/types/btc_delegation_test.go b/x/btcstaking/types/btc_delegation_test.go index c2b53094c..a97535c43 100644 --- a/x/btcstaking/types/btc_delegation_test.go +++ b/x/btcstaking/types/btc_delegation_test.go @@ -5,15 +5,15 @@ import ( "testing" sdkmath "cosmossdk.io/math" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/chaincfg" "github.com/stretchr/testify/require" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - btctest "github.com/babylonchain/babylon/testutil/bitcoin" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + btctest "github.com/babylonlabs-io/babylon/testutil/bitcoin" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) func FuzzBTCDelegation(f *testing.F) { diff --git a/x/btcstaking/types/btc_slashing_tx.go b/x/btcstaking/types/btc_slashing_tx.go index e6c249d63..2bd135905 100644 --- a/x/btcstaking/types/btc_slashing_tx.go +++ b/x/btcstaking/types/btc_slashing_tx.go @@ -10,9 +10,9 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" - "github.com/babylonchain/babylon/btcstaking" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btcstaking" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" ) type BTCSlashingTx []byte diff --git a/x/btcstaking/types/btc_slashing_tx_test.go b/x/btcstaking/types/btc_slashing_tx_test.go index adee66e84..aa90099ad 100644 --- a/x/btcstaking/types/btc_slashing_tx_test.go +++ b/x/btcstaking/types/btc_slashing_tx_test.go @@ -5,11 +5,11 @@ import ( "testing" sdkmath "cosmossdk.io/math" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - btctest "github.com/babylonchain/babylon/testutil/bitcoin" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + btctest "github.com/babylonlabs-io/babylon/testutil/bitcoin" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/types/btc_undelegation.go b/x/btcstaking/types/btc_undelegation.go index fdbee5495..177bcbf0e 100644 --- a/x/btcstaking/types/btc_undelegation.go +++ b/x/btcstaking/types/btc_undelegation.go @@ -1,8 +1,8 @@ package types import ( - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" ) func (ud *BTCUndelegation) HasCovenantQuorumOnSlashing(quorum uint32) bool { diff --git a/x/btcstaking/types/btc_undelegation_test.go b/x/btcstaking/types/btc_undelegation_test.go index 1306184d0..75b72c7bf 100644 --- a/x/btcstaking/types/btc_undelegation_test.go +++ b/x/btcstaking/types/btc_undelegation_test.go @@ -5,11 +5,11 @@ import ( "testing" sdkmath "cosmossdk.io/math" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - btctest "github.com/babylonchain/babylon/testutil/bitcoin" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + btctest "github.com/babylonlabs-io/babylon/testutil/bitcoin" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/btcsuite/btcd/chaincfg" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/types/btcstaking.go b/x/btcstaking/types/btcstaking.go index 8f22d7838..f907537f2 100644 --- a/x/btcstaking/types/btcstaking.go +++ b/x/btcstaking/types/btcstaking.go @@ -8,9 +8,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - asig "github.com/babylonchain/babylon/crypto/schnorr-adaptor-signature" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" + asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" ) func (fp *FinalityProvider) IsSlashed() bool { diff --git a/x/btcstaking/types/btcstaking.pb.go b/x/btcstaking/types/btcstaking.pb.go index 5fd7ae838..09e42a299 100644 --- a/x/btcstaking/types/btcstaking.pb.go +++ b/x/btcstaking/types/btcstaking.pb.go @@ -6,7 +6,7 @@ package types import ( cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" types "github.com/cosmos/cosmos-sdk/x/staking/types" _ "github.com/cosmos/gogoproto/gogoproto" @@ -78,7 +78,7 @@ type FinalityProvider struct { Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of the btc_pk, where the BTC // private key signs the bech32 bbn addr of the finality provider. Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` @@ -173,7 +173,7 @@ func (m *FinalityProvider) GetSluggish() bool { type FinalityProviderWithMeta struct { // btc_pk is the Bitcoin secp256k1 PK of thisfinality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // height is the queried Babylon height Height uint64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` // voting_power is the voting power of this finality provider at the given height @@ -264,14 +264,14 @@ type BTCDelegation struct { StakerAddr string `protobuf:"bytes,1,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of babylon_pk and btc_pk Pop *ProofOfPossessionBTC `protobuf:"bytes,3,opt,name=pop,proto3" json:"pop,omitempty"` // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to // If there is more than 1 PKs, then this means the delegation is restaked // to multiple finality providers - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` + FpBtcPkList []github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,4,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock StartHeight uint64 `protobuf:"varint,5,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` @@ -292,7 +292,7 @@ type BTCDelegation struct { // delegator_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the staking tx output. - DelegatorSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,11,opt,name=delegator_sig,json=delegatorSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_sig,omitempty"` + DelegatorSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,11,opt,name=delegator_sig,json=delegatorSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"delegator_sig,omitempty"` // covenant_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -431,11 +431,11 @@ type BTCUndelegation struct { // It effectively proves that the delegator wants to unbond and thus // Babylon will consider this BTC delegation unbonded. Delegator's BTC // on Bitcoin will be unbonded after timelock - DelegatorUnbondingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,3,opt,name=delegator_unbonding_sig,json=delegatorUnbondingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_unbonding_sig,omitempty"` + DelegatorUnbondingSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,3,opt,name=delegator_unbonding_sig,json=delegatorUnbondingSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"delegator_unbonding_sig,omitempty"` // delegator_slashing_sig is the signature on the slashing tx // by the delegator (i.e., SK corresponding to btc_pk). // It will be a part of the witness for the unbonding tx output. - DelegatorSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,4,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` + DelegatorSlashingSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,4,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` // covenant_slashing_sigs is a list of adaptor signatures on the slashing tx // by each covenant member // It will be a part of the witness for the staking tx output. @@ -592,8 +592,8 @@ func (m *BTCDelegatorDelegationIndex) GetStakingTxHashList() [][]byte { // SignatureInfo is a BIP-340 signature together with its signer's BIP-340 PK type SignatureInfo struct { - Pk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=pk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"pk,omitempty"` - Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,2,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` + Pk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=pk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"pk,omitempty"` + Sig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,2,opt,name=sig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"sig,omitempty"` } func (m *SignatureInfo) Reset() { *m = SignatureInfo{} } @@ -633,7 +633,7 @@ var xxx_messageInfo_SignatureInfo proto.InternalMessageInfo // covenant with different finality provider's public keys as encryption keys type CovenantAdaptorSignatures struct { // cov_pk is the public key of the covenant emulator, used as the public key of the adaptor signature - CovPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=cov_pk,json=covPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"cov_pk,omitempty"` + CovPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=cov_pk,json=covPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"cov_pk,omitempty"` // adaptor_sigs is a list of adaptor signatures, each encrypted by a restaked BTC finality provider's public key AdaptorSigs [][]byte `protobuf:"bytes,2,rep,name=adaptor_sigs,json=adaptorSigs,proto3" json:"adaptor_sigs,omitempty"` } @@ -690,7 +690,7 @@ type SelectiveSlashingEvidence struct { StakingTxHash string `protobuf:"bytes,1,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` // fp_btc_pk is the BTC PK of the finality provider who // launches the selective slashing offence - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // recovered_fp_btc_sk is the finality provider's BTC SK recovered from // the covenant adaptor/Schnorr signature pair. It is the consequence // of selective slashing. @@ -762,83 +762,83 @@ func init() { } var fileDescriptor_3851ae95ccfaf7db = []byte{ - // 1210 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0x13, 0xc7, - 0x1b, 0xce, 0xda, 0x8e, 0x93, 0xbc, 0xb6, 0x89, 0x19, 0x42, 0x58, 0x12, 0xfd, 0x12, 0xff, 0x5c, - 0x8a, 0xac, 0x96, 0xd8, 0x10, 0x68, 0x55, 0x0e, 0x3d, 0xc4, 0x71, 0x28, 0x11, 0x10, 0xdc, 0xb5, - 0x43, 0xd5, 0x56, 0xea, 0x6a, 0xbc, 0x3b, 0x59, 0x8f, 0x6c, 0xef, 0x6c, 0x77, 0xc6, 0xae, 0xf3, - 0x21, 0x2a, 0xf5, 0xda, 0x3b, 0x1f, 0x81, 0xcf, 0x50, 0xf5, 0x88, 0x38, 0x55, 0x39, 0x44, 0x15, - 0xf4, 0xda, 0xef, 0x50, 0xcd, 0xec, 0x7a, 0x77, 0x9d, 0x12, 0x0a, 0x98, 0x9b, 0xe7, 0xfd, 0xf7, - 0xbc, 0xf3, 0x3e, 0x8f, 0xdf, 0x59, 0xb8, 0xde, 0xc1, 0x9d, 0xe3, 0x3e, 0x73, 0x6b, 0x1d, 0x61, - 0x71, 0x81, 0x7b, 0xd4, 0x75, 0x6a, 0xa3, 0x5b, 0x89, 0x53, 0xd5, 0xf3, 0x99, 0x60, 0xe8, 0x72, - 0x18, 0x57, 0x4d, 0x78, 0x46, 0xb7, 0xd6, 0x56, 0x1c, 0xe6, 0x30, 0x15, 0x51, 0x93, 0xbf, 0x82, - 0xe0, 0xb5, 0xab, 0x16, 0xe3, 0x03, 0xc6, 0xcd, 0xc0, 0x11, 0x1c, 0x42, 0xd7, 0xb5, 0xe0, 0x54, - 0x8b, 0xb1, 0x3a, 0x44, 0xe0, 0x5b, 0xb5, 0x29, 0xb4, 0xb5, 0xcd, 0xd7, 0x77, 0xe5, 0x31, 0x2f, - 0x08, 0x28, 0xff, 0x95, 0x86, 0xe2, 0x3d, 0xea, 0xe2, 0x3e, 0x15, 0xc7, 0x4d, 0x9f, 0x8d, 0xa8, - 0x4d, 0x7c, 0x74, 0x03, 0x32, 0xd8, 0xb6, 0x7d, 0x5d, 0x2b, 0x69, 0x95, 0xa5, 0xba, 0xfe, 0xe2, - 0xd9, 0xd6, 0x4a, 0x88, 0xbd, 0x63, 0xdb, 0x3e, 0xe1, 0xbc, 0x25, 0x7c, 0xea, 0x3a, 0x86, 0x8a, - 0x42, 0x7b, 0x90, 0xb3, 0x09, 0xb7, 0x7c, 0xea, 0x09, 0xca, 0x5c, 0x3d, 0x55, 0xd2, 0x2a, 0xb9, - 0xed, 0x8f, 0xaa, 0x61, 0x46, 0x7c, 0x47, 0xd5, 0x5f, 0xb5, 0x11, 0x87, 0x1a, 0xc9, 0x3c, 0xf4, - 0x08, 0xc0, 0x62, 0x83, 0x01, 0xe5, 0x5c, 0x56, 0x49, 0x2b, 0xe8, 0xad, 0x93, 0xd3, 0xcd, 0xf5, - 0xa0, 0x10, 0xb7, 0x7b, 0x55, 0xca, 0x6a, 0x03, 0x2c, 0xba, 0xd5, 0x87, 0xc4, 0xc1, 0xd6, 0x71, - 0x83, 0x58, 0x2f, 0x9e, 0x6d, 0x41, 0x88, 0xd3, 0x20, 0x96, 0x91, 0x28, 0x80, 0x1e, 0x41, 0xb6, - 0x23, 0x2c, 0xd3, 0xeb, 0xe9, 0x99, 0x92, 0x56, 0xc9, 0xd7, 0x3f, 0x3f, 0x39, 0xdd, 0xdc, 0x76, - 0xa8, 0xe8, 0x0e, 0x3b, 0x55, 0x8b, 0x0d, 0x6a, 0xe1, 0x60, 0xac, 0x2e, 0xa6, 0xee, 0xe4, 0x50, - 0x13, 0xc7, 0x1e, 0xe1, 0xd5, 0xfa, 0x7e, 0xf3, 0xf6, 0x9d, 0x9b, 0xcd, 0x61, 0xe7, 0x01, 0x39, - 0x36, 0xe6, 0x3b, 0xc2, 0x6a, 0xf6, 0xd0, 0x97, 0x90, 0xf6, 0x98, 0xa7, 0xcf, 0xab, 0xcb, 0x7d, - 0x5a, 0x7d, 0x2d, 0x89, 0xd5, 0xa6, 0xcf, 0xd8, 0xd1, 0xe3, 0xa3, 0x26, 0xe3, 0x9c, 0xa8, 0x2e, - 0xea, 0xed, 0x5d, 0x43, 0xe6, 0xa1, 0x3b, 0xb0, 0xca, 0xfb, 0x98, 0x77, 0x89, 0x6d, 0x86, 0xa9, - 0x66, 0x97, 0x50, 0xa7, 0x2b, 0xf4, 0x6c, 0x49, 0xab, 0x64, 0x8c, 0x95, 0xd0, 0x5b, 0x0f, 0x9c, - 0xf7, 0x95, 0x0f, 0xdd, 0x00, 0x14, 0x65, 0x09, 0x6b, 0x92, 0xb1, 0xa0, 0x32, 0x8a, 0x93, 0x0c, - 0x61, 0x85, 0xd1, 0x6b, 0xb0, 0xc8, 0xfb, 0x43, 0xc7, 0xa1, 0xbc, 0xab, 0x2f, 0x96, 0xb4, 0xca, - 0xa2, 0x11, 0x9d, 0xcb, 0x4f, 0x53, 0xa0, 0x9f, 0xa5, 0xf9, 0x1b, 0x2a, 0xba, 0x8f, 0x88, 0xc0, - 0x89, 0x51, 0x69, 0x1f, 0x62, 0x54, 0xab, 0x90, 0x0d, 0x3b, 0x4d, 0xa9, 0x4e, 0xc3, 0x13, 0xfa, - 0x3f, 0xe4, 0x47, 0x4c, 0x50, 0xd7, 0x31, 0x3d, 0xf6, 0x13, 0xf1, 0x15, 0xc5, 0x19, 0x23, 0x17, - 0xd8, 0x9a, 0xd2, 0xf4, 0x86, 0x31, 0x65, 0xde, 0x79, 0x4c, 0xf3, 0x6f, 0x31, 0xa6, 0xec, 0x99, - 0x31, 0xfd, 0x9d, 0x85, 0x42, 0xbd, 0xbd, 0xdb, 0x20, 0x7d, 0xe2, 0x60, 0xa5, 0xca, 0xbb, 0x90, - 0x93, 0x04, 0x13, 0xdf, 0x7c, 0xab, 0x7f, 0x04, 0x04, 0xc1, 0xd2, 0x98, 0x18, 0x6b, 0xea, 0x03, - 0x2a, 0x30, 0xfd, 0x9e, 0x0a, 0xfc, 0x1e, 0x2e, 0x1c, 0x79, 0x66, 0xd0, 0x90, 0xd9, 0xa7, 0x5c, - 0x8e, 0x34, 0x3d, 0x43, 0x57, 0xb9, 0x23, 0xaf, 0x2e, 0xfb, 0x7a, 0x48, 0xb9, 0xa2, 0x96, 0x0b, - 0xec, 0x8b, 0xe9, 0xd9, 0xe7, 0x94, 0x2d, 0x1c, 0xfb, 0xff, 0x00, 0x88, 0x6b, 0x4f, 0xab, 0x7e, - 0x89, 0xb8, 0x76, 0xe8, 0x5e, 0x87, 0x25, 0xc1, 0x04, 0xee, 0x9b, 0x1c, 0x4f, 0x14, 0xbe, 0xa8, - 0x0c, 0x2d, 0xac, 0x72, 0xc3, 0x3b, 0x9a, 0x62, 0xac, 0xb4, 0x9d, 0x37, 0x96, 0x42, 0x4b, 0x7b, - 0xac, 0xf8, 0x0f, 0xdd, 0x6c, 0x28, 0xbc, 0xa1, 0x30, 0xa9, 0x3d, 0xd6, 0x97, 0x4a, 0x5a, 0xa5, - 0x60, 0x14, 0x43, 0xcf, 0x63, 0xe5, 0xd8, 0xb7, 0xc7, 0x68, 0x1b, 0x72, 0x4a, 0x13, 0x61, 0x35, - 0x50, 0xdc, 0x5c, 0x3c, 0x39, 0xdd, 0x94, 0xcc, 0xb7, 0x42, 0x4f, 0x7b, 0x6c, 0x00, 0x8f, 0x7e, - 0xa3, 0x1f, 0xa0, 0x60, 0x07, 0x9a, 0x60, 0xbe, 0xc9, 0xa9, 0xa3, 0xe7, 0x54, 0xd6, 0xdd, 0x93, - 0xd3, 0xcd, 0xcf, 0xde, 0x65, 0x76, 0x2d, 0xea, 0xb8, 0x58, 0x0c, 0x7d, 0x62, 0xe4, 0xa3, 0x7a, - 0x2d, 0xea, 0xa0, 0x43, 0x28, 0x58, 0x6c, 0x44, 0x5c, 0xec, 0x0a, 0x59, 0x9e, 0xeb, 0xf9, 0x52, - 0xba, 0x92, 0xdb, 0xbe, 0x79, 0x0e, 0xcb, 0xbb, 0x61, 0xec, 0x8e, 0x8d, 0xbd, 0xa0, 0x42, 0x50, - 0x95, 0x1b, 0xf9, 0x49, 0x99, 0x16, 0x75, 0x38, 0xfa, 0x18, 0x2e, 0x0c, 0xdd, 0x0e, 0x73, 0x6d, - 0x75, 0x57, 0x3a, 0x20, 0x7a, 0x41, 0x0d, 0xa5, 0x10, 0x59, 0xdb, 0x74, 0x40, 0xd0, 0xd7, 0x50, - 0x94, 0xba, 0x18, 0xba, 0x76, 0xa4, 0x7b, 0xfd, 0x82, 0x92, 0xd9, 0xf5, 0x73, 0x1a, 0xa8, 0xb7, - 0x77, 0x0f, 0x13, 0xd1, 0xc6, 0x72, 0x47, 0x58, 0x49, 0x83, 0x44, 0xf6, 0xb0, 0x8f, 0x07, 0xdc, - 0x1c, 0x11, 0x5f, 0x2d, 0xf4, 0xe5, 0x00, 0x39, 0xb0, 0x3e, 0x09, 0x8c, 0xe5, 0x5f, 0x33, 0xb0, - 0x7c, 0xa6, 0x96, 0xd4, 0x52, 0xa2, 0xe9, 0x71, 0xb0, 0x93, 0x8c, 0x5c, 0xdc, 0xf2, 0xbf, 0x28, - 0x4c, 0xbd, 0x0d, 0x85, 0x3f, 0xc2, 0x95, 0x98, 0xc2, 0x18, 0x40, 0x92, 0x99, 0x9e, 0x95, 0xcc, - 0xcb, 0x51, 0xe5, 0xc3, 0x49, 0x61, 0xc9, 0x2a, 0x83, 0xd5, 0x84, 0x6a, 0x26, 0x0d, 0x4b, 0xc4, - 0xcc, 0xac, 0x88, 0x2b, 0xb1, 0x7c, 0xc2, 0xba, 0x12, 0xf0, 0x08, 0x56, 0x63, 0x19, 0x25, 0xf0, - 0xb8, 0x3e, 0xff, 0x9e, 0x7a, 0x5a, 0x89, 0xf4, 0x14, 0xc3, 0x70, 0x64, 0xc1, 0x7a, 0x84, 0x33, - 0x35, 0xca, 0x60, 0xb1, 0x64, 0x15, 0xd8, 0xb5, 0x73, 0xc0, 0xa2, 0xea, 0xfb, 0xee, 0x11, 0x33, - 0xf4, 0x49, 0xa1, 0xe4, 0xe4, 0xe4, 0x4e, 0x29, 0xb7, 0xe0, 0x4a, 0xbc, 0x8a, 0x99, 0x1f, 0xef, - 0x64, 0x8e, 0xbe, 0x80, 0x8c, 0x4d, 0xfa, 0x5c, 0xd7, 0xde, 0x08, 0x34, 0xb5, 0xc8, 0x0d, 0x95, - 0x51, 0x3e, 0x80, 0xf5, 0xd7, 0x17, 0xdd, 0x77, 0x6d, 0x32, 0x46, 0x35, 0x58, 0x89, 0x17, 0x8d, - 0xd9, 0xc5, 0xbc, 0x1b, 0xdc, 0x48, 0x02, 0xe5, 0x8d, 0x8b, 0xd1, 0xca, 0xb9, 0x8f, 0x79, 0x57, - 0x35, 0xf9, 0x54, 0x83, 0xc2, 0xd4, 0x85, 0xd0, 0x3d, 0x48, 0xcd, 0xfc, 0x90, 0xa6, 0xbc, 0x1e, - 0x7a, 0x00, 0x69, 0xa9, 0x94, 0xd4, 0xac, 0x4a, 0x91, 0x55, 0xca, 0x3f, 0x6b, 0x70, 0xf5, 0x5c, - 0x92, 0xe5, 0x43, 0x65, 0xb1, 0xd1, 0x07, 0x78, 0xff, 0x2d, 0x36, 0x6a, 0xf6, 0xe4, 0x1f, 0x18, - 0x07, 0x18, 0x81, 0xf6, 0x52, 0x6a, 0x78, 0x39, 0x1c, 0xe1, 0xf2, 0xf2, 0x6f, 0x1a, 0x5c, 0x6d, - 0x91, 0x3e, 0xb1, 0x04, 0x1d, 0x91, 0x89, 0xb4, 0xf6, 0xe4, 0x57, 0x89, 0x6b, 0x11, 0x74, 0x1d, - 0x96, 0xcf, 0xb0, 0x10, 0xbc, 0xbb, 0x46, 0x61, 0x8a, 0x00, 0x64, 0xc0, 0x52, 0xf4, 0xa4, 0xcd, - 0xf8, 0xc6, 0x2e, 0x84, 0xaf, 0x19, 0xda, 0x82, 0x4b, 0x3e, 0x91, 0x9a, 0xf4, 0x89, 0x6d, 0x86, - 0xd5, 0x79, 0x2f, 0x58, 0x11, 0x46, 0x31, 0x72, 0xdd, 0x93, 0xe1, 0xad, 0xde, 0x27, 0x7b, 0x70, - 0x69, 0x4a, 0x66, 0x2d, 0x81, 0xc5, 0x90, 0xa3, 0x1c, 0x2c, 0x34, 0xf7, 0x0e, 0x1a, 0xfb, 0x07, - 0x5f, 0x15, 0xe7, 0x10, 0x40, 0x76, 0x67, 0xb7, 0xbd, 0xff, 0x64, 0xaf, 0xa8, 0xa1, 0x3c, 0x2c, - 0x1e, 0x1e, 0xd4, 0x1f, 0x1f, 0x34, 0xf6, 0x1a, 0xc5, 0x14, 0x5a, 0x80, 0xf4, 0xce, 0xc1, 0xb7, - 0xc5, 0x74, 0xfd, 0xe1, 0xef, 0x2f, 0x37, 0xb4, 0xe7, 0x2f, 0x37, 0xb4, 0x3f, 0x5f, 0x6e, 0x68, - 0xbf, 0xbc, 0xda, 0x98, 0x7b, 0xfe, 0x6a, 0x63, 0xee, 0x8f, 0x57, 0x1b, 0x73, 0xdf, 0xfd, 0xe7, - 0x65, 0xc6, 0xc9, 0x4f, 0x7b, 0x75, 0xb3, 0x4e, 0x56, 0x7d, 0xda, 0xdf, 0xfe, 0x27, 0x00, 0x00, - 0xff, 0xff, 0xbf, 0xab, 0xbe, 0x1d, 0x93, 0x0c, 0x00, 0x00, + // 1213 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0xdf, 0x6e, 0x1a, 0xc7, + 0x17, 0xf6, 0x02, 0xc6, 0xf6, 0x01, 0x62, 0x32, 0x71, 0x9c, 0x8d, 0xad, 0x9f, 0xcd, 0x8f, 0xa6, + 0x11, 0x6a, 0x63, 0xc8, 0x3f, 0xa9, 0xa9, 0xaa, 0x5e, 0x18, 0xe3, 0x34, 0x56, 0x13, 0x4c, 0x17, + 0x9c, 0xaa, 0x95, 0xaa, 0xed, 0xb0, 0x3b, 0x2c, 0x23, 0x60, 0x67, 0xbb, 0x33, 0x50, 0xfc, 0x14, + 0xed, 0x0b, 0xf4, 0xb6, 0xea, 0x03, 0xe4, 0x21, 0x72, 0x19, 0xe5, 0xaa, 0xf2, 0x85, 0x55, 0x25, + 0x52, 0x5f, 0xa0, 0x2f, 0x50, 0xcd, 0xec, 0xb2, 0x2c, 0xae, 0x1d, 0x39, 0xb1, 0xef, 0x98, 0xf3, + 0xef, 0x3b, 0x73, 0xbe, 0x8f, 0x33, 0x0b, 0xb7, 0xdb, 0xb8, 0x7d, 0xd8, 0x67, 0x6e, 0xa5, 0x2d, + 0x2c, 0x2e, 0x70, 0x8f, 0xba, 0x4e, 0x65, 0x74, 0x2f, 0x76, 0x2a, 0x7b, 0x3e, 0x13, 0x0c, 0x5d, + 0x0f, 0xe3, 0xca, 0x31, 0xcf, 0xe8, 0xde, 0xda, 0x8a, 0xc3, 0x1c, 0xa6, 0x22, 0x2a, 0xf2, 0x57, + 0x10, 0xbc, 0x76, 0xd3, 0x62, 0x7c, 0xc0, 0xb8, 0x19, 0x38, 0x82, 0x43, 0xe8, 0xba, 0x15, 0x9c, + 0x2a, 0x53, 0xac, 0x36, 0x11, 0xf8, 0x5e, 0x65, 0x06, 0x6d, 0x6d, 0xf3, 0xf4, 0xae, 0x3c, 0xe6, + 0x05, 0x01, 0xc5, 0xbf, 0x93, 0x90, 0x7f, 0x4c, 0x5d, 0xdc, 0xa7, 0xe2, 0xb0, 0xe1, 0xb3, 0x11, + 0xb5, 0x89, 0x8f, 0xee, 0x40, 0x0a, 0xdb, 0xb6, 0xaf, 0x6b, 0x05, 0xad, 0xb4, 0x54, 0xd5, 0x5f, + 0xbf, 0xd8, 0x5a, 0x09, 0xb1, 0xb7, 0x6d, 0xdb, 0x27, 0x9c, 0x37, 0x85, 0x4f, 0x5d, 0xc7, 0x50, + 0x51, 0x68, 0x17, 0x32, 0x36, 0xe1, 0x96, 0x4f, 0x3d, 0x41, 0x99, 0xab, 0x27, 0x0a, 0x5a, 0x29, + 0x73, 0xff, 0xa3, 0x72, 0x98, 0x31, 0xbd, 0xa3, 0xea, 0xaf, 0x5c, 0x9b, 0x86, 0x1a, 0xf1, 0x3c, + 0xf4, 0x0c, 0xc0, 0x62, 0x83, 0x01, 0xe5, 0x5c, 0x56, 0x49, 0x2a, 0xe8, 0xad, 0xa3, 0xe3, 0xcd, + 0xf5, 0xa0, 0x10, 0xb7, 0x7b, 0x65, 0xca, 0x2a, 0x03, 0x2c, 0xba, 0xe5, 0xa7, 0xc4, 0xc1, 0xd6, + 0x61, 0x8d, 0x58, 0xaf, 0x5f, 0x6c, 0x41, 0x88, 0x53, 0x23, 0x96, 0x11, 0x2b, 0x80, 0xf6, 0x21, + 0xdd, 0x16, 0x96, 0xe9, 0xf5, 0xf4, 0x54, 0x41, 0x2b, 0x65, 0xab, 0x8f, 0x8e, 0x8e, 0x37, 0x1f, + 0x3a, 0x54, 0x74, 0x87, 0xed, 0xb2, 0xc5, 0x06, 0x95, 0x70, 0x30, 0x7d, 0xdc, 0xe6, 0x5b, 0x94, + 0x4d, 0x8e, 0x15, 0x71, 0xe8, 0x11, 0x5e, 0xae, 0xee, 0x35, 0x1e, 0x3c, 0xbc, 0xdb, 0x18, 0xb6, + 0xbf, 0x26, 0x87, 0xc6, 0x7c, 0x5b, 0x58, 0x8d, 0x1e, 0xfa, 0x12, 0x92, 0x1e, 0xf3, 0xf4, 0x79, + 0x75, 0xbd, 0x4f, 0xcb, 0xa7, 0xd2, 0x58, 0x6e, 0xf8, 0x8c, 0x75, 0xf6, 0x3b, 0x0d, 0xc6, 0x39, + 0x51, 0x7d, 0x54, 0x5b, 0x3b, 0x86, 0xcc, 0x43, 0x0f, 0x61, 0x95, 0xf7, 0x31, 0xef, 0x12, 0xdb, + 0x0c, 0x53, 0xcd, 0x2e, 0xa1, 0x4e, 0x57, 0xe8, 0xe9, 0x82, 0x56, 0x4a, 0x19, 0x2b, 0xa1, 0xb7, + 0x1a, 0x38, 0x9f, 0x28, 0x1f, 0xba, 0x03, 0x28, 0xca, 0x12, 0xd6, 0x24, 0x63, 0x41, 0x65, 0xe4, + 0x27, 0x19, 0xc2, 0x0a, 0xa3, 0xd7, 0x60, 0x91, 0xf7, 0x87, 0x8e, 0x43, 0x79, 0x57, 0x5f, 0x2c, + 0x68, 0xa5, 0x45, 0x23, 0x3a, 0x17, 0x7f, 0x4f, 0x80, 0x7e, 0x92, 0xe8, 0x6f, 0xa9, 0xe8, 0x3e, + 0x23, 0x02, 0xc7, 0x86, 0xa5, 0x5d, 0xce, 0xb0, 0x56, 0x21, 0x1d, 0xf6, 0x9a, 0x50, 0xbd, 0x86, + 0x27, 0xf4, 0x7f, 0xc8, 0x8e, 0x98, 0xa0, 0xae, 0x63, 0x7a, 0xec, 0x67, 0xe2, 0x2b, 0x9a, 0x53, + 0x46, 0x26, 0xb0, 0x35, 0xa4, 0xe9, 0x1d, 0x83, 0x4a, 0xbd, 0xf7, 0xa0, 0xe6, 0xcf, 0x31, 0xa8, + 0xf4, 0x89, 0x41, 0xfd, 0x93, 0x86, 0x5c, 0xb5, 0xb5, 0x53, 0x23, 0x7d, 0xe2, 0x60, 0xa5, 0xcc, + 0xcf, 0x21, 0x23, 0x29, 0x26, 0xbe, 0x79, 0xae, 0x7f, 0x05, 0x04, 0xc1, 0xd2, 0x18, 0x1b, 0x6c, + 0xe2, 0x52, 0x55, 0x98, 0xfc, 0x40, 0x15, 0xfe, 0x00, 0x57, 0x3a, 0x9e, 0x19, 0xb4, 0x64, 0xf6, + 0x29, 0x97, 0x43, 0x4d, 0x5e, 0xa8, 0xaf, 0x4c, 0xc7, 0xab, 0xca, 0xce, 0x9e, 0x52, 0xae, 0xe8, + 0xe5, 0x02, 0xfb, 0x62, 0x76, 0xfe, 0x19, 0x65, 0x0b, 0x47, 0xff, 0x3f, 0x00, 0xe2, 0xda, 0xb3, + 0xda, 0x5f, 0x22, 0xae, 0x1d, 0xba, 0xd7, 0x61, 0x49, 0x30, 0x81, 0xfb, 0x26, 0xc7, 0x13, 0x9d, + 0x2f, 0x2a, 0x43, 0x13, 0xab, 0xdc, 0xf0, 0x96, 0xa6, 0x18, 0x2b, 0x85, 0x67, 0x8d, 0xa5, 0xd0, + 0xd2, 0x1a, 0x2b, 0x0d, 0x84, 0x6e, 0x36, 0x14, 0xde, 0x50, 0x98, 0xd4, 0x1e, 0xeb, 0x4b, 0x05, + 0xad, 0x94, 0x33, 0xf2, 0xa1, 0x67, 0x5f, 0x39, 0xf6, 0xec, 0x31, 0xba, 0x0f, 0x19, 0xa5, 0x8b, + 0xb0, 0x1a, 0x28, 0x7e, 0xae, 0x1e, 0x1d, 0x6f, 0x4a, 0xf6, 0x9b, 0xa1, 0xa7, 0x35, 0x36, 0x80, + 0x47, 0xbf, 0xd1, 0x8f, 0x90, 0xb3, 0x03, 0x5d, 0x30, 0xdf, 0xe4, 0xd4, 0xd1, 0x33, 0x2a, 0xeb, + 0x8b, 0xa3, 0xe3, 0xcd, 0xcf, 0xde, 0x6f, 0x7a, 0x4d, 0xea, 0xb8, 0x58, 0x0c, 0x7d, 0x62, 0x64, + 0xa3, 0x8a, 0x4d, 0xea, 0xa0, 0x03, 0xc8, 0x59, 0x6c, 0x44, 0x5c, 0xec, 0x0a, 0x09, 0xc0, 0xf5, + 0x6c, 0x21, 0x59, 0xca, 0xdc, 0xbf, 0x7b, 0x06, 0xd3, 0x3b, 0x61, 0xec, 0xb6, 0x8d, 0xbd, 0xa0, + 0x42, 0x50, 0x95, 0x1b, 0xd9, 0x49, 0x99, 0x26, 0x75, 0x38, 0xfa, 0x18, 0xae, 0x0c, 0xdd, 0x36, + 0x73, 0x6d, 0x75, 0x5b, 0x3a, 0x20, 0x7a, 0x4e, 0x8d, 0x25, 0x17, 0x59, 0x5b, 0x74, 0x40, 0xd0, + 0x37, 0x90, 0x97, 0xda, 0x18, 0xba, 0x76, 0xa4, 0x7e, 0xfd, 0x8a, 0x92, 0xda, 0xed, 0x33, 0x1a, + 0xa8, 0xb6, 0x76, 0x0e, 0x62, 0xd1, 0xc6, 0x72, 0x5b, 0x58, 0x71, 0x83, 0x44, 0xf6, 0xb0, 0x8f, + 0x07, 0xdc, 0x1c, 0x11, 0x5f, 0xad, 0xf6, 0xe5, 0x00, 0x39, 0xb0, 0x3e, 0x0f, 0x8c, 0xc5, 0xdf, + 0x52, 0xb0, 0x7c, 0xa2, 0x96, 0x54, 0x53, 0xac, 0xe9, 0x71, 0xb0, 0x9b, 0x8c, 0xcc, 0xb4, 0xe5, + 0xff, 0x90, 0x98, 0x38, 0x0f, 0x89, 0x1c, 0x6e, 0x4c, 0x49, 0x9c, 0x02, 0x48, 0x3a, 0x93, 0x17, + 0xa7, 0xf3, 0x7a, 0x54, 0xfb, 0x60, 0x52, 0x5a, 0xf2, 0xfa, 0x13, 0xac, 0xc6, 0x94, 0x33, 0x69, + 0x59, 0x62, 0xa6, 0x2e, 0x8e, 0xb9, 0x32, 0x95, 0x50, 0x58, 0x59, 0x42, 0x76, 0x60, 0x75, 0x2a, + 0xa5, 0x18, 0x22, 0xd7, 0xe7, 0x3f, 0x50, 0x53, 0x2b, 0x91, 0xa6, 0xa6, 0x30, 0x1c, 0x59, 0xb0, + 0x1e, 0xe1, 0xcc, 0x8c, 0x33, 0x58, 0x30, 0x69, 0x05, 0x76, 0xeb, 0x0c, 0xb0, 0xa8, 0xfa, 0x9e, + 0xdb, 0x61, 0x86, 0x3e, 0x29, 0x14, 0x9f, 0x9d, 0xdc, 0x2c, 0xc5, 0x26, 0xdc, 0x98, 0x2e, 0x65, + 0xe6, 0x4f, 0xb7, 0x33, 0x47, 0x8f, 0x20, 0x65, 0x93, 0x3e, 0xd7, 0xb5, 0x77, 0x02, 0xcd, 0xac, + 0x74, 0x43, 0x65, 0x14, 0xeb, 0xb0, 0x7e, 0x7a, 0xd1, 0x3d, 0xd7, 0x26, 0x63, 0x54, 0x81, 0x95, + 0xe9, 0xba, 0x31, 0xbb, 0x98, 0x77, 0x83, 0x1b, 0x49, 0xa0, 0xac, 0x71, 0x35, 0x5a, 0x3c, 0x4f, + 0x30, 0xef, 0xaa, 0x26, 0xff, 0xd0, 0x20, 0x37, 0x73, 0x21, 0xf4, 0x04, 0x12, 0x97, 0xf0, 0xa8, + 0x26, 0xbc, 0x1e, 0x7a, 0x06, 0x49, 0xa9, 0x96, 0xc4, 0xc5, 0xd5, 0x22, 0xeb, 0x14, 0x7f, 0xd1, + 0xe0, 0xe6, 0x99, 0x44, 0xcb, 0x67, 0xcb, 0x62, 0xa3, 0x4b, 0xf9, 0x1e, 0xb0, 0xd8, 0xa8, 0xd1, + 0x93, 0x7f, 0x65, 0x1c, 0xa0, 0x04, 0x0a, 0x4c, 0xa8, 0x11, 0x66, 0x70, 0x84, 0xcc, 0x8b, 0x2f, + 0x35, 0xb8, 0xd9, 0x24, 0x7d, 0x62, 0x09, 0x3a, 0x22, 0x13, 0x81, 0xed, 0xca, 0xef, 0x14, 0xd7, + 0x22, 0xe8, 0x36, 0x2c, 0x9f, 0xe0, 0x22, 0x78, 0x87, 0x8d, 0xdc, 0x0c, 0x0d, 0xa8, 0x05, 0x4b, + 0xd1, 0x03, 0x77, 0xe1, 0x37, 0x77, 0x21, 0x7c, 0xdb, 0xd0, 0x16, 0x5c, 0xf3, 0x89, 0xd4, 0xa6, + 0x4f, 0x6c, 0x33, 0xac, 0xcf, 0x7b, 0xc1, 0xba, 0x30, 0xf2, 0x91, 0xeb, 0xb1, 0x0c, 0x6f, 0xf6, + 0x3e, 0xd9, 0x85, 0x6b, 0x33, 0x72, 0x6b, 0x0a, 0x2c, 0x86, 0x1c, 0x65, 0x60, 0xa1, 0xb1, 0x5b, + 0xaf, 0xed, 0xd5, 0xbf, 0xca, 0xcf, 0x21, 0x80, 0xf4, 0xf6, 0x4e, 0x6b, 0xef, 0xf9, 0x6e, 0x5e, + 0x43, 0x59, 0x58, 0x3c, 0xa8, 0x57, 0xf7, 0xeb, 0xb5, 0xdd, 0x5a, 0x3e, 0x81, 0x16, 0x20, 0xb9, + 0x5d, 0xff, 0x2e, 0x9f, 0xac, 0xd6, 0x5f, 0xbe, 0xd9, 0xd0, 0x5e, 0xbd, 0xd9, 0xd0, 0xfe, 0x7a, + 0xb3, 0xa1, 0xfd, 0xfa, 0x76, 0x63, 0xee, 0xd5, 0xdb, 0x8d, 0xb9, 0x3f, 0xdf, 0x6e, 0xcc, 0x7d, + 0x7f, 0x8e, 0xeb, 0x8c, 0xe3, 0x9f, 0xfc, 0xea, 0x6e, 0xed, 0xb4, 0xfa, 0xe4, 0x7f, 0xf0, 0x6f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x12, 0x9b, 0x63, 0xae, 0xab, 0x0c, 0x00, 0x00, } func (m *FinalityProvider) Marshal() (dAtA []byte, err error) { @@ -1898,7 +1898,7 @@ func (m *FinalityProvider) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2077,7 +2077,7 @@ func (m *FinalityProviderWithMeta) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2290,7 +2290,7 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2361,7 +2361,7 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPkList = append(m.FpBtcPkList, v) if err := m.FpBtcPkList[len(m.FpBtcPkList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2541,7 +2541,7 @@ func (m *BTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.DelegatorSig = &v if err := m.DelegatorSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2803,7 +2803,7 @@ func (m *BTCUndelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.DelegatorUnbondingSig = &v if err := m.DelegatorUnbondingSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2838,7 +2838,7 @@ func (m *BTCUndelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.DelegatorSlashingSig = &v if err := m.DelegatorSlashingSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3157,7 +3157,7 @@ func (m *SignatureInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.Pk = &v if err := m.Pk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3192,7 +3192,7 @@ func (m *SignatureInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.Sig = &v if err := m.Sig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3277,7 +3277,7 @@ func (m *CovenantAdaptorSignatures) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.CovPk = &v if err := m.CovPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3426,7 +3426,7 @@ func (m *SelectiveSlashingEvidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/events.go b/x/btcstaking/types/events.go index 6b94d3ca2..a87dbf10e 100644 --- a/x/btcstaking/types/events.go +++ b/x/btcstaking/types/events.go @@ -1,7 +1,7 @@ package types import ( - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" ) func NewEventPowerDistUpdateWithBTCDel(ev *EventBTCDelegationStateUpdate) *EventPowerDistUpdate { diff --git a/x/btcstaking/types/events.pb.go b/x/btcstaking/types/events.pb.go index 38b23f396..c945e1f8d 100644 --- a/x/btcstaking/types/events.pb.go +++ b/x/btcstaking/types/events.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -270,7 +270,7 @@ func (*EventPowerDistUpdate) XXX_OneofWrappers() []interface{} { // is slashed // TODO: unify with existing slashing events type EventPowerDistUpdate_EventSlashedFinalityProvider struct { - Pk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=pk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"pk,omitempty"` + Pk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=pk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"pk,omitempty"` } func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) Reset() { @@ -323,36 +323,37 @@ func init() { } var fileDescriptor_74118427820fff75 = []byte{ - // 463 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x93, 0x4f, 0x6f, 0xd3, 0x40, - 0x10, 0xc5, 0x6d, 0x0b, 0xa1, 0x66, 0xcb, 0x1f, 0x61, 0x05, 0x14, 0x45, 0x60, 0x2a, 0x1f, 0x4a, - 0xc5, 0xc1, 0x6e, 0xd3, 0x0a, 0xee, 0x26, 0x0d, 0x41, 0x54, 0x28, 0xb2, 0xcb, 0x85, 0x8b, 0xb5, - 0x76, 0x26, 0xf6, 0x2a, 0x66, 0xd7, 0xca, 0x4e, 0x9c, 0xe4, 0x5b, 0xf4, 0x63, 0x71, 0xec, 0xb1, - 0xe2, 0x80, 0x50, 0xf2, 0x45, 0x90, 0x37, 0xa6, 0x44, 0x6d, 0x1c, 0x6e, 0xc9, 0xe8, 0xbd, 0xf7, - 0x7b, 0x33, 0xb6, 0x89, 0x1d, 0xd1, 0x68, 0x91, 0x09, 0xee, 0x46, 0x18, 0x4b, 0xa4, 0x63, 0xc6, - 0x13, 0xb7, 0x38, 0x71, 0xa1, 0x00, 0x8e, 0xd2, 0xc9, 0x27, 0x02, 0x85, 0xf9, 0xbc, 0xd2, 0x38, - 0xff, 0x34, 0x4e, 0x71, 0xd2, 0x6e, 0x26, 0x22, 0x11, 0x4a, 0xe1, 0x96, 0xbf, 0xd6, 0xe2, 0xf6, - 0xe1, 0xf6, 0xc0, 0x0d, 0xab, 0xd2, 0xd9, 0x01, 0x69, 0x9d, 0x97, 0x90, 0x2f, 0x30, 0xeb, 0x31, - 0x4e, 0x33, 0x86, 0x8b, 0xc1, 0x44, 0x14, 0x6c, 0x08, 0x13, 0xf3, 0x3d, 0x31, 0x46, 0x79, 0x4b, - 0x3f, 0xd0, 0x8f, 0xf6, 0x3b, 0x6f, 0x9c, 0xad, 0x74, 0xe7, 0xae, 0xc9, 0x37, 0x46, 0xb9, 0x7d, - 0xa5, 0x93, 0x57, 0x2a, 0xd5, 0xbb, 0xfc, 0xd0, 0x85, 0x0c, 0x12, 0x8a, 0x4c, 0xf0, 0x00, 0x29, - 0xc2, 0xd7, 0x7c, 0x48, 0x11, 0xcc, 0x43, 0xf2, 0xb4, 0x0a, 0x09, 0x71, 0x1e, 0xa6, 0x54, 0xa6, - 0x8a, 0xd3, 0xf0, 0x1f, 0x57, 0xe3, 0xcb, 0x79, 0x9f, 0xca, 0xd4, 0xfc, 0x48, 0x1a, 0x1c, 0x66, - 0xa1, 0x2c, 0xad, 0x2d, 0xe3, 0x40, 0x3f, 0x7a, 0xd2, 0x79, 0x5b, 0xd3, 0xe4, 0x1e, 0x6b, 0x2a, - 0xfd, 0x3d, 0x0e, 0x33, 0x85, 0xb5, 0x47, 0xe4, 0x85, 0x6a, 0x14, 0x40, 0x06, 0x31, 0xb2, 0x02, - 0x82, 0x8c, 0xca, 0x94, 0xf1, 0xc4, 0xbc, 0x20, 0x7b, 0x50, 0x56, 0xe7, 0x31, 0x54, 0xbb, 0x1e, - 0xd7, 0x10, 0xee, 0x79, 0xcf, 0x2b, 0x9f, 0x7f, 0x9b, 0x60, 0xdf, 0x18, 0xa4, 0xa9, 0x40, 0x03, - 0x31, 0x83, 0x49, 0x97, 0x49, 0xac, 0x36, 0x66, 0x84, 0xc8, 0xd2, 0x06, 0xc3, 0xf0, 0xf6, 0xa8, - 0xfd, 0x1a, 0xd0, 0xb6, 0x80, 0xf5, 0x30, 0x58, 0x47, 0xdc, 0xbd, 0x7a, 0x5f, 0xf3, 0x1b, 0x55, - 0x7a, 0x2f, 0x37, 0x13, 0xd2, 0x8c, 0x30, 0x0e, 0x87, 0x90, 0xad, 0x0f, 0x17, 0x4e, 0x55, 0x82, - 0xba, 0xdf, 0x7e, 0xe7, 0x6c, 0x17, 0xb4, 0xee, 0x81, 0xf5, 0x35, 0xff, 0x59, 0x84, 0x71, 0x17, - 0xb2, 0x8d, 0x61, 0x7b, 0x44, 0x5e, 0xee, 0x6a, 0x65, 0xf6, 0x88, 0x91, 0x8f, 0xd5, 0xae, 0x8f, - 0xbc, 0x77, 0x3f, 0x7f, 0xbd, 0xee, 0x24, 0x0c, 0xd3, 0x69, 0xe4, 0xc4, 0xe2, 0xbb, 0x5b, 0x95, - 0x88, 0x53, 0xca, 0xf8, 0xdf, 0x3f, 0x2e, 0x2e, 0x72, 0x90, 0x8e, 0xf7, 0x69, 0x70, 0x7a, 0x76, - 0x3c, 0x98, 0x46, 0x9f, 0x61, 0xe1, 0x1b, 0xf9, 0xd8, 0x7b, 0x40, 0x0c, 0x28, 0xbc, 0x8b, 0x1f, - 0x4b, 0x4b, 0xbf, 0x5e, 0x5a, 0xfa, 0xef, 0xa5, 0xa5, 0x5f, 0xad, 0x2c, 0xed, 0x7a, 0x65, 0x69, - 0x37, 0x2b, 0x4b, 0xfb, 0xf6, 0xdf, 0xdc, 0xf9, 0xe6, 0x67, 0xa0, 0x20, 0xd1, 0x43, 0xf5, 0xfe, - 0x9f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xc4, 0x7d, 0x08, 0x7a, 0x03, 0x00, 0x00, + // 466 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0xcd, 0x6e, 0xd3, 0x40, + 0x14, 0x85, 0x6d, 0x0b, 0xa1, 0x66, 0xca, 0x8f, 0xb0, 0x02, 0x8a, 0x22, 0x30, 0x95, 0x17, 0xa5, + 0x42, 0xc2, 0x6e, 0xd3, 0x48, 0xb0, 0x36, 0x69, 0x31, 0x02, 0x55, 0x91, 0x5d, 0x36, 0x6c, 0xac, + 0x19, 0xe7, 0xc6, 0x1e, 0xc5, 0xcc, 0x58, 0x99, 0x89, 0x93, 0xbc, 0x45, 0x1f, 0x8b, 0x65, 0x97, + 0xa8, 0x0b, 0x84, 0x92, 0x17, 0x41, 0x9e, 0x0c, 0x25, 0x6a, 0x93, 0xaa, 0xbb, 0xe4, 0xea, 0x9c, + 0xf3, 0x9d, 0x7b, 0xad, 0x41, 0x2e, 0xc1, 0x64, 0x5e, 0x70, 0xe6, 0x13, 0x99, 0x0a, 0x89, 0x47, + 0x94, 0x65, 0x7e, 0x75, 0xe4, 0x43, 0x05, 0x4c, 0x0a, 0xaf, 0x1c, 0x73, 0xc9, 0xed, 0xe7, 0x5a, + 0xe3, 0xfd, 0xd7, 0x78, 0xd5, 0x51, 0xbb, 0x99, 0xf1, 0x8c, 0x2b, 0x85, 0x5f, 0xff, 0x5a, 0x89, + 0xdb, 0xfb, 0x9b, 0x03, 0xd7, 0xac, 0x4a, 0xe7, 0xc6, 0xa8, 0x75, 0x52, 0x43, 0xce, 0x60, 0x7a, + 0x4a, 0x19, 0x2e, 0xa8, 0x9c, 0xf7, 0xc7, 0xbc, 0xa2, 0x03, 0x18, 0xdb, 0xef, 0x91, 0x35, 0x2c, + 0x5b, 0xe6, 0x9e, 0x79, 0xb0, 0xdb, 0x79, 0xe3, 0x6d, 0xa4, 0x7b, 0x37, 0x4d, 0x91, 0x35, 0x2c, + 0xdd, 0x0b, 0x13, 0xbd, 0x52, 0xa9, 0xc1, 0xf9, 0xc7, 0x1e, 0x14, 0x90, 0x61, 0x49, 0x39, 0x8b, + 0x25, 0x96, 0xf0, 0xad, 0x1c, 0x60, 0x09, 0xf6, 0x3e, 0x7a, 0xaa, 0x43, 0x12, 0x39, 0x4b, 0x72, + 0x2c, 0x72, 0xc5, 0x69, 0x44, 0x8f, 0xf5, 0xf8, 0x7c, 0x16, 0x62, 0x91, 0xdb, 0x9f, 0x50, 0x83, + 0xc1, 0x34, 0x11, 0xb5, 0xb5, 0x65, 0xed, 0x99, 0x07, 0x4f, 0x3a, 0x6f, 0xb7, 0x34, 0xb9, 0xc5, + 0x9a, 0x88, 0x68, 0x87, 0xc1, 0x54, 0x61, 0xdd, 0x21, 0x7a, 0xa1, 0x1a, 0xc5, 0x50, 0x40, 0x2a, + 0x69, 0x05, 0x71, 0x81, 0x45, 0x4e, 0x59, 0x66, 0x7f, 0x45, 0x3b, 0x50, 0x57, 0x67, 0x29, 0xe8, + 0x5d, 0x0f, 0xb7, 0x10, 0x6e, 0x79, 0x4f, 0xb4, 0x2f, 0xba, 0x4e, 0x70, 0xaf, 0x2c, 0xd4, 0x54, + 0xa0, 0x3e, 0x9f, 0xc2, 0xb8, 0x47, 0x85, 0xd4, 0x1b, 0x53, 0x84, 0x44, 0x6d, 0x83, 0x41, 0x72, + 0x7d, 0xd4, 0x70, 0x0b, 0x68, 0x53, 0xc0, 0x6a, 0x18, 0xaf, 0x22, 0x6e, 0x5e, 0x3d, 0x34, 0xa2, + 0x86, 0x4e, 0x3f, 0x2d, 0xed, 0x0c, 0x35, 0x89, 0x4c, 0x93, 0x01, 0x14, 0xab, 0xc3, 0x25, 0x13, + 0x95, 0xa0, 0xee, 0xb7, 0xdb, 0xe9, 0xde, 0x05, 0xdd, 0xf6, 0xc1, 0x42, 0x23, 0x7a, 0x46, 0x64, + 0xda, 0x83, 0x62, 0x6d, 0xd8, 0xce, 0xd1, 0xcb, 0xbb, 0x5a, 0xd9, 0x21, 0xb2, 0xca, 0x91, 0xda, + 0xf5, 0x51, 0xf0, 0xe1, 0xea, 0xf7, 0xeb, 0x6e, 0x46, 0x65, 0x3e, 0x21, 0x5e, 0xca, 0x7f, 0xf8, + 0xba, 0x44, 0x81, 0x89, 0x78, 0x47, 0xf9, 0xbf, 0xbf, 0xbe, 0x9c, 0x97, 0x20, 0xbc, 0xe0, 0x73, + 0xff, 0xb8, 0x7b, 0xd8, 0x9f, 0x90, 0x2f, 0x30, 0x8f, 0xac, 0x72, 0x14, 0x3c, 0x40, 0x16, 0x54, + 0xc1, 0xd9, 0xcf, 0x85, 0x63, 0x5e, 0x2e, 0x1c, 0xf3, 0xcf, 0xc2, 0x31, 0x2f, 0x96, 0x8e, 0x71, + 0xb9, 0x74, 0x8c, 0x5f, 0x4b, 0xc7, 0xf8, 0x7e, 0x8f, 0xe4, 0xd9, 0xfa, 0x53, 0x50, 0x18, 0xf2, + 0x50, 0xbd, 0x81, 0xe3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x5a, 0xe3, 0x63, 0x7e, 0x03, + 0x00, 0x00, } func (m *EventNewFinalityProvider) Marshal() (dAtA []byte, err error) { @@ -1128,7 +1129,7 @@ func (m *EventPowerDistUpdate_EventSlashedFinalityProvider) Unmarshal(dAtA []byt if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.Pk = &v if err := m.Pk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/expected_keepers.go b/x/btcstaking/types/expected_keepers.go index c36571416..237879011 100644 --- a/x/btcstaking/types/expected_keepers.go +++ b/x/btcstaking/types/expected_keepers.go @@ -4,10 +4,10 @@ import ( "context" "math/big" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + etypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) type BTCLightClientKeeper interface { diff --git a/x/btcstaking/types/genesis.pb.go b/x/btcstaking/types/genesis.pb.go index 087dcb664..3994319ac 100644 --- a/x/btcstaking/types/genesis.pb.go +++ b/x/btcstaking/types/genesis.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -140,7 +140,7 @@ type VotingPowerFP struct { // block_height is the height of the block the voting power was stored. BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` // fp_btc_pk the finality provider btc public key. - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // voting_power is the power of the finality provider at this specific block height. VotingPower uint64 `protobuf:"varint,3,opt,name=voting_power,json=votingPower,proto3" json:"voting_power,omitempty"` } @@ -307,9 +307,9 @@ type BTCDelegator struct { // idx the btc delegator index. Idx *BTCDelegatorDelegationIndex `protobuf:"bytes,1,opt,name=idx,proto3" json:"idx,omitempty"` // fp_btc_pk the finality provider btc public key. - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // del_btc_pk the delegator btc public key. - DelBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=del_btc_pk,json=delBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"del_btc_pk,omitempty"` + DelBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=del_btc_pk,json=delBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"del_btc_pk,omitempty"` } func (m *BTCDelegator) Reset() { *m = BTCDelegator{} } @@ -431,50 +431,50 @@ func init() { var fileDescriptor_85d7b95fa5620238 = []byte{ // 694 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0xdd, 0x4e, 0xd4, 0x4e, - 0x18, 0xc6, 0x29, 0xbb, 0x2c, 0xfc, 0x67, 0x97, 0x05, 0x86, 0xbf, 0x49, 0x43, 0xc2, 0x0a, 0xc5, - 0x8f, 0x8d, 0x26, 0x5d, 0x59, 0xd0, 0xc4, 0x43, 0xcb, 0x8a, 0xe2, 0x47, 0xd2, 0xd4, 0x95, 0x03, - 0x4e, 0x9a, 0x4e, 0x3b, 0xdb, 0x9d, 0x6c, 0x99, 0x69, 0x3a, 0x43, 0x65, 0xaf, 0xc1, 0x13, 0x0f, - 0xbd, 0x05, 0xef, 0xc4, 0x43, 0x0e, 0x8d, 0x07, 0xc6, 0xc0, 0x1d, 0x78, 0x01, 0xc6, 0x74, 0x5a, - 0x68, 0xc1, 0x5d, 0xc0, 0x18, 0xcf, 0x3a, 0x93, 0xe7, 0xfd, 0xcd, 0xfb, 0xbc, 0xf3, 0x4c, 0x0a, - 0xd6, 0x90, 0x83, 0x86, 0x01, 0xa3, 0x2d, 0x24, 0x5c, 0x2e, 0x9c, 0x01, 0xa1, 0x7e, 0x2b, 0x5e, - 0x6f, 0xf9, 0x98, 0x62, 0x4e, 0xb8, 0x1e, 0x46, 0x4c, 0x30, 0x78, 0x23, 0x13, 0xe9, 0xb9, 0x48, - 0x8f, 0xd7, 0x97, 0xfe, 0xf7, 0x99, 0xcf, 0xa4, 0xa2, 0x95, 0x7c, 0xa5, 0xe2, 0x25, 0x6d, 0x34, - 0x31, 0x74, 0x22, 0x67, 0x3f, 0x03, 0x2e, 0xdd, 0x19, 0xad, 0x29, 0xe0, 0x53, 0xdd, 0xed, 0xd1, - 0x3a, 0x42, 0x5d, 0x4c, 0x05, 0x89, 0xf1, 0xe5, 0x47, 0xe2, 0x18, 0x53, 0x91, 0x1d, 0xa9, 0xfd, - 0x28, 0x83, 0xda, 0xb3, 0xd4, 0xd5, 0x1b, 0xe1, 0x08, 0x0c, 0x1f, 0x82, 0x4a, 0xda, 0x93, 0xaa, - 0xac, 0x94, 0x9a, 0xd5, 0xf6, 0xb2, 0x3e, 0xd2, 0xa5, 0x6e, 0x4a, 0x91, 0x95, 0x89, 0xe1, 0x2e, - 0x80, 0x3d, 0x42, 0x9d, 0x80, 0x88, 0xa1, 0x1d, 0x46, 0x2c, 0x26, 0x1e, 0x8e, 0xb8, 0x3a, 0x29, - 0x11, 0x77, 0xc7, 0x20, 0xb6, 0xb3, 0x02, 0x33, 0xd3, 0x5b, 0x0b, 0xbd, 0x0b, 0x3b, 0x1c, 0xbe, - 0x06, 0x73, 0x48, 0xb8, 0xb6, 0x87, 0x03, 0xec, 0x3b, 0x82, 0x30, 0xca, 0xd5, 0x92, 0x84, 0xde, - 0x1a, 0x03, 0x35, 0xba, 0x5b, 0x9d, 0x33, 0xb1, 0x55, 0x47, 0xc2, 0xcd, 0x97, 0x1c, 0xee, 0x80, - 0xd9, 0x98, 0x09, 0x42, 0x7d, 0x3b, 0x64, 0xef, 0x92, 0x0e, 0xcb, 0x97, 0xc2, 0x76, 0xa5, 0xd6, - 0x4c, 0xa4, 0xdb, 0xa6, 0x55, 0x8b, 0xf3, 0x25, 0x87, 0x7b, 0x60, 0x11, 0x05, 0xcc, 0x1d, 0xd8, - 0x7d, 0x4c, 0xfc, 0xbe, 0xb0, 0xdd, 0xbe, 0x43, 0x28, 0x57, 0xa7, 0x24, 0xf0, 0xde, 0xb8, 0xee, - 0x92, 0x8a, 0xe7, 0xb2, 0xc0, 0x40, 0xb4, 0xcb, 0x0c, 0xe1, 0x5a, 0x0b, 0x28, 0xdf, 0xdc, 0x92, - 0x10, 0xf8, 0x02, 0xd4, 0x0b, 0xae, 0x59, 0xc4, 0xd5, 0x8a, 0xc4, 0xae, 0x5d, 0x69, 0x9a, 0x45, - 0xd6, 0x6c, 0xee, 0x99, 0x45, 0x1c, 0x3e, 0x06, 0x95, 0xf4, 0xc6, 0xd5, 0x69, 0xc9, 0x58, 0x1d, - 0xc3, 0x78, 0x9a, 0x88, 0x76, 0xa8, 0x87, 0x0f, 0xad, 0xac, 0x00, 0xee, 0x82, 0x5a, 0x1c, 0xda, - 0x1e, 0x17, 0xb6, 0xeb, 0xb8, 0x7d, 0xac, 0xce, 0x48, 0xc0, 0xe6, 0xd5, 0xc3, 0xea, 0x10, 0x2e, - 0xb6, 0x92, 0x12, 0x23, 0xc8, 0x8c, 0x59, 0x20, 0x0e, 0x3b, 0xd9, 0xa6, 0xf6, 0x49, 0x01, 0xb3, - 0xe7, 0x46, 0x0b, 0x57, 0x41, 0xad, 0x38, 0x4c, 0x55, 0x59, 0x51, 0x9a, 0x65, 0xab, 0x5a, 0x98, - 0x0c, 0xb4, 0xc0, 0x7f, 0xbd, 0xd0, 0x4e, 0xc6, 0x12, 0x0e, 0xd4, 0xc9, 0x15, 0xa5, 0x59, 0x33, - 0x1e, 0x7d, 0xfd, 0x76, 0xb3, 0xed, 0x13, 0xd1, 0x3f, 0x40, 0xba, 0xcb, 0xf6, 0x5b, 0x59, 0x5f, - 0xf2, 0x26, 0x4e, 0x17, 0x2d, 0x31, 0x0c, 0x31, 0xd7, 0x8d, 0x1d, 0x73, 0x63, 0xf3, 0x81, 0x79, - 0x80, 0x5e, 0xe2, 0xa1, 0x35, 0xdd, 0x0b, 0x0d, 0xe1, 0x9a, 0x83, 0xe4, 0xd8, 0x62, 0x1c, 0xd4, - 0x52, 0x7a, 0x6c, 0xe1, 0x9e, 0xb5, 0x8f, 0x0a, 0x58, 0xbe, 0xd4, 0xd9, 0x75, 0x7a, 0xef, 0x82, - 0xb9, 0x64, 0x90, 0x84, 0x8b, 0x88, 0xa0, 0x83, 0x24, 0x8a, 0xd2, 0x41, 0xb5, 0x7d, 0xff, 0x0f, - 0x66, 0x69, 0xd5, 0xe3, 0xb0, 0x53, 0x40, 0x68, 0x04, 0x2c, 0x8e, 0xc8, 0x13, 0x6c, 0x82, 0xf9, - 0x73, 0xc1, 0x44, 0x88, 0x66, 0x3d, 0xd5, 0xd1, 0x39, 0xf9, 0xef, 0x4a, 0xe1, 0xca, 0xbe, 0x2e, - 0x28, 0x85, 0xab, 0xfd, 0x54, 0x40, 0xad, 0x18, 0x32, 0xd8, 0x01, 0x25, 0xe2, 0x1d, 0x4a, 0x6e, - 0xb5, 0xdd, 0xbe, 0x46, 0x2c, 0xf3, 0x57, 0x98, 0x66, 0x2c, 0x29, 0xff, 0x27, 0x77, 0xda, 0x05, - 0xc0, 0xc3, 0xc1, 0x29, 0xb4, 0xf4, 0x57, 0xd0, 0x19, 0x0f, 0x07, 0x92, 0xaa, 0xbd, 0x57, 0x00, - 0xc8, 0x5f, 0x08, 0x9c, 0xcf, 0xed, 0x97, 0x53, 0x2b, 0xd7, 0x9e, 0x25, 0x7c, 0x02, 0xa6, 0xe4, - 0xfb, 0x92, 0xbd, 0x8d, 0x8f, 0x80, 0x3c, 0xed, 0x2c, 0x01, 0x6f, 0x43, 0xcf, 0x11, 0xd8, 0x4a, - 0x2b, 0x8d, 0x57, 0x9f, 0x8f, 0x1b, 0xca, 0xd1, 0x71, 0x43, 0xf9, 0x7e, 0xdc, 0x50, 0x3e, 0x9c, - 0x34, 0x26, 0x8e, 0x4e, 0x1a, 0x13, 0x5f, 0x4e, 0x1a, 0x13, 0x7b, 0x57, 0xba, 0x3c, 0x2c, 0xfe, - 0x0d, 0xa4, 0x65, 0x54, 0x91, 0xbf, 0x82, 0x8d, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x75, 0xe9, - 0x80, 0x92, 0xf5, 0x06, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x95, 0x4f, 0x4f, 0xd4, 0x40, + 0x18, 0xc6, 0x29, 0xbb, 0x2c, 0x38, 0xbb, 0x2c, 0x30, 0x68, 0xd2, 0x90, 0xb0, 0xc2, 0xe2, 0x9f, + 0x8d, 0xc6, 0xae, 0x2c, 0x98, 0xe8, 0xd1, 0xb2, 0xa2, 0x68, 0x34, 0x4d, 0xc5, 0x3d, 0x70, 0x69, + 0x3a, 0xed, 0x6c, 0x77, 0xb2, 0x65, 0xa6, 0xe9, 0x0c, 0x95, 0xbd, 0x7a, 0xf5, 0xe2, 0xd1, 0xef, + 0xe0, 0x17, 0xf1, 0xc8, 0xd1, 0x78, 0x30, 0x06, 0xbe, 0x81, 0x9f, 0xc0, 0x74, 0x5a, 0x68, 0xc1, + 0x5d, 0x58, 0x63, 0xbc, 0x75, 0x26, 0xcf, 0xfb, 0x9b, 0xf7, 0x79, 0xe7, 0x99, 0x14, 0xac, 0x21, + 0x1b, 0x0d, 0x7c, 0x46, 0x9b, 0x48, 0x38, 0x5c, 0xd8, 0x7d, 0x42, 0xbd, 0x66, 0xb4, 0xde, 0xf4, + 0x30, 0xc5, 0x9c, 0x70, 0x2d, 0x08, 0x99, 0x60, 0xf0, 0x46, 0x2a, 0xd2, 0x32, 0x91, 0x16, 0xad, + 0x2f, 0x5d, 0xf7, 0x98, 0xc7, 0xa4, 0xa2, 0x19, 0x7f, 0x25, 0xe2, 0xa5, 0xfa, 0x70, 0x62, 0x60, + 0x87, 0xf6, 0x7e, 0x0a, 0x5c, 0xba, 0x33, 0x5c, 0x93, 0xc3, 0x27, 0xba, 0xdb, 0xc3, 0x75, 0x84, + 0x3a, 0x98, 0x0a, 0x12, 0xe1, 0xcb, 0x8f, 0xc4, 0x11, 0xa6, 0x22, 0x3d, 0xb2, 0xfe, 0xab, 0x08, + 0x2a, 0xcf, 0x13, 0x57, 0x6f, 0x85, 0x2d, 0x30, 0x7c, 0x04, 0x4a, 0x49, 0x4f, 0xaa, 0xb2, 0x52, + 0x68, 0x94, 0x5b, 0xcb, 0xda, 0x50, 0x97, 0x9a, 0x21, 0x45, 0x66, 0x2a, 0x86, 0x1d, 0x00, 0xbb, + 0x84, 0xda, 0x3e, 0x11, 0x03, 0x2b, 0x08, 0x59, 0x44, 0x5c, 0x1c, 0x72, 0x75, 0x52, 0x22, 0xee, + 0x8e, 0x40, 0x6c, 0xa7, 0x05, 0x46, 0xaa, 0x37, 0x17, 0xba, 0x17, 0x76, 0x38, 0x7c, 0x0d, 0xe6, + 0x90, 0x70, 0x2c, 0x17, 0xfb, 0xd8, 0xb3, 0x05, 0x61, 0x94, 0xab, 0x05, 0x09, 0xbd, 0x35, 0x02, + 0xaa, 0xef, 0x6e, 0xb5, 0xcf, 0xc4, 0x66, 0x15, 0x09, 0x27, 0x5b, 0x72, 0xb8, 0x03, 0x66, 0x23, + 0x26, 0x08, 0xf5, 0xac, 0x80, 0xbd, 0x8f, 0x3b, 0x2c, 0x5e, 0x0a, 0xeb, 0x48, 0xad, 0x11, 0x4b, + 0xb7, 0x0d, 0xb3, 0x12, 0x65, 0x4b, 0x0e, 0xf7, 0xc0, 0x22, 0xf2, 0x99, 0xd3, 0xb7, 0x7a, 0x98, + 0x78, 0x3d, 0x61, 0x39, 0x3d, 0x9b, 0x50, 0xae, 0x4e, 0x49, 0xe0, 0xbd, 0x51, 0xdd, 0xc5, 0x15, + 0x2f, 0x64, 0x81, 0x8e, 0xe8, 0x2e, 0xd3, 0x85, 0x63, 0x2e, 0xa0, 0x6c, 0x73, 0x4b, 0x42, 0xe0, + 0x4b, 0x50, 0xcd, 0xb9, 0x66, 0x21, 0x57, 0x4b, 0x12, 0xbb, 0x76, 0xa5, 0x69, 0x16, 0x9a, 0xb3, + 0x99, 0x67, 0x16, 0x72, 0xf8, 0x04, 0x94, 0x92, 0x1b, 0x57, 0xa7, 0x25, 0x63, 0x75, 0x04, 0xe3, + 0x59, 0x2c, 0xda, 0xa1, 0x2e, 0x3e, 0x34, 0xd3, 0x02, 0xd8, 0x01, 0x95, 0x28, 0xb0, 0x5c, 0x2e, + 0x2c, 0xc7, 0x76, 0x7a, 0x58, 0x9d, 0x91, 0x80, 0xcd, 0xab, 0x87, 0xd5, 0x26, 0x5c, 0x6c, 0xc5, + 0x25, 0xba, 0x9f, 0x1a, 0x33, 0x41, 0x14, 0xb4, 0xd3, 0xcd, 0xfa, 0x17, 0x05, 0xcc, 0x9e, 0x1b, + 0x2d, 0x5c, 0x05, 0x95, 0xfc, 0x30, 0x55, 0x65, 0x45, 0x69, 0x14, 0xcd, 0x72, 0x6e, 0x32, 0x70, + 0x17, 0x5c, 0xeb, 0x06, 0x56, 0x3c, 0x96, 0xa0, 0xaf, 0x4e, 0xae, 0x28, 0x8d, 0x8a, 0xfe, 0xf8, + 0xfb, 0x8f, 0x9b, 0x9b, 0x1e, 0x11, 0xbd, 0x03, 0xa4, 0x39, 0x6c, 0xbf, 0x99, 0xf6, 0xe5, 0xdb, + 0x88, 0x3f, 0x20, 0xec, 0x74, 0xd9, 0x14, 0x83, 0x00, 0x73, 0x4d, 0xdf, 0x31, 0x36, 0x36, 0x1f, + 0x1a, 0x07, 0xe8, 0x15, 0x1e, 0x98, 0xd3, 0xdd, 0x40, 0x17, 0x8e, 0xd1, 0x8f, 0x0f, 0xce, 0x07, + 0x42, 0x2d, 0x24, 0x07, 0xe7, 0x6e, 0xba, 0xfe, 0x59, 0x01, 0xcb, 0x97, 0x7a, 0x1b, 0xaf, 0xfb, + 0xb9, 0x78, 0x94, 0x84, 0x8b, 0x90, 0xa0, 0x83, 0x38, 0x8c, 0xd2, 0x43, 0xb9, 0x75, 0xff, 0x2f, + 0xa6, 0x69, 0x56, 0xa3, 0xa0, 0x9d, 0x43, 0xd4, 0x09, 0x58, 0x1c, 0x92, 0x28, 0xd8, 0x00, 0xf3, + 0xe7, 0xa2, 0x89, 0x10, 0x4d, 0x7b, 0xaa, 0xa2, 0x73, 0xf2, 0x3f, 0x95, 0xc2, 0x91, 0x7d, 0x5d, + 0x50, 0x0a, 0xa7, 0xfe, 0x61, 0x12, 0x54, 0xf2, 0x31, 0x83, 0x6d, 0x50, 0x20, 0xee, 0xa1, 0xe4, + 0x96, 0x5b, 0xad, 0x31, 0x82, 0x99, 0xbd, 0xc3, 0x24, 0x65, 0x71, 0xf9, 0x7f, 0xba, 0xd5, 0x0e, + 0x00, 0x2e, 0xf6, 0x4f, 0xb1, 0x85, 0x7f, 0xc4, 0xce, 0xb8, 0xd8, 0x97, 0xdc, 0xfa, 0x47, 0x05, + 0x80, 0xec, 0x9d, 0xc0, 0xf9, 0x6c, 0x04, 0xc5, 0xc4, 0xce, 0xd8, 0xf3, 0x84, 0x4f, 0xc1, 0x94, + 0x7c, 0x65, 0xb2, 0xbb, 0xd1, 0x31, 0x90, 0xa7, 0x9d, 0xa5, 0xe0, 0x5d, 0xe0, 0xda, 0x02, 0x9b, + 0x49, 0xa5, 0xfe, 0xe6, 0xeb, 0x71, 0x4d, 0x39, 0x3a, 0xae, 0x29, 0x3f, 0x8f, 0x6b, 0xca, 0xa7, + 0x93, 0xda, 0xc4, 0xd1, 0x49, 0x6d, 0xe2, 0xdb, 0x49, 0x6d, 0x62, 0x6f, 0x0c, 0x9f, 0x87, 0xf9, + 0xbf, 0x82, 0x34, 0x8d, 0x4a, 0xf2, 0x97, 0xb0, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x9a, 0xc8, + 0x8f, 0x84, 0xfd, 0x06, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -1397,7 +1397,7 @@ func (m *VotingPowerFP) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1730,7 +1730,7 @@ func (m *BTCDelegator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1765,7 +1765,7 @@ func (m *BTCDelegator) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.DelBtcPk = &v if err := m.DelBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/genesis_test.go b/x/btcstaking/types/genesis_test.go index 6de9bc033..8e1720227 100644 --- a/x/btcstaking/types/genesis_test.go +++ b/x/btcstaking/types/genesis_test.go @@ -5,7 +5,7 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" "github.com/stretchr/testify/require" ) diff --git a/x/btcstaking/types/hooks.go b/x/btcstaking/types/hooks.go index 450ef8c26..89307fe1e 100644 --- a/x/btcstaking/types/hooks.go +++ b/x/btcstaking/types/hooks.go @@ -3,7 +3,7 @@ package types import ( "context" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" ) // combine multiple BTC staking hooks, all hook functions are run in array sequence diff --git a/x/btcstaking/types/incentive.pb.go b/x/btcstaking/types/incentive.pb.go index 4eba382f5..e1234e074 100644 --- a/x/btcstaking/types/incentive.pb.go +++ b/x/btcstaking/types/incentive.pb.go @@ -6,7 +6,7 @@ package types import ( cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -85,7 +85,7 @@ func (m *VotingPowerDistCache) GetFinalityProviders() []*FinalityProviderDistInf type FinalityProviderDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // addr is the address to receive commission from delegations. Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` // commission defines the commission rate of finality provider @@ -154,7 +154,7 @@ func (m *FinalityProviderDistInfo) GetBtcDels() []*BTCDelDistInfo { type BTCDelDistInfo struct { // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // staker_addr is the address to receive rewards from BTC delegation. StakerAddr string `protobuf:"bytes,2,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // staking_tx_hash is the staking tx hash of the BTC delegation @@ -228,39 +228,39 @@ func init() { } var fileDescriptor_ac354c3bd6d7a66b = []byte{ - // 502 bytes of a gzipped FileDescriptorProto + // 504 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4f, 0x6f, 0xd3, 0x30, 0x18, 0xc6, 0x9b, 0xae, 0x1b, 0xe0, 0x8e, 0x7f, 0x56, 0x91, 0xc2, 0x90, 0xb2, 0x52, 0x69, 0xa8, - 0x87, 0x35, 0x61, 0x1b, 0x42, 0xe2, 0x06, 0x59, 0x84, 0x98, 0xd8, 0xa4, 0x28, 0x4c, 0x1c, 0x38, - 0x10, 0x39, 0x8e, 0x9b, 0x58, 0x4d, 0xec, 0x2a, 0xf6, 0x42, 0xf3, 0x2d, 0xf8, 0x10, 0x7c, 0x84, - 0x7d, 0x08, 0x8e, 0xd3, 0x0e, 0x08, 0xed, 0x30, 0xa1, 0x56, 0x7c, 0x0f, 0x14, 0x27, 0xb0, 0x82, - 0x5a, 0xc1, 0x81, 0x9b, 0xed, 0xe7, 0x79, 0xfd, 0xbe, 0xcf, 0x4f, 0x7a, 0xc1, 0x56, 0x80, 0x82, - 0x22, 0xe1, 0xcc, 0x0a, 0x24, 0x16, 0x12, 0x8d, 0x28, 0x8b, 0xac, 0x7c, 0xc7, 0xa2, 0x0c, 0x13, - 0x26, 0x69, 0x4e, 0xcc, 0x71, 0xc6, 0x25, 0x87, 0xf7, 0x6a, 0x9b, 0x79, 0x65, 0x33, 0xf3, 0x9d, - 0x8d, 0x4e, 0xc4, 0x23, 0xae, 0x1c, 0x56, 0x79, 0xaa, 0xcc, 0x1b, 0xf7, 0x31, 0x17, 0x29, 0x17, - 0x7e, 0x25, 0x54, 0x97, 0x4a, 0xea, 0x7d, 0xd2, 0x40, 0xe7, 0x2d, 0x97, 0x94, 0x45, 0x2e, 0xff, - 0x40, 0x32, 0x87, 0x0a, 0xb9, 0x8f, 0x70, 0x4c, 0xe0, 0x36, 0x80, 0x92, 0x4b, 0x94, 0xf8, 0xb9, - 0x52, 0xfd, 0x71, 0x29, 0xeb, 0x5a, 0x57, 0xeb, 0xb7, 0xbc, 0x3b, 0x4a, 0x99, 0x2b, 0x83, 0xef, - 0x01, 0x1c, 0x52, 0x86, 0x12, 0x2a, 0x8b, 0xb2, 0x4b, 0x4e, 0x43, 0x92, 0x09, 0xbd, 0xd9, 0x5d, - 0xe9, 0xb7, 0x77, 0x2d, 0x73, 0xe1, 0xac, 0xe6, 0xcb, 0xba, 0xc0, 0xad, 0xfd, 0x65, 0xef, 0x03, - 0x36, 0xe4, 0xde, 0xdd, 0xe1, 0x1f, 0x8a, 0xe8, 0x7d, 0x69, 0x02, 0x7d, 0x99, 0x1f, 0x1e, 0x81, - 0xb5, 0x40, 0x62, 0x7f, 0x3c, 0x52, 0xe3, 0xad, 0xdb, 0x4f, 0x2f, 0x2e, 0x37, 0x77, 0x23, 0x2a, - 0xe3, 0x93, 0xc0, 0xc4, 0x3c, 0xb5, 0xea, 0xf6, 0x38, 0x46, 0x94, 0xfd, 0xbc, 0x58, 0xb2, 0x18, - 0x13, 0x61, 0xda, 0x07, 0xee, 0xde, 0x93, 0xc7, 0xee, 0x49, 0xf0, 0x9a, 0x14, 0xde, 0x6a, 0x20, - 0xb1, 0x3b, 0x82, 0xdb, 0xa0, 0x85, 0xc2, 0x30, 0xd3, 0x9b, 0x5d, 0xad, 0x7f, 0xc3, 0xd6, 0xcf, - 0x4f, 0x07, 0x9d, 0x1a, 0xd9, 0x8b, 0x30, 0xcc, 0x88, 0x10, 0x6f, 0x64, 0x46, 0x59, 0xe4, 0x29, - 0x17, 0x3c, 0x02, 0x00, 0xf3, 0x34, 0xa5, 0x42, 0x50, 0xce, 0xf4, 0x15, 0x55, 0x33, 0xb8, 0xb8, - 0xdc, 0x7c, 0x50, 0xd5, 0x88, 0x70, 0x64, 0x52, 0x6e, 0xa5, 0x48, 0xc6, 0xe6, 0x21, 0x89, 0x10, - 0x2e, 0x1c, 0x82, 0xcf, 0x4f, 0x07, 0xa0, 0xfe, 0xd2, 0x21, 0xd8, 0x9b, 0xfb, 0x60, 0x09, 0xf6, - 0xd6, 0x12, 0xec, 0xcf, 0xc1, 0xf5, 0x32, 0x79, 0x48, 0x12, 0xa1, 0xaf, 0x2a, 0xd8, 0x5b, 0x4b, - 0x60, 0xdb, 0xc7, 0xfb, 0x0e, 0x49, 0x7e, 0x21, 0xbe, 0x16, 0x48, 0xec, 0x90, 0x44, 0xf4, 0xbe, - 0x6b, 0xe0, 0xd6, 0xef, 0xda, 0xff, 0xc6, 0xf9, 0x0c, 0xb4, 0xcb, 0x39, 0x48, 0xe6, 0xff, 0x13, - 0x55, 0x50, 0x99, 0xcb, 0x47, 0xf8, 0x08, 0xdc, 0xae, 0x23, 0xf8, 0x72, 0xe2, 0xc7, 0x48, 0xc4, - 0x15, 0x60, 0xef, 0x66, 0xfd, 0x7c, 0x3c, 0x79, 0x85, 0x44, 0x0c, 0x1f, 0x82, 0xf5, 0x05, 0xb8, - 0xda, 0xf9, 0x15, 0x29, 0xfb, 0xf0, 0xf3, 0xd4, 0xd0, 0xce, 0xa6, 0x86, 0xf6, 0x6d, 0x6a, 0x68, - 0x1f, 0x67, 0x46, 0xe3, 0x6c, 0x66, 0x34, 0xbe, 0xce, 0x8c, 0xc6, 0xbb, 0xbf, 0x46, 0x9b, 0xcc, - 0xaf, 0xa2, 0xca, 0x19, 0xac, 0xa9, 0xe5, 0xd9, 0xfb, 0x11, 0x00, 0x00, 0xff, 0xff, 0x42, 0x6b, - 0x62, 0xab, 0xad, 0x03, 0x00, 0x00, + 0x87, 0x35, 0x61, 0x6c, 0x07, 0xb8, 0x41, 0x16, 0x21, 0x26, 0xfe, 0x45, 0x61, 0xe2, 0xc0, 0x81, + 0xc8, 0x76, 0xdc, 0xc4, 0x6a, 0x12, 0x57, 0xb1, 0x17, 0x9a, 0x6f, 0xc1, 0x87, 0xe0, 0x23, 0xec, + 0x43, 0x70, 0x9c, 0x76, 0x9a, 0x76, 0x98, 0x50, 0x7b, 0xe0, 0x6b, 0xa0, 0x38, 0x81, 0x15, 0xb4, + 0x4a, 0x3d, 0x70, 0xb3, 0xfd, 0x3c, 0xaf, 0xdf, 0xf7, 0xf9, 0x49, 0x2f, 0xd8, 0xc2, 0x08, 0x17, + 0x31, 0x4f, 0x2d, 0x2c, 0x89, 0x90, 0x68, 0xc4, 0xd2, 0xd0, 0xca, 0x77, 0x2c, 0x96, 0x12, 0x9a, + 0x4a, 0x96, 0x53, 0x73, 0x9c, 0x71, 0xc9, 0xe1, 0xbd, 0xda, 0x66, 0x5e, 0xda, 0xcc, 0x7c, 0x67, + 0xa3, 0x13, 0xf2, 0x90, 0x2b, 0x87, 0x55, 0x9e, 0x2a, 0xf3, 0xc6, 0x7d, 0xc2, 0x45, 0xc2, 0x85, + 0x5f, 0x09, 0xd5, 0xa5, 0x92, 0x7a, 0xdf, 0x34, 0xd0, 0xf9, 0xc8, 0x25, 0x4b, 0x43, 0x97, 0x7f, + 0xa1, 0x99, 0xc3, 0x84, 0xdc, 0x47, 0x24, 0xa2, 0x70, 0x1b, 0x40, 0xc9, 0x25, 0x8a, 0xfd, 0x5c, + 0xa9, 0xfe, 0xb8, 0x94, 0x75, 0xad, 0xab, 0xf5, 0x5b, 0xde, 0x1d, 0xa5, 0xcc, 0x95, 0xc1, 0xcf, + 0x00, 0x0e, 0x59, 0x8a, 0x62, 0x26, 0x8b, 0xb2, 0x4b, 0xce, 0x02, 0x9a, 0x09, 0xbd, 0xd9, 0x5d, + 0xe9, 0xb7, 0x9f, 0x58, 0xe6, 0x95, 0xb3, 0x9a, 0x2f, 0xeb, 0x02, 0xb7, 0xf6, 0x97, 0xbd, 0x0f, + 0xd2, 0x21, 0xf7, 0xee, 0x0e, 0xff, 0x51, 0x44, 0xef, 0xac, 0x09, 0xf4, 0x45, 0x7e, 0xf8, 0x1e, + 0xac, 0x61, 0x49, 0xfc, 0xf1, 0x48, 0x8d, 0xb7, 0x6e, 0x3f, 0x3d, 0xbf, 0xd8, 0xdc, 0x0b, 0x99, + 0x8c, 0x8e, 0xb0, 0x49, 0x78, 0x62, 0xd5, 0xed, 0x63, 0x84, 0xc5, 0x80, 0xf1, 0xdf, 0x57, 0x4b, + 0x16, 0x63, 0x2a, 0x4c, 0xfb, 0xc0, 0xdd, 0xdd, 0x7b, 0xec, 0x1e, 0xe1, 0xd7, 0xb4, 0xf0, 0x56, + 0xb1, 0x24, 0xee, 0x08, 0x6e, 0x83, 0x16, 0x0a, 0x82, 0x4c, 0x6f, 0x76, 0xb5, 0xfe, 0x0d, 0x5b, + 0x3f, 0x3d, 0x1e, 0x74, 0x6a, 0x68, 0x2f, 0x82, 0x20, 0xa3, 0x42, 0x7c, 0x90, 0x19, 0x4b, 0x43, + 0x4f, 0xb9, 0xe0, 0x5b, 0x00, 0x08, 0x4f, 0x12, 0x26, 0x04, 0xe3, 0xa9, 0xbe, 0xa2, 0x6a, 0x06, + 0xe7, 0x17, 0x9b, 0x0f, 0xaa, 0x1a, 0x11, 0x8c, 0x4c, 0xc6, 0xad, 0x04, 0xc9, 0xc8, 0x7c, 0x43, + 0x43, 0x44, 0x0a, 0x87, 0x92, 0xd3, 0xe3, 0x01, 0xa8, 0xbf, 0x74, 0x28, 0xf1, 0xe6, 0x3e, 0x58, + 0x00, 0xbe, 0xb5, 0x00, 0xfc, 0x73, 0x70, 0xbd, 0xcc, 0x1e, 0xd0, 0x58, 0xe8, 0xab, 0x0a, 0xf7, + 0xd6, 0x02, 0xdc, 0xf6, 0xe1, 0xbe, 0x43, 0xe3, 0x3f, 0x90, 0xaf, 0x61, 0x49, 0x1c, 0x1a, 0x8b, + 0xde, 0x4f, 0x0d, 0xdc, 0xfa, 0x5b, 0xfb, 0xff, 0x40, 0x9f, 0x81, 0x76, 0x39, 0x09, 0xcd, 0xfc, + 0xa5, 0xb8, 0x82, 0xca, 0x5c, 0x3e, 0xc2, 0x47, 0xe0, 0x76, 0x1d, 0xc2, 0x97, 0x13, 0x3f, 0x42, + 0x22, 0xaa, 0x10, 0x7b, 0x37, 0xeb, 0xe7, 0xc3, 0xc9, 0x2b, 0x24, 0x22, 0xf8, 0x10, 0xac, 0x5f, + 0x01, 0xac, 0x9d, 0x5f, 0xb2, 0xb2, 0xdf, 0x7d, 0x9f, 0x1a, 0xda, 0xc9, 0xd4, 0xd0, 0x7e, 0x4c, + 0x0d, 0xed, 0xeb, 0xcc, 0x68, 0x9c, 0xcc, 0x8c, 0xc6, 0xd9, 0xcc, 0x68, 0x7c, 0x5a, 0x22, 0xdc, + 0x64, 0x7e, 0x21, 0x55, 0x52, 0xbc, 0xa6, 0x56, 0x68, 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x84, 0x61, 0x20, 0xde, 0xb3, 0x03, 0x00, 0x00, } func (m *VotingPowerDistCache) Marshal() (dAtA []byte, err error) { @@ -682,7 +682,7 @@ func (m *FinalityProviderDistInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -888,7 +888,7 @@ func (m *BTCDelDistInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/mocked_keepers.go b/x/btcstaking/types/mocked_keepers.go index e3a42ecb0..d68d89080 100644 --- a/x/btcstaking/types/mocked_keepers.go +++ b/x/btcstaking/types/mocked_keepers.go @@ -9,10 +9,10 @@ import ( big "math/big" reflect "reflect" - types "github.com/babylonchain/babylon/types" - types0 "github.com/babylonchain/babylon/x/btccheckpoint/types" - types1 "github.com/babylonchain/babylon/x/btclightclient/types" - types2 "github.com/babylonchain/babylon/x/epoching/types" + types "github.com/babylonlabs-io/babylon/types" + types0 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + types1 "github.com/babylonlabs-io/babylon/x/btclightclient/types" + types2 "github.com/babylonlabs-io/babylon/x/epoching/types" gomock "github.com/golang/mock/gomock" ) diff --git a/x/btcstaking/types/msg.go b/x/btcstaking/types/msg.go index 8abc851e5..e7e3efe46 100644 --- a/x/btcstaking/types/msg.go +++ b/x/btcstaking/types/msg.go @@ -4,8 +4,8 @@ import ( "fmt" math "math" - "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/chaincfg/chainhash" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/btcstaking/types/msg_test.go b/x/btcstaking/types/msg_test.go index c6f66678a..ba69fd302 100644 --- a/x/btcstaking/types/msg_test.go +++ b/x/btcstaking/types/msg_test.go @@ -6,9 +6,9 @@ import ( "testing" "cosmossdk.io/errors" - "github.com/babylonchain/babylon/testutil/datagen" - bbntypes "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbntypes "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stktypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" diff --git a/x/btcstaking/types/params.go b/x/btcstaking/types/params.go index cd1835a46..f3fc1fd92 100644 --- a/x/btcstaking/types/params.go +++ b/x/btcstaking/types/params.go @@ -5,8 +5,8 @@ import ( "math" sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg" diff --git a/x/btcstaking/types/params.pb.go b/x/btcstaking/types/params.pb.go index a8ccd45f3..097fff47a 100644 --- a/x/btcstaking/types/params.pb.go +++ b/x/btcstaking/types/params.pb.go @@ -6,7 +6,7 @@ package types import ( cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -30,7 +30,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Params struct { // covenant_pks is the list of public keys held by the covenant committee // each PK follows encoding in BIP-340 spec on Bitcoin - CovenantPks []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,rep,name=covenant_pks,json=covenantPks,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"covenant_pks,omitempty"` + CovenantPks []github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,rep,name=covenant_pks,json=covenantPks,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"covenant_pks,omitempty"` // covenant_quorum is the minimum number of signatures needed for the covenant // multisignature CovenantQuorum uint32 `protobuf:"varint,2,opt,name=covenant_quorum,json=covenantQuorum,proto3" json:"covenant_quorum,omitempty"` @@ -192,40 +192,40 @@ func init() { var fileDescriptor_8d1392776a3e15b9 = []byte{ // 547 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0x8d, 0xbf, 0xe4, 0x4b, 0xe9, 0x34, 0xa5, 0x65, 0x00, 0x61, 0x82, 0xea, 0x44, 0x61, 0x41, - 0x90, 0xc0, 0x26, 0x6d, 0xc5, 0x02, 0x56, 0x09, 0xa8, 0x12, 0xa2, 0x8b, 0xe0, 0x14, 0x24, 0xd8, - 0x8c, 0xc6, 0xf6, 0xd4, 0x19, 0x25, 0x33, 0x13, 0x3c, 0x13, 0xcb, 0x7e, 0x0b, 0x96, 0x2c, 0x79, - 0x08, 0x1e, 0xa2, 0xcb, 0x8a, 0x15, 0xea, 0x22, 0x42, 0xc9, 0x1b, 0xf0, 0x04, 0xc8, 0x63, 0x3b, - 0xfc, 0x08, 0x09, 0xc4, 0xce, 0xf7, 0xdc, 0x73, 0xcf, 0xfd, 0xf1, 0x19, 0xd0, 0xf1, 0xb0, 0x97, - 0x4e, 0x05, 0x77, 0x3c, 0xe5, 0x4b, 0x85, 0x27, 0x94, 0x87, 0x4e, 0xdc, 0x73, 0x66, 0x38, 0xc2, - 0x4c, 0xda, 0xb3, 0x48, 0x28, 0x01, 0xaf, 0x17, 0x1c, 0xfb, 0x3b, 0xc7, 0x8e, 0x7b, 0xcd, 0x6b, - 0xa1, 0x08, 0x85, 0x66, 0x38, 0xd9, 0x57, 0x4e, 0x6e, 0xde, 0xf4, 0x85, 0x64, 0x42, 0xa2, 0x3c, - 0x91, 0x07, 0x79, 0xaa, 0xf3, 0xb5, 0x06, 0xea, 0x43, 0x2d, 0x0c, 0x5f, 0x83, 0x86, 0x2f, 0x62, - 0xc2, 0x31, 0x57, 0x68, 0x36, 0x91, 0xa6, 0xd1, 0xae, 0x76, 0x1b, 0x83, 0x87, 0x17, 0x8b, 0xd6, - 0x7e, 0x48, 0xd5, 0x78, 0xee, 0xd9, 0xbe, 0x60, 0x4e, 0xd1, 0xd7, 0x1f, 0x63, 0xca, 0xcb, 0xc0, - 0x51, 0xe9, 0x8c, 0x48, 0x7b, 0xf0, 0x6c, 0x78, 0x70, 0xf8, 0x60, 0x38, 0xf7, 0x9e, 0x93, 0xd4, - 0xdd, 0x2a, 0xb5, 0x86, 0x13, 0x09, 0xef, 0x80, 0x9d, 0xb5, 0xf4, 0xdb, 0xb9, 0x88, 0xe6, 0xcc, - 0xfc, 0xaf, 0x6d, 0x74, 0xb7, 0xdd, 0xcb, 0x25, 0xfc, 0x42, 0xa3, 0xf0, 0x2e, 0xd8, 0x95, 0x53, - 0x2c, 0xc7, 0x94, 0x87, 0x08, 0x07, 0x41, 0x44, 0xa4, 0x34, 0xab, 0x6d, 0xa3, 0xbb, 0xe9, 0xee, - 0x94, 0x78, 0x3f, 0x87, 0xe1, 0x21, 0xb8, 0xc1, 0x28, 0x47, 0x6b, 0xba, 0x4a, 0xd0, 0x29, 0x21, - 0x48, 0x62, 0x65, 0xd6, 0xda, 0x46, 0xb7, 0xea, 0x5e, 0x65, 0x94, 0x8f, 0x8a, 0xec, 0x49, 0x72, - 0x44, 0xc8, 0x08, 0x2b, 0x38, 0x02, 0x19, 0x8c, 0x7c, 0xc1, 0x18, 0x95, 0x92, 0x0a, 0x8e, 0x22, - 0xac, 0x88, 0xf9, 0x7f, 0xd6, 0x63, 0x70, 0xfb, 0x6c, 0xd1, 0xaa, 0x5c, 0x2c, 0x5a, 0xb7, 0xf2, - 0x13, 0xc9, 0x60, 0x62, 0x53, 0xe1, 0x30, 0xac, 0xc6, 0xf6, 0x31, 0x09, 0xb1, 0x9f, 0x3e, 0x25, - 0xbe, 0x7b, 0x85, 0x51, 0xfe, 0x64, 0x5d, 0xee, 0x62, 0x45, 0xe0, 0x2b, 0xb0, 0xbd, 0x1e, 0x43, - 0xcb, 0xd5, 0xb5, 0x5c, 0xef, 0x2f, 0xe4, 0x3e, 0x7d, 0xbc, 0x0f, 0x8a, 0x1f, 0x92, 0x89, 0x37, - 0x4a, 0x1d, 0xad, 0xdb, 0x07, 0x7b, 0x0c, 0x27, 0x08, 0xfb, 0x8a, 0xc6, 0x04, 0x9d, 0x52, 0x8e, - 0xa7, 0x54, 0xa5, 0xd9, 0x6f, 0x8c, 0x69, 0x40, 0x22, 0x69, 0x6e, 0xe8, 0x23, 0x36, 0x19, 0x4e, - 0xfa, 0x9a, 0x73, 0x54, 0x50, 0x86, 0x25, 0x03, 0xde, 0x03, 0x30, 0xdb, 0x77, 0xce, 0x3d, 0xc1, - 0x03, 0x7d, 0x26, 0xca, 0x88, 0x79, 0x49, 0xd7, 0xed, 0x32, 0xca, 0x5f, 0x96, 0x89, 0x13, 0xca, - 0x08, 0x44, 0xbf, 0xb2, 0xf5, 0x36, 0x9b, 0xff, 0xba, 0xcd, 0x4f, 0x0d, 0xb2, 0x8d, 0x1e, 0xd5, - 0xde, 0x7f, 0x68, 0x55, 0x3a, 0x04, 0x34, 0x46, 0x4a, 0x44, 0x24, 0x28, 0x9c, 0x67, 0x82, 0x8d, - 0x98, 0x44, 0xd9, 0x39, 0x4d, 0x43, 0x4f, 0x56, 0x86, 0xf0, 0x31, 0xa8, 0xe7, 0xb6, 0xd7, 0x7e, - 0xd9, 0xda, 0xdf, 0xb3, 0x7f, 0xeb, 0x7b, 0x3b, 0x17, 0x1a, 0xd4, 0xb2, 0x19, 0xdd, 0xa2, 0x64, - 0x70, 0x7c, 0xb6, 0xb4, 0x8c, 0xf3, 0xa5, 0x65, 0x7c, 0x59, 0x5a, 0xc6, 0xbb, 0x95, 0x55, 0x39, - 0x5f, 0x59, 0x95, 0xcf, 0x2b, 0xab, 0xf2, 0xe6, 0x8f, 0x86, 0x4e, 0x7e, 0x7c, 0x7b, 0xda, 0xdd, - 0x5e, 0x5d, 0x3f, 0x98, 0x83, 0x6f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6f, 0x91, 0xdb, 0xb2, 0x9e, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x53, 0xcb, 0x6e, 0xd3, 0x40, + 0x14, 0x8d, 0x49, 0x48, 0xe9, 0x34, 0xa5, 0x65, 0x00, 0x61, 0x82, 0xea, 0x44, 0x61, 0x41, 0x90, + 0xa8, 0x4d, 0x68, 0x16, 0x08, 0x56, 0x09, 0xa8, 0x12, 0x02, 0xa1, 0xe0, 0x14, 0x16, 0xb0, 0x18, + 0x8d, 0xed, 0xa9, 0x33, 0x4a, 0x66, 0x26, 0x78, 0x26, 0x56, 0xfc, 0x17, 0x2c, 0x59, 0xf2, 0x11, + 0x7c, 0x44, 0x97, 0x15, 0x2b, 0xd4, 0x45, 0x84, 0x92, 0x5f, 0xe0, 0x03, 0x90, 0xc7, 0x76, 0x78, + 0x88, 0x45, 0xd5, 0x9d, 0xef, 0xb9, 0xe7, 0x9e, 0xfb, 0xf0, 0x19, 0xd0, 0xf2, 0xb0, 0x97, 0x4c, + 0x04, 0x77, 0x3c, 0xe5, 0x4b, 0x85, 0xc7, 0x94, 0x87, 0x4e, 0xdc, 0x71, 0xa6, 0x38, 0xc2, 0x4c, + 0xda, 0xd3, 0x48, 0x28, 0x01, 0x6f, 0xe6, 0x1c, 0xfb, 0x37, 0xc7, 0x8e, 0x3b, 0xf5, 0x1b, 0xa1, + 0x08, 0x85, 0x66, 0x38, 0xe9, 0x57, 0x46, 0xae, 0xdf, 0xf6, 0x85, 0x64, 0x42, 0xa2, 0x2c, 0x91, + 0x05, 0x59, 0xaa, 0xf5, 0xb3, 0x02, 0xaa, 0x03, 0x2d, 0x0c, 0x3f, 0x80, 0x9a, 0x2f, 0x62, 0xc2, + 0x31, 0x57, 0x68, 0x3a, 0x96, 0xa6, 0xd1, 0x2c, 0xb7, 0x6b, 0xfd, 0xc7, 0x67, 0x8b, 0x46, 0x37, + 0xa4, 0x6a, 0x34, 0xf3, 0x6c, 0x5f, 0x30, 0x27, 0xef, 0x3b, 0xc1, 0x9e, 0xdc, 0xa7, 0xa2, 0x08, + 0x1d, 0x95, 0x4c, 0x89, 0xb4, 0xfb, 0x2f, 0x06, 0x07, 0xdd, 0x87, 0x83, 0x99, 0xf7, 0x92, 0x24, + 0xee, 0x56, 0xa1, 0x36, 0x18, 0x4b, 0x78, 0x0f, 0xec, 0xac, 0xc5, 0x3f, 0xce, 0x44, 0x34, 0x63, + 0xe6, 0xa5, 0xa6, 0xd1, 0xde, 0x76, 0xaf, 0x16, 0xf0, 0x1b, 0x8d, 0xc2, 0xfb, 0x60, 0x57, 0x4e, + 0xb0, 0x1c, 0x51, 0x1e, 0x22, 0x1c, 0x04, 0x11, 0x91, 0xd2, 0x2c, 0x37, 0x8d, 0xf6, 0xa6, 0xbb, + 0x53, 0xe0, 0xbd, 0x0c, 0x86, 0x5d, 0x70, 0x8b, 0x51, 0x8e, 0xd6, 0x74, 0x35, 0x47, 0xc7, 0x84, + 0x20, 0x89, 0x95, 0x59, 0x69, 0x1a, 0xed, 0xb2, 0x7b, 0x9d, 0x51, 0x3e, 0xcc, 0xb3, 0x47, 0xf3, + 0x43, 0x42, 0x86, 0x58, 0xc1, 0x21, 0x48, 0x61, 0xe4, 0x0b, 0xc6, 0xa8, 0x94, 0x54, 0x70, 0x14, + 0x61, 0x45, 0xcc, 0xcb, 0x69, 0x8f, 0xfe, 0xdd, 0x93, 0x45, 0xa3, 0x74, 0xb6, 0x68, 0xdc, 0xc9, + 0x8e, 0x24, 0x83, 0xb1, 0x4d, 0x85, 0xc3, 0xb0, 0x1a, 0xd9, 0xaf, 0x48, 0x88, 0xfd, 0xe4, 0x39, + 0xf1, 0xdd, 0x6b, 0x8c, 0xf2, 0x67, 0xeb, 0x72, 0x17, 0x2b, 0x02, 0xdf, 0x81, 0xed, 0xf5, 0x18, + 0x5a, 0xae, 0xaa, 0xe5, 0x3a, 0xe7, 0x90, 0xfb, 0xf6, 0x75, 0x1f, 0xe4, 0xbf, 0x24, 0x15, 0xaf, + 0x15, 0x3a, 0x5a, 0xb7, 0x07, 0xf6, 0x18, 0x9e, 0x23, 0xec, 0x2b, 0x1a, 0x13, 0x74, 0x4c, 0x39, + 0x9e, 0x50, 0x95, 0xa4, 0x3f, 0x32, 0xa6, 0x01, 0x89, 0xa4, 0xb9, 0xa1, 0x8f, 0x58, 0x67, 0x78, + 0xde, 0xd3, 0x9c, 0xc3, 0x9c, 0x32, 0x28, 0x18, 0xf0, 0x01, 0x80, 0xe9, 0xbe, 0x33, 0xee, 0x09, + 0x1e, 0xe8, 0x33, 0x51, 0x46, 0xcc, 0x2b, 0xba, 0x6e, 0x97, 0x51, 0xfe, 0xb6, 0x48, 0x1c, 0x51, + 0x46, 0x20, 0xfa, 0x97, 0xad, 0xb7, 0xd9, 0xbc, 0xe8, 0x36, 0x7f, 0x35, 0x48, 0x37, 0x7a, 0x52, + 0xf9, 0xfc, 0xa5, 0x51, 0x6a, 0x11, 0x50, 0x1b, 0x2a, 0x11, 0x91, 0x20, 0xf7, 0x9e, 0x09, 0x36, + 0x62, 0x12, 0xa5, 0xe7, 0x34, 0x0d, 0x3d, 0x59, 0x11, 0xc2, 0xa7, 0xa0, 0x9a, 0x19, 0x5f, 0xfb, + 0x65, 0xeb, 0xd1, 0x9e, 0xfd, 0x5f, 0xe7, 0xdb, 0x99, 0x50, 0xbf, 0x92, 0xce, 0xe8, 0xe6, 0x25, + 0xfd, 0xd7, 0x27, 0x4b, 0xcb, 0x38, 0x5d, 0x5a, 0xc6, 0x8f, 0xa5, 0x65, 0x7c, 0x5a, 0x59, 0xa5, + 0xd3, 0x95, 0x55, 0xfa, 0xbe, 0xb2, 0x4a, 0xef, 0xcf, 0x61, 0xe9, 0xf9, 0x9f, 0xef, 0x4f, 0xfb, + 0xdb, 0xab, 0xea, 0x47, 0x73, 0xf0, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x60, 0x31, 0x6e, 0xa0, 0xa2, 0x03, 0x00, 0x00, } @@ -487,7 +487,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.CovenantPks = append(m.CovenantPks, v) if err := m.CovenantPks[len(m.CovenantPks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/pop.go b/x/btcstaking/types/pop.go index dd5a562ae..004b31ca1 100644 --- a/x/btcstaking/types/pop.go +++ b/x/btcstaking/types/pop.go @@ -5,9 +5,9 @@ import ( "encoding/hex" "fmt" - "github.com/babylonchain/babylon/crypto/bip322" - "github.com/babylonchain/babylon/crypto/ecdsa" - bbn "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/crypto/bip322" + "github.com/babylonlabs-io/babylon/crypto/ecdsa" + bbn "github.com/babylonlabs-io/babylon/types" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/btcutil" diff --git a/x/btcstaking/types/pop.pb.go b/x/btcstaking/types/pop.pb.go index 32bfca102..f0d4519ef 100644 --- a/x/btcstaking/types/pop.pb.go +++ b/x/btcstaking/types/pop.pb.go @@ -178,25 +178,25 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/pop.proto", fileDescriptor_9d6ceb088d9e9f3a) } var fileDescriptor_9d6ceb088d9e9f3a = []byte{ - // 285 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4b, 0xc3, 0x30, - 0x1c, 0xc5, 0x9b, 0x89, 0x1b, 0xfb, 0x33, 0xa4, 0x04, 0xc5, 0x9d, 0xe2, 0xdc, 0x69, 0x78, 0x48, - 0x5c, 0x26, 0x78, 0xb6, 0xd5, 0x83, 0x20, 0x38, 0xd6, 0x9e, 0xbc, 0x8c, 0xa6, 0xeb, 0xba, 0xa0, - 0x36, 0xa5, 0x89, 0xc3, 0x7e, 0x0b, 0x3f, 0x96, 0xc7, 0x1d, 0x3d, 0x4a, 0xfb, 0x45, 0xa4, 0xb3, - 0xa5, 0x1e, 0xbc, 0xbd, 0x47, 0x5e, 0xde, 0xe3, 0xff, 0x83, 0x33, 0x11, 0x88, 0xfc, 0x45, 0x25, - 0x4c, 0x98, 0x50, 0x9b, 0xe0, 0x59, 0x26, 0x31, 0xdb, 0x4e, 0x59, 0xaa, 0x52, 0x9a, 0x66, 0xca, - 0x28, 0x7c, 0x52, 0x07, 0x68, 0x1b, 0xa0, 0xdb, 0xe9, 0xd8, 0xc0, 0xf1, 0x3c, 0x53, 0x6a, 0xfd, - 0xb8, 0x9e, 0x2b, 0xad, 0x23, 0xad, 0xa5, 0x4a, 0x1c, 0xdf, 0xc5, 0x2e, 0x0c, 0x84, 0x09, 0x97, - 0x5a, 0xc6, 0x4b, 0x93, 0xa7, 0xd1, 0x10, 0x8d, 0xd0, 0xe4, 0x88, 0x9f, 0xd3, 0x7f, 0x5b, 0xa8, - 0xe3, 0xbb, 0x9e, 0x8c, 0xfd, 0x3c, 0x8d, 0x16, 0x20, 0x4c, 0x58, 0x6b, 0x7c, 0x0a, 0xbd, 0xba, - 0x64, 0xd8, 0x19, 0xa1, 0xc9, 0x60, 0xd1, 0xfd, 0x7d, 0x1c, 0x5f, 0x43, 0xdf, 0xb9, 0x9f, 0xcf, - 0x38, 0xf7, 0x64, 0x8c, 0x87, 0xd0, 0x0b, 0x56, 0xab, 0x2c, 0xd2, 0x7a, 0xbf, 0xd2, 0x5f, 0x34, - 0x16, 0xdb, 0x70, 0xd0, 0xfe, 0xad, 0xe4, 0x05, 0x03, 0x68, 0xb7, 0x30, 0x40, 0xb7, 0xaa, 0xb9, - 0xba, 0xb4, 0xad, 0x46, 0x73, 0x6e, 0x23, 0xdc, 0x87, 0xc3, 0x3b, 0xf7, 0xd6, 0xbb, 0xb1, 0x3b, - 0xce, 0xc3, 0x67, 0x41, 0xd0, 0xae, 0x20, 0xe8, 0xbb, 0x20, 0xe8, 0xa3, 0x24, 0xd6, 0xae, 0x24, - 0xd6, 0x57, 0x49, 0xac, 0x27, 0x1e, 0x4b, 0xb3, 0x79, 0x13, 0x34, 0x54, 0xaf, 0xac, 0xbe, 0x2a, - 0xdc, 0x04, 0x32, 0x69, 0x0c, 0x7b, 0xff, 0xcb, 0xb2, 0x82, 0xa0, 0x45, 0x77, 0xcf, 0x72, 0xf6, - 0x13, 0x00, 0x00, 0xff, 0xff, 0x0d, 0x31, 0xf3, 0x97, 0x6e, 0x01, 0x00, 0x00, + // 287 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x31, 0x4b, 0xc3, 0x40, + 0x1c, 0xc5, 0x73, 0x15, 0x5b, 0xfa, 0xa7, 0x48, 0x38, 0x14, 0x3b, 0x9d, 0xb5, 0x53, 0x11, 0xbc, + 0xb3, 0x69, 0xc1, 0xd9, 0x44, 0x07, 0x17, 0x2d, 0x49, 0x26, 0x97, 0x92, 0x4b, 0xd3, 0x78, 0x58, + 0x73, 0x21, 0x77, 0x16, 0xf3, 0x2d, 0xfc, 0x58, 0x8e, 0x1d, 0x1d, 0x25, 0xf9, 0x22, 0x92, 0x9a, + 0x10, 0x07, 0xb7, 0xf7, 0xb8, 0x77, 0xef, 0xf1, 0xff, 0xc1, 0x19, 0x0f, 0x78, 0xbe, 0x91, 0x09, + 0xe3, 0x3a, 0x54, 0x3a, 0x78, 0x11, 0x49, 0xcc, 0xb6, 0x53, 0x96, 0xca, 0x94, 0xa6, 0x99, 0xd4, + 0x12, 0x9f, 0xd4, 0x01, 0xda, 0x06, 0xe8, 0x76, 0x3a, 0xd6, 0x70, 0xbc, 0xc8, 0xa4, 0x5c, 0x3f, + 0xae, 0x17, 0x52, 0xa9, 0x48, 0x29, 0x21, 0x13, 0xdb, 0x77, 0xb0, 0x03, 0x03, 0xae, 0xc3, 0xa5, + 0x12, 0xf1, 0x52, 0xe7, 0x69, 0x34, 0x44, 0x23, 0x34, 0x39, 0xb2, 0xce, 0xe9, 0xbf, 0x2d, 0xd4, + 0xf6, 0x1d, 0x4f, 0xc4, 0x7e, 0x9e, 0x46, 0x2e, 0x70, 0x1d, 0xd6, 0x1a, 0x9f, 0x42, 0xaf, 0x2e, + 0x19, 0x76, 0x46, 0x68, 0x32, 0x70, 0xbb, 0xbf, 0x8f, 0xe3, 0x6b, 0xe8, 0xdb, 0xf7, 0x8b, 0x99, + 0x65, 0x79, 0x22, 0xc6, 0x43, 0xe8, 0x05, 0xab, 0x55, 0x16, 0x29, 0xb5, 0x5f, 0xe9, 0xbb, 0x8d, + 0xc5, 0x26, 0x1c, 0xb4, 0x7f, 0x2b, 0x79, 0xc1, 0x00, 0xda, 0x2d, 0x0c, 0xd0, 0xad, 0x6a, 0xe6, + 0x57, 0xa6, 0xd1, 0x68, 0xcb, 0x32, 0x11, 0xee, 0xc3, 0xe1, 0x9d, 0x73, 0xeb, 0xdd, 0x98, 0x1d, + 0xfb, 0xe1, 0xb3, 0x20, 0x68, 0x57, 0x10, 0xf4, 0x5d, 0x10, 0xf4, 0x51, 0x12, 0x63, 0x57, 0x12, + 0xe3, 0xab, 0x24, 0xc6, 0xd3, 0x3c, 0x16, 0xfa, 0xf9, 0x8d, 0xd3, 0x50, 0xbe, 0xb2, 0xfa, 0xaa, + 0x4d, 0xc0, 0xd5, 0xa5, 0x90, 0x8d, 0x65, 0xef, 0x7f, 0x69, 0x56, 0x18, 0x14, 0xef, 0xee, 0x69, + 0xce, 0x7e, 0x02, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xd5, 0x14, 0x5e, 0x70, 0x01, 0x00, 0x00, } func (m *ProofOfPossessionBTC) Marshal() (dAtA []byte, err error) { diff --git a/x/btcstaking/types/pop_test.go b/x/btcstaking/types/pop_test.go index dc58f6dfd..86bd8ceff 100644 --- a/x/btcstaking/types/pop_test.go +++ b/x/btcstaking/types/pop_test.go @@ -11,9 +11,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/testutil/datagen" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) var ( diff --git a/x/btcstaking/types/query.pb.go b/x/btcstaking/types/query.pb.go index 369f69ab9..dc710bb9f 100644 --- a/x/btcstaking/types/query.pb.go +++ b/x/btcstaking/types/query.pb.go @@ -7,7 +7,7 @@ import ( context "context" cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/cosmos-proto" query "github.com/cosmos/cosmos-sdk/types/query" types "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -1159,10 +1159,10 @@ type BTCDelegationResponse struct { StakerAddr string `protobuf:"bytes,1,opt,name=staker_addr,json=stakerAddr,proto3" json:"staker_addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this BTC delegation // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // fp_btc_pk_list is the list of BIP-340 PKs of the finality providers that // this BTC delegation delegates to - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` + FpBtcPkList []github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,3,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` // start_height is the start BTC height of the BTC delegation // it is the start BTC height of the timelock StartHeight uint64 `protobuf:"varint,4,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` @@ -1488,7 +1488,7 @@ type FinalityProviderResponse struct { Addr string `protobuf:"bytes,3,opt,name=addr,proto3" json:"addr,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of the BTC_PK by the fp addr. // Essentially is the signature where the BTC SK sigs the fp addr. Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` @@ -1629,125 +1629,126 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/query.proto", fileDescriptor_74d49d26f7429697) } var fileDescriptor_74d49d26f7429697 = []byte{ - // 1884 bytes of a gzipped FileDescriptorProto + // 1889 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x59, 0x4b, 0x6c, 0xdb, 0xc8, 0x19, 0x0e, 0x6d, 0x45, 0xb1, 0x7f, 0xd9, 0x8e, 0x33, 0xeb, 0x24, 0x8c, 0x1c, 0xdb, 0x09, 0x9b, - 0x4d, 0x9c, 0x97, 0x18, 0x2b, 0xde, 0x14, 0xed, 0x76, 0x37, 0xb1, 0xec, 0xdd, 0x24, 0xbb, 0x31, - 0xa2, 0xd2, 0x49, 0x0b, 0x74, 0x8b, 0x12, 0x14, 0x39, 0xa2, 0x88, 0xc8, 0x24, 0xc3, 0x19, 0xb9, - 0x32, 0x02, 0x5f, 0x7a, 0xe8, 0xad, 0x40, 0x81, 0xf6, 0xda, 0xf3, 0x16, 0xe8, 0xb1, 0x39, 0x15, - 0xe8, 0x7d, 0x7b, 0x5b, 0x64, 0x0f, 0x2d, 0xf6, 0x10, 0x14, 0x49, 0xd1, 0x02, 0x05, 0x7a, 0xed, - 0xb9, 0xe0, 0xcc, 0x50, 0xa4, 0x24, 0x52, 0x0f, 0xc7, 0xbd, 0x89, 0x33, 0xff, 0xfb, 0xf1, 0xcd, - 0xcc, 0x2f, 0xb8, 0x58, 0x33, 0x6a, 0xfb, 0x4d, 0xcf, 0x55, 0x6b, 0xd4, 0x24, 0xd4, 0x78, 0xe6, - 0xb8, 0xb6, 0xba, 0xb7, 0xa6, 0x3e, 0x6f, 0xe1, 0x60, 0xbf, 0xe4, 0x07, 0x1e, 0xf5, 0xd0, 0x69, - 0x41, 0x52, 0x8a, 0x49, 0x4a, 0x7b, 0x6b, 0xc5, 0x05, 0xdb, 0xb3, 0x3d, 0x46, 0xa1, 0x86, 0xbf, - 0x38, 0x71, 0xf1, 0xbc, 0xed, 0x79, 0x76, 0x13, 0xab, 0x86, 0xef, 0xa8, 0x86, 0xeb, 0x7a, 0xd4, - 0xa0, 0x8e, 0xe7, 0x12, 0xb1, 0x7b, 0xce, 0xf4, 0xc8, 0xae, 0x47, 0x74, 0xce, 0xc6, 0x3f, 0xc4, - 0xd6, 0x25, 0xfe, 0xa5, 0xc6, 0x46, 0xd4, 0x30, 0x35, 0xd6, 0xa2, 0x6f, 0x41, 0x75, 0x4d, 0x50, - 0xd5, 0x0c, 0x82, 0xb9, 0x91, 0x1d, 0x42, 0xdf, 0xb0, 0x1d, 0x97, 0x69, 0x13, 0xb4, 0x4a, 0xba, - 0x6b, 0xbe, 0x11, 0x18, 0xbb, 0x91, 0xd6, 0xcb, 0xe9, 0x34, 0x09, 0x4f, 0x39, 0xdd, 0x4a, 0x86, - 0x2c, 0xcf, 0xe7, 0x04, 0xca, 0x02, 0xa0, 0x1f, 0x86, 0xe6, 0x54, 0x99, 0x74, 0x0d, 0x3f, 0x6f, - 0x61, 0x42, 0x15, 0x0d, 0xde, 0xeb, 0x5a, 0x25, 0xbe, 0xe7, 0x12, 0x8c, 0x3e, 0x84, 0x3c, 0xb7, - 0x42, 0x96, 0x2e, 0x48, 0xab, 0x85, 0xf2, 0x52, 0x29, 0x35, 0xc4, 0x25, 0xce, 0x56, 0xc9, 0x7d, - 0xf5, 0x7a, 0xe5, 0x98, 0x26, 0x58, 0x94, 0xef, 0xc2, 0x62, 0x42, 0x66, 0x65, 0xff, 0x47, 0x38, - 0x20, 0x8e, 0xe7, 0x0a, 0x95, 0x48, 0x86, 0x13, 0x7b, 0x7c, 0x85, 0x09, 0x9f, 0xd5, 0xa2, 0x4f, - 0xe5, 0x0b, 0x38, 0x9f, 0xce, 0x78, 0x14, 0x56, 0xd9, 0xb0, 0xc4, 0x84, 0x7f, 0xea, 0xb8, 0x46, - 0xd3, 0xa1, 0xfb, 0xd5, 0xc0, 0xdb, 0x73, 0x2c, 0x1c, 0x44, 0xa1, 0x40, 0x9f, 0x02, 0xc4, 0x19, - 0x12, 0x1a, 0x2e, 0x97, 0x44, 0x09, 0x84, 0xe9, 0x2c, 0xf1, 0x9a, 0x13, 0xe9, 0x2c, 0x55, 0x0d, - 0x1b, 0x0b, 0x5e, 0x2d, 0xc1, 0xa9, 0xfc, 0x45, 0x82, 0xe5, 0x2c, 0x4d, 0xc2, 0x91, 0x9f, 0x01, - 0xaa, 0x8b, 0xcd, 0xb0, 0xd2, 0xf8, 0xae, 0x2c, 0x5d, 0x98, 0x5c, 0x2d, 0x94, 0xd5, 0x0c, 0xa7, - 0x7a, 0xa5, 0x45, 0xc2, 0xb4, 0x53, 0xf5, 0x5e, 0x3d, 0xe8, 0x7e, 0x97, 0x2b, 0x13, 0xcc, 0x95, - 0x2b, 0x43, 0x5d, 0x11, 0xf2, 0x92, 0xbe, 0x6c, 0x88, 0x8c, 0xf4, 0x2b, 0xe7, 0x31, 0xbb, 0x08, - 0xb3, 0x75, 0x5f, 0xaf, 0x51, 0x53, 0xf7, 0x9f, 0xe9, 0x0d, 0xdc, 0x66, 0x61, 0x9b, 0xd6, 0xa0, - 0xee, 0x57, 0xa8, 0x59, 0x7d, 0xf6, 0x00, 0xb7, 0x95, 0x83, 0x8c, 0xb8, 0x77, 0x82, 0xf1, 0x53, - 0x38, 0xd5, 0x17, 0x0c, 0x11, 0xfe, 0xb1, 0x63, 0x31, 0xdf, 0x1b, 0x0b, 0xe5, 0xf7, 0x12, 0x14, - 0x99, 0xfe, 0xca, 0x93, 0xcd, 0x2d, 0xdc, 0xc4, 0x36, 0x6f, 0xf7, 0xc8, 0x81, 0x0a, 0xe4, 0x09, - 0x35, 0x68, 0x8b, 0x97, 0xd4, 0x5c, 0xf9, 0x5a, 0x86, 0xc6, 0x2e, 0xee, 0x1d, 0xc6, 0xa1, 0x09, - 0xce, 0x9e, 0xc2, 0x99, 0x38, 0x74, 0xe1, 0xfc, 0x59, 0x12, 0x8d, 0xd3, 0x6b, 0xaa, 0x08, 0xd4, - 0x53, 0x38, 0x19, 0x46, 0xda, 0x8a, 0xb7, 0x44, 0xc9, 0xdc, 0x18, 0xc5, 0xe8, 0x4e, 0x8c, 0xe6, - 0x6a, 0xd4, 0x4c, 0x88, 0x3f, 0xba, 0x62, 0xa9, 0xc3, 0xd5, 0xd4, 0x4c, 0x57, 0xbd, 0x9f, 0xe3, - 0x60, 0x83, 0x3e, 0xc0, 0x8e, 0xdd, 0xa0, 0xa3, 0x57, 0x0e, 0x3a, 0x03, 0xf9, 0x06, 0xe3, 0x61, - 0x46, 0xe5, 0x34, 0xf1, 0xa5, 0x3c, 0x86, 0x6b, 0xa3, 0xe8, 0x11, 0x51, 0xbb, 0x08, 0x33, 0x7b, - 0x1e, 0x75, 0x5c, 0x5b, 0xf7, 0xc3, 0x7d, 0xa6, 0x27, 0xa7, 0x15, 0xf8, 0x1a, 0x63, 0x51, 0xb6, - 0x61, 0x35, 0x55, 0xe0, 0x66, 0x2b, 0x08, 0xb0, 0x4b, 0x19, 0xd1, 0x18, 0x15, 0x9f, 0x15, 0x87, - 0x6e, 0x71, 0xc2, 0xbc, 0xd8, 0x49, 0x29, 0xe9, 0x64, 0x9f, 0xd9, 0x13, 0xfd, 0x66, 0xff, 0x4a, - 0x82, 0xeb, 0x4c, 0xd1, 0x86, 0x49, 0x9d, 0x3d, 0xdc, 0x07, 0x37, 0xbd, 0x21, 0xcf, 0x52, 0x75, - 0x54, 0xf5, 0xfb, 0x57, 0x09, 0x6e, 0x8c, 0x66, 0xcf, 0x11, 0xc2, 0xe0, 0x8f, 0x1d, 0xda, 0xd8, - 0xc6, 0xd4, 0xf8, 0xbf, 0xc2, 0xe0, 0x92, 0x68, 0x4c, 0xe6, 0x98, 0x41, 0xb1, 0xd5, 0x15, 0x58, - 0xe5, 0x8e, 0x40, 0xc9, 0xbe, 0xed, 0xc1, 0x39, 0x56, 0x7e, 0x2b, 0xc1, 0x95, 0xd4, 0x4a, 0x49, - 0x01, 0xaa, 0x11, 0xfa, 0xe5, 0xa8, 0xf2, 0xf8, 0x2f, 0x29, 0xa3, 0x1f, 0xd2, 0x40, 0x29, 0x80, - 0x73, 0x09, 0x50, 0xf2, 0x82, 0x14, 0x78, 0xba, 0x33, 0x14, 0x9e, 0xbc, 0x34, 0xd1, 0xda, 0xd9, - 0x18, 0xa8, 0xba, 0x08, 0x8e, 0x2e, 0xaf, 0x9f, 0xc1, 0xb9, 0x7e, 0xc0, 0x8d, 0x22, 0x7e, 0x13, - 0xde, 0x13, 0xc6, 0xea, 0xb4, 0xad, 0x37, 0x0c, 0xd2, 0x48, 0xc4, 0x7d, 0x5e, 0x6c, 0x3d, 0x69, - 0x3f, 0x30, 0x48, 0x23, 0xec, 0xfa, 0xe7, 0x69, 0xe7, 0x4c, 0x27, 0x4c, 0x3b, 0x30, 0xd7, 0x8d, - 0xdd, 0xe2, 0x84, 0x1b, 0x0f, 0xba, 0x67, 0xbb, 0xa0, 0x5b, 0xf9, 0x26, 0x0f, 0xa7, 0xd3, 0xd5, - 0x7d, 0x0f, 0x0a, 0xa1, 0x30, 0x1c, 0xe8, 0x86, 0x65, 0x71, 0xcc, 0x9b, 0xae, 0xc8, 0xaf, 0x5e, - 0xde, 0x5c, 0x10, 0x51, 0xda, 0xb0, 0xac, 0x00, 0x13, 0xb2, 0x43, 0x03, 0xc7, 0xb5, 0x35, 0xe0, - 0xc4, 0xe1, 0x22, 0xda, 0x86, 0x3c, 0xaf, 0x32, 0x16, 0xd8, 0x99, 0xca, 0x9d, 0x6f, 0x5f, 0xaf, - 0x94, 0x6d, 0x87, 0x36, 0x5a, 0xb5, 0x92, 0xe9, 0xed, 0xaa, 0xc2, 0x5e, 0xb3, 0x61, 0x38, 0x6e, - 0xf4, 0xa1, 0xd2, 0x7d, 0x1f, 0x93, 0x52, 0xe5, 0x61, 0xf5, 0xf6, 0xfa, 0xad, 0x6a, 0xab, 0xf6, - 0x39, 0xde, 0xd7, 0x8e, 0xd7, 0xc2, 0xba, 0x44, 0x5f, 0xc0, 0x5c, 0x5c, 0xb7, 0x4d, 0x87, 0x50, - 0x79, 0xf2, 0xc2, 0xe4, 0x3b, 0x88, 0x2d, 0x88, 0x82, 0x7f, 0xe4, 0xb0, 0xa6, 0x98, 0x21, 0xd4, - 0x08, 0xa8, 0x2e, 0xda, 0x2b, 0xc7, 0x41, 0x92, 0xad, 0xf1, 0x1e, 0x44, 0x4b, 0x00, 0xd8, 0xb5, - 0x22, 0x82, 0xe3, 0x8c, 0x60, 0x1a, 0xbb, 0xa2, 0x45, 0xd1, 0x22, 0x4c, 0x53, 0x8f, 0x1a, 0x4d, - 0x9d, 0x18, 0x54, 0xce, 0xb3, 0xdd, 0x29, 0xb6, 0xb0, 0x63, 0x50, 0x74, 0x09, 0xe6, 0x92, 0x15, - 0x80, 0xdb, 0xf2, 0x09, 0x96, 0xfc, 0x99, 0x38, 0xf9, 0xb8, 0x8d, 0x2e, 0xc3, 0x49, 0xd2, 0x34, - 0x48, 0x23, 0x41, 0x36, 0xc5, 0xc8, 0x66, 0xa3, 0x65, 0x4e, 0xf7, 0x01, 0x9c, 0x8d, 0xbb, 0x84, - 0x6d, 0xe9, 0xc4, 0xb1, 0x19, 0xfd, 0x34, 0xa3, 0x5f, 0xe8, 0x6c, 0xef, 0x84, 0xbb, 0x3b, 0x8e, - 0x1d, 0xb2, 0x3d, 0x85, 0x59, 0xd3, 0xdb, 0xc3, 0xae, 0xe1, 0xd2, 0x90, 0x9e, 0xc8, 0xc0, 0x9a, - 0xea, 0x56, 0x46, 0xe1, 0x6c, 0x0a, 0xda, 0x0d, 0xcb, 0xf0, 0x43, 0x49, 0x8e, 0xed, 0x1a, 0xb4, - 0x15, 0x60, 0xa2, 0xcd, 0x44, 0x62, 0x76, 0x1c, 0x9b, 0xa0, 0x1b, 0x80, 0x22, 0xdf, 0xbc, 0x16, - 0xf5, 0x5b, 0x54, 0x77, 0xac, 0xb6, 0x5c, 0x60, 0x17, 0xf2, 0xa8, 0xb8, 0x1f, 0xb3, 0x8d, 0x87, - 0x16, 0x3b, 0x8a, 0x0d, 0x06, 0xea, 0xf2, 0xcc, 0x05, 0x69, 0x75, 0x4a, 0x13, 0x5f, 0x68, 0x85, - 0xd5, 0x19, 0x6d, 0x11, 0xdd, 0xc2, 0xc4, 0x94, 0x67, 0x39, 0x26, 0xf1, 0xa5, 0x2d, 0x4c, 0x4c, - 0xf4, 0x3e, 0xcc, 0xb5, 0xdc, 0x9a, 0xe7, 0x5a, 0x2c, 0x3a, 0xce, 0x2e, 0x96, 0xe7, 0x98, 0x8a, - 0xd9, 0xce, 0xea, 0x13, 0x67, 0x17, 0x23, 0x13, 0x4e, 0xb7, 0xdc, 0xb8, 0x39, 0xf4, 0x40, 0x14, - 0xb2, 0x7c, 0x92, 0x75, 0x49, 0x29, 0xbb, 0x4b, 0x9e, 0x26, 0xd8, 0x3a, 0x7d, 0xb2, 0xd0, 0x4a, - 0x59, 0x0d, 0x6d, 0xe1, 0x6f, 0x01, 0x3d, 0x7a, 0x7f, 0xcc, 0x73, 0x5b, 0xf8, 0xaa, 0x78, 0x6d, - 0x28, 0x2f, 0x27, 0xe1, 0x6c, 0x86, 0x60, 0xb4, 0x0a, 0xf3, 0x09, 0x77, 0xda, 0x09, 0x40, 0x88, - 0xdd, 0xe4, 0xd9, 0xfe, 0x08, 0x16, 0xe3, 0x6c, 0xc7, 0x3c, 0x51, 0xc6, 0x27, 0x18, 0x93, 0xdc, - 0x21, 0x79, 0x1a, 0x51, 0x88, 0xac, 0x9b, 0xb0, 0xd8, 0xc9, 0x7a, 0x37, 0x77, 0xa7, 0x87, 0x0a, - 0xe5, 0x4b, 0x19, 0x61, 0xe9, 0x24, 0xfd, 0xa1, 0x5b, 0xf7, 0x34, 0x39, 0x12, 0x94, 0xd4, 0xc1, - 0xda, 0x27, 0xa5, 0x72, 0x73, 0x69, 0x95, 0xfb, 0x21, 0x14, 0x7b, 0x2a, 0x37, 0xe9, 0xca, 0x71, - 0xc6, 0x72, 0xb6, 0xbb, 0x78, 0x63, 0x4f, 0xea, 0x70, 0x26, 0xae, 0xdf, 0x04, 0x2f, 0x91, 0xf3, - 0x87, 0x2c, 0xe4, 0x85, 0x4e, 0x21, 0xc7, 0x9a, 0x88, 0x62, 0xc2, 0xca, 0x90, 0x03, 0x05, 0xdd, - 0x83, 0x9c, 0x85, 0x9b, 0x87, 0xbb, 0x35, 0x33, 0x4e, 0xe5, 0xcb, 0x1c, 0xc8, 0x99, 0x0f, 0x99, - 0x4f, 0xa0, 0x10, 0x76, 0x41, 0xe0, 0xf8, 0x09, 0x80, 0xff, 0x4e, 0x74, 0x2e, 0xc5, 0x1a, 0xf8, - 0xa1, 0xb4, 0x15, 0x93, 0x6a, 0x49, 0x3e, 0xb4, 0x0d, 0x60, 0x7a, 0xbb, 0xbb, 0x0e, 0x21, 0xd1, - 0xe9, 0x36, 0x5d, 0xb9, 0xf9, 0xed, 0xeb, 0x95, 0x45, 0x2e, 0x88, 0x58, 0xcf, 0x4a, 0x8e, 0xa7, - 0xee, 0x1a, 0xb4, 0x51, 0x7a, 0x84, 0x6d, 0xc3, 0xdc, 0xdf, 0xc2, 0xe6, 0xab, 0x97, 0x37, 0x41, - 0xe8, 0xd9, 0xc2, 0xa6, 0x96, 0x10, 0x80, 0x6e, 0x40, 0x8e, 0x9d, 0x01, 0x93, 0x43, 0xce, 0x00, - 0x46, 0x95, 0x40, 0xff, 0xdc, 0x51, 0xa0, 0xff, 0x47, 0x30, 0xe9, 0x7b, 0x3e, 0x2b, 0x91, 0x42, - 0xf9, 0x7a, 0xd6, 0x73, 0x3d, 0xf0, 0xbc, 0xfa, 0xe3, 0x7a, 0xd5, 0x23, 0x04, 0x33, 0x9b, 0x2b, - 0x4f, 0x36, 0xb5, 0x90, 0x0f, 0xad, 0xc3, 0x19, 0x56, 0x32, 0xd8, 0xd2, 0x05, 0x6b, 0x04, 0xe4, - 0x1c, 0xaa, 0x17, 0xc4, 0x6e, 0x85, 0x6f, 0x0a, 0x4c, 0x0f, 0xa1, 0x2d, 0xe2, 0xa2, 0x66, 0xc4, - 0x71, 0x82, 0x71, 0xcc, 0x47, 0x1c, 0xd4, 0x14, 0xd4, 0xf1, 0xe5, 0x6c, 0x6a, 0xe0, 0x05, 0x7c, - 0xba, 0xef, 0x02, 0x8e, 0x8a, 0x30, 0x45, 0x9a, 0x2d, 0xdb, 0x76, 0x48, 0x43, 0x06, 0x86, 0x8b, - 0x9d, 0xef, 0xf2, 0xef, 0x4e, 0xc1, 0x71, 0x76, 0x1f, 0x40, 0xbf, 0x94, 0x20, 0xcf, 0x27, 0x12, - 0xe8, 0x6a, 0x46, 0x04, 0xfa, 0x07, 0x33, 0xc5, 0x6b, 0xa3, 0x90, 0xf2, 0xc2, 0x53, 0xde, 0xff, - 0xc5, 0x37, 0xff, 0xf8, 0xcd, 0xc4, 0x0a, 0x5a, 0x52, 0x07, 0x0d, 0x94, 0xd0, 0x1f, 0x24, 0x38, - 0xd9, 0x33, 0x5a, 0x41, 0xe5, 0xe1, 0x6a, 0x7a, 0x07, 0x38, 0xc5, 0xdb, 0x63, 0xf1, 0x08, 0x1b, - 0x55, 0x66, 0xe3, 0x55, 0x74, 0x65, 0xa0, 0x8d, 0xea, 0x0b, 0x01, 0xcd, 0x07, 0xe8, 0x8f, 0x12, - 0x9c, 0xea, 0x7b, 0x42, 0xa0, 0xf5, 0x41, 0xba, 0xb3, 0x46, 0x3b, 0xc5, 0x0f, 0xc6, 0xe4, 0x12, - 0x36, 0xaf, 0x31, 0x9b, 0xaf, 0xa3, 0xab, 0x19, 0x36, 0xf7, 0x3f, 0x5e, 0xd0, 0x2b, 0x09, 0xe6, - 0x7b, 0x05, 0xa2, 0xdb, 0xe3, 0xa8, 0x8f, 0x6c, 0x5e, 0x1f, 0x8f, 0x49, 0x98, 0xbc, 0xc3, 0x4c, - 0xde, 0x46, 0x9f, 0x8f, 0x6c, 0xb2, 0xfa, 0xa2, 0xeb, 0x5d, 0x71, 0xd0, 0x4f, 0x82, 0xbe, 0x94, - 0x60, 0xae, 0x7b, 0x26, 0x81, 0xd6, 0x06, 0x59, 0x97, 0x3a, 0x6a, 0x29, 0x96, 0xc7, 0x61, 0x11, - 0xee, 0x94, 0x98, 0x3b, 0xab, 0xe8, 0xb2, 0x9a, 0x39, 0x06, 0x4d, 0x3e, 0x38, 0xd0, 0x3f, 0x25, - 0x58, 0x19, 0xf2, 0xfa, 0x44, 0x95, 0x41, 0x76, 0x8c, 0xf6, 0x94, 0x2e, 0x6e, 0xbe, 0x93, 0x0c, - 0xe1, 0xdc, 0xf7, 0x99, 0x73, 0xeb, 0xa8, 0x3c, 0x46, 0xae, 0x38, 0x38, 0x1d, 0xa0, 0xff, 0x4a, - 0xb0, 0x34, 0x70, 0xfe, 0x81, 0xee, 0x8d, 0x53, 0x3f, 0x69, 0x23, 0x9a, 0xe2, 0xc6, 0x3b, 0x48, - 0x10, 0x2e, 0x56, 0x99, 0x8b, 0x9f, 0xa1, 0x07, 0x87, 0x2f, 0x47, 0x86, 0xbe, 0xb1, 0xe3, 0xff, - 0x96, 0xe0, 0xfc, 0xa0, 0xc1, 0x0a, 0xba, 0x3b, 0x8e, 0xd5, 0x29, 0x13, 0x9e, 0xe2, 0xbd, 0xc3, - 0x0b, 0x10, 0x5e, 0xdf, 0x67, 0x5e, 0x6f, 0xa0, 0xbb, 0xef, 0xe8, 0x35, 0x43, 0xec, 0x9e, 0xa1, - 0xc2, 0x60, 0xc4, 0x4e, 0x1f, 0x50, 0x0c, 0x46, 0xec, 0x8c, 0xa9, 0xc5, 0x50, 0xc4, 0x36, 0x22, - 0x3e, 0x71, 0xc2, 0xa2, 0xff, 0x48, 0xb0, 0x38, 0x60, 0x64, 0x80, 0x3e, 0x1e, 0x27, 0xb0, 0x29, - 0x00, 0x72, 0xf7, 0xd0, 0xfc, 0xc2, 0xa3, 0x6d, 0xe6, 0xd1, 0x7d, 0xf4, 0xc9, 0xe1, 0xf3, 0x92, - 0x04, 0x9b, 0x3f, 0x49, 0x30, 0xdb, 0x85, 0x5b, 0xe8, 0xd6, 0xc8, 0x10, 0x17, 0xf9, 0xb4, 0x36, - 0x06, 0x87, 0xf0, 0x62, 0x8b, 0x79, 0xf1, 0x31, 0xfa, 0xc1, 0x68, 0x98, 0xa8, 0xbe, 0x48, 0x99, - 0x62, 0x1c, 0x54, 0x1e, 0x7d, 0xf5, 0x66, 0x59, 0xfa, 0xfa, 0xcd, 0xb2, 0xf4, 0xf7, 0x37, 0xcb, - 0xd2, 0xaf, 0xdf, 0x2e, 0x1f, 0xfb, 0xfa, 0xed, 0xf2, 0xb1, 0xbf, 0xbd, 0x5d, 0x3e, 0xf6, 0x93, - 0xa1, 0xd7, 0xbd, 0x76, 0x52, 0x21, 0xbb, 0xfb, 0xd5, 0xf2, 0xec, 0x3f, 0xa6, 0xdb, 0xff, 0x0b, - 0x00, 0x00, 0xff, 0xff, 0x33, 0x28, 0x24, 0xee, 0xad, 0x1b, 0x00, 0x00, + 0x4d, 0x9c, 0x87, 0xc5, 0x58, 0xf1, 0x6e, 0x1f, 0xdb, 0xdd, 0xc4, 0xb2, 0x77, 0x93, 0xec, 0xae, + 0x1b, 0x95, 0x4e, 0x5a, 0xa0, 0x2f, 0x81, 0xa2, 0x46, 0x14, 0x11, 0x99, 0xc3, 0x70, 0x46, 0xae, + 0x8c, 0xc0, 0x97, 0x1e, 0x7a, 0x2b, 0x50, 0xa0, 0xbd, 0xf6, 0xdc, 0x16, 0x3d, 0x36, 0xa7, 0x02, + 0xbd, 0x6f, 0x6f, 0x8b, 0xf4, 0xb0, 0x45, 0x0e, 0x41, 0x91, 0x14, 0x2d, 0x50, 0xa0, 0xd7, 0x9e, + 0x0b, 0xce, 0x0c, 0x45, 0x4a, 0x22, 0x65, 0xc9, 0x76, 0x6f, 0xd6, 0xcc, 0xff, 0x9e, 0xef, 0xff, + 0x86, 0xf3, 0x1b, 0x2e, 0x57, 0xcd, 0xea, 0x5e, 0x93, 0xb8, 0x7a, 0x95, 0x59, 0x94, 0x99, 0x4f, + 0x1d, 0xd7, 0xd6, 0x77, 0x57, 0xf5, 0x67, 0x2d, 0xec, 0xef, 0x15, 0x3c, 0x9f, 0x30, 0x82, 0xce, + 0x4a, 0x91, 0x42, 0x24, 0x52, 0xd8, 0x5d, 0xcd, 0xcf, 0xd9, 0xc4, 0x26, 0x5c, 0x42, 0x0f, 0xfe, + 0x12, 0xc2, 0xf9, 0x8b, 0x36, 0x21, 0x76, 0x13, 0xeb, 0xa6, 0xe7, 0xe8, 0xa6, 0xeb, 0x12, 0x66, + 0x32, 0x87, 0xb8, 0x54, 0xee, 0x5e, 0xb0, 0x08, 0xdd, 0x21, 0xb4, 0x22, 0xd4, 0xc4, 0x0f, 0xb9, + 0x75, 0x45, 0xfc, 0xd2, 0xa3, 0x20, 0xaa, 0x98, 0x99, 0xab, 0xe1, 0x6f, 0x29, 0x75, 0x43, 0x4a, + 0x55, 0x4d, 0x8a, 0x45, 0x90, 0x1d, 0x41, 0xcf, 0xb4, 0x1d, 0x97, 0x7b, 0x93, 0xb2, 0x5a, 0x72, + 0x6a, 0x9e, 0xe9, 0x9b, 0x3b, 0xa1, 0xd7, 0xab, 0xc9, 0x32, 0xb1, 0x4c, 0x85, 0xdc, 0x52, 0x8a, + 0x2d, 0xe2, 0x09, 0x01, 0x6d, 0x0e, 0xd0, 0x77, 0x83, 0x70, 0xca, 0xdc, 0xba, 0x81, 0x9f, 0xb5, + 0x30, 0x65, 0x9a, 0x01, 0xef, 0x74, 0xad, 0x52, 0x8f, 0xb8, 0x14, 0xa3, 0x0f, 0x20, 0x2b, 0xa2, + 0x50, 0x95, 0x4b, 0xca, 0x72, 0xae, 0xb8, 0x50, 0x48, 0x2c, 0x71, 0x41, 0xa8, 0x95, 0x32, 0x5f, + 0xbc, 0x5e, 0x3a, 0x61, 0x48, 0x15, 0xed, 0xeb, 0x30, 0x1f, 0xb3, 0x59, 0xda, 0xfb, 0x1e, 0xf6, + 0xa9, 0x43, 0x5c, 0xe9, 0x12, 0xa9, 0x70, 0x6a, 0x57, 0xac, 0x70, 0xe3, 0xd3, 0x46, 0xf8, 0x53, + 0xfb, 0x21, 0x5c, 0x4c, 0x56, 0x3c, 0x8e, 0xa8, 0x6c, 0x58, 0xe0, 0xc6, 0x3f, 0x71, 0x5c, 0xb3, + 0xe9, 0xb0, 0xbd, 0xb2, 0x4f, 0x76, 0x9d, 0x1a, 0xf6, 0xc3, 0x52, 0xa0, 0x4f, 0x00, 0xa2, 0x13, + 0x92, 0x1e, 0xae, 0x16, 0x24, 0x04, 0x82, 0xe3, 0x2c, 0x08, 0xcc, 0xc9, 0xe3, 0x2c, 0x94, 0x4d, + 0x1b, 0x4b, 0x5d, 0x23, 0xa6, 0xa9, 0xfd, 0x45, 0x81, 0xc5, 0x34, 0x4f, 0x32, 0x91, 0x9f, 0x00, + 0xaa, 0xcb, 0xcd, 0x00, 0x69, 0x62, 0x57, 0x55, 0x2e, 0x8d, 0x2f, 0xe7, 0x8a, 0x7a, 0x4a, 0x52, + 0xbd, 0xd6, 0x42, 0x63, 0xc6, 0x99, 0x7a, 0xaf, 0x1f, 0x74, 0xbf, 0x2b, 0x95, 0x31, 0x9e, 0xca, + 0xb5, 0x03, 0x53, 0x91, 0xf6, 0xe2, 0xb9, 0xac, 0xcb, 0x13, 0xe9, 0x77, 0x2e, 0x6a, 0x76, 0x19, + 0xa6, 0xeb, 0x5e, 0xa5, 0xca, 0xac, 0x8a, 0xf7, 0xb4, 0xd2, 0xc0, 0x6d, 0x5e, 0xb6, 0x49, 0x03, + 0xea, 0x5e, 0x89, 0x59, 0xe5, 0xa7, 0x0f, 0x70, 0x5b, 0xdb, 0x4f, 0xa9, 0x7b, 0xa7, 0x18, 0x3f, + 0x82, 0x33, 0x7d, 0xc5, 0x90, 0xe5, 0x1f, 0xb9, 0x16, 0xb3, 0xbd, 0xb5, 0xd0, 0x7e, 0xa7, 0x40, + 0x9e, 0xfb, 0x2f, 0x3d, 0xde, 0xd8, 0xc4, 0x4d, 0x6c, 0x8b, 0x76, 0x0f, 0x13, 0x28, 0x41, 0x96, + 0x32, 0x93, 0xb5, 0x04, 0xa4, 0x66, 0x8a, 0x37, 0x52, 0x3c, 0x76, 0x69, 0x6f, 0x73, 0x0d, 0x43, + 0x6a, 0xf6, 0x00, 0x67, 0xec, 0xd0, 0xc0, 0xf9, 0xb3, 0x22, 0x1b, 0xa7, 0x37, 0x54, 0x59, 0xa8, + 0x27, 0x70, 0x3a, 0xa8, 0x74, 0x2d, 0xda, 0x92, 0x90, 0xb9, 0x35, 0x4c, 0xd0, 0x9d, 0x1a, 0xcd, + 0x54, 0x99, 0x15, 0x33, 0x7f, 0x7c, 0x60, 0xa9, 0xc3, 0xf5, 0xc4, 0x93, 0x2e, 0x93, 0x9f, 0x62, + 0x7f, 0x9d, 0x3d, 0xc0, 0x8e, 0xdd, 0x60, 0xc3, 0x23, 0x07, 0x9d, 0x83, 0x6c, 0x83, 0xeb, 0xf0, + 0xa0, 0x32, 0x86, 0xfc, 0xa5, 0x3d, 0x82, 0x1b, 0xc3, 0xf8, 0x91, 0x55, 0xbb, 0x0c, 0x53, 0xbb, + 0x84, 0x39, 0xae, 0x5d, 0xf1, 0x82, 0x7d, 0xee, 0x27, 0x63, 0xe4, 0xc4, 0x1a, 0x57, 0xd1, 0xb6, + 0x60, 0x39, 0xd1, 0xe0, 0x46, 0xcb, 0xf7, 0xb1, 0xcb, 0xb8, 0xd0, 0x08, 0x88, 0x4f, 0xab, 0x43, + 0xb7, 0x39, 0x19, 0x5e, 0x94, 0xa4, 0x12, 0x4f, 0xb2, 0x2f, 0xec, 0xb1, 0xfe, 0xb0, 0x7f, 0xa1, + 0xc0, 0x4d, 0xee, 0x68, 0xdd, 0x62, 0xce, 0x2e, 0xee, 0xa3, 0x9b, 0xde, 0x92, 0xa7, 0xb9, 0x3a, + 0x2e, 0xfc, 0x7e, 0xa5, 0xc0, 0xad, 0xe1, 0xe2, 0x39, 0x46, 0x1a, 0xfc, 0xbe, 0xc3, 0x1a, 0x5b, + 0x98, 0x99, 0xff, 0x57, 0x1a, 0x5c, 0x90, 0x8d, 0xc9, 0x13, 0x33, 0x19, 0xae, 0x75, 0x15, 0x56, + 0x7b, 0x5f, 0xb2, 0x64, 0xdf, 0xf6, 0xe0, 0x33, 0xd6, 0x7e, 0xad, 0xc0, 0xb5, 0x44, 0xa4, 0x24, + 0x10, 0xd5, 0x10, 0xfd, 0x72, 0x5c, 0xe7, 0xf8, 0x2f, 0x25, 0xa5, 0x1f, 0x92, 0x48, 0xc9, 0x87, + 0x0b, 0x31, 0x52, 0x22, 0x7e, 0x02, 0x3d, 0xbd, 0x7f, 0x20, 0x3d, 0x91, 0x24, 0xd3, 0xc6, 0xf9, + 0x88, 0xa8, 0xba, 0x04, 0x8e, 0xef, 0x5c, 0x3f, 0x85, 0x0b, 0xfd, 0x84, 0x1b, 0x56, 0x7c, 0x05, + 0xde, 0x91, 0xc1, 0x56, 0x58, 0xbb, 0xd2, 0x30, 0x69, 0x23, 0x56, 0xf7, 0x59, 0xb9, 0xf5, 0xb8, + 0xfd, 0xc0, 0xa4, 0x8d, 0xa0, 0xeb, 0x9f, 0x25, 0xdd, 0x33, 0x9d, 0x32, 0x6d, 0xc3, 0x4c, 0x37, + 0x77, 0xcb, 0x1b, 0x6e, 0x34, 0xea, 0x9e, 0xee, 0xa2, 0x6e, 0xed, 0xab, 0x2c, 0x9c, 0x4d, 0x76, + 0xf7, 0x4d, 0xc8, 0x05, 0xc6, 0xb0, 0x5f, 0x31, 0x6b, 0x35, 0xc1, 0x79, 0x93, 0x25, 0xf5, 0xe5, + 0x8b, 0x95, 0x39, 0x59, 0xa5, 0xf5, 0x5a, 0xcd, 0xc7, 0x94, 0x6e, 0x33, 0xdf, 0x71, 0x6d, 0x03, + 0x84, 0x70, 0xb0, 0x88, 0x1e, 0x41, 0x56, 0xa0, 0x8c, 0x17, 0x76, 0xaa, 0xf4, 0x8d, 0x57, 0xaf, + 0x97, 0xd6, 0x6c, 0x87, 0x35, 0x5a, 0xd5, 0x82, 0x45, 0x76, 0x74, 0x19, 0x6f, 0xd3, 0xac, 0xd2, + 0x15, 0x87, 0x84, 0x3f, 0x75, 0xb6, 0xe7, 0x61, 0x5a, 0x28, 0x3d, 0x2c, 0xdf, 0x59, 0xbb, 0x5d, + 0x6e, 0x55, 0x3f, 0xc3, 0x7b, 0xc6, 0xc9, 0x6a, 0x80, 0x4c, 0xf4, 0x63, 0x98, 0x89, 0x90, 0xdb, + 0x74, 0x28, 0x53, 0xc7, 0x2f, 0x8d, 0x1f, 0xc9, 0x70, 0x4e, 0x82, 0xfe, 0x73, 0x87, 0x37, 0xc6, + 0x14, 0x65, 0xa6, 0xcf, 0x2a, 0xb2, 0xc5, 0x32, 0x82, 0x28, 0xf9, 0x9a, 0xe8, 0x43, 0xb4, 0x00, + 0x80, 0xdd, 0x5a, 0x28, 0x70, 0x92, 0x0b, 0x4c, 0x62, 0x57, 0xb6, 0x29, 0x9a, 0x87, 0x49, 0x46, + 0x98, 0xd9, 0xac, 0x50, 0x93, 0xa9, 0x59, 0xbe, 0x3b, 0xc1, 0x17, 0xb6, 0x4d, 0x86, 0xae, 0xc0, + 0x4c, 0x1c, 0x05, 0xb8, 0xad, 0x9e, 0xe2, 0x00, 0x98, 0x8a, 0x00, 0x80, 0xdb, 0xe8, 0x2a, 0x9c, + 0xa6, 0x4d, 0x93, 0x36, 0x62, 0x62, 0x13, 0x5c, 0x6c, 0x3a, 0x5c, 0x16, 0x72, 0xef, 0xc1, 0xf9, + 0xa8, 0x53, 0xf8, 0x56, 0x85, 0x3a, 0x36, 0x97, 0x9f, 0xe4, 0xf2, 0x73, 0x9d, 0xed, 0xed, 0x60, + 0x77, 0xdb, 0xb1, 0x03, 0xb5, 0x27, 0x30, 0x6d, 0x91, 0x5d, 0xec, 0x9a, 0x2e, 0x0b, 0xe4, 0xa9, + 0x0a, 0xbc, 0xb1, 0x6e, 0xa7, 0x80, 0x67, 0x43, 0xca, 0xae, 0xd7, 0x4c, 0x2f, 0xb0, 0xe4, 0xd8, + 0xae, 0xc9, 0x5a, 0x3e, 0xa6, 0xc6, 0x54, 0x68, 0x66, 0xdb, 0xb1, 0x29, 0xba, 0x05, 0x28, 0xcc, + 0x8d, 0xb4, 0x98, 0xd7, 0x62, 0x15, 0xa7, 0xd6, 0x56, 0x73, 0xfc, 0xa3, 0x3c, 0x04, 0xf8, 0x23, + 0xbe, 0xf1, 0xb0, 0xc6, 0xaf, 0x63, 0x93, 0x13, 0xbb, 0x3a, 0x75, 0x49, 0x59, 0x9e, 0x30, 0xe4, + 0x2f, 0xb4, 0xc4, 0xb1, 0xc6, 0x5a, 0xb4, 0x52, 0xc3, 0xd4, 0x52, 0xa7, 0x05, 0x2f, 0x89, 0xa5, + 0x4d, 0x4c, 0x2d, 0xf4, 0x2e, 0xcc, 0xb4, 0xdc, 0x2a, 0x71, 0x6b, 0xbc, 0x3a, 0xce, 0x0e, 0x56, + 0x67, 0xb8, 0x8b, 0xe9, 0xce, 0xea, 0x63, 0x67, 0x07, 0x23, 0x0b, 0xce, 0xb6, 0xdc, 0xa8, 0x41, + 0x2a, 0xbe, 0x04, 0xb3, 0x7a, 0x9a, 0x77, 0x4a, 0x21, 0xbd, 0x53, 0x9e, 0xc4, 0xd4, 0x3a, 0xbd, + 0x32, 0xd7, 0x4a, 0x58, 0x0d, 0x62, 0x11, 0xef, 0x81, 0x4a, 0xf8, 0x06, 0x99, 0x15, 0xb1, 0x88, + 0x55, 0xf9, 0xe2, 0xd0, 0x5e, 0x8c, 0xc3, 0xf9, 0x14, 0xc3, 0x68, 0x19, 0x66, 0x63, 0xe9, 0xb4, + 0x63, 0xa4, 0x10, 0xa5, 0x29, 0x4e, 0xfb, 0x43, 0x98, 0x8f, 0x4e, 0x3b, 0xd2, 0x09, 0x4f, 0x7c, + 0x8c, 0x2b, 0xa9, 0x1d, 0x91, 0x27, 0xa1, 0x84, 0x3c, 0x75, 0x0b, 0xe6, 0x3b, 0xa7, 0xde, 0xad, + 0xdd, 0xe9, 0xa2, 0x5c, 0xf1, 0x4a, 0x4a, 0x59, 0x3a, 0x87, 0xfe, 0xd0, 0xad, 0x13, 0x43, 0x0d, + 0x0d, 0xc5, 0x7d, 0xf0, 0xf6, 0x49, 0x40, 0x6e, 0x26, 0x09, 0xb9, 0x1f, 0x40, 0xbe, 0x07, 0xb9, + 0xf1, 0x54, 0x4e, 0x72, 0x95, 0xf3, 0xdd, 0xe0, 0x8d, 0x32, 0xa9, 0xc3, 0xb9, 0x08, 0xbf, 0x31, + 0x5d, 0xaa, 0x66, 0x0f, 0x09, 0xe4, 0xb9, 0x0e, 0x90, 0x23, 0x4f, 0x54, 0xb3, 0x60, 0xe9, 0x80, + 0x4b, 0x05, 0xdd, 0x83, 0x4c, 0x0d, 0x37, 0x0f, 0xf7, 0xe5, 0xcc, 0x35, 0xb5, 0xdf, 0x67, 0x40, + 0x4d, 0x7d, 0xcc, 0x7c, 0x0c, 0xb9, 0xa0, 0x0b, 0x7c, 0xc7, 0x8b, 0x91, 0xfc, 0xd7, 0xc2, 0xbb, + 0x29, 0xf2, 0x20, 0x2e, 0xa6, 0xcd, 0x48, 0xd4, 0x88, 0xeb, 0xa1, 0x2d, 0x00, 0x8b, 0xec, 0xec, + 0x38, 0x94, 0x86, 0x37, 0xdc, 0x64, 0x69, 0xe5, 0xd5, 0xeb, 0xa5, 0x79, 0x61, 0x88, 0xd6, 0x9e, + 0x16, 0x1c, 0xa2, 0xef, 0x98, 0xac, 0x51, 0xf8, 0x1c, 0xdb, 0xa6, 0xb5, 0xb7, 0x89, 0xad, 0x97, + 0x2f, 0x56, 0x40, 0xfa, 0xd9, 0xc4, 0x96, 0x11, 0x33, 0x80, 0x6e, 0x41, 0x86, 0xdf, 0x03, 0xe3, + 0x07, 0xdc, 0x03, 0x5c, 0x2a, 0x76, 0x03, 0x64, 0x8e, 0xe7, 0x06, 0xf8, 0x10, 0xc6, 0x3d, 0xe2, + 0x71, 0x90, 0xe4, 0x8a, 0x37, 0xd3, 0x1e, 0xed, 0x3e, 0x21, 0xf5, 0x47, 0xf5, 0x32, 0xa1, 0x14, + 0xf3, 0xa8, 0x4b, 0x8f, 0x37, 0x8c, 0x40, 0x0f, 0xad, 0xc1, 0x39, 0x0e, 0x1a, 0x5c, 0xab, 0x48, + 0xd5, 0x90, 0xca, 0x05, 0x59, 0xcf, 0xc9, 0xdd, 0x92, 0xd8, 0x94, 0xac, 0x1e, 0x90, 0x5b, 0xa8, + 0xc5, 0xac, 0x50, 0xe3, 0x14, 0xd7, 0x98, 0x0d, 0x35, 0x98, 0x25, 0xa5, 0xa3, 0x4f, 0xb4, 0x89, + 0x81, 0x9f, 0xe1, 0x93, 0x7d, 0x9f, 0xe1, 0x28, 0x0f, 0x13, 0xb4, 0xd9, 0xb2, 0x6d, 0x87, 0x36, + 0x54, 0xe0, 0xcc, 0xd8, 0xf9, 0x5d, 0xfc, 0xcd, 0x19, 0x38, 0xc9, 0xbf, 0x0a, 0xd0, 0xcf, 0x15, + 0xc8, 0x8a, 0xb9, 0x04, 0xba, 0x9e, 0x52, 0x81, 0xfe, 0xf1, 0x4c, 0xfe, 0xc6, 0x30, 0xa2, 0x02, + 0x7a, 0xda, 0xbb, 0x3f, 0xfb, 0xeb, 0x3f, 0x7e, 0x35, 0xb6, 0x84, 0x16, 0xf4, 0x41, 0x63, 0x25, + 0xf4, 0x07, 0x05, 0x4e, 0xf7, 0x0c, 0x58, 0x50, 0xf1, 0x60, 0x37, 0xbd, 0x63, 0x9c, 0xfc, 0x9d, + 0x91, 0x74, 0x64, 0x8c, 0x3a, 0x8f, 0xf1, 0x3a, 0xba, 0x36, 0x30, 0x46, 0xfd, 0xb9, 0x24, 0xe7, + 0x7d, 0xf4, 0x47, 0x05, 0xce, 0xf4, 0x3d, 0x24, 0xd0, 0xda, 0x20, 0xdf, 0x69, 0x03, 0x9e, 0xfc, + 0x7b, 0x23, 0x6a, 0xc9, 0x98, 0x57, 0x79, 0xcc, 0x37, 0xd1, 0xf5, 0x94, 0x98, 0xfb, 0x9f, 0x30, + 0xe8, 0xa5, 0x02, 0xb3, 0xbd, 0x06, 0xd1, 0x9d, 0x51, 0xdc, 0x87, 0x31, 0xaf, 0x8d, 0xa6, 0x24, + 0x43, 0xde, 0xe6, 0x21, 0x6f, 0xa1, 0xcf, 0x86, 0x0e, 0x59, 0x7f, 0xde, 0xf5, 0xba, 0xd8, 0xef, + 0x17, 0x41, 0xbf, 0x55, 0x60, 0xa6, 0x7b, 0x32, 0x81, 0x56, 0x07, 0x45, 0x97, 0x38, 0x70, 0xc9, + 0x17, 0x47, 0x51, 0x91, 0xe9, 0x14, 0x78, 0x3a, 0xcb, 0xe8, 0xaa, 0x9e, 0x3a, 0x0c, 0x8d, 0x3f, + 0x3b, 0xd0, 0x3f, 0x15, 0x58, 0x3a, 0xe0, 0x0d, 0x8a, 0x4a, 0x83, 0xe2, 0x18, 0xee, 0x41, 0x9d, + 0xdf, 0x38, 0x92, 0x0d, 0x99, 0xdc, 0xb7, 0x78, 0x72, 0x6b, 0xa8, 0x38, 0xc2, 0x59, 0x09, 0x72, + 0xda, 0x47, 0xff, 0x55, 0x60, 0x61, 0xe0, 0x14, 0x04, 0xdd, 0x1b, 0x05, 0x3f, 0x49, 0x83, 0x9a, + 0xfc, 0xfa, 0x11, 0x2c, 0xc8, 0x14, 0xcb, 0x3c, 0xc5, 0x4f, 0xd1, 0x83, 0xc3, 0xc3, 0x91, 0xb3, + 0x6f, 0x94, 0xf8, 0xbf, 0x15, 0xb8, 0x38, 0x68, 0xbc, 0x82, 0xee, 0x8e, 0x12, 0x75, 0xc2, 0x9c, + 0x27, 0x7f, 0xef, 0xf0, 0x06, 0x64, 0xd6, 0xf7, 0x79, 0xd6, 0xeb, 0xe8, 0xee, 0x11, 0xb3, 0xe6, + 0x8c, 0xdd, 0x33, 0x5a, 0x18, 0xcc, 0xd8, 0xc9, 0x63, 0x8a, 0xc1, 0x8c, 0x9d, 0x32, 0xbb, 0x38, + 0x90, 0xb1, 0xcd, 0x50, 0x4f, 0xde, 0xb0, 0xe8, 0x3f, 0x0a, 0xcc, 0x0f, 0x18, 0x1c, 0xa0, 0x8f, + 0x46, 0x29, 0x6c, 0x02, 0x81, 0xdc, 0x3d, 0xb4, 0xbe, 0xcc, 0x68, 0x8b, 0x67, 0x74, 0x1f, 0x7d, + 0x7c, 0xf8, 0x73, 0x89, 0x93, 0xcd, 0x9f, 0x14, 0x98, 0xee, 0xe2, 0x2d, 0x74, 0x7b, 0x68, 0x8a, + 0x0b, 0x73, 0x5a, 0x1d, 0x41, 0x43, 0x66, 0xb1, 0xc9, 0xb3, 0xf8, 0x08, 0x7d, 0x7b, 0x38, 0x4e, + 0xd4, 0x9f, 0x27, 0xcc, 0x32, 0xf6, 0x4b, 0xdf, 0xf9, 0xe2, 0xcd, 0xa2, 0xf2, 0xe5, 0x9b, 0x45, + 0xe5, 0xef, 0x6f, 0x16, 0x95, 0x5f, 0xbe, 0x5d, 0x3c, 0xf1, 0xe5, 0xdb, 0xc5, 0x13, 0x7f, 0x7b, + 0xbb, 0x78, 0xe2, 0x07, 0x43, 0x7c, 0xf0, 0xb5, 0xe3, 0x2e, 0xf9, 0xd7, 0x5f, 0x35, 0xcb, 0xff, + 0xd7, 0x74, 0xe7, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x53, 0x66, 0x0a, 0xb8, 0xb5, 0x1b, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -5924,7 +5925,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -5959,7 +5960,7 @@ func (m *BTCDelegationResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPkList = append(m.FpBtcPkList, v) if err := m.FpBtcPkList[len(m.FpBtcPkList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -6810,7 +6811,7 @@ func (m *FinalityProviderResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/btcstaking/types/tx.pb.go b/x/btcstaking/types/tx.pb.go index b2f595e61..316cac6f8 100644 --- a/x/btcstaking/types/tx.pb.go +++ b/x/btcstaking/types/tx.pb.go @@ -7,8 +7,8 @@ import ( context "context" cosmossdk_io_math "cosmossdk.io/math" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" - types1 "github.com/babylonchain/babylon/x/btccheckpoint/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" + types1 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" types "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -45,7 +45,7 @@ type MsgCreateFinalityProvider struct { Commission *cosmossdk_io_math.LegacyDec `protobuf:"bytes,3,opt,name=commission,proto3,customtype=cosmossdk.io/math.LegacyDec" json:"commission,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of this finality provider // the PK follows encoding in BIP-340 spec - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,4,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // pop is the proof of possession of btc_pk over the FP signer address. Pop *ProofOfPossessionBTC `protobuf:"bytes,5,opt,name=pop,proto3" json:"pop,omitempty"` } @@ -251,10 +251,10 @@ type MsgCreateBTCDelegation struct { // pop is the proof of possession of btc_pk by the staker_addr. Pop *ProofOfPossessionBTC `protobuf:"bytes,2,opt,name=pop,proto3" json:"pop,omitempty"` // btc_pk is the Bitcoin secp256k1 PK of the BTC delegator - BtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` + BtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,3,opt,name=btc_pk,json=btcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pk,omitempty"` // fp_btc_pk_list is the list of Bitcoin secp256k1 PKs of the finality providers, if there is more than one // finality provider pk it means that delegation is re-staked - FpBtcPkList []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,4,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` + FpBtcPkList []github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,4,rep,name=fp_btc_pk_list,json=fpBtcPkList,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk_list,omitempty"` // staking_time is the time lock used in staking transaction StakingTime uint32 `protobuf:"varint,5,opt,name=staking_time,json=stakingTime,proto3" json:"staking_time,omitempty"` // staking_value is the amount of satoshis locked in staking output @@ -268,7 +268,7 @@ type MsgCreateBTCDelegation struct { // It will be a part of the witness for the staking tx output. // The staking tx output further needs signatures from covenant and finality provider in // order to be spendable. - DelegatorSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,9,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` + DelegatorSlashingSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,9,opt,name=delegator_slashing_sig,json=delegatorSlashingSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"delegator_slashing_sig,omitempty"` // unbonding_time is the time lock used when funds are being unbonded. It is be used in: // - unbonding transaction, time lock spending path // - staking slashing transaction, change output @@ -286,7 +286,7 @@ type MsgCreateBTCDelegation struct { // Note that the tx itself does not contain signatures, which are off-chain. UnbondingSlashingTx *BTCSlashingTx `protobuf:"bytes,13,opt,name=unbonding_slashing_tx,json=unbondingSlashingTx,proto3,customtype=BTCSlashingTx" json:"unbonding_slashing_tx,omitempty"` // delegator_unbonding_slashing_sig is the signature on the slashing tx by the delegator (i.e., SK corresponding to btc_pk). - DelegatorUnbondingSlashingSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,14,opt,name=delegator_unbonding_slashing_sig,json=delegatorUnbondingSlashingSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"delegator_unbonding_slashing_sig,omitempty"` + DelegatorUnbondingSlashingSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,14,opt,name=delegator_unbonding_slashing_sig,json=delegatorUnbondingSlashingSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"delegator_unbonding_slashing_sig,omitempty"` } func (m *MsgCreateBTCDelegation) Reset() { *m = MsgCreateBTCDelegation{} } @@ -419,7 +419,7 @@ var xxx_messageInfo_MsgCreateBTCDelegationResponse proto.InternalMessageInfo type MsgAddCovenantSigs struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` // pk is the BTC public key of the covenant member - Pk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=pk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"pk,omitempty"` + Pk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=pk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"pk,omitempty"` // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation StakingTxHash string `protobuf:"bytes,3,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` @@ -429,7 +429,7 @@ type MsgAddCovenantSigs struct { SlashingTxSigs [][]byte `protobuf:"bytes,4,rep,name=slashing_tx_sigs,json=slashingTxSigs,proto3" json:"slashing_tx_sigs,omitempty"` // unbonding_tx_sig is the signature of the covenant on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - UnbondingTxSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,5,opt,name=unbonding_tx_sig,json=unbondingTxSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"unbonding_tx_sig,omitempty"` + UnbondingTxSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,5,opt,name=unbonding_tx_sig,json=unbondingTxSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"unbonding_tx_sig,omitempty"` // slashing_unbonding_tx_sigs is a list of adaptor signatures of the covenant // on slashing tx corresponding to unbonding tx submitted to babylon // the order of sigs should respect the order of finality providers @@ -545,7 +545,7 @@ type MsgBTCUndelegate struct { StakingTxHash string `protobuf:"bytes,2,opt,name=staking_tx_hash,json=stakingTxHash,proto3" json:"staking_tx_hash,omitempty"` // unbonding_tx_sig is the signature of the staker on the unbonding tx submitted to babylon // the signature follows encoding in BIP-340 spec - UnbondingTxSig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,3,opt,name=unbonding_tx_sig,json=unbondingTxSig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"unbonding_tx_sig,omitempty"` + UnbondingTxSig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,3,opt,name=unbonding_tx_sig,json=unbondingTxSig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"unbonding_tx_sig,omitempty"` } func (m *MsgBTCUndelegate) Reset() { *m = MsgBTCUndelegate{} } @@ -854,86 +854,86 @@ func init() { func init() { proto.RegisterFile("babylon/btcstaking/v1/tx.proto", fileDescriptor_4baddb53e97f38f2) } var fileDescriptor_4baddb53e97f38f2 = []byte{ - // 1259 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0x4f, 0x6f, 0x13, 0x47, - 0x14, 0xcf, 0xda, 0x89, 0x69, 0x9e, 0xe3, 0x24, 0x5d, 0x42, 0xd8, 0x6c, 0xc1, 0x76, 0x0c, 0x85, - 0x40, 0xc9, 0x9a, 0x84, 0x82, 0x4a, 0x50, 0x0f, 0x38, 0x09, 0x02, 0x15, 0xab, 0xd6, 0xda, 0xe9, - 0xa1, 0x3d, 0x58, 0xeb, 0xdd, 0xc9, 0x7a, 0x64, 0x7b, 0x67, 0xb5, 0x33, 0xb1, 0x1c, 0x55, 0xaa, - 0x2a, 0xd4, 0x6b, 0xa5, 0x9e, 0x7a, 0xe8, 0xa7, 0xe0, 0xc0, 0x47, 0xa8, 0x2a, 0x8e, 0x88, 0x53, - 0x95, 0x43, 0x54, 0x41, 0x25, 0x3e, 0x41, 0xa5, 0xde, 0x5a, 0xed, 0xec, 0x5f, 0xbb, 0xde, 0x92, - 0x60, 0x6e, 0xde, 0x99, 0xdf, 0xfb, 0xbd, 0xf7, 0x7e, 0xef, 0xbd, 0x99, 0x31, 0xe4, 0x5b, 0x5a, - 0xeb, 0xb0, 0x4b, 0xac, 0x72, 0x8b, 0xe9, 0x94, 0x69, 0x1d, 0x6c, 0x99, 0xe5, 0xfe, 0x46, 0x99, - 0x0d, 0x14, 0xdb, 0x21, 0x8c, 0x88, 0xe7, 0xfc, 0x7d, 0x25, 0xda, 0x57, 0xfa, 0x1b, 0xf2, 0x92, - 0x49, 0x4c, 0xc2, 0x11, 0x65, 0xf7, 0x97, 0x07, 0x96, 0x57, 0x74, 0x42, 0x7b, 0x84, 0x36, 0xbd, - 0x0d, 0xef, 0xc3, 0xdf, 0x3a, 0xef, 0x7d, 0x95, 0x7b, 0x94, 0xf3, 0xf7, 0xa8, 0xe9, 0x6f, 0x94, - 0xc6, 0x07, 0x60, 0x6b, 0x8e, 0xd6, 0x0b, 0x8c, 0x6f, 0xc4, 0x30, 0x7a, 0x1b, 0xe9, 0x1d, 0x9b, - 0x60, 0x8b, 0xb9, 0xb0, 0xa1, 0x05, 0x1f, 0x7d, 0xd9, 0x77, 0x15, 0xb1, 0xb5, 0x10, 0xd3, 0x36, - 0x82, 0x6f, 0x1f, 0x55, 0x48, 0xf0, 0x4b, 0x6c, 0x0f, 0x50, 0xfa, 0x3b, 0x05, 0x2b, 0x55, 0x6a, - 0x6e, 0x3b, 0x48, 0x63, 0xe8, 0x01, 0xb6, 0xb4, 0x2e, 0x66, 0x87, 0x35, 0x87, 0xf4, 0xb1, 0x81, - 0x1c, 0xf1, 0x06, 0x4c, 0x6b, 0x86, 0xe1, 0x48, 0x42, 0x51, 0x58, 0x9b, 0xad, 0x48, 0x2f, 0x9f, - 0xad, 0x2f, 0xf9, 0xf9, 0xde, 0x37, 0x0c, 0x07, 0x51, 0x5a, 0x67, 0x0e, 0xb6, 0x4c, 0x95, 0xa3, - 0xc4, 0x5d, 0xc8, 0x1a, 0x88, 0xea, 0x0e, 0xb6, 0x19, 0x26, 0x96, 0x94, 0x2a, 0x0a, 0x6b, 0xd9, - 0xcd, 0x4b, 0x8a, 0x6f, 0x11, 0xe9, 0xca, 0x03, 0x55, 0x76, 0x22, 0xa8, 0x1a, 0xb7, 0x13, 0xab, - 0x00, 0x3a, 0xe9, 0xf5, 0x30, 0xa5, 0x2e, 0x4b, 0x9a, 0xbb, 0x5e, 0x3f, 0x3a, 0x2e, 0x7c, 0xe4, - 0x11, 0x51, 0xa3, 0xa3, 0x60, 0x52, 0xee, 0x69, 0xac, 0xad, 0x3c, 0x46, 0xa6, 0xa6, 0x1f, 0xee, - 0x20, 0xfd, 0xe5, 0xb3, 0x75, 0xf0, 0xfd, 0xec, 0x20, 0x5d, 0x8d, 0x11, 0x88, 0x55, 0xc8, 0xb4, - 0x98, 0xde, 0xb4, 0x3b, 0xd2, 0x74, 0x51, 0x58, 0x9b, 0xab, 0xdc, 0x39, 0x3a, 0x2e, 0x6c, 0x9a, - 0x98, 0xb5, 0x0f, 0x5a, 0x8a, 0x4e, 0x7a, 0x65, 0x5f, 0x21, 0xbd, 0xad, 0x61, 0x2b, 0xf8, 0x28, - 0xb3, 0x43, 0x1b, 0x51, 0xa5, 0xf2, 0xa8, 0x76, 0xeb, 0xd3, 0x9b, 0xb5, 0x83, 0xd6, 0x17, 0xe8, - 0x50, 0x9d, 0x69, 0x31, 0xbd, 0xd6, 0x11, 0x3f, 0x87, 0xb4, 0x4d, 0x6c, 0x69, 0x86, 0x27, 0xf7, - 0x89, 0x32, 0xb6, 0x71, 0x94, 0x9a, 0x43, 0xc8, 0xfe, 0x97, 0xfb, 0x35, 0x42, 0x29, 0xe2, 0x51, - 0x54, 0x1a, 0xdb, 0xaa, 0x6b, 0xb7, 0x35, 0xfb, 0xe4, 0xcd, 0xd3, 0xeb, 0x5c, 0xae, 0xd2, 0x25, - 0x58, 0x4d, 0x54, 0x5e, 0x45, 0xd4, 0x26, 0x16, 0x45, 0xa5, 0x7f, 0x04, 0x38, 0x5f, 0xa5, 0xe6, - 0xae, 0x81, 0xd9, 0x84, 0xd5, 0x39, 0x17, 0xea, 0xe0, 0x16, 0x66, 0x2e, 0xc8, 0x67, 0xa4, 0x68, - 0xe9, 0xf7, 0x52, 0xb4, 0xe9, 0x09, 0x8b, 0x16, 0x97, 0x69, 0x15, 0x0a, 0x09, 0x02, 0x84, 0x22, - 0xfd, 0x76, 0x06, 0x96, 0x43, 0x29, 0x2b, 0x8d, 0xed, 0x1d, 0xd4, 0x45, 0xa6, 0xc6, 0xe3, 0xba, - 0x0b, 0x59, 0x37, 0x07, 0xe4, 0x34, 0x4f, 0x24, 0x15, 0x78, 0x60, 0x77, 0x31, 0xa8, 0x74, 0xea, - 0xdd, 0x2a, 0x1d, 0xeb, 0xbb, 0xf4, 0xfb, 0xe8, 0xbb, 0x6f, 0x60, 0x7e, 0xdf, 0x6e, 0x7a, 0x8c, - 0xcd, 0x2e, 0xa6, 0x4c, 0x9a, 0x2e, 0xa6, 0x27, 0xa0, 0xcd, 0xee, 0xdb, 0x15, 0x97, 0xf8, 0x31, - 0xa6, 0x4c, 0x5c, 0x85, 0x39, 0x3f, 0xa7, 0x26, 0xc3, 0x3d, 0xc4, 0xbb, 0x3b, 0xa7, 0x66, 0xfd, - 0xb5, 0x06, 0xee, 0x21, 0xf1, 0x12, 0xe4, 0x02, 0x48, 0x5f, 0xeb, 0x1e, 0x20, 0x29, 0x53, 0x14, - 0xd6, 0xd2, 0x6a, 0x60, 0xf7, 0x95, 0xbb, 0x26, 0x3e, 0x04, 0x08, 0x79, 0x06, 0xd2, 0x19, 0xae, - 0xdc, 0xb5, 0xb8, 0x72, 0xb1, 0x63, 0xac, 0xbf, 0xa1, 0x34, 0x1c, 0xcd, 0xa2, 0x9a, 0xee, 0x16, - 0xea, 0x91, 0xb5, 0x4f, 0xd4, 0xd9, 0xc0, 0xe1, 0x40, 0xdc, 0x84, 0x2c, 0xed, 0x6a, 0xb4, 0xed, - 0x53, 0x7d, 0xc0, 0x25, 0xfc, 0xf0, 0xe8, 0xb8, 0x90, 0xab, 0x34, 0xb6, 0xeb, 0xfe, 0x4e, 0x63, - 0xa0, 0x02, 0x0d, 0x7f, 0x8b, 0x04, 0x96, 0x0d, 0xaf, 0xf2, 0xc4, 0x69, 0x86, 0xd6, 0x14, 0x9b, - 0xd2, 0x2c, 0x37, 0xbf, 0x7b, 0x74, 0x5c, 0xb8, 0x7d, 0x1a, 0xa9, 0xea, 0xd8, 0xb4, 0x34, 0x76, - 0xe0, 0x20, 0x75, 0x29, 0x24, 0x0e, 0x7c, 0xd7, 0xb1, 0x29, 0x7e, 0x0c, 0xf3, 0x07, 0x56, 0x8b, - 0x58, 0x46, 0x28, 0x1c, 0x70, 0xe1, 0x72, 0xe1, 0x2a, 0x97, 0x6e, 0x15, 0xe6, 0x62, 0xb0, 0x81, - 0x94, 0xe5, 0xf3, 0x97, 0x8d, 0x40, 0x03, 0xf1, 0x2a, 0x2c, 0x44, 0x10, 0x4f, 0xdf, 0x39, 0xae, - 0x6f, 0xe4, 0xc0, 0x53, 0x78, 0x17, 0xce, 0x45, 0xc0, 0xb8, 0x42, 0xb9, 0x24, 0x85, 0xce, 0x86, - 0xf8, 0x68, 0x51, 0x7c, 0x22, 0x40, 0x31, 0xd2, 0x6a, 0x0c, 0xa3, 0xab, 0xda, 0xfc, 0xa4, 0xaa, - 0x5d, 0x0c, 0x5d, 0xec, 0x8d, 0xc6, 0x50, 0xc7, 0xe6, 0xd6, 0xa2, 0x3b, 0xe4, 0xf1, 0xf1, 0x2c, - 0x15, 0x21, 0x3f, 0x7e, 0x8e, 0xc3, 0x51, 0xff, 0x2b, 0x05, 0x62, 0x95, 0x9a, 0xf7, 0x0d, 0x63, - 0x9b, 0xf4, 0x91, 0xa5, 0x59, 0xac, 0x8e, 0x4d, 0x2a, 0x2e, 0x43, 0x86, 0x62, 0xd3, 0x42, 0xfe, - 0x84, 0xab, 0xfe, 0x97, 0xf8, 0x00, 0x52, 0xc1, 0x81, 0xf7, 0xce, 0x93, 0x92, 0xb2, 0x3b, 0xe2, - 0x15, 0x58, 0x88, 0x1a, 0xbb, 0xd9, 0xd6, 0x68, 0xdb, 0xbb, 0x98, 0xd4, 0x5c, 0xd8, 0xb2, 0x0f, - 0x35, 0xda, 0x16, 0xd7, 0x60, 0x31, 0x56, 0x14, 0x57, 0x45, 0xea, 0xcd, 0xa9, 0x3a, 0x1f, 0x35, - 0x2a, 0x8f, 0x58, 0x87, 0xc5, 0x78, 0x53, 0x70, 0xc1, 0x67, 0x26, 0x15, 0x7c, 0x3e, 0xd6, 0x53, - 0x6e, 0x83, 0xde, 0x03, 0x39, 0x0c, 0x67, 0xd4, 0x1b, 0x95, 0x32, 0x3c, 0xb0, 0xf3, 0x01, 0x62, - 0x6f, 0xc8, 0x96, 0x6e, 0x65, 0xdd, 0xf2, 0xf8, 0x42, 0x96, 0x2e, 0x80, 0xfc, 0x5f, 0xd9, 0xc3, - 0xaa, 0xfc, 0x2a, 0xc0, 0x62, 0x95, 0x9a, 0x95, 0xc6, 0xf6, 0x9e, 0xe5, 0xd7, 0x1c, 0x25, 0xd6, - 0x64, 0x8c, 0x96, 0xa9, 0x71, 0x5a, 0x8e, 0x53, 0x28, 0xfd, 0x9e, 0x15, 0x1a, 0x4e, 0x52, 0x06, - 0x69, 0x34, 0x8b, 0x30, 0xc5, 0x5f, 0x04, 0xb8, 0x50, 0xa5, 0x66, 0x1d, 0x75, 0x91, 0xce, 0x70, - 0x1f, 0x05, 0x8d, 0xbc, 0xeb, 0x5e, 0x45, 0x96, 0x3e, 0x79, 0xba, 0xeb, 0x70, 0xd6, 0x41, 0x3a, - 0xe9, 0x23, 0x07, 0x19, 0x4d, 0xff, 0xa8, 0xa7, 0xfe, 0xe5, 0xa1, 0x2e, 0x86, 0x5b, 0x0f, 0xdc, - 0x63, 0xbb, 0xde, 0x19, 0x0e, 0xfc, 0x0a, 0x5c, 0xfe, 0xbf, 0xd8, 0xc2, 0x24, 0x7e, 0x16, 0x60, - 0xa1, 0x4a, 0xcd, 0x3d, 0xdb, 0xd0, 0x18, 0xaa, 0xf1, 0xc7, 0xa7, 0x78, 0x07, 0x66, 0xb5, 0x03, - 0xd6, 0x26, 0x0e, 0x66, 0x87, 0x6f, 0xbd, 0x1f, 0x23, 0xa8, 0x78, 0x0f, 0x32, 0xde, 0xf3, 0xd5, - 0xbf, 0x21, 0x2f, 0x26, 0xdd, 0x90, 0x1c, 0x54, 0x99, 0x7e, 0x7e, 0x5c, 0x98, 0x52, 0x7d, 0x93, - 0xad, 0x79, 0x37, 0xfa, 0x88, 0xac, 0xb4, 0xc2, 0x5f, 0x39, 0xf1, 0xb8, 0x82, 0x98, 0x37, 0xff, - 0xcc, 0x40, 0xba, 0x4a, 0x4d, 0xf1, 0x07, 0x01, 0x96, 0x13, 0x9e, 0xa9, 0x37, 0x13, 0x5c, 0x27, - 0x3e, 0xaf, 0xe4, 0xcf, 0x4e, 0x6b, 0x11, 0x84, 0x23, 0x7e, 0x07, 0x4b, 0x63, 0x1f, 0x63, 0x4a, - 0x32, 0xe3, 0x38, 0xbc, 0x7c, 0xe7, 0x74, 0xf8, 0xd0, 0xff, 0xb7, 0x70, 0x76, 0xdc, 0x3b, 0x67, - 0xfd, 0x6d, 0x09, 0x0d, 0xc1, 0xe5, 0xdb, 0xa7, 0x82, 0x87, 0xce, 0x09, 0x2c, 0x8c, 0x9e, 0xbc, - 0xd7, 0x92, 0x99, 0x46, 0xa0, 0xf2, 0xc6, 0x89, 0xa1, 0xa1, 0x43, 0x0c, 0xb9, 0xe1, 0x43, 0xe5, - 0x6a, 0x32, 0xc7, 0x10, 0x50, 0x2e, 0x9f, 0x10, 0x18, 0xba, 0xfa, 0x51, 0x80, 0x95, 0xe4, 0xe9, - 0xbe, 0x95, 0x4c, 0x97, 0x68, 0x24, 0xdf, 0x7b, 0x07, 0xa3, 0x30, 0x9e, 0x7d, 0x98, 0x1b, 0x9a, - 0xd3, 0x2b, 0xc9, 0x64, 0x71, 0x9c, 0xac, 0x9c, 0x0c, 0x17, 0xf8, 0x91, 0x67, 0xbe, 0x7f, 0xf3, - 0xf4, 0xba, 0x50, 0x79, 0xfc, 0xfc, 0x55, 0x5e, 0x78, 0xf1, 0x2a, 0x2f, 0xfc, 0xf1, 0x2a, 0x2f, - 0xfc, 0xf4, 0x3a, 0x3f, 0xf5, 0xe2, 0x75, 0x7e, 0xea, 0xf7, 0xd7, 0xf9, 0xa9, 0xaf, 0xdf, 0x7a, - 0x67, 0x0e, 0xe2, 0xff, 0x2e, 0xf9, 0xb1, 0xdb, 0xca, 0xf0, 0x7f, 0x97, 0xb7, 0xfe, 0x0d, 0x00, - 0x00, 0xff, 0xff, 0xf6, 0xe9, 0xb3, 0x62, 0x79, 0x0f, 0x00, 0x00, + // 1263 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x13, 0xc7, + 0x17, 0xcf, 0xda, 0x89, 0xf9, 0xe6, 0x39, 0x4e, 0xf2, 0x5d, 0x42, 0xd8, 0x6c, 0xc1, 0x76, 0x0c, + 0x85, 0x40, 0xc9, 0x9a, 0x00, 0xa5, 0x34, 0x51, 0x0f, 0x38, 0x09, 0x02, 0x15, 0x17, 0x6b, 0xed, + 0xf4, 0x50, 0xa9, 0xb2, 0xd6, 0xbb, 0x93, 0xf5, 0xc8, 0xf6, 0xce, 0x76, 0x67, 0x62, 0x39, 0xaa, + 0x54, 0x55, 0x55, 0xaf, 0x95, 0x7a, 0xea, 0xa1, 0x7f, 0x05, 0x07, 0xfe, 0x86, 0x8a, 0x53, 0x85, + 0x38, 0x55, 0x39, 0x44, 0x15, 0x54, 0xe2, 0x6f, 0x68, 0x2f, 0xad, 0x76, 0xf6, 0xa7, 0x53, 0x6f, + 0x49, 0x70, 0x6e, 0xde, 0x99, 0xcf, 0xfb, 0xbc, 0xf7, 0x3e, 0xef, 0xbd, 0x99, 0x31, 0xe4, 0x5b, + 0x5a, 0x6b, 0xbf, 0x4b, 0xac, 0x72, 0x8b, 0xe9, 0x94, 0x69, 0x1d, 0x6c, 0x99, 0xe5, 0xfe, 0x5a, + 0x99, 0x0d, 0x14, 0xdb, 0x21, 0x8c, 0x88, 0xe7, 0xfc, 0x7d, 0x25, 0xda, 0x57, 0xfa, 0x6b, 0xf2, + 0x82, 0x49, 0x4c, 0xc2, 0x11, 0x65, 0xf7, 0x97, 0x07, 0x96, 0x97, 0x74, 0x42, 0x7b, 0x84, 0x36, + 0xbd, 0x0d, 0xef, 0xc3, 0xdf, 0x3a, 0xef, 0x7d, 0x95, 0x7b, 0x94, 0xf3, 0xf7, 0xa8, 0xe9, 0x6f, + 0x94, 0x46, 0x07, 0x60, 0x6b, 0x8e, 0xd6, 0x0b, 0x8c, 0x6f, 0xc4, 0x30, 0x7a, 0x1b, 0xe9, 0x1d, + 0x9b, 0x60, 0x8b, 0xb9, 0xb0, 0xa1, 0x05, 0x1f, 0x7d, 0xd9, 0x77, 0x15, 0xb1, 0xb5, 0x10, 0xd3, + 0xd6, 0x82, 0x6f, 0x1f, 0x55, 0x48, 0xf0, 0x4b, 0x6c, 0x0f, 0x50, 0xfa, 0x2b, 0x05, 0x4b, 0x55, + 0x6a, 0x6e, 0x3a, 0x48, 0x63, 0xe8, 0x01, 0xb6, 0xb4, 0x2e, 0x66, 0xfb, 0x35, 0x87, 0xf4, 0xb1, + 0x81, 0x1c, 0xf1, 0x06, 0x4c, 0x6a, 0x86, 0xe1, 0x48, 0x42, 0x51, 0x58, 0x99, 0xae, 0x48, 0x2f, + 0x9f, 0xad, 0x2e, 0xf8, 0xf9, 0xde, 0x37, 0x0c, 0x07, 0x51, 0x5a, 0x67, 0x0e, 0xb6, 0x4c, 0x95, + 0xa3, 0xc4, 0x6d, 0xc8, 0x1a, 0x88, 0xea, 0x0e, 0xb6, 0x19, 0x26, 0x96, 0x94, 0x2a, 0x0a, 0x2b, + 0xd9, 0x5b, 0x97, 0x14, 0xdf, 0x22, 0xd2, 0x95, 0x07, 0xaa, 0x6c, 0x45, 0x50, 0x35, 0x6e, 0x27, + 0x56, 0x01, 0x74, 0xd2, 0xeb, 0x61, 0x4a, 0x5d, 0x96, 0x34, 0x77, 0xbd, 0x7a, 0x70, 0x58, 0x78, + 0xcf, 0x23, 0xa2, 0x46, 0x47, 0xc1, 0xa4, 0xdc, 0xd3, 0x58, 0x5b, 0x79, 0x8c, 0x4c, 0x4d, 0xdf, + 0xdf, 0x42, 0xfa, 0xcb, 0x67, 0xab, 0xe0, 0xfb, 0xd9, 0x42, 0xba, 0x1a, 0x23, 0x10, 0x9f, 0x40, + 0xa6, 0xc5, 0xf4, 0xa6, 0xdd, 0x91, 0x26, 0x8b, 0xc2, 0xca, 0x4c, 0xe5, 0xde, 0xc1, 0x61, 0xe1, + 0x8e, 0x89, 0x59, 0x7b, 0xaf, 0xa5, 0xe8, 0xa4, 0x57, 0xf6, 0x15, 0xea, 0x6a, 0x2d, 0xba, 0x8a, + 0x49, 0xf0, 0x59, 0x66, 0xfb, 0x36, 0xa2, 0x4a, 0xe5, 0x51, 0xed, 0xf6, 0x9d, 0x9b, 0xb5, 0xbd, + 0xd6, 0xa7, 0x68, 0x5f, 0x9d, 0x6a, 0x31, 0xbd, 0xd6, 0x11, 0x3f, 0x81, 0xb4, 0x4d, 0x6c, 0x69, + 0x8a, 0xa7, 0xf7, 0x81, 0x32, 0xb2, 0x75, 0x94, 0x9a, 0x43, 0xc8, 0xee, 0x93, 0xdd, 0x1a, 0xa1, + 0x14, 0xf1, 0x38, 0x2a, 0x8d, 0x4d, 0xd5, 0xb5, 0x5b, 0x9f, 0xfe, 0xee, 0xcd, 0xd3, 0xeb, 0x5c, + 0xb0, 0xd2, 0x25, 0x58, 0x4e, 0xd4, 0x5e, 0x45, 0xd4, 0x26, 0x16, 0x45, 0xa5, 0xbf, 0x05, 0x38, + 0x5f, 0xa5, 0xe6, 0xb6, 0x81, 0xd9, 0x98, 0xf5, 0x39, 0x17, 0x2a, 0xe1, 0x96, 0x66, 0x26, 0xc8, + 0xe7, 0x48, 0xd9, 0xd2, 0xa7, 0x52, 0xb6, 0xc9, 0x31, 0xcb, 0x16, 0x97, 0x69, 0x19, 0x0a, 0x09, + 0x02, 0x84, 0x22, 0xfd, 0x7a, 0x06, 0x16, 0x43, 0x29, 0x2b, 0x8d, 0xcd, 0x2d, 0xd4, 0x45, 0xa6, + 0xc6, 0xe3, 0xfa, 0x18, 0xb2, 0x6e, 0x0e, 0xc8, 0x69, 0x1e, 0x4b, 0x2a, 0xf0, 0xc0, 0xee, 0x62, + 0x50, 0xe9, 0xd4, 0xbb, 0x55, 0x3a, 0xd6, 0x79, 0xe9, 0xd3, 0xe9, 0xbc, 0x2f, 0x61, 0x76, 0xd7, + 0x6e, 0x7a, 0x9c, 0xcd, 0x2e, 0xa6, 0x4c, 0x9a, 0x2c, 0xa6, 0xc7, 0x22, 0xce, 0xee, 0xda, 0x15, + 0x97, 0xfa, 0x31, 0xa6, 0x4c, 0x5c, 0x86, 0x19, 0x3f, 0xaf, 0x26, 0xc3, 0x3d, 0xc4, 0x3b, 0x3c, + 0xa7, 0x66, 0xfd, 0xb5, 0x06, 0xee, 0x21, 0xf1, 0x12, 0xe4, 0x02, 0x48, 0x5f, 0xeb, 0xee, 0x21, + 0x29, 0x53, 0x14, 0x56, 0xd2, 0x6a, 0x60, 0xf7, 0xb9, 0xbb, 0x26, 0x3e, 0x04, 0x08, 0x79, 0x06, + 0xd2, 0x19, 0xae, 0xde, 0xb5, 0xb8, 0x7a, 0xb1, 0xc3, 0xac, 0xbf, 0xa6, 0x34, 0x1c, 0xcd, 0xa2, + 0x9a, 0xee, 0x16, 0xeb, 0x91, 0xb5, 0x4b, 0xd4, 0xe9, 0xc0, 0xe1, 0x40, 0xbc, 0x05, 0x59, 0xda, + 0xd5, 0x68, 0xdb, 0xa7, 0xfa, 0x1f, 0x97, 0xf1, 0xff, 0x07, 0x87, 0x85, 0x5c, 0xa5, 0xb1, 0x59, + 0xf7, 0x77, 0x1a, 0x03, 0x15, 0x68, 0xf8, 0x5b, 0xfc, 0x0a, 0x16, 0x0d, 0xaf, 0xfa, 0xc4, 0x69, + 0x86, 0xd6, 0x14, 0x9b, 0xd2, 0x34, 0x37, 0xdf, 0x38, 0x38, 0x2c, 0x7c, 0x74, 0x32, 0xb1, 0xea, + 0xd8, 0xb4, 0x34, 0xb6, 0xe7, 0x20, 0x75, 0x21, 0xa4, 0x0e, 0xbc, 0xd7, 0xb1, 0x29, 0xbe, 0x0f, + 0xb3, 0x7b, 0x56, 0x8b, 0x58, 0x46, 0x28, 0x1d, 0x70, 0xe9, 0x72, 0xe1, 0x2a, 0x17, 0x6f, 0x19, + 0x66, 0x62, 0xb0, 0x81, 0x94, 0xe5, 0x53, 0x98, 0x8d, 0x40, 0x03, 0xf1, 0x2a, 0xcc, 0x45, 0x10, + 0x4f, 0xe1, 0x19, 0xae, 0x70, 0xe4, 0xc0, 0xd3, 0x78, 0x1b, 0xce, 0x45, 0xc0, 0xb8, 0x46, 0xb9, + 0x24, 0x8d, 0xce, 0x86, 0xf8, 0x68, 0x51, 0xfc, 0x5e, 0x80, 0x62, 0xa4, 0xd6, 0x08, 0x46, 0x57, + 0xb7, 0xd9, 0xf1, 0x75, 0xbb, 0x18, 0x3a, 0xd9, 0x39, 0x1a, 0x45, 0x1d, 0x9b, 0xeb, 0xf3, 0xee, + 0xb0, 0xc7, 0xc7, 0xb4, 0x54, 0x84, 0xfc, 0xe8, 0x79, 0x0e, 0x47, 0xfe, 0xcf, 0x14, 0x88, 0x55, + 0x6a, 0xde, 0x37, 0x8c, 0x4d, 0xd2, 0x47, 0x96, 0x66, 0xb1, 0x3a, 0x36, 0xa9, 0xb8, 0x08, 0x19, + 0x8a, 0x4d, 0x0b, 0xf9, 0x93, 0xae, 0xfa, 0x5f, 0xe2, 0x43, 0x48, 0x05, 0x07, 0xdf, 0x18, 0xf3, + 0x92, 0xb2, 0x3b, 0xe2, 0x15, 0x98, 0x8b, 0xda, 0xbb, 0xd9, 0xd6, 0x68, 0xdb, 0xbb, 0xa4, 0xd4, + 0x5c, 0xd8, 0xb8, 0x0f, 0x35, 0xda, 0x16, 0x57, 0x60, 0x3e, 0x56, 0x18, 0x57, 0x49, 0xea, 0xcd, + 0xab, 0x3a, 0x1b, 0xb5, 0x2b, 0x8f, 0x19, 0xc1, 0x7c, 0xbc, 0x31, 0xb8, 0xe8, 0x53, 0xe3, 0x8b, + 0x3e, 0x1b, 0xeb, 0x2c, 0xb7, 0x4d, 0x37, 0x40, 0x0e, 0x03, 0x3a, 0xea, 0x8f, 0x4a, 0x19, 0x1e, + 0xda, 0xf9, 0x00, 0xb1, 0x33, 0x64, 0x4b, 0xd7, 0xb3, 0x6e, 0x89, 0x7c, 0x31, 0x4b, 0x17, 0x40, + 0xfe, 0xb7, 0xf4, 0x61, 0x65, 0x7e, 0x11, 0x60, 0xbe, 0x4a, 0xcd, 0x4a, 0x63, 0x73, 0xc7, 0xf2, + 0xeb, 0x8e, 0x12, 0xeb, 0x32, 0x42, 0xcd, 0xd4, 0x28, 0x35, 0x47, 0x69, 0x94, 0x3e, 0x75, 0x8d, + 0x86, 0xd3, 0x94, 0x41, 0x3a, 0x9a, 0x47, 0x98, 0xe4, 0xcf, 0x02, 0x5c, 0xa8, 0x52, 0xb3, 0x8e, + 0xba, 0x48, 0x67, 0xb8, 0x8f, 0x82, 0x76, 0xde, 0x76, 0x2f, 0x26, 0x4b, 0x1f, 0x3f, 0xe1, 0x55, + 0x38, 0xeb, 0x20, 0x9d, 0xf4, 0x91, 0x83, 0x8c, 0xa6, 0x7f, 0xec, 0x53, 0xff, 0x2a, 0x51, 0xe7, + 0xc3, 0xad, 0x07, 0xee, 0x01, 0x5e, 0xef, 0x0c, 0x07, 0x7e, 0x05, 0x2e, 0xff, 0x57, 0x6c, 0x61, + 0x12, 0x3f, 0x09, 0x30, 0x57, 0xa5, 0xe6, 0x8e, 0x6d, 0x68, 0x0c, 0xd5, 0xf8, 0x63, 0x54, 0xbc, + 0x0b, 0xd3, 0xda, 0x1e, 0x6b, 0x13, 0x07, 0xb3, 0xfd, 0xb7, 0xde, 0x96, 0x11, 0x54, 0xdc, 0x80, + 0x8c, 0xf7, 0x9c, 0xf5, 0xef, 0xcb, 0x8b, 0x49, 0xf7, 0x25, 0x07, 0x55, 0x26, 0x9f, 0x1f, 0x16, + 0x26, 0x54, 0xdf, 0x64, 0x7d, 0xd6, 0x8d, 0x3e, 0x22, 0x2b, 0x2d, 0xf1, 0x37, 0x4f, 0x3c, 0xae, + 0x20, 0xe6, 0x5b, 0x7f, 0x64, 0x20, 0x5d, 0xa5, 0xa6, 0x7b, 0x74, 0x2d, 0x26, 0x3c, 0x5b, 0x6f, + 0x26, 0xb8, 0x4e, 0x7c, 0x6c, 0xc9, 0xf7, 0x4e, 0x6a, 0x11, 0x84, 0x23, 0x7e, 0x03, 0x0b, 0x23, + 0x9f, 0x66, 0x4a, 0x32, 0xe3, 0x28, 0xbc, 0x7c, 0xf7, 0x64, 0xf8, 0xd0, 0xff, 0xd7, 0x70, 0x76, + 0xd4, 0xab, 0x67, 0xf5, 0x6d, 0x09, 0x0d, 0xc1, 0xe5, 0x0f, 0x4f, 0x04, 0x0f, 0x9d, 0x13, 0x98, + 0x3b, 0x7a, 0xfe, 0x5e, 0x4b, 0x66, 0x3a, 0x02, 0x95, 0xd7, 0x8e, 0x0d, 0x0d, 0x1d, 0x62, 0xc8, + 0x0d, 0x1f, 0x2b, 0x57, 0x93, 0x39, 0x86, 0x80, 0x72, 0xf9, 0x98, 0xc0, 0xd0, 0xd5, 0x0f, 0x02, + 0x2c, 0x25, 0x4f, 0xf7, 0xed, 0x64, 0xba, 0x44, 0x23, 0x79, 0xe3, 0x1d, 0x8c, 0xc2, 0x78, 0x76, + 0x61, 0x66, 0x68, 0x4e, 0xaf, 0x24, 0x93, 0xc5, 0x71, 0xb2, 0x72, 0x3c, 0x5c, 0xe0, 0x47, 0x9e, + 0xfa, 0xf6, 0xcd, 0xd3, 0xeb, 0x42, 0xe5, 0xb3, 0xe7, 0xaf, 0xf2, 0xc2, 0x8b, 0x57, 0x79, 0xe1, + 0xf7, 0x57, 0x79, 0xe1, 0xc7, 0xd7, 0xf9, 0x89, 0x17, 0xaf, 0xf3, 0x13, 0xbf, 0xbd, 0xce, 0x4f, + 0x7c, 0x71, 0x8c, 0x9b, 0x73, 0x10, 0xff, 0xbf, 0xc9, 0x0f, 0xde, 0x56, 0x86, 0xff, 0xdf, 0xbc, + 0xfd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x82, 0xd4, 0xb3, 0x90, 0x8b, 0x0f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2368,7 +2368,7 @@ func (m *MsgCreateFinalityProvider) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2845,7 +2845,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPk = &v if err := m.BtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -2880,7 +2880,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPkList = append(m.FpBtcPkList, v) if err := m.FpBtcPkList[len(m.FpBtcPkList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3024,7 +3024,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.DelegatorSlashingSig = &v if err := m.DelegatorSlashingSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3166,7 +3166,7 @@ func (m *MsgCreateBTCDelegation) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.DelegatorUnbondingSlashingSig = &v if err := m.DelegatorUnbondingSlashingSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3333,7 +3333,7 @@ func (m *MsgAddCovenantSigs) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.Pk = &v if err := m.Pk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3432,7 +3432,7 @@ func (m *MsgAddCovenantSigs) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.UnbondingTxSig = &v if err := m.UnbondingTxSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -3663,7 +3663,7 @@ func (m *MsgBTCUndelegate) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.UnbondingTxSig = &v if err := m.UnbondingTxSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/checkpointing/README.md b/x/checkpointing/README.md index e95bfdc6d..565e5d467 100644 --- a/x/checkpointing/README.md +++ b/x/checkpointing/README.md @@ -102,7 +102,7 @@ message RawCheckpoint { // sigs bytes bls_multi_sig = 4 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } // RawCheckpointWithMeta wraps the raw checkpoint with metadata. @@ -115,7 +115,7 @@ message RawCheckpointWithMeta { // bls_aggr_pk defines the aggregated BLS public key bytes bls_aggr_pk = 3 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.PublicKey" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" ]; // power_sum defines the accumulated voting power for the checkpoint uint64 power_sum = 4; // lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -300,7 +300,7 @@ message VoteExtension { // bls_sig is the BLS signature bytes bls_sig = 6 [ (gogoproto.customtype) = - "github.com/babylonchain/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; } ``` diff --git a/x/checkpointing/abci.go b/x/checkpointing/abci.go index 15f5d4db9..760fbf895 100644 --- a/x/checkpointing/abci.go +++ b/x/checkpointing/abci.go @@ -5,9 +5,9 @@ import ( "fmt" "time" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" - "github.com/babylonchain/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" "github.com/cosmos/cosmos-sdk/telemetry" ) diff --git a/x/checkpointing/client/cli/query.go b/x/checkpointing/client/cli/query.go index d26a5bb07..fa5b4d59a 100644 --- a/x/checkpointing/client/cli/query.go +++ b/x/checkpointing/client/cli/query.go @@ -12,7 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/checkpointing/client/cli/tx.go b/x/checkpointing/client/cli/tx.go index 371caa21a..8de4578b0 100644 --- a/x/checkpointing/client/cli/tx.go +++ b/x/checkpointing/client/cli/tx.go @@ -9,7 +9,7 @@ import ( "cosmossdk.io/core/address" authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" - appparams "github.com/babylonchain/babylon/app/params" + appparams "github.com/babylonlabs-io/babylon/app/params" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -18,7 +18,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" // "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // GetTxCmd returns the transaction commands for this module diff --git a/x/checkpointing/client/cli/tx_test.go b/x/checkpointing/client/cli/tx_test.go index 1f35f1106..bee75d842 100644 --- a/x/checkpointing/client/cli/tx_test.go +++ b/x/checkpointing/client/cli/tx_test.go @@ -26,11 +26,11 @@ import ( authcodec "github.com/cosmos/cosmos-sdk/x/auth/codec" "github.com/stretchr/testify/suite" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/privval" - testutilcli "github.com/babylonchain/babylon/testutil/cli" - checkpointcli "github.com/babylonchain/babylon/x/checkpointing/client/cli" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/privval" + testutilcli "github.com/babylonlabs-io/babylon/testutil/cli" + checkpointcli "github.com/babylonlabs-io/babylon/x/checkpointing/client/cli" ) type mockCometRPC struct { diff --git a/x/checkpointing/client/cli/utils.go b/x/checkpointing/client/cli/utils.go index 50d049123..c30ad96dd 100644 --- a/x/checkpointing/client/cli/utils.go +++ b/x/checkpointing/client/cli/utils.go @@ -23,8 +23,8 @@ import ( staketypes "github.com/cosmos/cosmos-sdk/x/staking/types" flag "github.com/spf13/pflag" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // validator struct to define the fields of the validator diff --git a/x/checkpointing/genesis.go b/x/checkpointing/genesis.go index f285f08d1..b8449d647 100644 --- a/x/checkpointing/genesis.go +++ b/x/checkpointing/genesis.go @@ -3,8 +3,8 @@ package checkpointing import ( "context" - "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // InitGenesis initializes the capability module's state from a provided genesis diff --git a/x/checkpointing/genesis_test.go b/x/checkpointing/genesis_test.go index ba7e05bac..e6e9c18cf 100644 --- a/x/checkpointing/genesis_test.go +++ b/x/checkpointing/genesis_test.go @@ -3,17 +3,17 @@ package checkpointing_test import ( "testing" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/x/checkpointing" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/x/checkpointing" "github.com/cometbft/cometbft/crypto/ed25519" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" cosmosed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - simapp "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/x/checkpointing/types" + simapp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func TestInitGenesis(t *testing.T) { diff --git a/x/checkpointing/keeper/bls_signer.go b/x/checkpointing/keeper/bls_signer.go index 54e3ba974..8e7eb0ad8 100644 --- a/x/checkpointing/keeper/bls_signer.go +++ b/x/checkpointing/keeper/bls_signer.go @@ -4,8 +4,8 @@ import ( "github.com/cometbft/cometbft/crypto" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) type BlsSigner interface { diff --git a/x/checkpointing/keeper/bls_signer_test.go b/x/checkpointing/keeper/bls_signer_test.go index a6b367238..d11ee3727 100644 --- a/x/checkpointing/keeper/bls_signer_test.go +++ b/x/checkpointing/keeper/bls_signer_test.go @@ -4,8 +4,8 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/crypto/bls12381" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) var ( diff --git a/x/checkpointing/keeper/ckpt_state.go b/x/checkpointing/keeper/ckpt_state.go index 3cc30b4e2..72bf7a290 100644 --- a/x/checkpointing/keeper/ckpt_state.go +++ b/x/checkpointing/keeper/ckpt_state.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/checkpointing/keeper/genesis_bls.go b/x/checkpointing/keeper/genesis_bls.go index 71c3cab2e..7c404179e 100644 --- a/x/checkpointing/keeper/genesis_bls.go +++ b/x/checkpointing/keeper/genesis_bls.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/checkpointing/keeper/grpc_query_bls.go b/x/checkpointing/keeper/grpc_query_bls.go index ce9dfe4ac..35efb113f 100644 --- a/x/checkpointing/keeper/grpc_query_bls.go +++ b/x/checkpointing/keeper/grpc_query_bls.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/jinzhu/copier" "google.golang.org/grpc/codes" diff --git a/x/checkpointing/keeper/grpc_query_bls_test.go b/x/checkpointing/keeper/grpc_query_bls_test.go index 8ec938bd8..d6f74661f 100644 --- a/x/checkpointing/keeper/grpc_query_bls_test.go +++ b/x/checkpointing/keeper/grpc_query_bls_test.go @@ -10,11 +10,11 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + checkpointingkeeper "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // FuzzQueryBLSKeySet does the following checks diff --git a/x/checkpointing/keeper/grpc_query_checkpoint.go b/x/checkpointing/keeper/grpc_query_checkpoint.go index b4f1810d9..fa56c1843 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint.go @@ -9,7 +9,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/checkpointing/keeper/grpc_query_checkpoint_test.go b/x/checkpointing/keeper/grpc_query_checkpoint_test.go index c19342ecc..9da76a426 100644 --- a/x/checkpointing/keeper/grpc_query_checkpoint_test.go +++ b/x/checkpointing/keeper/grpc_query_checkpoint_test.go @@ -7,18 +7,18 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" - "github.com/babylonchain/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" "github.com/golang/mock/gomock" - "github.com/babylonchain/babylon/testutil/mocks" - "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/testutil/mocks" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" ) func FuzzQueryEpoch(f *testing.F) { diff --git a/x/checkpointing/keeper/hooks.go b/x/checkpointing/keeper/hooks.go index 5dcd29a80..8018c800f 100644 --- a/x/checkpointing/keeper/hooks.go +++ b/x/checkpointing/keeper/hooks.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/checkpointing/keeper/keeper.go b/x/checkpointing/keeper/keeper.go index e33ed4f79..59f9a9c7f 100644 --- a/x/checkpointing/keeper/keeper.go +++ b/x/checkpointing/keeper/keeper.go @@ -7,7 +7,7 @@ import ( corestoretypes "cosmossdk.io/core/store" - txformat "github.com/babylonchain/babylon/btctxformatter" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" "cosmossdk.io/log" "github.com/cosmos/cosmos-sdk/codec" @@ -15,9 +15,9 @@ import ( cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) type ( diff --git a/x/checkpointing/keeper/keeper_test.go b/x/checkpointing/keeper/keeper_test.go index 4dd46f58d..1316f363a 100644 --- a/x/checkpointing/keeper/keeper_test.go +++ b/x/checkpointing/keeper/keeper_test.go @@ -10,12 +10,12 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/mocks" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/mocks" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // FuzzKeeperAddRawCheckpoint checks diff --git a/x/checkpointing/keeper/msg_server.go b/x/checkpointing/keeper/msg_server.go index 04a088763..40c084723 100644 --- a/x/checkpointing/keeper/msg_server.go +++ b/x/checkpointing/keeper/msg_server.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) type msgServer struct { diff --git a/x/checkpointing/keeper/msg_server_test.go b/x/checkpointing/keeper/msg_server_test.go index e8b32e471..fffba8d6e 100644 --- a/x/checkpointing/keeper/msg_server_test.go +++ b/x/checkpointing/keeper/msg_server_test.go @@ -11,15 +11,15 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/app" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + checkpointingkeeper "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) // FuzzWrappedCreateValidator_InsufficientTokens tests adding new validators with zero voting power diff --git a/x/checkpointing/keeper/registration_state.go b/x/checkpointing/keeper/registration_state.go index 84a052c68..968a4d185 100644 --- a/x/checkpointing/keeper/registration_state.go +++ b/x/checkpointing/keeper/registration_state.go @@ -5,8 +5,8 @@ import ( "cosmossdk.io/store/prefix" storetypes "cosmossdk.io/store/types" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/checkpointing/keeper/val_bls_set.go b/x/checkpointing/keeper/val_bls_set.go index a3ba8df88..96815405e 100644 --- a/x/checkpointing/keeper/val_bls_set.go +++ b/x/checkpointing/keeper/val_bls_set.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" "fmt" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/checkpointing/keeper/val_bls_set_test.go b/x/checkpointing/keeper/val_bls_set_test.go index 1c4e84292..36f4cf822 100644 --- a/x/checkpointing/keeper/val_bls_set_test.go +++ b/x/checkpointing/keeper/val_bls_set_test.go @@ -9,11 +9,11 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - checkpointingkeeper "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + checkpointingkeeper "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) func FuzzGetValidatorBlsKeySet(f *testing.F) { diff --git a/x/checkpointing/module.go b/x/checkpointing/module.go index 7e5cb77cc..ff29c666f 100644 --- a/x/checkpointing/module.go +++ b/x/checkpointing/module.go @@ -13,9 +13,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/checkpointing/client/cli" - "github.com/babylonchain/babylon/x/checkpointing/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/client/cli" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/checkpointing/proposal.go b/x/checkpointing/proposal.go index b9d3a3696..68748c460 100644 --- a/x/checkpointing/proposal.go +++ b/x/checkpointing/proposal.go @@ -13,7 +13,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" + ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) const defaultInjectedTxIndex = 0 diff --git a/x/checkpointing/proposal_expected_keeper.go b/x/checkpointing/proposal_expected_keeper.go index 920c2eeb2..697ed90d6 100644 --- a/x/checkpointing/proposal_expected_keeper.go +++ b/x/checkpointing/proposal_expected_keeper.go @@ -3,9 +3,9 @@ package checkpointing import ( "context" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" cmtprotocrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/checkpointing/proposal_test.go b/x/checkpointing/proposal_test.go index b754547a7..afd88afd4 100644 --- a/x/checkpointing/proposal_test.go +++ b/x/checkpointing/proposal_test.go @@ -20,13 +20,13 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/testutil/mocks" - "github.com/babylonchain/babylon/x/checkpointing" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - et "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/testutil/mocks" + "github.com/babylonlabs-io/babylon/x/checkpointing" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + et "github.com/babylonlabs-io/babylon/x/epoching/types" ) type TestValidator struct { diff --git a/x/checkpointing/types/bls_key.pb.go b/x/checkpointing/types/bls_key.pb.go index cc2cd6b74..ca65cdc8f 100644 --- a/x/checkpointing/types/bls_key.pb.go +++ b/x/checkpointing/types/bls_key.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_crypto_bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + github_com_babylonlabs_io_babylon_crypto_bls12381 "github.com/babylonlabs-io/babylon/crypto/bls12381" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -27,7 +27,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // BlsKey wraps BLS public key with PoP type BlsKey struct { // pubkey is the BLS public key of a validator - Pubkey *github_com_babylonchain_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,1,opt,name=pubkey,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.PublicKey" json:"pubkey,omitempty"` + Pubkey *github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,1,opt,name=pubkey,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" json:"pubkey,omitempty"` // pop is the proof-of-possession of the BLS key Pop *ProofOfPossession `protobuf:"bytes,2,opt,name=pop,proto3" json:"pop,omitempty"` } @@ -80,7 +80,7 @@ type ProofOfPossession struct { Ed25519Sig []byte `protobuf:"bytes,1,opt,name=ed25519_sig,json=ed25519Sig,proto3" json:"ed25519_sig,omitempty"` // bls_sig is the result of PoP, bls_sig = sign(key = BLS_sk, data = // ed25519_sig) - BlsSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,2,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` + BlsSig *github_com_babylonlabs_io_babylon_crypto_bls12381.Signature `protobuf:"bytes,2,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` } func (m *ProofOfPossession) Reset() { *m = ProofOfPossession{} } @@ -246,7 +246,7 @@ type VoteExtension struct { // height is the height of the vote extension Height uint64 `protobuf:"varint,5,opt,name=height,proto3" json:"height,omitempty"` // bls_sig is the BLS signature - BlsSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,6,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` + BlsSig *github_com_babylonlabs_io_babylon_crypto_bls12381.Signature `protobuf:"bytes,6,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` } func (m *VoteExtension) Reset() { *m = VoteExtension{} } @@ -324,40 +324,40 @@ func init() { var fileDescriptor_3a8c0d37ce63f038 = []byte{ // 534 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4f, 0x8b, 0xd3, 0x4e, - 0x18, 0xc7, 0x3b, 0xed, 0xfe, 0xb2, 0xbf, 0x4e, 0xbb, 0xe0, 0x46, 0x59, 0x82, 0x42, 0x5a, 0x7b, - 0x90, 0xc2, 0x6a, 0x42, 0xbb, 0x14, 0xdc, 0xc3, 0x1e, 0x2c, 0x28, 0xc2, 0x82, 0x5b, 0x52, 0xac, - 0xe0, 0x25, 0x66, 0xd2, 0xd9, 0xcc, 0xd0, 0x69, 0x66, 0xc8, 0x4c, 0xe2, 0xe6, 0x05, 0x78, 0x13, - 0xf4, 0x15, 0xf8, 0x7a, 0x3c, 0xee, 0x51, 0xf6, 0xb0, 0x48, 0xfb, 0x46, 0x64, 0x92, 0xb8, 0xf8, - 0xa7, 0x45, 0x10, 0x6f, 0x33, 0xdf, 0xef, 0x93, 0xef, 0x7c, 0x9e, 0x67, 0x32, 0xf0, 0x01, 0x0a, - 0x50, 0xce, 0x78, 0xec, 0x86, 0x04, 0x87, 0x0b, 0xc1, 0x69, 0xac, 0x68, 0x1c, 0xb9, 0xd9, 0xc0, - 0x45, 0x4c, 0xfa, 0x0b, 0x9c, 0x3b, 0x22, 0xe1, 0x8a, 0x9b, 0x56, 0x55, 0xe7, 0xfc, 0x54, 0xe7, - 0x64, 0x83, 0xbb, 0x77, 0x22, 0x1e, 0xf1, 0xa2, 0xc8, 0xd5, 0xab, 0xb2, 0xbe, 0xf7, 0x09, 0x40, - 0x63, 0xcc, 0xe4, 0x29, 0xce, 0xcd, 0x97, 0xd0, 0x10, 0x29, 0x5a, 0xe0, 0xdc, 0x02, 0x5d, 0xd0, - 0x6f, 0x8f, 0x4f, 0xae, 0xae, 0x3b, 0xc7, 0x11, 0x55, 0x24, 0x45, 0x4e, 0xc8, 0x97, 0x6e, 0x95, - 0x1c, 0x92, 0x80, 0xc6, 0xee, 0x0d, 0x4e, 0x92, 0x0b, 0xc5, 0x35, 0xc4, 0x60, 0x78, 0xf4, 0x78, - 0xe0, 0x4c, 0x52, 0xc4, 0x68, 0x78, 0x8a, 0x73, 0xaf, 0x0a, 0x33, 0x4f, 0x60, 0x43, 0x70, 0x61, - 0xd5, 0xbb, 0xa0, 0xdf, 0x1a, 0x1e, 0x3a, 0xdb, 0xf8, 0x9c, 0x49, 0xc2, 0xf9, 0xf9, 0xd9, 0xf9, - 0x84, 0x4b, 0x89, 0xa5, 0xa4, 0x3c, 0xf6, 0xf4, 0x77, 0xbd, 0xf7, 0x00, 0xee, 0xff, 0x66, 0x99, - 0x1d, 0xd8, 0xc2, 0xf3, 0xe1, 0x68, 0x34, 0x38, 0xf6, 0x25, 0x8d, 0x4a, 0x60, 0x0f, 0x56, 0xd2, - 0x94, 0x46, 0xe6, 0x0c, 0xee, 0xea, 0xc1, 0x68, 0xb3, 0xfe, 0xf7, 0xdd, 0x4c, 0x69, 0x14, 0x07, - 0x2a, 0x4d, 0xb0, 0x67, 0x20, 0x26, 0xa7, 0x34, 0xea, 0xbd, 0x81, 0x07, 0xb3, 0x80, 0xd1, 0x79, - 0xa0, 0x78, 0xf2, 0x8a, 0x2a, 0x52, 0xce, 0x6e, 0x8a, 0x95, 0xf9, 0x0c, 0xee, 0x66, 0x01, 0xf3, - 0x25, 0x56, 0x16, 0xe8, 0x36, 0xfa, 0xad, 0xe1, 0xa3, 0xed, 0xbd, 0x6e, 0x88, 0xf0, 0x8c, 0x2c, - 0x60, 0x53, 0xac, 0x7a, 0xef, 0x00, 0xbc, 0xbd, 0xc1, 0x37, 0x0f, 0xe1, 0x7e, 0xf6, 0x5d, 0xf6, - 0x83, 0xf9, 0x3c, 0xc1, 0x52, 0x16, 0x8d, 0x37, 0xbd, 0x5b, 0x37, 0xc6, 0x93, 0x52, 0x37, 0x6d, - 0xd8, 0xd2, 0xed, 0x8b, 0x14, 0xe9, 0x7f, 0xa3, 0x1c, 0x81, 0xd7, 0x44, 0x4c, 0x4e, 0x52, 0xa4, - 0xc3, 0xee, 0xc3, 0x76, 0xc6, 0x35, 0x8d, 0x2f, 0xf8, 0x5b, 0x9c, 0x58, 0x8d, 0x2e, 0xe8, 0xef, - 0x78, 0xad, 0x52, 0x9b, 0x68, 0xa9, 0xf7, 0xa1, 0x0e, 0xf7, 0x66, 0x5c, 0xe1, 0xa7, 0x17, 0x0a, - 0xc7, 0xc5, 0xd0, 0x0f, 0xa0, 0x21, 0x69, 0x14, 0xe3, 0xa4, 0x3a, 0xb6, 0xda, 0x6d, 0x26, 0xab, - 0x6f, 0x21, 0x7b, 0x08, 0x21, 0x62, 0x3c, 0x5c, 0xf8, 0x24, 0x90, 0xa4, 0x38, 0xb7, 0x3d, 0xde, - 0xbb, 0xba, 0xee, 0x34, 0xc7, 0x5a, 0x7d, 0x1e, 0x48, 0xa2, 0x39, 0xab, 0xa5, 0x79, 0x0f, 0x36, - 0xb1, 0xe0, 0x21, 0xf1, 0xe3, 0x74, 0x69, 0xed, 0x14, 0x90, 0xff, 0x17, 0xc2, 0x8b, 0x74, 0xa9, - 0x79, 0x08, 0xa6, 0x11, 0x51, 0xd6, 0x7f, 0x85, 0x53, 0xed, 0x7e, 0xbc, 0x7b, 0xe3, 0x1f, 0xde, - 0xfd, 0xf8, 0xec, 0xf3, 0xca, 0x06, 0x97, 0x2b, 0x1b, 0x7c, 0x5d, 0xd9, 0xe0, 0xe3, 0xda, 0xae, - 0x5d, 0xae, 0xed, 0xda, 0x97, 0xb5, 0x5d, 0x7b, 0x3d, 0xfa, 0x53, 0xf8, 0xc5, 0x2f, 0xef, 0x56, - 0xe5, 0x02, 0x4b, 0x64, 0x14, 0x6f, 0xf0, 0xe8, 0x5b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xf8, - 0x77, 0x30, 0xdd, 0x03, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x93, 0x4f, 0x8b, 0xd3, 0x40, + 0x18, 0xc6, 0x3b, 0xed, 0x9a, 0xb5, 0xd3, 0x2e, 0xb8, 0x51, 0x96, 0xa0, 0x90, 0xd6, 0x1e, 0xa4, + 0xb0, 0x6e, 0x42, 0xbb, 0x2c, 0x2a, 0x22, 0x62, 0x41, 0x11, 0x16, 0xb4, 0xa6, 0xb0, 0x2b, 0x5e, + 0x62, 0x26, 0x9d, 0x4d, 0x86, 0x4e, 0xf3, 0x86, 0xcc, 0x24, 0x6e, 0x3e, 0x80, 0x57, 0xd1, 0x6f, + 0xe0, 0xc7, 0xf1, 0xb8, 0x47, 0xd9, 0xc3, 0x22, 0xed, 0x17, 0x91, 0x49, 0xe2, 0xe2, 0x9f, 0x16, + 0x0f, 0x7a, 0x9b, 0x79, 0xde, 0x37, 0xcf, 0xfc, 0xde, 0x67, 0x32, 0xf8, 0x0e, 0xf1, 0x48, 0xce, + 0x21, 0xb2, 0xfd, 0x90, 0xfa, 0xb3, 0x18, 0x58, 0x24, 0x59, 0x14, 0xd8, 0xd9, 0xc0, 0x26, 0x5c, + 0xb8, 0x33, 0x9a, 0x5b, 0x71, 0x02, 0x12, 0x74, 0xa3, 0xea, 0xb3, 0x7e, 0xe9, 0xb3, 0xb2, 0xc1, + 0xcd, 0x1b, 0x01, 0x04, 0x50, 0x34, 0xd9, 0x6a, 0x55, 0xf6, 0xf7, 0x3e, 0x23, 0xac, 0x8d, 0xb8, + 0x38, 0xa4, 0xb9, 0x7e, 0x8c, 0xb5, 0x38, 0x25, 0x33, 0x9a, 0x1b, 0xa8, 0x8b, 0xfa, 0xed, 0xd1, + 0xe3, 0xf3, 0x8b, 0xce, 0xc3, 0x80, 0xc9, 0x30, 0x25, 0x96, 0x0f, 0x73, 0xbb, 0x72, 0xe6, 0x1e, + 0x11, 0x7b, 0x0c, 0xec, 0x4b, 0xa0, 0x24, 0x8f, 0x25, 0x28, 0x8c, 0xc1, 0x70, 0xff, 0xfe, 0xc0, + 0x1a, 0xa7, 0x84, 0x33, 0xff, 0x90, 0xe6, 0x4e, 0x65, 0xa7, 0x3f, 0xc2, 0x8d, 0x18, 0x62, 0xa3, + 0xde, 0x45, 0xfd, 0xd6, 0x70, 0xd7, 0x5a, 0x47, 0x68, 0x8d, 0x13, 0x80, 0x93, 0x97, 0x27, 0x63, + 0x10, 0x82, 0x0a, 0xc1, 0x20, 0x72, 0xd4, 0x77, 0xbd, 0x0f, 0x08, 0x6f, 0xff, 0x51, 0xd2, 0x3b, + 0xb8, 0x45, 0xa7, 0xc3, 0x83, 0x83, 0xc1, 0x03, 0x57, 0xb0, 0xa0, 0x44, 0x76, 0x70, 0x25, 0x4d, + 0x58, 0xa0, 0xbf, 0xc6, 0x9b, 0x2a, 0x1a, 0x55, 0xac, 0xff, 0xcb, 0x3c, 0x13, 0x16, 0x44, 0x9e, + 0x4c, 0x13, 0xea, 0x68, 0x84, 0x8b, 0x09, 0x0b, 0x7a, 0x6f, 0xf1, 0xce, 0x91, 0xc7, 0xd9, 0xd4, + 0x93, 0x90, 0x1c, 0x33, 0x19, 0x96, 0xf9, 0x4d, 0xa8, 0xd4, 0x9f, 0xe1, 0xcd, 0xcc, 0xe3, 0xae, + 0xa0, 0xd2, 0x40, 0xdd, 0x46, 0xbf, 0x35, 0xdc, 0x5b, 0x3f, 0xed, 0x0a, 0x0b, 0x47, 0xcb, 0x3c, + 0x3e, 0xa1, 0xb2, 0xf7, 0x1e, 0xe1, 0xeb, 0x2b, 0xea, 0xfa, 0x2e, 0xde, 0xce, 0x7e, 0xc8, 0xae, + 0x37, 0x9d, 0x26, 0x54, 0x88, 0x62, 0xf4, 0xa6, 0x73, 0xed, 0xb2, 0xf0, 0xa4, 0xd4, 0x75, 0x13, + 0xb7, 0x54, 0x00, 0x71, 0x4a, 0xd4, 0xff, 0x51, 0x86, 0xe0, 0x34, 0x09, 0x17, 0xe3, 0x94, 0x28, + 0xb3, 0xdb, 0xb8, 0x9d, 0x81, 0xa2, 0x71, 0x63, 0x78, 0x47, 0x13, 0xa3, 0xd1, 0x45, 0xfd, 0x0d, + 0xa7, 0x55, 0x6a, 0x63, 0x25, 0xf5, 0x3e, 0xd5, 0xf1, 0xd6, 0x11, 0x48, 0xfa, 0xf4, 0x54, 0xd2, + 0xa8, 0x88, 0x7d, 0x07, 0x6b, 0x82, 0x05, 0x11, 0x4d, 0xaa, 0x63, 0xab, 0xdd, 0x6a, 0xb2, 0xfa, + 0x1a, 0xb2, 0xbb, 0x18, 0x13, 0x0e, 0xfe, 0xcc, 0x0d, 0x3d, 0x11, 0x16, 0xe7, 0xb6, 0x47, 0x5b, + 0xe7, 0x17, 0x9d, 0xe6, 0x48, 0xa9, 0xcf, 0x3d, 0x11, 0x2a, 0xce, 0x6a, 0xa9, 0xdf, 0xc2, 0x4d, + 0x1a, 0x83, 0x1f, 0xba, 0x51, 0x3a, 0x37, 0x36, 0x0a, 0xc8, 0xab, 0x85, 0xf0, 0x22, 0x9d, 0x2b, + 0x9e, 0x90, 0xb2, 0x20, 0x94, 0xc6, 0x95, 0xa2, 0x52, 0xed, 0x7e, 0xbe, 0x7d, 0xed, 0xbf, 0xde, + 0xfe, 0xe8, 0xd5, 0x97, 0x85, 0x89, 0xce, 0x16, 0x26, 0xfa, 0xb6, 0x30, 0xd1, 0xc7, 0xa5, 0x59, + 0x3b, 0x5b, 0x9a, 0xb5, 0xaf, 0x4b, 0xb3, 0xf6, 0xe6, 0xde, 0xdf, 0xed, 0x4f, 0x7f, 0x7b, 0xbf, + 0x32, 0x8f, 0xa9, 0x20, 0x5a, 0xf1, 0x16, 0xf7, 0xbf, 0x07, 0x00, 0x00, 0xff, 0xff, 0x0a, 0x52, + 0xce, 0x8d, 0xe5, 0x03, 0x00, 0x00, } func (m *BlsKey) Marshal() (dAtA []byte, err error) { @@ -774,7 +774,7 @@ func (m *BlsKey) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.PublicKey + var v github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey m.Pubkey = &v if err := m.Pubkey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -929,7 +929,7 @@ func (m *ProofOfPossession) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.Signature + var v github_com_babylonlabs_io_babylon_crypto_bls12381.Signature m.BlsSig = &v if err := m.BlsSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1370,7 +1370,7 @@ func (m *VoteExtension) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.Signature + var v github_com_babylonlabs_io_babylon_crypto_bls12381.Signature m.BlsSig = &v if err := m.BlsSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/checkpointing/types/checkpoint.pb.go b/x/checkpointing/types/checkpoint.pb.go index 4d3fdb84c..801ac381d 100644 --- a/x/checkpointing/types/checkpoint.pb.go +++ b/x/checkpointing/types/checkpoint.pb.go @@ -6,7 +6,7 @@ package types import ( bytes "bytes" fmt "fmt" - github_com_babylonchain_babylon_crypto_bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + github_com_babylonlabs_io_babylon_crypto_bls12381 "github.com/babylonlabs-io/babylon/crypto/bls12381" types "github.com/cometbft/cometbft/abci/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -81,7 +81,7 @@ type RawCheckpoint struct { Bitmap []byte `protobuf:"bytes,3,opt,name=bitmap,proto3" json:"bitmap,omitempty"` // bls_multi_sig defines the multi sig that is aggregated from individual BLS // sigs - BlsMultiSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,4,opt,name=bls_multi_sig,json=blsMultiSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_multi_sig,omitempty"` + BlsMultiSig *github_com_babylonlabs_io_babylon_crypto_bls12381.Signature `protobuf:"bytes,4,opt,name=bls_multi_sig,json=blsMultiSig,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" json:"bls_multi_sig,omitempty"` } func (m *RawCheckpoint) Reset() { *m = RawCheckpoint{} } @@ -137,7 +137,7 @@ type RawCheckpointWithMeta struct { // status defines the status of the checkpoint Status CheckpointStatus `protobuf:"varint,2,opt,name=status,proto3,enum=babylon.checkpointing.v1.CheckpointStatus" json:"status,omitempty"` // bls_aggr_pk defines the aggregated BLS public key - BlsAggrPk *github_com_babylonchain_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,3,opt,name=bls_aggr_pk,json=blsAggrPk,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.PublicKey" json:"bls_aggr_pk,omitempty"` + BlsAggrPk *github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,3,opt,name=bls_aggr_pk,json=blsAggrPk,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" json:"bls_aggr_pk,omitempty"` // power_sum defines the accumulated voting power for the checkpoint PowerSum uint64 `protobuf:"varint,4,opt,name=power_sum,json=powerSum,proto3" json:"power_sum,omitempty"` // lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -334,8 +334,8 @@ type BlsSig struct { EpochNum uint64 `protobuf:"varint,1,opt,name=epoch_num,json=epochNum,proto3" json:"epoch_num,omitempty"` // block_hash defines the 'BlockID.Hash', which is the hash of // the block that individual BLS sigs are signed on - BlockHash *BlockHash `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3,customtype=BlockHash" json:"block_hash,omitempty"` - BlsSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,3,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` + BlockHash *BlockHash `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3,customtype=BlockHash" json:"block_hash,omitempty"` + BlsSig *github_com_babylonlabs_io_babylon_crypto_bls12381.Signature `protobuf:"bytes,3,opt,name=bls_sig,json=blsSig,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" json:"bls_sig,omitempty"` // can't find cosmos_proto.scalar when compiling due to cosmos v0.45.4 does // not support scalar string signer_address = 4 [(cosmos_proto.scalar) = // "cosmos.AddressString"] @@ -414,61 +414,61 @@ func init() { } var fileDescriptor_73996df9c6aabde4 = []byte{ - // 853 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6f, 0xe3, 0x44, - 0x1c, 0x8d, 0x5b, 0x37, 0x6c, 0x26, 0xcd, 0x2a, 0x8c, 0xb6, 0x28, 0xca, 0x4a, 0x49, 0x28, 0x42, - 0x94, 0x05, 0xd9, 0x6a, 0x56, 0x48, 0xfc, 0x11, 0x82, 0xc4, 0x4d, 0x21, 0xda, 0xa6, 0x5b, 0xd9, - 0x09, 0x48, 0x2b, 0x21, 0x6b, 0x6c, 0x4f, 0xec, 0x21, 0xb6, 0xc7, 0xf2, 0x8c, 0xbb, 0x1b, 0xee, - 0x48, 0xa8, 0xa7, 0xfd, 0x02, 0x95, 0x90, 0xf8, 0x02, 0x7c, 0x07, 0x2e, 0x1c, 0xf7, 0x88, 0x16, - 0x69, 0x41, 0xed, 0x05, 0xf8, 0x14, 0x68, 0xc6, 0x4e, 0xd3, 0x6c, 0x59, 0xb1, 0xa0, 0xde, 0x26, - 0xcf, 0xef, 0x4d, 0x66, 0xde, 0xef, 0x3d, 0x0d, 0x78, 0xdb, 0x41, 0xce, 0x3c, 0xa4, 0xb1, 0xee, - 0x06, 0xd8, 0x9d, 0x25, 0x94, 0xc4, 0x9c, 0xc4, 0xbe, 0x7e, 0xbc, 0x7b, 0x09, 0xd0, 0x92, 0x94, - 0x72, 0x0a, 0x1b, 0x05, 0x55, 0x5b, 0xa1, 0x6a, 0xc7, 0xbb, 0xcd, 0xb6, 0x4f, 0xa9, 0x1f, 0x62, - 0x5d, 0xf2, 0x9c, 0x6c, 0xaa, 0x73, 0x12, 0x61, 0xc6, 0x51, 0x94, 0xe4, 0xd2, 0xe6, 0x2d, 0x9f, - 0xfa, 0x54, 0x2e, 0x75, 0xb1, 0x2a, 0xd0, 0xdb, 0x1c, 0xc7, 0x1e, 0x4e, 0x23, 0x12, 0x73, 0x1d, - 0x39, 0x2e, 0xd1, 0xf9, 0x3c, 0xc1, 0x2c, 0xff, 0xb8, 0xfd, 0xab, 0x02, 0x6a, 0x26, 0x7a, 0x68, - 0x5c, 0xfc, 0x17, 0xbc, 0x0d, 0x2a, 0x38, 0xa1, 0x6e, 0x60, 0xc7, 0x59, 0xd4, 0x50, 0x3a, 0xca, - 0x8e, 0x6a, 0xde, 0x90, 0xc0, 0x61, 0x16, 0xc1, 0x77, 0x01, 0x70, 0x42, 0xea, 0xce, 0xec, 0x00, - 0xb1, 0xa0, 0xb1, 0xd6, 0x51, 0x76, 0x36, 0xfb, 0xb5, 0xa7, 0xcf, 0xda, 0x95, 0xbe, 0x40, 0x3f, - 0x47, 0x2c, 0x30, 0x2b, 0xce, 0x62, 0x09, 0x5f, 0x03, 0x65, 0x87, 0xf0, 0x08, 0x25, 0x8d, 0x75, - 0xc1, 0x34, 0x8b, 0x5f, 0x10, 0x81, 0x9a, 0x13, 0x32, 0x3b, 0xca, 0x42, 0x4e, 0x6c, 0x46, 0xfc, - 0x86, 0x2a, 0x37, 0xfa, 0xf8, 0xe9, 0xb3, 0xf6, 0x07, 0x3e, 0xe1, 0x41, 0xe6, 0x68, 0x2e, 0x8d, - 0xf4, 0xc2, 0x08, 0x37, 0x40, 0x24, 0xd6, 0x2f, 0x0c, 0x4c, 0xe7, 0x09, 0xa7, 0xba, 0x13, 0xb2, - 0xdd, 0xee, 0xdd, 0xf7, 0x77, 0x35, 0x8b, 0xf8, 0x31, 0xe2, 0x59, 0x8a, 0xcd, 0xaa, 0x13, 0xb2, - 0x91, 0xd8, 0xd2, 0x22, 0xfe, 0x87, 0xea, 0x1f, 0xdf, 0xb7, 0x95, 0xed, 0x3f, 0xd7, 0xc0, 0xd6, - 0xca, 0xed, 0xbe, 0x24, 0x3c, 0x18, 0x61, 0x8e, 0xe0, 0x47, 0x40, 0x75, 0x67, 0x09, 0x97, 0x17, - 0xac, 0x76, 0xdf, 0xd2, 0x5e, 0x64, 0xba, 0xb6, 0x22, 0x37, 0xa5, 0x08, 0xf6, 0x41, 0x99, 0x71, - 0xc4, 0x33, 0x26, 0x1d, 0xb8, 0xd9, 0xbd, 0xf3, 0x62, 0xf9, 0x52, 0x6b, 0x49, 0x85, 0x59, 0x28, - 0xe1, 0x57, 0x40, 0x9c, 0xd7, 0x46, 0xbe, 0x9f, 0xda, 0xc9, 0x2c, 0x37, 0xe8, 0xff, 0x39, 0x70, - 0x94, 0x39, 0x21, 0x71, 0xef, 0xe1, 0xb9, 0xb0, 0x9e, 0xf5, 0x7c, 0x3f, 0x3d, 0x9a, 0x89, 0x29, - 0x26, 0xf4, 0x21, 0x4e, 0x6d, 0x96, 0x45, 0xd2, 0x5e, 0xd5, 0xbc, 0x21, 0x01, 0x2b, 0x8b, 0xe0, - 0x08, 0x54, 0x42, 0x32, 0xc5, 0xee, 0xdc, 0x0d, 0x71, 0x63, 0xa3, 0xb3, 0xbe, 0x53, 0xed, 0xea, - 0x2f, 0x7b, 0x05, 0x3c, 0x49, 0x3c, 0xc4, 0xb1, 0xb9, 0xdc, 0xa1, 0xf0, 0xfa, 0x47, 0x05, 0xc0, - 0x61, 0xfc, 0x35, 0x76, 0x39, 0xf6, 0x2e, 0xc5, 0xc9, 0x58, 0x31, 0x5a, 0x7f, 0x49, 0xa3, 0x17, - 0x73, 0x2a, 0x0c, 0x9f, 0x80, 0x5b, 0xf8, 0x91, 0x8c, 0xb1, 0x67, 0xbb, 0x34, 0x8a, 0x08, 0xb7, - 0x49, 0x3c, 0xa5, 0xd2, 0xfe, 0x6a, 0xf7, 0x0d, 0x6d, 0x99, 0x70, 0x4d, 0x24, 0x5c, 0x1b, 0x14, - 0x64, 0x43, 0x72, 0x87, 0xf1, 0x94, 0x9a, 0x10, 0x5f, 0xc1, 0xb6, 0x7f, 0x52, 0xc0, 0xd6, 0x3f, - 0xde, 0x0e, 0x7e, 0x0a, 0x36, 0xc4, 0x9c, 0xb0, 0x3c, 0xf6, 0x7f, 0x1b, 0x70, 0x2e, 0x84, 0xaf, - 0x83, 0xcd, 0xa2, 0x29, 0x98, 0xf8, 0x01, 0x97, 0x47, 0x55, 0x45, 0x46, 0x45, 0x39, 0x24, 0x04, - 0x3f, 0x59, 0x94, 0x49, 0xf4, 0x58, 0x26, 0xa0, 0xda, 0x6d, 0x6a, 0x79, 0xc9, 0xb5, 0x45, 0xc9, - 0xb5, 0xf1, 0xa2, 0xe4, 0x7d, 0xf5, 0xf1, 0x6f, 0x6d, 0xa5, 0xe8, 0x97, 0x40, 0x0b, 0xe3, 0xbf, - 0x5d, 0x03, 0xe5, 0x7e, 0xc8, 0x2c, 0xe2, 0x5f, 0x67, 0x77, 0xbf, 0x00, 0xaf, 0x88, 0x7c, 0x8a, - 0x76, 0xae, 0x5f, 0x47, 0x3b, 0xcb, 0x4e, 0x7e, 0xc4, 0x37, 0xc1, 0x4d, 0x46, 0xfc, 0x18, 0xa7, - 0x36, 0xf2, 0xbc, 0x14, 0x33, 0x26, 0xd3, 0x59, 0x31, 0x6b, 0x39, 0xda, 0xcb, 0x41, 0xf8, 0x0e, - 0x78, 0xf5, 0x18, 0x85, 0xc4, 0x43, 0x9c, 0x2e, 0x99, 0x1b, 0x92, 0x59, 0xbf, 0xf8, 0x50, 0x90, - 0xa5, 0x0f, 0xa5, 0x3b, 0x7f, 0x29, 0xa0, 0xfe, 0xfc, 0x34, 0xa0, 0x06, 0x1a, 0xc6, 0xbd, 0xa3, - 0xb1, 0x6d, 0x8d, 0x7b, 0xe3, 0x89, 0x65, 0xf7, 0x0c, 0x63, 0x32, 0x9a, 0x1c, 0xf4, 0xc6, 0xc3, - 0xc3, 0xcf, 0xea, 0xa5, 0x66, 0xfd, 0xe4, 0xb4, 0xb3, 0xd9, 0x73, 0xdd, 0x2c, 0xca, 0x42, 0x24, - 0x26, 0x0a, 0xb7, 0x01, 0xbc, 0xcc, 0xb7, 0x06, 0xbd, 0x83, 0xc1, 0x5e, 0x5d, 0x69, 0x82, 0x93, - 0xd3, 0x4e, 0xd9, 0xc2, 0x28, 0xc4, 0x1e, 0xdc, 0x01, 0x5b, 0x2b, 0x9c, 0x49, 0x7f, 0x34, 0x1c, - 0x8f, 0x07, 0x7b, 0xf5, 0xb5, 0x66, 0xed, 0xe4, 0xb4, 0x53, 0xb1, 0x32, 0x27, 0x22, 0x9c, 0x5f, - 0x65, 0x1a, 0xf7, 0x0f, 0xf7, 0x87, 0xe6, 0x68, 0xb0, 0x57, 0x5f, 0xcf, 0x99, 0x06, 0x8d, 0xa7, - 0x24, 0x8d, 0xae, 0x32, 0xf7, 0x87, 0x87, 0xbd, 0x83, 0xe1, 0x83, 0xc1, 0x5e, 0x5d, 0xcd, 0x99, - 0xfb, 0x24, 0x46, 0x21, 0xf9, 0x06, 0x7b, 0x4d, 0xf5, 0xbb, 0x1f, 0x5a, 0xa5, 0xfe, 0xfd, 0x9f, - 0xcf, 0x5a, 0xca, 0x93, 0xb3, 0x96, 0xf2, 0xfb, 0x59, 0x4b, 0x79, 0x7c, 0xde, 0x2a, 0x3d, 0x39, - 0x6f, 0x95, 0x7e, 0x39, 0x6f, 0x95, 0x1e, 0xbc, 0xf7, 0x6f, 0x33, 0x7a, 0xf4, 0xdc, 0x23, 0x24, - 0x9f, 0x03, 0xa7, 0x2c, 0x03, 0x77, 0xf7, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc9, 0x97, 0x52, - 0x24, 0xaa, 0x06, 0x00, 0x00, + // 852 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0xcf, 0x6e, 0x1b, 0x45, + 0x1c, 0xf6, 0x26, 0x1b, 0x53, 0x8f, 0xe3, 0xca, 0x8c, 0x1a, 0x64, 0xb9, 0x92, 0x6d, 0x82, 0x10, + 0xa1, 0xc0, 0xae, 0xe2, 0x1e, 0x40, 0xf4, 0x50, 0x6c, 0xc7, 0x01, 0xab, 0x71, 0x08, 0xbb, 0xb6, + 0x40, 0xbd, 0xac, 0x66, 0x77, 0xc7, 0xeb, 0xc1, 0xb3, 0x3b, 0xab, 0x9d, 0xd9, 0xb4, 0xe6, 0x05, + 0x40, 0x39, 0xf5, 0x05, 0x22, 0x21, 0xf1, 0x02, 0xbc, 0x03, 0x17, 0x8e, 0x3d, 0xa2, 0x4a, 0x14, + 0x94, 0x5c, 0x10, 0xbc, 0x04, 0x9a, 0xd9, 0x75, 0x1c, 0x37, 0x54, 0x14, 0x94, 0xdb, 0xf8, 0xdb, + 0xef, 0x37, 0x9e, 0xf9, 0xfe, 0x68, 0xc0, 0xbb, 0x2e, 0x72, 0xe7, 0x94, 0x45, 0xa6, 0x37, 0xc5, + 0xde, 0x2c, 0x66, 0x24, 0x12, 0x24, 0x0a, 0xcc, 0xe3, 0xdd, 0x4b, 0x80, 0x11, 0x27, 0x4c, 0x30, + 0x58, 0xcb, 0xa9, 0xc6, 0x0a, 0xd5, 0x38, 0xde, 0xad, 0x37, 0x03, 0xc6, 0x02, 0x8a, 0x4d, 0xc5, + 0x73, 0xd3, 0x89, 0x29, 0x48, 0x88, 0xb9, 0x40, 0x61, 0x9c, 0x8d, 0xd6, 0x6f, 0x05, 0x2c, 0x60, + 0x6a, 0x69, 0xca, 0x55, 0x8e, 0xde, 0x16, 0x38, 0xf2, 0x71, 0x12, 0x92, 0x48, 0x98, 0xc8, 0xf5, + 0x88, 0x29, 0xe6, 0x31, 0xe6, 0xd9, 0xc7, 0xed, 0x5f, 0x35, 0x50, 0xb1, 0xd0, 0xa3, 0xde, 0xc5, + 0x7f, 0xc1, 0xdb, 0xa0, 0x84, 0x63, 0xe6, 0x4d, 0x9d, 0x28, 0x0d, 0x6b, 0x5a, 0x4b, 0xdb, 0xd1, + 0xad, 0x1b, 0x0a, 0x38, 0x4c, 0x43, 0xf8, 0x3e, 0x00, 0x2e, 0x65, 0xde, 0xcc, 0x99, 0x22, 0x3e, + 0xad, 0xad, 0xb5, 0xb4, 0x9d, 0xcd, 0x6e, 0xe5, 0xd9, 0xf3, 0x66, 0xa9, 0x2b, 0xd1, 0xcf, 0x10, + 0x9f, 0x5a, 0x25, 0x77, 0xb1, 0x84, 0x6f, 0x80, 0xa2, 0x4b, 0x44, 0x88, 0xe2, 0xda, 0xba, 0x64, + 0x5a, 0xf9, 0x2f, 0xe8, 0x81, 0x8a, 0x4b, 0xb9, 0x13, 0xa6, 0x54, 0x10, 0x87, 0x93, 0xa0, 0xa6, + 0xab, 0x8d, 0xee, 0x3f, 0x7b, 0xde, 0xbc, 0x17, 0x10, 0x31, 0x4d, 0x5d, 0xc3, 0x63, 0xa1, 0x99, + 0x0b, 0x41, 0x91, 0xcb, 0x3f, 0x20, 0xcc, 0xbc, 0x90, 0x30, 0x99, 0xc7, 0x82, 0x99, 0x2e, 0xe5, + 0xbb, 0xed, 0xbb, 0x1f, 0xed, 0x1a, 0x36, 0x09, 0x22, 0x24, 0xd2, 0x04, 0x5b, 0x65, 0x97, 0xf2, + 0xa1, 0xdc, 0xd4, 0x26, 0xc1, 0xc7, 0xfa, 0x1f, 0xdf, 0x37, 0xb5, 0xed, 0xbf, 0xd6, 0xc0, 0xd6, + 0xca, 0xfd, 0xbe, 0x24, 0x62, 0x3a, 0xc4, 0x02, 0xc1, 0x7b, 0x40, 0xf7, 0x66, 0xb1, 0x50, 0x57, + 0x2c, 0xb7, 0xdf, 0x31, 0x5e, 0x26, 0xbb, 0xb1, 0x32, 0x6e, 0xa9, 0x21, 0xd8, 0x05, 0x45, 0x2e, + 0x90, 0x48, 0xb9, 0xd2, 0xe0, 0x66, 0xfb, 0xce, 0xcb, 0xc7, 0x97, 0xb3, 0xb6, 0x9a, 0xb0, 0xf2, + 0x49, 0xe8, 0x00, 0x79, 0x5e, 0x07, 0x05, 0x41, 0xe2, 0xc4, 0xb3, 0x4c, 0xa2, 0xff, 0xab, 0xc1, + 0x51, 0xea, 0x52, 0xe2, 0x3d, 0xc0, 0x73, 0x29, 0x3f, 0xef, 0x04, 0x41, 0x72, 0x34, 0x93, 0x4e, + 0xc6, 0xec, 0x11, 0x4e, 0x1c, 0x9e, 0x86, 0x4a, 0x62, 0xdd, 0xba, 0xa1, 0x00, 0x3b, 0x0d, 0xe1, + 0x10, 0x94, 0x28, 0x99, 0x60, 0x6f, 0xee, 0x51, 0x5c, 0xdb, 0x68, 0xad, 0xef, 0x94, 0xdb, 0xe6, + 0xab, 0x5e, 0x02, 0x8f, 0x63, 0x1f, 0x09, 0x6c, 0x2d, 0x77, 0xc8, 0xd5, 0xfe, 0x51, 0x03, 0x70, + 0x10, 0x7d, 0x8d, 0x3d, 0x81, 0xfd, 0x4b, 0x91, 0xea, 0xad, 0x48, 0x6d, 0xbe, 0xa2, 0xd4, 0x0b, + 0xa7, 0x72, 0xc9, 0xc7, 0xe0, 0x16, 0x7e, 0xac, 0xa2, 0xec, 0x3b, 0x1e, 0x0b, 0x43, 0x22, 0x1c, + 0x12, 0x4d, 0x98, 0x32, 0xa0, 0xdc, 0x7e, 0xcb, 0x58, 0xa6, 0xdc, 0x90, 0x29, 0x37, 0xfa, 0x39, + 0xb9, 0xa7, 0xb8, 0x83, 0x68, 0xc2, 0x2c, 0x88, 0xaf, 0x60, 0xdb, 0x3f, 0x69, 0x60, 0xeb, 0x1f, + 0x6f, 0x07, 0x3f, 0x01, 0x1b, 0xd2, 0x29, 0xac, 0x8e, 0xfd, 0xdf, 0x2c, 0xce, 0x06, 0xe1, 0x9b, + 0x60, 0x33, 0x6f, 0x0b, 0x26, 0xc1, 0x54, 0xa8, 0xa3, 0xea, 0x32, 0xa5, 0xb2, 0x20, 0x0a, 0x82, + 0xf7, 0x17, 0x85, 0x92, 0x5d, 0x56, 0x19, 0x28, 0xb7, 0xeb, 0x46, 0x56, 0x74, 0x63, 0x51, 0x74, + 0x63, 0xb4, 0x28, 0x7a, 0x57, 0x7f, 0xf2, 0x5b, 0x53, 0xcb, 0x3b, 0x26, 0xd1, 0x5c, 0xf8, 0x6f, + 0xd7, 0x40, 0xb1, 0x4b, 0xb9, 0x4d, 0x82, 0xeb, 0xec, 0xef, 0x57, 0xe0, 0x35, 0x99, 0x50, 0xd9, + 0xd0, 0xf5, 0xeb, 0x69, 0x68, 0xd1, 0xcd, 0x0e, 0xf9, 0x36, 0xb8, 0xc9, 0x49, 0x10, 0xe1, 0xc4, + 0x41, 0xbe, 0x9f, 0x60, 0xce, 0x55, 0x3e, 0x4b, 0x56, 0x25, 0x43, 0x3b, 0x19, 0x08, 0xdf, 0x03, + 0xaf, 0x1f, 0x23, 0x4a, 0x7c, 0x24, 0xd8, 0x92, 0xb9, 0xa1, 0x98, 0xd5, 0x8b, 0x0f, 0x39, 0x59, + 0x29, 0x51, 0xb8, 0xf3, 0xa7, 0x06, 0xaa, 0x2f, 0xfa, 0x01, 0x0d, 0x50, 0xeb, 0x3d, 0x38, 0x1a, + 0x39, 0xf6, 0xa8, 0x33, 0x1a, 0xdb, 0x4e, 0xa7, 0xd7, 0x1b, 0x0f, 0xc7, 0x07, 0x9d, 0xd1, 0xe0, + 0xf0, 0xd3, 0x6a, 0xa1, 0x5e, 0x3d, 0x39, 0x6d, 0x6d, 0x76, 0x3c, 0x2f, 0x0d, 0x53, 0x8a, 0xa4, + 0xa7, 0x70, 0x1b, 0xc0, 0xcb, 0x7c, 0xbb, 0xdf, 0x39, 0xe8, 0xef, 0x55, 0xb5, 0x3a, 0x38, 0x39, + 0x6d, 0x15, 0x6d, 0x8c, 0x28, 0xf6, 0xe1, 0x0e, 0xd8, 0x5a, 0xe1, 0x8c, 0xbb, 0xc3, 0xc1, 0x68, + 0xd4, 0xdf, 0xab, 0xae, 0xd5, 0x2b, 0x27, 0xa7, 0xad, 0x92, 0x9d, 0xba, 0x21, 0x11, 0xe2, 0x2a, + 0xb3, 0xf7, 0xf9, 0xe1, 0xfe, 0xc0, 0x1a, 0xf6, 0xf7, 0xaa, 0xeb, 0x19, 0xb3, 0xc7, 0xa2, 0x09, + 0x49, 0xc2, 0xab, 0xcc, 0xfd, 0xc1, 0x61, 0xe7, 0x60, 0xf0, 0xb0, 0xbf, 0x57, 0xd5, 0x33, 0xe6, + 0x3e, 0x89, 0x10, 0x25, 0xdf, 0x60, 0xbf, 0xae, 0x7f, 0xf7, 0x43, 0xa3, 0xd0, 0xfd, 0xe2, 0xe7, + 0xb3, 0x86, 0xf6, 0xf4, 0xac, 0xa1, 0xfd, 0x7e, 0xd6, 0xd0, 0x9e, 0x9c, 0x37, 0x0a, 0x4f, 0xcf, + 0x1b, 0x85, 0x5f, 0xce, 0x1b, 0x85, 0x87, 0x1f, 0xfe, 0xbb, 0x4b, 0x8f, 0x5f, 0x78, 0x8c, 0xd4, + 0xb3, 0xe0, 0x16, 0x55, 0xe8, 0xee, 0xfe, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x96, 0x67, 0xaf, 0xba, + 0xb2, 0x06, 0x00, 0x00, } func (this *RawCheckpoint) Equal(that interface{}) bool { @@ -1157,7 +1157,7 @@ func (m *RawCheckpoint) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.Signature + var v github_com_babylonlabs_io_babylon_crypto_bls12381.Signature m.BlsMultiSig = &v if err := m.BlsMultiSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1297,7 +1297,7 @@ func (m *RawCheckpointWithMeta) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.PublicKey + var v github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey m.BlsAggrPk = &v if err := m.BlsAggrPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1735,7 +1735,7 @@ func (m *BlsSig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.Signature + var v github_com_babylonlabs_io_babylon_crypto_bls12381.Signature m.BlsSig = &v if err := m.BlsSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/checkpointing/types/events.pb.go b/x/checkpointing/types/events.pb.go index 10e283497..7c2030c86 100644 --- a/x/checkpointing/types/events.pb.go +++ b/x/checkpointing/types/events.pb.go @@ -368,26 +368,26 @@ func init() { var fileDescriptor_950b7bd81c59f78a = []byte{ // 314 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0x4a, 0x4c, 0xaa, - 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xce, 0x48, 0x4d, 0xce, 0x2e, 0xc8, 0xcf, 0xcc, 0x2b, 0xc9, 0xcc, - 0x4b, 0xd7, 0x2f, 0x33, 0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, - 0xc9, 0x17, 0x92, 0x80, 0x2a, 0xd3, 0x43, 0x51, 0xa6, 0x57, 0x66, 0x28, 0xa5, 0x89, 0xd3, 0x00, - 0x84, 0x00, 0xc4, 0x10, 0xa5, 0x3c, 0x2e, 0x69, 0x57, 0x90, 0xa1, 0xce, 0x70, 0x09, 0xc7, 0xe4, - 0xe4, 0xd2, 0xdc, 0xd2, 0x9c, 0x44, 0x90, 0x16, 0x21, 0x7f, 0x2e, 0x2e, 0x84, 0x16, 0x09, 0x46, - 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x7d, 0x3d, 0x5c, 0x16, 0xeb, 0x05, 0x25, 0x96, 0x23, 0x0c, 0x0a, - 0xcf, 0x2c, 0xc9, 0xf0, 0x4d, 0x2d, 0x49, 0x0c, 0x42, 0x32, 0x42, 0x29, 0x83, 0x4b, 0x14, 0xcd, - 0xbe, 0xe0, 0xd4, 0xc4, 0x9c, 0xd4, 0x14, 0xea, 0xdb, 0x94, 0xcd, 0x25, 0x81, 0x6e, 0x53, 0x69, - 0x52, 0x6e, 0x66, 0x49, 0x09, 0x7d, 0x2c, 0x73, 0xce, 0xcf, 0x4b, 0xcb, 0x2c, 0xca, 0xa5, 0x8f, - 0x65, 0x6e, 0x99, 0x79, 0x89, 0x39, 0x99, 0x55, 0x74, 0xb2, 0x2c, 0xbf, 0x28, 0x3d, 0xbf, 0xa4, - 0x24, 0x35, 0x8f, 0xfa, 0x96, 0xdd, 0x60, 0xe4, 0x92, 0x82, 0xd8, 0x96, 0x9f, 0x97, 0x96, 0x93, - 0x99, 0x0c, 0xd2, 0x89, 0xd0, 0x22, 0x14, 0xc7, 0x25, 0x96, 0x8c, 0x90, 0x88, 0xc7, 0xb0, 0x5b, - 0x9d, 0x48, 0xbb, 0x83, 0x44, 0x93, 0xb1, 0x9a, 0x1f, 0xc5, 0x25, 0x90, 0x93, 0x9f, 0x9c, 0x98, - 0x83, 0x6c, 0x32, 0x13, 0x79, 0xbe, 0xe2, 0x07, 0x1b, 0x84, 0x90, 0x70, 0xf2, 0x3f, 0xf1, 0x48, - 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, - 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xd3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, - 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, 0x2d, 0xc9, 0x19, 0x89, 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0x5a, - 0x3e, 0x2e, 0xa9, 0x2c, 0x48, 0x2d, 0x4e, 0x62, 0x03, 0x67, 0x60, 0x63, 0x40, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x47, 0xbc, 0x3a, 0x24, 0x2e, 0x04, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0x31, 0x4b, 0x03, 0x31, + 0x18, 0x86, 0x1b, 0x07, 0x87, 0x38, 0x28, 0x85, 0x4a, 0xa9, 0x10, 0xa4, 0x20, 0xea, 0x60, 0x42, + 0x75, 0x70, 0xd6, 0xa2, 0x9b, 0x88, 0x75, 0x10, 0x3a, 0x28, 0x49, 0x4c, 0xef, 0x42, 0x73, 0xc9, + 0x71, 0x97, 0x3b, 0xad, 0xbf, 0xc2, 0x9f, 0xe5, 0xd8, 0xb1, 0xa3, 0xdc, 0xfd, 0x11, 0xb9, 0xb6, + 0x9a, 0x7a, 0x5a, 0x10, 0x29, 0x37, 0x26, 0xef, 0xf7, 0x3e, 0x0f, 0xdf, 0xf0, 0xc1, 0x3d, 0x46, + 0xd9, 0x48, 0x19, 0x4d, 0xb8, 0x2f, 0xf8, 0x30, 0x34, 0x52, 0x5b, 0xa9, 0x3d, 0x92, 0x76, 0x88, + 0x48, 0x85, 0xb6, 0x31, 0x0e, 0x23, 0x63, 0x4d, 0xbd, 0x39, 0x1f, 0xc3, 0xdf, 0xc6, 0x70, 0xda, + 0x69, 0x1d, 0x2e, 0x05, 0xb8, 0x8f, 0x19, 0xa4, 0xad, 0xe1, 0xce, 0x45, 0x01, 0xed, 0x7e, 0x05, + 0x67, 0x9c, 0x27, 0x41, 0xa2, 0x68, 0x51, 0xa9, 0x5f, 0x43, 0xe8, 0x2a, 0x4d, 0xb0, 0x0b, 0x0e, + 0x36, 0x8e, 0x09, 0x5e, 0x26, 0xc6, 0x3d, 0xfa, 0xe4, 0x40, 0x77, 0xd2, 0xfa, 0x57, 0xc2, 0xd2, + 0xde, 0x02, 0xa2, 0xed, 0xc3, 0x46, 0xc9, 0x77, 0x2b, 0xa8, 0x12, 0x8f, 0xab, 0x37, 0x0d, 0x61, + 0xb3, 0x6c, 0x4a, 0x58, 0x20, 0xad, 0xad, 0x46, 0xd6, 0x35, 0x7a, 0x20, 0xa3, 0xa0, 0x1a, 0xd9, + 0xa5, 0xd4, 0x54, 0xc9, 0x97, 0x8a, 0x64, 0x26, 0xf2, 0x8c, 0xb5, 0x42, 0xaf, 0x5e, 0x36, 0x01, + 0xb0, 0x35, 0xb3, 0x19, 0x3d, 0x50, 0x92, 0x17, 0x4d, 0x57, 0xa9, 0xdf, 0xc3, 0x6d, 0xee, 0x82, + 0x87, 0x1f, 0xee, 0xfd, 0x3f, 0xba, 0x7b, 0x0d, 0xfe, 0x2b, 0xbf, 0x0f, 0xb7, 0x94, 0xe1, 0x54, + 0x2d, 0x92, 0xd7, 0xfe, 0xb7, 0xd5, 0xe6, 0x14, 0xe4, 0x82, 0xf3, 0x9b, 0xb7, 0x0c, 0x81, 0x71, + 0x86, 0xc0, 0x7b, 0x86, 0xc0, 0x6b, 0x8e, 0x6a, 0xe3, 0x1c, 0xd5, 0x26, 0x39, 0xaa, 0xf5, 0x4f, + 0x3d, 0x69, 0xfd, 0x84, 0x61, 0x6e, 0x02, 0x32, 0xb7, 0x28, 0xca, 0xe2, 0x23, 0x69, 0x3e, 0x9f, + 0xe4, 0xb9, 0x74, 0xc9, 0x76, 0x14, 0x8a, 0x98, 0xad, 0x4f, 0x4f, 0xf8, 0xe4, 0x23, 0x00, 0x00, + 0xff, 0xff, 0xc6, 0xac, 0x9d, 0x86, 0x30, 0x04, 0x00, 0x00, } func (m *EventCheckpointAccumulating) Marshal() (dAtA []byte, err error) { diff --git a/x/checkpointing/types/expected_keepers.go b/x/checkpointing/types/expected_keepers.go index adeb297d1..53f15112c 100644 --- a/x/checkpointing/types/expected_keepers.go +++ b/x/checkpointing/types/expected_keepers.go @@ -7,7 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) // EpochingKeeper defines the expected interface needed to retrieve epoch info diff --git a/x/checkpointing/types/genesis.go b/x/checkpointing/types/genesis.go index bbe289ea9..065cd2268 100644 --- a/x/checkpointing/types/genesis.go +++ b/x/checkpointing/types/genesis.go @@ -12,7 +12,7 @@ import ( cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/crypto/bls12381" ) // DefaultGenesis returns the default Capability genesis state diff --git a/x/checkpointing/types/genesis.pb.go b/x/checkpointing/types/genesis.pb.go index 380afef3d..78fabad09 100644 --- a/x/checkpointing/types/genesis.pb.go +++ b/x/checkpointing/types/genesis.pb.go @@ -143,28 +143,28 @@ func init() { } var fileDescriptor_bf2c524ebc9800de = []byte{ - // 325 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xcf, 0x6a, 0x2a, 0x31, - 0x18, 0xc5, 0xcd, 0x15, 0xbc, 0x18, 0x5d, 0xb4, 0xb3, 0x12, 0xa1, 0x61, 0x90, 0x52, 0x84, 0x42, - 0x82, 0x16, 0x17, 0x42, 0x37, 0x75, 0xe3, 0xa2, 0x8b, 0x8a, 0x5d, 0x14, 0xba, 0x91, 0x24, 0x13, - 0xc6, 0x60, 0x9c, 0x0c, 0x93, 0x38, 0x34, 0x6f, 0xd1, 0x67, 0xe9, 0x53, 0x74, 0xe9, 0xb2, 0xcb, - 0xa2, 0x2f, 0x52, 0x66, 0x26, 0xb5, 0xb4, 0x30, 0xab, 0xfc, 0xf9, 0xce, 0xf9, 0xce, 0xe1, 0x07, - 0xaf, 0x18, 0x65, 0x4e, 0xe9, 0x84, 0xf0, 0xb5, 0xe0, 0x9b, 0x54, 0xcb, 0xc4, 0xca, 0x24, 0x26, - 0xf9, 0x88, 0xc4, 0x22, 0x11, 0x46, 0x1a, 0x9c, 0x66, 0xda, 0xea, 0xa0, 0xe7, 0x75, 0xf8, 0x97, - 0x0e, 0xe7, 0xa3, 0x7e, 0xc8, 0xb5, 0xd9, 0x6a, 0x43, 0x78, 0xe6, 0x52, 0xab, 0x89, 0x88, 0xc6, - 0x93, 0xc9, 0x68, 0x4a, 0x36, 0xc2, 0x79, 0x6f, 0xbf, 0x3e, 0x83, 0x29, 0xb3, 0xda, 0x08, 0x57, - 0xe9, 0x06, 0x4f, 0xb0, 0x3b, 0xaf, 0x42, 0x1f, 0x2d, 0xb5, 0x22, 0x98, 0xc3, 0xae, 0x2f, 0x51, - 0x88, 0x4c, 0x0f, 0x84, 0xcd, 0x61, 0x67, 0x7c, 0x89, 0xeb, 0xaa, 0x60, 0xef, 0xbe, 0x17, 0x6e, - 0xd9, 0x89, 0x4f, 0x77, 0x33, 0x78, 0x03, 0x10, 0xfe, 0xcc, 0x82, 0x6b, 0x78, 0x9e, 0x53, 0x25, - 0x23, 0x6a, 0x75, 0xb6, 0xa2, 0x51, 0x94, 0x09, 0x53, 0x2c, 0x07, 0xc3, 0xf6, 0xf2, 0xec, 0x34, - 0xb8, 0xab, 0xfe, 0x83, 0x29, 0xfc, 0xef, 0x5b, 0xf6, 0xfe, 0x85, 0x60, 0xd8, 0x19, 0x87, 0xf5, - 0xf9, 0x33, 0x55, 0x66, 0xb7, 0x58, 0x79, 0x06, 0xb7, 0x10, 0xe6, 0x54, 0xad, 0xd2, 0x1d, 0x2b, - 0xdc, 0xcd, 0xd2, 0x7d, 0x81, 0x2b, 0x5c, 0xb8, 0xc2, 0x85, 0x3d, 0x2e, 0xbc, 0xd8, 0xb1, 0xc2, - 0xda, 0xce, 0xa9, 0x5a, 0x94, 0xfa, 0xd9, 0xc3, 0xfb, 0x01, 0x81, 0xfd, 0x01, 0x81, 0xcf, 0x03, - 0x02, 0xaf, 0x47, 0xd4, 0xd8, 0x1f, 0x51, 0xe3, 0xe3, 0x88, 0x1a, 0xcf, 0x93, 0x58, 0xda, 0xf5, - 0x8e, 0x61, 0xae, 0xb7, 0xc4, 0x77, 0xe1, 0x6b, 0x2a, 0x93, 0xef, 0x07, 0x79, 0xf9, 0x43, 0xda, - 0xba, 0x54, 0x18, 0xd6, 0x2a, 0x29, 0xdf, 0x7c, 0x05, 0x00, 0x00, 0xff, 0xff, 0x1c, 0xab, 0xd1, - 0x3a, 0xf3, 0x01, 0x00, 0x00, + // 327 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x4f, 0x4b, 0xfb, 0x30, + 0x1c, 0xc6, 0x97, 0xdf, 0x60, 0x3f, 0x96, 0xed, 0xa0, 0x3d, 0x8d, 0x81, 0xa1, 0x0c, 0x91, 0x81, + 0x98, 0xb0, 0xc9, 0x90, 0x81, 0x17, 0x77, 0xd9, 0xc1, 0xcb, 0x9c, 0x07, 0xc1, 0xcb, 0x48, 0xda, + 0xd0, 0x85, 0x65, 0x4d, 0x69, 0xb2, 0x62, 0xde, 0x85, 0xaf, 0xc5, 0x57, 0xe1, 0x71, 0x47, 0x8f, + 0xb2, 0xbe, 0x11, 0x69, 0x1b, 0x27, 0x0a, 0x3d, 0xe5, 0xcf, 0xf7, 0x79, 0xbe, 0xcf, 0xc3, 0x07, + 0x5e, 0x30, 0xca, 0xac, 0x54, 0x31, 0x09, 0xd6, 0x3c, 0xd8, 0x24, 0x4a, 0xc4, 0x46, 0xc4, 0x11, + 0xc9, 0x46, 0x24, 0xe2, 0x31, 0xd7, 0x42, 0xe3, 0x24, 0x55, 0x46, 0x79, 0x3d, 0xa7, 0xc3, 0xbf, + 0x74, 0x38, 0x1b, 0xf5, 0xfd, 0x40, 0xe9, 0xad, 0xd2, 0x24, 0x48, 0x6d, 0x62, 0x14, 0xe1, 0xe1, + 0x78, 0x32, 0x19, 0x4d, 0xc9, 0x86, 0x5b, 0xe7, 0xed, 0xd7, 0x67, 0x30, 0xa9, 0x57, 0x1b, 0x6e, + 0x2b, 0xdd, 0xe0, 0x09, 0x76, 0xe7, 0x55, 0xe8, 0xa3, 0xa1, 0x86, 0x7b, 0x73, 0xd8, 0x75, 0x25, + 0x0a, 0x91, 0xee, 0x01, 0xbf, 0x39, 0xec, 0x8c, 0xcf, 0x71, 0x5d, 0x15, 0xec, 0xdc, 0xf7, 0xdc, + 0x2e, 0x3b, 0xd1, 0xf1, 0xae, 0x07, 0x6f, 0x00, 0xc2, 0x9f, 0x99, 0x77, 0x09, 0x4f, 0x33, 0x2a, + 0x45, 0x48, 0x8d, 0x4a, 0x57, 0x34, 0x0c, 0x53, 0xae, 0x8b, 0xe5, 0x60, 0xd8, 0x5e, 0x9e, 0x1c, + 0x07, 0x77, 0xd5, 0xbf, 0x37, 0x85, 0xff, 0x5d, 0xcb, 0xde, 0x3f, 0x1f, 0x0c, 0x3b, 0x63, 0xbf, + 0x3e, 0x7f, 0x26, 0xcb, 0xec, 0x16, 0x2b, 0x4f, 0xef, 0x16, 0xc2, 0x8c, 0xca, 0x55, 0xb2, 0x63, + 0x85, 0xbb, 0x59, 0xba, 0xcf, 0x70, 0x85, 0x0b, 0x57, 0xb8, 0xb0, 0xc3, 0x85, 0x17, 0x3b, 0x56, + 0x58, 0xdb, 0x19, 0x95, 0x8b, 0x52, 0x3f, 0x7b, 0x78, 0x3f, 0x20, 0xb0, 0x3f, 0x20, 0xf0, 0x79, + 0x40, 0xe0, 0x35, 0x47, 0x8d, 0x7d, 0x8e, 0x1a, 0x1f, 0x39, 0x6a, 0x3c, 0xdf, 0x44, 0xc2, 0xac, + 0x77, 0x0c, 0x07, 0x6a, 0x4b, 0x5c, 0x17, 0x49, 0x99, 0xbe, 0x12, 0xea, 0xfb, 0x49, 0x5e, 0xfe, + 0xb0, 0x36, 0x36, 0xe1, 0x9a, 0xb5, 0x4a, 0xce, 0xd7, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x75, + 0xb3, 0x01, 0x5c, 0xf5, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/checkpointing/types/keys.go b/x/checkpointing/types/keys.go index 53847c1c4..1db18fc52 100644 --- a/x/checkpointing/types/keys.go +++ b/x/checkpointing/types/keys.go @@ -1,7 +1,7 @@ package types import ( - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/crypto/bls12381" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/checkpointing/types/msgs.go b/x/checkpointing/types/msgs.go index 4af049c62..869f36578 100644 --- a/x/checkpointing/types/msgs.go +++ b/x/checkpointing/types/msgs.go @@ -9,7 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/crypto/bls12381" ) var ( diff --git a/x/checkpointing/types/msgs_test.go b/x/checkpointing/types/msgs_test.go index f8191cce7..89301ebbf 100644 --- a/x/checkpointing/types/msgs_test.go +++ b/x/checkpointing/types/msgs_test.go @@ -4,10 +4,10 @@ import ( "testing" sdkmath "cosmossdk.io/math" - appparams "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" - "github.com/babylonchain/babylon/x/checkpointing/types" + appparams "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/checkpointing/types/pop.go b/x/checkpointing/types/pop.go index 6e7586157..c5f14fc03 100644 --- a/x/checkpointing/types/pop.go +++ b/x/checkpointing/types/pop.go @@ -1,7 +1,7 @@ package types import ( - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/crypto/bls12381" "github.com/cometbft/cometbft/crypto/ed25519" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) diff --git a/x/checkpointing/types/pop_test.go b/x/checkpointing/types/pop_test.go index 3bd2aec76..10e03df6a 100644 --- a/x/checkpointing/types/pop_test.go +++ b/x/checkpointing/types/pop_test.go @@ -1,8 +1,8 @@ package types_test import ( - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/privval" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/privval" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/stretchr/testify/require" diff --git a/x/checkpointing/types/query.pb.go b/x/checkpointing/types/query.pb.go index 485d8e0ec..30aef80a1 100644 --- a/x/checkpointing/types/query.pb.go +++ b/x/checkpointing/types/query.pb.go @@ -6,7 +6,7 @@ package types import ( context "context" fmt "fmt" - github_com_babylonchain_babylon_crypto_bls12381 "github.com/babylonchain/babylon/crypto/bls12381" + github_com_babylonlabs_io_babylon_crypto_bls12381 "github.com/babylonlabs-io/babylon/crypto/bls12381" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -759,7 +759,7 @@ type RawCheckpointResponse struct { Bitmap []byte `protobuf:"bytes,3,opt,name=bitmap,proto3" json:"bitmap,omitempty"` // bls_multi_sig defines the multi sig that is aggregated from individual BLS // sigs - BlsMultiSig *github_com_babylonchain_babylon_crypto_bls12381.Signature `protobuf:"bytes,4,opt,name=bls_multi_sig,json=blsMultiSig,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.Signature" json:"bls_multi_sig,omitempty"` + BlsMultiSig *github_com_babylonlabs_io_babylon_crypto_bls12381.Signature `protobuf:"bytes,4,opt,name=bls_multi_sig,json=blsMultiSig,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" json:"bls_multi_sig,omitempty"` } func (m *RawCheckpointResponse) Reset() { *m = RawCheckpointResponse{} } @@ -899,7 +899,7 @@ type RawCheckpointWithMetaResponse struct { // status_desc respresents the description of status enum. StatusDesc string `protobuf:"bytes,3,opt,name=status_desc,json=statusDesc,proto3" json:"status_desc,omitempty"` // bls_aggr_pk defines the aggregated BLS public key - BlsAggrPk *github_com_babylonchain_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,4,opt,name=bls_aggr_pk,json=blsAggrPk,proto3,customtype=github.com/babylonchain/babylon/crypto/bls12381.PublicKey" json:"bls_aggr_pk,omitempty"` + BlsAggrPk *github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey `protobuf:"bytes,4,opt,name=bls_aggr_pk,json=blsAggrPk,proto3,customtype=github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" json:"bls_aggr_pk,omitempty"` // power_sum defines the accumulated voting power for the checkpoint PowerSum uint64 `protobuf:"varint,5,opt,name=power_sum,json=powerSum,proto3" json:"power_sum,omitempty"` // lifecycle defines the lifecycle of this checkpoint, i.e., each state @@ -1002,87 +1002,87 @@ func init() { } var fileDescriptor_113f1ca5c3c2ca44 = []byte{ - // 1266 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0x5d, 0x6f, 0x1b, 0x45, - 0x17, 0xee, 0xda, 0x49, 0xf4, 0xfa, 0x38, 0xcd, 0x5b, 0x46, 0xa5, 0x35, 0x6e, 0xeb, 0x94, 0xa5, - 0x94, 0xb4, 0xa8, 0xbb, 0xb2, 0xd3, 0x7c, 0x50, 0xfa, 0x01, 0x2e, 0x81, 0x4a, 0xfd, 0x20, 0x6c, - 0x68, 0x91, 0x90, 0xe8, 0x32, 0xbb, 0x99, 0xae, 0x17, 0xaf, 0x77, 0x37, 0x9e, 0x59, 0x27, 0x56, - 0xa9, 0x90, 0xe0, 0x0f, 0x54, 0x42, 0xe2, 0x8a, 0x7f, 0xc0, 0x0d, 0xdc, 0x71, 0xcd, 0x55, 0x25, - 0x10, 0xaa, 0x84, 0x90, 0x10, 0x48, 0x50, 0x25, 0x88, 0xdf, 0x81, 0x76, 0x76, 0x1c, 0x7b, 0x6d, - 0xaf, 0x1d, 0x3b, 0xb9, 0xe1, 0x2e, 0x3e, 0x7b, 0xce, 0xcc, 0x73, 0x9e, 0xf3, 0x31, 0x4f, 0xe0, - 0x8c, 0x81, 0x8d, 0xa6, 0xe3, 0xb9, 0xaa, 0x59, 0x21, 0x66, 0xd5, 0xf7, 0x6c, 0x97, 0xd9, 0xae, - 0xa5, 0x36, 0x8a, 0xea, 0x46, 0x40, 0xea, 0x4d, 0xc5, 0xaf, 0x7b, 0xcc, 0x43, 0x39, 0xe1, 0xa5, - 0xc4, 0xbc, 0x94, 0x46, 0x31, 0x7f, 0xd4, 0xf2, 0x2c, 0x8f, 0x3b, 0xa9, 0xe1, 0x5f, 0x91, 0x7f, - 0xfe, 0xa4, 0xe5, 0x79, 0x96, 0x43, 0x54, 0xec, 0xdb, 0x2a, 0x76, 0x5d, 0x8f, 0x61, 0x66, 0x7b, - 0x2e, 0x15, 0x5f, 0x67, 0xc5, 0x57, 0xfe, 0xcb, 0x08, 0x1e, 0xa8, 0xcc, 0xae, 0x11, 0xca, 0x70, - 0xcd, 0x17, 0x0e, 0x67, 0x13, 0x41, 0x19, 0x0e, 0xd5, 0xab, 0x44, 0xc0, 0xca, 0x9f, 0x4b, 0xf4, - 0x6b, 0x1b, 0x84, 0xeb, 0x79, 0xd3, 0xa3, 0x35, 0x8f, 0xaa, 0x06, 0xa6, 0x24, 0x4a, 0x4d, 0x6d, - 0x14, 0x0d, 0xc2, 0x70, 0x51, 0xf5, 0xb1, 0x65, 0xbb, 0x1c, 0x60, 0xe4, 0x2b, 0x7f, 0x23, 0xc1, - 0xa9, 0xf7, 0x42, 0x17, 0x0d, 0x6f, 0x5e, 0xdf, 0x3d, 0xe8, 0x96, 0x4d, 0x99, 0x46, 0x36, 0x02, - 0x42, 0x19, 0x2a, 0xc3, 0x14, 0x65, 0x98, 0x05, 0x34, 0x27, 0x9d, 0x96, 0xe6, 0x66, 0x4a, 0xe7, - 0x95, 0x24, 0x82, 0x94, 0xf6, 0x01, 0x6b, 0x3c, 0x42, 0x13, 0x91, 0xe8, 0x6d, 0x80, 0xf6, 0xcd, - 0xb9, 0xd4, 0x69, 0x69, 0x2e, 0x5b, 0x3a, 0xab, 0x44, 0x30, 0x95, 0x10, 0xa6, 0x12, 0x55, 0x40, - 0xc0, 0x54, 0x56, 0xb1, 0x45, 0xc4, 0xfd, 0x5a, 0x47, 0xa4, 0xfc, 0xa3, 0x04, 0x85, 0x24, 0xb4, - 0xd4, 0xf7, 0x5c, 0x4a, 0xd0, 0xc7, 0xf0, 0xff, 0x3a, 0xde, 0xd4, 0xdb, 0xd8, 0x42, 0xdc, 0xe9, - 0xb9, 0x6c, 0x69, 0x29, 0x19, 0x77, 0xec, 0xb4, 0x0f, 0x6c, 0x56, 0xb9, 0x4d, 0x18, 0x6e, 0x9d, - 0xa8, 0xcd, 0xd4, 0x3b, 0x3f, 0x53, 0xf4, 0x4e, 0x9f, 0x64, 0x5e, 0x19, 0x9a, 0x8c, 0x38, 0xac, - 0x33, 0x9b, 0x65, 0x78, 0xa1, 0x37, 0x99, 0x16, 0xed, 0x27, 0x20, 0x43, 0x7c, 0xcf, 0xac, 0xe8, - 0x6e, 0x50, 0xe3, 0xcc, 0x4f, 0x68, 0xff, 0xe3, 0x86, 0x3b, 0x41, 0x4d, 0xfe, 0x14, 0xf2, 0xfd, - 0x22, 0x05, 0x05, 0xf7, 0x61, 0x26, 0x4e, 0x01, 0x8f, 0xdf, 0x07, 0x03, 0x87, 0x63, 0x0c, 0xc8, - 0xeb, 0xfd, 0x6e, 0xa7, 0x2d, 0xe0, 0xf1, 0x5a, 0x4b, 0x63, 0xd7, 0xfa, 0x89, 0x04, 0x27, 0xfa, - 0x5e, 0xf3, 0xdf, 0x2b, 0xf4, 0x17, 0x12, 0x9c, 0xe4, 0xa9, 0x94, 0x1d, 0xba, 0x1a, 0x18, 0x8e, - 0x6d, 0xde, 0x24, 0xcd, 0xce, 0x19, 0x1b, 0x54, 0xec, 0x03, 0x1b, 0x9e, 0x9f, 0x5b, 0xa3, 0xde, - 0x8b, 0x42, 0x50, 0xba, 0x0e, 0xc7, 0x1b, 0xd8, 0xb1, 0xd7, 0x31, 0xf3, 0xea, 0xfa, 0xa6, 0xcd, - 0x2a, 0xba, 0xd8, 0x41, 0x2d, 0x6a, 0x2f, 0x24, 0x53, 0x7b, 0xaf, 0x15, 0x18, 0xd2, 0x5a, 0x76, - 0xe8, 0x4d, 0xd2, 0xd4, 0x8e, 0x36, 0x7a, 0x8d, 0x07, 0x48, 0xeb, 0x22, 0x1c, 0xe7, 0xf9, 0xac, - 0x84, 0x4c, 0x89, 0x8d, 0xb3, 0x97, 0xe9, 0xb9, 0x0f, 0xb9, 0xde, 0x38, 0x41, 0xc1, 0x01, 0x6c, - 0x3b, 0x79, 0x05, 0xe4, 0xa8, 0x71, 0x89, 0x49, 0x5c, 0xd6, 0x71, 0xcb, 0x75, 0x2f, 0x68, 0x0f, - 0xf8, 0x2c, 0x64, 0x23, 0x88, 0x66, 0x68, 0x15, 0x20, 0x81, 0x9b, 0xb8, 0x9f, 0xfc, 0x55, 0x0a, - 0x5e, 0x1a, 0x78, 0x8e, 0x80, 0x7c, 0x02, 0x32, 0xcc, 0xf6, 0x75, 0x1e, 0xd9, 0xca, 0x95, 0xd9, - 0x3e, 0xf7, 0xef, 0xbe, 0x25, 0xd5, 0x7d, 0x0b, 0xda, 0x80, 0xe9, 0x08, 0xb6, 0xf0, 0x48, 0xf3, - 0x42, 0xdf, 0x49, 0x4e, 0x7b, 0x0f, 0x90, 0x94, 0x0e, 0xdb, 0x8a, 0xcb, 0xea, 0x4d, 0x2d, 0x4b, - 0xdb, 0x96, 0xfc, 0x55, 0x38, 0xd2, 0xed, 0x80, 0x8e, 0x40, 0xba, 0x4a, 0x9a, 0x1c, 0x7e, 0x46, - 0x0b, 0xff, 0x44, 0x47, 0x61, 0xb2, 0x81, 0x9d, 0x80, 0x08, 0xcc, 0xd1, 0x8f, 0x4b, 0xa9, 0x65, - 0x49, 0xfe, 0x04, 0xce, 0x70, 0x10, 0xb7, 0x30, 0x65, 0xf1, 0x71, 0x8e, 0x37, 0xc1, 0x41, 0xd4, - 0xf2, 0x33, 0x78, 0x79, 0xc8, 0x5d, 0xa2, 0x0a, 0xf7, 0x12, 0x96, 0xae, 0xba, 0xc7, 0x6d, 0x94, - 0xb4, 0x6c, 0x7f, 0x95, 0xe0, 0xf9, 0xfe, 0x6b, 0x7e, 0xe0, 0xd2, 0x38, 0x03, 0x33, 0x86, 0xe3, - 0x99, 0x55, 0xbd, 0x82, 0x69, 0x45, 0xaf, 0x90, 0x2d, 0x4e, 0x63, 0x46, 0x9b, 0xe6, 0xd6, 0x1b, - 0x98, 0x56, 0x6e, 0x90, 0x2d, 0x74, 0x0c, 0xa6, 0x0c, 0x9b, 0xd5, 0xb0, 0x9f, 0x4b, 0x9f, 0x96, - 0xe6, 0xa6, 0x35, 0xf1, 0x0b, 0x61, 0x38, 0x1c, 0x4e, 0x7e, 0x2d, 0x70, 0x98, 0xad, 0x53, 0xdb, - 0xca, 0x4d, 0x84, 0x9f, 0xcb, 0x57, 0x7e, 0xff, 0x73, 0xf6, 0x35, 0xcb, 0x66, 0x95, 0xc0, 0x50, - 0x4c, 0xaf, 0xa6, 0x8a, 0xcc, 0xcc, 0x0a, 0xb6, 0x5d, 0x75, 0x57, 0x9f, 0xd4, 0x9b, 0x3e, 0xf3, - 0x42, 0xf5, 0x52, 0x2c, 0xcd, 0x2f, 0x17, 0x95, 0x35, 0xdb, 0x72, 0x31, 0x0b, 0xea, 0x44, 0xcb, - 0x1a, 0x0e, 0xbd, 0x1d, 0x1e, 0xb9, 0x66, 0x5b, 0xf2, 0x3f, 0x12, 0x9c, 0x8a, 0xb3, 0x4e, 0xee, - 0xfa, 0xeb, 0x98, 0xed, 0x8e, 0x3a, 0x7a, 0x03, 0x26, 0xc3, 0x22, 0x90, 0x31, 0xaa, 0x17, 0x05, - 0x86, 0xcd, 0x2f, 0x7a, 0x7b, 0x9d, 0x50, 0x53, 0x30, 0x00, 0x91, 0xe9, 0x2d, 0x42, 0x4d, 0xf4, - 0x22, 0x4c, 0x0b, 0x96, 0x88, 0x6d, 0x55, 0x18, 0x67, 0x61, 0x22, 0xc4, 0x19, 0x72, 0xc4, 0x4d, - 0xe8, 0x1a, 0x40, 0xe4, 0x12, 0x0a, 0x37, 0xce, 0x43, 0xb6, 0x94, 0x57, 0x22, 0x55, 0xa7, 0xb4, - 0x54, 0x9d, 0xf2, 0x7e, 0x4b, 0xd5, 0x95, 0x27, 0x1e, 0xff, 0x35, 0x2b, 0x69, 0x19, 0x1e, 0x13, - 0x5a, 0xe5, 0xaf, 0xd3, 0x70, 0x6a, 0xe0, 0xbb, 0x83, 0xae, 0xc3, 0x84, 0x59, 0xf5, 0xc7, 0x6e, - 0x18, 0x1e, 0xdc, 0xd1, 0xec, 0xa9, 0xb1, 0x65, 0x5a, 0x17, 0x5f, 0xe9, 0x1e, 0xbe, 0x3e, 0x82, - 0xb0, 0x86, 0x3a, 0xb6, 0xac, 0xba, 0xee, 0x57, 0xf7, 0xd3, 0x15, 0xbb, 0x0f, 0x50, 0x48, 0x15, - 0x7d, 0xd3, 0xb2, 0xea, 0xab, 0xd5, 0xb0, 0xa3, 0x7d, 0x6f, 0x93, 0xd4, 0x75, 0x1a, 0xd4, 0x72, - 0x93, 0x51, 0x47, 0x73, 0xc3, 0x5a, 0x50, 0x43, 0x77, 0x21, 0xe3, 0xd8, 0x0f, 0x88, 0xd9, 0x34, - 0x1d, 0x92, 0x9b, 0x1a, 0xf6, 0xd2, 0x0f, 0x6c, 0x2d, 0xad, 0x7d, 0x52, 0xe9, 0x19, 0xc0, 0x24, - 0x9f, 0x70, 0xf4, 0x83, 0x04, 0xcf, 0xf5, 0xe8, 0x4a, 0xb4, 0x34, 0x6c, 0x13, 0x26, 0xe8, 0xe6, - 0xfc, 0xf2, 0xe8, 0x81, 0x11, 0x3a, 0xf9, 0xd2, 0xe7, 0xbf, 0xfc, 0xfd, 0x65, 0xea, 0x22, 0x2a, - 0xa9, 0x89, 0x9a, 0xbf, 0x4b, 0xf9, 0xa8, 0x0f, 0xa3, 0x22, 0x3d, 0x42, 0xdf, 0x4b, 0x70, 0x38, - 0x76, 0x32, 0x9a, 0x1f, 0x05, 0x47, 0x0b, 0xfc, 0xc5, 0xd1, 0x82, 0x04, 0xf0, 0xcb, 0x1c, 0xf8, - 0x22, 0xba, 0xb8, 0x57, 0xe0, 0xea, 0xc3, 0xdd, 0x0d, 0xf6, 0x08, 0x7d, 0x2b, 0xc1, 0x4c, 0x5c, - 0xeb, 0xa1, 0x91, 0x60, 0xb4, 0xf6, 0x7e, 0x7e, 0x61, 0xc4, 0x28, 0x81, 0xbe, 0xc8, 0xd1, 0xbf, - 0x8a, 0xce, 0xed, 0x99, 0xf6, 0xb0, 0x65, 0x8e, 0x74, 0xab, 0x29, 0xb4, 0x38, 0xe4, 0xfa, 0x04, - 0x11, 0x98, 0x5f, 0x1a, 0x39, 0x4e, 0x00, 0xbf, 0xc2, 0x81, 0x2f, 0xa1, 0x05, 0x75, 0xe0, 0xff, - 0x92, 0x3e, 0x0f, 0xe6, 0x72, 0x2e, 0xc6, 0xfb, 0x77, 0x12, 0x64, 0x3b, 0x5e, 0x72, 0x54, 0x1c, - 0x82, 0xa3, 0x57, 0x6e, 0xe5, 0x4b, 0xa3, 0x84, 0x08, 0xd4, 0xaf, 0x73, 0xd4, 0x0b, 0x68, 0x3e, - 0x19, 0x35, 0x07, 0x19, 0x03, 0xab, 0x8a, 0x4d, 0xf5, 0x93, 0x04, 0xc7, 0xfa, 0x6b, 0x10, 0x74, - 0x79, 0x4c, 0xe9, 0x12, 0x65, 0x72, 0x65, 0x5f, 0xc2, 0x47, 0x5e, 0xe0, 0x49, 0xa9, 0xe8, 0xc2, - 0xb0, 0xa4, 0x2e, 0x75, 0x8a, 0x2e, 0xf4, 0x87, 0x04, 0xb9, 0x24, 0x85, 0x81, 0xae, 0x0e, 0x81, - 0x34, 0x44, 0x06, 0xe5, 0xaf, 0x8d, 0x1d, 0x2f, 0x92, 0xba, 0xca, 0x93, 0x5a, 0x46, 0x8b, 0xc9, - 0x49, 0x39, 0x98, 0x32, 0xbd, 0x7b, 0xb6, 0xc5, 0x4e, 0x2a, 0xbf, 0xfb, 0x64, 0xbb, 0x20, 0x3d, - 0xdd, 0x2e, 0x48, 0xcf, 0xb6, 0x0b, 0xd2, 0xe3, 0x9d, 0xc2, 0xa1, 0xa7, 0x3b, 0x85, 0x43, 0xbf, - 0xed, 0x14, 0x0e, 0x7d, 0xb8, 0x30, 0xec, 0xd9, 0xd8, 0xea, 0xba, 0x8a, 0x35, 0x7d, 0x42, 0x8d, - 0x29, 0xfe, 0xee, 0xce, 0xff, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xee, 0xf6, 0x49, 0x5b, 0xd1, 0x11, - 0x00, 0x00, + // 1265 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0xdd, 0x6f, 0xdb, 0x54, + 0x14, 0x9f, 0x93, 0xb6, 0x22, 0x27, 0x5d, 0x19, 0x57, 0x63, 0x0b, 0xd9, 0x96, 0x0e, 0x33, 0x46, + 0x37, 0x34, 0x5b, 0x49, 0xd7, 0x0f, 0xed, 0x13, 0x32, 0x0a, 0x93, 0xf6, 0xa1, 0xce, 0x65, 0x43, + 0xe2, 0x61, 0xe6, 0xda, 0xbd, 0x73, 0x4c, 0x1c, 0xdb, 0xcd, 0xbd, 0x4e, 0x1b, 0x8d, 0x09, 0x09, + 0xfe, 0x81, 0x49, 0x48, 0x3c, 0xf2, 0x0f, 0xf0, 0x02, 0x6f, 0x3c, 0xf3, 0x34, 0x09, 0x84, 0x26, + 0xf1, 0x00, 0x02, 0x09, 0xa6, 0x16, 0xf1, 0x77, 0x20, 0x5f, 0xdf, 0x34, 0x71, 0x12, 0x27, 0x4d, + 0xda, 0x17, 0xde, 0x9a, 0xe3, 0x73, 0xee, 0xfd, 0x9d, 0xdf, 0xf9, 0xb8, 0xbf, 0xc2, 0x19, 0x03, + 0x1b, 0x4d, 0xc7, 0x73, 0x55, 0xb3, 0x42, 0xcc, 0xaa, 0xef, 0xd9, 0x2e, 0xb3, 0x5d, 0x4b, 0x6d, + 0x14, 0xd5, 0x8d, 0x80, 0xd4, 0x9b, 0x8a, 0x5f, 0xf7, 0x98, 0x87, 0x72, 0xc2, 0x4b, 0x89, 0x79, + 0x29, 0x8d, 0x62, 0xfe, 0xa8, 0xe5, 0x59, 0x1e, 0x77, 0x52, 0xc3, 0xbf, 0x22, 0xff, 0xfc, 0x49, + 0xcb, 0xf3, 0x2c, 0x87, 0xa8, 0xd8, 0xb7, 0x55, 0xec, 0xba, 0x1e, 0xc3, 0xcc, 0xf6, 0x5c, 0x2a, + 0xbe, 0xce, 0x8a, 0xaf, 0xfc, 0x97, 0x11, 0x3c, 0x52, 0x99, 0x5d, 0x23, 0x94, 0xe1, 0x9a, 0x2f, + 0x1c, 0xce, 0x26, 0x82, 0x32, 0x1c, 0xaa, 0x57, 0x89, 0x80, 0x95, 0x3f, 0x97, 0xe8, 0xd7, 0x36, + 0x08, 0xd7, 0xf3, 0xa6, 0x47, 0x6b, 0x1e, 0x55, 0x0d, 0x4c, 0x49, 0x94, 0x9a, 0xda, 0x28, 0x1a, + 0x84, 0xe1, 0xa2, 0xea, 0x63, 0xcb, 0x76, 0x39, 0xc0, 0xc8, 0x57, 0xfe, 0x56, 0x82, 0x53, 0xf7, + 0x42, 0x17, 0x0d, 0x6f, 0xde, 0xd8, 0x3d, 0xe8, 0xb6, 0x4d, 0x99, 0x46, 0x36, 0x02, 0x42, 0x19, + 0x2a, 0xc3, 0x14, 0x65, 0x98, 0x05, 0x34, 0x27, 0x9d, 0x96, 0xe6, 0x66, 0x4a, 0xe7, 0x95, 0x24, + 0x82, 0x94, 0xf6, 0x01, 0x6b, 0x3c, 0x42, 0x13, 0x91, 0xe8, 0x7d, 0x80, 0xf6, 0xcd, 0xb9, 0xd4, + 0x69, 0x69, 0x2e, 0x5b, 0x3a, 0xab, 0x44, 0x30, 0x95, 0x10, 0xa6, 0x12, 0x55, 0x40, 0xc0, 0x54, + 0x56, 0xb1, 0x45, 0xc4, 0xfd, 0x5a, 0x47, 0xa4, 0xfc, 0x93, 0x04, 0x85, 0x24, 0xb4, 0xd4, 0xf7, + 0x5c, 0x4a, 0xd0, 0x27, 0xf0, 0x72, 0x1d, 0x6f, 0xea, 0x6d, 0x6c, 0x21, 0xee, 0xf4, 0x5c, 0xb6, + 0xb4, 0x94, 0x8c, 0x3b, 0x76, 0xda, 0x47, 0x36, 0xab, 0xdc, 0x21, 0x0c, 0xb7, 0x4e, 0xd4, 0x66, + 0xea, 0x9d, 0x9f, 0x29, 0xfa, 0xa0, 0x4f, 0x32, 0x6f, 0x0d, 0x4d, 0x46, 0x1c, 0xd6, 0x99, 0xcd, + 0x32, 0xbc, 0xd6, 0x9b, 0x4c, 0x8b, 0xf6, 0x13, 0x90, 0x21, 0xbe, 0x67, 0x56, 0x74, 0x37, 0xa8, + 0x71, 0xe6, 0x27, 0xb4, 0x97, 0xb8, 0xe1, 0x6e, 0x50, 0x93, 0x3f, 0x83, 0x7c, 0xbf, 0x48, 0x41, + 0xc1, 0x43, 0x98, 0x89, 0x53, 0xc0, 0xe3, 0xf7, 0xc1, 0xc0, 0xe1, 0x18, 0x03, 0xf2, 0x7a, 0xbf, + 0xdb, 0x69, 0x0b, 0x78, 0xbc, 0xd6, 0xd2, 0xd8, 0xb5, 0x7e, 0x26, 0xc1, 0x89, 0xbe, 0xd7, 0xfc, + 0xff, 0x0a, 0xfd, 0xa5, 0x04, 0x27, 0x79, 0x2a, 0x65, 0x87, 0xae, 0x06, 0x86, 0x63, 0x9b, 0xb7, + 0x48, 0xb3, 0x73, 0xc6, 0x06, 0x15, 0xfb, 0xc0, 0x86, 0xe7, 0x97, 0xd6, 0xa8, 0xf7, 0xa2, 0x10, + 0x94, 0xae, 0xc3, 0xf1, 0x06, 0x76, 0xec, 0x75, 0xcc, 0xbc, 0xba, 0xbe, 0x69, 0xb3, 0x8a, 0x2e, + 0x76, 0x50, 0x8b, 0xda, 0x0b, 0xc9, 0xd4, 0x3e, 0x68, 0x05, 0x86, 0xb4, 0x96, 0x1d, 0x7a, 0x8b, + 0x34, 0xb5, 0xa3, 0x8d, 0x5e, 0xe3, 0x01, 0xd2, 0xba, 0x08, 0xc7, 0x79, 0x3e, 0x2b, 0x21, 0x53, + 0x62, 0xe3, 0xec, 0x65, 0x7a, 0x1e, 0x42, 0xae, 0x37, 0x4e, 0x50, 0x70, 0x00, 0xdb, 0x4e, 0x5e, + 0x01, 0x39, 0x6a, 0x5c, 0x62, 0x12, 0x97, 0x75, 0xdc, 0x72, 0xc3, 0x0b, 0xda, 0x03, 0x3e, 0x0b, + 0xd9, 0x08, 0xa2, 0x19, 0x5a, 0x05, 0x48, 0xe0, 0x26, 0xee, 0x27, 0x7f, 0x9d, 0x82, 0x37, 0x06, + 0x9e, 0x23, 0x20, 0x9f, 0x80, 0x0c, 0xb3, 0x7d, 0x9d, 0x47, 0xb6, 0x72, 0x65, 0xb6, 0xcf, 0xfd, + 0xbb, 0x6f, 0x49, 0x75, 0xdf, 0x82, 0x36, 0x60, 0x3a, 0x82, 0x2d, 0x3c, 0xd2, 0xbc, 0xd0, 0x77, + 0x93, 0xd3, 0xde, 0x03, 0x24, 0xa5, 0xc3, 0xb6, 0xe2, 0xb2, 0x7a, 0x53, 0xcb, 0xd2, 0xb6, 0x25, + 0x7f, 0x0d, 0x8e, 0x74, 0x3b, 0xa0, 0x23, 0x90, 0xae, 0x92, 0x26, 0x87, 0x9f, 0xd1, 0xc2, 0x3f, + 0xd1, 0x51, 0x98, 0x6c, 0x60, 0x27, 0x20, 0x02, 0x73, 0xf4, 0xe3, 0x52, 0x6a, 0x59, 0x92, 0x3f, + 0x85, 0x33, 0x1c, 0xc4, 0x6d, 0x4c, 0x59, 0x7c, 0x9c, 0xe3, 0x4d, 0x70, 0x10, 0xb5, 0xfc, 0x1c, + 0xde, 0x1c, 0x72, 0x97, 0xa8, 0xc2, 0x83, 0x84, 0xa5, 0xab, 0xee, 0x71, 0x1b, 0x25, 0x2d, 0xdb, + 0xdf, 0x24, 0x78, 0xb5, 0xff, 0x9a, 0x1f, 0xb8, 0x34, 0xce, 0xc0, 0x8c, 0xe1, 0x78, 0x66, 0x55, + 0xaf, 0x60, 0x5a, 0xd1, 0x2b, 0x64, 0x8b, 0xd3, 0x98, 0xd1, 0xa6, 0xb9, 0xf5, 0x26, 0xa6, 0x95, + 0x9b, 0x64, 0x0b, 0x1d, 0x83, 0x29, 0xc3, 0x66, 0x35, 0xec, 0xe7, 0xd2, 0xa7, 0xa5, 0xb9, 0x69, + 0x4d, 0xfc, 0x42, 0x26, 0x1c, 0x0e, 0x27, 0xbf, 0x16, 0x38, 0xcc, 0xd6, 0xa9, 0x6d, 0xe5, 0x26, + 0xc2, 0xcf, 0xe5, 0xeb, 0x7f, 0xfc, 0x35, 0x7b, 0xd9, 0xb2, 0x59, 0x25, 0x30, 0x14, 0xd3, 0xab, + 0xa9, 0x22, 0x33, 0x07, 0x1b, 0xf4, 0x82, 0xed, 0xa9, 0xbb, 0x0a, 0xa5, 0xde, 0xf4, 0x99, 0x17, + 0xea, 0x97, 0x62, 0x69, 0x7e, 0xb9, 0xa8, 0xac, 0xd9, 0x96, 0x8b, 0x59, 0x50, 0x27, 0x5a, 0xd6, + 0x70, 0xe8, 0x9d, 0xf0, 0xd0, 0x35, 0xdb, 0x92, 0xff, 0x95, 0xe0, 0x54, 0x9c, 0x77, 0x72, 0xdf, + 0x5f, 0xc7, 0x6c, 0x77, 0xd8, 0xd1, 0x3b, 0x30, 0x19, 0x96, 0x81, 0x8c, 0x51, 0xbf, 0x28, 0x30, + 0x6c, 0x7f, 0xd1, 0xdd, 0xeb, 0x84, 0x9a, 0x82, 0x03, 0x88, 0x4c, 0xef, 0x11, 0x6a, 0xa2, 0xd7, + 0x61, 0x5a, 0xf0, 0x44, 0x6c, 0xab, 0xc2, 0x38, 0x0f, 0x13, 0x21, 0xce, 0x90, 0x25, 0x6e, 0x42, + 0xd7, 0x01, 0x22, 0x97, 0x50, 0xba, 0x71, 0x26, 0xb2, 0xa5, 0xbc, 0x12, 0xe9, 0x3a, 0xa5, 0xa5, + 0xeb, 0x94, 0x0f, 0x5b, 0xba, 0xae, 0x3c, 0xf1, 0xf4, 0xef, 0x59, 0x49, 0xcb, 0xf0, 0x98, 0xd0, + 0x2a, 0x7f, 0x93, 0x86, 0x53, 0x03, 0x5f, 0x1e, 0x74, 0x03, 0x26, 0xcc, 0xaa, 0x3f, 0x76, 0xcb, + 0xf0, 0xe0, 0x8e, 0x76, 0x4f, 0x8d, 0x2d, 0xd4, 0xba, 0xf8, 0x4a, 0xf7, 0xf0, 0xa5, 0x43, 0x58, + 0x43, 0x1d, 0x5b, 0x56, 0x5d, 0xf7, 0xab, 0xfb, 0xeb, 0x8b, 0xdd, 0x47, 0x28, 0x24, 0x8b, 0xbe, + 0x6b, 0x59, 0xf5, 0xd5, 0x6a, 0xd8, 0xd5, 0xbe, 0xb7, 0x49, 0xea, 0x3a, 0x0d, 0x6a, 0xb9, 0xc9, + 0xa8, 0xab, 0xb9, 0x61, 0x2d, 0xa8, 0xa1, 0xfb, 0x90, 0x71, 0xec, 0x47, 0xc4, 0x6c, 0x9a, 0x0e, + 0xc9, 0x4d, 0x0d, 0x7b, 0xed, 0x07, 0x36, 0x97, 0xd6, 0x3e, 0xa9, 0xf4, 0x02, 0x60, 0x92, 0x4f, + 0x39, 0xfa, 0x51, 0x82, 0x57, 0x7a, 0xb4, 0x25, 0x5a, 0x1a, 0xb6, 0x0d, 0x13, 0xb4, 0x73, 0x7e, + 0x79, 0xf4, 0xc0, 0x08, 0x9d, 0x7c, 0xe9, 0x8b, 0x5f, 0xff, 0xf9, 0x2a, 0x75, 0x11, 0x95, 0xd4, + 0x44, 0xdd, 0xdf, 0xa5, 0x7e, 0xd4, 0xc7, 0x51, 0x99, 0x9e, 0xa0, 0x1f, 0x24, 0x38, 0x1c, 0x3b, + 0x19, 0xcd, 0x8f, 0x82, 0xa3, 0x05, 0xfe, 0xe2, 0x68, 0x41, 0x02, 0xf8, 0x15, 0x0e, 0x7c, 0x11, + 0x5d, 0xdc, 0x2b, 0x70, 0xf5, 0xf1, 0xee, 0x16, 0x7b, 0x82, 0xbe, 0x93, 0x60, 0x26, 0xae, 0xf7, + 0xd0, 0x48, 0x30, 0x5a, 0xbb, 0x3f, 0xbf, 0x30, 0x62, 0x94, 0x40, 0x5f, 0xe4, 0xe8, 0xdf, 0x46, + 0xe7, 0xf6, 0x4c, 0x7b, 0xd8, 0x32, 0x47, 0xba, 0x15, 0x15, 0x5a, 0x1c, 0x72, 0x7d, 0x82, 0x10, + 0xcc, 0x2f, 0x8d, 0x1c, 0x27, 0x80, 0x5f, 0xe5, 0xc0, 0x97, 0xd0, 0x82, 0x3a, 0xf0, 0xff, 0x49, + 0x9f, 0x07, 0x73, 0x49, 0x17, 0xe3, 0xfd, 0x7b, 0x09, 0xb2, 0x1d, 0xaf, 0x39, 0x2a, 0x0e, 0xc1, + 0xd1, 0x2b, 0xb9, 0xf2, 0xa5, 0x51, 0x42, 0x04, 0xea, 0xcb, 0x1c, 0xf5, 0x02, 0x9a, 0x4f, 0x46, + 0xcd, 0x41, 0xc6, 0xc0, 0xaa, 0x62, 0x57, 0xfd, 0x2c, 0xc1, 0xb1, 0xfe, 0x3a, 0x04, 0x5d, 0x19, + 0x53, 0xbe, 0x44, 0x99, 0x5c, 0xdd, 0x97, 0xf8, 0x91, 0x17, 0x78, 0x52, 0x2a, 0xba, 0x30, 0x2c, + 0xa9, 0x4b, 0x9d, 0xc2, 0x0b, 0xfd, 0x29, 0x41, 0x2e, 0x49, 0x65, 0xa0, 0x6b, 0x43, 0x20, 0x0d, + 0x91, 0x42, 0xf9, 0xeb, 0x63, 0xc7, 0x8b, 0xa4, 0xae, 0xf1, 0xa4, 0x96, 0xd1, 0x62, 0x72, 0x52, + 0x0e, 0xa6, 0x4c, 0xef, 0x9e, 0x6d, 0xb1, 0x93, 0xca, 0xf7, 0x9e, 0x6d, 0x17, 0xa4, 0xe7, 0xdb, + 0x05, 0xe9, 0xc5, 0x76, 0x41, 0x7a, 0xba, 0x53, 0x38, 0xf4, 0x7c, 0xa7, 0x70, 0xe8, 0xf7, 0x9d, + 0xc2, 0xa1, 0x8f, 0x97, 0x86, 0x3f, 0x1c, 0x5b, 0x5d, 0x97, 0xb1, 0xa6, 0x4f, 0xa8, 0x31, 0xc5, + 0xdf, 0xde, 0xf9, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xae, 0x51, 0x3c, 0x6e, 0xd7, 0x11, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3930,7 +3930,7 @@ func (m *RawCheckpointResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.Signature + var v github_com_babylonlabs_io_babylon_crypto_bls12381.Signature m.BlsMultiSig = &v if err := m.BlsMultiSig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -4258,7 +4258,7 @@ func (m *RawCheckpointWithMetaResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_crypto_bls12381.PublicKey + var v github_com_babylonlabs_io_babylon_crypto_bls12381.PublicKey m.BlsAggrPk = &v if err := m.BlsAggrPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/checkpointing/types/tx.pb.go b/x/checkpointing/types/tx.pb.go index 9a309d96a..7ba7e05c5 100644 --- a/x/checkpointing/types/tx.pb.go +++ b/x/checkpointing/types/tx.pb.go @@ -115,30 +115,30 @@ func init() { func init() { proto.RegisterFile("babylon/checkpointing/v1/tx.proto", fileDescriptor_6b16c54750152c21) } var fileDescriptor_6b16c54750152c21 = []byte{ - // 357 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0x3d, 0x4b, 0xfb, 0x40, - 0x1c, 0xc7, 0x73, 0xff, 0xf2, 0x77, 0x38, 0xb7, 0x50, 0xb4, 0x66, 0x48, 0x1f, 0x04, 0x91, 0x0e, - 0x77, 0xb4, 0xc5, 0x45, 0xb7, 0x3a, 0x4a, 0x11, 0x3a, 0x28, 0x88, 0x50, 0x2e, 0xe9, 0x71, 0x0d, - 0x79, 0xb8, 0x90, 0xdf, 0x59, 0x9a, 0x4d, 0x9c, 0xc4, 0xc9, 0xd5, 0xad, 0x2f, 0xa1, 0x2f, 0xc3, - 0xb1, 0xa3, 0xa3, 0xb4, 0x43, 0x7d, 0x19, 0xd2, 0x24, 0x45, 0xac, 0xde, 0xe2, 0x76, 0x0f, 0x9f, - 0xdf, 0xf7, 0x81, 0x3b, 0x5c, 0x77, 0x98, 0x93, 0x06, 0x32, 0xa2, 0xee, 0x88, 0xbb, 0x7e, 0x2c, - 0xbd, 0x48, 0x79, 0x91, 0xa0, 0xe3, 0x16, 0x55, 0x13, 0x12, 0x27, 0x52, 0x49, 0xb3, 0x52, 0x20, - 0xe4, 0x1b, 0x42, 0xc6, 0x2d, 0xab, 0x2c, 0xa4, 0x90, 0x19, 0x44, 0xd7, 0xab, 0x9c, 0xb7, 0x8e, - 0xb4, 0x92, 0x4e, 0x00, 0x03, 0x9f, 0xa7, 0x05, 0x57, 0x75, 0x25, 0x84, 0x12, 0x28, 0x28, 0xe6, - 0xe7, 0x80, 0xc3, 0x15, 0xfb, 0x32, 0xb6, 0xf6, 0x0b, 0x20, 0x84, 0x6c, 0x3a, 0x04, 0x91, 0x5f, - 0x34, 0xe6, 0x08, 0x1f, 0xf4, 0x40, 0x5c, 0x27, 0x2c, 0x8e, 0xf9, 0xf0, 0x3c, 0xe1, 0x4c, 0xf1, - 0x2b, 0x16, 0x78, 0x43, 0xa6, 0x64, 0x62, 0xb6, 0x71, 0xc9, 0xe7, 0x69, 0x05, 0xd5, 0xd0, 0xf1, - 0x6e, 0xbb, 0x46, 0x74, 0xe9, 0x49, 0x37, 0x80, 0x0b, 0x9e, 0xf6, 0xd7, 0xb0, 0x79, 0x8b, 0xcb, - 0x21, 0x88, 0x81, 0x9b, 0x49, 0x0d, 0xc6, 0x1b, 0xad, 0xca, 0xbf, 0x4c, 0xa4, 0x49, 0xf2, 0x24, - 0xa4, 0x88, 0x4a, 0x8a, 0xa8, 0xa4, 0x07, 0x62, 0xcb, 0xbd, 0x6f, 0x86, 0x3f, 0xce, 0x4e, 0xeb, - 0x8f, 0xd3, 0xaa, 0xf1, 0x31, 0xad, 0x1a, 0x0f, 0xab, 0x59, 0xf3, 0x57, 0xa3, 0xc6, 0x21, 0xae, - 0x6b, 0x1b, 0xf5, 0x39, 0xc4, 0x32, 0x02, 0xde, 0x7e, 0x41, 0xb8, 0xd4, 0x03, 0x61, 0x3e, 0x21, - 0xbc, 0xa7, 0x29, 0xdf, 0xd1, 0xf7, 0xd5, 0xea, 0x5b, 0x67, 0x7f, 0x18, 0xda, 0x84, 0xb2, 0xfe, - 0xdf, 0xaf, 0x66, 0x4d, 0xd4, 0xbd, 0x7c, 0x5d, 0xd8, 0x68, 0xbe, 0xb0, 0xd1, 0xfb, 0xc2, 0x46, - 0xcf, 0x4b, 0xdb, 0x98, 0x2f, 0x6d, 0xe3, 0x6d, 0x69, 0x1b, 0x37, 0x27, 0xc2, 0x53, 0xa3, 0x3b, - 0x87, 0xb8, 0x32, 0xa4, 0x85, 0x8f, 0x3b, 0x62, 0x5e, 0xb4, 0xd9, 0xd0, 0xc9, 0xd6, 0x4f, 0x51, - 0x69, 0xcc, 0xc1, 0xd9, 0xc9, 0xde, 0xba, 0xf3, 0x19, 0x00, 0x00, 0xff, 0xff, 0xd4, 0x29, 0x9a, - 0x31, 0xa2, 0x02, 0x00, 0x00, + // 360 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x92, 0xbb, 0x4a, 0x2b, 0x41, + 0x18, 0xc7, 0x77, 0x4e, 0x38, 0xa7, 0x98, 0xd3, 0x2d, 0x41, 0xe3, 0x16, 0x9b, 0x8b, 0x20, 0x12, + 0x70, 0x86, 0x24, 0x85, 0xa0, 0x5d, 0x2c, 0x25, 0x85, 0x29, 0x14, 0x44, 0x08, 0x33, 0x9b, 0x61, + 0xb2, 0xec, 0x65, 0x96, 0xfd, 0xc6, 0x90, 0xed, 0xc4, 0x4a, 0xac, 0x6c, 0xed, 0xf2, 0x08, 0x79, + 0x0c, 0xcb, 0x94, 0x96, 0x92, 0x14, 0xf1, 0x31, 0x24, 0xbb, 0x1b, 0xc4, 0xe8, 0x36, 0x76, 0x73, + 0xf9, 0x7d, 0xff, 0x0b, 0x33, 0xb8, 0xce, 0x19, 0x4f, 0x7c, 0x15, 0x52, 0x67, 0x24, 0x1c, 0x2f, + 0x52, 0x6e, 0xa8, 0xdd, 0x50, 0xd2, 0x71, 0x8b, 0xea, 0x09, 0x89, 0x62, 0xa5, 0x95, 0x59, 0xc9, + 0x11, 0xf2, 0x05, 0x21, 0xe3, 0x96, 0x55, 0x96, 0x4a, 0xaa, 0x14, 0xa2, 0xeb, 0x55, 0xc6, 0x5b, + 0x07, 0x85, 0x92, 0xdc, 0x87, 0x81, 0x27, 0x92, 0x9c, 0xab, 0x3a, 0x0a, 0x02, 0x05, 0x14, 0x34, + 0xf3, 0x32, 0x80, 0x0b, 0xcd, 0x3e, 0x8d, 0xad, 0xdd, 0x1c, 0x08, 0x20, 0x9d, 0x0e, 0x40, 0x66, + 0x17, 0x8d, 0x39, 0xc2, 0x7b, 0x3d, 0x90, 0x57, 0x31, 0x8b, 0x22, 0x31, 0x3c, 0x8b, 0x05, 0xd3, + 0xe2, 0x92, 0xf9, 0xee, 0x90, 0x69, 0x15, 0x9b, 0x6d, 0x5c, 0xf2, 0x44, 0x52, 0x41, 0x35, 0x74, + 0xf8, 0xbf, 0x5d, 0x23, 0x45, 0xe9, 0x49, 0xd7, 0x87, 0x73, 0x91, 0xf4, 0xd7, 0xb0, 0x79, 0x83, + 0xcb, 0x01, 0xc8, 0x81, 0x93, 0x4a, 0x0d, 0xc6, 0x1b, 0xad, 0xca, 0x9f, 0x54, 0xa4, 0x49, 0xb2, + 0x24, 0x24, 0x8f, 0x4a, 0xf2, 0xa8, 0xa4, 0x07, 0x72, 0xcb, 0xbd, 0x6f, 0x06, 0xdf, 0xce, 0x4e, + 0xea, 0x0f, 0xd3, 0xaa, 0xf1, 0x3e, 0xad, 0x1a, 0xf7, 0xab, 0x59, 0xf3, 0x47, 0xa3, 0xc6, 0x3e, + 0xae, 0x17, 0x36, 0xea, 0x0b, 0x88, 0x54, 0x08, 0xa2, 0xfd, 0x8c, 0x70, 0xa9, 0x07, 0xd2, 0x7c, + 0x44, 0x78, 0xa7, 0xa0, 0x7c, 0xa7, 0xb8, 0x6f, 0xa1, 0xbe, 0x75, 0xfa, 0x8b, 0xa1, 0x4d, 0x28, + 0xeb, 0xef, 0xdd, 0x6a, 0xd6, 0x44, 0xdd, 0x8b, 0x97, 0x85, 0x8d, 0xe6, 0x0b, 0x1b, 0xbd, 0x2d, + 0x6c, 0xf4, 0xb4, 0xb4, 0x8d, 0xf9, 0xd2, 0x36, 0x5e, 0x97, 0xb6, 0x71, 0x7d, 0x2c, 0x5d, 0x3d, + 0xba, 0xe5, 0xc4, 0x51, 0x01, 0xcd, 0x7d, 0x7c, 0xc6, 0xe1, 0xc8, 0x55, 0x9b, 0x2d, 0x9d, 0x6c, + 0xfd, 0x15, 0x9d, 0x44, 0x02, 0xf8, 0xbf, 0xf4, 0xb5, 0x3b, 0x1f, 0x01, 0x00, 0x00, 0xff, 0xff, + 0x74, 0x07, 0x94, 0x5c, 0xa4, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/checkpointing/types/types.go b/x/checkpointing/types/types.go index dabec4b71..116728539 100644 --- a/x/checkpointing/types/types.go +++ b/x/checkpointing/types/types.go @@ -11,9 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - txformat "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) const ( diff --git a/x/checkpointing/types/types_test.go b/x/checkpointing/types/types_test.go index 3875024c9..ea0f2a791 100644 --- a/x/checkpointing/types/types_test.go +++ b/x/checkpointing/types/types_test.go @@ -7,9 +7,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // a single validator diff --git a/x/checkpointing/types/utils.go b/x/checkpointing/types/utils.go index faef788dd..8a1c4f8e1 100644 --- a/x/checkpointing/types/utils.go +++ b/x/checkpointing/types/utils.go @@ -7,8 +7,8 @@ import ( "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" ) func (m BlsSig) Hash() BlsSigHash { diff --git a/x/checkpointing/types/val_bls_set.go b/x/checkpointing/types/val_bls_set.go index 8db7764e5..9603d4bc5 100644 --- a/x/checkpointing/types/val_bls_set.go +++ b/x/checkpointing/types/val_bls_set.go @@ -3,7 +3,7 @@ package types import ( "fmt" - "github.com/babylonchain/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/crypto/bls12381" "github.com/boljen/go-bitmap" "github.com/cosmos/cosmos-sdk/codec" ) diff --git a/x/checkpointing/vote_ext.go b/x/checkpointing/vote_ext.go index ea4239de3..6bdd10e1d 100644 --- a/x/checkpointing/vote_ext.go +++ b/x/checkpointing/vote_ext.go @@ -8,8 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/checkpointing/keeper" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/keeper" + ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // VoteExtensionHandler defines a BLS-based vote extension handlers for Babylon. diff --git a/x/checkpointing/vote_ext_test.go b/x/checkpointing/vote_ext_test.go index 3b91aaf6b..90c57342f 100644 --- a/x/checkpointing/vote_ext_test.go +++ b/x/checkpointing/vote_ext_test.go @@ -7,9 +7,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" ) // FuzzAddBLSSigVoteExtension_MultipleVals tests adding BLS signatures via VoteExtension diff --git a/x/epoching/abci.go b/x/epoching/abci.go index 14fc82c2b..04097d3aa 100644 --- a/x/epoching/abci.go +++ b/x/epoching/abci.go @@ -5,8 +5,8 @@ import ( "fmt" "time" - "github.com/babylonchain/babylon/x/epoching/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/telemetry" diff --git a/x/epoching/client/cli/query.go b/x/epoching/client/cli/query.go index 34c439cb6..80656ce80 100644 --- a/x/epoching/client/cli/query.go +++ b/x/epoching/client/cli/query.go @@ -5,7 +5,7 @@ import ( "fmt" "strconv" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" diff --git a/x/epoching/client/cli/tx.go b/x/epoching/client/cli/tx.go index 42923beaf..a3fd11931 100644 --- a/x/epoching/client/cli/tx.go +++ b/x/epoching/client/cli/tx.go @@ -7,8 +7,8 @@ import ( "github.com/spf13/cobra" - "github.com/babylonchain/babylon/app/params" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/app/params" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" diff --git a/x/epoching/genesis.go b/x/epoching/genesis.go index efd7b985d..2c96e3694 100644 --- a/x/epoching/genesis.go +++ b/x/epoching/genesis.go @@ -2,8 +2,8 @@ package epoching import ( "context" - "github.com/babylonchain/babylon/x/epoching/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // InitGenesis initializes the capability module's state from a provided genesis diff --git a/x/epoching/genesis_test.go b/x/epoching/genesis_test.go index ae92a5024..22c4450d9 100644 --- a/x/epoching/genesis_test.go +++ b/x/epoching/genesis_test.go @@ -3,11 +3,11 @@ package epoching_test import ( "testing" - "github.com/babylonchain/babylon/x/epoching" + "github.com/babylonlabs-io/babylon/x/epoching" "github.com/stretchr/testify/require" - simapp "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/x/epoching/types" + simapp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) func TestExportGenesis(t *testing.T) { diff --git a/x/epoching/keeper/drop_validator_msg_decorator.go b/x/epoching/keeper/drop_validator_msg_decorator.go index c9f3baa45..c6261b1e3 100644 --- a/x/epoching/keeper/drop_validator_msg_decorator.go +++ b/x/epoching/keeper/drop_validator_msg_decorator.go @@ -1,7 +1,7 @@ package keeper import ( - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) diff --git a/x/epoching/keeper/epoch_msg_queue.go b/x/epoching/keeper/epoch_msg_queue.go index 52970fc52..232bef822 100644 --- a/x/epoching/keeper/epoch_msg_queue.go +++ b/x/epoching/keeper/epoch_msg_queue.go @@ -9,7 +9,7 @@ import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/epoching/keeper/epoch_msg_queue_test.go b/x/epoching/keeper/epoch_msg_queue_test.go index 22703df73..b7fe5504d 100644 --- a/x/epoching/keeper/epoch_msg_queue_test.go +++ b/x/epoching/keeper/epoch_msg_queue_test.go @@ -4,16 +4,16 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/epoching/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - appparams "github.com/babylonchain/babylon/app/params" + appparams "github.com/babylonlabs-io/babylon/app/params" ) var ( diff --git a/x/epoching/keeper/epoch_slashed_val_set.go b/x/epoching/keeper/epoch_slashed_val_set.go index a52b89624..1fa73f77e 100644 --- a/x/epoching/keeper/epoch_slashed_val_set.go +++ b/x/epoching/keeper/epoch_slashed_val_set.go @@ -5,7 +5,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/epoching/keeper/epoch_slashed_val_set_test.go b/x/epoching/keeper/epoch_slashed_val_set_test.go index 90ae8ad4b..8231b9bb1 100644 --- a/x/epoching/keeper/epoch_slashed_val_set_test.go +++ b/x/epoching/keeper/epoch_slashed_val_set_test.go @@ -7,13 +7,13 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) func FuzzSlashedValSet(f *testing.F) { diff --git a/x/epoching/keeper/epoch_val_set.go b/x/epoching/keeper/epoch_val_set.go index 4095df178..baef32df6 100644 --- a/x/epoching/keeper/epoch_val_set.go +++ b/x/epoching/keeper/epoch_val_set.go @@ -5,7 +5,7 @@ import ( errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/epoching/keeper/epoch_val_set_test.go b/x/epoching/keeper/epoch_val_set_test.go index 8bc1e3b89..32b886bbb 100644 --- a/x/epoching/keeper/epoch_val_set_test.go +++ b/x/epoching/keeper/epoch_val_set_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" diff --git a/x/epoching/keeper/epochs.go b/x/epoching/keeper/epochs.go index 8ee863952..089318d63 100644 --- a/x/epoching/keeper/epochs.go +++ b/x/epoching/keeper/epochs.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) func (k Keeper) setEpochInfo(ctx context.Context, epochNumber uint64, epoch *types.Epoch) { diff --git a/x/epoching/keeper/epochs_test.go b/x/epoching/keeper/epochs_test.go index a4a3dff99..30aaf91c3 100644 --- a/x/epoching/keeper/epochs_test.go +++ b/x/epoching/keeper/epochs_test.go @@ -6,8 +6,8 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" ) func FuzzEpochs(f *testing.F) { diff --git a/x/epoching/keeper/grpc_query.go b/x/epoching/keeper/grpc_query.go index 9d88cc565..d3ea77434 100644 --- a/x/epoching/keeper/grpc_query.go +++ b/x/epoching/keeper/grpc_query.go @@ -7,7 +7,7 @@ import ( "cosmossdk.io/math" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/query" diff --git a/x/epoching/keeper/grpc_query_test.go b/x/epoching/keeper/grpc_query_test.go index 92fc074fc..fa92bb853 100644 --- a/x/epoching/keeper/grpc_query_test.go +++ b/x/epoching/keeper/grpc_query_test.go @@ -11,9 +11,9 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // FuzzParamsQuery fuzzes queryClient.Params diff --git a/x/epoching/keeper/hooks.go b/x/epoching/keeper/hooks.go index 10db4a52a..525e26640 100644 --- a/x/epoching/keeper/hooks.go +++ b/x/epoching/keeper/hooks.go @@ -4,8 +4,8 @@ import ( "context" "cosmossdk.io/math" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - "github.com/babylonchain/babylon/x/epoching/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) diff --git a/x/epoching/keeper/keeper.go b/x/epoching/keeper/keeper.go index 11741f489..f0eacc6c0 100644 --- a/x/epoching/keeper/keeper.go +++ b/x/epoching/keeper/keeper.go @@ -6,7 +6,7 @@ import ( corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/log" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" ) diff --git a/x/epoching/keeper/keeper_test.go b/x/epoching/keeper/keeper_test.go index 80ea94d3b..cb7068120 100644 --- a/x/epoching/keeper/keeper_test.go +++ b/x/epoching/keeper/keeper_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/require" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/epoching/types" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) func TestParams(t *testing.T) { diff --git a/x/epoching/keeper/lifecycle_delegation.go b/x/epoching/keeper/lifecycle_delegation.go index d00859908..8213c8e15 100644 --- a/x/epoching/keeper/lifecycle_delegation.go +++ b/x/epoching/keeper/lifecycle_delegation.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/epoching/keeper/lifecycle_validator.go b/x/epoching/keeper/lifecycle_validator.go index 75f6250bf..76026a72e 100644 --- a/x/epoching/keeper/lifecycle_validator.go +++ b/x/epoching/keeper/lifecycle_validator.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/epoching/keeper/modified_staking.go b/x/epoching/keeper/modified_staking.go index 44c193494..d0b122c11 100644 --- a/x/epoching/keeper/modified_staking.go +++ b/x/epoching/keeper/modified_staking.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" abci "github.com/cometbft/cometbft/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/epoching/keeper/msg_server.go b/x/epoching/keeper/msg_server.go index 3db5b554d..280abec88 100644 --- a/x/epoching/keeper/msg_server.go +++ b/x/epoching/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( "context" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" diff --git a/x/epoching/keeper/msg_server_test.go b/x/epoching/keeper/msg_server_test.go index cd1857f9f..2707c0cde 100644 --- a/x/epoching/keeper/msg_server_test.go +++ b/x/epoching/keeper/msg_server_test.go @@ -8,8 +8,8 @@ import ( stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" - testhelper "github.com/babylonchain/babylon/testutil/helper" - "github.com/babylonchain/babylon/x/epoching/types" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // TODO (fuzz tests): replace the following tests with fuzz ones diff --git a/x/epoching/keeper/params.go b/x/epoching/keeper/params.go index 3f0a67762..38d0c8ea2 100644 --- a/x/epoching/keeper/params.go +++ b/x/epoching/keeper/params.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // SetParams sets the x/epoching module parameters. diff --git a/x/epoching/keeper/params_test.go b/x/epoching/keeper/params_test.go index 01ff49ae6..1c193b7f0 100644 --- a/x/epoching/keeper/params_test.go +++ b/x/epoching/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/stretchr/testify/require" ) diff --git a/x/epoching/keeper/staking_functions.go b/x/epoching/keeper/staking_functions.go index 577e7c88e..3d9e1935c 100644 --- a/x/epoching/keeper/staking_functions.go +++ b/x/epoching/keeper/staking_functions.go @@ -10,7 +10,7 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" ) // CheckMsgCreateValidator performs checks on a given `MsgCreateValidator` message diff --git a/x/epoching/module.go b/x/epoching/module.go index f21bdcdcb..06e611eb6 100644 --- a/x/epoching/module.go +++ b/x/epoching/module.go @@ -13,9 +13,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/epoching/client/cli" - "github.com/babylonchain/babylon/x/epoching/keeper" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/client/cli" + "github.com/babylonlabs-io/babylon/x/epoching/keeper" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/epoching/types/epoching.pb.go b/x/epoching/types/epoching.pb.go index 4ce345009..09e4bbfd7 100644 --- a/x/epoching/types/epoching.pb.go +++ b/x/epoching/types/epoching.pb.go @@ -651,63 +651,63 @@ func init() { } var fileDescriptor_2f2f209d5311f84c = []byte{ - // 881 bytes of a gzipped FileDescriptorProto + // 883 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x95, 0xdf, 0x6e, 0xe3, 0x44, 0x14, 0xc6, 0xe3, 0xfc, 0x6b, 0x73, 0x92, 0x74, 0xc3, 0xb4, 0x8b, 0xb2, 0x15, 0x4a, 0x4b, 0x10, - 0xa8, 0xaa, 0x90, 0x4d, 0x4b, 0xb9, 0x05, 0x35, 0x4d, 0x84, 0x8b, 0x68, 0x56, 0x98, 0x6d, 0x2f, - 0xb8, 0xc0, 0x1a, 0xdb, 0x53, 0xdb, 0x5a, 0x7b, 0xc6, 0xf2, 0x8c, 0xb3, 0xed, 0x05, 0xef, 0xb0, - 0xcf, 0x81, 0x78, 0x10, 0x2e, 0xf7, 0x92, 0x3b, 0x50, 0xfb, 0x20, 0x8b, 0x66, 0xec, 0x38, 0x29, - 0x8d, 0x5a, 0x95, 0xbd, 0xf3, 0x9c, 0xf3, 0x9d, 0x6f, 0xce, 0xf9, 0xe5, 0x68, 0x02, 0x43, 0x07, - 0x3b, 0xd7, 0x11, 0xa3, 0x06, 0x49, 0x98, 0x1b, 0x84, 0xd4, 0x37, 0x66, 0x07, 0xe5, 0xb7, 0x9e, - 0xa4, 0x4c, 0x30, 0xb4, 0x59, 0x68, 0xf4, 0x32, 0x3e, 0x3b, 0xd8, 0xde, 0xf1, 0x19, 0xf3, 0x23, - 0x62, 0x28, 0x89, 0x93, 0x5d, 0x1a, 0x22, 0x8c, 0x09, 0x17, 0x38, 0x4e, 0xf2, 0xaa, 0xed, 0x2d, - 0x9f, 0xf9, 0x4c, 0x7d, 0x1a, 0xf2, 0xab, 0x88, 0xee, 0xb8, 0x8c, 0xc7, 0x8c, 0x1b, 0x5c, 0xe0, - 0xd7, 0xf9, 0x6d, 0x0e, 0x11, 0xf8, 0xc0, 0x10, 0x57, 0x85, 0x60, 0x50, 0x08, 0x1c, 0xcc, 0x49, - 0x99, 0x75, 0x59, 0x48, 0xf3, 0xfc, 0xf0, 0x8f, 0x2a, 0x34, 0x26, 0xb2, 0x0f, 0xf4, 0x29, 0x74, - 0x54, 0x43, 0x36, 0xcd, 0x62, 0x87, 0xa4, 0x7d, 0x6d, 0x57, 0xdb, 0xab, 0x5b, 0x6d, 0x15, 0x9b, - 0xaa, 0x10, 0x3a, 0x82, 0x8f, 0xdd, 0x2c, 0x4d, 0x09, 0x15, 0x76, 0x2e, 0x0d, 0xa9, 0x20, 0xe9, - 0x0c, 0x47, 0xfd, 0xaa, 0x12, 0x6f, 0x15, 0x59, 0x65, 0x78, 0x5a, 0xe4, 0xd0, 0x97, 0x80, 0x2e, - 0xc3, 0x94, 0x0b, 0xdb, 0x89, 0x98, 0xfb, 0xda, 0x0e, 0x48, 0xe8, 0x07, 0xa2, 0x5f, 0x53, 0x15, - 0x3d, 0x95, 0x19, 0xc9, 0x84, 0xa9, 0xe2, 0xc8, 0x84, 0x67, 0x11, 0x2e, 0xc5, 0x92, 0x42, 0xbf, - 0xbe, 0xab, 0xed, 0xb5, 0x0f, 0xb7, 0xf5, 0x1c, 0x91, 0x3e, 0x47, 0xa4, 0xbf, 0x9a, 0x23, 0x1a, - 0xd5, 0xdf, 0xfe, 0xbd, 0xa3, 0x59, 0x5d, 0x59, 0xa8, 0xbc, 0x64, 0x06, 0x7d, 0x01, 0xcf, 0x38, - 0xc1, 0x11, 0x49, 0x6d, 0x9c, 0x24, 0x76, 0x80, 0x79, 0xd0, 0x6f, 0xec, 0x6a, 0x7b, 0x1d, 0xab, - 0x9b, 0x87, 0x8f, 0x93, 0xc4, 0xc4, 0x3c, 0x40, 0xfb, 0xf0, 0x51, 0xa1, 0x2b, 0x1a, 0x94, 0xca, - 0xa6, 0x52, 0x16, 0x06, 0x79, 0x7f, 0x98, 0x07, 0xc3, 0xf7, 0x75, 0xe8, 0xfe, 0x94, 0x91, 0x8c, - 0x78, 0x67, 0x84, 0x73, 0xec, 0x13, 0xb4, 0x09, 0x0d, 0x71, 0x65, 0x87, 0x9e, 0xe2, 0xd5, 0xb1, - 0xea, 0xe2, 0xea, 0xd4, 0x43, 0xcf, 0xa1, 0x19, 0x73, 0x5f, 0x46, 0xab, 0x2a, 0xda, 0x88, 0xb9, - 0x7f, 0xea, 0x49, 0xc4, 0x2b, 0x18, 0xb4, 0x9d, 0xa5, 0xf1, 0xbf, 0x03, 0xf8, 0x1f, 0x93, 0xb7, - 0x9c, 0x72, 0xea, 0x5f, 0x61, 0x4b, 0x5e, 0xed, 0xa6, 0x04, 0x0b, 0x62, 0xcf, 0x70, 0x14, 0x7a, - 0x58, 0xb0, 0x54, 0x8d, 0xde, 0x3e, 0xdc, 0xd7, 0xf3, 0x7d, 0xd0, 0x8b, 0x85, 0xd1, 0x8b, 0x95, - 0xd0, 0xcf, 0xb8, 0x7f, 0xa2, 0x4a, 0x2e, 0xe6, 0x15, 0x66, 0xc5, 0x42, 0xf1, 0xbd, 0x28, 0x32, - 0xa1, 0x23, 0xfd, 0x3d, 0x12, 0x11, 0x1f, 0x0b, 0xa2, 0x40, 0xb5, 0x0f, 0x3f, 0x7b, 0xc0, 0x77, - 0x5c, 0x48, 0xcd, 0x8a, 0xd5, 0x8e, 0x17, 0x47, 0x34, 0x85, 0x0d, 0xe9, 0x94, 0xd1, 0xd2, 0x6b, - 0x4d, 0x79, 0x7d, 0xfe, 0x80, 0xd7, 0x79, 0x29, 0x36, 0x2b, 0x56, 0x37, 0x5e, 0x0e, 0xcc, 0x27, - 0x77, 0x88, 0x1f, 0x52, 0x3b, 0x25, 0xa5, 0xeb, 0xfa, 0xa3, 0x93, 0x8f, 0x64, 0x89, 0x45, 0x96, - 0xac, 0xe5, 0xe4, 0xff, 0x89, 0xa2, 0xdf, 0x60, 0x47, 0x91, 0xc5, 0xd4, 0x25, 0x91, 0x9d, 0x51, - 0x87, 0x51, 0x2f, 0xa4, 0x25, 0x8a, 0x90, 0xd1, 0x7e, 0x4b, 0x5d, 0x75, 0xf4, 0x10, 0x64, 0x55, - 0x7d, 0x3e, 0x2f, 0x1e, 0x97, 0xb5, 0x66, 0xc5, 0xfa, 0x24, 0x7e, 0x20, 0x3f, 0x6a, 0x40, 0x2d, - 0xe6, 0xfe, 0xf0, 0x77, 0x0d, 0x36, 0x2e, 0x70, 0xf4, 0xb3, 0xc0, 0x82, 0x9c, 0x27, 0x9e, 0x6c, - 0xec, 0x08, 0x1a, 0x5c, 0x1e, 0xd5, 0x0a, 0x6e, 0x1c, 0x0e, 0xf4, 0x15, 0x0f, 0x8c, 0x3e, 0x62, - 0xd4, 0x53, 0x45, 0x56, 0x2e, 0xbe, 0xb7, 0x8c, 0xd5, 0xc7, 0x96, 0xb1, 0xf6, 0xe4, 0x65, 0x1c, - 0x32, 0x40, 0xe5, 0xe6, 0xfc, 0x18, 0x5e, 0x12, 0xf7, 0xda, 0x8d, 0x08, 0x7a, 0x01, 0xeb, 0x33, - 0x1c, 0xd9, 0xd8, 0xf3, 0xf2, 0x57, 0xa6, 0x65, 0xad, 0xcd, 0x70, 0x74, 0xec, 0x79, 0x29, 0xfa, - 0x36, 0x4f, 0x45, 0xe1, 0x25, 0xe9, 0x57, 0x77, 0x6b, 0x6a, 0xb3, 0x56, 0x4d, 0x73, 0x97, 0x80, - 0xaa, 0x97, 0xfe, 0xc3, 0xf7, 0x1a, 0x3c, 0x5f, 0x30, 0xfb, 0x70, 0x48, 0xcb, 0xad, 0x56, 0xef, - 0xb6, 0x7a, 0x00, 0x4d, 0x1c, 0xb3, 0x8c, 0x8a, 0x02, 0xcc, 0x8b, 0xf9, 0xaf, 0x2e, 0x9f, 0xda, - 0xf2, 0x27, 0x3f, 0x61, 0x21, 0xb5, 0x0a, 0xe1, 0x3d, 0xe4, 0xf5, 0xc7, 0x90, 0x37, 0x9e, 0x8e, - 0xfc, 0x0d, 0x6c, 0x2e, 0x00, 0xdc, 0x61, 0xee, 0x91, 0xbb, 0xcc, 0x3d, 0x92, 0x0f, 0x32, 0xc9, - 0x53, 0x4b, 0xcc, 0xf7, 0x57, 0xc2, 0x59, 0xc9, 0x55, 0xd9, 0x28, 0xf4, 0xdf, 0x40, 0x6b, 0xf1, - 0x4a, 0x20, 0xa8, 0x97, 0x57, 0x75, 0x2c, 0xf5, 0x8d, 0xb6, 0xa0, 0x91, 0xb0, 0x37, 0x24, 0x07, - 0x59, 0xb3, 0xf2, 0xc3, 0xfe, 0x14, 0x5a, 0x25, 0x75, 0xd4, 0x86, 0xb5, 0x13, 0x6b, 0x72, 0xfc, - 0x6a, 0x32, 0xee, 0x55, 0x10, 0x40, 0x73, 0xf4, 0x72, 0x3a, 0x9e, 0x8c, 0x7b, 0x1a, 0xea, 0x42, - 0xeb, 0x7c, 0x2a, 0x4f, 0xa7, 0xd3, 0xef, 0x7b, 0x55, 0xd4, 0x81, 0xf5, 0xfc, 0x38, 0x19, 0xf7, - 0x6a, 0xb2, 0xca, 0x9a, 0x9c, 0xbd, 0xbc, 0x98, 0x8c, 0x7b, 0xf5, 0xd1, 0x0f, 0x7f, 0xde, 0x0c, - 0xb4, 0x77, 0x37, 0x03, 0xed, 0x9f, 0x9b, 0x81, 0xf6, 0xf6, 0x76, 0x50, 0x79, 0x77, 0x3b, 0xa8, - 0xfc, 0x75, 0x3b, 0xa8, 0xfc, 0xf2, 0x95, 0x1f, 0x8a, 0x20, 0x73, 0x74, 0x97, 0xc5, 0x46, 0x31, - 0x9f, 0x1b, 0xe0, 0x90, 0xce, 0x0f, 0xc6, 0xd5, 0xe2, 0x5f, 0x5b, 0x5c, 0x27, 0x84, 0x3b, 0x4d, - 0x05, 0xfc, 0xeb, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9a, 0x6a, 0x0b, 0x3c, 0xd6, 0x07, 0x00, - 0x00, + 0xa8, 0xaa, 0xc0, 0x56, 0x43, 0xb9, 0x05, 0x35, 0x4d, 0x44, 0x2a, 0x6d, 0xb3, 0xc2, 0x6c, 0x7b, + 0xc1, 0x05, 0xd6, 0xd8, 0x9e, 0xda, 0xd6, 0xda, 0x1e, 0xcb, 0x33, 0xce, 0xb6, 0x17, 0xbc, 0xc3, + 0x3e, 0x07, 0xe2, 0x41, 0xb8, 0xdc, 0x4b, 0xee, 0x40, 0xed, 0x83, 0x2c, 0x9a, 0x19, 0xc7, 0x49, + 0x69, 0x94, 0xaa, 0xec, 0x9d, 0xe7, 0x9c, 0xef, 0x7c, 0x73, 0xce, 0x2f, 0x47, 0x13, 0xe8, 0xdb, + 0xd8, 0xbe, 0x09, 0x69, 0x6c, 0x90, 0x84, 0x3a, 0x7e, 0x10, 0x7b, 0xc6, 0xec, 0xa8, 0xf8, 0xd6, + 0x93, 0x94, 0x72, 0x8a, 0xb6, 0x73, 0x8d, 0x5e, 0xc4, 0x67, 0x47, 0xbb, 0x7b, 0x1e, 0xa5, 0x5e, + 0x48, 0x0c, 0x29, 0xb1, 0xb3, 0x2b, 0x83, 0x07, 0x11, 0x61, 0x1c, 0x47, 0x89, 0xaa, 0xda, 0xdd, + 0xf1, 0xa8, 0x47, 0xe5, 0xa7, 0x21, 0xbe, 0xf2, 0xe8, 0x9e, 0x43, 0x59, 0x44, 0x99, 0xc1, 0x38, + 0x7e, 0xa3, 0x6e, 0xb3, 0x09, 0xc7, 0x47, 0x06, 0xbf, 0xce, 0x05, 0xbd, 0x5c, 0x60, 0x63, 0x46, + 0x8a, 0xac, 0x43, 0x83, 0x58, 0xe5, 0xfb, 0x7f, 0x94, 0xa1, 0x36, 0x16, 0x7d, 0xa0, 0xcf, 0xa1, + 0x25, 0x1b, 0xb2, 0xe2, 0x2c, 0xb2, 0x49, 0xda, 0xd5, 0xf6, 0xb5, 0x83, 0xaa, 0xd9, 0x94, 0xb1, + 0xa9, 0x0c, 0xa1, 0x63, 0xf8, 0xd4, 0xc9, 0xd2, 0x94, 0xc4, 0xdc, 0x52, 0xd2, 0x20, 0xe6, 0x24, + 0x9d, 0xe1, 0xb0, 0x5b, 0x96, 0xe2, 0x9d, 0x3c, 0x2b, 0x0d, 0xcf, 0xf2, 0x1c, 0xfa, 0x1a, 0xd0, + 0x55, 0x90, 0x32, 0x6e, 0xd9, 0x21, 0x75, 0xde, 0x58, 0x3e, 0x09, 0x3c, 0x9f, 0x77, 0x2b, 0xb2, + 0xa2, 0x23, 0x33, 0x43, 0x91, 0x98, 0xc8, 0x38, 0x9a, 0xc0, 0xb3, 0x10, 0x17, 0x62, 0x41, 0xa1, + 0x5b, 0xdd, 0xd7, 0x0e, 0x9a, 0x83, 0x5d, 0x5d, 0x21, 0xd2, 0xe7, 0x88, 0xf4, 0xd7, 0x73, 0x44, + 0xc3, 0xea, 0xbb, 0xbf, 0xf7, 0x34, 0xb3, 0x2d, 0x0a, 0xa5, 0x97, 0xc8, 0xa0, 0xaf, 0xe0, 0x19, + 0x23, 0x38, 0x24, 0xa9, 0x85, 0x93, 0xc4, 0xf2, 0x31, 0xf3, 0xbb, 0xb5, 0x7d, 0xed, 0xa0, 0x65, + 0xb6, 0x55, 0xf8, 0x24, 0x49, 0x26, 0x98, 0xf9, 0xe8, 0x10, 0x3e, 0xc9, 0x75, 0x79, 0x83, 0x42, + 0x59, 0x97, 0xca, 0xdc, 0x40, 0xf5, 0x87, 0x99, 0xdf, 0xff, 0x50, 0x85, 0xf6, 0x4f, 0x19, 0xc9, + 0x88, 0x7b, 0x4e, 0x18, 0xc3, 0x1e, 0x41, 0xdb, 0x50, 0xe3, 0xd7, 0x56, 0xe0, 0x4a, 0x5e, 0x2d, + 0xb3, 0xca, 0xaf, 0xcf, 0x5c, 0xf4, 0x1c, 0xea, 0x11, 0xf3, 0x44, 0xb4, 0x2c, 0xa3, 0xb5, 0x88, + 0x79, 0x67, 0xae, 0x40, 0xbc, 0x82, 0x41, 0xd3, 0x5e, 0x1a, 0xff, 0x07, 0x80, 0xff, 0x31, 0x79, + 0xc3, 0x2e, 0xa6, 0xfe, 0x15, 0x76, 0xc4, 0xd5, 0x4e, 0x4a, 0x30, 0x27, 0xd6, 0x0c, 0x87, 0x81, + 0x8b, 0x39, 0x4d, 0xe5, 0xe8, 0xcd, 0xc1, 0xa1, 0xae, 0xf6, 0x41, 0xcf, 0x17, 0x46, 0xcf, 0x57, + 0x42, 0x3f, 0x67, 0xde, 0xa9, 0x2c, 0xb9, 0x9c, 0x57, 0x4c, 0x4a, 0x26, 0x8a, 0x1e, 0x44, 0xd1, + 0x04, 0x5a, 0xc2, 0xdf, 0x25, 0x21, 0xf1, 0x30, 0x27, 0x12, 0x54, 0x73, 0xf0, 0xc5, 0x1a, 0xdf, + 0x51, 0x2e, 0x9d, 0x94, 0xcc, 0x66, 0xb4, 0x38, 0xa2, 0x29, 0x6c, 0x09, 0xa7, 0x2c, 0x2e, 0xbc, + 0x36, 0xa4, 0xd7, 0x97, 0x6b, 0xbc, 0x2e, 0x0a, 0xf1, 0xa4, 0x64, 0xb6, 0xa3, 0xe5, 0xc0, 0x7c, + 0x72, 0x9b, 0x78, 0x41, 0x6c, 0xa5, 0xa4, 0x70, 0xdd, 0x7c, 0x74, 0xf2, 0xa1, 0x28, 0x31, 0xc9, + 0x92, 0xb5, 0x98, 0xfc, 0x3f, 0x51, 0xf4, 0x1b, 0xec, 0x49, 0xb2, 0x38, 0x76, 0x48, 0x68, 0x65, + 0xb1, 0x4d, 0x63, 0x37, 0x88, 0x0b, 0x14, 0x01, 0x8d, 0xbb, 0x0d, 0x79, 0xd5, 0xf1, 0x3a, 0xc8, + 0xb2, 0xfa, 0x62, 0x5e, 0x3c, 0x2a, 0x6a, 0x27, 0x25, 0xf3, 0xb3, 0x68, 0x4d, 0x7e, 0x58, 0x83, + 0x4a, 0xc4, 0xbc, 0xfe, 0xef, 0x1a, 0x6c, 0x5d, 0xe2, 0xf0, 0x67, 0x8e, 0x39, 0xb9, 0x48, 0x5c, + 0xd1, 0xd8, 0x31, 0xd4, 0x98, 0x38, 0xca, 0x15, 0xdc, 0x1a, 0xf4, 0xf4, 0x15, 0x0f, 0x8c, 0x3e, + 0xa4, 0xb1, 0x2b, 0x8b, 0x4c, 0x25, 0x7e, 0xb0, 0x8c, 0xe5, 0xc7, 0x96, 0xb1, 0xf2, 0xe4, 0x65, + 0xec, 0x53, 0x40, 0xc5, 0xe6, 0xbc, 0x0c, 0xae, 0x88, 0x73, 0xe3, 0x84, 0x04, 0xbd, 0x80, 0xcd, + 0x19, 0x0e, 0x2d, 0xec, 0xba, 0xea, 0x95, 0x69, 0x98, 0x1b, 0x33, 0x1c, 0x9e, 0xb8, 0x6e, 0x8a, + 0xbe, 0x57, 0xa9, 0x30, 0xb8, 0x22, 0xdd, 0xf2, 0x7e, 0x45, 0x6e, 0xd6, 0xaa, 0x69, 0xee, 0x13, + 0x90, 0xf5, 0xc2, 0xbf, 0xff, 0x41, 0x83, 0xe7, 0x0b, 0x66, 0x1f, 0x0f, 0x69, 0xb9, 0xd5, 0xf2, + 0xfd, 0x56, 0x8f, 0xa0, 0x8e, 0x23, 0x9a, 0xc5, 0x3c, 0x07, 0xf3, 0x62, 0xfe, 0xab, 0x8b, 0xa7, + 0xb6, 0xf8, 0xc9, 0x4f, 0x69, 0x10, 0x9b, 0xb9, 0xf0, 0x01, 0xf2, 0xea, 0x63, 0xc8, 0x6b, 0x4f, + 0x47, 0xfe, 0x16, 0xb6, 0x17, 0x00, 0xee, 0x31, 0x77, 0xc9, 0x7d, 0xe6, 0x2e, 0x51, 0x83, 0x8c, + 0x55, 0x6a, 0x89, 0xf9, 0xe1, 0x4a, 0x38, 0x2b, 0xb9, 0x4a, 0x1b, 0x89, 0xfe, 0x3b, 0x68, 0x2c, + 0x5e, 0x09, 0x04, 0xd5, 0xe2, 0xaa, 0x96, 0x29, 0xbf, 0xd1, 0x0e, 0xd4, 0x12, 0xfa, 0x96, 0x28, + 0x90, 0x15, 0x53, 0x1d, 0x0e, 0xa7, 0xd0, 0x28, 0xa8, 0xa3, 0x26, 0x6c, 0x9c, 0x9a, 0xe3, 0x93, + 0xd7, 0xe3, 0x51, 0xa7, 0x84, 0x00, 0xea, 0xc3, 0x57, 0xd3, 0xd1, 0x78, 0xd4, 0xd1, 0x50, 0x1b, + 0x1a, 0x17, 0x53, 0x71, 0x3a, 0x9b, 0xfe, 0xd8, 0x29, 0xa3, 0x16, 0x6c, 0xaa, 0xe3, 0x78, 0xd4, + 0xa9, 0x88, 0x2a, 0x73, 0x7c, 0xfe, 0xea, 0x72, 0x3c, 0xea, 0x54, 0x87, 0x2f, 0xff, 0xbc, 0xed, + 0x69, 0xef, 0x6f, 0x7b, 0xda, 0x3f, 0xb7, 0x3d, 0xed, 0xdd, 0x5d, 0xaf, 0xf4, 0xfe, 0xae, 0x57, + 0xfa, 0xeb, 0xae, 0x57, 0xfa, 0x65, 0xe0, 0x05, 0xdc, 0xcf, 0x6c, 0xdd, 0xa1, 0x91, 0x91, 0xcf, + 0x17, 0x62, 0x9b, 0x7d, 0x13, 0xd0, 0xf9, 0xd1, 0xb8, 0x5e, 0xfc, 0x6f, 0xf3, 0x9b, 0x84, 0x30, + 0xbb, 0x2e, 0x91, 0x7f, 0xfb, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x40, 0x5d, 0x2a, 0x76, 0xd8, + 0x07, 0x00, 0x00, } func (m *Epoch) Marshal() (dAtA []byte, err error) { diff --git a/x/epoching/types/epoching_test.go b/x/epoching/types/epoching_test.go index a82e9e303..451f406fb 100644 --- a/x/epoching/types/epoching_test.go +++ b/x/epoching/types/epoching_test.go @@ -1,11 +1,11 @@ package types_test import ( - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" "math/rand" "testing" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/stretchr/testify/require" ) diff --git a/x/epoching/types/events.pb.go b/x/epoching/types/events.pb.go index a1b01c203..bd2c2aef1 100644 --- a/x/epoching/types/events.pb.go +++ b/x/epoching/types/events.pb.go @@ -598,48 +598,48 @@ func init() { proto.RegisterFile("babylon/epoching/v1/events.proto", fileDescrip var fileDescriptor_2f0a2c43c7aaeb43 = []byte{ // 674 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0xcd, 0x6e, 0xd4, 0x3c, - 0x14, 0x6d, 0xe6, 0xef, 0x53, 0xfd, 0xf5, 0xd7, 0x33, 0x8c, 0x22, 0x2a, 0x86, 0x61, 0xa4, 0x8a, - 0x4a, 0xc0, 0xa4, 0x05, 0x84, 0x10, 0xbb, 0x0e, 0x54, 0x6a, 0x91, 0x40, 0x10, 0xda, 0x22, 0xb1, - 0x89, 0x9c, 0xd8, 0x24, 0x16, 0x89, 0x1d, 0xd9, 0xce, 0xd0, 0x79, 0x0b, 0x5e, 0x80, 0x1d, 0x0f, - 0xc0, 0x4b, 0x20, 0x58, 0x76, 0x89, 0x58, 0x20, 0xd4, 0xae, 0x78, 0x0b, 0x14, 0xe7, 0xa7, 0x81, - 0x4e, 0x51, 0xc5, 0x06, 0xb1, 0xf3, 0x3d, 0xe7, 0xdc, 0xeb, 0x9c, 0x7b, 0x1d, 0x1b, 0xf4, 0x5d, - 0xe4, 0x4e, 0x42, 0xce, 0x2c, 0x12, 0x73, 0x2f, 0xa0, 0xcc, 0xb7, 0xc6, 0x1b, 0x16, 0x19, 0x13, - 0xa6, 0xe4, 0x30, 0x16, 0x5c, 0x71, 0xd8, 0xce, 0x15, 0xc3, 0x42, 0x31, 0x1c, 0x6f, 0x5c, 0xec, - 0xf8, 0xdc, 0xe7, 0x9a, 0xb7, 0xd2, 0x55, 0x26, 0x1d, 0xdc, 0x06, 0x8b, 0x5b, 0x69, 0xea, 0x88, - 0xf8, 0x94, 0x6d, 0xa5, 0x72, 0x78, 0x05, 0xcc, 0xe9, 0x3c, 0x87, 0x25, 0x91, 0x4b, 0x84, 0x69, - 0xf4, 0x8d, 0xb5, 0x86, 0xfd, 0xbf, 0xc6, 0x1e, 0x6b, 0x68, 0x70, 0x13, 0xcc, 0xeb, 0xac, 0x2d, - 0x86, 0xcf, 0x9d, 0xf3, 0xbe, 0x06, 0x3a, 0x3a, 0x69, 0x1b, 0x31, 0x1c, 0x92, 0xa7, 0x09, 0x49, - 0x08, 0x7e, 0x24, 0x7d, 0x38, 0x04, 0x6d, 0x2e, 0xa8, 0x4f, 0x19, 0x0a, 0x1d, 0x6d, 0xc3, 0x51, - 0x93, 0x98, 0xe8, 0x12, 0xb3, 0xf6, 0x72, 0x41, 0xe9, 0xd4, 0xdd, 0x49, 0x4c, 0x4e, 0xed, 0x55, - 0x3b, 0xb5, 0x17, 0xec, 0x82, 0x56, 0x40, 0xa8, 0x1f, 0x28, 0xb3, 0xae, 0xc9, 0x3c, 0x82, 0x6d, - 0xd0, 0x54, 0x07, 0x0e, 0xc5, 0x66, 0xa3, 0x6f, 0xac, 0xcd, 0xd9, 0x0d, 0x75, 0xb0, 0x83, 0xe1, - 0x05, 0xd0, 0x8a, 0xa4, 0x9f, 0xa2, 0x4d, 0x8d, 0x36, 0x23, 0xe9, 0xef, 0x60, 0xf8, 0xaa, 0xf2, - 0x59, 0x48, 0x29, 0x41, 0xdd, 0x44, 0x11, 0x69, 0xb6, 0xfa, 0xf5, 0xb5, 0xb9, 0xd1, 0xbd, 0x2f, - 0x5f, 0x2f, 0xdf, 0xf1, 0xa9, 0x0a, 0x12, 0x77, 0xe8, 0xf1, 0xc8, 0xf2, 0x78, 0x44, 0x94, 0xfb, - 0x52, 0x9d, 0x2c, 0x90, 0xeb, 0x51, 0x2b, 0x35, 0x22, 0x87, 0xfa, 0xd3, 0x37, 0x8b, 0x12, 0x36, - 0x2c, 0xca, 0x96, 0x90, 0x84, 0x1d, 0xd0, 0x24, 0x42, 0x70, 0x61, 0xfe, 0xa7, 0x5d, 0x67, 0xc1, - 0xe0, 0x9d, 0x01, 0xda, 0x3a, 0xf9, 0x59, 0x88, 0x64, 0xb0, 0x1b, 0x08, 0x22, 0x03, 0x1e, 0x62, - 0xb8, 0x0e, 0x3a, 0x32, 0x45, 0x08, 0x76, 0xc6, 0x5c, 0x51, 0xe6, 0x3b, 0x31, 0x7f, 0x9d, 0x77, - 0xbd, 0x6e, 0xc3, 0x9c, 0xdb, 0xd7, 0xd4, 0x93, 0x94, 0x81, 0xd7, 0x01, 0x54, 0x5c, 0xa1, 0xf0, - 0x67, 0x7d, 0x4d, 0xeb, 0x97, 0x34, 0x53, 0x55, 0xdf, 0x00, 0xb0, 0xac, 0x8f, 0x42, 0x8a, 0x91, - 0xe2, 0x42, 0x9a, 0xf5, 0xd4, 0xb9, 0xbd, 0x5c, 0x54, 0x2f, 0x89, 0xc1, 0x07, 0x23, 0x9f, 0xec, - 0x73, 0x81, 0xe2, 0x98, 0xe0, 0x07, 0x24, 0x24, 0x3e, 0x52, 0x04, 0x5e, 0x03, 0xcb, 0x38, 0x5b, - 0x73, 0xe1, 0x20, 0x8c, 0x05, 0x91, 0x32, 0x9f, 0xeb, 0x52, 0x49, 0x6c, 0x66, 0x78, 0x2a, 0x2e, - 0x37, 0x2b, 0xc5, 0xb5, 0x4c, 0x5c, 0x12, 0x85, 0xb8, 0x0b, 0x5a, 0x28, 0xe2, 0x09, 0x2b, 0x07, - 0x9c, 0x45, 0x69, 0x1f, 0x31, 0x61, 0x3c, 0xd2, 0x03, 0x9e, 0xb5, 0xb3, 0x00, 0xae, 0x82, 0x85, - 0xec, 0xc4, 0xb8, 0x3c, 0x61, 0x18, 0x89, 0x89, 0x9e, 0x74, 0xc3, 0x9e, 0xd7, 0xe8, 0x28, 0x07, - 0x07, 0x1f, 0x0d, 0xd0, 0xad, 0xfa, 0xd8, 0x63, 0xf8, 0x1f, 0x75, 0xf2, 0xb6, 0x06, 0x56, 0xaa, - 0x4e, 0xf4, 0xdf, 0x6d, 0x93, 0x3f, 0xb3, 0x73, 0x17, 0x98, 0x92, 0x27, 0xc2, 0x23, 0xce, 0x59, - 0xae, 0xba, 0x19, 0xbf, 0xff, 0xab, 0xb7, 0x11, 0xb8, 0x84, 0x89, 0x54, 0x94, 0x21, 0x45, 0x39, - 0x9b, 0x92, 0x5e, 0xd7, 0xe9, 0x2b, 0x15, 0xd1, 0xfe, 0xd9, 0xfd, 0x69, 0x4c, 0xef, 0x4f, 0xf3, - 0xf7, 0xfd, 0x69, 0x4d, 0xeb, 0xcf, 0x77, 0x03, 0xac, 0x56, 0xfb, 0x73, 0x1f, 0x31, 0x8f, 0x84, - 0x7b, 0xcc, 0xe5, 0x0c, 0x53, 0xe6, 0xe7, 0x07, 0x98, 0x72, 0xf6, 0x17, 0x06, 0x7f, 0x15, 0x2c, - 0x7a, 0x82, 0x64, 0x1d, 0xcb, 0x2f, 0xb1, 0x86, 0xfe, 0x4f, 0x17, 0x0a, 0x78, 0x3b, 0xbb, 0xcc, - 0xce, 0x77, 0x16, 0x46, 0x0f, 0x3f, 0x1d, 0xf5, 0x8c, 0xc3, 0xa3, 0x9e, 0xf1, 0xed, 0xa8, 0x67, - 0xbc, 0x39, 0xee, 0xcd, 0x1c, 0x1e, 0xf7, 0x66, 0x3e, 0x1f, 0xf7, 0x66, 0x5e, 0xac, 0x57, 0x2e, - 0xb0, 0xfc, 0xc5, 0xf0, 0x02, 0x44, 0x59, 0x11, 0x58, 0x07, 0x27, 0x4f, 0x8c, 0xbe, 0xc9, 0xdc, - 0x96, 0x7e, 0x34, 0x6e, 0xfd, 0x08, 0x00, 0x00, 0xff, 0xff, 0xb9, 0x83, 0x9b, 0xc9, 0x83, 0x06, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x55, 0xcb, 0x6e, 0xd4, 0x30, + 0x14, 0x6d, 0xe6, 0x85, 0x6a, 0xfa, 0xf4, 0x0c, 0xa3, 0x88, 0x8a, 0x61, 0x18, 0xa9, 0xa2, 0x12, + 0x74, 0x42, 0x0b, 0x42, 0x88, 0x5d, 0x07, 0x2a, 0xb5, 0x12, 0x20, 0x08, 0x6d, 0x91, 0xd8, 0x44, + 0x4e, 0x6c, 0x12, 0x8b, 0xc4, 0x8e, 0x6c, 0x67, 0xe8, 0xfc, 0x05, 0x3f, 0xc0, 0x8e, 0x0f, 0xe0, + 0x27, 0x10, 0x2c, 0xbb, 0x44, 0x2c, 0x10, 0x6a, 0x57, 0xfc, 0x05, 0x8a, 0xf3, 0x68, 0xa0, 0x2d, + 0xaa, 0xd8, 0x20, 0x76, 0xbe, 0xe7, 0x9c, 0x7b, 0x9d, 0x73, 0xaf, 0x63, 0x83, 0xbe, 0x8b, 0xdc, + 0x49, 0xc8, 0x99, 0x45, 0x62, 0xee, 0x05, 0x94, 0xf9, 0xd6, 0x78, 0xcd, 0x22, 0x63, 0xc2, 0x94, + 0x1c, 0xc6, 0x82, 0x2b, 0x0e, 0xdb, 0xb9, 0x62, 0x58, 0x28, 0x86, 0xe3, 0xb5, 0xcb, 0x1d, 0x9f, + 0xfb, 0x5c, 0xf3, 0x56, 0xba, 0xca, 0xa4, 0x83, 0x3b, 0x60, 0x7e, 0x33, 0x4d, 0x1d, 0x11, 0x9f, + 0xb2, 0xcd, 0x54, 0x0e, 0xaf, 0x81, 0x19, 0x9d, 0xe7, 0xb0, 0x24, 0x72, 0x89, 0x30, 0x8d, 0xbe, + 0xb1, 0xd2, 0xb0, 0x2f, 0x6a, 0xec, 0x89, 0x86, 0x06, 0xeb, 0x60, 0x56, 0x67, 0x6d, 0x32, 0x7c, + 0xee, 0x9c, 0x0f, 0x35, 0xd0, 0xd1, 0x49, 0x5b, 0x88, 0xe1, 0x90, 0x3c, 0x4b, 0x48, 0x42, 0xf0, + 0x63, 0xe9, 0xc3, 0x21, 0x68, 0x73, 0x41, 0x7d, 0xca, 0x50, 0xe8, 0x68, 0x1b, 0x8e, 0x9a, 0xc4, + 0x44, 0x97, 0x98, 0xb6, 0x17, 0x0b, 0x4a, 0xa7, 0xee, 0x4c, 0x62, 0x72, 0x62, 0xaf, 0xda, 0x89, + 0xbd, 0x60, 0x17, 0xb4, 0x02, 0x42, 0xfd, 0x40, 0x99, 0x75, 0x4d, 0xe6, 0x11, 0x6c, 0x83, 0xa6, + 0xda, 0x77, 0x28, 0x36, 0x1b, 0x7d, 0x63, 0x65, 0xc6, 0x6e, 0xa8, 0xfd, 0x6d, 0x0c, 0x2f, 0x81, + 0x56, 0x24, 0xfd, 0x14, 0x6d, 0x6a, 0xb4, 0x19, 0x49, 0x7f, 0x1b, 0xc3, 0xd7, 0x95, 0xcf, 0x42, + 0x4a, 0x09, 0xea, 0x26, 0x8a, 0x48, 0xb3, 0xd5, 0xaf, 0xaf, 0xcc, 0x8c, 0xee, 0x7f, 0xfd, 0x76, + 0xf5, 0xae, 0x4f, 0x55, 0x90, 0xb8, 0x43, 0x8f, 0x47, 0x96, 0xc7, 0x23, 0xa2, 0xdc, 0x57, 0xea, + 0x78, 0x81, 0x5c, 0x8f, 0x5a, 0xa9, 0x11, 0x39, 0xd4, 0x9f, 0xbe, 0x51, 0x94, 0xb0, 0x61, 0x51, + 0xb6, 0x84, 0x24, 0xec, 0x80, 0x26, 0x11, 0x82, 0x0b, 0xf3, 0x82, 0x76, 0x9d, 0x05, 0x83, 0xf7, + 0x06, 0x68, 0xeb, 0xe4, 0xe7, 0x21, 0x92, 0xc1, 0x4e, 0x20, 0x88, 0x0c, 0x78, 0x88, 0xe1, 0x2d, + 0xd0, 0x91, 0x29, 0x42, 0xb0, 0x33, 0xe6, 0x8a, 0x32, 0xdf, 0x89, 0xf9, 0x9b, 0xbc, 0xeb, 0x75, + 0x1b, 0xe6, 0xdc, 0x9e, 0xa6, 0x9e, 0xa6, 0x0c, 0xbc, 0x09, 0xa0, 0xe2, 0x0a, 0x85, 0xbf, 0xea, + 0x6b, 0x5a, 0xbf, 0xa0, 0x99, 0xaa, 0x7a, 0x15, 0xc0, 0xb2, 0x3e, 0x0a, 0x29, 0x46, 0x8a, 0x0b, + 0x69, 0xd6, 0x53, 0xe7, 0xf6, 0x62, 0x51, 0xbd, 0x24, 0x06, 0x1f, 0x8d, 0x7c, 0xb2, 0x2f, 0x04, + 0x8a, 0x63, 0x82, 0x1f, 0x92, 0x90, 0xf8, 0x48, 0x11, 0x78, 0x03, 0x2c, 0xe2, 0x6c, 0xcd, 0x85, + 0x83, 0x30, 0x16, 0x44, 0xca, 0x7c, 0xae, 0x0b, 0x25, 0xb1, 0x91, 0xe1, 0xa9, 0xb8, 0xdc, 0xac, + 0x14, 0xd7, 0x32, 0x71, 0x49, 0x14, 0xe2, 0x2e, 0x68, 0xa1, 0x88, 0x27, 0xac, 0x1c, 0x70, 0x16, + 0xa5, 0x7d, 0xc4, 0x84, 0xf1, 0x48, 0x0f, 0x78, 0xda, 0xce, 0x02, 0xb8, 0x0c, 0xe6, 0xb2, 0x13, + 0xe3, 0xf2, 0x84, 0x61, 0x24, 0x26, 0x7a, 0xd2, 0x0d, 0x7b, 0x56, 0xa3, 0xa3, 0x1c, 0x1c, 0x7c, + 0x32, 0x40, 0xb7, 0xea, 0x63, 0x97, 0xe1, 0xff, 0xd4, 0xc9, 0xbb, 0x1a, 0x58, 0xaa, 0x3a, 0xd1, + 0x7f, 0xb7, 0x4d, 0xfe, 0xce, 0xce, 0x3d, 0x60, 0x4a, 0x9e, 0x08, 0x8f, 0x38, 0x67, 0xb9, 0xea, + 0x66, 0xfc, 0xde, 0xef, 0xde, 0x46, 0xe0, 0x0a, 0x26, 0x52, 0x51, 0x86, 0x14, 0xe5, 0xec, 0x94, + 0xf4, 0xba, 0x4e, 0x5f, 0xaa, 0x88, 0xf6, 0xce, 0xee, 0x4f, 0xe3, 0xf4, 0xfe, 0x34, 0xff, 0xdc, + 0x9f, 0xd6, 0x69, 0xfd, 0xf9, 0x61, 0x80, 0xe5, 0x6a, 0x7f, 0x1e, 0x20, 0xe6, 0x91, 0x70, 0x97, + 0xb9, 0x9c, 0x61, 0xca, 0xfc, 0xfc, 0x00, 0x53, 0xce, 0xfe, 0xc1, 0xe0, 0xaf, 0x83, 0x79, 0x4f, + 0x90, 0xac, 0x63, 0xf9, 0x25, 0xd6, 0xd0, 0xff, 0xe9, 0x5c, 0x01, 0x6f, 0x65, 0x97, 0xd9, 0xf9, + 0xce, 0xc2, 0xe8, 0xd1, 0xe7, 0xc3, 0x9e, 0x71, 0x70, 0xd8, 0x33, 0xbe, 0x1f, 0xf6, 0x8c, 0xb7, + 0x47, 0xbd, 0xa9, 0x83, 0xa3, 0xde, 0xd4, 0x97, 0xa3, 0xde, 0xd4, 0xcb, 0xf5, 0xca, 0x05, 0x96, + 0xbf, 0x18, 0x21, 0x72, 0xe5, 0x2a, 0xe5, 0x45, 0x68, 0xed, 0x1f, 0x3f, 0x32, 0xfa, 0x2e, 0x73, + 0x5b, 0xfa, 0xd9, 0xb8, 0xfd, 0x33, 0x00, 0x00, 0xff, 0xff, 0x6d, 0x85, 0x55, 0x11, 0x85, 0x06, 0x00, 0x00, } diff --git a/x/epoching/types/genesis.pb.go b/x/epoching/types/genesis.pb.go index 77f300cdf..6120270f5 100644 --- a/x/epoching/types/genesis.pb.go +++ b/x/epoching/types/genesis.pb.go @@ -75,7 +75,7 @@ func init() { func init() { proto.RegisterFile("babylon/epoching/v1/genesis.proto", fileDescriptor_2ef836361c424501) } var fileDescriptor_2ef836361c424501 = []byte{ - // 200 bytes of a gzipped FileDescriptorProto + // 202 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2d, 0xc8, 0x4f, 0xce, 0xc8, 0xcc, 0x4b, 0xd7, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, @@ -83,12 +83,12 @@ var fileDescriptor_2ef836361c424501 = []byte{ 0x83, 0x58, 0x10, 0xa5, 0x52, 0x0a, 0xd8, 0x4c, 0x2b, 0x48, 0x2c, 0x4a, 0xcc, 0x85, 0x1a, 0xa6, 0xe4, 0xc9, 0xc5, 0xe3, 0x0e, 0x31, 0x3d, 0xb8, 0x24, 0xb1, 0x24, 0x55, 0xc8, 0x92, 0x8b, 0x0d, 0x22, 0x2f, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x87, 0xc5, 0x36, 0xbd, 0x00, 0xb0, - 0x12, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x1a, 0x9c, 0xbc, 0x4e, 0x3c, 0x92, 0x63, + 0x12, 0x27, 0x96, 0x13, 0xf7, 0xe4, 0x19, 0x82, 0xa0, 0x1a, 0x9c, 0x7c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, - 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x20, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, - 0x3f, 0x57, 0x1f, 0x6a, 0x5c, 0x72, 0x46, 0x62, 0x66, 0x1e, 0x8c, 0xa3, 0x5f, 0x81, 0x70, 0x60, - 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x75, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xa9, 0x51, 0x6f, 0x4e, 0x0f, 0x01, 0x00, 0x00, + 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x28, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, 0x39, + 0x3f, 0x57, 0x1f, 0x6a, 0x5c, 0x4e, 0x62, 0x52, 0xb1, 0x6e, 0x66, 0x3e, 0x8c, 0xab, 0x5f, 0x81, + 0x70, 0x62, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x7d, 0xc6, 0x80, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x30, 0xa3, 0x4a, 0x33, 0x11, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/epoching/types/genesis_test.go b/x/epoching/types/genesis_test.go index 925ae1db6..a974f6572 100644 --- a/x/epoching/types/genesis_test.go +++ b/x/epoching/types/genesis_test.go @@ -3,10 +3,10 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/epoching" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/epoching" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/stretchr/testify/require" ) diff --git a/x/epoching/types/msg_test.go b/x/epoching/types/msg_test.go index f5822d564..b94157622 100644 --- a/x/epoching/types/msg_test.go +++ b/x/epoching/types/msg_test.go @@ -5,11 +5,11 @@ import ( "time" sdkmath "cosmossdk.io/math" - appparams "github.com/babylonchain/babylon/app/params" + appparams "github.com/babylonlabs-io/babylon/app/params" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/cosmos/cosmos-sdk/codec" codectypes "github.com/cosmos/cosmos-sdk/codec/types" cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" diff --git a/x/epoching/types/params.pb.go b/x/epoching/types/params.pb.go index 21ae0f84b..94aed1d31 100644 --- a/x/epoching/types/params.pb.go +++ b/x/epoching/types/params.pb.go @@ -76,7 +76,7 @@ func init() { func init() { proto.RegisterFile("babylon/epoching/v1/params.proto", fileDescriptor_c9e38cfe55335900) } var fileDescriptor_c9e38cfe55335900 = []byte{ - // 201 bytes of a gzipped FileDescriptorProto + // 203 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0x2d, 0xc8, 0x4f, 0xce, 0xc8, 0xcc, 0x4b, 0xd7, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, @@ -84,12 +84,12 @@ var fileDescriptor_c9e38cfe55335900 = []byte{ 0x58, 0x10, 0xa5, 0x4a, 0x01, 0x5c, 0x6c, 0x01, 0x60, 0xad, 0x42, 0x0e, 0x5c, 0x7c, 0x60, 0xe5, 0xf1, 0x99, 0x79, 0x25, 0xa9, 0x45, 0x65, 0x89, 0x39, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x2c, 0x4e, 0x92, 0x9f, 0xee, 0xc9, 0x8b, 0x56, 0x26, 0xe6, 0xe6, 0x58, 0x29, 0xa1, 0xca, 0x2b, 0x05, 0xf1, - 0x82, 0x05, 0x3c, 0xa1, 0x7c, 0x2b, 0x96, 0x17, 0x0b, 0xe4, 0x19, 0x9d, 0xbc, 0x4e, 0x3c, 0x92, + 0x82, 0x05, 0x3c, 0xa1, 0x7c, 0x2b, 0x96, 0x17, 0x0b, 0xe4, 0x19, 0x9d, 0x7c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, - 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x20, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, - 0x39, 0x3f, 0x57, 0x1f, 0xea, 0xc2, 0xe4, 0x8c, 0xc4, 0xcc, 0x3c, 0x18, 0x47, 0xbf, 0x02, 0xe1, - 0xa5, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x23, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xa6, 0x7d, 0x61, 0x54, 0xf3, 0x00, 0x00, 0x00, + 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x28, 0x3d, 0xb3, 0x24, 0xa3, 0x34, 0x49, 0x2f, + 0x39, 0x3f, 0x57, 0x1f, 0xea, 0xc2, 0x9c, 0xc4, 0xa4, 0x62, 0xdd, 0xcc, 0x7c, 0x18, 0x57, 0xbf, + 0x02, 0xe1, 0xa9, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, 0x33, 0x8d, 0x01, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x12, 0xc9, 0x0a, 0x86, 0xf5, 0x00, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/epoching/types/params_test.go b/x/epoching/types/params_test.go index 83424dd41..c8096638d 100644 --- a/x/epoching/types/params_test.go +++ b/x/epoching/types/params_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/epoching/types" "github.com/stretchr/testify/require" ) diff --git a/x/epoching/types/query.pb.go b/x/epoching/types/query.pb.go index ab85b879b..4d5e795ae 100644 --- a/x/epoching/types/query.pb.go +++ b/x/epoching/types/query.pb.go @@ -1268,94 +1268,94 @@ func init() { func init() { proto.RegisterFile("babylon/epoching/v1/query.proto", fileDescriptor_1821b530f2ec2711) } var fileDescriptor_1821b530f2ec2711 = []byte{ - // 1384 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6f, 0x1b, 0x45, - 0x1b, 0xce, 0x3a, 0x4e, 0xbe, 0xe6, 0x4d, 0xf3, 0x25, 0x9d, 0xb4, 0xfd, 0x52, 0xa7, 0x75, 0xfa, - 0x6d, 0xa1, 0x2d, 0x49, 0xb3, 0xdb, 0x34, 0x29, 0xd0, 0x1f, 0x50, 0x35, 0x2d, 0x25, 0x41, 0x2d, - 0x4a, 0x17, 0xe8, 0x81, 0xcb, 0x32, 0xf6, 0x4e, 0xd6, 0x2b, 0xd6, 0xbb, 0xdb, 0x9d, 0xb1, 0x49, - 0x54, 0x8a, 0x10, 0xe2, 0xc8, 0xa1, 0x12, 0x07, 0x84, 0x90, 0x10, 0x88, 0x23, 0x7f, 0x01, 0x2a, - 0x07, 0x8e, 0x3d, 0x16, 0x71, 0xe1, 0x04, 0xa8, 0xe5, 0x0f, 0x41, 0xfb, 0xce, 0xac, 0xbd, 0x76, - 0xd6, 0xb5, 0x13, 0x55, 0xdc, 0xec, 0xf7, 0xe7, 0xf3, 0x3e, 0xef, 0xcc, 0xec, 0x03, 0x73, 0x15, - 0x5a, 0xd9, 0xf6, 0xc3, 0xc0, 0x64, 0x51, 0x58, 0xad, 0x79, 0x81, 0x6b, 0x36, 0x97, 0xcc, 0xbb, - 0x0d, 0x16, 0x6f, 0x1b, 0x51, 0x1c, 0x8a, 0x90, 0x4c, 0xab, 0x00, 0x23, 0x0d, 0x30, 0x9a, 0x4b, - 0xa5, 0x83, 0x6e, 0xe8, 0x86, 0xe8, 0x37, 0x93, 0x5f, 0x32, 0xb4, 0x34, 0xe7, 0x86, 0xa1, 0xeb, - 0x33, 0x13, 0xff, 0x55, 0x1a, 0x9b, 0xa6, 0xf0, 0xea, 0x8c, 0x0b, 0x5a, 0x8f, 0x54, 0xc0, 0x51, - 0x15, 0x40, 0x23, 0xcf, 0xa4, 0x41, 0x10, 0x0a, 0x2a, 0xbc, 0x30, 0xe0, 0xca, 0x3b, 0x5f, 0x0d, - 0x79, 0x3d, 0xe4, 0x66, 0x85, 0x72, 0x26, 0x21, 0x98, 0xcd, 0xa5, 0x0a, 0x13, 0x74, 0xc9, 0x8c, - 0xa8, 0xeb, 0x05, 0x18, 0xac, 0x62, 0x8f, 0xe7, 0xc1, 0x8e, 0x68, 0x4c, 0xeb, 0x69, 0x35, 0x3d, - 0x2f, 0xa2, 0x35, 0x03, 0xc6, 0xe8, 0x07, 0x81, 0xdc, 0x4e, 0xfa, 0x6c, 0x60, 0xa2, 0xc5, 0xee, - 0x36, 0x18, 0x17, 0xfa, 0x06, 0x4c, 0x77, 0x58, 0x79, 0x14, 0x06, 0x9c, 0x91, 0x0b, 0x30, 0x2a, - 0x1b, 0xcc, 0x68, 0xc7, 0xb5, 0xd3, 0xe3, 0xe7, 0x66, 0x8d, 0x1c, 0x66, 0x0c, 0x99, 0xb4, 0x5a, - 0x7c, 0xf4, 0xc7, 0xdc, 0x90, 0xa5, 0x12, 0xf4, 0x15, 0x38, 0x84, 0x15, 0xdf, 0x48, 0x02, 0xd7, - 0x83, 0xcd, 0x50, 0xb5, 0x22, 0xb3, 0x30, 0x86, 0xc9, 0x76, 0xd0, 0xa8, 0x63, 0xd9, 0xa2, 0xb5, - 0x0f, 0x0d, 0x6f, 0x37, 0xea, 0xba, 0x05, 0x87, 0xbb, 0xb3, 0x14, 0x94, 0x57, 0x61, 0x04, 0xa3, - 0x14, 0x12, 0x3d, 0x17, 0x09, 0xa6, 0xa5, 0x29, 0x96, 0x4c, 0xd0, 0x3f, 0xc8, 0xd6, 0xe4, 0x59, - 0x28, 0x37, 0x00, 0xda, 0x2c, 0xab, 0xc2, 0x27, 0x0d, 0xb9, 0x12, 0x23, 0x59, 0x89, 0x21, 0x4f, - 0x85, 0x5a, 0x89, 0xb1, 0x41, 0x5d, 0xa6, 0x72, 0xad, 0x4c, 0xa6, 0xfe, 0xad, 0x06, 0xff, 0xdb, - 0xd1, 0x42, 0xe1, 0xbe, 0x08, 0xa3, 0x08, 0x23, 0xa1, 0x70, 0x78, 0x40, 0xe0, 0x2a, 0x83, 0xbc, - 0xd9, 0x81, 0xaf, 0x80, 0xf8, 0x4e, 0xf5, 0xc5, 0xa7, 0x8a, 0x64, 0x01, 0x96, 0x60, 0x06, 0xf1, - 0x5d, 0x6b, 0xc4, 0x31, 0x0b, 0x84, 0xea, 0x26, 0x57, 0xef, 0xc2, 0x91, 0x1c, 0x9f, 0x42, 0x7f, - 0x02, 0x26, 0xaa, 0xd2, 0x6e, 0xb7, 0xd9, 0x2f, 0x5a, 0xfb, 0xab, 0x99, 0x60, 0xf2, 0x22, 0xfc, - 0x57, 0x6e, 0xb4, 0x12, 0x36, 0x02, 0x87, 0xc6, 0xdb, 0x08, 0xb5, 0x68, 0x4d, 0xa0, 0x75, 0x55, - 0x19, 0xf5, 0x8f, 0xb3, 0x27, 0xe2, 0x16, 0x77, 0xf9, 0x20, 0x27, 0xa2, 0x6b, 0x47, 0x85, 0x3d, - 0xef, 0xe8, 0x7b, 0x2d, 0x7b, 0x0c, 0x64, 0x7b, 0x35, 0xe4, 0xeb, 0x50, 0xac, 0x73, 0x37, 0x5d, - 0xd0, 0x7c, 0xee, 0x82, 0x6e, 0x37, 0x58, 0x83, 0x39, 0xb7, 0x18, 0xe7, 0x59, 0x8e, 0x31, 0xef, - 0xf9, 0xad, 0xe9, 0x07, 0x0d, 0x66, 0x11, 0xe3, 0x4d, 0x2a, 0x18, 0x17, 0xb9, 0x44, 0x05, 0x4e, - 0xc7, 0x26, 0xf6, 0xb1, 0xc0, 0x91, 0x5b, 0x98, 0x83, 0x71, 0xc9, 0x62, 0x35, 0x6c, 0x04, 0x42, - 0xad, 0x00, 0xd0, 0x74, 0x2d, 0xb1, 0x74, 0x31, 0x39, 0xbc, 0x67, 0x26, 0x1f, 0x6a, 0x70, 0x34, - 0x1f, 0xa5, 0xe2, 0xd3, 0x82, 0x03, 0x3e, 0xba, 0x24, 0x52, 0x3b, 0x43, 0xee, 0xc9, 0xfe, 0xe4, - 0xde, 0xf4, 0xb8, 0xb0, 0x26, 0xfd, 0xce, 0xda, 0xcf, 0x8f, 0xe3, 0x4b, 0x50, 0x46, 0xf0, 0x77, - 0xa8, 0xef, 0x39, 0x54, 0x84, 0xf1, 0x4d, 0x6f, 0x93, 0x55, 0xb7, 0xab, 0x7e, 0x3a, 0x2b, 0x39, - 0x02, 0xfb, 0x9a, 0xd4, 0xb7, 0xa9, 0xe3, 0xc4, 0x48, 0xf2, 0x98, 0xf5, 0x9f, 0x26, 0xf5, 0xaf, - 0x3a, 0x4e, 0xac, 0x7f, 0xae, 0xc1, 0x5c, 0xcf, 0x6c, 0x35, 0x7d, 0xef, 0x74, 0x72, 0x43, 0xba, - 0x7c, 0x6f, 0x93, 0xcd, 0x14, 0x90, 0x8f, 0x85, 0x5c, 0x3e, 0xee, 0x50, 0xff, 0x1d, 0x41, 0x05, - 0x7b, 0x2f, 0x72, 0xa8, 0x68, 0x8f, 0x91, 0xd4, 0x49, 0xfa, 0xe9, 0x97, 0x15, 0x8a, 0xeb, 0xcc, - 0x67, 0x2e, 0x8e, 0x95, 0x37, 0x84, 0xc3, 0x3a, 0x51, 0x38, 0x4c, 0x0e, 0xe1, 0xc2, 0xf1, 0xde, - 0xd9, 0x6a, 0x88, 0x6b, 0x32, 0x1d, 0x91, 0xca, 0x77, 0xf1, 0x74, 0x2e, 0xd2, 0xbc, 0x1a, 0x49, - 0x23, 0x84, 0xf9, 0x49, 0xf6, 0x55, 0x4c, 0x66, 0x62, 0xe2, 0x5f, 0xbd, 0xf2, 0xbf, 0x6a, 0xea, - 0xd9, 0xeb, 0x00, 0xd0, 0xba, 0xf4, 0xd0, 0x4c, 0x97, 0x98, 0x9e, 0xce, 0x72, 0xaf, 0x6d, 0xc8, - 0x30, 0x2b, 0x93, 0x41, 0xce, 0x00, 0x11, 0xa1, 0xa0, 0xbe, 0xdd, 0x0c, 0x85, 0x17, 0xb8, 0x76, - 0x14, 0x7e, 0xc4, 0x62, 0x04, 0x3b, 0x6c, 0x4d, 0xa1, 0xe7, 0x0e, 0x3a, 0x36, 0x12, 0x7b, 0xd7, - 0xf1, 0x1d, 0xde, 0xfb, 0xf1, 0x7d, 0x58, 0x80, 0x89, 0xce, 0x27, 0xfa, 0xff, 0xb0, 0xbf, 0x45, - 0x65, 0x85, 0xc5, 0x8a, 0xcd, 0xf1, 0x94, 0xcd, 0x0a, 0x8b, 0xc9, 0x0a, 0x1c, 0xee, 0x78, 0xc5, - 0x6d, 0x2f, 0x10, 0x2c, 0x6e, 0x52, 0x5f, 0xbd, 0x12, 0x07, 0xb3, 0xcf, 0xf9, 0xba, 0xf2, 0x25, - 0x13, 0x6e, 0x7a, 0x31, 0x17, 0x76, 0xc5, 0x0f, 0xab, 0x1f, 0xda, 0x35, 0xe6, 0xb9, 0x35, 0x81, - 0xd8, 0x8b, 0xd6, 0x14, 0x7a, 0x56, 0x13, 0xc7, 0x1a, 0xda, 0xc9, 0x1a, 0x4c, 0xfa, 0xb4, 0x15, - 0x9c, 0xa8, 0xa0, 0x99, 0x22, 0x8e, 0x59, 0x32, 0xa4, 0x02, 0x32, 0x52, 0x89, 0x64, 0xbc, 0x9b, - 0x4a, 0xa4, 0xd5, 0xe2, 0x83, 0x3f, 0xe7, 0x34, 0x6b, 0x22, 0x49, 0xc4, 0x5a, 0x89, 0x87, 0x2c, - 0xc2, 0x34, 0x67, 0xd4, 0x67, 0xb1, 0x4d, 0xa3, 0xc8, 0xae, 0x51, 0x5e, 0xb3, 0x6b, 0x6c, 0x6b, - 0x66, 0x04, 0x4f, 0xf1, 0x94, 0x74, 0x5d, 0x8d, 0xa2, 0x35, 0xca, 0x6b, 0x6b, 0x6c, 0x8b, 0xcc, - 0xc3, 0x01, 0x15, 0xae, 0x70, 0x52, 0x5e, 0x9b, 0x19, 0xc5, 0xe0, 0x49, 0xe9, 0x90, 0x30, 0x29, - 0xaf, 0xe9, 0x3f, 0x69, 0xf8, 0x0d, 0xda, 0xf9, 0x92, 0x93, 0x69, 0x18, 0x11, 0x5b, 0xb6, 0xe7, - 0xa8, 0xcb, 0x52, 0x14, 0x5b, 0xeb, 0x0e, 0x39, 0x04, 0xa3, 0x75, 0xee, 0x26, 0xd6, 0x02, 0x5a, - 0x47, 0xea, 0xdc, 0x5d, 0x77, 0x12, 0xc6, 0x73, 0x28, 0x19, 0xaf, 0x64, 0xd8, 0xb8, 0x02, 0xb0, - 0x07, 0x22, 0xc6, 0x2a, 0x2d, 0x12, 0xa6, 0x60, 0xb8, 0xce, 0x5d, 0x35, 0x74, 0xf2, 0x53, 0x6f, - 0xc2, 0x81, 0x1d, 0xef, 0xe4, 0x20, 0xcb, 0x4f, 0xbf, 0x6e, 0x85, 0xbd, 0x7d, 0xdd, 0xf4, 0x6f, - 0x34, 0x38, 0x9c, 0xff, 0x20, 0x91, 0x63, 0x00, 0x3c, 0x31, 0xdb, 0x0e, 0xe3, 0x55, 0xc5, 0xdc, - 0x18, 0x5a, 0xae, 0x33, 0x5e, 0xdd, 0xc1, 0x53, 0xa1, 0x1f, 0x4f, 0xc3, 0xbb, 0xe6, 0xe9, 0xdc, - 0xe3, 0x71, 0x18, 0xc1, 0x3b, 0x4e, 0x3e, 0xd5, 0x60, 0x54, 0x2a, 0x51, 0x72, 0xaa, 0xd7, 0x90, - 0x5d, 0xb2, 0xb7, 0x74, 0xba, 0x7f, 0xa0, 0x1c, 0x55, 0x3f, 0xf1, 0xd9, 0x6f, 0x7f, 0x7f, 0x59, - 0x38, 0x46, 0x66, 0xcd, 0xde, 0x2a, 0x9c, 0x7c, 0xa5, 0xc1, 0x58, 0x4b, 0xb9, 0x92, 0xf9, 0xde, - 0xc5, 0xbb, 0x45, 0x71, 0x69, 0x61, 0xa0, 0x58, 0x85, 0x65, 0x09, 0xb1, 0x2c, 0x90, 0x97, 0xcc, - 0x9e, 0x7a, 0x9f, 0x9b, 0xf7, 0x5a, 0xe7, 0xe2, 0xb5, 0xf9, 0xfb, 0xe4, 0x0b, 0x0d, 0xa0, 0x2d, - 0x4e, 0x49, 0xbf, 0x76, 0x59, 0x95, 0x5c, 0x3a, 0x33, 0x58, 0xf0, 0x40, 0x44, 0x29, 0x61, 0xfb, - 0xb5, 0x06, 0xfb, 0xb3, 0x7a, 0x93, 0x2c, 0xf6, 0xee, 0x91, 0xa3, 0x59, 0x4b, 0xc6, 0xa0, 0xe1, - 0x0a, 0xd4, 0x3c, 0x82, 0x7a, 0x81, 0xe8, 0xb9, 0xa0, 0x3a, 0xde, 0x46, 0xf2, 0x5d, 0xba, 0x44, - 0xd4, 0x1d, 0xfd, 0x96, 0x98, 0x91, 0x67, 0x7d, 0x97, 0x98, 0x15, 0x49, 0xfa, 0x45, 0x84, 0xb4, - 0x42, 0xce, 0x0d, 0xbc, 0x44, 0xb3, 0x2e, 0xef, 0x27, 0x27, 0x3f, 0x6a, 0x30, 0xd9, 0x25, 0xbe, - 0xc8, 0xd9, 0xde, 0xcd, 0xf3, 0xd5, 0x64, 0x69, 0x69, 0x17, 0x19, 0x0a, 0xf4, 0x32, 0x82, 0x5e, - 0x24, 0x0b, 0xcf, 0x00, 0x7d, 0x51, 0x4a, 0xb7, 0x36, 0xda, 0x9f, 0x35, 0x20, 0x3b, 0xf5, 0x12, - 0x59, 0xee, 0xdd, 0xbe, 0xa7, 0x36, 0x2b, 0xad, 0xec, 0x2e, 0x49, 0xc1, 0xbe, 0x84, 0xb0, 0xcf, - 0x93, 0xe5, 0x5c, 0xd8, 0xad, 0x8f, 0x3a, 0xca, 0x1d, 0xcc, 0x34, 0xef, 0xa5, 0x12, 0xee, 0x3e, - 0xf9, 0x45, 0x83, 0xe9, 0x1c, 0x99, 0x43, 0x9e, 0x01, 0xa5, 0xb7, 0x2e, 0x2b, 0x9d, 0xdf, 0x65, - 0x96, 0x9a, 0xe0, 0x32, 0x4e, 0xf0, 0x32, 0x59, 0xc9, 0x9d, 0xc0, 0x69, 0x65, 0x66, 0x47, 0x48, - 0xf5, 0xdf, 0xfd, 0xe4, 0xbc, 0x8c, 0x67, 0x34, 0x10, 0xe9, 0x77, 0xa3, 0x3b, 0xb4, 0x5a, 0x69, - 0x71, 0xc0, 0x68, 0x05, 0xf5, 0x0a, 0x42, 0xbd, 0x40, 0x5e, 0x19, 0xfc, 0x60, 0xb7, 0x37, 0xc0, - 0x99, 0x58, 0x7d, 0xeb, 0xd1, 0x93, 0xb2, 0xf6, 0xf8, 0x49, 0x59, 0xfb, 0xeb, 0x49, 0x59, 0x7b, - 0xf0, 0xb4, 0x3c, 0xf4, 0xf8, 0x69, 0x79, 0xe8, 0xf7, 0xa7, 0xe5, 0xa1, 0xf7, 0xcf, 0xba, 0x9e, - 0xa8, 0x35, 0x2a, 0x46, 0x35, 0xac, 0xa7, 0xc5, 0xab, 0x35, 0xea, 0x05, 0xad, 0x4e, 0x5b, 0xed, - 0x5e, 0x62, 0x3b, 0x62, 0xbc, 0x32, 0x8a, 0xdf, 0x90, 0xe5, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, - 0xad, 0xee, 0x6f, 0xab, 0xf3, 0x11, 0x00, 0x00, + // 1381 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4d, 0x6f, 0xdc, 0x44, + 0x18, 0x8e, 0x37, 0x9b, 0xd0, 0xbc, 0x69, 0x48, 0x3a, 0x69, 0x4b, 0xba, 0x69, 0x37, 0xc5, 0x85, + 0xb6, 0x24, 0x8d, 0xcd, 0x26, 0x29, 0xd0, 0x0f, 0xa8, 0x9a, 0x96, 0x92, 0x48, 0x29, 0x4a, 0x0d, + 0xf4, 0xc0, 0xc5, 0x8c, 0xd7, 0x13, 0xaf, 0x85, 0xbf, 0xea, 0x99, 0x5d, 0x12, 0x95, 0x22, 0x84, + 0x38, 0x72, 0xa8, 0xc4, 0x01, 0x21, 0x24, 0x04, 0xe2, 0xc8, 0x2f, 0x40, 0xe5, 0xc0, 0xb1, 0xc7, + 0x22, 0x2e, 0x9c, 0x00, 0xb5, 0xfc, 0x10, 0xe4, 0x99, 0xf1, 0xae, 0x77, 0x63, 0x77, 0x37, 0x51, + 0xc5, 0x6d, 0xf7, 0xfd, 0x7c, 0xde, 0xe7, 0x9d, 0x19, 0x3f, 0x30, 0x67, 0x61, 0x6b, 0xc7, 0x0b, + 0x03, 0x9d, 0x44, 0x61, 0xbd, 0xe1, 0x06, 0x8e, 0xde, 0xaa, 0xe9, 0x77, 0x9a, 0x24, 0xde, 0xd1, + 0xa2, 0x38, 0x64, 0x21, 0x9a, 0x96, 0x01, 0x5a, 0x1a, 0xa0, 0xb5, 0x6a, 0x95, 0xc3, 0x4e, 0xe8, + 0x84, 0xdc, 0xaf, 0x27, 0xbf, 0x44, 0x68, 0x65, 0xce, 0x09, 0x43, 0xc7, 0x23, 0x3a, 0xff, 0x67, + 0x35, 0xb7, 0x74, 0xe6, 0xfa, 0x84, 0x32, 0xec, 0x47, 0x32, 0xe0, 0xb8, 0x0c, 0xc0, 0x91, 0xab, + 0xe3, 0x20, 0x08, 0x19, 0x66, 0x6e, 0x18, 0x50, 0xe9, 0x9d, 0xaf, 0x87, 0xd4, 0x0f, 0xa9, 0x6e, + 0x61, 0x4a, 0x04, 0x04, 0xbd, 0x55, 0xb3, 0x08, 0xc3, 0x35, 0x3d, 0xc2, 0x8e, 0x1b, 0xf0, 0x60, + 0x19, 0x7b, 0x32, 0x0f, 0x76, 0x84, 0x63, 0xec, 0xa7, 0xd5, 0xd4, 0xbc, 0x88, 0xf6, 0x0c, 0x3c, + 0x46, 0x3d, 0x0c, 0xe8, 0x56, 0xd2, 0x67, 0x93, 0x27, 0x1a, 0xe4, 0x4e, 0x93, 0x50, 0xa6, 0x6e, + 0xc2, 0x74, 0x97, 0x95, 0x46, 0x61, 0x40, 0x09, 0xba, 0x00, 0xa3, 0xa2, 0xc1, 0x8c, 0x72, 0x52, + 0x39, 0x3b, 0xbe, 0x34, 0xab, 0xe5, 0x30, 0xa3, 0x89, 0xa4, 0xd5, 0xf2, 0xc3, 0xbf, 0xe6, 0x86, + 0x0c, 0x99, 0xa0, 0xae, 0xc0, 0x11, 0x5e, 0xf1, 0xed, 0x24, 0x70, 0x3d, 0xd8, 0x0a, 0x65, 0x2b, + 0x34, 0x0b, 0x63, 0x3c, 0xd9, 0x0c, 0x9a, 0x3e, 0x2f, 0x5b, 0x36, 0x0e, 0x70, 0xc3, 0xbb, 0x4d, + 0x5f, 0x35, 0xe0, 0x68, 0x6f, 0x96, 0x84, 0xf2, 0x06, 0x8c, 0xf0, 0x28, 0x89, 0x44, 0xcd, 0x45, + 0xc2, 0xd3, 0xd2, 0x14, 0x43, 0x24, 0xa8, 0x1f, 0x65, 0x6b, 0xd2, 0x2c, 0x94, 0x1b, 0x00, 0x1d, + 0x96, 0x65, 0xe1, 0xd3, 0x9a, 0x58, 0x89, 0x96, 0xac, 0x44, 0x13, 0xa7, 0x42, 0xae, 0x44, 0xdb, + 0xc4, 0x0e, 0x91, 0xb9, 0x46, 0x26, 0x53, 0xfd, 0x5e, 0x81, 0x17, 0x76, 0xb5, 0x90, 0xb8, 0x2f, + 0xc2, 0x28, 0x87, 0x91, 0x50, 0x38, 0x3c, 0x20, 0x70, 0x99, 0x81, 0xde, 0xe9, 0xc2, 0x57, 0xe2, + 0xf8, 0xce, 0xf4, 0xc5, 0x27, 0x8b, 0x64, 0x01, 0x56, 0x60, 0x86, 0xe3, 0xbb, 0xd6, 0x8c, 0x63, + 0x12, 0x30, 0xd9, 0x4d, 0xac, 0xde, 0x81, 0x63, 0x39, 0x3e, 0x89, 0xfe, 0x14, 0x4c, 0xd4, 0x85, + 0xdd, 0xec, 0xb0, 0x5f, 0x36, 0x0e, 0xd6, 0x33, 0xc1, 0xe8, 0x65, 0x78, 0x5e, 0x6c, 0xd4, 0x0a, + 0x9b, 0x81, 0x8d, 0xe3, 0x1d, 0x0e, 0xb5, 0x6c, 0x4c, 0x70, 0xeb, 0xaa, 0x34, 0xaa, 0x9f, 0x66, + 0x4f, 0xc4, 0x4d, 0xea, 0xd0, 0x41, 0x4e, 0x44, 0xcf, 0x8e, 0x4a, 0xfb, 0xde, 0xd1, 0x8f, 0x4a, + 0xf6, 0x18, 0x88, 0xf6, 0x72, 0xc8, 0xb7, 0xa0, 0xec, 0x53, 0x27, 0x5d, 0xd0, 0x7c, 0xee, 0x82, + 0x6e, 0x35, 0x49, 0x93, 0xd8, 0x37, 0x09, 0xa5, 0x59, 0x8e, 0x79, 0xde, 0xb3, 0x5b, 0xd3, 0x4f, + 0x0a, 0xcc, 0x72, 0x8c, 0x1b, 0x98, 0x11, 0xca, 0x72, 0x89, 0x0a, 0xec, 0xae, 0x4d, 0x1c, 0x20, + 0x81, 0x2d, 0xb6, 0x30, 0x07, 0xe3, 0x82, 0xc5, 0x7a, 0xd8, 0x0c, 0x98, 0x5c, 0x01, 0x70, 0xd3, + 0xb5, 0xc4, 0xd2, 0xc3, 0xe4, 0xf0, 0xbe, 0x99, 0x7c, 0xa0, 0xc0, 0xf1, 0x7c, 0x94, 0x92, 0x4f, + 0x03, 0x0e, 0x79, 0xdc, 0x25, 0x90, 0x9a, 0x19, 0x72, 0x4f, 0xf7, 0x27, 0x77, 0xc3, 0xa5, 0xcc, + 0x98, 0xf4, 0xba, 0x6b, 0x3f, 0x3b, 0x8e, 0x2f, 0x41, 0x95, 0x83, 0xbf, 0x8d, 0x3d, 0xd7, 0xc6, + 0x2c, 0x8c, 0x37, 0xdc, 0x2d, 0x52, 0xdf, 0xa9, 0x7b, 0xe9, 0xac, 0xe8, 0x18, 0x1c, 0x68, 0x61, + 0xcf, 0xc4, 0xb6, 0x1d, 0x73, 0x92, 0xc7, 0x8c, 0xe7, 0x5a, 0xd8, 0xbb, 0x6a, 0xdb, 0xb1, 0xfa, + 0xa5, 0x02, 0x73, 0x85, 0xd9, 0x72, 0xfa, 0xe2, 0x74, 0x74, 0x43, 0xb8, 0x3c, 0x77, 0x8b, 0xcc, + 0x94, 0x38, 0x1f, 0x0b, 0xb9, 0x7c, 0xdc, 0xc6, 0xde, 0x7b, 0x0c, 0x33, 0xf2, 0x41, 0x64, 0x63, + 0xd6, 0x19, 0x23, 0xa9, 0x93, 0xf4, 0x53, 0x2f, 0x4b, 0x14, 0xd7, 0x89, 0x47, 0x1c, 0x3e, 0x56, + 0xde, 0x10, 0x36, 0xe9, 0x46, 0x61, 0x13, 0x31, 0x84, 0x03, 0x27, 0x8b, 0xb3, 0xe5, 0x10, 0xd7, + 0x44, 0x3a, 0x47, 0x2a, 0xde, 0xc5, 0xb3, 0xb9, 0x48, 0xf3, 0x6a, 0x24, 0x8d, 0x38, 0xcc, 0xcf, + 0xb2, 0xaf, 0x62, 0x32, 0x13, 0x61, 0xff, 0xeb, 0x95, 0xff, 0x5d, 0x91, 0xcf, 0x5e, 0x17, 0x80, + 0xf6, 0xa5, 0x87, 0x56, 0xba, 0xc4, 0xf4, 0x74, 0x56, 0x8b, 0xb6, 0x21, 0xc2, 0x8c, 0x4c, 0x06, + 0x3a, 0x07, 0x88, 0x85, 0x0c, 0x7b, 0x66, 0x2b, 0x64, 0x6e, 0xe0, 0x98, 0x51, 0xf8, 0x09, 0x89, + 0x39, 0xd8, 0x61, 0x63, 0x8a, 0x7b, 0x6e, 0x73, 0xc7, 0x66, 0x62, 0xef, 0x39, 0xbe, 0xc3, 0xfb, + 0x3f, 0xbe, 0x0f, 0x4a, 0x30, 0xd1, 0xfd, 0x44, 0xbf, 0x08, 0x07, 0xdb, 0x54, 0x5a, 0x24, 0x96, + 0x6c, 0x8e, 0xa7, 0x6c, 0x5a, 0x24, 0x46, 0x2b, 0x70, 0xb4, 0xeb, 0x15, 0x37, 0xdd, 0x80, 0x91, + 0xb8, 0x85, 0x3d, 0xf9, 0x4a, 0x1c, 0xce, 0x3e, 0xe7, 0xeb, 0xd2, 0x97, 0x4c, 0xb8, 0xe5, 0xc6, + 0x94, 0x99, 0x96, 0x17, 0xd6, 0x3f, 0x36, 0x1b, 0xc4, 0x75, 0x1a, 0x8c, 0x63, 0x2f, 0x1b, 0x53, + 0xdc, 0xb3, 0x9a, 0x38, 0xd6, 0xb8, 0x1d, 0xad, 0xc1, 0xa4, 0x87, 0xdb, 0xc1, 0x89, 0x0a, 0x9a, + 0x29, 0xf3, 0x31, 0x2b, 0x9a, 0x50, 0x40, 0x5a, 0x2a, 0x91, 0xb4, 0xf7, 0x53, 0x89, 0xb4, 0x5a, + 0xbe, 0xff, 0xf7, 0x9c, 0x62, 0x4c, 0x24, 0x89, 0xbc, 0x56, 0xe2, 0x41, 0x8b, 0x30, 0x4d, 0x09, + 0xf6, 0x48, 0x6c, 0xe2, 0x28, 0x32, 0x1b, 0x98, 0x36, 0xcc, 0x06, 0xd9, 0x9e, 0x19, 0xe1, 0xa7, + 0x78, 0x4a, 0xb8, 0xae, 0x46, 0xd1, 0x1a, 0xa6, 0x8d, 0x35, 0xb2, 0x8d, 0xe6, 0xe1, 0x90, 0x0c, + 0x97, 0x38, 0x31, 0x6d, 0xcc, 0x8c, 0xf2, 0xe0, 0x49, 0xe1, 0x10, 0x30, 0x31, 0x6d, 0xa8, 0xbf, + 0x28, 0xfc, 0x1b, 0xb4, 0xfb, 0x25, 0x47, 0xd3, 0x30, 0xc2, 0xb6, 0x4d, 0xd7, 0x96, 0x97, 0xa5, + 0xcc, 0xb6, 0xd7, 0x6d, 0x74, 0x04, 0x46, 0x7d, 0xea, 0x24, 0xd6, 0x12, 0xb7, 0x8e, 0xf8, 0xd4, + 0x59, 0xb7, 0x13, 0xc6, 0x73, 0x28, 0x19, 0xb7, 0x32, 0x6c, 0x5c, 0x01, 0xd8, 0x07, 0x11, 0x63, + 0x56, 0x9b, 0x84, 0x29, 0x18, 0xf6, 0xa9, 0x23, 0x87, 0x4e, 0x7e, 0xaa, 0x2d, 0x38, 0xb4, 0xeb, + 0x9d, 0x1c, 0x64, 0xf9, 0xe9, 0xd7, 0xad, 0xb4, 0xbf, 0xaf, 0x9b, 0xfa, 0x9d, 0x02, 0x47, 0xf3, + 0x1f, 0x24, 0x74, 0x02, 0x80, 0x26, 0x66, 0xd3, 0x26, 0xb4, 0x2e, 0x99, 0x1b, 0xe3, 0x96, 0xeb, + 0x84, 0xd6, 0x77, 0xf1, 0x54, 0xea, 0xc7, 0xd3, 0xf0, 0x9e, 0x79, 0x5a, 0x7a, 0x34, 0x0e, 0x23, + 0xfc, 0x8e, 0xa3, 0xcf, 0x15, 0x18, 0x15, 0x4a, 0x14, 0x9d, 0x29, 0x1a, 0xb2, 0x47, 0xf6, 0x56, + 0xce, 0xf6, 0x0f, 0x14, 0xa3, 0xaa, 0xa7, 0xbe, 0xf8, 0xe3, 0xdf, 0xaf, 0x4b, 0x27, 0xd0, 0xac, + 0x5e, 0xac, 0xc2, 0xd1, 0x37, 0x0a, 0x8c, 0xb5, 0x95, 0x2b, 0x9a, 0x2f, 0x2e, 0xde, 0x2b, 0x8a, + 0x2b, 0x0b, 0x03, 0xc5, 0x4a, 0x2c, 0x35, 0x8e, 0x65, 0x01, 0xbd, 0xa2, 0x17, 0xea, 0x7d, 0xaa, + 0xdf, 0x6d, 0x9f, 0x8b, 0x37, 0xe7, 0xef, 0xa1, 0xaf, 0x14, 0x80, 0x8e, 0x38, 0x45, 0xfd, 0xda, + 0x65, 0x55, 0x72, 0xe5, 0xdc, 0x60, 0xc1, 0x03, 0x11, 0x25, 0x85, 0xed, 0xb7, 0x0a, 0x1c, 0xcc, + 0xea, 0x4d, 0xb4, 0x58, 0xdc, 0x23, 0x47, 0xb3, 0x56, 0xb4, 0x41, 0xc3, 0x25, 0xa8, 0x79, 0x0e, + 0xea, 0x25, 0xa4, 0xe6, 0x82, 0xea, 0x7a, 0x1b, 0xd1, 0x0f, 0xe9, 0x12, 0xb9, 0xee, 0xe8, 0xb7, + 0xc4, 0x8c, 0x3c, 0xeb, 0xbb, 0xc4, 0xac, 0x48, 0x52, 0x2f, 0x72, 0x48, 0x2b, 0x68, 0x69, 0xe0, + 0x25, 0xea, 0xbe, 0xb8, 0x9f, 0x14, 0xfd, 0xac, 0xc0, 0x64, 0x8f, 0xf8, 0x42, 0xaf, 0x16, 0x37, + 0xcf, 0x57, 0x93, 0x95, 0xda, 0x1e, 0x32, 0x24, 0xe8, 0x65, 0x0e, 0x7a, 0x11, 0x2d, 0x3c, 0x05, + 0xf4, 0x45, 0x21, 0xdd, 0x3a, 0x68, 0x7f, 0x55, 0x00, 0xed, 0xd6, 0x4b, 0x68, 0xb9, 0xb8, 0x7d, + 0xa1, 0x36, 0xab, 0xac, 0xec, 0x2d, 0x49, 0xc2, 0xbe, 0xc4, 0x61, 0x9f, 0x47, 0xcb, 0xb9, 0xb0, + 0xdb, 0x1f, 0x75, 0x2e, 0x77, 0x78, 0xa6, 0x7e, 0x37, 0x95, 0x70, 0xf7, 0xd0, 0x6f, 0x0a, 0x4c, + 0xe7, 0xc8, 0x1c, 0xf4, 0x14, 0x28, 0xc5, 0xba, 0xac, 0x72, 0x7e, 0x8f, 0x59, 0x72, 0x82, 0xcb, + 0x7c, 0x82, 0xd7, 0xd0, 0x4a, 0xee, 0x04, 0x76, 0x3b, 0x33, 0x3b, 0x42, 0xaa, 0xff, 0xee, 0x25, + 0xe7, 0x65, 0x3c, 0xa3, 0x81, 0x50, 0xbf, 0x1b, 0xdd, 0xa5, 0xd5, 0x2a, 0x8b, 0x03, 0x46, 0x4b, + 0xa8, 0x57, 0x38, 0xd4, 0x0b, 0xe8, 0xf5, 0xc1, 0x0f, 0x76, 0x67, 0x03, 0x94, 0xb0, 0xd5, 0x8d, + 0x87, 0x8f, 0xab, 0xca, 0xa3, 0xc7, 0x55, 0xe5, 0x9f, 0xc7, 0x55, 0xe5, 0xfe, 0x93, 0xea, 0xd0, + 0xa3, 0x27, 0xd5, 0xa1, 0x3f, 0x9f, 0x54, 0x87, 0x3e, 0x5c, 0x72, 0x5c, 0xd6, 0x68, 0x5a, 0x5a, + 0x3d, 0xf4, 0xd3, 0xe2, 0x1e, 0xb6, 0xe8, 0xa2, 0x1b, 0xb6, 0x7b, 0x6d, 0x77, 0xba, 0xb1, 0x9d, + 0x88, 0x50, 0x6b, 0x94, 0x7f, 0x45, 0x96, 0xff, 0x0b, 0x00, 0x00, 0xff, 0xff, 0x29, 0x2d, 0xf8, + 0x0c, 0xf5, 0x11, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/epoching/types/tx.pb.go b/x/epoching/types/tx.pb.go index fd16d4af4..71db40e2d 100644 --- a/x/epoching/types/tx.pb.go +++ b/x/epoching/types/tx.pb.go @@ -453,44 +453,44 @@ func init() { func init() { proto.RegisterFile("babylon/epoching/v1/tx.proto", fileDescriptor_a5fc8fed8f4e58b6) } var fileDescriptor_a5fc8fed8f4e58b6 = []byte{ - // 585 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x4f, 0x6f, 0x12, 0x41, - 0x18, 0xc6, 0x77, 0x6d, 0x6d, 0xd2, 0x57, 0x63, 0x75, 0x25, 0x16, 0x56, 0xb2, 0x20, 0x68, 0x54, - 0xb4, 0xbb, 0x52, 0xb5, 0x6a, 0xe3, 0x41, 0xd1, 0x78, 0x30, 0x21, 0x31, 0x98, 0xc6, 0xc4, 0xc4, - 0x98, 0x59, 0x76, 0x32, 0x6c, 0x60, 0x67, 0xd6, 0x9d, 0x69, 0x53, 0x4e, 0x36, 0x9e, 0x3c, 0x7a, - 0xf0, 0x6c, 0xfa, 0x11, 0x7a, 0xf0, 0x43, 0xf4, 0xd8, 0x78, 0xf2, 0x64, 0x0c, 0x1c, 0xea, 0x07, - 0xf0, 0x03, 0x18, 0xf6, 0x2f, 0x02, 0x0b, 0xe8, 0x8d, 0xe1, 0x7d, 0xde, 0xe7, 0xf9, 0xc1, 0x3e, - 0x3b, 0x90, 0x37, 0x91, 0xd9, 0xed, 0x30, 0x6a, 0x60, 0x97, 0x35, 0x5b, 0x36, 0x25, 0xc6, 0x4e, - 0xd5, 0x10, 0xbb, 0xba, 0xeb, 0x31, 0xc1, 0x94, 0xf3, 0xe1, 0x54, 0x8f, 0xa6, 0xfa, 0x4e, 0x55, - 0xcd, 0x10, 0x46, 0x98, 0x3f, 0x37, 0x06, 0x9f, 0x02, 0xa9, 0x5a, 0x68, 0x32, 0xee, 0x30, 0x6e, - 0x70, 0x81, 0xda, 0x81, 0x8d, 0x89, 0x05, 0x4a, 0xbc, 0xd4, 0xe2, 0xa4, 0x24, 0x17, 0x79, 0xc8, - 0xe1, 0xa1, 0x22, 0x17, 0x58, 0xbc, 0x0d, 0xbc, 0x83, 0x43, 0x38, 0x5a, 0x0d, 0xdd, 0x1d, 0xee, - 0xaf, 0x39, 0x9c, 0x04, 0x83, 0xd2, 0x1b, 0x50, 0xea, 0x9c, 0xbc, 0xf2, 0x90, 0xeb, 0x62, 0xeb, - 0x29, 0xee, 0x60, 0x82, 0x04, 0x56, 0xee, 0xc2, 0x82, 0xc3, 0x49, 0x56, 0x2e, 0xca, 0xd7, 0x4e, - 0xad, 0x97, 0xf5, 0xd0, 0x2a, 0x44, 0xd3, 0x43, 0x34, 0xbd, 0xce, 0x49, 0xb4, 0xd1, 0x18, 0xe8, - 0x37, 0xcf, 0x7e, 0xdc, 0x2f, 0x48, 0xbf, 0xf6, 0x0b, 0xd2, 0x87, 0xe3, 0x83, 0xca, 0xe0, 0x9b, - 0x52, 0x1e, 0xd4, 0x71, 0xfb, 0x06, 0xe6, 0x2e, 0xa3, 0x1c, 0x97, 0x10, 0x64, 0x92, 0xe9, 0x16, - 0xb5, 0xa2, 0xf8, 0x7b, 0xc3, 0xf1, 0x57, 0xa6, 0xc4, 0x27, 0x3b, 0x69, 0x00, 0x1a, 0xe4, 0x27, - 0x45, 0xc4, 0x08, 0x6d, 0xc8, 0x25, 0xf3, 0x1a, 0x26, 0x36, 0x6d, 0xe0, 0x98, 0xe3, 0xe1, 0x30, - 0x47, 0x65, 0x0a, 0xc7, 0xc8, 0x62, 0x1a, 0x4c, 0x19, 0x2e, 0xa5, 0x86, 0xc5, 0x44, 0xef, 0xa1, - 0x9c, 0x88, 0x9e, 0x20, 0xda, 0xc4, 0x9d, 0x2d, 0x6a, 0x32, 0x6a, 0xd9, 0x34, 0xfa, 0xbb, 0x6d, - 0x46, 0x95, 0x67, 0xc3, 0x6c, 0x77, 0xa6, 0xb0, 0xa5, 0x5a, 0xa4, 0x51, 0xae, 0xc1, 0x8d, 0x39, - 0x00, 0x62, 0xde, 0xcf, 0x32, 0xac, 0x0c, 0x1e, 0x85, 0x6b, 0x21, 0x81, 0x5f, 0xf8, 0x7d, 0x54, - 0x36, 0x60, 0x19, 0x6d, 0x8b, 0x16, 0xf3, 0x6c, 0xd1, 0xf5, 0x11, 0x97, 0x6b, 0xd9, 0x6f, 0x5f, - 0xd7, 0x32, 0x21, 0xe5, 0x63, 0xcb, 0xf2, 0x30, 0xe7, 0x2f, 0x85, 0x67, 0x53, 0xd2, 0x48, 0xa4, - 0xca, 0x03, 0x58, 0x0a, 0x1a, 0x9d, 0x3d, 0xe1, 0xff, 0xae, 0x8b, 0xfa, 0x84, 0x17, 0x48, 0x0f, - 0x42, 0x6a, 0x8b, 0x87, 0x3f, 0x0a, 0x52, 0x23, 0x5c, 0xd8, 0x3c, 0x33, 0xe0, 0x4f, 0xac, 0x4a, - 0x39, 0x58, 0x1d, 0xa1, 0x8a, 0x88, 0xd7, 0x7f, 0x2f, 0xc2, 0x42, 0x9d, 0x13, 0xa5, 0x0d, 0x2b, - 0xa3, 0xc5, 0xbf, 0x3a, 0x31, 0x70, 0xbc, 0xc2, 0xaa, 0x31, 0xa7, 0x30, 0x0a, 0x55, 0xde, 0xc1, - 0xb9, 0xf1, 0xa2, 0x5f, 0x9f, 0xe1, 0x92, 0x48, 0xd5, 0xea, 0xdc, 0xd2, 0x38, 0x72, 0x4f, 0x86, - 0x0b, 0x29, 0xcd, 0xd6, 0x67, 0xb8, 0x8d, 0xe8, 0xd5, 0x8d, 0x7f, 0xd3, 0xc7, 0x08, 0x5f, 0x64, - 0x28, 0xce, 0xac, 0xf2, 0xfd, 0x19, 0xe6, 0xa9, 0x9b, 0xea, 0xa3, 0xff, 0xdd, 0x8c, 0x01, 0x4d, - 0x38, 0xfd, 0x57, 0x73, 0x2f, 0xa7, 0x39, 0x0e, 0xab, 0xd4, 0x9b, 0xf3, 0xa8, 0xa2, 0x0c, 0xf5, - 0xe4, 0xde, 0xf1, 0x41, 0x45, 0xae, 0x3d, 0x3f, 0xec, 0x69, 0xf2, 0x51, 0x4f, 0x93, 0x7f, 0xf6, - 0x34, 0xf9, 0x53, 0x5f, 0x93, 0x8e, 0xfa, 0x9a, 0xf4, 0xbd, 0xaf, 0x49, 0xaf, 0x6f, 0x11, 0x5b, - 0xb4, 0xb6, 0x4d, 0xbd, 0xc9, 0x1c, 0x23, 0x34, 0x6e, 0xb6, 0x90, 0x4d, 0xa3, 0x83, 0xb1, 0x9b, - 0x5c, 0xfa, 0xa2, 0xeb, 0x62, 0x6e, 0x2e, 0xf9, 0xb7, 0xf7, 0xed, 0x3f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0xdf, 0xdb, 0xcd, 0x7f, 0x7f, 0x06, 0x00, 0x00, + // 586 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xc1, 0x8e, 0xd2, 0x40, + 0x1c, 0xc6, 0x5b, 0x77, 0xdd, 0x64, 0x47, 0xe3, 0x6a, 0x25, 0x2e, 0x54, 0x52, 0x10, 0x34, 0x2a, + 0x4a, 0x1b, 0x50, 0x57, 0xdd, 0x78, 0x50, 0x34, 0x9e, 0x24, 0x31, 0x98, 0x8d, 0x89, 0x89, 0x31, + 0x53, 0x3a, 0x19, 0x1a, 0xe8, 0x4c, 0xed, 0xcc, 0x6e, 0x96, 0x93, 0x1b, 0x4f, 0x1e, 0x3d, 0x78, + 0x36, 0xfb, 0x08, 0x7b, 0xf0, 0x21, 0xf6, 0xb8, 0xf1, 0xe4, 0xc9, 0x18, 0x38, 0xac, 0x0f, 0xe0, + 0x03, 0x98, 0xb6, 0xd3, 0x16, 0x81, 0x02, 0xee, 0x8d, 0xe1, 0xff, 0xfd, 0xbf, 0xef, 0x07, 0xfd, + 0x3a, 0x20, 0x6f, 0x42, 0xb3, 0xdf, 0xa3, 0xc4, 0x40, 0x2e, 0x6d, 0x77, 0x6c, 0x82, 0x8d, 0x9d, + 0x9a, 0xc1, 0x77, 0x75, 0xd7, 0xa3, 0x9c, 0x2a, 0x17, 0xc5, 0x54, 0x8f, 0xa6, 0xfa, 0x4e, 0x4d, + 0xcd, 0x60, 0x8a, 0x69, 0x30, 0x37, 0xfc, 0x4f, 0xa1, 0x54, 0x2d, 0xb4, 0x29, 0x73, 0x28, 0x33, + 0x18, 0x87, 0xdd, 0xd0, 0xc6, 0x44, 0x1c, 0x26, 0x5e, 0x6a, 0x71, 0x5a, 0x92, 0x0b, 0x3d, 0xe8, + 0x30, 0xa1, 0xc8, 0x85, 0x16, 0xef, 0x42, 0xef, 0xf0, 0x20, 0x46, 0xeb, 0xc2, 0xdd, 0x61, 0xc1, + 0x9a, 0xc3, 0x70, 0x38, 0x28, 0xbd, 0x05, 0x4a, 0x93, 0xe1, 0xd7, 0x1e, 0x74, 0x5d, 0x64, 0x3d, + 0x43, 0x3d, 0x84, 0x21, 0x47, 0xca, 0x3d, 0xb0, 0xe4, 0x30, 0x9c, 0x95, 0x8b, 0xf2, 0x8d, 0x33, + 0xf5, 0xb2, 0x2e, 0xac, 0x04, 0x9a, 0x2e, 0xd0, 0xf4, 0x26, 0xc3, 0xd1, 0x46, 0xcb, 0xd7, 0x6f, + 0x9e, 0xff, 0xb4, 0x5f, 0x90, 0x7e, 0xef, 0x17, 0xa4, 0x8f, 0xc7, 0x07, 0x15, 0xff, 0x9b, 0x52, + 0x1e, 0xa8, 0x93, 0xf6, 0x2d, 0xc4, 0x5c, 0x4a, 0x18, 0x2a, 0x41, 0x90, 0x49, 0xa6, 0x5b, 0xc4, + 0x8a, 0xe2, 0xef, 0x8f, 0xc6, 0x5f, 0x9b, 0x11, 0x9f, 0xec, 0xa4, 0x01, 0x68, 0x20, 0x3f, 0x2d, + 0x22, 0x46, 0xe8, 0x82, 0x5c, 0x32, 0x6f, 0x20, 0x6c, 0x93, 0x16, 0x8a, 0x39, 0x1e, 0x8d, 0x72, + 0x54, 0x66, 0x70, 0x8c, 0x2d, 0xa6, 0xc1, 0x94, 0xc1, 0x95, 0xd4, 0xb0, 0x98, 0xe8, 0x03, 0x28, + 0x27, 0xa2, 0xa7, 0x90, 0xb4, 0x51, 0x6f, 0x8b, 0x98, 0x94, 0x58, 0x36, 0x89, 0xfe, 0x6e, 0x9b, + 0x12, 0xe5, 0xf9, 0x28, 0xdb, 0xdd, 0x19, 0x6c, 0xa9, 0x16, 0x69, 0x94, 0x55, 0x70, 0x6b, 0x01, + 0x80, 0x98, 0xf7, 0x8b, 0x0c, 0xd6, 0xfc, 0x47, 0xe1, 0x5a, 0x90, 0xa3, 0x97, 0x41, 0x1f, 0x95, + 0x0d, 0xb0, 0x0a, 0xb7, 0x79, 0x87, 0x7a, 0x36, 0xef, 0x07, 0x88, 0xab, 0x8d, 0xec, 0xf7, 0x6f, + 0xd5, 0x8c, 0xa0, 0x7c, 0x62, 0x59, 0x1e, 0x62, 0xec, 0x15, 0xf7, 0x6c, 0x82, 0x5b, 0x89, 0x54, + 0x79, 0x08, 0x56, 0xc2, 0x46, 0x67, 0x4f, 0x05, 0xbf, 0xeb, 0xb2, 0x3e, 0xe5, 0x05, 0xd2, 0xc3, + 0x90, 0xc6, 0xf2, 0xe1, 0xcf, 0x82, 0xd4, 0x12, 0x0b, 0x9b, 0xe7, 0x7c, 0xfe, 0xc4, 0xaa, 0x94, + 0x03, 0xeb, 0x63, 0x54, 0x11, 0x71, 0xfd, 0xcf, 0x32, 0x58, 0x6a, 0x32, 0xac, 0x74, 0xc1, 0xda, + 0x78, 0xf1, 0xaf, 0x4f, 0x0d, 0x9c, 0xac, 0xb0, 0x6a, 0x2c, 0x28, 0x8c, 0x42, 0x95, 0xf7, 0xe0, + 0xc2, 0x64, 0xd1, 0x6f, 0xce, 0x71, 0x49, 0xa4, 0x6a, 0x6d, 0x61, 0x69, 0x1c, 0xb9, 0x27, 0x83, + 0x4b, 0x29, 0xcd, 0xd6, 0xe7, 0xb8, 0x8d, 0xe9, 0xd5, 0x8d, 0xff, 0xd3, 0xc7, 0x08, 0x5f, 0x65, + 0x50, 0x9c, 0x5b, 0xe5, 0x07, 0x73, 0xcc, 0x53, 0x37, 0xd5, 0xc7, 0x27, 0xdd, 0x8c, 0x01, 0x4d, + 0x70, 0xf6, 0x9f, 0xe6, 0x5e, 0x4d, 0x73, 0x1c, 0x55, 0xa9, 0xb7, 0x17, 0x51, 0x45, 0x19, 0xea, + 0xe9, 0xbd, 0xe3, 0x83, 0x8a, 0xdc, 0x78, 0x71, 0x38, 0xd0, 0xe4, 0xa3, 0x81, 0x26, 0xff, 0x1a, + 0x68, 0xf2, 0xe7, 0xa1, 0x26, 0x1d, 0x0d, 0x35, 0xe9, 0xc7, 0x50, 0x93, 0xde, 0xd4, 0xb1, 0xcd, + 0x3b, 0xdb, 0xa6, 0xde, 0xa6, 0x8e, 0x21, 0x8c, 0x7b, 0xd0, 0x64, 0x55, 0x9b, 0x46, 0x47, 0x63, + 0x37, 0xb9, 0xf6, 0x79, 0xdf, 0x45, 0xcc, 0x5c, 0x09, 0xee, 0xef, 0x3b, 0x7f, 0x03, 0x00, 0x00, + 0xff, 0xff, 0xdc, 0x26, 0x42, 0x47, 0x81, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/epoching/types/validator_test.go b/x/epoching/types/validator_test.go index d885c0d32..ba6468dc9 100644 --- a/x/epoching/types/validator_test.go +++ b/x/epoching/types/validator_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/stretchr/testify/require" ) diff --git a/x/finality/README.md b/x/finality/README.md index 2f8954dcf..aae159c08 100644 --- a/x/finality/README.md +++ b/x/finality/README.md @@ -159,7 +159,7 @@ secp256k1 secret key, as per EOTS's extractability property. // signatures with correct public randomness on two conflicting Babylon headers message Evidence { // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // block_height is the height of the conflicting blocks uint64 block_height = 2; // master_pub_rand is the master public randomness the finality provider has committed to @@ -173,10 +173,10 @@ message Evidence { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - bytes canonical_finality_sig = 6 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes canonical_finality_sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; // fork_finality_sig is the finality signature to the fork block // where finality signature is an EOTS signature - bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; } ``` @@ -214,7 +214,7 @@ The information stored for tracking finality provider liveness is as follows: message FinalityProviderSigningInfo { // fp_btc_pk is the BTC PK of the finality provider that casts this finality // signature - bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // start_height is the block height at which finality provider become active int64 start_height = 2; // missed_blocks_counter defines a counter to avoid unnecessary array reads. @@ -254,7 +254,7 @@ message MsgAddFinalitySig { string signer = 1; // fp_btc_pk is the BTC PK of the finality provider that casts this vote - bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; // block_height is the height of the voted block uint64 block_height = 3; // block_app_hash is the AppHash of the voted block @@ -263,7 +263,7 @@ message MsgAddFinalitySig { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - bytes finality_sig = 5 [ (gogoproto.customtype) = "github.com/babylonchain/babylon/types.SchnorrEOTSSig" ]; + bytes finality_sig = 5 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; } ``` diff --git a/x/finality/abci.go b/x/finality/abci.go index 1b62dac38..93ef8852a 100644 --- a/x/finality/abci.go +++ b/x/finality/abci.go @@ -8,8 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func BeginBlocker(ctx context.Context, k keeper.Keeper) error { diff --git a/x/finality/client/cli/query.go b/x/finality/client/cli/query.go index 78ece2d87..da6ef9361 100644 --- a/x/finality/client/cli/query.go +++ b/x/finality/client/cli/query.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) const ( diff --git a/x/finality/client/cli/query_params.go b/x/finality/client/cli/query_params.go index 16ff79e70..ea616d06b 100644 --- a/x/finality/client/cli/query_params.go +++ b/x/finality/client/cli/query_params.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func CmdQueryParams() *cobra.Command { diff --git a/x/finality/client/cli/tx.go b/x/finality/client/cli/tx.go index d1ed88abd..384d87448 100644 --- a/x/finality/client/cli/tx.go +++ b/x/finality/client/cli/tx.go @@ -6,8 +6,8 @@ import ( "strconv" "strings" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" diff --git a/x/finality/genesis.go b/x/finality/genesis.go index bf1974280..43018ece9 100644 --- a/x/finality/genesis.go +++ b/x/finality/genesis.go @@ -3,8 +3,8 @@ package finality import ( "context" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" ) // InitGenesis initializes the module's state from a provided genesis state. diff --git a/x/finality/genesis_test.go b/x/finality/genesis_test.go index e99999e4e..f66eb3555 100644 --- a/x/finality/genesis_test.go +++ b/x/finality/genesis_test.go @@ -3,10 +3,10 @@ package finality_test import ( "testing" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/finality" - "github.com/babylonchain/babylon/x/finality/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/finality" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/stretchr/testify/require" ) diff --git a/x/finality/keeper/evidence.go b/x/finality/keeper/evidence.go index 393058d4b..4a18c7d69 100644 --- a/x/finality/keeper/evidence.go +++ b/x/finality/keeper/evidence.go @@ -4,8 +4,8 @@ import ( "context" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/keeper/genesis.go b/x/finality/keeper/genesis.go index 9a70531cb..1c41be585 100644 --- a/x/finality/keeper/genesis.go +++ b/x/finality/keeper/genesis.go @@ -6,9 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - btcstk "github.com/babylonchain/babylon/btcstaking" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + btcstk "github.com/babylonlabs-io/babylon/btcstaking" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) // InitGenesis initializes the keeper state from a provided initial genesis state. diff --git a/x/finality/keeper/genesis_test.go b/x/finality/keeper/genesis_test.go index bbec05549..cdad29119 100644 --- a/x/finality/keeper/genesis_test.go +++ b/x/finality/keeper/genesis_test.go @@ -6,10 +6,10 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func FuzzTestExportGenesis(f *testing.F) { diff --git a/x/finality/keeper/grpc_query.go b/x/finality/keeper/grpc_query.go index 5f38bba40..1478f8f26 100644 --- a/x/finality/keeper/grpc_query.go +++ b/x/finality/keeper/grpc_query.go @@ -12,8 +12,8 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/finality/keeper/grpc_query_test.go b/x/finality/keeper/grpc_query_test.go index e4a360197..d8d878696 100644 --- a/x/finality/keeper/grpc_query_test.go +++ b/x/finality/keeper/grpc_query_test.go @@ -11,11 +11,11 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func FuzzBlock(f *testing.F) { diff --git a/x/finality/keeper/hooks.go b/x/finality/keeper/hooks.go index 8d18422c7..ba2140001 100644 --- a/x/finality/keeper/hooks.go +++ b/x/finality/keeper/hooks.go @@ -7,8 +7,8 @@ import ( "cosmossdk.io/collections" sdk "github.com/cosmos/cosmos-sdk/types" - bbntypes "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbntypes "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) var _ types.BtcStakingHooks = Hooks{} diff --git a/x/finality/keeper/indexed_blocks.go b/x/finality/keeper/indexed_blocks.go index 07455ffb1..00d3bd649 100644 --- a/x/finality/keeper/indexed_blocks.go +++ b/x/finality/keeper/indexed_blocks.go @@ -4,7 +4,7 @@ import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/keeper/keeper.go b/x/finality/keeper/keeper.go index 8b131d070..fe185a569 100644 --- a/x/finality/keeper/keeper.go +++ b/x/finality/keeper/keeper.go @@ -10,7 +10,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) type ( diff --git a/x/finality/keeper/liveness.go b/x/finality/keeper/liveness.go index ae2fbb5db..59cf453cc 100644 --- a/x/finality/keeper/liveness.go +++ b/x/finality/keeper/liveness.go @@ -6,8 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/types" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/types" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" ) // HandleLiveness handles liveness of each active finality provider for a given height diff --git a/x/finality/keeper/liveness_test.go b/x/finality/keeper/liveness_test.go index 563cba5ee..da92702e5 100644 --- a/x/finality/keeper/liveness_test.go +++ b/x/finality/keeper/liveness_test.go @@ -7,10 +7,10 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func FuzzHandleLiveness(f *testing.F) { diff --git a/x/finality/keeper/msg_server.go b/x/finality/keeper/msg_server.go index f0cd17b80..3576f7cd1 100644 --- a/x/finality/keeper/msg_server.go +++ b/x/finality/keeper/msg_server.go @@ -7,9 +7,9 @@ import ( "time" errorsmod "cosmossdk.io/errors" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" diff --git a/x/finality/keeper/msg_server_test.go b/x/finality/keeper/msg_server_test.go index 1401db82e..231ef895e 100644 --- a/x/finality/keeper/msg_server_test.go +++ b/x/finality/keeper/msg_server_test.go @@ -7,12 +7,12 @@ import ( "time" "cosmossdk.io/core/header" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/finality/keeper/params.go b/x/finality/keeper/params.go index 15241fefc..7ee128b5f 100644 --- a/x/finality/keeper/params.go +++ b/x/finality/keeper/params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) // SetParams sets the x/finality module parameters. diff --git a/x/finality/keeper/params_test.go b/x/finality/keeper/params_test.go index b34d260d5..649fd3eda 100644 --- a/x/finality/keeper/params_test.go +++ b/x/finality/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/finality/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/stretchr/testify/require" ) diff --git a/x/finality/keeper/public_randomness.go b/x/finality/keeper/public_randomness.go index a46a630fd..68cb87e84 100644 --- a/x/finality/keeper/public_randomness.go +++ b/x/finality/keeper/public_randomness.go @@ -7,8 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/keeper/query.go b/x/finality/keeper/query.go index 8d23eb5b1..43483804f 100644 --- a/x/finality/keeper/query.go +++ b/x/finality/keeper/query.go @@ -1,7 +1,7 @@ package keeper import ( - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) var _ types.QueryServer = Keeper{} diff --git a/x/finality/keeper/query_params.go b/x/finality/keeper/query_params.go index 6d3d896f0..a24021da4 100644 --- a/x/finality/keeper/query_params.go +++ b/x/finality/keeper/query_params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/finality/keeper/query_params_test.go b/x/finality/keeper/query_params_test.go index 857747a54..2bdbfcc07 100644 --- a/x/finality/keeper/query_params_test.go +++ b/x/finality/keeper/query_params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/finality/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/stretchr/testify/require" ) diff --git a/x/finality/keeper/signing_info.go b/x/finality/keeper/signing_info.go index 80d80cc82..85fb5f605 100644 --- a/x/finality/keeper/signing_info.go +++ b/x/finality/keeper/signing_info.go @@ -8,8 +8,8 @@ import ( errorsmod "cosmossdk.io/errors" "github.com/bits-and-blooms/bitset" - bbntypes "github.com/babylonchain/babylon/types" - finalitytypes "github.com/babylonchain/babylon/x/finality/types" + bbntypes "github.com/babylonlabs-io/babylon/types" + finalitytypes "github.com/babylonlabs-io/babylon/x/finality/types" ) // GetMissedBlockBitmapValue returns true if a finality provider missed signing diff --git a/x/finality/keeper/tallying.go b/x/finality/keeper/tallying.go index 6a10d4afa..9af4c6fec 100644 --- a/x/finality/keeper/tallying.go +++ b/x/finality/keeper/tallying.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/keeper/tallying_bench_test.go b/x/finality/keeper/tallying_bench_test.go index 1e93139d9..abe4c38ca 100644 --- a/x/finality/keeper/tallying_bench_test.go +++ b/x/finality/keeper/tallying_bench_test.go @@ -8,11 +8,11 @@ import ( "testing" "time" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/finality/keeper/tallying_test.go b/x/finality/keeper/tallying_test.go index 6605afc50..881985136 100644 --- a/x/finality/keeper/tallying_test.go +++ b/x/finality/keeper/tallying_test.go @@ -5,12 +5,12 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" diff --git a/x/finality/keeper/votes.go b/x/finality/keeper/votes.go index ffc13a8dc..8014fa751 100644 --- a/x/finality/keeper/votes.go +++ b/x/finality/keeper/votes.go @@ -7,8 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "cosmossdk.io/store/prefix" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/keeper/votes_bench_test.go b/x/finality/keeper/votes_bench_test.go index ec35ffcdc..2f78a75c4 100644 --- a/x/finality/keeper/votes_bench_test.go +++ b/x/finality/keeper/votes_bench_test.go @@ -8,11 +8,11 @@ import ( "time" "cosmossdk.io/core/header" - "github.com/babylonchain/babylon/testutil/datagen" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/finality/module.go b/x/finality/module.go index 81a1f8df0..1ab4e359e 100644 --- a/x/finality/module.go +++ b/x/finality/module.go @@ -11,9 +11,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/finality/client/cli" - "github.com/babylonchain/babylon/x/finality/keeper" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/client/cli" + "github.com/babylonlabs-io/babylon/x/finality/keeper" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/finality/types/events.go b/x/finality/types/events.go index 6e16582b4..6c6f400ca 100644 --- a/x/finality/types/events.go +++ b/x/finality/types/events.go @@ -1,6 +1,6 @@ package types -import "github.com/babylonchain/babylon/types" +import "github.com/babylonlabs-io/babylon/types" func NewEventSlashedFinalityProvider(evidence *Evidence) *EventSlashedFinalityProvider { return &EventSlashedFinalityProvider{ diff --git a/x/finality/types/events.pb.go b/x/finality/types/events.pb.go index 1f7fdd4b7..b6d9a35f6 100644 --- a/x/finality/types/events.pb.go +++ b/x/finality/types/events.pb.go @@ -172,7 +172,7 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/events.proto", fileDescriptor_c34c03aae5e3e6bf) } var fileDescriptor_c34c03aae5e3e6bf = []byte{ - // 250 bytes of a gzipped FileDescriptorProto + // 252 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0x4f, 0xcb, 0xcc, 0x4b, 0xcc, 0xc9, 0x2c, 0xa9, 0xd4, 0x2f, 0x33, 0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x86, 0xaa, @@ -183,12 +183,12 @@ var fileDescriptor_c34c03aae5e3e6bf = []byte{ 0x51, 0x10, 0x5c, 0xb9, 0x92, 0x1b, 0x97, 0x2a, 0xd4, 0xe8, 0xd2, 0xf4, 0xf4, 0xcc, 0xe2, 0x0c, 0x74, 0xb3, 0x5d, 0x52, 0x4b, 0x52, 0x93, 0x4b, 0x52, 0x53, 0x84, 0x64, 0xb9, 0xb8, 0x0a, 0x4a, 0x93, 0x72, 0x32, 0x93, 0xe3, 0xb3, 0x53, 0x2b, 0xc1, 0xb6, 0x70, 0x06, 0x71, 0x42, 0x44, 0xbc, - 0x53, 0x2b, 0x09, 0x9a, 0x13, 0x94, 0x5a, 0x96, 0x5a, 0x44, 0xd8, 0x1c, 0x27, 0xaf, 0x13, 0x8f, + 0x53, 0x2b, 0x09, 0x9a, 0x13, 0x94, 0x5a, 0x96, 0x5a, 0x44, 0xd8, 0x1c, 0x27, 0x9f, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, - 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, - 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x7a, 0x2e, 0x39, 0x23, 0x31, 0x33, 0x0f, 0xc6, 0xd1, 0xaf, 0x40, - 0x04, 0x61, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xf4, 0x8c, 0x01, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x62, 0xf7, 0x2c, 0xf5, 0x9a, 0x01, 0x00, 0x00, + 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x7a, 0x2e, 0x27, 0x31, 0xa9, 0x58, 0x37, 0x33, 0x1f, 0xc6, 0xd5, + 0xaf, 0x40, 0x04, 0x62, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0xfc, 0x8c, 0x01, 0x01, + 0x00, 0x00, 0xff, 0xff, 0x58, 0x3c, 0x4f, 0x58, 0x9c, 0x01, 0x00, 0x00, } func (m *EventSlashedFinalityProvider) Marshal() (dAtA []byte, err error) { diff --git a/x/finality/types/expected_keepers.go b/x/finality/types/expected_keepers.go index 1be3bdab0..f4d6e58d9 100644 --- a/x/finality/types/expected_keepers.go +++ b/x/finality/types/expected_keepers.go @@ -3,8 +3,8 @@ package types import ( "context" - bbn "github.com/babylonchain/babylon/types" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" + bbn "github.com/babylonlabs-io/babylon/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" ) type BTCStakingKeeper interface { diff --git a/x/finality/types/finality.go b/x/finality/types/finality.go index 9c40441a9..1338273cf 100644 --- a/x/finality/types/finality.go +++ b/x/finality/types/finality.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" - "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/crypto/eots" "github.com/btcsuite/btcd/btcec/v2" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/finality/types/finality.pb.go b/x/finality/types/finality.pb.go index 466fe2bd9..8d2eb5f4b 100644 --- a/x/finality/types/finality.pb.go +++ b/x/finality/types/finality.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -160,11 +160,11 @@ func (m *PubRandCommit) GetCommitment() []byte { // signatures with correct public randomness on two conflicting Babylon headers type Evidence struct { // fp_btc_pk is the BTC PK of the finality provider that casts this vote - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // block_height is the height of the conflicting blocks BlockHeight uint64 `protobuf:"varint,2,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` // pub_rand is the public randomness the finality provider has committed to - PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` + PubRand *github_com_babylonlabs_io_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` // canonical_app_hash is the AppHash of the canonical block CanonicalAppHash []byte `protobuf:"bytes,4,opt,name=canonical_app_hash,json=canonicalAppHash,proto3" json:"canonical_app_hash,omitempty"` // fork_app_hash is the AppHash of the fork block @@ -173,10 +173,10 @@ type Evidence struct { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - CanonicalFinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,6,opt,name=canonical_finality_sig,json=canonicalFinalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"canonical_finality_sig,omitempty"` + CanonicalFinalitySig *github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig `protobuf:"bytes,6,opt,name=canonical_finality_sig,json=canonicalFinalitySig,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" json:"canonical_finality_sig,omitempty"` // fork_finality_sig is the finality signature to the fork block // where finality signature is an EOTS signature - ForkFinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,7,opt,name=fork_finality_sig,json=forkFinalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"fork_finality_sig,omitempty"` + ForkFinalitySig *github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig `protobuf:"bytes,7,opt,name=fork_finality_sig,json=forkFinalitySig,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" json:"fork_finality_sig,omitempty"` } func (m *Evidence) Reset() { *m = Evidence{} } @@ -237,7 +237,7 @@ func (m *Evidence) GetForkAppHash() []byte { // liveness activity. type FinalityProviderSigningInfo struct { // fp_btc_pk is the BTC PK of the finality provider that casts this vote - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // start_height is the block height at which finality provider become active StartHeight int64 `protobuf:"varint,2,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` // missed_blocks_counter defines a counter to avoid unnecessary array reads. @@ -304,41 +304,41 @@ func init() { } var fileDescriptor_ca5b87e52e3e6d02 = []byte{ - // 533 bytes of a gzipped FileDescriptorProto + // 539 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x30, - 0x18, 0x6e, 0x68, 0x69, 0x3b, 0x37, 0x13, 0x90, 0x8d, 0xa9, 0x7c, 0x28, 0x2b, 0x39, 0xf5, 0x80, - 0xda, 0x7d, 0x09, 0x71, 0x25, 0xd3, 0xd0, 0x0a, 0x07, 0x2a, 0x87, 0x13, 0x17, 0xcb, 0x71, 0xdc, - 0xc4, 0x6a, 0x63, 0x5b, 0x89, 0x53, 0xad, 0xfc, 0x0a, 0x7e, 0xd6, 0x8e, 0x3b, 0xa2, 0x1d, 0x26, - 0xd4, 0xfe, 0x0f, 0x84, 0xe2, 0xa4, 0xe9, 0x7a, 0x02, 0x81, 0xb8, 0xc5, 0xef, 0xfb, 0xea, 0xf9, - 0x78, 0xfd, 0x38, 0xc0, 0xf1, 0xb1, 0xbf, 0x98, 0x09, 0x3e, 0x9c, 0x30, 0x8e, 0x67, 0x4c, 0x2d, - 0x86, 0xf3, 0xe3, 0xea, 0x7b, 0x20, 0x13, 0xa1, 0x84, 0xb5, 0x57, 0xce, 0x0c, 0xaa, 0xfa, 0xfc, - 0xf8, 0xf9, 0x7e, 0x28, 0x42, 0xa1, 0xfb, 0xc3, 0xfc, 0xab, 0x18, 0x75, 0x10, 0x30, 0x47, 0x3c, - 0xa0, 0x57, 0x34, 0x70, 0x67, 0x82, 0x4c, 0xad, 0x03, 0xd0, 0x8c, 0x28, 0x0b, 0x23, 0xd5, 0x35, - 0x7a, 0x46, 0xbf, 0x01, 0xcb, 0x93, 0xf5, 0x0c, 0xb4, 0xb1, 0x94, 0x28, 0xc2, 0x69, 0xd4, 0x7d, - 0xd0, 0x33, 0xfa, 0x26, 0x6c, 0x61, 0x29, 0x2f, 0x71, 0x1a, 0x59, 0x2f, 0xc1, 0x4e, 0xc1, 0xf3, - 0x95, 0x06, 0xdd, 0x7a, 0xcf, 0xe8, 0xb7, 0xe1, 0xa6, 0xe0, 0x28, 0xb0, 0x3b, 0xce, 0x7c, 0x88, - 0x79, 0x70, 0x2e, 0xe2, 0x98, 0x29, 0xeb, 0x15, 0x30, 0x53, 0x85, 0x13, 0x85, 0xb6, 0x78, 0x3a, - 0xba, 0x76, 0x59, 0x90, 0xf5, 0x80, 0xc9, 0xb3, 0x18, 0xc9, 0xcc, 0x47, 0x09, 0xe6, 0x81, 0x26, - 0x6c, 0x40, 0xc0, 0xb3, 0xb8, 0x84, 0xb2, 0x6c, 0x00, 0x88, 0x86, 0x8b, 0x29, 0x57, 0x9a, 0xd4, - 0x84, 0xf7, 0x2a, 0xce, 0xcf, 0x3a, 0x68, 0x5f, 0xcc, 0x59, 0x40, 0x39, 0xa1, 0x16, 0x04, 0x3b, - 0x13, 0x89, 0x7c, 0x45, 0x90, 0x9c, 0x6a, 0x3a, 0xd3, 0x7d, 0x73, 0x7b, 0x77, 0x78, 0x12, 0x32, - 0x15, 0x65, 0xfe, 0x80, 0x88, 0x78, 0x58, 0x2e, 0x8c, 0x44, 0x98, 0xf1, 0xf5, 0x61, 0xa8, 0x16, - 0x92, 0xa6, 0x03, 0x77, 0x34, 0x3e, 0x3d, 0x3b, 0x1a, 0x67, 0xfe, 0x47, 0xba, 0x80, 0xad, 0x89, - 0x74, 0x15, 0x19, 0x4f, 0x73, 0x17, 0x7e, 0xbe, 0xb0, 0xb5, 0x8b, 0x42, 0x62, 0x47, 0xd7, 0x4a, - 0x17, 0x1e, 0x68, 0x57, 0x0e, 0xb4, 0x42, 0xf7, 0xed, 0xed, 0xdd, 0xe1, 0xd9, 0x9f, 0xb1, 0x7a, - 0x24, 0xe2, 0x22, 0x49, 0x4a, 0xbf, 0xb0, 0x25, 0x4b, 0xe3, 0xaf, 0x81, 0x45, 0x30, 0x17, 0x9c, - 0x11, 0x3c, 0x43, 0xd5, 0x8d, 0x34, 0xf4, 0x02, 0x1e, 0x57, 0x9d, 0x77, 0xe5, 0xd5, 0x38, 0x60, - 0x77, 0x22, 0x92, 0xe9, 0x66, 0xf0, 0xa1, 0x1e, 0xec, 0xe4, 0xc5, 0xf5, 0x0c, 0x07, 0x07, 0x1b, - 0xc4, 0x75, 0x60, 0x50, 0xca, 0xc2, 0x6e, 0xf3, 0x2f, 0x45, 0x5f, 0x7c, 0xfa, 0xec, 0x79, 0x2c, - 0x84, 0xfb, 0x15, 0xee, 0xfb, 0x12, 0xd6, 0x63, 0xa1, 0x15, 0x80, 0x27, 0x5a, 0xd3, 0x16, 0x55, - 0xeb, 0x1f, 0xa9, 0x1e, 0xe5, 0x90, 0xf7, 0x58, 0x9c, 0x6b, 0x03, 0xbc, 0x58, 0x9f, 0xc7, 0x89, - 0xc8, 0xa3, 0x90, 0x78, 0x2c, 0xe4, 0x8c, 0x87, 0x23, 0x3e, 0x11, 0xff, 0x2b, 0x13, 0x5b, 0xc9, - 0xce, 0x33, 0x51, 0xdf, 0x4e, 0xf6, 0x09, 0x78, 0x1a, 0xb3, 0x34, 0xa5, 0x01, 0xd2, 0x49, 0x49, - 0x11, 0x11, 0x19, 0x57, 0x34, 0xd1, 0x01, 0xa9, 0xc3, 0xbd, 0xa2, 0xa9, 0x9f, 0x62, 0x7a, 0x5e, - 0xb4, 0xdc, 0x0f, 0xd7, 0x4b, 0xdb, 0xb8, 0x59, 0xda, 0xc6, 0x8f, 0xa5, 0x6d, 0x7c, 0x5b, 0xd9, - 0xb5, 0x9b, 0x95, 0x5d, 0xfb, 0xbe, 0xb2, 0x6b, 0x5f, 0x8e, 0x7e, 0xa7, 0xf6, 0x6a, 0xf3, 0x97, - 0xd0, 0xc2, 0xfd, 0xa6, 0x7e, 0xf5, 0xa7, 0xbf, 0x02, 0x00, 0x00, 0xff, 0xff, 0xd3, 0x32, 0x14, - 0xff, 0x46, 0x04, 0x00, 0x00, + 0x18, 0x6e, 0x68, 0x69, 0x3b, 0x37, 0x13, 0x90, 0x8d, 0xa9, 0x7c, 0x28, 0x2b, 0x39, 0xf5, 0x00, + 0x2d, 0xfb, 0x10, 0x42, 0xdc, 0xc8, 0x34, 0xb4, 0x0a, 0x24, 0xaa, 0x74, 0x5c, 0xb8, 0x58, 0x4e, + 0xe2, 0x24, 0x56, 0x1b, 0xdb, 0x8a, 0x9d, 0x6a, 0xe5, 0x07, 0x70, 0xe6, 0x67, 0x21, 0x4e, 0x3b, + 0xa2, 0x1d, 0x26, 0xd4, 0xfe, 0x11, 0x14, 0xe7, 0xa3, 0xeb, 0x09, 0x04, 0xda, 0x2d, 0x7e, 0xdf, + 0x57, 0xcf, 0xc7, 0xeb, 0x27, 0x06, 0x96, 0x8b, 0xdc, 0xc5, 0x8c, 0xd1, 0x61, 0x40, 0x28, 0x9a, + 0x11, 0xb9, 0x18, 0xce, 0x0f, 0xaa, 0xef, 0x01, 0x4f, 0x98, 0x64, 0xc6, 0x4e, 0x31, 0x33, 0xa8, + 0xea, 0xf3, 0x83, 0xc7, 0xbb, 0x21, 0x0b, 0x99, 0xea, 0x0f, 0xb3, 0xaf, 0x7c, 0xd4, 0x82, 0x40, + 0x1f, 0x51, 0x1f, 0x5f, 0x60, 0xdf, 0x9e, 0x31, 0x6f, 0x6a, 0xec, 0x81, 0x66, 0x84, 0x49, 0x18, + 0xc9, 0xae, 0xd6, 0xd3, 0xfa, 0x0d, 0xa7, 0x38, 0x19, 0x8f, 0x40, 0x1b, 0x71, 0x0e, 0x23, 0x24, + 0xa2, 0xee, 0x9d, 0x9e, 0xd6, 0xd7, 0x9d, 0x16, 0xe2, 0xfc, 0x0c, 0x89, 0xc8, 0x78, 0x0a, 0xb6, + 0x72, 0x9e, 0x2f, 0xd8, 0xef, 0xd6, 0x7b, 0x5a, 0xbf, 0xed, 0xac, 0x0b, 0x96, 0x04, 0xdb, 0xe3, + 0xd4, 0x75, 0x10, 0xf5, 0x4f, 0x58, 0x1c, 0x13, 0x69, 0x3c, 0x03, 0xba, 0x90, 0x28, 0x91, 0x70, + 0x83, 0xa7, 0xa3, 0x6a, 0x67, 0x39, 0x59, 0x0f, 0xe8, 0x34, 0x8d, 0x21, 0x4f, 0x5d, 0x98, 0x20, + 0xea, 0x2b, 0xc2, 0x86, 0x03, 0x68, 0x1a, 0x17, 0x50, 0x86, 0x09, 0x80, 0xa7, 0xe0, 0x62, 0x4c, + 0xa5, 0x22, 0xd5, 0x9d, 0x1b, 0x15, 0xeb, 0x6b, 0x03, 0xb4, 0x4f, 0xe7, 0xc4, 0xc7, 0xd4, 0xc3, + 0xc6, 0x39, 0xd8, 0x0a, 0x38, 0x74, 0xa5, 0x07, 0xf9, 0x54, 0xd1, 0xe9, 0xf6, 0xeb, 0xab, 0xeb, + 0xfd, 0xe3, 0x90, 0xc8, 0x28, 0x75, 0x07, 0x1e, 0x8b, 0x87, 0xc5, 0xc2, 0x66, 0xc8, 0x15, 0x2f, + 0x08, 0x2b, 0x8f, 0x43, 0xb9, 0xe0, 0x58, 0x0c, 0xec, 0xd1, 0xf8, 0xe8, 0xf8, 0xe5, 0x38, 0x75, + 0xdf, 0xe3, 0x85, 0xd3, 0x0a, 0xb8, 0x2d, 0xbd, 0xf1, 0x34, 0xf3, 0xe1, 0x66, 0x2b, 0x2b, 0x7d, + 0xe4, 0x22, 0x3b, 0xaa, 0x56, 0xf8, 0xf8, 0x04, 0xda, 0x95, 0x07, 0xa5, 0xd1, 0x7e, 0x73, 0x75, + 0xbd, 0xff, 0xea, 0x6f, 0x79, 0x27, 0x5e, 0x44, 0x59, 0x92, 0x14, 0x9e, 0x9d, 0x16, 0x2f, 0xcc, + 0x3f, 0x07, 0x86, 0x87, 0x28, 0xa3, 0xc4, 0x43, 0x33, 0x58, 0xdd, 0x4a, 0x43, 0x2d, 0xe1, 0x7e, + 0xd5, 0x79, 0x5b, 0x5c, 0x8f, 0x05, 0xb6, 0x03, 0x96, 0x4c, 0xd7, 0x83, 0x77, 0xd5, 0x60, 0x27, + 0x2b, 0x96, 0x33, 0x1c, 0xec, 0xad, 0x11, 0xcb, 0xd0, 0x40, 0x41, 0xc2, 0x6e, 0xf3, 0x9f, 0x65, + 0x9f, 0x7e, 0x3c, 0x9f, 0x4c, 0x48, 0xe8, 0xec, 0x56, 0xc8, 0xef, 0x0a, 0xe0, 0x09, 0x09, 0x8d, + 0x00, 0x3c, 0x50, 0xaa, 0x36, 0xc8, 0x5a, 0xff, 0x4d, 0x76, 0x2f, 0x03, 0xbd, 0xc1, 0x63, 0xfd, + 0xd0, 0xc0, 0x93, 0xf2, 0x3c, 0x4e, 0x58, 0x16, 0x89, 0x64, 0x42, 0x42, 0x4a, 0x68, 0x38, 0xa2, + 0x01, 0xbb, 0xbd, 0x6c, 0x6c, 0x64, 0x3c, 0xcb, 0x46, 0x7d, 0x33, 0xe3, 0x87, 0xe0, 0x61, 0x4c, + 0x84, 0xc0, 0x3e, 0x54, 0x89, 0x11, 0xd0, 0x63, 0x29, 0x95, 0x38, 0x51, 0x41, 0xa9, 0x3b, 0x3b, + 0x79, 0x53, 0xfd, 0x94, 0xe2, 0x24, 0x6f, 0xd9, 0x1f, 0xbe, 0x2f, 0x4d, 0xed, 0x72, 0x69, 0x6a, + 0xbf, 0x96, 0xa6, 0xf6, 0x6d, 0x65, 0xd6, 0x2e, 0x57, 0x66, 0xed, 0xe7, 0xca, 0xac, 0x7d, 0x3e, + 0xfc, 0xb3, 0xde, 0x8b, 0xf5, 0x8b, 0xa1, 0xa4, 0xbb, 0x4d, 0xf5, 0x02, 0x1c, 0xfd, 0x0e, 0x00, + 0x00, 0xff, 0xff, 0xb1, 0x31, 0x31, 0x81, 0x52, 0x04, 0x00, 0x00, } func (m *IndexedBlock) Marshal() (dAtA []byte, err error) { @@ -974,7 +974,7 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1028,7 +1028,7 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrPubRand + var v github_com_babylonlabs_io_babylon_types.SchnorrPubRand m.PubRand = &v if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1131,7 +1131,7 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrEOTSSig + var v github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig m.CanonicalFinalitySig = &v if err := m.CanonicalFinalitySig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1166,7 +1166,7 @@ func (m *Evidence) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrEOTSSig + var v github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig m.ForkFinalitySig = &v if err := m.ForkFinalitySig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1251,7 +1251,7 @@ func (m *FinalityProviderSigningInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/finality/types/genesis.pb.go b/x/finality/types/genesis.pb.go index 596eaf57b..6707ca5ab 100644 --- a/x/finality/types/genesis.pb.go +++ b/x/finality/types/genesis.pb.go @@ -5,7 +5,7 @@ package types import ( fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" io "io" @@ -141,10 +141,10 @@ type VoteSig struct { // block_height is the height of the voted block. BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` // fp_btc_pk is the BTC PK of the finality provider that casts this vote - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // finality_sig is the finality signature to this block // where finality signature is an EOTS signature, i.e. - FinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,3,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` + FinalitySig *github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig `protobuf:"bytes,3,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` } func (m *VoteSig) Reset() { *m = VoteSig{} } @@ -192,9 +192,9 @@ type PublicRandomness struct { // block_height is the height of block which the finality provider submited public randomness. BlockHeight uint64 `protobuf:"varint,1,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` // fp_btc_pk is the BTC PK of the finality provider that casts this vote. - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // pub_rand is the public randomness the finality provider has committed to. - PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` + PubRand *github_com_babylonlabs_io_babylon_types.SchnorrPubRand `protobuf:"bytes,3,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` } func (m *PublicRandomness) Reset() { *m = PublicRandomness{} } @@ -240,7 +240,7 @@ func (m *PublicRandomness) GetBlockHeight() uint64 { // PubRandCommitWithPK is the public randomness commitment with the finality provider's BTC public key type PubRandCommitWithPK struct { // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // pub_rand_commit is the public randomness commitment PubRandCommit *PubRandCommit `protobuf:"bytes,2,opt,name=pub_rand_commit,json=pubRandCommit,proto3" json:"pub_rand_commit,omitempty"` } @@ -288,7 +288,7 @@ func (m *PubRandCommitWithPK) GetPubRandCommit() *PubRandCommit { // SigningInfo stores finality provider signing info of corresponding BTC public key. type SigningInfo struct { // fp_btc_pk is the BTC PK of the finality provider - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // fp_signing_info represents the signing info of this finality provider. FpSigningInfo FinalityProviderSigningInfo `protobuf:"bytes,2,opt,name=fp_signing_info,json=fpSigningInfo,proto3" json:"fp_signing_info"` } @@ -337,7 +337,7 @@ func (m *SigningInfo) GetFpSigningInfo() FinalityProviderSigningInfo { // BTC public key. type FinalityProviderMissedBlocks struct { // fp_btc_pk is the BTC PK of the finality provider - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // missed_blocks is an array of missed blocks by the finality provider. MissedBlocks []MissedBlock `protobuf:"bytes,2,rep,name=missed_blocks,json=missedBlocks,proto3" json:"missed_blocks"` } @@ -450,51 +450,51 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/genesis.proto", fileDescriptor_52dc577f74d797d1) } var fileDescriptor_52dc577f74d797d1 = []byte{ - // 689 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0x5f, 0x6b, 0xdb, 0x3c, - 0x14, 0xc6, 0xe3, 0x24, 0x4d, 0x52, 0x25, 0x79, 0xdb, 0x57, 0x2d, 0x2f, 0xa6, 0x6f, 0x97, 0xa6, - 0x86, 0x41, 0xae, 0x9c, 0xfe, 0x63, 0xac, 0xf4, 0x2e, 0xa3, 0x5b, 0xdb, 0x30, 0x66, 0xe4, 0xb1, - 0xc1, 0x36, 0x66, 0x6c, 0x47, 0x76, 0x44, 0x63, 0xcb, 0x58, 0x4a, 0x68, 0xbe, 0xc5, 0xbe, 0xcc, - 0xae, 0xc7, 0xee, 0x7a, 0xd9, 0xcb, 0x51, 0xb6, 0x30, 0xda, 0x2f, 0x32, 0x22, 0x3b, 0x8d, 0x97, - 0x7a, 0x6d, 0x19, 0x2b, 0xbb, 0x93, 0x4e, 0x9e, 0xf3, 0xcb, 0x39, 0xd2, 0x73, 0x64, 0xb0, 0x6e, - 0x99, 0xd6, 0xb0, 0x47, 0xfd, 0xa6, 0x43, 0x7c, 0xb3, 0x47, 0xf8, 0xb0, 0x39, 0xd8, 0x6c, 0xba, - 0xd8, 0xc7, 0x8c, 0x30, 0x35, 0x08, 0x29, 0xa7, 0x70, 0x29, 0x96, 0xa8, 0x13, 0x89, 0x3a, 0xd8, - 0x5c, 0x59, 0x76, 0xa9, 0x4b, 0xc5, 0xef, 0xcd, 0xf1, 0x2a, 0x92, 0xae, 0xd4, 0xd3, 0x68, 0x81, - 0x19, 0x9a, 0x5e, 0x0c, 0x5b, 0x51, 0xd2, 0x14, 0x57, 0x60, 0xa1, 0x51, 0xbe, 0xe6, 0x41, 0xe5, - 0x59, 0x54, 0x82, 0xce, 0x4d, 0x8e, 0xe1, 0x2e, 0x28, 0x44, 0x10, 0x59, 0xaa, 0x4b, 0x8d, 0xf2, - 0xd6, 0xff, 0x6a, 0x4a, 0x49, 0xaa, 0x26, 0x24, 0xad, 0xfc, 0xe9, 0x68, 0x2d, 0x83, 0xe2, 0x04, - 0x78, 0x00, 0xfe, 0x21, 0x7e, 0x07, 0x9f, 0xe0, 0x8e, 0x61, 0xf5, 0xa8, 0x7d, 0xcc, 0xe4, 0x6c, - 0x3d, 0xd7, 0x28, 0x6f, 0xad, 0xa7, 0x22, 0x0e, 0x23, 0x69, 0x6b, 0xac, 0x44, 0x55, 0x92, 0xd8, - 0x31, 0xb8, 0x07, 0xe6, 0xf1, 0x80, 0x74, 0xb0, 0x6f, 0x63, 0x26, 0xe7, 0x04, 0xe4, 0x41, 0x2a, - 0x64, 0x3f, 0x56, 0xa1, 0xa9, 0x1e, 0xee, 0x82, 0xf9, 0x01, 0xe5, 0xd8, 0x60, 0xc4, 0x65, 0x72, - 0x5e, 0x24, 0xaf, 0xa6, 0x26, 0xbf, 0xa2, 0x1c, 0xeb, 0xc4, 0x45, 0xa5, 0x41, 0xb4, 0x60, 0x10, - 0x81, 0x7f, 0x83, 0xbe, 0xd5, 0x23, 0xb6, 0x11, 0x9a, 0x7e, 0x87, 0x7a, 0x3e, 0x66, 0x4c, 0x9e, - 0x13, 0x88, 0x87, 0xe9, 0xe7, 0x20, 0xd4, 0xe8, 0x4a, 0x8c, 0x16, 0x83, 0x99, 0x08, 0xd4, 0xc0, - 0x42, 0xd0, 0xb7, 0x04, 0xd0, 0xb0, 0xa9, 0xe7, 0x11, 0x2e, 0x17, 0x04, 0xb1, 0xf1, 0x2b, 0xe2, - 0x38, 0xf9, 0x89, 0x50, 0xbe, 0x26, 0xbc, 0xab, 0xb5, 0x51, 0x35, 0x48, 0x06, 0x61, 0x1b, 0x54, - 0x19, 0x71, 0x7d, 0xe2, 0xbb, 0x06, 0xf1, 0x1d, 0xca, 0xe4, 0xa2, 0xe0, 0xd5, 0x53, 0x79, 0x7a, - 0xa4, 0x3c, 0xf4, 0x1d, 0x1a, 0x5f, 0x57, 0x85, 0x4d, 0x43, 0x0c, 0xbe, 0x03, 0x55, 0x8f, 0x30, - 0x36, 0xbd, 0xb3, 0x92, 0x80, 0x6d, 0xa6, 0xc2, 0x9e, 0xc6, 0x6b, 0x2d, 0xa4, 0xe3, 0xe3, 0x0e, - 0x9f, 0x8b, 0xcc, 0xe8, 0xd2, 0x26, 0x74, 0x2f, 0x11, 0x53, 0xbe, 0x49, 0xa0, 0x18, 0x1f, 0x33, - 0x5c, 0x07, 0x15, 0xf1, 0x17, 0x46, 0x17, 0x13, 0xb7, 0xcb, 0x85, 0xbf, 0xf2, 0xa8, 0x2c, 0x62, - 0x07, 0x22, 0x04, 0x11, 0x98, 0x77, 0x02, 0xc3, 0xe2, 0xb6, 0x11, 0x1c, 0xcb, 0xd9, 0xba, 0xd4, - 0xa8, 0xb4, 0x1e, 0x9d, 0x8f, 0xd6, 0xb6, 0x5c, 0xc2, 0xbb, 0x7d, 0x4b, 0xb5, 0xa9, 0xd7, 0x8c, - 0xcb, 0xb2, 0xbb, 0x26, 0xf1, 0x27, 0x9b, 0x26, 0x1f, 0x06, 0x98, 0xa9, 0xad, 0x43, 0x6d, 0x7b, - 0x67, 0x43, 0xeb, 0x5b, 0x6d, 0x3c, 0x44, 0x45, 0x27, 0x68, 0x71, 0x5b, 0x3b, 0x86, 0x6f, 0x41, - 0x65, 0xd2, 0xc2, 0xd8, 0x12, 0x72, 0x4e, 0x60, 0x1f, 0x9f, 0x8f, 0xd6, 0x76, 0xee, 0x86, 0xd5, - 0xed, 0xae, 0x4f, 0xc3, 0x70, 0xff, 0xc5, 0x4b, 0x7d, 0xec, 0x96, 0xf2, 0x84, 0xa6, 0x13, 0x57, - 0x19, 0x49, 0x60, 0x71, 0xd6, 0x03, 0x7f, 0xab, 0x51, 0x1d, 0x94, 0x26, 0x46, 0xfb, 0xed, 0x26, - 0x63, 0xf7, 0xa1, 0x62, 0xec, 0x38, 0xe5, 0xa3, 0x04, 0x96, 0x52, 0x2c, 0xf9, 0x73, 0x03, 0xd2, - 0x9f, 0x69, 0xe0, 0xe8, 0xfa, 0xa4, 0x64, 0xc5, 0x1b, 0xa4, 0xdc, 0x3e, 0x29, 0x33, 0x33, 0xa2, - 0x7c, 0x96, 0x40, 0x39, 0x61, 0xfd, 0x7b, 0xa9, 0xf7, 0x3d, 0x58, 0x70, 0x02, 0x23, 0x39, 0x8a, - 0x71, 0xbd, 0x1b, 0x77, 0x1a, 0x9e, 0xeb, 0x93, 0x59, 0x75, 0x82, 0x44, 0x50, 0xf9, 0x24, 0x81, - 0xd5, 0x9b, 0x26, 0xee, 0x5e, 0x9a, 0x6a, 0xcf, 0xbe, 0x07, 0xd9, 0x1b, 0x1e, 0x97, 0x44, 0x35, - 0xa9, 0xe3, 0xbf, 0x07, 0xca, 0x09, 0x09, 0x5c, 0x06, 0x73, 0xe2, 0x9d, 0x17, 0xb5, 0xe6, 0x50, - 0xb4, 0x81, 0xff, 0x81, 0x42, 0x94, 0x24, 0x4e, 0xaf, 0x84, 0xe2, 0x5d, 0xeb, 0xe8, 0xf4, 0xa2, - 0x26, 0x9d, 0x5d, 0xd4, 0xa4, 0xef, 0x17, 0x35, 0xe9, 0xc3, 0x65, 0x2d, 0x73, 0x76, 0x59, 0xcb, - 0x7c, 0xb9, 0xac, 0x65, 0xde, 0x6c, 0xdc, 0xd6, 0xe0, 0xc9, 0xf4, 0x93, 0x27, 0x7a, 0xb5, 0x0a, - 0xe2, 0x6b, 0xb7, 0xfd, 0x23, 0x00, 0x00, 0xff, 0xff, 0x2a, 0x93, 0x7e, 0xf6, 0x83, 0x07, 0x00, - 0x00, + // 693 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x95, 0xcf, 0x6f, 0xd3, 0x4a, + 0x10, 0xc7, 0xe3, 0x24, 0x4d, 0xd2, 0x4d, 0xf2, 0xda, 0xb7, 0xad, 0x9e, 0xac, 0xbe, 0x92, 0xa6, + 0x96, 0x90, 0x72, 0xc1, 0xe9, 0x2f, 0x21, 0x4a, 0x6f, 0x41, 0x85, 0x96, 0x80, 0xb0, 0x36, 0x05, + 0x24, 0x04, 0x58, 0xb6, 0xb3, 0x76, 0x56, 0x8d, 0xbd, 0x96, 0x77, 0x13, 0x35, 0xff, 0x05, 0xff, + 0x0d, 0x67, 0xc4, 0xa5, 0xc7, 0x1e, 0x51, 0x85, 0x2a, 0x48, 0xff, 0x11, 0x94, 0xb5, 0xd3, 0x98, + 0xd4, 0xb4, 0x95, 0xa0, 0xe2, 0xb6, 0x3b, 0xf9, 0xce, 0x27, 0x33, 0xb3, 0x33, 0x63, 0xb0, 0x6a, + 0x1a, 0xe6, 0xa0, 0x4b, 0xbd, 0xba, 0x4d, 0x3c, 0xa3, 0x4b, 0xf8, 0xa0, 0xde, 0x5f, 0xaf, 0x3b, + 0xd8, 0xc3, 0x8c, 0x30, 0xd5, 0x0f, 0x28, 0xa7, 0x70, 0x21, 0x92, 0xa8, 0x63, 0x89, 0xda, 0x5f, + 0x5f, 0x5a, 0x74, 0xa8, 0x43, 0xc5, 0xef, 0xf5, 0xd1, 0x29, 0x94, 0x2e, 0x55, 0x93, 0x68, 0xbe, + 0x11, 0x18, 0x6e, 0x04, 0x5b, 0x52, 0x92, 0x14, 0x17, 0x60, 0xa1, 0x51, 0xbe, 0x66, 0x41, 0xe9, + 0x49, 0x18, 0x42, 0x8b, 0x1b, 0x1c, 0xc3, 0x6d, 0x90, 0x0b, 0x21, 0xb2, 0x54, 0x95, 0x6a, 0xc5, + 0x8d, 0xff, 0xd5, 0x84, 0x90, 0x54, 0x4d, 0x48, 0x1a, 0xd9, 0xe3, 0xb3, 0x95, 0x14, 0x8a, 0x1c, + 0xe0, 0x1e, 0xf8, 0x87, 0x78, 0x6d, 0x7c, 0x84, 0xdb, 0xba, 0xd9, 0xa5, 0xd6, 0x21, 0x93, 0xd3, + 0xd5, 0x4c, 0xad, 0xb8, 0xb1, 0x9a, 0x88, 0xd8, 0x0f, 0xa5, 0x8d, 0x91, 0x12, 0x95, 0x49, 0xec, + 0xc6, 0xe0, 0x0e, 0x98, 0xc5, 0x7d, 0xd2, 0xc6, 0x9e, 0x85, 0x99, 0x9c, 0x11, 0x90, 0x3b, 0x89, + 0x90, 0xdd, 0x48, 0x85, 0x26, 0x7a, 0xb8, 0x0d, 0x66, 0xfb, 0x94, 0x63, 0x9d, 0x11, 0x87, 0xc9, + 0x59, 0xe1, 0xbc, 0x9c, 0xe8, 0xfc, 0x8a, 0x72, 0xdc, 0x22, 0x0e, 0x2a, 0xf4, 0xc3, 0x03, 0x83, + 0x08, 0xfc, 0xeb, 0xf7, 0xcc, 0x2e, 0xb1, 0xf4, 0xc0, 0xf0, 0xda, 0xd4, 0xf5, 0x30, 0x63, 0xf2, + 0x8c, 0x40, 0xdc, 0x4d, 0xae, 0x83, 0x50, 0xa3, 0x0b, 0x31, 0x9a, 0xf7, 0xa7, 0x2c, 0x50, 0x03, + 0x73, 0x7e, 0xcf, 0x14, 0x40, 0xdd, 0xa2, 0xae, 0x4b, 0xb8, 0x9c, 0x13, 0xc4, 0xda, 0xaf, 0x88, + 0x23, 0xe7, 0x47, 0x42, 0xf9, 0x9a, 0xf0, 0x8e, 0xd6, 0x44, 0x65, 0x3f, 0x6e, 0x84, 0x4d, 0x50, + 0x66, 0xc4, 0xf1, 0x88, 0xe7, 0xe8, 0xc4, 0xb3, 0x29, 0x93, 0xf3, 0x82, 0x57, 0x4d, 0xe4, 0xb5, + 0x42, 0xe5, 0xbe, 0x67, 0xd3, 0xe8, 0xb9, 0x4a, 0x6c, 0x62, 0x62, 0xf0, 0x2d, 0x28, 0xbb, 0x84, + 0xb1, 0xc9, 0x9b, 0x15, 0x04, 0x6c, 0x3d, 0x11, 0xf6, 0x38, 0x3a, 0x6b, 0x01, 0x1d, 0x95, 0x3b, + 0x78, 0x2e, 0x3c, 0xc3, 0x47, 0x1b, 0xd3, 0xdd, 0x98, 0x4d, 0xf9, 0x2e, 0x81, 0x7c, 0x54, 0x66, + 0xb8, 0x0a, 0x4a, 0xe2, 0x2f, 0xf4, 0x0e, 0x26, 0x4e, 0x87, 0x8b, 0xfe, 0xca, 0xa2, 0xa2, 0xb0, + 0xed, 0x09, 0x13, 0x3c, 0x00, 0xb3, 0xb6, 0xaf, 0x9b, 0xdc, 0xd2, 0xfd, 0x43, 0x39, 0x5d, 0x95, + 0x6a, 0xa5, 0xc6, 0x83, 0xd3, 0xb3, 0x95, 0x2d, 0x87, 0xf0, 0x4e, 0xcf, 0x54, 0x2d, 0xea, 0xd6, + 0xa3, 0xb0, 0xba, 0x86, 0xc9, 0xee, 0x11, 0x3a, 0xbe, 0xd6, 0xf9, 0xc0, 0xc7, 0x4c, 0x6d, 0xec, + 0x6b, 0x9b, 0x5b, 0x6b, 0x5a, 0xcf, 0x6c, 0xe2, 0x01, 0xca, 0xdb, 0x7e, 0x83, 0x5b, 0xda, 0x21, + 0x7c, 0x07, 0x4a, 0xe3, 0x24, 0x46, 0x4d, 0x21, 0x67, 0x04, 0xf8, 0xe1, 0xe9, 0xd9, 0xca, 0xfd, + 0x9b, 0x82, 0x5b, 0x56, 0xc7, 0xa3, 0x41, 0xb0, 0xfb, 0xe2, 0xa0, 0x35, 0xea, 0x98, 0xe2, 0x98, + 0xd7, 0x22, 0x8e, 0x32, 0x94, 0xc0, 0xfc, 0x74, 0x1f, 0xfc, 0xbd, 0x64, 0x5f, 0x82, 0xc2, 0xb8, + 0xdd, 0x7e, 0x23, 0xd1, 0xa8, 0x0b, 0x51, 0x3e, 0xea, 0x3c, 0xe5, 0xa3, 0x04, 0x16, 0x12, 0x5a, + 0xf3, 0xe7, 0x24, 0xa4, 0x3f, 0x95, 0xc4, 0xd3, 0xcb, 0x33, 0x93, 0x16, 0xdb, 0x48, 0xb9, 0x7e, + 0x66, 0xa6, 0xa6, 0x45, 0xf9, 0x2c, 0x81, 0x62, 0x6c, 0x08, 0x6e, 0x29, 0xe2, 0xf7, 0x60, 0xce, + 0xf6, 0xf5, 0xf8, 0x58, 0x46, 0x11, 0xaf, 0xdd, 0x68, 0x90, 0x2e, 0x4f, 0x69, 0xd9, 0xf6, 0x63, + 0x46, 0xe5, 0x93, 0x04, 0x96, 0xaf, 0x9a, 0xbe, 0x5b, 0x4a, 0xab, 0x39, 0xbd, 0x1d, 0xd2, 0x57, + 0xac, 0x9a, 0x58, 0x3c, 0x89, 0xcb, 0x60, 0x07, 0x14, 0x63, 0x12, 0xb8, 0x08, 0x66, 0xc4, 0xd6, + 0x17, 0xd1, 0x66, 0x50, 0x78, 0x81, 0xff, 0x81, 0x5c, 0xe8, 0x24, 0xea, 0x57, 0x40, 0xd1, 0xad, + 0xf1, 0xec, 0x78, 0x58, 0x91, 0x4e, 0x86, 0x15, 0xe9, 0xdb, 0xb0, 0x22, 0x7d, 0x38, 0xaf, 0xa4, + 0x4e, 0xce, 0x2b, 0xa9, 0x2f, 0xe7, 0x95, 0xd4, 0x9b, 0x8d, 0xeb, 0x53, 0x3c, 0x9a, 0x7c, 0x02, + 0x45, 0xb6, 0x66, 0x4e, 0x7c, 0xfd, 0x36, 0x7f, 0x04, 0x00, 0x00, 0xff, 0xff, 0xae, 0x0d, 0xf5, + 0xca, 0x93, 0x07, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -1485,7 +1485,7 @@ func (m *VoteSig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1520,7 +1520,7 @@ func (m *VoteSig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrEOTSSig + var v github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig m.FinalitySig = &v if err := m.FinalitySig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1624,7 +1624,7 @@ func (m *PublicRandomness) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1659,7 +1659,7 @@ func (m *PublicRandomness) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrPubRand + var v github_com_babylonlabs_io_babylon_types.SchnorrPubRand m.PubRand = &v if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1744,7 +1744,7 @@ func (m *PubRandCommitWithPK) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1865,7 +1865,7 @@ func (m *SigningInfo) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1983,7 +1983,7 @@ func (m *FinalityProviderMissedBlocks) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/finality/types/genesis_test.go b/x/finality/types/genesis_test.go index 00b8b7c3e..3b1969ff6 100644 --- a/x/finality/types/genesis_test.go +++ b/x/finality/types/genesis_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/x/finality/types" ) func TestGenesisState_Validate(t *testing.T) { diff --git a/x/finality/types/hooks.go b/x/finality/types/hooks.go index 743c6dabc..d87591ab8 100644 --- a/x/finality/types/hooks.go +++ b/x/finality/types/hooks.go @@ -3,7 +3,7 @@ package types import ( "context" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" ) // combine multiple finality hooks, all hook functions are run in array sequence diff --git a/x/finality/types/keys.go b/x/finality/types/keys.go index 532809c4b..055de21d4 100644 --- a/x/finality/types/keys.go +++ b/x/finality/types/keys.go @@ -4,7 +4,7 @@ import ( "cosmossdk.io/collections" "github.com/cosmos/cosmos-sdk/types/address" - "github.com/babylonchain/babylon/types" + "github.com/babylonlabs-io/babylon/types" ) const ( diff --git a/x/finality/types/mocked_keepers.go b/x/finality/types/mocked_keepers.go index 157edc91e..c546a68da 100644 --- a/x/finality/types/mocked_keepers.go +++ b/x/finality/types/mocked_keepers.go @@ -8,8 +8,8 @@ import ( context "context" reflect "reflect" - types "github.com/babylonchain/babylon/types" - types0 "github.com/babylonchain/babylon/x/btcstaking/types" + types "github.com/babylonlabs-io/babylon/types" + types0 "github.com/babylonlabs-io/babylon/x/btcstaking/types" gomock "github.com/golang/mock/gomock" ) diff --git a/x/finality/types/msg.go b/x/finality/types/msg.go index 7a1757f27..a92b1bbc9 100644 --- a/x/finality/types/msg.go +++ b/x/finality/types/msg.go @@ -3,7 +3,7 @@ package types import ( fmt "fmt" - "github.com/babylonchain/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/crypto/eots" "github.com/cometbft/cometbft/crypto/merkle" "github.com/cometbft/cometbft/crypto/tmhash" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/finality/types/msg_test.go b/x/finality/types/msg_test.go index 1ea69b6fa..349185828 100644 --- a/x/finality/types/msg_test.go +++ b/x/finality/types/msg_test.go @@ -4,9 +4,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/crypto/eots" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/x/finality/types" + "github.com/babylonlabs-io/babylon/crypto/eots" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/stretchr/testify/require" ) diff --git a/x/finality/types/params.pb.go b/x/finality/types/params.pb.go index cd6131dc4..cec13955b 100644 --- a/x/finality/types/params.pb.go +++ b/x/finality/types/params.pb.go @@ -101,30 +101,30 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/params.proto", fileDescriptor_25539c9a61c72ee9) } var fileDescriptor_25539c9a61c72ee9 = []byte{ - // 359 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x91, 0x31, 0x4b, 0xfb, 0x40, - 0x18, 0xc6, 0x73, 0xff, 0x96, 0x0e, 0xa1, 0xcb, 0x3f, 0x56, 0xa8, 0x15, 0xd2, 0xe0, 0x54, 0x04, - 0x73, 0x2d, 0x82, 0x83, 0x63, 0xe9, 0x24, 0x0e, 0x25, 0x15, 0x04, 0x97, 0x70, 0x49, 0xce, 0xf4, - 0xa5, 0xbd, 0xbb, 0x90, 0x4b, 0x5a, 0xf3, 0x2d, 0x1c, 0x1d, 0x1d, 0x1d, 0x1d, 0xfc, 0x10, 0x1d, - 0x8b, 0x93, 0x38, 0x14, 0x69, 0x07, 0x3f, 0x86, 0xd2, 0xbb, 0x04, 0x97, 0xe3, 0xde, 0xfb, 0x3d, - 0xef, 0x3d, 0xcf, 0xbd, 0x67, 0x3a, 0x01, 0x09, 0x8a, 0xb9, 0xe0, 0xf8, 0x1e, 0x38, 0x99, 0x43, - 0x56, 0xe0, 0xc5, 0x00, 0x27, 0x24, 0x25, 0x4c, 0xba, 0x49, 0x2a, 0x32, 0x61, 0x1d, 0x94, 0x0a, - 0xb7, 0x52, 0xb8, 0x8b, 0x41, 0xa7, 0x15, 0x8b, 0x58, 0x28, 0x8e, 0xf7, 0x3b, 0x2d, 0xed, 0xfc, - 0x27, 0x0c, 0xb8, 0xc0, 0x6a, 0x2d, 0x8f, 0x8e, 0x42, 0x21, 0x99, 0x90, 0xbe, 0xd6, 0xea, 0x42, - 0xa3, 0x93, 0x1f, 0x64, 0x36, 0xc6, 0xca, 0xc9, 0xea, 0x9b, 0x2d, 0x09, 0x31, 0xa7, 0x91, 0x1f, - 0xcc, 0x45, 0x38, 0x93, 0xfe, 0x12, 0x78, 0x24, 0x96, 0x6d, 0xe4, 0xa0, 0x5e, 0xcd, 0xb3, 0x34, - 0x1b, 0x2a, 0x74, 0xab, 0xc8, 0xbe, 0xa3, 0xca, 0xe3, 0x4b, 0x88, 0xfd, 0x0c, 0x18, 0x15, 0x79, - 0xd6, 0xfe, 0xa7, 0x3b, 0x2a, 0x36, 0x81, 0xf8, 0x46, 0x13, 0x0b, 0xcc, 0x43, 0x06, 0xdc, 0x2f, - 0x7d, 0x12, 0x9a, 0x56, 0x26, 0x35, 0x07, 0xf5, 0x9a, 0xc3, 0x8b, 0xd5, 0xa6, 0x6b, 0x7c, 0x6e, - 0xba, 0xc7, 0x3a, 0xa3, 0x8c, 0x66, 0x2e, 0x08, 0xcc, 0x48, 0x36, 0x75, 0xaf, 0x69, 0x4c, 0xc2, - 0x62, 0x44, 0xc3, 0xf7, 0xb7, 0x33, 0xb3, 0x7c, 0xc2, 0x88, 0x86, 0x2f, 0xdf, 0xaf, 0xa7, 0xc8, - 0xb3, 0x18, 0xf0, 0x89, 0xba, 0x73, 0x4c, 0xd3, 0x32, 0x9c, 0x63, 0x36, 0xf7, 0x56, 0x49, 0x1e, - 0xf8, 0x29, 0xe1, 0x51, 0xbb, 0xee, 0xa0, 0x5e, 0xdd, 0x33, 0x19, 0xf0, 0x71, 0x1e, 0x78, 0x84, - 0x47, 0x97, 0xf5, 0xa7, 0xe7, 0xae, 0x31, 0xbc, 0x5a, 0x6d, 0x6d, 0xb4, 0xde, 0xda, 0xe8, 0x6b, - 0x6b, 0xa3, 0xc7, 0x9d, 0x6d, 0xac, 0x77, 0xb6, 0xf1, 0xb1, 0xb3, 0x8d, 0xbb, 0x7e, 0x0c, 0xd9, - 0x34, 0x0f, 0xdc, 0x50, 0x30, 0x5c, 0xce, 0x3f, 0x9c, 0x12, 0xe0, 0x55, 0x81, 0x1f, 0xfe, 0x3e, - 0x2c, 0x2b, 0x12, 0x2a, 0x83, 0x86, 0x1a, 0xea, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb0, - 0x39, 0x84, 0xbb, 0xd1, 0x01, 0x00, 0x00, + // 361 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x91, 0x31, 0x6b, 0xe3, 0x30, + 0x14, 0xc7, 0xad, 0x4b, 0xc8, 0x60, 0xb2, 0x9c, 0x2f, 0x07, 0xb9, 0x1c, 0x38, 0xe6, 0xa6, 0x70, + 0x10, 0xab, 0x69, 0xa1, 0x43, 0xc7, 0x90, 0x31, 0x43, 0x70, 0x0a, 0x85, 0x2e, 0x46, 0xb2, 0x55, + 0xe7, 0x11, 0x4b, 0x32, 0x96, 0x9d, 0xd4, 0xdf, 0xa2, 0x63, 0xc7, 0x8e, 0x1d, 0x3b, 0xf4, 0x43, + 0x64, 0x0c, 0x9d, 0x4a, 0x87, 0x50, 0x92, 0xa1, 0x1f, 0xa3, 0x25, 0x96, 0x4d, 0x17, 0xa1, 0xa7, + 0xdf, 0xff, 0xe9, 0xff, 0xd7, 0x93, 0xe9, 0x50, 0x42, 0x8b, 0x58, 0x0a, 0x7c, 0x03, 0x82, 0xc4, + 0x90, 0x15, 0x78, 0x35, 0xc2, 0x09, 0x49, 0x09, 0x57, 0x6e, 0x92, 0xca, 0x4c, 0x5a, 0xbf, 0x2a, + 0x85, 0x5b, 0x2b, 0xdc, 0xd5, 0xa8, 0xd7, 0x89, 0x64, 0x24, 0x4b, 0x8e, 0x8f, 0x3b, 0x2d, 0xed, + 0xfd, 0x24, 0x1c, 0x84, 0xc4, 0xe5, 0x5a, 0x1d, 0xfd, 0x09, 0xa4, 0xe2, 0x52, 0xf9, 0x5a, 0xab, + 0x0b, 0x8d, 0xfe, 0x7d, 0x22, 0xb3, 0x35, 0x2b, 0x9d, 0xac, 0x13, 0xb3, 0xa3, 0x20, 0x12, 0x2c, + 0xf4, 0x69, 0x2c, 0x83, 0xa5, 0xf2, 0xd7, 0x20, 0x42, 0xb9, 0xee, 0x22, 0x07, 0x0d, 0x1a, 0x9e, + 0xa5, 0xd9, 0xb8, 0x44, 0x57, 0x25, 0x39, 0x76, 0xd4, 0x79, 0x7c, 0x05, 0x91, 0x9f, 0x01, 0x67, + 0x32, 0xcf, 0xba, 0x3f, 0x74, 0x47, 0xcd, 0xe6, 0x10, 0x5d, 0x6a, 0x62, 0x81, 0xf9, 0x9b, 0x83, + 0xf0, 0x2b, 0x9f, 0x84, 0xa5, 0xb5, 0x49, 0xc3, 0x41, 0x83, 0xf6, 0xf8, 0x7c, 0xb3, 0xeb, 0x1b, + 0x6f, 0xbb, 0xfe, 0x5f, 0x9d, 0x51, 0x85, 0x4b, 0x17, 0x24, 0xe6, 0x24, 0x5b, 0xb8, 0x53, 0x16, + 0x91, 0xa0, 0x98, 0xb0, 0xe0, 0xe5, 0x79, 0x68, 0x56, 0x4f, 0x98, 0xb0, 0xe0, 0xf1, 0xe3, 0xe9, + 0x3f, 0xf2, 0x2c, 0x0e, 0x62, 0x5e, 0xde, 0x39, 0x63, 0x69, 0x15, 0xce, 0x31, 0xdb, 0x47, 0xab, + 0x24, 0xa7, 0x7e, 0x4a, 0x44, 0xd8, 0x6d, 0x3a, 0x68, 0xd0, 0xf4, 0x4c, 0x0e, 0x62, 0x96, 0x53, + 0x8f, 0x88, 0xf0, 0xa2, 0x79, 0xff, 0xd0, 0x37, 0xc6, 0xd3, 0xcd, 0xde, 0x46, 0xdb, 0xbd, 0x8d, + 0xde, 0xf7, 0x36, 0xba, 0x3b, 0xd8, 0xc6, 0xf6, 0x60, 0x1b, 0xaf, 0x07, 0xdb, 0xb8, 0x3e, 0x8d, + 0x20, 0x5b, 0xe4, 0xd4, 0x0d, 0x24, 0xc7, 0xd5, 0xfc, 0x63, 0x42, 0xd5, 0x10, 0x64, 0x5d, 0xe2, + 0xdb, 0xef, 0x2f, 0xcb, 0x8a, 0x84, 0x29, 0xda, 0x2a, 0xc7, 0x7a, 0xf6, 0x15, 0x00, 0x00, 0xff, + 0xff, 0xda, 0x3a, 0x9d, 0x97, 0xd3, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/x/finality/types/query.pb.go b/x/finality/types/query.pb.go index 1f4648346..a0f7f3271 100644 --- a/x/finality/types/query.pb.go +++ b/x/finality/types/query.pb.go @@ -6,7 +6,7 @@ package types import ( context "context" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -207,7 +207,7 @@ func (m *QueryListPublicRandomnessRequest) GetPagination() *query.PageRequest { type QueryListPublicRandomnessResponse struct { // pub_rand_map is the map where the key is the height and the value // is the public randomness at this height for the given finality provider - PubRandMap map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,1,rep,name=pub_rand_map,json=pubRandMap,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + PubRandMap map[uint64]*github_com_babylonlabs_io_babylon_types.SchnorrPubRand `protobuf:"bytes,1,rep,name=pub_rand_map,json=pubRandMap,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrPubRand" json:"pub_rand_map,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -678,7 +678,7 @@ func (m *QueryVotesAtHeightRequest) GetHeight() uint64 { type QueryVotesAtHeightResponse struct { // btc_pk is the Bitcoin secp256k1 PK of finality providers who have signed the block at given height. // the PK follows encoding in BIP-340 spec - BtcPks []github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,1,rep,name=btc_pks,json=btcPks,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"btc_pks,omitempty"` + BtcPks []github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,1,rep,name=btc_pks,json=btcPks,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"btc_pks,omitempty"` } func (m *QueryVotesAtHeightResponse) Reset() { *m = QueryVotesAtHeightResponse{} } @@ -1123,7 +1123,7 @@ func init() { proto.RegisterType((*QueryParamsResponse)(nil), "babylon.finality.v1.QueryParamsResponse") proto.RegisterType((*QueryListPublicRandomnessRequest)(nil), "babylon.finality.v1.QueryListPublicRandomnessRequest") proto.RegisterType((*QueryListPublicRandomnessResponse)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse") - proto.RegisterMapType((map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse.PubRandMapEntry") + proto.RegisterMapType((map[uint64]*github_com_babylonlabs_io_babylon_types.SchnorrPubRand)(nil), "babylon.finality.v1.QueryListPublicRandomnessResponse.PubRandMapEntry") proto.RegisterType((*PubRandCommitResponse)(nil), "babylon.finality.v1.PubRandCommitResponse") proto.RegisterType((*QueryListPubRandCommitRequest)(nil), "babylon.finality.v1.QueryListPubRandCommitRequest") proto.RegisterType((*QueryListPubRandCommitResponse)(nil), "babylon.finality.v1.QueryListPubRandCommitResponse") @@ -1147,90 +1147,90 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/query.proto", fileDescriptor_32bddab77af6fdae) } var fileDescriptor_32bddab77af6fdae = []byte{ - // 1317 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdf, 0x6f, 0xdb, 0xd4, - 0x17, 0xef, 0xcd, 0xd6, 0x6c, 0x3b, 0x4d, 0xb6, 0xee, 0xae, 0xdb, 0xb7, 0xdf, 0x8c, 0xa5, 0x99, - 0x37, 0xda, 0xd2, 0x0e, 0xbb, 0x4d, 0xcb, 0xd8, 0x06, 0x68, 0x6b, 0xa0, 0xa5, 0x81, 0x2e, 0x0b, - 0x2e, 0x9a, 0xb4, 0x3d, 0x60, 0xec, 0xf4, 0x26, 0xb1, 0x9a, 0xd8, 0x5e, 0xec, 0x44, 0x0d, 0xd3, - 0x24, 0x84, 0xc4, 0x1e, 0x10, 0x48, 0x48, 0xbc, 0xc0, 0xc3, 0x1e, 0xd8, 0x03, 0x2f, 0xfc, 0x1f, - 0x68, 0x8f, 0x15, 0xf0, 0x80, 0x26, 0x51, 0xa1, 0x96, 0x3f, 0x04, 0xe5, 0xde, 0xeb, 0xc4, 0x4e, - 0x9c, 0x1f, 0x2d, 0x11, 0x6f, 0xf6, 0xf5, 0xf9, 0xf1, 0xf9, 0x7c, 0xce, 0xc9, 0xb9, 0xa7, 0x85, - 0x29, 0x4d, 0xd5, 0xea, 0x25, 0xd3, 0x90, 0xf2, 0xba, 0xa1, 0x96, 0x74, 0xa7, 0x2e, 0xd5, 0x16, - 0xa5, 0x47, 0x55, 0x52, 0xa9, 0x8b, 0x56, 0xc5, 0x74, 0x4c, 0x7c, 0x8e, 0x1b, 0x88, 0xae, 0x81, - 0x58, 0x5b, 0x8c, 0x4d, 0x14, 0xcc, 0x82, 0x49, 0xbf, 0x4b, 0x8d, 0x27, 0x66, 0x1a, 0x7b, 0xa5, - 0x60, 0x9a, 0x85, 0x12, 0x91, 0x54, 0x4b, 0x97, 0x54, 0xc3, 0x30, 0x1d, 0xd5, 0xd1, 0x4d, 0xc3, - 0xe6, 0x5f, 0xe7, 0x72, 0xa6, 0x5d, 0x36, 0x6d, 0x49, 0x53, 0x6d, 0xc2, 0x32, 0x48, 0xb5, 0x45, - 0x8d, 0x38, 0xea, 0xa2, 0x64, 0xa9, 0x05, 0xdd, 0xa0, 0xc6, 0xdc, 0x36, 0x11, 0x84, 0xca, 0x52, - 0x2b, 0x6a, 0xd9, 0x8d, 0x26, 0x04, 0x59, 0x34, 0x21, 0x52, 0x1b, 0x61, 0x02, 0xf0, 0x47, 0x8d, - 0x3c, 0x59, 0xea, 0x28, 0x93, 0x47, 0x55, 0x62, 0x3b, 0x42, 0x16, 0xce, 0xf9, 0x4e, 0x6d, 0xcb, - 0x34, 0x6c, 0x82, 0x6f, 0x42, 0x98, 0x25, 0x98, 0x44, 0x09, 0x34, 0x3b, 0x96, 0xbc, 0x28, 0x06, - 0x10, 0x17, 0x99, 0x53, 0xea, 0xf8, 0x8b, 0xbd, 0xa9, 0x11, 0x99, 0x3b, 0x08, 0xdf, 0x20, 0x48, - 0xd0, 0x90, 0x1b, 0xba, 0xed, 0x64, 0xab, 0x5a, 0x49, 0xcf, 0xc9, 0xaa, 0xb1, 0x65, 0x96, 0x0d, - 0x62, 0xbb, 0x69, 0xf1, 0x65, 0x88, 0xe6, 0x2d, 0x45, 0x73, 0x72, 0x8a, 0xb5, 0xad, 0x14, 0xc9, - 0x0e, 0x4d, 0x73, 0x4a, 0x86, 0xbc, 0x95, 0x72, 0x72, 0xd9, 0xed, 0x75, 0xb2, 0x83, 0xd7, 0x00, - 0x5a, 0x4a, 0x4c, 0x86, 0x28, 0x8c, 0x69, 0x91, 0xc9, 0x26, 0x36, 0x64, 0x13, 0x59, 0x61, 0xb8, - 0x6c, 0x62, 0x56, 0x2d, 0x10, 0x1e, 0x5e, 0xf6, 0x78, 0x0a, 0xbb, 0x21, 0xb8, 0xdc, 0x03, 0x0f, - 0x27, 0xfc, 0x1c, 0x41, 0xc4, 0xaa, 0x6a, 0x4a, 0x45, 0x35, 0xb6, 0x94, 0xb2, 0x6a, 0x4d, 0xa2, - 0xc4, 0xb1, 0xd9, 0xb1, 0xe4, 0x5a, 0x20, 0xef, 0xbe, 0xe1, 0xc4, 0x6c, 0x55, 0x6b, 0x9c, 0xde, - 0x55, 0xad, 0x55, 0xc3, 0xa9, 0xd4, 0x53, 0x37, 0x5e, 0xee, 0x4d, 0x2d, 0x17, 0x74, 0xa7, 0x58, - 0xd5, 0xc4, 0x9c, 0x59, 0x96, 0x78, 0xd4, 0x5c, 0x51, 0xd5, 0x0d, 0xf7, 0x45, 0x72, 0xea, 0x16, - 0xb1, 0xc5, 0xcd, 0x5c, 0xd1, 0x30, 0x2b, 0x15, 0x1e, 0x41, 0x06, 0xab, 0x19, 0x0a, 0xbf, 0x1f, - 0x20, 0xc9, 0x4c, 0x5f, 0x49, 0x18, 0x24, 0xaf, 0x26, 0xb1, 0x77, 0xe0, 0x4c, 0x1b, 0x42, 0x3c, - 0x0e, 0xc7, 0xb6, 0x49, 0x9d, 0xd6, 0xe1, 0xb8, 0xdc, 0x78, 0xc4, 0x13, 0x30, 0x5a, 0x53, 0x4b, - 0x55, 0x42, 0x13, 0x45, 0x64, 0xf6, 0x72, 0x2b, 0x74, 0x03, 0x09, 0x0f, 0xe0, 0x3c, 0x77, 0x7f, - 0xd7, 0x2c, 0x97, 0x75, 0xa7, 0xa9, 0x62, 0x02, 0x22, 0x46, 0xb5, 0xac, 0xb8, 0x42, 0xf2, 0x68, - 0x60, 0x54, 0xcb, 0xdc, 0x1e, 0xc7, 0x01, 0x72, 0xd4, 0xa7, 0x4c, 0x0c, 0x87, 0x47, 0xf6, 0x9c, - 0x08, 0x5f, 0x21, 0xb8, 0xe4, 0x95, 0xd7, 0x9b, 0xe4, 0x3f, 0x6f, 0x9d, 0xdf, 0x43, 0x10, 0xef, - 0x06, 0x86, 0x33, 0xde, 0x81, 0x73, 0xcd, 0xb6, 0x61, 0x34, 0x3c, 0xdd, 0x93, 0xee, 0xdb, 0x3d, - 0x9d, 0x11, 0x45, 0xdf, 0xa9, 0x5b, 0x1e, 0x79, 0xdc, 0x6a, 0x3b, 0x1e, 0x5e, 0x33, 0x98, 0x6d, - 0xd5, 0xec, 0xd1, 0x12, 0x77, 0xbc, 0x2d, 0x31, 0x96, 0x9c, 0x0b, 0x9e, 0x0a, 0x41, 0xb4, 0xbc, - 0xed, 0x33, 0x0f, 0x67, 0xa9, 0x06, 0xa9, 0x92, 0x99, 0xdb, 0x76, 0xcb, 0x7a, 0x01, 0xc2, 0x45, - 0xa2, 0x17, 0x8a, 0x0e, 0xcf, 0xc7, 0xdf, 0x84, 0xbb, 0x7c, 0x6c, 0x71, 0x63, 0x2e, 0xfb, 0x9b, - 0x30, 0xaa, 0x35, 0x0e, 0xf8, 0x78, 0xba, 0x1c, 0x08, 0x24, 0x6d, 0x6c, 0x91, 0x1d, 0xb2, 0xc5, - 0x3c, 0x99, 0xbd, 0xf0, 0x23, 0x82, 0x0b, 0xcd, 0x02, 0xd0, 0x2f, 0xcd, 0x99, 0x74, 0x1b, 0xc2, - 0xb6, 0xa3, 0x3a, 0x55, 0x36, 0xf3, 0x4e, 0x27, 0x67, 0xba, 0x56, 0x4f, 0xe7, 0x41, 0x37, 0xa9, - 0xb9, 0xcc, 0xdd, 0x86, 0xd6, 0x76, 0xcf, 0x10, 0xfc, 0xaf, 0x03, 0x63, 0x6b, 0x30, 0x53, 0x22, - 0x36, 0x6f, 0xb1, 0x01, 0x98, 0x73, 0x87, 0xa1, 0x35, 0x8c, 0xb0, 0x04, 0xff, 0xa7, 0xf0, 0xee, - 0x9b, 0x0e, 0xb1, 0x57, 0x9c, 0x75, 0x5a, 0xa8, 0x7e, 0x75, 0x2c, 0x43, 0x2c, 0xc8, 0x89, 0xd3, - 0xba, 0x07, 0x27, 0xd8, 0x2f, 0x9a, 0xf1, 0x8a, 0xa4, 0xae, 0xbf, 0xdc, 0x9b, 0x4a, 0x0e, 0x36, - 0x30, 0x53, 0xe9, 0xec, 0xd2, 0xf2, 0x42, 0xb6, 0xaa, 0x7d, 0x48, 0xea, 0x72, 0x58, 0x6b, 0x0c, - 0x01, 0x5b, 0xb8, 0x09, 0x13, 0x34, 0xdd, 0x6a, 0x4d, 0xdf, 0x22, 0x46, 0x8e, 0x0c, 0x3e, 0x3d, - 0x04, 0x19, 0xce, 0xb7, 0xb9, 0x36, 0xb5, 0x3f, 0x49, 0xf8, 0x19, 0xef, 0xbb, 0x4b, 0x81, 0xea, - 0x37, 0x1d, 0x9b, 0xe6, 0xc2, 0x53, 0xc4, 0x35, 0x6b, 0x94, 0xd4, 0xfd, 0xee, 0xb9, 0x0d, 0x23, - 0xb6, 0xa3, 0x56, 0x1c, 0xc5, 0xa7, 0xdc, 0x18, 0x3d, 0x63, 0x42, 0x0d, 0xad, 0xb7, 0x9e, 0x23, - 0x5e, 0x87, 0x36, 0x20, 0x9c, 0xe2, 0x5b, 0x70, 0xca, 0xc5, 0xec, 0x76, 0x58, 0x1f, 0x8e, 0x2d, - 0xfb, 0xe1, 0x35, 0xd8, 0xdb, 0xbc, 0xff, 0x37, 0xf5, 0x82, 0xa1, 0x1b, 0x85, 0xb4, 0x91, 0x37, - 0x0f, 0x51, 0xbf, 0xcf, 0x60, 0xb2, 0xd3, 0x9b, 0xf3, 0xfb, 0x04, 0xce, 0xe4, 0x2d, 0xc5, 0x66, - 0x5f, 0x14, 0xdd, 0xc8, 0x9b, 0xbc, 0x92, 0x0b, 0x81, 0x2c, 0xd7, 0xf8, 0x73, 0xb6, 0x62, 0x36, - 0x58, 0x56, 0x3c, 0x21, 0xf9, 0xd6, 0x13, 0xcd, 0x5b, 0x9e, 0x43, 0x41, 0xeb, 0xcc, 0xdd, 0xac, - 0xb2, 0xbf, 0x84, 0xe8, 0xc8, 0x25, 0xfc, 0xc5, 0xed, 0x25, 0x7f, 0x12, 0xce, 0xf0, 0x53, 0x18, - 0x6f, 0x63, 0xe8, 0x16, 0xf2, 0xa8, 0x14, 0x4f, 0xfb, 0x28, 0x0e, 0xaf, 0xcc, 0x73, 0xb7, 0xd9, - 0x68, 0xf7, 0x4f, 0x53, 0x7c, 0x16, 0xa2, 0x99, 0x7b, 0x19, 0x65, 0x2d, 0x9d, 0x59, 0xd9, 0x48, - 0x3f, 0x5c, 0x7d, 0x6f, 0x7c, 0x04, 0x47, 0xe1, 0x54, 0xeb, 0x15, 0xe1, 0x13, 0x70, 0x6c, 0x25, - 0xf3, 0x60, 0x3c, 0x94, 0xfc, 0x32, 0x0a, 0xa3, 0x54, 0x09, 0xfc, 0x39, 0x82, 0x30, 0xdb, 0x46, - 0x71, 0xf7, 0xb1, 0xed, 0x5f, 0x7d, 0x63, 0xb3, 0xfd, 0x0d, 0x19, 0x68, 0xe1, 0xca, 0x17, 0xbf, - 0xfd, 0xfd, 0x5d, 0xe8, 0x12, 0xbe, 0x28, 0x75, 0xdf, 0xc4, 0xf1, 0x9f, 0x08, 0x26, 0x82, 0x76, - 0x42, 0xfc, 0xc6, 0x61, 0x77, 0x48, 0x06, 0xef, 0xfa, 0xd1, 0x56, 0x4f, 0xe1, 0x3e, 0x05, 0x9b, - 0xc5, 0x19, 0xa9, 0xd7, 0x1f, 0x05, 0x8a, 0xc5, 0xeb, 0x6d, 0x4b, 0x8f, 0x7d, 0x3f, 0xa8, 0x27, - 0x92, 0x45, 0x23, 0xd3, 0x95, 0x86, 0x85, 0x56, 0x4a, 0xba, 0xed, 0xe0, 0x5f, 0x11, 0x9c, 0xed, - 0xd8, 0x5a, 0x70, 0xf2, 0x50, 0x2b, 0x0e, 0x63, 0xb6, 0x74, 0x84, 0xb5, 0x48, 0xf8, 0x98, 0xd2, - 0xca, 0xe0, 0x8d, 0x7f, 0x41, 0xcb, 0xb7, 0xa6, 0x51, 0x52, 0x4f, 0x11, 0x8c, 0xd2, 0xe6, 0xc3, - 0xd3, 0xdd, 0x41, 0x79, 0xf7, 0x94, 0xd8, 0x4c, 0x5f, 0x3b, 0x0e, 0xf8, 0x1a, 0x05, 0x3c, 0x8d, - 0xaf, 0x06, 0x02, 0x66, 0x77, 0xb2, 0xf4, 0x98, 0x4d, 0xfc, 0x27, 0xf8, 0x6b, 0x04, 0xd0, 0xba, - 0xee, 0xf1, 0x7c, 0x6f, 0x89, 0x7c, 0x8b, 0x4b, 0xec, 0xda, 0x60, 0xc6, 0x03, 0x35, 0x33, 0xdf, - 0x15, 0x9e, 0x21, 0x88, 0xfa, 0x6e, 0x6a, 0x2c, 0x76, 0x4f, 0x12, 0xb4, 0x07, 0xc4, 0xa4, 0x81, - 0xed, 0x39, 0xae, 0x79, 0x8a, 0xeb, 0x55, 0x7c, 0x25, 0x10, 0x57, 0xad, 0xe1, 0xd3, 0x92, 0xeb, - 0x67, 0x04, 0x27, 0xdd, 0x2b, 0x08, 0xbf, 0xd6, 0x3d, 0x55, 0xdb, 0xf5, 0x1f, 0x9b, 0x1b, 0xc4, - 0x94, 0x03, 0x5a, 0xa7, 0x80, 0x52, 0xf8, 0xce, 0x51, 0x3b, 0xce, 0xbd, 0x19, 0xf1, 0xf7, 0x08, - 0xa2, 0xbe, 0xfb, 0xb6, 0x97, 0x9a, 0x41, 0x1b, 0x42, 0x2f, 0x35, 0x03, 0x2f, 0x72, 0x61, 0x9a, - 0x82, 0x4f, 0xe0, 0x78, 0x20, 0xf8, 0xd6, 0x9d, 0xfd, 0x13, 0x82, 0x31, 0xcf, 0x74, 0xc7, 0x3d, - 0x7a, 0xa9, 0xf3, 0x36, 0x8e, 0xbd, 0x3e, 0xa0, 0x35, 0x07, 0x75, 0x8b, 0x82, 0x5a, 0xc6, 0xc9, - 0x40, 0x50, 0xbe, 0x3b, 0xab, 0x5d, 0x4c, 0xfc, 0x03, 0x82, 0x88, 0xef, 0x1a, 0x1a, 0x2c, 0x77, - 0x53, 0x41, 0x71, 0x50, 0x73, 0x8e, 0x75, 0x8e, 0x62, 0xbd, 0x8a, 0x85, 0xfe, 0x58, 0x53, 0x1f, - 0xbc, 0xd8, 0x8f, 0xa3, 0xdd, 0xfd, 0x38, 0xfa, 0x6b, 0x3f, 0x8e, 0xbe, 0x3d, 0x88, 0x8f, 0xec, - 0x1e, 0xc4, 0x47, 0xfe, 0x38, 0x88, 0x8f, 0x3c, 0x5c, 0xe8, 0xb7, 0xc2, 0xee, 0xb4, 0xc2, 0xd2, - 0x6d, 0x56, 0x0b, 0xd3, 0xff, 0xd6, 0x2c, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0x75, 0xb1, 0x13, - 0x1f, 0x8b, 0x12, 0x00, 0x00, + // 1318 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x58, 0xdf, 0x6f, 0xdb, 0x54, + 0x14, 0xee, 0xcd, 0xd6, 0x6c, 0x3b, 0x4d, 0xb6, 0xee, 0xae, 0x1b, 0x25, 0xa3, 0x69, 0xea, 0x8d, + 0xb6, 0xb4, 0x9b, 0xbd, 0xa6, 0x65, 0x6c, 0x05, 0xb4, 0x35, 0xd0, 0xd2, 0x88, 0x2e, 0x64, 0x2e, + 0x9a, 0xb4, 0x3d, 0x60, 0xec, 0xd4, 0x49, 0xad, 0x26, 0xbe, 0x5e, 0xec, 0x44, 0x0d, 0xd3, 0x24, + 0x84, 0xc4, 0x1e, 0x10, 0x48, 0x48, 0xbc, 0xc0, 0xc3, 0x1e, 0x40, 0x88, 0x17, 0xfe, 0x0f, 0xb4, + 0xc7, 0x69, 0xf0, 0x80, 0x26, 0x51, 0xa1, 0x96, 0x3f, 0x04, 0xe5, 0xde, 0xeb, 0xc4, 0x4e, 0x9c, + 0x1f, 0x2d, 0x11, 0x6f, 0xf1, 0xf5, 0xf9, 0xf1, 0x7d, 0xdf, 0x39, 0x3e, 0xf7, 0xb4, 0x30, 0xa9, + 0xa9, 0x5a, 0xad, 0x48, 0x4c, 0x29, 0x6f, 0x98, 0x6a, 0xd1, 0x70, 0x6a, 0x52, 0x75, 0x41, 0x7a, + 0x58, 0xd1, 0xcb, 0x35, 0xd1, 0x2a, 0x13, 0x87, 0xe0, 0x73, 0xdc, 0x40, 0x74, 0x0d, 0xc4, 0xea, + 0x42, 0x6c, 0xac, 0x40, 0x0a, 0x84, 0xbe, 0x97, 0xea, 0xbf, 0x98, 0x69, 0xec, 0xb5, 0x02, 0x21, + 0x85, 0xa2, 0x2e, 0xa9, 0x96, 0x21, 0xa9, 0xa6, 0x49, 0x1c, 0xd5, 0x31, 0x88, 0x69, 0xf3, 0xb7, + 0x73, 0x39, 0x62, 0x97, 0x88, 0x2d, 0x69, 0xaa, 0xad, 0xb3, 0x0c, 0x52, 0x75, 0x41, 0xd3, 0x1d, + 0x75, 0x41, 0xb2, 0xd4, 0x82, 0x61, 0x52, 0x63, 0x6e, 0x9b, 0x08, 0x42, 0x65, 0xa9, 0x65, 0xb5, + 0xe4, 0x46, 0x13, 0x82, 0x2c, 0x1a, 0x10, 0xa9, 0x8d, 0x30, 0x06, 0xf8, 0x6e, 0x3d, 0x4f, 0x96, + 0x3a, 0xca, 0xfa, 0xc3, 0x8a, 0x6e, 0x3b, 0x42, 0x16, 0xce, 0xf9, 0x4e, 0x6d, 0x8b, 0x98, 0xb6, + 0x8e, 0x6f, 0x42, 0x98, 0x25, 0x18, 0x47, 0x09, 0x34, 0x3b, 0x92, 0xbc, 0x28, 0x06, 0x10, 0x17, + 0x99, 0x53, 0xea, 0xf8, 0xb3, 0xbd, 0xc9, 0x21, 0x99, 0x3b, 0x08, 0xdf, 0x20, 0x48, 0xd0, 0x90, + 0x1b, 0x86, 0xed, 0x64, 0x2b, 0x5a, 0xd1, 0xc8, 0xc9, 0xaa, 0xb9, 0x45, 0x4a, 0xa6, 0x6e, 0xbb, + 0x69, 0xf1, 0x14, 0x44, 0xf3, 0x96, 0xa2, 0x39, 0x39, 0xc5, 0xda, 0x51, 0xb6, 0xf5, 0x5d, 0x9a, + 0xe6, 0x94, 0x0c, 0x79, 0x2b, 0xe5, 0xe4, 0xb2, 0x3b, 0xeb, 0xfa, 0x2e, 0x5e, 0x03, 0x68, 0x2a, + 0x31, 0x1e, 0xa2, 0x30, 0xa6, 0x45, 0x26, 0x9b, 0x58, 0x97, 0x4d, 0x64, 0x85, 0xe1, 0xb2, 0x89, + 0x59, 0xb5, 0xa0, 0xf3, 0xf0, 0xb2, 0xc7, 0x53, 0x78, 0x11, 0x82, 0xa9, 0x2e, 0x78, 0x38, 0xe1, + 0x9f, 0x11, 0x44, 0xac, 0x8a, 0xa6, 0x94, 0x55, 0x73, 0x4b, 0x29, 0xa9, 0xd6, 0x38, 0x4a, 0x1c, + 0x9b, 0x1d, 0x49, 0xae, 0x05, 0xf2, 0xee, 0x19, 0x4e, 0xcc, 0x56, 0xb4, 0xfa, 0xe9, 0x1d, 0xd5, + 0x5a, 0x35, 0x9d, 0x72, 0x2d, 0xb5, 0xfc, 0x72, 0x6f, 0xf2, 0x7a, 0xc1, 0x70, 0xb6, 0x2b, 0x9a, + 0x98, 0x23, 0x25, 0x89, 0x47, 0x2d, 0xaa, 0x9a, 0x7d, 0xd5, 0x20, 0xee, 0xa3, 0xe4, 0xd4, 0x2c, + 0xdd, 0x16, 0x37, 0x73, 0xdb, 0x26, 0x29, 0x97, 0x79, 0x0c, 0x19, 0xac, 0x46, 0x30, 0xfc, 0x41, + 0x80, 0x28, 0x33, 0x3d, 0x45, 0x61, 0xa0, 0xbc, 0xaa, 0xc4, 0xde, 0x85, 0x33, 0x2d, 0x18, 0xf1, + 0x28, 0x1c, 0xdb, 0xd1, 0x6b, 0xb4, 0x12, 0xc7, 0xe5, 0xfa, 0x4f, 0x3c, 0x06, 0xc3, 0x55, 0xb5, + 0x58, 0xd1, 0x69, 0xa2, 0x88, 0xcc, 0x1e, 0x96, 0x43, 0x37, 0x90, 0x70, 0x1f, 0xce, 0x73, 0xf7, + 0xf7, 0x48, 0xa9, 0x64, 0x38, 0x0d, 0x1d, 0x13, 0x10, 0x31, 0x2b, 0x25, 0xc5, 0x95, 0x92, 0x47, + 0x03, 0xb3, 0x52, 0xe2, 0xf6, 0x38, 0x0e, 0x90, 0xa3, 0x3e, 0x25, 0xdd, 0x74, 0x78, 0x64, 0xcf, + 0x89, 0xf0, 0x15, 0x82, 0x09, 0xaf, 0xc0, 0xde, 0x24, 0xff, 0x7b, 0xf3, 0xfc, 0x11, 0x82, 0x78, + 0x27, 0x30, 0x9c, 0xf1, 0x2e, 0x9c, 0x6b, 0x34, 0x0e, 0xa3, 0xe1, 0xe9, 0x9f, 0x74, 0xcf, 0xfe, + 0x69, 0x8f, 0x28, 0xfa, 0x4e, 0xdd, 0xf2, 0xc8, 0xa3, 0x56, 0xcb, 0xf1, 0xe0, 0x9a, 0x81, 0xb4, + 0x54, 0xb3, 0x4b, 0x4b, 0xdc, 0xf6, 0xb6, 0xc4, 0x48, 0x72, 0x2e, 0x78, 0x2e, 0x04, 0xd1, 0xf2, + 0xb6, 0xcf, 0x3c, 0x9c, 0xa5, 0x1a, 0xa4, 0x8a, 0x24, 0xb7, 0xe3, 0x96, 0xf5, 0x02, 0x84, 0xb7, + 0x75, 0xa3, 0xb0, 0xed, 0xf0, 0x7c, 0xfc, 0x49, 0xb8, 0xc3, 0x07, 0x17, 0x37, 0xe6, 0xb2, 0xbf, + 0x05, 0xc3, 0x5a, 0xfd, 0x80, 0x0f, 0xa8, 0xa9, 0x40, 0x20, 0x69, 0x73, 0x4b, 0xdf, 0xd5, 0xb7, + 0x98, 0x27, 0xb3, 0x17, 0x7e, 0x44, 0x70, 0xa1, 0x51, 0x00, 0xfa, 0xa6, 0x31, 0x95, 0x6e, 0x41, + 0xd8, 0x76, 0x54, 0xa7, 0xc2, 0xa6, 0xde, 0xe9, 0xe4, 0x4c, 0xc7, 0xea, 0x19, 0x3c, 0xe8, 0x26, + 0x35, 0x97, 0xb9, 0xdb, 0xc0, 0xda, 0xee, 0x29, 0x82, 0x57, 0xda, 0x30, 0x36, 0x47, 0x33, 0x25, + 0x62, 0xf3, 0x16, 0xeb, 0x83, 0x39, 0x77, 0x18, 0x58, 0xc3, 0x08, 0x8b, 0xf0, 0x2a, 0x85, 0x77, + 0x8f, 0x38, 0xba, 0xbd, 0xe2, 0xac, 0xd3, 0x42, 0xf5, 0xaa, 0x23, 0x81, 0x58, 0x90, 0x13, 0xa7, + 0x75, 0x17, 0x4e, 0xb0, 0x2f, 0x9a, 0xf1, 0x8a, 0xa4, 0x6e, 0xbc, 0xdc, 0x9b, 0x5c, 0xea, 0x77, + 0x64, 0xa6, 0xd2, 0xd9, 0xc5, 0xa5, 0x6b, 0xd9, 0x8a, 0xf6, 0xa1, 0x5e, 0x93, 0xc3, 0x5a, 0x7d, + 0x0c, 0xd8, 0xc2, 0x4d, 0x18, 0xa3, 0x09, 0x57, 0xab, 0xc6, 0x96, 0x6e, 0xe6, 0xf4, 0xfe, 0xe7, + 0x87, 0x20, 0xc3, 0xf9, 0x16, 0xd7, 0x86, 0xfa, 0x27, 0x75, 0x7e, 0xc6, 0x3b, 0x6f, 0x22, 0x50, + 0xff, 0x86, 0x63, 0xc3, 0x5c, 0x78, 0x82, 0xb8, 0x6a, 0xf5, 0xa2, 0xba, 0xef, 0x3d, 0x37, 0x62, + 0xc4, 0x76, 0xd4, 0xb2, 0xa3, 0xf8, 0xb4, 0x1b, 0xa1, 0x67, 0x4c, 0xaa, 0x81, 0x75, 0xd7, 0x4f, + 0x88, 0x57, 0xa2, 0x05, 0x08, 0xa7, 0xf8, 0x36, 0x9c, 0x72, 0x31, 0xbb, 0x3d, 0xd6, 0x83, 0x63, + 0xd3, 0x7e, 0x70, 0x2d, 0xf6, 0x0e, 0xff, 0x02, 0x36, 0x8d, 0x82, 0x69, 0x98, 0x85, 0xb4, 0x99, + 0x27, 0x87, 0xa8, 0xdf, 0x67, 0x30, 0xde, 0xee, 0xcd, 0xf9, 0x7d, 0x02, 0x67, 0xf2, 0x96, 0x62, + 0xb3, 0x37, 0x8a, 0x61, 0xe6, 0x09, 0xaf, 0xe4, 0xb5, 0x40, 0x96, 0x6b, 0xfc, 0x77, 0xb6, 0x4c, + 0xea, 0x2c, 0xcb, 0x9e, 0x90, 0x7c, 0xf3, 0x89, 0xe6, 0x2d, 0xcf, 0xa1, 0xa0, 0xb5, 0xe7, 0x6e, + 0x54, 0xd9, 0x5f, 0x42, 0x74, 0xe4, 0x12, 0xfe, 0xe6, 0xf6, 0x92, 0x3f, 0x09, 0x67, 0xf8, 0x29, + 0x8c, 0xb6, 0x30, 0x74, 0x0b, 0x79, 0x54, 0x8a, 0xa7, 0x7d, 0x14, 0x07, 0x57, 0xe6, 0xb9, 0x5b, + 0x6c, 0xb8, 0xfb, 0xe7, 0x29, 0x3e, 0x0b, 0xd1, 0xcc, 0x47, 0x19, 0x65, 0x2d, 0x9d, 0x59, 0xd9, + 0x48, 0x3f, 0x58, 0x7d, 0x7f, 0x74, 0x08, 0x47, 0xe1, 0x54, 0xf3, 0x11, 0xe1, 0x13, 0x70, 0x6c, + 0x25, 0x73, 0x7f, 0x34, 0x94, 0xfc, 0x32, 0x0a, 0xc3, 0x54, 0x09, 0xfc, 0x39, 0x82, 0x30, 0xdb, + 0x48, 0x71, 0xe7, 0xc1, 0xed, 0x5f, 0x7f, 0x63, 0xb3, 0xbd, 0x0d, 0x19, 0x68, 0xe1, 0xd2, 0x17, + 0xbf, 0xff, 0xf3, 0x5d, 0x68, 0x02, 0x5f, 0x94, 0x3a, 0x6f, 0xe3, 0xf8, 0x2f, 0x04, 0x63, 0x41, + 0x7b, 0x21, 0x7e, 0xf3, 0xb0, 0x7b, 0x24, 0x83, 0x77, 0xfd, 0x68, 0xeb, 0xa7, 0x70, 0x8f, 0x82, + 0xcd, 0xe2, 0x8c, 0xd4, 0xed, 0x0f, 0x03, 0xc5, 0xe2, 0xf5, 0xb6, 0xa5, 0x47, 0xbe, 0x0f, 0xea, + 0xb1, 0x64, 0xd1, 0xc8, 0x74, 0xa9, 0x61, 0xa1, 0x95, 0xa2, 0x61, 0x3b, 0xf8, 0x05, 0x82, 0xb3, + 0x6d, 0x7b, 0x0b, 0x4e, 0x1e, 0x6a, 0xc9, 0x61, 0xcc, 0x16, 0x8f, 0xb0, 0x18, 0x09, 0x1f, 0x53, + 0x5a, 0x19, 0xbc, 0xf1, 0x1f, 0x68, 0xf9, 0x16, 0x35, 0x4a, 0xea, 0x09, 0x82, 0x61, 0xda, 0x7c, + 0x78, 0xba, 0x33, 0x28, 0xef, 0xa6, 0x12, 0x9b, 0xe9, 0x69, 0xc7, 0x01, 0x5f, 0xa1, 0x80, 0xa7, + 0xf1, 0xe5, 0x40, 0xc0, 0xec, 0x56, 0x96, 0x1e, 0xb1, 0x89, 0xff, 0x18, 0x7f, 0x8d, 0x00, 0x9a, + 0x17, 0x3e, 0x9e, 0xef, 0x2e, 0x91, 0x6f, 0x75, 0x89, 0x5d, 0xe9, 0xcf, 0xb8, 0xaf, 0x66, 0xe6, + 0xdb, 0xc2, 0x53, 0x04, 0x51, 0xdf, 0x5d, 0x8d, 0xc5, 0xce, 0x49, 0x82, 0x36, 0x81, 0x98, 0xd4, + 0xb7, 0x3d, 0xc7, 0x35, 0x4f, 0x71, 0xbd, 0x8e, 0x2f, 0x05, 0xe2, 0xaa, 0xd6, 0x7d, 0x9a, 0x72, + 0xfd, 0x8a, 0xe0, 0xa4, 0x7b, 0x05, 0xe1, 0x37, 0x3a, 0xa7, 0x6a, 0xb9, 0xfe, 0x63, 0x73, 0xfd, + 0x98, 0x72, 0x40, 0xeb, 0x14, 0x50, 0x0a, 0xdf, 0x3e, 0x6a, 0xc7, 0xb9, 0x37, 0x23, 0xfe, 0x1e, + 0x41, 0xd4, 0x77, 0xdf, 0x76, 0x53, 0x33, 0x68, 0x43, 0xe8, 0xa6, 0x66, 0xe0, 0x45, 0x2e, 0x4c, + 0x53, 0xf0, 0x09, 0x1c, 0x0f, 0x04, 0xdf, 0xbc, 0xb3, 0x7f, 0x41, 0x30, 0xe2, 0x99, 0xee, 0xb8, + 0x4b, 0x2f, 0xb5, 0xdf, 0xc6, 0xb1, 0xab, 0x7d, 0x5a, 0x73, 0x50, 0xcb, 0x14, 0xd4, 0x12, 0x4e, + 0x06, 0x82, 0xf2, 0xdd, 0x59, 0xad, 0x62, 0xe2, 0x1f, 0x10, 0x44, 0x7c, 0xd7, 0x50, 0x7f, 0xb9, + 0x1b, 0x0a, 0x8a, 0xfd, 0x9a, 0x73, 0xac, 0x73, 0x14, 0xeb, 0x65, 0x2c, 0xf4, 0xc6, 0x9a, 0xda, + 0x78, 0xb6, 0x1f, 0x47, 0xcf, 0xf7, 0xe3, 0xe8, 0xef, 0xfd, 0x38, 0xfa, 0xf6, 0x20, 0x3e, 0xf4, + 0xfc, 0x20, 0x3e, 0xf4, 0xe7, 0x41, 0x7c, 0xe8, 0x41, 0xb2, 0xf7, 0x12, 0xbb, 0xdb, 0x0c, 0x4c, + 0xf7, 0x59, 0x2d, 0x4c, 0xff, 0x67, 0xb3, 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1a, 0x6c, + 0x72, 0x7b, 0x91, 0x12, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -3129,10 +3129,10 @@ func (m *QueryListPublicRandomnessResponse) Unmarshal(dAtA []byte) error { return io.ErrUnexpectedEOF } if m.PubRandMap == nil { - m.PubRandMap = make(map[uint64]*github_com_babylonchain_babylon_types.SchnorrPubRand) + m.PubRandMap = make(map[uint64]*github_com_babylonlabs_io_babylon_types.SchnorrPubRand) } var mapkey uint64 - var mapvalue1 github_com_babylonchain_babylon_types.SchnorrPubRand + var mapvalue1 github_com_babylonlabs_io_babylon_types.SchnorrPubRand var mapvalue = &mapvalue1 for iNdEx < postIndex { entryPreIndex := iNdEx @@ -3213,7 +3213,7 @@ func (m *QueryListPublicRandomnessResponse) Unmarshal(dAtA []byte) error { iNdEx += skippy } } - m.PubRandMap[mapkey] = ((*github_com_babylonchain_babylon_types.SchnorrPubRand)(mapvalue)) + m.PubRandMap[mapkey] = ((*github_com_babylonlabs_io_babylon_types.SchnorrPubRand)(mapvalue)) iNdEx = postIndex case 2: if wireType != 2 { @@ -4201,7 +4201,7 @@ func (m *QueryVotesAtHeightResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.BtcPks = append(m.BtcPks, v) if err := m.BtcPks[len(m.BtcPks)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/finality/types/signing_info.go b/x/finality/types/signing_info.go index 9d0f41b90..72cbe4cd1 100644 --- a/x/finality/types/signing_info.go +++ b/x/finality/types/signing_info.go @@ -1,7 +1,7 @@ package types import ( - bbntypes "github.com/babylonchain/babylon/types" + bbntypes "github.com/babylonlabs-io/babylon/types" ) // NewFinalityProviderSigningInfo creates a new FinalityProviderSigningInfo instance diff --git a/x/finality/types/tx.pb.go b/x/finality/types/tx.pb.go index ae1564fc9..a4768d48e 100644 --- a/x/finality/types/tx.pb.go +++ b/x/finality/types/tx.pb.go @@ -6,7 +6,7 @@ package types import ( context "context" fmt "fmt" - github_com_babylonchain_babylon_types "github.com/babylonchain/babylon/types" + github_com_babylonlabs_io_babylon_types "github.com/babylonlabs-io/babylon/types" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" @@ -36,7 +36,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type MsgCommitPubRandList struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` // fp_btc_pk is the BTC PK of the finality provider that commits the public randomness - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // start_height is the start block height of the list of public randomness StartHeight uint64 `protobuf:"varint,3,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` // num_pub_rand is the number of public randomness committed @@ -49,7 +49,7 @@ type MsgCommitPubRandList struct { // randomness on behalf of fp_btc_pk // TODO: another option is to restrict signer to correspond to fp_btc_pk. This restricts // the tx submitter to be the holder of fp_btc_pk. Decide this later - Sig *github_com_babylonchain_babylon_types.BIP340Signature `protobuf:"bytes,6,opt,name=sig,proto3,customtype=github.com/babylonchain/babylon/types.BIP340Signature" json:"sig,omitempty"` + Sig *github_com_babylonlabs_io_babylon_types.BIP340Signature `protobuf:"bytes,6,opt,name=sig,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340Signature" json:"sig,omitempty"` } func (m *MsgCommitPubRandList) Reset() { *m = MsgCommitPubRandList{} } @@ -154,11 +154,11 @@ var xxx_messageInfo_MsgCommitPubRandListResponse proto.InternalMessageInfo type MsgAddFinalitySig struct { Signer string `protobuf:"bytes,1,opt,name=signer,proto3" json:"signer,omitempty"` // fp_btc_pk is the BTC PK of the finality provider that casts this vote - FpBtcPk *github_com_babylonchain_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonchain/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` + FpBtcPk *github_com_babylonlabs_io_babylon_types.BIP340PubKey `protobuf:"bytes,2,opt,name=fp_btc_pk,json=fpBtcPk,proto3,customtype=github.com/babylonlabs-io/babylon/types.BIP340PubKey" json:"fp_btc_pk,omitempty"` // block_height is the height of the voted block BlockHeight uint64 `protobuf:"varint,3,opt,name=block_height,json=blockHeight,proto3" json:"block_height,omitempty"` // pub_rand is the public randomness committed at this height - PubRand *github_com_babylonchain_babylon_types.SchnorrPubRand `protobuf:"bytes,4,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` + PubRand *github_com_babylonlabs_io_babylon_types.SchnorrPubRand `protobuf:"bytes,4,opt,name=pub_rand,json=pubRand,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrPubRand" json:"pub_rand,omitempty"` // proof is the proof that the given public randomness is committed under the commitment Proof *crypto.Proof `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` // block_app_hash is the AppHash of the voted block @@ -167,7 +167,7 @@ type MsgAddFinalitySig struct { // where finality signature is an EOTS signature, i.e., // the `s` in a Schnorr signature `(r, s)` // `r` is the public randomness that is already committed by the finality provider - FinalitySig *github_com_babylonchain_babylon_types.SchnorrEOTSSig `protobuf:"bytes,7,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonchain/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` + FinalitySig *github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig `protobuf:"bytes,7,opt,name=finality_sig,json=finalitySig,proto3,customtype=github.com/babylonlabs-io/babylon/types.SchnorrEOTSSig" json:"finality_sig,omitempty"` } func (m *MsgAddFinalitySig) Reset() { *m = MsgAddFinalitySig{} } @@ -377,52 +377,52 @@ func init() { func init() { proto.RegisterFile("babylon/finality/v1/tx.proto", fileDescriptor_2dd6da066b6baf1d) } var fileDescriptor_2dd6da066b6baf1d = []byte{ - // 712 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x4f, 0x4f, 0x13, 0x4d, - 0x1c, 0xee, 0x52, 0x28, 0x2f, 0xd3, 0x86, 0x37, 0xec, 0x4b, 0x5e, 0x96, 0x82, 0xdb, 0xda, 0x10, - 0x83, 0x44, 0x77, 0xa1, 0x20, 0x11, 0x6e, 0xd4, 0x68, 0x50, 0x6c, 0x6c, 0xb6, 0x7a, 0xd1, 0xc3, - 0x66, 0xff, 0x75, 0x76, 0x02, 0x3b, 0x33, 0xee, 0xcc, 0x12, 0x7a, 0x33, 0x7e, 0x02, 0x0f, 0x7e, - 0x10, 0x0e, 0x26, 0x9e, 0xbd, 0x71, 0x31, 0x21, 0x9e, 0x0c, 0x87, 0xc6, 0xc0, 0x81, 0xaf, 0x61, - 0x76, 0x77, 0x4a, 0x29, 0x94, 0x58, 0x3d, 0x78, 0xdb, 0x99, 0xdf, 0x33, 0xf3, 0x3c, 0xfb, 0x7b, - 0x9e, 0xdf, 0x80, 0x79, 0xdb, 0xb2, 0xdb, 0x7b, 0x04, 0xeb, 0x2d, 0x84, 0xad, 0x3d, 0xc4, 0xdb, - 0xfa, 0xfe, 0x8a, 0xce, 0x0f, 0x34, 0x1a, 0x12, 0x4e, 0xe4, 0xff, 0x44, 0x55, 0xeb, 0x56, 0xb5, - 0xfd, 0x95, 0xe2, 0x34, 0x24, 0x90, 0x24, 0x75, 0x3d, 0xfe, 0x4a, 0xa1, 0xc5, 0x5b, 0xdc, 0xc3, - 0xae, 0x17, 0x06, 0x08, 0x73, 0xdd, 0x09, 0xdb, 0x94, 0x13, 0x9d, 0x86, 0x84, 0xb4, 0x44, 0x79, - 0xd6, 0x21, 0x2c, 0x20, 0xcc, 0x4c, 0xcf, 0xa5, 0x0b, 0x51, 0x9a, 0x49, 0x57, 0x7a, 0xc0, 0x60, - 0x4c, 0x1e, 0x30, 0x28, 0x0a, 0xe5, 0x41, 0xda, 0xa8, 0x15, 0x5a, 0x81, 0x38, 0x5a, 0xf9, 0x32, - 0x02, 0xa6, 0xeb, 0x0c, 0x3e, 0x22, 0x41, 0x80, 0x78, 0x23, 0xb2, 0x0d, 0x0b, 0xbb, 0xcf, 0x11, - 0xe3, 0xf2, 0xff, 0x20, 0xc7, 0x10, 0xc4, 0x5e, 0xa8, 0x48, 0x65, 0x69, 0x71, 0xc2, 0x10, 0x2b, - 0xd9, 0x00, 0x13, 0x2d, 0x6a, 0xda, 0xdc, 0x31, 0xe9, 0xae, 0x32, 0x52, 0x96, 0x16, 0x0b, 0xb5, - 0xf5, 0x93, 0x4e, 0xa9, 0x0a, 0x11, 0xf7, 0x23, 0x5b, 0x73, 0x48, 0xa0, 0x0b, 0x52, 0xc7, 0xb7, - 0x10, 0xee, 0x2e, 0x74, 0xde, 0xa6, 0x1e, 0xd3, 0x6a, 0x4f, 0x1b, 0xab, 0x6b, 0xcb, 0x8d, 0xc8, - 0xde, 0xf1, 0xda, 0xc6, 0x78, 0x8b, 0xd6, 0xb8, 0xd3, 0xd8, 0x95, 0x6f, 0x83, 0x02, 0xe3, 0x56, - 0xc8, 0x4d, 0xdf, 0x43, 0xd0, 0xe7, 0x4a, 0xb6, 0x2c, 0x2d, 0x8e, 0x1a, 0xf9, 0x64, 0x6f, 0x3b, - 0xd9, 0x92, 0xcb, 0xa0, 0x80, 0xa3, 0xc0, 0xa4, 0x91, 0x6d, 0x86, 0x16, 0x76, 0x95, 0xd1, 0x04, - 0x02, 0x70, 0x14, 0x08, 0xd1, 0xb2, 0x0a, 0x80, 0x93, 0xfc, 0x45, 0xe0, 0x61, 0xae, 0x8c, 0xc5, - 0xca, 0x8c, 0x4b, 0x3b, 0xf2, 0x0e, 0xc8, 0x32, 0x04, 0x95, 0x5c, 0x22, 0x79, 0xe3, 0xa4, 0x53, - 0x7a, 0xf0, 0x3b, 0x92, 0x9b, 0x08, 0x62, 0x8b, 0x47, 0xa1, 0x67, 0xc4, 0xb7, 0x6c, 0xe6, 0xdf, - 0x9f, 0x1f, 0x2e, 0x89, 0x96, 0x54, 0x54, 0x30, 0x3f, 0xa8, 0x85, 0x86, 0xc7, 0x28, 0xc1, 0xcc, - 0xab, 0x7c, 0xce, 0x82, 0xa9, 0x3a, 0x83, 0x5b, 0xae, 0xfb, 0x44, 0xd8, 0xd0, 0x44, 0xf0, 0x6f, - 0x37, 0xd8, 0xde, 0x23, 0xce, 0xee, 0x95, 0x06, 0x27, 0x7b, 0xa2, 0xc1, 0x4d, 0xf0, 0x4f, 0x5f, - 0x73, 0x0b, 0xb5, 0x87, 0x27, 0x9d, 0xd2, 0xda, 0x70, 0xac, 0x4d, 0xc7, 0xc7, 0x24, 0x0c, 0xc5, - 0xcf, 0x1b, 0xe3, 0x54, 0x78, 0xa2, 0x81, 0xb1, 0x24, 0xc2, 0x89, 0x1d, 0xf9, 0xaa, 0xa2, 0xf5, - 0x22, 0xae, 0xa5, 0x11, 0xd7, 0x1a, 0x71, 0xdd, 0x48, 0x61, 0xf2, 0x02, 0x98, 0x4c, 0x75, 0x5a, - 0x94, 0x9a, 0xbe, 0xc5, 0xfc, 0xd4, 0x2e, 0x23, 0x55, 0xbf, 0x45, 0xe9, 0xb6, 0xc5, 0x7c, 0xf9, - 0x0d, 0x28, 0x74, 0xf3, 0x6c, 0xc6, 0x96, 0x8e, 0xff, 0xa1, 0xdc, 0xc7, 0x2f, 0x5e, 0x36, 0x9b, - 0x08, 0x1a, 0xf9, 0x56, 0xcf, 0x96, 0x7e, 0x67, 0xe7, 0xc0, 0xec, 0x35, 0xe3, 0x2e, 0x6c, 0xfd, - 0x28, 0x81, 0x7f, 0xeb, 0x0c, 0xbe, 0xa2, 0xae, 0xc5, 0xbd, 0x46, 0x32, 0x54, 0xf2, 0x3a, 0x98, - 0xb0, 0x22, 0xee, 0x93, 0x10, 0xf1, 0x76, 0xea, 0x6b, 0x4d, 0xf9, 0xf6, 0xe9, 0xfe, 0xb4, 0x18, - 0xd7, 0x2d, 0xd7, 0x0d, 0x3d, 0xc6, 0x9a, 0x3c, 0x44, 0x18, 0x1a, 0x3d, 0xa8, 0xbc, 0x01, 0x72, - 0xe9, 0x58, 0x26, 0x8e, 0xe7, 0xab, 0x73, 0xda, 0x80, 0x77, 0x43, 0x4b, 0x49, 0x6a, 0xa3, 0x47, - 0x9d, 0x52, 0xc6, 0x10, 0x07, 0x36, 0x27, 0x63, 0xc1, 0xbd, 0xab, 0x2a, 0xb3, 0x60, 0xe6, 0x8a, - 0xaa, 0xae, 0xe2, 0xea, 0xd7, 0x11, 0x90, 0xad, 0x33, 0x28, 0xbf, 0x05, 0x53, 0xd7, 0x07, 0xfe, - 0xee, 0x40, 0xca, 0x41, 0xc1, 0x2e, 0xae, 0x0c, 0x0d, 0xed, 0x52, 0xcb, 0x3e, 0x98, 0xbc, 0x92, - 0xff, 0x3b, 0x37, 0x5d, 0xd2, 0x8f, 0x2b, 0x6a, 0xc3, 0xe1, 0x2e, 0x98, 0x6c, 0x50, 0xe8, 0xb3, - 0x64, 0xe1, 0xa6, 0xf3, 0x97, 0x51, 0xc5, 0x7b, 0xc3, 0xa0, 0xba, 0x1c, 0xc5, 0xb1, 0x77, 0xe7, - 0x87, 0x4b, 0x52, 0xed, 0xd9, 0xd1, 0xa9, 0x2a, 0x1d, 0x9f, 0xaa, 0xd2, 0x8f, 0x53, 0x55, 0xfa, - 0x70, 0xa6, 0x66, 0x8e, 0xcf, 0xd4, 0xcc, 0xf7, 0x33, 0x35, 0xf3, 0x7a, 0xf9, 0x57, 0x41, 0x3c, - 0xe8, 0x3d, 0xc9, 0x49, 0x26, 0xed, 0x5c, 0xf2, 0x1e, 0xaf, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, - 0x95, 0x73, 0xec, 0x64, 0x4f, 0x06, 0x00, 0x00, + // 714 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0x4f, 0x4f, 0x13, 0x4f, + 0x18, 0xee, 0x52, 0x28, 0x3f, 0xa6, 0x0d, 0xbf, 0xb0, 0x12, 0x59, 0x0a, 0x6e, 0x6b, 0x43, 0x0c, + 0x12, 0xd9, 0x95, 0x42, 0x50, 0xf1, 0x44, 0x8d, 0x06, 0x23, 0x8d, 0xcd, 0x16, 0x2e, 0x26, 0x66, + 0xb3, 0xff, 0x3a, 0x3b, 0xa1, 0xbb, 0x33, 0xce, 0xcc, 0x12, 0x7a, 0x33, 0x7e, 0x02, 0x0f, 0x7e, + 0x10, 0x0e, 0x5e, 0x3d, 0x9a, 0x70, 0x31, 0x21, 0x9e, 0x0c, 0x87, 0xc6, 0xc0, 0x81, 0xaf, 0x61, + 0xba, 0x3b, 0xa5, 0x14, 0x4a, 0xac, 0x1e, 0xbc, 0xed, 0xbc, 0xef, 0xf3, 0xce, 0xf3, 0xec, 0xfb, + 0xbc, 0xef, 0x80, 0x79, 0xdb, 0xb2, 0x5b, 0x4d, 0x1c, 0xea, 0x0d, 0x14, 0x5a, 0x4d, 0xc4, 0x5b, + 0xfa, 0xfe, 0x8a, 0xce, 0x0f, 0x34, 0x42, 0x31, 0xc7, 0xf2, 0x2d, 0x91, 0xd5, 0xba, 0x59, 0x6d, + 0x7f, 0x25, 0x3f, 0x0d, 0x31, 0xc4, 0x71, 0x5e, 0xef, 0x7c, 0x25, 0xd0, 0xfc, 0x1d, 0xee, 0x85, + 0xae, 0x47, 0x03, 0x14, 0x72, 0xdd, 0xa1, 0x2d, 0xc2, 0xb1, 0x4e, 0x28, 0xc6, 0x0d, 0x91, 0x9e, + 0x75, 0x30, 0x0b, 0x30, 0x33, 0x93, 0xba, 0xe4, 0x20, 0x52, 0x33, 0xc9, 0x49, 0x0f, 0x18, 0xec, + 0x90, 0x07, 0x0c, 0x8a, 0x44, 0x71, 0x90, 0x36, 0x62, 0x51, 0x2b, 0x10, 0xa5, 0xa5, 0xaf, 0x23, + 0x60, 0xba, 0xca, 0xe0, 0x33, 0x1c, 0x04, 0x88, 0xd7, 0x22, 0xdb, 0xb0, 0x42, 0x77, 0x1b, 0x31, + 0x2e, 0xdf, 0x06, 0x19, 0x86, 0x60, 0xe8, 0x51, 0x45, 0x2a, 0x4a, 0x8b, 0x13, 0x86, 0x38, 0xc9, + 0x3b, 0x60, 0xa2, 0x41, 0x4c, 0x9b, 0x3b, 0x26, 0xd9, 0x53, 0x46, 0x8a, 0xd2, 0x62, 0xae, 0xf2, + 0xf8, 0xa4, 0x5d, 0x58, 0x83, 0x88, 0xfb, 0x91, 0xad, 0x39, 0x38, 0xd0, 0x05, 0x69, 0xd3, 0xb2, + 0xd9, 0x32, 0xc2, 0xdd, 0xa3, 0xce, 0x5b, 0xc4, 0x63, 0x5a, 0xe5, 0x65, 0x6d, 0x75, 0xed, 0x61, + 0x2d, 0xb2, 0x5f, 0x79, 0x2d, 0x63, 0xbc, 0x41, 0x2a, 0xdc, 0xa9, 0xed, 0xc9, 0x77, 0x41, 0x8e, + 0x71, 0x8b, 0x72, 0xd3, 0xf7, 0x10, 0xf4, 0xb9, 0x92, 0x2e, 0x4a, 0x8b, 0xa3, 0x46, 0x36, 0x8e, + 0x6d, 0xc5, 0x21, 0xb9, 0x08, 0x72, 0x61, 0x14, 0x98, 0x24, 0xb2, 0x4d, 0x6a, 0x85, 0xae, 0x32, + 0x1a, 0x43, 0x40, 0x18, 0x05, 0x42, 0xb6, 0xac, 0x02, 0xe0, 0xc4, 0xff, 0x11, 0x78, 0x21, 0x57, + 0xc6, 0x3a, 0xda, 0x8c, 0x4b, 0x11, 0xb9, 0x0a, 0xd2, 0x0c, 0x41, 0x25, 0x13, 0x8b, 0x7e, 0x7a, + 0xd2, 0x2e, 0x3c, 0xfa, 0x33, 0xd1, 0x75, 0x04, 0x43, 0x8b, 0x47, 0xd4, 0x33, 0x3a, 0xf7, 0x6c, + 0x64, 0x3f, 0x9c, 0x1f, 0x2e, 0x89, 0xb6, 0x94, 0x54, 0x30, 0x3f, 0xa8, 0x8d, 0x86, 0xc7, 0x08, + 0x0e, 0x99, 0x57, 0xfa, 0x92, 0x06, 0x53, 0x55, 0x06, 0x37, 0x5d, 0xf7, 0x85, 0xb0, 0xa2, 0x8e, + 0xe0, 0xbf, 0x6f, 0xb2, 0xdd, 0xc4, 0xce, 0xde, 0x95, 0x26, 0xc7, 0x31, 0xd1, 0xe4, 0x5d, 0xf0, + 0x5f, 0x5f, 0x83, 0x73, 0x95, 0x8d, 0x93, 0x76, 0x61, 0x7d, 0x58, 0xde, 0xba, 0xe3, 0x87, 0x98, + 0x52, 0xd1, 0x00, 0x63, 0x9c, 0x08, 0x67, 0x34, 0x30, 0x16, 0x8f, 0x72, 0x6c, 0x4a, 0xb6, 0xac, + 0x68, 0xbd, 0x51, 0xd7, 0x92, 0x51, 0xd7, 0x6a, 0x9d, 0xbc, 0x91, 0xc0, 0xe4, 0x05, 0x30, 0x99, + 0x28, 0xb5, 0x08, 0x31, 0x7d, 0x8b, 0xf9, 0x89, 0x69, 0x46, 0xa2, 0x7f, 0x93, 0x90, 0x2d, 0x8b, + 0xf9, 0xf2, 0x5b, 0x90, 0xeb, 0xce, 0xb5, 0xd9, 0x31, 0x76, 0xfc, 0xaf, 0x05, 0x3f, 0x7f, 0xbd, + 0x53, 0xaf, 0x23, 0x68, 0x64, 0x1b, 0x3d, 0x73, 0xfa, 0xfd, 0x9d, 0x03, 0xb3, 0xd7, 0xec, 0xbb, + 0x30, 0xf7, 0x93, 0x04, 0xfe, 0xaf, 0x32, 0xb8, 0x4b, 0x5c, 0x8b, 0x7b, 0xb5, 0x78, 0xbd, 0xe4, + 0x75, 0x30, 0x61, 0x45, 0xdc, 0xc7, 0x14, 0xf1, 0x56, 0xe2, 0x6e, 0x45, 0xf9, 0xfe, 0x79, 0x79, + 0x5a, 0x2c, 0xee, 0xa6, 0xeb, 0x52, 0x8f, 0xb1, 0x3a, 0xa7, 0x28, 0x84, 0x46, 0x0f, 0x2a, 0x3f, + 0x01, 0x99, 0x64, 0x41, 0x63, 0xdf, 0xb3, 0xe5, 0x39, 0x6d, 0xc0, 0x0b, 0xa2, 0x25, 0x24, 0x95, + 0xd1, 0xa3, 0x76, 0x21, 0x65, 0x88, 0x82, 0x8d, 0xc9, 0x8e, 0xe0, 0xde, 0x55, 0xa5, 0x59, 0x30, + 0x73, 0x45, 0x55, 0x57, 0x71, 0xf9, 0xdb, 0x08, 0x48, 0x57, 0x19, 0x94, 0xdf, 0x81, 0xa9, 0xeb, + 0xab, 0x7f, 0x7f, 0x20, 0xe5, 0xa0, 0xf1, 0xce, 0xaf, 0x0c, 0x0d, 0xed, 0x52, 0xcb, 0x3e, 0x98, + 0xbc, 0xb2, 0x05, 0xf7, 0x6e, 0xba, 0xa4, 0x1f, 0x97, 0xd7, 0x86, 0xc3, 0x5d, 0x30, 0xd9, 0x20, + 0xd7, 0x67, 0xc9, 0xc2, 0x4d, 0xf5, 0x97, 0x51, 0xf9, 0x07, 0xc3, 0xa0, 0xba, 0x1c, 0xf9, 0xb1, + 0xf7, 0xe7, 0x87, 0x4b, 0x52, 0x65, 0xfb, 0xe8, 0x54, 0x95, 0x8e, 0x4f, 0x55, 0xe9, 0xe7, 0xa9, + 0x2a, 0x7d, 0x3c, 0x53, 0x53, 0xc7, 0x67, 0x6a, 0xea, 0xc7, 0x99, 0x9a, 0x7a, 0x53, 0xfe, 0xfd, + 0x28, 0x1e, 0xf4, 0x9e, 0xe7, 0x78, 0x2a, 0xed, 0x4c, 0xfc, 0x36, 0xaf, 0xfe, 0x0a, 0x00, 0x00, + 0xff, 0xff, 0x0a, 0x87, 0xfa, 0xed, 0x5b, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1071,7 +1071,7 @@ func (m *MsgCommitPubRandList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1178,7 +1178,7 @@ func (m *MsgCommitPubRandList) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340Signature + var v github_com_babylonlabs_io_babylon_types.BIP340Signature m.Sig = &v if err := m.Sig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1345,7 +1345,7 @@ func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.BIP340PubKey + var v github_com_babylonlabs_io_babylon_types.BIP340PubKey m.FpBtcPk = &v if err := m.FpBtcPk.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1399,7 +1399,7 @@ func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrPubRand + var v github_com_babylonlabs_io_babylon_types.SchnorrPubRand m.PubRand = &v if err := m.PubRand.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err @@ -1504,7 +1504,7 @@ func (m *MsgAddFinalitySig) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - var v github_com_babylonchain_babylon_types.SchnorrEOTSSig + var v github_com_babylonlabs_io_babylon_types.SchnorrEOTSSig m.FinalitySig = &v if err := m.FinalitySig.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err diff --git a/x/incentive/abci.go b/x/incentive/abci.go index 66cdb7da9..7967e1f43 100644 --- a/x/incentive/abci.go +++ b/x/incentive/abci.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/babylonchain/babylon/x/incentive/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/telemetry" sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/incentive/client/cli/query.go b/x/incentive/client/cli/query.go index de89a08d9..7831a6d71 100644 --- a/x/incentive/client/cli/query.go +++ b/x/incentive/client/cli/query.go @@ -4,7 +4,7 @@ import ( "fmt" "strconv" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" diff --git a/x/incentive/client/cli/query_params.go b/x/incentive/client/cli/query_params.go index f6c20a168..377f02715 100644 --- a/x/incentive/client/cli/query_params.go +++ b/x/incentive/client/cli/query_params.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" ) func CmdQueryParams() *cobra.Command { diff --git a/x/incentive/client/cli/tx.go b/x/incentive/client/cli/tx.go index d039820c2..b3f12788d 100644 --- a/x/incentive/client/cli/tx.go +++ b/x/incentive/client/cli/tx.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" diff --git a/x/incentive/genesis.go b/x/incentive/genesis.go index 1122dbdba..a078143ca 100644 --- a/x/incentive/genesis.go +++ b/x/incentive/genesis.go @@ -2,8 +2,8 @@ package incentive import ( "context" - "github.com/babylonchain/babylon/x/incentive/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" ) // InitGenesis initializes the module's state from a provided genesis state. diff --git a/x/incentive/genesis_test.go b/x/incentive/genesis_test.go index bb3f7e509..7bd9ca000 100644 --- a/x/incentive/genesis_test.go +++ b/x/incentive/genesis_test.go @@ -3,10 +3,10 @@ package incentive_test import ( "testing" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/incentive" - "github.com/babylonchain/babylon/x/incentive/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/incentive" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/keeper/btc_staking_gauge.go b/x/incentive/keeper/btc_staking_gauge.go index 481cf9b63..4992ef782 100644 --- a/x/incentive/keeper/btc_staking_gauge.go +++ b/x/incentive/keeper/btc_staking_gauge.go @@ -4,8 +4,8 @@ import ( "context" "cosmossdk.io/store/prefix" - bstypes "github.com/babylonchain/babylon/x/btcstaking/types" - "github.com/babylonchain/babylon/x/incentive/types" + bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/incentive/keeper/btc_staking_gauge_test.go b/x/incentive/keeper/btc_staking_gauge_test.go index bd7585324..957886b93 100644 --- a/x/incentive/keeper/btc_staking_gauge_test.go +++ b/x/incentive/keeper/btc_staking_gauge_test.go @@ -4,9 +4,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" diff --git a/x/incentive/keeper/btc_timestamping_gauge.go b/x/incentive/keeper/btc_timestamping_gauge.go index 96e5b28a7..d4ed4f01d 100644 --- a/x/incentive/keeper/btc_timestamping_gauge.go +++ b/x/incentive/keeper/btc_timestamping_gauge.go @@ -4,8 +4,8 @@ import ( "context" "cosmossdk.io/math" "cosmossdk.io/store/prefix" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - "github.com/babylonchain/babylon/x/incentive/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/incentive/keeper/btc_timestamping_gauge_test.go b/x/incentive/keeper/btc_timestamping_gauge_test.go index 3b42cae19..84d962b65 100644 --- a/x/incentive/keeper/btc_timestamping_gauge_test.go +++ b/x/incentive/keeper/btc_timestamping_gauge_test.go @@ -5,9 +5,9 @@ import ( "testing" "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" diff --git a/x/incentive/keeper/grpc_query.go b/x/incentive/keeper/grpc_query.go index 341359b7d..3f1274d3b 100644 --- a/x/incentive/keeper/grpc_query.go +++ b/x/incentive/keeper/grpc_query.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/incentive/keeper/grpc_query_test.go b/x/incentive/keeper/grpc_query_test.go index 9d609f307..048a7ad55 100644 --- a/x/incentive/keeper/grpc_query_test.go +++ b/x/incentive/keeper/grpc_query_test.go @@ -4,9 +4,9 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/keeper/intercept_fee_collector.go b/x/incentive/keeper/intercept_fee_collector.go index 88500e558..05cc6c5be 100644 --- a/x/incentive/keeper/intercept_fee_collector.go +++ b/x/incentive/keeper/intercept_fee_collector.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" ) // HandleCoinsInFeeCollector intercepts a portion of coins in fee collector, and distributes diff --git a/x/incentive/keeper/intercept_fee_collector_test.go b/x/incentive/keeper/intercept_fee_collector_test.go index 189be6ba1..2f583caa2 100644 --- a/x/incentive/keeper/intercept_fee_collector_test.go +++ b/x/incentive/keeper/intercept_fee_collector_test.go @@ -6,10 +6,10 @@ import ( sdkmath "cosmossdk.io/math" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/golang/mock/gomock" diff --git a/x/incentive/keeper/keeper.go b/x/incentive/keeper/keeper.go index 4d931f4fe..9929989cd 100644 --- a/x/incentive/keeper/keeper.go +++ b/x/incentive/keeper/keeper.go @@ -5,7 +5,7 @@ import ( "fmt" "cosmossdk.io/log" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/incentive/keeper/msg_server.go b/x/incentive/keeper/msg_server.go index 3d9ff5399..5dfe5833e 100644 --- a/x/incentive/keeper/msg_server.go +++ b/x/incentive/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( "context" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "google.golang.org/grpc/codes" diff --git a/x/incentive/keeper/msg_server_test.go b/x/incentive/keeper/msg_server_test.go index 5b68ded8d..78a0783a9 100644 --- a/x/incentive/keeper/msg_server_test.go +++ b/x/incentive/keeper/msg_server_test.go @@ -5,10 +5,10 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/keeper/params.go b/x/incentive/keeper/params.go index 4e8c80e72..aac26aec0 100644 --- a/x/incentive/keeper/params.go +++ b/x/incentive/keeper/params.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" ) // SetParams sets the x/incentive module parameters. diff --git a/x/incentive/keeper/params_test.go b/x/incentive/keeper/params_test.go index e2ee0a1da..e6196521a 100644 --- a/x/incentive/keeper/params_test.go +++ b/x/incentive/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/keeper/query_params.go b/x/incentive/keeper/query_params.go index b58c8c1ec..18b4fe8f4 100644 --- a/x/incentive/keeper/query_params.go +++ b/x/incentive/keeper/query_params.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/incentive/keeper/query_params_test.go b/x/incentive/keeper/query_params_test.go index c98188c76..ec943cc99 100644 --- a/x/incentive/keeper/query_params_test.go +++ b/x/incentive/keeper/query_params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/keeper/reward_gauge.go b/x/incentive/keeper/reward_gauge.go index d06cbf3fd..57c598150 100644 --- a/x/incentive/keeper/reward_gauge.go +++ b/x/incentive/keeper/reward_gauge.go @@ -3,7 +3,7 @@ package keeper import ( "context" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/incentive/keeper/reward_gauge_test.go b/x/incentive/keeper/reward_gauge_test.go index 74a840c13..53bf8f34b 100644 --- a/x/incentive/keeper/reward_gauge_test.go +++ b/x/incentive/keeper/reward_gauge_test.go @@ -3,7 +3,7 @@ package keeper_test import ( "testing" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/module.go b/x/incentive/module.go index 862daf4ff..254a95231 100644 --- a/x/incentive/module.go +++ b/x/incentive/module.go @@ -6,9 +6,9 @@ import ( "encoding/json" "fmt" - "github.com/babylonchain/babylon/x/incentive/client/cli" - "github.com/babylonchain/babylon/x/incentive/keeper" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/client/cli" + "github.com/babylonlabs-io/babylon/x/incentive/keeper" + "github.com/babylonlabs-io/babylon/x/incentive/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" diff --git a/x/incentive/types/expected_keepers.go b/x/incentive/types/expected_keepers.go index a8000ec2d..434a96c0d 100644 --- a/x/incentive/types/expected_keepers.go +++ b/x/incentive/types/expected_keepers.go @@ -2,7 +2,7 @@ package types import ( "context" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/incentive/types/genesis.pb.go b/x/incentive/types/genesis.pb.go index d2c7b135c..223029c7b 100644 --- a/x/incentive/types/genesis.pb.go +++ b/x/incentive/types/genesis.pb.go @@ -75,7 +75,7 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/genesis.proto", fileDescriptor_41d5400dc6b4b931) } var fileDescriptor_41d5400dc6b4b931 = []byte{ - // 195 bytes of a gzipped FileDescriptorProto + // 197 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xcf, 0xcc, 0x4b, 0x4e, 0xcd, 0x2b, 0xc9, 0x2c, 0x4b, 0xd5, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x84, 0x2a, 0xd0, @@ -83,12 +83,12 @@ var fileDescriptor_41d5400dc6b4b931 = []byte{ 0x72, 0x98, 0x26, 0x15, 0x24, 0x16, 0x25, 0xe6, 0x42, 0x0d, 0x52, 0x72, 0xe7, 0xe2, 0x71, 0x87, 0x98, 0x1c, 0x5c, 0x92, 0x58, 0x92, 0x2a, 0x64, 0xce, 0xc5, 0x06, 0x91, 0x97, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x36, 0x92, 0xd4, 0xc3, 0xb0, 0x49, 0x2f, 0x00, 0xac, 0xc0, 0x89, 0xe5, 0xc4, 0x3d, - 0x79, 0x86, 0x20, 0xa8, 0x72, 0x27, 0xef, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, + 0x79, 0x86, 0x20, 0xa8, 0x72, 0x27, 0xdf, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, - 0x88, 0x32, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x1a, 0x96, - 0x9c, 0x91, 0x98, 0x99, 0x07, 0xe3, 0xe8, 0x57, 0x20, 0x39, 0xae, 0xa4, 0xb2, 0x20, 0xb5, 0x38, - 0x89, 0x0d, 0xec, 0x38, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8c, 0xa1, 0x97, 0x7e, 0x08, - 0x01, 0x00, 0x00, + 0x88, 0x32, 0x4e, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x1a, 0x96, + 0x93, 0x98, 0x54, 0xac, 0x9b, 0x99, 0x0f, 0xe3, 0xea, 0x57, 0x20, 0x39, 0xaf, 0xa4, 0xb2, 0x20, + 0xb5, 0x38, 0x89, 0x0d, 0xec, 0x3c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x33, 0x58, 0xf9, + 0x93, 0x0a, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/incentive/types/genesis_test.go b/x/incentive/types/genesis_test.go index 230e2c670..8f30abae3 100644 --- a/x/incentive/types/genesis_test.go +++ b/x/incentive/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/incentive/types" + "github.com/babylonlabs-io/babylon/x/incentive/types" "github.com/stretchr/testify/require" ) diff --git a/x/incentive/types/incentive.pb.go b/x/incentive/types/incentive.pb.go index 304f85dba..98d972e2e 100644 --- a/x/incentive/types/incentive.pb.go +++ b/x/incentive/types/incentive.pb.go @@ -138,7 +138,7 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/incentive.proto", fileDescriptor_3954bc4942045a7a) } var fileDescriptor_3954bc4942045a7a = []byte{ - // 269 bytes of a gzipped FileDescriptorProto + // 271 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xcf, 0xcc, 0x4b, 0x4e, 0xcd, 0x2b, 0xc9, 0x2c, 0x4b, 0x45, 0xb0, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, 0x85, 0x04, 0xa1, 0x4a, 0xf4, 0xe0, 0x12, 0x52, 0x22, 0xe9, 0xf9, @@ -151,11 +151,11 @@ var fileDescriptor_3954bc4942045a7a = []byte{ 0xa8, 0x2d, 0x10, 0x4a, 0xb7, 0x38, 0x25, 0x5b, 0xbf, 0xa4, 0xb2, 0x20, 0xb5, 0x18, 0xac, 0xa1, 0x38, 0x08, 0x62, 0xb2, 0xd2, 0x33, 0x46, 0x2e, 0xee, 0xa0, 0xd4, 0xf2, 0xc4, 0xa2, 0x14, 0x7a, 0x59, 0x29, 0x54, 0xc2, 0xc5, 0x5f, 0x9e, 0x59, 0x92, 0x91, 0x52, 0x94, 0x58, 0x9e, 0x17, 0x0f, - 0xb1, 0x8c, 0x89, 0xfa, 0x96, 0xf1, 0xc1, 0xed, 0x00, 0xf3, 0x9d, 0xbc, 0x4f, 0x3c, 0x92, 0x63, + 0xb1, 0x8c, 0x89, 0xfa, 0x96, 0xf1, 0xc1, 0xed, 0x00, 0xf3, 0x9d, 0x7c, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, - 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x10, 0xc9, 0x4c, 0x68, 0x14, 0x26, 0x67, 0x24, 0x66, - 0xe6, 0xc1, 0x38, 0xfa, 0x15, 0x48, 0x91, 0x0e, 0xb6, 0x22, 0x89, 0x0d, 0x1c, 0x51, 0xc6, 0x80, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x83, 0xc5, 0xfb, 0x16, 0x02, 0x00, 0x00, + 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x18, 0xc9, 0x4c, 0x68, 0x14, 0xe6, 0x24, 0x26, 0x15, + 0xeb, 0x66, 0xe6, 0xc3, 0xb8, 0xfa, 0x15, 0x48, 0xd1, 0x0e, 0xb6, 0x24, 0x89, 0x0d, 0x1c, 0x55, + 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd1, 0xc1, 0x22, 0xfc, 0x18, 0x02, 0x00, 0x00, } func (m *Gauge) Marshal() (dAtA []byte, err error) { diff --git a/x/incentive/types/mocked_keepers.go b/x/incentive/types/mocked_keepers.go index 833bbb50d..b0e07c0e9 100644 --- a/x/incentive/types/mocked_keepers.go +++ b/x/incentive/types/mocked_keepers.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - types "github.com/babylonchain/babylon/x/epoching/types" + types "github.com/babylonlabs-io/babylon/x/epoching/types" types0 "github.com/cosmos/cosmos-sdk/types" gomock "github.com/golang/mock/gomock" ) diff --git a/x/incentive/types/params.pb.go b/x/incentive/types/params.pb.go index a0062b8d6..ac7b99865 100644 --- a/x/incentive/types/params.pb.go +++ b/x/incentive/types/params.pb.go @@ -79,7 +79,7 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/params.proto", fileDescriptor_c42276168f0adf4b) } var fileDescriptor_c42276168f0adf4b = []byte{ - // 294 bytes of a gzipped FileDescriptorProto + // 296 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xcf, 0xcc, 0x4b, 0x4e, 0xcd, 0x2b, 0xc9, 0x2c, 0x4b, 0xd5, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x84, 0xca, 0xeb, 0xc1, @@ -93,12 +93,12 @@ var fileDescriptor_c42276168f0adf4b = []byte{ 0x31, 0x4a, 0x28, 0x86, 0x4b, 0xa0, 0x28, 0x15, 0x64, 0x2e, 0x92, 0xf1, 0x4c, 0xe4, 0x1a, 0xcf, 0x0f, 0x33, 0x0a, 0x66, 0x7a, 0x22, 0x97, 0x70, 0x52, 0x49, 0x72, 0x7c, 0x71, 0x49, 0x62, 0x76, 0x66, 0x5e, 0x3a, 0xdc, 0x02, 0x66, 0x72, 0x2d, 0x10, 0x4c, 0x2a, 0x49, 0x0e, 0x86, 0x18, 0x06, - 0xb5, 0xc2, 0x8a, 0x65, 0xc6, 0x02, 0x79, 0x06, 0x27, 0xef, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, + 0xb5, 0xc2, 0x8a, 0x65, 0xc6, 0x02, 0x79, 0x06, 0x27, 0xdf, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, - 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, - 0x87, 0x46, 0x4d, 0x72, 0x46, 0x62, 0x66, 0x1e, 0x8c, 0xa3, 0x5f, 0x81, 0x14, 0x93, 0x25, 0x95, - 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x58, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x55, 0x13, - 0x48, 0x09, 0xeb, 0x01, 0x00, 0x00, + 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4e, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, + 0x87, 0x46, 0x4d, 0x4e, 0x62, 0x52, 0xb1, 0x6e, 0x66, 0x3e, 0x8c, 0xab, 0x5f, 0x81, 0x14, 0x97, + 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x49, 0x6c, 0xe0, 0x78, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, + 0x1a, 0x83, 0x6c, 0xe6, 0xed, 0x01, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/x/incentive/types/query.pb.go b/x/incentive/types/query.pb.go index 46405c449..a0829633e 100644 --- a/x/incentive/types/query.pb.go +++ b/x/incentive/types/query.pb.go @@ -404,46 +404,46 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/query.proto", fileDescriptor_e1a59cc0c7c44135) } var fileDescriptor_e1a59cc0c7c44135 = []byte{ - // 610 bytes of a gzipped FileDescriptorProto + // 611 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0x3f, 0x6f, 0xd3, 0x40, 0x18, 0xc6, 0xe3, 0xb4, 0x09, 0xf4, 0x5a, 0x04, 0x3d, 0x22, 0xe4, 0x38, 0xc5, 0x24, 0x96, 0x40, - 0x95, 0x00, 0x5b, 0xcd, 0x1f, 0x15, 0x90, 0x00, 0x29, 0x08, 0x31, 0x20, 0x45, 0xe0, 0x76, 0x62, - 0x89, 0x2e, 0xce, 0xc9, 0xb1, 0x1a, 0xfb, 0x5c, 0xfb, 0x5c, 0x08, 0x55, 0x16, 0x3e, 0x01, 0x12, - 0x13, 0x3b, 0x0b, 0xdf, 0x82, 0xb1, 0x63, 0x25, 0x16, 0x26, 0x04, 0x09, 0x1f, 0x04, 0xe5, 0xee, - 0x1c, 0xb9, 0x8d, 0x5d, 0x5a, 0xb6, 0xf3, 0xfb, 0x3e, 0xef, 0xf3, 0xfe, 0x72, 0x7e, 0x1c, 0x70, - 0xb3, 0x87, 0x7a, 0xa3, 0x21, 0xf1, 0x0c, 0xc7, 0xb3, 0xb0, 0x47, 0x9d, 0x03, 0x6c, 0xec, 0x47, - 0x38, 0x18, 0xe9, 0x7e, 0x40, 0x28, 0x81, 0xeb, 0xa2, 0xad, 0xcf, 0xdb, 0x4a, 0xc9, 0x26, 0x36, - 0x61, 0x5d, 0x63, 0x76, 0xe2, 0x42, 0x65, 0xc3, 0x26, 0xc4, 0x1e, 0x62, 0x03, 0xf9, 0x8e, 0x81, - 0x3c, 0x8f, 0x50, 0x44, 0x1d, 0xe2, 0x85, 0xa2, 0xab, 0x2e, 0x6e, 0xf1, 0x51, 0x80, 0xdc, 0xb8, - 0x5f, 0x5b, 0xec, 0xcf, 0x4f, 0x5c, 0xa2, 0x95, 0x00, 0x7c, 0x3d, 0x03, 0x7b, 0xc5, 0xe6, 0x4c, - 0xbc, 0x1f, 0xe1, 0x90, 0x6a, 0x1d, 0x70, 0xfd, 0x44, 0x35, 0xf4, 0x89, 0x17, 0x62, 0xb8, 0x0d, - 0x8a, 0xdc, 0x5f, 0x96, 0xaa, 0xd2, 0xe6, 0x6a, 0xbd, 0xac, 0x2f, 0xfc, 0x0e, 0x9d, 0x8f, 0xb4, - 0x97, 0x8f, 0x7e, 0xde, 0xca, 0x99, 0x42, 0xae, 0x35, 0x81, 0xcc, 0xfc, 0x4c, 0xfc, 0x16, 0x05, - 0xfd, 0x17, 0x28, 0xb2, 0x71, 0xbc, 0x0b, 0xca, 0xe0, 0x12, 0xea, 0xf7, 0x03, 0x1c, 0x72, 0xd7, - 0x15, 0x33, 0x7e, 0xd4, 0x7e, 0x4b, 0xa0, 0x9c, 0x32, 0x26, 0x60, 0x2c, 0x70, 0x25, 0x60, 0xf5, - 0xae, 0xcd, 0x1a, 0xb2, 0x54, 0x5d, 0xda, 0x5c, 0xad, 0x3f, 0x49, 0x61, 0xca, 0x34, 0xd1, 0x93, - 0xc5, 0xe7, 0x1e, 0x0d, 0x46, 0xe6, 0x5a, 0x90, 0x28, 0x29, 0x5d, 0xb0, 0xbe, 0x20, 0x81, 0xd7, - 0xc0, 0xd2, 0x1e, 0x1e, 0x09, 0xda, 0xd9, 0x11, 0x36, 0x41, 0xe1, 0x00, 0x0d, 0x23, 0x2c, 0xe7, - 0xd9, 0xbd, 0xa8, 0x29, 0x0c, 0x09, 0x1b, 0x93, 0x8b, 0x1f, 0xe5, 0x1f, 0x48, 0x5a, 0x0b, 0x54, - 0x18, 0x5d, 0x7b, 0xf7, 0xd9, 0x0e, 0x45, 0x7b, 0x8e, 0x67, 0x73, 0x89, 0xb8, 0x9c, 0x1b, 0xa0, - 0x38, 0xc0, 0x8e, 0x3d, 0xa0, 0x6c, 0xdb, 0xb2, 0x29, 0x9e, 0xb4, 0x0e, 0xd8, 0x48, 0x1f, 0x13, - 0x97, 0xa3, 0x83, 0x02, 0xbb, 0x15, 0xf1, 0xa2, 0xe4, 0x14, 0x20, 0x81, 0xc2, 0x64, 0xda, 0x53, - 0x50, 0x8d, 0xfd, 0x76, 0x1d, 0x17, 0x87, 0x14, 0xb9, 0xfe, 0x69, 0x96, 0x0a, 0x58, 0xc1, 0x3e, - 0xb1, 0x06, 0x5d, 0x2f, 0x72, 0x05, 0xce, 0x65, 0x56, 0xe8, 0x44, 0xae, 0xb6, 0x03, 0x6a, 0x67, - 0x18, 0xfc, 0x1f, 0x55, 0xfd, 0x73, 0x01, 0x14, 0x98, 0x2b, 0x7c, 0x0f, 0x8a, 0x3c, 0x58, 0xf0, - 0x76, 0xd6, 0xfb, 0x3d, 0x91, 0x60, 0xe5, 0xce, 0xbf, 0x64, 0x1c, 0x49, 0xab, 0x7d, 0xf8, 0xfe, - 0xe7, 0x53, 0xbe, 0x02, 0xcb, 0x46, 0xd6, 0xb7, 0x04, 0xbf, 0x48, 0x60, 0x2d, 0x19, 0x02, 0x78, - 0xf7, 0x7c, 0x11, 0xe3, 0x20, 0xf7, 0x2e, 0x92, 0x47, 0xed, 0x21, 0xc3, 0x69, 0xc0, 0xad, 0x14, - 0x1c, 0xf1, 0x59, 0x18, 0x87, 0xe2, 0x30, 0x36, 0x92, 0xf9, 0x87, 0x5f, 0x25, 0x70, 0xf5, 0x54, - 0x1c, 0xa0, 0x9e, 0xb5, 0x3c, 0x3d, 0x6e, 0x8a, 0x71, 0x6e, 0xbd, 0xe0, 0x6d, 0x31, 0x5e, 0x03, - 0xde, 0x4f, 0xe1, 0xed, 0x51, 0xab, 0x1b, 0xf2, 0x21, 0x8e, 0x68, 0x1c, 0xf2, 0xf4, 0x8e, 0xe1, - 0x37, 0x09, 0x94, 0xd2, 0x92, 0x02, 0x1b, 0x67, 0x00, 0x64, 0x05, 0x53, 0x69, 0x5e, 0x6c, 0x48, - 0xa0, 0x3f, 0x66, 0xe8, 0xdb, 0xb0, 0x95, 0x81, 0x4e, 0x13, 0x93, 0x31, 0xff, 0x3c, 0xff, 0xe3, - 0xf6, 0xcb, 0xa3, 0x89, 0x2a, 0x1d, 0x4f, 0x54, 0xe9, 0xd7, 0x44, 0x95, 0x3e, 0x4e, 0xd5, 0xdc, - 0xf1, 0x54, 0xcd, 0xfd, 0x98, 0xaa, 0xb9, 0x37, 0x5b, 0xb6, 0x43, 0x07, 0x51, 0x4f, 0xb7, 0x88, - 0x1b, 0x5b, 0x5b, 0x03, 0xe4, 0x78, 0xf3, 0x3d, 0xef, 0x12, 0x9b, 0xe8, 0xc8, 0xc7, 0x61, 0xaf, - 0xc8, 0xfe, 0x8c, 0x1b, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x1f, 0x12, 0x0c, 0x37, 0x06, - 0x00, 0x00, + 0x95, 0xa0, 0xb6, 0xc8, 0x1f, 0x15, 0x90, 0x00, 0x29, 0x08, 0x31, 0x11, 0x81, 0xdb, 0x89, 0x25, + 0x3a, 0x27, 0x27, 0xc7, 0x6a, 0xec, 0x73, 0xed, 0x73, 0x21, 0x54, 0x59, 0xf8, 0x04, 0x48, 0x4c, + 0xec, 0x2c, 0x7c, 0x0b, 0xc6, 0x8e, 0x95, 0x58, 0x98, 0x10, 0x24, 0x7c, 0x10, 0x94, 0xbb, 0x73, + 0xe4, 0x36, 0x76, 0x69, 0xd9, 0xce, 0xef, 0xfb, 0xbc, 0xcf, 0xfb, 0xcb, 0xf9, 0x71, 0xc0, 0x4d, + 0x0b, 0x59, 0xa3, 0x21, 0xf1, 0x0c, 0xc7, 0xeb, 0x61, 0x8f, 0x3a, 0x07, 0xd8, 0xd8, 0x8f, 0x70, + 0x30, 0xd2, 0xfd, 0x80, 0x50, 0x02, 0xd7, 0x45, 0x5b, 0x9f, 0xb7, 0x95, 0x92, 0x4d, 0x6c, 0xc2, + 0xba, 0xc6, 0xec, 0xc4, 0x85, 0xca, 0x86, 0x4d, 0x88, 0x3d, 0xc4, 0x06, 0xf2, 0x1d, 0x03, 0x79, + 0x1e, 0xa1, 0x88, 0x3a, 0xc4, 0x0b, 0x45, 0x57, 0x5d, 0xdc, 0xe2, 0xa3, 0x00, 0xb9, 0x71, 0xbf, + 0xb6, 0xd8, 0x9f, 0x9f, 0xb8, 0x44, 0x2b, 0x01, 0xf8, 0x7a, 0x06, 0xf6, 0x8a, 0xcd, 0x99, 0x78, + 0x3f, 0xc2, 0x21, 0xd5, 0x3a, 0xe0, 0xfa, 0x89, 0x6a, 0xe8, 0x13, 0x2f, 0xc4, 0x70, 0x1b, 0x14, + 0xb9, 0xbf, 0x2c, 0x55, 0xa5, 0xcd, 0xd5, 0x7a, 0x59, 0x5f, 0xf8, 0x1d, 0x3a, 0x1f, 0x69, 0x2f, + 0x1f, 0xfd, 0xbc, 0x95, 0x33, 0x85, 0x5c, 0x6b, 0x02, 0x99, 0xf9, 0x99, 0xf8, 0x2d, 0x0a, 0xfa, + 0x2f, 0x50, 0x64, 0xe3, 0x78, 0x17, 0x94, 0xc1, 0x25, 0xd4, 0xef, 0x07, 0x38, 0xe4, 0xae, 0x2b, + 0x66, 0xfc, 0xa8, 0xfd, 0x96, 0x40, 0x39, 0x65, 0x4c, 0xc0, 0xf4, 0xc0, 0x95, 0x80, 0xd5, 0xbb, + 0x36, 0x6b, 0xc8, 0x52, 0x75, 0x69, 0x73, 0xb5, 0xfe, 0x24, 0x85, 0x29, 0xd3, 0x44, 0x4f, 0x16, + 0x9f, 0x7b, 0x34, 0x18, 0x99, 0x6b, 0x41, 0xa2, 0xa4, 0x74, 0xc1, 0xfa, 0x82, 0x04, 0x5e, 0x03, + 0x4b, 0x7b, 0x78, 0x24, 0x68, 0x67, 0x47, 0xd8, 0x04, 0x85, 0x03, 0x34, 0x8c, 0xb0, 0x9c, 0x67, + 0xf7, 0xa2, 0xa6, 0x30, 0x24, 0x6c, 0x4c, 0x2e, 0x7e, 0x94, 0x7f, 0x20, 0x69, 0x2d, 0x50, 0x61, + 0x74, 0xed, 0xdd, 0x67, 0x3b, 0x14, 0xed, 0x39, 0x9e, 0xcd, 0x25, 0xe2, 0x72, 0x6e, 0x80, 0xe2, + 0x00, 0x3b, 0xf6, 0x80, 0xb2, 0x6d, 0xcb, 0xa6, 0x78, 0xd2, 0x3a, 0x60, 0x23, 0x7d, 0x4c, 0x5c, + 0x8e, 0x0e, 0x0a, 0xec, 0x56, 0xc4, 0x8b, 0x92, 0x53, 0x80, 0x04, 0x0a, 0x93, 0x69, 0x4f, 0x41, + 0x35, 0xf6, 0xdb, 0x75, 0x5c, 0x1c, 0x52, 0xe4, 0xfa, 0xa7, 0x59, 0x2a, 0x60, 0x05, 0xfb, 0xa4, + 0x37, 0xe8, 0x7a, 0x91, 0x2b, 0x70, 0x2e, 0xb3, 0x42, 0x27, 0x72, 0xb5, 0x1d, 0x50, 0x3b, 0xc3, + 0xe0, 0xff, 0xa8, 0xea, 0x9f, 0x0b, 0xa0, 0xc0, 0x5c, 0xe1, 0x7b, 0x50, 0xe4, 0xc1, 0x82, 0xb7, + 0xb3, 0xde, 0xef, 0x89, 0x04, 0x2b, 0x77, 0xfe, 0x25, 0xe3, 0x48, 0x5a, 0xed, 0xc3, 0xf7, 0x3f, + 0x9f, 0xf2, 0x15, 0x58, 0x36, 0xb2, 0xbe, 0x25, 0xf8, 0x45, 0x02, 0x6b, 0xc9, 0x10, 0xc0, 0xbb, + 0xe7, 0x8b, 0x18, 0x07, 0xb9, 0x77, 0x91, 0x3c, 0x6a, 0x0f, 0x19, 0x4e, 0x03, 0xde, 0x4f, 0xc1, + 0x11, 0x9f, 0x85, 0x71, 0x28, 0x0e, 0x63, 0x23, 0x99, 0x7f, 0xf8, 0x55, 0x02, 0x57, 0x4f, 0xc5, + 0x01, 0xea, 0x59, 0xcb, 0xd3, 0xe3, 0xa6, 0x18, 0xe7, 0xd6, 0x0b, 0xde, 0x16, 0xe3, 0x35, 0xe0, + 0x56, 0x0a, 0xaf, 0x45, 0x7b, 0xdd, 0x90, 0x0f, 0x71, 0x44, 0xe3, 0x90, 0xa7, 0x77, 0x0c, 0xbf, + 0x49, 0xa0, 0x94, 0x96, 0x14, 0xd8, 0x38, 0x03, 0x20, 0x2b, 0x98, 0x4a, 0xf3, 0x62, 0x43, 0x02, + 0xfd, 0x31, 0x43, 0xdf, 0x86, 0xad, 0x0c, 0x74, 0x9a, 0x98, 0x8c, 0xf9, 0xe7, 0xf9, 0x1f, 0xb7, + 0x5f, 0x1e, 0x4d, 0x54, 0xe9, 0x78, 0xa2, 0x4a, 0xbf, 0x26, 0xaa, 0xf4, 0x71, 0xaa, 0xe6, 0x8e, + 0xa7, 0x6a, 0xee, 0xc7, 0x54, 0xcd, 0xbd, 0x69, 0xd8, 0x0e, 0x1d, 0x44, 0x96, 0xde, 0x23, 0x6e, + 0x6c, 0x3d, 0x44, 0x56, 0xb8, 0xe5, 0x90, 0xf9, 0xa6, 0x77, 0x89, 0x5d, 0x74, 0xe4, 0xe3, 0xd0, + 0x2a, 0xb2, 0xbf, 0xe3, 0xc6, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xfc, 0x04, 0x89, 0x39, + 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/incentive/types/tx.pb.go b/x/incentive/types/tx.pb.go index dece25fd3..6d52b0959 100644 --- a/x/incentive/types/tx.pb.go +++ b/x/incentive/types/tx.pb.go @@ -241,37 +241,37 @@ func init() { func init() { proto.RegisterFile("babylon/incentive/tx.proto", fileDescriptor_b4de6776d39a3a22) } var fileDescriptor_b4de6776d39a3a22 = []byte{ - // 467 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x4f, 0x6b, 0xd4, 0x40, - 0x1c, 0xdd, 0xb1, 0x7f, 0xa4, 0x63, 0xa9, 0x74, 0x28, 0x34, 0x9b, 0x43, 0x5a, 0x82, 0x87, 0x65, - 0xb1, 0x19, 0xb7, 0x82, 0x42, 0x6f, 0xc6, 0xa3, 0x2c, 0x4a, 0x44, 0x04, 0x0f, 0xca, 0x24, 0x19, - 0x26, 0x83, 0x66, 0x26, 0x64, 0xa6, 0xdb, 0xee, 0x45, 0xc4, 0x4f, 0x20, 0x7e, 0x0c, 0x4f, 0x3d, - 0xf8, 0x21, 0x7a, 0x2c, 0x3d, 0x79, 0x52, 0xd9, 0x3d, 0xf4, 0x6b, 0xc8, 0x64, 0x26, 0xed, 0xda, - 0x14, 0xf4, 0x34, 0xf3, 0xdb, 0xf7, 0xe6, 0xfd, 0xde, 0xef, 0xfd, 0x36, 0xd0, 0x4f, 0x49, 0x3a, - 0xfd, 0x20, 0x05, 0xe6, 0x22, 0xa3, 0x42, 0xf3, 0x09, 0xc5, 0xfa, 0x38, 0xaa, 0x6a, 0xa9, 0x25, - 0xda, 0x74, 0x58, 0x74, 0x89, 0xf9, 0x5b, 0x4c, 0x32, 0xd9, 0xa0, 0xd8, 0xdc, 0x2c, 0xd1, 0xef, - 0x67, 0x52, 0x95, 0x52, 0xbd, 0xb3, 0x80, 0x2d, 0x1c, 0xb4, 0x6d, 0x2b, 0x5c, 0x2a, 0x86, 0x27, - 0x23, 0x73, 0x38, 0x20, 0x70, 0x40, 0x4a, 0x14, 0xc5, 0x93, 0x51, 0x4a, 0x35, 0x19, 0xe1, 0x4c, - 0x72, 0xd1, 0xe2, 0x5d, 0x63, 0x15, 0xa9, 0x49, 0xe9, 0x84, 0xc3, 0xe7, 0x70, 0x73, 0xac, 0xd8, - 0x6b, 0xae, 0x8b, 0xbc, 0x26, 0x47, 0x09, 0x3d, 0x22, 0x75, 0x8e, 0x10, 0x5c, 0xd6, 0xd3, 0x8a, - 0x7a, 0x60, 0x17, 0x0c, 0xd6, 0x92, 0xe6, 0x8e, 0x3c, 0x78, 0x9b, 0xe4, 0x79, 0x4d, 0x95, 0xf2, - 0x6e, 0x35, 0x3f, 0xb7, 0xe5, 0xc1, 0xfa, 0xe7, 0x8b, 0x93, 0x61, 0x5b, 0x85, 0x1f, 0x61, 0xbf, - 0x23, 0x98, 0x50, 0x55, 0x49, 0xa1, 0x28, 0x22, 0x70, 0xc5, 0x78, 0x53, 0x1e, 0xd8, 0x5d, 0x1a, - 0xdc, 0xd9, 0xef, 0x47, 0x6e, 0x48, 0xe3, 0x3e, 0x72, 0xee, 0xa3, 0xa7, 0x92, 0x8b, 0xf8, 0xc1, - 0xe9, 0xcf, 0x9d, 0xde, 0xb7, 0x5f, 0x3b, 0x03, 0xc6, 0x75, 0x71, 0x98, 0x46, 0x99, 0x2c, 0x5d, - 0x22, 0xee, 0xd8, 0x53, 0xf9, 0x7b, 0x6c, 0x9c, 0xa9, 0xe6, 0x81, 0x4a, 0xac, 0x72, 0xf8, 0x15, - 0xc0, 0xbb, 0x63, 0xc5, 0x5e, 0x55, 0x39, 0xd1, 0xf4, 0x45, 0x33, 0x2a, 0x7a, 0x04, 0xd7, 0xc8, - 0xa1, 0x2e, 0x64, 0xcd, 0xf5, 0xd4, 0x0e, 0x15, 0x7b, 0xe7, 0xdf, 0xf7, 0xb6, 0x5c, 0xf7, 0x27, - 0xd6, 0xfa, 0x4b, 0x5d, 0x73, 0xc1, 0x92, 0x2b, 0x2a, 0x7a, 0x0c, 0x57, 0x6d, 0x58, 0xcd, 0xc8, - 0xc6, 0x6f, 0x67, 0x95, 0x91, 0x6d, 0x11, 0x2f, 0x1b, 0xbf, 0x89, 0xa3, 0x1f, 0x6c, 0x98, 0x48, - 0xae, 0x84, 0xc2, 0x3e, 0xdc, 0xbe, 0xe6, 0xa9, 0x8d, 0x64, 0xff, 0x1c, 0xc0, 0xa5, 0xb1, 0x62, - 0x28, 0x87, 0x1b, 0xd7, 0xb6, 0x70, 0xef, 0x86, 0x6e, 0x9d, 0x68, 0xfd, 0xfb, 0xff, 0xc3, 0xba, - 0x5c, 0xc0, 0x5b, 0xb8, 0xfe, 0x57, 0x32, 0xe1, 0xcd, 0xaf, 0x17, 0x39, 0xfe, 0xf0, 0xdf, 0x9c, - 0x56, 0xdf, 0x5f, 0xf9, 0x74, 0x71, 0x32, 0x04, 0xf1, 0xb3, 0xd3, 0x59, 0x00, 0xce, 0x66, 0x01, - 0xf8, 0x3d, 0x0b, 0xc0, 0x97, 0x79, 0xd0, 0x3b, 0x9b, 0x07, 0xbd, 0x1f, 0xf3, 0xa0, 0xf7, 0x66, - 0xb4, 0xb0, 0x4f, 0x27, 0x9b, 0x15, 0x84, 0x8b, 0xb6, 0xc0, 0xc7, 0x8b, 0x9f, 0x90, 0x59, 0x6f, - 0xba, 0xda, 0xfc, 0x53, 0x1f, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc7, 0x73, 0x0d, 0x40, 0x64, - 0x03, 0x00, 0x00, + // 469 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xce, 0xd8, 0x1f, 0xd2, 0xb1, 0x54, 0x3a, 0x14, 0xba, 0xd9, 0xc3, 0xb6, 0x2c, 0x1e, 0x42, + 0x30, 0x3b, 0xa6, 0x05, 0x85, 0xde, 0x8c, 0xe7, 0xa0, 0xac, 0x88, 0xe0, 0x41, 0x99, 0xcd, 0x0e, + 0x93, 0xc1, 0xee, 0xce, 0xb2, 0x6f, 0x9a, 0x36, 0x17, 0x11, 0xff, 0x02, 0xf1, 0xcf, 0xf0, 0xd4, + 0x83, 0x7f, 0x44, 0x8f, 0xa5, 0x27, 0x4f, 0x2a, 0xc9, 0xa1, 0xff, 0x86, 0xcc, 0xce, 0x6c, 0x1b, + 0xbb, 0x05, 0x7b, 0x9a, 0x79, 0xf9, 0xbe, 0xf9, 0xde, 0xf7, 0xbe, 0x97, 0xc5, 0x7e, 0xc2, 0x92, + 0xe9, 0xa1, 0xca, 0xa9, 0xcc, 0x47, 0x3c, 0xd7, 0x72, 0xc2, 0xa9, 0x3e, 0x89, 0x8a, 0x52, 0x69, + 0x45, 0x36, 0x1d, 0x16, 0x5d, 0x61, 0xfe, 0x96, 0x50, 0x42, 0x55, 0x28, 0x35, 0x37, 0x4b, 0xf4, + 0xdb, 0x23, 0x05, 0x99, 0x82, 0x0f, 0x16, 0xb0, 0x85, 0x83, 0xb6, 0x6d, 0x45, 0x33, 0x10, 0x74, + 0xd2, 0x37, 0x87, 0x03, 0x02, 0x07, 0x24, 0x0c, 0x38, 0x9d, 0xf4, 0x13, 0xae, 0x59, 0x9f, 0x8e, + 0x94, 0xcc, 0x6b, 0xbc, 0x69, 0xac, 0x60, 0x25, 0xcb, 0x9c, 0x70, 0xf8, 0x12, 0x6f, 0x0e, 0x41, + 0xbc, 0x95, 0x7a, 0x9c, 0x96, 0xec, 0x38, 0xe6, 0xc7, 0xac, 0x4c, 0x09, 0xc1, 0xcb, 0x7a, 0x5a, + 0x70, 0x0f, 0xed, 0xa2, 0xce, 0x5a, 0x5c, 0xdd, 0x89, 0x87, 0xef, 0xb3, 0x34, 0x2d, 0x39, 0x80, + 0x77, 0xaf, 0xfa, 0xb9, 0x2e, 0x0f, 0xd6, 0xbf, 0x5c, 0x9e, 0x76, 0xeb, 0x2a, 0xfc, 0x84, 0xdb, + 0x0d, 0xc1, 0x98, 0x43, 0xa1, 0x72, 0xe0, 0x84, 0xe1, 0x15, 0xe3, 0x0d, 0x3c, 0xb4, 0xbb, 0xd4, + 0x79, 0xb0, 0xd7, 0x8e, 0xdc, 0x90, 0xc6, 0x7d, 0xe4, 0xdc, 0x47, 0x2f, 0x94, 0xcc, 0x07, 0x4f, + 0xce, 0x7e, 0xed, 0xb4, 0xbe, 0xff, 0xde, 0xe9, 0x08, 0xa9, 0xc7, 0x47, 0x49, 0x34, 0x52, 0x99, + 0x4b, 0xc4, 0x1d, 0x3d, 0x48, 0x3f, 0x52, 0xe3, 0x0c, 0xaa, 0x07, 0x10, 0x5b, 0xe5, 0xf0, 0x1b, + 0xc2, 0x0f, 0x87, 0x20, 0xde, 0x14, 0x29, 0xd3, 0xfc, 0x55, 0x35, 0x2a, 0x79, 0x8a, 0xd7, 0xd8, + 0x91, 0x1e, 0xab, 0x52, 0xea, 0xa9, 0x1d, 0x6a, 0xe0, 0x5d, 0xfc, 0xe8, 0x6d, 0xb9, 0xee, 0xcf, + 0xad, 0xf5, 0xd7, 0xba, 0x94, 0xb9, 0x88, 0xaf, 0xa9, 0xe4, 0x19, 0x5e, 0xb5, 0x61, 0x55, 0x23, + 0x1b, 0xbf, 0x8d, 0x55, 0x46, 0xb6, 0xc5, 0x60, 0xd9, 0xf8, 0x8d, 0x1d, 0xfd, 0x60, 0xc3, 0x44, + 0x72, 0x2d, 0x14, 0xb6, 0xf1, 0xf6, 0x0d, 0x4f, 0x75, 0x24, 0x7b, 0x17, 0x08, 0x2f, 0x0d, 0x41, + 0x90, 0x14, 0x6f, 0xdc, 0xd8, 0xc2, 0xa3, 0x5b, 0xba, 0x35, 0xa2, 0xf5, 0x1f, 0xdf, 0x85, 0x75, + 0xb5, 0x80, 0xf7, 0x78, 0xfd, 0x9f, 0x64, 0xc2, 0xdb, 0x5f, 0x2f, 0x72, 0xfc, 0xee, 0xff, 0x39, + 0xb5, 0xbe, 0xbf, 0xf2, 0xf9, 0xf2, 0xb4, 0x8b, 0x06, 0xc3, 0xb3, 0x59, 0x80, 0xce, 0x67, 0x01, + 0xfa, 0x33, 0x0b, 0xd0, 0xd7, 0x79, 0xd0, 0x3a, 0x9f, 0x07, 0xad, 0x9f, 0xf3, 0xa0, 0xf5, 0x6e, + 0x7f, 0x61, 0x9f, 0x4e, 0xf6, 0x90, 0x25, 0xd0, 0x93, 0xaa, 0x2e, 0xe9, 0xc9, 0xe2, 0x47, 0x64, + 0x16, 0x9c, 0xac, 0x56, 0xff, 0xd5, 0xfd, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9f, 0x43, 0xa9, + 0xe8, 0x66, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/monitor/client/cli/query.go b/x/monitor/client/cli/query.go index 50e9b2a2e..31b0bc1e2 100644 --- a/x/monitor/client/cli/query.go +++ b/x/monitor/client/cli/query.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/monitor/client/cli/tx.go b/x/monitor/client/cli/tx.go index c1836f6e7..4d55ca102 100644 --- a/x/monitor/client/cli/tx.go +++ b/x/monitor/client/cli/tx.go @@ -7,7 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" ) // GetTxCmd returns the transaction commands for this module diff --git a/x/monitor/genesis.go b/x/monitor/genesis.go index b786d9685..df03d8cce 100644 --- a/x/monitor/genesis.go +++ b/x/monitor/genesis.go @@ -2,8 +2,8 @@ package monitor import ( "context" - "github.com/babylonchain/babylon/x/monitor/keeper" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/keeper" + "github.com/babylonlabs-io/babylon/x/monitor/types" ) // InitGenesis initializes the capability module's state from a provided genesis diff --git a/x/monitor/genesis_test.go b/x/monitor/genesis_test.go index db95adb13..fbb1b2b00 100644 --- a/x/monitor/genesis_test.go +++ b/x/monitor/genesis_test.go @@ -3,11 +3,11 @@ package monitor_test import ( "testing" - "github.com/babylonchain/babylon/x/monitor" + "github.com/babylonlabs-io/babylon/x/monitor" "github.com/stretchr/testify/require" - simapp "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/x/monitor/types" + simapp "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/x/monitor/types" ) func TestExportGenesis(t *testing.T) { diff --git a/x/monitor/keeper/grpc_query.go b/x/monitor/keeper/grpc_query.go index 6a38d7a90..422194296 100644 --- a/x/monitor/keeper/grpc_query.go +++ b/x/monitor/keeper/grpc_query.go @@ -3,7 +3,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/x/monitor/keeper/grpc_query_test.go b/x/monitor/keeper/grpc_query_test.go index 6f33b8fe7..53ea0862f 100644 --- a/x/monitor/keeper/grpc_query_test.go +++ b/x/monitor/keeper/grpc_query_test.go @@ -8,13 +8,13 @@ import ( "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/testutil/datagen" - "github.com/babylonchain/babylon/testutil/mocks" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" - types2 "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/testutil/mocks" + ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types2 "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" ) func FuzzQueryEndedEpochBtcHeight(f *testing.F) { diff --git a/x/monitor/keeper/hooks.go b/x/monitor/keeper/hooks.go index 4b012fd44..8a0a3d492 100644 --- a/x/monitor/keeper/hooks.go +++ b/x/monitor/keeper/hooks.go @@ -3,8 +3,8 @@ package keeper import ( "context" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - etypes "github.com/babylonchain/babylon/x/epoching/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + etypes "github.com/babylonlabs-io/babylon/x/epoching/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/monitor/keeper/keeper.go b/x/monitor/keeper/keeper.go index 9bd40ab8b..c7ada1120 100644 --- a/x/monitor/keeper/keeper.go +++ b/x/monitor/keeper/keeper.go @@ -5,10 +5,10 @@ import ( corestoretypes "cosmossdk.io/core/store" "fmt" - ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types" + ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" "cosmossdk.io/log" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/monitor/module.go b/x/monitor/module.go index b4674ff00..40586622e 100644 --- a/x/monitor/module.go +++ b/x/monitor/module.go @@ -12,9 +12,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/monitor/client/cli" - "github.com/babylonchain/babylon/x/monitor/keeper" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/client/cli" + "github.com/babylonlabs-io/babylon/x/monitor/keeper" + "github.com/babylonlabs-io/babylon/x/monitor/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/monitor/types/expected_keepers.go b/x/monitor/types/expected_keepers.go index 0150c8dc2..d63fffa07 100644 --- a/x/monitor/types/expected_keepers.go +++ b/x/monitor/types/expected_keepers.go @@ -2,7 +2,7 @@ package types import ( "context" - lc "github.com/babylonchain/babylon/x/btclightclient/types" + lc "github.com/babylonlabs-io/babylon/x/btclightclient/types" ) type BTCLightClientKeeper interface { diff --git a/x/monitor/types/genesis.pb.go b/x/monitor/types/genesis.pb.go index 8e2be0c21..2de642697 100644 --- a/x/monitor/types/genesis.pb.go +++ b/x/monitor/types/genesis.pb.go @@ -66,16 +66,17 @@ func init() { func init() { proto.RegisterFile("babylon/monitor/v1/genesis.proto", fileDescriptor_fb844fd916189e7b) } var fileDescriptor_fb844fd916189e7b = []byte{ - // 144 bytes of a gzipped FileDescriptorProto + // 146 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x48, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xcf, 0xcd, 0xcf, 0xcb, 0x2c, 0xc9, 0x2f, 0xd2, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x82, 0xaa, 0xd0, 0x83, 0xaa, 0xd0, 0x2b, 0x33, 0x54, 0xe2, 0xe3, 0xe2, 0x71, 0x87, 0x28, 0x0a, 0x2e, 0x49, - 0x2c, 0x49, 0x75, 0xf2, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, - 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xfd, - 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, 0x41, 0xc9, 0x19, 0x89, - 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0xdc, 0xe6, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, 0x36, 0xb0, - 0xad, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x9f, 0x6b, 0xe2, 0x99, 0x00, 0x00, 0x00, + 0x2c, 0x49, 0x75, 0xf2, 0x3e, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, + 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x28, 0xc3, + 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, 0x41, 0x39, 0x89, 0x49, + 0xc5, 0xba, 0x99, 0xf9, 0x30, 0xae, 0x7e, 0x05, 0xdc, 0xee, 0x92, 0xca, 0x82, 0xd4, 0xe2, 0x24, + 0x36, 0xb0, 0xbd, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x4f, 0x6b, 0xc3, 0x9b, 0x00, + 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/monitor/types/genesis_test.go b/x/monitor/types/genesis_test.go index 5c5092312..73008eb98 100644 --- a/x/monitor/types/genesis_test.go +++ b/x/monitor/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/monitor/types" + "github.com/babylonlabs-io/babylon/x/monitor/types" "github.com/stretchr/testify/require" ) diff --git a/x/monitor/types/keys.go b/x/monitor/types/keys.go index 1f65b3c03..ccd101ec8 100644 --- a/x/monitor/types/keys.go +++ b/x/monitor/types/keys.go @@ -2,7 +2,7 @@ package types import ( "fmt" - "github.com/babylonchain/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/checkpointing/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/monitor/types/query.pb.go b/x/monitor/types/query.pb.go index 210128e1c..321e6d2de 100644 --- a/x/monitor/types/query.pb.go +++ b/x/monitor/types/query.pb.go @@ -229,33 +229,33 @@ func init() { func init() { proto.RegisterFile("babylon/monitor/v1/query.proto", fileDescriptor_a8aafb034c55a8f2) } var fileDescriptor_a8aafb034c55a8f2 = []byte{ - // 404 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x93, 0x4f, 0x8b, 0xd3, 0x40, - 0x18, 0xc6, 0x1b, 0xff, 0xd1, 0xce, 0x71, 0x14, 0x94, 0x56, 0x62, 0xc9, 0x41, 0x0b, 0x62, 0x86, - 0x5a, 0x3d, 0x29, 0x1e, 0x5a, 0x2a, 0x15, 0x44, 0x30, 0x37, 0xbd, 0x84, 0xc9, 0x74, 0xc8, 0x0c, - 0x4d, 0x66, 0xa6, 0x99, 0x49, 0xb1, 0x94, 0x5e, 0x3c, 0x7a, 0x12, 0xfc, 0x22, 0x7e, 0x0c, 0x2f, - 0x42, 0xc1, 0x8b, 0xc7, 0xa5, 0xdd, 0x0f, 0xb2, 0x64, 0x9a, 0xcd, 0x65, 0xd3, 0x2d, 0xbb, 0x7b, - 0xcc, 0xfb, 0xe6, 0xf9, 0xcd, 0xfb, 0xbc, 0xcf, 0x0c, 0x70, 0x23, 0x1c, 0x2d, 0x13, 0x29, 0x50, - 0x2a, 0x05, 0x37, 0x32, 0x43, 0x8b, 0x3e, 0x9a, 0xe7, 0x34, 0x5b, 0xfa, 0x2a, 0x93, 0x46, 0x42, - 0x58, 0xf6, 0xfd, 0xb2, 0xef, 0x2f, 0xfa, 0xed, 0xc7, 0xb1, 0x94, 0x71, 0x42, 0x11, 0x56, 0x1c, - 0x61, 0x21, 0xa4, 0xc1, 0x86, 0x4b, 0xa1, 0xf7, 0x0a, 0xef, 0x1d, 0x78, 0xf2, 0xb9, 0x00, 0x8c, - 0xc5, 0x94, 0x4e, 0xc7, 0x4a, 0x12, 0x36, 0x34, 0x64, 0x42, 0x79, 0xcc, 0x4c, 0x40, 0xe7, 0x39, - 0xd5, 0x06, 0x76, 0x40, 0x8b, 0x16, 0x8d, 0x50, 0xe4, 0xe9, 0x23, 0xa7, 0xeb, 0xf4, 0xee, 0x04, - 0x4d, 0x5b, 0xf8, 0x94, 0xa7, 0xde, 0x17, 0xd0, 0x3d, 0xac, 0xd7, 0x4a, 0x0a, 0x4d, 0xe1, 0x6b, - 0xf0, 0x30, 0x32, 0x24, 0x4c, 0x8a, 0x62, 0x48, 0x12, 0x4e, 0x85, 0x09, 0x99, 0xfd, 0xa5, 0xc4, - 0x3d, 0x88, 0x0c, 0xf9, 0x58, 0x7c, 0x8f, 0x6c, 0x73, 0x2f, 0xf7, 0xde, 0x83, 0x67, 0x16, 0x1d, - 0x50, 0x25, 0x33, 0x43, 0xa7, 0x23, 0x46, 0xc9, 0x4c, 0x49, 0x2e, 0x4c, 0xdd, 0x88, 0x64, 0xa6, - 0x4c, 0xc8, 0xb0, 0x66, 0x96, 0xd9, 0x0a, 0x9a, 0x45, 0x61, 0x82, 0x35, 0xf3, 0x30, 0xe8, 0x1d, - 0xe7, 0xdc, 0x68, 0xd4, 0x97, 0x3f, 0x6e, 0x83, 0xbb, 0xf6, 0x0c, 0xf8, 0xdb, 0x01, 0xf7, 0x6b, - 0x76, 0x01, 0x07, 0xfe, 0xc5, 0x68, 0xfc, 0x23, 0x9b, 0x6f, 0xbf, 0xba, 0x9a, 0x68, 0xef, 0xc1, - 0xf3, 0xbf, 0xff, 0x3b, 0xfd, 0x75, 0xab, 0x07, 0x9f, 0xa2, 0x9a, 0xdb, 0x62, 0x83, 0xd3, 0x68, - 0x55, 0x25, 0xba, 0x86, 0x7f, 0x1d, 0xd0, 0xb9, 0x64, 0x37, 0xf0, 0xcd, 0xc1, 0x29, 0x8e, 0x27, - 0xd3, 0x7e, 0x7b, 0x3d, 0x71, 0x69, 0x65, 0x60, 0xad, 0xbc, 0x80, 0xcf, 0xeb, 0xac, 0x90, 0x4a, - 0xa8, 0xd1, 0xaa, 0x8a, 0x7f, 0x3d, 0xfc, 0xf0, 0x67, 0xeb, 0x3a, 0x9b, 0xad, 0xeb, 0x9c, 0x6c, - 0x5d, 0xe7, 0xe7, 0xce, 0x6d, 0x6c, 0x76, 0x6e, 0xe3, 0xff, 0xce, 0x6d, 0x7c, 0x45, 0x31, 0x37, - 0x2c, 0x8f, 0x7c, 0x22, 0xd3, 0x73, 0x20, 0x61, 0x98, 0x8b, 0x8a, 0xfe, 0xad, 0xe2, 0x9b, 0xa5, - 0xa2, 0x3a, 0xba, 0x67, 0x1f, 0xc9, 0xe0, 0x2c, 0x00, 0x00, 0xff, 0xff, 0xf9, 0x12, 0xa1, 0x9a, - 0x78, 0x03, 0x00, 0x00, + // 405 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x53, 0x4d, 0xab, 0x13, 0x31, + 0x14, 0xed, 0xf8, 0x45, 0x9b, 0x65, 0x14, 0x94, 0x56, 0xc6, 0x32, 0x0b, 0x2d, 0x48, 0x27, 0xd4, + 0xea, 0x4a, 0x71, 0xd1, 0x52, 0x29, 0x28, 0x82, 0xb3, 0xd3, 0xcd, 0x90, 0x49, 0xc3, 0x24, 0x74, + 0x26, 0x49, 0x27, 0x99, 0x62, 0x29, 0xdd, 0xb8, 0x74, 0x25, 0xf8, 0x47, 0xfc, 0x19, 0x6e, 0x84, + 0x82, 0x1b, 0x97, 0xd2, 0xfa, 0x43, 0x64, 0xd2, 0x79, 0xb3, 0x79, 0xd3, 0x57, 0xde, 0x7b, 0xcb, + 0xdc, 0x93, 0x73, 0xee, 0x3d, 0xf7, 0x24, 0xc0, 0x8d, 0x70, 0xb4, 0x4a, 0xa4, 0x40, 0xa9, 0x14, + 0xdc, 0xc8, 0x0c, 0x2d, 0x07, 0x68, 0x91, 0xd3, 0x6c, 0xe5, 0xab, 0x4c, 0x1a, 0x09, 0x61, 0x89, + 0xfb, 0x25, 0xee, 0x2f, 0x07, 0xed, 0x87, 0xb1, 0x94, 0x71, 0x42, 0x11, 0x56, 0x1c, 0x61, 0x21, + 0xa4, 0xc1, 0x86, 0x4b, 0xa1, 0x0f, 0x0c, 0xef, 0x35, 0x78, 0xf4, 0xa1, 0x10, 0x98, 0x88, 0x19, + 0x9d, 0x4d, 0x94, 0x24, 0x6c, 0x64, 0xc8, 0x94, 0xf2, 0x98, 0x99, 0x80, 0x2e, 0x72, 0xaa, 0x0d, + 0xec, 0x80, 0x16, 0x2d, 0x80, 0x50, 0xe4, 0xe9, 0x03, 0xa7, 0xeb, 0xf4, 0x6e, 0x05, 0x4d, 0x5b, + 0x78, 0x9f, 0xa7, 0xde, 0x47, 0xd0, 0x3d, 0xce, 0xd7, 0x4a, 0x0a, 0x4d, 0xe1, 0x0b, 0x70, 0x3f, + 0x32, 0x24, 0x4c, 0x8a, 0x62, 0x48, 0x12, 0x4e, 0x85, 0x09, 0x99, 0xbd, 0x52, 0xca, 0xdd, 0x8b, + 0x0c, 0x79, 0x57, 0x9c, 0xc7, 0x16, 0x3c, 0xd0, 0xbd, 0x37, 0xe0, 0x89, 0x95, 0x0e, 0xa8, 0x92, + 0x99, 0xa1, 0xb3, 0x31, 0xa3, 0x64, 0xae, 0x24, 0x17, 0xa6, 0x6e, 0x44, 0x32, 0x57, 0x26, 0x64, + 0x58, 0x33, 0xab, 0xd9, 0x0a, 0x9a, 0x45, 0x61, 0x8a, 0x35, 0xf3, 0x30, 0xe8, 0x9d, 0xd6, 0xb9, + 0xd6, 0xa8, 0xcf, 0xbe, 0xde, 0x04, 0xb7, 0x6d, 0x0f, 0xf8, 0xc3, 0x01, 0x77, 0x6b, 0x76, 0x01, + 0x87, 0xfe, 0xf9, 0x68, 0xfc, 0x13, 0x9b, 0x6f, 0x3f, 0xbf, 0x1c, 0xe9, 0xe0, 0xc1, 0xf3, 0xbf, + 0xfc, 0xfe, 0xf7, 0xfd, 0x46, 0x0f, 0x3e, 0x46, 0x35, 0xaf, 0xc5, 0x06, 0xa7, 0xd1, 0xba, 0x4a, + 0x74, 0x03, 0x7f, 0x39, 0xa0, 0x73, 0xc1, 0x6e, 0xe0, 0xcb, 0xa3, 0x53, 0x9c, 0x4e, 0xa6, 0xfd, + 0xea, 0x6a, 0xe4, 0xd2, 0xca, 0xd0, 0x5a, 0xe9, 0xc3, 0xa7, 0x75, 0x56, 0x48, 0x45, 0xd4, 0x68, + 0x5d, 0xc5, 0xbf, 0x19, 0xbd, 0xfd, 0xb9, 0x73, 0x9d, 0xed, 0xce, 0x75, 0xfe, 0xee, 0x5c, 0xe7, + 0xdb, 0xde, 0x6d, 0x6c, 0xf7, 0x6e, 0xe3, 0xcf, 0xde, 0x6d, 0x7c, 0x1a, 0xc4, 0xdc, 0xb0, 0x3c, + 0xf2, 0x89, 0x4c, 0xcf, 0x04, 0x13, 0x1c, 0xe9, 0x3e, 0x97, 0x95, 0xfe, 0xe7, 0xaa, 0x83, 0x59, + 0x29, 0xaa, 0xa3, 0x3b, 0xf6, 0x9b, 0x0c, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x10, 0xaa, 0x98, + 0x3e, 0x7a, 0x03, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/zoneconcierge/README.md b/x/zoneconcierge/README.md index d9dda333c..f873f4030 100644 --- a/x/zoneconcierge/README.md +++ b/x/zoneconcierge/README.md @@ -472,7 +472,7 @@ for different use cases, e.g., BTC-assisted unbonding. The phase 2 integration does not require any change to the PoS blockchain's code. Rather, it only needs to deploy a [Babylon -contract](https://github.com/babylonchain/babylon-contract) on the PoS +contract](https://github.com/babylonlabs-io/babylon-contract) on the PoS blockchain, and start an IBC relayer between Babylon and the Babylon contract on the PoS blockchain. The Babylon contract can be deployed to a blockchain supporting [CosmWasm](https://github.com/CosmWasm/cosmwasm) smart contracts, diff --git a/x/zoneconcierge/abci.go b/x/zoneconcierge/abci.go index 7ea1514bb..a0989f678 100644 --- a/x/zoneconcierge/abci.go +++ b/x/zoneconcierge/abci.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/telemetry" ) diff --git a/x/zoneconcierge/client/cli/query.go b/x/zoneconcierge/client/cli/query.go index 2b0c5ad9c..ca0f1b682 100644 --- a/x/zoneconcierge/client/cli/query.go +++ b/x/zoneconcierge/client/cli/query.go @@ -9,7 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // GetQueryCmd returns the cli query commands for this module diff --git a/x/zoneconcierge/client/cli/tx.go b/x/zoneconcierge/client/cli/tx.go index 9ba77b787..23bd93b94 100644 --- a/x/zoneconcierge/client/cli/tx.go +++ b/x/zoneconcierge/client/cli/tx.go @@ -6,7 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/client" // "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // GetTxCmd returns the transaction commands for this module diff --git a/x/zoneconcierge/genesis.go b/x/zoneconcierge/genesis.go index 6cdc963bf..84771473c 100644 --- a/x/zoneconcierge/genesis.go +++ b/x/zoneconcierge/genesis.go @@ -2,8 +2,8 @@ package zoneconcierge import ( "context" - "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/zoneconcierge/genesis_test.go b/x/zoneconcierge/genesis_test.go index 59ae3107d..e4b3181e9 100644 --- a/x/zoneconcierge/genesis_test.go +++ b/x/zoneconcierge/genesis_test.go @@ -3,10 +3,10 @@ package zoneconcierge_test import ( "testing" - keepertest "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/testutil/nullify" - "github.com/babylonchain/babylon/x/zoneconcierge" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + keepertest "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/testutil/nullify" + "github.com/babylonlabs-io/babylon/x/zoneconcierge" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/keeper/canonical_chain_indexer.go b/x/zoneconcierge/keeper/canonical_chain_indexer.go index 2348ba387..52d89b965 100644 --- a/x/zoneconcierge/keeper/canonical_chain_indexer.go +++ b/x/zoneconcierge/keeper/canonical_chain_indexer.go @@ -7,7 +7,7 @@ import ( sdkerrors "cosmossdk.io/errors" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/zoneconcierge/keeper/canonical_chain_indexer_test.go b/x/zoneconcierge/keeper/canonical_chain_indexer_test.go index 1b1f929ff..af484b32c 100644 --- a/x/zoneconcierge/keeper/canonical_chain_indexer_test.go +++ b/x/zoneconcierge/keeper/canonical_chain_indexer_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/keeper/chain_info_indexer.go b/x/zoneconcierge/keeper/chain_info_indexer.go index e7e7d06bd..a3ae402d1 100644 --- a/x/zoneconcierge/keeper/chain_info_indexer.go +++ b/x/zoneconcierge/keeper/chain_info_indexer.go @@ -7,7 +7,7 @@ import ( errorsmod "cosmossdk.io/errors" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func (k Keeper) setChainInfo(ctx context.Context, chainInfo *types.ChainInfo) { diff --git a/x/zoneconcierge/keeper/epoch_chain_info_indexer.go b/x/zoneconcierge/keeper/epoch_chain_info_indexer.go index 5faf156ad..5584b008e 100644 --- a/x/zoneconcierge/keeper/epoch_chain_info_indexer.go +++ b/x/zoneconcierge/keeper/epoch_chain_info_indexer.go @@ -8,8 +8,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" - bbn "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + bbn "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // GetEpochChainInfo gets the latest chain info of a given epoch for a given chain ID diff --git a/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go b/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go index 79a99337d..59dc52c50 100644 --- a/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go +++ b/x/zoneconcierge/keeper/epoch_chain_info_indexer_test.go @@ -7,8 +7,8 @@ import ( ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" ) func FuzzEpochChainInfoIndexer(f *testing.F) { diff --git a/x/zoneconcierge/keeper/epochs.go b/x/zoneconcierge/keeper/epochs.go index d61d89761..6c3bfac89 100644 --- a/x/zoneconcierge/keeper/epochs.go +++ b/x/zoneconcierge/keeper/epochs.go @@ -4,8 +4,8 @@ import ( "context" "cosmossdk.io/store/prefix" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/zoneconcierge/keeper/fork_indexer.go b/x/zoneconcierge/keeper/fork_indexer.go index 2ec7e6ba3..68d98243f 100644 --- a/x/zoneconcierge/keeper/fork_indexer.go +++ b/x/zoneconcierge/keeper/fork_indexer.go @@ -7,7 +7,7 @@ import ( sdkerrors "cosmossdk.io/errors" "cosmossdk.io/store/prefix" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/zoneconcierge/keeper/fork_indexer_test.go b/x/zoneconcierge/keeper/fork_indexer_test.go index 8195f6b01..c1ef1a522 100644 --- a/x/zoneconcierge/keeper/fork_indexer_test.go +++ b/x/zoneconcierge/keeper/fork_indexer_test.go @@ -4,8 +4,8 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/keeper/grpc_query.go b/x/zoneconcierge/keeper/grpc_query.go index 7d9e0226e..5cb71dfca 100644 --- a/x/zoneconcierge/keeper/grpc_query.go +++ b/x/zoneconcierge/keeper/grpc_query.go @@ -3,8 +3,8 @@ package keeper import ( "context" - bbntypes "github.com/babylonchain/babylon/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + bbntypes "github.com/babylonlabs-io/babylon/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/query" "google.golang.org/grpc/codes" diff --git a/x/zoneconcierge/keeper/grpc_query_test.go b/x/zoneconcierge/keeper/grpc_query_test.go index 08c5cab8b..4885659e9 100644 --- a/x/zoneconcierge/keeper/grpc_query_test.go +++ b/x/zoneconcierge/keeper/grpc_query_test.go @@ -4,18 +4,18 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/app" - btclightclienttypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/app" + btclightclienttypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/cosmos/cosmos-sdk/types/query" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" - "github.com/babylonchain/babylon/testutil/datagen" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) type chainInfo struct { diff --git a/x/zoneconcierge/keeper/header_handler.go b/x/zoneconcierge/keeper/header_handler.go index 3bfdd046e..e4bfa635d 100644 --- a/x/zoneconcierge/keeper/header_handler.go +++ b/x/zoneconcierge/keeper/header_handler.go @@ -6,7 +6,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // HandleHeaderWithValidCommit handles a CZ header with a valid QC diff --git a/x/zoneconcierge/keeper/hooks.go b/x/zoneconcierge/keeper/hooks.go index fc523f54e..8621183dc 100644 --- a/x/zoneconcierge/keeper/hooks.go +++ b/x/zoneconcierge/keeper/hooks.go @@ -5,9 +5,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) type Hooks struct { diff --git a/x/zoneconcierge/keeper/ibc_header_decorator.go b/x/zoneconcierge/keeper/ibc_header_decorator.go index 1e8967be2..930f33e6e 100644 --- a/x/zoneconcierge/keeper/ibc_header_decorator.go +++ b/x/zoneconcierge/keeper/ibc_header_decorator.go @@ -6,7 +6,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) var _ sdk.PostDecorator = &IBCHeaderDecorator{} diff --git a/x/zoneconcierge/keeper/ibc_packet.go b/x/zoneconcierge/keeper/ibc_packet.go index 266e8fd35..c4f6bbc03 100644 --- a/x/zoneconcierge/keeper/ibc_packet.go +++ b/x/zoneconcierge/keeper/ibc_packet.go @@ -8,7 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/telemetry" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" diff --git a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go index d3adb444c..7df7c61ad 100644 --- a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go +++ b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp.go @@ -8,12 +8,12 @@ import ( channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // finalizedInfo is a private struct that stores metadata and proofs diff --git a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp_test.go b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp_test.go index 531657d26..7a2d1a7c6 100644 --- a/x/zoneconcierge/keeper/ibc_packet_btc_timestamp_test.go +++ b/x/zoneconcierge/keeper/ibc_packet_btc_timestamp_test.go @@ -5,10 +5,10 @@ import ( "math/rand" "testing" - "github.com/babylonchain/babylon/app" - "github.com/babylonchain/babylon/testutil/datagen" - btclckeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" + "github.com/babylonlabs-io/babylon/app" + "github.com/babylonlabs-io/babylon/testutil/datagen" + btclckeeper "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/keeper/keeper.go b/x/zoneconcierge/keeper/keeper.go index b34290f6e..82fee2b40 100644 --- a/x/zoneconcierge/keeper/keeper.go +++ b/x/zoneconcierge/keeper/keeper.go @@ -6,7 +6,7 @@ import ( corestoretypes "cosmossdk.io/core/store" "cosmossdk.io/log" storetypes "cosmossdk.io/store/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" diff --git a/x/zoneconcierge/keeper/keeper_test.go b/x/zoneconcierge/keeper/keeper_test.go index 51b04f56d..1d5392735 100644 --- a/x/zoneconcierge/keeper/keeper_test.go +++ b/x/zoneconcierge/keeper/keeper_test.go @@ -6,8 +6,8 @@ import ( ibctmtypes "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" - "github.com/babylonchain/babylon/testutil/datagen" - zckeeper "github.com/babylonchain/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/testutil/datagen" + zckeeper "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" ) // SimulateNewHeaders generates a non-zero number of canonical headers diff --git a/x/zoneconcierge/keeper/msg_server.go b/x/zoneconcierge/keeper/msg_server.go index dee48dd04..26d5e9c96 100644 --- a/x/zoneconcierge/keeper/msg_server.go +++ b/x/zoneconcierge/keeper/msg_server.go @@ -4,7 +4,7 @@ import ( "context" errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) diff --git a/x/zoneconcierge/keeper/params.go b/x/zoneconcierge/keeper/params.go index 04989eea9..f9661e57d 100644 --- a/x/zoneconcierge/keeper/params.go +++ b/x/zoneconcierge/keeper/params.go @@ -2,7 +2,7 @@ package keeper import ( "context" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) // SetParams sets the x/zoneconcierge module parameters. diff --git a/x/zoneconcierge/keeper/params_test.go b/x/zoneconcierge/keeper/params_test.go index b8f8f772d..a35f8116f 100644 --- a/x/zoneconcierge/keeper/params_test.go +++ b/x/zoneconcierge/keeper/params_test.go @@ -3,8 +3,8 @@ package keeper_test import ( "testing" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/keeper/proof_btc_timestamp.go b/x/zoneconcierge/keeper/proof_btc_timestamp.go index 8f6b52368..248fe6b1a 100644 --- a/x/zoneconcierge/keeper/proof_btc_timestamp.go +++ b/x/zoneconcierge/keeper/proof_btc_timestamp.go @@ -6,10 +6,10 @@ import ( cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func (k Keeper) ProveCZHeaderInEpoch(_ context.Context, header *types.IndexedHeader, epoch *epochingtypes.Epoch) (*cmtcrypto.ProofOps, error) { diff --git a/x/zoneconcierge/keeper/proof_btc_timestamp_test.go b/x/zoneconcierge/keeper/proof_btc_timestamp_test.go index 48190e086..d58d3d666 100644 --- a/x/zoneconcierge/keeper/proof_btc_timestamp_test.go +++ b/x/zoneconcierge/keeper/proof_btc_timestamp_test.go @@ -12,13 +12,13 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - testkeeper "github.com/babylonchain/babylon/testutil/keeper" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - zctypes "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + testkeeper "github.com/babylonlabs-io/babylon/testutil/keeper" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + zctypes "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func FuzzProofCZHeaderInEpoch(f *testing.F) { diff --git a/x/zoneconcierge/module.go b/x/zoneconcierge/module.go index 20ab32932..5fcc64a16 100644 --- a/x/zoneconcierge/module.go +++ b/x/zoneconcierge/module.go @@ -11,9 +11,9 @@ import ( abci "github.com/cometbft/cometbft/abci/types" - "github.com/babylonchain/babylon/x/zoneconcierge/client/cli" - "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/client/cli" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" diff --git a/x/zoneconcierge/module_ibc.go b/x/zoneconcierge/module_ibc.go index cee536d91..1484bc322 100644 --- a/x/zoneconcierge/module_ibc.go +++ b/x/zoneconcierge/module_ibc.go @@ -2,8 +2,8 @@ package zoneconcierge import ( errorsmod "cosmossdk.io/errors" - "github.com/babylonchain/babylon/x/zoneconcierge/keeper" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/keeper" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" diff --git a/x/zoneconcierge/types/btc_timestamp.go b/x/zoneconcierge/types/btc_timestamp.go index 6d520a61e..c1cde804e 100644 --- a/x/zoneconcierge/types/btc_timestamp.go +++ b/x/zoneconcierge/types/btc_timestamp.go @@ -10,13 +10,13 @@ import ( cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto" sdk "github.com/cosmos/cosmos-sdk/types" - txformat "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" - bbn "github.com/babylonchain/babylon/types" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclckeeper "github.com/babylonchain/babylon/x/btclightclient/keeper" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + bbn "github.com/babylonlabs-io/babylon/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclckeeper "github.com/babylonlabs-io/babylon/x/btclightclient/keeper" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ) func GetCZHeaderKey(chainID string, height uint64) []byte { diff --git a/x/zoneconcierge/types/btc_timestamp_test.go b/x/zoneconcierge/types/btc_timestamp_test.go index 2f513329d..24033ed88 100644 --- a/x/zoneconcierge/types/btc_timestamp_test.go +++ b/x/zoneconcierge/types/btc_timestamp_test.go @@ -10,13 +10,13 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/stretchr/testify/require" - txformat "github.com/babylonchain/babylon/btctxformatter" - "github.com/babylonchain/babylon/crypto/bls12381" - "github.com/babylonchain/babylon/testutil/datagen" - testhelper "github.com/babylonchain/babylon/testutil/helper" - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + txformat "github.com/babylonlabs-io/babylon/btctxformatter" + "github.com/babylonlabs-io/babylon/crypto/bls12381" + "github.com/babylonlabs-io/babylon/testutil/datagen" + testhelper "github.com/babylonlabs-io/babylon/testutil/helper" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" ) func signBLSWithBitmap(blsSKs []bls12381.PrivateKey, bm bitmap.Bitmap, msg []byte) (bls12381.Signature, error) { diff --git a/x/zoneconcierge/types/expected_keepers.go b/x/zoneconcierge/types/expected_keepers.go index 695af1467..574a0b7fd 100644 --- a/x/zoneconcierge/types/expected_keepers.go +++ b/x/zoneconcierge/types/expected_keepers.go @@ -3,13 +3,13 @@ package types import ( "context" - bbn "github.com/babylonchain/babylon/types" + bbn "github.com/babylonlabs-io/babylon/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" //nolint:staticcheck - btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" - btclctypes "github.com/babylonchain/babylon/x/btclightclient/types" - checkpointingtypes "github.com/babylonchain/babylon/x/checkpointing/types" - epochingtypes "github.com/babylonchain/babylon/x/epoching/types" + btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types" + checkpointingtypes "github.com/babylonlabs-io/babylon/x/checkpointing/types" + epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types" ctypes "github.com/cometbft/cometbft/rpc/core/types" sdk "github.com/cosmos/cosmos-sdk/types" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" diff --git a/x/zoneconcierge/types/genesis.pb.go b/x/zoneconcierge/types/genesis.pb.go index 1eed06657..a0ae3e52e 100644 --- a/x/zoneconcierge/types/genesis.pb.go +++ b/x/zoneconcierge/types/genesis.pb.go @@ -85,7 +85,7 @@ func init() { } var fileDescriptor_56f290ad7c2c7dc7 = []byte{ - // 228 bytes of a gzipped FileDescriptorProto + // 230 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4b, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xaf, 0xca, 0xcf, 0x4b, 0x4d, 0xce, 0xcf, 0x4b, 0xce, 0x4c, 0x2d, 0x4a, 0x4f, 0xd5, 0x2f, 0x33, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0xce, 0x2c, 0xd6, 0x2b, 0x28, 0xca, @@ -95,12 +95,12 @@ var fileDescriptor_56f290ad7c2c7dc7 = []byte{ 0x54, 0x21, 0x71, 0x2e, 0xf6, 0x82, 0xfc, 0xa2, 0x92, 0xf8, 0xcc, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0x36, 0x10, 0xd7, 0x33, 0x45, 0xc8, 0x8e, 0x8b, 0x0d, 0xa2, 0x51, 0x82, 0x49, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x41, 0x0f, 0x97, 0x83, 0xf4, 0x02, 0xc0, 0xea, 0x9c, 0x58, 0x4e, - 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x72, 0xf2, 0x3f, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, + 0xdc, 0x93, 0x67, 0x08, 0x82, 0xea, 0x72, 0x0a, 0x3c, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, - 0x39, 0x86, 0x28, 0xd3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, - 0x99, 0xc9, 0x19, 0x89, 0x99, 0x79, 0x30, 0x8e, 0x7e, 0x05, 0x9a, 0x1f, 0x4a, 0x2a, 0x0b, 0x52, - 0x8b, 0x93, 0xd8, 0xc0, 0x1e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x6c, 0xb2, 0x6d, 0xbb, - 0x41, 0x01, 0x00, 0x00, + 0x39, 0x86, 0x28, 0xf3, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, 0xa8, + 0x99, 0x39, 0x89, 0x49, 0xc5, 0xba, 0x99, 0xf9, 0x30, 0xae, 0x7e, 0x05, 0x9a, 0x2f, 0x4a, 0x2a, + 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, 0x5e, 0x30, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x70, + 0xce, 0xb1, 0x43, 0x01, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { diff --git a/x/zoneconcierge/types/genesis_test.go b/x/zoneconcierge/types/genesis_test.go index 0902eb6d7..859e66e14 100644 --- a/x/zoneconcierge/types/genesis_test.go +++ b/x/zoneconcierge/types/genesis_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/types/mocked_keepers.go b/x/zoneconcierge/types/mocked_keepers.go index f5eb253fc..2daa01fae 100644 --- a/x/zoneconcierge/types/mocked_keepers.go +++ b/x/zoneconcierge/types/mocked_keepers.go @@ -8,11 +8,11 @@ import ( context "context" reflect "reflect" - types "github.com/babylonchain/babylon/types" - types0 "github.com/babylonchain/babylon/x/btccheckpoint/types" - types1 "github.com/babylonchain/babylon/x/btclightclient/types" - types2 "github.com/babylonchain/babylon/x/checkpointing/types" - types3 "github.com/babylonchain/babylon/x/epoching/types" + types "github.com/babylonlabs-io/babylon/types" + types0 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + types1 "github.com/babylonlabs-io/babylon/x/btclightclient/types" + types2 "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types3 "github.com/babylonlabs-io/babylon/x/epoching/types" coretypes "github.com/cometbft/cometbft/rpc/core/types" types4 "github.com/cosmos/cosmos-sdk/types" types5 "github.com/cosmos/ibc-go/modules/capability/types" diff --git a/x/zoneconcierge/types/packet.pb.go b/x/zoneconcierge/types/packet.pb.go index 6e123e938..1ca32360f 100644 --- a/x/zoneconcierge/types/packet.pb.go +++ b/x/zoneconcierge/types/packet.pb.go @@ -5,10 +5,10 @@ package types import ( fmt "fmt" - types3 "github.com/babylonchain/babylon/x/btccheckpoint/types" - types "github.com/babylonchain/babylon/x/btclightclient/types" - types2 "github.com/babylonchain/babylon/x/checkpointing/types" - types1 "github.com/babylonchain/babylon/x/epoching/types" + types3 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + types "github.com/babylonlabs-io/babylon/x/btclightclient/types" + types2 "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types1 "github.com/babylonlabs-io/babylon/x/epoching/types" proto "github.com/cosmos/gogoproto/proto" io "io" math "math" @@ -211,37 +211,37 @@ func init() { } var fileDescriptor_be12e124c5c4fdb9 = []byte{ - // 471 bytes of a gzipped FileDescriptorProto + // 474 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x4f, 0x6f, 0xd3, 0x30, 0x18, 0xc6, 0x1b, 0xca, 0x2a, 0x70, 0x37, 0x84, 0x7c, 0x21, 0xda, 0x21, 0x9a, 0x2a, 0x01, 0x45, - 0x9a, 0x1c, 0x65, 0x88, 0x03, 0x27, 0xa4, 0x96, 0x3f, 0xab, 0x10, 0x30, 0x85, 0x71, 0xd9, 0xa5, - 0xb2, 0xdd, 0xb7, 0x8d, 0xd5, 0xd6, 0x8e, 0x12, 0xaf, 0x5b, 0xf7, 0x29, 0xf8, 0x52, 0x48, 0x1c, - 0x77, 0xe4, 0x88, 0xda, 0x2f, 0x82, 0xec, 0xfc, 0x69, 0x52, 0x94, 0x4b, 0xe4, 0xf7, 0xc9, 0xcf, - 0x8f, 0xfd, 0x3e, 0x7e, 0xd1, 0x73, 0x46, 0xd9, 0x7a, 0xa1, 0xa4, 0x7f, 0xa7, 0x24, 0x70, 0x25, + 0x1a, 0x8e, 0x32, 0x0e, 0x88, 0x13, 0x52, 0xcb, 0x9f, 0x55, 0x08, 0x34, 0xc2, 0xb8, 0xec, 0x52, + 0xd9, 0xee, 0xdb, 0xc6, 0x6a, 0x6b, 0x47, 0x89, 0xd7, 0xad, 0xfb, 0x14, 0x7c, 0x29, 0x24, 0x8e, + 0x3b, 0x72, 0x44, 0xed, 0x17, 0x41, 0x76, 0xfe, 0x2c, 0xe9, 0x94, 0x4b, 0xe4, 0xf7, 0xc9, 0xcf, + 0x8f, 0xfd, 0x3e, 0x7e, 0xd1, 0x73, 0x46, 0xd9, 0x7a, 0xa1, 0xa4, 0x7f, 0xa3, 0x24, 0x70, 0x25, 0xb9, 0x80, 0x64, 0x06, 0xfe, 0x2a, 0xf0, 0x63, 0xca, 0xe7, 0xa0, 0x49, 0x9c, 0x28, 0xad, 0xb0, - 0x9b, 0x63, 0xa4, 0x86, 0x91, 0x55, 0x70, 0x7c, 0x5a, 0x18, 0x30, 0xcd, 0x79, 0x04, 0x7c, 0x1e, - 0x2b, 0x21, 0xb5, 0x31, 0xa8, 0x09, 0x99, 0xcf, 0xf1, 0xab, 0x82, 0xde, 0xfd, 0x11, 0x72, 0x66, - 0xe8, 0xff, 0x50, 0x52, 0x31, 0x5e, 0x88, 0x59, 0x64, 0xbe, 0x50, 0x3a, 0x57, 0x94, 0x9c, 0xef, - 0x15, 0x3c, 0xc4, 0x8a, 0x47, 0xb9, 0x6b, 0xb1, 0xce, 0x99, 0xd3, 0xc6, 0x6e, 0xeb, 0x7d, 0x59, - 0xba, 0x97, 0xa0, 0x67, 0x57, 0x55, 0xf9, 0xc2, 0x26, 0xf2, 0x9e, 0x6a, 0x8a, 0xbf, 0xa0, 0x23, - 0xa6, 0xf9, 0x58, 0x8b, 0x25, 0xa4, 0x9a, 0x2e, 0x63, 0xd7, 0x39, 0x71, 0xfa, 0xdd, 0xb3, 0x17, - 0xa4, 0x29, 0x27, 0x32, 0xb8, 0x1c, 0x5e, 0x16, 0xf4, 0x79, 0x2b, 0x3c, 0x64, 0x9a, 0x97, 0xf5, - 0xe0, 0x11, 0xea, 0x64, 0x71, 0xf7, 0x7e, 0xb5, 0xd1, 0x61, 0x15, 0xc5, 0xef, 0x50, 0x27, 0x02, - 0x3a, 0x81, 0x24, 0x3f, 0xe2, 0x65, 0xf3, 0x11, 0x23, 0x39, 0x81, 0x5b, 0x98, 0x9c, 0x5b, 0x3c, - 0xcc, 0xb7, 0xe1, 0x11, 0xea, 0x9a, 0xab, 0x66, 0x55, 0xea, 0x3e, 0x38, 0x69, 0xf7, 0xbb, 0x67, - 0xfd, 0xd2, 0x65, 0x2f, 0xcb, 0xec, 0xa6, 0x99, 0xc5, 0x48, 0x4e, 0x55, 0x88, 0x98, 0xe6, 0x59, - 0x99, 0xe2, 0xb7, 0x08, 0xd9, 0x40, 0xc7, 0x42, 0x4e, 0x95, 0xdb, 0xb6, 0xf7, 0x29, 0xdf, 0x89, - 0x94, 0x59, 0xaf, 0x02, 0xf2, 0xc1, 0xac, 0xc3, 0xc7, 0x56, 0x32, 0x36, 0xf8, 0x2b, 0x7a, 0x92, - 0xd0, 0x9b, 0xf1, 0xee, 0x95, 0xdd, 0x87, 0x7b, 0xed, 0xd4, 0x26, 0xc2, 0x78, 0x84, 0xf4, 0x66, - 0x58, 0x6a, 0xe1, 0x51, 0x52, 0x2d, 0xf1, 0x0f, 0x84, 0x4d, 0x57, 0xe9, 0x35, 0x5b, 0x8a, 0x34, - 0x15, 0x4a, 0x8e, 0xe7, 0xb0, 0x76, 0x0f, 0xf6, 0x3c, 0xeb, 0x23, 0xb8, 0x0a, 0xc8, 0xf7, 0x92, - 0xff, 0x0c, 0xeb, 0xf0, 0x29, 0xd3, 0xbc, 0xa6, 0xe0, 0x4f, 0xe8, 0x20, 0x4e, 0x94, 0x9a, 0xba, - 0x1d, 0xeb, 0x14, 0x34, 0x87, 0x7d, 0x61, 0xb0, 0x8f, 0x42, 0xd2, 0x85, 0xb8, 0x83, 0xc9, 0x30, - 0xa2, 0x42, 0xda, 0xbc, 0xb2, 0xfd, 0x83, 0x6f, 0xbf, 0x37, 0x9e, 0x73, 0xbf, 0xf1, 0x9c, 0xbf, - 0x1b, 0xcf, 0xf9, 0xb9, 0xf5, 0x5a, 0xf7, 0x5b, 0xaf, 0xf5, 0x67, 0xeb, 0xb5, 0xae, 0xde, 0xcc, - 0x84, 0x8e, 0xae, 0x19, 0xe1, 0x6a, 0xe9, 0xe7, 0xee, 0xdc, 0xec, 0x2e, 0x0a, 0xff, 0x76, 0x6f, - 0x3a, 0xf5, 0x3a, 0x86, 0x94, 0x75, 0xec, 0x4c, 0xbe, 0xfe, 0x17, 0x00, 0x00, 0xff, 0xff, 0x31, - 0xea, 0x29, 0xbc, 0xb1, 0x03, 0x00, 0x00, + 0x9b, 0x63, 0xa4, 0x86, 0x91, 0x55, 0x70, 0x78, 0x5c, 0x18, 0x30, 0xcd, 0x79, 0x04, 0x7c, 0x1e, + 0x2b, 0x21, 0xb5, 0x31, 0xa8, 0x09, 0x99, 0xcf, 0xe1, 0xab, 0x82, 0xbe, 0xfb, 0x23, 0xe4, 0xcc, + 0xd0, 0xf7, 0x50, 0x52, 0x31, 0x5e, 0x88, 0x59, 0x64, 0xbe, 0x50, 0x3a, 0x57, 0x94, 0x9c, 0xef, + 0x15, 0x3c, 0xc4, 0x8a, 0x47, 0xb9, 0x6b, 0xb1, 0xce, 0x99, 0xe3, 0xc6, 0x6e, 0xeb, 0x7d, 0x59, + 0xba, 0x97, 0xa0, 0x67, 0x17, 0x55, 0xf9, 0xcc, 0x26, 0xf2, 0x81, 0x6a, 0x8a, 0xbf, 0xa2, 0x03, + 0xa6, 0xf9, 0x58, 0x8b, 0x25, 0xa4, 0x9a, 0x2e, 0x63, 0xd7, 0x39, 0x72, 0xfa, 0xdd, 0x93, 0x17, + 0xa4, 0x29, 0x27, 0x32, 0x38, 0x1f, 0x9e, 0x17, 0xf4, 0x69, 0x2b, 0xdc, 0x67, 0x9a, 0x97, 0xf5, + 0xe0, 0x11, 0xea, 0x64, 0x71, 0xf7, 0x7e, 0xb7, 0xd1, 0x7e, 0x15, 0xc5, 0xef, 0x51, 0x27, 0x02, + 0x3a, 0x81, 0x24, 0x3f, 0xe2, 0x65, 0xf3, 0x11, 0x23, 0x39, 0x81, 0x6b, 0x98, 0x9c, 0x5a, 0x3c, + 0xcc, 0xb7, 0xe1, 0x11, 0xea, 0x9a, 0xab, 0x66, 0x55, 0xea, 0x3e, 0x38, 0x6a, 0xf7, 0xbb, 0x27, + 0xfd, 0xd2, 0x65, 0x27, 0xcb, 0xec, 0xa6, 0x99, 0xc5, 0x48, 0x4e, 0x55, 0x88, 0x98, 0xe6, 0x59, + 0x99, 0xe2, 0x77, 0x08, 0xd9, 0x40, 0xc7, 0x42, 0x4e, 0x95, 0xdb, 0xb6, 0xf7, 0x29, 0xdf, 0x89, + 0x94, 0x59, 0xaf, 0x02, 0xf2, 0xd1, 0xac, 0xc3, 0xc7, 0x56, 0x32, 0x36, 0xf8, 0x1b, 0x7a, 0x92, + 0xd0, 0xab, 0xf1, 0xdd, 0x2b, 0xbb, 0x0f, 0x77, 0xda, 0xa9, 0x4d, 0x84, 0xf1, 0x08, 0xe9, 0xd5, + 0xb0, 0xd4, 0xc2, 0x83, 0xa4, 0x5a, 0xe2, 0x9f, 0x08, 0x9b, 0xae, 0xd2, 0x4b, 0xb6, 0x14, 0x69, + 0x2a, 0x94, 0x1c, 0xcf, 0x61, 0xed, 0xee, 0xed, 0x78, 0xd6, 0x47, 0x70, 0x15, 0x90, 0x1f, 0x25, + 0xff, 0x05, 0xd6, 0xe1, 0x53, 0xa6, 0x79, 0x4d, 0xc1, 0x9f, 0xd1, 0x5e, 0x9c, 0x28, 0x35, 0x75, + 0x3b, 0xd6, 0x29, 0x68, 0x0e, 0xfb, 0xcc, 0x60, 0x9f, 0x84, 0xa4, 0x0b, 0x71, 0x03, 0x93, 0x61, + 0x44, 0x85, 0xb4, 0x79, 0x65, 0xfb, 0x07, 0xdf, 0xff, 0x6c, 0x3c, 0xe7, 0x76, 0xe3, 0x39, 0xff, + 0x36, 0x9e, 0xf3, 0x6b, 0xeb, 0xb5, 0x6e, 0xb7, 0x5e, 0xeb, 0xef, 0xd6, 0x6b, 0x5d, 0xbc, 0x9d, + 0x09, 0x1d, 0x5d, 0x32, 0xc2, 0xd5, 0xd2, 0xcf, 0xdd, 0x17, 0x94, 0xa5, 0xaf, 0x85, 0x2a, 0x4a, + 0xff, 0x7a, 0x67, 0x3e, 0xf5, 0x3a, 0x86, 0x94, 0x75, 0xec, 0x54, 0xbe, 0xf9, 0x1f, 0x00, 0x00, + 0xff, 0xff, 0x7d, 0x8d, 0x6b, 0xdb, 0xb3, 0x03, 0x00, 0x00, } func (m *ZoneconciergePacketData) Marshal() (dAtA []byte, err error) { diff --git a/x/zoneconcierge/types/params.pb.go b/x/zoneconcierge/types/params.pb.go index ac4b27c33..732cfcecd 100644 --- a/x/zoneconcierge/types/params.pb.go +++ b/x/zoneconcierge/types/params.pb.go @@ -79,7 +79,7 @@ func init() { } var fileDescriptor_c0696c936eb15fe4 = []byte{ - // 227 bytes of a gzipped FileDescriptorProto + // 229 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xaf, 0xca, 0xcf, 0x4b, 0x4d, 0xce, 0xcf, 0x4b, 0xce, 0x4c, 0x2d, 0x4a, 0x4f, 0xd5, 0x2f, 0x33, 0xd4, 0x2f, 0x48, 0x2c, 0x4a, 0xcc, 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, @@ -89,12 +89,12 @@ var fileDescriptor_c0696c936eb15fe4 = []byte{ 0xe6, 0xa6, 0xe6, 0x97, 0x96, 0xc4, 0x17, 0x83, 0x0c, 0x49, 0x29, 0x96, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x75, 0x52, 0xfd, 0x74, 0x4f, 0x5e, 0xb1, 0x32, 0x31, 0x37, 0xc7, 0x4a, 0x09, 0xb7, 0x5a, 0xa5, 0x20, 0xf1, 0xcc, 0xa4, 0xe4, 0x00, 0xb0, 0x5c, 0x08, 0x44, 0x2a, 0x18, 0x22, 0x63, 0xc5, - 0xf2, 0x62, 0x81, 0x3c, 0xa3, 0x93, 0xff, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, + 0xf2, 0x62, 0x81, 0x3c, 0xa3, 0x53, 0xe0, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, - 0x44, 0x99, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x3d, 0x92, - 0x9c, 0x91, 0x98, 0x99, 0x07, 0xe3, 0xe8, 0x57, 0xa0, 0x79, 0xbf, 0xa4, 0xb2, 0x20, 0xb5, 0x38, - 0x89, 0x0d, 0xec, 0x17, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2d, 0xf3, 0xe4, 0xef, 0x24, - 0x01, 0x00, 0x00, + 0x44, 0x99, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x43, 0x3d, 0x92, + 0x93, 0x98, 0x54, 0xac, 0x9b, 0x99, 0x0f, 0xe3, 0xea, 0x57, 0xa0, 0x05, 0x40, 0x49, 0x65, 0x41, + 0x6a, 0x71, 0x12, 0x1b, 0xd8, 0x37, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2d, 0x2b, 0x77, + 0x59, 0x26, 0x01, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { diff --git a/x/zoneconcierge/types/params_test.go b/x/zoneconcierge/types/params_test.go index c4be306d0..863b9cb39 100644 --- a/x/zoneconcierge/types/params_test.go +++ b/x/zoneconcierge/types/params_test.go @@ -3,7 +3,7 @@ package types_test import ( "testing" - "github.com/babylonchain/babylon/x/zoneconcierge/types" + "github.com/babylonlabs-io/babylon/x/zoneconcierge/types" "github.com/stretchr/testify/require" ) diff --git a/x/zoneconcierge/types/query.pb.go b/x/zoneconcierge/types/query.pb.go index 64d219deb..c2f8f49dd 100644 --- a/x/zoneconcierge/types/query.pb.go +++ b/x/zoneconcierge/types/query.pb.go @@ -6,9 +6,9 @@ package types import ( context "context" fmt "fmt" - types2 "github.com/babylonchain/babylon/x/btccheckpoint/types" - types1 "github.com/babylonchain/babylon/x/checkpointing/types" - types "github.com/babylonchain/babylon/x/epoching/types" + types2 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + types1 "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types "github.com/babylonlabs-io/babylon/x/epoching/types" query "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -1012,81 +1012,81 @@ func init() { } var fileDescriptor_cd665af90102da38 = []byte{ - // 1176 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0xdc, 0x44, - 0x14, 0x8e, 0xf3, 0xab, 0xc9, 0x5b, 0x0a, 0xd5, 0x24, 0x2d, 0x8b, 0xdb, 0x6e, 0x22, 0x43, 0x69, - 0x5a, 0x12, 0x9b, 0x4d, 0x49, 0xab, 0x72, 0xa0, 0x6a, 0x52, 0x92, 0x46, 0x45, 0xa5, 0x35, 0x04, - 0x24, 0x2e, 0xc6, 0xf6, 0xce, 0x7a, 0xad, 0x64, 0x3d, 0x5b, 0xdb, 0xbb, 0xed, 0x36, 0x84, 0x03, - 0xea, 0x1d, 0x24, 0x2e, 0x88, 0x13, 0x27, 0x0e, 0x1c, 0x7a, 0xe3, 0x4f, 0x40, 0xea, 0x81, 0x43, - 0x25, 0x2e, 0x9c, 0x10, 0x4a, 0xf8, 0x37, 0x90, 0x90, 0x67, 0xc6, 0xbb, 0xfe, 0xb9, 0xeb, 0x0d, - 0xb9, 0xed, 0x8c, 0xdf, 0xfb, 0xbe, 0xef, 0xbd, 0x79, 0x33, 0xef, 0x2d, 0xbc, 0x65, 0xe8, 0x46, - 0x77, 0x8f, 0x38, 0xca, 0x53, 0xe2, 0x60, 0x93, 0x38, 0xa6, 0x8d, 0x5d, 0x0b, 0x2b, 0x9d, 0xaa, - 0xf2, 0xa8, 0x8d, 0xdd, 0xae, 0xdc, 0x72, 0x89, 0x4f, 0x50, 0x99, 0x5b, 0xc9, 0x31, 0x2b, 0xb9, - 0x53, 0x15, 0xe7, 0x2d, 0x62, 0x11, 0x6a, 0xa4, 0x04, 0xbf, 0x98, 0xbd, 0x78, 0xc1, 0x22, 0xc4, - 0xda, 0xc3, 0x8a, 0xde, 0xb2, 0x15, 0xdd, 0x71, 0x88, 0xaf, 0xfb, 0x36, 0x71, 0x3c, 0xfe, 0xf5, - 0xaa, 0x49, 0xbc, 0x26, 0xf1, 0x14, 0x43, 0xf7, 0x30, 0xa3, 0x51, 0x3a, 0x55, 0x03, 0xfb, 0x7a, - 0x55, 0x69, 0xe9, 0x96, 0xed, 0x50, 0x63, 0x6e, 0xbb, 0x1c, 0xea, 0x33, 0x7c, 0xd3, 0x6c, 0x60, - 0x73, 0xb7, 0x45, 0x6c, 0xc7, 0x0f, 0xf4, 0xc5, 0x36, 0xb8, 0xf5, 0x95, 0xd0, 0xba, 0xff, 0xc5, - 0x76, 0xac, 0xc0, 0x3a, 0x65, 0x2a, 0x85, 0xa6, 0xb8, 0x45, 0xcc, 0x06, 0xb7, 0x0a, 0x7f, 0x27, - 0xc9, 0x53, 0xc9, 0x89, 0xe7, 0x81, 0x59, 0x5f, 0xca, 0xb5, 0x6e, 0xe9, 0xae, 0xde, 0xe4, 0xd1, - 0x4b, 0xf3, 0x80, 0x1e, 0x06, 0x31, 0x3f, 0xa0, 0x9b, 0x2a, 0x7e, 0xd4, 0xc6, 0x9e, 0x2f, 0xed, - 0xc0, 0x5c, 0x6c, 0xd7, 0x6b, 0x11, 0xc7, 0xc3, 0xe8, 0x03, 0x98, 0x66, 0xce, 0x65, 0x61, 0x51, - 0x58, 0x2a, 0xad, 0x2e, 0xca, 0x79, 0x27, 0x21, 0x33, 0xcf, 0xf5, 0xc9, 0x17, 0x7f, 0x2d, 0x8c, - 0xa9, 0xdc, 0x4b, 0xda, 0xe2, 0x64, 0x77, 0xb1, 0x5e, 0xc3, 0x2e, 0x27, 0x43, 0x6f, 0xc0, 0x8c, - 0xd9, 0xd0, 0x6d, 0x47, 0xb3, 0x6b, 0x14, 0x77, 0x56, 0x3d, 0x45, 0xd7, 0xdb, 0x35, 0x74, 0x0e, - 0xa6, 0x1b, 0xd8, 0xb6, 0x1a, 0x7e, 0x79, 0x7c, 0x51, 0x58, 0x9a, 0x54, 0xf9, 0x4a, 0xfa, 0x51, - 0xe0, 0x02, 0x43, 0x24, 0x2e, 0xf0, 0x56, 0x60, 0x1f, 0xec, 0x70, 0x81, 0x97, 0xf3, 0x05, 0x6e, - 0x3b, 0x35, 0xfc, 0x04, 0xd7, 0x38, 0x00, 0x77, 0x43, 0xeb, 0xf0, 0x4a, 0x9d, 0xb8, 0xbb, 0x1a, - 0x5b, 0x7a, 0x94, 0xb6, 0xb4, 0xba, 0x90, 0x0f, 0xb3, 0x49, 0xdc, 0x5d, 0x4f, 0x2d, 0x05, 0x4e, - 0x0c, 0xca, 0x93, 0x34, 0x38, 0x4b, 0xb5, 0x6d, 0x04, 0x41, 0x7c, 0x64, 0x7b, 0x7e, 0x18, 0xe8, - 0x26, 0x40, 0xbf, 0xa2, 0xb8, 0xc2, 0xb7, 0x65, 0x56, 0x7e, 0x72, 0x50, 0x7e, 0x32, 0xab, 0x72, - 0x5e, 0x7e, 0xf2, 0x03, 0xdd, 0xc2, 0xdc, 0x57, 0x8d, 0x78, 0x4a, 0x5f, 0xc3, 0xb9, 0x24, 0x01, - 0x8f, 0xff, 0x3c, 0xcc, 0x86, 0xa9, 0x0c, 0xce, 0x68, 0x62, 0x69, 0x56, 0x9d, 0xe1, 0xb9, 0xf4, - 0xd0, 0x56, 0x8c, 0x7e, 0x9c, 0x27, 0x68, 0x18, 0x3d, 0x43, 0x8e, 0xf1, 0xaf, 0x45, 0xf9, 0xbd, - 0x6d, 0xa7, 0x4e, 0xc2, 0x08, 0x07, 0xf1, 0x4b, 0x1a, 0xbc, 0x9e, 0x72, 0xe3, 0xba, 0xef, 0x40, - 0x89, 0x9a, 0x79, 0x9a, 0xed, 0xd4, 0x09, 0xf5, 0x2c, 0xad, 0xbe, 0x99, 0x9f, 0x75, 0x0a, 0x41, - 0x11, 0xc0, 0xec, 0xa1, 0x49, 0x9f, 0xc3, 0x79, 0x4a, 0xf0, 0x61, 0x70, 0x6f, 0x32, 0xc5, 0xd1, - 0x1b, 0xa5, 0x39, 0xed, 0x26, 0xcd, 0xfe, 0xa4, 0x3a, 0x43, 0x37, 0xee, 0xb7, 0x9b, 0x71, 0xe5, - 0xe3, 0x09, 0xe5, 0x35, 0xb8, 0x90, 0x0d, 0x7c, 0xa2, 0xf2, 0xbf, 0xe2, 0xf9, 0x09, 0x4e, 0x94, - 0xd7, 0x52, 0x81, 0x2b, 0xb2, 0x99, 0x71, 0xaa, 0xc7, 0x29, 0xaa, 0x9f, 0x05, 0x28, 0xa7, 0xe9, - 0x79, 0x80, 0xb7, 0xe1, 0x54, 0x78, 0x23, 0x58, 0x70, 0x85, 0x2f, 0x56, 0xe8, 0x77, 0x72, 0xd5, - 0xf7, 0x19, 0x3f, 0x8c, 0x40, 0x27, 0x3d, 0x90, 0x44, 0xae, 0x06, 0x1e, 0x73, 0x34, 0x91, 0xe3, - 0xb1, 0x44, 0x4a, 0x06, 0x5c, 0xcc, 0xc1, 0x3d, 0xb1, 0x24, 0x48, 0x9f, 0xc2, 0x02, 0xe5, 0xd8, - 0xb4, 0x1d, 0x7d, 0xcf, 0x7e, 0x8a, 0x6b, 0xa3, 0x5d, 0x21, 0x34, 0x0f, 0x53, 0x2d, 0x97, 0x74, - 0x30, 0xd5, 0x3e, 0xa3, 0xb2, 0x85, 0xf4, 0x4c, 0x80, 0xc5, 0x7c, 0x58, 0xae, 0xfe, 0x4b, 0x38, - 0x5b, 0x0f, 0x3f, 0x6b, 0xe9, 0x6a, 0x5d, 0x1e, 0xf0, 0xc4, 0xc5, 0x50, 0x29, 0xe8, 0x5c, 0x3d, - 0xcd, 0x24, 0xf9, 0x70, 0x25, 0x43, 0x45, 0xf0, 0x69, 0xc7, 0xf1, 0xed, 0xbd, 0xbb, 0xf4, 0xe9, - 0x3e, 0xfe, 0xa3, 0xdf, 0x0f, 0x7e, 0x22, 0x1a, 0xfc, 0xf3, 0x09, 0xb8, 0x5a, 0x84, 0x96, 0xa7, - 0x61, 0x07, 0xe6, 0x13, 0x69, 0x08, 0xb3, 0x20, 0x14, 0xbd, 0xb3, 0xa8, 0x9e, 0x62, 0x42, 0x37, - 0x01, 0x58, 0xd1, 0x51, 0x30, 0x56, 0xdd, 0x62, 0x0f, 0xac, 0xd7, 0xc8, 0x3b, 0x55, 0x99, 0x96, - 0x96, 0xca, 0x4a, 0x94, 0xba, 0xde, 0x87, 0x57, 0x5d, 0xfd, 0xb1, 0xd6, 0x1f, 0x09, 0x68, 0x7c, - 0xd1, 0xea, 0x8a, 0x8d, 0x0f, 0x01, 0x86, 0xaa, 0x3f, 0xde, 0xe8, 0xed, 0xa9, 0xa7, 0xdd, 0xe8, - 0x12, 0xed, 0x00, 0x32, 0x7c, 0x53, 0xf3, 0xda, 0x46, 0xd3, 0xf6, 0x3c, 0x9b, 0x38, 0xda, 0x2e, - 0xee, 0x96, 0x27, 0x13, 0x98, 0xf1, 0x79, 0xa5, 0x53, 0x95, 0x3f, 0xe9, 0xd9, 0xdf, 0xc3, 0x5d, - 0xf5, 0x8c, 0xe1, 0x9b, 0xb1, 0x1d, 0xb4, 0x45, 0xb3, 0x4f, 0xea, 0xe5, 0x29, 0x8a, 0x54, 0x1d, - 0xd0, 0xfa, 0x03, 0xb3, 0x8c, 0xa2, 0x61, 0xfe, 0xab, 0xcf, 0x4e, 0xc3, 0x14, 0x3d, 0x30, 0xf4, - 0xad, 0x00, 0xd3, 0x6c, 0x4e, 0x40, 0x03, 0xca, 0x2f, 0x3d, 0x9e, 0x88, 0x2b, 0x05, 0xad, 0xd9, - 0x99, 0x4b, 0x4b, 0xdf, 0xfc, 0xf1, 0xcf, 0xf7, 0xe3, 0x12, 0x5a, 0x54, 0x86, 0xcc, 0x44, 0xe8, - 0xb9, 0x00, 0xd3, 0xec, 0xce, 0x0e, 0x55, 0x14, 0x9b, 0x61, 0x86, 0x2a, 0x8a, 0xcf, 0x29, 0xd2, - 0x16, 0x55, 0x74, 0x1b, 0xdd, 0xca, 0x57, 0xd4, 0xaf, 0x4d, 0x65, 0x3f, 0xbc, 0x29, 0x07, 0x0a, - 0x7b, 0x48, 0x94, 0x7d, 0x76, 0x25, 0x0e, 0xd0, 0x0f, 0x02, 0xcc, 0xf6, 0xc6, 0x00, 0xa4, 0x0c, - 0x51, 0x91, 0x9c, 0x48, 0xc4, 0x77, 0x8b, 0x3b, 0x14, 0xcf, 0x25, 0x7b, 0x5c, 0xd0, 0x4f, 0x02, - 0x40, 0xff, 0x75, 0x40, 0x85, 0xa8, 0xa2, 0x2f, 0xa1, 0x58, 0x1d, 0xc1, 0x83, 0xab, 0x5b, 0xa1, - 0xea, 0x2e, 0xa3, 0x4b, 0xc3, 0xd4, 0xd1, 0xc4, 0xa2, 0x5f, 0x05, 0x78, 0x2d, 0xd1, 0xd3, 0xd1, - 0xda, 0x10, 0xd6, 0xec, 0xe1, 0x42, 0xbc, 0x3e, 0xaa, 0x1b, 0x57, 0x7c, 0x8d, 0x2a, 0x5e, 0x41, - 0xef, 0xe4, 0x2b, 0x66, 0x0f, 0x4b, 0x54, 0xf7, 0x2f, 0x02, 0x94, 0x22, 0x6d, 0x1a, 0x0d, 0xcb, - 0x54, 0x7a, 0xa2, 0x10, 0x57, 0x47, 0x71, 0xe1, 0x5a, 0xdf, 0xa3, 0x5a, 0x65, 0xb4, 0x9c, 0xaf, - 0x95, 0x37, 0xba, 0x48, 0xc9, 0xa2, 0xdf, 0x05, 0x38, 0x93, 0xec, 0xa9, 0xe8, 0x7a, 0x01, 0xfa, - 0x8c, 0xe6, 0x2e, 0xde, 0x18, 0xd9, 0xaf, 0xf8, 0x8d, 0x4b, 0x6b, 0x67, 0xa9, 0xf7, 0x94, 0xfd, - 0xde, 0x40, 0x71, 0x80, 0x7e, 0x13, 0x60, 0x2e, 0xa3, 0xcf, 0xa2, 0x9b, 0x43, 0x94, 0xe5, 0xb7, - 0x7c, 0xf1, 0xfd, 0xe3, 0xb8, 0xf2, 0xb8, 0x6e, 0xd0, 0xb8, 0xaa, 0x48, 0xc9, 0x8f, 0x2b, 0xb3, - 0xed, 0xa3, 0x7f, 0x05, 0xb8, 0x38, 0xb0, 0x65, 0xa2, 0x8d, 0x91, 0x64, 0x65, 0xf7, 0x79, 0xf1, - 0xce, 0xff, 0x03, 0xe1, 0x51, 0x3e, 0xa4, 0x51, 0xde, 0x43, 0xdb, 0x85, 0xa3, 0xcc, 0x78, 0x39, - 0x03, 0xc4, 0xde, 0xcb, 0xb9, 0xfe, 0xf1, 0x8b, 0xc3, 0x8a, 0xf0, 0xf2, 0xb0, 0x22, 0xfc, 0x7d, - 0x58, 0x11, 0xbe, 0x3b, 0xaa, 0x8c, 0xbd, 0x3c, 0xaa, 0x8c, 0xfd, 0x79, 0x54, 0x19, 0xfb, 0x62, - 0xcd, 0xb2, 0xfd, 0x46, 0xdb, 0x90, 0x4d, 0xd2, 0x0c, 0xe9, 0x28, 0x4c, 0x8f, 0xfb, 0x49, 0x82, - 0xdd, 0xef, 0xb6, 0xb0, 0x67, 0x4c, 0xd3, 0x3f, 0xd4, 0xd7, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, - 0x03, 0xf9, 0xf2, 0x6b, 0xc4, 0x10, 0x00, 0x00, + // 1182 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x57, 0xcf, 0x6f, 0x1b, 0xc5, + 0x17, 0xcf, 0xe6, 0x57, 0x93, 0xe7, 0x6f, 0xbf, 0x54, 0x93, 0xb4, 0x98, 0x6d, 0xeb, 0x44, 0x0b, + 0xa5, 0x69, 0x49, 0x76, 0x71, 0x4a, 0x1b, 0x95, 0x03, 0x55, 0x93, 0x92, 0x34, 0x2a, 0xaa, 0x9a, + 0x85, 0x80, 0xc4, 0xc5, 0xec, 0xae, 0xc7, 0xf6, 0x2a, 0xf1, 0x8e, 0xbb, 0xb3, 0x76, 0xeb, 0x86, + 0x70, 0x40, 0xbd, 0x83, 0xc4, 0x05, 0x71, 0xe2, 0xc4, 0x81, 0x43, 0x6f, 0xfc, 0x09, 0x48, 0x3d, + 0x70, 0xa8, 0xc4, 0x85, 0x13, 0x42, 0x09, 0xff, 0x06, 0x12, 0xda, 0x99, 0x59, 0x7b, 0x7f, 0xda, + 0xeb, 0x90, 0x9b, 0x67, 0xf6, 0xbd, 0xcf, 0xe7, 0xf3, 0xde, 0xbc, 0x99, 0xf7, 0x0c, 0x6f, 0x99, + 0x86, 0xd9, 0xdd, 0x27, 0x8e, 0xf6, 0x8c, 0x38, 0xd8, 0x22, 0x8e, 0x65, 0x63, 0xb7, 0x8e, 0xb5, + 0x4e, 0x59, 0x7b, 0xdc, 0xc6, 0x6e, 0x57, 0x6d, 0xb9, 0xc4, 0x23, 0xa8, 0x28, 0xac, 0xd4, 0x88, + 0x95, 0xda, 0x29, 0xcb, 0xf3, 0x75, 0x52, 0x27, 0xcc, 0x48, 0xf3, 0x7f, 0x71, 0x7b, 0xf9, 0x52, + 0x9d, 0x90, 0xfa, 0x3e, 0xd6, 0x8c, 0x96, 0xad, 0x19, 0x8e, 0x43, 0x3c, 0xc3, 0xb3, 0x89, 0x43, + 0xc5, 0xd7, 0xeb, 0x16, 0xa1, 0x4d, 0x42, 0x35, 0xd3, 0xa0, 0x98, 0xd3, 0x68, 0x9d, 0xb2, 0x89, + 0x3d, 0xa3, 0xac, 0xb5, 0x8c, 0xba, 0xed, 0x30, 0x63, 0x61, 0xbb, 0x1c, 0xe8, 0x33, 0x3d, 0xcb, + 0x6a, 0x60, 0x6b, 0xaf, 0x45, 0x6c, 0xc7, 0xf3, 0xf5, 0x45, 0x36, 0x84, 0xf5, 0xb5, 0xc0, 0xba, + 0xff, 0xc5, 0x76, 0xea, 0xbe, 0x75, 0xc2, 0x54, 0x09, 0x4c, 0x71, 0x8b, 0x58, 0x0d, 0x61, 0x15, + 0xfc, 0x8e, 0x93, 0x27, 0x92, 0x13, 0xcd, 0x03, 0xb7, 0xbe, 0x92, 0x69, 0xdd, 0x32, 0x5c, 0xa3, + 0x29, 0xa2, 0x57, 0xe6, 0x01, 0xed, 0xf8, 0x31, 0x3f, 0x62, 0x9b, 0x3a, 0x7e, 0xdc, 0xc6, 0xd4, + 0x53, 0x76, 0x61, 0x2e, 0xb2, 0x4b, 0x5b, 0xc4, 0xa1, 0x18, 0x7d, 0x00, 0xd3, 0xdc, 0xb9, 0x28, + 0x2d, 0x4a, 0x4b, 0x85, 0xd5, 0x45, 0x35, 0xeb, 0x24, 0x54, 0xee, 0xb9, 0x3e, 0xf9, 0xf2, 0xcf, + 0x85, 0x31, 0x5d, 0x78, 0x29, 0x5b, 0x82, 0xec, 0x3e, 0x36, 0xaa, 0xd8, 0x15, 0x64, 0xe8, 0x0d, + 0x98, 0xb1, 0x1a, 0x86, 0xed, 0x54, 0xec, 0x2a, 0xc3, 0x9d, 0xd5, 0xcf, 0xb0, 0xf5, 0x76, 0x15, + 0x5d, 0x80, 0xe9, 0x06, 0xb6, 0xeb, 0x0d, 0xaf, 0x38, 0xbe, 0x28, 0x2d, 0x4d, 0xea, 0x62, 0xa5, + 0xfc, 0x20, 0x09, 0x81, 0x01, 0x92, 0x10, 0x78, 0xc7, 0xb7, 0xf7, 0x77, 0x84, 0xc0, 0xab, 0xd9, + 0x02, 0xb7, 0x9d, 0x2a, 0x7e, 0x8a, 0xab, 0x02, 0x40, 0xb8, 0xa1, 0x75, 0xf8, 0x5f, 0x8d, 0xb8, + 0x7b, 0x15, 0xbe, 0xa4, 0x8c, 0xb6, 0xb0, 0xba, 0x90, 0x0d, 0xb3, 0x49, 0xdc, 0x3d, 0xaa, 0x17, + 0x7c, 0x27, 0x0e, 0x45, 0x95, 0x0a, 0x9c, 0x67, 0xda, 0x36, 0xfc, 0x20, 0x3e, 0xb2, 0xa9, 0x17, + 0x04, 0xba, 0x09, 0xd0, 0xaf, 0x28, 0xa1, 0xf0, 0x6d, 0x95, 0x97, 0x9f, 0xea, 0x97, 0x9f, 0xca, + 0xab, 0x5c, 0x94, 0x9f, 0xfa, 0xc8, 0xa8, 0x63, 0xe1, 0xab, 0x87, 0x3c, 0x95, 0xaf, 0xe0, 0x42, + 0x9c, 0x40, 0xc4, 0x7f, 0x11, 0x66, 0x83, 0x54, 0xfa, 0x67, 0x34, 0xb1, 0x34, 0xab, 0xcf, 0x88, + 0x5c, 0x52, 0xb4, 0x15, 0xa1, 0x1f, 0x17, 0x09, 0x1a, 0x46, 0xcf, 0x91, 0x23, 0xfc, 0x37, 0xc3, + 0xfc, 0x74, 0xdb, 0xa9, 0x91, 0x20, 0xc2, 0x41, 0xfc, 0x4a, 0x05, 0x5e, 0x4f, 0xb8, 0x09, 0xdd, + 0xf7, 0xa0, 0xc0, 0xcc, 0x68, 0xc5, 0x76, 0x6a, 0x84, 0x79, 0x16, 0x56, 0xdf, 0xcc, 0xce, 0x3a, + 0x83, 0x60, 0x08, 0x60, 0xf5, 0xd0, 0x94, 0xcf, 0xe0, 0x22, 0x23, 0xf8, 0xd0, 0xbf, 0x37, 0xa9, + 0xe2, 0xd8, 0x8d, 0xaa, 0x38, 0xed, 0x26, 0xcb, 0xfe, 0xa4, 0x3e, 0xc3, 0x36, 0x1e, 0xb6, 0x9b, + 0x51, 0xe5, 0xe3, 0x31, 0xe5, 0x55, 0xb8, 0x94, 0x0e, 0x7c, 0xaa, 0xf2, 0xbf, 0x14, 0xf9, 0xf1, + 0x4f, 0x54, 0xd4, 0x52, 0x8e, 0x2b, 0xb2, 0x99, 0x72, 0xaa, 0x27, 0x29, 0xaa, 0x9f, 0x24, 0x28, + 0x26, 0xe9, 0x45, 0x80, 0x77, 0xe1, 0x4c, 0x70, 0x23, 0x78, 0x70, 0xb9, 0x2f, 0x56, 0xe0, 0x77, + 0x7a, 0xd5, 0xf7, 0xa9, 0x38, 0x0c, 0x5f, 0x27, 0x3b, 0x90, 0x58, 0xae, 0x06, 0x1e, 0x73, 0x38, + 0x91, 0xe3, 0x91, 0x44, 0x2a, 0x26, 0x5c, 0xce, 0xc0, 0x3d, 0xb5, 0x24, 0x28, 0x9f, 0xc0, 0x02, + 0xe3, 0xd8, 0xb4, 0x1d, 0x63, 0xdf, 0x7e, 0x86, 0xab, 0xa3, 0x5d, 0x21, 0x34, 0x0f, 0x53, 0x2d, + 0x97, 0x74, 0x30, 0xd3, 0x3e, 0xa3, 0xf3, 0x85, 0xf2, 0x5c, 0x82, 0xc5, 0x6c, 0x58, 0xa1, 0xfe, + 0x0b, 0x38, 0x5f, 0x0b, 0x3e, 0x57, 0x92, 0xd5, 0xba, 0x3c, 0xe0, 0x89, 0x8b, 0xa0, 0x32, 0xd0, + 0xb9, 0x5a, 0x92, 0x49, 0xf1, 0xe0, 0x5a, 0x8a, 0x0a, 0xff, 0xd3, 0xae, 0xe3, 0xd9, 0xfb, 0xf7, + 0xd9, 0xd3, 0x7d, 0xf2, 0x47, 0xbf, 0x1f, 0xfc, 0x44, 0x38, 0xf8, 0x17, 0x13, 0x70, 0x3d, 0x0f, + 0xad, 0x48, 0xc3, 0x2e, 0xcc, 0xc7, 0xd2, 0x10, 0x64, 0x41, 0xca, 0x7b, 0x67, 0x51, 0x2d, 0xc1, + 0x84, 0x6e, 0x03, 0xf0, 0xa2, 0x63, 0x60, 0xbc, 0xba, 0xe5, 0x1e, 0x58, 0xaf, 0x91, 0x77, 0xca, + 0x2a, 0x2b, 0x2d, 0x9d, 0x97, 0x28, 0x73, 0x7d, 0x08, 0xff, 0x77, 0x8d, 0x27, 0x95, 0xfe, 0x48, + 0xc0, 0xe2, 0x0b, 0x57, 0x57, 0x64, 0x7c, 0xf0, 0x31, 0x74, 0xe3, 0xc9, 0x46, 0x6f, 0x4f, 0x3f, + 0xeb, 0x86, 0x97, 0x68, 0x17, 0x90, 0xe9, 0x59, 0x15, 0xda, 0x36, 0x9b, 0x36, 0xa5, 0x36, 0x71, + 0x2a, 0x7b, 0xb8, 0x5b, 0x9c, 0x8c, 0x61, 0x46, 0xe7, 0x95, 0x4e, 0x59, 0xfd, 0xb8, 0x67, 0xff, + 0x00, 0x77, 0xf5, 0x73, 0xa6, 0x67, 0x45, 0x76, 0xd0, 0x16, 0xcb, 0x3e, 0xa9, 0x15, 0xa7, 0x18, + 0x52, 0x79, 0x40, 0xeb, 0xf7, 0xcd, 0x52, 0x8a, 0x86, 0xfb, 0xaf, 0x3e, 0x3f, 0x0b, 0x53, 0xec, + 0xc0, 0xd0, 0x37, 0x12, 0x4c, 0xf3, 0x39, 0x01, 0x0d, 0x28, 0xbf, 0xe4, 0x78, 0x22, 0xaf, 0xe4, + 0xb4, 0xe6, 0x67, 0xae, 0x2c, 0x7d, 0xfd, 0xfb, 0xdf, 0xdf, 0x8d, 0x2b, 0x68, 0x51, 0x1b, 0x32, + 0x13, 0xa1, 0x17, 0x12, 0x4c, 0xf3, 0x3b, 0x3b, 0x54, 0x51, 0x64, 0x86, 0x19, 0xaa, 0x28, 0x3a, + 0xa7, 0x28, 0x5b, 0x4c, 0xd1, 0x5d, 0x74, 0x27, 0x5b, 0x51, 0xbf, 0x36, 0xb5, 0x83, 0xe0, 0xa6, + 0x1c, 0x6a, 0xfc, 0x21, 0xd1, 0x0e, 0xf8, 0x95, 0x38, 0x44, 0xdf, 0x4b, 0x30, 0xdb, 0x1b, 0x03, + 0x90, 0x36, 0x44, 0x45, 0x7c, 0x22, 0x91, 0xdf, 0xcd, 0xef, 0x90, 0x3f, 0x97, 0xfc, 0x71, 0x41, + 0x3f, 0x4a, 0x00, 0xfd, 0xd7, 0x01, 0xe5, 0xa2, 0x0a, 0xbf, 0x84, 0x72, 0x79, 0x04, 0x0f, 0xa1, + 0x6e, 0x85, 0xa9, 0xbb, 0x8a, 0xae, 0x0c, 0x53, 0xc7, 0x12, 0x8b, 0x7e, 0x91, 0xe0, 0xb5, 0x58, + 0x4f, 0x47, 0x37, 0x87, 0xb0, 0xa6, 0x0f, 0x17, 0xf2, 0xad, 0x51, 0xdd, 0x84, 0xe2, 0x1b, 0x4c, + 0xf1, 0x0a, 0x7a, 0x27, 0x5b, 0x31, 0x7f, 0x58, 0xc2, 0xba, 0x7f, 0x96, 0xa0, 0x10, 0x6a, 0xd3, + 0x68, 0x58, 0xa6, 0x92, 0x13, 0x85, 0xbc, 0x3a, 0x8a, 0x8b, 0xd0, 0xfa, 0x1e, 0xd3, 0xaa, 0xa2, + 0xe5, 0x6c, 0xad, 0xa2, 0xd1, 0x85, 0x4a, 0x16, 0xfd, 0x26, 0xc1, 0xb9, 0x78, 0x4f, 0x45, 0xb7, + 0x72, 0xd0, 0xa7, 0x34, 0x77, 0x79, 0x6d, 0x64, 0xbf, 0xfc, 0x37, 0x2e, 0xa9, 0x9d, 0xa7, 0x9e, + 0x6a, 0x07, 0xbd, 0x81, 0xe2, 0x10, 0xfd, 0x2a, 0xc1, 0x5c, 0x4a, 0x9f, 0x45, 0xb7, 0x87, 0x28, + 0xcb, 0x6e, 0xf9, 0xf2, 0xfb, 0x27, 0x71, 0x15, 0x71, 0xad, 0xb1, 0xb8, 0xca, 0x48, 0xcb, 0x8e, + 0x2b, 0xb5, 0xed, 0xa3, 0x7f, 0x24, 0xb8, 0x3c, 0xb0, 0x65, 0xa2, 0x8d, 0x91, 0x64, 0xa5, 0xf7, + 0x79, 0xf9, 0xde, 0x7f, 0x03, 0x11, 0x51, 0xee, 0xb0, 0x28, 0x1f, 0xa0, 0xed, 0xdc, 0x51, 0xa6, + 0xbc, 0x9c, 0x3e, 0x62, 0xef, 0xe5, 0x5c, 0xdf, 0x79, 0x79, 0x54, 0x92, 0x5e, 0x1d, 0x95, 0xa4, + 0xbf, 0x8e, 0x4a, 0xd2, 0xb7, 0xc7, 0xa5, 0xb1, 0x57, 0xc7, 0xa5, 0xb1, 0x3f, 0x8e, 0x4b, 0x63, + 0x9f, 0xaf, 0xd5, 0x6d, 0xaf, 0xd1, 0x36, 0x55, 0x8b, 0x34, 0x03, 0xba, 0x7d, 0xc3, 0xa4, 0x2b, + 0x36, 0xe9, 0xb1, 0x3f, 0x8d, 0xf1, 0x7b, 0xdd, 0x16, 0xa6, 0xe6, 0x34, 0xfb, 0x4b, 0x7d, 0xe3, + 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x09, 0x4f, 0xa5, 0xb2, 0xc6, 0x10, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/zoneconcierge/types/tx.pb.go b/x/zoneconcierge/types/tx.pb.go index 032e66afa..d9f617164 100644 --- a/x/zoneconcierge/types/tx.pb.go +++ b/x/zoneconcierge/types/tx.pb.go @@ -135,7 +135,7 @@ func init() { func init() { proto.RegisterFile("babylon/zoneconcierge/v1/tx.proto", fileDescriptor_35e2112d987e4e18) } var fileDescriptor_35e2112d987e4e18 = []byte{ - // 331 bytes of a gzipped FileDescriptorProto + // 333 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0x4a, 0x4c, 0xaa, 0xcc, 0xc9, 0xcf, 0xd3, 0xaf, 0xca, 0xcf, 0x4b, 0x4d, 0xce, 0xcf, 0x4b, 0xce, 0x4c, 0x2d, 0x4a, 0x4f, 0xd5, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, @@ -151,12 +151,12 @@ var fileDescriptor_35e2112d987e4e18 = []byte{ 0x93, 0x67, 0x08, 0x82, 0xea, 0xb2, 0xe2, 0x6b, 0x7a, 0xbe, 0x41, 0x0b, 0x61, 0x9e, 0x92, 0x24, 0x97, 0x38, 0x9a, 0xd3, 0x82, 0x52, 0x8b, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x8d, 0xaa, 0xb8, 0x98, 0x7d, 0x8b, 0xd3, 0x85, 0x72, 0xb8, 0x78, 0x50, 0x5c, 0xae, 0x89, 0xdb, 0x46, 0x34, 0x93, 0xa4, - 0x0c, 0x89, 0x56, 0x0a, 0xb3, 0x54, 0x8a, 0xb5, 0xe1, 0xf9, 0x06, 0x2d, 0x46, 0x27, 0xff, 0x13, + 0x0c, 0x89, 0x56, 0x0a, 0xb3, 0x54, 0x8a, 0xb5, 0xe1, 0xf9, 0x06, 0x2d, 0x46, 0xa7, 0xc0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, - 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, - 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x9a, 0x9e, 0x9c, 0x91, 0x98, 0x99, 0x07, 0xe3, 0xe8, 0x57, - 0xa0, 0xc5, 0x46, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0x2a, 0x8c, 0x01, 0x01, 0x00, - 0x00, 0xff, 0xff, 0x05, 0xf5, 0x03, 0x87, 0x3a, 0x02, 0x00, 0x00, + 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0x32, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, + 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x9a, 0x9e, 0x93, 0x98, 0x54, 0xac, 0x9b, 0x99, 0x0f, 0xe3, + 0xea, 0x57, 0xa0, 0xc5, 0x47, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, 0x38, 0x32, 0x8c, 0x01, + 0x01, 0x00, 0x00, 0xff, 0xff, 0x55, 0x48, 0x49, 0xed, 0x3c, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/zoneconcierge/types/zoneconcierge.pb.go b/x/zoneconcierge/types/zoneconcierge.pb.go index 8f4031b56..8e3d792b7 100644 --- a/x/zoneconcierge/types/zoneconcierge.pb.go +++ b/x/zoneconcierge/types/zoneconcierge.pb.go @@ -5,10 +5,10 @@ package types import ( fmt "fmt" - types2 "github.com/babylonchain/babylon/x/btccheckpoint/types" - types3 "github.com/babylonchain/babylon/x/btclightclient/types" - types1 "github.com/babylonchain/babylon/x/checkpointing/types" - types "github.com/babylonchain/babylon/x/epoching/types" + types2 "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" + types3 "github.com/babylonlabs-io/babylon/x/btclightclient/types" + types1 "github.com/babylonlabs-io/babylon/x/checkpointing/types" + types "github.com/babylonlabs-io/babylon/x/epoching/types" crypto "github.com/cometbft/cometbft/proto/tendermint/crypto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" @@ -639,68 +639,68 @@ func init() { } var fileDescriptor_ab886e1868e5c5cd = []byte{ - // 964 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xcf, 0xc6, 0x4e, 0xd2, 0x3c, 0xc7, 0x6d, 0x98, 0xa4, 0xd4, 0x0d, 0xc2, 0xb1, 0x5c, 0xa9, - 0xb8, 0x08, 0xd6, 0xb2, 0x81, 0x03, 0xdc, 0xb0, 0xd5, 0xd2, 0x14, 0x44, 0xd1, 0xda, 0x2d, 0x08, - 0x81, 0x56, 0xfb, 0x67, 0xbc, 0xbb, 0xca, 0x7a, 0xc7, 0xda, 0x9d, 0xb8, 0x71, 0x3e, 0x45, 0xbf, - 0x05, 0x5c, 0xf9, 0x00, 0xdc, 0x39, 0xf6, 0xc8, 0x0d, 0x94, 0x7c, 0x05, 0x2e, 0xdc, 0xd0, 0xbc, - 0x99, 0x59, 0xef, 0x26, 0x32, 0x49, 0x2f, 0xd1, 0xce, 0xcc, 0xef, 0xbd, 0xf7, 0x7b, 0xbf, 0xf7, - 0xc7, 0x81, 0x8f, 0x5c, 0xc7, 0x5d, 0xc4, 0x2c, 0xe9, 0x9e, 0xb1, 0x84, 0x7a, 0x2c, 0xf1, 0x22, - 0x9a, 0x06, 0xb4, 0x3b, 0xef, 0x95, 0x2f, 0xcc, 0x59, 0xca, 0x38, 0x23, 0x0d, 0x85, 0x36, 0xcb, - 0x8f, 0xf3, 0xde, 0xc1, 0x7e, 0xc0, 0x02, 0x86, 0xa0, 0xae, 0xf8, 0x92, 0xf8, 0x83, 0xc3, 0x80, - 0xb1, 0x20, 0xa6, 0x5d, 0x3c, 0xb9, 0x27, 0x93, 0x2e, 0x8f, 0xa6, 0x34, 0xe3, 0xce, 0x74, 0xa6, - 0x00, 0xef, 0x73, 0x9a, 0xf8, 0x34, 0x9d, 0x46, 0x09, 0xef, 0x7a, 0xe9, 0x62, 0xc6, 0x99, 0xc0, - 0xb2, 0x89, 0x7a, 0xce, 0xd9, 0xb9, 0xdc, 0xf3, 0x42, 0xea, 0x1d, 0xcf, 0x98, 0x40, 0xce, 0x7b, - 0xe5, 0x0b, 0x85, 0x7e, 0xa8, 0xd1, 0xcb, 0x97, 0x28, 0x09, 0x10, 0x1d, 0x67, 0xf6, 0x31, 0x5d, - 0x28, 0xdc, 0xa3, 0x95, 0xb8, 0x2b, 0x2e, 0xdb, 0x1a, 0x4a, 0x67, 0xcc, 0x0b, 0x15, 0x4a, 0x7f, - 0x2b, 0x8c, 0x59, 0x20, 0x19, 0x47, 0x41, 0x28, 0xfe, 0xd2, 0x9c, 0x65, 0xe1, 0x46, 0xe2, 0xdb, - 0xbf, 0xaf, 0x43, 0xfd, 0x28, 0xf1, 0xe9, 0x29, 0xf5, 0x9f, 0x52, 0xc7, 0xa7, 0x29, 0xb9, 0x0f, - 0xb7, 0xbc, 0xd0, 0x89, 0x12, 0x3b, 0xf2, 0x1b, 0x46, 0xcb, 0xe8, 0x6c, 0x5b, 0x5b, 0x78, 0x3e, - 0xf2, 0x09, 0x81, 0x6a, 0xe8, 0x64, 0x61, 0x63, 0xbd, 0x65, 0x74, 0x76, 0x2c, 0xfc, 0x26, 0xef, - 0xc2, 0x66, 0x48, 0x85, 0xdb, 0x46, 0xa5, 0x65, 0x74, 0xaa, 0x96, 0x3a, 0x91, 0x4f, 0xa1, 0x2a, - 0xf4, 0x6d, 0x54, 0x5b, 0x46, 0xa7, 0xd6, 0x3f, 0x30, 0xa5, 0xf8, 0xa6, 0x16, 0xdf, 0x1c, 0x6b, - 0xf1, 0x07, 0xd5, 0xd7, 0x7f, 0x1d, 0x1a, 0x16, 0xa2, 0x89, 0x09, 0x7b, 0x2a, 0x01, 0x3b, 0x44, - 0x3a, 0x36, 0x06, 0xdc, 0xc0, 0x80, 0xef, 0xa8, 0x27, 0x49, 0xf4, 0xa9, 0x88, 0xde, 0x87, 0xbb, - 0x97, 0xf1, 0x92, 0xcc, 0x26, 0x92, 0xd9, 0x2b, 0x5b, 0x48, 0x66, 0x0f, 0xa0, 0xae, 0x6d, 0x50, - 0xbc, 0xc6, 0x16, 0x62, 0x77, 0xd4, 0xe5, 0x63, 0x71, 0x47, 0x1e, 0xc2, 0x1d, 0x0d, 0xe2, 0xa7, - 0x92, 0xc4, 0x2d, 0x24, 0xa1, 0x6d, 0xc7, 0xa7, 0x82, 0x40, 0xfb, 0x19, 0x6c, 0x3c, 0x61, 0xe9, - 0x71, 0x46, 0xbe, 0x84, 0x2d, 0xc9, 0x20, 0x6b, 0x54, 0x5a, 0x95, 0x4e, 0xad, 0xff, 0x81, 0xb9, - 0xaa, 0x3f, 0xcd, 0x92, 0xe0, 0x96, 0xb6, 0x6b, 0xff, 0x63, 0xc0, 0xf6, 0x10, 0xa5, 0x4e, 0x26, - 0xec, 0xff, 0xea, 0xf0, 0x0d, 0xd4, 0x63, 0x87, 0xd3, 0x8c, 0xab, 0xa4, 0xb1, 0x20, 0x6f, 0x11, - 0x71, 0x47, 0x5a, 0xab, 0x82, 0x0f, 0x40, 0x9d, 0xed, 0x89, 0xc8, 0x04, 0xeb, 0x58, 0xeb, 0x1f, - 0xae, 0x76, 0x86, 0x09, 0x5b, 0x35, 0x69, 0x24, 0xb3, 0xff, 0x02, 0xee, 0xe7, 0xd3, 0x44, 0x7d, - 0x45, 0x2b, 0xb3, 0x3d, 0x76, 0x92, 0x70, 0x6c, 0x81, 0xaa, 0x75, 0xaf, 0x00, 0x90, 0x91, 0xb3, - 0xa1, 0x78, 0x6e, 0xff, 0x6a, 0x00, 0xc9, 0xd3, 0xfe, 0x3e, 0xe2, 0xe1, 0x77, 0x62, 0xe8, 0xc8, - 0x00, 0x40, 0xe5, 0x9f, 0x4c, 0x18, 0x2a, 0x50, 0xeb, 0x3f, 0x58, 0x4d, 0x2a, 0xf7, 0x60, 0x6d, - 0x7b, 0xb9, 0x86, 0xdf, 0xc2, 0x5d, 0x9c, 0x60, 0xdd, 0x1c, 0x91, 0x2e, 0xb9, 0x14, 0xec, 0x3d, - 0x73, 0x39, 0xf1, 0xa6, 0x9c, 0x78, 0x13, 0x83, 0x3f, 0x9f, 0x65, 0x16, 0x41, 0x4b, 0xc9, 0xf4, - 0x48, 0x76, 0x45, 0xfb, 0xb7, 0x0a, 0x90, 0x27, 0x51, 0xe2, 0xc4, 0xd1, 0x19, 0xf5, 0x6f, 0x54, - 0xaa, 0x17, 0xb0, 0x3f, 0xd1, 0x06, 0x76, 0x21, 0x9f, 0xf5, 0x9b, 0xe7, 0x43, 0x26, 0x57, 0x23, - 0x7e, 0x0e, 0x80, 0x89, 0x48, 0x67, 0x15, 0x35, 0x63, 0xda, 0x59, 0xbe, 0x13, 0xe6, 0x3d, 0x13, - 0x89, 0x5b, 0xdb, 0x78, 0xa5, 0x34, 0xb9, 0x9d, 0x3a, 0xaf, 0xec, 0xe5, 0x76, 0x51, 0x23, 0xba, - 0xec, 0x9e, 0xd2, 0x26, 0x12, 0x3e, 0x2c, 0xe7, 0xd5, 0x30, 0xbf, 0xb3, 0xea, 0x69, 0xf1, 0x48, - 0x5e, 0x00, 0x71, 0xb9, 0x67, 0x67, 0x27, 0xee, 0x34, 0xca, 0xb2, 0x88, 0x25, 0x62, 0xb9, 0xe1, - 0xc4, 0x16, 0x7d, 0x96, 0x57, 0xe4, 0xbc, 0x67, 0x8e, 0x72, 0xfc, 0xd7, 0x74, 0x61, 0xed, 0xba, - 0xdc, 0x2b, 0xdd, 0x90, 0xaf, 0x60, 0x03, 0x0b, 0x80, 0x93, 0x5c, 0xeb, 0xf7, 0x56, 0x2b, 0x85, - 0x15, 0xbb, 0x5a, 0x15, 0x4b, 0xda, 0xb7, 0xff, 0x35, 0x60, 0x17, 0x21, 0xa8, 0xc4, 0x88, 0x3a, - 0x31, 0xf5, 0x89, 0x05, 0xf5, 0xb9, 0x13, 0x47, 0xbe, 0xc3, 0x59, 0x6a, 0x67, 0x94, 0x37, 0x0c, - 0x9c, 0xd9, 0x8f, 0x57, 0x6b, 0xf0, 0x52, 0xc3, 0x45, 0x87, 0x0e, 0xe2, 0x4c, 0xb0, 0xde, 0xc9, - 0x7d, 0x8c, 0x28, 0x27, 0x8f, 0x61, 0x57, 0x36, 0x5b, 0xa1, 0x32, 0x37, 0xe8, 0xb3, 0xdb, 0xb3, - 0x9c, 0x1c, 0xd6, 0xe7, 0x19, 0xec, 0x15, 0xdd, 0xcc, 0x9d, 0x18, 0x09, 0x56, 0xae, 0xf7, 0xb4, - 0xbb, 0xf4, 0xf4, 0xd2, 0x89, 0x47, 0x94, 0xb7, 0x7f, 0x59, 0x87, 0x7b, 0x2b, 0xe4, 0x21, 0x23, - 0x68, 0xc8, 0x38, 0xde, 0xd9, 0x95, 0xf1, 0x30, 0xae, 0x0f, 0xb6, 0x8f, 0xc6, 0xc3, 0xb3, 0xd2, - 0x80, 0x90, 0x1f, 0x80, 0x14, 0xc9, 0x67, 0xa8, 0xb6, 0x52, 0xe1, 0xc3, 0x6b, 0x4a, 0x58, 0xa8, - 0x4f, 0x31, 0x15, 0x55, 0xb1, 0x9f, 0xf5, 0x28, 0x2b, 0xcf, 0xa2, 0x59, 0x38, 0xa7, 0xbe, 0xda, - 0xb6, 0x8f, 0x56, 0x77, 0xda, 0x38, 0x75, 0x92, 0xcc, 0xf1, 0x78, 0xc4, 0x64, 0x5f, 0xec, 0x15, - 0x7c, 0x6b, 0x2f, 0xed, 0x9f, 0xe0, 0xce, 0x60, 0x3c, 0x44, 0x75, 0x46, 0x34, 0x98, 0xd2, 0x84, - 0x93, 0x23, 0xa8, 0x89, 0xc6, 0xd6, 0x5b, 0x5d, 0x76, 0x48, 0xa7, 0x18, 0xa7, 0xf8, 0x73, 0x3a, - 0xef, 0x99, 0x83, 0xf1, 0x50, 0xab, 0x31, 0x61, 0x16, 0xb8, 0xdc, 0x53, 0x7b, 0x6e, 0xf0, 0xfc, - 0x8f, 0xf3, 0xa6, 0xf1, 0xe6, 0xbc, 0x69, 0xfc, 0x7d, 0xde, 0x34, 0x5e, 0x5f, 0x34, 0xd7, 0xde, - 0x5c, 0x34, 0xd7, 0xfe, 0xbc, 0x68, 0xae, 0xfd, 0xf8, 0x59, 0x10, 0xf1, 0xf0, 0xc4, 0x35, 0x3d, - 0x36, 0xed, 0x2a, 0xcf, 0xb8, 0x25, 0xf4, 0xa1, 0x7b, 0x7a, 0xe9, 0x9f, 0x21, 0xbe, 0x98, 0xd1, - 0xcc, 0xdd, 0xc4, 0xdf, 0xd1, 0x4f, 0xfe, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xbe, 0xdf, 0x50, 0x58, - 0x32, 0x09, 0x00, 0x00, + // 968 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0xdd, 0x6e, 0x1b, 0x45, + 0x14, 0xce, 0xc6, 0x4e, 0xd2, 0x1c, 0xc7, 0x6d, 0x98, 0xa4, 0xd4, 0x0d, 0xc2, 0xb1, 0x5c, 0xa9, + 0xb8, 0x88, 0xae, 0x65, 0x83, 0x84, 0xe0, 0x0e, 0x5b, 0x2d, 0x4d, 0x41, 0xfc, 0xac, 0xdd, 0x82, + 0x10, 0x68, 0xb5, 0x3f, 0x63, 0xef, 0x2a, 0xeb, 0x1d, 0x6b, 0x67, 0xe2, 0xc6, 0x79, 0x8a, 0xbe, + 0x05, 0xdc, 0xf2, 0x00, 0xdc, 0x73, 0xd9, 0x4b, 0xee, 0x40, 0xc9, 0x2b, 0x70, 0xc3, 0x1d, 0x9a, + 0x33, 0x33, 0xeb, 0x75, 0x22, 0x93, 0x70, 0x13, 0xed, 0xcc, 0x7c, 0xe7, 0x9c, 0xef, 0x7c, 0xe7, + 0xc7, 0x81, 0x0f, 0x7c, 0xcf, 0x9f, 0x27, 0x2c, 0x6d, 0x9f, 0xb1, 0x94, 0x06, 0x2c, 0x0d, 0x62, + 0x9a, 0x8d, 0x69, 0x7b, 0xd6, 0x59, 0xbe, 0xb0, 0xa7, 0x19, 0x13, 0x8c, 0xd4, 0x34, 0xda, 0x5e, + 0x7e, 0x9c, 0x75, 0x0e, 0xf6, 0xc7, 0x6c, 0xcc, 0x10, 0xd4, 0x96, 0x5f, 0x0a, 0x7f, 0x70, 0x38, + 0x66, 0x6c, 0x9c, 0xd0, 0x36, 0x9e, 0xfc, 0x93, 0x51, 0x5b, 0xc4, 0x13, 0xca, 0x85, 0x37, 0x99, + 0x6a, 0xc0, 0xbb, 0x82, 0xa6, 0x21, 0xcd, 0x26, 0x71, 0x2a, 0xda, 0x41, 0x36, 0x9f, 0x0a, 0x26, + 0xb1, 0x6c, 0xa4, 0x9f, 0x73, 0x76, 0xbe, 0x08, 0x82, 0x88, 0x06, 0xc7, 0x53, 0x26, 0x91, 0xb3, + 0xce, 0xf2, 0x85, 0x46, 0x3f, 0x34, 0xe8, 0xc5, 0x4b, 0x9c, 0x8e, 0x11, 0x9d, 0x70, 0xf7, 0x98, + 0xce, 0x35, 0xee, 0xd1, 0x4a, 0xdc, 0x15, 0x97, 0x4d, 0x03, 0xa5, 0x53, 0x16, 0x44, 0x1a, 0x65, + 0xbe, 0x35, 0xc6, 0x2e, 0x90, 0x4c, 0xe2, 0x71, 0x24, 0xff, 0xd2, 0x9c, 0x65, 0xe1, 0x46, 0xe1, + 0x9b, 0xbf, 0xad, 0x43, 0xf5, 0x28, 0x0d, 0xe9, 0x29, 0x0d, 0x9f, 0x51, 0x2f, 0xa4, 0x19, 0xb9, + 0x0f, 0xb7, 0x82, 0xc8, 0x8b, 0x53, 0x37, 0x0e, 0x6b, 0x56, 0xc3, 0x6a, 0x6d, 0x3b, 0x5b, 0x78, + 0x3e, 0x0a, 0x09, 0x81, 0x72, 0xe4, 0xf1, 0xa8, 0xb6, 0xde, 0xb0, 0x5a, 0x3b, 0x0e, 0x7e, 0x93, + 0xb7, 0x61, 0x33, 0xa2, 0xd2, 0x6d, 0xad, 0xd4, 0xb0, 0x5a, 0x65, 0x47, 0x9f, 0xc8, 0x47, 0x50, + 0x96, 0xfa, 0xd6, 0xca, 0x0d, 0xab, 0x55, 0xe9, 0x1e, 0xd8, 0x4a, 0x7c, 0xdb, 0x88, 0x6f, 0x0f, + 0x8d, 0xf8, 0xbd, 0xf2, 0xeb, 0x3f, 0x0f, 0x2d, 0x07, 0xd1, 0xc4, 0x86, 0x3d, 0x9d, 0x80, 0x1b, + 0x21, 0x1d, 0x17, 0x03, 0x6e, 0x60, 0xc0, 0xb7, 0xf4, 0x93, 0x22, 0xfa, 0x4c, 0x46, 0xef, 0xc2, + 0xdd, 0xcb, 0x78, 0x45, 0x66, 0x13, 0xc9, 0xec, 0x2d, 0x5b, 0x28, 0x66, 0x0f, 0xa0, 0x6a, 0x6c, + 0x50, 0xbc, 0xda, 0x16, 0x62, 0x77, 0xf4, 0xe5, 0x13, 0x79, 0x47, 0x1e, 0xc2, 0x1d, 0x03, 0x12, + 0xa7, 0x8a, 0xc4, 0x2d, 0x24, 0x61, 0x6c, 0x87, 0xa7, 0x92, 0x40, 0xf3, 0x39, 0x6c, 0x3c, 0x65, + 0xd9, 0x31, 0x27, 0x9f, 0xc1, 0x96, 0x62, 0xc0, 0x6b, 0xa5, 0x46, 0xa9, 0x55, 0xe9, 0xbe, 0x67, + 0xaf, 0xea, 0x4f, 0x7b, 0x49, 0x70, 0xc7, 0xd8, 0x35, 0xff, 0xb6, 0x60, 0xbb, 0x8f, 0x52, 0xa7, + 0x23, 0xf6, 0x5f, 0x75, 0xf8, 0x12, 0xaa, 0x89, 0x27, 0x28, 0x17, 0x3a, 0x69, 0x2c, 0xc8, 0xff, + 0x88, 0xb8, 0xa3, 0xac, 0x75, 0xc1, 0x7b, 0xa0, 0xcf, 0xee, 0x48, 0x66, 0x82, 0x75, 0xac, 0x74, + 0x0f, 0x57, 0x3b, 0xc3, 0x84, 0x9d, 0x8a, 0x32, 0x52, 0xd9, 0x7f, 0x0a, 0xf7, 0xf3, 0x69, 0xa2, + 0xa1, 0xa6, 0xc5, 0xdd, 0x80, 0x9d, 0xa4, 0x02, 0x5b, 0xa0, 0xec, 0xdc, 0x2b, 0x00, 0x54, 0x64, + 0xde, 0x97, 0xcf, 0xcd, 0x5f, 0x2c, 0x20, 0x79, 0xda, 0xdf, 0xc5, 0x22, 0xfa, 0x46, 0x0e, 0x1d, + 0xe9, 0x01, 0xe8, 0xfc, 0xd3, 0x11, 0x43, 0x05, 0x2a, 0xdd, 0x07, 0xab, 0x49, 0xe5, 0x1e, 0x9c, + 0xed, 0x20, 0xd7, 0xf0, 0x2b, 0xb8, 0x8b, 0x13, 0x6c, 0x9a, 0x23, 0x36, 0x25, 0x57, 0x82, 0xbd, + 0x63, 0x2f, 0x26, 0xde, 0x56, 0x13, 0x6f, 0x63, 0xf0, 0xaf, 0xa7, 0xdc, 0x21, 0x68, 0xa9, 0x98, + 0x1e, 0xa9, 0xae, 0x68, 0xfe, 0x5a, 0x02, 0xf2, 0x34, 0x4e, 0xbd, 0x24, 0x3e, 0xa3, 0xe1, 0x8d, + 0x4a, 0xf5, 0x02, 0xf6, 0x47, 0xc6, 0xc0, 0x2d, 0xe4, 0xb3, 0x7e, 0xf3, 0x7c, 0xc8, 0xe8, 0x6a, + 0xc4, 0x4f, 0x00, 0x30, 0x11, 0xe5, 0xac, 0xa4, 0x67, 0xcc, 0x38, 0xcb, 0x77, 0xc2, 0xac, 0x63, + 0x23, 0x71, 0x67, 0x1b, 0xaf, 0xb4, 0x26, 0xb7, 0x33, 0xef, 0x95, 0xbb, 0xd8, 0x2e, 0x7a, 0x44, + 0x17, 0xdd, 0xb3, 0xb4, 0x89, 0xa4, 0x0f, 0xc7, 0x7b, 0xd5, 0xcf, 0xef, 0x9c, 0x6a, 0x56, 0x3c, + 0x92, 0x17, 0x40, 0x7c, 0x11, 0xb8, 0xfc, 0xc4, 0x9f, 0xc4, 0x9c, 0xc7, 0x2c, 0x95, 0xcb, 0x0d, + 0x27, 0xb6, 0xe8, 0x73, 0x79, 0x45, 0xce, 0x3a, 0xf6, 0x20, 0xc7, 0x7f, 0x41, 0xe7, 0xce, 0xae, + 0x2f, 0x82, 0xa5, 0x1b, 0xf2, 0x39, 0x6c, 0x60, 0x01, 0x70, 0x92, 0x2b, 0xdd, 0xce, 0x6a, 0xa5, + 0xb0, 0x62, 0x57, 0xab, 0xe2, 0x28, 0xfb, 0xe6, 0x3f, 0x16, 0xec, 0x22, 0x04, 0x95, 0x18, 0x50, + 0x2f, 0xa1, 0x21, 0x71, 0xa0, 0x3a, 0xf3, 0x92, 0x38, 0xf4, 0x04, 0xcb, 0x5c, 0x4e, 0x45, 0xcd, + 0xc2, 0x99, 0x7d, 0xbc, 0x5a, 0x83, 0x97, 0x06, 0x2e, 0x3b, 0xb4, 0x97, 0x70, 0xc9, 0x7a, 0x27, + 0xf7, 0x31, 0xa0, 0x82, 0x3c, 0x81, 0x5d, 0xd5, 0x6c, 0x85, 0xca, 0xdc, 0xa0, 0xcf, 0x6e, 0x4f, + 0x73, 0x72, 0x58, 0x9f, 0xe7, 0xb0, 0x57, 0x74, 0x33, 0xf3, 0x12, 0x24, 0x58, 0xba, 0xde, 0xd3, + 0xee, 0xc2, 0xd3, 0x4b, 0x2f, 0x19, 0x50, 0xd1, 0xfc, 0x79, 0x1d, 0xee, 0xad, 0x90, 0x87, 0x0c, + 0xa0, 0xa6, 0xe2, 0x04, 0x67, 0x57, 0xc6, 0xc3, 0xba, 0x3e, 0xd8, 0x3e, 0x1a, 0xf7, 0xcf, 0x96, + 0x06, 0x84, 0x7c, 0x0f, 0xa4, 0x48, 0x9e, 0xa3, 0xda, 0x5a, 0x85, 0xf7, 0xaf, 0x29, 0x61, 0xa1, + 0x3e, 0xc5, 0x54, 0x74, 0xc5, 0x7e, 0x32, 0xa3, 0xac, 0x3d, 0xcb, 0x66, 0x11, 0x82, 0x86, 0x7a, + 0xdb, 0x3e, 0x5a, 0xdd, 0x69, 0xc3, 0xcc, 0x4b, 0xb9, 0x17, 0x88, 0x98, 0xa9, 0xbe, 0xd8, 0x2b, + 0xf8, 0x36, 0x5e, 0x9a, 0x3f, 0xc2, 0x9d, 0xde, 0xb0, 0x8f, 0xea, 0x0c, 0xe8, 0x78, 0x42, 0x53, + 0x41, 0x8e, 0xa0, 0x22, 0x1b, 0xdb, 0x6c, 0x75, 0xd5, 0x21, 0xad, 0x62, 0x9c, 0xe2, 0xcf, 0xe9, + 0xac, 0x63, 0xf7, 0x86, 0x7d, 0xa3, 0xc6, 0x88, 0x39, 0xe0, 0x8b, 0x40, 0xef, 0xb9, 0xde, 0xb7, + 0xbf, 0x9f, 0xd7, 0xad, 0x37, 0xe7, 0x75, 0xeb, 0xaf, 0xf3, 0xba, 0xf5, 0xfa, 0xa2, 0xbe, 0xf6, + 0xe6, 0xa2, 0xbe, 0xf6, 0xc7, 0x45, 0x7d, 0xed, 0x87, 0x8f, 0xc7, 0xb1, 0x88, 0x4e, 0x7c, 0x3b, + 0x60, 0x93, 0xb6, 0xf6, 0x9c, 0x78, 0x3e, 0x7f, 0x1c, 0x33, 0x73, 0x6c, 0x9f, 0x5e, 0xfa, 0x77, + 0x48, 0xcc, 0xa7, 0x94, 0xfb, 0x9b, 0xf8, 0x4b, 0xfa, 0xe1, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xa3, 0x29, 0xc3, 0x31, 0x34, 0x09, 0x00, 0x00, } func (m *IndexedHeader) Marshal() (dAtA []byte, err error) { From 8bcb55d2209eeea962942c20899f4591d25a04f0 Mon Sep 17 00:00:00 2001 From: Runchao Han Date: Tue, 30 Jul 2024 15:27:45 +1000 Subject: [PATCH 119/119] chore: fix license name (#5) --- LICENSE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE b/LICENSE index d08b6069f..dc41cf54b 100644 --- a/LICENSE +++ b/LICENSE @@ -8,10 +8,10 @@ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved. Parameters -Licensor: BabylonLabs, Ltd. +Licensor: Babylon Labs, Ltd. Licensed Work: Babylon - The Licensed Work is (c) 2023 BabylonLabs, Ltd. + The Licensed Work is (c) 2023 Babylon Labs, Ltd. Additional Use Grant: None.