Skip to content

Commit

Permalink
Merge pull request #41 from babylonchain/release/v0.2.0
Browse files Browse the repository at this point in the history
Release/v0.2.0
  • Loading branch information
KonradStaniec authored Jun 7, 2024
2 parents ab14fc8 + 3c29492 commit 1f17f23
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 452 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
resource_class: large
steps:
- go/install:
version: "1.21.4"
version: "1.22.3"
- checkout
- run:
name: Print Go environment
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.21-alpine as builder
FROM golang:1.22.3-alpine as builder

# Version to build. Default is the Git HEAD.
ARG VERSION="HEAD"
Expand Down
2 changes: 1 addition & 1 deletion cmd/processFailedTxCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var processFailedTxCmd = &cobra.Command{
return err
}

parsedGlobalParams, err := services.NewGlobalParams(globalParamPath)
parsedGlobalParams, err := services.NewVersionedParamsRetriever(globalParamPath)

if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/unbondCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var runUnbondingPipelineCmd = &cobra.Command{
return err
}

parsedGlobalParams, err := services.NewGlobalParams(globalParamPath)
parsedGlobalParams, err := services.NewVersionedParamsRetriever(globalParamPath)

if err != nil {
return err
Expand Down
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module github.com/babylonchain/cli-tools

go 1.21.6
go 1.22.3

toolchain go1.22.4

require (
github.com/babylonchain/babylon v0.8.6-0.20240426101001-7778c798e236
Expand Down Expand Up @@ -48,6 +50,7 @@ require (

require (
github.com/babylonchain/covenant-signer v0.1.2
github.com/babylonchain/networks/parameters v0.2.0
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
github.com/btcsuite/btcwallet/wallet/txauthor v1.3.4
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
Expand Down Expand Up @@ -324,4 +327,4 @@ require (
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/babylonchain/covenant-signer => github.com/babylonchain/covenant-signer v0.1.2
replace github.com/babylonchain/covenant-signer => github.com/babylonchain/covenant-signer-private v0.2.0
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,10 @@ github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/babylonchain/babylon v0.8.6-0.20240426101001-7778c798e236 h1:Ydna4VcP56xu1+zdgygqHdSCeMduZjuznVhr4exO5do=
github.com/babylonchain/babylon v0.8.6-0.20240426101001-7778c798e236/go.mod h1:lfeASLNJgcUsX7LEns3HRUv0k+MjzcB2q2AMasfz38M=
github.com/babylonchain/covenant-signer v0.1.2 h1:MaiMG2Rouw+wsA4PhWUtx9/WCYh0Y9r1rMENvzYs8zY=
github.com/babylonchain/covenant-signer v0.1.2/go.mod h1:alX7NoDE2m7gW4O17hLAsluU30P0XaP5RlThAco8Y9Q=
github.com/babylonchain/covenant-signer-private v0.2.0 h1:/Z6o9KLDSSHz0A3M/bUKzTjSr7pKX6cIG36tRE/4UzQ=
github.com/babylonchain/covenant-signer-private v0.2.0/go.mod h1:eJOoz//rsRCCrAhop+/EqXcnsEgPEy+T8LO7ak6dBHo=
github.com/babylonchain/networks/parameters v0.2.0 h1:f3e1MwMFm33mIKji7AgQk39aO9YIfbCbbjXtQHEQ99E=
github.com/babylonchain/networks/parameters v0.2.0/go.mod h1:nejhvrL7Iwh5Vunvkg7pnomQZlHnyNzOY9lQaDp6tOA=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
Expand Down
298 changes: 8 additions & 290 deletions internal/services/global_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,306 +2,24 @@ package services

import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"math"
"os"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"

"github.com/babylonchain/babylon/btcstaking"
"github.com/babylonchain/networks/parameters/parser"
)

func checkPositive(value uint64) error {
if value == 0 {
return fmt.Errorf("value must be positive")
}
return nil
}

func parseTimeLockValue(timelock uint64) (uint16, error) {
if timelock > math.MaxUint16 {
return 0, fmt.Errorf("timelock value %d is too large. Max: %d", timelock, math.MaxUint16)
}

if err := checkPositive(timelock); err != nil {
return 0, fmt.Errorf("invalid timelock value: %w", err)
}

return uint16(timelock), nil
}

func parseConfirmationDepthValue(confirmationDepth uint64) (uint16, error) {
if confirmationDepth > math.MaxUint16 {
return 0, fmt.Errorf("confirmation depth value %d is too large. Max: %d", confirmationDepth, math.MaxUint16)
}

if err := checkPositive(confirmationDepth); err != nil {
return 0, fmt.Errorf("invalid confirmation depth value: %w", err)
}

return uint16(confirmationDepth), nil
}

func parseBtcValue(value uint64) (btcutil.Amount, error) {
if value > math.MaxInt64 {
return 0, fmt.Errorf("value %d is too large. Max: %d", value, math.MaxInt64)
}

if err := checkPositive(value); err != nil {
return 0, fmt.Errorf("invalid btc value value: %w", err)
}
// retrun amount in satoshis
return btcutil.Amount(value), nil
type VersionedParamsRetriever struct {
*parser.ParsedGlobalParams
}

func parseUint32(value uint64) (uint32, error) {
if value > math.MaxUint32 {
return 0, fmt.Errorf("value %d is too large. Max: %d", value, math.MaxUint32)
}

if err := checkPositive(value); err != nil {
return 0, fmt.Errorf("invalid value: %w", err)
}

return uint32(value), nil
}

// parseCovenantPubKeyFromHex parses public key string to btc public key
// the input should be 33 bytes
func parseCovenantPubKeyFromHex(pkStr string) (*btcec.PublicKey, error) {
pkBytes, err := hex.DecodeString(pkStr)
func NewVersionedParamsRetriever(path string) (*VersionedParamsRetriever, error) {
parsedGlobalParams, err := parser.NewParsedGlobalParamsFromFile(path)
if err != nil {
return nil, err
}

pk, err := btcec.ParsePubKey(pkBytes)
if err != nil {
return nil, err
}

return pk, nil
return &VersionedParamsRetriever{parsedGlobalParams}, nil
}

var _ ParamsRetriever = (*ParsedGlobalParams)(nil)

type VersionedGlobalParams struct {
Version uint64 `json:"version"`
ActivationHeight uint64 `json:"activation_height"`
StakingCap uint64 `json:"staking_cap"`
Tag string `json:"tag"`
CovenantPks []string `json:"covenant_pks"`
CovenantQuorum uint64 `json:"covenant_quorum"`
UnbondingTime uint64 `json:"unbonding_time"`
UnbondingFee uint64 `json:"unbonding_fee"`
MaxStakingAmount uint64 `json:"max_staking_amount"`
MinStakingAmount uint64 `json:"min_staking_amount"`
MaxStakingTime uint64 `json:"max_staking_time"`
MinStakingTime uint64 `json:"min_staking_time"`
ConfirmationDepth uint64 `json:"confirmation_depth"`
}

type GlobalParams struct {
Versions []*VersionedGlobalParams `json:"versions"`
}

type ParsedGlobalParams struct {
Versions []*ParsedVersionedGlobalParams
}

type ParsedVersionedGlobalParams struct {
Version uint64
ActivationHeight uint64
StakingCap btcutil.Amount
Tag []byte
CovenantPks []*btcec.PublicKey
CovenantQuorum uint32
UnbondingTime uint16
UnbondingFee btcutil.Amount
MaxStakingAmount btcutil.Amount
MinStakingAmount btcutil.Amount
MaxStakingTime uint16
MinStakingTime uint16
ConfirmationDepth uint16
}

func NewGlobalParams(filePath string) (*ParsedGlobalParams, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}

var globalParams GlobalParams
err = json.Unmarshal(data, &globalParams)
if err != nil {
return nil, err
}

parsedGlobalParams, err := ParseGlobalParams(&globalParams)

if err != nil {
return nil, err
}

return parsedGlobalParams, nil
}

func parseVersionedGlobalParams(p *VersionedGlobalParams) (*ParsedVersionedGlobalParams, error) {
tag, err := hex.DecodeString(p.Tag)

if err != nil {
return nil, fmt.Errorf("invalid tag: %w", err)
}

if len(tag) != btcstaking.MagicBytesLen {
return nil, fmt.Errorf("invalid tag length, expected %d, got %d", btcstaking.MagicBytesLen, len(p.Tag))
}

if len(p.CovenantPks) == 0 {
return nil, fmt.Errorf("empty covenant public keys")
}
if p.CovenantQuorum > uint64(len(p.CovenantPks)) {
return nil, fmt.Errorf("covenant quorum cannot be more than the amount of covenants")
}

quroum, err := parseUint32(p.CovenantQuorum)
if err != nil {
return nil, fmt.Errorf("invalid covenant quorum: %w", err)
}

var covenantKeys []*btcec.PublicKey
for _, covPk := range p.CovenantPks {
pk, err := parseCovenantPubKeyFromHex(covPk)
if err != nil {
return nil, fmt.Errorf("invalid covenant public key %s: %w", covPk, err)
}

covenantKeys = append(covenantKeys, pk)
}

maxStakingAmount, err := parseBtcValue(p.MaxStakingAmount)

if err != nil {
return nil, fmt.Errorf("invalid max_staking_amount: %w", err)
}

minStakingAmount, err := parseBtcValue(p.MinStakingAmount)

if err != nil {
return nil, fmt.Errorf("invalid min_staking_amount: %w", err)
}

if maxStakingAmount <= minStakingAmount {
return nil, fmt.Errorf("max-staking-amount must be larger than min-staking-amount")
}

ubTime, err := parseTimeLockValue(p.UnbondingTime)
if err != nil {
return nil, fmt.Errorf("invalid unbonding_time: %w", err)
}

ubFee, err := parseBtcValue(p.UnbondingFee)
if err != nil {
return nil, fmt.Errorf("invalid unbonding_fee: %w", err)
}

maxStakingTime, err := parseTimeLockValue(p.MaxStakingTime)
if err != nil {
return nil, fmt.Errorf("invalid max_staking_time: %w", err)
}

minStakingTime, err := parseTimeLockValue(p.MinStakingTime)
if err != nil {
return nil, fmt.Errorf("invalid min_staking_time: %w", err)
}

// NOTE: Allow config when max-staking-time is equal to min-staking-time, as then
// we can configure a fixed staking time.
if maxStakingTime < minStakingTime {
return nil, fmt.Errorf("max-staking-time must be larger or equalt min-staking-time")
}

confirmationDepth, err := parseConfirmationDepthValue(p.ConfirmationDepth)
if err != nil {
return nil, fmt.Errorf("invalid confirmation_depth: %w", err)
}

stakingCap, err := parseBtcValue(p.StakingCap)
if err != nil {
return nil, fmt.Errorf("invalid staking_cap: %w", err)
}

return &ParsedVersionedGlobalParams{
Version: p.Version,
ActivationHeight: p.ActivationHeight,
StakingCap: stakingCap,
Tag: tag,
CovenantPks: covenantKeys,
CovenantQuorum: quroum,
UnbondingTime: ubTime,
UnbondingFee: ubFee,
MaxStakingAmount: maxStakingAmount,
MinStakingAmount: minStakingAmount,
MaxStakingTime: maxStakingTime,
MinStakingTime: minStakingTime,
ConfirmationDepth: confirmationDepth,
}, nil
}

func ParseGlobalParams(p *GlobalParams) (*ParsedGlobalParams, error) {
if len(p.Versions) == 0 {
return nil, fmt.Errorf("global params must have at least one version")
}
var parsedVersions []*ParsedVersionedGlobalParams

for _, v := range p.Versions {
vCopy := v
cv, err := parseVersionedGlobalParams(vCopy)

if err != nil {
return nil, fmt.Errorf("invalid params with version %d: %w", vCopy.Version, err)
}

// Check latest version
if len(parsedVersions) > 0 {
pv := parsedVersions[len(parsedVersions)-1]

if cv.Version != pv.Version+1 {
return nil, fmt.Errorf("invalid params with version %d. versions should be monotonically increasing by 1", cv.Version)
}
if cv.StakingCap < pv.StakingCap {
return nil, fmt.Errorf("invalid params with version %d. staking cap cannot be decreased in later versions", cv.Version)
}
if cv.ActivationHeight < pv.ActivationHeight {
return nil, fmt.Errorf("invalid params with version %d. activation height cannot be overlapping between earlier and later versions", cv.Version)
}
}

parsedVersions = append(parsedVersions, cv)
}

return &ParsedGlobalParams{
Versions: parsedVersions,
}, nil
}

func (g *ParsedGlobalParams) getVersionedGlobalParamsByHeight(btcHeight uint64) *ParsedVersionedGlobalParams {
// Iterate the list in reverse (i.e. decreasing ActivationHeight)
// and identify the first element that has an activation height below
// the specified BTC height.
for i := len(g.Versions) - 1; i >= 0; i-- {
paramsVersion := g.Versions[i]
if paramsVersion.ActivationHeight <= btcHeight {
return paramsVersion
}
}
return nil
}

func (g *ParsedGlobalParams) ParamsByHeight(_ context.Context, height uint64) (*SystemParams, error) {
versionedParams := g.getVersionedGlobalParamsByHeight(height)
func (g *VersionedParamsRetriever) ParamsByHeight(_ context.Context, height uint64) (*SystemParams, error) {
versionedParams := g.ParsedGlobalParams.GetVersionedGlobalParamsByHeight(height)
if versionedParams == nil {
return nil, fmt.Errorf("no global params for height %d", height)
}
Expand Down
Loading

0 comments on commit 1f17f23

Please sign in to comment.