Skip to content

Commit ae9c27b

Browse files
authored
refactor(adapter): adapt signature payload provider for non aggregator (#221)
* refactor(adapter): extract block id creation * Update ev-node version and refactor cometcompat to adapter - Bump github.com/evstack/ev-node to v1.0.0-beta.2.0.20250821181753-974aa15383de - Move cometcompat helpers to adapter package and update imports - Remove cometcompat package and related files - Add providers.go to adapter for signature and validator hash providers - Refactor usage across codebase to use adapter package functions * typo + issue * latest commit * fix height 1 blockid * updates * linting * bump ev node * bump again * bump to main
1 parent 37999a2 commit ae9c27b

18 files changed

Lines changed: 304 additions & 227 deletions

.github/workflows/integration_test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
runs-on: ubuntu-latest
1717
timeout-minutes: 30
1818
env:
19-
EVNODE_VERSION: "v1.0.0-beta.2.0.20250818133040-d096a24e7052"
19+
EVNODE_VERSION: "v1.0.0-beta.2.0.20250901092248-017d6d45a621"
2020
IGNITE_VERSION: "v29.3.1"
2121
IGNITE_EVOLVE_APP_VERSION: "main" # use tagged when apps has tagged (blocked on things)
2222
EVOLVE_IMAGE_REPO: "evolve-gm"
@@ -59,7 +59,7 @@ jobs:
5959
timeout-minutes: 30
6060
env:
6161
DO_NOT_TRACK: true
62-
EVNODE_VERSION: "v1.0.0-beta.2.0.20250818133040-d096a24e7052"
62+
EVNODE_VERSION: "v1.0.0-beta.2.0.20250901092248-017d6d45a621"
6363
IGNITE_VERSION: "v29.3.1"
6464
IGNITE_EVOLVE_APP_VERSION: "main" # use tagged when apps has tagged (blocked on things)
6565
outputs:
@@ -266,7 +266,7 @@ jobs:
266266
GMD_HOME: ${{ needs.liveness.outputs.gmd_home }}
267267
HERMES_VERSION: "v1.13.1"
268268
GAIA_VERSION: "v25.1.0"
269-
EVNODE_VERSION: "v1.0.0-beta.2.0.20250818133040-d096a24e7052"
269+
EVNODE_VERSION: "v1.0.0-beta.2.0.20250901092248-017d6d45a621"
270270
EVNODE_DA_VERSION: "v1.0.0-beta.1"
271271
steps:
272272
- name: Set up Go

.github/workflows/migration_test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
timeout-minutes: 45
1414
env:
1515
DO_NOT_TRACK: true
16-
EVNODE_VERSION: "v1.0.0-beta.2.0.20250818133040-d096a24e7052"
16+
EVNODE_VERSION: "v1.0.0-beta.2.0.20250901092248-017d6d45a621"
1717
IGNITE_VERSION: "v29.3.1"
1818
IGNITE_EVOLVE_APP_VERSION: "main" # use tagged when apps has tagged (blocked on things)
1919
steps:

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ RUN apk add --no-cache \
77
bash
88

99
# Set environment variables
10-
ENV EVNODE_VERSION=v1.0.0-beta.2.0.20250818133040-d096a24e7052
10+
ENV EVNODE_VERSION=v1.0.0-beta.2.0.20250901092248-017d6d45a621
1111
ENV IGNITE_VERSION=v29.3.1
1212
ENV IGNITE_EVOLVE_APP_VERSION=main
1313

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ require (
2525
github.com/cosmos/cosmos-proto v1.0.0-beta.5
2626
github.com/cosmos/cosmos-sdk v0.50.14
2727
github.com/cosmos/gogoproto v1.7.0
28-
github.com/evstack/ev-node v1.0.0-beta.2.0.20250818133040-d096a24e7052
29-
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250818133040-d096a24e7052
30-
github.com/evstack/ev-node/da v0.0.0-20250818133040-d096a24e7052
31-
github.com/evstack/ev-node/sequencers/single v0.0.0-20250818133040-d096a24e7052
28+
github.com/evstack/ev-node v1.0.0-beta.2.0.20250901092248-017d6d45a621
29+
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250901092248-017d6d45a621
30+
github.com/evstack/ev-node/da v0.0.0-20250901092248-017d6d45a621
31+
github.com/evstack/ev-node/sequencers/single v0.0.0-20250901092248-017d6d45a621
3232
github.com/go-kit/kit v0.13.0
3333
github.com/golang/protobuf v1.5.4
3434
github.com/grpc-ecosystem/grpc-gateway v1.16.0

go.sum

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,14 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
290290
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
291291
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
292292
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
293-
github.com/evstack/ev-node v1.0.0-beta.2.0.20250818133040-d096a24e7052 h1:Fsu6gkxsANYfl/AgDEABDN7dmeEXCIcFSPgFKTHZEwA=
294-
github.com/evstack/ev-node v1.0.0-beta.2.0.20250818133040-d096a24e7052/go.mod h1:LEP7bA5MA8+khDuZWmJcg8K8KXQ5jJVLTSETggQbrV0=
295-
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250818133040-d096a24e7052 h1:FhMa6ZiUSPSq4EeQXAheS6+7vaOSika3eDgSQiTbMJk=
296-
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250818133040-d096a24e7052/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
297-
github.com/evstack/ev-node/da v0.0.0-20250818133040-d096a24e7052 h1:aHPY3amXzULbIn7M5lslwo3lz9w89gP04wbLNa/k/LI=
298-
github.com/evstack/ev-node/da v0.0.0-20250818133040-d096a24e7052/go.mod h1:ooBV3tAL2o9brFql9I4DKgoDP4BchF3aMrUDR4ARC/k=
299-
github.com/evstack/ev-node/sequencers/single v0.0.0-20250818133040-d096a24e7052 h1:PDM62mPdhXDkOU8RZkBbw7ALKVtXpvgZPYNjfJEwnQc=
300-
github.com/evstack/ev-node/sequencers/single v0.0.0-20250818133040-d096a24e7052/go.mod h1:ll3+DmIF9X5mgyNhT/BaMZBVkS9bPDaq7tWHCqwtdkA=
293+
github.com/evstack/ev-node v1.0.0-beta.2.0.20250901092248-017d6d45a621 h1:c3CM78SnNlQoYqzzYaUTpBAR/FK7JDfS0gd9fTRGe2E=
294+
github.com/evstack/ev-node v1.0.0-beta.2.0.20250901092248-017d6d45a621/go.mod h1:jY/c+EkBt8G8srFBTpKuHrxioLYNLgDn1lFMktITA5Q=
295+
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250901092248-017d6d45a621 h1:BXfwY70MP9Amivmcs8bWeXZzmOx8dE6Re9jbsKv+YbI=
296+
github.com/evstack/ev-node/core v1.0.0-beta.1.0.20250901092248-017d6d45a621/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY=
297+
github.com/evstack/ev-node/da v0.0.0-20250901092248-017d6d45a621 h1:nuv0sVhGhjkoF50iKGfi56XwkvlqcKKW1l19MG1Y3LA=
298+
github.com/evstack/ev-node/da v0.0.0-20250901092248-017d6d45a621/go.mod h1:ooBV3tAL2o9brFql9I4DKgoDP4BchF3aMrUDR4ARC/k=
299+
github.com/evstack/ev-node/sequencers/single v0.0.0-20250901092248-017d6d45a621 h1:WvaJVarlm+UQXclO86Fl/xMldJrquIGH6SBR6Fsapng=
300+
github.com/evstack/ev-node/sequencers/single v0.0.0-20250901092248-017d6d45a621/go.mod h1:I9phdwpqEQjkvZVnhf3dvh4wozbiZ2BLY3cwCFxzT08=
301301
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
302302
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
303303
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=

pkg/adapter/adapter.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
rstore "github.com/evstack/ev-node/pkg/store"
3232
"github.com/evstack/ev-node/types"
3333

34-
"github.com/evstack/ev-abci/pkg/cometcompat"
3534
"github.com/evstack/ev-abci/pkg/p2p"
3635
execstore "github.com/evstack/ev-abci/pkg/store"
3736
)
@@ -326,11 +325,21 @@ func (a *Adapter) ExecuteTxs(
326325
return nil, 0, fmt.Errorf("get last commit: %w", err)
327326
}
328327

329-
abciHeader, err := cometcompat.ToABCIHeader(header, lastCommit)
328+
abciHeader, err := ToABCIHeader(header, lastCommit)
330329
if err != nil {
331330
return nil, 0, fmt.Errorf("compute header hash: %w", err)
332331
}
333332

333+
cmtTxs := make(cmttypes.Txs, len(txs))
334+
for i := range txs {
335+
cmtTxs[i] = txs[i]
336+
}
337+
338+
abciBlock, currentBlockID, err := MakeABCIBlock(blockHeight, cmtTxs, s, abciHeader, lastCommit)
339+
if err != nil {
340+
return nil, 0, err
341+
}
342+
334343
ppResp, err := a.App.ProcessProposal(&abci.RequestProcessProposal{
335344
Hash: abciHeader.Hash(),
336345
Height: int64(blockHeight),
@@ -448,26 +457,10 @@ func (a *Adapter) ExecuteTxs(
448457
if err != nil {
449458
return nil, 0, err
450459
}
451-
cmtTxs := make(cmttypes.Txs, len(txs))
452-
for i := range txs {
453-
cmtTxs[i] = txs[i]
454-
}
455-
456-
abciBlock := s.MakeBlock(int64(blockHeight), cmtTxs, lastCommit, nil, s.Validators.Proposer.Address)
457460

458-
blockParts, err := abciBlock.MakePartSet(cmttypes.BlockPartSizeBytes)
459-
if err != nil {
460-
return nil, 0, fmt.Errorf("make part set: %w", err)
461-
}
462-
463-
// use abci header hash to match the light client validation check
464-
// where sh.Header.Hash() (comet header) must equal sh.Commit.BlockID.Hash
465-
currentBlockID := cmttypes.BlockID{
466-
Hash: abciHeader.Hash(),
467-
PartSetHeader: blockParts.Header(),
468-
}
461+
// saving data to ev-abci store
469462

470-
if err := a.Store.SaveBlockID(ctx, blockHeight, &currentBlockID); err != nil {
463+
if err := a.Store.SaveBlockID(ctx, blockHeight, currentBlockID); err != nil {
471464
return nil, 0, fmt.Errorf("save block ID: %w", err)
472465
}
473466

@@ -497,13 +490,13 @@ func (a *Adapter) ExecuteTxs(
497490
func fireEvents(
498491
eventBus cmttypes.BlockEventPublisher,
499492
block *cmttypes.Block,
500-
blockID cmttypes.BlockID,
493+
blockID *cmttypes.BlockID,
501494
abciResponse *abci.ResponseFinalizeBlock,
502495
validatorUpdates []*cmttypes.Validator,
503496
) error {
504497
if err := eventBus.PublishEventNewBlock(cmttypes.EventDataNewBlock{
505498
Block: block,
506-
BlockID: blockID,
499+
BlockID: *blockID,
507500
ResultFinalizeBlock: *abciResponse,
508501
}); err != nil {
509502
return fmt.Errorf("publish new block event: %w", err)
@@ -618,14 +611,14 @@ func cometCommitToABCICommitInfo(commit *cmttypes.Commit) abci.CommitInfo {
618611
}
619612

620613
type StackedEvent struct {
621-
blockID cmttypes.BlockID
614+
blockID *cmttypes.BlockID
622615
block *cmttypes.Block
623616
abciResponse *abci.ResponseFinalizeBlock
624617
validatorUpdates []*cmttypes.Validator
625618
}
626619

627620
func (a *Adapter) stackBlockCommitEvents(
628-
blockID cmttypes.BlockID,
621+
blockID *cmttypes.BlockID,
629622
block *cmttypes.Block,
630623
abciResponse *abci.ResponseFinalizeBlock,
631624
validatorUpdates []*cmttypes.Validator,

pkg/adapter/adapter_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424

2525
"github.com/evstack/ev-node/types"
2626

27-
"github.com/evstack/ev-abci/pkg/cometcompat"
2827
execstore "github.com/evstack/ev-abci/pkg/store"
2928
)
3029

@@ -104,7 +103,7 @@ func TestExecuteFiresEvents(t *testing.T) {
104103
AppHash: []byte("apphash1"),
105104
}
106105

107-
headerBz, err := cometcompat.SignaturePayloadProvider(adapter.Store)(&header)
106+
headerBz, err := AggregatorNodeSignatureBytesProvider(adapter)(&header)
108107
require.NoError(t, err)
109108

110109
sig, err := privKey.Sign(headerBz)
Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
package cometcompat
1+
package adapter
22

33
import (
44
"errors"
55
"fmt"
66

77
cmbytes "github.com/cometbft/cometbft/libs/bytes"
88
cmprotoversion "github.com/cometbft/cometbft/proto/tendermint/version"
9+
cmtstate "github.com/cometbft/cometbft/state"
910
cmttypes "github.com/cometbft/cometbft/types"
1011
cmtversion "github.com/cometbft/cometbft/version"
1112

@@ -74,3 +75,34 @@ func ToABCIBlockMeta(abciBlock *cmttypes.Block) (*cmttypes.BlockMeta, error) {
7475
NumTxs: len(abciBlock.Txs),
7576
}, nil
7677
}
78+
79+
// MakeABCIBlock makes an ABCI block and its block ID.
80+
func MakeABCIBlock(
81+
blockHeight uint64,
82+
cmtTxs cmttypes.Txs,
83+
currentState *cmtstate.State,
84+
abciHeader cmttypes.Header,
85+
lastCommit *cmttypes.Commit,
86+
) (*cmttypes.Block, *cmttypes.BlockID, error) {
87+
abciBlock := currentState.MakeBlock(
88+
int64(blockHeight),
89+
cmtTxs,
90+
lastCommit,
91+
nil,
92+
currentState.Validators.Proposer.Address,
93+
)
94+
95+
blockParts, err := abciBlock.MakePartSet(cmttypes.BlockPartSizeBytes)
96+
if err != nil {
97+
return nil, nil, fmt.Errorf("make part set: %w", err)
98+
}
99+
100+
// use abci header hash to match the light client validation check
101+
// where sh.Header.Hash() (comet header) must equal sh.Commit.BlockID.Hash
102+
currentBlockID := &cmttypes.BlockID{
103+
Hash: abciHeader.Hash(),
104+
PartSetHeader: blockParts.Header(),
105+
}
106+
107+
return abciBlock, currentBlockID, nil
108+
}

pkg/adapter/providers.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package adapter
2+
3+
import (
4+
"bytes"
5+
"context"
6+
stdsha256 "crypto/sha256"
7+
"encoding/hex"
8+
"fmt"
9+
10+
tmcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
11+
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
12+
cmttypes "github.com/cometbft/cometbft/types"
13+
"github.com/libp2p/go-libp2p/core/crypto"
14+
15+
evtypes "github.com/evstack/ev-node/types"
16+
)
17+
18+
func AggregatorNodeSignatureBytesProvider(adapter *Adapter) evtypes.AggregatorNodeSignatureBytesProvider {
19+
return func(header *evtypes.Header) ([]byte, error) {
20+
blockID, err := adapter.Store.GetBlockID(context.Background(), header.Height())
21+
if err != nil && header.Height() > 1 {
22+
return nil, err
23+
}
24+
25+
return createVote(header, blockID), nil
26+
}
27+
}
28+
29+
func SyncNodeSignatureBytesProvider(adapter *Adapter) evtypes.SyncNodeSignatureBytesProvider {
30+
return func(ctx context.Context, header *evtypes.Header, data *evtypes.Data) ([]byte, error) {
31+
blockHeight := header.Height()
32+
blockID := &cmttypes.BlockID{}
33+
34+
if header.Height() > 1 { // first block has an empty block ID
35+
cmtTxs := make(cmttypes.Txs, len(data.Txs))
36+
for i := range data.Txs {
37+
cmtTxs[i] = cmttypes.Tx(data.Txs[i])
38+
}
39+
40+
lastCommit, err := adapter.GetLastCommit(ctx, blockHeight)
41+
if err != nil {
42+
return nil, fmt.Errorf("get last commit: %w", err)
43+
}
44+
45+
abciHeader, err := ToABCIHeader(*header, lastCommit)
46+
if err != nil {
47+
return nil, fmt.Errorf("compute header hash: %w", err)
48+
}
49+
50+
currentState, err := adapter.Store.LoadState(ctx)
51+
if err != nil {
52+
return nil, fmt.Errorf("load state: %w", err)
53+
}
54+
55+
_, blockID, err = MakeABCIBlock(blockHeight, cmtTxs, currentState, abciHeader, lastCommit)
56+
if err != nil {
57+
return nil, fmt.Errorf("make ABCI block: %w", err)
58+
}
59+
}
60+
61+
return createVote(header, blockID), nil
62+
}
63+
}
64+
65+
// createVote builds the vote for the given header and block ID to be signed.
66+
func createVote(header *evtypes.Header, blockID *cmttypes.BlockID) []byte {
67+
vote := cmtproto.Vote{
68+
Type: cmtproto.PrecommitType,
69+
Height: int64(header.Height()), //nolint:gosec
70+
BlockID: blockID.ToProto(),
71+
Round: 0,
72+
Timestamp: header.Time(),
73+
ValidatorAddress: header.ProposerAddress,
74+
ValidatorIndex: 0,
75+
}
76+
77+
chainID := header.ChainID()
78+
consensusVoteBytes := cmttypes.VoteSignBytes(chainID, &vote)
79+
80+
return consensusVoteBytes
81+
}
82+
83+
// ValidatorHasher returns a function that calculates the ValidatorHash
84+
// compatible with CometBFT. This function is intended to be injected into ev-node's Manager.
85+
func ValidatorHasherProvider() func(proposerAddress []byte, pubKey crypto.PubKey) (evtypes.Hash, error) {
86+
return func(proposerAddress []byte, pubKey crypto.PubKey) (evtypes.Hash, error) {
87+
var calculatedHash evtypes.Hash
88+
89+
var cometBftPubKey tmcryptoed25519.PubKey
90+
if pubKey.Type() == crypto.Ed25519 {
91+
rawKey, err := pubKey.Raw()
92+
if err != nil {
93+
return calculatedHash, fmt.Errorf("failed to get raw bytes from libp2p public key: %w", err)
94+
}
95+
if len(rawKey) != tmcryptoed25519.PubKeySize {
96+
return calculatedHash, fmt.Errorf("libp2p public key size (%d) does not match CometBFT Ed25519 PubKeySize (%d)", len(rawKey), tmcryptoed25519.PubKeySize)
97+
}
98+
cometBftPubKey = rawKey
99+
} else {
100+
return calculatedHash, fmt.Errorf("unsupported public key type '%s', expected Ed25519 for CometBFT compatibility", pubKey.Type())
101+
}
102+
103+
votingPower := int64(1)
104+
sequencerValidator := cmttypes.NewValidator(cometBftPubKey, votingPower)
105+
106+
derivedAddress := sequencerValidator.Address.Bytes()
107+
if !bytes.Equal(derivedAddress, proposerAddress) {
108+
return calculatedHash, fmt.Errorf("CRITICAL MISMATCH - derived validator address (%s) does not match expected proposer address (%s). PubKey used for derivation: %s",
109+
hex.EncodeToString(derivedAddress),
110+
hex.EncodeToString(proposerAddress),
111+
hex.EncodeToString(cometBftPubKey.Bytes()))
112+
}
113+
114+
sequencerValidatorSet := cmttypes.NewValidatorSet([]*cmttypes.Validator{sequencerValidator})
115+
116+
hashSumBytes := sequencerValidatorSet.Hash()
117+
118+
calculatedHash = make(evtypes.Hash, stdsha256.Size)
119+
copy(calculatedHash, hashSumBytes)
120+
121+
return calculatedHash, nil
122+
}
123+
}

0 commit comments

Comments
 (0)