Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/workflows/docker-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,26 @@ jobs:
EVM_IMAGE_REPO: ghcr.io/${{ github.repository_owner }}/ev-node-evm
EVM_NODE_IMAGE_TAG: ${{ inputs.image-tag }}

docker-signed-submit-evm-tests:
name: Docker Signed Submit EVM E2E Tests
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
- name: set up go
uses: actions/setup-go@v6.5.0
with:
go-version: "1.27.0"
cache-dependency-path: "**/go.sum"
- name: Install just
uses: extractions/setup-just@v4
Comment thread
damiannolan marked this conversation as resolved.
Dismissed
- name: Run Docker Signed Submit EVM E2E Tests
run: just test-docker-signed-submit-evm
env:
EVM_IMAGE_REPO: ghcr.io/${{ github.repository_owner }}/ev-node-evm
EVM_NODE_IMAGE_TAG: ${{ inputs.image-tag }}

test-docker-compat:
name: Docker Compatibility E2E Tests
permissions:
Expand Down
6 changes: 6 additions & 0 deletions .just/test.just
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ test-docker-upgrade-e2e:
@echo "--> Running Docker Upgrade E2E tests"
@cd test/docker-e2e && go test -mod=readonly -failfast -v -tags='docker_e2e evm' -timeout=30m -run '^TestEVMSingleUpgradeSuite$$/^TestEVMSingleUpgrade$$' ./...

# Run Docker E2E signed blob submission test against the evm binary and reth
[group('test')]
test-docker-signed-submit-evm:
@echo "--> Running Docker signed blob submission EVM E2E test"
@cd test/docker-e2e && go test -mod=readonly -failfast -v -tags='docker_e2e evm' -timeout=30m -run '^TestDockerSuite$$/^TestSignedBlobSubmissionEVM$$' ./...

# Run Docker E2E cross-version compatibility tests
[group('test')]
test-docker-compat:
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Client-side signed blob submission via the new `da/celestia` module: with `da.tx_signer.enabled`, `testapp` and `evm` sign PayForBlobs locally and broadcast them over consensus gRPC (`x-token` auth), so they can submit through DA endpoints that cannot sign, such as da-proxy. Off by default. `block.NewDAClient` and `pkg/cmd.StartNode` accept options (`block.WithSubmitter`) to inject a submitter; existing callers are unaffected.

### Fixed

- Prune per-height state snapshots in `all` pruning mode, keep the state needed to replay the oldest retained block, and stop pruning from falling behind when more than 10k blocks are produced per interval [#3469](https://github.com/evstack/ev-node/pull/3469).
Expand Down
2 changes: 1 addition & 1 deletion apps/evm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ If you'd ever like to restart a fresh node, make sure to remove the originally c

The EVM app includes a Force Inclusion API server that exposes an Ethereum-compatible JSON-RPC endpoint for submitting transactions directly to the DA layer for force inclusion.

When enabling this server, the node operator will be paying for the gas costs of the transactions submitted through the API on the DA layer. The application costs are still paid by the transaction signer.
When enabling this server, the node operator will be paying for the gas costs of the transactions submitted through the API on the DA layer. The application costs are still paid by the transaction signer. With `--evnode.da.tx_signer.enabled`, those submissions are signed with the `da.tx_signer` key on any node role, so the key must be funded.

### Enabling the Force Inclusion API

Expand Down
30 changes: 23 additions & 7 deletions apps/evm/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/evstack/ev-node/block"
"github.com/evstack/ev-node/core/execution"
coresequencer "github.com/evstack/ev-node/core/sequencer"
"github.com/evstack/ev-node/da/celestia"
"github.com/evstack/ev-node/execution/evm"
"github.com/evstack/ev-node/node"
rollcmd "github.com/evstack/ev-node/pkg/cmd"
Expand Down Expand Up @@ -59,14 +60,34 @@ var RunCmd = &cobra.Command{
return err
}

forceInclusionAddr, err := cmd.Flags().GetString(flagForceInclusionServer)
if err != nil {
return fmt.Errorf("failed to get '%s' flag: %w", flagForceInclusionServer, err)
}

// The force inclusion server submits to DA too, so it needs the signer on any node role.
var daOpts []block.DAClientOption
if nodeConfig.DA.TxSigner.Enabled && (nodeConfig.Node.Aggregator || nodeConfig.Node.Promotable || forceInclusionAddr != "") {
signerCfg, err := celestia.ConfigFromNode(nodeConfig)
if err != nil {
return err
}
submitter, err := celestia.New(cmd.Context(), signerCfg, logger)
if err != nil {
return fmt.Errorf("failed to create DA tx signer: %w", err)
}
defer submitter.Close()
daOpts = append(daOpts, block.WithSubmitter(submitter))
}

var daClient block.FullDAClient
if nodeConfig.DAEnabled() {
blobClient, err := blobrpc.NewWSClient(cmd.Context(), logger, nodeConfig.GetDAAddress(), nodeConfig.DA.AuthToken, "")
if err != nil {
return fmt.Errorf("failed to create blob client: %w", err)
}
defer blobClient.Close()
daClient = block.NewDAClient(blobClient, nodeConfig, logger)
daClient = block.NewDAClient(blobClient, nodeConfig, logger, daOpts...)
} else {
logger.Info().Msg("DA address is not configured; syncing through P2P only")
}
Expand Down Expand Up @@ -98,11 +119,6 @@ var RunCmd = &cobra.Command{
}

// Start force inclusion API server if address is provided
forceInclusionAddr, err := cmd.Flags().GetString(flagForceInclusionServer)
if err != nil {
return fmt.Errorf("failed to get '%s' flag: %w", flagForceInclusionServer, err)
}

if forceInclusionAddr != "" {
if daClient == nil {
return fmt.Errorf("force inclusion server requires a DA address")
Expand Down Expand Up @@ -139,7 +155,7 @@ var RunCmd = &cobra.Command{
}()
}

return rollcmd.StartNode(logger, cmd, executor, sequencer, nodeKey, datastore, nodeConfig, genesis, node.NodeOptions{})
return rollcmd.StartNode(logger, cmd, executor, sequencer, nodeKey, datastore, nodeConfig, genesis, node.NodeOptions{}, daOpts...)
},
}

Expand Down
Loading
Loading