Skip to content

Commit

Permalink
add oracle flag & flag checker to msgupdateoracle of opchild (#105)
Browse files Browse the repository at this point in the history
* add oracle flag & flag checker to msgupdateoracle of opchild

* update launch cmd

* fix reflect ptr

* add more prompt

---------

Co-authored-by: beer-1 <[email protected]>
  • Loading branch information
sh-cha and beer-1 authored Aug 28, 2024
1 parent 7a2cc2e commit a428c7d
Show file tree
Hide file tree
Showing 17 changed files with 2,052 additions and 397 deletions.
1,304 changes: 1,154 additions & 150 deletions api/opinit/ophost/v1/tx.pulsar.go

Large diffs are not rendered by default.

181 changes: 123 additions & 58 deletions api/opinit/ophost/v1/types.pulsar.go

Large diffs are not rendered by default.

13 changes: 4 additions & 9 deletions contrib/launchtools/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,23 @@ func LaunchCmd(
steps []LauncherStepFuncFactory[*Config],
) *cobra.Command {
cmd := &cobra.Command{
Use: "launch [target-chain-id]",
Use: "launch",
Short: "Launch a new instance of the app",
Long: `Launch a new instance of the app. This command will execute a series of steps to
initialize the app and generate the necessary configuration files. The artifacts will be stored in the
specified directory. The command will output the artifacts to stdout too.
Example:
$ launchtools launch mahalo-3 --artifacts-dir ./ --with-config ./config.json
$ launchtools launch --artifacts-dir ./ --with-config ./config.json
`,
Args: cobra.ExactArgs(1),
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
sdk.SetAddrCacheEnabled(false)
defer sdk.SetAddrCacheEnabled(true)

clientCtx := client.GetClientContextFromCmd(cmd)
serverCtx := server.GetServerContextFromCmd(cmd)

targetNetwork := args[0]
if targetNetwork == "" {
return errors.New("target chain id is required")
}

artifactsDir, err := cmd.Flags().GetString(flagArtifactsDir)
if err != nil {
return errors.Wrap(err, "failed to get artifacts flag")
Expand All @@ -62,7 +57,7 @@ $ launchtools launch mahalo-3 --artifacts-dir ./ --with-config ./config.json
return err
}

if err := config.Finalize(targetNetwork, bufio.NewReader(clientCtx.Input)); err != nil {
if err := config.Finalize(bufio.NewReader(clientCtx.Input)); err != nil {
return errors.Wrap(err, "failed to finalize config")
}

Expand Down
57 changes: 49 additions & 8 deletions contrib/launchtools/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func NewConfig(path string) (*Config, error) {
return ret, nil
}

func (i *Config) Finalize(targetNetwork string, buf *bufio.Reader) error {
func (i *Config) Finalize(buf *bufio.Reader) error {
if i.L1Config == nil {
i.L1Config = &L1Config{}
}
Expand All @@ -65,13 +65,13 @@ func (i *Config) Finalize(targetNetwork string, buf *bufio.Reader) error {
}

// finalize all fields
if err := i.L1Config.Finalize(targetNetwork); err != nil {
if err := i.L1Config.Finalize(buf); err != nil {
return err
}
if err := i.L2Config.Finalize(); err != nil {
return err
}
if err := i.OpBridge.Finalize(); err != nil {
if err := i.OpBridge.Finalize(buf); err != nil {
return err
}
if err := i.SystemKeys.Finalize(buf); err != nil {
Expand Down Expand Up @@ -117,15 +117,27 @@ type OpBridge struct {

// batch submission setup
BatchSubmissionTarget ophosttypes.BatchInfo_ChainType `json:"batch_submission_target"`

// oracle setup
EnableOracle *bool `json:"enable_oracle,omitempty"`
}

func (opBridge *OpBridge) Finalize() error {
func (opBridge *OpBridge) Finalize(buf *bufio.Reader) error {
if opBridge.OutputSubmissionStartHeight == 0 {
opBridge.OutputSubmissionStartHeight = 1
}

if opBridge.BatchSubmissionTarget == ophosttypes.BatchInfo_CHAIN_TYPE_UNSPECIFIED {
opBridge.BatchSubmissionTarget = ophosttypes.BatchInfo_CHAIN_TYPE_INITIA
useCelestia, err := input.GetConfirmation("Use Celestia as DA layer?", buf, os.Stderr)
if err != nil {
return err
}

if useCelestia {
opBridge.BatchSubmissionTarget = ophosttypes.BatchInfo_CHAIN_TYPE_CELESTIA
} else {
opBridge.BatchSubmissionTarget = ophosttypes.BatchInfo_CHAIN_TYPE_INITIA
}
}

if opBridge.OutputSubmissionInterval == nil {
Expand All @@ -138,6 +150,15 @@ func (opBridge *OpBridge) Finalize() error {
opBridge.OutputFinalizationPeriod = &period
}

if opBridge.EnableOracle == nil {
enableOracle, err := input.GetConfirmation("Enable oracle?", buf, os.Stderr)
if err != nil {
return err
}

opBridge.EnableOracle = &enableOracle
}

return nil
}

Expand Down Expand Up @@ -205,13 +226,33 @@ type L1Config struct {
GasPrices string `json:"gas_prices,omitempty"`
}

func (l1config *L1Config) Finalize(targetNetwork string) error {
func (l1config *L1Config) Finalize(buf *bufio.Reader) error {
if l1config.ChainID == "" {
l1config.ChainID = targetNetwork
chainID, err := input.GetString("Enter L1 chain id", buf)
if err != nil {
return err
}
l1config.ChainID = chainID
}

if l1config.RPC_URL == "" {
l1config.RPC_URL = fmt.Sprintf("https://rpc.%s.initia.xyz:443", targetNetwork)
defaultRPC := fmt.Sprintf("https://rpc.%s.initia.xyz:443", l1config.ChainID)
promt := fmt.Sprintf("Use default L1 rpc [%s]?", defaultRPC)
useDefault, err := input.GetConfirmation(promt, buf, os.Stderr)
if err != nil {
return err
}

if useDefault {
l1config.RPC_URL = fmt.Sprintf("https://rpc.%s.initia.xyz:443", l1config.ChainID)
} else {
rpcURL, err := input.GetString("Enter L1 rpc url", buf)
if err != nil {
return err
}

l1config.RPC_URL = rpcURL
}
}

if l1config.GasPrices == "" {
Expand Down
3 changes: 3 additions & 0 deletions contrib/launchtools/steps/opbridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func InitializeOpBridge(
*config.OpBridge.OutputSubmissionInterval,
*config.OpBridge.OutputFinalizationPeriod,
config.OpBridge.OutputSubmissionStartHeight,
*config.OpBridge.EnableOracle,
)

ctx.Logger().Info("creating op bridge...", "message", createOpBridgeMessage.String())
Expand Down Expand Up @@ -112,6 +113,7 @@ func createOpBridge(
submissionInterval time.Duration,
finalizationPeriod time.Duration,
submissionStartHeight uint64,
enableOracle bool,
) (*ophosttypes.MsgCreateBridge, error) {
// generate ophosthooktypes.PermsMetadata
// assume that all channels in IBC keeper need to be permitted on OPChild
Expand Down Expand Up @@ -144,6 +146,7 @@ func createOpBridge(
FinalizationPeriod: finalizationPeriod,
SubmissionStartHeight: submissionStartHeight,
Metadata: permsMetadataJSON,
OracleEnabled: enableOracle,
},
), nil
}
17 changes: 16 additions & 1 deletion proto/opinit/ophost/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ message MsgUpdateBatchInfo {
option (amino.name) = "ophost/MsgUpdateBatchInfo";

// authority is the address that controls the module (defaults to x/gov unless overwritten)
// or the current challenger address.
// or the current proposer address.
string authority = 1 [(gogoproto.moretags) = "yaml:\"authority\"", (cosmos_proto.scalar) = "cosmos.AddressString"];
uint64 bridge_id = 2 [(gogoproto.moretags) = "yaml:\"bridge_id\""];
BatchInfo new_batch_info = 3
Expand All @@ -263,6 +263,21 @@ message MsgUpdateBatchInfoResponse {
uint64 l2_block_number = 2;
}

// MsgUpdateOracleFlag is a message to change oracle config
message MsgUpdateOracleConfig {
option (cosmos.msg.v1.signer) = "authority";
option (amino.name) = "ophost/MsgUpdateOracleConfig";

// authority is the address that controls the module (defaults to x/gov unless overwritten)
// or the current proposer address.
string authority = 1 [(gogoproto.moretags) = "yaml:\"authority\"", (cosmos_proto.scalar) = "cosmos.AddressString"];
uint64 bridge_id = 2 [(gogoproto.moretags) = "yaml:\"bridge_id\""];
bool oracle_enabled = 3 [(gogoproto.moretags) = "yaml:\"oracle_enabled\""];
}

// MsgUpdateOracleFlagResponse returns a message handle result.
message MsgUpdateOracleConfigResponse {}

// MsgUpdateMetadata is a message to change metadata
message MsgUpdateMetadata {
option (cosmos.msg.v1.signer) = "authority";
Expand Down
6 changes: 5 additions & 1 deletion proto/opinit/ophost/v1/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ message BridgeConfig {
];
// The the first l2 block will be recorded on l1.
uint64 submission_start_height = 6;

// oracle_enabled is a flag to enable oracle.
bool oracle_enabled = 7;

// Normally it is IBC channelID for permissioned IBC relayer.
bytes metadata = 7;
bytes metadata = 8;
}

// BatchInfo defines the set of batch information.
Expand Down
11 changes: 10 additions & 1 deletion x/opchild/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,16 @@ func (ms MsgServer) UpdateOracle(ctx context.Context, req *types.MsgUpdateOracle
return nil, err
}

err := ms.Keeper.ApplyOracleUpdate(ctx, req.Height, req.Data)
// config check
info, err := ms.Keeper.BridgeInfo.Get(ctx)
if err != nil {
return nil, err
}
if !info.BridgeConfig.OracleEnabled {
return nil, types.ErrOracleDisabled
}

err = ms.Keeper.ApplyOracleUpdate(ctx, req.Height, req.Data)
if err != nil {
return nil, err
}
Expand Down
24 changes: 24 additions & 0 deletions x/opchild/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ func Test_MsgServer_UpdateOracle(t *testing.T) {
bridgeInfo := types.BridgeInfo{
L1ChainId: defaultHostChainId,
L1ClientId: defaultClientId,
BridgeConfig: ophosttypes.BridgeConfig{
OracleEnabled: true,
},
}
err := opchildKeeper.BridgeInfo.Set(ctx, bridgeInfo)
require.NoError(t, err)
Expand Down Expand Up @@ -621,3 +624,24 @@ func Test_MsgServer_UpdateOracle(t *testing.T) {
_, err = ms.UpdateOracle(ctx, types.NewMsgUpdateOracle(addrsStr[1], 11, extCommitBz))
require.Error(t, err)
}

func Test_MsgServer_UpdateOracleFail(t *testing.T) {
ctx, input := createDefaultTestInput(t)
opchildKeeper := input.OPChildKeeper

defaultHostChainId := "test-host-1"
defaultClientId := "test-client-id"
bridgeInfo := types.BridgeInfo{
L1ChainId: defaultHostChainId,
L1ClientId: defaultClientId,
BridgeConfig: ophosttypes.BridgeConfig{
OracleEnabled: false,
},
}
err := opchildKeeper.BridgeInfo.Set(ctx, bridgeInfo)
require.NoError(t, err)

ms := keeper.NewMsgServerImpl(opchildKeeper)
_, err = ms.UpdateOracle(ctx, types.NewMsgUpdateOracle(addrsStr[0], 11, []byte{}))
require.EqualError(t, err, types.ErrOracleDisabled.Error())
}
3 changes: 2 additions & 1 deletion x/opchild/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ var (
ErrOracleTimestampNotExists = errorsmod.Register(ModuleName, 25, "oracle timestamp does not exist")
ErrInvalidOracleTimestamp = errorsmod.Register(ModuleName, 26, "oracle timestamp is old")
ErrBridgeInfoNotExists = errorsmod.Register(ModuleName, 27, "bridge info does not exist")
ErrOracleDisabled = errorsmod.Register(ModuleName, 28, "oracle is disabled")

// Antehandler error
ErrRedundantTx = errorsmod.Register(ModuleName, 28, "tx messages are all redundant")
ErrRedundantTx = errorsmod.Register(ModuleName, 29, "tx messages are all redundant")
)
31 changes: 31 additions & 0 deletions x/ophost/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func (ms MsgServer) CreateBridge(ctx context.Context, req *types.MsgCreateBridge
sdk.NewAttribute(types.AttributeKeyBatchChainType, req.Config.BatchInfo.ChainType.StringWithoutPrefix()),
sdk.NewAttribute(types.AttributeKeyBatchSubmitter, req.Config.BatchInfo.Submitter),
sdk.NewAttribute(types.AttributeKeyBridgeId, strconv.FormatUint(bridgeId, 10)),
sdk.NewAttribute(types.AttributeKeyOracleEnabled, strconv.FormatBool(req.Config.OracleEnabled)),
))

if err := ms.bridgeHook.BridgeCreated(ctx, bridgeId, req.Config); err != nil {
Expand Down Expand Up @@ -497,6 +498,36 @@ func (ms MsgServer) UpdateBatchInfo(ctx context.Context, req *types.MsgUpdateBat
}, nil
}

func (ms MsgServer) UpdateOracleConfig(ctx context.Context, req *types.MsgUpdateOracleConfig) (*types.MsgUpdateOracleConfigResponse, error) {
if err := req.Validate(ms.authKeeper.AddressCodec()); err != nil {
return nil, err
}

bridgeId := req.BridgeId
config, err := ms.GetBridgeConfig(ctx, bridgeId)
if err != nil {
return nil, err
}

// gov or current proposer can update metadata.
if ms.authority != req.Authority && config.Proposer != req.Authority {
return nil, govtypes.ErrInvalidSigner.Wrapf("invalid authority; expected %s or %s, got %s", ms.authority, config.Proposer, req.Authority)
}

config.OracleEnabled = req.OracleEnabled

if err := ms.SetBridgeConfig(ctx, bridgeId, config); err != nil {
return nil, err
}

sdk.UnwrapSDKContext(ctx).EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeUpdateBatchInfo,
sdk.NewAttribute(types.AttributeKeyBridgeId, strconv.FormatUint(bridgeId, 10)),
sdk.NewAttribute(types.AttributeKeyOracleEnabled, strconv.FormatBool(config.OracleEnabled)),
))
return &types.MsgUpdateOracleConfigResponse{}, nil
}

func (ms MsgServer) UpdateMetadata(ctx context.Context, req *types.MsgUpdateMetadata) (*types.MsgUpdateMetadataResponse, error) {
if err := req.Validate(ms.authKeeper.AddressCodec()); err != nil {
return nil, err
Expand Down
47 changes: 46 additions & 1 deletion x/ophost/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,51 @@ func Test_UpdateBatchInfo(t *testing.T) {
require.Error(t, err)
}

func Test_UpdateOracleConfig(t *testing.T) {
ctx, input := createDefaultTestInput(t)
ms := keeper.NewMsgServerImpl(input.OPHostKeeper)

config := types.BridgeConfig{
Proposer: addrsStr[0],
Challengers: []string{addrsStr[1]},
SubmissionInterval: time.Second * 10,
FinalizationPeriod: time.Second * 60,
SubmissionStartHeight: 1,
Metadata: []byte{1, 2, 3},
BatchInfo: types.BatchInfo{Submitter: addrsStr[0], ChainType: types.BatchInfo_CHAIN_TYPE_INITIA},
OracleEnabled: true,
}

_, err := ms.CreateBridge(ctx, types.NewMsgCreateBridge(addrsStr[0], config))
require.NoError(t, err)

// gov signer
govAddr, err := input.AccountKeeper.AddressCodec().BytesToString(authtypes.NewModuleAddress("gov"))
require.NoError(t, err)
msg := types.NewMsgUpdateOracleConfig(govAddr, 1, false)
_, err = ms.UpdateOracleConfig(ctx, msg)
require.NoError(t, err)
_config, err := ms.GetBridgeConfig(ctx, 1)
require.NoError(t, err)
require.Equal(t, false, _config.OracleEnabled)

// current proposer signer
msg = types.NewMsgUpdateOracleConfig(addrsStr[0], 1, true)
_, err = ms.UpdateOracleConfig(ctx, msg)
require.NoError(t, err)
_config, err = ms.GetBridgeConfig(ctx, 1)
require.NoError(t, err)
require.Equal(t, true, _config.OracleEnabled)

// invalid signer
invalidAddr, err := input.AccountKeeper.AddressCodec().BytesToString(authtypes.NewModuleAddress(types.ModuleName))
require.NoError(t, err)
msg = types.NewMsgUpdateOracleConfig(invalidAddr, 1, false)
require.NoError(t, err)

_, err = ms.UpdateOracleConfig(ctx, msg)
require.Error(t, err)
}
func Test_UpdateMetadata(t *testing.T) {
ctx, input := createDefaultTestInput(t)
ms := keeper.NewMsgServerImpl(input.OPHostKeeper)
Expand Down Expand Up @@ -469,7 +514,7 @@ func Test_UpdateMetadata(t *testing.T) {
require.Equal(t, []byte{4, 5, 6}, _config.Metadata)
require.Equal(t, []byte{4, 5, 6}, input.BridgeHook.metadata)

// current challenger
// current proposer
msg = types.NewMsgUpdateMetadata(addrsStr[0], 1, []byte{7, 8, 9})
_, err = ms.UpdateMetadata(ctx, msg)
require.NoError(t, err)
Expand Down
1 change: 1 addition & 0 deletions x/ophost/types/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ const (
AttributeKeyL2Sequence = "l2_sequence"
AttributeKeyFinalizedOutputIndex = "finalized_output_index"
AttributeKeyFinalizedL2BlockNumber = "finalized_l2_block_number"
AttributeKeyOracleEnabled = "oracle_enabled"
)
Loading

0 comments on commit a428c7d

Please sign in to comment.