diff --git a/.github/workflows/astria-build-and-publish-image.yml b/.github/workflows/astria-build-and-publish-image.yml new file mode 100644 index 000000000..57c2bd6f7 --- /dev/null +++ b/.github/workflows/astria-build-and-publish-image.yml @@ -0,0 +1,68 @@ +name: Build and Publish Docker image + +# Trigger on pushes to astria branch, new semantic version tags, and pull request updates +on: + workflow_dispatch: + push: + branches: + - "astria" + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+" + # trigger on pull request updates when target is `astria` branch + pull_request: + branches: + - "astria" + +jobs: + build-and-publish-latest: + runs-on: ubuntu-latest + steps: + # Checking out the repo + - uses: actions/checkout@v3 + # Setting up Go + - uses: actions/setup-go@v4 + with: + go-version: "^1.20.x" # The Go version to download (if necessary) and use. + - run: go version + + # https://github.com/docker/setup-qemu-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # Generate correct tabs and labels + - name: Docker metadata + id: metadata + uses: docker/metadata-action@v4 + with: + images: | + ghcr.io/astriaorg/go-ethereum + tags: | + type=ref,event=pr + type=semver,pattern={{major}}.{{minor}}.{{patch}} + type=sha + # set latest tag for `astria` branch + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'astria') }} + - name: Build and push + uses: docker/build-push-action@v4 + with: + # this gets rid of the unknown/unknown image that is created without this setting + # https://github.com/docker/build-push-action/issues/820#issuecomment-1455687416 + provenance: false + context: . + # It takes a long time to build the arm image right now, so we only build it on tags which is what we use for releases, or on merges to the default branch. + platforms: ${{ (contains(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/astria') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} + push: true + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index ed69a0478..8087898af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,9 +20,14 @@ RUN cd /go-ethereum && go run build/ci.go install -static ./cmd/geth FROM alpine:latest RUN apk add --no-cache ca-certificates +# Astria - add bash and jq to support start-geth.sh in conductor +RUN apk add bash jq +# Astria - copy genesis.json so it can be used in start-geth.sh +COPY genesis.json /genesis.json COPY --from=builder /go-ethereum/build/bin/geth /usr/local/bin/ -EXPOSE 8545 8546 30303 30303/udp +# Astria - add 50051 for GRPC +EXPOSE 8545 8546 30303 30303/udp 50051 ENTRYPOINT ["geth"] # Add some metadata labels to help programatic image consumption diff --git a/Dockerfile.alltools b/Dockerfile.alltools index 70ccc3982..598a45998 100644 --- a/Dockerfile.alltools +++ b/Dockerfile.alltools @@ -22,7 +22,8 @@ FROM alpine:latest RUN apk add --no-cache ca-certificates COPY --from=builder /go-ethereum/build/bin/* /usr/local/bin/ -EXPOSE 8545 8546 30303 30303/udp +# Astria - add 50051 for GRPC +EXPOSE 8545 8546 30303 30303/udp 50051 # Add some metadata labels to help programatic image consumption ARG COMMIT="" diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 027dac7bd..bda22b4e0 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/grpc/execution" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/internal/version" @@ -201,6 +202,14 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { if ctx.IsSet(utils.GraphQLEnabledFlag.Name) { utils.RegisterGraphQLService(stack, backend, filterSystem, &cfg.Node) } + + // Configure gRPC if requested. + if ctx.IsSet(utils.GRPCEnabledFlag.Name) { + serviceV1a1 := execution.NewExecutionServiceServerV1Alpha1(eth) + serviceV1a2 := execution.NewExecutionServiceServerV1Alpha2(eth) + utils.RegisterGRPCExecutionService(stack, serviceV1a1, serviceV1a2, &cfg.Node) + } + // Add the Ethereum Stats daemon if requested. if cfg.Ethstats.URL != "" { utils.RegisterEthStatsService(stack, backend, cfg.Ethstats.URL) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 2d4fe3dc0..84db68ddd 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -176,6 +176,9 @@ var ( utils.AllowUnprotectedTxs, utils.BatchRequestLimit, utils.BatchResponseMaxSize, + utils.GRPCEnabledFlag, + utils.GRPCHostFlag, + utils.GRPCPortFlag, } metricsFlags = []cli.Flag{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e9a7c7c11..99a285c1c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -55,6 +55,8 @@ import ( "github.com/ethereum/go-ethereum/ethdb/remotedb" "github.com/ethereum/go-ethereum/ethstats" "github.com/ethereum/go-ethereum/graphql" + executionv1a1 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha1" + executionv1a2 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha2" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/les" @@ -733,6 +735,24 @@ var ( Usage: "Enables the (deprecated) personal namespace", Category: flags.APICategory, } + // grpc + GRPCEnabledFlag = &cli.BoolFlag{ + Name: "grpc", + Usage: "Enable the gRPC server", + Category: flags.APICategory, + } + GRPCHostFlag = &cli.StringFlag{ + Name: "grpc.addr", + Usage: "gRPC server listening interface", + Value: node.DefaultGRPCHost, + Category: flags.APICategory, + } + GRPCPortFlag = &cli.IntFlag{ + Name: "grpc.port", + Usage: "gRPC server listening port", + Value: node.DefaultGRPCPort, + Category: flags.APICategory, + } // Network Settings MaxPeersFlag = &cli.IntFlag{ @@ -1175,6 +1195,19 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) { } } +// setGRPC creates the gRPC RPC listener interface string from the set command +// line flags, returning empty if the gRPC endpoint is disabled. +func setGRPC(ctx *cli.Context, cfg *node.Config) { + if ctx.Bool(GRPCEnabledFlag.Name) { + if ctx.IsSet(GRPCHostFlag.Name) { + cfg.GRPCHost = ctx.String(GRPCHostFlag.Name) + } + if ctx.IsSet(GRPCPortFlag.Name) { + cfg.GRPCPort = ctx.Int(GRPCPortFlag.Name) + } + } +} + // setGraphQL creates the GraphQL listener interface string from the set // command line flags, returning empty if the GraphQL endpoint is disabled. func setGraphQL(ctx *cli.Context, cfg *node.Config) { @@ -1415,6 +1448,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { SetP2PConfig(ctx, &cfg.P2P) setIPC(ctx, cfg) setHTTP(ctx, cfg) + setGRPC(ctx, cfg) setGraphQL(ctx, cfg) setWS(ctx, cfg) setNodeUserIdent(ctx, cfg) @@ -1948,6 +1982,14 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst } } +// RegisterGRPCExecutionService adds the gRPC API to the node. +// It was done this way so that our grpc execution server can access the ethapi.Backend +func RegisterGRPCExecutionService(stack *node.Node, execServerV1a1 executionv1a1.ExecutionServiceServer, execServerV1a2 executionv1a2.ExecutionServiceServer, cfg *node.Config) { + if err := node.NewGRPCServerHandler(stack, execServerV1a1, execServerV1a2, cfg); err != nil { + Fatalf("Failed to register the gRPC service: %v", err) + } +} + // RegisterFilterAPI adds the eth log filtering RPC API to the node. func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem { isLightClient := ethcfg.SyncMode == downloader.LightSync diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 8eb9863da..cae8cb853 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -234,7 +234,6 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa } // Verify the block's difficulty based on its timestamp and parent's difficulty expected := ethash.CalcDifficulty(chain, header.Time, parent) - if expected.Cmp(header.Difficulty) != 0 { return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) } diff --git a/core/blockchain.go b/core/blockchain.go index f458da825..521b3a3a6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -319,10 +319,10 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis return nil, ErrNoGenesis } - bc.currentBlock.Store(nil) - bc.currentSnapBlock.Store(nil) - bc.currentFinalBlock.Store(nil) - bc.currentSafeBlock.Store(nil) + bc.currentBlock.Store(bc.genesisBlock.Header()) + bc.currentSnapBlock.Store(bc.genesisBlock.Header()) + bc.currentFinalBlock.Store(bc.genesisBlock.Header()) + bc.currentSafeBlock.Store(bc.genesisBlock.Header()) // Update chain info data metrics chainInfoGauge.Update(metrics.GaugeInfoValue{"chain_id": bc.chainConfig.ChainID.String()}) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 0d4e05da4..750838466 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -72,6 +72,8 @@ type TxPool struct { subs event.SubscriptionScope // Subscription scope to unsubscribe all on shutdown quit chan chan error // Quit channel to tear down the head updater + + astria *astriaOrdered } // New creates a new transaction pool to gather, sort and filter inbound @@ -356,6 +358,108 @@ func (p *TxPool) Stats() (int, int) { return runnable, blocked } +func (pool *TxPool) SetAstriaOrdered(rawTxs [][]byte) { + txs := []*types.Transaction{} + for idx, rawTx := range rawTxs { + tx := new(types.Transaction) + err := tx.UnmarshalBinary(rawTx) + if err != nil { + log.Warn("failed to unmarshal raw astria tx bytes", rawTx, "at index", idx, "error:", err) + continue + } + + err = pool.astriaValidate(tx) + if err != nil { + log.Warn("astria tx failed validation at index", idx, "error:", err) + continue + } + + txs = append(txs, tx) + } + + pool.astria = newAstriaOrdered(types.Transactions(txs)) +} + +func (pool *TxPool) ClearAstriaOrdered() { + if pool.astria == nil { + return + } + pool.astria.clear() +} + +func (pool *TxPool) AstriaOrdered() *types.Transactions { + // sus but whatever + if pool.astria == nil { + return &types.Transactions{} + } + return &pool.astria.txs +} + +// validateTx checks whether a transaction is valid according to the consensus +// rules and adheres to some heuristic limits of the local node (price and size). +func (pool *TxPool) astriaValidate(tx *types.Transaction) error { + // Accept only legacy transactions until EIP-2718/2930 activates. + if !pool.eip2718 && tx.Type() != types.LegacyTxType { + return core.ErrTxTypeNotSupported + } + // Reject dynamic fee transactions until EIP-1559 activates. + if !pool.eip1559 && tx.Type() == types.DynamicFeeTxType { + return core.ErrTxTypeNotSupported + } + // Reject transactions over defined size to prevent DOS attacks + if tx.Size() > txMaxSize { + return ErrOversizedData + } + // Check whether the init code size has been exceeded. + if pool.shanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { + return fmt.Errorf("%w: code size %v limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) + } + // Transactions can't be negative. This may never happen using RLP decoded + // transactions but may occur if you create a transaction using the RPC. + if tx.Value().Sign() < 0 { + return ErrNegativeValue + } + // Ensure the transaction doesn't exceed the current block limit gas. + if pool.currentMaxGas < tx.Gas() { + return ErrGasLimit + } + // Sanity check for extremely large numbers + if tx.GasFeeCap().BitLen() > 256 { + return core.ErrFeeCapVeryHigh + } + if tx.GasTipCap().BitLen() > 256 { + return core.ErrTipVeryHigh + } + // Ensure gasFeeCap is greater than or equal to gasTipCap. + if tx.GasFeeCapIntCmp(tx.GasTipCap()) < 0 { + return core.ErrTipAboveFeeCap + } + // Make sure the transaction is signed properly. + from, err := types.Sender(pool.signer, tx) + if err != nil { + return ErrInvalidSender + } + // Ensure the transaction adheres to nonce ordering + if pool.currentState.GetNonce(from) > tx.Nonce() { + return core.ErrNonceTooLow + } + // Transactor should have enough funds to cover the costs + // cost == V + GP * GL + balance := pool.currentState.GetBalance(from) + if balance.Cmp(tx.Cost()) < 0 { + return core.ErrInsufficientFunds + } + // Ensure the transaction has more gas than the basic tx fee. + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, pool.shanghai) + if err != nil { + return err + } + if tx.Gas() < intrGas { + return core.ErrIntrinsicGas + } + return nil +} + // Content retrieves the data content of the transaction pool, returning all the // pending as well as queued transactions, grouped by account and sorted by nonce. func (p *TxPool) Content() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) { @@ -415,3 +519,17 @@ func (p *TxPool) Status(hash common.Hash) TxStatus { } return TxStatusUnknown } + +type astriaOrdered struct { + txs types.Transactions +} + +func newAstriaOrdered(txs types.Transactions) *astriaOrdered { + return &astriaOrdered{ + txs: txs, + } +} + +func (ao *astriaOrdered) clear() { + ao.txs = *&types.Transactions{} +} diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index d1e199141..56a4fcda6 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -172,6 +172,7 @@ func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI { // If there are payloadAttributes: we try to assemble a block with the payloadAttributes // and return its payloadID. func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, payloadAttributes *engine.PayloadAttributes) (engine.ForkChoiceResponse, error) { + log.Info("ForkchoiceUpdatedV1 called") if payloadAttributes != nil { if payloadAttributes.Withdrawals != nil { return engine.STATUS_INVALID, engine.InvalidParams.With(errors.New("withdrawals not supported in V1")) diff --git a/genesis.json b/genesis.json new file mode 100644 index 000000000..57fca8b3f --- /dev/null +++ b/genesis.json @@ -0,0 +1,22 @@ +{ + "config": { + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "terminalTotalDifficulty": 0, + "ethash": {} + }, + "difficulty": "10000000", + "gasLimit": "8000000", + "alloc": { + "0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102": { "balance": "300000000000000000000" } + } +} diff --git a/go.mod b/go.mod index 385d5afdc..991d1ce0a 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa github.com/google/uuid v1.3.0 - github.com/gorilla/websocket v1.4.2 + github.com/gorilla/websocket v1.5.0 github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-bexpr v0.1.10 github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 @@ -70,6 +70,8 @@ require ( golang.org/x/text v0.13.0 golang.org/x/time v0.3.0 golang.org/x/tools v0.13.0 + google.golang.org/grpc v1.53.0 + google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -106,7 +108,6 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -123,7 +124,8 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/onsi/ginkgo v1.16.4 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.12.0 // indirect @@ -138,7 +140,7 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect + google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect gopkg.in/yaml.v2 v2.4.0 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index cc38e7975..db164a506 100644 --- a/go.sum +++ b/go.sum @@ -230,6 +230,7 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= @@ -294,7 +295,6 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -321,8 +321,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= @@ -472,20 +472,23 @@ github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= @@ -764,6 +767,7 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -847,6 +851,7 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= @@ -908,6 +913,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -921,6 +928,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -933,8 +942,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8 h1:KR8+MyP7/qOlV+8Af01LtjL04bu7on42eVsxT4EyBQk= +google.golang.org/protobuf v1.28.2-0.20220831092852-f930b1dc76e8/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/graphql/graphql.go b/graphql/graphql.go index 49be23af6..b1c024d3b 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -83,12 +83,26 @@ type Account struct { r *Resolver address common.Address blockNrOrHash rpc.BlockNumberOrHash + state *state.StateDB + mu sync.Mutex } // getState fetches the StateDB object for an account. func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { + a.mu.Lock() + defer a.mu.Unlock() + if a.state != nil { + return a.state, nil + } state, _, err := a.r.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash) - return state, err + if err != nil { + return nil, err + } + a.state = state + // Cache the state object. This is done so that concurrent resolvers + // don't have to fetch the object from DB individually. + a.state.GetOrNewStateObject(a.address) + return a.state, nil } func (a *Account) Address(ctx context.Context) (common.Address, error) { diff --git a/grpc/README.md b/grpc/README.md new file mode 100644 index 000000000..3c57c1cb2 --- /dev/null +++ b/grpc/README.md @@ -0,0 +1,48 @@ +This package provides a gRPC server as an entrypoint to the EVM. + +## Build and run from source: +```bash +# install necessary dependencies +brew install leveldb + +# build geth +make geth + +# generating protobuf files +buf generate buf.build/astria/astria --path "astria/execution" +``` + +See [private_network.md](../private_network.md) for running a local geth node. + +### Running with remote Docker image: +```bash +docker run --rm \ + -p 8545:8545 -p 30303:30303 -p 50051:50051 \ + ghcr.io/astriaorg/go-ethereum --goerli \ + --grpc --grpc.addr "0.0.0.0" --grpc.port 50051 +``` + +### Local Docker workflow: +```bash +# build local docker image +docker build \ + --build-arg COMMIT=$(git rev-parse HEAD) \ + --build-arg VERSION=0.1 \ + --build-arg BUILDNUM=1 \ + --tag ghcr.io/astriaorg/go-ethereum:local . + +# run local docker image +docker run --rm \ + -p 8545:8545 -p 30303:30303 -p 50051:50051 \ + ghcr.io/astriaorg/go-ethereum:local --goerli \ + --grpc --grpc.addr "0.0.0.0" --grpc.port 50051 + +# build and push to remote from local (as opposed to gh action) +docker build \ + --build-arg COMMIT=$(git rev-parse HEAD) \ + --build-arg VERSION=0.1 \ + --build-arg BUILDNUM=1 \ + --tag ghcr.io/astriaorg/go-ethereum:latest . +echo $CR_PAT | docker login ghcr.io -u astriaorg --password-stdin +docker push ghcr.io/astriaorg/go-ethereum:latest +``` diff --git a/grpc/buf.gen.yaml b/grpc/buf.gen.yaml new file mode 100644 index 000000000..32ceca95f --- /dev/null +++ b/grpc/buf.gen.yaml @@ -0,0 +1,22 @@ +# buf.gen.yaml +version: v1 +managed: + enabled: true + go_package_prefix: + # : name in go.mod + # : where generated code should be output + # default: / + default: github.com/ethereum/go-ethereum/grpc + # Remove `except` field if googleapis is not used + # except: + # - buf.build/googleapis/googleapis +plugins: + - plugin: buf.build/grpc/go + out: gen + opt: + - paths=source_relative + # dependencies + - plugin: buf.build/protocolbuffers/go + out: gen + opt: + - paths=source_relative diff --git a/grpc/execution/server.go b/grpc/execution/server.go new file mode 100644 index 000000000..dd048f1c6 --- /dev/null +++ b/grpc/execution/server.go @@ -0,0 +1,382 @@ +// Package execution provides the gRPC server for the execution layer. +// +// Its procedures will be called from the conductor. It is responsible +// for immediately executing lists of ordered transactions that come from the shared sequencer. +package execution + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/catalyst" + executionv1a1 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha1" + executionv1a2 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha2" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/miner" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/timestamppb" +) + +// executionServiceServer is the implementation of the ExecutionServiceServerV1Alpha1 interface. +type ExecutionServiceServerV1Alpha1 struct { + // NOTE - from the generated code: + // All implementations must embed UnimplementedExecutionServiceServer + // for forward compatibility + executionv1a1.UnimplementedExecutionServiceServer + + consensus *catalyst.ConsensusAPI + eth *eth.Ethereum + + bc *core.BlockChain +} + +func NewExecutionServiceServerV1Alpha1(eth *eth.Ethereum) *ExecutionServiceServerV1Alpha1 { + consensus := catalyst.NewConsensusAPI(eth) + + bc := eth.BlockChain() + + return &ExecutionServiceServerV1Alpha1{ + eth: eth, + consensus: consensus, + bc: bc, + } +} + +func (s *ExecutionServiceServerV1Alpha1) DoBlock(ctx context.Context, req *executionv1a1.DoBlockRequest) (*executionv1a1.DoBlockResponse, error) { + log.Info("DoBlock called request", "request", req) + prevHeadHash := common.BytesToHash(req.PrevBlockHash) + + // The Engine API has been modified to use transactions from this mempool and abide by it's ordering. + s.eth.TxPool().SetAstriaOrdered(req.Transactions) + + // Do the whole Engine API in a single loop + startForkChoice := &engine.ForkchoiceStateV1{ + HeadBlockHash: prevHeadHash, + SafeBlockHash: prevHeadHash, + FinalizedBlockHash: prevHeadHash, + } + payloadAttributes := &engine.PayloadAttributes{ + Timestamp: uint64(req.GetTimestamp().GetSeconds()), + Random: common.Hash{}, + SuggestedFeeRecipient: common.Address{}, + } + + fcStartResp, err := s.consensus.ForkchoiceUpdatedV1(*startForkChoice, payloadAttributes) + if err != nil { + return nil, err + } + + // TODO: we should probably just execute + store the block directly instead of using the engine api. + payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID) + if err != nil { + log.Error("failed to call GetPayloadV1", "err", err) + return nil, err + } + + // call blockchain.InsertChain to actually execute and write the blocks to state + block, err := engine.ExecutableDataToBlock(*payloadResp) + if err != nil { + return nil, err + } + blocks := types.Blocks{ + block, + } + n, err := s.bc.InsertChain(blocks) + if err != nil { + return nil, err + } + if n != 1 { + return nil, fmt.Errorf("failed to insert block into blockchain (n=%d)", n) + } + + // remove txs from original mempool + for _, tx := range block.Transactions() { + s.eth.TxPool().RemoveTx(tx.Hash()) + } + + finalizedBlock := s.bc.CurrentFinalBlock() + newForkChoice := &engine.ForkchoiceStateV1{ + HeadBlockHash: block.Hash(), + SafeBlockHash: block.Hash(), + FinalizedBlockHash: finalizedBlock.Hash(), + } + fcEndResp, err := s.consensus.ForkchoiceUpdatedV1(*newForkChoice, nil) + if err != nil { + log.Error("failed to call ForkchoiceUpdatedV1", "err", err) + return nil, err + } + + res := &executionv1a1.DoBlockResponse{ + BlockHash: fcEndResp.PayloadStatus.LatestValidHash.Bytes(), + } + return res, nil +} + +func (s *ExecutionServiceServerV1Alpha1) FinalizeBlock(ctx context.Context, req *executionv1a1.FinalizeBlockRequest) (*executionv1a1.FinalizeBlockResponse, error) { + header := s.bc.GetHeaderByHash(common.BytesToHash(req.BlockHash)) + if header == nil { + return nil, fmt.Errorf("failed to get header for block hash 0x%x", req.BlockHash) + } + + s.bc.SetFinalized(header) + return &executionv1a1.FinalizeBlockResponse{}, nil +} + +func (s *ExecutionServiceServerV1Alpha1) InitState(ctx context.Context, req *executionv1a1.InitStateRequest) (*executionv1a1.InitStateResponse, error) { + currHead := s.bc.CurrentHeader() + res := &executionv1a1.InitStateResponse{ + BlockHash: currHead.Hash().Bytes(), + } + + return res, nil +} + +// ExecutionServiceServerV1Alpha2 is the implementation of the +// ExecutionServiceServer interface. +type ExecutionServiceServerV1Alpha2 struct { + // NOTE - from the generated code: All implementations must embed + // UnimplementedExecutionServiceServer for forward compatibility + executionv1a2.UnimplementedExecutionServiceServer + + eth *eth.Ethereum + bc *core.BlockChain +} + +func NewExecutionServiceServerV1Alpha2(eth *eth.Ethereum) *ExecutionServiceServerV1Alpha2 { + bc := eth.BlockChain() + + if merger := eth.Merger(); !merger.PoSFinalized() { + merger.FinalizePoS() + } + + return &ExecutionServiceServerV1Alpha2{ + eth: eth, + bc: bc, + } +} + +// GetBlock will return a block given an identifier. +func (s *ExecutionServiceServerV1Alpha2) GetBlock(ctx context.Context, req *executionv1a2.GetBlockRequest) (*executionv1a2.Block, error) { + log.Info("GetBlock called", "request", req) + + res, err := s.getBlockFromIdentifier(req.GetIdentifier()) + if err != nil { + log.Error("failed finding block", err) + return nil, err + } + + log.Info("GetBlock completed", "request", req, "response", res) + return res, nil +} + +// BatchGetBlocks will return an array of Blocks given an array of block +// identifiers. +func (s *ExecutionServiceServerV1Alpha2) BatchGetBlocks(ctx context.Context, req *executionv1a2.BatchGetBlocksRequest) (*executionv1a2.BatchGetBlocksResponse, error) { + log.Info("BatchGetBlocks called", "request", req) + var blocks []*executionv1a2.Block + + ids := req.GetIdentifiers() + for _, id := range ids { + block, err := s.getBlockFromIdentifier(id) + if err != nil { + log.Error("failed finding block with id", id, "error", err) + return nil, err + } + + blocks = append(blocks, block) + } + + res := &executionv1a2.BatchGetBlocksResponse{ + Blocks: blocks, + } + + log.Info("BatchGetBlocks completed", "request", req, "response", res) + return res, nil +} + +// ExecuteBlock drives deterministic derivation of a rollup block from sequencer +// block data +func (s *ExecutionServiceServerV1Alpha2) ExecuteBlock(ctx context.Context, req *executionv1a2.ExecuteBlockRequest) (*executionv1a2.Block, error) { + log.Info("ExecuteBlock called", "request", req) + + // Validate block being created has valid previous hash + prevHeadHash := common.BytesToHash(req.PrevBlockHash) + softHash := s.bc.CurrentSafeBlock().Hash() + if prevHeadHash != softHash { + return nil, status.Error(codes.FailedPrecondition, "Block can only be created on top of soft block.") + } + + // This set of ordered TXs on the TxPool is has been configured to be used by + // the Miner when building a payload. + s.eth.TxPool().SetAstriaOrdered(req.Transactions) + + // Build a payload to add to the chain + payloadAttributes := &miner.BuildPayloadArgs{ + Parent: prevHeadHash, + Timestamp: uint64(req.GetTimestamp().GetSeconds()), + Random: common.Hash{}, + FeeRecipient: common.Address{}, + } + payload, err := s.eth.Miner().BuildPayload(payloadAttributes) + if err != nil { + log.Error("failed to build payload", "err", err) + return nil, status.Error(codes.InvalidArgument, "Could not build block with provided txs") + } + + // call blockchain.InsertChain to actually execute and write the blocks to + // state + block, err := engine.ExecutableDataToBlock(*payload.Resolve().ExecutionPayload) + if err != nil { + log.Error("failed to convert executable data to block", err) + return nil, status.Error(codes.Internal, "failed to execute block") + } + blocks := types.Blocks{ + block, + } + n, err := s.bc.InsertChain(blocks) + if err != nil { + log.Error("failed to insert block to chain", err, "index", n) + return nil, status.Error(codes.Internal, "failed to insert block to chain") + } + + // remove txs from original mempool + for _, tx := range block.Transactions() { + s.eth.TxPool().RemoveTx(tx.Hash()) + } + + res := &executionv1a2.Block{ + Number: uint32(block.NumberU64()), + Hash: block.Hash().Bytes(), + Timestamp: ×tamppb.Timestamp{ + Seconds: int64(block.Time()), + }, + } + + log.Info("ExecuteBlock completed", "request", req, "response", res) + return res, nil +} + +// GetCommitmentState fetches the current CommitmentState of the chain. +func (s *ExecutionServiceServerV1Alpha2) GetCommitmentState(ctx context.Context, req *executionv1a2.GetCommitmentStateRequest) (*executionv1a2.CommitmentState, error) { + log.Info("GetCommitmentState called", "request", req) + + softBlock, err := ethHeaderToExecutionBlock(s.bc.CurrentSafeBlock()) + if err != nil { + log.Error("error finding safe block", err) + return nil, status.Error(codes.Internal, "could not locate soft block") + } + firmBlock, err := ethHeaderToExecutionBlock(s.bc.CurrentFinalBlock()) + if err != nil { + log.Error("error finding final block", err) + return nil, status.Error(codes.Internal, "could not locate firm block") + } + + res := &executionv1a2.CommitmentState{ + Soft: softBlock, + Firm: firmBlock, + } + + log.Info("GetCommitmentState completed", "request", req, "response", res) + return res, nil +} + +// UpdateCommitmentState replaces the whole CommitmentState with a new +// CommitmentState. +func (s *ExecutionServiceServerV1Alpha2) UpdateCommitmentState(ctx context.Context, req *executionv1a2.UpdateCommitmentStateRequest) (*executionv1a2.CommitmentState, error) { + log.Info("UpdateCommitmentState called", "request", req) + + softEthHash := common.BytesToHash(req.CommitmentState.Soft.Hash) + firmEthHash := common.BytesToHash(req.CommitmentState.Firm.Hash) + + // Validate that the firm and soft blocks exist before going further + softBlock := s.bc.GetBlockByHash(softEthHash) + if softBlock == nil { + return nil, status.Error(codes.InvalidArgument, "Soft block specified does not exist") + } + firmBlock := s.bc.GetBlockByHash(firmEthHash) + if firmBlock == nil { + return nil, status.Error(codes.InvalidArgument, "Firm block specified does not exist") + } + + currentHead := s.bc.CurrentBlock().Hash() + + // Update the canonical chain to soft block. We must do this before last + // validation step since there is no way to check if firm block descends from + // anything but the canonical chain + if currentHead != softEthHash { + if _, err := s.bc.SetCanonical(softBlock); err != nil { + log.Error("failed updating canonical chain to soft block", err) + return nil, status.Error(codes.Internal, "Could not update head to safe hash") + } + } + + // Once head is updated validate that firm belongs to chain + if s.bc.GetCanonicalHash(firmBlock.NumberU64()) != firmEthHash { + log.Error("firm block not found in canonical chain defined by soft block, rolling back") + + // We don't want partial commitments, rolling back. + rollbackBlock := s.bc.GetBlockByHash(currentHead) + if _, err := s.bc.SetCanonical(rollbackBlock); err != nil { + panic("rollback to previous head after failed validation failed") + } + + return nil, status.Error(codes.InvalidArgument, "soft block in request is not a descendant of the current firmly committed block") + } + + // Updating the safe and final after everything validated + currentSafe := s.bc.CurrentSafeBlock().Hash() + if currentSafe != softEthHash { + s.bc.SetSafe(softBlock.Header()) + } + currentFirm := s.bc.CurrentFinalBlock().Hash() + if currentFirm != firmEthHash { + s.bc.SetFinalized(firmBlock.Header()) + } + + log.Info("UpdateCommitmentState completed", "request", req) + return req.CommitmentState, nil +} + +func (s *ExecutionServiceServerV1Alpha2) getBlockFromIdentifier(identifier *executionv1a2.BlockIdentifier) (*executionv1a2.Block, error) { + var header *types.Header + + // Grab the header based on the identifier provided + switch idType := identifier.Identifier.(type) { + case *executionv1a2.BlockIdentifier_BlockNumber: + header = s.bc.GetHeaderByNumber(uint64(identifier.GetBlockNumber())) + case *executionv1a2.BlockIdentifier_BlockHash: + header = s.bc.GetHeaderByHash(common.BytesToHash(identifier.GetBlockHash())) + default: + return nil, status.Errorf(codes.InvalidArgument, "identifier has unexpected type %T", idType) + } + + if header == nil { + return nil, status.Errorf(codes.NotFound, "Couldn't locate block with identifier %s", identifier.Identifier) + } + + res, err := ethHeaderToExecutionBlock(header) + if err != nil { + // This should never happen since we validate header exists above. + return nil, status.Error(codes.Internal, "internal error") + } + + return res, nil +} + +func ethHeaderToExecutionBlock(header *types.Header) (*executionv1a2.Block, error) { + if header == nil { + return nil, fmt.Errorf("cannot convert nil header to execution block") + } + + return &executionv1a2.Block{ + Number: uint32(header.Number.Int64()), + Hash: header.Hash().Bytes(), + ParentBlockHash: header.ParentHash.Bytes(), + }, nil +} diff --git a/grpc/gen/astria/execution/v1alpha1/execution.pb.go b/grpc/gen/astria/execution/v1alpha1/execution.pb.go new file mode 100644 index 000000000..cdd95aa5b --- /dev/null +++ b/grpc/gen/astria/execution/v1alpha1/execution.pb.go @@ -0,0 +1,510 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: astria/execution/v1alpha1/execution.proto + +package executionv1alpha1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DoBlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PrevBlockHash []byte `protobuf:"bytes,1,opt,name=prev_block_hash,json=prevBlockHash,proto3" json:"prev_block_hash,omitempty"` + Transactions [][]byte `protobuf:"bytes,2,rep,name=transactions,proto3" json:"transactions,omitempty"` + Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *DoBlockRequest) Reset() { + *x = DoBlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DoBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DoBlockRequest) ProtoMessage() {} + +func (x *DoBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DoBlockRequest.ProtoReflect.Descriptor instead. +func (*DoBlockRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{0} +} + +func (x *DoBlockRequest) GetPrevBlockHash() []byte { + if x != nil { + return x.PrevBlockHash + } + return nil +} + +func (x *DoBlockRequest) GetTransactions() [][]byte { + if x != nil { + return x.Transactions + } + return nil +} + +func (x *DoBlockRequest) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +type DoBlockResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockHash []byte `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` +} + +func (x *DoBlockResponse) Reset() { + *x = DoBlockResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DoBlockResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DoBlockResponse) ProtoMessage() {} + +func (x *DoBlockResponse) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DoBlockResponse.ProtoReflect.Descriptor instead. +func (*DoBlockResponse) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{1} +} + +func (x *DoBlockResponse) GetBlockHash() []byte { + if x != nil { + return x.BlockHash + } + return nil +} + +type FinalizeBlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockHash []byte `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` +} + +func (x *FinalizeBlockRequest) Reset() { + *x = FinalizeBlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FinalizeBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FinalizeBlockRequest) ProtoMessage() {} + +func (x *FinalizeBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FinalizeBlockRequest.ProtoReflect.Descriptor instead. +func (*FinalizeBlockRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{2} +} + +func (x *FinalizeBlockRequest) GetBlockHash() []byte { + if x != nil { + return x.BlockHash + } + return nil +} + +type FinalizeBlockResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FinalizeBlockResponse) Reset() { + *x = FinalizeBlockResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FinalizeBlockResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FinalizeBlockResponse) ProtoMessage() {} + +func (x *FinalizeBlockResponse) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FinalizeBlockResponse.ProtoReflect.Descriptor instead. +func (*FinalizeBlockResponse) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{3} +} + +type InitStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *InitStateRequest) Reset() { + *x = InitStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InitStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InitStateRequest) ProtoMessage() {} + +func (x *InitStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InitStateRequest.ProtoReflect.Descriptor instead. +func (*InitStateRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{4} +} + +type InitStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BlockHash []byte `protobuf:"bytes,1,opt,name=block_hash,json=blockHash,proto3" json:"block_hash,omitempty"` +} + +func (x *InitStateResponse) Reset() { + *x = InitStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InitStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InitStateResponse) ProtoMessage() {} + +func (x *InitStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha1_execution_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InitStateResponse.ProtoReflect.Descriptor instead. +func (*InitStateResponse) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha1_execution_proto_rawDescGZIP(), []int{5} +} + +func (x *InitStateResponse) GetBlockHash() []byte { + if x != nil { + return x.BlockHash + } + return nil +} + +var File_astria_execution_v1alpha1_execution_proto protoreflect.FileDescriptor + +var file_astria_execution_v1alpha1_execution_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x61, 0x73, 0x74, + 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x96, 0x01, 0x0a, 0x0e, 0x44, 0x6f, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x70, 0x72, + 0x65, 0x76, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x22, 0x30, 0x0a, 0x0f, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x22, 0x35, 0x0a, 0x14, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x22, 0x17, 0x0a, 0x15, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x12, 0x0a, 0x10, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x32, 0x0a, 0x11, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x32, 0xd0, 0x02, 0x0a, 0x10, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, + 0x66, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x61, + 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x61, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x07, 0x44, 0x6f, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x12, 0x29, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, + 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x72, 0x0a, 0x0d, 0x46, 0x69, 0x6e, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2f, 0x2e, 0x61, 0x73, 0x74, + 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x61, 0x73, + 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x87, 0x02, + 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, + 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, + 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, + 0x75, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2f, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x3b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x45, 0x58, 0xaa, 0x02, 0x19, 0x41, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x19, 0x41, 0x73, 0x74, 0x72, 0x69, 0x61, 0x5c, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0xe2, 0x02, 0x25, 0x41, 0x73, 0x74, 0x72, 0x69, 0x61, 0x5c, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1b, 0x41, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x3a, 0x3a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_astria_execution_v1alpha1_execution_proto_rawDescOnce sync.Once + file_astria_execution_v1alpha1_execution_proto_rawDescData = file_astria_execution_v1alpha1_execution_proto_rawDesc +) + +func file_astria_execution_v1alpha1_execution_proto_rawDescGZIP() []byte { + file_astria_execution_v1alpha1_execution_proto_rawDescOnce.Do(func() { + file_astria_execution_v1alpha1_execution_proto_rawDescData = protoimpl.X.CompressGZIP(file_astria_execution_v1alpha1_execution_proto_rawDescData) + }) + return file_astria_execution_v1alpha1_execution_proto_rawDescData +} + +var file_astria_execution_v1alpha1_execution_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_astria_execution_v1alpha1_execution_proto_goTypes = []interface{}{ + (*DoBlockRequest)(nil), // 0: astria.execution.v1alpha1.DoBlockRequest + (*DoBlockResponse)(nil), // 1: astria.execution.v1alpha1.DoBlockResponse + (*FinalizeBlockRequest)(nil), // 2: astria.execution.v1alpha1.FinalizeBlockRequest + (*FinalizeBlockResponse)(nil), // 3: astria.execution.v1alpha1.FinalizeBlockResponse + (*InitStateRequest)(nil), // 4: astria.execution.v1alpha1.InitStateRequest + (*InitStateResponse)(nil), // 5: astria.execution.v1alpha1.InitStateResponse + (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp +} +var file_astria_execution_v1alpha1_execution_proto_depIdxs = []int32{ + 6, // 0: astria.execution.v1alpha1.DoBlockRequest.timestamp:type_name -> google.protobuf.Timestamp + 4, // 1: astria.execution.v1alpha1.ExecutionService.InitState:input_type -> astria.execution.v1alpha1.InitStateRequest + 0, // 2: astria.execution.v1alpha1.ExecutionService.DoBlock:input_type -> astria.execution.v1alpha1.DoBlockRequest + 2, // 3: astria.execution.v1alpha1.ExecutionService.FinalizeBlock:input_type -> astria.execution.v1alpha1.FinalizeBlockRequest + 5, // 4: astria.execution.v1alpha1.ExecutionService.InitState:output_type -> astria.execution.v1alpha1.InitStateResponse + 1, // 5: astria.execution.v1alpha1.ExecutionService.DoBlock:output_type -> astria.execution.v1alpha1.DoBlockResponse + 3, // 6: astria.execution.v1alpha1.ExecutionService.FinalizeBlock:output_type -> astria.execution.v1alpha1.FinalizeBlockResponse + 4, // [4:7] is the sub-list for method output_type + 1, // [1:4] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_astria_execution_v1alpha1_execution_proto_init() } +func file_astria_execution_v1alpha1_execution_proto_init() { + if File_astria_execution_v1alpha1_execution_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_astria_execution_v1alpha1_execution_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DoBlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha1_execution_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DoBlockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha1_execution_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FinalizeBlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha1_execution_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FinalizeBlockResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha1_execution_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha1_execution_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitStateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_astria_execution_v1alpha1_execution_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_astria_execution_v1alpha1_execution_proto_goTypes, + DependencyIndexes: file_astria_execution_v1alpha1_execution_proto_depIdxs, + MessageInfos: file_astria_execution_v1alpha1_execution_proto_msgTypes, + }.Build() + File_astria_execution_v1alpha1_execution_proto = out.File + file_astria_execution_v1alpha1_execution_proto_rawDesc = nil + file_astria_execution_v1alpha1_execution_proto_goTypes = nil + file_astria_execution_v1alpha1_execution_proto_depIdxs = nil +} diff --git a/grpc/gen/astria/execution/v1alpha1/execution_grpc.pb.go b/grpc/gen/astria/execution/v1alpha1/execution_grpc.pb.go new file mode 100644 index 000000000..7412181b2 --- /dev/null +++ b/grpc/gen/astria/execution/v1alpha1/execution_grpc.pb.go @@ -0,0 +1,183 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: astria/execution/v1alpha1/execution.proto + +package executionv1alpha1 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ExecutionService_InitState_FullMethodName = "/astria.execution.v1alpha1.ExecutionService/InitState" + ExecutionService_DoBlock_FullMethodName = "/astria.execution.v1alpha1.ExecutionService/DoBlock" + ExecutionService_FinalizeBlock_FullMethodName = "/astria.execution.v1alpha1.ExecutionService/FinalizeBlock" +) + +// ExecutionServiceClient is the client API for ExecutionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ExecutionServiceClient interface { + InitState(ctx context.Context, in *InitStateRequest, opts ...grpc.CallOption) (*InitStateResponse, error) + DoBlock(ctx context.Context, in *DoBlockRequest, opts ...grpc.CallOption) (*DoBlockResponse, error) + FinalizeBlock(ctx context.Context, in *FinalizeBlockRequest, opts ...grpc.CallOption) (*FinalizeBlockResponse, error) +} + +type executionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewExecutionServiceClient(cc grpc.ClientConnInterface) ExecutionServiceClient { + return &executionServiceClient{cc} +} + +func (c *executionServiceClient) InitState(ctx context.Context, in *InitStateRequest, opts ...grpc.CallOption) (*InitStateResponse, error) { + out := new(InitStateResponse) + err := c.cc.Invoke(ctx, ExecutionService_InitState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) DoBlock(ctx context.Context, in *DoBlockRequest, opts ...grpc.CallOption) (*DoBlockResponse, error) { + out := new(DoBlockResponse) + err := c.cc.Invoke(ctx, ExecutionService_DoBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) FinalizeBlock(ctx context.Context, in *FinalizeBlockRequest, opts ...grpc.CallOption) (*FinalizeBlockResponse, error) { + out := new(FinalizeBlockResponse) + err := c.cc.Invoke(ctx, ExecutionService_FinalizeBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExecutionServiceServer is the server API for ExecutionService service. +// All implementations must embed UnimplementedExecutionServiceServer +// for forward compatibility +type ExecutionServiceServer interface { + InitState(context.Context, *InitStateRequest) (*InitStateResponse, error) + DoBlock(context.Context, *DoBlockRequest) (*DoBlockResponse, error) + FinalizeBlock(context.Context, *FinalizeBlockRequest) (*FinalizeBlockResponse, error) + mustEmbedUnimplementedExecutionServiceServer() +} + +// UnimplementedExecutionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedExecutionServiceServer struct { +} + +func (UnimplementedExecutionServiceServer) InitState(context.Context, *InitStateRequest) (*InitStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InitState not implemented") +} +func (UnimplementedExecutionServiceServer) DoBlock(context.Context, *DoBlockRequest) (*DoBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DoBlock not implemented") +} +func (UnimplementedExecutionServiceServer) FinalizeBlock(context.Context, *FinalizeBlockRequest) (*FinalizeBlockResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method FinalizeBlock not implemented") +} +func (UnimplementedExecutionServiceServer) mustEmbedUnimplementedExecutionServiceServer() {} + +// UnsafeExecutionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ExecutionServiceServer will +// result in compilation errors. +type UnsafeExecutionServiceServer interface { + mustEmbedUnimplementedExecutionServiceServer() +} + +func RegisterExecutionServiceServer(s grpc.ServiceRegistrar, srv ExecutionServiceServer) { + s.RegisterService(&ExecutionService_ServiceDesc, srv) +} + +func _ExecutionService_InitState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(InitStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).InitState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_InitState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).InitState(ctx, req.(*InitStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_DoBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DoBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).DoBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_DoBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).DoBlock(ctx, req.(*DoBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_FinalizeBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FinalizeBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).FinalizeBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_FinalizeBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).FinalizeBlock(ctx, req.(*FinalizeBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ExecutionService_ServiceDesc is the grpc.ServiceDesc for ExecutionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ExecutionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "astria.execution.v1alpha1.ExecutionService", + HandlerType: (*ExecutionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "InitState", + Handler: _ExecutionService_InitState_Handler, + }, + { + MethodName: "DoBlock", + Handler: _ExecutionService_DoBlock_Handler, + }, + { + MethodName: "FinalizeBlock", + Handler: _ExecutionService_FinalizeBlock_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "astria/execution/v1alpha1/execution.proto", +} diff --git a/grpc/gen/astria/execution/v1alpha2/execution.pb.go b/grpc/gen/astria/execution/v1alpha2/execution.pb.go new file mode 100644 index 000000000..e62d75737 --- /dev/null +++ b/grpc/gen/astria/execution/v1alpha2/execution.pb.go @@ -0,0 +1,865 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc (unknown) +// source: astria/execution/v1alpha2/execution.proto + +package executionv1alpha2 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The set of information which deterministic driver of block production +// must know about a given rollup Block +type Block struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The block number + Number uint32 `protobuf:"varint,1,opt,name=number,proto3" json:"number,omitempty"` + // The hash of the block + Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` + // The hash from the parent block + ParentBlockHash []byte `protobuf:"bytes,3,opt,name=parent_block_hash,json=parentBlockHash,proto3" json:"parent_block_hash,omitempty"` + // Timestamp on the block, standardized to google protobuf standard. + Timestamp *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *Block) Reset() { + *x = Block{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Block) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Block) ProtoMessage() {} + +func (x *Block) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Block.ProtoReflect.Descriptor instead. +func (*Block) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{0} +} + +func (x *Block) GetNumber() uint32 { + if x != nil { + return x.Number + } + return 0 +} + +func (x *Block) GetHash() []byte { + if x != nil { + return x.Hash + } + return nil +} + +func (x *Block) GetParentBlockHash() []byte { + if x != nil { + return x.ParentBlockHash + } + return nil +} + +func (x *Block) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +// Fields which are indexed for finding blocks on a blockchain. +type BlockIdentifier struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Identifier: + // + // *BlockIdentifier_BlockNumber + // *BlockIdentifier_BlockHash + Identifier isBlockIdentifier_Identifier `protobuf_oneof:"identifier"` +} + +func (x *BlockIdentifier) Reset() { + *x = BlockIdentifier{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BlockIdentifier) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BlockIdentifier) ProtoMessage() {} + +func (x *BlockIdentifier) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BlockIdentifier.ProtoReflect.Descriptor instead. +func (*BlockIdentifier) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{1} +} + +func (m *BlockIdentifier) GetIdentifier() isBlockIdentifier_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *BlockIdentifier) GetBlockNumber() uint32 { + if x, ok := x.GetIdentifier().(*BlockIdentifier_BlockNumber); ok { + return x.BlockNumber + } + return 0 +} + +func (x *BlockIdentifier) GetBlockHash() []byte { + if x, ok := x.GetIdentifier().(*BlockIdentifier_BlockHash); ok { + return x.BlockHash + } + return nil +} + +type isBlockIdentifier_Identifier interface { + isBlockIdentifier_Identifier() +} + +type BlockIdentifier_BlockNumber struct { + BlockNumber uint32 `protobuf:"varint,1,opt,name=block_number,json=blockNumber,proto3,oneof"` +} + +type BlockIdentifier_BlockHash struct { + BlockHash []byte `protobuf:"bytes,2,opt,name=block_hash,json=blockHash,proto3,oneof"` +} + +func (*BlockIdentifier_BlockNumber) isBlockIdentifier_Identifier() {} + +func (*BlockIdentifier_BlockHash) isBlockIdentifier_Identifier() {} + +// Used in GetBlock to find a single block. +type GetBlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identifier *BlockIdentifier `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"` +} + +func (x *GetBlockRequest) Reset() { + *x = GetBlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetBlockRequest) ProtoMessage() {} + +func (x *GetBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetBlockRequest.ProtoReflect.Descriptor instead. +func (*GetBlockRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{2} +} + +func (x *GetBlockRequest) GetIdentifier() *BlockIdentifier { + if x != nil { + return x.Identifier + } + return nil +} + +// Used in BatchGetBlocks, will find all or none based on the list of +// identifiers. +type BatchGetBlocksRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Identifiers []*BlockIdentifier `protobuf:"bytes,1,rep,name=identifiers,proto3" json:"identifiers,omitempty"` +} + +func (x *BatchGetBlocksRequest) Reset() { + *x = BatchGetBlocksRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetBlocksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetBlocksRequest) ProtoMessage() {} + +func (x *BatchGetBlocksRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetBlocksRequest.ProtoReflect.Descriptor instead. +func (*BatchGetBlocksRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{3} +} + +func (x *BatchGetBlocksRequest) GetIdentifiers() []*BlockIdentifier { + if x != nil { + return x.Identifiers + } + return nil +} + +// The list of blocks in response to BatchGetBlocks. +type BatchGetBlocksResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Blocks []*Block `protobuf:"bytes,1,rep,name=blocks,proto3" json:"blocks,omitempty"` +} + +func (x *BatchGetBlocksResponse) Reset() { + *x = BatchGetBlocksResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BatchGetBlocksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BatchGetBlocksResponse) ProtoMessage() {} + +func (x *BatchGetBlocksResponse) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BatchGetBlocksResponse.ProtoReflect.Descriptor instead. +func (*BatchGetBlocksResponse) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{4} +} + +func (x *BatchGetBlocksResponse) GetBlocks() []*Block { + if x != nil { + return x.Blocks + } + return nil +} + +// ExecuteBlockRequest contains all the information needed to create a new rollup +// block. +// +// This information comes from previous rollup blocks, as well as from sequencer +// blocks. +type ExecuteBlockRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The hash of previous block, which new block will be created on top of. + PrevBlockHash []byte `protobuf:"bytes,1,opt,name=prev_block_hash,json=prevBlockHash,proto3" json:"prev_block_hash,omitempty"` + // List of transactions to include in the new block. + Transactions [][]byte `protobuf:"bytes,2,rep,name=transactions,proto3" json:"transactions,omitempty"` + // Timestamp to be used for new block. + Timestamp *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (x *ExecuteBlockRequest) Reset() { + *x = ExecuteBlockRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecuteBlockRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecuteBlockRequest) ProtoMessage() {} + +func (x *ExecuteBlockRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecuteBlockRequest.ProtoReflect.Descriptor instead. +func (*ExecuteBlockRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{5} +} + +func (x *ExecuteBlockRequest) GetPrevBlockHash() []byte { + if x != nil { + return x.PrevBlockHash + } + return nil +} + +func (x *ExecuteBlockRequest) GetTransactions() [][]byte { + if x != nil { + return x.Transactions + } + return nil +} + +func (x *ExecuteBlockRequest) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +// The CommitmentState holds the block at each stage of sequencer commitment +// level +// +// A Valid CommitmentState: +// - Block numbers are such that soft >= firm. +// - No blocks ever decrease in block number. +// - The chain defined by soft is the head of the canonical chain the firm block +// must belong to. +type CommitmentState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Soft commitment is the rollup block matching latest sequencer block. + Soft *Block `protobuf:"bytes,1,opt,name=soft,proto3" json:"soft,omitempty"` + // Firm commitment is achieved when data has been seen in DA. + Firm *Block `protobuf:"bytes,2,opt,name=firm,proto3" json:"firm,omitempty"` +} + +func (x *CommitmentState) Reset() { + *x = CommitmentState{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommitmentState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommitmentState) ProtoMessage() {} + +func (x *CommitmentState) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommitmentState.ProtoReflect.Descriptor instead. +func (*CommitmentState) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{6} +} + +func (x *CommitmentState) GetSoft() *Block { + if x != nil { + return x.Soft + } + return nil +} + +func (x *CommitmentState) GetFirm() *Block { + if x != nil { + return x.Firm + } + return nil +} + +// There is only one CommitmentState object, so the request is empty. +type GetCommitmentStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *GetCommitmentStateRequest) Reset() { + *x = GetCommitmentStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetCommitmentStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetCommitmentStateRequest) ProtoMessage() {} + +func (x *GetCommitmentStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetCommitmentStateRequest.ProtoReflect.Descriptor instead. +func (*GetCommitmentStateRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{7} +} + +// The CommitmentState to set, must include complete state. +type UpdateCommitmentStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CommitmentState *CommitmentState `protobuf:"bytes,1,opt,name=commitment_state,json=commitmentState,proto3" json:"commitment_state,omitempty"` +} + +func (x *UpdateCommitmentStateRequest) Reset() { + *x = UpdateCommitmentStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateCommitmentStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateCommitmentStateRequest) ProtoMessage() {} + +func (x *UpdateCommitmentStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_astria_execution_v1alpha2_execution_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateCommitmentStateRequest.ProtoReflect.Descriptor instead. +func (*UpdateCommitmentStateRequest) Descriptor() ([]byte, []int) { + return file_astria_execution_v1alpha2_execution_proto_rawDescGZIP(), []int{8} +} + +func (x *UpdateCommitmentStateRequest) GetCommitmentState() *CommitmentState { + if x != nil { + return x.CommitmentState + } + return nil +} + +var File_astria_execution_v1alpha2_execution_proto protoreflect.FileDescriptor + +var file_astria_execution_v1alpha2_execution_proto_rawDesc = []byte{ + 0x0a, 0x29, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2f, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x61, 0x73, 0x74, + 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x99, 0x01, 0x0a, 0x05, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x2a, 0x0a, + 0x11, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x65, 0x0a, 0x0f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0b, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x48, + 0x00, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x42, 0x0c, 0x0a, 0x0a, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x5d, 0x0a, 0x0f, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4a, 0x0a, + 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, 0x6c, + 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x0a, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x65, 0x0a, 0x15, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x52, 0x0b, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, + 0x22, 0x52, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, + 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x73, 0x74, + 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x06, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x22, 0x9b, 0x01, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, + 0x70, 0x72, 0x65, 0x76, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x76, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x22, 0x7d, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x04, 0x73, 0x6f, 0x66, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x04, 0x73, 0x6f, 0x66, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x66, + 0x69, 0x72, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x04, 0x66, 0x69, 0x72, + 0x6d, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x75, + 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x55, + 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, + 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x32, 0xbb, 0x04, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x58, 0x0a, 0x08, 0x47, 0x65, + 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x75, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x30, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, + 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x0c, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x2e, 0x2e, 0x61, 0x73, + 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x42, + 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x73, + 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x76, 0x0a, + 0x12, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x34, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x7c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x37, + 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x73, 0x74, 0x72, 0x69, 0x61, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x42, 0x87, 0x02, 0x0a, 0x1d, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x73, 0x74, 0x72, + 0x69, 0x61, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x32, 0x42, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x50, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d, + 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x61, 0x73, + 0x74, 0x72, 0x69, 0x61, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x3b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0xa2, 0x02, 0x03, 0x41, 0x45, 0x58, 0xaa, + 0x02, 0x19, 0x41, 0x73, 0x74, 0x72, 0x69, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0xca, 0x02, 0x19, 0x41, 0x73, + 0x74, 0x72, 0x69, 0x61, 0x5c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0xe2, 0x02, 0x25, 0x41, 0x73, 0x74, 0x72, 0x69, 0x61, + 0x5c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x32, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x1b, 0x41, 0x73, 0x74, 0x72, 0x69, 0x61, 0x3a, 0x3a, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x32, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_astria_execution_v1alpha2_execution_proto_rawDescOnce sync.Once + file_astria_execution_v1alpha2_execution_proto_rawDescData = file_astria_execution_v1alpha2_execution_proto_rawDesc +) + +func file_astria_execution_v1alpha2_execution_proto_rawDescGZIP() []byte { + file_astria_execution_v1alpha2_execution_proto_rawDescOnce.Do(func() { + file_astria_execution_v1alpha2_execution_proto_rawDescData = protoimpl.X.CompressGZIP(file_astria_execution_v1alpha2_execution_proto_rawDescData) + }) + return file_astria_execution_v1alpha2_execution_proto_rawDescData +} + +var file_astria_execution_v1alpha2_execution_proto_msgTypes = make([]protoimpl.MessageInfo, 9) +var file_astria_execution_v1alpha2_execution_proto_goTypes = []interface{}{ + (*Block)(nil), // 0: astria.execution.v1alpha2.Block + (*BlockIdentifier)(nil), // 1: astria.execution.v1alpha2.BlockIdentifier + (*GetBlockRequest)(nil), // 2: astria.execution.v1alpha2.GetBlockRequest + (*BatchGetBlocksRequest)(nil), // 3: astria.execution.v1alpha2.BatchGetBlocksRequest + (*BatchGetBlocksResponse)(nil), // 4: astria.execution.v1alpha2.BatchGetBlocksResponse + (*ExecuteBlockRequest)(nil), // 5: astria.execution.v1alpha2.ExecuteBlockRequest + (*CommitmentState)(nil), // 6: astria.execution.v1alpha2.CommitmentState + (*GetCommitmentStateRequest)(nil), // 7: astria.execution.v1alpha2.GetCommitmentStateRequest + (*UpdateCommitmentStateRequest)(nil), // 8: astria.execution.v1alpha2.UpdateCommitmentStateRequest + (*timestamppb.Timestamp)(nil), // 9: google.protobuf.Timestamp +} +var file_astria_execution_v1alpha2_execution_proto_depIdxs = []int32{ + 9, // 0: astria.execution.v1alpha2.Block.timestamp:type_name -> google.protobuf.Timestamp + 1, // 1: astria.execution.v1alpha2.GetBlockRequest.identifier:type_name -> astria.execution.v1alpha2.BlockIdentifier + 1, // 2: astria.execution.v1alpha2.BatchGetBlocksRequest.identifiers:type_name -> astria.execution.v1alpha2.BlockIdentifier + 0, // 3: astria.execution.v1alpha2.BatchGetBlocksResponse.blocks:type_name -> astria.execution.v1alpha2.Block + 9, // 4: astria.execution.v1alpha2.ExecuteBlockRequest.timestamp:type_name -> google.protobuf.Timestamp + 0, // 5: astria.execution.v1alpha2.CommitmentState.soft:type_name -> astria.execution.v1alpha2.Block + 0, // 6: astria.execution.v1alpha2.CommitmentState.firm:type_name -> astria.execution.v1alpha2.Block + 6, // 7: astria.execution.v1alpha2.UpdateCommitmentStateRequest.commitment_state:type_name -> astria.execution.v1alpha2.CommitmentState + 2, // 8: astria.execution.v1alpha2.ExecutionService.GetBlock:input_type -> astria.execution.v1alpha2.GetBlockRequest + 3, // 9: astria.execution.v1alpha2.ExecutionService.BatchGetBlocks:input_type -> astria.execution.v1alpha2.BatchGetBlocksRequest + 5, // 10: astria.execution.v1alpha2.ExecutionService.ExecuteBlock:input_type -> astria.execution.v1alpha2.ExecuteBlockRequest + 7, // 11: astria.execution.v1alpha2.ExecutionService.GetCommitmentState:input_type -> astria.execution.v1alpha2.GetCommitmentStateRequest + 8, // 12: astria.execution.v1alpha2.ExecutionService.UpdateCommitmentState:input_type -> astria.execution.v1alpha2.UpdateCommitmentStateRequest + 0, // 13: astria.execution.v1alpha2.ExecutionService.GetBlock:output_type -> astria.execution.v1alpha2.Block + 4, // 14: astria.execution.v1alpha2.ExecutionService.BatchGetBlocks:output_type -> astria.execution.v1alpha2.BatchGetBlocksResponse + 0, // 15: astria.execution.v1alpha2.ExecutionService.ExecuteBlock:output_type -> astria.execution.v1alpha2.Block + 6, // 16: astria.execution.v1alpha2.ExecutionService.GetCommitmentState:output_type -> astria.execution.v1alpha2.CommitmentState + 6, // 17: astria.execution.v1alpha2.ExecutionService.UpdateCommitmentState:output_type -> astria.execution.v1alpha2.CommitmentState + 13, // [13:18] is the sub-list for method output_type + 8, // [8:13] is the sub-list for method input_type + 8, // [8:8] is the sub-list for extension type_name + 8, // [8:8] is the sub-list for extension extendee + 0, // [0:8] is the sub-list for field type_name +} + +func init() { file_astria_execution_v1alpha2_execution_proto_init() } +func file_astria_execution_v1alpha2_execution_proto_init() { + if File_astria_execution_v1alpha2_execution_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_astria_execution_v1alpha2_execution_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Block); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BlockIdentifier); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetBlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetBlocksRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchGetBlocksResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecuteBlockRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommitmentState); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetCommitmentStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateCommitmentStateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_astria_execution_v1alpha2_execution_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*BlockIdentifier_BlockNumber)(nil), + (*BlockIdentifier_BlockHash)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_astria_execution_v1alpha2_execution_proto_rawDesc, + NumEnums: 0, + NumMessages: 9, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_astria_execution_v1alpha2_execution_proto_goTypes, + DependencyIndexes: file_astria_execution_v1alpha2_execution_proto_depIdxs, + MessageInfos: file_astria_execution_v1alpha2_execution_proto_msgTypes, + }.Build() + File_astria_execution_v1alpha2_execution_proto = out.File + file_astria_execution_v1alpha2_execution_proto_rawDesc = nil + file_astria_execution_v1alpha2_execution_proto_goTypes = nil + file_astria_execution_v1alpha2_execution_proto_depIdxs = nil +} diff --git a/grpc/gen/astria/execution/v1alpha2/execution_grpc.pb.go b/grpc/gen/astria/execution/v1alpha2/execution_grpc.pb.go new file mode 100644 index 000000000..905f0779b --- /dev/null +++ b/grpc/gen/astria/execution/v1alpha2/execution_grpc.pb.go @@ -0,0 +1,273 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: astria/execution/v1alpha2/execution.proto + +package executionv1alpha2 + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + ExecutionService_GetBlock_FullMethodName = "/astria.execution.v1alpha2.ExecutionService/GetBlock" + ExecutionService_BatchGetBlocks_FullMethodName = "/astria.execution.v1alpha2.ExecutionService/BatchGetBlocks" + ExecutionService_ExecuteBlock_FullMethodName = "/astria.execution.v1alpha2.ExecutionService/ExecuteBlock" + ExecutionService_GetCommitmentState_FullMethodName = "/astria.execution.v1alpha2.ExecutionService/GetCommitmentState" + ExecutionService_UpdateCommitmentState_FullMethodName = "/astria.execution.v1alpha2.ExecutionService/UpdateCommitmentState" +) + +// ExecutionServiceClient is the client API for ExecutionService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type ExecutionServiceClient interface { + // GetBlock will return a block given an identifier. + GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*Block, error) + // BatchGetBlocks will return an array of Blocks given an array of block + // identifiers. + BatchGetBlocks(ctx context.Context, in *BatchGetBlocksRequest, opts ...grpc.CallOption) (*BatchGetBlocksResponse, error) + // ExecuteBlock is called to deterministically derive a rollup block from + // filtered sequencer block information. + ExecuteBlock(ctx context.Context, in *ExecuteBlockRequest, opts ...grpc.CallOption) (*Block, error) + // GetCommitmentState fetches the current CommitmentState of the chain. + GetCommitmentState(ctx context.Context, in *GetCommitmentStateRequest, opts ...grpc.CallOption) (*CommitmentState, error) + // UpdateCommitmentState replaces the whole CommitmentState with a new + // CommitmentState. + UpdateCommitmentState(ctx context.Context, in *UpdateCommitmentStateRequest, opts ...grpc.CallOption) (*CommitmentState, error) +} + +type executionServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewExecutionServiceClient(cc grpc.ClientConnInterface) ExecutionServiceClient { + return &executionServiceClient{cc} +} + +func (c *executionServiceClient) GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*Block, error) { + out := new(Block) + err := c.cc.Invoke(ctx, ExecutionService_GetBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) BatchGetBlocks(ctx context.Context, in *BatchGetBlocksRequest, opts ...grpc.CallOption) (*BatchGetBlocksResponse, error) { + out := new(BatchGetBlocksResponse) + err := c.cc.Invoke(ctx, ExecutionService_BatchGetBlocks_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) ExecuteBlock(ctx context.Context, in *ExecuteBlockRequest, opts ...grpc.CallOption) (*Block, error) { + out := new(Block) + err := c.cc.Invoke(ctx, ExecutionService_ExecuteBlock_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) GetCommitmentState(ctx context.Context, in *GetCommitmentStateRequest, opts ...grpc.CallOption) (*CommitmentState, error) { + out := new(CommitmentState) + err := c.cc.Invoke(ctx, ExecutionService_GetCommitmentState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionServiceClient) UpdateCommitmentState(ctx context.Context, in *UpdateCommitmentStateRequest, opts ...grpc.CallOption) (*CommitmentState, error) { + out := new(CommitmentState) + err := c.cc.Invoke(ctx, ExecutionService_UpdateCommitmentState_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ExecutionServiceServer is the server API for ExecutionService service. +// All implementations must embed UnimplementedExecutionServiceServer +// for forward compatibility +type ExecutionServiceServer interface { + // GetBlock will return a block given an identifier. + GetBlock(context.Context, *GetBlockRequest) (*Block, error) + // BatchGetBlocks will return an array of Blocks given an array of block + // identifiers. + BatchGetBlocks(context.Context, *BatchGetBlocksRequest) (*BatchGetBlocksResponse, error) + // ExecuteBlock is called to deterministically derive a rollup block from + // filtered sequencer block information. + ExecuteBlock(context.Context, *ExecuteBlockRequest) (*Block, error) + // GetCommitmentState fetches the current CommitmentState of the chain. + GetCommitmentState(context.Context, *GetCommitmentStateRequest) (*CommitmentState, error) + // UpdateCommitmentState replaces the whole CommitmentState with a new + // CommitmentState. + UpdateCommitmentState(context.Context, *UpdateCommitmentStateRequest) (*CommitmentState, error) + mustEmbedUnimplementedExecutionServiceServer() +} + +// UnimplementedExecutionServiceServer must be embedded to have forward compatible implementations. +type UnimplementedExecutionServiceServer struct { +} + +func (UnimplementedExecutionServiceServer) GetBlock(context.Context, *GetBlockRequest) (*Block, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetBlock not implemented") +} +func (UnimplementedExecutionServiceServer) BatchGetBlocks(context.Context, *BatchGetBlocksRequest) (*BatchGetBlocksResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method BatchGetBlocks not implemented") +} +func (UnimplementedExecutionServiceServer) ExecuteBlock(context.Context, *ExecuteBlockRequest) (*Block, error) { + return nil, status.Errorf(codes.Unimplemented, "method ExecuteBlock not implemented") +} +func (UnimplementedExecutionServiceServer) GetCommitmentState(context.Context, *GetCommitmentStateRequest) (*CommitmentState, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetCommitmentState not implemented") +} +func (UnimplementedExecutionServiceServer) UpdateCommitmentState(context.Context, *UpdateCommitmentStateRequest) (*CommitmentState, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateCommitmentState not implemented") +} +func (UnimplementedExecutionServiceServer) mustEmbedUnimplementedExecutionServiceServer() {} + +// UnsafeExecutionServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ExecutionServiceServer will +// result in compilation errors. +type UnsafeExecutionServiceServer interface { + mustEmbedUnimplementedExecutionServiceServer() +} + +func RegisterExecutionServiceServer(s grpc.ServiceRegistrar, srv ExecutionServiceServer) { + s.RegisterService(&ExecutionService_ServiceDesc, srv) +} + +func _ExecutionService_GetBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).GetBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_GetBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).GetBlock(ctx, req.(*GetBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_BatchGetBlocks_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BatchGetBlocksRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).BatchGetBlocks(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_BatchGetBlocks_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).BatchGetBlocks(ctx, req.(*BatchGetBlocksRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_ExecuteBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExecuteBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).ExecuteBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_ExecuteBlock_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).ExecuteBlock(ctx, req.(*ExecuteBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_GetCommitmentState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetCommitmentStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).GetCommitmentState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_GetCommitmentState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).GetCommitmentState(ctx, req.(*GetCommitmentStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionService_UpdateCommitmentState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateCommitmentStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionServiceServer).UpdateCommitmentState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ExecutionService_UpdateCommitmentState_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionServiceServer).UpdateCommitmentState(ctx, req.(*UpdateCommitmentStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// ExecutionService_ServiceDesc is the grpc.ServiceDesc for ExecutionService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ExecutionService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "astria.execution.v1alpha2.ExecutionService", + HandlerType: (*ExecutionServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetBlock", + Handler: _ExecutionService_GetBlock_Handler, + }, + { + MethodName: "BatchGetBlocks", + Handler: _ExecutionService_BatchGetBlocks_Handler, + }, + { + MethodName: "ExecuteBlock", + Handler: _ExecutionService_ExecuteBlock_Handler, + }, + { + MethodName: "GetCommitmentState", + Handler: _ExecutionService_GetCommitmentState_Handler, + }, + { + MethodName: "UpdateCommitmentState", + Handler: _ExecutionService_UpdateCommitmentState_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "astria/execution/v1alpha2/execution.proto", +} diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 4f0f5fe86..7151aa82a 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -70,6 +70,11 @@ var ( Usage: "Log format to use (json|logfmt|terminal)", Category: flags.LoggingCategory, } + logfmtFlag = &cli.BoolFlag{ + Name: "log.logfmt", + Usage: "Format logs with logfmt", + Category: flags.LoggingCategory, + } logFileFlag = &cli.StringFlag{ Name: "log.file", Usage: "Write logs to a file", diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 38a792412..1ffdab395 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1868,9 +1868,12 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c // Ensure only eip155 signed transactions are submitted if EIP155Required is set. return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC") } + + // save transaction in geth mempool as well, so things like forge can look it up if err := b.SendTx(ctx, tx); err != nil { return common.Hash{}, err } + // Print a log with full tx details for manual investigations and interventions head := b.CurrentBlock() signer := types.MakeSigner(b.ChainConfig(), head.Number, head.Time) diff --git a/miner/payload_building.go b/miner/payload_building.go index 69ffab75b..c00577933 100644 --- a/miner/payload_building.go +++ b/miner/payload_building.go @@ -187,57 +187,19 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) { random: args.Random, withdrawals: args.Withdrawals, beaconRoot: args.BeaconRoot, - noTxs: true, + noTxs: false, } - empty := w.getSealingBlock(emptyParams) - if empty.err != nil { - return nil, empty.err + start := time.Now() + full := w.getSealingBlock(emptyParams) + if full.err != nil { + return nil, full.err } // Construct a payload object for return. - payload := newPayload(empty.block, args.Id()) - - // Spin up a routine for updating the payload in background. This strategy - // can maximum the revenue for including transactions with highest fee. - go func() { - // Setup the timer for re-building the payload. The initial clock is kept - // for triggering process immediately. - timer := time.NewTimer(0) - defer timer.Stop() - - // Setup the timer for terminating the process if SECONDS_PER_SLOT (12s in - // the Mainnet configuration) have passed since the point in time identified - // by the timestamp parameter. - endTimer := time.NewTimer(time.Second * 12) - - fullParams := &generateParams{ - timestamp: args.Timestamp, - forceTime: true, - parentHash: args.Parent, - coinbase: args.FeeRecipient, - random: args.Random, - withdrawals: args.Withdrawals, - beaconRoot: args.BeaconRoot, - noTxs: false, - } + payload := newPayload(full.block, args.Id()) - for { - select { - case <-timer.C: - start := time.Now() - r := w.getSealingBlock(fullParams) - if r.err == nil { - payload.update(r, time.Since(start)) - } - timer.Reset(w.recommit) - case <-payload.stop: - log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") - return - case <-endTimer.C: - log.Info("Stopping work on payload", "id", payload.id, "reason", "timeout") - return - } - } - }() + // Add the updated block to the payload + payload.update(full, time.Since(start)) + log.Info("Stopping work on payload", "id", payload.id, "reason", "delivery") return payload, nil } diff --git a/miner/worker.go b/miner/worker.go index f68070281..9c206f7c6 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -792,7 +792,89 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction) (*typ return receipt, err } -func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error { +// This is a copy of commitTransactions, but updated to take a list of txs instead of using heap +func (w *worker) commitAstriaTransactions(env *environment, txs *types.Transactions, interrupt *atomic.int32) error { + gasLimit := env.header.GasLimit + if env.gasPool == nil { + env.gasPool = new(core.GasPool).AddGas(gasLimit) + } + var coalescedLogs []*types.Log + + for _, tx := range *txs { + // Check interruption signal and abort building if it's fired. + if interrupt != nil { + if signal := atomic.LoadInt32(interrupt); signal != commitInterruptNone { + return signalToErr(signal) + } + } + // If we don't have enough gas for any further transactions then we're done. + if env.gasPool.Gas() < params.TxGas { + log.Trace("Not enough gas for further transactions", "have", env.gasPool, "want", params.TxGas) + break + } + + // Error may be ignored here. The error has already been checked + // during transaction acceptance is the transaction pool. + from, _ := types.Sender(env.signer, tx) + + // Check whether the tx is replay protected. If we're not in the EIP155 hf + // phase, start ignoring the sender until we do. + if tx.Protected() && !w.chainConfig.IsEIP155(env.header.Number) { + log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", w.chainConfig.EIP155Block) + + continue + } + // Start executing the transaction + env.state.SetTxContext(tx.Hash(), env.tcount) + + logs, err := w.commitTransaction(env, tx) + switch { + case errors.Is(err, core.ErrGasLimitReached): + // Pop the current out-of-gas transaction without shifting in the next from the account + log.Trace("Gas limit exceeded for current block", "sender", from) + + case errors.Is(err, core.ErrNonceTooLow): + // New head notification data race between the transaction pool and miner, shift + log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce()) + + case errors.Is(err, core.ErrNonceTooHigh): + // Reorg notification data race between the transaction pool and miner, skip account = + log.Trace("Skipping account with hight nonce", "sender", from, "nonce", tx.Nonce()) + + case errors.Is(err, nil): + // Everything ok, collect the logs and shift in the next transaction from the same account + coalescedLogs = append(coalescedLogs, logs...) + env.tcount++ + + case errors.Is(err, types.ErrTxTypeNotSupported): + // Pop the unsupported transaction without shifting in the next from the account + log.Trace("Skipping unsupported transaction type", "sender", from, "type", tx.Type()) + + default: + // Strange error, discard the transaction and get the next in line (note, the + // nonce-too-high clause will prevent us from executing in vain). + log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err) + } + } + if !w.isRunning() && len(coalescedLogs) > 0 { + // We don't push the pendingLogsEvent while we are sealing. The reason is that + // when we are sealing, the worker will regenerate a sealing block every 3 seconds. + // In order to avoid pushing the repeated pendingLog, we disable the pending log pushing. + + // make a copy, the state caches the logs and these logs get "upgraded" from pending to mined + // logs by filling in the block hash when the block was mined by the local miner. This can + // cause a race condition if a log was "upgraded" before the PendingLogsEvent is processed. + cpy := make([]*types.Log, len(coalescedLogs)) + for i, l := range coalescedLogs { + cpy[i] = new(types.Log) + *cpy[i] = *l + } + w.pendingLogsFeed.Send(cpy) + } + return nil +} + +func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByPriceAndNonce, interrupt *atomic.int32) error { gasLimit := env.header.GasLimit if env.gasPool == nil { env.gasPool = new(core.GasPool).AddGas(gasLimit) @@ -981,6 +1063,18 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { return env, nil } +func (w *worker) fillAstriaTransactions(interrupt *atomic.int32, env *environment) error { + // Use pre ordered array of txs + astriaTxs := w.eth.TxPool().AstriaOrdered() + if len(*astriaTxs) > 0 { + if err := w.commitAstriaTransactions(env, astriaTxs, interrupt); err != nil { + return err + } + } + w.eth.TxPool().ClearAstriaOrdered() + return nil +} + // fillTransactions retrieves the pending transactions from the txpool and fills them // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. @@ -1027,7 +1121,7 @@ func (w *worker) generateWork(params *generateParams) *newPayloadResult { }) defer timer.Stop() - err := w.fillTransactions(interrupt, work) + err := w.fillAstriaTransactions(interrupt, work) if errors.Is(err, errBlockInterruptedByTimeout) { log.Warn("Block building is interrupted", "allowance", common.PrettyDuration(w.newpayloadTimeout)) } @@ -1069,7 +1163,7 @@ func (w *worker) commitWork(interrupt *atomic.Int32, timestamp int64) { return } // Fill pending transactions from the txpool into the block. - err = w.fillTransactions(interrupt, work) + err = w.fillAstriaTransactions(interrupt, work) switch { case err == nil: // The entire block is filled, decrease resubmit interval in case diff --git a/node/config.go b/node/config.go index 949db887e..d1e29baa0 100644 --- a/node/config.go +++ b/node/config.go @@ -190,6 +190,12 @@ type Config struct { // Requests using ip address directly are not affected GraphQLVirtualHosts []string `toml:",omitempty"` + // GRPCHost is the host interface on which to start the gRPC server. If this + // field is empty, no gRPC API endpoint will be started. + GRPCHost string `toml:",omitempty"` + // GRPCPort is the TCP port number on which to start the gRPC server. + GRPCPort int `toml:",omitempty"` + // Logger is a custom logger to use with the p2p.Server. Logger log.Logger `toml:",omitempty"` @@ -267,12 +273,29 @@ func (c *Config) HTTPEndpoint() string { return net.JoinHostPort(c.HTTPHost, fmt.Sprintf("%d", c.HTTPPort)) } +// GRPCEndpoint resolves a gRPC endpoint based on the configured host interface +// and port parameters. +func (c *Config) GRPCEndpoint() string { + if c.GRPCHost == "" { + return "" + } + return fmt.Sprintf("%s:%d", c.GRPCHost, c.GRPCPort) +} + // DefaultHTTPEndpoint returns the HTTP endpoint used by default. func DefaultHTTPEndpoint() string { config := &Config{HTTPHost: DefaultHTTPHost, HTTPPort: DefaultHTTPPort, AuthPort: DefaultAuthPort} return config.HTTPEndpoint() } +// DefaultGRPCEndpoint returns the gRPC endpoint used by default. +// NOTE - implemented this to be consistent with DefaultHTTPEndpoint, but +// neither are ever used +func DefaultGRPCEndpoint() string { + config := &Config{GRPCHost: DefaultGRPCHost, GRPCPort: DefaultGRPCPort} + return config.GRPCEndpoint() +} + // WSEndpoint resolves a websocket endpoint based on the configured host interface // and port parameters. func (c *Config) WSEndpoint() string { diff --git a/node/defaults.go b/node/defaults.go index 42d9d4cde..2780723e7 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -34,6 +34,9 @@ const ( DefaultWSPort = 8546 // Default TCP port for the websocket RPC server DefaultAuthHost = "localhost" // Default host interface for the authenticated apis DefaultAuthPort = 8551 // Default port for the authenticated apis + // grpc + DefaultGRPCHost = "[::1]" // Default host interface for the gRPC server + DefaultGRPCPort = 50051 // Default port for the gRPC server ) const ( @@ -72,6 +75,9 @@ var DefaultConfig = Config{ NAT: nat.Any(), }, DBEngine: "", // Use whatever exists, will default to Pebble if non-existent and supported + // grpc + GRPCHost: DefaultGRPCHost, + GRPCPort: DefaultGRPCPort, } // DefaultDataDir is the default data directory to use for the databases and other diff --git a/node/grpcstack.go b/node/grpcstack.go new file mode 100644 index 000000000..a85ccf7a6 --- /dev/null +++ b/node/grpcstack.go @@ -0,0 +1,73 @@ +package node + +import ( + "net" + "sync" + + executionv1a1 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha1" + executionv1a2 "github.com/ethereum/go-ethereum/grpc/gen/astria/execution/v1alpha2" + "github.com/ethereum/go-ethereum/log" + "google.golang.org/grpc" +) + +// GRPCServerHandler is the gRPC server handler. +// It gives us a way to attach the gRPC server to the node so it can be stopped on shutdown. +type GRPCServerHandler struct { + mu sync.Mutex + + endpoint string + server *grpc.Server + executionServiceServerV1a1 *executionv1a1.ExecutionServiceServer + executionServiceServerV1a2 *executionv1a2.ExecutionServiceServer +} + +// NewServer creates a new gRPC server. +// It registers the execution service server. +// It registers the gRPC server with the node so it can be stopped on shutdown. +func NewGRPCServerHandler(node *Node, execServiceV1a1 executionv1a1.ExecutionServiceServer, execServiceV1a2 executionv1a2.ExecutionServiceServer, cfg *Config) error { + server := grpc.NewServer() + + log.Info("gRPC server enabled", "endpoint", cfg.GRPCEndpoint()) + + serverHandler := &GRPCServerHandler{ + endpoint: cfg.GRPCEndpoint(), + server: server, + executionServiceServerV1a1: &execServiceV1a1, + executionServiceServerV1a2: &execServiceV1a2, + } + + executionv1a1.RegisterExecutionServiceServer(server, execServiceV1a1) + executionv1a2.RegisterExecutionServiceServer(server, execServiceV1a2) + + node.RegisterGRPCServer(serverHandler) + return nil +} + +// Start starts the gRPC server if it is enabled. +func (handler *GRPCServerHandler) Start() error { + handler.mu.Lock() + defer handler.mu.Unlock() + + if handler.endpoint == "" { + return nil + } + + // Start the gRPC server + lis, err := net.Listen("tcp", handler.endpoint) + if err != nil { + return err + } + go handler.server.Serve(lis) + log.Info("gRPC server started", "endpoint", handler.endpoint) + return nil +} + +// Stop stops the gRPC server. +func (handler *GRPCServerHandler) Stop() error { + handler.mu.Lock() + defer handler.mu.Unlock() + + handler.server.Stop() + log.Info("gRPC server stopped", "endpoint", handler.endpoint) + return nil +} diff --git a/node/node.go b/node/node.go index 41c9971fe..edd706f34 100644 --- a/node/node.go +++ b/node/node.go @@ -64,6 +64,9 @@ type Node struct { ipc *ipcServer // Stores information about the ipc http server inprocHandler *rpc.Server // In-process RPC request handler to process the API requests + // grpc + grpcServerHandler *GRPCServerHandler // Stores information about the grpc server + databases map[*closeTrackingDB]struct{} // All open databases } @@ -272,9 +275,16 @@ func (n *Node) openEndpoints() error { // start RPC endpoints err := n.startRPC() if err != nil { + n.log.Error("failed to start RPC endpoints", "err", err) n.stopRPC() n.server.Stop() } + // start GRPC endpoints + err = n.startGRPC() + if err != nil { + n.log.Error("failed to start gRPC endpoints", "err", err) + n.stopGRPC() + } return err } @@ -304,6 +314,9 @@ func (n *Node) stopServices(running []Lifecycle) error { // Stop p2p networking. n.server.Stop() + // Stop GRPC server + n.stopGRPC() + if len(failure.Services) > 0 { return failure } @@ -535,6 +548,23 @@ func (n *Node) stopRPC() { n.stopInProc() } +func (n *Node) startGRPC() error { + if n.grpcServerHandler != nil { + // start the server + if err := n.grpcServerHandler.Start(); err != nil { + return err + } + } + + return nil +} + +func (n *Node) stopGRPC() { + if n.grpcServerHandler != nil { + n.grpcServerHandler.Stop() + } +} + // startInProc registers all RPC APIs on the inproc server. func (n *Node) startInProc(apis []rpc.API) error { for _, api := range apis { @@ -602,6 +632,19 @@ func (n *Node) getAPIs() (unauthenticated, all []rpc.API) { return unauthenticated, n.rpcAPIs } +// RegisterGRPCServer registers a gRPC server on the node. +// This allows us to control grpc server startup and shutdown from the node. +func (n *Node) RegisterGRPCServer(handler *GRPCServerHandler) { + n.lock.Lock() + defer n.lock.Unlock() + + if n.state != initializingState { + panic("can't register gRPC server on running/stopped node") + } + + n.grpcServerHandler = handler +} + // RegisterHandler mounts a handler on the given path on the canonical HTTP server. // // The name of the handler is shown in a log message when the HTTP server starts @@ -681,6 +724,11 @@ func (n *Node) HTTPEndpoint() string { return "http://" + n.http.listenAddr() } +// GRPCENDPOINT returns the URL of the GRPC server. +func (n *Node) GRPCEndpoint() string { + return "http://" + n.grpcServerHandler.endpoint +} + // WSEndpoint returns the current JSON-RPC over WebSocket endpoint. func (n *Node) WSEndpoint() string { if n.http.wsAllowed() { diff --git a/private_network.md b/private_network.md new file mode 100644 index 000000000..7da7a2768 --- /dev/null +++ b/private_network.md @@ -0,0 +1,25 @@ +# private network + +### astria +1. Make a new account in Metamask (or whichever method you prefer). Copy paste the address into `genesis.json`'s `alloc` field. This account will be allocated 300 ETH at startup. + +2. To build and initialize Geth: +```bash +make geth +./build/bin/geth --datadir ~/.astriageth/ init genesis.json +``` + +To run without mining (ie. using the conductor): +```bash +./build/bin/geth --datadir ~/.astriageth/ --http --http.port=8545 --ws --ws.port=8545 --networkid=1337 --http.corsdomain='*' --ws.origins='*' --grpc --grpc.addr=localhost --grpc.port 50051 +``` + +4. Open up Metamask and go to the Localhost 8545 network. You should see your account has 300 ETH. You can now transfer this to other accounts. + +### ethash +To run with mining (which you don't want if running Astria): +1. Remove the `"terminalTotalDifficulty": 0,` line in `genesis.json`. Then run steps 1-2 as above. +2. Replace the etherbase in the following with your account (it doesn't really matter though, since mining doesn't require signing). Then, +```bash +./build/bin/geth --datadir ~/.astriageth/ --http --http.port=8545 --ws --ws.port=8545 --networkid=1337 --http.corsdomain='*' --ws.origins='*' --mine --miner.threads 1 --miner.etherbase=0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102 --grpc --grpc.addr=localhost --grpc.port 50051 +```