diff --git a/Dockerfile b/Dockerfile index de15567131..0637ae9832 100644 --- a/Dockerfile +++ b/Dockerfile @@ -335,6 +335,7 @@ RUN rm -f /home/user/target/machines/latest COPY --from=prover-export /bin/jit /usr/local/bin/ COPY --from=node-builder /workspace/target/bin/deploy /usr/local/bin/ COPY --from=node-builder /workspace/target/bin/seq-coordinator-invalidate /usr/local/bin/ +COPY --from=node-builder /workspace/target/bin/mockexternalsigner /usr/local/bin/ COPY --from=module-root-calc /workspace/target/machines/latest/machine.wavm.br /home/user/target/machines/latest/ COPY --from=module-root-calc /workspace/target/machines/latest/until-host-io-state.bin /home/user/target/machines/latest/ COPY --from=module-root-calc /workspace/target/machines/latest/module-root.txt /home/user/target/machines/latest/ diff --git a/Makefile b/Makefile index f6dcc16140..2251b5f0e9 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ all: build build-replay-env test-gen-proofs @touch .make/all .PHONY: build -build: $(patsubst %,$(output_root)/bin/%, nitro deploy relay daserver autonomous-auctioneer bidder-client datool seq-coordinator-invalidate nitro-val seq-coordinator-manager dbconv) +build: $(patsubst %,$(output_root)/bin/%, nitro deploy relay daserver autonomous-auctioneer bidder-client datool mockexternalsigner seq-coordinator-invalidate nitro-val seq-coordinator-manager dbconv) @printf $(done) .PHONY: build-node-deps @@ -320,6 +320,9 @@ $(output_root)/bin/bidder-client: $(DEP_PREDICATE) build-node-deps $(output_root)/bin/datool: $(DEP_PREDICATE) build-node-deps go build $(GOLANG_PARAMS) -o $@ "$(CURDIR)/cmd/datool" +$(output_root)/bin/mockexternalsigner: $(DEP_PREDICATE) build-node-deps + go build $(GOLANG_PARAMS) -o $@ "$(CURDIR)/cmd/mockexternalsigner" + $(output_root)/bin/seq-coordinator-invalidate: $(DEP_PREDICATE) build-node-deps go build $(GOLANG_PARAMS) -o $@ "$(CURDIR)/cmd/seq-coordinator-invalidate" diff --git a/arbnode/dataposter/data_poster.go b/arbnode/dataposter/data_poster.go index a977b9fc08..5accd6312d 100644 --- a/arbnode/dataposter/data_poster.go +++ b/arbnode/dataposter/data_poster.go @@ -41,6 +41,7 @@ import ( "github.com/ethereum/go-ethereum/signer/core/apitypes" "github.com/offchainlabs/nitro/arbnode/dataposter/dbstorage" + "github.com/offchainlabs/nitro/arbnode/dataposter/externalsignertest" "github.com/offchainlabs/nitro/arbnode/dataposter/noop" redisstorage "github.com/offchainlabs/nitro/arbnode/dataposter/redis" "github.com/offchainlabs/nitro/arbnode/dataposter/slice" @@ -1297,6 +1298,21 @@ type ExternalSignerCfg struct { InsecureSkipVerify bool `koanf:"insecure-skip-verify"` } +func ExternalSignerTestCfg(addr common.Address, url string) (*ExternalSignerCfg, error) { + cp, err := externalsignertest.CertPaths() + if err != nil { + return nil, fmt.Errorf("getting certificates path: %w", err) + } + return &ExternalSignerCfg{ + Address: common.Bytes2Hex(addr.Bytes()), + URL: url, + Method: externalsignertest.SignerMethod, + RootCA: cp.ServerCert, + ClientCert: cp.ClientCert, + ClientPrivateKey: cp.ClientKey, + }, nil +} + type DangerousConfig struct { // This should be used with caution, only when dataposter somehow gets in a // bad state and we require clearing it. diff --git a/arbnode/dataposter/dataposter_test.go b/arbnode/dataposter/dataposter_test.go index dc5df1a6c4..83401b2484 100644 --- a/arbnode/dataposter/dataposter_test.go +++ b/arbnode/dataposter/dataposter_test.go @@ -3,7 +3,6 @@ package dataposter import ( "context" "errors" - "fmt" "math/big" "testing" "time" @@ -25,21 +24,6 @@ import ( "github.com/offchainlabs/nitro/util/arbmath" ) -func signerTestCfg(addr common.Address, url string) (*ExternalSignerCfg, error) { - cp, err := externalsignertest.CertPaths() - if err != nil { - return nil, fmt.Errorf("getting certificates path: %w", err) - } - return &ExternalSignerCfg{ - Address: common.Bytes2Hex(addr.Bytes()), - URL: url, - Method: externalsignertest.SignerMethod, - RootCA: cp.ServerCert, - ClientCert: cp.ClientCert, - ClientPrivateKey: cp.ClientKey, - }, nil -} - var ( blobTx = types.NewTx( &types.BlobTx{ @@ -80,7 +64,7 @@ func TestExternalSigner(t *testing.T) { return } }() - signerCfg, err := signerTestCfg(srv.Address, srv.URL()) + signerCfg, err := ExternalSignerTestCfg(srv.Address, srv.URL()) if err != nil { t.Fatalf("Error getting signer test config: %v", err) } diff --git a/arbnode/dataposter/externalsignertest/externalsignertest.go b/arbnode/dataposter/externalsignertest/externalsignertest.go index 51ccec1903..c71a36fc91 100644 --- a/arbnode/dataposter/externalsignertest/externalsignertest.go +++ b/arbnode/dataposter/externalsignertest/externalsignertest.go @@ -42,7 +42,7 @@ type CertAbsPaths struct { type SignerServer struct { *http.Server *SignerAPI - listener net.Listener + Listener net.Listener } func basePath() (string, error) { @@ -147,7 +147,7 @@ func (s *SignerServer) Start() error { if err != nil { return err } - if err := s.ServeTLS(s.listener, cp.ServerCert, cp.ServerKey); err != nil && !errors.Is(err, http.ErrServerClosed) { + if err := s.ServeTLS(s.Listener, cp.ServerCert, cp.ServerKey); err != nil && !errors.Is(err, http.ErrServerClosed) { return err } return nil diff --git a/cmd/datool/datool.go b/cmd/datool/datool.go index 67998880e0..14c89979fd 100644 --- a/cmd/datool/datool.go +++ b/cmd/datool/datool.go @@ -100,7 +100,7 @@ func parseClientStoreConfig(args []string) (*ClientStoreConfig, error) { f.String("url", "", "URL of DAS server to connect to") f.String("message", "", "message to send") f.Int("random-message-size", 0, "send a message of a specified number of random bytes") - f.String("signing-key", "", "ecdsa private key to sign the message with, treated as a hex string if prefixed with 0x otherise treated as a file; if not specified the message is not signed") + f.String("signing-key", "", "ecdsa private key to sign the message with, treated as a hex string if prefixed with 0x otherwise treated as a file; if not specified the message is not signed") f.String("signing-wallet", "", "wallet containing ecdsa key to sign the message with") f.String("signing-wallet-password", genericconf.PASSWORD_NOT_SET, "password to unlock the wallet, if not specified the user is prompted for the password") f.Duration("das-retention-period", 24*time.Hour, "The period which DASes are requested to retain the stored batches.") diff --git a/cmd/mockexternalsigner/mockexternalsigner.go b/cmd/mockexternalsigner/mockexternalsigner.go new file mode 100644 index 0000000000..4678d586ef --- /dev/null +++ b/cmd/mockexternalsigner/mockexternalsigner.go @@ -0,0 +1,98 @@ +package main + +import ( + "crypto/tls" + "crypto/x509" + "math/big" + "net/http" + "os" + "time" + + "github.com/ethereum/go-ethereum/rpc" + + "github.com/offchainlabs/nitro/arbnode/dataposter" + "github.com/offchainlabs/nitro/arbnode/dataposter/externalsignertest" + "github.com/offchainlabs/nitro/cmd/genericconf" + "github.com/offchainlabs/nitro/cmd/util" + "github.com/offchainlabs/nitro/util/testhelpers" +) + +func main() { + args := os.Args + if len(args) != 2 { + panic("Usage: mockexternalsigner [private_key]") + } + srv, err := NewServer(args[1]) + if err != nil { + panic(err) + } + go func() { + if err := srv.Start(); err != nil { + panic(err) + } + }() + signerCfg, err := dataposter.ExternalSignerTestCfg(srv.Address, srv.URL()) + if err != nil { + panic(err) + } + print(" --externalSignerUrl " + signerCfg.URL) + print(" --externalSignerAddress " + signerCfg.Address) + print(" --externalSignerMethod " + signerCfg.Method) + print(" --externalSignerRootCA " + signerCfg.RootCA) + print(" --externalSignerClientCert " + signerCfg.ClientCert) + print(" --externalSignerClientPrivateKey " + signerCfg.ClientPrivateKey) + if signerCfg.InsecureSkipVerify { + print(" --externalSignerInsecureSkipVerify ") + } +} + +func NewServer(privateKey string) (*externalsignertest.SignerServer, error) { + rpcServer := rpc.NewServer() + txOpts, _, err := util.OpenWallet( + "mockexternalsigner", + &genericconf.WalletConfig{PrivateKey: privateKey}, + big.NewInt(1337), + ) + if err != nil { + return nil, err + } + s := &externalsignertest.SignerAPI{SignerFn: txOpts.Signer, Address: txOpts.From} + if err := rpcServer.RegisterName("test", s); err != nil { + return nil, err + } + cp, err := externalsignertest.CertPaths() + if err != nil { + return nil, err + } + clientCert, err := os.ReadFile(cp.ClientCert) + if err != nil { + return nil, err + } + pool := x509.NewCertPool() + pool.AppendCertsFromPEM(clientCert) + + ln, err := testhelpers.FreeTCPPortListener() + if err != nil { + return nil, err + } + + httpServer := &http.Server{ + Addr: ln.Addr().String(), + Handler: rpcServer, + ReadTimeout: 30 * time.Second, + ReadHeaderTimeout: 30 * time.Second, + WriteTimeout: 30 * time.Second, + IdleTimeout: 120 * time.Second, + TLSConfig: &tls.Config{ + MinVersion: tls.VersionTLS12, + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: pool, + }, + } + + return &externalsignertest.SignerServer{ + Server: httpServer, + SignerAPI: s, + Listener: ln, + }, nil +} diff --git a/execution/nodeInterface/NodeInterface.go b/execution/nodeInterface/NodeInterface.go index 20282f8231..189640d5d1 100644 --- a/execution/nodeInterface/NodeInterface.go +++ b/execution/nodeInterface/NodeInterface.go @@ -405,7 +405,7 @@ func (n NodeInterface) ConstructOutboxProof(c ctx, evm mech, size, leaf uint64) if !balanced { // This tree isn't balanced, so we'll need to use the partials to recover the missing info. - // To do this, we'll walk the boundry of what's known, computing hashes along the way + // To do this, we'll walk the boundary of what's known, computing hashes along the way step := *minPartialPlace step.Leaf += 1 << step.Level // we start on the min partial's zero-hash sibling diff --git a/relay/relay_stress_test.go b/relay/relay_stress_test.go index 93ba510193..e2cff07341 100644 --- a/relay/relay_stress_test.go +++ b/relay/relay_stress_test.go @@ -93,7 +93,7 @@ func (ts *dummyTxStreamer) AddBroadcastMessages(feedMessages []*message.Broadcas time.Sleep(50 * time.Millisecond) if !ts.logConnection { ts.logConnection = true - log.Info("test client is succesfully receiving messages", "client_Id", ts.id, "msg_size", feedMessages[0].Size()) + log.Info("test client is successfully receiving messages", "client_Id", ts.id, "msg_size", feedMessages[0].Size()) } return nil } diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index ee0c3b4a3a..fe2fa2df1d 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -64,21 +64,6 @@ func addNewBatchPoster(ctx context.Context, t *testing.T, builder *NodeBuilder, } } -func externalSignerTestCfg(addr common.Address, url string) (*dataposter.ExternalSignerCfg, error) { - cp, err := externalsignertest.CertPaths() - if err != nil { - return nil, fmt.Errorf("getting certificates path: %w", err) - } - return &dataposter.ExternalSignerCfg{ - Address: common.Bytes2Hex(addr.Bytes()), - URL: url, - Method: externalsignertest.SignerMethod, - RootCA: cp.ServerCert, - ClientCert: cp.ClientCert, - ClientPrivateKey: cp.ClientKey, - }, nil -} - func testBatchPosterParallel(t *testing.T, useRedis bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -105,7 +90,7 @@ func testBatchPosterParallel(t *testing.T, useRedis bool) { builder := NewNodeBuilder(ctx).DefaultConfig(t, true) builder.nodeConfig.BatchPoster.Enable = false builder.nodeConfig.BatchPoster.RedisUrl = redisUrl - signerCfg, err := externalSignerTestCfg(srv.Address, srv.URL()) + signerCfg, err := dataposter.ExternalSignerTestCfg(srv.Address, srv.URL()) if err != nil { t.Fatalf("Error getting external signer config: %v", err) } diff --git a/system_tests/fast_confirm_test.go b/system_tests/fast_confirm_test.go index 8eb71bffd4..384e9649c6 100644 --- a/system_tests/fast_confirm_test.go +++ b/system_tests/fast_confirm_test.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/arbnode/dataposter" "github.com/offchainlabs/nitro/arbnode/dataposter/externalsignertest" "github.com/offchainlabs/nitro/arbnode/dataposter/storage" "github.com/offchainlabs/nitro/arbos/l2pricing" @@ -174,7 +175,7 @@ func TestFastConfirmation(t *testing.T) { err = stakerA.Initialize(ctx) Require(t, err) cfg := arbnode.ConfigDefaultL1NonSequencerTest() - signerCfg, err := externalSignerTestCfg(srv.Address, srv.URL()) + signerCfg, err := dataposter.ExternalSignerTestCfg(srv.Address, srv.URL()) if err != nil { t.Fatalf("Error getting external signer config: %v", err) } @@ -375,7 +376,7 @@ func TestFastConfirmationWithSafe(t *testing.T) { err = stakerA.Initialize(ctx) Require(t, err) cfg := arbnode.ConfigDefaultL1NonSequencerTest() - signerCfg, err := externalSignerTestCfg(srv.Address, srv.URL()) + signerCfg, err := dataposter.ExternalSignerTestCfg(srv.Address, srv.URL()) if err != nil { t.Fatalf("Error getting external signer config: %v", err) } diff --git a/system_tests/outbox_test.go b/system_tests/outbox_test.go index 10d1ebec42..2b3ff38da1 100644 --- a/system_tests/outbox_test.go +++ b/system_tests/outbox_test.go @@ -283,7 +283,7 @@ func TestOutboxProofs(t *testing.T) { if !balanced { // This tree isn't balanced, so we'll need to use the partials to recover the missing info. - // To do this, we'll walk the boundry of what's known, computing hashes along the way + // To do this, we'll walk the boundary of what's known, computing hashes along the way zero := common.Hash{} diff --git a/system_tests/seqinbox_test.go b/system_tests/seqinbox_test.go index e0da2d4f3f..a8a7ee1b2e 100644 --- a/system_tests/seqinbox_test.go +++ b/system_tests/seqinbox_test.go @@ -352,7 +352,7 @@ func testSequencerInboxReaderImpl(t *testing.T, validator bool) { AfterDelayedMessagesRead: 1, }) if diff := diffAccessList(accessed, *wantAL); diff != "" { - t.Errorf("Access list mistmatch:\n%s\n", diff) + t.Errorf("Access list mismatch:\n%s\n", diff) } if i%5 == 0 { tx, err = seqInbox.AddSequencerL2Batch(&seqOpts, big.NewInt(int64(len(blockStates))), batchData, big.NewInt(1), gasRefunderAddr, big.NewInt(0), big.NewInt(0)) diff --git a/system_tests/staker_test.go b/system_tests/staker_test.go index 55c13d664d..e0444055d9 100644 --- a/system_tests/staker_test.go +++ b/system_tests/staker_test.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbnode" + "github.com/offchainlabs/nitro/arbnode/dataposter" "github.com/offchainlabs/nitro/arbnode/dataposter/externalsignertest" "github.com/offchainlabs/nitro/arbnode/dataposter/storage" "github.com/offchainlabs/nitro/arbos/l2pricing" @@ -229,7 +230,7 @@ func stakerTestImpl(t *testing.T, faultyStaker bool, honestStakerInactive bool) } Require(t, err) cfg := arbnode.ConfigDefaultL1NonSequencerTest() - signerCfg, err := externalSignerTestCfg(srv.Address, srv.URL()) + signerCfg, err := dataposter.ExternalSignerTestCfg(srv.Address, srv.URL()) if err != nil { t.Fatalf("Error getting external signer config: %v", err) } diff --git a/validator/server_jit/spawner.go b/validator/server_jit/spawner.go index 91b1e818f0..476a0170a5 100644 --- a/validator/server_jit/spawner.go +++ b/validator/server_jit/spawner.go @@ -32,8 +32,8 @@ type JitSpawnerConfigFecher func() *JitSpawnerConfig var DefaultJitSpawnerConfig = JitSpawnerConfig{ Workers: 0, Cranelift: true, + WasmMemoryUsageLimit: 4294967296, // 2^32 WASM memory limit MaxExecutionTime: time.Minute * 10, - WasmMemoryUsageLimit: 4294967296, // 2^32 WASM memeory limit } func JitSpawnerConfigAddOptions(prefix string, f *flag.FlagSet) { @@ -87,7 +87,7 @@ func (v *JitSpawner) execute( ) (validator.GoGlobalState, error) { machine, err := v.machineLoader.GetMachine(ctx, moduleRoot) if err != nil { - return validator.GoGlobalState{}, fmt.Errorf("unabled to get WASM machine: %w", err) + return validator.GoGlobalState{}, fmt.Errorf("unable to get WASM machine: %w", err) } state, err := machine.prove(ctx, entry)