Skip to content

Commit

Permalink
Release v0.3.0 (#525)
Browse files Browse the repository at this point in the history
  • Loading branch information
RafilxTenfen authored Jul 19, 2024
2 parents e13904f + 937cb8c commit 8f83363
Show file tree
Hide file tree
Showing 78 changed files with 3,511 additions and 2,220 deletions.
26 changes: 26 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ orbs:
aws-ecr: circleci/[email protected]

jobs:
check-mock-gen:
machine:
image: ubuntu-2204:2024.01.1
steps:
- checkout
- go/install:
version: "1.21.4"
- go/load-cache:
key: go-mod-v6-{{ checksum "go.sum" }}
- go/mod-download
- go/save-cache:
key: go-mod-v6-{{ checksum "go.sum" }}
path: "/home/circleci/.go_workspace/pkg/mod"
- run:
name: Run make mock-gen
command: |
make mock-gen
- run:
name: Check for uncommitted changes
command: |
if ! git diff --exit-code; then
echo "Uncommitted changes detected. Please run 'make mock-gen' before committing."
exit 1
fi
build_lint_test:
machine:
image: ubuntu-2204:2024.01.1
Expand Down Expand Up @@ -85,6 +110,7 @@ jobs:
workflows:
CI:
jobs:
- check-mock-gen
- build_lint_test
- build_docker:
filters:
Expand Down
7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ RUN go mod download
COPY ./ /go/src/github.com/babylonchain/finality-provider/

# Cosmwasm - Download correct libwasmvm version
RUN WASMVM_VERSION=$(go list -m github.com/CosmWasm/wasmvm | cut -d ' ' -f 2) && \
RUN WASMVM_VERSION=$(grep github.com/CosmWasm/wasmvm go.mod | cut -d' ' -f2) && \
wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/libwasmvm_muslc.$(uname -m).a \
-O /lib/libwasmvm_muslc.a && \
-O /lib/libwasmvm_muslc.$(uname -m).a && \
# verify checksum
wget https://github.com/CosmWasm/wasmvm/releases/download/$WASMVM_VERSION/checksums.txt -O /tmp/checksums.txt && \
sha256sum /lib/libwasmvm_muslc.a | grep $(cat /tmp/checksums.txt | grep libwasmvm_muslc.$(uname -m) | cut -d ' ' -f 1)
sha256sum /lib/libwasmvm_muslc.$(uname -m).a | grep $(cat /tmp/checksums.txt | grep libwasmvm_muslc.$(uname -m) | cut -d ' ' -f 1)

RUN CGO_LDFLAGS="$CGO_LDFLAGS -lstdc++ -lm -lsodium" \
CGO_ENABLED=1 \
Expand All @@ -42,7 +42,6 @@ RUN addgroup --gid 1138 -S finality-provider && adduser --uid 1138 -S finality-p
RUN apk add bash curl jq

COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/fpd /bin/fpd
COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/fpcli /bin/fpcli
COPY --from=builder /go/src/github.com/babylonchain/finality-provider/build/eotsd /bin/eotsd

WORKDIR /home/finality-provider
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ build-docker:

.PHONY: build build-docker

.PHONY: test
test:
go test ./...

Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ The above command will build and install the following binaries to
`$GOPATH/bin`:

- `eotsd`: The daemon program for the EOTS manager.
- `fpd`: The daemon program for the finality-provider.
- `fpcli`: The CLI tool for interacting with the finality-provider daemon.
- `fpd`: The daemon program for the finality-provider with overall commands.

If your shell cannot find the installed binaries, make sure `$GOPATH/bin` is in
the `$PATH` of your shell. Usually these commands will do the job
Expand Down
165 changes: 95 additions & 70 deletions clientcontroller/babylon.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ import (
"time"

sdkErr "cosmossdk.io/errors"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"

"cosmossdk.io/math"
bbnclient "github.com/babylonchain/babylon/client/client"
bbntypes "github.com/babylonchain/babylon/types"
btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types"
btclctypes "github.com/babylonchain/babylon/x/btclightclient/types"
btcstakingtypes "github.com/babylonchain/babylon/x/btcstaking/types"
ckpttypes "github.com/babylonchain/babylon/x/checkpointing/types"
finalitytypes "github.com/babylonchain/babylon/x/finality/types"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
cmtcrypto "github.com/cometbft/cometbft/proto/tendermint/crypto"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkquery "github.com/cosmos/cosmos-sdk/types/query"
sttypes "github.com/cosmos/cosmos-sdk/x/staking/types"
Expand Down Expand Up @@ -76,19 +74,17 @@ func (bc *BabylonController) mustGetTxSigner() string {
}

func (bc *BabylonController) GetKeyAddress() sdk.AccAddress {
// get key address, retrieves address based on key name which is configured in
// cfg *stakercfg.BBNConfig. If this fails, it means we have misconfiguration problem
// get key address, retrieves address based on the key name which is configured in
// cfg *stakercfg.BBNConfig. If this fails, it means we have a misconfiguration problem
// and we should panic.
// This is checked at the start of BabylonController, so if it fails something is really wrong

keyRec, err := bc.bbnClient.GetKeyring().Key(bc.cfg.Key)

if err != nil {
panic(fmt.Sprintf("Failed to get key address: %s", err))
}

addr, err := keyRec.GetAddress()

if err != nil {
panic(fmt.Sprintf("Failed to get key address: %s", err))
}
Expand All @@ -110,55 +106,93 @@ func (bc *BabylonController) reliablySendMsgs(msgs []sdk.Msg, expectedErrs []*sd
}

// RegisterFinalityProvider registers a finality provider via a MsgCreateFinalityProvider to Babylon
// it returns tx hash, registered epoch, and error
// it returns tx hash and error
func (bc *BabylonController) RegisterFinalityProvider(
chainPk []byte,
fpPk *btcec.PublicKey,
pop []byte,
commission *math.LegacyDec,
description []byte,
masterPubRand string,
) (*types.TxResponse, uint64, error) {
var bbnPop btcstakingtypes.ProofOfPossession
) (*types.TxResponse, error) {
var bbnPop btcstakingtypes.ProofOfPossessionBTC
if err := bbnPop.Unmarshal(pop); err != nil {
return nil, 0, fmt.Errorf("invalid proof-of-possession: %w", err)
return nil, fmt.Errorf("invalid proof-of-possession: %w", err)
}

var sdkDescription sttypes.Description
if err := sdkDescription.Unmarshal(description); err != nil {
return nil, 0, fmt.Errorf("invalid description: %w", err)
return nil, fmt.Errorf("invalid description: %w", err)
}

fpAddr := bc.mustGetTxSigner()
msg := &btcstakingtypes.MsgCreateFinalityProvider{
Signer: bc.mustGetTxSigner(),
BabylonPk: &secp256k1.PubKey{Key: chainPk},
BtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk),
Pop: &bbnPop,
Commission: commission,
Description: &sdkDescription,
MasterPubRand: masterPubRand,
Addr: fpAddr,
BtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk),
Pop: &bbnPop,
Commission: commission,
Description: &sdkDescription,
}

res, err := bc.reliablySendMsg(msg, emptyErrs, emptyErrs)
if err != nil {
return nil, 0, err
return nil, err
}

return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil
}

// CommitPubRandList commits a list of Schnorr public randomness via a MsgCommitPubRand to Babylon
// it returns tx hash and error
func (bc *BabylonController) CommitPubRandList(
fpPk *btcec.PublicKey,
startHeight uint64,
numPubRand uint64,
commitment []byte,
sig *schnorr.Signature,
) (*types.TxResponse, error) {
msg := &finalitytypes.MsgCommitPubRandList{
Signer: bc.mustGetTxSigner(),
FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk),
StartHeight: startHeight,
NumPubRand: numPubRand,
Commitment: commitment,
Sig: bbntypes.NewBIP340SignatureFromBTCSig(sig),
}

registeredEpoch, err := bc.QueryFinalityProviderRegisteredEpoch(fpPk)
unrecoverableErrs := []*sdkErr.Error{
finalitytypes.ErrInvalidPubRand,
finalitytypes.ErrTooFewPubRand,
finalitytypes.ErrNoPubRandYet,
btcstakingtypes.ErrFpNotFound,
}

res, err := bc.reliablySendMsg(msg, emptyErrs, unrecoverableErrs)
if err != nil {
return nil, 0, err
return nil, err
}

return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, registeredEpoch, nil
return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil
}

