Skip to content

Commit

Permalink
chore: refactor op e2e tests - part 3 (#181)
Browse files Browse the repository at this point in the history
  • Loading branch information
lesterli authored Dec 3, 2024
1 parent d21b419 commit 01402ac
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 45 deletions.
43 changes: 4 additions & 39 deletions itest/opstackl2/op_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,17 @@
package e2etest_op

import (
"encoding/json"
"testing"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
opcc "github.com/babylonlabs-io/finality-provider/clientcontroller/opstackl2"
e2eutils "github.com/babylonlabs-io/finality-provider/itest"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

// This test case will be removed by the final PR
func TestOpTestManagerSetup(t *testing.T) {
ctm := StartOpL2ConsumerManager(t)
defer ctm.Stop(t)

// setup logger
config := zap.NewDevelopmentConfig()
config.Level = zap.NewAtomicLevelAt(zapcore.Level(zap.DebugLevel))
logger, err := config.Build()
require.NoError(t, err)

// create cosmwasm client
cwConfig := ctm.OpConsumerController.Cfg.ToCosmwasmConfig()
cwClient, err := opcc.NewCwClient(&cwConfig, logger)
require.NoError(t, err)

// query cw contract config
queryMsg := map[string]interface{}{
"config": struct{}{},
}
queryMsgBytes, err := json.Marshal(queryMsg)
require.NoError(t, err)

var queryConfigResponse *wasmtypes.QuerySmartContractStateResponse
require.Eventually(t, func() bool {
queryConfigResponse, err = cwClient.QuerySmartContractState(
ctm.OpConsumerController.Cfg.OPFinalityGadgetAddress,
string(queryMsgBytes),
)
return err == nil
}, e2eutils.EventuallyWaitTimeOut, e2eutils.EventuallyPollTime)
// create and register Babylon FP and OP consumer FP
fps := ctm.setupBabylonAndConsumerFp(t)

var cfgResp Config
err = json.Unmarshal(queryConfigResponse.Data, &cfgResp)
require.NoError(t, err)
t.Logf("Response config query from CW contract: %+v", cfgResp)
require.Equal(t, opConsumerChainId, cfgResp.ConsumerId)
// send a BTC delegation and wait for activation
ctm.delegateBTCAndWaitForActivation(t, fps[0], fps[1])
}
78 changes: 76 additions & 2 deletions itest/opstackl2/op_test_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
bbncfg "github.com/babylonlabs-io/babylon/client/config"
bbntypes "github.com/babylonlabs-io/babylon/types"
bbncc "github.com/babylonlabs-io/finality-provider/clientcontroller/babylon"
opcc "github.com/babylonlabs-io/finality-provider/clientcontroller/opstackl2"
cwclient "github.com/babylonlabs-io/finality-provider/cosmwasmclient/client"
Expand All @@ -24,8 +25,10 @@ import (
"github.com/babylonlabs-io/finality-provider/metrics"
"github.com/babylonlabs-io/finality-provider/testutil/log"
"github.com/babylonlabs-io/finality-provider/types"
"github.com/btcsuite/btcd/btcec/v2"
sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/lightningnetwork/lnd/signal"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
Expand All @@ -44,6 +47,9 @@ type OpL2ConsumerTestManager struct {
BaseDir string
BabylonHandler *e2eutils.BabylonNodeHandler
OpConsumerController *opcc.OPStackL2ConsumerController
EOTSServerHandler *e2eutils.EOTSServerHandler
BabylonFpApp *service.FinalityProviderApp
ConsumerFpApp *service.FinalityProviderApp
}

// Config is the config of the OP finality gadget cw contract
Expand Down Expand Up @@ -80,8 +86,7 @@ func StartOpL2ConsumerManager(t *testing.T) *OpL2ConsumerTestManager {
t.Logf(log.Prefix("Register consumer %s to Babylon"), opConsumerChainId)

// create cosmwasm client
// consumer FP config will be defined and updated later
_, opConsumerCfg := createConsumerFpConfig(t, testDir, babylonHandler)
consumerFpCfg, opConsumerCfg := createConsumerFpConfig(t, testDir, babylonHandler)
cwConfig := opConsumerCfg.ToCosmwasmConfig()
cwClient, err := opcc.NewCwClient(&cwConfig, logger)
require.NoError(t, err)
Expand All @@ -93,10 +98,35 @@ func StartOpL2ConsumerManager(t *testing.T) *OpL2ConsumerTestManager {
// update opConsumerCfg with opFinalityGadgetAddress
opConsumerCfg.OPFinalityGadgetAddress = opFinalityGadgetAddress

// update consumer FP config with opConsumerCfg
consumerFpCfg.OPStackL2Config = opConsumerCfg

// create Babylon FP config
babylonFpCfg := createBabylonFpConfig(t, testDir, babylonHandler)

// create shutdown interceptor
shutdownInterceptor, err := signal.Intercept()
require.NoError(t, err)

// create EOTS handler and EOTS gRPC clients for Babylon and consumer
eotsHandler, EOTSClients := base_test_manager.StartEotsManagers(t, logger, testDir, babylonFpCfg, consumerFpCfg, &shutdownInterceptor)

// create Babylon consumer controller
babylonConsumerController, err := bbncc.NewBabylonConsumerController(babylonFpCfg.BabylonConfig, &babylonFpCfg.BTCNetParams, logger)
require.NoError(t, err)

// create and start Babylon FP app
babylonFpApp := base_test_manager.CreateAndStartFpApp(t, logger, babylonFpCfg, babylonConsumerController, EOTSClients[0])
t.Log(log.Prefix("Started Babylon FP App"))

// create op consumer controller
opConsumerController, err := opcc.NewOPStackL2ConsumerController(opConsumerCfg, logger)
require.NoError(t, err)

// create and start consumer FP app
consumerFpApp := base_test_manager.CreateAndStartFpApp(t, logger, consumerFpCfg, opConsumerController, EOTSClients[1])
t.Log(log.Prefix("Started Consumer FP App"))

ctm := &OpL2ConsumerTestManager{
BaseTestManager: BaseTestManager{
BBNClient: babylonController,
Expand All @@ -106,6 +136,9 @@ func StartOpL2ConsumerManager(t *testing.T) *OpL2ConsumerTestManager {
BaseDir: testDir,
BabylonHandler: babylonHandler,
OpConsumerController: opConsumerController,
EOTSServerHandler: eotsHandler,
BabylonFpApp: babylonFpApp,
ConsumerFpApp: consumerFpApp,
}

return ctm
Expand Down Expand Up @@ -278,6 +311,47 @@ func deployCwContract(t *testing.T, cwClient *cwclient.Client) string {
return listContractsResponse.Contracts[0]
}

func (ctm *OpL2ConsumerTestManager) setupBabylonAndConsumerFp(t *testing.T) []*bbntypes.BIP340PubKey {
// create and register Babylon FP
babylonFpPk := base_test_manager.CreateAndRegisterFinalityProvider(t, ctm.BabylonFpApp, e2eutils.ChainID)
t.Logf(log.Prefix("Registered Finality Provider %s for %s"), babylonFpPk.MarshalHex(), e2eutils.ChainID)

// wait for Babylon FP registration
require.Eventually(t, func() bool {
_, err := ctm.BBNClient.QueryFinalityProviders()
return err == nil
}, e2eutils.EventuallyWaitTimeOut, e2eutils.EventuallyPollTime, "Failed to wait for Babylon FP registration")

// create and register consumer FP
consumerFpPk := base_test_manager.CreateAndRegisterFinalityProvider(t, ctm.ConsumerFpApp, opConsumerChainId)
t.Logf(log.Prefix("Registered Finality Provider %s for %s"), consumerFpPk.MarshalHex(), opConsumerChainId)

// wait for consumer FP registration
require.Eventually(t, func() bool {
_, err := ctm.BBNClient.QueryConsumerFinalityProviders(opConsumerChainId)
return err == nil
}, e2eutils.EventuallyWaitTimeOut, e2eutils.EventuallyPollTime, "Failed to wait for consumer FP registration")

return []*bbntypes.BIP340PubKey{babylonFpPk, consumerFpPk}
}

func (ctm *OpL2ConsumerTestManager) delegateBTCAndWaitForActivation(t *testing.T, babylonFpPk *bbntypes.BIP340PubKey, consumerFpPk *bbntypes.BIP340PubKey) {
// send a BTC delegation
ctm.InsertBTCDelegation(t, []*btcec.PublicKey{babylonFpPk.MustToBTCPK(), consumerFpPk.MustToBTCPK()},
e2eutils.StakingTime, e2eutils.StakingAmount)

// check the BTC delegation is pending
delsResp := ctm.WaitForNPendingDels(t, 1)
del, err := e2eutils.ParseRespBTCDelToBTCDel(delsResp[0])
require.NoError(t, err)

// send covenant sigs
ctm.InsertCovenantSigForDelegation(t, del)

// check the BTC delegation is active
ctm.WaitForNActiveDels(t, 1)
}

func (ctm *OpL2ConsumerTestManager) Stop(t *testing.T) {
t.Log("Stopping test manager")
var err error
Expand Down
109 changes: 105 additions & 4 deletions itest/test-manager/base_test_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package test_manager

import (
"encoding/hex"
"fmt"
"math/rand"
"path/filepath"
"testing"
"time"

sdkmath "cosmossdk.io/math"
"github.com/babylonlabs-io/babylon/btcstaking"
txformat "github.com/babylonlabs-io/babylon/btctxformatter"
asig "github.com/babylonlabs-io/babylon/crypto/schnorr-adaptor-signature"
Expand All @@ -15,17 +18,24 @@ import (
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
"github.com/babylonlabs-io/finality-provider/clientcontroller/api"
bbncc "github.com/babylonlabs-io/finality-provider/clientcontroller/babylon"
"github.com/babylonlabs-io/finality-provider/eotsmanager/client"
eotsclient "github.com/babylonlabs-io/finality-provider/eotsmanager/client"
eotsconfig "github.com/babylonlabs-io/finality-provider/eotsmanager/config"
fpcfg "github.com/babylonlabs-io/finality-provider/finality-provider/config"
"github.com/babylonlabs-io/finality-provider/finality-provider/service"
e2eutils "github.com/babylonlabs-io/finality-provider/itest"
"github.com/babylonlabs-io/finality-provider/metrics"
"github.com/babylonlabs-io/finality-provider/types"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/wire"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkquerytypes "github.com/cosmos/cosmos-sdk/types/query"
"github.com/lightningnetwork/lnd/signal"
"github.com/stretchr/testify/require"

bbncc "github.com/babylonlabs-io/finality-provider/clientcontroller/babylon"
"github.com/babylonlabs-io/finality-provider/finality-provider/service"
"github.com/babylonlabs-io/finality-provider/types"
"go.uber.org/zap"
)

type BaseTestManager struct {
Expand Down Expand Up @@ -533,3 +543,94 @@ func (tm *BaseTestManager) FinalizeUntilEpoch(t *testing.T, epoch uint64) {

t.Logf("epoch %d is finalised", epoch)
}

func StartEotsManagers(
t *testing.T,
logger *zap.Logger,
testDir string,
babylonFpCfg *fpcfg.Config,
consumerFpCfg *fpcfg.Config,
shutdownInterceptor *signal.Interceptor,
) (*e2eutils.EOTSServerHandler, []*eotsclient.EOTSManagerGRpcClient) {
fpCfgs := []*fpcfg.Config{babylonFpCfg, consumerFpCfg}
eotsClients := make([]*eotsclient.EOTSManagerGRpcClient, len(fpCfgs))
eotsHomeDirs := []string{filepath.Join(testDir, "babylon-eots-home"), filepath.Join(testDir, "consumer-eots-home")}
eotsConfigs := make([]*eotsconfig.Config, len(fpCfgs))
for i := 0; i < len(fpCfgs); i++ {
eotsCfg := eotsconfig.DefaultConfigWithHomePathAndPorts(
eotsHomeDirs[i],
eotsconfig.DefaultRPCPort+i,
metrics.DefaultEotsConfig().Port+i,
)
eotsConfigs[i] = eotsCfg
}

eh := e2eutils.NewEOTSServerHandlerMultiFP(t, logger, eotsConfigs, eotsHomeDirs, shutdownInterceptor)
eh.Start()

// create EOTS clients
for i := 0; i < len(fpCfgs); i++ {
// wait for EOTS servers to start
// see https://github.com/babylonchain/finality-provider/pull/517
var eotsCli *eotsclient.EOTSManagerGRpcClient
var err error
require.Eventually(t, func() bool {
eotsCli, err = eotsclient.NewEOTSManagerGRpcClient(fpCfgs[i].EOTSManagerAddress)
if err != nil {
t.Logf("Error creating EOTS client: %v", err)
return false
}
eotsClients[i] = eotsCli
return true
}, 5*time.Second, time.Second, "Failed to create EOTS client")
}
return eh, eotsClients
}

func CreateAndStartFpApp(
t *testing.T,
logger *zap.Logger,
cfg *fpcfg.Config,
cc api.ConsumerController,
eotsCli *client.EOTSManagerGRpcClient,
) *service.FinalityProviderApp {
bc, err := bbncc.NewBabylonController(cfg.BabylonConfig, &cfg.BTCNetParams, logger)
require.NoError(t, err)

fpdb, err := cfg.DatabaseConfig.GetDbBackend()
require.NoError(t, err)

fpApp, err := service.NewFinalityProviderApp(cfg, bc, cc, eotsCli, fpdb, logger)
require.NoError(t, err)

err = fpApp.Start()
require.NoError(t, err)

return fpApp
}

func CreateAndRegisterFinalityProvider(t *testing.T, fpApp *service.FinalityProviderApp, chainId string) *bbntypes.BIP340PubKey {
fpCfg := fpApp.GetConfig()
keyName := fpCfg.BabylonConfig.Key
moniker := fmt.Sprintf("%s-%s", chainId, e2eutils.MonikerPrefix)
commission := sdkmath.LegacyZeroDec()
desc := e2eutils.NewDescription(moniker)

res, err := fpApp.CreateFinalityProvider(
keyName,
chainId,
e2eutils.Passphrase,
e2eutils.HdPath,
nil,
desc,
&commission,
)
require.NoError(t, err)

fpPk, err := bbntypes.NewBIP340PubKeyFromHex(res.FpInfo.BtcPkHex)
require.NoError(t, err)

_, err = fpApp.RegisterFinalityProvider(fpPk.MarshalHex())
require.NoError(t, err)
return fpPk
}

0 comments on commit 01402ac

Please sign in to comment.