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

Feat/tx update batch info #74

Merged
merged 6 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 5 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
155 changes: 153 additions & 2 deletions cmd/opinitd/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"fmt"
"strings"

"cosmossdk.io/errors"
"github.com/spf13/cobra"
Expand All @@ -23,6 +24,9 @@ import (
"github.com/initia-labs/opinit-bots/provider/child"
"github.com/initia-labs/opinit-bots/types"

opchildtypes "github.com/initia-labs/OPinit/x/opchild/types"
ophosttypes "github.com/initia-labs/OPinit/x/ophost/types"

sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand All @@ -35,6 +39,7 @@ func txCmd(ctx *cmdContext) *cobra.Command {

cmd.AddCommand(
txGrantOracleCmd(ctx),
txUpdateBatchInfoCmd(ctx),
)
return cmd
}
Expand All @@ -54,7 +59,12 @@ func txGrantOracleCmd(baseCtx *cmdContext) *cobra.Command {
baseCtx := types.NewContext(ctx, baseCtx.logger.Named(string(bottypes.BotTypeExecutor)), baseCtx.homePath).
WithErrGrp(errGrp)

account, err := l2BroadcasterAccount(baseCtx, cmd)
cfg, err := getExecutorConfig(baseCtx, cmd)
if err != nil {
return err
}

account, err := l2BroadcasterAccount(baseCtx, cfg)
if err != nil {
return err
}
Expand Down Expand Up @@ -107,7 +117,99 @@ func txGrantOracleCmd(baseCtx *cmdContext) *cobra.Command {
return cmd
}

func l2BroadcasterAccount(ctx types.Context, cmd *cobra.Command) (*broadcaster.BroadcasterAccount, error) {
func txUpdateBatchInfoCmd(baseCtx *cmdContext) *cobra.Command {
cmd := &cobra.Command{
Use: "update-batch-info [chain-type] [new-submitter-address]",
Args: cobra.ExactArgs(2),
Short: "Update batch info with new chain type and new submitter address",
Long: `Update batch info with new chain type and new submitter address.
Before running this command, you need to
(1) register a new key for the new submitter address
(2) update the DA configuration in the executor config.
`,
RunE: func(cmd *cobra.Command, args []string) error {
cmdCtx, botDone := context.WithCancel(cmd.Context())
gracefulShutdown(botDone)

errGrp, ctx := errgroup.WithContext(cmdCtx)

baseCtx := types.NewContext(ctx, baseCtx.logger.Named(string(bottypes.BotTypeExecutor)), baseCtx.homePath).
WithErrGrp(errGrp)

cfg, err := getExecutorConfig(baseCtx, cmd)
if err != nil {
return err
}

chainType := args[0]
newSubmitterAddress := args[1]

err = validateBatchInfoArgs(cfg, chainType, newSubmitterAddress)
if err != nil {
return err
}

bridgeId, err := QueryBridgeId(baseCtx, cfg)
if err != nil {
return err
}

proposerAccount, err := l1ProposerAccount(baseCtx, cfg, bridgeId)
if err != nil {
return err
}

err = proposerAccount.Load(baseCtx)
if err != nil {
return err
}

updateBatchInfoMsg := &ophosttypes.MsgUpdateBatchInfo{
Authority: proposerAccount.GetAddressString(),
BridgeId: bridgeId,
NewBatchInfo: ophosttypes.BatchInfo{
Submitter: newSubmitterAddress,
ChainType: ophosttypes.BatchInfo_ChainType(ophosttypes.BatchInfo_ChainType_value[chainType]),
},
}

txBytes, _, err := proposerAccount.BuildTxWithMsgs(ctx, []sdk.Msg{updateBatchInfoMsg})
if err != nil {
return errors.Wrapf(err, "simulation failed")
}

res, err := proposerAccount.BroadcastTxSync(baseCtx, txBytes)
if err != nil {
// TODO: handle error, may repeat sending tx
return fmt.Errorf("broadcast txs: %w", err)
}
bz, err := json.Marshal(res)
if err != nil {
return err
}
fmt.Println(string(bz))
return nil
},
}

cmd = configFlag(baseCtx.v, cmd)
return cmd
}

func validateBatchInfoArgs(cfg *executortypes.Config, chainType string, newAddress string) error {
chainType = strings.ToUpper(chainType)
if chainType != ophosttypes.BatchInfo_INITIA.String() && chainType != ophosttypes.BatchInfo_CELESTIA.String() {
return fmt.Errorf("supported chain type: %s, %s", ophosttypes.BatchInfo_INITIA.String(), ophosttypes.BatchInfo_CELESTIA.String())
}

_, err := keys.DecodeBech32AccAddr(newAddress, cfg.DANodeConfig().Bech32Prefix)
if err != nil {
return errors.Wrapf(err, "failed to decode address with given bech32 prefix: %s", cfg.DANodeConfig().Bech32Prefix)
}
return nil
}

func getExecutorConfig(ctx types.Context, cmd *cobra.Command) (*executortypes.Config, error) {
configPath, err := getConfigPath(cmd, ctx.HomePath(), string(bottypes.BotTypeExecutor))
if err != nil {
return nil, err
Expand All @@ -119,6 +221,55 @@ func l2BroadcasterAccount(ctx types.Context, cmd *cobra.Command) (*broadcaster.B
return nil, err
}

return cfg, nil
}

func QueryBridgeId(ctx types.Context, cfg *executortypes.Config) (uint64, error) {
l2Config := cfg.L2NodeConfig()
cdc, _, err := child.GetCodec(l2Config.BroadcasterConfig.Bech32Prefix)
if err != nil {
return 0, err
}

l2RpcClient, err := rpcclient.NewRPCClient(cdc, l2Config.RPC)
if err != nil {
return 0, err
}
queryCtx, cancel := rpcclient.GetQueryContext(ctx, 0)
defer cancel()
bridgeInfoResponse, err := opchildtypes.NewQueryClient(l2RpcClient).BridgeInfo(queryCtx, &opchildtypes.QueryBridgeInfoRequest{})
if err != nil {
return 0, errors.Wrap(err, "failed to query opchild bridge info")
}
return bridgeInfoResponse.BridgeInfo.BridgeId, nil
}

func l1ProposerAccount(ctx types.Context, cfg *executortypes.Config, bridgeId uint64) (*broadcaster.BroadcasterAccount, error) {
l1Config := cfg.L1NodeConfig()
broadcasterConfig := l1Config.BroadcasterConfig
cdc, txConfig, err := child.GetCodec(broadcasterConfig.Bech32Prefix)
if err != nil {
return nil, err
}

rpcClient, err := rpcclient.NewRPCClient(cdc, l1Config.RPC)
if err != nil {
return nil, err
}
queryCtx, cancel := rpcclient.GetQueryContext(ctx, 0)
defer cancel()
bridgeResponse, err := ophosttypes.NewQueryClient(rpcClient).Bridge(queryCtx, &ophosttypes.QueryBridgeRequest{BridgeId: bridgeId})
if err != nil {
return nil, errors.Wrap(err, "failed to query ophost bridge info")
}

keyringConfig := broadcastertypes.KeyringConfig{
Address: bridgeResponse.BridgeConfig.Proposer,
}
return broadcaster.NewBroadcasterAccount(ctx, *broadcasterConfig, cdc, txConfig, rpcClient, keyringConfig)
}

func l2BroadcasterAccount(ctx types.Context, cfg *executortypes.Config) (*broadcaster.BroadcasterAccount, error) {
l2Config := cfg.L2NodeConfig()
broadcasterConfig := l2Config.BroadcasterConfig
cdc, txConfig, err := child.GetCodec(broadcasterConfig.Bech32Prefix)
Expand Down
6 changes: 3 additions & 3 deletions e2e/batch_reconstruction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ func TestBatchReconstructionTest(t *testing.T) {
name: "initia with go relayer",
daChainConfig: DAChainConfig{
ChainConfig: *l1ChainConfig,
ChainType: ophosttypes.BatchInfo_CHAIN_TYPE_INITIA,
ChainType: ophosttypes.BatchInfo_INITIA,
},
relayerImpl: ibc.CosmosRly,
},
{
name: "initia with hermes relayer",
daChainConfig: DAChainConfig{
ChainConfig: *l1ChainConfig,
ChainType: ophosttypes.BatchInfo_CHAIN_TYPE_INITIA,
ChainType: ophosttypes.BatchInfo_INITIA,
},
relayerImpl: ibc.Hermes,
},
Expand All @@ -101,7 +101,7 @@ func TestBatchReconstructionTest(t *testing.T) {
NumValidators: 1,
NumFullNodes: 0,
},
ChainType: ophosttypes.BatchInfo_CHAIN_TYPE_CELESTIA,
ChainType: ophosttypes.BatchInfo_CELESTIA,
},
relayerImpl: ibc.CosmosRly,
},
Expand Down
8 changes: 4 additions & 4 deletions e2e/da_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ func (da *DAChain) GetFullNode() *DAChainNode {

func (da *DAChain) QueryBatchData(ctx context.Context) ([][]byte, error) {
switch da.ChainType {
case ophosttypes.BatchInfo_CHAIN_TYPE_INITIA:
case ophosttypes.BatchInfo_INITIA:
return da.QueryInitiaBatchData(ctx)
case ophosttypes.BatchInfo_CHAIN_TYPE_CELESTIA:
case ophosttypes.BatchInfo_CELESTIA:
return da.QueryCelestiaBatchData(ctx)
}
return nil, fmt.Errorf("unsupported chain type")
}

func (da *DAChain) QueryInitiaBatchData(ctx context.Context) ([][]byte, error) {
if da.ChainType != ophosttypes.BatchInfo_CHAIN_TYPE_INITIA {
if da.ChainType != ophosttypes.BatchInfo_INITIA {
return nil, fmt.Errorf("unmatched chain type")
}

Expand Down Expand Up @@ -112,7 +112,7 @@ func (da *DAChain) QueryInitiaBatchData(ctx context.Context) ([][]byte, error) {
}

func (da *DAChain) QueryCelestiaBatchData(ctx context.Context) ([][]byte, error) {
if da.ChainType != ophosttypes.BatchInfo_CHAIN_TYPE_CELESTIA {
if da.ChainType != ophosttypes.BatchInfo_CELESTIA {
return nil, fmt.Errorf("unmatched chain type")
}

Expand Down
33 changes: 28 additions & 5 deletions e2e/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,26 +334,48 @@ type CosmosTx struct {
}

// GrantOraclePermissions grants oracle permissions to the oracle bridge executor.
func (op *DockerOPBot) GrantOraclePermissions(ctx context.Context, oracleBridgeExecutorAddress string) error {
func (op *DockerOPBot) GrantOraclePermissions(ctx context.Context, oracleBridgeExecutorAddress string) (string, error) {
cmd := op.c.GrantOraclePermissions(oracleBridgeExecutorAddress, op.HomeDir())

ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()

res := op.Exec(ctx, cmd, nil)
if res.Err != nil {
return res.Err
return "", res.Err
}

output := CosmosTx{}
err := json.Unmarshal(res.Stdout, &output)
if err != nil {
return err
return "", err
}
if output.Code != 0 {
return fmt.Errorf("transaction failed with code %d: %s", output.Code, output.Log)
return "", fmt.Errorf("transaction failed with code %d: %s", output.Code, output.Log)
}
return nil
return output.Hash, nil
}

func (op *DockerOPBot) UpdateBatchInfo(ctx context.Context, chainType string, newBatchSubmitterAddress string) (string, error) {
cmd := op.c.UpdateBatchInfo(chainType, newBatchSubmitterAddress, op.HomeDir())

ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()

res := op.Exec(ctx, cmd, nil)
if res.Err != nil {
return "", res.Err
}

output := CosmosTx{}
err := json.Unmarshal(res.Stdout, &output)
if err != nil {
return "", err
}
if output.Code != 0 {
return "", fmt.Errorf("transaction failed with code %d: %s", output.Code, output.Log)
}
return output.Hash, nil
}

// Exec executes the command in the bot's container.
Expand Down Expand Up @@ -532,4 +554,5 @@ type OPBotCommander interface {
RestoreKey(chainID, keyName, bech32Prefix, mnemonic, homeDir string) []string
Start(botName string, homeDir string) []string
GrantOraclePermissions(address string, homeDir string) []string
UpdateBatchInfo(chainType string, newBatchSubmitterAddress string, homeDir string) []string
}
28 changes: 14 additions & 14 deletions e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ go 1.22.5

require (
cosmossdk.io/math v1.4.0
github.com/initia-labs/OPinit v0.6.1
github.com/initia-labs/OPinit/api v0.6.0
github.com/cosmos/ibc-go/v8 v8.5.0
github.com/initia-labs/OPinit v0.6.2
github.com/initia-labs/OPinit/api v0.6.2
github.com/initia-labs/opinit-bots v0.1.11
github.com/skip-mev/connect/v2 v2.0.1
github.com/strangelove-ventures/interchaintest/v8 v8.8.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
moul.io/zapfilter v1.7.0
github.com/cosmos/ibc-go/v8 v8.5.0
)

require (
Expand Down Expand Up @@ -48,16 +48,16 @@ require (
cloud.google.com/go/compute/metadata v0.5.0 // indirect
cloud.google.com/go/iam v1.1.12 // indirect
cloud.google.com/go/storage v1.41.0 // indirect
cosmossdk.io/api v0.7.5
cosmossdk.io/api v0.7.6
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/core v0.11.1 // indirect
cosmossdk.io/depinject v1.0.0 // indirect
cosmossdk.io/depinject v1.1.0 // indirect
cosmossdk.io/errors v1.0.1 // indirect
cosmossdk.io/log v1.4.1 // indirect
cosmossdk.io/store v1.1.1 // indirect
cosmossdk.io/x/evidence v0.1.1 // indirect
cosmossdk.io/x/feegrant v0.1.1
cosmossdk.io/x/tx v0.13.5 // indirect
cosmossdk.io/x/tx v0.13.7 // indirect
cosmossdk.io/x/upgrade v0.1.4 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
Expand Down Expand Up @@ -94,13 +94,13 @@ require (
github.com/consensys/bavard v0.1.13 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/cosmos-db v1.0.2 // indirect
github.com/cosmos/cosmos-db v1.1.0 // indirect
github.com/cosmos/cosmos-proto v1.0.0-beta.5
github.com/cosmos/cosmos-sdk v0.50.10
github.com/cosmos/cosmos-sdk v0.50.11
github.com/cosmos/go-bip39 v1.0.0 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/gogoproto v1.7.0
github.com/cosmos/iavl v1.2.0 // indirect
github.com/cosmos/iavl v1.2.2 // indirect
github.com/cosmos/ibc-go/modules/capability v1.0.1 // indirect
github.com/cosmos/ics23/go v0.11.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
Expand All @@ -121,7 +121,7 @@ require (
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
github.com/emicklei/dot v1.6.1 // indirect
github.com/emicklei/dot v1.6.2 // indirect
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
github.com/ethereum/go-ethereum v1.14.9 // indirect
github.com/fatih/color v1.17.0 // indirect
Expand All @@ -142,7 +142,7 @@ require (
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/flatbuffers v2.0.8+incompatible // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/orderedcode v0.0.1 // indirect
Expand Down Expand Up @@ -278,9 +278,9 @@ require (
google.golang.org/api v0.189.0 // indirect
google.golang.org/genproto v0.0.0-20240722135656-d784300faade // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2
google.golang.org/genproto/googleapis/rpc v0.0.0-20240930140551-af27646dc61f // indirect
google.golang.org/grpc v1.67.1 // indirect
google.golang.org/protobuf v1.35.1
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
Expand Down
Loading
Loading