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

chore: upgrade multibuild #113

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ jobs:
run: |
make test-e2e-cache-btc-staking-pre-approval

e2e-run-upgrade-signet:
e2e-run-upgrade-v1:
needs: [e2e-docker-build-babylon, e2e-docker-build-babylon-before-upgrade, e2e-docker-build-e2e-init-chain]
runs-on: ubuntu-22.04
steps:
Expand Down Expand Up @@ -218,6 +218,6 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: 1.21
- name: Run e2e TestSoftwareUpgradeSignetLaunchTestSuite
- name: Run e2e TestSoftwareUpgradeV1TestnetTestSuite
run: |
sudo make test-e2e-cache-upgrade-signet
sudo make test-e2e-cache-upgrade-v1
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### Misc Improvements

* [#113](https://github.com/babylonlabs-io/babylon/pull/113) Add multibuild binary
for upgrade handler `testnet` and `mainnet`.

## v0.11.0

### State Machine Breaking
Expand Down
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=babylon \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"

# Handles the inclusion of upgrade in binary
ifeq (testnet,$(findstring testnet,$(BABYLON_BUILD_OPTIONS)))
BUILD_TAGS += testnet
else
BUILD_TAGS += mainnet
endif

# DB backend selection
ifeq (cleveldb,$(findstring cleveldb,$(BABYLON_BUILD_OPTIONS)))
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
Expand Down Expand Up @@ -153,7 +160,10 @@ $(BUILD_TARGETS): $(BUILDDIR)/
$(BUILDDIR)/:
mkdir -p $(BUILDDIR)/

.PHONY: build build-linux
build-testnet:
BABYLON_BUILD_OPTIONS=testnet make build

.PHONY: build build-linux build-testnet

mockgen_cmd=go run github.com/golang/mock/mockgen@v1.6.0

Expand Down Expand Up @@ -277,8 +287,8 @@ test-e2e-cache-btc-staking:
test-e2e-cache-btc-staking-pre-approval:
go test -run TestBTCStakingPreApprovalTestSuite -mod=readonly -timeout=60m -v $(PACKAGES_E2E) --tags=e2e

test-e2e-cache-upgrade-signet:
go test -run TestSoftwareUpgradeSignetLaunchTestSuite -mod=readonly -timeout=60m -v $(PACKAGES_E2E) --tags=e2e
test-e2e-cache-upgrade-v1:
go test -run TestSoftwareUpgradeV1TestnetTestSuite -mod=readonly -timeout=60m -v $(PACKAGES_E2E) --tags=e2e

test-sim-nondeterminism:
@echo "Running non-determinism test..."
Expand Down
11 changes: 0 additions & 11 deletions app/e2e_include_upgrades.go

This file was deleted.

20 changes: 20 additions & 0 deletions app/include_upgrade_mainnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//go:build mainnet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember Go allows to build with multiple tags e.g., -tags "mainnet,testnet". Wondering what will happen in this case 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question, in both cases I am replacing the upgrades var from app.go with a new upgrade
So, the question is which one ? 😅

One other point is that in the makefile or it includes mainnet or testnet to the build tags

babylon/Makefile

Lines 82 to 87 in aea173f

# Handles the inclusion of upgrade in binary
ifeq (testnet,$(findstring testnet,$(BABYLON_BUILD_OPTIONS)))
BUILD_TAGS += testnet
else
BUILD_TAGS += mainnet
endif


package app

import (
"github.com/babylonlabs-io/babylon/app/upgrades"
v1 "github.com/babylonlabs-io/babylon/app/upgrades/v1"
"github.com/babylonlabs-io/babylon/app/upgrades/v1/mainnet"
)

// init is used to include v1 upgrade for mainnet data
func init() {
Upgrades = []upgrades.Upgrade{v1.CreateUpgrade(v1.UpgradeDataString{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only place beside tests that imports mainnet and is included only if there is a mainnet in build tags

Makefile sets by default this build tag

BtcStakingParamStr: mainnet.BtcStakingParamStr,
FinalityParamStr: mainnet.FinalityParamStr,
NewBtcHeadersStr: mainnet.NewBtcHeadersStr,
SignedFPsStr: mainnet.SignedFPsStr,
TokensDistributionStr: mainnet.TokensDistributionStr,
})}
}
21 changes: 21 additions & 0 deletions app/include_upgrade_testnet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build testnet

package app

import (
"github.com/babylonlabs-io/babylon/app/upgrades"
v1 "github.com/babylonlabs-io/babylon/app/upgrades/v1"
"github.com/babylonlabs-io/babylon/app/upgrades/v1/testnet"
)

// init is used to include v1 upgrade testnet data
// it is also used for e2e testing
func init() {
Upgrades = []upgrades.Upgrade{v1.CreateUpgrade(v1.UpgradeDataString{
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only place beside tests that imports testnet and is included only if there is a testnet in build tags

BtcStakingParamStr: testnet.BtcStakingParamStr,
FinalityParamStr: testnet.FinalityParamStr,
NewBtcHeadersStr: testnet.NewBtcHeadersStr,
SignedFPsStr: testnet.SignedFPsStr,
TokensDistributionStr: testnet.TokensDistributionStr,
})}
}
5 changes: 4 additions & 1 deletion app/upgrades/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ type Upgrade struct {
UpgradeName string

// CreateUpgradeHandler defines the function that creates an upgrade handler
CreateUpgradeHandler func(*module.Manager, module.Configurator, *keepers.AppKeepers) upgradetypes.UpgradeHandler
CreateUpgradeHandler CreateUpgradeHandler
RafilxTenfen marked this conversation as resolved.
Show resolved Hide resolved

// Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed.
StoreUpgrades store.StoreUpgrades
}

// CreateUpgradeHandler returns a function to run the upgrade handler according to the x/upgrade handler.
type CreateUpgradeHandler func(*module.Manager, module.Configurator, *keepers.AppKeepers) upgradetypes.UpgradeHandler

// Fork defines a struct containing the requisite fields for a non-software upgrade proposal
// Hard Fork at a given height to implement.
// There is one time code that can be added for the start of the Fork, in `BeginForkLogic`.
Expand Down
42 changes: 38 additions & 4 deletions app/upgrades/v1/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,34 @@
# Signet Launch
# Upgrade V1

This folder contains a software upgrade for testing purposes.
DO NOT USE IN PRODUCTION!
Babylon launched as Phase-1 without a cosmos chain running
to collect BTC staking prior to decentralize the finality provider
set of operators. The first upgrade of Babylon chain to start
receiving BTC delegations will include the BTC headers created
during Phase-1 and upgrade, finality providers registered in the
dashboard, tokens distribution for the active users and operators
that participated and need to finish their actions and update of
parameters for `x/finality` and `x/btcstaking` modules.

## Compile signet launch upgrade
## Testnet vs Mainnet

Babylon upgrade data will be different for mainnet and testnet,
finality providers should not use the same keys for mainnet and testnet.
So to register himself and test, the finality providers will use two
different registrations one for mainnet and another for testnet. The
BTC Headers also are different as the Bitcoin mainnet and signet produces
different block headers. So, the upgrade data will be divided into 2
`app/upgrades/v1`:

- `app/upgrades/v1/mainnet` contains the files with JSON string for mainnet.
- `app/upgrades/v1/testnet` contains the files with JSON string for testnet.

## Devnets

Devnets that are only for internal testing should just replace the upgrade
data files in testnet and build the binary with `make build-testnet`. No need
to push the devenet data into the github repository.

## Upgrade data as string

This upgrade loads 5 JSONs from strings in different files.

Expand Down Expand Up @@ -72,3 +97,12 @@ finish their actions, by example:

> This data for token distribution will be built accordingly with the
data collected during Phase-1.

## Building with Upgrade

Upgrade plan is included based on the build tags.
By default the mainnet data is included with the upgrade plan,
so running `make build` already adds the mainnet build tag and
includes the upgrade plan with the mainnet data. If `make build-testnet`
is run, it includes the `testnet` build tag and only includes the
data for testnet in the upgrade plan.
17 changes: 0 additions & 17 deletions app/upgrades/v1/btcstaking_params_test.go

This file was deleted.

28 changes: 28 additions & 0 deletions app/upgrades/v1/data_params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package v1_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/babylonlabs-io/babylon/app"
v1 "github.com/babylonlabs-io/babylon/app/upgrades/v1"
)

