Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: new command phase1 stake to BTC delegation #90

Merged
merged 42 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
580adf8
chore: init command draft
RafilxTenfen Oct 16, 2024
db1692a
chore: add get tx details from tx hash only
RafilxTenfen Oct 16, 2024
d76b933
chore: add initial impl to btc staking from phase 1
RafilxTenfen Nov 5, 2024
7a53e09
Merge branch 'main' of github.com:babylonlabs-io/btc-staker into rafi…
RafilxTenfen Nov 18, 2024
ea40b9f
feat: add cli to create babylon create btc delegation from staking tx
RafilxTenfen Nov 20, 2024
0374d0b
chore: add #90 to changelog
RafilxTenfen Nov 20, 2024
b41aa7a
chore: add stake command to CLI
RafilxTenfen Nov 20, 2024
90d7a95
fix: lint
RafilxTenfen Nov 20, 2024
0fe2886
chore: move cli and manager to separated file
RafilxTenfen Nov 20, 2024
2021de6
chore: manager split btc data
RafilxTenfen Nov 20, 2024
17ebc5d
chore: split func to generate covenant pk
RafilxTenfen Nov 20, 2024
35ec159
chore: add staking of phase 1 test
RafilxTenfen Nov 20, 2024
81b947b
fix: lint
RafilxTenfen Nov 21, 2024
7c745dd
trytest: stuck at including finality provider to running chain
RafilxTenfen Nov 21, 2024
323cdcf
chore: add last err to debug
RafilxTenfen Nov 21, 2024
f57a446
pass json serializable params
KonradStaniec Nov 22, 2024
916d27d
chore: refactory send transaction to phase 1
RafilxTenfen Nov 22, 2024
5dfe472
Merge branch 'rafilx/migrate-stk-to-phase2' of github.com:babylonlabs…
RafilxTenfen Nov 22, 2024
75c02d3
Merge branch 'main' of github.com:babylonlabs-io/btc-staker into rafi…
RafilxTenfen Nov 22, 2024
fdc155e
chore: fix comment
RafilxTenfen Nov 22, 2024
15cb74d
chore: address PR comments
RafilxTenfen Nov 25, 2024
ffff690
chore: rollback rand
RafilxTenfen Nov 25, 2024
503c8a5
chore: use rand previous created
RafilxTenfen Nov 25, 2024
4e7844f
Merge branch 'main' of github.com:babylonlabs-io/btc-staker into rafi…
RafilxTenfen Nov 25, 2024
86b1da9
chore: add possible responde of BTC delegation to consumer
RafilxTenfen Nov 25, 2024
cb95513
chore: try to refactory to receive BTC delegation tx hash
RafilxTenfen Nov 25, 2024
6bea332
chore: moved to use command
RafilxTenfen Nov 25, 2024
0f0e989
chore: add todo
RafilxTenfen Nov 25, 2024
8be6baf
chore: fix lint and allow nonamedreturns
RafilxTenfen Nov 26, 2024
9958f45
chore: remove go routine of mine empty blocks
RafilxTenfen Nov 26, 2024
417d18f
chore: add new field to transaction tracked of tx hash of btc delegation
RafilxTenfen Nov 26, 2024
5eb2542
tryfix: get btc delegation tx hash
RafilxTenfen Nov 26, 2024
28eae57
fix: lint removed unused func
RafilxTenfen Nov 26, 2024
cce90a9
chore: add goroutine to return the cmd request
RafilxTenfen Nov 26, 2024
9f1f0ab
chore: address pr comment and simplified the stking tx migration
RafilxTenfen Nov 27, 2024
d0a1c86
chore: add btc del tx hash to delegation sent to babylon
RafilxTenfen Nov 27, 2024
5e096b1
fix: lint removed unused func
RafilxTenfen Nov 27, 2024
a97cd8c
chore: removed txInclusionHeightFlag flag and getting the block heigh…
RafilxTenfen Nov 28, 2024
0a2eb54
chore: rename BtcDelegationTxHash to BabylonBTCDelegationTxHash
RafilxTenfen Nov 28, 2024
2c7964d
chore: update error msg
RafilxTenfen Nov 28, 2024
325cc3e
fix: lint
RafilxTenfen Nov 28, 2024
f63aab8
chore: add back tx-inclusion-height as optional, if not set queries t…
RafilxTenfen Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ linters:
- nilerr
# - nlreturn # Style wise I personally like this one, todo(lazar): unlax at somepoint, good practice
- noctx
- nonamedreturns
# - nonamedreturns
- nosprintfhostport
- paralleltest
- reassign
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Improvements

