diff --git a/backend/cmd/eth1indexer/main.go b/backend/cmd/eth1indexer/main.go index 47806252c..bbee6e5e3 100644 --- a/backend/cmd/eth1indexer/main.go +++ b/backend/cmd/eth1indexer/main.go @@ -180,7 +180,7 @@ func Run() { return } - transforms := make([]func(blk *types.Eth1Block, cache *freecache.Cache) (*types.BulkMutations, *types.BulkMutations, error), 0) + transforms := make([]db.TransformFunc, 0) transforms = append(transforms, bt.TransformBlock, bt.TransformTx, diff --git a/backend/cmd/misc/main.go b/backend/cmd/misc/main.go index 43b499bcb..c2af150de 100644 --- a/backend/cmd/misc/main.go +++ b/backend/cmd/misc/main.go @@ -3,15 +3,15 @@ package misc import ( "bytes" "context" - "os" - "database/sql" "encoding/base64" "encoding/json" + "flag" "fmt" "math" "math/big" "net/http" + "os" "strconv" "strings" "sync" @@ -23,6 +23,13 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" "github.com/go-redis/redis/v8" + _ "github.com/jackc/pgx/v5/stdlib" + "github.com/pkg/errors" + utilMath "github.com/protolambda/zrnt/eth2/util/math" + go_ens "github.com/wealdtech/go-ens/v3" + "golang.org/x/sync/errgroup" + "google.golang.org/api/option" + "github.com/gobitfly/beaconchain/cmd/misc/commands" "github.com/gobitfly/beaconchain/cmd/misc/misctypes" "github.com/gobitfly/beaconchain/pkg/commons/cache" @@ -37,14 +44,6 @@ import ( "github.com/gobitfly/beaconchain/pkg/exporter/modules" "github.com/gobitfly/beaconchain/pkg/exporter/services" "github.com/gobitfly/beaconchain/pkg/notification" - _ "github.com/jackc/pgx/v5/stdlib" - "github.com/pkg/errors" - utilMath "github.com/protolambda/zrnt/eth2/util/math" - go_ens "github.com/wealdtech/go-ens/v3" - "golang.org/x/sync/errgroup" - "google.golang.org/api/option" - - "flag" "github.com/Gurpartap/storekit-go" ) @@ -1607,7 +1606,7 @@ func indexOldEth1Blocks(startBlock uint64, endBlock uint64, batchSize uint64, co return } - transforms := make([]func(blk *types.Eth1Block, cache *freecache.Cache) (*types.BulkMutations, *types.BulkMutations, error), 0) + transforms := make([]db.TransformFunc, 0) log.Infof("transformerFlag: %v", transformerFlag) transformerList := strings.Split(transformerFlag, ",") diff --git a/backend/pkg/commons/db/bigtable.go b/backend/pkg/commons/db/bigtable.go index ff4de7833..cdb1ad5db 100644 --- a/backend/pkg/commons/db/bigtable.go +++ b/backend/pkg/commons/db/bigtable.go @@ -14,10 +14,11 @@ import ( gcp_bigtable "cloud.google.com/go/bigtable" "github.com/go-redis/redis/v8" + itypes "github.com/gobitfly/eth-rewards/types" + "github.com/gobitfly/beaconchain/pkg/commons/log" "github.com/gobitfly/beaconchain/pkg/commons/types" "github.com/gobitfly/beaconchain/pkg/commons/utils" - itypes "github.com/gobitfly/eth-rewards/types" "golang.org/x/sync/errgroup" "google.golang.org/api/option" @@ -66,7 +67,7 @@ type Bigtable struct { tableMachineMetrics *gcp_bigtable.Table - redisCache *redis.Client + redisCache RedisClient LastAttestationCache map[uint64]uint64 LastAttestationCacheMux *sync.Mutex @@ -78,7 +79,29 @@ type Bigtable struct { machineMetricsQueuedWritesChan chan (types.BulkMutation) } +type RedisClient interface { + SCard(ctx context.Context, key string) *redis.IntCmd + SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd + Pipeline() redis.Pipeliner + Get(ctx context.Context, key string) *redis.StringCmd + Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd +} + func InitBigtable(project, instance, chainId, redisAddress string) (*Bigtable, error) { + rdc := redis.NewClient(&redis.Options{ + Addr: redisAddress, + ReadTimeout: time.Second * 20, + }) + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + if err := rdc.Ping(ctx).Err(); err != nil { + return nil, err + } + + return InitBigtableWithCache(ctx, project, instance, chainId, rdc) +} + +func InitBigtableWithCache(ctx context.Context, project, instance, chainId string, rdc RedisClient) (*Bigtable, error) { if utils.Config.Bigtable.Emulator { if utils.Config.Bigtable.EmulatorHost == "" { utils.Config.Bigtable.EmulatorHost = "127.0.0.1" @@ -90,26 +113,13 @@ func InitBigtable(project, instance, chainId, redisAddress string) (*Bigtable, e log.Fatal(err, "unable to set bigtable emulator environment variable", 0) } } - ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) - defer cancel() poolSize := 50 btClient, err := gcp_bigtable.NewClient(ctx, project, instance, option.WithGRPCConnectionPool(poolSize)) - // btClient, err := gcp_bigtable.NewClient(context.Background(), project, instance) - if err != nil { return nil, err } - rdc := redis.NewClient(&redis.Options{ - Addr: redisAddress, - ReadTimeout: time.Second * 20, - }) - - if err := rdc.Ping(ctx).Err(); err != nil { - return nil, err - } - bt := &Bigtable{ client: btClient, tableData: btClient.Open("data"), diff --git a/backend/pkg/commons/db/bigtable_eth1.go b/backend/pkg/commons/db/bigtable_eth1.go index 3861374f2..7409e9a09 100644 --- a/backend/pkg/commons/db/bigtable_eth1.go +++ b/backend/pkg/commons/db/bigtable_eth1.go @@ -10,6 +10,7 @@ import ( "fmt" "math/big" "sort" + "strconv" "strings" "sync" "time" @@ -23,8 +24,6 @@ import ( "github.com/gobitfly/beaconchain/pkg/commons/types" "github.com/gobitfly/beaconchain/pkg/commons/utils" - "strconv" - gcp_bigtable "cloud.google.com/go/bigtable" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/types/known/timestamppb" @@ -711,7 +710,9 @@ func TimestampToBigtableTimeDesc(ts time.Time) string { return fmt.Sprintf("%04d%02d%02d%02d%02d%02d", 9999-ts.Year(), 12-ts.Month(), 31-ts.Day(), 23-ts.Hour(), 59-ts.Minute(), 59-ts.Second()) } -func (bigtable *Bigtable) IndexEventsWithTransformers(start, end int64, transforms []func(blk *types.Eth1Block, cache *freecache.Cache) (bulkData *types.BulkMutations, bulkMetadataUpdates *types.BulkMutations, err error), concurrency int64, cache *freecache.Cache) error { +type TransformFunc func(blk *types.Eth1Block, cache *freecache.Cache) (bulkData *types.BulkMutations, bulkMetadataUpdates *types.BulkMutations, err error) + +func (bigtable *Bigtable) IndexEventsWithTransformers(start, end int64, transforms []TransformFunc, concurrency int64, cache *freecache.Cache) error { g := new(errgroup.Group) g.SetLimit(int(concurrency)) @@ -1048,8 +1049,19 @@ func (bigtable *Bigtable) TransformTx(blk *types.Eth1Block, cache *freecache.Cac BlobTxFee: blobFee, BlobGasPrice: tx.GetBlobGasPrice(), IsContractCreation: isContract, - ErrorMsg: tx.GetErrorMsg(), + ErrorMsg: "", + Status: types.StatusType(tx.Status), + } + for _, itx := range tx.Itx { + if itx.ErrorMsg != "" { + indexedTx.ErrorMsg = itx.ErrorMsg + if indexedTx.Status == types.StatusType_SUCCESS { + indexedTx.Status = types.StatusType_PARTIAL + } + break + } } + // Mark Sender and Recipient for balance update bigtable.markBalanceUpdate(indexedTx.From, []byte{0x0}, bulkMetadataUpdates, cache) bigtable.markBalanceUpdate(indexedTx.To, []byte{0x0}, bulkMetadataUpdates, cache) @@ -1135,9 +1147,16 @@ func (bigtable *Bigtable) TransformBlobTx(blk *types.Eth1Block, cache *freecache GasPrice: tx.GetGasPrice(), BlobTxFee: blobFee, BlobGasPrice: tx.GetBlobGasPrice(), - ErrorMsg: tx.GetErrorMsg(), + ErrorMsg: "", BlobVersionedHashes: tx.GetBlobVersionedHashes(), } + for _, itx := range tx.Itx { + if itx.ErrorMsg != "" { + indexedTx.ErrorMsg = itx.ErrorMsg + break + } + } + // Mark Sender and Recipient for balance update bigtable.markBalanceUpdate(indexedTx.From, []byte{0x0}, bulkMetadataUpdates, cache) bigtable.markBalanceUpdate(indexedTx.To, []byte{0x0}, bulkMetadataUpdates, cache) @@ -1240,7 +1259,7 @@ func (bigtable *Bigtable) TransformContract(blk *types.Eth1Block, cache *freecac contractUpdate := &types.IsContractUpdate{ IsContract: itx.GetType() == "create", // also use success status of enclosing transaction, as even successful sub-calls can still be reverted later in the tx - Success: itx.GetErrorMsg() == "" && tx.GetErrorMsg() == "", + Success: itx.GetErrorMsg() == "" && tx.GetStatus() == 1, } b, err := proto.Marshal(contractUpdate) if err != nil { @@ -1303,12 +1322,26 @@ func (bigtable *Bigtable) TransformItx(blk *types.Eth1Block, cache *freecache.Ca } iReversed := reversePaddedIndex(i, TX_PER_BLOCK_LIMIT) + var revertSource string for j, itx := range tx.GetItx() { - if j >= ITX_PER_TX_LIMIT { + if j > ITX_PER_TX_LIMIT { return nil, nil, fmt.Errorf("unexpected number of internal transactions in block expected at most %d but got: %v, tx: %x", ITX_PER_TX_LIMIT, j, tx.GetHash()) } jReversed := reversePaddedIndex(j, ITX_PER_TX_LIMIT) + // check for error before skipping, otherwise we loose track of cascading reverts + var reverted bool + if itx.ErrorMsg != "" { + reverted = true + // only save the highest root revert + if revertSource == "" || !strings.HasPrefix(itx.Path, revertSource) { + revertSource = strings.TrimSuffix(itx.Path, "]") + } + } + if revertSource != "" && strings.HasPrefix(itx.Path, revertSource) { + reverted = true + } + if itx.Path == "[]" || bytes.Equal(itx.Value, []byte{0x0}) { // skip top level and empty calls continue } @@ -1322,6 +1355,7 @@ func (bigtable *Bigtable) TransformItx(blk *types.Eth1Block, cache *freecache.Ca From: itx.GetFrom(), To: itx.GetTo(), Value: itx.GetValue(), + Reverted: reverted, } bigtable.markBalanceUpdate(indexedItx.To, []byte{0x0}, bulkMetadataUpdates, cache) diff --git a/backend/pkg/commons/db/bigtable_init.go b/backend/pkg/commons/db/bigtable_init.go index c7a83ffb7..e7b0b5ef1 100644 --- a/backend/pkg/commons/db/bigtable_init.go +++ b/backend/pkg/commons/db/bigtable_init.go @@ -12,6 +12,8 @@ import ( gcp_bigtable "cloud.google.com/go/bigtable" ) +var ErrTableAlreadyExist = fmt.Errorf("aborting bigtable schema init as tables are already present") + func InitBigtableSchema() error { tables := make(map[string]map[string]gcp_bigtable.GCPolicy) @@ -74,7 +76,7 @@ func InitBigtableSchema() error { } if len(existingTables) > 0 { - return fmt.Errorf("aborting bigtable schema init as tables are already present") + return ErrTableAlreadyExist } for name, definition := range tables { diff --git a/backend/pkg/commons/db/db.go b/backend/pkg/commons/db/db.go index 8a16a64dc..2608eaa4f 100644 --- a/backend/pkg/commons/db/db.go +++ b/backend/pkg/commons/db/db.go @@ -14,6 +14,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/gobitfly/beaconchain/pkg/commons/log" "github.com/gobitfly/beaconchain/pkg/commons/metrics" @@ -32,6 +33,17 @@ import ( "github.com/jackc/pgx/v5/stdlib" ) +type SQLReaderDb interface { + Close() error + Get(dest interface{}, query string, args ...interface{}) error + GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error + Select(dest interface{}, query string, args ...interface{}) error + SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error + Query(query string, args ...any) (*sql.Rows, error) + Preparex(query string) (*sqlx.Stmt, error) + Rebind(query string) string +} + //go:embed migrations/*/*.sql var EmbedMigrations embed.FS @@ -39,7 +51,7 @@ var DBPGX *pgxpool.Conn // DB is a pointer to the explorer-database var WriterDb *sqlx.DB -var ReaderDb *sqlx.DB +var ReaderDb SQLReaderDb var UserReader *sqlx.DB var UserWriter *sqlx.DB diff --git a/backend/pkg/commons/db/ens.go b/backend/pkg/commons/db/ens.go index 119f6c00b..4c1c77ba3 100644 --- a/backend/pkg/commons/db/ens.go +++ b/backend/pkg/commons/db/ens.go @@ -81,6 +81,8 @@ func (bigtable *Bigtable) TransformEnsNameRegistered(blk *types.Eth1Block, cache metrics.TaskDuration.WithLabelValues("bt_transform_ens").Observe(time.Since(startTime).Seconds()) }() + bulkData = &types.BulkMutations{} + bulkMetadataUpdates = &types.BulkMutations{} var ensCrontractAddresses map[string]string switch bigtable.chainId { case "1": @@ -90,11 +92,9 @@ func (bigtable *Bigtable) TransformEnsNameRegistered(blk *types.Eth1Block, cache case "11155111": ensCrontractAddresses = ensContracts.ENSCrontractAddressesSepolia default: - return nil, nil, nil + return bulkData, bulkMetadataUpdates, nil } - bulkData = &types.BulkMutations{} - bulkMetadataUpdates = &types.BulkMutations{} keys := make(map[string]bool) ethLog := gethtypes.Log{} diff --git a/backend/pkg/commons/db/statistics.go b/backend/pkg/commons/db/statistics.go index 1fc197ce7..3c75a567b 100644 --- a/backend/pkg/commons/db/statistics.go +++ b/backend/pkg/commons/db/statistics.go @@ -1602,7 +1602,7 @@ func WriteExecutionChartSeriesForDay(day int64) error { totalBlobCount = totalBlobCount.Add(decimal.NewFromInt(int64(len(tx.BlobVersionedHashes)))) default: - log.Fatal(fmt.Errorf("error unknown tx type %v hash: %x", tx.Status, tx.Hash), "", 0) + log.Fatal(fmt.Errorf("error unknown tx type %v hash: %x", tx.Type, tx.Hash), "", 0) } totalTxFees = totalTxFees.Add(txFees) @@ -1611,7 +1611,7 @@ func WriteExecutionChartSeriesForDay(day int64) error { failedTxCount += 1 totalFailedGasUsed = totalFailedGasUsed.Add(gasUsed) totalFailedTxFee = totalFailedTxFee.Add(txFees) - case 1: + case 1, 2: successTxCount += 1 default: log.Fatal(fmt.Errorf("error unknown status code %v hash: %x", tx.Status, tx.Hash), "", 0) diff --git a/backend/pkg/commons/rpc/erigon.go b/backend/pkg/commons/rpc/erigon.go index eeacf95e6..c57e1dd61 100644 --- a/backend/pkg/commons/rpc/erigon.go +++ b/backend/pkg/commons/rpc/erigon.go @@ -2,30 +2,33 @@ package rpc import ( "context" - "encoding/hex" - - "github.com/gobitfly/beaconchain/pkg/commons/contracts/oneinchoracle" - "github.com/gobitfly/beaconchain/pkg/commons/log" - - "github.com/gobitfly/beaconchain/pkg/commons/erc20" - "fmt" "math/big" + "net/http" + "os" "strings" + "sync" "time" + "github.com/gobitfly/beaconchain/pkg/commons/contracts/oneinchoracle" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/raw" + "github.com/gobitfly/beaconchain/pkg/commons/erc20" + "github.com/gobitfly/beaconchain/pkg/commons/log" + "github.com/gobitfly/beaconchain/pkg/commons/metrics" + "github.com/gobitfly/beaconchain/pkg/commons/types" + "github.com/gobitfly/beaconchain/pkg/commons/utils" + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + gethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" gethrpc "github.com/ethereum/go-ethereum/rpc" - "github.com/gobitfly/beaconchain/pkg/commons/types" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/types/known/timestamppb" - - gethtypes "github.com/ethereum/go-ethereum/core/types" ) type ErigonClient struct { @@ -34,6 +37,8 @@ type ErigonClient struct { ethClient *ethclient.Client chainID *big.Int multiChecker *Balance + + rawStore raw.StoreReader } var CurrentErigonClient *ErigonClient @@ -44,17 +49,40 @@ func NewErigonClient(endpoint string) (*ErigonClient, error) { endpoint: endpoint, } - rpcClient, err := gethrpc.Dial(client.endpoint) - if err != nil { - return nil, fmt.Errorf("error dialing rpc node: %w", err) + var opts []gethrpc.ClientOption + if utils.Config != nil { + if utils.Config.RawBigtable.Project != "" && utils.Config.RawBigtable.Instance != "" { + if utils.Config.RawBigtable.Emulator { + err := os.Setenv("BIGTABLE_EMULATOR_HOST", fmt.Sprintf("%s:%d", utils.Config.RawBigtable.EmulatorHost, utils.Config.RawBigtable.EmulatorPort)) + if err != nil { + return nil, fmt.Errorf("error while setting BIGTABLE_EMULATOR_HOST env: %w", err) + } + } + project, instance := utils.Config.RawBigtable.Project, utils.Config.RawBigtable.Instance + var db database.Database + bt, err := database.NewBigTable(project, instance, nil) + if err != nil { + return nil, err + } + db = database.Wrap(bt, raw.Table) + if utils.Config.RawBigtable.Remote != "" { + db = database.NewRemoteClient(utils.Config.RawBigtable.Remote) + } + rawStore := raw.WithCache(raw.NewStore(db)) + roundTripper := raw.NewBigTableEthRaw(rawStore, utils.Config.Chain.Id) + opts = append(opts, gethrpc.WithHTTPClient(&http.Client{ + Transport: raw.NewWithFallback(roundTripper, http.DefaultTransport), + })) + client.rawStore = rawStore + } } - client.rpcClient = rpcClient - ethClient, err := ethclient.Dial(client.endpoint) + rpcClient, err := gethrpc.DialOptions(context.Background(), client.endpoint, opts...) if err != nil { return nil, fmt.Errorf("error dialing rpc node: %w", err) } - client.ethClient = ethClient + client.rpcClient = rpcClient + client.ethClient = ethclient.NewClient(rpcClient) client.multiChecker, err = NewBalance(common.HexToAddress("0xb1F8e55c7f64D203C1400B9D8555d050F94aDF39"), client.ethClient) if err != nil { @@ -89,104 +117,110 @@ func (client *ErigonClient) GetRPCClient() *gethrpc.Client { return client.rpcClient } -func (client *ErigonClient) GetBlock(number int64, traceMode string) (*types.Eth1Block, *types.GetBlockTimings, error) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) - defer cancel() +type minimalBlock struct { + Hash string `json:"hash"` +} +func (client *ErigonClient) GetBlock(number int64, traceMode string) (*types.Eth1Block, *types.GetBlockTimings, error) { start := time.Now() timings := &types.GetBlockTimings{} + mu := sync.Mutex{} - block, err := client.ethClient.BlockByNumber(ctx, big.NewInt(number)) - if err != nil { + defer func() { + metrics.TaskDuration.WithLabelValues("rpc_el_get_block").Observe(time.Since(start).Seconds()) + }() + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + var traces []*Eth1InternalTransactionWithPosition + var block *gethtypes.Block + var receipts []*gethtypes.Receipt + g := new(errgroup.Group) + g.Go(func() error { + b, err := client.ethClient.BlockByNumber(ctx, big.NewInt(number)) + if err != nil { + return err + } + mu.Lock() + timings.Headers = time.Since(start) + mu.Unlock() + block = b + return nil + }) + g.Go(func() error { + if err := client.rpcClient.CallContext(ctx, &receipts, "eth_getBlockReceipts", fmt.Sprintf("0x%x", number)); err != nil { + return fmt.Errorf("error retrieving receipts for block %v: %w", number, err) + } + mu.Lock() + timings.Receipts = time.Since(start) + mu.Unlock() + return nil + }) + g.Go(func() error { + t, err := client.getTrace(traceMode, big.NewInt(number)) + if err != nil { + return fmt.Errorf("error retrieving traces for block %v: %w", number, err) + } + traces = t + mu.Lock() + timings.Traces = time.Since(start) + mu.Unlock() + return nil + }) + if err := g.Wait(); err != nil { return nil, nil, err } - - timings.Headers = time.Since(start) - start = time.Now() - - c := &types.Eth1Block{ - Hash: block.Hash().Bytes(), - ParentHash: block.ParentHash().Bytes(), - UncleHash: block.UncleHash().Bytes(), - Coinbase: block.Coinbase().Bytes(), - Root: block.Root().Bytes(), - TxHash: block.TxHash().Bytes(), - ReceiptHash: block.ReceiptHash().Bytes(), - Difficulty: block.Difficulty().Bytes(), - Number: block.NumberU64(), - GasLimit: block.GasLimit(), - GasUsed: block.GasUsed(), - Time: timestamppb.New(time.Unix(int64(block.Time()), 0)), - Extra: block.Extra(), - MixDigest: block.MixDigest().Bytes(), - Bloom: block.Bloom().Bytes(), - Uncles: []*types.Eth1Block{}, - Transactions: []*types.Eth1Transaction{}, - Withdrawals: []*types.Eth1Withdrawal{}, - } - blobGasUsed := block.BlobGasUsed() - if blobGasUsed != nil { - c.BlobGasUsed = *blobGasUsed - } - excessBlobGas := block.ExcessBlobGas() - if excessBlobGas != nil { - c.ExcessBlobGas = *excessBlobGas - } - - if block.BaseFee() != nil { - c.BaseFee = block.BaseFee().Bytes() - } - - for _, uncle := range block.Uncles() { - pbUncle := &types.Eth1Block{ - Hash: uncle.Hash().Bytes(), - ParentHash: uncle.ParentHash.Bytes(), - UncleHash: uncle.UncleHash.Bytes(), - Coinbase: uncle.Coinbase.Bytes(), - Root: uncle.Root.Bytes(), - TxHash: uncle.TxHash.Bytes(), - ReceiptHash: uncle.ReceiptHash.Bytes(), - Difficulty: uncle.Difficulty.Bytes(), - Number: uncle.Number.Uint64(), - GasLimit: uncle.GasLimit, - GasUsed: uncle.GasUsed, - Time: timestamppb.New(time.Unix(int64(uncle.Time), 0)), - Extra: uncle.Extra, - MixDigest: uncle.MixDigest.Bytes(), - Bloom: uncle.Bloom.Bytes(), + // we cannot trust block.Hash(), some chain (gnosis) have extra field that are included in the hash computation + // so extract it from the receipts or from the node again if no receipt (it should be very rare) + var blockHash common.Hash + if len(receipts) != 0 { + blockHash = receipts[0].BlockHash + } else { + var res minimalBlock + if err := client.rpcClient.CallContext(ctx, &res, "eth_getBlockByNumber", fmt.Sprintf("0x%x", number), false); err != nil { + return nil, nil, fmt.Errorf("error retrieving blockHash %v: %w", number, err) } - - c.Uncles = append(c.Uncles, pbUncle) + blockHash = common.HexToHash(res.Hash) } - receipts := make([]*gethtypes.Receipt, len(block.Transactions())) - - if len(block.Withdrawals()) > 0 { - withdrawalsIndexed := make([]*types.Eth1Withdrawal, 0, len(block.Withdrawals())) - for _, w := range block.Withdrawals() { - withdrawalsIndexed = append(withdrawalsIndexed, &types.Eth1Withdrawal{ - Index: w.Index, - ValidatorIndex: w.Validator, - Address: w.Address.Bytes(), - Amount: new(big.Int).SetUint64(w.Amount).Bytes(), - }) + withdrawals := make([]*types.Eth1Withdrawal, len(block.Withdrawals())) + for i, withdrawal := range block.Withdrawals() { + withdrawals[i] = &types.Eth1Withdrawal{ + Index: withdrawal.Index, + ValidatorIndex: withdrawal.Validator, + Address: withdrawal.Address.Bytes(), + Amount: new(big.Int).SetUint64(withdrawal.Amount).Bytes(), } - c.Withdrawals = withdrawalsIndexed } - txs := block.Transactions() + transactions := make([]*types.Eth1Transaction, len(block.Transactions())) + traceIndex := 0 + if len(receipts) != len(block.Transactions()) { + return nil, nil, fmt.Errorf("block %s receipts length [%d] mismatch with transactions length [%d]", block.Number(), len(receipts), len(block.Transactions())) + } + for txPosition, receipt := range receipts { + logs := make([]*types.Eth1Log, len(receipt.Logs)) + for i, log := range receipt.Logs { + topics := make([][]byte, len(log.Topics)) + for j, topic := range log.Topics { + topics[j] = topic.Bytes() + } + logs[i] = &types.Eth1Log{ + Address: log.Address.Bytes(), + Data: log.Data, + Removed: log.Removed, + Topics: topics, + } + } - for _, tx := range txs { - var from []byte - sender, err := gethtypes.Sender(gethtypes.NewCancunSigner(tx.ChainId()), tx) - if err != nil { - from, _ = hex.DecodeString("abababababababababababababababababababab") - log.Error(err, "error converting tx to msg", 0, map[string]interface{}{"tx": tx.Hash()}) - } else { - from = sender.Bytes() + var internals []*types.Eth1InternalTransaction + for ; traceIndex < len(traces) && traces[traceIndex].txPosition == txPosition; traceIndex++ { + internals = append(internals, &traces[traceIndex].Eth1InternalTransaction) } - pbTx := &types.Eth1Transaction{ + tx := block.Transactions()[txPosition] + transactions[txPosition] = &types.Eth1Transaction{ Type: uint32(tx.Type()), Nonce: tx.Nonce(), GasPrice: tx.GasPrice().Bytes(), @@ -195,192 +229,139 @@ func (client *ErigonClient) GetBlock(number int64, traceMode string) (*types.Eth Gas: tx.Gas(), Value: tx.Value().Bytes(), Data: tx.Data(), - From: from, - ChainId: tx.ChainId().Bytes(), - AccessList: []*types.AccessList{}, - Hash: tx.Hash().Bytes(), - Itx: []*types.Eth1InternalTransaction{}, - BlobVersionedHashes: [][]byte{}, - } - - if tx.BlobGasFeeCap() != nil { - pbTx.MaxFeePerBlobGas = tx.BlobGasFeeCap().Bytes() - } - for _, h := range tx.BlobHashes() { - pbTx.BlobVersionedHashes = append(pbTx.BlobVersionedHashes, h.Bytes()) - } - - if tx.To() != nil { - pbTx.To = tx.To().Bytes() - } - - c.Transactions = append(c.Transactions, pbTx) - } - - g := new(errgroup.Group) - - g.Go(func() error { - if block.NumberU64() == 0 { // genesis block is not traceable - return nil - } - - var traceError error - if traceMode == "parity" || traceMode == "parity/geth" { - traces, err := client.TraceParity(block.NumberU64()) - - if err != nil { - if traceMode == "parity" { - return fmt.Errorf("error tracing block via parity style traces (%v), %v: %w", block.Number(), block.Hash(), err) - } else { - log.Error(err, "error tracing block via parity style traces", 0, map[string]interface{}{"blockNumber": block.Number(), "blockHash": block.Hash()}) - } - traceError = err - } else { - for _, trace := range traces { - if trace.Type == "reward" { - continue - } - - if trace.TransactionHash == "" { - continue - } - - if trace.TransactionPosition >= len(c.Transactions) { - return fmt.Errorf("error transaction position %v out of range", trace.TransactionPosition) - } - - if trace.Error == "" { - c.Transactions[trace.TransactionPosition].Status = 1 - } else { - c.Transactions[trace.TransactionPosition].Status = 0 - c.Transactions[trace.TransactionPosition].ErrorMsg = trace.Error - } - - tracePb := &types.Eth1InternalTransaction{ - Type: trace.Type, - Path: fmt.Sprint(trace.TraceAddress), - } - - if tracePb.Type == "call" { - tracePb.Type = trace.Action.CallType - } - - if trace.Type == "create" { - tracePb.From = common.FromHex(trace.Action.From) - tracePb.To = common.FromHex(trace.Result.Address) - tracePb.Value = common.FromHex(trace.Action.Value) - } else if trace.Type == "suicide" { - tracePb.From = common.FromHex(trace.Action.Address) - tracePb.To = common.FromHex(trace.Action.RefundAddress) - tracePb.Value = common.FromHex(trace.Action.Balance) - } else if trace.Type == "call" { - tracePb.From = common.FromHex(trace.Action.From) - tracePb.To = common.FromHex(trace.Action.To) - tracePb.Value = common.FromHex(trace.Action.Value) - } else { - spew.Dump(trace) - log.Fatal(fmt.Errorf("unknown trace type %v in tx %v", trace.Type, trace.TransactionHash), "", 0) - } - - c.Transactions[trace.TransactionPosition].Itx = append(c.Transactions[trace.TransactionPosition].Itx, tracePb) + To: func() []byte { + if tx.To() != nil { + return tx.To().Bytes() } - } - } - - if traceMode == "geth" || (traceError != nil && traceMode == "parity/geth") { - gethTraceData, err := client.TraceGeth(block.Hash()) - - if err != nil { - return fmt.Errorf("error tracing block via geth style traces (%v), %v: %w", block.Number(), block.Hash(), err) - } - - // log.LogInfo("retrieved %v calls via geth", len(gethTraceData)) - - for _, trace := range gethTraceData { - if trace.Error == "" { - c.Transactions[trace.TransactionPosition].Status = 1 - } else { - c.Transactions[trace.TransactionPosition].Status = 0 - c.Transactions[trace.TransactionPosition].ErrorMsg = trace.Error + return nil + }(), + From: func() []byte { + // this won't make a request in most cases as the sender is already present in the cache + // context https://github.com/ethereum/go-ethereum/blob/v1.14.11/ethclient/ethclient.go#L268 + sender, err := client.ethClient.TransactionSender(context.Background(), tx, blockHash, uint(txPosition)) + if err != nil { + sender = common.HexToAddress("abababababababababababababababababababab") + log.Error(err, fmt.Sprintf("could not retrieve tx sender %v", tx.Hash()), 0) } - - if trace.Type == "CREATE2" { - trace.Type = "CREATE" + return sender.Bytes() + }(), + ChainId: tx.ChainId().Bytes(), + AccessList: []*types.AccessList{}, + Hash: tx.Hash().Bytes(), + ContractAddress: receipt.ContractAddress[:], + CommulativeGasUsed: receipt.CumulativeGasUsed, + GasUsed: receipt.GasUsed, + LogsBloom: receipt.Bloom[:], + Status: receipt.Status, + Logs: logs, + Itx: internals, + MaxFeePerBlobGas: func() []byte { + if tx.BlobGasFeeCap() != nil { + return tx.BlobGasFeeCap().Bytes() } - - tracePb := &types.Eth1InternalTransaction{ - Type: strings.ToLower(trace.Type), - Path: "0", + return nil + }(), + BlobVersionedHashes: func() (b [][]byte) { + for _, h := range tx.BlobHashes() { + b = append(b, h.Bytes()) } - - tracePb.From = trace.From.Bytes() - tracePb.To = trace.To.Bytes() - tracePb.Value = common.FromHex(trace.Value) - if trace.Type == "CREATE" { - } else if trace.Type == "SELFDESTRUCT" { - } else if trace.Type == "SUICIDE" { - } else if trace.Type == "CALL" || trace.Type == "DELEGATECALL" || trace.Type == "STATICCALL" { - } else if trace.Type == "" { - log.Error(fmt.Errorf("geth style trace without type"), "", 0, map[string]interface{}{"type": trace.Type, "block.Number": block.Number(), "block.Hash": block.Hash()}) - spew.Dump(trace) - continue - } else { - spew.Dump(trace) - log.Fatal(fmt.Errorf("unknown trace type %v in tx %v", trace.Type, trace.TransactionPosition), "", 0) + return b + }(), + BlobGasPrice: func() []byte { + if receipt.BlobGasPrice != nil { + return receipt.BlobGasPrice.Bytes() } - c.Transactions[trace.TransactionPosition].Itx = append(c.Transactions[trace.TransactionPosition].Itx, tracePb) - } + return nil + }(), + BlobGasUsed: receipt.BlobGasUsed, } - - timings.Traces = time.Since(start) - - // log.LogInfo("retrieved %v traces for %v txs", len(traces), len(c.Transactions)) - - return nil - }) - - if err = client.rpcClient.CallContext(ctx, &receipts, "eth_getBlockReceipts", fmt.Sprintf("0x%x", block.NumberU64())); err != nil { - return nil, nil, fmt.Errorf("error retrieving receipts for block %v: %w", block.Number(), err) } - timings.Receipts = time.Since(start) - start = time.Now() - - for i, r := range receipts { - c.Transactions[i].ContractAddress = r.ContractAddress[:] - c.Transactions[i].CommulativeGasUsed = r.CumulativeGasUsed - c.Transactions[i].GasUsed = r.GasUsed - c.Transactions[i].LogsBloom = r.Bloom[:] - c.Transactions[i].Logs = make([]*types.Eth1Log, 0, len(r.Logs)) - - if r.BlobGasPrice != nil { - c.Transactions[i].BlobGasPrice = r.BlobGasPrice.Bytes() + uncles := make([]*types.Eth1Block, len(block.Uncles())) + for i, uncle := range block.Uncles() { + uncles[i] = &types.Eth1Block{ + Hash: uncle.Hash().Bytes(), + ParentHash: uncle.ParentHash.Bytes(), + UncleHash: uncle.UncleHash.Bytes(), + Coinbase: uncle.Coinbase.Bytes(), + Root: uncle.Root.Bytes(), + TxHash: uncle.TxHash.Bytes(), + ReceiptHash: uncle.ReceiptHash.Bytes(), + Difficulty: uncle.Difficulty.Bytes(), + Number: uncle.Number.Uint64(), + GasLimit: uncle.GasLimit, + GasUsed: uncle.GasUsed, + Time: timestamppb.New(time.Unix(int64(uncle.Time), 0)), + Extra: uncle.Extra, + MixDigest: uncle.MixDigest.Bytes(), + Bloom: uncle.Bloom.Bytes(), } - c.Transactions[i].BlobGasUsed = r.BlobGasUsed - - for _, l := range r.Logs { - pbLog := &types.Eth1Log{ - Address: l.Address.Bytes(), - Data: l.Data, - Removed: l.Removed, - Topics: make([][]byte, 0, len(l.Topics)), - } + } - for _, t := range l.Topics { - pbLog.Topics = append(pbLog.Topics, t.Bytes()) + return &types.Eth1Block{ + Hash: blockHash.Bytes(), + ParentHash: block.ParentHash().Bytes(), + UncleHash: block.UncleHash().Bytes(), + Coinbase: block.Coinbase().Bytes(), + Root: block.Root().Bytes(), + TxHash: block.TxHash().Bytes(), + ReceiptHash: block.ReceiptHash().Bytes(), + Difficulty: block.Difficulty().Bytes(), + Number: block.NumberU64(), + GasLimit: block.GasLimit(), + GasUsed: block.GasUsed(), + Time: timestamppb.New(time.Unix(int64(block.Time()), 0)), + Extra: block.Extra(), + MixDigest: block.MixDigest().Bytes(), + Bloom: block.Bloom().Bytes(), + BaseFee: func() []byte { + if block.BaseFee() != nil { + return block.BaseFee().Bytes() } - c.Transactions[i].Logs = append(c.Transactions[i].Logs, pbLog) - } - } + return nil + }(), + Uncles: uncles, + Transactions: transactions, + Withdrawals: withdrawals, + BlobGasUsed: func() uint64 { + blobGasUsed := block.BlobGasUsed() + if blobGasUsed != nil { + return *blobGasUsed + } + return 0 + }(), + ExcessBlobGas: func() uint64 { + excessBlobGas := block.ExcessBlobGas() + if excessBlobGas != nil { + return *excessBlobGas + } + return 0 + }(), + }, timings, nil +} - if err := g.Wait(); err != nil { - return nil, nil, fmt.Errorf("error retrieving traces for block %v: %w", block.Number(), err) +func (client *ErigonClient) GetBlocks(start, end int64, traceMode string) ([]*types.Eth1Block, error) { + _, err := client.rawStore.ReadBlocksByNumber(client.chainID.Uint64(), start, end) + if err != nil { + return nil, err } - - return c, timings, nil + blocks := make([]*types.Eth1Block, end-start+1) + for i := start; i <= end; i++ { + block, _, err := client.GetBlock(i, traceMode) + if err != nil { + return nil, err + } + blocks[i-start] = block + } + return blocks, nil } func (client *ErigonClient) GetBlockNumberByHash(hash string) (uint64, error) { + startTime := time.Now() + defer func() { + metrics.TaskDuration.WithLabelValues("rpc_el_get_block_number_by_hash").Observe(time.Since(startTime).Seconds()) + }() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() @@ -392,6 +373,11 @@ func (client *ErigonClient) GetBlockNumberByHash(hash string) (uint64, error) { } func (client *ErigonClient) GetLatestEth1BlockNumber() (uint64, error) { + startTime := time.Now() + defer func() { + metrics.TaskDuration.WithLabelValues("rpc_el_get_latest_eth1_block_number").Observe(time.Since(startTime).Seconds()) + }() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() @@ -441,10 +427,10 @@ func extractCalls(r *GethTraceCallResult, d *[]*GethTraceCallResult) { } } -func (client *ErigonClient) TraceGeth(blockHash common.Hash) ([]*GethTraceCallResult, error) { +func (client *ErigonClient) TraceGeth(blockNumber *big.Int) ([]*GethTraceCallResult, error) { var res []*GethTraceCallResultWrapper - err := client.rpcClient.Call(&res, "debug_traceBlockByHash", blockHash, gethTracerArg) + err := client.rpcClient.Call(&res, "debug_traceBlockByNumber", hexutil.EncodeBig(blockNumber), gethTracerArg) if err != nil { return nil, err } @@ -538,6 +524,11 @@ func (client *ErigonClient) TraceParityTx(txHash string) ([]*ParityTraceResult, } func (client *ErigonClient) GetBalances(pairs []*types.Eth1AddressBalance, addressIndex, tokenIndex int) ([]*types.Eth1AddressBalance, error) { + startTime := time.Now() + defer func() { + metrics.TaskDuration.WithLabelValues("rpc_el_get_balances").Observe(time.Since(startTime).Seconds()) + }() + batchElements := make([]gethrpc.BatchElem, 0, len(pairs)) ret := make([]*types.Eth1AddressBalance, len(pairs)) @@ -550,8 +541,6 @@ func (client *ErigonClient) GetBalances(pairs []*types.Eth1AddressBalance, addre Token: pair.Token, } - // log.LogInfo("retrieving balance for %x / %x", ret[i].Address, ret[i].Token) - if len(pair.Token) < 20 { batchElements = append(batchElements, gethrpc.BatchElem{ Method: "eth_getBalance", @@ -586,8 +575,6 @@ func (client *ErigonClient) GetBalances(pairs []*types.Eth1AddressBalance, addre res := strings.TrimPrefix(*el.Result.(*string), "0x") ret[i].Balance = new(big.Int).SetBytes(common.FromHex(res)).Bytes() - - // log.LogInfo("retrieved balance %x / %x: %x (%v)", ret[i].Address, ret[i].Token, ret[i].Balance, *el.Result.(*string)) } return ret, nil @@ -743,3 +730,106 @@ func toCallArg(msg ethereum.CallMsg) interface{} { } return arg } + +func (client *ErigonClient) getTrace(traceMode string, blockNumber *big.Int) ([]*Eth1InternalTransactionWithPosition, error) { + if blockNumber.Uint64() == 0 { // genesis block is not traceable + return nil, nil + } + switch traceMode { + case "parity": + return client.getTraceParity(blockNumber) + case "parity/geth": + traces, err := client.getTraceParity(blockNumber) + if err == nil { + return traces, nil + } + log.Error(err, fmt.Sprintf("error tracing block via parity style traces (%v)", blockNumber), 0) + // fallback to geth traces + fallthrough + case "geth": + return client.getTraceGeth(blockNumber) + } + return nil, fmt.Errorf("unknown trace mode '%s'", traceMode) +} + +func (client *ErigonClient) getTraceParity(blockNumber *big.Int) ([]*Eth1InternalTransactionWithPosition, error) { + traces, err := client.TraceParity(blockNumber.Uint64()) + if err != nil { + return nil, fmt.Errorf("error tracing block via parity style traces (%v): %w", blockNumber, err) + } + + var indexedTraces []*Eth1InternalTransactionWithPosition + for _, trace := range traces { + if trace.Type == "reward" { + continue + } + if trace.TransactionHash == "" { + continue + } + + from, to, value, traceType := trace.ConvertFields() + indexedTraces = append(indexedTraces, &Eth1InternalTransactionWithPosition{ + Eth1InternalTransaction: types.Eth1InternalTransaction{ + Type: traceType, + From: from, + To: to, + Value: value, + ErrorMsg: trace.Error, + Path: fmt.Sprint(trace.TraceAddress), + }, + txPosition: trace.TransactionPosition, + }) + } + return indexedTraces, nil +} + +func (client *ErigonClient) getTraceGeth(blockNumber *big.Int) ([]*Eth1InternalTransactionWithPosition, error) { + traces, err := client.TraceGeth(blockNumber) + if err != nil { + return nil, fmt.Errorf("error tracing block via geth style traces (%v): %w", blockNumber, err) + } + + var indexedTraces []*Eth1InternalTransactionWithPosition + var txPosition int + paths := make(map[*GethTraceCallResult]string) + for i, trace := range traces { + switch trace.Type { + case "CREATE2": + trace.Type = "CREATE" + case "CREATE", "SELFDESTRUCT", "SUICIDE", "CALL", "DELEGATECALL", "STATICCALL", "CALLCODE": + case "": + log.Error(fmt.Errorf("geth style trace without type"), "", 0, map[string]interface{}{"type": trace.Type, "block.Number": blockNumber}) + spew.Dump(trace) + continue + default: + spew.Dump(trace) + log.Fatal(fmt.Errorf("unknown trace type %v in tx %v:%v", trace.Type, blockNumber.String(), trace.TransactionPosition), "", 0) + } + if txPosition != trace.TransactionPosition { + txPosition = trace.TransactionPosition + paths = make(map[*GethTraceCallResult]string) + } + for index, call := range trace.Calls { + paths[call] = fmt.Sprintf("%s %d", paths[trace], index) + } + + log.Tracef("appending trace %v to tx %d:%x from %v to %v value %v", i, blockNumber, trace.TransactionPosition, trace.From, trace.To, trace.Value) + indexedTraces = append(indexedTraces, &Eth1InternalTransactionWithPosition{ + Eth1InternalTransaction: types.Eth1InternalTransaction{ + Type: strings.ToLower(trace.Type), + From: trace.From.Bytes(), + To: trace.To.Bytes(), + Value: common.FromHex(trace.Value), + ErrorMsg: trace.Error, + Path: fmt.Sprintf("[%s]", strings.TrimPrefix(paths[trace], " ")), + }, + txPosition: trace.TransactionPosition, + }) + } + return indexedTraces, nil +} + +type Eth1InternalTransactionWithPosition struct { + types.Eth1InternalTransaction + txPosition int +} diff --git a/backend/pkg/commons/rpc/erigon_test.go b/backend/pkg/commons/rpc/erigon_test.go new file mode 100644 index 000000000..70bb915cd --- /dev/null +++ b/backend/pkg/commons/rpc/erigon_test.go @@ -0,0 +1,80 @@ +package rpc + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + "os" + "testing" +) + +func TestGnosisBlockHash(t *testing.T) { + gnosisURL := os.Getenv("GNOSIS_NODE_URL") + if gnosisURL == "" { + t.Skip("skipping test, set GNOSIS_NODE_URL") + } + + erigonClient, err := NewErigonClient(gnosisURL) + if err != nil { + t.Fatalf("error initializing erigon client: %v", err) + } + + tests := []struct { + name string + block int64 + }{ + { + name: "old block with extra fields", + block: 68140, + }, + { + name: "old block with extra fields #2", + block: 19187811, + }, + { + name: "without receipts", + block: 38039324, + }, + { + name: "newest block", + block: 37591835, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + parsed, _, err := erigonClient.GetBlock(tt.block, "parity/geth") + if err != nil { + t.Fatal(err) + } + + type MinimalBlock struct { + Result struct { + Hash string `json:"hash"` + } `json:"result"` + } + + query := fmt.Sprintf(`{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params": ["0x%x",false],"id":1}`, tt.block) + req, err := http.NewRequest(http.MethodPost, gnosisURL, bytes.NewBufferString(query)) + if err != nil { + t.Fatal(err) + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatal(err) + } + defer resp.Body.Close() + + var res MinimalBlock + if err := json.NewDecoder(resp.Body).Decode(&res); err != nil { + t.Fatal(err) + } + + if got, want := fmt.Sprintf("0x%x", parsed.Hash), res.Result.Hash; got != want { + t.Errorf("got %v want %v", got, want) + } + }) + } +} diff --git a/backend/pkg/commons/types/eth1.pb.go b/backend/pkg/commons/types/eth1.pb.go index 803743344..67d872858 100644 --- a/backend/pkg/commons/types/eth1.pb.go +++ b/backend/pkg/commons/types/eth1.pb.go @@ -369,14 +369,12 @@ type Eth1Transaction struct { AccessList []*AccessList `protobuf:"bytes,15,rep,name=access_list,json=accessList,proto3" json:"access_list,omitempty"` Hash []byte `protobuf:"bytes,16,opt,name=hash,proto3" json:"hash,omitempty"` // Receipt fields - ContractAddress []byte `protobuf:"bytes,17,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` - CommulativeGasUsed uint64 `protobuf:"varint,18,opt,name=commulative_gas_used,json=commulativeGasUsed,proto3" json:"commulative_gas_used,omitempty"` - GasUsed uint64 `protobuf:"varint,19,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` - LogsBloom []byte `protobuf:"bytes,20,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty"` - Status uint64 `protobuf:"varint,21,opt,name=status,proto3" json:"status,omitempty"` - // reserved 22; // string error_msg = 22; - ErrorMsg string `protobuf:"bytes,22,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` - Logs []*Eth1Log `protobuf:"bytes,23,rep,name=logs,proto3" json:"logs,omitempty"` + ContractAddress []byte `protobuf:"bytes,17,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty"` + CommulativeGasUsed uint64 `protobuf:"varint,18,opt,name=commulative_gas_used,json=commulativeGasUsed,proto3" json:"commulative_gas_used,omitempty"` + GasUsed uint64 `protobuf:"varint,19,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + LogsBloom []byte `protobuf:"bytes,20,opt,name=logs_bloom,json=logsBloom,proto3" json:"logs_bloom,omitempty"` + Status uint64 `protobuf:"varint,21,opt,name=status,proto3" json:"status,omitempty"` + Logs []*Eth1Log `protobuf:"bytes,23,rep,name=logs,proto3" json:"logs,omitempty"` // Internal transactions Itx []*Eth1InternalTransaction `protobuf:"bytes,24,rep,name=itx,proto3" json:"itx,omitempty"` // EIP 4844 transaction @@ -545,13 +543,6 @@ func (x *Eth1Transaction) GetStatus() uint64 { return 0 } -func (x *Eth1Transaction) GetErrorMsg() string { - if x != nil { - return x.ErrorMsg - } - return "" -} - func (x *Eth1Transaction) GetLogs() []*Eth1Log { if x != nil { return x.Logs @@ -1278,9 +1269,7 @@ type Eth1TransactionIndexed struct { TxFee []byte `protobuf:"bytes,8,opt,name=tx_fee,json=txFee,proto3" json:"tx_fee,omitempty"` GasPrice []byte `protobuf:"bytes,9,opt,name=gas_price,json=gasPrice,proto3" json:"gas_price,omitempty"` IsContractCreation bool `protobuf:"varint,10,opt,name=is_contract_creation,json=isContractCreation,proto3" json:"is_contract_creation,omitempty"` - // reserved 11; // bool invokes_contract = 11; - InvokesContract bool `protobuf:"varint,11,opt,name=invokes_contract,json=invokesContract,proto3" json:"invokes_contract,omitempty"` - ErrorMsg string `protobuf:"bytes,12,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` + ErrorMsg string `protobuf:"bytes,12,opt,name=error_msg,json=errorMsg,proto3" json:"error_msg,omitempty"` // EIP 4844 BlobTxFee []byte `protobuf:"bytes,13,opt,name=blob_tx_fee,json=blobTxFee,proto3" json:"blob_tx_fee,omitempty"` BlobGasPrice []byte `protobuf:"bytes,14,opt,name=blob_gas_price,json=blobGasPrice,proto3" json:"blob_gas_price,omitempty"` @@ -1389,13 +1378,6 @@ func (x *Eth1TransactionIndexed) GetIsContractCreation() bool { return false } -func (x *Eth1TransactionIndexed) GetInvokesContract() bool { - if x != nil { - return x.InvokesContract - } - return false -} - func (x *Eth1TransactionIndexed) GetErrorMsg() string { if x != nil { return x.ErrorMsg @@ -2032,7 +2014,7 @@ var file_eth1_proto_rawDesc = []byte{ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xca, 0x06, 0x0a, 0x0f, 0x45, 0x74, 0x68, 0x31, + 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xb3, 0x06, 0x0a, 0x0f, 0x45, 0x74, 0x68, 0x31, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, @@ -2067,255 +2049,252 @@ var file_eth1_proto_rawDesc = []byte{ 0x6c, 0x6f, 0x67, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x73, 0x42, 0x6c, 0x6f, 0x6f, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, - 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, - 0x12, 0x22, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x74, 0x68, 0x31, 0x4c, 0x6f, 0x67, 0x52, 0x04, - 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x03, 0x69, 0x74, 0x78, 0x18, 0x18, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x74, 0x68, 0x31, 0x49, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x03, 0x69, 0x74, 0x78, 0x12, 0x2e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x65, - 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x19, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x65, 0x65, 0x50, 0x65, 0x72, 0x42, - 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, - 0x1a, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x6c, - 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x1b, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, - 0x64, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, - 0x55, 0x73, 0x65, 0x64, 0x22, 0x4d, 0x0a, 0x10, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, - 0x63, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, - 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x22, 0x49, 0x0a, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x69, - 0x0a, 0x07, 0x45, 0x74, 0x68, 0x31, 0x4c, 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x64, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x17, 0x45, 0x74, - 0x68, 0x31, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, - 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, - 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x22, 0xf3, 0x05, 0x0a, 0x10, 0x45, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, - 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, - 0x0a, 0x0a, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, - 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, - 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x64, - 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, - 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x73, - 0x65, 0x46, 0x65, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x5f, 0x63, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x75, 0x6e, 0x63, 0x6c, 0x65, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x65, 0x76, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x03, 0x6d, 0x65, 0x76, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x5f, 0x67, - 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, - 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x2a, - 0x0a, 0x11, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, - 0x69, 0x63, 0x65, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x68, 0x69, 0x67, 0x68, 0x65, - 0x73, 0x74, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78, - 0x5f, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, - 0x78, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x63, 0x6c, 0x65, - 0x5f, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x75, - 0x6e, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x69, 0x6e, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, - 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x62, - 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, - 0x65, 0x78, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, - 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, - 0x62, 0x47, 0x61, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x20, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x62, 0x6c, 0x6f, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x88, 0x02, 0x0a, 0x10, 0x45, - 0x74, 0x68, 0x31, 0x55, 0x6e, 0x63, 0x6c, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x74, 0x75, 0x73, 0x12, 0x22, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x17, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x74, 0x68, 0x31, 0x4c, 0x6f, + 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x03, 0x69, 0x74, 0x78, 0x18, 0x18, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x74, 0x68, + 0x31, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x69, 0x74, 0x78, 0x12, 0x2e, 0x0a, 0x14, 0x6d, 0x61, 0x78, + 0x5f, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, + 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x46, 0x65, 0x65, 0x50, + 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x62, 0x6c, 0x6f, + 0x62, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x24, 0x0a, + 0x0e, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, + 0x1b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x50, 0x72, + 0x69, 0x63, 0x65, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, + 0x75, 0x73, 0x65, 0x64, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, + 0x47, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x4a, 0x04, 0x08, 0x16, 0x10, 0x17, 0x22, 0x4d, 0x0a, + 0x10, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x49, 0x0a, 0x0a, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, + 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x69, 0x0a, 0x07, 0x45, 0x74, 0x68, 0x31, 0x4c, + 0x6f, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, + 0x70, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, + 0x63, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x17, 0x45, 0x74, 0x68, 0x31, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xf3, 0x05, + 0x0a, 0x10, 0x45, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x6e, 0x63, 0x6c, 0x65, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x75, 0x6e, 0x63, + 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, + 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, + 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, + 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, - 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, + 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, - 0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, - 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x12, 0x1e, 0x0a, - 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x2e, 0x0a, - 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, - 0x65, 0x77, 0x61, 0x72, 0x64, 0x22, 0xdb, 0x01, 0x0a, 0x15, 0x45, 0x74, 0x68, 0x31, 0x57, 0x69, - 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, - 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, - 0x69, 0x6d, 0x65, 0x22, 0xf5, 0x03, 0x0a, 0x16, 0x45, 0x74, 0x68, 0x31, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, - 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x15, 0x0a, 0x06, - 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x78, - 0x46, 0x65, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x73, 0x5f, 0x63, 0x6f, - 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, - 0x76, 0x6f, 0x6b, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1e, 0x0a, 0x0b, 0x62, 0x6c, - 0x6f, 0x62, 0x5f, 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x54, 0x78, 0x46, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x6c, - 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x29, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xfe, 0x01, 0x0a, 0x1e, - 0x45, 0x74, 0x68, 0x31, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, + 0x73, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, + 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x12, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x12, 0x1f, 0x0a, + 0x0b, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x13, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0a, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2b, + 0x0a, 0x11, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6d, + 0x65, 0x76, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x65, 0x76, 0x12, 0x28, 0x0a, + 0x10, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x77, 0x65, 0x73, 0x74, 0x47, + 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x68, 0x69, 0x67, 0x68, 0x65, + 0x73, 0x74, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0f, 0x68, 0x69, 0x67, 0x68, 0x65, 0x73, 0x74, 0x47, 0x61, 0x73, 0x50, 0x72, + 0x69, 0x63, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x78, 0x5f, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x18, 0x19, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x52, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x75, 0x6e, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x77, + 0x61, 0x72, 0x64, 0x12, 0x3c, 0x0a, 0x1a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x18, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, + 0x65, 0x64, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, + 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x65, 0x78, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x12, 0x34, 0x0a, + 0x16, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x62, + 0x6c, 0x6f, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0x88, 0x02, 0x0a, 0x10, 0x45, 0x74, 0x68, 0x31, 0x55, 0x6e, 0x63, 0x6c, + 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x62, + 0x61, 0x73, 0x65, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, + 0x61, 0x73, 0x65, 0x46, 0x65, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63, + 0x75, 0x6c, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x64, 0x69, 0x66, 0x66, + 0x69, 0x63, 0x75, 0x6c, 0x74, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x72, 0x65, 0x77, 0x61, 0x72, 0x64, 0x22, 0xdb, + 0x01, 0x0a, 0x15, 0x45, 0x74, 0x68, 0x31, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, + 0x6c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x27, 0x0a, 0x0f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0xd0, 0x03, 0x0a, + 0x16, 0x45, 0x74, 0x68, 0x31, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, + 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x66, + 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, + 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x15, 0x0a, 0x06, 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x78, 0x46, 0x65, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x73, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x1e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, + 0x6c, 0x6f, 0x62, 0x54, 0x78, 0x46, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x62, + 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x29, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4a, 0x04, 0x08, 0x0b, 0x10, 0x0c, 0x22, + 0xfe, 0x01, 0x0a, 0x1e, 0x45, 0x74, 0x68, 0x31, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, + 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, + 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, + 0x22, 0xb3, 0x03, 0x0a, 0x1a, 0x45, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x62, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, + 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x22, 0xb3, 0x03, 0x0a, - 0x1a, 0x45, 0x74, 0x68, 0x31, 0x42, 0x6c, 0x6f, 0x62, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, - 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x15, 0x0a, 0x06, - 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x78, - 0x46, 0x65, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x1e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x54, 0x78, 0x46, 0x65, 0x65, - 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, - 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x62, 0x47, 0x61, - 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, - 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x73, 0x67, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x73, 0x67, 0x12, 0x32, - 0x0a, 0x15, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x13, 0x62, - 0x6c, 0x6f, 0x62, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x48, 0x61, 0x73, 0x68, - 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x10, 0x45, 0x74, 0x68, 0x31, 0x45, 0x52, 0x43, 0x32, 0x30, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xeb, 0x01, 0x0a, 0x11, 0x45, - 0x74, 0x68, 0x31, 0x45, 0x52, 0x43, 0x37, 0x32, 0x31, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, - 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x6f, 0x6b, - 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, - 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, - 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x19, 0x0a, - 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x64, 0x22, 0x9e, 0x02, 0x0a, 0x12, 0x45, 0x54, 0x68, - 0x31, 0x45, 0x52, 0x43, 0x31, 0x31, 0x35, 0x35, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, - 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, - 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x19, 0x0a, 0x08, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2a, 0x32, 0x0a, 0x0a, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x01, - 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x10, 0x02, 0x42, 0x09, 0x5a, - 0x07, 0x2e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x15, 0x0a, 0x06, 0x74, 0x78, 0x5f, 0x66, 0x65, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x74, 0x78, 0x46, 0x65, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, + 0x72, 0x69, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x12, 0x1e, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x74, 0x78, 0x5f, + 0x66, 0x65, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x62, 0x54, + 0x78, 0x46, 0x65, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x67, 0x61, 0x73, + 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x62, 0x6c, + 0x6f, 0x62, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6e, + 0x76, 0x6f, 0x6b, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x6b, 0x65, 0x73, 0x43, 0x6f, 0x6e, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, + 0x73, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, + 0x73, 0x67, 0x12, 0x32, 0x0a, 0x15, 0x62, 0x6c, 0x6f, 0x62, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x13, 0x62, 0x6c, 0x6f, 0x62, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x64, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x10, 0x45, 0x74, 0x68, 0x31, 0x45, + 0x52, 0x43, 0x32, 0x30, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xeb, + 0x01, 0x0a, 0x11, 0x45, 0x74, 0x68, 0x31, 0x45, 0x52, 0x43, 0x37, 0x32, 0x31, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, + 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, + 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, + 0x6f, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x64, 0x22, 0x9e, 0x02, 0x0a, + 0x12, 0x45, 0x54, 0x68, 0x31, 0x45, 0x52, 0x43, 0x31, 0x31, 0x35, 0x35, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, + 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x02, 0x74, 0x6f, + 0x12, 0x19, 0x0a, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2a, 0x32, 0x0a, + 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, + 0x53, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x10, + 0x02, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/backend/pkg/commons/types/eth1.proto b/backend/pkg/commons/types/eth1.proto index c1a7ff9ad..68ec119b9 100644 --- a/backend/pkg/commons/types/eth1.proto +++ b/backend/pkg/commons/types/eth1.proto @@ -64,8 +64,7 @@ message Eth1Transaction { uint64 gas_used = 19; bytes logs_bloom = 20; uint64 status = 21; - //reserved 22; // string error_msg = 22; - string error_msg = 22; + reserved 22; // string error_msg = 22; repeated Eth1Log logs = 23; @@ -174,8 +173,7 @@ message Eth1TransactionIndexed { bytes tx_fee = 8; bytes gas_price = 9; bool is_contract_creation = 10; -// reserved 11; // bool invokes_contract = 11; - bool invokes_contract = 11; + reserved 11; // bool invokes_contract = 11; string error_msg = 12; // EIP 4844