From f1977f60599670944d5093b51958eeea5dc31617 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Mon, 27 Mar 2023 12:13:36 -0700 Subject: [PATCH 01/21] Adding features to mempool to support our pre-ordered txs --- core/txpool/txpool.go | 97 ++++++++++++++++++++++++++++++++ miner/worker.go | 127 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 207 insertions(+), 17 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index ac4486c6cba..a1f194341ee 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -26,6 +26,7 @@ import ( "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" @@ -259,6 +260,7 @@ type TxPool struct { pendingNonces *noncer // Pending state tracking virtual nonces currentMaxGas uint64 // Current gas limit for transaction caps + astria *astriaOrdered locals *accountSet // Set of local transaction to exempt from eviction rules journal *journal // Journal of local transaction to back up to disk @@ -926,6 +928,97 @@ func (pool *TxPool) AddLocal(tx *types.Transaction) error { return errs[0] } +func (pool *TxPool) SetAstriaOrdered(rawTxs []hexutil.Bytes) { + txs := &types.Transactions{} + for idx, rawTx := range rawTxs { + tx := new(types.Transaction) + err := tx.UnmarshalBinary(rawTx); + if err != nil { + log.Info("Failed to unmarshall raw astria tx bytes", rawTx, "at index", idx) + continue + } + + err = pool.astriaValidate(tx) + if err != nil { + log.Info("Astria tx failed validation at index", idx, "failed validation:" err) + continue + } + + txs = append(txs, tx) + } + + pool.astria.txs = txs +} + +func (pool *TxPool) AstriaOrdered() *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 +} + // AddRemotes enqueues a batch of transactions into the pool if they are valid. If the // senders are not among the locally tracked ones, full pricing constraints will apply. // @@ -1647,6 +1740,10 @@ func (a addressesByHeartbeat) Len() int { return len(a) } func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +type astriaOrdered struct { + txs types.Transactions +} + // accountSet is simply a set of addresses to check for existence, and a signer // capable of deriving addresses from transactions. type accountSet struct { diff --git a/miner/worker.go b/miner/worker.go index 67a5842d23e..00ec9046bb0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -877,6 +877,88 @@ func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]* return receipt.Logs, nil } +// 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 *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 *int32) error { gasLimit := env.header.GasLimit if env.gasPool == nil { @@ -1068,26 +1150,37 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { // into the given sealing block. The transaction selection and ordering strategy can // be customized with the plugin in the future. func (w *worker) fillTransactions(interrupt *int32, env *environment) error { - // Split the pending transactions into locals and remotes - // Fill the block with all available pending transactions. - pending := w.eth.TxPool().Pending(true) - localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending - for _, account := range w.eth.TxPool().Locals() { - if txs := remoteTxs[account]; len(txs) > 0 { - delete(remoteTxs, account) - localTxs[account] = txs - } - } - if len(localTxs) > 0 { - txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - if err := w.commitTransactions(env, txs, interrupt); err != nil { + // 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 } } - if len(remoteTxs) > 0 { - txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - if err := w.commitTransactions(env, txs, interrupt); err != nil { - return err + + // Original Geth Code + if false { + // Split the pending transactions into locals and remotes + // Fill the block with all available pending transactions. + pending := w.eth.TxPool().Pending(true) + localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending + for _, account := range w.eth.TxPool().Locals() { + if txs := remoteTxs[account]; len(txs) > 0 { + delete(remoteTxs, account) + localTxs[account] = txs + } + } + if len(localTxs) > 0 { + txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) + if err := w.commitTransactions(env, txs, interrupt); err != nil { + return err + } + } + if len(remoteTxs) > 0 { + txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) + if err := w.commitTransactions(env, txs, interrupt); err != nil { + return err + } } } return nil From abf7de2ef2ea44c57530855c5ae6c18bfe412da8 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Mon, 27 Mar 2023 15:29:15 -0700 Subject: [PATCH 02/21] Add framing for gRPC to execute blocks --- cmd/geth/config.go | 2 +- cmd/utils/flags.go | 4 +-- core/txpool/txpool.go | 7 ++--- grpc/execution/server.go | 66 ++++++++++++++++++++++++---------------- node/grpcstack.go | 7 ++--- 5 files changed, 48 insertions(+), 38 deletions(-) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 75becbf5902..651c5239859 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -174,7 +174,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { // Configure gRPC if requested. if ctx.IsSet(utils.GRPCEnabledFlag.Name) { - utils.RegisterGRPCService(stack, backend, &cfg.Node) + utils.RegisterGRPCService(stack, eth, &cfg.Node) } // Add the Ethereum Stats daemon if requested. diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2b16231d1ea..bd7ba973ce8 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2066,8 +2066,8 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst // RegisterGRPCService adds the gRPC API to the node. // It was done this way so that our grpc execution server can access the ethapi.Backend -func RegisterGRPCService(stack *node.Node, backend ethapi.Backend, cfg *node.Config) { - if err := node.NewGRPCServerHandler(stack, backend, cfg); err != nil { +func RegisterGRPCService(stack *node.Node, eth *eth.Ethereum, cfg *node.Config) { + if err := node.NewGRPCServerHandler(stack, eth, cfg); err != nil { Fatalf("Failed to register the gRPC service: %v", err) } } diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index a1f194341ee..88e72a10e1a 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -26,7 +26,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" @@ -928,8 +927,8 @@ func (pool *TxPool) AddLocal(tx *types.Transaction) error { return errs[0] } -func (pool *TxPool) SetAstriaOrdered(rawTxs []hexutil.Bytes) { - txs := &types.Transactions{} +func (pool *TxPool) SetAstriaOrdered(rawTxs [][]byte) { + txs := *&types.Transactions{} for idx, rawTx := range rawTxs { tx := new(types.Transaction) err := tx.UnmarshalBinary(rawTx); @@ -940,7 +939,7 @@ func (pool *TxPool) SetAstriaOrdered(rawTxs []hexutil.Bytes) { err = pool.astriaValidate(tx) if err != nil { - log.Info("Astria tx failed validation at index", idx, "failed validation:" err) + log.Info("Astria tx failed validation at index", idx, "failed validation:", err) continue } diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 5c32c51280e..00f71ccb0b8 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -7,7 +7,9 @@ package execution import ( "context" - "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/catalyst" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" @@ -20,13 +22,17 @@ type ExecutionServiceServer struct { // for forward compatibility executionv1.UnimplementedExecutionServiceServer - // TODO - will need access to the consensus api to call functions for building a block - // e.g. getPayload, newPayload, forkchoiceUpdated + consensus *catalyst.ConsensusAPI + eth *eth.Ethereum +} - Backend ethapi.Backend +func NewExecutionServiceServer(backend ethapi.Backend, eth *eth.Ethereum) *ExecutionServiceServer { + consensus := catalyst.NewConsensusAPI(eth) - // TODO - will need access to forkchoice on first run. - // this will probably be passed in when calling NewServer + return &ExecutionServiceServer{ + eth: eth, + consensus: consensus, + } } // FIXME - how do we know which hash to start with? will probably need another api function like @@ -35,30 +41,36 @@ type ExecutionServiceServer struct { func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.DoBlockRequest) (*executionv1.DoBlockResponse, error) { log.Info("DoBlock called request", "request", req) - // NOTE - Request.Header.ParentHash needs to match forkchoice head hash - // ParentHash should be the forkchoice head of the last block - - // TODO - need to call consensus api to build a block + // The Engine API has been modified to use transactions from this mempool and abide by it's ordering. + s.eth.TxPool().SetAstriaOrdered(req.Transactions) - // txs := bytesToTransactions(req.Transactions) - // for _, tx := range txs { - // s.Backend.SendTx(ctx, tx) - // } + // Do the whole Engine API in a single loop + startForkChoice := &engine.ForkchoiceStateV1{} + payloadAttributes := &engine.PayloadAttributes{} + fcStartResp, err := s.consensus.ForkchoiceUpdatedV1(*startForkChoice, payloadAttributes) + if err != nil { + return nil, err + } + payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID) + if err != nil { + return nil, err + } + payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) + if err != nil { + return nil, err + } + newForkChoice := &engine.ForkchoiceStateV1{ + HeadBlockHash: *payloadStatus.LatestValidHash, + SafeBlockHash: *payloadStatus.LatestValidHash, + FinalizedBlockHash: *payloadStatus.LatestValidHash, + } + fcEndResp, err := s.consensus.ForkchoiceUpdatedV1(*newForkChoice, nil) + if err != nil { + return nil, err + } res := &executionv1.DoBlockResponse{ - // TODO - get state root from last block - StateRoot: []byte{0x00}, + StateRoot: fcEndResp.PayloadStatus.LatestValidHash.Bytes(), } return res, nil } - -// convert bytes to transactions -func bytesToTransactions(b [][]byte) []*types.Transaction { - txs := []*types.Transaction{} - for _, txBytes := range b { - tx := &types.Transaction{} - tx.UnmarshalBinary(txBytes) - txs = append(txs, tx) - } - return txs -} diff --git a/node/grpcstack.go b/node/grpcstack.go index 1c0c3f4768a..c28304cfd5e 100644 --- a/node/grpcstack.go +++ b/node/grpcstack.go @@ -4,6 +4,7 @@ import ( "net" "sync" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/grpc/execution" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" "github.com/ethereum/go-ethereum/internal/ethapi" @@ -24,12 +25,10 @@ type GRPCServerHandler struct { // 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, backend ethapi.Backend, cfg *Config) error { +func NewGRPCServerHandler(node *Node, eth *eth.Ethereum, cfg *Config) error { server := grpc.NewServer() - executionServiceServer := &execution.ExecutionServiceServer{ - Backend: backend, - } + executionServiceServer := execution.NewExecutionServiceServer(eth) log.Info("gRPC server enabled", "endpoint", cfg.GRPCEndpoint()) From 8ce5584133d6dcf7283204659dc4d2c5aabb34de Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Mon, 27 Mar 2023 15:36:04 -0700 Subject: [PATCH 03/21] Remove public engine API call --- cmd/utils/flags.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index bd7ba973ce8..c1e639c6fa7 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2042,9 +2042,10 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend Fatalf("Failed to create the LES server: %v", err) } } - if err := ethcatalyst.Register(stack, backend); err != nil { - Fatalf("Failed to register the Engine API service: %v", err) - } + // We don't want to publicly expose the engine API, instead use grpc endpoints + // if err := ethcatalyst.Register(stack, backend); err != nil { + // Fatalf("Failed to register the Engine API service: %v", err) + // } stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) return backend.APIBackend, backend } From 2060a4e1501befc1d98ffba706bbd29ea7cb353a Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Mon, 27 Mar 2023 16:31:27 -0700 Subject: [PATCH 04/21] Fix circular dependencies --- cmd/geth/config.go | 4 +++- cmd/utils/flags.go | 5 +++-- grpc/execution/server.go | 3 +-- node/grpcstack.go | 13 ++++--------- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 651c5239859..a45ab6602ef 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/cmd/utils" "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" @@ -174,7 +175,8 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { // Configure gRPC if requested. if ctx.IsSet(utils.GRPCEnabledFlag.Name) { - utils.RegisterGRPCService(stack, eth, &cfg.Node) + service := execution.NewExecutionServiceServer(eth) + utils.RegisterGRPCService(stack, service, &cfg.Node) } // Add the Ethereum Stats daemon if requested. diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index c1e639c6fa7..ca6545b87f2 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -57,6 +57,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb/remotedb" "github.com/ethereum/go-ethereum/ethstats" "github.com/ethereum/go-ethereum/graphql" + executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/flags" "github.com/ethereum/go-ethereum/les" @@ -2067,8 +2068,8 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst // RegisterGRPCService adds the gRPC API to the node. // It was done this way so that our grpc execution server can access the ethapi.Backend -func RegisterGRPCService(stack *node.Node, eth *eth.Ethereum, cfg *node.Config) { - if err := node.NewGRPCServerHandler(stack, eth, cfg); err != nil { +func RegisterGRPCService(stack *node.Node, execServer executionv1.ExecutionServiceServer, cfg *node.Config) { + if err := node.NewGRPCServerHandler(stack, execServer, cfg); err != nil { Fatalf("Failed to register the gRPC service: %v", err) } } diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 00f71ccb0b8..e5f0bc57712 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -11,7 +11,6 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/catalyst" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" ) @@ -26,7 +25,7 @@ type ExecutionServiceServer struct { eth *eth.Ethereum } -func NewExecutionServiceServer(backend ethapi.Backend, eth *eth.Ethereum) *ExecutionServiceServer { +func NewExecutionServiceServer(eth *eth.Ethereum) *ExecutionServiceServer { consensus := catalyst.NewConsensusAPI(eth) return &ExecutionServiceServer{ diff --git a/node/grpcstack.go b/node/grpcstack.go index c28304cfd5e..4ebb22e013a 100644 --- a/node/grpcstack.go +++ b/node/grpcstack.go @@ -4,10 +4,7 @@ import ( "net" "sync" - "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/grpc/execution" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "google.golang.org/grpc" ) @@ -19,26 +16,24 @@ type GRPCServerHandler struct { endpoint string server *grpc.Server - executionServiceServer *execution.ExecutionServiceServer + executionServiceServer *executionv1.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, eth *eth.Ethereum, cfg *Config) error { +func NewGRPCServerHandler(node *Node, execService executionv1.ExecutionServiceServer, cfg *Config) error { server := grpc.NewServer() - executionServiceServer := execution.NewExecutionServiceServer(eth) - log.Info("gRPC server enabled", "endpoint", cfg.GRPCEndpoint()) serverHandler := &GRPCServerHandler{ endpoint: cfg.GRPCEndpoint(), server: server, - executionServiceServer: executionServiceServer, + executionServiceServer: &execService, } - executionv1.RegisterExecutionServiceServer(server, executionServiceServer) + executionv1.RegisterExecutionServiceServer(server, execService) node.RegisterGRPCServer(serverHandler) return nil From dda2605d9df8ec66050f6a0a14b6592858902399 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Wed, 29 Mar 2023 13:33:43 -0700 Subject: [PATCH 05/21] Updated to use new Init, and fill out starting attributes --- grpc/README.md | 9 +- grpc/execution/server.go | 26 +- grpc/gen/proto/execution/v1/execution.pb.go | 224 ++++++++++++++---- .../proto/execution/v1/execution_grpc.pb.go | 39 ++- 4 files changed, 249 insertions(+), 49 deletions(-) diff --git a/grpc/README.md b/grpc/README.md index eb91757bc3d..d3d49668139 100644 --- a/grpc/README.md +++ b/grpc/README.md @@ -1,6 +1,8 @@ This package provides a gRPC server as an entrypoint to the EVM. -## Build and run from source: + + +Helpful commands (MacOS): ```bash # install necessary dependencies brew install leveldb @@ -8,6 +10,11 @@ brew install leveldb # build geth make geth +# generating protobuf files +buf generate buf.build/astria/execution-apis + +# TODO - run beacon? + # run geth ./build/bin/geth --goerli --grpc --grpc.addr "0.0.0.0" --grpc.port 50051 ``` diff --git a/grpc/execution/server.go b/grpc/execution/server.go index e5f0bc57712..9e83d2bb069 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -8,6 +8,7 @@ import ( "context" "github.com/ethereum/go-ethereum/beacon/engine" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/catalyst" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" @@ -34,18 +35,24 @@ func NewExecutionServiceServer(eth *eth.Ethereum) *ExecutionServiceServer { } } -// FIXME - how do we know which hash to start with? will probably need another api function like -// GetHeadHash() to get the head hash of the forkchoice - func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.DoBlockRequest) (*executionv1.DoBlockResponse, error) { log.Info("DoBlock called request", "request", req) + prevHeadHash := common.BytesToHash(req.PrevStateRoot) // 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{} - payloadAttributes := &engine.PayloadAttributes{} + 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 @@ -73,3 +80,12 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D } return res, nil } + +func (s *ExecutionServiceServer) InitState(ctx context.Context, req *executionv1.InitStateRequest) (*executionv1.InitStateResponse, error) { + currHead := s.eth.BlockChain().CurrentHeader() + res := &executionv1.InitStateResponse{ + StateRoot: currHead.Hash().Bytes(), + } + + return res, nil +} diff --git a/grpc/gen/proto/execution/v1/execution.pb.go b/grpc/gen/proto/execution/v1/execution.pb.go index aca5c123480..2382493e64f 100644 --- a/grpc/gen/proto/execution/v1/execution.pb.go +++ b/grpc/gen/proto/execution/v1/execution.pb.go @@ -9,6 +9,7 @@ package executionv1 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" ) @@ -25,8 +26,9 @@ type DoBlockRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Header []byte `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` - Transactions [][]byte `protobuf:"bytes,2,rep,name=transactions,proto3" json:"transactions,omitempty"` + PrevStateRoot []byte `protobuf:"bytes,1,opt,name=prev_state_root,json=prevStateRoot,proto3" json:"prev_state_root,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() { @@ -61,9 +63,9 @@ func (*DoBlockRequest) Descriptor() ([]byte, []int) { return file_proto_execution_v1_execution_proto_rawDescGZIP(), []int{0} } -func (x *DoBlockRequest) GetHeader() []byte { +func (x *DoBlockRequest) GetPrevStateRoot() []byte { if x != nil { - return x.Header + return x.PrevStateRoot } return nil } @@ -75,6 +77,13 @@ func (x *DoBlockRequest) GetTransactions() [][]byte { 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 @@ -122,39 +131,140 @@ func (x *DoBlockResponse) GetStateRoot() []byte { return nil } +type InitStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *InitStateRequest) Reset() { + *x = InitStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_execution_v1_execution_proto_msgTypes[2] + 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_proto_execution_v1_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 InitStateRequest.ProtoReflect.Descriptor instead. +func (*InitStateRequest) Descriptor() ([]byte, []int) { + return file_proto_execution_v1_execution_proto_rawDescGZIP(), []int{2} +} + +type InitStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StateRoot []byte `protobuf:"bytes,1,opt,name=state_root,json=stateRoot,proto3" json:"state_root,omitempty"` +} + +func (x *InitStateResponse) Reset() { + *x = InitStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_execution_v1_execution_proto_msgTypes[3] + 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_proto_execution_v1_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 InitStateResponse.ProtoReflect.Descriptor instead. +func (*InitStateResponse) Descriptor() ([]byte, []int) { + return file_proto_execution_v1_execution_proto_rawDescGZIP(), []int{3} +} + +func (x *InitStateResponse) GetStateRoot() []byte { + if x != nil { + return x.StateRoot + } + return nil +} + var File_proto_execution_v1_execution_proto protoreflect.FileDescriptor var file_proto_execution_v1_execution_proto_rawDesc = []byte{ 0x0a, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, - 0x76, 0x31, 0x22, 0x4c, 0x0a, 0x0e, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 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, - 0x22, 0x30, 0x0a, 0x0f, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, - 0x6f, 0x74, 0x32, 0x5a, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x12, 0x1c, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, - 0x2e, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xb8, - 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 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, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x45, 0x58, 0x58, - 0xaa, 0x02, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0xe2, 0x02, - 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x45, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x76, 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, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0d, 0x70, 0x72, 0x65, 0x76, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 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, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 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, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x32, 0xa8, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x07, 0x44, + 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x1c, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x09, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x1e, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1f, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0xb8, 0x01, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x42, 0x0e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 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, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, + 0x31, 0x3b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0xa2, 0x02, 0x03, + 0x45, 0x58, 0x58, 0xaa, 0x02, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x0c, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x18, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5c, 0x56, 0x31, + 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -169,19 +279,25 @@ func file_proto_execution_v1_execution_proto_rawDescGZIP() []byte { return file_proto_execution_v1_execution_proto_rawDescData } -var file_proto_execution_v1_execution_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_proto_execution_v1_execution_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_proto_execution_v1_execution_proto_goTypes = []interface{}{ - (*DoBlockRequest)(nil), // 0: execution.v1.DoBlockRequest - (*DoBlockResponse)(nil), // 1: execution.v1.DoBlockResponse + (*DoBlockRequest)(nil), // 0: execution.v1.DoBlockRequest + (*DoBlockResponse)(nil), // 1: execution.v1.DoBlockResponse + (*InitStateRequest)(nil), // 2: execution.v1.InitStateRequest + (*InitStateResponse)(nil), // 3: execution.v1.InitStateResponse + (*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp } var file_proto_execution_v1_execution_proto_depIdxs = []int32{ - 0, // 0: execution.v1.ExecutionService.DoBlock:input_type -> execution.v1.DoBlockRequest - 1, // 1: execution.v1.ExecutionService.DoBlock:output_type -> execution.v1.DoBlockResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 4, // 0: execution.v1.DoBlockRequest.timestamp:type_name -> google.protobuf.Timestamp + 0, // 1: execution.v1.ExecutionService.DoBlock:input_type -> execution.v1.DoBlockRequest + 2, // 2: execution.v1.ExecutionService.InitState:input_type -> execution.v1.InitStateRequest + 1, // 3: execution.v1.ExecutionService.DoBlock:output_type -> execution.v1.DoBlockResponse + 3, // 4: execution.v1.ExecutionService.InitState:output_type -> execution.v1.InitStateResponse + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] 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_proto_execution_v1_execution_proto_init() } @@ -214,6 +330,30 @@ func file_proto_execution_v1_execution_proto_init() { return nil } } + file_proto_execution_v1_execution_proto_msgTypes[2].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_proto_execution_v1_execution_proto_msgTypes[3].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{ @@ -221,7 +361,7 @@ func file_proto_execution_v1_execution_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_proto_execution_v1_execution_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 4, NumExtensions: 0, NumServices: 1, }, diff --git a/grpc/gen/proto/execution/v1/execution_grpc.pb.go b/grpc/gen/proto/execution/v1/execution_grpc.pb.go index 63995f7e874..1faf8aeb74d 100644 --- a/grpc/gen/proto/execution/v1/execution_grpc.pb.go +++ b/grpc/gen/proto/execution/v1/execution_grpc.pb.go @@ -19,7 +19,8 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - ExecutionService_DoBlock_FullMethodName = "/execution.v1.ExecutionService/DoBlock" + ExecutionService_DoBlock_FullMethodName = "/execution.v1.ExecutionService/DoBlock" + ExecutionService_InitState_FullMethodName = "/execution.v1.ExecutionService/InitState" ) // ExecutionServiceClient is the client API for ExecutionService service. @@ -27,6 +28,7 @@ const ( // 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 { DoBlock(ctx context.Context, in *DoBlockRequest, opts ...grpc.CallOption) (*DoBlockResponse, error) + InitState(ctx context.Context, in *InitStateRequest, opts ...grpc.CallOption) (*InitStateResponse, error) } type executionServiceClient struct { @@ -46,11 +48,21 @@ func (c *executionServiceClient) DoBlock(ctx context.Context, in *DoBlockRequest return out, nil } +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 +} + // ExecutionServiceServer is the server API for ExecutionService service. // All implementations must embed UnimplementedExecutionServiceServer // for forward compatibility type ExecutionServiceServer interface { DoBlock(context.Context, *DoBlockRequest) (*DoBlockResponse, error) + InitState(context.Context, *InitStateRequest) (*InitStateResponse, error) mustEmbedUnimplementedExecutionServiceServer() } @@ -61,6 +73,9 @@ type UnimplementedExecutionServiceServer struct { func (UnimplementedExecutionServiceServer) DoBlock(context.Context, *DoBlockRequest) (*DoBlockResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DoBlock not implemented") } +func (UnimplementedExecutionServiceServer) InitState(context.Context, *InitStateRequest) (*InitStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method InitState not implemented") +} func (UnimplementedExecutionServiceServer) mustEmbedUnimplementedExecutionServiceServer() {} // UnsafeExecutionServiceServer may be embedded to opt out of forward compatibility for this service. @@ -92,6 +107,24 @@ func _ExecutionService_DoBlock_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +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) +} + // 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) @@ -103,6 +136,10 @@ var ExecutionService_ServiceDesc = grpc.ServiceDesc{ MethodName: "DoBlock", Handler: _ExecutionService_DoBlock_Handler, }, + { + MethodName: "InitState", + Handler: _ExecutionService_InitState_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "proto/execution/v1/execution.proto", From 7fd75bd7053ad6e0de6346f4507902ac5723f6a2 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Wed, 29 Mar 2023 15:27:08 -0700 Subject: [PATCH 06/21] Add clear astriaordered, cleanup --- core/txpool/txpool.go | 20 +++++++++++++++++--- miner/worker.go | 1 + 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 88e72a10e1a..3e68ecfc07c 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -259,7 +259,7 @@ type TxPool struct { pendingNonces *noncer // Pending state tracking virtual nonces currentMaxGas uint64 // Current gas limit for transaction caps - astria *astriaOrdered + astria *astriaOrdered locals *accountSet // Set of local transaction to exempt from eviction rules journal *journal // Journal of local transaction to back up to disk @@ -931,7 +931,7 @@ func (pool *TxPool) SetAstriaOrdered(rawTxs [][]byte) { txs := *&types.Transactions{} for idx, rawTx := range rawTxs { tx := new(types.Transaction) - err := tx.UnmarshalBinary(rawTx); + err := tx.UnmarshalBinary(rawTx) if err != nil { log.Info("Failed to unmarshall raw astria tx bytes", rawTx, "at index", idx) continue @@ -946,7 +946,11 @@ func (pool *TxPool) SetAstriaOrdered(rawTxs [][]byte) { txs = append(txs, tx) } - pool.astria.txs = txs + pool.astria = newAstriaOrdered(&txs) +} + +func (pool *TxPool) ClearAstriaOrdered() { + pool.astria.clear() } func (pool *TxPool) AstriaOrdered() *types.Transactions { @@ -1743,6 +1747,16 @@ type astriaOrdered struct { txs types.Transactions } +func newAstriaOrdered(txs *types.Transactions) *astriaOrdered { + return &astriaOrdered{ + txs: *txs, + } +} + +func (ao *astriaOrdered) clear() { + ao.txs = *&types.Transactions{} +} + // accountSet is simply a set of addresses to check for existence, and a signer // capable of deriving addresses from transactions. type accountSet struct { diff --git a/miner/worker.go b/miner/worker.go index 00ec9046bb0..27b445e7622 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1157,6 +1157,7 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) error { return err } } + w.eth.TxPool().ClearAstriaOrdered() // Original Geth Code if false { From 2b6ae0217571ebd1864109063d18efe3db4ac550 Mon Sep 17 00:00:00 2001 From: Jordan Oroshiba Date: Thu, 30 Mar 2023 11:20:59 -0700 Subject: [PATCH 07/21] readme fix --- grpc/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/grpc/README.md b/grpc/README.md index d3d49668139..6f6607fa2b6 100644 --- a/grpc/README.md +++ b/grpc/README.md @@ -1,8 +1,6 @@ This package provides a gRPC server as an entrypoint to the EVM. - - -Helpful commands (MacOS): +## Build and run from source: ```bash # install necessary dependencies brew install leveldb From 76b5c7c35ec89765460418e7b87b48770851666d Mon Sep 17 00:00:00 2001 From: Jesse Snyder Date: Fri, 31 Mar 2023 19:40:57 -0600 Subject: [PATCH 08/21] add bash and jq to final docker image --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile b/Dockerfile index 0b51035e366..ce3414df97d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,10 @@ 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/ # Astria - add 50051 for GRPC From 87f8f7dcbf6ff3ed25610defc403f82c18ac859d Mon Sep 17 00:00:00 2001 From: elizabeth Date: Tue, 4 Apr 2023 16:55:51 -0400 Subject: [PATCH 09/21] make txpool interface --- core/txpool/txpool.go | 1 + eth/api_backend.go | 3 +-- eth/backend.go | 6 ++++-- grpc/execution/server.go | 4 ++-- les/server.go | 4 ++-- les/server_handler.go | 8 ++++---- les/server_requests.go | 3 ++- miner/miner.go | 23 ++++++++++++++++++++++- private_network.md | 2 +- 9 files changed, 39 insertions(+), 15 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 3e68ecfc07c..a73056c8d0f 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -310,6 +310,7 @@ func NewTxPool(config Config, chainconfig *params.ChainConfig, chain blockChain) reorgShutdownCh: make(chan struct{}), initDoneCh: make(chan struct{}), gasPrice: new(big.Int).SetUint64(config.PriceLimit), + //astriaOrdered: newAstriaOrdered(), } pool.locals = newAccountSet(pool.signer) for _, addr := range config.Locals { diff --git a/eth/api_backend.go b/eth/api_backend.go index ac160b0736a..55562c3b745 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -30,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -311,7 +310,7 @@ func (b *EthAPIBackend) TxPoolContentFrom(addr common.Address) (types.Transactio return b.eth.TxPool().ContentFrom(addr) } -func (b *EthAPIBackend) TxPool() *txpool.TxPool { +func (b *EthAPIBackend) TxPool() TxPool { return b.eth.TxPool() } diff --git a/eth/backend.go b/eth/backend.go index 6368c0e03c5..c1c30d21cd5 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -62,12 +62,14 @@ import ( // Deprecated: use ethconfig.Config instead. type Config = ethconfig.Config +type TxPool = miner.TxPool + // Ethereum implements the Ethereum full node service. type Ethereum struct { config *ethconfig.Config // Handlers - txPool *txpool.TxPool + txPool TxPool blockchain *core.BlockChain handler *handler ethDialCandidates enode.Iterator @@ -468,7 +470,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } -func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool } +func (s *Ethereum) TxPool() TxPool { return s.txPool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 9e83d2bb069..7413baafcd1 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -49,8 +49,8 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D FinalizedBlockHash: prevHeadHash, } payloadAttributes := &engine.PayloadAttributes{ - Timestamp: uint64(req.GetTimestamp().GetSeconds()), - Random: common.Hash{}, + Timestamp: uint64(req.GetTimestamp().GetSeconds()), + Random: common.Hash{}, SuggestedFeeRecipient: common.Address{}, } fcStartResp, err := s.consensus.ForkchoiceUpdatedV1(*startForkChoice, payloadAttributes) diff --git a/les/server.go b/les/server.go index 06bbc30fb0d..ca3ebb2308c 100644 --- a/les/server.go +++ b/les/server.go @@ -22,13 +22,13 @@ import ( "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/les/flowcontrol" vfs "github.com/ethereum/go-ethereum/les/vflux/server" "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" @@ -50,7 +50,7 @@ type ethBackend interface { BloomIndexer() *core.ChainIndexer ChainDb() ethdb.Database Synced() bool - TxPool() *txpool.TxPool + TxPool() miner.TxPool } type LesServer struct { diff --git a/les/server_handler.go b/les/server_handler.go index 2ea496ac2c3..5553493d813 100644 --- a/les/server_handler.go +++ b/les/server_handler.go @@ -27,13 +27,13 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/les/flowcontrol" "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" @@ -63,7 +63,7 @@ type serverHandler struct { forkFilter forkid.Filter blockchain *core.BlockChain chainDb ethdb.Database - txpool *txpool.TxPool + txpool miner.TxPool server *LesServer closeCh chan struct{} // Channel used to exit all background routines of handler. @@ -74,7 +74,7 @@ type serverHandler struct { addTxsSync bool } -func newServerHandler(server *LesServer, blockchain *core.BlockChain, chainDb ethdb.Database, txpool *txpool.TxPool, synced func() bool) *serverHandler { +func newServerHandler(server *LesServer, blockchain *core.BlockChain, chainDb ethdb.Database, txpool miner.TxPool, synced func() bool) *serverHandler { handler := &serverHandler{ forkFilter: forkid.NewFilter(blockchain), server: server, @@ -344,7 +344,7 @@ func (h *serverHandler) BlockChain() *core.BlockChain { } // TxPool implements serverBackend -func (h *serverHandler) TxPool() *txpool.TxPool { +func (h *serverHandler) TxPool() miner.TxPool { return h.txpool } diff --git a/les/server_requests.go b/les/server_requests.go index 033b11d7937..4ac52f79788 100644 --- a/les/server_requests.go +++ b/les/server_requests.go @@ -28,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -37,7 +38,7 @@ type serverBackend interface { ArchiveMode() bool AddTxsSync() bool BlockChain() *core.BlockChain - TxPool() *txpool.TxPool + TxPool() miner.TxPool GetHelperTrie(typ uint, index uint64) *trie.Trie } diff --git a/miner/miner.go b/miner/miner.go index c969aec7354..e0acbbc8421 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -36,11 +36,32 @@ import ( "github.com/ethereum/go-ethereum/params" ) +type TxPool interface { + AddRemotes(txs []*types.Transaction) []error + AddLocal(tx *types.Transaction) error + Pending(enforceTips bool) map[common.Address]types.Transactions + Get(hash common.Hash) *types.Transaction + Nonce(addr common.Address) uint64 + Stats() (int, int) + SetGasPrice(price *big.Int) + Has(hash common.Hash) bool + SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription + Stop() + Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) + ContentFrom(addr common.Address) (types.Transactions, types.Transactions) + AstriaOrdered() *types.Transactions + ClearAstriaOrdered() + SetAstriaOrdered(rawTxs [][]byte) + AddRemotesSync(txs []*types.Transaction) []error + Locals() []common.Address + Status(hashes []common.Hash) []txpool.TxStatus +} + // Backend wraps all methods required for mining. Only full node is capable // to offer all the functions here. type Backend interface { BlockChain() *core.BlockChain - TxPool() *txpool.TxPool + TxPool() TxPool } // Config is the configuration parameters of mining. diff --git a/private_network.md b/private_network.md index 1b9bb03e72e..9b1a448f16e 100644 --- a/private_network.md +++ b/private_network.md @@ -6,7 +6,7 @@ ```bash make geth ./build/bin/geth --datadir ~/.astriageth/ init genesis.json -./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=0xDB8c0F738639Da247bC67251548a186b2107bf4d +./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=0xDB8c0F738639Da247bC67251548a186b2107bf4d --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. \ No newline at end of file From 10926527de339a1d1aec3edacc54052760954947 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Tue, 4 Apr 2023 17:32:19 -0400 Subject: [PATCH 10/21] no more panics, update DoBlock to also update state + store block --- core/txpool/txpool.go | 19 +++++++++++++------ grpc/execution/server.go | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index a73056c8d0f..b9c13ebe0e7 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -929,32 +929,39 @@ func (pool *TxPool) AddLocal(tx *types.Transaction) error { } func (pool *TxPool) SetAstriaOrdered(rawTxs [][]byte) { - txs := *&types.Transactions{} + txs := []*types.Transaction{} for idx, rawTx := range rawTxs { tx := new(types.Transaction) err := tx.UnmarshalBinary(rawTx) if err != nil { - log.Info("Failed to unmarshall raw astria tx bytes", rawTx, "at index", idx) + log.Warn("failed to unmarshal raw astria tx bytes", rawTx, "at index", idx, "error:", err) continue } err = pool.astriaValidate(tx) if err != nil { - log.Info("Astria tx failed validation at index", idx, "failed validation:", err) + log.Warn("astria tx failed validation at index", idx, "error:", err) continue } txs = append(txs, tx) } - pool.astria = newAstriaOrdered(&txs) + 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 } @@ -1748,9 +1755,9 @@ type astriaOrdered struct { txs types.Transactions } -func newAstriaOrdered(txs *types.Transactions) *astriaOrdered { +func newAstriaOrdered(txs types.Transactions) *astriaOrdered { return &astriaOrdered{ - txs: *txs, + txs: txs, } } diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 7413baafcd1..764cadc8f4f 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -6,9 +6,12 @@ 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" executionv1 "github.com/ethereum/go-ethereum/grpc/gen/proto/execution/v1" @@ -24,14 +27,19 @@ type ExecutionServiceServer struct { consensus *catalyst.ConsensusAPI eth *eth.Ethereum + + bc *core.BlockChain } func NewExecutionServiceServer(eth *eth.Ethereum) *ExecutionServiceServer { consensus := catalyst.NewConsensusAPI(eth) + bc := eth.BlockChain() + return &ExecutionServiceServer{ eth: eth, consensus: consensus, + bc: bc, } } @@ -61,10 +69,11 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D if err != nil { return nil, err } - payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) - if err != nil { - return nil, err - } + payloadStatus := fcStartResp.PayloadStatus + // payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) + // if err != nil { + // return nil, err + // } newForkChoice := &engine.ForkchoiceStateV1{ HeadBlockHash: *payloadStatus.LatestValidHash, SafeBlockHash: *payloadStatus.LatestValidHash, @@ -75,7 +84,24 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D 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) + } + res := &executionv1.DoBlockResponse{ + // RENAME THIS - this is not the state root!! it's the block hash StateRoot: fcEndResp.PayloadStatus.LatestValidHash.Bytes(), } return res, nil From 1b6a23ffafc7a421c89989f195ebd2dce7d923c7 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Tue, 4 Apr 2023 18:58:02 -0400 Subject: [PATCH 11/21] cleanup --- cmd/utils/flags.go | 1 - common/types.go | 3 ++- consensus/ethash/consensus.go | 47 +++++++++++++++++------------------ eth/catalyst/api.go | 42 +++++++++++++++---------------- genesis.json | 38 ++++++++++++++-------------- grpc/execution/server.go | 41 ++++++++++++++++++++++-------- node/node.go | 2 ++ private_network.md | 14 +++++++++-- 8 files changed, 109 insertions(+), 79 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ca6545b87f2..72888493120 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2043,7 +2043,6 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend Fatalf("Failed to create the LES server: %v", err) } } - // We don't want to publicly expose the engine API, instead use grpc endpoints // if err := ethcatalyst.Register(stack, backend); err != nil { // Fatalf("Failed to register the Engine API service: %v", err) // } diff --git a/common/types.go b/common/types.go index 218ca0be4c4..f3bb737fba4 100644 --- a/common/types.go +++ b/common/types.go @@ -76,7 +76,8 @@ func (h Hash) Hex() string { return hexutil.Encode(h[:]) } // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (h Hash) TerminalString() string { - return fmt.Sprintf("%x..%x", h[:3], h[29:]) + //return fmt.Sprintf("%x..%x", h[:3], h[29:]) + return h.String() } // String implements the stringer interface and is used also by the logger when diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index c3c06c541ca..5b8340c17ea 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -17,7 +17,6 @@ package ethash import ( - "bytes" "errors" "fmt" "math/big" @@ -280,11 +279,11 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa return errOlderBlockTime } // Verify the block's difficulty based on its timestamp and parent's difficulty - expected := ethash.CalcDifficulty(chain, header.Time, parent) + //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) - } + // if expected.Cmp(header.Difficulty) != 0 { + // return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected) + // } // Verify that the gas limit is <= 2^63-1 if header.GasLimit > params.MaxGasLimit { return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit) @@ -538,21 +537,21 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type return ethash.shared.verifySeal(chain, header, fulldag) } // Ensure that we have a valid difficulty for the block - if header.Difficulty.Sign() <= 0 { + if header.Difficulty.Sign() < 0 { return errInvalidDifficulty } // Recompute the digest and PoW values number := header.Number.Uint64() - var ( - digest []byte - result []byte - ) + // var ( + // digest []byte + // result []byte + // ) // If fast-but-heavy PoW verification was requested, use an ethash dataset if fulldag { dataset := ethash.dataset(number, true) if dataset.generated() { - digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + //digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) // Datasets are unmapped in a finalizer. Ensure that the dataset stays alive // until after the call to hashimotoFull so it's not unmapped while being used. @@ -566,24 +565,24 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type if !fulldag { cache := ethash.cache(number) - size := datasetSize(number) - if ethash.config.PowMode == ModeTest { - size = 32 * 1024 - } - digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + // size := datasetSize(number) + // if ethash.config.PowMode == ModeTest { + // size = 32 * 1024 + // } + //digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) // Caches are unmapped in a finalizer. Ensure that the cache stays alive // until after the call to hashimotoLight so it's not unmapped while being used. runtime.KeepAlive(cache) } // Verify the calculated values against the ones provided in the header - if !bytes.Equal(header.MixDigest[:], digest) { - return errInvalidMixDigest - } - target := new(big.Int).Div(two256, header.Difficulty) - if new(big.Int).SetBytes(result).Cmp(target) > 0 { - return errInvalidPoW - } + // if !bytes.Equal(header.MixDigest[:], digest) { + // return errInvalidMixDigest + // } + // target := new(big.Int).Div(two256, header.Difficulty) + // if new(big.Int).SetBytes(result).Cmp(target) > 0 { + // return errInvalidPoW + // } return nil } @@ -594,7 +593,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H if parent == nil { return consensus.ErrUnknownAncestor } - header.Difficulty = ethash.CalcDifficulty(chain, header.Time, parent) + header.Difficulty = common.Big0 //ethash.CalcDifficulty(chain, header.Time, parent) return nil } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 9077f20bffc..98186024b56 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -262,27 +262,27 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl } return engine.STATUS_SYNCING, nil } - // Block is known locally, just sanity check that the beacon client does not - // attempt to push us back to before the merge. - if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 { - var ( - td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64()) - ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1) - ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty - ) - if td == nil || (block.NumberU64() > 0 && ptd == nil) { - log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd) - return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check") - } - if td.Cmp(ttd) < 0 { - log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) - return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil - } - if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 { - log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) - return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil - } - } + // // Block is known locally, just sanity check that the beacon client does not + // // attempt to push us back to before the merge. + // if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 { + // var ( + // td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64()) + // ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1) + // ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty + // ) + // if td == nil || (block.NumberU64() > 0 && ptd == nil) { + // log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd) + // return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check") + // } + // if td.Cmp(ttd) < 0 { + // log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) + // return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil + // } + // if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 { + // log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) + // return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil + // } + // } valid := func(id *engine.PayloadID) engine.ForkChoiceResponse { return engine.ForkChoiceResponse{ PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash}, diff --git a/genesis.json b/genesis.json index 0669d58c454..7bc481d758a 100644 --- a/genesis.json +++ b/genesis.json @@ -1,21 +1,21 @@ { "config": { - "chainId": 1337, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "ethash": {} - }, - "difficulty": "10000", - "gasLimit": "8000000", - "alloc": { - "0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102": { "balance": "300000000000000000000" } - } - } \ No newline at end of file + "chainId": 1337, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "ethash": {} + }, + "difficulty": "10000000", + "gasLimit": "8000000", + "alloc": { + "0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102": { "balance": "300000000000000000000" } + } +} diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 764cadc8f4f..39e5dcaffce 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -7,6 +7,7 @@ package execution import ( "context" "fmt" + "time" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" @@ -65,26 +66,23 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D if err != nil { return nil, err } + // super janky but this is what the payload builder does :/ (miner.worker.buildPayload()) + // we should probably just execute + store the block directly instead of using the engine api. + time.Sleep(time.Second) payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID) if err != nil { + log.Error("failed to call GetPayloadV1", "err", err) return nil, err } - payloadStatus := fcStartResp.PayloadStatus - // payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) + + // _, err = engine.ExecutableDataToBlock(*payloadResp) // if err != nil { + // log.Error("failed to call ExecutableDataToBlock", "err", err) // return nil, err // } - newForkChoice := &engine.ForkchoiceStateV1{ - HeadBlockHash: *payloadStatus.LatestValidHash, - SafeBlockHash: *payloadStatus.LatestValidHash, - FinalizedBlockHash: *payloadStatus.LatestValidHash, - } - fcEndResp, err := s.consensus.ForkchoiceUpdatedV1(*newForkChoice, nil) - if err != nil { - return nil, err - } // call blockchain.InsertChain to actually execute and write the blocks to state + // TODO we might not actually need this since the miner loop should seal and call blockchain.WriteBlockAndSetHead block, err := engine.ExecutableDataToBlock(*payloadResp) if err != nil { return nil, err @@ -100,6 +98,27 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D return nil, fmt.Errorf("failed to insert block into blockchain (n=%d)", n) } + //payloadStatus := fcStartResp.PayloadStatus + // payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) + // if err != nil { + // return nil, err + // } + // newForkChoice := &engine.ForkchoiceStateV1{ + // HeadBlockHash: payloadResp.BlockHash, + // SafeBlockHash: payloadResp.BlockHash, + // FinalizedBlockHash: payloadResp.BlockHash, + // } + newForkChoice := &engine.ForkchoiceStateV1{ + HeadBlockHash: block.Hash(), + SafeBlockHash: block.Hash(), + FinalizedBlockHash: block.Hash(), + } + fcEndResp, err := s.consensus.ForkchoiceUpdatedV1(*newForkChoice, nil) + if err != nil { + log.Error("failed to call ForkchoiceUpdatedV1", "err", err) + return nil, err + } + res := &executionv1.DoBlockResponse{ // RENAME THIS - this is not the state root!! it's the block hash StateRoot: fcEndResp.PayloadStatus.LatestValidHash.Bytes(), diff --git a/node/node.go b/node/node.go index fe1b17592bc..2e8efac3040 100644 --- a/node/node.go +++ b/node/node.go @@ -274,12 +274,14 @@ 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 diff --git a/private_network.md b/private_network.md index 9b1a448f16e..9d5b57391ec 100644 --- a/private_network.md +++ b/private_network.md @@ -2,11 +2,21 @@ 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. Replace the etherbase in the following with your account (it doesn't really matter though, since mining doesn't require signing). Then, run: +2. To build and initialize Geth: ```bash make geth ./build/bin/geth --datadir ~/.astriageth/ init genesis.json -./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=0xDB8c0F738639Da247bC67251548a186b2107bf4d --grpc --grpc.addr=localhost --grpc.port 50051 +``` + +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='*' --miner.threads 1 --miner.etherbase=0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102 --grpc --grpc.addr=localhost --grpc.port 50051 +``` + +To run with mining: +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 ``` 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. \ No newline at end of file From 1a16737426054d7bf0e9cb811ef9377a8370e86d Mon Sep 17 00:00:00 2001 From: elizabeth Date: Tue, 4 Apr 2023 19:13:05 -0400 Subject: [PATCH 12/21] set post-merge at genesis --- cmd/utils/flags.go | 4 +-- common/types.go | 3 +-- consensus/ethash/consensus.go | 46 +++++++++++++++++------------------ eth/catalyst/api.go | 42 ++++++++++++++++---------------- genesis.json | 1 + grpc/README.md | 2 -- grpc/execution/server.go | 23 +++--------------- private_network.md | 11 ++++++--- 8 files changed, 58 insertions(+), 74 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 72888493120..b61a9b78634 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2043,9 +2043,7 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend Fatalf("Failed to create the LES server: %v", err) } } - // if err := ethcatalyst.Register(stack, backend); err != nil { - // Fatalf("Failed to register the Engine API service: %v", err) - // } + stack.RegisterAPIs(tracers.APIs(backend.APIBackend)) return backend.APIBackend, backend } diff --git a/common/types.go b/common/types.go index f3bb737fba4..218ca0be4c4 100644 --- a/common/types.go +++ b/common/types.go @@ -76,8 +76,7 @@ func (h Hash) Hex() string { return hexutil.Encode(h[:]) } // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (h Hash) TerminalString() string { - //return fmt.Sprintf("%x..%x", h[:3], h[29:]) - return h.String() + return fmt.Sprintf("%x..%x", h[:3], h[29:]) } // String implements the stringer interface and is used also by the logger when diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 5b8340c17ea..a949522d856 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -17,6 +17,7 @@ package ethash import ( + "bytes" "errors" "fmt" "math/big" @@ -279,11 +280,10 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa return errOlderBlockTime } // 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) - // } + 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) + } // Verify that the gas limit is <= 2^63-1 if header.GasLimit > params.MaxGasLimit { return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit) @@ -543,15 +543,15 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type // Recompute the digest and PoW values number := header.Number.Uint64() - // var ( - // digest []byte - // result []byte - // ) + var ( + digest []byte + result []byte + ) // If fast-but-heavy PoW verification was requested, use an ethash dataset if fulldag { dataset := ethash.dataset(number, true) if dataset.generated() { - //digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) // Datasets are unmapped in a finalizer. Ensure that the dataset stays alive // until after the call to hashimotoFull so it's not unmapped while being used. @@ -565,24 +565,24 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type if !fulldag { cache := ethash.cache(number) - // size := datasetSize(number) - // if ethash.config.PowMode == ModeTest { - // size = 32 * 1024 - // } - //digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) + size := datasetSize(number) + if ethash.config.PowMode == ModeTest { + size = 32 * 1024 + } + digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64()) // Caches are unmapped in a finalizer. Ensure that the cache stays alive // until after the call to hashimotoLight so it's not unmapped while being used. runtime.KeepAlive(cache) } // Verify the calculated values against the ones provided in the header - // if !bytes.Equal(header.MixDigest[:], digest) { - // return errInvalidMixDigest - // } - // target := new(big.Int).Div(two256, header.Difficulty) - // if new(big.Int).SetBytes(result).Cmp(target) > 0 { - // return errInvalidPoW - // } + if !bytes.Equal(header.MixDigest[:], digest) { + return errInvalidMixDigest + } + target := new(big.Int).Div(two256, header.Difficulty) + if new(big.Int).SetBytes(result).Cmp(target) > 0 { + return errInvalidPoW + } return nil } @@ -593,7 +593,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H if parent == nil { return consensus.ErrUnknownAncestor } - header.Difficulty = common.Big0 //ethash.CalcDifficulty(chain, header.Time, parent) + header.Difficulty = ethash.CalcDifficulty(chain, header.Time, parent) return nil } diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 98186024b56..9077f20bffc 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -262,27 +262,27 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl } return engine.STATUS_SYNCING, nil } - // // Block is known locally, just sanity check that the beacon client does not - // // attempt to push us back to before the merge. - // if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 { - // var ( - // td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64()) - // ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1) - // ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty - // ) - // if td == nil || (block.NumberU64() > 0 && ptd == nil) { - // log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd) - // return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check") - // } - // if td.Cmp(ttd) < 0 { - // log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) - // return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil - // } - // if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 { - // log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) - // return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil - // } - // } + // Block is known locally, just sanity check that the beacon client does not + // attempt to push us back to before the merge. + if block.Difficulty().BitLen() > 0 || block.NumberU64() == 0 { + var ( + td = api.eth.BlockChain().GetTd(update.HeadBlockHash, block.NumberU64()) + ptd = api.eth.BlockChain().GetTd(block.ParentHash(), block.NumberU64()-1) + ttd = api.eth.BlockChain().Config().TerminalTotalDifficulty + ) + if td == nil || (block.NumberU64() > 0 && ptd == nil) { + log.Error("TDs unavailable for TTD check", "number", block.NumberU64(), "hash", update.HeadBlockHash, "td", td, "parent", block.ParentHash(), "ptd", ptd) + return engine.STATUS_INVALID, errors.New("TDs unavailable for TDD check") + } + if td.Cmp(ttd) < 0 { + log.Error("Refusing beacon update to pre-merge", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) + return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil + } + if block.NumberU64() > 0 && ptd.Cmp(ttd) >= 0 { + log.Error("Parent block is already post-ttd", "number", block.NumberU64(), "hash", update.HeadBlockHash, "diff", block.Difficulty(), "age", common.PrettyAge(time.Unix(int64(block.Time()), 0))) + return engine.ForkChoiceResponse{PayloadStatus: engine.INVALID_TERMINAL_BLOCK, PayloadID: nil}, nil + } + } valid := func(id *engine.PayloadID) engine.ForkChoiceResponse { return engine.ForkChoiceResponse{ PayloadStatus: engine.PayloadStatusV1{Status: engine.VALID, LatestValidHash: &update.HeadBlockHash}, diff --git a/genesis.json b/genesis.json index 7bc481d758a..57fca8b3f88 100644 --- a/genesis.json +++ b/genesis.json @@ -11,6 +11,7 @@ "istanbulBlock": 0, "berlinBlock": 0, "londonBlock": 0, + "terminalTotalDifficulty": 0, "ethash": {} }, "difficulty": "10000000", diff --git a/grpc/README.md b/grpc/README.md index 6f6607fa2b6..855fa0e22d5 100644 --- a/grpc/README.md +++ b/grpc/README.md @@ -11,8 +11,6 @@ make geth # generating protobuf files buf generate buf.build/astria/execution-apis -# TODO - run beacon? - # run geth ./build/bin/geth --goerli --grpc --grpc.addr "0.0.0.0" --grpc.port 50051 ``` diff --git a/grpc/execution/server.go b/grpc/execution/server.go index 39e5dcaffce..18f413d8c84 100644 --- a/grpc/execution/server.go +++ b/grpc/execution/server.go @@ -66,7 +66,8 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D if err != nil { return nil, err } - // super janky but this is what the payload builder does :/ (miner.worker.buildPayload()) + + // super janky but this is what the payload builder requires :/ (miner.worker.buildPayload()) // we should probably just execute + store the block directly instead of using the engine api. time.Sleep(time.Second) payloadResp, err := s.consensus.GetPayloadV1(*fcStartResp.PayloadID) @@ -75,14 +76,7 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D return nil, err } - // _, err = engine.ExecutableDataToBlock(*payloadResp) - // if err != nil { - // log.Error("failed to call ExecutableDataToBlock", "err", err) - // return nil, err - // } - // call blockchain.InsertChain to actually execute and write the blocks to state - // TODO we might not actually need this since the miner loop should seal and call blockchain.WriteBlockAndSetHead block, err := engine.ExecutableDataToBlock(*payloadResp) if err != nil { return nil, err @@ -98,16 +92,6 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D return nil, fmt.Errorf("failed to insert block into blockchain (n=%d)", n) } - //payloadStatus := fcStartResp.PayloadStatus - // payloadStatus, err := s.consensus.NewPayloadV1(*payloadResp) - // if err != nil { - // return nil, err - // } - // newForkChoice := &engine.ForkchoiceStateV1{ - // HeadBlockHash: payloadResp.BlockHash, - // SafeBlockHash: payloadResp.BlockHash, - // FinalizedBlockHash: payloadResp.BlockHash, - // } newForkChoice := &engine.ForkchoiceStateV1{ HeadBlockHash: block.Hash(), SafeBlockHash: block.Hash(), @@ -120,7 +104,7 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D } res := &executionv1.DoBlockResponse{ - // RENAME THIS - this is not the state root!! it's the block hash + // TODO: RENAME THIS - this is not the state root!! it's the block hash StateRoot: fcEndResp.PayloadStatus.LatestValidHash.Bytes(), } return res, nil @@ -129,6 +113,7 @@ func (s *ExecutionServiceServer) DoBlock(ctx context.Context, req *executionv1.D func (s *ExecutionServiceServer) InitState(ctx context.Context, req *executionv1.InitStateRequest) (*executionv1.InitStateResponse, error) { currHead := s.eth.BlockChain().CurrentHeader() res := &executionv1.InitStateResponse{ + // TODO: RENAME THIS - this is not the state root!! it's the block hash StateRoot: currHead.Hash().Bytes(), } diff --git a/private_network.md b/private_network.md index 9d5b57391ec..f1af315b12f 100644 --- a/private_network.md +++ b/private_network.md @@ -1,5 +1,6 @@ # 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: @@ -13,10 +14,12 @@ To run without mining (ie. using the conductor): ./build/bin/geth --datadir ~/.astriageth/ --http --http.port=8545 --ws --ws.port=8545 --networkid=1337 --http.corsdomain='*' --ws.origins='*' --miner.threads 1 --miner.etherbase=0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102 --grpc --grpc.addr=localhost --grpc.port 50051 ``` -To run with mining: -Replace the etherbase in the following with your account (it doesn't really matter though, since mining doesn't require signing). Then, +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 ``` - -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. \ No newline at end of file From 66442db5dff74a6b7ab6a702990b83656881bc2d Mon Sep 17 00:00:00 2001 From: elizabeth Date: Tue, 4 Apr 2023 19:16:29 -0400 Subject: [PATCH 13/21] cleanup --- consensus/ethash/consensus.go | 2 +- grpc/README.md | 5 ++--- miner/worker.go | 26 -------------------------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index a949522d856..481fe28b7de 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -537,7 +537,7 @@ func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *type return ethash.shared.verifySeal(chain, header, fulldag) } // Ensure that we have a valid difficulty for the block - if header.Difficulty.Sign() < 0 { + if header.Difficulty.Sign() <= 0 { return errInvalidDifficulty } // Recompute the digest and PoW values diff --git a/grpc/README.md b/grpc/README.md index 855fa0e22d5..666fe69c508 100644 --- a/grpc/README.md +++ b/grpc/README.md @@ -10,11 +10,10 @@ make geth # generating protobuf files buf generate buf.build/astria/execution-apis - -# run geth -./build/bin/geth --goerli --grpc --grpc.addr "0.0.0.0" --grpc.port 50051 ``` +See [private_network.md](../private_network.md) for running a local geth node. + ### Running with remote Docker image: ```bash docker run --rm \ diff --git a/miner/worker.go b/miner/worker.go index 27b445e7622..5baf69aeae5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1158,32 +1158,6 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment) error { } } w.eth.TxPool().ClearAstriaOrdered() - - // Original Geth Code - if false { - // Split the pending transactions into locals and remotes - // Fill the block with all available pending transactions. - pending := w.eth.TxPool().Pending(true) - localTxs, remoteTxs := make(map[common.Address]types.Transactions), pending - for _, account := range w.eth.TxPool().Locals() { - if txs := remoteTxs[account]; len(txs) > 0 { - delete(remoteTxs, account) - localTxs[account] = txs - } - } - if len(localTxs) > 0 { - txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee) - if err := w.commitTransactions(env, txs, interrupt); err != nil { - return err - } - } - if len(remoteTxs) > 0 { - txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee) - if err := w.commitTransactions(env, txs, interrupt); err != nil { - return err - } - } - } return nil } From 5628ee423dd601efbc913cd2ff32b230bb0aa8b3 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Wed, 5 Apr 2023 17:36:16 -0400 Subject: [PATCH 14/21] doc update --- private_network.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/private_network.md b/private_network.md index f1af315b12f..7da7a2768f6 100644 --- a/private_network.md +++ b/private_network.md @@ -11,7 +11,7 @@ make geth 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='*' --miner.threads 1 --miner.etherbase=0x46B77EFDFB20979E1C29ec98DcE73e3eCbF64102 --grpc --grpc.addr=localhost --grpc.port 50051 +./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. From a76e673b3f1b8fb5d8994dd9fde33057bd149b19 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Wed, 5 Apr 2023 17:42:01 -0400 Subject: [PATCH 15/21] remove txpool interface changes --- eth/backend.go | 2 +- les/server.go | 4 ++-- les/server_handler.go | 8 ++++---- les/server_requests.go | 3 +-- miner/miner.go | 23 +---------------------- 5 files changed, 9 insertions(+), 31 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index c1c30d21cd5..c0cda7de483 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -62,7 +62,7 @@ import ( // Deprecated: use ethconfig.Config instead. type Config = ethconfig.Config -type TxPool = miner.TxPool +type TxPool = *txpool.TxPool // Ethereum implements the Ethereum full node service. type Ethereum struct { diff --git a/les/server.go b/les/server.go index ca3ebb2308c..06bbc30fb0d 100644 --- a/les/server.go +++ b/les/server.go @@ -22,13 +22,13 @@ import ( "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/les/flowcontrol" vfs "github.com/ethereum/go-ethereum/les/vflux/server" "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" @@ -50,7 +50,7 @@ type ethBackend interface { BloomIndexer() *core.ChainIndexer ChainDb() ethdb.Database Synced() bool - TxPool() miner.TxPool + TxPool() *txpool.TxPool } type LesServer struct { diff --git a/les/server_handler.go b/les/server_handler.go index 5553493d813..2ea496ac2c3 100644 --- a/les/server_handler.go +++ b/les/server_handler.go @@ -27,13 +27,13 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/les/flowcontrol" "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" @@ -63,7 +63,7 @@ type serverHandler struct { forkFilter forkid.Filter blockchain *core.BlockChain chainDb ethdb.Database - txpool miner.TxPool + txpool *txpool.TxPool server *LesServer closeCh chan struct{} // Channel used to exit all background routines of handler. @@ -74,7 +74,7 @@ type serverHandler struct { addTxsSync bool } -func newServerHandler(server *LesServer, blockchain *core.BlockChain, chainDb ethdb.Database, txpool miner.TxPool, synced func() bool) *serverHandler { +func newServerHandler(server *LesServer, blockchain *core.BlockChain, chainDb ethdb.Database, txpool *txpool.TxPool, synced func() bool) *serverHandler { handler := &serverHandler{ forkFilter: forkid.NewFilter(blockchain), server: server, @@ -344,7 +344,7 @@ func (h *serverHandler) BlockChain() *core.BlockChain { } // TxPool implements serverBackend -func (h *serverHandler) TxPool() miner.TxPool { +func (h *serverHandler) TxPool() *txpool.TxPool { return h.txpool } diff --git a/les/server_requests.go b/les/server_requests.go index 4ac52f79788..033b11d7937 100644 --- a/les/server_requests.go +++ b/les/server_requests.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/light" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" ) @@ -38,7 +37,7 @@ type serverBackend interface { ArchiveMode() bool AddTxsSync() bool BlockChain() *core.BlockChain - TxPool() miner.TxPool + TxPool() *txpool.TxPool GetHelperTrie(typ uint, index uint64) *trie.Trie } diff --git a/miner/miner.go b/miner/miner.go index e0acbbc8421..c969aec7354 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -36,32 +36,11 @@ import ( "github.com/ethereum/go-ethereum/params" ) -type TxPool interface { - AddRemotes(txs []*types.Transaction) []error - AddLocal(tx *types.Transaction) error - Pending(enforceTips bool) map[common.Address]types.Transactions - Get(hash common.Hash) *types.Transaction - Nonce(addr common.Address) uint64 - Stats() (int, int) - SetGasPrice(price *big.Int) - Has(hash common.Hash) bool - SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription - Stop() - Content() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) - ContentFrom(addr common.Address) (types.Transactions, types.Transactions) - AstriaOrdered() *types.Transactions - ClearAstriaOrdered() - SetAstriaOrdered(rawTxs [][]byte) - AddRemotesSync(txs []*types.Transaction) []error - Locals() []common.Address - Status(hashes []common.Hash) []txpool.TxStatus -} - // Backend wraps all methods required for mining. Only full node is capable // to offer all the functions here. type Backend interface { BlockChain() *core.BlockChain - TxPool() TxPool + TxPool() *txpool.TxPool } // Config is the configuration parameters of mining. From b917991dbcaa3adc1e41c4c0731e3e76e484cc24 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Wed, 5 Apr 2023 17:43:08 -0400 Subject: [PATCH 16/21] cleanup --- core/txpool/txpool.go | 1 - 1 file changed, 1 deletion(-) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index b9c13ebe0e7..8597f6190f6 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -310,7 +310,6 @@ func NewTxPool(config Config, chainconfig *params.ChainConfig, chain blockChain) reorgShutdownCh: make(chan struct{}), initDoneCh: make(chan struct{}), gasPrice: new(big.Int).SetUint64(config.PriceLimit), - //astriaOrdered: newAstriaOrdered(), } pool.locals = newAccountSet(pool.signer) for _, addr := range config.Locals { From a03dc52aa324466ba9e79e2aab34c9cfb3374510 Mon Sep 17 00:00:00 2001 From: elizabeth Date: Wed, 5 Apr 2023 17:45:00 -0400 Subject: [PATCH 17/21] cleanup --- eth/api_backend.go | 3 ++- eth/backend.go | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/eth/api_backend.go b/eth/api_backend.go index 55562c3b745..ac160b0736a 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/gasprice" @@ -310,7 +311,7 @@ func (b *EthAPIBackend) TxPoolContentFrom(addr common.Address) (types.Transactio return b.eth.TxPool().ContentFrom(addr) } -func (b *EthAPIBackend) TxPool() TxPool { +func (b *EthAPIBackend) TxPool() *txpool.TxPool { return b.eth.TxPool() } diff --git a/eth/backend.go b/eth/backend.go index c0cda7de483..6368c0e03c5 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -62,14 +62,12 @@ import ( // Deprecated: use ethconfig.Config instead. type Config = ethconfig.Config -type TxPool = *txpool.TxPool - // Ethereum implements the Ethereum full node service. type Ethereum struct { config *ethconfig.Config // Handlers - txPool TxPool + txPool *txpool.TxPool blockchain *core.BlockChain handler *handler ethDialCandidates enode.Iterator @@ -470,7 +468,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } -func (s *Ethereum) TxPool() TxPool { return s.txPool } +func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } From 2ad53de672cc2ee2ab11f6cb286cf470486158e0 Mon Sep 17 00:00:00 2001 From: Jesse Snyder Date: Mon, 10 Apr 2023 10:25:33 -0500 Subject: [PATCH 18/21] build and push images wih tags defined by git tags --- .../astria-build-and-publish-image.yml | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/.github/workflows/astria-build-and-publish-image.yml b/.github/workflows/astria-build-and-publish-image.yml index 24d0c582139..ea29a06abe0 100644 --- a/.github/workflows/astria-build-and-publish-image.yml +++ b/.github/workflows/astria-build-and-publish-image.yml @@ -1,9 +1,21 @@ 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 # Running this job only for astria branch + - "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 @@ -14,6 +26,20 @@ jobs: go-version: "^1.20.x" # The Go version to download (if necessary) and use. - run: go version + - name: Set image tag + id: set-image-tag + run: | + if [[ $GITHUB_REF == refs/tags/* ]]; then + TAG=${GITHUB_REF#refs/tags/} + elif [[ $GITHUB_REF == refs/heads/* ]]; then + TAG=latest + elif [[ $GITHUB_REF == refs/pull/* ]]; then + TAG=${GITHUB_SHA} + else + TAG=unrecognized + fi + echo "::set-output name=tag::$TAG" + - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin @@ -25,6 +51,6 @@ jobs: --build-arg COMMIT=${GITHUB_SHA} \ --build-arg VERSION=0.1 \ --build-arg BUILDNUM=${GITHUB_RUN_NUMBER} \ - --tag ghcr.io/astriaorg/go-ethereum:latest . + --tag ghcr.io/astriaorg/go-ethereum:${{ steps.set-image-tag.outputs.tag }} . - name: Push latest Docker image - run: docker push ghcr.io/astriaorg/go-ethereum:latest + run: docker push ghcr.io/astriaorg/go-ethereum:${{ steps.set-image-tag.outputs.tag }} From fd64549de141c4195990708009ba96bc71e6681b Mon Sep 17 00:00:00 2001 From: Jesse Snyder Date: Mon, 10 Apr 2023 10:43:14 -0500 Subject: [PATCH 19/21] build for multiple architectures. use docker-metadata action for semver --- .../astria-build-and-publish-image.yml | 55 ++++++++++--------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/.github/workflows/astria-build-and-publish-image.yml b/.github/workflows/astria-build-and-publish-image.yml index ea29a06abe0..774a6536519 100644 --- a/.github/workflows/astria-build-and-publish-image.yml +++ b/.github/workflows/astria-build-and-publish-image.yml @@ -20,37 +20,38 @@ jobs: build-and-publish-latest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 # Checking out the repo + # Checking out the repo + - uses: actions/checkout@v2 + # 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 - - name: Set image tag - id: set-image-tag - run: | - if [[ $GITHUB_REF == refs/tags/* ]]; then - TAG=${GITHUB_REF#refs/tags/} - elif [[ $GITHUB_REF == refs/heads/* ]]; then - TAG=latest - elif [[ $GITHUB_REF == refs/pull/* ]]; then - TAG=${GITHUB_SHA} - else - TAG=unrecognized - fi - echo "::set-output name=tag::$TAG" - + # https://github.com/docker/setup-qemu-action + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 - name: Log in to registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin - - # TODO - build for amd64 and arm64? - # FIXME - version needs to be autoincrement, probably from git tags? - - name: Build latest Docker image - run: | - docker build \ - --build-arg COMMIT=${GITHUB_SHA} \ - --build-arg VERSION=0.1 \ - --build-arg BUILDNUM=${GITHUB_RUN_NUMBER} \ - --tag ghcr.io/astriaorg/go-ethereum:${{ steps.set-image-tag.outputs.tag }} . - - name: Push latest Docker image - run: docker push ghcr.io/astriaorg/go-ethereum:${{ steps.set-image-tag.outputs.tag }} + # 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 + - name: Build and push + uses: docker/build-push-action@v2 + with: + context: . + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} From ce743f228eb6e69cce6375557e18af8f16b11c93 Mon Sep 17 00:00:00 2001 From: Jesse Snyder Date: Mon, 10 Apr 2023 11:22:28 -0500 Subject: [PATCH 20/21] add push: true --- .github/workflows/astria-build-and-publish-image.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/astria-build-and-publish-image.yml b/.github/workflows/astria-build-and-publish-image.yml index 774a6536519..422c3d5dcc7 100644 --- a/.github/workflows/astria-build-and-publish-image.yml +++ b/.github/workflows/astria-build-and-publish-image.yml @@ -53,5 +53,6 @@ jobs: with: context: . platforms: linux/amd64,linux/arm64 + push: true tags: ${{ steps.metadata.outputs.tags }} labels: ${{ steps.metadata.outputs.labels }} From bc1f02cfaca000f079d89344baf67823c1625102 Mon Sep 17 00:00:00 2001 From: Jesse Snyder Date: Mon, 10 Apr 2023 12:15:59 -0500 Subject: [PATCH 21/21] only build arm for git tags/releases --- .github/workflows/astria-build-and-publish-image.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/astria-build-and-publish-image.yml b/.github/workflows/astria-build-and-publish-image.yml index 422c3d5dcc7..374702c8522 100644 --- a/.github/workflows/astria-build-and-publish-image.yml +++ b/.github/workflows/astria-build-and-publish-image.yml @@ -52,7 +52,8 @@ jobs: uses: docker/build-push-action@v2 with: context: . - platforms: linux/amd64,linux/arm64 + # It takes over 30 minutes to build the arm image right now, so we only build it on tags which is what we use for releases. + platforms: ${{ contains(github.ref, 'refs/tags/v') && 'linux/amd64,linux/arm64' || 'linux/amd64' }} push: true tags: ${{ steps.metadata.outputs.tags }} labels: ${{ steps.metadata.outputs.labels }}