From ce238cad7148f632dc630e4f1d8d805a4e37399f Mon Sep 17 00:00:00 2001 From: ImJeremyHe Date: Tue, 7 Nov 2023 16:00:17 +0800 Subject: [PATCH] Forwarding Tx --- .gitmodules | 2 +- arbnode/node.go | 6 ++- espresso/client.go | 64 +++++++++++++++++++++--- execution/gethexec/espresso_sequencer.go | 13 +++-- nitro-testnode | 2 +- 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/.gitmodules b/.gitmodules index cdc2690376..7c0825d089 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,7 +20,7 @@ [submodule "nitro-testnode"] path = nitro-testnode url = https://github.com/EspressoSystems/nitro-testnode - branch = integration + branch = integration [submodule "espresso-sequencer"] path = espresso-sequencer url = https://github.com/EspressoSystems/espresso-sequencer.git diff --git a/arbnode/node.go b/arbnode/node.go index 4fbfaf4bb2..52bdf8ce92 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -281,6 +281,7 @@ func DeployOnL1(ctx context.Context, parentChainReader *headerreader.HeaderReade type Config struct { Sequencer bool `koanf:"sequencer"` + Espresso bool `koanf:"espresso"` ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"` InboxReader InboxReaderConfig `koanf:"inbox-reader" reload:"hot"` DelayedSequencer DelayedSequencerConfig `koanf:"delayed-sequencer" reload:"hot"` @@ -299,6 +300,9 @@ type Config struct { } func (c *Config) Validate() error { + if c.Espresso && !c.Sequencer { + return errors.New("cannot enable espresso without enabling sequencer") + } if c.ParentChainReader.Enable && c.Sequencer && !c.DelayedSequencer.Enable { log.Warn("delayed sequencer is not enabled, despite sequencer and l1 reader being enabled") } @@ -620,7 +624,7 @@ func createNodeImpl( if err != nil { return nil, err } - } else if config.Sequencer && !config.Dangerous.NoSequencerCoordinator { + } else if config.Sequencer && !config.Dangerous.NoSequencerCoordinator && !config.Espresso { return nil, errors.New("sequencer must be enabled with coordinator, unless dangerous.no-sequencer-coordinator set") } dbs := []ethdb.Database{arbDb} diff --git a/espresso/client.go b/espresso/client.go index 5659af0b92..0286acdaf4 100644 --- a/espresso/client.go +++ b/espresso/client.go @@ -1,6 +1,7 @@ package espresso import ( + "bytes" "context" "encoding/json" "fmt" @@ -8,23 +9,26 @@ import ( "net/http" "strings" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" ) type Client struct { - baseUrl string - client *http.Client - log log.Logger + baseUrl string + client *http.Client + log log.Logger + namespace uint64 } -func NewClient(log log.Logger, url string) *Client { +func NewClient(log log.Logger, url string, namespace uint64) *Client { if !strings.HasSuffix(url, "/") { url += "/" } return &Client{ - baseUrl: url, - client: http.DefaultClient, - log: log, + baseUrl: url, + client: http.DefaultClient, + log: log, + namespace: namespace, } } @@ -52,8 +56,52 @@ func (c *Client) FetchHeader(ctx context.Context, blockHeight uint64) (Header, e return res, nil } -func (c *Client) FetchTransactionsInBlock(ctx context.Context, block uint64, header *Header, namespace uint64) (TransactionsInBlock, error) { +type RawTransaction struct { + Vm int `json:"vm"` + Payload []int8 `json:"payload"` +} + +func (c *Client) SubmitTransaction(ctx context.Context, tx *types.Transaction) error { + var txnBytes, err = json.Marshal(tx) + if err != nil { + return err + } + // json.RawMessage is a []byte array, which is marshalled as a base64-encoded string. + // Our sequencer API expects a JSON array. + payload := make([]int8, len(txnBytes)) + for i := range payload { + payload[i] = int8(txnBytes[i]) + } + txn := RawTransaction{ + Vm: int(c.namespace), + Payload: payload, + } + marshalled, err := json.Marshal(txn) + if err != nil { + return err + } + fmt.Println(c.baseUrl) + request, err := http.NewRequest("POST", c.baseUrl+"submit/submit", bytes.NewBuffer(marshalled)) + if err != nil { + return err + } + request.Header.Set("Content-Type", "application/json") + client := &http.Client{} + response, err := client.Do(request) + if err != nil { + return err + } + defer response.Body.Close() + if response.StatusCode != 200 { + return fmt.Errorf("receieved unexpected status code: %v", response.StatusCode) + } + return nil +} + +func (c *Client) FetchTransactionsInBlock(ctx context.Context, block uint64, header *Header) (TransactionsInBlock, error) { + namespace := c.namespace var res NamespaceResponse + log.Info(fmt.Sprintf("Fetching tx, block: %d, namespace: %d", block, namespace)) if err := c.get(ctx, &res, "availability/block/%d/namespace/%d", block, namespace); err != nil { return TransactionsInBlock{}, err } diff --git a/execution/gethexec/espresso_sequencer.go b/execution/gethexec/espresso_sequencer.go index 82f573d8af..1e7d48fd96 100644 --- a/execution/gethexec/espresso_sequencer.go +++ b/execution/gethexec/espresso_sequencer.go @@ -33,9 +33,9 @@ type HotShotState struct { nextSeqBlockNum uint64 } -func NewHotShotState(log log.Logger, url string) *HotShotState { +func NewHotShotState(log log.Logger, url string, namespace uint64) *HotShotState { return &HotShotState{ - client: *espresso.NewClient(log, url), + client: *espresso.NewClient(log, url, namespace), // TODO: Load this from the inbox reader so that new sequencers don't read redundant blocks // https://github.com/EspressoSystems/espresso-sequencer/issues/734 nextSeqBlockNum: 0, @@ -62,7 +62,7 @@ func NewEspressoSequencer(execEngine *ExecutionEngine, configFetcher SequencerCo return &EspressoSequencer{ execEngine: execEngine, config: configFetcher, - hotShotState: NewHotShotState(log.New(), config.HotShotUrl), + hotShotState: NewHotShotState(log.New(), config.HotShotUrl, config.EspressoNamespace), }, nil } @@ -80,12 +80,11 @@ func (s *EspressoSequencer) createBlock(ctx context.Context) (returnValue bool) nextSeqBlockNum := s.hotShotState.nextSeqBlockNum log.Info("Attempting to sequence Espresso block", "block_num", nextSeqBlockNum) header, err := s.hotShotState.client.FetchHeader(ctx, nextSeqBlockNum) - namespace := s.config().EspressoNamespace if err != nil { log.Warn("Unable to fetch header for block number, will retry", "block_num", nextSeqBlockNum) return false } - arbTxns, err := s.hotShotState.client.FetchTransactionsInBlock(ctx, nextSeqBlockNum, &header, namespace) + arbTxns, err := s.hotShotState.client.FetchTransactionsInBlock(ctx, nextSeqBlockNum, &header) if err != nil { log.Error("Error fetching transactions", "err", err) return false @@ -143,6 +142,10 @@ func (s *EspressoSequencer) Start(ctxIn context.Context) error { // Required methods for the TransactionPublisher interface func (s *EspressoSequencer) PublishTransaction(parentCtx context.Context, tx *types.Transaction, options *arbitrum_types.ConditionalOptions) error { + if err := s.hotShotState.client.SubmitTransaction(parentCtx, tx); err != nil { + log.Error("Failed to submit transaction", err) + return err + } return nil } diff --git a/nitro-testnode b/nitro-testnode index 179cf311b3..7c8b39a81b 160000 --- a/nitro-testnode +++ b/nitro-testnode @@ -1 +1 @@ -Subproject commit 179cf311b384f4e8b7e5bbb23306fd17630b41a2 +Subproject commit 7c8b39a81bda80f51c59adcd3e135f080b3c211d