func TestHardCodedBtcStakingParamsAreValid(t *testing.T) {
bbnApp := app.NewTmpBabylonApp()
for _, upgradeData := range UpgradeV1Data {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

each unit test now check both testnet and mainnet data files

loadedParamas, err := v1.LoadBtcStakingParamsFromData(bbnApp.AppCodec(), upgradeData.BtcStakingParamStr)
require.NoError(t, err)
require.NoError(t, loadedParamas.Validate())
}
}

func TestHardCodedFinalityParamsAreValid(t *testing.T) {
bbnApp := app.NewTmpBabylonApp()
for _, upgradeData := range UpgradeV1Data {
loadedParamas, err := v1.LoadFinalityParamsFromData(bbnApp.AppCodec(), upgradeData.FinalityParamStr)
require.NoError(t, err)
require.NoError(t, loadedParamas.Validate())
}
}
115 changes: 59 additions & 56 deletions app/upgrades/v1/data_signed_fps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,78 +20,81 @@ import (
)

func TestValidateSignatureSignedFPsFromData(t *testing.T) {
bbnApp := app.NewTmpBabylonApp()
cdc := bbnApp.AppCodec()
// the chain ID in context needs to match the one used when creating the tx signature.
chainID := "bbn-1"
for _, upgradeData := range UpgradeV1Data {
bbnApp := app.NewTmpBabylonApp()
cdc := bbnApp.AppCodec()
// the chain ID in context needs to match the one used when creating the tx signature.
chainID := "bbn-1"

ctx := bbnApp.BaseApp.NewContextLegacy(true, tmproto.Header{Height: 1, ChainID: chainID, Time: time.Now().UTC()})
buff := bytes.NewBufferString(upgradeData.SignedFPsStr)
simulateTx := false

var d v1.DataSignedFps
err := json.Unmarshal(buff.Bytes(), &d)
require.NoError(t, err)

ctx := bbnApp.BaseApp.NewContextLegacy(true, tmproto.Header{Height: 1, ChainID: chainID, Time: time.Now().UTC()})
buff := bytes.NewBufferString(v1.SignedFPsStr)
simulateTx := false
antehandlerSigVerifier := buildAnteHandlerSigVerifier(t, bbnApp)

var d v1.DataSignedFps
err := json.Unmarshal(buff.Bytes(), &d)
require.NoError(t, err)
fpAddrs := make(map[string]interface{}, len(d.SignedTxsFP))
for _, txAny := range d.SignedTxsFP {
txBytes, err := json.Marshal(txAny)
require.NoError(t, err)

antehandlerSigVerifier := buildAnteHandlerSigVerifier(t, bbnApp)
// decodes the transaction
tx, err := bbnApp.TxConfig().TxJSONDecoder()(txBytes)
require.NoError(t, err)

fpAddrs := make(map[string]interface{}, len(d.SignedTxsFP))
for _, txAny := range d.SignedTxsFP {
txBytes, err := json.Marshal(txAny)
require.NoError(t, err)
msgs := tx.GetMsgs()
require.Len(t, msgs, 1)

// decodes the transaction
tx, err := bbnApp.TxConfig().TxJSONDecoder()(txBytes)
require.NoError(t, err)
msg, ok := msgs[0].(*btcstktypes.MsgCreateFinalityProvider)
require.True(t, ok)

msgs := tx.GetMsgs()
require.Len(t, msgs, 1)
_, exist := fpAddrs[msg.Addr]
require.False(t, exist)
fpAddrs[msg.Addr] = nil

msg, ok := msgs[0].(*btcstktypes.MsgCreateFinalityProvider)
require.True(t, ok)
require.NoError(t, msg.ValidateBasic())

_, exist := fpAddrs[msg.Addr]
require.False(t, exist)
fpAddrs[msg.Addr] = nil
// loads messages from the tx, only one message per tx is allowed.
msgsV2, err := tx.GetMsgsV2()
require.NoError(t, err)
require.Len(t, msgsV2, 1)

require.NoError(t, msg.ValidateBasic())
msgV2 := msgsV2[0]
signers, err := cdc.GetMsgV2Signers(msgV2)
require.NoError(t, err)
require.Len(t, signers, 1)

// loads messages from the tx, only one message per tx is allowed.
msgsV2, err := tx.GetMsgsV2()
require.NoError(t, err)
require.Len(t, msgsV2, 1)
// checks that the signer_infos corresponding address in the transaction
// matches the FP address defined.
signerAddrStr, err := cdc.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(signers[0])
require.NoError(t, err)

msgV2 := msgsV2[0]
signers, err := cdc.GetMsgV2Signers(msgV2)
require.NoError(t, err)
require.Len(t, signers, 1)
signerBbnAddr, err := sdk.AccAddressFromBech32(signerAddrStr)
require.NoError(t, err)

// checks that the signer_infos corresponding address in the transaction
// matches the FP address defined.
signerAddrStr, err := cdc.InterfaceRegistry().SigningContext().AddressCodec().BytesToString(signers[0])
require.NoError(t, err)

signerBbnAddr, err := sdk.AccAddressFromBech32(signerAddrStr)
require.NoError(t, err)
require.Equal(t, msg.Addr, signerAddrStr)
// Proof of Possession check only for type BIP340 as expected in the networks registry instructions
require.NoError(t, msg.Pop.VerifyBIP340(signerBbnAddr, msg.BtcPk))

require.Equal(t, msg.Addr, signerAddrStr)
// Proof of Possession check only for type BIP340 as expected in the networks registry instructions
require.NoError(t, msg.Pop.VerifyBIP340(signerBbnAddr, msg.BtcPk))
// creates the account with the signer address and sets the
// sequence and acc number to zero every time, for this reason
// it needs to remove account right after, otherwise new accounts
// would have account number +1 and the signature verification would fail.
acc := bbnApp.AccountKeeper.NewAccountWithAddress(ctx, signerBbnAddr)
require.NoError(t, acc.SetSequence(0))
require.NoError(t, acc.SetAccountNumber(0))
bbnApp.AccountKeeper.SetAccount(ctx, acc)

// creates the account with the signer address and sets the
// sequence and acc number to zero every time, for this reason
// it needs to remove account right after, otherwise new accounts
// would have account number +1 and the signature verification would fail.
acc := bbnApp.AccountKeeper.NewAccountWithAddress(ctx, signerBbnAddr)
require.NoError(t, acc.SetSequence(0))
require.NoError(t, acc.SetAccountNumber(0))
bbnApp.AccountKeeper.SetAccount(ctx, acc)
_, err = antehandlerSigVerifier(ctx, tx, simulateTx)
require.NoError(t, err)

_, err = antehandlerSigVerifier(ctx, tx, simulateTx)
require.NoError(t, err)

bbnApp.AccountKeeper.RemoveAccount(ctx, acc)
bbnApp.AccountKeeper.RemoveAccount(ctx, acc)
}
}

}

func buildAnteHandlerSigVerifier(t *testing.T, bbnApp *app.BabylonApp) sdk.AnteHandler {
Expand Down
Loading