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: refactor op e2e tests - part 5 #185

Merged
merged 2 commits into from
Dec 4, 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
44 changes: 9 additions & 35 deletions clientcontroller/opstackl2/consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,41 +181,13 @@ func (cc *OPStackL2ConsumerController) SubmitFinalitySig(
proof []byte,
sig *btcec.ModNScalar,
) (*types.TxResponse, error) {
cmtProof := cmtcrypto.Proof{}
if err := cmtProof.Unmarshal(proof); err != nil {
return nil, err
}

msg := SubmitFinalitySignatureMsg{
SubmitFinalitySignature: SubmitFinalitySignatureMsgParams{
FpPubkeyHex: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk).MarshalHex(),
Height: block.Height,
PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRand).MustMarshal(),
Proof: ConvertProof(cmtProof),
BlockHash: block.Hash,
Signature: bbntypes.NewSchnorrEOTSSigFromModNScalar(sig).MustMarshal(),
},
}
payload, err := json.Marshal(msg)
if err != nil {
return nil, err
}
execMsg := &wasmtypes.MsgExecuteContract{
Sender: cc.CwClient.MustGetAddr(),
Contract: cc.Cfg.OPFinalityGadgetAddress,
Msg: payload,
}

res, err := cc.ReliablySendMsg(execMsg, nil, nil)
if err != nil {
return nil, err
}
cc.logger.Debug(
"Successfully submitted finality signature",
zap.Uint64("height", block.Height),
zap.String("block_hash", hex.EncodeToString(block.Hash)),
return cc.SubmitBatchFinalitySigs(
fpPk,
[]*types.BlockInfo{block},
[]*btcec.FieldVal{pubRand},
[][]byte{proof},
[]*btcec.ModNScalar{sig},
)
return &types.TxResponse{TxHash: res.TxHash}, nil
}

// SubmitBatchFinalitySigs submits a batch of finality signatures
Expand All @@ -230,6 +202,7 @@ func (cc *OPStackL2ConsumerController) SubmitBatchFinalitySigs(
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))
fpPkHex := bbntypes.NewBIP340PubKeyFromBTCPK(fpPk).MarshalHex()
for i, block := range blocks {
cmtProof := cmtcrypto.Proof{}
if err := cmtProof.Unmarshal(proofList[i]); err != nil {
Expand All @@ -238,7 +211,7 @@ func (cc *OPStackL2ConsumerController) SubmitBatchFinalitySigs(

msg := SubmitFinalitySignatureMsg{
SubmitFinalitySignature: SubmitFinalitySignatureMsgParams{
FpPubkeyHex: bbntypes.NewBIP340PubKeyFromBTCPK(fpPk).MarshalHex(),
FpPubkeyHex: fpPkHex,
Height: block.Height,
PubRand: bbntypes.NewSchnorrPubRandFromFieldVal(pubRandList[i]).MustMarshal(),
Proof: ConvertProof(cmtProof),
Expand All @@ -264,6 +237,7 @@ func (cc *OPStackL2ConsumerController) SubmitBatchFinalitySigs(
}
cc.logger.Debug(
"Successfully submitted finality signatures in a batch",
zap.String("fp_pk_hex", fpPkHex),
zap.Uint64("start_height", blocks[0].Height),
zap.Uint64("end_height", blocks[len(blocks)-1].Height),
)
Expand Down
59 changes: 59 additions & 0 deletions itest/opstackl2/op_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
package e2etest_op

import (
"encoding/hex"
"encoding/json"
"math/rand"
"strings"
"testing"
"time"

"github.com/babylonlabs-io/finality-provider/testutil"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -42,3 +48,56 @@ func TestPubRandCommitment(t *testing.T) {
consumerCfg := ctm.ConsumerFpApp.GetConfig()
require.Equal(t, uint64(consumerCfg.NumPubRand), pubRand.EndHeight())
}

// TestFinalitySigSubmission tests the consumer controller's function:
// - SubmitBatchFinalitySigs
func TestFinalitySigSubmission(t *testing.T) {
ctm := StartOpL2ConsumerManager(t)
defer ctm.Stop(t)

// create and register Babylon FP and OP consumer FP
fps := ctm.setupBabylonAndConsumerFp(t)

// send a BTC delegation and wait for activation
consumerFpPk := fps[1]
ctm.delegateBTCAndWaitForActivation(t, fps[0], consumerFpPk)

// get the consumer FP instance
consumerFpInstance := ctm.getConsumerFpInstance(t, consumerFpPk)

// commit pub rand with start height 1
// this will call consumer controller's CommitPubRandList function
_, err := consumerFpInstance.CommitPubRand(1)
require.NoError(t, err)

// mock batch of blocks with start height 1 and end height 3
blocks := testutil.GenBlocks(
rand.New(rand.NewSource(time.Now().UnixNano())),
1,
3,
)

// submit finality signature
// this will call consumer controller's SubmitBatchFinalitySignatures function
_, err = consumerFpInstance.SubmitBatchFinalitySignatures(blocks)
require.NoError(t, err)

// fill the query message with the block height and hash
queryMsg := map[string]interface{}{
"block_voters": map[string]interface{}{
"height": blocks[2].Height,
// it requires the block hash without the 0x prefix
"hash": strings.TrimPrefix(hex.EncodeToString(blocks[2].Hash), "0x"),
},
}

// query block_voters from finality gadget CW contract
queryResponse := ctm.queryCwContract(t, queryMsg)
var voters []string
err = json.Unmarshal(queryResponse.Data, &voters)
require.NoError(t, err)

// check the voter, it should be the consumer FP public key
require.Equal(t, 1, len(voters))
require.Equal(t, consumerFpPk.MarshalHex(), voters[0])
}
38 changes: 31 additions & 7 deletions itest/opstackl2/op_test_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,10 @@ type OpL2ConsumerTestManager struct {
ConsumerEOTSClient *client.EOTSManagerGRpcClient
}

// Config is the config of the OP finality gadget cw contract
// It will be removed by the final PR
type Config struct {
ConsumerId string `json:"consumer_id"`
}

// - start Babylon node and wait for it starts
// StartOpL2ConsumerManager
// - starts Babylon node and wait for it starts
// - deploys finality gadget cw contract
// - creates and starts Babylon and consumer FPs without any FP instances
func StartOpL2ConsumerManager(t *testing.T) *OpL2ConsumerTestManager {
// Setup base dir and logger
testDir, err := e2eutils.BaseDir("op-fp-e2e-test")
Expand Down Expand Up @@ -371,6 +368,33 @@ func (ctm *OpL2ConsumerTestManager) delegateBTCAndWaitForActivation(t *testing.T
ctm.WaitForNActiveDels(t, 1)
}

func (ctm *OpL2ConsumerTestManager) queryCwContract(
t *testing.T,
queryMsg map[string]interface{},
) *wasmtypes.QuerySmartContractStateResponse {
logger := ctm.ConsumerFpApp.Logger()

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

// marshal query message
queryMsgBytes, err := json.Marshal(queryMsg)
require.NoError(t, err)

var queryResponse *wasmtypes.QuerySmartContractStateResponse
require.Eventually(t, func() bool {
queryResponse, err = cwClient.QuerySmartContractState(
ctm.OpConsumerController.Cfg.OPFinalityGadgetAddress,
string(queryMsgBytes),
)
return err == nil
}, e2eutils.EventuallyWaitTimeOut, e2eutils.EventuallyPollTime)

return queryResponse
}

func (ctm *OpL2ConsumerTestManager) Stop(t *testing.T) {
t.Log("Stopping test manager")
var err error
Expand Down
Loading