* [#90](https://github.com/babylonlabs-io/btc-staker/pull/90) Add CLI to create
babylon BTC delegation from phase-1 BTC staking transaction.
* [#99](https://github.com/babylonlabs-io/btc-staker/pull/99) Bump babylon version
and adapt staker to the changes

Expand Down
1 change: 0 additions & 1 deletion babylonclient/babyloncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,6 @@ func (bc *BabylonController) RegisterFinalityProvider(
Pop: pop,
}

fpPrivKeyBBN.PubKey()
relayerMsgs := bbnclient.ToProviderMsgs([]sdk.Msg{registerMsg})

_, err := bc.bbnClient.SendMessageWithSigner(context.Background(), fpAddr, fpPrivKeyBBN, relayerMsgs)
Expand Down
83 changes: 83 additions & 0 deletions cmd/stakercli/daemon/daemoncommands.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package daemon

import (
"context"
"errors"
"fmt"
"strconv"

"github.com/babylonlabs-io/btc-staker/cmd/stakercli/helpers"
scfg "github.com/babylonlabs-io/btc-staker/stakercfg"
dc "github.com/babylonlabs-io/btc-staker/stakerservice/client"
"github.com/babylonlabs-io/networks/parameters/parser"
"github.com/cometbft/cometbft/libs/os"
"github.com/urfave/cli"
)

Expand All @@ -26,6 +30,7 @@ var DaemonCommands = []cli.Command{
listStakingTransactionsCmd,
withdrawableTransactionsCmd,
unbondCmd,
stakeFromPhase1Cmd,
},
},
}
Expand All @@ -37,6 +42,7 @@ const (
fpPksFlag = "finality-providers-pks"
stakingTransactionHashFlag = "staking-transaction-hash"
stakerAddressFlag = "staker-address"
txInclusionHeightFlag = "tx-inclusion-height"
)

