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

F/finality contract #49

Merged
merged 11 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*.dll
*.so
*.dylib
# IDE files
.idea

# Test binary, built with `go test -c`
*.test
Expand All @@ -20,4 +22,4 @@ vendor/
# Go workspace file
coverage.txt

demo/build/
demo/build/
1 change: 1 addition & 0 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Params defines the parameters for the x/babylon module.
| ----- | ---- | ----- | ----------- |
| `babylon_contract_address` | [string](#string) | | babylon_contract_address is the address of the Babylon contract |
| `btc_staking_contract_address` | [string](#string) | | btc_staking_contract_address is the address of the BTC staking contract |
| `btc_finality_contract_address` | [string](#string) | | btc_finality_contract_address is the address of the BTC finality contract |
| `max_gas_begin_blocker` | [uint32](#uint32) | | max_gas_begin_blocker defines the maximum gas that can be spent in a contract sudo callback |


Expand Down
1,567 changes: 604 additions & 963 deletions go.work.sum

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion proto/babylonchain/babylon/v1beta1/babylon.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ message Params {
// btc_staking_contract_address is the address of the BTC staking contract
string btc_staking_contract_address = 2
[ (cosmos_proto.scalar) = "cosmos.AddressString" ];
// btc_finality_contract_address is the address of the BTC finality contract
string btc_finality_contract_address = 3
[ (cosmos_proto.scalar) = "cosmos.AddressString" ];
// max_gas_begin_blocker defines the maximum gas that can be spent in a
// contract sudo callback
uint32 max_gas_begin_blocker = 3;
uint32 max_gas_begin_blocker = 4;
}
26 changes: 16 additions & 10 deletions tests/e2e/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,33 @@ func (s *BabylonSDKTestSuite) Test1ContractDeployment() {
s.NotEmpty(providerCli.Chain.ChainID)
s.NotEmpty(consumerContracts.Babylon)
s.NotEmpty(consumerContracts.BTCStaking)
s.NotEmpty(consumerContracts.BTCFinality)

s.ProviderCli = providerCli
s.ConsumerCli = consumerCli
s.ConsumerContract = consumerContracts

// query admin
adminResp, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{"admin": {}})
// query admins
adminRespStaking, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{"admin": {}})
s.NoError(err)
s.Equal(adminResp["admin"], s.ConsumerCli.GetSender().String())
s.Equal(adminRespStaking["admin"], s.ConsumerCli.GetSender().String())
adminRespFinality, err := s.ConsumerCli.Query(s.ConsumerContract.BTCFinality, Query{"admin": {}})
s.NoError(err)
s.Equal(adminRespFinality["admin"], s.ConsumerCli.GetSender().String())

// get Babylon contract address
// get contract addresses
babylonContractAddress := s.ConsumerContract.Babylon.String()
btcStakingContractAddress := s.ConsumerContract.BTCStaking.String()
btcFinalityContractAddress := s.ConsumerContract.BTCFinality.String()

// update the contract address in parameters
msgUpdateParams := &bbntypes.MsgUpdateParams{
Authority: s.ConsumerApp.BabylonKeeper.GetAuthority(),
Params: bbntypes.Params{
MaxGasBeginBlocker: 500_000,
BabylonContractAddress: babylonContractAddress,
BtcStakingContractAddress: btcStakingContractAddress,
MaxGasBeginBlocker: 500_000,
BabylonContractAddress: babylonContractAddress,
BtcStakingContractAddress: btcStakingContractAddress,
BtcFinalityContractAddress: btcFinalityContractAddress,
},
}
s.ConsumerCli.MustExecGovProposal(msgUpdateParams)
Expand All @@ -112,9 +118,9 @@ func (s *BabylonSDKTestSuite) Test1ContractDeployment() {
params := s.ConsumerApp.BabylonKeeper.GetParams(s.ConsumerChain.GetContext())
s.Equal(babylonContractAddress, params.BabylonContractAddress)
s.Equal(btcStakingContractAddress, params.BtcStakingContractAddress)
s.Equal(btcFinalityContractAddress, params.BtcFinalityContractAddress)
}

// TestExample is an example test case
func (s *BabylonSDKTestSuite) Test2MockConsumerFpDelegation() {
// generate headers
headersMsg := types.GenBTCHeadersMsg()
Expand Down Expand Up @@ -165,7 +171,7 @@ func (s *BabylonSDKTestSuite) Test5NextBlock() {
// get current height
height := s.ConsumerChain.GetContext().BlockHeight()
// ensure the current block is not indexed yet
_, err := s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{
_, err := s.ConsumerCli.Query(s.ConsumerContract.BTCFinality, Query{
"block": {
"height": uint64(height),
},
Expand All @@ -176,7 +182,7 @@ func (s *BabylonSDKTestSuite) Test5NextBlock() {
s.ConsumerChain.NextBlock()

// ensure the current block is indexed
_, err = s.ConsumerCli.Query(s.ConsumerContract.BTCStaking, Query{
_, err = s.ConsumerCli.Query(s.ConsumerContract.BTCFinality, Query{
"block": {
"height": uint64(height),
},
Expand Down
24 changes: 20 additions & 4 deletions tests/e2e/test_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ func NewConsumerClient(t *testing.T, chain *ibctesting.TestChain) *TestConsumerC
}

type ConsumerContract struct {
Babylon sdk.AccAddress
BTCStaking sdk.AccAddress
Babylon sdk.AccAddress
BTCStaking sdk.AccAddress
BTCFinality sdk.AccAddress
}

func (p *TestConsumerClient) GetSender() sdk.AccAddress {
Expand All @@ -101,6 +102,7 @@ func (p *TestConsumerClient) GetSender() sdk.AccAddress {
func (p *TestConsumerClient) BootstrapContracts() (*ConsumerContract, error) {
babylonContractWasmId := p.Chain.StoreCodeFile("../testdata/babylon_contract.wasm").CodeID
btcStakingContractWasmId := p.Chain.StoreCodeFile("../testdata/btc_staking.wasm").CodeID
btcFinalityContractWasmId := p.Chain.StoreCodeFile("../testdata/btc_finality.wasm").CodeID

// Instantiate the contract
// TODO: parameterise
Expand All @@ -111,6 +113,13 @@ func (p *TestConsumerClient) BootstrapContracts() (*ConsumerContract, error) {
if err != nil {
return nil, err
}
btcFinalityInitMsg := map[string]interface{}{
"admin": p.GetSender().String(),
}
btcFinalityInitMsgBytes, err := json.Marshal(btcFinalityInitMsg)
if err != nil {
return nil, err
}
initMsg := map[string]interface{}{
"network": "regtest",
"babylon_tag": "01020304",
Expand All @@ -121,6 +130,8 @@ func (p *TestConsumerClient) BootstrapContracts() (*ConsumerContract, error) {
"btc_staking_msg": btcStakingInitMsgBytes,
"consumer_name": "test-consumer",
"consumer_description": "test-consumer-description",
"btc_finality_code_id": btcFinalityContractWasmId,
"btc_finality_msg": btcFinalityInitMsgBytes,
"admin": p.GetSender().String(),
}
initMsgBytes, err := json.Marshal(initMsg)
Expand All @@ -137,10 +148,15 @@ func (p *TestConsumerClient) BootstrapContracts() (*ConsumerContract, error) {
if !ok {
return nil, fmt.Errorf("failed to instantiate BTC staking contract")
}
btcFinalityContractAddr, ok := res["btc_finality"]
if !ok {
return nil, fmt.Errorf("failed to instantiate BTC finality contract")
}

r := ConsumerContract{
Babylon: babylonContractAddr,
BTCStaking: sdk.MustAccAddressFromBech32(btcStakingContractAddr.(string)),
Babylon: babylonContractAddr,
BTCStaking: sdk.MustAccAddressFromBech32(btcStakingContractAddr.(string)),
BTCFinality: sdk.MustAccAddressFromBech32(btcFinalityContractAddr.(string)),
}
p.Contracts = r
return &r, nil
Expand Down
36 changes: 10 additions & 26 deletions tests/scripts/download_release.sh
Original file line number Diff line number Diff line change
@@ -1,41 +1,25 @@
#!/bin/bash
set -o nounset -o pipefail
set -o errexit -o nounset -o pipefail
command -v shellcheck >/dev/null && shellcheck "$0"

OWNER="babylonchain"
OWNER="babylonlabs-io"
REPO="babylon-contract"
CONTRACTS="babylon_contract btc_staking"
CONTRACTS="babylon_contract btc_staking btc_finality"
OUTPUT_FOLDER="$(dirname "$0")/../testdata"

[ -z "$GITHUB_API_TOKEN" ] && echo "Error: Please define GITHUB_API_TOKEN variable." >&2 && exit 1

[ $# -ne 1 ] && echo "Usage: $0 <version>" && exit 1
type curl >&2
type wget >&2

TAG="$1"

GH_API="https://api.github.com"
GH_REPO="$GH_API/repos/$OWNER/$REPO"
GH_TAGS="$GH_REPO/releases/tags/$TAG"
AUTH="Authorization: token $GITHUB_API_TOKEN"

# Validate token
curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }

# Read asset tags
RESPONSE=$(curl -sH "$AUTH" "$GH_TAGS")

for CONTRACT in $CONTRACTS
do
# Get id of the contract
ID=$(echo "$RESPONSE" | grep -C3 "name.:.\+$CONTRACT.wasm" | grep -w id | cut -f1 -d, | awk '{print $2}')

[ -z "$ID" ] && echo "Error: Failed to get asset id, response: $RESPONSE" | awk 'length($0)<100' >&2 && exit 1
GH_ASSET="$GH_REPO/releases/assets/$ID"

# Download asset file
echo -n "Downloading $CONTRACT..." >&2
curl -s -L -H "Authorization: token $GITHUB_API_TOKEN" -H 'Accept: application/octet-stream' "$GH_ASSET" >"$OUTPUT_FOLDER/$CONTRACT.wasm"
echo "$TAG" >"$OUTPUT_FOLDER/version.txt"
FILE="$CONTRACT.wasm.zip"
URL="https://github.com/$OWNER/$REPO/releases/download/$TAG/$FILE"
wget -nv -O "$OUTPUT_FOLDER/$FILE" "$URL"
unzip -p "$OUTPUT_FOLDER/$FILE" >"$OUTPUT_FOLDER/$CONTRACT.wasm"
rm -f "$OUTPUT_FOLDER/$FILE"
echo "done." >&2
done
echo "$TAG" >"$OUTPUT_FOLDER/version.txt"
Binary file modified tests/testdata/babylon_contract.wasm
Binary file not shown.
Binary file added tests/testdata/btc_finality.wasm
Binary file not shown.
Binary file modified tests/testdata/btc_staking.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/testdata/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.9.0-rc.1
v0.10.0-rc.0
37 changes: 31 additions & 6 deletions x/babylon/keeper/wasm.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,37 @@ func (k Keeper) getBTCStakingContractAddr(ctx sdk.Context) sdk.AccAddress {
return addr
}

// SendBeginBlockMsg sends a BeginBlock sudo message to the BTC staking contract via sudo
func (k Keeper) getBTCFinalityContractAddr(ctx sdk.Context) sdk.AccAddress {
// get address of the BTC finality contract
addrStr := k.GetParams(ctx).BtcFinalityContractAddress
if len(addrStr) == 0 {
// the BTC finality contract address is not set yet, skip sending BeginBlockMsg
return nil
}
addr, err := sdk.AccAddressFromBech32(addrStr)
if err != nil {
// Although this is a programming error so we should panic, we emit
// a warning message to minimise the impact on the consumer chain's operation
k.Logger(ctx).Warn("the BTC finality contract address is malformed", "contract", addrStr, "error", err)
return nil
}
if !k.wasm.HasContractInfo(ctx, addr) {
// NOTE: it's possible that the default contract address does not correspond to
// any contract. We emit a warning message rather than panic to minimise the
// impact on the consumer chain's operation
k.Logger(ctx).Warn("the BTC finality contract address is not on-chain", "contract", addrStr)
return nil
}

return addr
}

// SendBeginBlockMsg sends a BeginBlock sudo message to the BTC finality contract via sudo
func (k Keeper) SendBeginBlockMsg(c context.Context) error {
ctx := sdk.UnwrapSDKContext(c)

// try to get and parse BTC staking contract
addr := k.getBTCStakingContractAddr(ctx)
// try to get and parse BTC finality contract
addr := k.getBTCFinalityContractAddr(ctx)
if addr == nil {
return nil
}
Expand All @@ -58,12 +83,12 @@ func (k Keeper) SendBeginBlockMsg(c context.Context) error {
return k.doSudoCall(ctx, addr, msg)
}

// SendEndBlockMsg sends a EndBlock sudo message to the BTC staking contract via sudo
// SendEndBlockMsg sends a EndBlock sudo message to the BTC finality contract via sudo
func (k Keeper) SendEndBlockMsg(c context.Context) error {
ctx := sdk.UnwrapSDKContext(c)

// try to get and parse BTC staking contract
addr := k.getBTCStakingContractAddr(ctx)
// try to get and parse BTC finality contract
addr := k.getBTCFinalityContractAddr(ctx)
if addr == nil {
return nil
}
Expand Down
Loading
Loading