// SubmitFinalitySig submits the finality signature via a MsgAddVote to Babylon
func (bc *BabylonController) SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeight uint64, blockHash []byte, sig *btcec.ModNScalar) (*types.TxResponse, error) {
func (bc *BabylonController) SubmitFinalitySig(
fpPk *btcec.PublicKey,
block *types.BlockInfo,
pubRand *btcec.FieldVal,
proof []byte, // TODO: have a type for proof
sig *btcec.ModNScalar,
) (*types.TxResponse, error) {
cmtProof := cmtcrypto.Proof{}
if err := cmtProof.Unmarshal(proof); err != nil {
return nil, err
}

msg := &finalitytypes.MsgAddFinalitySig{
Signer: bc.mustGetTxSigner(),
FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk),
BlockHeight: blockHeight,
BlockAppHash: blockHash,
BlockHeight: block.Height,
PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRand),
Proof: &cmtProof,
BlockAppHash: block.Hash,
FinalitySig: bbntypes.NewSchnorrEOTSSigFromModNScalar(sig),
}

Expand All @@ -177,17 +211,30 @@ func (bc *BabylonController) SubmitFinalitySig(fpPk *btcec.PublicKey, blockHeigh
}

// SubmitBatchFinalitySigs submits a batch of finality signatures to Babylon
func (bc *BabylonController) SubmitBatchFinalitySigs(fpPk *btcec.PublicKey, blocks []*types.BlockInfo, sigs []*btcec.ModNScalar) (*types.TxResponse, error) {
func (bc *BabylonController) SubmitBatchFinalitySigs(
fpPk *btcec.PublicKey,
blocks []*types.BlockInfo,
pubRandList []*btcec.FieldVal,
proofList [][]byte,
sigs []*btcec.ModNScalar,
) (*types.TxResponse, error) {
if len(blocks) != len(sigs) {
return nil, fmt.Errorf("the number of blocks %v should match the number of finality signatures %v", len(blocks), len(sigs))
}

msgs := make([]sdk.Msg, 0, len(blocks))
for i, b := range blocks {
cmtProof := cmtcrypto.Proof{}
if err := cmtProof.Unmarshal(proofList[i]); err != nil {
return nil, err
}

msg := &finalitytypes.MsgAddFinalitySig{
Signer: bc.mustGetTxSigner(),
FpBtcPk: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk),
BlockHeight: b.Height,
PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRandList[i]),
Proof: &cmtProof,
BlockAppHash: b.Hash,
FinalitySig: bbntypes.NewSchnorrEOTSSigFromModNScalar(sigs[i]),
}
Expand Down Expand Up @@ -227,34 +274,32 @@ func (bc *BabylonController) QueryFinalityProviderVotingPower(fpPk *btcec.Public
blockHeight,
)
if err != nil {
return 0, fmt.Errorf("failed to query the finality provider's voting power at height %d: %w", blockHeight, err)
return 0, fmt.Errorf("failed to query BTC delegations: %w", err)
}

return res.VotingPower, nil
}

// QueryFinalityProviderRegisteredEpoch queries the registered epoch of the finality provider
func (bc *BabylonController) QueryFinalityProviderRegisteredEpoch(fpPk *btcec.PublicKey) (uint64, error) {
res, err := bc.bbnClient.QueryClient.FinalityProvider(
bbntypes.NewBIP340PubKeyFromBTCPK(fpPk).MarshalHex(),
)
if err != nil {
return 0, fmt.Errorf("failed to query finality provider registered epoch: %w", err)
}

return res.FinalityProvider.RegisteredEpoch, nil
}

func (bc *BabylonController) QueryLatestFinalizedBlocks(count uint64) ([]*types.BlockInfo, error) {
return bc.queryLatestBlocks(nil, count, finalitytypes.QueriedBlockStatus_FINALIZED, true)
}

func (bc *BabylonController) QueryLastFinalizedEpoch() (uint64, error) {
resp, err := bc.bbnClient.LatestEpochFromStatus(ckpttypes.Finalized)
// QueryLastCommittedPublicRand returns the last public randomness commitments
func (bc *BabylonController) QueryLastCommittedPublicRand(fpPk *btcec.PublicKey, count uint64) (map[uint64]*finalitytypes.PubRandCommitResponse, error) {
fpBtcPk := bbntypes.NewBIP340PubKeyFromBTCPK(fpPk)

pagination := &sdkquery.PageRequest{
// NOTE: the count is limited by pagination queries
Limit: count,
Reverse: true,
}

res, err := bc.bbnClient.QueryClient.ListPubRandCommit(fpBtcPk.MarshalHex(), pagination)
if err != nil {
return 0, err
return nil, fmt.Errorf("failed to query committed public randomness: %w", err)
}
return resp.RawCheckpoint.EpochNum, nil

return res.PubRandCommitMap, nil
}

func (bc *BabylonController) QueryBlocks(startHeight, endHeight, limit uint64) ([]*types.BlockInfo, error) {
Expand Down Expand Up @@ -359,15 +404,10 @@ func (bc *BabylonController) Close() error {
Implementations for e2e tests only
*/

func (bc *BabylonController) GetBBNClient() *bbnclient.Client {
return bc.bbnClient
}

func (bc *BabylonController) CreateBTCDelegation(
delBabylonPk *secp256k1.PubKey,
delBtcPk *bbntypes.BIP340PubKey,
fpPks []*btcec.PublicKey,
pop *btcstakingtypes.ProofOfPossession,
pop *btcstakingtypes.ProofOfPossessionBTC,
stakingTime uint32,
stakingValue int64,
stakingTxInfo *btcctypes.TransactionInfo,
Expand All @@ -384,8 +424,7 @@ func (bc *BabylonController) CreateBTCDelegation(
fpBtcPks = append(fpBtcPks, *bbntypes.NewBIP340PubKeyFromBTCPK(v))
}
msg := &btcstakingtypes.MsgCreateBTCDelegation{
Signer: bc.mustGetTxSigner(),
BabylonPk: delBabylonPk,
StakerAddr: bc.mustGetTxSigner(),
Pop: pop,
BtcPk: delBtcPk,
FpBtcPkList: fpBtcPks,
Expand Down Expand Up @@ -550,17 +589,3 @@ func (bc *BabylonController) SubmitCovenantSigs(

return &types.TxResponse{TxHash: res.TxHash, Events: res.Events}, nil
}

func (bc *BabylonController) InsertSpvProofs(submitter string, proofs []*btcctypes.BTCSpvProof) (*provider.RelayerTxResponse, error) {
msg := &btcctypes.MsgInsertBTCSpvProof{
Submitter: submitter,
Proofs: proofs,
}

res, err := bc.reliablySendMsg(msg, emptyErrs, emptyErrs)
if err != nil {
return nil, err
}

return res, nil
}
Loading

0 comments on commit 8f83363

Please sign in to comment.