From 18f3274ca453017845e4ae722e4d45879234c4e4 Mon Sep 17 00:00:00 2001 From: Kevin <33023258+kkkk666@users.noreply.github.com> Date: Thu, 10 Jul 2025 14:49:21 +0800 Subject: [PATCH 01/49] chore: replace "l2scan" with "Xangle" (#242) * chore: replace "l2scan" with "Xangle" * chore: modify faucet description & xangle png --------- Co-authored-by: kevin --- docs/developers/babylon_genesis_chain/baby_faucets.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers/babylon_genesis_chain/baby_faucets.mdx b/docs/developers/babylon_genesis_chain/baby_faucets.mdx index eff8d84d..3f63ff95 100644 --- a/docs/developers/babylon_genesis_chain/baby_faucets.mdx +++ b/docs/developers/babylon_genesis_chain/baby_faucets.mdx @@ -63,7 +63,7 @@ To claim testnet tokens from the IT Rocket tBABY Faucet, you will need to: 1. Create a testnet BABY wallet account to obtain a wallet address. 2. Visit the [IT Rocket tBABY Faucet](https://testnet.itrocket.net/babylon/faucet) -3. Enter your wallet address and click the "GET TOKENS" button. +3. Enter your wallet address and click the "REQUEST tBABY" button.
Date: Thu, 10 Jul 2025 11:00:15 +0400 Subject: [PATCH 02/49] Daria/cli ref clean (#208) * create clean branch w new color scheme * overview * rm duplicate overview * rm guide --------- Co-authored-by: Daria Agadzhanova --- .../babylon_cli/create_bls_key.mdx | 19 +++++++++++++++++++ .../babylon_node/babylon_cli/gen_tx.mdx | 7 +++++++ .../babylon_cli/generate_bls_pop.mdx | 5 +++++ .../babylon_node/babylon_cli/keys.mdx | 14 ++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx b/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx index 9d3d48e5..56ff5a75 100644 --- a/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx +++ b/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx @@ -20,7 +20,11 @@ babylond create-bls-key [flags] Before using this command, ensure you have: +<<<<<<< HEAD - Initialized your Babylon node with [`babylond init`](./init.mdx) or [`babylond testnet`](./testnet.mdx) +======= +- Initialized your Babylon node with [`babylond init`](./init.md) or [`babylond testnet`](./testnet.md) +>>>>>>> d9fd4df (Daria/cli ref clean (#208)) - Confirmed that `priv_validator_key.json` exists in your node's configuration directory - Planned your BLS key password security strategy @@ -287,6 +291,7 @@ systemctl start babylond ## Related Commands ### Validator Setup +<<<<<<< HEAD - [`babylond init`](./init.mdx) - Initialize node (required prerequisite) - [`babylond testnet`](./testnet.mdx) - Initialize testnet configuration - [`babylond gentx`](./gen_tx.mdx) - Generate validator genesis transaction @@ -299,4 +304,18 @@ systemctl start babylond ### Node Operations - [`babylond start`](./start.mdx) - Start the validator node - [`babylond status`](./status.mdx) - Check validator status +======= +- [`babylond init`](./init.md) - Initialize node (required prerequisite) +- [`babylond testnet`](./testnet.md) - Initialize testnet configuration +- [`babylond gentx`](./gentx.md) - Generate validator genesis transaction +- [`babylond add-genesis-account`](./add-genesis-account.md) - Add validator account to genesis + +### Key Management +- [`babylond keys`](./keys.md) - Manage keyring keys +- [`babylond comet show-validator`](./comet.md#show-validator) - Show validator public key + +### Node Operations +- [`babylond start`](./start.md) - Start the validator node +- [`babylond status`](./status.md) - Check validator status +>>>>>>> d9fd4df (Daria/cli ref clean (#208)) diff --git a/docs/operators/babylon_node/babylon_cli/gen_tx.mdx b/docs/operators/babylon_node/babylon_cli/gen_tx.mdx index c1295441..a1dc5bda 100644 --- a/docs/operators/babylon_node/babylon_cli/gen_tx.mdx +++ b/docs/operators/babylon_node/babylon_cli/gen_tx.mdx @@ -20,10 +20,17 @@ babylond gentx [key_name] [amount] [flags] Before using this command, ensure you have: +<<<<<<< HEAD - Initialized your Babylon node with [`babylond init`](./init.mdx) - Created validator keys with [`babylond keys add`](./keys.mdx) - Created BLS keys with [`babylond create-bls-key`](./create_bls_key.mdx) - Added your validator account to genesis with [`babylond add-genesis-account`](./add_genesis_account.mdx) +======= +- Initialized your Babylon node with [`babylond init`](./init.md) +- Created validator keys with [`babylond keys add`](./keys.md) +- Created BLS keys with [`babylond create-bls-key`](./create-bls-key.md) +- Added your validator account to genesis with [`babylond add-genesis-account`](./add-genesis-account.md) +>>>>>>> d9fd4df (Daria/cli ref clean (#208)) ## Arguments diff --git a/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx b/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx index 5b66efd8..8cdb1914 100644 --- a/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx +++ b/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx @@ -20,8 +20,13 @@ babylond generate-bls-pop [flags] Before using this command, ensure you have: +<<<<<<< HEAD - Initialized your Babylon node with [`babylond init`](./init.mdx) - Created BLS keys with [`babylond create-bls-key`](./create_bls_key.mdx) +======= +- Initialized your Babylon node with [`babylond init`](./init.md) +- Created BLS keys with [`babylond create-bls-key`](./create-bls-key.md) +>>>>>>> d9fd4df (Daria/cli ref clean (#208)) - Confirmed that both key files exist: - `priv_validator_key.json` (contains Ed25519 keys) - `bls_key.json` or BLS keys embedded in `priv_validator_key.json` diff --git a/docs/operators/babylon_node/babylon_cli/keys.mdx b/docs/operators/babylon_node/babylon_cli/keys.mdx index a1123c43..49f19963 100644 --- a/docs/operators/babylon_node/babylon_cli/keys.mdx +++ b/docs/operators/babylon_node/babylon_cli/keys.mdx @@ -675,6 +675,7 @@ echo "✅ Validator keys created and added to genesis" ## Related Commands ### Validator Operations +<<<<<<< HEAD - [`babylond gentx`](./gen_tx.mdx) - Generate genesis transaction using keys - [`babylond tx checkpointing create-validator`](./tx.mdx) - Create validator using keys - [`babylond generate-bls-pop`](./generate_bls_pop.mdx) - Generate proof-of-possession with keys @@ -686,4 +687,17 @@ echo "✅ Validator keys created and added to genesis" ### Address Operations - [`babylond debug addr`](./debug.mdx#addr) - Convert address formats - [`babylond debug pubkey`](./debug.mdx#pubkey) - Debug public key formats +======= +- [`babylond gentx`](./gentx.md) - Generate genesis transaction using keys +- [`babylond tx checkpointing create-validator`](./tx-checkpointing.md) - Create validator using keys +- [`babylond generate-bls-pop`](./generate-bls-pop.md) - Generate proof-of-possession with keys + +### Node Setup +- [`babylond init`](./init.md) - Initialize node (creates validator consensus keys) +- [`babylond add-genesis-account`](./add-genesis-account.md) - Add key addresses to genesis + +### Address Operations +- [`babylond debug addr`](./debug.md#addr) - Convert address formats +- [`babylond debug pubkey`](./debug.md#pubkey) - Debug public key formats +>>>>>>> d9fd4df (Daria/cli ref clean (#208)) From cbb6648d2809b7dbfb85e3337670fad38693adac Mon Sep 17 00:00:00 2001 From: Jenks Date: Fri, 11 Jul 2025 10:58:11 +1000 Subject: [PATCH 03/49] fixed borken links --- .../babylon_cli/create_bls_key.mdx | 23 +++++++------------ .../babylon_node/babylon_cli/gen_tx.mdx | 7 ------ .../babylon_cli/generate_bls_pop.mdx | 9 ++------ .../babylon_node/babylon_cli/keys.mdx | 15 ------------ 4 files changed, 10 insertions(+), 44 deletions(-) diff --git a/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx b/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx index 56ff5a75..90b877ce 100644 --- a/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx +++ b/docs/operators/babylon_node/babylon_cli/create_bls_key.mdx @@ -20,11 +20,7 @@ babylond create-bls-key [flags] Before using this command, ensure you have: -<<<<<<< HEAD - Initialized your Babylon node with [`babylond init`](./init.mdx) or [`babylond testnet`](./testnet.mdx) -======= -- Initialized your Babylon node with [`babylond init`](./init.md) or [`babylond testnet`](./testnet.md) ->>>>>>> d9fd4df (Daria/cli ref clean (#208)) - Confirmed that `priv_validator_key.json` exists in your node's configuration directory - Planned your BLS key password security strategy @@ -291,7 +287,6 @@ systemctl start babylond ## Related Commands ### Validator Setup -<<<<<<< HEAD - [`babylond init`](./init.mdx) - Initialize node (required prerequisite) - [`babylond testnet`](./testnet.mdx) - Initialize testnet configuration - [`babylond gentx`](./gen_tx.mdx) - Generate validator genesis transaction @@ -304,18 +299,16 @@ systemctl start babylond ### Node Operations - [`babylond start`](./start.mdx) - Start the validator node - [`babylond status`](./status.mdx) - Check validator status -======= -- [`babylond init`](./init.md) - Initialize node (required prerequisite) -- [`babylond testnet`](./testnet.md) - Initialize testnet configuration -- [`babylond gentx`](./gentx.md) - Generate validator genesis transaction -- [`babylond add-genesis-account`](./add-genesis-account.md) - Add validator account to genesis +- [`babylond init`](./init.mdx) - Initialize node (required prerequisite) +- [`babylond testnet`](./testnet.mdx) - Initialize testnet configuration +- [`babylond gentx`](./gentx.mdx) - Generate validator genesis transaction +- [`babylond add-genesis-account`](./add-genesis-account.mdx) - Add validator account to genesis ### Key Management -- [`babylond keys`](./keys.md) - Manage keyring keys -- [`babylond comet show-validator`](./comet.md#show-validator) - Show validator public key +- [`babylond keys`](./keys.mdx) - Manage keyring keys +- [`babylond comet show-validator`](./comet.mdx#show-validator) - Show validator public key ### Node Operations -- [`babylond start`](./start.md) - Start the validator node -- [`babylond status`](./status.md) - Check validator status ->>>>>>> d9fd4df (Daria/cli ref clean (#208)) +- [`babylond start`](./start.mdx) - Start the validator node +- [`babylond status`](./status.mdx) - Check validator status diff --git a/docs/operators/babylon_node/babylon_cli/gen_tx.mdx b/docs/operators/babylon_node/babylon_cli/gen_tx.mdx index a1dc5bda..5c393fb3 100644 --- a/docs/operators/babylon_node/babylon_cli/gen_tx.mdx +++ b/docs/operators/babylon_node/babylon_cli/gen_tx.mdx @@ -20,17 +20,10 @@ babylond gentx [key_name] [amount] [flags] Before using this command, ensure you have: -<<<<<<< HEAD -- Initialized your Babylon node with [`babylond init`](./init.mdx) -- Created validator keys with [`babylond keys add`](./keys.mdx) -- Created BLS keys with [`babylond create-bls-key`](./create_bls_key.mdx) -- Added your validator account to genesis with [`babylond add-genesis-account`](./add_genesis_account.mdx) -======= - Initialized your Babylon node with [`babylond init`](./init.md) - Created validator keys with [`babylond keys add`](./keys.md) - Created BLS keys with [`babylond create-bls-key`](./create-bls-key.md) - Added your validator account to genesis with [`babylond add-genesis-account`](./add-genesis-account.md) ->>>>>>> d9fd4df (Daria/cli ref clean (#208)) ## Arguments diff --git a/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx b/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx index 8cdb1914..666a44b1 100644 --- a/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx +++ b/docs/operators/babylon_node/babylon_cli/generate_bls_pop.mdx @@ -20,16 +20,11 @@ babylond generate-bls-pop [flags] Before using this command, ensure you have: -<<<<<<< HEAD - Initialized your Babylon node with [`babylond init`](./init.mdx) - Created BLS keys with [`babylond create-bls-key`](./create_bls_key.mdx) -======= -- Initialized your Babylon node with [`babylond init`](./init.md) -- Created BLS keys with [`babylond create-bls-key`](./create-bls-key.md) ->>>>>>> d9fd4df (Daria/cli ref clean (#208)) - Confirmed that both key files exist: - - `priv_validator_key.json` (contains Ed25519 keys) - - `bls_key.json` or BLS keys embedded in `priv_validator_key.json` +- `priv_validator_key.json` (contains Ed25519 keys) +- `bls_key.json` or BLS keys embedded in `priv_validator_key.json` ## Arguments diff --git a/docs/operators/babylon_node/babylon_cli/keys.mdx b/docs/operators/babylon_node/babylon_cli/keys.mdx index 49f19963..33d7f734 100644 --- a/docs/operators/babylon_node/babylon_cli/keys.mdx +++ b/docs/operators/babylon_node/babylon_cli/keys.mdx @@ -675,7 +675,6 @@ echo "✅ Validator keys created and added to genesis" ## Related Commands ### Validator Operations -<<<<<<< HEAD - [`babylond gentx`](./gen_tx.mdx) - Generate genesis transaction using keys - [`babylond tx checkpointing create-validator`](./tx.mdx) - Create validator using keys - [`babylond generate-bls-pop`](./generate_bls_pop.mdx) - Generate proof-of-possession with keys @@ -687,17 +686,3 @@ echo "✅ Validator keys created and added to genesis" ### Address Operations - [`babylond debug addr`](./debug.mdx#addr) - Convert address formats - [`babylond debug pubkey`](./debug.mdx#pubkey) - Debug public key formats -======= -- [`babylond gentx`](./gentx.md) - Generate genesis transaction using keys -- [`babylond tx checkpointing create-validator`](./tx-checkpointing.md) - Create validator using keys -- [`babylond generate-bls-pop`](./generate-bls-pop.md) - Generate proof-of-possession with keys - -### Node Setup -- [`babylond init`](./init.md) - Initialize node (creates validator consensus keys) -- [`babylond add-genesis-account`](./add-genesis-account.md) - Add key addresses to genesis - -### Address Operations -- [`babylond debug addr`](./debug.md#addr) - Convert address formats -- [`babylond debug pubkey`](./debug.md#pubkey) - Debug public key formats ->>>>>>> d9fd4df (Daria/cli ref clean (#208)) - From 2bb5811933f4ae73286f661b16d68589c3da31d1 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 11 Jul 2025 11:47:38 +0800 Subject: [PATCH 04/49] fix: optimize api response css & faucet typo --- docs/developers/babylon_genesis_chain/baby_faucets.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developers/babylon_genesis_chain/baby_faucets.mdx b/docs/developers/babylon_genesis_chain/baby_faucets.mdx index 3f63ff95..eff8d84d 100644 --- a/docs/developers/babylon_genesis_chain/baby_faucets.mdx +++ b/docs/developers/babylon_genesis_chain/baby_faucets.mdx @@ -63,7 +63,7 @@ To claim testnet tokens from the IT Rocket tBABY Faucet, you will need to: 1. Create a testnet BABY wallet account to obtain a wallet address. 2. Visit the [IT Rocket tBABY Faucet](https://testnet.itrocket.net/babylon/faucet) -3. Enter your wallet address and click the "REQUEST tBABY" button. +3. Enter your wallet address and click the "GET TOKENS" button.
Date: Fri, 11 Jul 2025 21:04:29 +1000 Subject: [PATCH 05/49] re-draw bsn architecture diagrams in engineering diagram styles (#216) --- .../bsns/cosmos_chains/cosmos_chains.mdx | 4 ++-- .../bsns/op_stack_chains/op_stack_chains.mdx | 4 ++-- .../cosmos/bsn_architecture_cosmos.png | Bin 0 -> 43366 bytes .../cosmos/bsn_architecture_cosmos_dark.png | Bin 0 -> 47828 bytes .../developers/op_stack/bsn_architecture_op.png | Bin 0 -> 47709 bytes .../op_stack/bsn_architecture_op_dark.png | Bin 0 -> 50924 bytes 6 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 static/img/developers/cosmos/bsn_architecture_cosmos.png create mode 100644 static/img/developers/cosmos/bsn_architecture_cosmos_dark.png create mode 100644 static/img/developers/op_stack/bsn_architecture_op.png create mode 100644 static/img/developers/op_stack/bsn_architecture_op_dark.png diff --git a/docs/developers/bsns/cosmos_chains/cosmos_chains.mdx b/docs/developers/bsns/cosmos_chains/cosmos_chains.mdx index cbc4f31f..c2afb6ed 100644 --- a/docs/developers/bsns/cosmos_chains/cosmos_chains.mdx +++ b/docs/developers/bsns/cosmos_chains/cosmos_chains.mdx @@ -18,8 +18,8 @@ for example, X→ Y means "Y queries data from X and the data flows from X to Y"
diff --git a/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx b/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx index 361f3309..eae94665 100644 --- a/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx +++ b/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx @@ -18,8 +18,8 @@ The design involves the following main components:
diff --git a/static/img/developers/cosmos/bsn_architecture_cosmos.png b/static/img/developers/cosmos/bsn_architecture_cosmos.png new file mode 100644 index 0000000000000000000000000000000000000000..2317b56aadafd06bc1bf34c6b2648b2149a08c73 GIT binary patch literal 43366 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 X@+37BclSgQ@V9@@A#&y}+pGTqPhKfB literal 0 HcmV?d00001 diff --git a/static/img/developers/cosmos/bsn_architecture_cosmos_dark.png b/static/img/developers/cosmos/bsn_architecture_cosmos_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..97b8824af5df7f136cd22da2f9891d97fe8374a0 GIT binary patch literal 47828 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 Date: Tue, 15 Jul 2025 23:21:35 +1000 Subject: [PATCH 06/49] Jenks/re org nav (#244) * initial structure * small fixes to developer docs * update developer.mdx & populated stakers.mdx pagfe * fixed broken links * Update query.mdx * removed community pool proposal type * Update docusaurus.config.js * initial structure * fix: adjust style & format baby staking guide (#196) Co-authored-by: kevin * updated cosmos & op stack chain .mdxs (#200) * Merge remote-tracking branch 'origin/main' into jenks/re-org-nav --------- Co-authored-by: Kevin <33023258+kkkk666@users.noreply.github.com> Co-authored-by: kevin --- docs/{developers => }/bsns/_category_.json | 2 +- docs/{developers => }/bsns/bsns.mdx | 4 +- .../bsns/cosmos_chains/_category_.json | 0 .../bsns/cosmos_chains/babylon_sdk.mdx | 0 .../bsns/cosmos_chains/cosmos_chains.mdx | 0 .../integrating_as_cosmos_chain.mdx | 0 .../bsns/cosmos_chains/running_btc_staker.mdx | 0 .../running_finality_provider.mdx | 0 .../bsns/op_stack_chains/op_stack_chains.mdx | 2 +- .../explorers/explorers.mdx | 6 +- .../node_information.mdx | 2 +- docs/developers/developers.mdx | 8 +- docs/guides/architecture/_category_.json | 4 +- docs/guides/governance/governance.mdx | 1 - .../submit_proposals/submit_proposals.mdx | 2 +- .../submit_proposals/submit_via_web.mdx | 1 - docs/guides/overview/_category_.json | 2 +- docs/guides/overview/overview.mdx | 2 +- .../phases_of_the_launch/phase-3/phase-3.mdx | 2 +- .../babylon_node/babylon_cli/query.mdx | 2 +- .../baby_stakers/_category_.json | 2 +- .../baby_stakers/baby_stakers.mdx | 6 +- .../baby_stakers/baby_staking_cli.mdx | 0 .../baby_stakers/baby_staking_integration.mdx | 0 .../baby_stakers/baby_staking_tools.mdx | 0 .../baby_staking_via_mintscan.mdx | 0 .../baby_stakers/staking_mechanism.mdx | 0 .../btc_stakers/_category_.json | 2 +- .../btc_stakers/btc_stakers.mdx | 0 .../btc_stakers/btc_staking_tools.mdx | 0 .../btc_stakers/campaigns/_category_.json | 0 .../btc_stakers/campaigns/pioneer_nfts.mdx | 0 .../liquid_staking/_category_.json | 0 .../liquid_staking/liquid_staking_tokens.mdx | 2 +- .../native_staking/_category_.json | 0 .../native_staking/custody_support.mdx | 0 .../native_staking/geo_blocking.mdx | 0 .../native_staking/staking_via_cli.mdx | 0 .../native_staking/unbonding_via_cli.mdx | 0 .../native_staking/unbonding_via_web.mdx | 2 +- .../native_staking/web_staking.mdx | 4 +- docs/stakers/stakers.mdx | 125 ++++++++++++++++++ docusaurus.config.js | 30 ++++- sidebars-default.js | 4 +- src/components/homepage/GuidesAndSamples.tsx | 6 +- src/components/homepage/HeroSection.tsx | 6 +- 46 files changed, 189 insertions(+), 40 deletions(-) rename docs/{developers => }/bsns/_category_.json (77%) rename docs/{developers => }/bsns/bsns.mdx (96%) rename docs/{developers => }/bsns/cosmos_chains/_category_.json (100%) rename docs/{developers => }/bsns/cosmos_chains/babylon_sdk.mdx (100%) rename docs/{developers => }/bsns/cosmos_chains/cosmos_chains.mdx (100%) rename docs/{developers => }/bsns/cosmos_chains/integrating_as_cosmos_chain.mdx (100%) rename docs/{developers => }/bsns/cosmos_chains/running_btc_staker.mdx (100%) rename docs/{developers => }/bsns/cosmos_chains/running_finality_provider.mdx (100%) rename docs/{developers => }/bsns/op_stack_chains/op_stack_chains.mdx (99%) rename docs/{guides => stakers}/baby_stakers/_category_.json (82%) rename docs/{guides => stakers}/baby_stakers/baby_stakers.mdx (93%) rename docs/{guides => stakers}/baby_stakers/baby_staking_cli.mdx (100%) rename docs/{guides => stakers}/baby_stakers/baby_staking_integration.mdx (100%) rename docs/{guides => stakers}/baby_stakers/baby_staking_tools.mdx (100%) rename docs/{guides => stakers}/baby_stakers/baby_staking_via_mintscan.mdx (100%) rename docs/{guides => stakers}/baby_stakers/staking_mechanism.mdx (100%) rename docs/{guides => stakers}/btc_stakers/_category_.json (81%) rename docs/{guides => stakers}/btc_stakers/btc_stakers.mdx (100%) rename docs/{guides => stakers}/btc_stakers/btc_staking_tools.mdx (100%) rename docs/{guides => stakers}/btc_stakers/campaigns/_category_.json (100%) rename docs/{guides => stakers}/btc_stakers/campaigns/pioneer_nfts.mdx (100%) rename docs/{guides => stakers}/btc_stakers/liquid_staking/_category_.json (100%) rename docs/{guides => stakers}/btc_stakers/liquid_staking/liquid_staking_tokens.mdx (95%) rename docs/{guides => stakers}/btc_stakers/native_staking/_category_.json (100%) rename docs/{guides => stakers}/btc_stakers/native_staking/custody_support.mdx (100%) rename docs/{guides => stakers}/btc_stakers/native_staking/geo_blocking.mdx (100%) rename docs/{guides => stakers}/btc_stakers/native_staking/staking_via_cli.mdx (100%) rename docs/{guides => stakers}/btc_stakers/native_staking/unbonding_via_cli.mdx (100%) rename docs/{guides => stakers}/btc_stakers/native_staking/unbonding_via_web.mdx (86%) rename docs/{guides => stakers}/btc_stakers/native_staking/web_staking.mdx (97%) create mode 100644 docs/stakers/stakers.mdx diff --git a/docs/developers/bsns/_category_.json b/docs/bsns/_category_.json similarity index 77% rename from docs/developers/bsns/_category_.json rename to docs/bsns/_category_.json index a1f51657..dd5561b7 100644 --- a/docs/developers/bsns/_category_.json +++ b/docs/bsns/_category_.json @@ -1,6 +1,6 @@ { "position": 2, "label": "Bitcoin Supercharged Networks", - "collapsible": true, + "collapsible": false, "collapsed": true } diff --git a/docs/developers/bsns/bsns.mdx b/docs/bsns/bsns.mdx similarity index 96% rename from docs/developers/bsns/bsns.mdx rename to docs/bsns/bsns.mdx index ec422523..112ca77a 100644 --- a/docs/developers/bsns/bsns.mdx +++ b/docs/bsns/bsns.mdx @@ -22,7 +22,7 @@ BTC-backed Finality Providers are held accountable, even when equivocating Finality Providers constitute a majority. Cosmos Chain Integration Guide @@ -51,7 +51,7 @@ The [Forkless Rollups with Bitcoin staking](https://babylonchain.io/blog/forkles blog post provides more details. OP-stack L2 Chain Integration Guide diff --git a/docs/developers/bsns/cosmos_chains/_category_.json b/docs/bsns/cosmos_chains/_category_.json similarity index 100% rename from docs/developers/bsns/cosmos_chains/_category_.json rename to docs/bsns/cosmos_chains/_category_.json diff --git a/docs/developers/bsns/cosmos_chains/babylon_sdk.mdx b/docs/bsns/cosmos_chains/babylon_sdk.mdx similarity index 100% rename from docs/developers/bsns/cosmos_chains/babylon_sdk.mdx rename to docs/bsns/cosmos_chains/babylon_sdk.mdx diff --git a/docs/developers/bsns/cosmos_chains/cosmos_chains.mdx b/docs/bsns/cosmos_chains/cosmos_chains.mdx similarity index 100% rename from docs/developers/bsns/cosmos_chains/cosmos_chains.mdx rename to docs/bsns/cosmos_chains/cosmos_chains.mdx diff --git a/docs/developers/bsns/cosmos_chains/integrating_as_cosmos_chain.mdx b/docs/bsns/cosmos_chains/integrating_as_cosmos_chain.mdx similarity index 100% rename from docs/developers/bsns/cosmos_chains/integrating_as_cosmos_chain.mdx rename to docs/bsns/cosmos_chains/integrating_as_cosmos_chain.mdx diff --git a/docs/developers/bsns/cosmos_chains/running_btc_staker.mdx b/docs/bsns/cosmos_chains/running_btc_staker.mdx similarity index 100% rename from docs/developers/bsns/cosmos_chains/running_btc_staker.mdx rename to docs/bsns/cosmos_chains/running_btc_staker.mdx diff --git a/docs/developers/bsns/cosmos_chains/running_finality_provider.mdx b/docs/bsns/cosmos_chains/running_finality_provider.mdx similarity index 100% rename from docs/developers/bsns/cosmos_chains/running_finality_provider.mdx rename to docs/bsns/cosmos_chains/running_finality_provider.mdx diff --git a/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx b/docs/bsns/op_stack_chains/op_stack_chains.mdx similarity index 99% rename from docs/developers/bsns/op_stack_chains/op_stack_chains.mdx rename to docs/bsns/op_stack_chains/op_stack_chains.mdx index eae94665..556438d6 100644 --- a/docs/developers/bsns/op_stack_chains/op_stack_chains.mdx +++ b/docs/bsns/op_stack_chains/op_stack_chains.mdx @@ -94,4 +94,4 @@ We have developed local deployment scripts for the OP stack integration. - https://github.com/Snapchain/babylon-deployment for spinning up an OP stack chain integrating with Babylon Edge devnet - https://github.com/Snapchain/op-chain-deployment for spinning up the entire stack (OP stack chain + ETH L1 + Babylon Genesis + Bitcoin) ---- +--- \ No newline at end of file diff --git a/docs/developers/babylon_genesis_chain/explorers/explorers.mdx b/docs/developers/babylon_genesis_chain/explorers/explorers.mdx index d37e0154..e5fd45c7 100644 --- a/docs/developers/babylon_genesis_chain/explorers/explorers.mdx +++ b/docs/developers/babylon_genesis_chain/explorers/explorers.mdx @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; # Chain Explorers -## Babylon Genesis Mainnet +### Babylon Genesis Mainnet Block scanners for Phase 2 Babylon Genesis Mainnet (`bbn-1`). @@ -21,7 +21,7 @@ Block scanners for Phase 2 Babylon Genesis Mainnet (`bbn-1`). | [Xangle](https://babylon-explorer.xangle.io/mainnet/home) | `https://babylon-explorer.xangle.io/mainnet/home` | -## Babylon Genesis Testnet +### Babylon Genesis Testnet Block scanners for Phase 2 Babylon Genesis Testnet (`bbn-test-5`). @@ -33,7 +33,7 @@ Block scanners for Phase 2 Babylon Genesis Testnet (`bbn-test-5`). | [Xangle](https://babylon-explorer.xangle.io/testnet/home) | `https://babylon-explorer.xangle.io/testnet/home` | -## Babylon Genesis Devnet +### Babylon Genesis Devnet | Service | URL | |---------|-----| diff --git a/docs/developers/babylon_genesis_chain/node_information.mdx b/docs/developers/babylon_genesis_chain/node_information.mdx index 0166e550..3ef3a2e2 100644 --- a/docs/developers/babylon_genesis_chain/node_information.mdx +++ b/docs/developers/babylon_genesis_chain/node_information.mdx @@ -7,7 +7,7 @@ sidebar_position: 1 import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -## Nodes and Endpoints Information for Babylon Genesis Chain +## Endpoints Information ### Babylon Genesis Mainnet diff --git a/docs/developers/developers.mdx b/docs/developers/developers.mdx index 60a080f0..651cb405 100644 --- a/docs/developers/developers.mdx +++ b/docs/developers/developers.mdx @@ -24,6 +24,8 @@ offers unique opportunities in the shared-security space. - IBC-enabled communication - Native Bitcoin staking protocols +Read more on [Bitcoin Supercharged Network](/bsns/). + #### 2. Smart Contract Development **Utilize the extremely programmable Babylon Genesis** - Deploy CosmWasm smart contracts @@ -34,6 +36,8 @@ offers unique opportunities in the shared-security space. - Rust-based smart contract development (CosmWasm) - Partner oracles that work with Babylon Genesis +Read more on [dApp deployments](/developers/dapps/smart_contract_deployment). + #### 3. Infrastructure and Tooling **Develop Critical Network Components** - Build monitoring and validation tools (e.g. via Vigilantes) @@ -62,8 +66,8 @@ offers unique opportunities in the shared-security space. 3. **Check out BSN reference implementations** - - [Babylon SDK](/developers/bsns/cosmos_chains/babylon_sdk) - - [BSN integrations guide](/developers/bsns/) + - [Babylon SDK](/bsns/cosmos_chains/babylon_sdk) + - [BSN integrations guide](/bsns/) --- diff --git a/docs/guides/architecture/_category_.json b/docs/guides/architecture/_category_.json index 7a8b152f..7797249a 100644 --- a/docs/guides/architecture/_category_.json +++ b/docs/guides/architecture/_category_.json @@ -1,7 +1,7 @@ { "position": 2, "label": "Architecture", - "collapsible": true, - "collapsed": true, + "collapsible": false, + "collapsed": false, "className": "architecture_sidebar_header" } \ No newline at end of file diff --git a/docs/guides/governance/governance.mdx b/docs/guides/governance/governance.mdx index a323cf81..4886eb54 100644 --- a/docs/guides/governance/governance.mdx +++ b/docs/guides/governance/governance.mdx @@ -73,7 +73,6 @@ Babylon's governance supports several types of proposals: - **Text Proposals**: Proposals for signaling community sentiment or discussing ideas. - **Parameter Change Proposals**: Modify specific blockchain parameters without changing underlying code. -- **Community Spend Proposals**: Request funds from the community pool for projects, initiatives, or development. - **Software Upgrade Proposals**: Coordinate chain-wide software upgrades with specific upgrade heights or times. Each type of proposal has two urgency levels: standard or expedited. diff --git a/docs/guides/governance/submit_proposals/submit_proposals.mdx b/docs/guides/governance/submit_proposals/submit_proposals.mdx index b7dff58c..8a8e2606 100644 --- a/docs/guides/governance/submit_proposals/submit_proposals.mdx +++ b/docs/guides/governance/submit_proposals/submit_proposals.mdx @@ -8,7 +8,7 @@ keywords: [governance, proposals, submission, Babylon, Genesis] # Submit Proposals -This guide provides detailed instructions for preparing and submitting governance proposals in the Babylon Genesis ecosystem. Whether you're creating text proposals for signaling, parameter changes, community pool funding, or software upgrades, this guide will help you navigate the process with ease. +This guide provides detailed instructions for preparing and submitting governance proposals in the Babylon Genesis ecosystem. Whether you're creating text proposals for signaling, parameter changes, or software upgrades, this guide will help you navigate the process with ease. ## Choose Proposal Types diff --git a/docs/guides/governance/submit_proposals/submit_via_web.mdx b/docs/guides/governance/submit_proposals/submit_via_web.mdx index 25d04ca3..48686437 100644 --- a/docs/guides/governance/submit_proposals/submit_via_web.mdx +++ b/docs/guides/governance/submit_proposals/submit_via_web.mdx @@ -26,7 +26,6 @@ Click on "New Proposal". Select the proposal type from the available options: - Text Proposal - Parameter Change - Software Upgrade -- Community Pool Spend ### Step 3: Fill in Proposal Details diff --git a/docs/guides/overview/_category_.json b/docs/guides/overview/_category_.json index d50cab7f..b0bd8a95 100644 --- a/docs/guides/overview/_category_.json +++ b/docs/guides/overview/_category_.json @@ -1,7 +1,7 @@ { "position": 1, "label": "Overview", - "collapsible": true, + "collapsible": false, "collapsed": false, "className": "overview_sidebar_header", "link": { diff --git a/docs/guides/overview/overview.mdx b/docs/guides/overview/overview.mdx index c4ec0e37..280d0904 100644 --- a/docs/guides/overview/overview.mdx +++ b/docs/guides/overview/overview.mdx @@ -108,7 +108,7 @@ provide a comprehensive set of tools and documentation to help you get started. * [Babylon node](/operators/babylon_node/installation_guide) * [Babylon RPC](/api/babylon-gRPC/babylon-grpc-api-docs) -* [Babylon SDK (Cosmos SDK reference smart contracts)](/developers/bsns/cosmos_chains/babylon_sdk) +* [Babylon SDK (Cosmos SDK reference smart contracts)](/bsns/cosmos_chains/babylon_sdk) Interchain communication is handled through [IBC protocol](https://tutorials.cosmos.network/academy/3-ibc/). diff --git a/docs/guides/overview/phases_of_the_launch/phase-3/phase-3.mdx b/docs/guides/overview/phases_of_the_launch/phase-3/phase-3.mdx index fd94a57b..345351b9 100644 --- a/docs/guides/overview/phases_of_the_launch/phase-3/phase-3.mdx +++ b/docs/guides/overview/phases_of_the_launch/phase-3/phase-3.mdx @@ -14,7 +14,7 @@ Sophisticated cross-chain communication and time synchronization are required fo The final phase establishes Babylon as a marketplace for shared security. Babylon Genesis will be the control plane to coordinate security arrangements between stakers and BSNs. - Read more on BSNs diff --git a/docs/operators/babylon_node/babylon_cli/query.mdx b/docs/operators/babylon_node/babylon_cli/query.mdx index ca33b8dd..88cafa59 100644 --- a/docs/operators/babylon_node/babylon_cli/query.mdx +++ b/docs/operators/babylon_node/babylon_cli/query.mdx @@ -27,7 +27,7 @@ babylond query [module] [subcommand] [flags] | **auth** | Account authentication and management | accounts, account info, module accounts | | **bank** | Token balances and transfers | balances, total supply, denomination metadata | | **staking** | Validator bonding and delegations | validators, delegations, staking pool | -| **distribution** | Staking reward distribution | rewards, commission, community pool | +| **distribution** | Staking reward distribution | rewards, commission | | **gov** | Governance proposals and voting | proposals, votes, governance parameters | | **slashing** | Validator penalty tracking | signing info, slashing parameters | diff --git a/docs/guides/baby_stakers/_category_.json b/docs/stakers/baby_stakers/_category_.json similarity index 82% rename from docs/guides/baby_stakers/_category_.json rename to docs/stakers/baby_stakers/_category_.json index 04897450..a82447fd 100644 --- a/docs/guides/baby_stakers/_category_.json +++ b/docs/stakers/baby_stakers/_category_.json @@ -1,7 +1,7 @@ { "position": 4.1, "label": "BABY Stakers", - "collapsible": true, + "collapsible": false, "collapsed": true, "className": "baby_stakers_sidebar_header" } \ No newline at end of file diff --git a/docs/guides/baby_stakers/baby_stakers.mdx b/docs/stakers/baby_stakers/baby_stakers.mdx similarity index 93% rename from docs/guides/baby_stakers/baby_stakers.mdx rename to docs/stakers/baby_stakers/baby_stakers.mdx index 7cb41193..10282767 100644 --- a/docs/guides/baby_stakers/baby_stakers.mdx +++ b/docs/stakers/baby_stakers/baby_stakers.mdx @@ -37,7 +37,7 @@ end. 4. **Funds Status**: Important: Your funds remain available in your wallet until the epoch ends. -*More on the staking mechanism can be found [here](/guides/baby_stakers/staking_mechanism).* +*More on the staking mechanism can be found [here](/stakers/baby_stakers/staking_mechanism).* ## Slashing Conditions @@ -58,7 +58,7 @@ delegation decisions. - **Partial Slashing**: Calibrated slashing parameters in percentage help protect delegators from catastrophic loss. -*More on the slashing conditions can be found [here](/guides/baby_stakers/staking_mechanism).* +*More on the slashing conditions can be found [here](/stakers/baby_stakers/staking_mechanism).* ## Fast Unbonding @@ -83,7 +83,7 @@ automatically released and returned to the delegator. - Released tokens become fully liquid and transferable; there are no more restrictions. -*More on fast unbonding process [here](/guides/baby_stakers/staking_mechanism).* +*More on fast unbonding process [here](/stakers/baby_stakers/staking_mechanism).* ## Relationship with Bitcoin Staking diff --git a/docs/guides/baby_stakers/baby_staking_cli.mdx b/docs/stakers/baby_stakers/baby_staking_cli.mdx similarity index 100% rename from docs/guides/baby_stakers/baby_staking_cli.mdx rename to docs/stakers/baby_stakers/baby_staking_cli.mdx diff --git a/docs/guides/baby_stakers/baby_staking_integration.mdx b/docs/stakers/baby_stakers/baby_staking_integration.mdx similarity index 100% rename from docs/guides/baby_stakers/baby_staking_integration.mdx rename to docs/stakers/baby_stakers/baby_staking_integration.mdx diff --git a/docs/guides/baby_stakers/baby_staking_tools.mdx b/docs/stakers/baby_stakers/baby_staking_tools.mdx similarity index 100% rename from docs/guides/baby_stakers/baby_staking_tools.mdx rename to docs/stakers/baby_stakers/baby_staking_tools.mdx diff --git a/docs/guides/baby_stakers/baby_staking_via_mintscan.mdx b/docs/stakers/baby_stakers/baby_staking_via_mintscan.mdx similarity index 100% rename from docs/guides/baby_stakers/baby_staking_via_mintscan.mdx rename to docs/stakers/baby_stakers/baby_staking_via_mintscan.mdx diff --git a/docs/guides/baby_stakers/staking_mechanism.mdx b/docs/stakers/baby_stakers/staking_mechanism.mdx similarity index 100% rename from docs/guides/baby_stakers/staking_mechanism.mdx rename to docs/stakers/baby_stakers/staking_mechanism.mdx diff --git a/docs/guides/btc_stakers/_category_.json b/docs/stakers/btc_stakers/_category_.json similarity index 81% rename from docs/guides/btc_stakers/_category_.json rename to docs/stakers/btc_stakers/_category_.json index 4694d039..f74b3056 100644 --- a/docs/guides/btc_stakers/_category_.json +++ b/docs/stakers/btc_stakers/_category_.json @@ -1,7 +1,7 @@ { "position": 4, "label": "BTC Stakers", - "collapsible": true, + "collapsible": false, "collapsed": true, "className": "btc_stakers_sidebar_header" } \ No newline at end of file diff --git a/docs/guides/btc_stakers/btc_stakers.mdx b/docs/stakers/btc_stakers/btc_stakers.mdx similarity index 100% rename from docs/guides/btc_stakers/btc_stakers.mdx rename to docs/stakers/btc_stakers/btc_stakers.mdx diff --git a/docs/guides/btc_stakers/btc_staking_tools.mdx b/docs/stakers/btc_stakers/btc_staking_tools.mdx similarity index 100% rename from docs/guides/btc_stakers/btc_staking_tools.mdx rename to docs/stakers/btc_stakers/btc_staking_tools.mdx diff --git a/docs/guides/btc_stakers/campaigns/_category_.json b/docs/stakers/btc_stakers/campaigns/_category_.json similarity index 100% rename from docs/guides/btc_stakers/campaigns/_category_.json rename to docs/stakers/btc_stakers/campaigns/_category_.json diff --git a/docs/guides/btc_stakers/campaigns/pioneer_nfts.mdx b/docs/stakers/btc_stakers/campaigns/pioneer_nfts.mdx similarity index 100% rename from docs/guides/btc_stakers/campaigns/pioneer_nfts.mdx rename to docs/stakers/btc_stakers/campaigns/pioneer_nfts.mdx diff --git a/docs/guides/btc_stakers/liquid_staking/_category_.json b/docs/stakers/btc_stakers/liquid_staking/_category_.json similarity index 100% rename from docs/guides/btc_stakers/liquid_staking/_category_.json rename to docs/stakers/btc_stakers/liquid_staking/_category_.json diff --git a/docs/guides/btc_stakers/liquid_staking/liquid_staking_tokens.mdx b/docs/stakers/btc_stakers/liquid_staking/liquid_staking_tokens.mdx similarity index 95% rename from docs/guides/btc_stakers/liquid_staking/liquid_staking_tokens.mdx rename to docs/stakers/btc_stakers/liquid_staking/liquid_staking_tokens.mdx index 37494b4c..b5e0f4ec 100644 --- a/docs/guides/btc_stakers/liquid_staking/liquid_staking_tokens.mdx +++ b/docs/stakers/btc_stakers/liquid_staking/liquid_staking_tokens.mdx @@ -21,4 +21,4 @@ However, it's important to understand that when using liquid staking protocols: - The protocol manages the holder's stake and receives the points/rewards - The holder is trusting the liquid staking protocol with their Bitcoin -See a list of liquid staking tokens (LSTs) protocols at [BTC Staking Tools](/guides/btc_stakers/btc_staking_tools) page. +See a list of liquid staking tokens (LSTs) protocols at [BTC Staking Tools](/stakers/btc_stakers/btc_staking_tools) page. diff --git a/docs/guides/btc_stakers/native_staking/_category_.json b/docs/stakers/btc_stakers/native_staking/_category_.json similarity index 100% rename from docs/guides/btc_stakers/native_staking/_category_.json rename to docs/stakers/btc_stakers/native_staking/_category_.json diff --git a/docs/guides/btc_stakers/native_staking/custody_support.mdx b/docs/stakers/btc_stakers/native_staking/custody_support.mdx similarity index 100% rename from docs/guides/btc_stakers/native_staking/custody_support.mdx rename to docs/stakers/btc_stakers/native_staking/custody_support.mdx diff --git a/docs/guides/btc_stakers/native_staking/geo_blocking.mdx b/docs/stakers/btc_stakers/native_staking/geo_blocking.mdx similarity index 100% rename from docs/guides/btc_stakers/native_staking/geo_blocking.mdx rename to docs/stakers/btc_stakers/native_staking/geo_blocking.mdx diff --git a/docs/guides/btc_stakers/native_staking/staking_via_cli.mdx b/docs/stakers/btc_stakers/native_staking/staking_via_cli.mdx similarity index 100% rename from docs/guides/btc_stakers/native_staking/staking_via_cli.mdx rename to docs/stakers/btc_stakers/native_staking/staking_via_cli.mdx diff --git a/docs/guides/btc_stakers/native_staking/unbonding_via_cli.mdx b/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx similarity index 100% rename from docs/guides/btc_stakers/native_staking/unbonding_via_cli.mdx rename to docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx diff --git a/docs/guides/btc_stakers/native_staking/unbonding_via_web.mdx b/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx similarity index 86% rename from docs/guides/btc_stakers/native_staking/unbonding_via_web.mdx rename to docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx index b3cba13f..2235fb98 100644 --- a/docs/guides/btc_stakers/native_staking/unbonding_via_web.mdx +++ b/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx @@ -9,7 +9,7 @@ import ThemedImage from '@theme/ThemedImage'; # Unbond via Web ## Step 1: Connect Your Wallet -First, connect your wallet to [Babylon Staking Dashboard](https://btcstaking.babylonlabs.io/). Once your [compatible wallet](/guides/btc_stakers/native_staking/web_staking/#compatible-wallets) is successfully connected, you will be able to view the staking history list. If there are stakes that have not been transitioned yet, they will appear in the **Pending Registration** list. On the other hand, stakes that have already been transitioned to Phase 2 Babylon Genesis will show up in the **Babylon Genesis Stakes** list. +First, connect your wallet to [Babylon Staking Dashboard](https://btcstaking.babylonlabs.io/). Once your [compatible wallet](/stakers/btc_stakers/native_staking/web_staking/#compatible-wallets) is successfully connected, you will be able to view the staking history list. If there are stakes that have not been transitioned yet, they will appear in the **Pending Registration** list. On the other hand, stakes that have already been transitioned to Phase 2 Babylon Genesis will show up in the **Babylon Genesis Stakes** list. ## Step 2: Unbond BTC Stake ### Unbonding Before Transition to Phase 2 Babylon Genesis diff --git a/docs/guides/btc_stakers/native_staking/web_staking.mdx b/docs/stakers/btc_stakers/native_staking/web_staking.mdx similarity index 97% rename from docs/guides/btc_stakers/native_staking/web_staking.mdx rename to docs/stakers/btc_stakers/native_staking/web_staking.mdx index d508ed1c..8333fd81 100644 --- a/docs/guides/btc_stakers/native_staking/web_staking.mdx +++ b/docs/stakers/btc_stakers/native_staking/web_staking.mdx @@ -33,7 +33,7 @@ Visit the [Babylon Staking](https://btcstaking.babylonlabs.io/) website. /> #### Step 2: Connect Your Wallet -Connect your [compatible wallet](/guides/btc_stakers/native_staking/web_staking/#compatible-wallets) +Connect your [compatible wallet](/stakers/btc_stakers/native_staking/web_staking/#compatible-wallets) compatible wallet to continue with the staking operation. + + + + +## Two Staking Mechanisms + +### 1. Bitcoin (BTC) Staking + +**BTC staking** enables Bitcoin holders to stake their assets directly on the Bitcoin network in a self-custodial manner without wrapping or bridging. BTC stakers delegate to **Finality Providers** who enhance the security of the Proof-of-Stake chain. + +#### Key Features: +- **Self-custodial**: Maintain direct control of your Bitcoin +- **Native operation**: No wrapped tokens or bridges required +- **Trustless execution**: No reliance on third parties +- **Slashing capability**: Protocol-enforced penalties for malicious behavior +- **Multi-staking**: Delegate across multiple Finality Providers and BSNs + +#### Benefits: +- **Earn BABY rewards**: Receive a portion of the annual inflation allocated to BTC stakers +- **Secure the network**: Contribute to Babylon Genesis chain's security +- **Maintain Bitcoin ownership**: Your BTC remains on the Bitcoin blockchain +- **Fast unbonding**: ~2 days compared to typical 21 days in most PoS chains + +### 2. BABY Token Staking + +**BABY staking** is a native staking mechanism that secures the Babylon Genesis chain. BABY token holders delegate to chain validators to accrue inflationary rewards proportional to their stake. + +#### Key Features: +- **Epoch-based staking**: Delayed execution queue for enhanced security +- **Fast unbonding**: ~2 days via Bitcoin timestamping protocol +- **Governance participation**: Voting power in chain governance +- **Partial slashing**: 5% slashing for double-signing violations + +#### Benefits: +- **Earn rewards**: Receive a portion of the annual inflation allocated to BABY stakers +- **Secure the network**: Contribute to the Babylon Genesis chain's security and decentralization +- **Governance rights**: Participate in shaping the future of the network +- **Fast unbonding**: Significantly reduced unbonding period + + +## How They Work Together + +The dual-staking model creates a robust security framework: + +### Security Model +- **BTC stakers** delegate to Finality Providers who enhance PoS security +- **BABY stakers** delegate to validators who oversee block production and consensus +- Both mechanisms contribute to securing the Babylon Genesis chain + +### Reward Distribution +The annual inflation (8%) is distributed among: +- **BTC stakers**: 4% of annual inflation +- **BABY stakers**: 4% of annual inflation + +### Governance +- **BABY stakers** participate in governance with voting power +- **BTC stakers** do not participate in governance but receive rewards + + +## Risk Considerations + +### BTC Staking Risks +- **Slashing risk**: 0.1% maximum penalty for protocol violations +- **Finality Provider risk**: Choose reliable Finality Providers +- **Market volatility**: BTC price fluctuations affect staking value + +### BABY Staking Risks +- **Slashing risk**: 5% penalty for validator double-signing +- **Validator risk**: Choose reliable validators with good track records +- **Market volatility**: BABY price fluctuations affect staking value + +## Advanced Features + +### Fast Unbonding +Both BTC and BABY staking benefit from Babylon's Bitcoin Timestamping protocol: +- **~2 days unbonding** vs typical 21 days +- **Bitcoin checkpoint verification** ensures security +- **Automatic token release** once confirmations are met + +### Multi-Staking (BTC) +BTC stakers can delegate across multiple Finality Providers and BSNs simultaneously: +- **Diversify risk** across multiple networks +- **Maximize rewards** from multiple sources +- **Maintain security isolation** between networks + +## Next Steps + +- **BTC Stakers**: Explore [BTC staking guides](/stakers/btc_stakers/) +- **BABY Stakers**: Explore [BABY staking guides](/stakers/baby_stakers/) +- **Learn more**: Read about [Babylon Genesis architecture](/guides/architecture/) +- **Get support**: Visit [community channels](https://babylonlabs.io/community) + +This dual-staking model represents the foundation of Babylon's Bitcoin Secured Network, +combining the robustness of Bitcoin with the efficiency of Proof of Stake consensus to +create a secure, decentralized, and rewarding staking ecosystem. + diff --git a/docusaurus.config.js b/docusaurus.config.js index 2d8982be..eae8bd7a 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -186,20 +186,40 @@ const config = { }, items: [ { - label: 'Docs', + label: 'Overview', to: '/guides/overview/', className: 'guides-top-header', }, { - label: 'Operators', - to: '/operators/', - className: 'operators-top-header', + label: 'Stakers', + to: '/stakers/', + className: 'stakers-top-header', }, { label: 'Developers', to: '/developers/', className: 'developers-top-header', }, + { + label: 'Operators', + to: '/operators/', + className: 'operators-top-header', + }, + { + label: 'BSNs', + to: '/bsns/', + className: 'bsns-top-header', + }, + { + label: 'Operators', + to: '/operators/', + className: 'operators-top-header', + }, + { + label: 'BSNs', + to: '/bsns/', + className: 'bsns-top-header', + }, { label: 'API', items: [ @@ -217,7 +237,7 @@ const config = { ], }, { - label: 'Participate', + label: 'Community', to: 'https://babylonlabs.io/community', }, { diff --git a/sidebars-default.js b/sidebars-default.js index 4f7f0333..f9482437 100644 --- a/sidebars-default.js +++ b/sidebars-default.js @@ -17,8 +17,10 @@ import cometBFTSidebar from './docs/api/comet-bft/sidebar' const sidebars = { // By default, Docusaurus generates a sidebar from the docs folder structure guides: [{ type: 'autogenerated', dirName: 'guides' }], - operators: [{ type: 'autogenerated', dirName: 'operators' }], + stakers: [{ type: 'autogenerated', dirName: 'stakers' }], developers: [{ type: 'autogenerated', dirName: 'developers' }], + operators: [{ type: 'autogenerated', dirName: 'operators' }], + bsns: [{ type: 'autogenerated', dirName: 'bsns' }], stakingApi: [ { type: 'category', diff --git a/src/components/homepage/GuidesAndSamples.tsx b/src/components/homepage/GuidesAndSamples.tsx index 0330e6f1..8afd1b52 100644 --- a/src/components/homepage/GuidesAndSamples.tsx +++ b/src/components/homepage/GuidesAndSamples.tsx @@ -65,14 +65,14 @@ const samples: Sample[] = [ source: 'https://github.com/babylonlabs-io/babylon-integration-deployment/tree/main/deployments/btc-staking-integration-bitcoind', blog: 'https://babylonlabs.io/blog/babylon-bitcoin-security-for-cosmos-and-beyond', - demo: '/developers/bsns', + demo: '/bsns/', }, { title: 'L2 Integrations Guides', platform: 'For OP Stacks chains', - blog: '/developers/bsns/op_stack_chains', + blog: '/bsns/op_stack_chains', source: 'https://babylonlabs.io/blog/forkless-rollups-with-bitcoin-staking', - demo: '/developers/bsns/op_stack_chains', + demo: '/bsns/op_stack_chains', }, { title: 'CosmWasm Contract Deployment Guides', diff --git a/src/components/homepage/HeroSection.tsx b/src/components/homepage/HeroSection.tsx index 417b3a52..4ff7ccb5 100644 --- a/src/components/homepage/HeroSection.tsx +++ b/src/components/homepage/HeroSection.tsx @@ -12,7 +12,7 @@ import { useBaseUrlUtils } from '@docusaurus/useBaseUrl'; const PRODUCTS = [ { title: 'Stake BTC', - link: '/guides/btc_stakers', + link: '/stakers/btc_stakers', icon: WalletCreditCardRegular, lightImage: 'img/landing-page/hero/btc_stakers.png', darkImage: 'img/landing-page/hero/btc_stakers_dark.png', @@ -20,7 +20,7 @@ const PRODUCTS = [ }, { title: 'Stake BABY', - link: '/guides/baby_stakers', + link: '/stakers/baby_stakers', icon: WalletCreditCardRegular, lightImage: 'img/landing-page/hero/btc_stakers.png', darkImage: 'img/landing-page/hero/btc_stakers_dark.png', @@ -44,7 +44,7 @@ const PRODUCTS = [ }, { title: 'Build BSNs', - link: '/developers/bsns', + link: '/bsns', icon: DiversityRegular, lightImage: 'img/landing-page/hero/bsn_developers.png', darkImage: 'img/landing-page/hero/bsn_developers_dark.png', From 350eb1de3e94e1c571454a6202efe5a14efca14a Mon Sep 17 00:00:00 2001 From: Jenks Date: Wed, 16 Jul 2025 15:44:35 +1000 Subject: [PATCH 07/49] corrected duplication issue with to Nav --- docusaurus.config.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/docusaurus.config.js b/docusaurus.config.js index eae8bd7a..53b84017 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -210,16 +210,6 @@ const config = { to: '/bsns/', className: 'bsns-top-header', }, - { - label: 'Operators', - to: '/operators/', - className: 'operators-top-header', - }, - { - label: 'BSNs', - to: '/bsns/', - className: 'bsns-top-header', - }, { label: 'API', items: [ @@ -237,8 +227,8 @@ const config = { ], }, { - label: 'Community', - to: 'https://babylonlabs.io/community', + label: 'Support', + to: 'https://discord.com/invite/babylonglobal', }, { href: 'https://discord.com/invite/babylonglobal', From 0cb6874828f2b957c108e6759377a357f1449a51 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 18 Jul 2025 00:26:48 +0800 Subject: [PATCH 08/49] fix: Restore the image link --- src/components/homepage/BlogSection.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/homepage/BlogSection.tsx b/src/components/homepage/BlogSection.tsx index 99b6dc2d..65e4d3a6 100644 --- a/src/components/homepage/BlogSection.tsx +++ b/src/components/homepage/BlogSection.tsx @@ -11,19 +11,19 @@ interface FeaturedBlogPost { const blogPosts: FeaturedBlogPost[] = [ { title: "Bitcoin Staking 101: Part 3 - Babylon's Bitcoin Staking Contract", - image: "/img/blog/05-26-babylon-s-bitcoin-staking-contract/xangle_baby_faucet.png", + image: "/img/blog/05-26-babylon-s-bitcoin-staking-contract/img.png", link: "https://babylonlabs.io/blog/babylon-s-bitcoin-staking-contract", readTime: 14 }, { title: "Bitcoin Staking 101: Part 2 - Technical Preliminaries of Bitcoin Staking", - image: "/img/blog/05-25-technical-preliminaries-of-bitcoin-staking/xangle_baby_faucet.png", + image: "/img/blog/05-25-technical-preliminaries-of-bitcoin-staking/img.png", link: "https://babylonlabs.io/blog/technical-preliminaries-of-bitcoin-staking", readTime: 12 }, { title: "Bitcoin Staking 101: Part 1 - What is Bitcoin Staking?", - image: "/img/blog/05-24-what-is-bitcoin-staking/xangle_baby_faucet.png", + image: "/img/blog/05-24-what-is-bitcoin-staking/img.png", link: "https://babylonlabs.io/blog/what-is-bitcoin-staking", readTime: 5 } From ae2382a8b701615dae9f653450530d9492007485 Mon Sep 17 00:00:00 2001 From: Kevin <33023258+kkkk666@users.noreply.github.com> Date: Mon, 21 Jul 2025 13:58:58 +0800 Subject: [PATCH 09/49] chore: Update-Unbonding-Time (#249) Co-authored-by: kevin --- .../native_staking/unbonding_via_cli.mdx | 56 +++++++++---------- .../native_staking/unbonding_via_web.mdx | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx b/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx index 65836853..1f9104b7 100644 --- a/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx +++ b/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx @@ -87,33 +87,33 @@ Prepare a ```parameters.json``` file containing global parameters. This file mus - File Structure: The file should contain a Versions field, whose value is an array. Each element in the array corresponds to the global parameters of a version, with the following format: ```json { - "Versions": [ - { - "Version": 3, - "ActivationHeight": 874088, - "StakingCap": 3, - "CapHeight": 875090, - "Tag": "bbn1", - "CovenantPks": ["d45c70d28f169e1f0c7f4a78e2bc73497afe585b70aa897955989068f3350aaa", - "4b15848e495a3a62283daaadb3f458a00859fe48e321f0121ebabbdd6698f9fa", - "23b29f89b45f4af41588dcaf0ca572ada32872a88224f311373917f1b37d08d1", - "d3c79b99ac4d265c2f97ac11e3232c07a598b020cf56c6f055472c893c0967ae", - "8242640732773249312c47ca7bdb50ca79f15f2ecc32b9c83ceebba44fb74df7", - "e36200aaa8dce9453567bba108bdc51f7f1174b97a65e4dc4402fc5de779d41c", - "cbdd028cfe32c1c1f2d84bfec71e19f92df509bba7b8ad31ca6c1a134fe09204", - "f178fcce82f95c524b53b077e6180bd2d779a9057fdff4255a0af95af918cee0", - "de13fc96ea6899acbdc5db3afaa683f62fe35b60ff6eb723dad28a11d2b12f8c"], - "CovenantQuorum": 6, - "UnbondingTime": 1008, - "UnbondingFee": 10000, - "MaxStakingAmount": 500000000000, - "MinStakingAmount": 500000, - "MaxStakingTime": 64000, - "MinStakingTime": 64000, - "ConfirmationDepth": 30 - }, - // Parameters of other versions... - ] + "version": 5, + "covenant_pks": [ + "d45c70d28f169e1f0c7f4a78e2bc73497afe585b70aa897955989068f3350aaa", + "4b15848e495a3a62283daaadb3f458a00859fe48e321f0121ebabbdd6698f9fa", + "23b29f89b45f4af41588dcaf0ca572ada32872a88224f311373917f1b37d08d1", + "d3c79b99ac4d265c2f97ac11e3232c07a598b020cf56c6f055472c893c0967ae", + "8242640732773249312c47ca7bdb50ca79f15f2ecc32b9c83ceebba44fb74df7", + "e36200aaa8dce9453567bba108bdc51f7f1174b97a65e4dc4402fc5de779d41c", + "f178fcce82f95c524b53b077e6180bd2d779a9057fdff4255a0af95af918cee0", + "de13fc96ea6899acbdc5db3afaa683f62fe35b60ff6eb723dad28a11d2b12f8c", + "cbdd028cfe32c1c1f2d84bfec71e19f92df509bba7b8ad31ca6c1a134fe09204" + ], + "covenant_quorum": 6, + "min_staking_value_sat": 500000, + "max_staking_value_sat": 500000000000, + "min_staking_time_blocks": 64000, + "max_staking_time_blocks": 64000, + "slashing_pk_script": "6a07626162796c6f6e", + "min_slashing_tx_fee_sat": 150000, + "slashing_rate": "0.001000000000000000", + "unbonding_time_blocks": 301, + "unbonding_fee_sat": 9600, + "min_commission_rate": "0.030000000000000000", + "max_active_finality_providers": 0, + "delegation_creation_base_gas_fee": 1095000, + "allow_list_expiration_height": 139920, + "btc_activation_height": 905634 } ``` - Parameter Explanation: @@ -433,7 +433,7 @@ You can use the following command to get the list of all staking transactions in stakercli daemon list -staking -transactions ``` ### Minimum Unbonding Time -There is a minimum unbonding time currently set to 1008 BTC blocks. After this period, the unbonding timelock will expire, and the staked funds will be unbonded. You can monitor the progress of the Bitcoin blocks in the `bitcoind` systemd logs using `journalctl -u bitcoind -f` or by comparing the latest block in your node with a BTC explorer like `https://mempool.space/mainnet`. +There is a minimum unbonding time currently set to 301 BTC blocks. After this period, the unbonding timelock will expire, and the staked funds will be unbonded. You can monitor the progress of the Bitcoin blocks in the `bitcoind` systemd logs using `journalctl -u bitcoind -f` or by comparing the latest block in your node with a BTC explorer like `https://mempool.space/mainnet`. ### Troubleshooting diff --git a/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx b/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx index 2235fb98..8ae98cca 100644 --- a/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx +++ b/docs/stakers/btc_stakers/native_staking/unbonding_via_web.mdx @@ -26,7 +26,7 @@ If your stake has already been transitioned and is listed in the **Babylon Genes /> ## Step 3: Wait for the Unbonding Period and Withdraw -After you initiate the unbonding process, you need to wait for a specific period to complete the unbonding. Specifically, you must wait for 1,008 Bitcoin blocks (~7 days) to be mined, which typically takes around one week. This waiting period ensures the stability and security of the network. +After you initiate the unbonding process, you need to wait for a specific period to complete the unbonding. Specifically, you must wait for 301 Bitcoin blocks (~2 days) to be mined, which typically takes around one week. This waiting period ensures the stability and security of the network. Once the unbonding period has elapsed, return to the staking history list in your wallet. Locate the unbonded stake. For stakes that have completed the unbonding process, you will see a **Withdraw** button. Click on the **Withdraw** button to transfer the unbonded funds back to your wallet. After clicking **Withdraw**, confirm the transaction in your wallet, and the funds will be on their way to your wallet address. :::note From b3ae631dfccebc14eef668750119e79f3a4cd19e Mon Sep 17 00:00:00 2001 From: Sam <48280694+itrocket-team@users.noreply.github.com> Date: Mon, 21 Jul 2025 09:03:19 +0300 Subject: [PATCH 10/49] Added commands to babylon_usage_guide.mdx (#246) --- .../babylon_node/babylon_usage_guide.mdx | 171 +++++++++++++++++- 1 file changed, 170 insertions(+), 1 deletion(-) diff --git a/docs/operators/babylon_node/babylon_usage_guide.mdx b/docs/operators/babylon_node/babylon_usage_guide.mdx index 5bdf7880..0d11184b 100644 --- a/docs/operators/babylon_node/babylon_usage_guide.mdx +++ b/docs/operators/babylon_node/babylon_usage_guide.mdx @@ -3,4 +3,173 @@ sidebar_class_name: node_operators_installation_guide_sidebar sidebar_label: Usage Guide sidebar_position: 1 --- -//ITRocket guide \ No newline at end of file +# CLI Usage Guide + +### Key Management 🔑 +Add new wallet: +``` +babylond keys add +``` + +Restore executing wallet: +``` +babylond keys add --recover +``` + +List all wallets: +``` +babylond keys list +``` + +Delete wallet: +``` +babylond keys delete +``` + +Export key (saves it to `wallet.backup`): +``` +babylond keys export +``` + +Import key (restore from wallet.backup): +``` +babylond keys import wallet.backup +``` + +### Tokens 💰 +Check balance: +``` +babylond q bank balances +``` + +Withdraw all rewards: +``` +babylond tx distribution withdraw-all-rewards --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 +``` + +Withdraw rewards and commission from your validator: +``` +babylond tx distribution withdraw-rewards $(babylond keys show --bech val -a) --from --commission --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Delegate to your validator: +``` +babylond tx epoching delegate $(babylond keys show --bech val -a) ubbn --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Delegate to another validator: +``` +babylond tx epoching delegate ubbn --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Redelegate stake to another validator: +``` +babylond tx epoching redelegate ubbn --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Unbond from your validator: +``` +babylond tx epoching unbond $(babylond keys show --bech val -a) ubbn --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Unbond from another validator: +``` +babylond tx epoching unbond ubbn --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Transfer funds: +``` +babylond tx bank send ubbn --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Transfer funds to multiple accounts: +``` +babylond tx bank multi-send ubbn --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +### Governance 🗳️ +View proposals list: +``` +babylond query gov proposals +``` + +View proposal: +``` +babylond query gov proposal +``` + +Vote: +``` +babylond tx gov vote --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +### Validator Operations 👨‍💻 +Create new validator: +``` +# Create a validator.json file with validator details (replace moniker, details, etc. with your data): +echo "{\"pubkey\":{\"@type\":\"/cosmos.crypto.ed25519.PubKey\",\"key\":\"$(babylond comet show-validator | grep -Po '\"key\":\s*\"\K[^"]*')\"}, + \"amount\": \"1000000ubbn\", + \"moniker\": \"test\", + \"identity\": \"\", + \"website\": \"\", + \"security\": \"\", + \"details\": \"I love Babylon ❤️\", + \"commission-rate\": \"0.1\", + \"commission-max-rate\": \"0.2\", + \"commission-max-change-rate\": \"0.01\", + \"min-self-delegation\": \"1\" +}" > validator.json + +# Create a validator using JSON file +babylond tx checkpointing create-validator validator.json --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 +``` + +Edit validator (from `new-moniker`, `identity`, `details`, `commission-rate` flags, use only those you want to edit): +``` +babylond tx epoching edit-validator \ +--commission-rate 0.1 \ +--new-moniker "" \ +--identity "" \ +--details "" \ +--from \ +--chain-id bbn-1 \ +--gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 \ +-y +``` + +Unjail validator: +``` +babylond tx slashing unjail --from --chain-id bbn-1 --gas auto --gas-prices 0.002ubbn --gas-adjustment 1.5 -y +``` + +Your validator details: +``` +babylond query staking validator $(babylond keys show --bech val -a) +``` + +Another validator details: +``` +babylond query staking validator +``` + +Slashing parameters: +``` +babylond query slashing params +``` + +Signing and jailing info of your validator: +``` +babylond query slashing signing-info $(babylond tendermint show-validator) +``` + +Signing and jailing info of another validator: +``` +babylond query slashing signing-info '' +``` + +Active validators list: +``` +babylond query staking validators +``` + +*Guide provided by [ITRocket team](https://itrocket.net/).* From 281b4f9dd63d2db6603b320348df2ced4dddabe1 Mon Sep 17 00:00:00 2001 From: Jenks Date: Mon, 21 Jul 2025 16:07:27 +1000 Subject: [PATCH 11/49] Update docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx b/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx index 1f9104b7..36d48847 100644 --- a/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx +++ b/docs/stakers/btc_stakers/native_staking/unbonding_via_cli.mdx @@ -433,7 +433,7 @@ You can use the following command to get the list of all staking transactions in stakercli daemon list -staking -transactions ``` ### Minimum Unbonding Time -There is a minimum unbonding time currently set to 301 BTC blocks. After this period, the unbonding timelock will expire, and the staked funds will be unbonded. You can monitor the progress of the Bitcoin blocks in the `bitcoind` systemd logs using `journalctl -u bitcoind -f` or by comparing the latest block in your node with a BTC explorer like `https://mempool.space/mainnet`. +There is a minimum unbonding time currently set to 301 BTC blocks. After this period, the unbonding timelock will expire, and the staked funds will be unbonded. You can monitor the progress of the Bitcoin blocks in the `bitcoind` systemd logs using `journalctl -u bitcoind -f` or by comparing the latest block in your node with a BTC explorer like [https://mempool.space/mainnet](https://mempool.space/mainnet). ### Troubleshooting From 7bfcc4ad9492b4bb30ece129f4916839a5a86457 Mon Sep 17 00:00:00 2001 From: Jenks Date: Thu, 24 Jul 2025 17:09:21 +1000 Subject: [PATCH 12/49] removed global_config.mdx --- .../services/global_config.mdx | 9 - .../staking_backend/staking_backend.mdx | 2 +- .../babylon_validators/babylon_validators.mdx | 40 +--- .../baby_stakers/staking_mechanism.mdx | 4 +- .../babylon_genesis_modules/btc_staking.html | 1 - .../finality_providers.html | 2 +- .../zone_concierge.html | 216 +++++++++--------- .../phase-2/registration.html | 2 +- 8 files changed, 110 insertions(+), 166 deletions(-) delete mode 100644 docs/developers/staking_backend/services/global_config.mdx diff --git a/docs/developers/staking_backend/services/global_config.mdx b/docs/developers/staking_backend/services/global_config.mdx deleted file mode 100644 index 736e8c11..00000000 --- a/docs/developers/staking_backend/services/global_config.mdx +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Global Configuration -sidebar_label: Global Configuration -sidebar_position: 4 ---- - -# Global Configuration - -{/* TODO */} \ No newline at end of file diff --git a/docs/developers/staking_backend/staking_backend.mdx b/docs/developers/staking_backend/staking_backend.mdx index d4451e3e..44e34871 100644 --- a/docs/developers/staking_backend/staking_backend.mdx +++ b/docs/developers/staking_backend/staking_backend.mdx @@ -49,7 +49,7 @@ properly set up: - **RabbitMQ** - [Setup Guide](https://www.rabbitmq.com/download.html) _Handles message queuing between system components_ -- **Global Configuration** - [Setup Guide](./services/global_config) +- **Global Configuration** - Setup guide will be available soon. _Defines system-wide parameters for all services_ {/* Database Migration (Optional) - Clone Phase-1 database snapshot, apply snapshot to new MongoDB clusters. diff --git a/docs/operators/babylon_validators/babylon_validators.mdx b/docs/operators/babylon_validators/babylon_validators.mdx index 51e04a11..ed8d5db9 100644 --- a/docs/operators/babylon_validators/babylon_validators.mdx +++ b/docs/operators/babylon_validators/babylon_validators.mdx @@ -49,18 +49,12 @@ Initialize your validator key with `babylond init` will create the BABY key you need for consensus participation and a BLS key used in checkpointing and timestamping to Bitcoin blockchain. -See [3. Key Management](/operators/babylon_validators/installation_guide/#3-key-management) -for more details. - ### 3. Create a Validator Instead of using `staking` module of Cosmos SDK, Babylon Genesis uses `checkpointing` module for validator registration and management. To create a validator, use `babylond tx checkpointing create-validator` command. -See [4. Create a Validator](/operators/babylon_validators/installation_guide/#4-create-a-validator) -for more details. - ### 4. Verify Your Validator To verify your validator, first get your validator's operator address with @@ -71,38 +65,6 @@ registration request is in the queue. Initially, your status will be `0 - BOND_STATUS_UNBONDED`. When active, your status will change to `3 - BOND_STATUS_BONDED`. -See [5. Verify Your Validator](/operators/babylon_validators/installation_guide/#51-verifying-validator-setup) -for more details and rules. - ## Communication -Join the `#finality-providers` channel in the `- tech-zone -` section of our -[Discord server](https://discord.com/invite/babylonglobal) for all communications. -Testnet announcements will also be made there. - -## CosmWasm Governance Proposals - -The Babylon Genesis chain will initially use permissioned CosmWasm. After public -launch on 10 April 2025, dApp developers are expected to submit governance proposals -for either (a) deploying CosmWasm smart contracts or (b) whitelisting addresses to -deploy such contracts. These proposals can be expedited (24-hour voting) or standard -(72-hour voting). **It is important that all validators with voting power actively -monitor on-chain proposals, review them (**[Governance guidelines](https://docs.babylonlabs.io/guides/governance/))** -, and participate in governance.** - -## Version Information - -- **Babylon Genesis node**: Version [v1.0.1](https://github.com/babylonlabs-io/babylon/releases/tag/v1.0.1)([Releases page](https://github.com/babylonlabs-io/babylon/releases)) - -## Faucets - -There are two ways to get tBABY for Phase 2 Testnet: - -1. [Babylon Labs Discord Faucet](https://discord.com/channels/1266159481218457600/1266159481218457600) -2. [Xangle Faucet](https://babylon-explorer.xangle.io/testnet/faucet) (0.01 tBABY each request) - -## Documentation - -- [Node Setup guide](https://github.com/babylonlabs-io/networks/tree/main/bbn-1/babylon-node) -- [Validator Setup Guide](https://github.com/babylonlabs-io/networks/blob/main/bbn-1/babylon-validators/README.md) -- [Governance guidelines](https://docs.babylonlabs.io/guides/governance/) \ No newline at end of file +Join the `#finality-providers` \ No newline at end of file diff --git a/docs/stakers/baby_stakers/staking_mechanism.mdx b/docs/stakers/baby_stakers/staking_mechanism.mdx index a59642e3..243fa0c4 100644 --- a/docs/stakers/baby_stakers/staking_mechanism.mdx +++ b/docs/stakers/baby_stakers/staking_mechanism.mdx @@ -89,9 +89,7 @@ system will conduct the following actions: To monitor pending staking transactions that will be processed at epoch end: -- Use [Babylon Genesis Explorers](/developers/babylon_genesis_chain/#chain-explorer) that support epochised staking, or - -- Use [Babylon Node](/operators/babylon_node/installation_guide/) or [RPC Endpoints](/developers/babylon_genesis_chain/#node-information) to query the `LastEpochMsgs` endpoint in the +- Use [Babylon Node](/operators/babylon_node/installation_guide/) or RPC Endpoints to query the `LastEpochMsgs` endpoint in the `x/epoching` module. - Check with compatible wallet interfaces. diff --git a/static/remote-docs/guides/architecture/babylon_genesis_modules/btc_staking.html b/static/remote-docs/guides/architecture/babylon_genesis_modules/btc_staking.html index 7a3d0390..2537daf2 100644 --- a/static/remote-docs/guides/architecture/babylon_genesis_modules/btc_staking.html +++ b/static/remote-docs/guides/architecture/babylon_genesis_modules/btc_staking.html @@ -757,7 +757,6 @@

MsgSelectiveSlashingEvidence

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. diff --git a/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html b/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html index ca123d52..7985a1e8 100644 --- a/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html +++ b/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html @@ -55,7 +55,7 @@

    Finality Provider

    Finality Provider Architecture Diagram

    Finality Provider for Consumer Networks Specification

    For detailed technical specifications and requirements of the finality provider -program for Consumer networks, please see SPEC-CONSUMER.md. +program for Consumer networks, please see ./docs/SPEC-CONSUMER.md. The spec document outlines the Consumer's interfaces, message handlers and queries. It also provides guidance for integrators.

    diff --git a/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html b/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html index 581c4bee..6a5b09c9 100644 --- a/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html +++ b/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html @@ -59,10 +59,9 @@

    Table of contents

  5. State

    State

    -

    The Zone Concierge module keeps handling IBC headers of PoS systems, and -maintains the following KV stores.

    +

    The Zone Concierge module maintains a simplified header indexing system with the following KV stores. Consumer registration is handled by the btcstkconsumer module.

    Parameters

    The parameter storage maintains the Zone Concierge module's parameters. The Zone Concierge module's parameters are represented as a @@ -117,54 +115,36 @@

    Parameters

    [ (gogoproto.moretags) = "yaml:\"ibc_packet_timeout_seconds\"" ]; } -

    ChainInfo

    -

    The chain info storage maintains ChainInfo -for each PoS system. The key is the PoS system's ConsumerID, which is the ID -of the IBC light client. The value is a ChainInfo object. The ChainInfo is a -structure storing the information of a PoS system that checkpoints to Babylon -Genesis.

    -
    // ChainInfo is the information of a Consumer
    -message ChainInfo {
    -  // consumer_id is the ID of the consumer
    -  string consumer_id = 1;
    -  // latest_header is the latest header in the Consumer's canonical chain
    -  IndexedHeader latest_header = 2;
    -  // latest_forks is the latest forks, formed as a series of IndexedHeader (from
    -  // low to high)
    -  Forks latest_forks = 3;
    -  // timestamped_headers_count is the number of timestamped headers in the Consumer's
    -  // canonical chain
    -  uint64 timestamped_headers_count = 4;
    -}
    -
    -

    EpochChainInfo

    -

    The epoch chain info storage maintains -ChainInfo at the end of each Babylon epoch for each PoS system. The key is the -PoS system's ConsumerID plus the epoch number, and the value is a ChainInfo -object.

    -

    CanonicalChain

    -

    The canonical chain storage maintains the -metadata of canonical IBC headers of a PoS system. The key is the BSN's -ConsumerID plus the height, and the value is a IndexedHeader object. -IndexedHeader is a structure storing IBC header's metadata.

    -
    // IndexedHeader is the metadata of a Consumer header
    +

    LatestEpochHeaders

    +

    The latest epoch headers storage maintains +the most recent header received from each BSN during the current epoch. The +key is the BSN's ConsumerID, and the value is an IndexedHeader object. +This storage is cleared at the end of each epoch when headers are moved to the +finalized storage.

    +

    FinalizedEpochHeaders

    +

    The finalized epoch headers storage +maintains headers that have been finalized for each BSN and epoch. The key +is the epoch number plus the BSN's ConsumerID, and the value is an +IndexedHeaderWithProof object. The IndexedHeaderWithProof contains both the +header metadata and the inclusion proof.

    +
    // IndexedHeader is the metadata of a BSN header
     message IndexedHeader {
    -  // consumer_id is the unique ID of the consumer
    +  // consumer_id is the unique ID of the BSN
       string consumer_id = 1;
       // hash is the hash of this header
       bytes hash = 2;
    -  // height is the height of this header on the Consumer's ledger
    -  // (hash, height) jointly provides the position of the header on the Consumer's ledger
    +  // height is the height of this header on the BSN's ledger.
    +  // (hash, height) jointly provide the position of the header on the BSN ledger
       uint64 height = 3;
    -  // time is the timestamp of this header on the Consumer's ledger.
    -  // It is needed for the Consumer to unbond all mature validators/delegations
    -  // before this timestamp when this header is BTC-finalised
    +  // time is the timestamp of this header on the BSN's ledger.
    +  // It is needed for a BSN to unbond all mature validators/delegations before
    +  // this timestamp, when this header is BTC-finalised
       google.protobuf.Timestamp time = 4 [ (gogoproto.stdtime) = true ];
    -  // babylon_header_hash is the hash of the babylon block that includes this
    -  // Consumer header
    +  // babylon_header_hash is the hash of the babylon block that includes this BSN
    +  // header
       bytes babylon_header_hash = 5;
       // babylon_header_height is the height of the babylon block that includes this
    -  // Consumer header
    +  // BSN header
       uint64 babylon_header_height = 6;
       // epoch is the epoch number of this header on Babylon ledger
       uint64 babylon_epoch = 7;
    @@ -173,12 +153,32 @@ 

    CanonicalChain

    // the header on Babylon ledger bytes babylon_tx_hash = 8; } + +// IndexedHeaderWithProof is an indexed header with a proof that the header is +// included in the epoch +message IndexedHeaderWithProof { + IndexedHeader header = 1; + // proof is an inclusion proof that the header + // is committed to the `app_hash` of the sealer header of header.babylon_epoch + tendermint.crypto.ProofOps proof = 2; +} +
    +

    BSNBTCState

    +

    The BSN BTC state storage maintains +unified BTC synchronization state for each BSN. The key is the BSN's +ConsumerID, and the value is a BSNBTCState object that tracks the base +BTC header and last sent BTC header segment for each BSN.

    +
    // BSNBTCState stores per-BSN BTC synchronization state
    +// This includes both the base header and the last sent segment
    +message BSNBTCState {
    +  // base_header is the base BTC header for this BSN
    +  // This represents the starting point from which BTC headers are synchronized
    +  babylon.btclightclient.v1.BTCHeaderInfo base_header = 1;
    +  // last_sent_segment is the last segment of BTC headers sent to this BSN
    +  // This is used to determine the next headers to send and handle reorgs
    +  BTCChainSegment last_sent_segment = 2;
    +}
     
    -

    Fork

    -

    The fork storage maintains the metadata of canonical -IBC headers of a PoS system. The key is the PoS system's ConsumerID plus the -height, and the value is a list of IndexedHeader objects, which represent fork -headers at that height.

    Params

    The parameter storage maintains the parameters for the Zone Concierge module.

    @@ -222,32 +222,33 @@

    PostHandler for intercepting IBC headers

  6. Extract the header info and the client state from the message
  7. Determine if the header is on a fork by checking if the client is frozen
  8. Call HandleHeaderWithValidCommit to process the header
  9. -
  10. If the PoS system hosting the header is not known to Babylon Genesis, -initialize ChainInfo storage for the PoS system
  11. -
  12. If the header is on a fork, insert the header to the fork storage and update -ChainInfo
  13. -
  14. If the header is canonical, insert the header to the canonical chain storage -and update ChainInfo
  15. -
  16. Unfreeze the client if it was frozen due to a fork header
  17. +
  18. Check if the BSN is registered through the btcstkconsumer module and is a Cosmos BSN; if not, ignore the header
  19. +
  20. Create an IndexedHeader with the header metadata and Babylon context
  21. +
  22. If the header is not on a fork and is newer than the existing latest header, +update the latest epoch header for the BSN
  23. +
  24. Log fork events for monitoring and debugging purposes

Hooks

The Zone Concierge module subscribes to the Epoching module's AfterEpochEnds -hook for indexing the epochs when receiving -headers from BSNs, the Checkpointing module's AfterRawCheckpointSealed -hook for recording epoch chain info proofs, -and the Checkpointing module's AfterRawCheckpointFinalized +hook for recording epoch headers, the +Checkpointing module's AfterRawCheckpointSealed +hook for recording epoch header proofs, and +the Checkpointing module's AfterRawCheckpointFinalized hook for sending BTC timestamps to BSNs.

Indexing headers upon AfterEpochEnds

The AfterEpochEnds hook is triggered when an epoch is ended, i.e., the last block in this epoch has been committed by CometBFT. Upon AfterEpochEnds, the -Zone Concierge will save the current ChainInfo to the EpochChainInfo storage -for each BSN.

+Zone Concierge will:

+
    +
  1. Record all current latest epoch headers as finalized headers for the completed epoch
  2. +
  3. Clear the latest epoch headers to prepare for the next epoch
  4. +

Recording proofs upon AfterRawCheckpointSealed

The AfterRawCheckpointSealed hook is triggered when an epoch's raw checkpoint is sealed by validator signatures. Upon AfterRawCheckpointSealed, the Zone Concierge will:

    -
  1. Record epoch chain info with inclusion proofs for each BSN
  2. +
  3. Generate inclusion proofs for all finalized headers in the sealed epoch
  4. Generate and store the proof that the epoch is sealed

Sending BTC timestamps upon AfterRawCheckpointFinalized

@@ -261,11 +262,11 @@

Sending BTC timestamps upon AfterRawCheckpointFinalized

Bitcoin.

// BTCTimestamp is a BTC timestamp that carries information of a BTC-finalized epoch
 // It includes a number of BTC headers, a raw checkpoint, an epoch metadata, and 
-// a Consumer header if there exists Consumer headers checkpointed to this epoch.
+// a BSN header if there exists BSN headers checkpointed to this epoch.
 // Upon a newly finalized epoch in Babylon, Babylon will send a BTC timestamp to each
-// PoS blockchain that has phase-2 integration with Babylon via IBC.
+// BSN via IBC.
 message BTCTimestamp {
-  // header is the last Consumer header in the finalized Babylon epoch
+  // header is the last BSN header in the finalized Babylon epoch
   babylon.zoneconcierge.v1.IndexedHeader header = 1;
 
   /*
@@ -290,25 +291,24 @@ 

Sending BTC timestamps upon AfterRawCheckpointFinalized

/* Proofs that the header is finalized */ - babylon.zoneconcierge.v1.ProofFinalizedChainInfo proof = 6; + babylon.zoneconcierge.v1.ProofFinalizedHeader proof = 6; } -// ProofFinalizedChainInfo is a set of proofs that attest a chain info is +// ProofFinalizedHeader is a set of proofs that attest a header is // BTC-finalized -message ProofFinalizedChainInfo { +message ProofFinalizedHeader { /* - The following fields include proofs that attest the chain info is + The following fields include proofs that attest the header is BTC-finalized */ - // proof_consumer_header_in_epoch is the proof that the Consumer header is timestamped - // within a certain epoch - tendermint.crypto.ProofOps proof_consumer_header_in_epoch = 1; // proof_epoch_sealed is the proof that the epoch is sealed - babylon.zoneconcierge.v1.ProofEpochSealed proof_epoch_sealed = 2; + babylon.zoneconcierge.v1.ProofEpochSealed proof_epoch_sealed = 1; // proof_epoch_submitted is the proof that the epoch's checkpoint is included // in BTC ledger It is the two TransactionInfo in the best (i.e., earliest) // checkpoint submission - repeated babylon.btccheckpoint.v1.TransactionInfo proof_epoch_submitted = 3; + repeated babylon.btccheckpoint.v1.TransactionInfo proof_epoch_submitted = 2; + // proof_consumer_header_in_epoch is the proof that the BSN header is included in the epoch + tendermint.crypto.ProofOps proof_consumer_header_in_epoch = 3; }

When AfterRawCheckpointFinalized is triggered, the Zone Concierge module will @@ -317,18 +317,8 @@

Sending BTC timestamps upon AfterRawCheckpointFinalized

  1. Determine BTC headers to broadcast: Get all BTC headers to be sent in BTC -timestamps by:

    -
      -
    • Finding the segment of BTC headers sent upon the last time -AfterRawCheckpointFinalized was triggered
    • -
    • If all BTC headers in the segment are no longer canonical (due to a Bitcoin -reorg), send the last w+1 BTC headers from the current tip, where w is -the checkpoint_finalization_timeout -parameter in the -BTCCheckpoint module
    • -
    • Otherwise, send BTC headers from the latest header that is still canonical -in the segment to the current tip of the BTC light client
    • -
    +timestamps using the global broadcast strategy (fallback to the last w+1 +BTC headers from the current tip for compatibility)

  2. Broadcast BTC timestamps to all open channels: For each open IBC channel @@ -336,7 +326,7 @@

    Sending BTC timestamps upon AfterRawCheckpointFinalized

    • Find the ConsumerID of the counterparty chain (i.e., the PoS system) in the IBC channel
    • -
    • Get the ChainInfo of the ConsumerID at the last finalised epoch
    • +
    • Get the finalized header for the ConsumerID at the last finalised epoch
    • Get the metadata of the last finalised epoch and its corresponding raw checkpoint
    • Generate the proof that the last PoS system's canonical header is committed @@ -364,20 +354,23 @@

      Broadcasting BTC Headers

      The EndBlocker calls BroadcastBTCHeaders to send BTC headers to all open IBC channels with BSNs. This ensures that BSNs' BTC light clients stay synchronized with Babylon Genesis' BTC light client.

      -

      The header selection logic follows the same rules as described in the Hooks -section:

      +

      The header selection logic now uses per-BSN BTC state tracking with the +following enhanced rules:

        -
      • If no headers have been sent previously: Send the last w+1 BTC headers from -the tip
      • -
      • If headers have been sent previously: -
          -
        • If the last sent segment is still valid (no Bitcoin reorg): Send headers -from the last sent header to the current tip
        • -
        • If the last sent segment is invalid (Bitcoin reorg occurred): Send the last -w+1 headers from the current tip
        • -
        -
      • +
      • BSN-specific BTC state: Each BSN has its own BSNBTCState +that tracks the base BTC header and last sent segment
      • +
      • No BSN base header: Falls back to sending the last w+1 BTC headers +from the tip (where w is the confirmation depth parameter)
      • +
      • BSN base header exists but no headers sent: Send headers from the +BSN's base header to the current tip
      • +
      • Headers previously sent: Send headers from the child of the most recent +valid header in the last sent segment to the current tip
      • +
      • Reorg detection: If no header from the last sent segment is still valid +(indicating a Bitcoin reorg), fall back to sending from the BSN's base +header to the current tip
      +

      This per-BSN approach provides better efficiency and reorg handling +compared to the previous global broadcast strategy.

      Broadcasting BTC Staking Events

      After broadcasting BTC headers, the EndBlocker calls BroadcastBTCStakingConsumerEvents to propagate BTC staking events to relevant @@ -429,21 +422,21 @@

      Handling Inbound IBC Packets

      Inbound IBC Packets

      The inbound packet structure is defined as follows. Currently, the Zone Concierge module handles one type of -incoming packet: ConsumerSlashingIBCPacket. This packet type allows BSNs to +incoming packet: BSNSlashingIBCPacket. This packet type allows BSNs to report slashing evidence for finality providers.

      // InboundPacket represents packets received by Babylon from other chains
       message InboundPacket {
         // packet is the actual message carried in the IBC packet
         oneof packet {
      -    ConsumerSlashingIBCPacket consumer_slashing = 1;
      +    BSNSlashingIBCPacket bsn_slashing = 1;
         }
       }
       
      -// ConsumerSlashingIBCPacket defines the slashing information that a Consumer sends to Babylon's ZoneConcierge upon a
      -// Consumer slashing event.
      -// It includes the FP public key, the Consumer block height at the slashing event, and the double sign evidence.
      -message ConsumerSlashingIBCPacket {
      -  /// evidence is the FP slashing evidence that the Consumer sends to Babylon
      +// BSNSlashingIBCPacket defines the slashing information that a BSN sends to Babylon's ZoneConcierge upon a
      +// BSN slashing event.
      +// It includes the FP public key, the BSN block height at the slashing event, and the double sign evidence.
      +message BSNSlashingIBCPacket {
      +  /// evidence is the FP slashing evidence that the BSN sends to Babylon
         babylon.finality.v1.Evidence evidence = 1;
       }
       
      @@ -500,7 +493,7 @@

      IBC Communication Protocol

      | Packet Direction | Types | |-----------------|-------| | Outbound | BTCHeaders, BTCTimestamp, BTCStakingConsumerEvent | -| Inbound | ConsumerSlashingIBCPacket |

      +| Inbound | BSNSlashingIBCPacket |

      Relaying BTC Headers

      Zone Concierge relays BTC headers from Babylon Genesis' BTC light client to BSNs in two scenarios:

      @@ -513,7 +506,8 @@

      Relaying BTC Headers

This ensures BSNs can keep their BTC light clients synchronized with Bitcoin's canonical chain. The headers are sent through IBC packets to all open channels -between Babylon and the BSNs.

+between Babylon and the BSNs, with enhanced per-consumer tracking for improved +efficiency and reorg handling.

Relaying BTC Timestamps

Zone Concierge sends BTC timestamps to BSNs when a Babylon epoch becomes BTC-finalised. The AfterRawCheckpointFinalized hook is triggered when an diff --git a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html b/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html index 25fbe6d3..00109bad 100644 --- a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html +++ b/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html @@ -499,7 +499,7 @@

Explanation of Fields

Specifying more than one finality provider constitutes multi-staking, i.e delegating across multiple BSNs. The system enforces the following constraints:

Stake Creation

-

Post-staking Registration

+

Single Step Delegation

A Bitcoin staker can receive voting power through their Bitcoin stake delegation by following this process:

    @@ -131,13 +131,13 @@

    Post-staking Registration

    for the slashing transactions and unbonding transaction. The BTC Delegation is now activated.
-

Pre-staking Registration

+

Expression of Interest Delegation (EOI)

The above mechanism requires the staker to first lock their funds and then request the Babylon blockchain to activate the stake. For stakers that want to avoid this and prefer to first receive confirmation -and then lock their funds on Bitcoin, the pre-staking registration +and then lock their funds on Bitcoin, the Expression of Interest (EOI) procedure can be used.

-

The pre-staking registration procedure works as follows:

+

The EOI procedure works as follows:

  1. The BTC staker constructs the following transactions (whose specifications can be found here) and sends them on Babylon @@ -189,9 +189,7 @@

    Parameters

    // PARAMETERS COVERING STAKING // 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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + repeated bytes covenant_pks = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.BIP340PubKey" ]; // covenant_quorum is the minimum number of signatures needed for the covenant // multisignature uint32 covenant_quorum = 2; @@ -199,15 +197,13 @@

    Parameters

    int64 min_staking_value_sat = 3; // max_staking_value_sat is the maximum of satoshis locked in staking output int64 max_staking_value_sat = 4; - // min_staking_time is the minimum lock time specified in staking output - // script + // min_staking_time is the minimum lock time specified in staking output script uint32 min_staking_time_blocks = 5; - // max_staking_time_blocks is the maximum lock time time specified in staking - // output script + // max_staking_time_blocks is the maximum lock time time specified in staking output script uint32 max_staking_time_blocks = 6; // PARAMETERS COVERING SLASHING - // slashing_pk_script is the pk_script expected in slashing output ie. the - // first output of slashing transaction + // slashing_pk_script is the pk_script expected in slashing output ie. the first + // output of slashing transaction bytes slashing_pk_script = 7; // min_slashing_tx_fee_sat is the minimum amount of tx fee (quantified // in Satoshi) needed for the pre-signed slashing tx. It covers both: @@ -217,34 +213,25 @@

    Parameters

    // expressed as a decimal (e.g., 0.5 for 50%). Maximal precion is 2 decimal // places string slashing_rate = 9 [ - (cosmos_proto.scalar) = "cosmos.Dec", - (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false + (cosmos_proto.scalar) = "cosmos.Dec", + (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", + (gogoproto.nullable) = false ]; // PARAMETERS COVERING UNBONDING - // unbonding_time is the exact unbonding time required from unbonding - // transaction it must be larger than `checkpoint_finalization_timeout` from - // `btccheckpoint` module + // unbonding_time_blocks is the required timelock on unbonding transaction in BTC blocks uint32 unbonding_time_blocks = 10; - // unbonding_fee exact fee required for unbonding transaction + // unbonding_fee_sat is the exact fee required for unbonding transaction int64 unbonding_fee_sat = 11; // PARAMETERS COVERING FINALITY PROVIDERS - // min_commission_rate is the chain-wide minimum commission rate that a - // finality provider can charge their delegators expressed as a decimal (e.g., - // 0.5 for 50%). Maximal precion is 2 decimal places + // min_commission_rate is the chain-wide minimum commission rate that a finality provider + // can charge their delegators expressed as a decimal (e.g., 0.5 for 50%). Maximal precion + // is 2 decimal places string min_commission_rate = 12 [ (gogoproto.customtype) = "cosmossdk.io/math.LegacyDec", - (gogoproto.nullable) = false + (gogoproto.nullable) = false ]; // base gas fee for delegation creation uint64 delegation_creation_base_gas_fee = 13; - // allow_list_expiration_height is the height at which the allow list expires - // i.e all staking transactions are allowed to enter Babylon chain afterwards - // setting it to 0 means allow list is disabled - uint64 allow_list_expiration_height = 14; - // btc_activation_height is the btc height from which parameters are activated - // (inclusive) - uint32 btc_activation_height = 15; }

    Finality providers

    @@ -256,42 +243,31 @@

    Finality providers

    finality provider.

    // 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 = 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/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;
    -  // 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
    -  uint32 slashed_btc_height = 7;
    -  // jailed defines whether the finality provider is jailed
    -  bool jailed = 8;
    -  // highest_voted_height is the highest height for which the
    -  // finality provider has voted
    -  uint32 highest_voted_height = 9;
    -  // consumer_id is the ID of the consumer the finality provider is operating
    -  // on. If it's missing / empty, it's assumed the finality provider is
    -  // operating in the Babylon chain.
    -  string consumer_id = 10;
    -  // commission_info contains information details of the finality provider commission.
    -  CommissionInfo commission_info = 11;
    +    // 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/babylonlabs-io/babylon/v4/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
    +    uint32 slashed_btc_height = 7;
    +    // jailed defines whether the finality provider is jailed
    +    bool jailed = 8;
     }
     

    BTC delegations

    @@ -309,14 +285,14 @@

    BTC delegations

    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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 - // multi-staked to multiple finality providers - repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; + // 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/babylonlabs-io/babylon/v4/types.BIP340PubKey" ]; // staking_time is the number of blocks for which the delegation is locked on BTC chain uint32 staking_time = 5; // start_height is the start BTC height of the BTC delegation @@ -339,7 +315,7 @@

    BTC delegations

    // 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 = 12 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes delegator_sig = 12 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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. @@ -379,7 +355,7 @@

    BTC delegations

    // 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 = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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. @@ -431,7 +407,7 @@

    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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.BIP340PubKey" ]; // pop is the proof of possession of btc_pk over the FP signer address. ProofOfPossessionBTC pop = 5; } @@ -510,10 +486,10 @@

    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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes btc_pk = 3 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + repeated bytes fp_btc_pk_list = 4 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 @@ -529,7 +505,7 @@

    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 = 10 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes delegator_slashing_sig = 10 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 @@ -547,7 +523,7 @@

    MsgCreateBTCDelegation

    // Note that the tx itself does not contain signatures, which are off-chain. bytes unbonding_slashing_tx = 14 [ (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/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes delegator_unbonding_slashing_sig = 15 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.BIP340Signature" ]; }

    Upon MsgCreateBTCDelegation, a Babylon node will execute as follows:

    @@ -591,10 +567,9 @@

    MsgCreateBTCDelegation

    Babylon.
  2. If the allow-list is enabled, ensure that the staking transaction is in the allow-list.
  3. -
  4. If the delegation contains an inclusion proof (optional due to the capability -for pre-staking registration), verify the inclusion proof and ensure that it is -BTCConfirmationDepth-deep in the Bitcoin blockchain, where -BTCConfirmationDepth is a module parameter specified in the BTC +
  5. If the delegation contains an inclusion proof (it is optional due to EOI), +verify the inclusion proof and ensure that it is BTCConfirmationDepth-deep in the Bitcoin +blockchain, where BTCConfirmationDepth is a module parameter specified in the BTC Checkpoint module.
  6. Create a BTCDelegation object and save it to the BTC delegation storage and the BTC delegation index storage.
  7. @@ -605,8 +580,8 @@

    MsgAddBTCDelegationInclusionProof

    Bitcoin blockchain. This message is utilised for notifying the Babylon blockchain that a staking transaction that was previously submitted through -the pre- staking registration process and is now on Bitcoin and has -received sufficient confirmations to become active.

    +the EOI process is now on Bitcoin and has received sufficient +confirmations to become active.

    // MsgAddBTCDelegationInclusionProof is the message for adding proof of inclusion of BTC delegation on BTC chain
     message MsgAddBTCDelegationInclusionProof {
       option (cosmos.msg.v1.signer) = "signer";
    @@ -641,7 +616,7 @@ 

    MsgAddCovenantSigs

    string signer = 1; // pk is the BTC public key of the covenant member - bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.BIP340PubKey" ]; // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 3; @@ -651,7 +626,7 @@

    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/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes unbonding_tx_sig = 5 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 @@ -687,15 +662,9 @@

    MsgBTCUndelegate

    // staking_tx_hash is the hash of the staking tx. // It uniquely identifies a BTC delegation string staking_tx_hash = 2; - // stake_spending_tx is a bitcoin transaction that spends the staking - // transaction i.e it has staking output as an input - bytes stake_spending_tx = 3; - // spend_spending_tx_inclusion_proof is the proof of inclusion of the - // stake_spending_tx in the BTC chain - InclusionProof stake_spending_tx_inclusion_proof = 4; - // funding_transactions is a list of bitcoin transactions that funds the stake_spending_tx - // i.e. they are inputs of the stake_spending_tx - repeated bytes funding_transactions = 5; + // 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/babylonlabs-io/babylon/v4/types.BIP340Signature" ]; }

    Upon BTCUndelegate, a Babylon node will execute as follows:

    diff --git a/static/remote-docs/guides/architecture/babylon_genesis_modules/checkpointing.html b/static/remote-docs/guides/architecture/babylon_genesis_modules/checkpointing.html index d98c5be8..03032cea 100644 --- a/static/remote-docs/guides/architecture/babylon_genesis_modules/checkpointing.html +++ b/static/remote-docs/guides/architecture/babylon_genesis_modules/checkpointing.html @@ -97,7 +97,7 @@

    Concepts

    the whole checkpoint data. After their inclusion, an off-chain program called the -Vigilante Reporter +Vigilante Reporter submits inclusion proofs to the BTC Checkpoint module, which is responsible for monitoring their confirmation status and @@ -126,7 +126,7 @@

    Checkpoint

    // sigs bytes bls_multi_sig = 4 [ (gogoproto.customtype) = - "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/v4/crypto/bls12381.Signature" ]; } // RawCheckpointWithMeta wraps the raw checkpoint with metadata. @@ -139,7 +139,7 @@

    Checkpoint

    // bls_aggr_pk defines the aggregated BLS public key bytes bls_aggr_pk = 3 [ (gogoproto.customtype) = - "github.com/babylonlabs-io/babylon/crypto/bls12381.PublicKey" ]; + "github.com/babylonlabs-io/babylon/v4/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 @@ -296,7 +296,7 @@

    ExtendVote

    // bls_sig is the BLS signature bytes bls_sig = 6 [ (gogoproto.customtype) = - "github.com/babylonlabs-io/babylon/crypto/bls12381.Signature" ]; + "github.com/babylonlabs-io/babylon/v4/crypto/bls12381.Signature" ]; }

    VerifyVoteExtension

    diff --git a/static/remote-docs/guides/architecture/babylon_genesis_modules/epoching.html b/static/remote-docs/guides/architecture/babylon_genesis_modules/epoching.html index bba7340c..dc18a62b 100644 --- a/static/remote-docs/guides/architecture/babylon_genesis_modules/epoching.html +++ b/static/remote-docs/guides/architecture/babylon_genesis_modules/epoching.html @@ -184,9 +184,7 @@

    Babylon's Epoching module design

    Delaying wrapped messages to the end of epochs. The Epoching module maintains a message queue for each epoch. Upon each wrapped message, the Epoching module performs basic sanity checks, then enqueues the message to the -message queue. When the epoch ends, the Epoching module will forward queued -messages to the Staking module. Consequently, the Staking module receives and -handles staking-related messages, and performs validator set updates.

    +message queue. Before a message is enqueued, the Epoching module locks the associated funds for the duration of the epoch. At epoch completion, it unlocks those funds to enable message execution, making the message eligible for forwarding. When the epoch ends, the Epoching module will forward queued messages to the Staking module. Consequently, the Staking module receives and handles staking-related messages, and performs validator set updates.

    Bitcoin-assisted Unbonding. Babylon implements the Bitcoin-assisted unbonding mechanism by invoking the Staking module upon a checkpointed epoch . Specifically, the Staking module's BlockValidatorUpdates @@ -210,7 +208,27 @@

    Parameters

    // epoch_interval is the number of consecutive blocks to form an epoch uint64 epoch_interval = 1 [ (gogoproto.moretags) = "yaml:\"epoch_interval\"" ]; + + // execute_gas defines raw gas for different executions. + ExecuteGas execute_gas = 2 + [ (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"execute_gas\"" ]; + + // minimum_amount is a minimum amount for staking message cancel_unbonding_delegation + uint64 min_amount = 3 + [ (gogoproto.moretags) = "yaml:\"min_amount\"" ]; } + +// ExecuteGas defines the raw gas for the enqueued message execution. + message ExecuteGas { + option (gogoproto.equal) = true; + + uint64 delegate = 1 [(gogoproto.moretags) = "yaml:\"delegate\""]; + uint64 undelegate = 2 [(gogoproto.moretags) = "yaml:\"undelegate\""]; + uint64 begin_redelegate = 3 [(gogoproto.moretags) = "yaml:\"begin_redelegate\""]; + uint64 cancel_unbonding_delegation = 4 [(gogoproto.moretags) = "yaml:\"cancel_unbonding_delegation\""]; + uint64 edit_validator = 5 [(gogoproto.moretags) = "yaml:\"edit_validator\""]; + uint64 create_validator = 6 [(gogoproto.moretags) = "yaml:\"create_validator\""]; + }

    Epochs

    The epoch storage maintains the metadata of each epoch. @@ -231,14 +249,17 @@

    Epochs

    // 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 = 5; + bytes sealer_app_hash = 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 - bytes sealer_block_hash = 6; + bytes sealer_block_hash = 7; }

    Epoch message queue

    @@ -263,7 +284,7 @@

    Epoch message queue

    // 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 + // Epoching module oneof msg { cosmos.staking.v1beta1.MsgCreateValidator msg_create_validator = 5; cosmos.staking.v1beta1.MsgDelegate msg_delegate = 6; @@ -414,6 +435,7 @@

    EndBlocker

    following if at the last block of the current epoch:

    1. Get all queued messages of this epoch in the epoch message queue storage.
    2. +
    3. Unescrow (unlock) the funds previously locked for these messages so they are available for staking-message execution.
    4. Forward each of the queued messages to the corresponding message handler in the Staking module.
    5. Emit events about the execution results of the messages.
    6. @@ -535,7 +557,7 @@

      Events

      Queries

      The Epoching module provides a set of queries about epochs, validators and delegations, listed at -docs.babylonlabs.io.

      +docs.babylonlabs.io.

      diff --git a/static/remote-docs/guides/architecture/babylon_genesis_modules/finality.html b/static/remote-docs/guides/architecture/babylon_genesis_modules/finality.html index a759a504..1c26136c 100644 --- a/static/remote-docs/guides/architecture/babylon_genesis_modules/finality.html +++ b/static/remote-docs/guides/architecture/babylon_genesis_modules/finality.html @@ -135,17 +135,14 @@

      Parameters

      // Params defines the parameters for the module.
       message Params {
         option (gogoproto.goproto_stringer) = false;
      -
      -  // max_active_finality_providers is the maximum number of active finality providers in the BTC staking protocol
      -  uint32 max_active_finality_providers = 1;
         // signed_blocks_window defines the size of the sliding window for tracking finality provider liveness
      -  int64 signed_blocks_window  = 2;
      +  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 = 3;
      +  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 jailed
      -  bytes min_signed_per_window = 4 [
      +  // 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",
           (gogoproto.nullable)   = false,
      @@ -153,14 +150,7 @@ 

      Parameters

      ]; // min_pub_rand is the minimum number of public randomness each // message should commit - uint64 min_pub_rand = 5; - // jail_duration is the minimum period of time that a finality provider remains jailed - google.protobuf.Duration jail_duration = 6 - [(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true]; - // finality_activation_height is the babylon block height which the finality module will - // start to accept finality voting and the minimum allowed value for the public randomness - // commit start height. - uint64 finality_activation_height = 7; + uint64 min_pub_rand = 4; }

      Voting power table

      @@ -235,11 +225,12 @@

      Equivocation evidences

      // 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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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/babylonlabs-io/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 @@ -248,10 +239,10 @@

      Equivocation evidences

      // 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/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; + bytes canonical_finality_sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; + bytes fork_finality_sig = 7 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.SchnorrEOTSSig" ]; }

      Signing info tracker

      @@ -284,7 +275,7 @@

      Signing info tracker

      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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 1 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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. @@ -315,7 +306,7 @@

      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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 @@ -326,7 +317,7 @@

      MsgCommitPubRandList

      // 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 - bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/types.BIP340Signature" ]; + bytes sig = 6 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.BIP340Signature" ]; }

      Upon MsgCommitPubRandList, a Babylon node will execute as follows:

      @@ -352,7 +343,7 @@

      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/babylonlabs-io/babylon/types.BIP340PubKey" ]; + bytes fp_btc_pk = 2 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/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 @@ -361,7 +352,7 @@

      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/babylonlabs-io/babylon/types.SchnorrEOTSSig" ]; + bytes finality_sig = 5 [ (gogoproto.customtype) = "github.com/babylonlabs-io/babylon/v4/types.SchnorrEOTSSig" ]; }

      Upon MsgAddFinalitySig, a Babylon node will execute as follows:

      diff --git a/static/remote-docs/guides/architecture/btc_staking_program/btc_reorg_procedure.html b/static/remote-docs/guides/architecture/btc_staking_program/btc_reorg_procedure.html index f4f0e2ac..565d1005 100644 --- a/static/remote-docs/guides/architecture/btc_staking_program/btc_reorg_procedure.html +++ b/static/remote-docs/guides/architecture/btc_staking_program/btc_reorg_procedure.html @@ -24,94 +24,87 @@

      Large BTC Reorgs Recovery Procedure

      -

      Babylon relies on a number of confirmation blocks on Bitcoin to accept BTC -staking transactions. This number is defined inside the x/btccheckpoint +

      Babylon relies in a number of confirmation blocks in BTC to accept BTC +staking transacitons, this number is defined inside the x/btccheckpoint Parameter as BtcConfirmationDepth and as k in the research papers -which we consider to be an irreversible block.

      -

      If for some unexpected reason there is a reorg in the Bitcoin blockchain +which we considerate to be an irreversible block.

      +

      If for some unexpected reason there is a reorg in the bitcoin blockchain larger than the BtcConfirmationDepth, the chain should halt and revoke all the BTC delegations that were recorded until the first reorg block height.

      -

      By example, if the Bitcoin chain is in block height 150 and Babylon chain has a -BtcConfirmationDepth of 10 and it is submitted a valid Bitcoin reorg of 15 blocks -that rollbacks Bitcoin to block height 136, every BTC delegation that was included -in Bitcoin block 136 or higher should be deleted as the inclusion proof will -be different. BTC delegations that are included in the Bitcoin block height 135 or lower -will not be affected as the Bitcoin rollbacks only happens if there is a better -chain presented. A better chain means a chain that has more blocks, so any BTC -delegation included in block 135 or prior would still be considered valid.

      +

      By example, if BTC is in block height 150 and Babylon chain has a +BtcConfirmationDepth of 10 and it is submitted a valid BTC reorg of 10 blocks +that rollbacks BTC to block height 140, every BTC delegation that was included +in BTC block 140 or higher should be deleted as the inclusion proof will +be different. BTC delegations included before BTC block height 140 will not +be affected as the BTC rollbacks only happens if there is a better chain +presented, a better chain means chain with more blocks, so any BTC delegation +included in block 139 or prior would still be considered valid.

      This recovery procedure only cares about the BTC transactions that were executed in blocks which have been rollbacked.

      Chain Halt

      -

      If the chain is halted due to a Bitcoin chain reorg larger than BtcConfirmationDepth, -there are a few steps to be followed to gather the data to be modified by the +

      If the chain halted due to a BTC reorg largest than BtcConfirmationDepth, +there is a few steps to be followed to gather the data to be modified at the emergency upgrade handler:

      -

      1. Collect Corresponding Babylon Height

      -

      The correlation of Bitcoin and Babylon block heights can be found in the x/btcstaking +

      1. Collect correspondent Babylon height

      +

      The correlation of BTC and Babylon block heights can be found in the x/btcstaking state in the BlockHeightChains, currently there is no query for it, but it can be retrieved by exporting the genesis state.

      -

      2. Collect Bitcoin Related Messages that were Rollbacked

      -

      After having collected the Babylon block height corresponding to the Bitcoin block +

      2. Collect BTC related msgs that were rollbacked

      +

      After having collected the babylon block height corresponded to the BTC block height which the rollback happened, iterate over every transaction until -the halt block, then gather all the messages which were approved and are of one of -the types: MsgCreateBTCDelegation, MsgAddBTCDelegationInclusionProof, -MsgBTCUndelegate, MsgInsertHeaders and MsgInsertBTCSpvProof.

      -

      3. Analyze Each Message

      -

      Each Bitcoin related message that was rollbacked might need to have a different treatment.

      +the halt block and gather all the messages which were approved and are one of +the types: MsgCreateBTCDelegation, MsgAddBTCDelegationInclusionProof and +MsgBTCUndelegate.

      +

      3. Analyze each message

      +

      Each BTC related msg that was rollbacked might need to have a different treatment.

      3.1 MsgCreateBTCDelegation

      -

      The message which creates a new Bitcoin delegation, if it doesn't have inclusion proof -can stay as it was not active, and neither had the inclusion -proof been sent.

      -

      If there was an inclusion proof, verify if the proof is from one of the Bitcoin block -heights which was rollbacked. If it is from a Bitcoin block that was not reorg, -but it was only later included in the Babylon chain, this is good and there is -nothing to do. Now if it was rollbacked, this BTC staking transaction needs to -be removed from the following modules states x/btcstaking, x/finality, +

      The msg which creates a new BTC delegation, if doesn't have inclusion proof +can stay as it is was not active or anything and neither had the inclusion +proof sent.

      +

      If there was a inclusion proof, verify if the proof is one from the BTC block +heights which was rollbacked, if it is from an BTC block that was not reorg, +but it was only later included in the Babylon chain, all good and there is +nothing to do. Now, if it was rollbacked this BTC staking transaction needs to +be removed from the following modules state x/btcstaking, x/finality, x/incentives.

      • x/btcstaking
        • Remove from BTCDelegatorKey -the BTC staking transaction hash.
        • +the BTC staking tx hash.
        • Remove from BTCDelegationKey -the BTC staking transaction hash.
        • +the BTC staking tx hash.
        • Remove the PowerDistUpdateKey if a EventPowerDistUpdate_BtcDelStateUpdate was emitted for that -BTC staking transaction hash.
        • +BTC staking tx hash.
      • x/finality
        • Update the voting power amount in VotingPowerKey -by subtracting the satoshi amounts of the Finality Provider that the BTC +by subtracting the satoshi amounts of the finality provider that the BTC delegation delegated to if that BTC delegation was active.
        • Subtract the TotalVotingPower and the respective FinalityProviderDistInfo -based on which Finality Provider was delegated to in +based on which finality provider was delegated to in VotingPowerDistCacheKey if that BTC delegation was active.
      • x/incentives If that BTC delegation was ever active, there is a need to -subtract the voting power from the rewards tracker. Also it only modifies -the values from now on. If rewards were accrued from a BTC staking transaction -that was rollbacked, the past is behind us, and it should be left with the funds -that were accrued, losing a few coins in the rewards. +subtract the voting power from the rewards tracker. Also it is only modified +the values from now on, if rewards were accured from a BTC staking transaction +that was rollbacked, the past is behind us and it should be let with the funds +that were accured, losing a few coins in the rewards.
        • For the incentives module state there is a single function which should be called BtcDelegationUnbonded -which receives as parameter the Finality Provider and BTC delegator Babylon -address and the amount of satoshis from the rollbacked BTC delegation. +which receives as parameter the Finality provider and BTC delegator baby +address and the amount of satoshi from the rollbacked BTC delegation. This will already update all the keys in the state accordingly.
      -
      -

      Note transactions that were included during blocks 150 ~ 141 (150 - BtcConfirmationDepth) -in a 15 Bitcoin blocks rollback are invalid and should be removed but were -also not considered deep enough to be active. Dropping those proofs and -the event updates to voting power table is enough to handle during the -recovery procedure.

      -

      3.2 MsgAddBTCDelegationInclusionProof

      Check if the proof is one from the BTC block heights which was rollbacked, if it is not, there is no need to do anything. If it was rollbacked @@ -119,25 +112,27 @@

      3.2 MsgAddBTCDelegationInclusionProof

      to remove the data from the 3 modules states.

      3.3 MsgBTCUndelegate

      Check if the inclusion proof had a reorg in the BTC blocks, if it is not -rollbacked, there is nothing to do. If it was rollbacked, remove the existence of this BTC undelegation and the affecting 3 modules states with similar steps taken at 3.1.

      +rollbacked, there is nothing to do. If it was rollbacked it is needed +to remove the existence of this BTC undelegation and affecting 3 modules state +with similar steps took at 3.1.

      • x/btcstaking
        • Clean out the field for BtcUndelegation in BTCDelegation for the key BTCDelegationKey -in which corresponds to the BTC staking transaction hash.
        • +in which corresponds to the BTC staking tx hash.
        • Remove the PowerDistUpdateKey if a EventPowerDistUpdate_BtcDelStateUpdate was emitted for that -BTC staking transaction hash with Undelegate.
        • +BTC staking tx hash with Undelegate.
      • x/finality
        • Update the voting power amount in VotingPowerKey -by adding the satoshi amounts of the Finality Provider that the BTC +by adding the satoshi amounts of the finality provider that the BTC delegation delegated to.
        • Add the TotalVotingPower and the respective FinalityProviderDistInfo -based on which Finality Provider was delegated to in +based on which finality provider was delegated to in VotingPowerDistCacheKey.
      • @@ -145,38 +140,20 @@

        3.3 MsgBTCUndelegate

        • For the incentives module state there is a single function which should be called BtcDelegationActivated -which receives as parameter the Finality Provider and BTC delegator Babylon -address and the amount of satoshis from the rollbacked BTC undelegate. +which receives as parameter the Finality provider and BTC delegator baby +address and the amount of satoshi from the rollbacked BTC undelegate. This will already update all the keys in the state accordingly.
      -

      3.4 MsgInsertHeaders

      -

      The module x/btclightclient automatically handles the rollback of blocks, the issue -relies when the Babylon chain was halted while Bitcoin was producing new blocks, the -new blocks should have it's headers collected and included into the Babylon chain -state when it is being recovered. If the headers are not inserted, an attacker -could mine just 1-2 blocks on the forked Bitcoin chain and cause Babylon chain -to execute fake delegations, right after Babylon chain restarts. To avoid this, -Babylon should insert headers of the created Bitcoin blocks while it was -down during the recovery procedure.

      -

      3.5 MsgInsertBTCSpvProof

      -

      All the proofs that were sent by the Vigilante Reporter in the Bitcoin blocks -that were affected by the rollback, will need to be revoked and might modify -the status of checkpoints. The recovery procedure for this specific case -might also need to modify the Vigilante to send again transactions of -checkpoints to the main chain of Bitcoin. This inserted proofs will -then need to be included into the Babylon state and checkpoint status updated -accordingly to the chain configuration of BtcConfirmationDepth and -CheckpointFinalizationTimeout in the x/btccheckpoint module.

      4. Overall updates

      Beside the specific cases of the messages sent, there is also the need -to update some states about the new heights as in:

      +to update some state about the new heights as in:

      • x/btcstaking
        • Update BTCHeightKey -the Babylon height corresponding to the BTC block height
        • +the babylon height corresponded to the BTC block height
        • Remove the LargestBtcReorgInBlocks value previous set, to avoid halting again from the same BTC reorg.
        @@ -184,15 +161,18 @@

        4. Overall updates

      Create the emergency upgrade handler

      The emergency upgrade handler is called a -Fork in the structures as the chain is halted and there is no possibility to create a software upgrade proposal -that nicely handles the upgrade plan. So, the fork structure +Fork in the structures as the chain is halted +and there is no possibility to create a software upgrade proposal +that handles nicely the upgrade plan. So, the fork structure would contain as the name something that correlates with the BTC block heights which were reorg, the upgrade height would be defined as the Babylon block height in which the panic for reorg happened and the BeginForkLogic should contain a single function that modifies the keepers with the data collected during step 3.

      After that, tag a new release with the emergency upgrade in it, following -the Release Procedure. Test the logic in a private environment and if all the state is modified as expected, announce the new binary for Validators.

      +the Release Procedure +test the logic in a private enviroment and if it all the state is modified +as expected, announce the new binary for validators.

      diff --git a/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html b/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html index 7985a1e8..ded9f342 100644 --- a/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html +++ b/static/remote-docs/guides/architecture/btc_staking_program/finality_providers.html @@ -35,7 +35,7 @@

      Finality Provider

      A Babylon Genesis network node that provides chain data and transaction submission capabilities. While not mandatory, running your own node is strongly recommended for security rather than relying on third-party RPC nodes. -See the Setup Node Guide +See the Setup Node Guide for details.
    7. Extractable One-Time Signature (EOTS) Manager: A secure key management daemon that handles EOTS key operations, @@ -69,7 +69,7 @@

      EOTS Manager

      Note: EOTS stands for Extractable One Time Signature. You can read more about it in -the Babylon BTC Staking Litepaper. +the Babylon BTC Staking Litepaper. In short, the EOTS manager generates EOTS public/private randomness pairs. The finality provider commits the public part of these pairs to Babylon Genesis for every future block height that they intend to provide a finality signature for. If the finality diff --git a/static/remote-docs/guides/architecture/consumer_zone_programs/babylon_contracts.html b/static/remote-docs/guides/architecture/consumer_zone_programs/babylon_contracts.html index 2154820e..69522500 100644 --- a/static/remote-docs/guides/architecture/consumer_zone_programs/babylon_contracts.html +++ b/static/remote-docs/guides/architecture/consumer_zone_programs/babylon_contracts.html @@ -24,15 +24,16 @@

      Cosmos BSN Contracts

      -

      This repository contains the CosmWasm smart contracts that enable -the integration of Cosmos BSNs with the Babylon BTC Staking protocol.

      +

      This repository contains the CosmWasm smart contracts that enable the +integration of Cosmos BSNs with the Babylon BTC Staking protocol.

      Architecture

      The contracts are written in Rust, and use the CosmWasm framework to interact -with the BSN's Cosmos application layer. -There's a thin layer which adds a babylon module -, which provides the necessary functionality to interact with the contracts -through privileged calls (sudo messages) and custom messages. -This thin layer is naturally written in Go, and uses the Cosmos SDK.

      +with the BSN's Cosmos application layer. There's a thin layer which adds a +babylon +module , +which provides the necessary functionality to interact with the contracts +through privileged calls (sudo messages) and custom messages. This thin layer +is naturally written in Go, and uses the Cosmos SDK.

      An integrator can import the babylon module into their Cosmos SDK-based chain, and use the provided functionality to interact with the Cosmos BSN contracts, following the demo app's guidelines and layout, which is provided in @@ -41,6 +42,11 @@

      Architecture

      integration and future upgrades.

      A broad architecture diagram, along with the contracts' main interfaces, can be found in the docs/ARCHITECTURE.md documentation.

      +

      Contract Migration

      +

      All contracts support CosmWasm's built-in migration mechanism for upgrading +contract logic while preserving state. For detailed migration procedures, +troubleshooting, and best practices, see the MIGRATION.md +guide.

      Development

      Prerequisites

      Make sure you have cargo-run-script installed and docker running.

      @@ -70,8 +76,8 @@

      Integration tests the contract

      Note: Requires the optimized contract to be built (cargo optimize)

      cargo test --test integration
       
      -

      Alternatively, you can run the following command, that makes sure to build the optimized contract before running -the integration tests.

      +

      Alternatively, you can run the following command, that makes sure to build the +optimized contract before running the integration tests.

      cargo run-script integration
       

      E2E tests

      diff --git a/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html b/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html deleted file mode 100644 index 6a5b09c9..00000000 --- a/static/remote-docs/guides/architecture/consumer_zone_programs/zone_concierge.html +++ /dev/null @@ -1,539 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      ZoneConcierge

      -

      The Zone Concierge module is responsible for providing BTC staking integration -functionalities for Bitcoin Supercharged Networks (BSNs) connecting
      -to Babylon Genesis through IBC. It leverages the IBC protocol to receive BSNs' -headers, and propagate BTC timestamps of those headers and information -associated with the BTC staking protocol (e.g., finality providers, BTC stakes, -and more).
      -The Zone Concierge module synchronises the following information with BSNs (aka -consumers) via IBC packets:

      -
        -
      • BTC Headers: Babylon Genesis forwards the BTC headers maintained by its -BTC light client to BSNs.
        -This allows BSNs to maintain an image of the Bitcoin chain and verify -information included in it through inclusion proofs (e.g., an inclusion -proof of a BTC Timestamp containing BSN headers).
      • -
      • BTC Timestamps: When a Babylon Genesis epoch is finalized, the Babylon -Genesis chain sends BTC timestamps to BSNs. Each BTC timestamp contains: -
          -
        • The latest BSN header that was checkpointed in the finalised epoch
        • -
        • Recent BTC headers that extend the BSN's BTC light client
        • -
        • The finalised epoch's metadata and raw checkpoint
        • -
        • Proofs that a BSN header was included in an epoch and the epoch was -timestamped on the Bitcoin chain.
        • -
        -
      • -
      • BTC Staking: Babylon Genesis enables trustless Bitcoin staking for BSNs by -synchronising staking-related information between Bitcoin, Babylon Genesis and -BSNs. This allows BTC holders to stake their BTC to secure BSNs without -requiring any custodial solutions.
      • -
      -

      Table of contents

      - -

      State

      -

      The Zone Concierge module maintains a simplified header indexing system with the following KV stores. Consumer registration is handled by the btcstkconsumer module.

      -

      Parameters

      -

      The parameter storage maintains the Zone Concierge -module's parameters. The Zone Concierge module's parameters are represented as a -Params object defined as -follows:

      -
      // Params defines the parameters for the module.
      -message Params {
      -  option (gogoproto.equal) = true;
      -  
      -  // ibc_packet_timeout_seconds is the time period after which an unrelayed 
      -  // IBC packet becomes timeout, measured in seconds
      -  uint32 ibc_packet_timeout_seconds = 1
      -      [ (gogoproto.moretags) = "yaml:\"ibc_packet_timeout_seconds\"" ];
      -}
      -
      -

      LatestEpochHeaders

      -

      The latest epoch headers storage maintains -the most recent header received from each BSN during the current epoch. The -key is the BSN's ConsumerID, and the value is an IndexedHeader object. -This storage is cleared at the end of each epoch when headers are moved to the -finalized storage.

      -

      FinalizedEpochHeaders

      -

      The finalized epoch headers storage -maintains headers that have been finalized for each BSN and epoch. The key -is the epoch number plus the BSN's ConsumerID, and the value is an -IndexedHeaderWithProof object. The IndexedHeaderWithProof contains both the -header metadata and the inclusion proof.

      -
      // IndexedHeader is the metadata of a BSN header
      -message IndexedHeader {
      -  // consumer_id is the unique ID of the BSN
      -  string consumer_id = 1;
      -  // hash is the hash of this header
      -  bytes hash = 2;
      -  // height is the height of this header on the BSN's ledger.
      -  // (hash, height) jointly provide the position of the header on the BSN ledger
      -  uint64 height = 3;
      -  // time is the timestamp of this header on the BSN's ledger.
      -  // It is needed for a BSN to unbond all mature validators/delegations before
      -  // this timestamp, when this header is BTC-finalised
      -  google.protobuf.Timestamp time = 4 [ (gogoproto.stdtime) = true ];
      -  // babylon_header_hash is the hash of the babylon block that includes this BSN
      -  // header
      -  bytes babylon_header_hash = 5;
      -  // babylon_header_height is the height of the babylon block that includes this
      -  // BSN header
      -  uint64 babylon_header_height = 6;
      -  // epoch is the epoch number of this header on Babylon ledger
      -  uint64 babylon_epoch = 7;
      -  // babylon_tx_hash is the hash of the tx that includes this header
      -  // (babylon_block_height, babylon_tx_hash) jointly provides the position of
      -  // the header on Babylon ledger
      -  bytes babylon_tx_hash = 8;
      -}
      -
      -// IndexedHeaderWithProof is an indexed header with a proof that the header is
      -// included in the epoch
      -message IndexedHeaderWithProof {
      -  IndexedHeader header = 1;
      -  // proof is an inclusion proof that the header
      -  // is committed to the `app_hash` of the sealer header of header.babylon_epoch
      -  tendermint.crypto.ProofOps proof = 2;
      -}
      -
      -

      BSNBTCState

      -

      The BSN BTC state storage maintains -unified BTC synchronization state for each BSN. The key is the BSN's -ConsumerID, and the value is a BSNBTCState object that tracks the base -BTC header and last sent BTC header segment for each BSN.

      -
      // BSNBTCState stores per-BSN BTC synchronization state
      -// This includes both the base header and the last sent segment
      -message BSNBTCState {
      -  // base_header is the base BTC header for this BSN
      -  // This represents the starting point from which BTC headers are synchronized
      -  babylon.btclightclient.v1.BTCHeaderInfo base_header = 1;
      -  // last_sent_segment is the last segment of BTC headers sent to this BSN
      -  // This is used to determine the next headers to send and handle reorgs
      -  BTCChainSegment last_sent_segment = 2;
      -}
      -
      -

      Params

      -

      The parameter storage maintains the parameters for the -Zone Concierge module.

      -
      // Params defines the parameters for the module.
      -message Params {
      -  option (gogoproto.equal) = true;
      -  
      -  // ibc_packet_timeout_seconds is the time period after which an unrelayed 
      -  // IBC packet becomes timeout, measured in seconds
      -  uint32 ibc_packet_timeout_seconds = 1
      -      [ (gogoproto.moretags) = "yaml:\"ibc_packet_timeout_seconds\"" ];
      -}
      -
      -

      Port

      -

      The port storage maintains the port ID for the Zone -Concierge module. The key is PortKey and the value is the port ID string.

      -

      LastSentBTCSegment

      -

      The last sent BTC segment storage maintains information -about the last BTC chain segment that was broadcast to other light clients. The -key is LastSentBTCSegmentKey and the value is a BTCChainSegment object, -defined as follows.

      -
      // Btc light client chain segment grown during last finalized epoch
      -message BTCChainSegment {
      -  repeated babylon.btclightclient.v1.BTCHeaderInfo btc_headers = 1;
      -}
      -
      -

      SealedEpochProof

      -

      The sealed epoch proof storage maintains proofs that -epochs were properly sealed. The key is SealedEpochProofKey plus the epoch -number, and the value is a ProofEpochSealed object.

      -

      PostHandler for intercepting IBC headers

      -

      The Zone Concierge module implements a -PostHandler -IBCHeaderDecorator to intercept headers sent to the IBC client -module. -The IBCHeaderDecorator PostHandler is defined at -x/zoneconcierge/keeper/ibc_header_decorator.go.

      -

      For each IBC client update message in the transaction, the PostHandler -executes as follows:

      -
        -
      1. Extract the header info and the client state from the message
      2. -
      3. Determine if the header is on a fork by checking if the client is frozen
      4. -
      5. Call HandleHeaderWithValidCommit to process the header
      6. -
      7. Check if the BSN is registered through the btcstkconsumer module and is a Cosmos BSN; if not, ignore the header
      8. -
      9. Create an IndexedHeader with the header metadata and Babylon context
      10. -
      11. If the header is not on a fork and is newer than the existing latest header, -update the latest epoch header for the BSN
      12. -
      13. Log fork events for monitoring and debugging purposes
      14. -
      -

      Hooks

      -

      The Zone Concierge module subscribes to the Epoching module's AfterEpochEnds -hook for recording epoch headers, the -Checkpointing module's AfterRawCheckpointSealed -hook for recording epoch header proofs, and -the Checkpointing module's AfterRawCheckpointFinalized -hook for sending BTC timestamps to BSNs.

      -

      Indexing headers upon AfterEpochEnds

      -

      The AfterEpochEnds hook is triggered when an epoch is ended, i.e., the last -block in this epoch has been committed by CometBFT. Upon AfterEpochEnds, the -Zone Concierge will:

      -
        -
      1. Record all current latest epoch headers as finalized headers for the completed epoch
      2. -
      3. Clear the latest epoch headers to prepare for the next epoch
      4. -
      -

      Recording proofs upon AfterRawCheckpointSealed

      -

      The AfterRawCheckpointSealed hook is triggered when an epoch's raw checkpoint -is sealed by validator signatures. Upon AfterRawCheckpointSealed, the Zone -Concierge will:

      -
        -
      1. Generate inclusion proofs for all finalized headers in the sealed epoch
      2. -
      3. Generate and store the proof that the epoch is sealed
      4. -
      -

      Sending BTC timestamps upon AfterRawCheckpointFinalized

      -

      The AfterRawCheckpointFinalized hook is triggered upon a checkpoint becoming -finalised, i.e., Bitcoin transactions of the checkpoint become w-deep in -Bitcoin's canonical chain, where w is the checkpoint_finalization_timeout -parameter in the -BTCCheckpoint module.

      -

      The BTCTimestamp structure
      -includes a header and a set of proofs that the header is checkpointed by -Bitcoin.

      -
      // BTCTimestamp is a BTC timestamp that carries information of a BTC-finalized epoch
      -// It includes a number of BTC headers, a raw checkpoint, an epoch metadata, and 
      -// a BSN header if there exists BSN headers checkpointed to this epoch.
      -// Upon a newly finalized epoch in Babylon, Babylon will send a BTC timestamp to each
      -// BSN via IBC.
      -message BTCTimestamp {
      -  // header is the last BSN header in the finalized Babylon epoch
      -  babylon.zoneconcierge.v1.IndexedHeader header = 1;
      -
      -  /*
      -    Data for BTC light client
      -  */
      -  // btc_headers is BTC headers between
      -  // - the block AFTER the common ancestor of BTC tip at epoch `lastFinalizedEpoch-1` and BTC tip at epoch `lastFinalizedEpoch`
      -  // - BTC tip at epoch `lastFinalizedEpoch`
      -  // where `lastFinalizedEpoch` is the last finalized epoch in Babylon
      -  repeated babylon.btclightclient.v1.BTCHeaderInfo btc_headers = 2;
      -
      -  /*
      -    Data for Babylon epoch chain
      -  */
      -  // epoch_info is the metadata of the sealed epoch
      -  babylon.epoching.v1.Epoch epoch_info = 3;
      -  // raw_checkpoint is the raw checkpoint that seals this epoch
      -  babylon.checkpointing.v1.RawCheckpoint raw_checkpoint = 4;
      -  // btc_submission_key is position of two BTC txs that include the raw checkpoint of this epoch
      -  babylon.btccheckpoint.v1.SubmissionKey btc_submission_key = 5;
      -
      -  /* 
      -    Proofs that the header is finalized
      -  */
      -  babylon.zoneconcierge.v1.ProofFinalizedHeader proof = 6;
      -}
      -
      -// ProofFinalizedHeader is a set of proofs that attest a header is
      -// BTC-finalized
      -message ProofFinalizedHeader {
      -  /*
      -    The following fields include proofs that attest the header is
      -    BTC-finalized
      -  */
      -  // proof_epoch_sealed is the proof that the epoch is sealed
      -  babylon.zoneconcierge.v1.ProofEpochSealed proof_epoch_sealed = 1;
      -  // proof_epoch_submitted is the proof that the epoch's checkpoint is included
      -  // in BTC ledger It is the two TransactionInfo in the best (i.e., earliest)
      -  // checkpoint submission
      -  repeated babylon.btccheckpoint.v1.TransactionInfo proof_epoch_submitted = 2;
      -  // proof_consumer_header_in_epoch is the proof that the BSN header is included in the epoch
      -  tendermint.crypto.ProofOps proof_consumer_header_in_epoch = 3;
      -}
      -
      -

      When AfterRawCheckpointFinalized is triggered, the Zone Concierge module will -send an IBC packet including a BTCTimestamp to each BSN. The logic is defined -at x/zoneconcierge/keeper/hooks.go and works as follows:

      -
        -
      1. -

        Determine BTC headers to broadcast: Get all BTC headers to be sent in BTC -timestamps using the global broadcast strategy (fallback to the last w+1 -BTC headers from the current tip for compatibility)

        -
      2. -
      3. -

        Broadcast BTC timestamps to all open channels: For each open IBC channel -with Babylon Genesis' Zone Concierge module:

        -
          -
        • Find the ConsumerID of the counterparty chain (i.e., the PoS system) in -the IBC channel
        • -
        • Get the finalized header for the ConsumerID at the last finalised epoch
        • -
        • Get the metadata of the last finalised epoch and its corresponding raw -checkpoint
        • -
        • Generate the proof that the last PoS system's canonical header is committed -to the epoch's metadata (if applicable)
        • -
        • Generate the proof that the epoch is sealed, i.e., receives a BLS -multisignature generated by validators with >2/3 total voting power at the -last finalised epoch
        • -
        • Generate the proof that the epoch's checkpoint is submitted, i.e., encoded -in transactions on Bitcoin
        • -
        • Assemble all the above and the BTC headers obtained in step 1 as -BTCTimestamp, and send it to the IBC channel in an IBC packet
        • -
        -
      4. -
      5. -

        Update last sent segment: If headers were broadcast, update the last sent -BTC segment for future reference

        -
      6. -
      -

      EndBlocker

      -

      The Zone Concierge module implements an EndBlocker function that is executed -at the end of every block. The EndBlocker is defined at -x/zoneconcierge/abci.go, and broadcasts BTC headers and BTC staking -related events.

      -

      Broadcasting BTC Headers

      -

      The EndBlocker calls BroadcastBTCHeaders to send BTC headers to all open IBC -channels with BSNs. This ensures that BSNs' BTC light clients stay synchronized -with Babylon Genesis' BTC light client.

      -

      The header selection logic now uses per-BSN BTC state tracking with the -following enhanced rules:

      -
        -
      • BSN-specific BTC state: Each BSN has its own BSNBTCState -that tracks the base BTC header and last sent segment
      • -
      • No BSN base header: Falls back to sending the last w+1 BTC headers -from the tip (where w is the confirmation depth parameter)
      • -
      • BSN base header exists but no headers sent: Send headers from the -BSN's base header to the current tip
      • -
      • Headers previously sent: Send headers from the child of the most recent -valid header in the last sent segment to the current tip
      • -
      • Reorg detection: If no header from the last sent segment is still valid -(indicating a Bitcoin reorg), fall back to sending from the BSN's base -header to the current tip
      • -
      -

      This per-BSN approach provides better efficiency and reorg handling -compared to the previous global broadcast strategy.

      -

      Broadcasting BTC Staking Events

      -

      After broadcasting BTC headers, the EndBlocker calls -BroadcastBTCStakingConsumerEvents to propagate BTC staking events to relevant -BSNs. This function handles the distribution of BTC staking-related events that -need to be communicated to BSNs. The process works as follows:

      -
        -
      1. -

        Getting events: Gets all pending events from x/btcstaking module's -store

        -
      2. -
      3. -

        Channel Mapping: For each BSN that has events:

        -
      4. -
      -
        -
      • Retrieves all open IBC channels connected to that BSN's port
      • -
      • Maps the consumer ID (a BSN's identifier) to its corresponding active -channels
      • -
      -
        -
      1. -

        Event Distribution:

        -
          -
        • Groups events by consumer ID
        • -
        • For each BSN: -
            -
          • Assembles its relevant events into an IBC packet
          • -
          • Sends the packet to the IBC channel with that BSN
          • -
          -
        • -
        -
      2. -
      3. -

        Cleanup and State Management:

        -
          -
        • After successful transmission, removes sent events from the pending queue
        • -
        • Updates relevant indices and counters
        • -
        -
      4. -
      -

      This process ensures that all BTC staking events are reliably propagated to the -corresponding BSNs, maintaining consistency across the network and enabling -proper operation of the BTC staking system.

      -

      Handling Inbound IBC Packets

      -

      The Zone Concierge module implements the OnRecvPacket function to handle -incoming IBC packets from BSNs. The packet handling is defined at -x/zoneconcierge/module_ibc.go and processes different types -of inbound packets.

      -

      Inbound IBC Packets

      -

      The inbound packet structure is -defined as follows. Currently, the Zone Concierge module handles one type of -incoming packet: BSNSlashingIBCPacket. This packet type allows BSNs to -report slashing evidence for finality providers.

      -
      // InboundPacket represents packets received by Babylon from other chains
      -message InboundPacket {
      -  // packet is the actual message carried in the IBC packet
      -  oneof packet {
      -    BSNSlashingIBCPacket bsn_slashing = 1;
      -  }
      -}
      -
      -// BSNSlashingIBCPacket defines the slashing information that a BSN sends to Babylon's ZoneConcierge upon a
      -// BSN slashing event.
      -// It includes the FP public key, the BSN block height at the slashing event, and the double sign evidence.
      -message BSNSlashingIBCPacket {
      -  /// evidence is the FP slashing evidence that the BSN sends to Babylon
      -  babylon.finality.v1.Evidence evidence = 1;
      -}
      -
      -

      Processing Inbound IBC Packets

      -

      The HandleConsumerSlashing function (called upon -OnRecvPacket) processes slashing reports -received from BSNs through IBC packets, with the following workflow:

      -
        -
      1. Verifying Evidence: -
          -
        • Validates that slashing evidence is present and well-formed
        • -
        • Extracts the BTC secret key from the evidence
        • -
        • Verifies that the finality provider's BTC public key matches the evidence
        • -
        -
      2. -
      3. Slashing Execution: -
          -
        • Updates the BSN finality provider's slashed status
        • -
        • Sends power distribution update events to adjust the Babylon Genesis -finality provider's voting power (necessary because all BTC stakes must -delegate to a Babylon Genesis finality provider, so slashing affects their -voting power)
        • -
        • Identifies all BTC delegations associated with the slashed finality -provider
        • -
        • Identifies all affected BSNs, where "affected" means there exists a slashed -BTC delegation that multi-stakes to a finality provider in this BSN
        • -
        • Creates slashed BTC delegation events for each affected BSN
        • -
        • Propagates the slashing event to each BSN such that the BSN will update the -status of affected BTC delegations and update the voting power of affected -BSN finality providers. (Note: The propagation timing depends on the IBC -relayer's operation schedule and is not under direct control of this -module)
        • -
        -
      4. -
      5. Event Emission: Emits a EventSlashedFinalityProvider event for external -slashing mechanisms (e.g., BTC slasher/vigilante)
      6. -
      -

      Messages and Queries

      -

      The Zone Concierge module only has one message MsgUpdateParams for updating -the module parameters via a governance proposal.

      -

      It provides a set of queries about the status of checkpointed PoS systems, -listed at -docs.babylonlabs.io.

      -

      BSN Integration

      -

      The Zone Concierge module connects Babylon Genesis and BSNs, relaying three -types of information through IBC: BTC headers, BTC timestamps, and BTC staking -events.

      -

      IBC Communication Protocol

      -

      | Configuration Type | Value | -|-------------------|--------| -| Port | zoneconcierge | -| Ordering | ORDERED | -| Version | zoneconcierge-1 |

      -

      | Packet Direction | Types | -|-----------------|-------| -| Outbound | BTCHeaders, BTCTimestamp, BTCStakingConsumerEvent | -| Inbound | BSNSlashingIBCPacket |

      -

      Relaying BTC Headers

      -

      Zone Concierge relays BTC headers from Babylon Genesis' BTC light client to BSNs -in two scenarios:

      -
        -
      1. When a new BTC timestamp is being sent (triggered by -AfterRawCheckpointFinalized, see Sending BTC -Timestamps)
      2. -
      3. Periodically via the BroadcastBTCHeaders function which is called upon -EndBlock
      4. -
      -

      This ensures BSNs can keep their BTC light clients synchronized with Bitcoin's -canonical chain. The headers are sent through IBC packets to all open channels -between Babylon and the BSNs, with enhanced per-consumer tracking for improved -efficiency and reorg handling.

      -

      Relaying BTC Timestamps

      -

      Zone Concierge sends BTC timestamps to BSNs when a Babylon epoch becomes -BTC-finalised. The AfterRawCheckpointFinalized hook is triggered when an -epoch's checkpoint becomes w-deep in Bitcoin's canonical chain, which then -broadcasts BTCTimestamp packets to all open IBC channels.

      -

      Each BTCTimestamp includes:

      -
        -
      • BTC headers to keep BSN light clients synchronised
      • -
      • Epoch metadata and raw checkpoint
      • -
      • Proofs that the epoch is finalized
      • -
      -

      The Hooks section -provides details of assembling and broadcasting BTC timestamps.

      -

      Relaying BTC Staking Events

      -

      Zone Concierge relays BTC staking events between Babylon Genesis and BSNs to -enable trustless BTC staking. The module handles:

      -
        -
      • Broadcasting staking events to BSNs via BroadcastBTCStakingConsumerEvents -during EndBlock
      • -
      • Validating BSN registration during IBC channel creation
      • -
      • Processing slashing reports from BSNs
      • -
      -

      See EndBlocker section for details on the event broadcasting -process.

      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/mainnet/covonent_committee/covonent_committee.html b/static/remote-docs/guides/networks/phase-1/mainnet/covonent_committee/covonent_committee.html deleted file mode 100644 index 27b59195..00000000 --- a/static/remote-docs/guides/networks/phase-1/mainnet/covonent_committee/covonent_committee.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Covenant Committee

      -

      The Covenant Emulation committee comprises of entities operating a covenant -signer to sign on-demand unbonding and slashing transactions. -The committee has 9 seats, which are filled by the following entities:

      -
        -
      • Babylon Labs: 3 seats
      • -
      • CoinSummer Labs: 1 seat
      • -
      • RockX: 1 seat
      • -
      • AltLayer: 1 seat
      • -
      • Zellic: 1 seat
      • -
      • Informal Systems: 1 seat
      • -
      • Cubist: 1 seat
      • -
      -

      The covenant emulation committee operates on all phases of the Babylon mainnet -launch, and during the transitionary stage between Phase-1 and Phase-2 -will operate separate programs for each stage to support both Phase-1 and -Phase-2 stakers. -Below, we detail the specifics of the operation for each phase.

      -

      Phase-2

      -

      During Phase-2, the covenant emulation committee is responsible for operationg -the covenant-emulator, -a daemon responsible for connecting with a Babylon Genesis node and monitoring -for staking registrations that are pending verification. Once such a staking -transaction is identified, the covenant emulator daemon submits signatures for -the on-demand unbonding, slashing, and unbonding slashing transactions.

      -
      -

      Note: The Babylon Genesis chain involves slashing of finality providers -for double signing offences. This means that in Phase-2, covenant committee -members submit not only unbonding signatures, but slashing signatures as -well.

      -
      -

      The latest list of covenant public keys and operating entities can be found -here.

      -
      -

      Important: The above list might be outdated. The best source of truth on the -current covenant committee members and their keys is the Babylon -Genesis node parameters. You should aim to retrieve the parameters from -there.

      -
      -

      Phase-1

      -

      During Phase-1, the covenant emulation committee is responsible for operating -the covenant signer, -a daemon accepting requests for signing on-demand unbonding transactions.

      -

      The Covenant Emulation Committee has 9 members, 3 of which -are operated by Babylon Labs. The Covenant quorum configuration as -well as the current members can be found in the -staking parameters.

      -

      A full list of the endpoints and the corresponding Covenant BTC Public Keys -for the phase-1 covenant committee follows below, grouped by the operating entity.

      -
      -

      Note: Use this list only for on-demand unbonding of Phase-1 stakes, -i.e., stakes that have not been registered to the Babylon Genesis node. -On-demand unbonding of stakes registered on Babylon Genesis -follows a different procedure which is documented -here.

      -
      -
        -
      • Babylon Labs -
          -
        • Signer 0 -
            -
          • key: 03d45c70d28f169e1f0c7f4a78e2bc73497afe585b70aa897955989068f3350aaa
          • -
          • URL: https://covenant-signer0.babylonlabs.io
          • -
          -
        • -
        • Signer 1 -
            -
          • key: 034b15848e495a3a62283daaadb3f458a00859fe48e321f0121ebabbdd6698f9fa
          • -
          • URL: https://covenant-signer1.babylonlabs.io
          • -
          -
        • -
        • Signer 2 -
            -
          • key: 0223b29f89b45f4af41588dcaf0ca572ada32872a88224f311373917f1b37d08d1
          • -
          • URL: https://covenant-signer2.babylonlabs.io
          • -
          -
        • -
        -
      • -
      • CoinSummer Labs -
          -
        • key: 02d3c79b99ac4d265c2f97ac11e3232c07a598b020cf56c6f055472c893c0967ae
        • -
        • URL: https://babylon-covenant-signer.coinsummer.com
        • -
        -
      • -
      • RockX -
          -
        • key: 03f178fcce82f95c524b53b077e6180bd2d779a9057fdff4255a0af95af918cee0
        • -
        • URL: https://babylon-mainnet-covenant-signer.rockx.com
        • -
        -
      • -
      • AltLayer -
          -
        • key: 038242640732773249312c47ca7bdb50ca79f15f2ecc32b9c83ceebba44fb74df7
        • -
        • URL: https://babylon-mainnet-covenant-signer.alt.technology
        • -
        -
      • -
      • Zellic -
          -
        • key: 03cbdd028cfe32c1c1f2d84bfec71e19f92df509bba7b8ad31ca6c1a134fe09204
        • -
        • URL: https://babylon-mainnet-covenant-signer.zellic.net
        • -
        -
      • -
      • Informal Systems -
          -
        • key: 03e36200aaa8dce9453567bba108bdc51f7f1174b97a65e4dc4402fc5de779d41c
        • -
        • URL: https://covenant-signer-babylon.informalsystems.io
        • -
        -
      • -
      • Cubist -
          -
        • key: 03de13fc96ea6899acbdc5db3afaa683f62fe35b60ff6eb723dad28a11d2b12f8c
        • -
        • URL: https://bbn-mainnet-covsign.cubestake.xyz
        • -
        -
      • -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/mainnet/finality_provider_registration.html b/static/remote-docs/guides/networks/phase-1/mainnet/finality_provider_registration.html deleted file mode 100644 index 889a8266..00000000 --- a/static/remote-docs/guides/networks/phase-1/mainnet/finality_provider_registration.html +++ /dev/null @@ -1,356 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Finality Provider Information Registry

      -
      -

      ⚠️ Important: Phase-1 registrations of finality providers are now -closed and this guide is a legacy one. -Finality providers that intend to register to the Babylon Genesis network -(phase-2 mainnet) -- either Phase-1 finality providers or new ones -- -should follow the -finality provider operation -guide

      -
      -

      This is the finality provider registration guide for the first phase of the -Babylon Bitcoin staking mainnet.

      -

      Background

      -

      The Babylon Bitcoin staking mainnet will be launched in phases. The first phase -will only involve Bitcoin holders submitting Bitcoin staking transactions to -the Bitcoin chain to lock their Bitcoins, without any Proof of Stake (PoS) -chain operating to be secured by the stake. This effectively means that for -this phase, finality providers will only need to register and publish their -Extractable One Time Signature (EOTS) keys. Bitcoin stakers can make -delegations to a finality provider by associating the staking transaction with -the finality provider's EOTS public key. Finality providers do not need to run -the finality service since for this phase there is no PoS chain to be secured -by it.

      -

      The most common way for Bitcoin holders to stake is to use the Babylon Bitcoin -staking web application. This web application provides a curated list of -finality providers for the stakers to choose from for their delegations. -Besides critical information such as the EOTS public key and the commission -rate, for each finality provider, the web application also displays -human-friendly information such as the moniker and the website URL.

      -

      This repository is the place for finality providers to register such -information and all the finality providers listed in this repository will be -visible in the web application. This guide instructs finality providers on how -to get listed.

      -

      Registration Eligibility Criteria

      -

      For security and quality reasons, strict eligibility criteria are imposed, -focusing on the finality provider's proven commitment and identity -verification. More specifically, for a finality provider to be eligible for -inclusion in this information registry, it needs to meet the following -requirements:

      -
        -
      • having participated in the -Babylon testnet-4,
      • -
      • to go through a know your business (KYB) process conducted by Babylon Labs, and
      • -
      • to submit a pull request (PR) before the deadline of August 20th, 12pm -coordinated universal time (UTC).
      • -
      -

      The pull request created should contain the finality provider's information -combined with its EOTS public key, and a signature signed over the information -using the corresponding EOTS private key.

      -

      Missed the Registration?

      -

      After the deadline, this registration will be closed. Exceptions will only be -made rarely and on a case-by-case basis for entities that have significant -impacts and contributions to the industry. In addition, in order to be -considered, the finality provider MUST NOT accept any delegation before it -is registered. Otherwise, the application will be rejected, no exception.

      -

      Ineligible finality providers can still participate in this phase by accepting -Bitcoin stakes from their users. The -Babylon Bitcoin Staking indexer -will identify such delegations and display the finality providers' EOTS -public key in the web application to acknowledge their existence. However:

      -
        -
      1. -

        besides the EOTS public key, no more information about such finality -providers will be displayed since they are not registered.

        -
      2. -
      3. -

        the web application will not allow users to delegate to such finality -providers.

        -
      4. -
      5. -

        such finality providers' commission rate will be assumed to be 0% for any -staking reward related calculation. In other words, such finality providers -will not receive any commissions from the delegations it has received. -In later phases, the finality provider will be able to modify its commission -rate.

        -
      6. -
      -

      Registration Steps

      -

      The registration of a finality provider requires the generation of an -Extractable-One-Time-Signature (EOTS) key pair, which will serve as the -identifier for the finality provider. The EOTS mechanism is built on top of -Schnorr signatures, the signature scheme used in Bitcoin. It is described in -more detail in the -Bitcoin Staking light paper. -In the following, we use the terms finality provider keys, BTC keys, and -EOTS keys interchangeably.

      -

      In Phase-1, finality providers only need to generate their EOTS key pair and -sign their finality provider information (covered later in this guide). In -later phases, finality providers are expected to actively run the finality -provider program with their EOTS keys to provide economic security to PoS -chains and earn commissions.

      -

      1. Install EOTS Manager

      -

      The EOTS daemon is utilized to create the EOTS keys of the finality provider. -To follow this guide, please use the -eotsd v0.4.0 -version. This is a Golang project and requires version 1.21 or later. Install -Go by following the instructions in the -official Go installation guide.

      -

      Download the EOTS Manager code with git clone

      -
      $ git clone https://github.com/babylonlabs-io/finality-provider.git
      -
      -Cloning into 'finality-provider'...
      -
      -

      Checkout to the v0.4.0 release tag

      -
      $ cd finality-provider # cd into the project directory
      -$ git checkout v0.4.0
      -
      -Note: switching to 'v0.4.0'.
      -
      -

      At the root of the finality provider repository install the binaries

      -
      $ make install
      -
      -CGO_CFLAGS="-O -D__BLST_PORTABLE__" go install -mod=readonly --tags "" --ldflags ''  ./...
      -
      -
      -

      eotsd is part of the finality provider service suite, so running -make install also generates fpd which is not used in this guide.

      -
      -

      Check if the installation succeeded by running eotsd --help.

      -
      $ eotsd --help
      -
      -NAME:
      -   eotsd - Extractable One Time Signature Daemon (eotsd).
      -
      -USAGE:
      -   eotsd [global options] command [command options] [arguments...]
      -
      -COMMANDS:
      -   start               Start the Extractable One Time Signature Daemon.
      -   init                Initialize the eotsd home directory.
      -   sign-schnorr        Signs a Schnorr signature over arbitrary data with the EOTS private key.
      -   verify-schnorr-sig  Verify a Schnorr signature over arbitrary data with the given public key.
      -   help, h             Shows a list of commands or help for one command
      -
      -   Key management:
      -     keys  Command sets of managing keys for interacting with BTC eots keys.
      -
      -GLOBAL OPTIONS:
      -   --help, -h  show help
      -
      -

      2. Create EOTS Keys

      -

      For starters, it is needed to run the eotsd init command to initialize a home -directory for the EOTS manager. This directory is created in the default home -location or a location specified by the --home flag.

      -
      eotsd init --home /path/to/eotsd/home/
      -
      -

      After initialization, the home directory will have the following structure

      -
      ls /path/to/eotsd/home/
      -  ├── eotsd.conf # Eotsd-specific configuration file.
      -  ├── logs       # Eotsd logs
      -
      -

      Next, it is needed to create an EOTS key pair to identify your finality -provider by running eotsd keys add. This BTC EOTS key pair is stored in the -file system and will be used in later steps of the guide to sign the finality -provider information file. In future phases of the Babylon mainnet, it is -expected for this key to further be utilized to provide Bitcoin security to PoS -chains.

      -

      This command has several flag options:

      -
        -
      • --home specifies the home directory of the eotsd in which -the new key will be stored.
      • -
      • --key-name mandatory flag that identifies the name of the key to be -generated.
      • -
      • --passphrase specifies the password used to encrypt the key, if such a -passphrase is required.
      • -
      • --hd-path is the hd derivation path of the private key.
      • -
      • --keyring-backend specifies the keyring backend, any of -[file, os, kwallet, test, pass, memory] are available, by default test is -used.
      • -
      • --recover indicates whether the user wants to provide a seed phrase to -recover an existing key instead of creating a new one.
      • -
      -
      eotsd keys add --home /path/to/eotsd/home/ --key-name my-key-name --keyring-backend file
      -
      -Enter keyring passphrase (attempt 1/3):
      -...
      -
      -2024-04-25T17:11:09.369163Z     info    successfully created an EOTS key        {"key name": "my-key-name", "pk": "50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383"}
      -New key for the BTC chain is created (mnemonic should be kept in a safe place for recovery):
      -{
      -  "name": "my-key-name",
      -  "pub_key_hex": "50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383",
      -  "mnemonic": "bad mnemonic private tilt wish bulb miss plate achieve manage feel word safe dash vanish little miss hockey connect tail certain spread urban series"
      -}
      -
      -
      -

      Reminder: if the --keyring-backend flag was used to create the key, the -same flag should be used later for accessing this key.

      -
      -

      At the end of these steps, the EOTS BTC key pair will be generated. The key -pair or the mnemonic generated must be stored in a safe place, as it is -expected to be needed for the finality provider's participation in PoS security -in the future stages of the Babylon mainnet. Finality providers that don't have -access to their keys, will not be able to transition to later stages.

      -

      ⚠ Warning! -Store the mnemonic in a safe place. The mnemonic is the only way you can -recover your keys in the case of loss or file system corruption.

      -

      3. Create your Finality Provider Information object

      -

      After forking -the current repository, navigate to the bbn-1/finality-providers directory -and create a file under the finality-providers/registry/${nickname}.json -path. ${nickname}, corresponds to a unique human-readable nickname your -finality provider can be identified with (e.g. your moniker). It should not -contain white spaces or unrecognizable characters.

      -

      Inside this file, store the following JSON information corresponding to the -finality provider.

      -
      {
      -  "description": {
      -    "moniker": "<moniker>",
      -    "identity": "<identity>",
      -    "website": "<website>",
      -    "security_contact": "<security_contact>",
      -    "details": "<details>"
      -  },
      -  "eots_pk": "<finality_provider_eots_pk>",
      -  "commission": "<commission_decimal>"
      -}
      -
      -

      Properties descriptions:

      -
        -
      • moniker: nickname of the finality provider.
      • -
      • identity: optional Keybase.io identity signature. It is used to retrieve -the finality provider icon, the same way Cosmos-SDK uses for validators.
      • -
      • website: optional website link URL.
      • -
      • security_contact: required email for security contact.
      • -
      • details: any other optional detail information.
      • -
      • eots_pk: the btc pub key in hex format (The pub_key_hex property of the -eotsd keys add command output).
      • -
      • commission: the commission charged for BTC staking rewards. -The commission will be parsed as a decimal: -
          -
        • "1.00" represents 100% commission.
        • -
        • "0.10" represents 10% commission.
        • -
        • "0.03" represents 03% commission.
        • -
        -
      • -
      -

      ⚠ Warning! -The minimum commission value accepted is 3%. It will remain immutable and can't -be changed during the first phase of the Babylon mainnet. Please, define the -commission rate wisely. Bitcoin stakers may earn various types of rewards. The -commission rate you set affects every commission you earn on such rewards -through their delegations.

      -

      4. Sign the Finality Provider information

      -

      To attest the ownership of the EOTS public key contained in the finality -provider information file, the registry requires signing the file using the -corresponding EOTS private key. This is another step of validation that -guarantees that the information provided by the finality provider is legitimate -and not tampered with.

      -

      To sign the information file with the EOTS private key use the -eotsd sign-schnorr [file-path] command. This command takes as an argument one -file path, which in this case is the file created in step -3, hashes the file -content using sha256, and signs the hash with the EOTS private key in Schnorr -format based on the key-name or eots-pk flag. If both flags --key-name -and --eots-pk are provided, --eots-pk takes priority.

      -
      $ eotsd sign-schnorr bbn-1/finality-providers/registry/${nickname}.json \
      -  --home /path/to/eotsd/home/ --key-name my-key-name --keyring-backend file
      -
      -{
      -  "key_name": "my-key-name",
      -  "pub_key_hex": "50b106208c921b5e8a1c45494306fe1fc2cf68f33b8996420867dc7667fde383",
      -  "signed_data_hash_hex": "b123ef5f69545cd07ad505c6d3b4931aa87b6adb361fb492275bb81374d98953",
      -  "schnorr_signature_hex": "b91fc06b30b78c0ca66a7e033184d89b61cd6ab572329b20f6052411ab83502effb5c9a1173ed69f20f6502a741eeb5105519bb3f67d37612bc2bcce411f8d72"
      -}
      -
      -

      The signature is the value of the schnorr_signature_hex field of the above -output. A file should be created under ./finality-providers/sigs with the -filename being the same as the finality provider information stored under -./finality-providers/registry but with the .sig extension (e.g. -${nickname}.sig). The content of the file should be the plain value of the -schnorr_signature_hex field.

      -

      ⚠ Warning! -The signature was generated by reading the entire file data, not only the file -content. For proper verification, the exact file used for signing should be -submitted in the pull request.

      -

      5. Create Pull Request

      -

      The finality provider information and signature should be stored under the -registry and sigs directories respectively. Both file names should have the -same name (e.g. ${nickname}), but with .json and .sig extensions -respectively. -Make sure that you submit exactly the same file that the signature was -generated for to ensure proper verification.

      -

      The validity of the finality provider data can be checked locally before -creating a pull request through the following script (replace ${nickname} -with the filename you previously used):

      -
      $ ./bbn-1/finality-providers/scripts/verify-valid-fp.sh ${nickname}
      -
      -Verifying /.../bbn-1/finality-providers/scripts/../registry/my_nickname.json
      -Finality Provider Moniker: my great moniker
      -Finality Provider Security Contact: security@email.com
      -Finality Provider Commission: 0.050000000000000000
      -Finality Provider EOTS Public Key: a89e7caf57360bc8b791df72abc3fb6d2ddc0e06e171c9f17c4ea1299e677565
      -Finality Provider Signature: 5e39939ccf68b8d30e134e132fe0e234b0840db3f380e17c57a0170c77235af3a555d8ea59eaacfaf43eaaa55d740549ee7f74cf844ed10dda2c81303006c348
      -Verifying signature with eotsd...
      -Verification is successful!
      -
      -

      The pull request should follow the below template:

      -
      # New ${nickname} Finality Provider
      -
      -## Checklist
      -
      -- [ ] I have followed the finality provider information registry
      -[guide](https://github.com/babylonlabs-io/networks/blob/main/bbn-1/finality-providers/README.md)
      -- [ ] I have backed up my mnemonic
      -- [ ] I have read and agree to the [Babylon Ecosystem Participant License](https://docs.babylonlabs.io/assets/files/babylon-ecosystem-participant-license.pdf) and the [Babylon Ecosystem Participant Agreement](https://docs.babylonlabs.io/assets/files/babylon-ecosystem-participant-agreement.pdf).
      -
      -> [!CAUTION]
      -> The loss of the (generated keys + mnemonic) makes the finality provider
      -useless and unable to provide finality, which would lead to no transition to
      -later phases of the Babylon network.
      -
      -

      6. Modifying Finality Provider Information

      -

      During the operation of the first stage of the Babylon mainnet, -a finality provider can/can't perform the following updates.

      -
        -
      • ❌ Commission can not be changed
      • -
      • ❌ Finality Provider EOTS key can not be changed
      • -
      • ✅ Moniker, identity, website, security contact, and details can be changed.
      • -
      -

      To update the changeable fields, the finality provider should -modify the JSON object containing their information, -replace their old signature with a new one created using their EOTS private -key, and create a pull request updating their information. -These steps can be performed by the processes outlined previously in the guide -and the pull request submitted by the same GitHub account.

      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/mainnet/global_parameters.html b/static/remote-docs/guides/networks/phase-1/mainnet/global_parameters.html deleted file mode 100644 index 71bea3a9..00000000 --- a/static/remote-docs/guides/networks/phase-1/mainnet/global_parameters.html +++ /dev/null @@ -1,159 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Staking Parameters

      -
      -

      Important Note: These parameters apply only to the Phase-1 of the Babylon -launch. From Phase-2 onwards, the parameters listed here will be deprecated, -and the Babylon Genesis chain will be the source of all staking parameters.

      -
      -

      The staking parameters are governance parameters that specify what constitutes -a valid staking transaction that should be considered as an active one for -the lock-only phase-1 system. -They are maintained by Babylon and are timestamped on Bitcoin by a Bitcoin -governance wallet owned by it. They are additionally included in a GitHub -registry for easy retrieval and timestamp verification.

      -

      Specification

      -

      The global-params.json file contains a JSON array (versions), with each -array element representing one version of the parameters. The array -elements are ordered by increasing version.

      -
      {
      -  "versions": [
      -    {
      -      "version": "<params_version>",
      -      "activation_height": "<bitcoin_activation_height>",
      -      "staking_cap": "<satoshis_staking_cap_of_version>",
      -      "cap_height": "<bitcoin_cap_height>",
      -      "tag": "<magic_hex_encoded_bytes_to_identify_staking_txs>",
      -      "covenant_pks": [
      -        "<covenant_btc_pk1>",
      -        "<covenant_btc_pk2>",
      -      ],
      -      "covenant_quorum": "<covenant_quorum>",
      -      "unbonding_time": "<unbonding_time_btc_blocks>",
      -      "unbonding_fee": "<unbonding_fee_satoshis>",
      -      "max_staking_amount": "<max_staking_amount_satoshis>",
      -      "min_staking_amount": "<min_staking_amount_satoshis>",
      -      "max_staking_time": "<max_staking_time_btc_blocks>",
      -      "min_staking_time": "<min_staking_time_btc_blocks>",
      -      "confirmation_depth": "<confirmation_depth>"
      -    },
      -    ...
      -  ]
      -}
      -
      -

      The hash of each version of the parameters is further timestamped on Bitcoin by -a Babylon owned governance wallet to enable easy verification.

      -

      A parameters version has the following rules:

      -
        -
      • Version: The version should be an integer and versions should be -monotonically increasing by 1 with an initial value of 0.
      • -
      • ActivationHeight: The activation height describes the Bitcoin height from -which the parameters of this version are taken into account. Each new -version, should have a strictly larger activation height than the previous -version. This ensures that for any transaction, we can identify which staking -parameters should apply to it.
      • -
      • StakingCap: The staking cap describes the limit of Bitcoins that are -accepted in total for this parameters version. It includes Bitcoins that have -been accepted in prior versions. A later version should have a larger or -equal staking cap than a prior version in which the StakingCap is set. -If StakingCap is set, it should be strictly larger than the maximum staking amount.
      • -
      • CapHeight: The cap height is a different cap mechanism than StakingCap. -It allows staking transactions to be accepted as long as their inclusion height -is in the range of ActivationHeight and CapHeight (inclusive) for this -parameters version. Note: Only one of CapHeight and StakingCap can be set in a -single parameters version. A later version should have a larger or equal cap height -than a prior version where CapHeight is set.
      • -
      • CovenantPKs: Specifies the public keys of the covenant committee.
      • -
      • CovenantQuorum: Specifies the quorum required by the covenant committee for -unbonding transactions to be confirmed.
      • -
      • UnbondingFee: Specifies the required fee that an unbonding transaction -should have in satoshis. Can change arbitrarily between versions.
      • -
      • MinStakingAmount/MaxStakingAmount: Specify the range of acceptable staking -amounts in satoshis. Can change arbitrarily between versions. The maximum -should be larger or equal to the minimum.
      • -
      • MinStakingTime/MaxStakingTime: Specify the range of acceptable staking -periods in BTC blocks. Can change arbitrarily between versions. The maximum -should be larger or equal to the minimum. The maximum cannot be larger than -65535.
      • -
      • ConfirmationDepth: The number of confirmations required for transactions -to be deep enough on the Bitcoin ledger so that their reversal is highly -improbable. Inclusion of a transaction in a block means the confirmation depth -for the transaction is 1. More appended blocks further increment its -confirmation depth.
      • -
      -

      Rules specification:

      -
      Let v_n and v_m be versions `n` and `m` respectively, with `m > n`.
      -
      -In between versions:
      -- v_m.Version == v_n.Version + (m - n)
      -- v_m.ActivationHeight > v_n.ActivationHeight
      -- v_m.StakingCap >= v_n.StakingCap if v_n.StakingCap != 0
      -
      -For a particular version:
      -- len(v_m.Tag) == 4
      -- ValidBTCPks(v_m.CovenantPks)
      -- len(v_m.CovenantPks) > 0
      -- len(v_m.ActivationHeight) > 0
      -
      -- v_m.StakingCap == 0 => v_m.CapHeight > 0
      -- v_m.StakingCap > 0 => v_m.CapHeight == 0
      -- v_m.StakingCap > 0 => v_m.StakingCap > v_m.MaxStakingAmount
      -
      -- v_m.CovenantQuorum <= len(v_m.CovenantPks)
      -- v_m.CovenantQuorum < 2^32
      -- v_m.CovenantKeys.each(Key: validHexSchnorrKey(Key))
      -
      -- v_m.MinStakingAmount >= v_m.UnbondingFee + 1000
      -- v_m.MaxStakingAmount >= v_m.MinStakingAmount
      -- v_m.MaxStakingAmount < 2^63 && v_m.MinStakingAmount < 2^63 && v_m.StakingCap < 2^63
      -
      -- v_m.MaxStakingTime >= v_m.MinStakingTime
      -- v_m.MaxStakingTime > 0 && v_m.MinStakingTime > 0 && v_m.UnbondingTime > 0
      -- v_m.MaxStakingTime <= 65535 && v_m.MinStakingTime <= 65535 && v_m.UnbondingTime <= 65535
      -
      -- v_m.ConfirmationDepth > 1 && v_m.ConfirmationDepth <= 65535
      -
      -

      Updating staking parameters

      -

      Given that the staking parameters are used by multiple entities running in a distributed -environment to validate staking and unbonding transactions, -all updates to the global-params.json must be made in well-defined and -transparent manner.

      -

      To update parameters the following steps will be taken:

      -
        -
      1. The Babylon team creates a PR in this repository with an updated global-params.json file. -The only allowed modification to this file is appending a new object to the versions -collection. The newly appended object must obey all rules defined in the previous paragraph.
      2. -
      3. All interested entities, for example, covenant signers, approve this PR. Each -approval is interpreted as being ready to validate transactions using the new global-params.json -introduced by the PR.
      4. -
      5. After enough approvals are gathered, the PR is merged. -Now the tip of the main branch contains the last version of staking parameters.
      6. -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/testnet/covonent_committee/covonent_committee.html b/static/remote-docs/guides/networks/phase-1/testnet/covonent_committee/covonent_committee.html deleted file mode 100644 index a26bce91..00000000 --- a/static/remote-docs/guides/networks/phase-1/testnet/covonent_committee/covonent_committee.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Covenant Committee

      -

      The Covenant Emulation Committee comprises entities operating -Covenant Signer daemons.

      -

      For this testnet, the Covenant Emulation Committee has 9 members, 3 of which -are operated by the Babylon Foundation. The Covenant quorum configuration as -well as the current members can be found in the -staking parameters.

      -

      A full list of the endpoints follows below, grouped by the operating entity.

      -

      Babylon Foundation

      -
        -
      • https://covenant-signer0.testnet.babylonchain.io:443
      • -
      • https://covenant-signer1.testnet.babylonchain.io:443
      • -
      • https://covenant-signer2.testnet.babylonchain.io:443
      • -
      -

      CoinSummer Labs

      -
        -
      • http://54.167.222.28:9791
      • -
      -

      RockX

      -
        -
      • https://babylon-covenant-signer.rockx.com:443
      • -
      -

      AltLayer

      -
        -
      • https://babylon-covenant-signer.alt.technology:443
      • -
      -

      Zellic

      -
        -
      • https://babylon-covenant-signer.zellic.io:443
      • -
      -

      Informal Systems

      -
        -
      • https://covenant-signer-babylon.informalsystems.dev:443
      • -
      -

      Cubist

      -
        -
      • https://bbn-test-4-covsign.cubestake.xyz:443
      • -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/testnet/finality_provider_registration.html b/static/remote-docs/guides/networks/phase-1/testnet/finality_provider_registration.html deleted file mode 100644 index 8203fa61..00000000 --- a/static/remote-docs/guides/networks/phase-1/testnet/finality_provider_registration.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Finality Provider Information Registry

      -

      Due to fulfillment of the finality provider quotas, -registration will be turned off for the bbn-test-4 -on Monday, 24 June 2024 EoD AoE.

      -

      The bbn-test-4 testnet will focus on the security of the staked Bitcoins by -testing the user's interaction with the BTC signet network. This will be a -lock-only network without a Babylon chain operating, meaning that the only -participants of this testnet will be finality providers and Bitcoin stakers. -This effectively means that for the next testnet, finality providers will only -be receiving Bitcoin Signet delegations and not have to vote for blocks.

      -

      Bitcoin holders that stake their Bitcoin can use Babylon's staking web -application to select the finality provider they want to delegate -their attestation of power to. They do so by including the finality provider's -BTC public key in the self-custodial Bitcoin Staking script. -Babylon will employ a Bitcoin indexer that collects all staking transactions -and extracts the finality provider BTC public keys that receive delegations -for display in the staking web application. -While the BTC public key is the only identifying information required -for a finality provider, it does not expose all the information that a -finality provider might want to share to attract more stake delegations.

      -

      The Babylon web application will additionally employ the finality provider -information registry in this repository to display additional information -such as the finality provider's moniker, website, and identity. -To protect this registry against spam, we require finality providers to submit -a deposit using the self-custodial Bitcoin staking to lock 0.1 signet BTC for -one year. The deposit will be fully in the custody of the finality provider, -but not be counted as active stake and can be retrieved -after the deposit period expires.

      -

      An entry can be created in this registry by opening a pull -request containing:

      -
        -
      1. Their identifying information combined with their BTC public key.
      2. -
      3. A signature of the information using the corresponding BTC private key.
      4. -
      5. A proof of submitting their deposit and the deposit having sufficient -confirmations.
      6. -
      -

      Finality providers can submit their information prior to or after the testnet -launch. To be included in the initial list that is displayed in the staking -web app, they have to submit the information prior to the launch.

      -

      The rest of the document explains the steps to create your finality provider's -keys and submitting the required information to be included in the registry.

      -

      Versions

      -
        -
      • etosd - ae30623a634450db81ce1755839754cc822bf5e5
      • -
      • stakercli - 9be9838ca1124b64660dd1bdd57790bd7cc74e11
      • -
      -

      1. Create Finality Provider Keys

      -

      Finality Provider BTC key generation is covered by steps 1-3 from -this guide. -These steps describe how to set up the EOTS manager and generate the finality -provider keys using it. In this phase, finality providers should only use the -EOTS manager to generate their BTC keys and sign their finality provider -information (covered later in this guide). In later stages, finality providers -will be expected to operate a live version of the EOTS manager in order to -provide economic security to PoS chains.

      -

      At the end of these steps, your finality provider Bitcoin key pair will be -generated. Make sure that you store the key pair or the mnemonic you have -generated in a safe place, as it is going to be needed for your participation -on PoS security in the future stages of the Babylon testnet. Finality providers -that don't have access to their keys, will not be able to transition to later -stages.

      -

      ⚠ Store the mnemonic used for keys creation in a safe place.

      -

      2. Deposit self-lock BTC

      -

      Finality providers that want to register their information must make a deposit -of 0.1 signet BTC using the self-custodial Bitcoin Staking script. -This is required to keep the finality provider information registry open, -but protect it from spam and entities that do not make a real commitment to the project. -The deposit will be locked for 52560 blocks (i.e. ~one year), -and will not be counted towards the active stake of the system. -Note that the deposit is still fully in the custody of the creator of the -transaction, but will only become unlocked after the deposit period expires.

      -

      ⚠ Warning! -The deposit amount of 10000000 signet satoshi is the minimum amount required -for registration. Any deposit below this number will be considered an invalid -registration. There is no need to deposit more than 10000000, but -such deposits with higher value will be considered as -a valid registrations.

      -

      The deposit is a Bitcoin transaction with an output containing the deposit value -committing to the Babylon Bitcoin Staking script. -A special set of values should be used for the deposit to be a valid one. -More specifically, -to create a valid deposit, you can follow the steps -in this guide, -with the following flags on the -stakercli transaction create-phase1-staking-transaction command:

      -
        -
      • --finality-provider-pk=<finality_provider_eots_pk> The public key of your finality provider -previous generated.
      • -
      • --staker-pk The public key of the account who funds the deposit transaction.
      • -
      • --staking-amount=10000000, i.e. 0.1 signet BTC
      • -
      • --staking-time=52560, i.e. ~1 year
      • -
      • --magic-bytes=62627434 "bbt4" as hex
      • -
      • --covenant-committee-pks=50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 -
          -
        • This public key does not have a discrete logarithm therefore rendering the -unbonding and slashing paths of the Bitcoin Staking script unusable. -This makes the timelock path the only usable path as it only requires the -staker's key.
        • -
        -
      • -
      • --covenant-quorum=1
      • -
      • --network=signet
      • -
      -

      The difference between --staker-pk and --finality-provider-pk -is that the --finality-provider-pk flag specifies the public key of the -finality provider being registered, while the --staker-pk flag specifies -the Bitcoin public key that funds the deposit transaction. -It is recommended that the finality provider public key should be securely -stored and not hold any funds. Therefore, for creating the deposit -transaction, it is recommended that one funds the deposit transaction -with a separate public key (i.e. the --staker-pk) that holds the funds.

      -
      stakercli transaction create-phase1-staking-transaction \
      -  --staker-pk=<your_generated_staker_pub_key> \
      -  --finality-provider-pk=<your_finality_provider_eots_pk> \
      -  --staking-amount=10000000 --staking-time=52560 --magic-bytes=62627434 \
      -  --covenant-committee-pks=50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 \
      -  --covenant-quorum=1 --network=signet
      -
      -{
      -  "staking_tx_hex": "020000000002404b4c00000000002251207c2649dc890238fada228d52a4c25fcef82e1cf3d7f53895ca0fcfb15dd142bb0000000000000000496a476262743400b91ea4619bc7b3f93e5015976f52f666ae4eb5c98018a6c8e41424905fa8591fa89e7caf57360bc8b791df72abc3fb6d2ddc0e06e171c9f17c4ea1299e677565cd5000000000"
      -}
      -
      -

      With the phase1 staking transaction you still need to fund with -bitcoin-cli fundrawtransaction and then sign it with your BTC key -bitcoin-cli signrawtransactionwithwallet.

      -

      After signing the transaction you should have it in -hex format. -It is possible to verify if your transaction has the correct parameters before -submitting it to the Signet BTC ledger by using the following script:

      -
      $ export FP_BTC_PK=<your_finality_provider_eots_pk>
      -$ export SIGNED_TX=<your_signed_tx_hex>
      -
      -$ ./bbn-test-4/finality-providers/scripts/fp-check-tx.sh
      -
      -Provided transaction is valid staking transaction!
      -
      -

      The success of the above command means that the signed transaction in hex format -is ready for propagation to the Bitcoin ledger. -This can happen in several ways:

      - -
      curl https://bitcoin-testnet-archive.allthatnode.com \
      -  --request POST \
      -  --header 'content-type: text/plain;' \
      -  --data '{"jsonrpc": "1.0", "id": "1", "method": "sendrawtransaction", "params": ["02000000000101ffa5874fdf64a535a4beae47ba0e66278b046baf7b3f3855dbf0413060aaeef90000000000fdffffff03404b4c00000000002251207c2649dc890238fada228d52a4c25fcef82e1cf3d7f53895ca0fcfb15dd142bb0000000000000000496a476262743400b91ea4619bc7b3f93e5015976f52f666ae4eb5c98018a6c8e41424905fa8591fa89e7caf57360bc8b791df72abc3fb6d2ddc0e06e171c9f17c4ea1299e677565cd50c876f7f70d0000001600141b9b57f4d4555e65ceb98c465c9580b0d6b0d0f60247304402200ae05daea3dc62ee7f2720c87705da28077ab19e420538eea5b92718271b4356022026c8367ac8bcd0b6d011842159cd525db672b234789a8d37725b247858c90a120121020721ef511b0faee2a487a346fdb96425d9dd7fa79210adbe7b47f0bcdc7e29de00000000"]}'
      -
      -f22b9a1892df0e50977455b85b65324b079a9f230c5a9dede5ac711b9415d15b
      -
      -

      Once the transaction is submited onchain it outputs an transaction hash. -Wait a few minutes and make sure that the transaction is included in the -blockchain by using the explorer -https://live.blockcypher.com/btc-testnet/tx/<btc_staking_tx_hash>.

      -
      -

      Make sure that the transaction has at least 6 confirmations block before -creation of the pull request.

      -
      -

      Keep the following information for inclusion in your finality provider -information. This will be used to prove that you are indeed the submitter of -the deposit.

      -
      {
      -  ...
      -  "deposit": {
      -    "tx_hash": "f22b9a1892df0e50977455b85b65324b079a9f230c5a9dede5ac711b9415d15b",
      -    "signed_tx": "02000000000101ffa5874fdf64a535a4beae47ba0e66278b046baf7b3f3855dbf0413060aaeef90000000000fdffffff03404b4c00000000002251207c2649dc890238fada228d52a4c25fcef82e1cf3d7f53895ca0fcfb15dd142bb0000000000000000496a476262743400b91ea4619bc7b3f93e5015976f52f666ae4eb5c98018a6c8e41424905fa8591fa89e7caf57360bc8b791df72abc3fb6d2ddc0e06e171c9f17c4ea1299e677565cd50c876f7f70d0000001600141b9b57f4d4555e65ceb98c465c9580b0d6b0d0f60247304402200ae05daea3dc62ee7f2720c87705da28077ab19e420538eea5b92718271b4356022026c8367ac8bcd0b6d011842159cd525db672b234789a8d37725b247858c90a120121020721ef511b0faee2a487a346fdb96425d9dd7fa79210adbe7b47f0bcdc7e29de00000000"
      -  }
      -}
      -
      -

      3. Create your Finality Provider information object

      -

      After forking the current repository, -navigate to the finality-providers directory and create a file under the -finality-providers/registry/${nickname}.json path. -${nickname}, corresponds to a unique human readable nickname your finality -provider can be identified with (e.g. your moniker). It should not contain -white spaces or unrecognizable characters.

      -

      Inside this file, store the following JSON information corresponding to your -finality provider.

      -
      {
      -  "description": {
      -    "moniker": "<moniker>",
      -    "identity": "<identity>",
      -    "website": "<website>",
      -    "security_contact": "<security_contact>",
      -    "details": "<details>"
      -  },
      -  "btc_pk": "<eots_btc_pk>",
      -  "commission": "<commission_decimal>",
      -  "deposit": {
      -    "tx_hash": "tx_hash",
      -    "signed_tx": "signed_tx_hex"
      -  }
      -}
      -
      -

      Properties descriptions:

      -
        -
      • moniker: nickname of the finality provider.
      • -
      • identity: optional identity signature (e.g. UPort or Keybase).
      • -
      • website: optional website link.
      • -
      • security_contact: required email for security contact.
      • -
      • details: any other optional detail information.
      • -
      • btc_pk: the btc pub key as hex.
      • -
      • commision: the commission charged from btc stakers rewards. -Comission will be parsed as sdk.Dec: -
          -
        • "1.00" represents 100% commission.
        • -
        • "0.10" represents 10% commission.
        • -
        • "0.01" represents 01% commission.
        • -
        -
      • -
      • deposit: contains data for proof of locking. -
          -
        • tx_hash: The transaction hash of the deposit.
        • -
        • signed_tx: The funded signed locking transaction as hex.
        • -
        -
      • -
      -

      4. Sign the Finality Provider information

      -

      Once you create your finality provider information, you need to prove that you -are indeed the owner of the Bitcoin Public Key contained within it. You can do -so, by signing the file with the corresponding Bitcoin Private Key of your -finality provider. This is another step of validation that -guarantees that the information provided by the finality provider was not tempered -and that the finality provider posseses the private key of that particular pub key.

      -

      To sign the file, -head back to the guide that you used to create your finality provider keys, -and more specifically the -signing step. -After signing the file, you should get this output:

      -
      {
      -  "key_name": "my-key-name",
      -  "pub_key_hex": "c23e674f8fd2f28756a1536339646b84d40cf7205a8bb48bc6c6c68043964ab3",
      -  "signed_data_hash_hex": "b123ef5f69545cd07ad505c6d3b4931aa87b6adb361fb492275bb81374d98953",
      -  "schnorr_signature_hex": "b91fc06b30b78c0ca66a7e033184d89b61cd6ab572329b20f6052411ab83502effb5c9a1173ed69f20f6502a741eeb5105519bb3f67d37612bc2bcce411f8d72"
      -}
      -
      -

      The signature is specified by the schnorr_signature_hex field of the output. -A file should be created under ./finality-providers/sigs with the filename -being the same as the finality provider information stored under ./finality-providers/registry -but with the .sig extension (e.g. ${nickname}.sig). -The content of the file should be the plain value of the schnorr_signature_hex field.

      -

      ⚠ Warning! -The signature was generated by reading the entire file data, not only the file -content. For proper verification, the exact file used for signing should -be submited in the pull request.

      -

      5. Create Pull Request

      -

      Submit your finality provider information under the registry directory and -your signature under the sigs directory. Both file names should have the -same name (e.g. ${nickname}), but with .json and .sig extensions respectively. -Make sure that you submit exactly the same file that you signed to ensure proper -verification.

      -

      If you have installed all the binaries in your path, check out locally if your -finality provider is valid before creating the pull request:

      -
      $ ./bbn-test-4/finality-providers/scripts/verify-new-fp-offchain.sh && \
      -  ./bbn-test-4/finality-providers/scripts/verify-new-fp-onchain.sh
      -
      -From https://github.com/babylonchain/networks
      - * branch            main       -> FETCH_HEAD
      -verify bbn-test-4/finality-providers/registry/my_nickname.json
      -fp moniker: my great moniker
      -fp nickname: my_nickname
      -fp btcpk: a89e7caf57360bc8b791df72abc3fb6d2ddc0e06e171c9f17c4ea1299e677565
      -fp signature: 5e39939ccf68b8d30e134e132fe0e234b0840db3f380e17c57a0170c77235af3a555d8ea59eaacfaf43eaaa55d740549ee7f74cf844ed10dda2c81303006c348
      -eotsd verify signature
      -Verification is successful!
      -stakercli check transaction
      -Provided transaction is valid staking transaction!
      -  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
      -                                 Dload  Upload   Total   Spent    Left  Speed
      -100  2728  100  2728    0     0   4790      0 --:--:-- --:--:-- --:--:--  4785
      -BTC check transaction
      -✅ 'my_nickname' is a valid fp registration
      -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-1/testnet/global_parameters.html b/static/remote-docs/guides/networks/phase-1/testnet/global_parameters.html deleted file mode 100644 index e379408f..00000000 --- a/static/remote-docs/guides/networks/phase-1/testnet/global_parameters.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Staking Parameters

      -

      The staking parameters are governance parameters that specify what constitutes -a valid staking transaction that should be considered as an active one for -the lock-only testnet system. -They are maintained by Babylon and are timestamped on Bitcoin by a Bitcoin -governance wallet owned by it. They are additionally included in a GitHub -registry for easy retrieval and timestamp verification.

      -

      Specification

      -

      The global-params.json file contains a JSON array (versions), with each -array element representing one version of the testnet parameters. The array -elements are ordered by increasing version.

      -
      {
      -  "versions: [
      -    {
      -      "version": <params_version>,
      -      "activation_height": <bitcoin_activation_height>,
      -      "staking_cap": <satoshis_staking_cap_of_version>,
      -      "cap_height": <bitcoin_cap_height>,
      -      "tag": "<magic_hex_encoded_bytes_to_identify_staking_txs>",
      -      "covenant_pks": [
      -        "<covenant_btc_pk1>",
      -        "<covenant_btc_pk2>",
      -        ...
      -      ],
      -      "covenant_quorum": <covenant_quorum>,
      -      "unbonding_time": <unbonding_time_btc_blocks>,
      -      "unbonding_fee": <unbonding_fee_satoshis>,
      -      "max_staking_amount": <max_staking_amount_satoshis>,
      -      "min_staking_amount": <min_staking_amount_satoshis>,
      -      "max_staking_time": <max_staking_time_btc_blocks>,
      -      "min_staking_time": <min_staking_time_btc_blocks>,
      -      "confirmation_depth": <confirmation_depth>
      -    },
      -    ...
      -  ]
      -}
      -
      -

      The hash of each version of the parameters is further timestamped on Bitcoin by -a Babylon owned governance wallet to enable easy verification.

      -

      A parameters version has the following rules:

      -
        -
      • Version: The version should be an integer and versions should be -monotonically increasing by 1 with an initial value of 0.
      • -
      • ActivationHeight: The activation height describes the Bitcoin height from -which the parameters of this version are taken into account. Each new -version, should have a strictly larger activation height than the previous -version. This ensures that for any transaction, we can identify which staking -parameters should apply to it.
      • -
      • StakingCap: The staking cap describes the limit of Bitcoins that are -accepted in total for this parameters version. It includes Bitcoins that have -been accepted in prior versions. A later version should have a larger or -equal staking cap than a prior version in which the StakingCap is set. -If StakingCap is set, it should be strictly larger than the maximum staking amount.
      • -
      • CapHeight: The cap height is a different cap mechanism than StakingCap. -It allows staking transactions to be accepted as long as their inclusion height -is in the range of ActivationHeight and CapHeight (inclusive) for this -parameters version. Note: Only one of CapHeight and StakingCap can be set in a -single parameters version. A later version should have a larger or equal cap height -than a prior version where CapHeight is set.
      • -
      • CovenantPKs: Specifies the public keys of the covenant committee.
      • -
      • CovenantQuorum: Specifies the quorum required by the covenant committee for -unbonding transactions to be confirmed.
      • -
      • UnbondingFee: Specifies the required fee that an unbonding transaction -should have in satoshis. Can change arbitrarily between versions.
      • -
      • MinStakingAmount/MaxStakingAmount: Specify the range of acceptable staking -amounts in satoshis. Can change arbitrarily between versions. The maximum -should be larger or equal to the minimum.
      • -
      • MinStakingTime/MaxStakingTime: Specify the range of acceptable staking -periods in BTC blocks. Can change arbitrarily between versions. The maximum -should be larger or equal to the minimum. The maximum cannot be larger than -65535.
      • -
      • ConfirmationDepth: The number of confirmations required for transactions -to be deep enough on the Bitcoin ledger so that their reversal is highly -improbable. Inclusion of a transaction in a block means the confirmation depth -for the transaction is 1. More appended blocks further increment its -confirmation depth.
      • -
      -

      Rules specification:

      -
      Let v_n and v_m be versions `n` and `m` respectively, with `m > n`.
      -
      -In between versions:
      -- v_m.Version == v_n.Version + (m - n)
      -- v_m.ActivationHeight > v_n.ActivationHeight
      -- v_m.StakingCap >= v_n.StakingCap if v_n.StakingCap != 0
      -
      -For a particular version:
      -- len(v_m.Tag) == 4
      -- ValidBTCPks(v_m.CovenantPks)
      -- len(v_m.CovenantPks) > 0
      -- v_m.CovenantQuorum <= len(v_m.CovenantPks)
      -- v_m.StakingCap > v_m.MaxStakingAmount
      -- v_m.MaxStakingAmount >= v_m.MinStakingAmount
      -- v_m.MaxStakingTime >= v_m.MinStakingTime
      -- v_m.MaxStakingTime <= 65535
      -- v_m.StakingCap = 0 && v_m.CapHeight != 0 || v_m.StakingCap != 0 && v_m.CapHeight == 0 
      -
      -

      Updating staking parameters

      -

      Given that the staking parameters are used by multiple entities running in a distributed -environment to validate staking and unbonding transactions, -all updates to the global-params.json must be made in well-defined and -transparent manner.

      -

      To update parameters the following steps will be taken:

      -
        -
      1. The Babylon team creates a PR in this repository with an updated global-params.json file. -The only allowed modification to this file is appending a new object to the versions -collection. The newly appended object must obey all rules defined in the previous paragraph.
      2. -
      3. All interested entities, for example, covenant signers, approve this PR. Each -approval is interpreted as being ready to validate transactions using the new global-params.json -introduced by the PR.
      4. -
      5. After enough approvals are gathered, the PR is merged. -Now the tip of the main branch contains the last version of staking parameters.
      6. -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-2/mainnet/mainnet.html b/static/remote-docs/guides/networks/phase-2/mainnet/mainnet.html deleted file mode 100644 index 69ee7d1f..00000000 --- a/static/remote-docs/guides/networks/phase-2/mainnet/mainnet.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Babylon Mainnet

      -

      Welcome to the network page for the Babylon mainnet. -This is your central hub -for network participation information, whether you're running a node, -operating as a validator, providing finality services, or participating -in the covenant committee.

      -

      Babylon Genesis Chain (Phase-2 Mainnet)

      -

      Network Parameters

      -

      Chain ID

      -

      bbn-1

      -

      Genesis

      -

      The genesis file can be retrieved from here.

      -

      State snapshot

      -

      A snapshot including state up to height 226 can be retrieved from -here.

      -

      To boot a node with this snapshot, Babylon version v1.0.1 should be used -(reference).

      -

      Some additional network snapshot sources are also listed:

      -
        -
      • https://babylon.explorers.guru/snapshots
      • -
      • https://polkachu.com/babylon_partnership
      • -
      -

      Seed nodes

      -

      Seed nodes can be retrieved from here.

      -

      Peers

      -

      Peers can be retrieved from here.

      -

      Endpoints

      -
      RPC
      -

      Pruned:

      -
        -
      • https://babylon.nodes.guru/rpc
      • -
      • https://babylon-rpc.polkachu.com
      • -
      -

      Archive:

      -
        -
      • https://babylon-archive.nodes.guru/rpc
      • -
      • https://babylon-archive-rpc.polkachu.com
      • -
      -
      LCD (node API)
      -

      Pruned:

      -
        -
      • https://babylon.nodes.guru/api
      • -
      • https://babylon-api.polkachu.com
      • -
      -

      Archive:

      -
        -
      • https://babylon-archive.nodes.guru/api
      • -
      • https://babylon-archive-api.polkachu.com
      • -
      -
      gRPC
      -

      Pruned:

      -
        -
      • babylon.nodes.guru:443
      • -
      • babylon-grpc.polkachu.com:20690
      • -
      -

      Archive:

      -
        -
      • babylon-archive.nodes.guru:443
      • -
      • babylon-archive-grpc.polkachu.com:20690
      • -
      -

      Babylon Genesis network participants

      -

      There are four types of participants in the Babylon network. -Please see the setup and configuration guides below:

      - -

      Phase-1 Mainnet

      -

      With the launch of the Babylon Genesis chain mainnet, the Babylon mainnet -will enter into a transitionary stage in which Phase-1 stakes will either -register on the Babylon Genesis chain or on-demand unbond and withdraw. -After the launch of the Babylon Genesis chain mainnet, the Phase-1 mainnet will -be considered legacy without any new staking caps planned or stakes accepted.

      -
      -

      ⚠️ Warning: The Babylon Genesis mainnet has not yet launched, so the -Phase-1 mainnet still remains the current supported Babylon mainnet.

      -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/networks/phase-2/testnet/testnet.html b/static/remote-docs/guides/networks/phase-2/testnet/testnet.html deleted file mode 100644 index ddcb4fd8..00000000 --- a/static/remote-docs/guides/networks/phase-2/testnet/testnet.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Babylon testnet-5 Network

      -

      Welcome to the network page for the Babylon Phase-2 testnet (bbn-test-5). -This is your central hub -for network participation information, whether you're running a node, -operating as a validator, providing finality services, or participating -in the covenant committee.

      -

      Network Parameters

      -

      Chain ID

      -

      bbn-test-5

      -

      Genesis

      -

      The genesis file can be retrieved from here.

      -

      State snapshot

      -

      A snapshot including state up to height 200 can be retrieved from -here.

      -

      To boot a node with this snapshot, Babylon version v1.0.0-rc.3 should be used -(reference).

      -

      Some additional network snapshot sources are also listed:

      -
        -
      • https://polkachu.com/testnets/babylon/snapshots
      • -
      • https://www.imperator.co/services/chain-services/testnets/babylon
      • -
      • https://services.contributiondao.com/testnet/babylon/snapshots
      • -
      -

      Seed nodes

      -

      Seed nodes can be retrieved from here.

      -

      Peers

      -

      Peers can be retrieved from here.

      -

      Endpoints

      -
        -
      1. RPC
      2. -
      -

      Pruned:

      -
        -
      • https://babylon-testnet-rpc.nodes.guru
      • -
      • https://babylon-testnet-rpc.polkachu.com
      • -
      • https://rpc-babylon-testnet.imperator.co
      • -
      • https://babylon-testnet-rpc.contributiondao.com
      • -
      -

      Archive:

      -
        -
      • https://babylon-testnet-rpc-archive-1.nodes.guru
      • -
      -
        -
      1. LCD (node API)
      2. -
      -

      Pruned:

      -
        -
      • https://babylon-testnet-api.nodes.guru
      • -
      • https://babylon-testnet-api.polkachu.com
      • -
      • https://lcd-babylon-testnet.imperator.co
      • -
      • https://babylon-testnet-api.contributiondao.com
      • -
      -

      Archive:

      -
        -
      • https://babylon-testnet-api-archive-1.nodes.guru
      • -
      -
        -
      1. gRPC
      2. -
      -
        -
      • https://babylon-testnet-grpc.nodes.guru
      • -
      • http://babylon-testnet-grpc.polkachu.com:20690
      • -
      • grpc-babylon-testnet.imperator.co:443
      • -
      -

      Covenant Committee

      -

      The covenant committee consists of 9 signing keys with a quorum being achieved -with 6 signatures. Below are the members of the covenant committee and the -BTC public keys associated with them.

      -
        -
      • Babylon Labs: -
          -
        • fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737
        • -
        • 0aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25
        • -
        • 17921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4
        • -
        -
      • -
      • Cubist -
          -
        • 113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0
        • -
        -
      • -
      • Informal Systems -
          -
        • 79a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0
        • -
        -
      • -
      • Zellic -
          -
        • 3bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899c
        • -
        -
      • -
      • RockX -
          -
        • d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36
        • -
        -
      • -
      • AltLayer -
          -
        • f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8e
        • -
        -
      • -
      • CoinSummer Labs -
          -
        • 40afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092df
        • -
        -
      • -
      -

      Alternatively, the list can be retrieved from here.

      -

      Network Participants

      -

      There are four types of participants in the Babylon network. -Please see the setup and configuration guides below:

      - - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/eligibility.html b/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/eligibility.html deleted file mode 100644 index 438b2f2c..00000000 --- a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/eligibility.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Staking Registration Eligibility

      -
        -
      1. Introduction
      2. -
      3. Terminology -
          -
        1. Bitcoin Stake Registration
        2. -
        3. Stakes Allow-List
        4. -
        5. Finality Voting Activation
        6. -
        -
      4. -
      5. Timeline of Events -
          -
        1. Chain Launch
        2. -
        3. Finality Voting Activation
        4. -
        5. Allow-list Expiration
        6. -
        -
      6. -
      7. Retrieving details about the timeline
      8. -
      -

      1. Introduction

      -

      This document outlines the various stages of the Babylon Genesis chain launch -and details the points in which different Finality Providers -and BTC stakes are eligible for registration. -The launch is structured into three key stages:

      -
        -
      • Stage 1: Babylon Genesis Chain Launch: At this stage, only -Finality Providers and allow-listed stakes can register. -The allow-list specifies a list of transaction hashes that -are eligible for registration. These transaction hashes are -typically associated with existing transactions (e.g., coming from Phase-1). -The purpose of the allow-list is for Bitcoin stakes to be onboarded -in two separate stages, with the bulk of the stakes coming in the second -stage. This ensures a smooth launch focused on safety -and incremental onboarding of stakes. After the allow-list expires -at a pre-determined time, all stakes, including new ones, can register. -Note that even though stakes and Finality Providers can register, -they do not have voting power. This comes at the next stage.
      • -
      • Stage 2: Bitcoin Staking Finality Activation Bitcoin Stake receives -finality voting power leading to -Finality Providers starting to submit finality votes -and BTC stakers receiving staking rewards.
      • -
      • Stage 3: Uncapped Bitcoin Staking: All stakeholders can register and new -stakes can be created. BTC Staking is uncapped.
      • -
      -

      2. Terminology

      -

      2.1. Bitcoin Stake Registration

      -

      Bitcoin stake registration involves the submission of -Bitcoin stakes to the Babylon Genesis chain in order for the stake -to receive voting power and earn rewards.

      -

      There are 2 ways to create stakes, either through pre-staking registration or -post-staking registration.

      -
        -
      • Pre-staking registration: The process in which a staker registers their -stake on Babylon before staking on Bitcoin, without providing a proof -of inclusion.
      • -
      • Post-staking registration: The process in which a staker first stakes on -Bitcoin and then registers the stake on Babylon.
      • -
      -

      To see more on this please refer to the -Registering Bitcoin Stake -documentation.

      -

      2.2. Stakes Allow-List

      -

      The allow-list consists of a collection of transaction hashes corresponding -to Bitcoin staking transactions. It has a pre-determined expiration date and -is implemented as a mechanism to initially restrict the stakes that can register into the chain in order -to ensure the secure and gradual launch of the system (similar to the caps mechanism on Phase-1). -While the allow-list is active, only post-staking registrations are allowed -with Bitcoin staking transactions that have a hash included in the allow-list. -Pre-staking registrations are not permitted until the allow-list has expired.

      -
      -

      ⚡ Note -The allow-list will expire at a predefined block height. Once it has expired, -all stake types, both pre-staking and post-staking registrations become -valid for staking.

      -
      -

      2.3. Finality Voting Activation

      -

      Another measure to ensure that the Bitcoin Staking protocol -is smoothly launched is the delayed -activation of the finality voting power of Bitcoin Stakes. -This delay is necessary because Babylon Chain enables the staking of -the Bitcoin asset, meaning that sufficient amount of time should be -given for the Bitcoin asset to be onboarded.

      -

      Finality voting activation refers to the point at which -Bitcoin Stakes receive finality voting power and when -Finality Providers, that such stakes are delegated to, -can begin casting votes to finalize blocks on the Babylon chain. -The time of the finality voting activation -is determined by a block height included in the Babylon chain -x/btcstaking module parameters -and will be specified at launch time.

      -

      Once finality voting is activated, BTC stakers can start earning rewards -based on their voting power.

      -

      3. Timeline of Events

      -

      Staking Timeline

      -

      3.1. Babylon Genesis Chain Launch

      -

      The Babylon Genesis launch procedure involves the chain -starting to produce blocks that contain transactions. -At this point, the following actors can start onboarding -onto the chain:

      -
        -
      • CometBFT Validators: CometBFT validators can permissionlessly -submit validator registration transactions and become eligible -for producing Babylon blocks. More details on the CometBFT -validator registration procedure can be found here.
      • -
      • Finality Providers: Finality Providers can permissionlessly -register to Babylon Genesis. Note that Finality Providers -that have operated and received delegations in a Phase-1 Babylon -network, should register using exactly the same EOTS key they -used for the corresponding network -(i.e., for Babylon Genesis mainnet use the same key as with the Phase-1 mainnet). -More details on how to register a Finality Provider or migrate the Phase-1 -EOTS key to Babylon Genesis can be found -here.
      • -
      • BTC Stake Registration Bitcoin stakes for which their hash -is included in the allow-list and the Finality Provider to which -they have been delegated to has registered -can now register to Babylon Genesis. -More details on how to register your Bitcoin stakes -here.
      • -
      -
      -

      ⚡ Important Bitcoin stakes cannot register to Babylon Genesis -unless the Finality Provider they have been delegated to has registered. -For Phase-1 stakes, this means that the Phase-1 Finality Providers -should register first, before stake registration is attempted.

      -
      -
      -

      ⚠️ Warning Phase-1 stakes should always follow the post-staking -registration procedure. Following the pre-staking registration -procedure for a Phase-1 stake will lead to this stake's inability -to ever register on the Babylon Genesis chain.

      -
      -
      -

      ⚡ Important While Finality Providers and Bitcoin Stakers can -register at this point, the Bitcoin stake does not yet have voting power -and is not eligible for receiving rewards. Voting power and rewards -will start being granted once the finality protocol activates -(see following sections).

      -
      -

      3.2. Finality Voting Activation

      -

      When finality voting is activated, Finality Providers can begin -participating in the voting process to finalize blocks based -on the voting power they have received from their Bitcoin Stake -delegations. Note that only the active set of Finality Providers -determined by a top-X ranking based on the Finality Providers' -stake can participate in voting. The number of active Finality Providers is determined -by a parameter of the x/btcstaking module.

      -

      3.3. Allow-list Expiration

      -

      Once the allow-list has expired, stake registration becomes fully -open and uncapped, allowing both existing stakes (e.g., from Phase-1) -and new stakes to be registered. Finality Providers can continue their -operations as usual, maintaining their role in the network without -any changes.

      -

      4. Retrieving details about the timeline

      -

      To obtain information about the activation block height and the allow-list of -staking transactions, you can query the BTC Staking module or inspect the -relevant code.

      -

      Retrieving the Activation Block Height -The Finality Activation block height can be retrieved by the -x/btcstaking parameters. You can retrieve those:

      -
        -
      • through the CLI and an RPC node connection
      • -
      -
      babylond query btcstaking params --node <rpcnode>
      -
      -
        -
      • through an LCD/API node connection (you can find one -for the Babylon Genesis public networks -here)
      • -
      • by parsing through the upgrade handler responsible for specifying it -(e.g., for testnet)
      • -
      -
      app/upgrades/v1/testnet/btcstaking_params.go
      -
      -

      Retrieving the Allow-list of Staking Transaction Hashes -The transaction hashes in the allow-list are hardcoded in -the codebase for each different deployed -network. -For example, the testnet allow-list transaction -hashes can be found here:

      -
      app/upgrades/v1/testnet/allowed_staking_tx_hashes.go
      -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html b/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html deleted file mode 100644 index 00109bad..00000000 --- a/static/remote-docs/guides/overview/phases_of_the_launch/phase-2/registration.html +++ /dev/null @@ -1,875 +0,0 @@ - - - - - - Remote Documentation - - - -
      - -

      Bitcoin Stake Registration

      -

      Table of contents

      -
        -
      1. Introduction
      2. -
      3. Bitcoin Stake Registration Methods -
          -
        1. Multi-Staking to BSNs
        2. -
        3. BSN and Finality Provider Selection
        4. -
        5. Multi-Staking Validation
        6. -
        7. Post-Staking Registration
        8. -
        9. Pre-Staking Registration
        10. -
        -
      4. -
      5. Bitcoin Stake Registration -
          -
        1. Overview of Data that needs to be Submitted
        2. -
        3. Babylon Chain BTC Staking Parameters
        4. -
        5. Creating the Bitcoin transactions
        6. -
        7. The MsgCreateBTCDelegation Babylon message
        8. -
        9. Constructing the MsgCreateBTCDelegation
        10. -
        -
      6. -
      7. Managing your Bitcoin Stake -
          -
        1. On-demand unbonding
        2. -
        3. Withdrawing Expired/Unbonded BTC Stake
        4. -
        5. Withdrawing Remaining Funds after Slashing
        6. -
        -
      8. -
      9. Bitcoin Staking Rewards -
          -
        1. Rewards Distribution
        2. -
        3. Rewards Withdrawal
        4. -
        -
      10. -
      -

      1. Introduction

      -

      This document walks through the communication protocol -with the Babylon Genesis chain in order to register Bitcoin stakes. -The document is structured as follows:

      -
        -
      • Section 2 provides an overview -of the two flows for registering stakes on the Babylon Genesis chain.
      • -
      • Section 3 describes the data required for stake registration, -the registration process itself, and the MsgCreateBTCDelegation message used -to communicate staking transactions to the Babylon Genesis chain.
      • -
      • Section 4 details stake management, including -on-demand unbonding and withdrawal.
      • -
      • Section 5 focuses on the Bitcoin staking rewards -and how to access them.
      • -
      -

      Target Audience: This document is intended as a reference for technical -readers that intend to implement their own methods for registering Bitcoin stakes -(either ones already on Bitcoin or new ones). Alternative methods of staking -(or hosting a staking platform) include using the front-end CLI -(running the simple staking -reference implementation) or using the -Staker CLI program.

      -

      2. Bitcoin Stake Registration Methods

      -

      Bitcoin stakes must be registered on the Babylon Genesis blockchain -to gain voting power and earn rewards. This registration process involves -submitting a registration transaction followed by the validation of the staking operation by key -network components including the Babylon Genesis chain CometBFT Validators -and the covenant committee.

      -

      There are two main methods for registering Bitcoin stakes on the Babylon Genesis chain:

      -
        -
      • Post-staking registration: This applies to stakers who have already submitted -their BTC Staking transaction on the Bitcoin network and then register it on Babylon Genesis -(e.g., Phase-1 stakers).
      • -
      • Pre-staking registration: This is for stakers who seek validation from the Babylon Genesis -chain before submitting their staking transaction to Bitcoin and locking their funds, -ensuring acceptance guarantees (e.g., newly created stakes after the Babylon Genesis chain launch).
      • -
      -

      Each approach is designed to accommodate different staking preferences and -circumstances. In the following sections, we will explore the approaches in more detail.

      -
      -

      ⚡ A Note on k-depth: In the following sections, -we frequently refer to k-depth. The Babylon Genesis chain -only activates staking transactions if they reach k-depth, -where k is a Babylon Genesis chain parameter defined in the -x/btccheckpoint module (as btc_confirmation_depth) -and controlled by governance.

      -

      Depth measures how deep a transaction's block is within the Bitcoin blockchain. -It is calculated as the difference between the Bitcoin tip height and the block -containing the transaction.

      -

      Example: If the Bitcoin tip height is 100, then:

      -
        -
      • Block 99 is 1-deep
      • -
      • Block 90 is 10-deep
      • -
      -
      -

      2.1. Multi-Staking to BSNs

      -

      Multi-staking is the ability to stake BTC to secure multiple BSNs -(Bitcoin Supercharged Networks). When staking singularly to a finality provider, -one finality provider is selected, enabling staking to secure a single BSN. -With multi-staking, Bitcoin holders can delegate to multiple finality providers -simultaneously, with each finality provider securing a different BSN.

      -

      2.2. Post-Staking Registration

      -

      This flow applies to stakers whose BTC staking transaction has already -been confirmed in a Bitcoin block that is k-deep -and is subsequently registered on the Babylon Genesis chain. -For example, this includes participants from the Babylon Phase-1 network.

      -

      The following diagram illustrates the post-staking registration flow: -stake-registration-post-staking-flow

      -

      Steps:

      -
        -
      1. Generate staking metadata: Retrieve the staking transaction -from its included Bitcoin block and generate the proof of inclusion.
      2. -
      3. Fill the MsgCreateBTCDelegation message with the unbonding transaction, -signed slashing transactions and Proof of Possession (POP) and broadcast it to -the Babylon Genesis blockchain (details on how to do this will be provided in -Section 3.4.)
      4. -
      5. Await Covenant Verification: The stake will remain in a PENDING state until the covenants -provide their verification signatures.
      6. -
      7. Activation: Once a quorum of covenant signatures is reached, -the stake is designated as ACTIVE.
      8. -
      -
      -

      ⚠️ Critical Warning: When migrating your stake from Phase-1, it is essential -to include the proof of inclusion to specify that your stake has already -been included on the Bitcoin ledger. -Failing to provide this proof will make the Babylon node expect -your stake to be included in a later Bitcoin height, leading to -the rejection of any subsequent staking registrations of it. -In those cases, the stake will have to be unbonded and staked again.

      -

      ⚠️ Important Warning about Finality Providers: Be cautious when selecting -Finality Providers for your stake. If the Finality Providers you delegate to get -slashed before your stake is registered, your stake may become stuck. This is -particularly important when delegating across multiple BSNs.

      -
      -

      2.3. Pre-Staking Registration

      -

      The Pre-staking registration flow is for stakers who seek -verification from the Babylon chain before submitting their -BTC staking transaction to the Bitcoin ledger. By doing so, -they gain assurance that their stake will be accepted before -locking their funds on Bitcoin.

      -

      The process begins with the staker submitting all relevant staking data -to the Babylon Genesis chain. Subsequently, the covenant committee provides -verification signatures for on-demand unbonding and slashing, -giving the staker the required assurance for moving on with broadcasting -their BTC staking transaction. After the transaction is confirmed in -a Bitcoin block that is k-deep, the staker -(or an automated service like the -Vigilante Watcher) -submits a proof of inclusion to finalize the registration -and lead to stake activation.

      -

      The following diagram illustrates the pre-staking registration flow: -stake-registration-pre-staking-flow

      -

      Steps:

      -
        -
      1. Fill the MsgCreateBTCDelegation message with necessary metadata and -broadcast it to the Babylon Genesis blockchain. -(details on how to do this -will be provided in Section 3.4.) -
        -

        ⚡ Note: As the staking transaction is not on the Bitcoin ledger yet, -the proof of inclusion should be omitted. This signals that the pre-staking -registration flow is followed and a proof of inclusion will be submitted later.

        -
        -
      2. -
      3. Await Covenant Verification: -Until then, the stake remains as PENDING.
      4. -
      5. Verification: -Once a quorum of signatures is reached, the stake is labeled VERIFIED, -meaning the necessary covenant signatures for slashing and on-demand unbonding are in place.
      6. -
      7. BTC Staking Submission: Following verification, the staker signs and broadcasts -the BTC Staking transaction to the Bitcoin network.
      8. -
      9. Monitor for Bitcoin Inclusion: The -Vigilante Watcher (or the staker) -monitors Bitcoin for transaction confirmation and k-deep inclusion.
      10. -
      11. Confirm k-deep Inclusion: -The Vigilante Watcher will identify that the transaction is k-deep in the Bitcoin chain.
      12. -
      13. Submit Proof of Inclusion: -Once the transaction is k-deep, the Vigilante Watcher (or the staker) submits -MsgAddBTCDelegationInclusionProof. -
        -

        ⚡ Note: If you prefer not to rely on the Vigilante Watcher, you can manually track -Bitcoin depth and submit this message yourself. Details on the message -construction can be found on the x/btcstaking module documentation. -For the rest of the document, we will assume reliance on the Vigilante Watcher service -for simplicity.

        -
        -
      14. -
      15. Activation: -Upon receiving the proof of inclusion, the stake is marked as active.
      16. -
      -
      -

      ⚠️ Critical Warning: After your transaction is confirmed in a Bitcoin block, -remember to submit the proof of inclusion to complete the registration process.

      -

      ⚠️ Important: Gas Requirements for Pre-staking Registration

      -

      Since pre-staking registration does not require prior fund commitment -on Bitcoin, it could be exploited for chain spamming. This is especially -due to the multiple covenant signature submissions that it triggers.

      -

      To mitigate this, submitting a MsgCreateBTCDelegation via -the pre-staking registration flow requires an increased -minimum gas fee that covers the gas for the staking, -covenant signatures, and proof of inclusion submissions. -This minimum gas is defined by the delegation_creation_base_gas_fee -staking parameter of the Babylon Genesis chain -(this parameter will be detailed in -Section 3.2.).

      -

      ⚠️ Important Warning about Finality Providers: Be cautious when selecting -Finality Providers for your stake. If the Finality Providers you delegate to get -slashed before your stake is registered, your stake may become stuck. This is -particularly important when delegating across multiple BSNs.

      -
      -

      3. Bitcoin Stake Registration

      -

      3.1. Overview of Registration Data

      -

      Registering a Bitcoin stake on the Babylon Genesis chain requires submitting the -staking transaction along with essential metadata. -This section provides an overview of the required data, -while later sections detail how to create and package it into a -Babylon Genesis registration transaction.

      -

      Key Registration Data:

      -
        -
      • BTC Staking Transaction: The Bitcoin transaction that locks the Bitcoin stake -in the self-custodial Bitcoin staking script. It can be submitted signed or unsigned, -depending on the staking flow and UTXO inputs.
      • -
      • Unbonding Transaction: An unsigned unbonding transaction allowing -the staker to on-demand unbond their stake. It is submitted to the Babylon Genesis chain -and co-signed by the covenants upon verification.
      • -
      • Slashing Transactions: Two staker pre-signed slashing transactions -(one for staking, one for unbonding) that ensure enforcement -of slashing if the Finality Providers to which the stake is delegated to -double-signs. They are submitted to the Babylon Genesis chain and co-signed -by the covenants upon verification.
      • -
      • Proof of Possession: Confirms ownership of the Bitcoin key -by the Babylon account used for stake registration.
      • -
      • Merkle Proof of Inclusion: Verifies transaction inclusion in a Bitcoin -block that is k-deep. Submitted during initial registration in the post-staking -registration flow, or later in the pre-staking registration flow.
      • -
      -
      -

      ⚠️ Critical Warning: The proof of inclusion is a vital part of your -registration data. -Ensure it is included to verify your stake's origin from past Bitcoin -block heights. Failure to include it will lead to your -stake needing to unbond and be staked again.

      -

      ⚡ Note: More details on the Bitcoin staking, unbonding, and slashing -transactions can be found in the -Bitcoin Staking script specification.

      -

      ⚠️ Important Warning about Finality Providers: Be cautious when selecting -Finality Providers for your stake. If the Finality Providers you delegate to get -slashed before your stake is registered, your stake may become stuck. This is -particularly important when delegating across multiple BSNs.

      -
      -

      Once assembled, this data is packaged into a Babylon Genesis chain transaction and -broadcast to the network. The process differs based on whether the staker -follows the pre-staking or post-staking registration flow.

      -

      Upcoming Sections:

      -
        -
      • Required parameters for BTC Staking transactions.
      • -
      • Construction of Bitcoin transactions for staking.
      • -
      • Building the Babylon Genesis chain transaction with required staking data.
      • -
      • Submitting the registration transaction to Babylon Genesis.
      • -
      -

      3.2. Babylon Genesis Chain BTC Staking Parameters

      -

      BTC Staking transactions must adhere to parameters defined by the Babylon Genesis chain, -which vary based on Bitcoin block heights. Each parameter version -is defined by a btc_activation_height, determining the Bitcoin height -from which the parameter version takes effect. -To determine the applicable parameter version for a staking taking -effect at Bitcoin block height lookup_btc_height:

      -
        -
      1. Sort all parameter versions by btc_activation_height in ascending order.
      2. -
      3. The first parameter version with lookup_btc_height >= btc_activation_height -applies to the staking.
      4. -
      -

      Below is an overview of the key staking parameters contained in the different -versions managed by the x/btcstaking module:

      -
        -
      • covenant_pks: -BIP-340 public keys of the covenant committee (64-character hex strings). -The public keys are an x-coordinate only -representation of a secp256k1 curve point as the y-coordinate is implied.
      • -
      • covenant_quorum: -The minimum number of signatures to achieve a covenants quorum.
      • -
      • min_staking_value_sat / max_staking_value_sat: -The minimum/maximum Bitcoin stake in satoshis (smallest unit of Bitcoin).
      • -
      • min_staking_time_blocks / max_staking_time_blocks: -The minimum/maximum Bitcoin staking duration (in Bitcoin blocks).
      • -
      • slashing_pk_script: -The pk_script expected in the first output of the slashing transaction. -It is stored as a sequence of bytes, representing -the conditions for spending the output.
      • -
      • min_slashing_tx_fee_sat: -The minimum transaction fee (in satoshis) required for the pre-signed slashing -transaction.
      • -
      • slashing_rate: A scalar specifying the percentage of stake -slashed if the Finality Provider double-signs.
      • -
      • unbonding_time_blocks: -The on-demand unbonding time in Bitcoin blocks.
      • -
      • unbonding_fee_sat: -The Bitcoin fee in satoshis required for unbonding transactions.
      • -
      • min_commission_rate: A scalar defining the minimum commission rate -for Finality Providers.
      • -
      • delegation_creation_base_gas_fee: Defines the minimum -gas fee to be paid when registering a stake through the pre-staking -registration flow.
      • -
      • allow_list_expiration_height: The Babylon block height -at which the initial staking transaction allow-list expires. -More details on the allow list can be found here.
      • -
      • btc_activation_height: The Bitcoin block height at which the parameter version -takes effect.
      • -
      -
      -

      ⚡ Retrieving Staking Parameters

      -

      These parameters are part of the x/btcstaking -module parameters that can be queried via a Babylon node using -RPC/LCD endpoints or the CLI.

      -

      ⚠️ Warning: Make sure that you are retrieving the BTC Staking parameters -from a trusted node and you verify their authenticity using additional -sources. Failure to use the correct BTC Staking parameters might make your -stake unverifiable or temporarily frozen on Bitcoin (in the case of an -invalid covenant emulation committee).

      -
      -
      -

      ⚡ Choosing the Correct Staking Parameters

      -

      Stakers must ensure that their Bitcoin transaction adheres -to the correct parameters based on the registration flow -that is followed:

      -
        -
      • Post-staking registration flow: Use parameters corresponding to -the Bitcoin block height in which the staking transaction is included -(similar to phase-1).
      • -
      • Pre-staking registration flow: Use the parameters matching the -Babylon on-chain Bitcoin light client at the time of pre-staking -registration. This ensures that the transaction commits to be validated -against the current staking parameters version (as observed by Babylon Genesis). -This ensures that the pre-staking registered transaction will remain valid even if -it is later included -in a Bitcoin block for which different parameters take effect, -The on-chain Bitcoin light client tip height can be retrieved by querying -the x/btclightclient module using RPC/LCD endpoints -or the CLI.
      • -
      -
      -

      3.3. Creating Bitcoin Transactions

      -

      The Bitcoin staking parameters from the previous section are used -to create the necessary Bitcoin transactions for registering -a Bitcoin stake on the Babylon Genesis and Bitcoin ledgers. -These transactions include:

      -
        -
      • BTC Staking Transaction: The Bitcoin transaction that locks -the stake in the self-custodial Bitcoin staking script.
      • -
      • Slashing Transaction: A pre-signed transaction consenting -to slashing in case of double-signing.
      • -
      • Unbonding Transaction: The on-demand unbonding transaction used to -unlock the stake before the originally committed timelock expires.
      • -
      • Unbonding Slashing Transaction: A pre-signed transaction consenting -to slashing during the unbonding process in case of double-signing.
      • -
      -

      You can create these transactions using:

      - -
      -

      ⚡ Note: Ensure you use the valid Babylon parameters when creating -the Bitcoin transactions.

      -
      -

      3.4. The MsgCreateBTCDelegation Babylon Message

      -

      Cosmos SDK transactions are used for registering -BTC delegations on Babylon Genesis. -The MsgCreateBTCDelegation message -bundles the necessary staking data and registers -the Bitcoin stake on the Babylon Genesis blockchain.

      -

      Key Fields in MsgCreateBTCDelegation

      -
      // MsgCreateBTCDelegation is the message for creating a BTC delegation
      -message MsgCreateBTCDelegation {
      -  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 = 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 across different BSNs.
      -  // If there is more than one finality provider pk, it means the delegation is multi-staked
      -  // across multiple BSNs, with at most one finality provider per BSN allowed.
      -  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
      -  int64 staking_value = 6;
      -  // staking_tx is a bitcoin staking transaction i.e transaction that locks funds
      -  bytes staking_tx = 7 ;
      -  // staking_tx_inclusion_proof is the inclusion proof of the staking tx in BTC chain
      -  InclusionProof staking_tx_inclusion_proof = 8;
      -  // 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" ];
      -  // 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/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
      -  // - unbonding slashing transaction, change output
      -  // It must be smaller than math.MaxUInt16 and larger that max(MinUnbondingTime, CheckpointFinalizationTimeout)
      -  uint32 unbonding_time = 11;
      -  // 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;
      -  // 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;
      -  // 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" ];
      -  // 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/babylonlabs-io/babylon/types.BIP340Signature" ];
      -}
      -
      -

      Explanation of Fields

      -
        -
      • -

        staker_addr: -A Bech32-encoded Babylon address (bbn...) representing the -staker's Babylon account where staking rewards will be accumulated. -This should be the same address that signs the registration transaction.

        -
      • -
      • -

        pop (Proof of Possession): -A cryptographic signature proving that the submitter of the registration -transaction is the owner of the Bitcoin private key used for staking.

        -
          -
        • btc_sig_type: Specifies the signature algorithm used. -The options are: - -
        • -
        • btc_sig: The signature generated by signing the staker address using the -chosen algorithm. The verification process differs by algorithm:
        • -
        • BIP-340: The hash of the staker address bytes should be signed.
        • -
        • BIP-322: Bytes of the bech32 encoded address should be signed.
        • -
        • ECDSA: Bytes of the bech32 encoded address should be signed.
        • -
        -
        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;
        -}
        -
        -
      • -
      • -

        btc_pk: -This Bitcoin secp256k1 public key of the BTC staker, -in BIP-340 format (Schnorr signatures). It is a compact, 32-byte -value derived from the staker's private key. This public key corresponds to -the staker public used to construct the staking script used -in the BTC Staking transaction.

        -
      • -
      • -

        fp_btc_pk_list: -A list of the secp256k1 public keys of the finality providers -(FPs) to which the stake is delegated in BIP-340 format (Schnorr signatures) -and compact 32-byte representation.

        -
        -

        Specifying more than one finality provider constitutes multi-staking, -i.e delegating across multiple BSNs. The system enforces the following constraints:

        -
          -
        • Exactly one finality provider must be securing the Babylon Genesis chain.
        • -
        • At most one finality provider may be selected per consumer BSN.
        • -
        • The total number of finality providers must not exceed the -max_multi_staked_fps limit, which can be queried from the registered BSN. -The system will validate your selection against all multi-staking constraints -before accepting the delegation. -Each public key should be exactly the same as the one used when -constructing the staking script.
        • -
        -
        -
      • -
      • -

        staking_time: -The duration of staking in Bitcoin blocks. This is the same -as the timelock used when constructing the staking script -and must comply with the Babylon staking parameters.

        -
      • -
      • -

        staking_value: -The amount of satoshis locked in the staking output of the BTC -staking transaction (staking_tx). This value must precisely match the Bitcoin -amount in the staking transaction.

        -
      • -
      • -

        staking_tx: -The Bitcoin staking transaction in hex format. This transaction locks -the Bitcoin funds in the staking output and it is crucial that it follows -precisely the staking script format using the -correct Bitcoin staking parameters. Some of the values included in the -MsgCreateBTCDelegation should match with the values in the staking transaction.

        -
        -

        ⚠️ Important: Should the Inputs of the Staking Transaction be Signed?

        -

        Whether the staking transaction should include signed or unsigned -UTXO inputs depends on the type of inputs used. -Since the Babylon Genesis chain tracks staking transactions based on -their transaction hash, it's crucial for the staker to submit -the staking transaction in a format that contains all the -necessary data to generate the full hash corresponding -to the fully signed transaction.

        -

        For legacy inputs that require the script_sig field to be filled, -the signature must be included when submitting the -transaction to Babylon Genesis, as this field directly influences -the transaction hash.

        -

        On the other hand, for inputs that require the witness field -(e.g., SegWit inputs), the signature does not need to be -included as part of the transaction.

        -

        While this distinction doesn't affect the guarantees of staking -transactions following the post-staking registration flow -(since stakes are first committed to Bitcoin), stakers opting -for the pre-staking registration flow must ensure that any legacy inputs -(which require the script_sig field) must submit the staking transaction -as fully signed.

        -

        For example, if a staker creates a staking transaction with multiple inputs, -and at least one of them is a legacy input, the transaction should be submitted -such that:

        -
          -
        • Legacy inputs have their script_sig field filled with the signature.
        • -
        • Other inputs, such as SegWit inputs, can be provided without the witness -to minimize costs.
        • -
        -

        The downside to this is that by submitting a fully signed -staking transaction, there is a risk of it being propagated -to Bitcoin prematurely, before receiving the covenant signatures -(i.e., same as with post-staking registration which is first -on Bitcoin before receiving covenant verification). -However, some stakers might still choose the pre-staking -registration flow, as it requires less waiting time -(if the staker chooses to rely on the Vigilante Watcher) -compared to the post-staking registration flow.

        -
        -
      • -
      • -

        staking_tx_inclusion_proof (Optional): -A merkle proof showing the staking transaction's inclusion in k-deep -Bitcoin block. This field should be filled in when going through -the post-staking registration flow and left empty when going through the pre-staking registration flow. -The field is defined as an InclusionProof protobuf data type (specified below) -with the following fields:

        -
        // in x/btccheckpoint module types
        -message TransactionKey {
        -  uint32 index = 1;
        -  bytes hash = 2
        -    [ (gogoproto.customtype) =
        -    "github.com/babylonlabs-io/babylon/types.BTCHeaderHashBytes" ];
        -}
        -
        -// in x/btcstaking module types
        -message InclusionProof {
        -    // key is the position (txIdx, blockHash) of this tx on BTC blockchain
        -    babylon.btccheckpoint.v1.TransactionKey key = 1;
        -    // proof is the Merkle proof that this tx is included in the position in `key`
        -    bytes proof = 2;
        -}
        -
        -
          -
        • key: Identifies the transaction's position in the Bitcoin blockchain. -The key should correspond to the TransactionKey type, -which contains two fields: -
            -
          • txIdx: The index of the transaction within the block (e.g., tx number 42).
          • -
          • blockHash: The hash of the block containing the transaction.
          • -
          -
        • -
        • proof: A Merkle proof verifying the transaction's inclusion in the Bitcoin chain. -It is a list of transaction hashes the staking transaction hash is paired with -(recursively), in order to trace up to obtain the merkle root of the block, deepest -pairing first. Some resources on constructing the proof: - -
        • -
        -
      • -
      • -

        slashing_tx / delegator_slashing_sig: -The slashing transaction that spends the BTC staking transaction through the -slashing path and the staker's BIP-340 (Schnorr) signature for it. -Both are in hex format. -This transaction is considered fully signed once it has signatures -from the staker, a quorum of the covenants, and the Finality Provider. -Upon transaction verification, the covenant signatures are added, -meaning that only the Finality Provider's signature is missing. -According to the BTC Staking protocol, this means if the Finality Provider double-signs, -and its private key is exposed, leading to the full signature set.

        -
      • -
      • -

        unbonding_time: -The on-demand unbonding period measured in Bitcoin blocks. -This is the same as the timelock used when constructing -the unbonding script -and must comply with the Babylon staking parameters.

        -
      • -
      • -

        unbonding_tx: -The unsigned unbonding transaction in hex format. The submission of the unbonding -transaction is a requirement in order to (1) receive a quorum of covenant -signatures for the unbonding transaction and (2) -for the verification of the slashing transaction that spends the unbonding one.

        -
      • -
      • -

        unbonding_value: -The amount of satoshis committed to the unbonding output of the unbonding transaction.

        -
      • -
      • -

        unbonding_slashing_tx / delegator_unbonding_slashing_sig: -The slashing transaction that spends the on-demand unbonding transaction through the -slashing path and the staker's BIP-340 (Schnorr) signature for it. -Both are in hex format. -This transaction has the same properties with the slashing_tx, -with the difference that it spends the -slashing path of the on-demand unbonding transaction.

        -
      • -
      -

      3.5. Constructing the MsgCreateBTCDelegation

      -

      There are multiple ways to construct and broadcast the MsgCreateBTCDelegation -message to the Babylon network:

      -
        -
      • Command line interface (CLI): -Use the babylond tx btcstaking create-btc-delegation command.
      • -
      • TypeScript Implementation: -Generate the message using TypeScript following -this reference implementation -and broadcast to the Babylon network.
      • -
      • Golang Implementation: -Construct the message using Golang based on this -type reference -and broadcast to the Babylon network.
      • -
      • External References: -For detailed instructions on broadcasting transactions, -refer to the external -Cosmos SDK documentation.
      • -
      -
      -

      ⚠️ Important:

      -
        -
      • Phase-1 staking transactions using the post-staking registration flow will -only be accepted if they meet -these eligibility criteria.
      • -
      • New Phase-2 staking registration, whether created -through the pre-staking or post-staking registration flow, -will only be accepted once the allow-list expires.
      • -
      -
      -

      4. Managing your Bitcoin Stake

      -

      4.1. On-demand Unbonding

      -

      On-demand unbonding allows stakers to initiate the unbonding -of their staked BTC before the original timelock they have committed -to in the original staking transaction expires. The funds become -available for withdrawal after an unbonding period specified -in the Babylon parameters (see Section 3.2.).

      -

      To on-demand unbond, stakers must submit the same on-demand unbonding -transaction they registered as part of their stake earlier, -but only after adding the required signatures:

      -
        -
      • The staker's signature, and
      • -
      • A quorum of covenant signatures
      • -
      -

      The covenant signatures are recorded and committed on-chain as part -of the stake activation process. A stake will not be activated -(or verified, in the case of pre-staking registration) -unless it has received a quorum of covenant signatures for unbonding.

      -

      To retrieve the unbonding transaction and add the necessary signatures, -follow these steps:

      -
        -
      1. Retrieve the unbonding transaction and covenant signatures -by querying the Babylon ledger (e.g., through the RPC/LCD or CLI).
      2. -
      3. Add your own signature to the unbonding transaction witness.
      4. -
      5. Add the covenant signatures to the unbonding transaction witness.
      6. -
      7. Broadcast the fully signed transaction to the Bitcoin network.
      8. -
      -

      For a practical example of how to construct the add the signatures -to construct a fully signed unbonding transaction, -refer to:

      - -
      -

      ⚡ Note: Unbonding Notification on the Babylon Genesis Chain

      -

      The Babylon system employs -the Vigilante Unbonding Watcher, -a service that monitors the Bitcoin ledger for on-demand unbonding transactions -and reports them back to the Babylon Genesis chain. Once the unbonding transaction -is included Bitcoin, the Vigilante detects it and notifies the Babylon Genesis chain, -causing the stake to lose its voting power.

      -
      -

      4.2. Withdrawing Expired/Unbonded Bitcoin Stake

      -

      The withdrawal process involves submitting a Bitcoin transaction -that transfers staked BTC from Babylon protocol output (either staking or -unbonding or change from slashing) to the address under staker wallet control, -once its timelock has expired.

      -

      The process involves the following steps:

      -
        -
      1. Retrieve the staking/unbonding transaction with the -expired timelock.
      2. -
      3. Construct a withdrawal transaction signed by the staker.
      4. -
      5. Submit the transaction to the Bitcoin blockchain.
      6. -
      -

      For a practical example of how to construct the withdrawal transaction, -refer to:

      - -

      4.3. Withdrawing Remaining Funds after Slashing

      -

      A Bitcoin stake is slashed if one of the Finality Providers to -which it is delegated to double-signs. When delegating across multiple -BSNs, slashing can be triggered by misbehavior from any -finality provider in the delegation set. Slashing involves -broadcasting a slashing transaction -that sends a portion of the slashed funds to a burn address -(as defined in the staking parameters in Section 3.2.), -while the remaining funds are transfered to a timelock script, -which can later be withdrawn using the same withdrawal process -defined in the previous section.

      -

      To determine the slashing timelock, refer to the unbonding_time_blocks -parameter in the Babylon Chain BTC Staking Parameters. Babylon Genesis ensures that the timelock on the change output of a slashing -transaction matches the unbonding time. Therefore, the unbonding time -parameter effectively represents your slashing timelock. The reasoning behind -the timelock is that we want to avoid situations in which finality providers -could use slashing as a way to unbond instantly. Note that when delegated to -multiple finality providers across BSNs, slashing affects the entire -delegation regardless of which specific finality provider misbehaved.

      -

      5. Bitcoin Staking Rewards

      -

      Bitcoin stakers are rewarded with native tokens from -the chain they help secure, in exchange for the economic security -they provide.

      -

      5.1. Rewards Distribution

      -

      The rewards are distributed as follows:

      -
        -
      • -

        A fixed number of native tokens are minted upon the creation of each new block.

        -
      • -
      • -

        The minted rewards are allocated among three groups:

        -
          -
        • Native stakers
        • -
        • Bitcoin stakers
        • -
        • Community pool
        • -
        -

        The allocation is controlled by specific parameters:

        -
          -
        • Bitcoin Stakers Portion: Defined by the btc_staking_portion -parameter, which specifies the portion of rewards allocated to Bitcoin -stakers. This is calculated based on the voting power and commission rate -of the Finality Provider the stake has been delegated to.
        • -
        • Community Pool Portion: Typically defined in the x/distribution -module of the Cosmos SDK, often referred to as the community tax.
        • -
        • Native Stakers Portion: The remaining rewards, after allocations to -Bitcoin stakers and the community pool, are distributed to native stakers.
        • -
        -
      • -
      • -

        Rewards for Bitcoin stakers are distributed based on the voting power -and commission rates of all finality providers in their delegation set. -The rewards are entered into a gauge, which stakers can query and withdraw -from through a transaction submission.

        -
      • -
      • -

        Rewards are distributed when a block is finalized. The system processes -finalized blocks to ensure that all eligible stakers receive their rewards -based on the voting power and commission rates at the time of finalization.

        -
      • -
      -

      5.2. Rewards Withdrawal

      -

      Rewards can be withdrawn by submitting a MsgWithdrawReward message:

      -
      // MsgWithdrawReward defines a message for withdrawing reward of a stakeholder.
      -message MsgWithdrawReward {
      -    option (cosmos.msg.v1.signer) = "address";
      -    // type is the stakeholder type {finality_provider, btc_staker}
      -    string type = 1;
      -    // address is the address of the stakeholder in bech32 string
      -    // signer of this msg has to be this address
      -    string address = 2;
      -}
      -
      -

      The message defines the following fields:

      -
        -
      • type: Specifies the stakeholder type for reward withdrawal. Allowed values: -
          -
        • finality_provider
        • -
        • btc_staker
        • -
        -
      • -
      • address: The bech32 address of the stakeholder -(must match the signer of the message).
      • -
      -

      Submitting the Withdrawal Transaction: -Rewards can be withdrawn by:

      -
        -
      • Submitting the MsgWithdrawReward via any RPC/LCD node
      • -
      • Using the CLI babylond tx incentive withdraw-reward <type>
      • -
      • You can claim rewards programmatically using the -TypeScript implementation. Please refer to the TypeScript claim rewards implementation.
      • -
      -

      Querying for available rewards: -Rewards can be checked using the x/incentive module:

      -
        -
      • via an RPC/LCD query -on the URL /babylon/incentive/address/{address}/reward_gauge, -where address is the bech32 address of the staker.
      • -
      • via the CLI command -babylond query incentive reward-gauges <bech32-address>
      • -
      • via TypeScript: You can use the TypeScript implementation to query rewards. -Please refer to the TypeScript library documentation.
      • -
      -

      6. Available BSNs

      -

      To view the list of available BSNs or obtain further information about each BSN, -including attributes such as max_multi_staked_fps you can use -thex/btcstkconsumer module.

      -

      Querying for available BSNs: -This can be checked using the x/btcstkconsumer module:

      -
        -
      • via an RPC/LCD query -List all registered BSNs -/babylon/btcstkconsumer/v1/consumer_registry_list -Retrieve data for a specific BSN -/babylon/btcstkconsumer/v1/consumers_registry/{consumer_ids}
      • -
      • via the CLI command -To retrieve the list of BSNs -babylond query btcstkconsumer registered-consumers -To retrieve a specific BSN -babylond query btcstkconsumer registered-consumer <consumer-id>
      • -
      • Protobuf Reference: -To see the proto file, please refer to the -btcstkconsumer proto.
      • -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/guides/specifications/bitcoin_staking_scripts-version-next-v4.x.html b/static/remote-docs/guides/specifications/bitcoin_staking_scripts-version-next-v4.x.html deleted file mode 100644 index e525cac6..00000000 --- a/static/remote-docs/guides/specifications/bitcoin_staking_scripts-version-next-v4.x.html +++ /dev/null @@ -1,417 +0,0 @@ - - - - - - Remote Documentation - - - -
      -
      Version: next-v4.x
      -

      Bitcoin Staking Transactions Specification

      -

      Table of contents

      -
        -
      1. Introduction
      2. -
      3. Preliminaries -
          -
        1. Building Blocks
        2. -
        3. Stakeholders
        4. -
        -
      4. -
      5. BTC Staking Protocol Transactions -
          -
        1. The Staking Output
        2. -
        3. The Unbonding Output
        4. -
        5. The Slashing Refund Output
        6. -
        -
      6. -
      -

      1. Introduction

      -

      The Babylon BTC Staking protocol turns Bitcoin into a staking asset, -aiming to onboard both the asset and its holders to the -Bitcoin Supercharged Networks (BSNs) ecosystem and the Babylon Genesis -chain (the first BSN).

      -

      Bitcoin holders can stake their BTC by locking it using a -special transaction on the Bitcoin network. -Once locked, the Bitcoin contributes to the economic security of -BSNs selected to be secured, -which in turn enables new opportunities for stakers, -such as earning staking yields.

      -

      This document specifies the structure of the transactions involved -in the BTC Staking protocol. -These transactions must conform to a defined format and -commit to specific Taproot scripts. -The values in these scripts are governed by -parameters defined on the Babylon Genesis chain and -the staker's selections.

      -
      -

      ⚡ For information on retrieving Babylon Genesis parameters and -registering valid staking transactions, -refer to the -registering Bitcoin stakes documentation

      -
      -

      2. Preliminaries

      -

      2.1. Building Blocks

      -

      The Bitcoin Staking protocol transaction specification is -heavily based on Bitcoin's -Taproot upgrade, -which introduced -Schnorr signatures.

      -

      2.2. Stakeholders

      -

      The Bitcoin Staking protocol involves the following stakeholders:

      -
        -
      • Bitcoin Staker: -The Bitcoin staker is the controller and beneficiary of the -Bitcoin stake once it is created. -The staker is identified by their Bitcoin public key -(referenced as <StakerPk> in the staking scripts). -
        -

        ⚡ The staker public key does not need to match the UTXO funder of the -staking transaction. The funding UTXO can originate from any source, -including multi-sig, MPC, or threshold-controlled accounts.

        -
        -
      • -
      • Finality Providers: -Bitcoin Staking supports delegated staking, -allowing voting power from a stake to be assigned -to a finality provider. -A finality provider is identified by their EOTS public -key (<FinalityProviderPk>) and participates in the finality -voting round of a specific BSN. -The selection of finality providers determines which BSNs the stake will secure, -as each finality provider may only secure one BSN. Bitcoin stakers can delegate -to multiple finality providers across different BSNs by including their -EOTS keys in the staking script. -
        -

        ⚡ Multi-staking to finality providers across different BSNs is -supported from v3 of the Babylon Genesis node. The system enforces that -at least one finality provider must secure the Babylon Genesis chain, -with at most one finality provider per BSN. This allows -BTC stakers to provide security to multiple networks simultaneously -while maintaining proper validation constraints.

        -
        -
      • -
      • Covenant Committee: -The role of the covenant committee (identified -by the Bitcoin public keys of its members CovenantPk1..CovenantPkN) -is to protect BSNs against attacks from the BTC stakers and finality providers. -It achieves this by representing itself as an M-out-of-N multi-signature -that co-signs BTC transactions with the BTC staker. Through co-signing, -the covenant committee enforces spending rules on the staked Bitcoin, -so that they can only be spent in a protocol compliant manner. -The co-signatures are published on the Babylon Genesis chain and -are a pre-requisite for the stake's activation. -There's no way the covenant committee can act against the stakers, -except rejecting their staking requests.
      • -
      • Babylon Genesis chain: -The Babylon Genesis chain is the first BSN and acts as the control layer -for the BTC staking protocol. All Bitcoin stakes and finality providers -must be registered on the Babylon Genesis chain. -It is also responsible for propagating staking-related data to other BSNs.
      • -
      -
      -

      ⚠️ Staking scripts must not contain duplicate keys. -The public keys for StakerPk, FinalityProviderPk, and each CovenantPk -must be unique within a single stake.

      -
      -

      3. BTC Staking Protocol Transactions

      -

      The Bitcoin Staking protocol defines four key transaction types:

      -
        -
      • Staking Transaction: -A staking transaction is a Bitcoin -transaction that locks a specific amount of BTC into -the Babylon-recognized staking script. -It marks the beginning of a BTC staking lifecycle. -The requirements for a valid staking transaction are: -
          -
        • It can contain an arbitrary number of inputs.
        • -
        • It can contain an arbitrary number of outputs, -with the requirement that at least one of those outputs -—referred to as the staking output— -is a Taproot output that commits to the Bitcoin Staking script.
        • -
        -
      • -
      • Unbonding Transaction: -The unbonding transaction is a Bitcoin transaction -that enables the staker to on-demand unbond their Bitcoin before the staking -timelock they originally committed to as part of the staking transaction expires. -The requirements for a valid unbonding transaction are: -
          -
        • It contains exactly one input which points to the staking output in which the -Bitcoin to be on-demand unbonded have been locked in.
        • -
        • It contains exactly one output—referred to as the unbonding output— -that is a Taproot output committing to the Bitcoin Staking unbonding script.
        • -
        • The Bitcoin fee of the unbonding transaction must be equal to the fee -for unbonding transactions specified in the -Babylon Genesis parameters.
        • -
        -
      • -
      • Slashing Transaction: -The slashing transaction is used to punish a BTC staker -when the finality provider they have delegated to double-signs. 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 Genesis chain's parameters, and
          • -
          • the second sending the remaining funds to a Taproot output—referred to as the -slashing refund output— which locks the funds in a short timelock before they are redeemable -by the staker.
          • -
          -
        • -
        • The fee of the Bitcoin slashing transaction must be larger than or equal to the -minimum fee specified for slashing transactions in the -Babylon Genesis parameters.
        • -
        -
      • -
      • Withdrawal Transaction: -The withdrawal transaction is a Bitcoin transaction that -extracts unlocked Bitcoin from the timelock script associated with a Bitcoin Staking script -(either Staking, Unbonding, or Slashing). The only requirement for a valid withdrawal transaction -is that one of its inputs is a Staking, Unbonding, or Slashing output.
      • -
      -

      The following diagram shows how the above transactions create and spend -different Bitcoin outputs:

      -
      stateDiagram-v2
      -    active: Staking output
      -    unbonding: Unbonding output
      -    state stake_slashing <<fork>>
      -    state unbonding_slashing <<fork>>
      -    burn_staking: Burn address output
      -    change_staking: Change output
      -    burn_unbonding: Burn address output
      -    change_unbonding: Change output
      -
      -    [*] --> active: Staking transaction
      -
      -    active --> unbonding: Unbonding transaction
      -
      -    unbonding --> [*]: Unbonding withdrawal transaction
      -
      -    unbonding --> unbonding_slashing: Slashing transaction
      -    unbonding_slashing --> burn_unbonding
      -    unbonding_slashing --> change_unbonding
      -    change_unbonding --> [*]: Withdrawal transaction
      -
      -    active --> [*]: Staking withdrawal transaction
      -
      -    active --> stake_slashing: Slashing transaction
      -
      -    stake_slashing --> burn_staking
      -    stake_slashing --> change_staking
      -    change_staking --> [*]: Withdrawal transaction
      -
      -

      3.1. The Staking Output

      -

      The staking output is a Taproot output which can only be spent through -the script spending path. -The key spending path is disabled by using the "Nothing Up My Sleeve" -(NUMS) point as the internal key. -The NUMS point used is the one defined in -BIP341:

      -
      H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)
      -
      -

      This point is derived by hashing the standard uncompressed encoding of the -secp256k1 base point G as the X coordinate.

      -

      The staking output can be spent through one of the following three script paths:

      -
        -
      1. -

        Timelock Path: -This path locks the staker's Bitcoin for a predefined number of Bitcoin blocks.

        -
        <StakerPK> OP_CHECKSIGVERIFY  <TimelockBlocks> OP_CHECKSEQUENCEVERIFY
        -
        -

        Fields:

        -
          -
        • <StakerPK> is the BTC staker's public key.
        • -
        • <TimelockBlocks> defines the number of Bitcoin blocks the funds -are committed to remain locked. This duration starts once the staking -transaction is confirmed in a Bitcoin block. -Requirements: -
            -
          • The timelock must be lower than 65535.
          • -
          • The timelock should be within the bounds for Bitcoin staking transaction -timelocks defined in the -Babylon Genesis parameters.
          • -
          -
        • -
        -
      2. -
      3. -

        Unbonding Path: -This path allows the staker to unlock their Bitcoin on-demand, -before the timelock expires.

        -
        <StakerPk> OP_CHECKSIGVERIFY
        -<CovenantPk1> OP_CHECKSIG <CovenantPk2> OP_CHECKSIGADD ... <CovenantPkN> OP_CHECKSIGADD
        -<CovenantThreshold> OP_NUMEQUAL
        -
        -

        Fields:

        -
          -
        • StakerPK is the BTC staker's public key.
        • -
        • CovenantPk1..CovenantPkN are the lexicographically sorted public keys of the -covenant committee as defined in the -Babylon Genesis parameters.
        • -
        • CovenantThreshold is a Babylon parameter specifying the number of how many -covenant committee member signatures are required. It is defined in the -Babylon Genesis parameters.
        • -
        -

        This path protects against immediate withdrawal without protocol-compliant unbonding, -by requiring signatures from a quorum of the covenant committee.

        -
      4. -
      5. -

        Slashing Path: -This path is used to slash staked funds when the -finality provider to which they have been delegated to -is proven to have double-signed.

        -
        <StakerPk> OP_CHECKSIGVERIFY
        -<FinalityProviderPk1> OP_CHECKSIG <FinalityProviderPk2> OP_CHECKSIGADD ... <FinalityProviderPkN> OP_CHECKSIGADD
        -1 OP_NUMEQUAL
        -<CovenantPk1> OP_CHECKSIG <CovenantPk2> OP_CHECKSIGADD ... <CovenantPkN> OP_CHECKSIGADD
        -<CovenantThreshold> OP_NUMEQUAL
        -
        -

        Fields:

        -
          -
        • StakerPK is the BTC staker's public key.
        • -
        • FinalityProviderPk1..FinalityProviderPkN are the lexicographically sorted -public keys of the finality providers to which the stake is delegated. -
          -

          ⚡ Multi-staking to finality providers across different BSNs is -supported from v3 of the Babylon Genesis node. -The system enforces that at least one finality provider must secure the Babylon Genesis chain, -with at most one finality provider per BSN.

          -
          -
        • -
        • CovenantPk1..CovenantPkN are the lexicographically sorted public keys of the -covenant committee as defined in the -Babylon Genesis parameters.
        • -
        • CovenantThreshold is a Babylon parameter specifying the number of how many -covenant committee member signatures are required. It is defined in the -Babylon Genesis parameters.
        • -
        -

        This path can only be executed with the collaboration of the BTC staker, finality provider, -and covenant committee. The staker is required to submit a pre-signature -for spending the slashing path in order for their stake to be accepted. -The covenant signatures are required to protect against -non protocol-compliant withdrawals. More details on the procedure -for registering stake can be found on the -registering Bitcoin stakes documentation.

        -
      6. -
      -
      -

      ⚡ Key Difference Between the Unbonding and Slashing Paths

      -

      The main difference lies in the presence of <FinalityProviderPk> in -the slashing path which has the following implications:

      -
        -
      • For a staking request to become active, the BTC staker must include -a valid (unsigned) unbonding transaction in the staking request. -It becomes active only when the Babylon Genesis chain receives -CovenantThreshold signatures by the covenant committee. -Since the unbonding path does not include <FinalityProviderPk>, -the staker can exit at any time without needing the finality provider's -consent.
      • -
      • In contrast, the slashing path does include <FinalityProviderPk> and -requires a pre-signed slashing transaction by both the staker and a -CovenantThreshold of the covenant emulation committee to become active. -This ensures that the finality provider's cooperation is needed to prevent -slashing, but not to execute it. If a finality provider misbehaves, -their key is exposed and can be used to execute the slashing.
      • -
      -
      -

      3.2. The Unbonding Output

      -

      The unbonding output is a Taproot output which can only be spent through the -script spending path. The key spending path is disabled by using -the "Nothing Up My Sleeve" (NUMS) point as the internal key. -The NUMS point used is the one defined in -BIP341:

      -
      H = lift_x(0x50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0)
      -
      -

      This point is derived by hashing the standard uncompressed encoding of the -secp256k1 base point G as the X coordinate.

      -

      The unbonding output can be spent through one of the following two script paths:

      -
        -
      1. Timelock path: -This path locks the staker's Bitcoin for a predefined number of Bitcoin blocks. -
        <StakerPK> OP_CHECKSIGVERIFY  <TimelockBlocks> OP_CHECKSEQUENCEVERIFY
        -
        -Fields: -
          -
        • <StakerPK> is the BTC staker's public key.
        • -
        • <TimelockBlocks> defines the unbonding time. It must equal -the value specified for unbonding defined in the -Babylon Genesis parameters.
        • -
        -
      2. -
      3. Slashing path: -This path is used to slash staked funds when the -finality provider to which they have been delegated to -is proven to have double-signed while the stake is in the unbonding period. -
        <StakerPk> OP_CHECKSIGVERIFY
        -<FinalityProviderPk1> OP_CHECKSIG <FinalityProviderPk2> OP_CHECKSIGADD ... <FinalityProviderPkN> OP_CHECKSIGADD
        -1 OP_NUMEQUAL
        -<CovenantPk1> OP_CHECKSIG <CovenantPk2> OP_CHECKSIGADD ... <CovenantPkN> OP_CHECKSIGADD
        -<CovenantThreshold> OP_NUMEQUAL
        -
        -Fields: -
          -
        • StakerPK is the BTC staker's public key.
        • -
        • FinalityProviderPk1..FinalityProviderPkN are the lexicographically sorted -public keys of the finality providers to which the stake is delegated. -
          -

          ⚡ Multi-staking to finality providers across different BSNs is -supported from v3 of the Babylon Genesis node. -The system enforces that at least one finality provider must secure the Babylon Genesis chain, -with at most one finality provider per consumer chain/BSN.

          -
          -
        • -
        • CovenantPk1..CovenantPkN are the lexicographically sorted public keys of the -covenant committee as defined in the -Babylon Genesis parameters.
        • -
        • CovenantThreshold is a Babylon parameter specifying the number of how many -covenant committee member signatures are required. It is defined in the -Babylon Genesis parameters.
        • -
        -
      4. -
      -
      -

      ⚡ Slashing Path in the Unbonding Output

      -

      The presence of the slashing path in the unbonding output ensures that a BTC staker -can still be slashed during the unbonding period, -if their delegated finality provider double-signs.

      -
      -

      3.3. The Slashing Refund Output

      -

      The slashing refund output returns the non-slashed portion of the staked funds -to the staker in the case of slashing. It is an output committing to the -following timelock script:

      -
      <StakerPK> OP_CHECKSIGVERIFY  <TimelockBlocks> OP_CHECKSEQUENCEVERIFY`
      -
      -

      Fields:

      -
        -
      • <StakerPK> is BTC staker public key.
      • -
      • <TimelockBlocks> defines the time in which the funds -will remain locked before being accessible. This timelock is there -to ensure that the slashing path is not maliciously used to retrieve the -remaining funds faster than the unbonding time. It must equal -the value specified for unbonding time defined in the -Babylon Genesis parameters.
      • -
      - -
      - - - \ No newline at end of file diff --git a/static/remote-docs/operators/babylon_node/installation_guide-version-testnet.html b/static/remote-docs/operators/babylon_node/installation_guide-version-testnet.html index c36f8e8b..473c66bf 100644 --- a/static/remote-docs/operators/babylon_node/installation_guide-version-testnet.html +++ b/static/remote-docs/operators/babylon_node/installation_guide-version-testnet.html @@ -50,7 +50,7 @@

      1. Install Babylon Binary

      # tag corresponds to the version of the software # you want to install -- depends on which # height you sync from -git checkout v1.0.0-rc.6-fix +git checkout v2.3.1 # we use this to ensure that the testnet-specific upgrade data # are included in the binary BABYLON_BUILD_OPTIONS="testnet" make install @@ -63,7 +63,7 @@

      1. Install Babylon Binary

      You can verify your installation by executing the version command:

      babylond version
      -v1.0.0-rc.6-fix
      +v2.3.1
       

      If your shell cannot find the installed binary, make sure $GOPATH/bin is in your shell's $PATH. Use the following command to add it to your profile, @@ -74,7 +74,7 @@

      1. Install Babylon Binary

      2. Set up your node, home directory, and configuration

      In this section we will initialize your node and create the necessary configuration directory through the init command.

      -
      babylond init <moniker> --chain-id bbn-test-5 --home <path>
      +
      babylond init <moniker> --chain-id bbn-test-6 --home <path>
       

      Parameters:

        @@ -163,7 +163,7 @@

        2. Set up your node, home directory, and configuration

        the initial state of the blockchain and is crucial for successfully syncing your node. You can inspect the file here or use the following commands to download it directly:

        -
        wget https://raw.githubusercontent.com/babylonlabs-io/networks/refs/heads/main/bbn-test-5/network-artifacts/genesis.json
        +
        wget https://raw.githubusercontent.com/babylonlabs-io/networks/refs/heads/main/bbn-test-6/network-artifacts/genesis.json
         mv genesis.json <path>/config/genesis.json # You must insert the home directory of your node
         

        3. Prepare for sync

        @@ -181,11 +181,11 @@

        3.1. Sync through a network snapshot

        and import this snapshot to quickly reach a recent block height.

        You can obtain the network snapshot here.

        To extract the snapshot, utilize the following command:

        -
        tar -xvf bbn-test-5.tar.gz -C <path>
        +
        tar -xvf bbn-test-6.tar.gz -C <path>
         

        Parameters:

          -
        • bbn-test-5.tar.gz: Name of the compressed blockchain snapshot file
        • +
        • bbn-test-6.tar.gz: Name of the compressed blockchain snapshot file
        • <path> : Your node's home directory

        After importing the state, you can now start your node as specified in section @@ -207,7 +207,7 @@

        3.2. Sync from scratch

    Your node will sync blocks until it reaches a software upgrade height.

    At that point, you will have to perform the steps matching the corresponding -upgrade height.

    +upgrade height.

    Note: When building the upgrade binary, include the following build flag so that testnet-specific upgrade data are included in the binary:

    BABYLON_BUILD_OPTIONS="testnet" make install
    @@ -216,7 +216,7 @@ 

    3.2. Sync from scratch

    full blockchain.

    4. Start the node

    You can start your node using the following command:

    -
    babylond start --chain-id bbn-test-5 --home <path> --x-crisis-skip-assert-invariants
    +
    babylond start --chain-id bbn-test-6 --home <path>
     

    Parameters: