Skip to content

Commit

Permalink
Feat/split oracletx (#45)
Browse files Browse the repository at this point in the history
* find tx using txsearch with tx hash

* change sequence

* add oracle executor account to avoid executor sequence mismatch

* query block header instead of block

* handle tx failed

* remove redunt sequence err

* update readme

* return sender when creating msgs & split msg queue every sender

* set bridge info first

* update authz grant checker

* add sender

* add broadcaster account checker

* sender not set bug fix

* delete debug print

* add sender to pendingtx

* add sender when unmarshalling processed msgs

* remove redundant msg queue allocation

* format

* delete processed msgs from db when simulation failed and error is handled

* change oracle tx sender

* change proof query error (#46)

* enable to query withdrawals that their tree is not finalized yet (#47)

* introduce authz tx msg command (#48)

* introduce authz tx msg command

* update readme

* format

* update evm version

* can disable to relay oracle data by emptying oracle-bridge-executor
  • Loading branch information
sh-cha authored Nov 19, 2024
1 parent 5f2e7de commit 88491e9
Show file tree
Hide file tree
Showing 49 changed files with 1,208 additions and 624 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ To ensure compatibility with the node version, check the following versions:

| L1 Node | MiniMove | MiniWasm | MiniEVM |
| ------- | -------- | -------- | ------- |
| v0.5.3+ | v0.5.3+ | v0.5.2+ | v0.5.2+ |
| v0.6.1+ | v0.6.4+ | v0.6.4+ | v0.6.6+ |

### Build and Configure

Expand Down
9 changes: 7 additions & 2 deletions challenger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ To configure the Challenger, fill in the values in the `~/.opinit/challenger.jso
// Version is the version used to build output root.
// Please refer to `spec_version.json` for the correct version for each network.
"version": 1,
// ListenAddress is the address to listen for incoming requests.
"listen_address": "localhost:3001",
// Server is the configuration for the server.
"server": {
"address": "localhost:3000",
"allow_origins": "*",
"allow_headers": "Origin, Content-Type, Accept",
"allow_methods": "GET",
},
"l1_node": {
"chain_id": "testnet-l1-1",
"bech32_prefix": "init",
Expand Down
2 changes: 1 addition & 1 deletion challenger/child/child.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func NewChildV1(
}

func (ch *Child) Initialize(ctx context.Context, processedHeight int64, startOutputIndex uint64, host hostNode, bridgeInfo ophosttypes.QueryBridgeResponse, challenger challenger) (time.Time, error) {
_, err := ch.BaseChild.Initialize(ctx, processedHeight, startOutputIndex, bridgeInfo, nil)
_, err := ch.BaseChild.Initialize(ctx, processedHeight, startOutputIndex, bridgeInfo, nil, nil)
if err != nil {
return time.Time{}, err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/opinitd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func NewRootCmd() *cobra.Command {
resetHeightsCmd(ctx),
resetHeightCmd(ctx),
migration015Cmd(ctx),
txCmd(ctx),
version.NewVersionCommand(),
)
return rootCmd
Expand Down
124 changes: 124 additions & 0 deletions cmd/opinitd/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package main

import (
"context"
"encoding/json"
"fmt"

"cosmossdk.io/errors"
"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"

"github.com/cosmos/cosmos-sdk/x/authz"

"github.com/initia-labs/opinit-bots/bot"
bottypes "github.com/initia-labs/opinit-bots/bot/types"
executortypes "github.com/initia-labs/opinit-bots/executor/types"
"github.com/initia-labs/opinit-bots/keys"
"github.com/initia-labs/opinit-bots/node/broadcaster"
broadcastertypes "github.com/initia-labs/opinit-bots/node/broadcaster/types"
"github.com/initia-labs/opinit-bots/node/rpcclient"
"github.com/initia-labs/opinit-bots/provider/child"
"github.com/initia-labs/opinit-bots/types"

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

// txCmd represents the tx command
func txCmd(ctx *cmdContext) *cobra.Command {
cmd := &cobra.Command{
Use: "tx",
Short: "send a transaction",
}

cmd.AddCommand(
txGrantOracleCmd(ctx),
)
return cmd
}

func txGrantOracleCmd(baseCtx *cmdContext) *cobra.Command {
cmd := &cobra.Command{
Use: "grant-oracle [oracle-account-address]",
Args: cobra.ExactArgs(1),
Short: "Grant oracle permission to the given account",
Long: `Grant oracle permission to the given account on L2 chain`,
RunE: func(cmd *cobra.Command, args []string) error {
cmdCtx, botDone := context.WithCancel(cmd.Context())
gracefulShutdown(botDone)

errGrp, ctx := errgroup.WithContext(cmdCtx)
ctx = types.WithErrGrp(ctx, errGrp)

account, err := l2BroadcasterAccount(baseCtx, cmd)
if err != nil {
return err
}
err = account.Load(ctx)
if err != nil {
return err
}

oracleAddress, err := keys.DecodeBech32AccAddr(args[0], account.Bech32Prefix())
if err != nil {
return err
}

grantMsg, err := authz.NewMsgGrant(account.GetAddress(), oracleAddress, authz.NewGenericAuthorization(types.MsgUpdateOracleTypeUrl), nil)
if err != nil {
return err
}

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

res, err := account.BroadcastTxSync(ctx, 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 l2BroadcasterAccount(ctx *cmdContext, cmd *cobra.Command) (*broadcaster.BroadcasterAccount, error) {
configPath, err := getConfigPath(cmd, ctx.homePath, string(bottypes.BotTypeExecutor))
if err != nil {
return nil, err
}

cfg := &executortypes.Config{}
err = bot.LoadJsonConfig(configPath, cfg)
if err != nil {
return nil, err
}

l2Config := cfg.L2NodeConfig(ctx.homePath)
broadcasterConfig := l2Config.BroadcasterConfig
cdc, txConfig, err := child.GetCodec(broadcasterConfig.Bech32Prefix)
if err != nil {
return nil, err
}

rpcClient, err := rpcclient.NewRPCClient(cdc, l2Config.RPC)
if err != nil {
return nil, err
}

keyringConfig := broadcastertypes.KeyringConfig{
Name: cfg.BridgeExecutor,
}

return broadcaster.NewBroadcasterAccount(*broadcasterConfig, cdc, txConfig, rpcClient, keyringConfig)
}
93 changes: 71 additions & 22 deletions executor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@ To configure the Executor, fill in the values in the `~/.opinit/executor.json` f
// Version is the version used to build output root.
// Please refer to `spec_version.json` for the correct version for each network.
"version": 1,
// ListenAddress is the address to listen for incoming requests.
"listen_address": "localhost:3000",
// Server is the configuration for the server.
"server": {
"address": "localhost:3000",
"allow_origins": "*",
"allow_headers": "Origin, Content-Type, Accept",
"allow_methods": "GET",
},
"l1_node": {
"chain_id": "testnet-l1-1",
"bech32_prefix": "init",
Expand Down Expand Up @@ -47,6 +52,11 @@ To configure the Executor, fill in the values in the `~/.opinit/executor.json` f
//
// If you don't want to use the bridge executor feature, you can leave it empty.
"bridge_executor": "",
// OracleBridgeExecutor is the key name in the keyring for the oracle bridge executor,
// which is used to relay oracle transaction from l1 to l2.
//
// If L2 is using oracle, you need to set this field.
"oracle_bridge_executor": "",

// DisableOutputSubmitter is the flag to disable the output submitter.
// If it is true, the output submitter will not be started.
Expand Down Expand Up @@ -80,6 +90,14 @@ To configure the Executor, fill in the values in the `~/.opinit/executor.json` f
}
```

### Oracle config
If you want to enable to relay oracle data, the `oracle_bridge_executor` field must be set. The oracle data is stored in the 0th tx of each L1 block. The bridge executor submits a `MsgUpdateOracle` containing the 0th Tx of l1 block to l2 when a block in l1 is created.

The `oracle_bridge_executor` must be an account that has received the authz grant from the executor. If it is not set, you can set the authz with the command below.
```bash
opinitd tx grant-oracle [oracle-account-address]
```

### Start height config examples

If the latest height stored in the db is not 0, start height config is ignored.
Expand Down Expand Up @@ -319,13 +337,18 @@ curl localhost:3000/status

```json
{
"bridge_id": 1,
"bridge_id": 0,
"host": {
"node": {
"last_block_height": 0,
"broadcaster": {
"pending_txs": 0,
"sequence": 0
"accounts_status": [
{
"address": "",
"sequence": 0
}
]
}
},
"last_proposed_output_index": 0,
Expand All @@ -336,7 +359,16 @@ curl localhost:3000/status
"last_block_height": 0,
"broadcaster": {
"pending_txs": 0,
"sequence": 0
"accounts_status": [
{
"address": "",
"sequence": 0
},
{
"address": "",
"sequence": 0
}
]
}
},
"last_updated_oracle_height": 0,
Expand All @@ -350,7 +382,7 @@ curl localhost:3000/status
},
"batch": {
"node": {
"last_block_height": 0,
"last_block_height": 0
},
"batch_info": {
"submitter": "",
Expand All @@ -364,7 +396,12 @@ curl localhost:3000/status
"da": {
"broadcaster": {
"pending_txs": 0,
"sequence": 0
"accounts_status": [
{
"address": "",
"sequence": 0
}
]
}
}
}
Expand All @@ -379,20 +416,32 @@ initiad tx ophost finalize-token-withdrawal ./withdrawal-info.json --gas= --gas-

```go
type QueryWithdrawalResponse struct {
// fields required to withdraw funds
BridgeId uint64 `json:"bridge_id"`
OutputIndex uint64 `json:"output_index"`
WithdrawalProofs [][]byte `json:"withdrawal_proofs"`
Sender string `json:"sender"`
Sequence uint64 `json:"sequence"`
Amount string `json:"amount"`
Version []byte `json:"version"`
StorageRoot []byte `json:"storage_root"`
LatestBlockHash []byte `json:"latest_block_hash"`

// extra info
BlockNumber int64 `json:"block_number"`
Receiver string `json:"receiver"`
WithdrawalHash []byte `json:"withdrawal_hash"`
Sequence uint64 `json:"sequence"`
To string `json:"to"`
From string `json:"from"`
Amount types.Coin `json:"amount"`
OutputIndex uint64 `json:"output_index"`
BridgeId uint64 `json:"bridge_id"`
WithdrawalProofs [][]byte `json:"withdrawal_proofs"`
Version []byte `json:"version"`
StorageRoot []byte `json:"storage_root"`
LastBlockHash []byte `json:"last_block_hash"`
}
```

```bash
curl localhost:3000/withdrawals/{address}
```
default options
- `limit`: 10
- `offset`: 0
- `order`: desc


```go
type QueryWithdrawalsResponse struct {
Withdrawals []QueryWithdrawalResponse `json:"withdrawals"`
Next uint64 `json:"next"`
Total uint64 `json:"total"`
}
```
6 changes: 4 additions & 2 deletions executor/batch/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,12 @@ func (bs *BatchSubmitter) finalizeBatch(ctx context.Context, blockHeight int64)
checksums,
)

msg, err := bs.da.CreateBatchMsg(headerData)
msg, sender, err := bs.da.CreateBatchMsg(headerData)
if err != nil {
return err
} else if msg != nil {
bs.processedMsgs = append(bs.processedMsgs, btypes.ProcessedMsgs{
Sender: sender,
Msgs: []sdk.Msg{msg},
Timestamp: time.Now().UnixNano(),
Save: true,
Expand All @@ -220,11 +221,12 @@ func (bs *BatchSubmitter) finalizeBatch(ctx context.Context, blockHeight int64)
types.MustInt64ToUint64(int64(len(checksums))),
chunk,
)
msg, err := bs.da.CreateBatchMsg(chunkData)
msg, sender, err := bs.da.CreateBatchMsg(chunkData)
if err != nil {
return err
} else if msg != nil {
bs.processedMsgs = append(bs.processedMsgs, btypes.ProcessedMsgs{
Sender: sender,
Msgs: []sdk.Msg{msg},
Timestamp: time.Now().UnixNano(),
Save: true,
Expand Down
8 changes: 4 additions & 4 deletions executor/batch/noop_da.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ func NewNoopDA() *NoopDA {
return &NoopDA{}
}

func (n NoopDA) Start(_ context.Context) {}
func (n NoopDA) HasKey() bool { return false }
func (n NoopDA) CreateBatchMsg(_ []byte) (sdk.Msg, error) { return nil, nil }
func (n NoopDA) BroadcastMsgs(nil btypes.ProcessedMsgs) {}
func (n NoopDA) Start(_ context.Context) {}
func (n NoopDA) HasKey() bool { return false }
func (n NoopDA) CreateBatchMsg(_ []byte) (sdk.Msg, string, error) { return nil, "", nil }
func (n NoopDA) BroadcastMsgs(nil btypes.ProcessedMsgs) {}
func (n NoopDA) ProcessedMsgsToRawKV(_ []btypes.ProcessedMsgs, _ bool) ([]types.RawKV, error) {
return nil, nil
}
Expand Down
Loading

0 comments on commit 88491e9

Please sign in to comment.