var (
Expand Down Expand Up @@ -133,6 +139,36 @@ var stakeCmd = cli.Command{
Action: stake,
}

var stakeFromPhase1Cmd = cli.Command{
Name: "stake-from-phase1",
ShortName: "stfp1",
Usage: "\nstakercli daemon stake-from-phase1 [fullpath/to/global_parameters.json]" +
" --staking-transaction-hash [txHashHex] --staker-address [btcStakerAddrHex] --tx-inclusion-height [blockHeightTxInclusion]",
Description: "Creates a Babylon BTC delegation transaction from the Phase1 BTC staking transaction",
Flags: []cli.Flag{
cli.StringFlag{
Name: stakingDaemonAddressFlag,
Usage: "full address of the staker daemon in format tcp:://<host>:<port>",
Value: defaultStakingDaemonAddress,
},
cli.StringFlag{
Name: stakingTransactionHashFlag,
Usage: "Hash of original staking transaction in bitcoin hex format",
Required: true,
},
cli.StringFlag{
Name: stakerAddressFlag,
Usage: "BTC address of the staker in hex",
Required: true,
},
cli.Uint64Flag{
Name: txInclusionHeightFlag,
Usage: "Expected BTC height at which transaction was included. This value is important to choose correct global parameters for transaction, if set doesn't query bitcoin to get the block height from txHash",
},
},
Action: stakeFromPhase1TxBTC,
}

var unstakeCmd = cli.Command{
Name: "unstake",
ShortName: "ust",
Expand Down Expand Up @@ -335,6 +371,53 @@ func stake(ctx *cli.Context) error {
return nil
}

func stakeFromPhase1TxBTC(ctx *cli.Context) error {
daemonAddress := ctx.String(stakingDaemonAddressFlag)
client, err := dc.NewStakerServiceJSONRPCClient(daemonAddress)
if err != nil {
return err
}

sctx := context.Background()
stakingTransactionHash := ctx.String(stakingTransactionHashFlag)
if len(stakingTransactionHash) == 0 {
return errors.New("staking tx hash hex is empty")
}

inputGlobalParamsFilePath := ctx.Args().First()
if len(inputGlobalParamsFilePath) == 0 {
return errors.New("json file input is empty")
}

if !os.FileExists(inputGlobalParamsFilePath) {
return fmt.Errorf("json file input %s does not exist", inputGlobalParamsFilePath)
}

globalParams, err := parser.NewParsedGlobalParamsFromFile(inputGlobalParamsFilePath)
if err != nil {
return fmt.Errorf("error parsing file %s: %w", inputGlobalParamsFilePath, err)
}

blockHeighTxInclusion := ctx.Uint64(txInclusionHeightFlag)
if blockHeighTxInclusion == 0 {
resp, err := client.BtcTxDetails(sctx, stakingTransactionHash)
if err != nil {
return fmt.Errorf("error to get btc tx and block data from staking tx %s: %w", stakingTransactionHash, err)
}

blockHeighTxInclusion = uint64(resp.Blk.Height)
}

paramsForHeight := globalParams.GetVersionedGlobalParamsByHeight(blockHeighTxInclusion)
if paramsForHeight == nil {
return fmt.Errorf("error getting param version from global params %s with height %d", inputGlobalParamsFilePath, blockHeighTxInclusion)
}

stakerAddress := ctx.String(stakerAddressFlag)
_, err = client.BtcDelegationFromBtcStakingTx(sctx, stakerAddress, stakingTransactionHash, paramsForHeight)
return err
}

func unstake(ctx *cli.Context) error {
daemonAddress := ctx.String(stakingDaemonAddressFlag)
client, err := dc.NewStakerServiceJSONRPCClient(daemonAddress)
Expand Down
82 changes: 17 additions & 65 deletions cmd/stakercli/transaction/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/urfave/cli"

cmdadmin "github.com/babylonlabs-io/btc-staker/cmd/stakercli/admin"
cmddaemon "github.com/babylonlabs-io/btc-staker/cmd/stakercli/daemon"
"github.com/babylonlabs-io/btc-staker/cmd/stakercli/transaction"
"github.com/babylonlabs-io/btc-staker/itest/testutil"
"github.com/babylonlabs-io/btc-staker/utils"
)

Expand Down Expand Up @@ -71,9 +70,6 @@ var (
Versions: []*parser.VersionedGlobalParams{&defaultParam},
}

//nolint:errchkjson
paramsMarshalled, _ = json.Marshal(globalParams)

parsedGlobalParams, _ = parser.ParseGlobalParams(&globalParams)
lastParams = parsedGlobalParams.Versions[len(parsedGlobalParams.Versions)-1]
)
Expand Down Expand Up @@ -110,36 +106,12 @@ func FuzzFinalityProviderDeposit(f *testing.F) {
fmt.Sprintf("--staking-time=%d", fpStakingTimeLock),
}

app := testApp()
stakingTx := appRunCreatePhase1StakingTx(r, t, app, append(createTxCmdArgs, commonFlags...))
app := testutil.TestApp()
stakingTx := testutil.AppRunCreatePhase1StakingTx(r, t, app, append(createTxCmdArgs, commonFlags...))
require.NotNil(t, stakingTx)
})
}

func appRunCreatePhase1StakingTxWithParams(r *rand.Rand, t *testing.T, app *cli.App, arguments []string) transaction.CreatePhase1StakingTxResponse {
args := []string{"stakercli", "transaction", "create-phase1-staking-transaction-with-params"}
args = append(args, arguments...)
output := appRunWithOutput(r, t, app, args)

var data transaction.CreatePhase1StakingTxResponse
err := json.Unmarshal([]byte(output), &data)
require.NoError(t, err)

return data
}

func appRunCreatePhase1StakingTx(r *rand.Rand, t *testing.T, app *cli.App, arguments []string) transaction.CreatePhase1StakingTxResponse {
args := []string{"stakercli", "transaction", "create-phase1-staking-transaction"}
args = append(args, arguments...)
output := appRunWithOutput(r, t, app, args)

var data transaction.CreatePhase1StakingTxResponse
err := json.Unmarshal([]byte(output), &data)
require.NoError(t, err)

return data
}

func appRunCheckPhase1StakingTxParams(r *rand.Rand, t *testing.T, app *cli.App, arguments []string) transaction.CheckPhase1StakingTxResponse {
args := []string{"stakercli", "transaction", "check-phase1-staking-transaction-params"}
args = append(args, arguments...)
Expand Down Expand Up @@ -192,15 +164,6 @@ func readFromFile(t *testing.T, f *os.File) string {
return buf.String()
}

func testApp() *cli.App {
app := cli.NewApp()
app.Name = "stakercli"
app.Commands = append(app.Commands, cmddaemon.DaemonCommands...)
app.Commands = append(app.Commands, cmdadmin.AdminCommands...)
app.Commands = append(app.Commands, transaction.TransactionCommands...)
return app
}

func appRunCreatePhase1UnbondingTx(r *rand.Rand, t *testing.T, app *cli.App, arguments []string) transaction.CreatePhase1UnbondingTxResponse {
args := []string{"stakercli", "transaction", "create-phase1-unbonding-transaction"}
args = append(args, arguments...)
Expand All @@ -223,19 +186,8 @@ func appRunCreatePhase1WithdrawalTx(r *rand.Rand, t *testing.T, app *cli.App, ar
return data
}

func randRange(_ *rand.Rand, min, max int) int {
return rand.Intn(max+1-min) + min
}

func createTempFileWithParams(f *testing.F) string {
file, err := os.CreateTemp("", "tmpParams-*.json")
require.NoError(f, err)
defer file.Close()
_, err = file.Write(paramsMarshalled)
require.NoError(f, err)
info, err := file.Stat()
require.NoError(f, err)
return filepath.Join(os.TempDir(), info.Name())
func randRange(r *rand.Rand, minV, maxV int) int {
return r.Intn(maxV+1-minV) + minV
}

type StakeParameters struct {
Expand Down Expand Up @@ -280,7 +232,7 @@ func createCustomValidStakeParams(

func TestCheckPhase1StakingTransactionCmd(t *testing.T) {
t.Parallel()
app := testApp()
app := testutil.TestApp()
stakerCliCheckP1StkTx := []string{
"stakercli", "transaction", "check-phase1-staking-transaction",
"--covenant-quorum=1",
Expand Down Expand Up @@ -386,12 +338,12 @@ func TestCheckPhase1StakingTransactionCmd(t *testing.T) {

// Property: Every create should end without error for valid params
func FuzzCreatPhase1Tx(f *testing.F) {
paramsFilePath := createTempFileWithParams(f)
paramsFilePath := testutil.CreateTempFileWithParams(f)

datagen.AddRandomSeedsToFuzzer(f, 5)
f.Fuzz(func(t *testing.T, seed int64) {
r := rand.New(rand.NewSource(seed))
app := testApp()
app := testutil.TestApp()

var args []string
args = append(args, paramsFilePath)
Expand All @@ -400,7 +352,7 @@ func FuzzCreatPhase1Tx(f *testing.F) {

args = append(args, createArgs...)

resCreate := appRunCreatePhase1StakingTxWithParams(
resCreate := testutil.AppRunCreatePhase1StakingTxWithParams(
r, t, app, args,
)
require.NotNil(t, resCreate)
Expand All @@ -412,12 +364,12 @@ func keyToSchnorrHex(key *btcec.PublicKey) string {
}

func FuzzCheckPhase1Tx(f *testing.F) {
paramsFilePath := createTempFileWithParams(f)
paramsFilePath := testutil.CreateTempFileWithParams(f)

datagen.AddRandomSeedsToFuzzer(f, 5)
f.Fuzz(func(t *testing.T, seed int64) {
r := rand.New(rand.NewSource(seed))
app := testApp()
app := testutil.TestApp()

stakerParams, _ := createCustomValidStakeParams(t, r, &globalParams, &chaincfg.RegressionNetParams)

Expand Down Expand Up @@ -462,7 +414,7 @@ func FuzzCheckPhase1Tx(f *testing.F) {
}

func FuzzCreateUnbondingTx(f *testing.F) {
paramsFilePath := createTempFileWithParams(f)
paramsFilePath := testutil.CreateTempFileWithParams(f)

datagen.AddRandomSeedsToFuzzer(f, 10)
f.Fuzz(func(t *testing.T, seed int64) {
Expand Down Expand Up @@ -495,7 +447,7 @@ func FuzzCreateUnbondingTx(f *testing.F) {
fmt.Sprintf("--network=%s", chaincfg.RegressionNetParams.Name),
}

app := testApp()
app := testutil.TestApp()
unbondingTxResponse := appRunCreatePhase1UnbondingTx(r, t, app, createTxCmdArgs)
require.NotNil(t, unbondingTxResponse)
utx, _, err := bbn.NewBTCTxFromHex(unbondingTxResponse.UnbondingTxHex)
Expand All @@ -512,7 +464,7 @@ func FuzzCreateUnbondingTx(f *testing.F) {
}

func FuzzCreateWithdrawalStaking(f *testing.F) {
paramsFilePath := createTempFileWithParams(f)
paramsFilePath := testutil.CreateTempFileWithParams(f)

datagen.AddRandomSeedsToFuzzer(f, 10)
f.Fuzz(func(t *testing.T, seed int64) {
Expand Down Expand Up @@ -557,7 +509,7 @@ func FuzzCreateWithdrawalStaking(f *testing.F) {
fmt.Sprintf("--network=%s", chaincfg.RegressionNetParams.Name),
}

app := testApp()
app := testutil.TestApp()
wr := appRunCreatePhase1WithdrawalTx(r, t, app, createTxCmdArgs)
require.NotNil(t, wr)

Expand Down Expand Up @@ -600,7 +552,7 @@ func FuzzCreateWithdrawalStaking(f *testing.F) {
}

func FuzzCreateWithdrawalUnbonding(f *testing.F) {
paramsFilePath := createTempFileWithParams(f)
paramsFilePath := testutil.CreateTempFileWithParams(f)

datagen.AddRandomSeedsToFuzzer(f, 10)
f.Fuzz(func(t *testing.T, seed int64) {
Expand Down Expand Up @@ -668,7 +620,7 @@ func FuzzCreateWithdrawalUnbonding(f *testing.F) {
fmt.Sprintf("--network=%s", chaincfg.RegressionNetParams.Name),
}

app := testApp()
app := testutil.TestApp()
wr := appRunCreatePhase1WithdrawalTx(r, t, app, createTxCmdArgs)
require.NotNil(t, wr)

Expand Down
3 changes: 2 additions & 1 deletion itest/bitcoind_node_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package e2etest
import (
"encoding/json"
"fmt"
"github.com/ory/dockertest/v3"
"os"
"strconv"
"strings"
"testing"
"time"

"github.com/ory/dockertest/v3"

"github.com/babylonlabs-io/btc-staker/itest/containers"
"github.com/stretchr/testify/require"
)
Expand Down
16 changes: 4 additions & 12 deletions itest/containers/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,11 @@ func (m *Manager) RunBabylondResource(
coventantQuorum int,
baseHeaderHex string,
slashingPkScript string,
covenantPk1 *btcec.PublicKey,
covenantPk2 *btcec.PublicKey,
covenantPk3 *btcec.PublicKey,
covenantPks ...*btcec.PublicKey,
) (*dockertest.Resource, error) {
covenantPks := []*bbn.BIP340PubKey{
bbn.NewBIP340PubKeyFromBTCPK(covenantPk1),
bbn.NewBIP340PubKeyFromBTCPK(covenantPk2),
bbn.NewBIP340PubKeyFromBTCPK(covenantPk3),
}

var covenantPksStr []string
for _, pk := range covenantPks {
covenantPksStr = append(covenantPksStr, pk.MarshalHex())
covenantPksStr := make([]string, len(covenantPks))
for i, cvPk := range covenantPks {
covenantPksStr[i] = bbn.NewBIP340PubKeyFromBTCPK(cvPk).MarshalHex()
}

cmd := []string{
Expand Down
Loading