refactor(warp): Core -> Message — track warp v1.22.0

Rename across the evm warp backend and the warp precompile: warp.Core ->
warp.Message, NewCore -> NewMessage, ParseCore -> ParseMessage, the .Core field
-> .Message, and local core/msgCore/testCore vars -> msg/testMsg. deps: warp
v1.21.0 -> v1.22.0, precompile v0.11.0 -> v0.12.0.

geth's core/types and core/vm imports are untouched — the rename is scoped to
the warp message type, never the geth core package. ./warp/... and
./precompile/contracts/warp/... green, including TestWarpWrongNetworkID.
This commit is contained in:
2026-06-27 00:48:35 -07:00
parent 4d4e961f81
commit 2bc16e3494
13 changed files with 118 additions and 114 deletions
+2 -2
View File
@@ -34,7 +34,7 @@ require (
github.com/luxfi/metric v1.5.9
github.com/luxfi/p2p v1.21.1
github.com/luxfi/pq v1.0.3
github.com/luxfi/precompile v0.11.0
github.com/luxfi/precompile v0.12.0
github.com/luxfi/runtime v1.1.3
github.com/luxfi/sys v0.1.0
github.com/luxfi/timer v1.0.2
@@ -44,7 +44,7 @@ require (
github.com/luxfi/validators v1.2.0
github.com/luxfi/version v1.0.1
github.com/luxfi/vm v1.2.5
github.com/luxfi/warp v1.21.0
github.com/luxfi/warp v1.22.0
github.com/mattn/go-colorable v0.1.15
github.com/mattn/go-isatty v0.0.22
github.com/spf13/cast v1.10.0
+4
View File
@@ -324,6 +324,8 @@ github.com/luxfi/precompile v0.10.0 h1:Hz7gUZ3gN5uCjN427+Tpnqnxd0XCf8dAgnN56+5J6
github.com/luxfi/precompile v0.10.0/go.mod h1:0n+LNoJjHyPvNs+8XoGshujoZhCFuwy2/HXHmeGA2Do=
github.com/luxfi/precompile v0.11.0 h1:LdSsfoBxPzkLfIkKtwM44ySE9vDfDEKKj0qUejkLJjs=
github.com/luxfi/precompile v0.11.0/go.mod h1:tJMbLUbBEY7ZetUjfUmRDSD76sSQ30X7DddP07eWj6M=
github.com/luxfi/precompile v0.12.0 h1:tKYWAIn6Ma4D4c+eW/IBGJyOvrkZcl5qXkhyhBjZ92k=
github.com/luxfi/precompile v0.12.0/go.mod h1:zU20NTtiSrUZzaNQJc3zTrZSydJKUV+rGzOgM+AGfFE=
github.com/luxfi/proto v1.3.5 h1:AW11rnu5xyvB7beyowoiY9uIffLOF3+eMR/a3EkK2c8=
github.com/luxfi/proto v1.3.5/go.mod h1:ixTofGpdW1rTYr+wgTuBhAsgBv8GnWYHMLWbPNEdm7M=
github.com/luxfi/resource v0.0.1 h1:mTh+ICWSy548GTUSSyx7V/X5dV18oEwxZeQEYGJQhD4=
@@ -356,6 +358,8 @@ github.com/luxfi/warp v1.20.0 h1:CyUokvCZ2ZhIpbziKPzCdqdvdMc1V32JpyoZTM2tShs=
github.com/luxfi/warp v1.20.0/go.mod h1:4a6ZqXSsQVpm1nl1Q5i6SYPjDcdHvPyEoj4M9pvrIHE=
github.com/luxfi/warp v1.21.0 h1:QRgDJuGkp0V3GkmnboHTOKl9Ak0ZHc8DcQqbV4gnCRM=
github.com/luxfi/warp v1.21.0/go.mod h1:4a6ZqXSsQVpm1nl1Q5i6SYPjDcdHvPyEoj4M9pvrIHE=
github.com/luxfi/warp v1.22.0 h1:S3yiVUaBkHwMkYMAUxHpyVqRe8ZubugCozBgUyRczNA=
github.com/luxfi/warp v1.22.0/go.mod h1:4a6ZqXSsQVpm1nl1Q5i6SYPjDcdHvPyEoj4M9pvrIHE=
github.com/luxfi/zap v0.8.11 h1:jT+ol9rj557MRdmnzxrVUCR3CDFaE+8OpzUsLIn92og=
github.com/luxfi/zap v0.8.11/go.mod h1:JfqII8VtVQYLLTX6obU1DP9sjGqf9L24vfug5ifh0b8=
github.com/luxfi/zapcodec v1.0.1 h1:pRxLxCOi6uihQMg8A8riDjNjefU2cXZxfRVZ+obeuL8=
+1 -1
View File
@@ -2219,6 +2219,6 @@ type warpVerifierAdapter struct {
}
// Verify implements warp.Verifier interface
func (w *warpVerifierAdapter) Verify(ctx context.Context, core *luxwarp.Core, justification []byte) error {
func (w *warpVerifierAdapter) Verify(ctx context.Context, core *luxwarp.Message, justification []byte) error {
return w.backend.Verify(ctx, core, justification)
}
+10 -10
View File
@@ -122,7 +122,7 @@ func (c *Config) Equal(s precompileconfig.Config) bool {
}
func (c *Config) Accept(acceptCtx *precompileconfig.AcceptContext, blockHash common.Hash, blockNumber uint64, txHash common.Hash, logIndex int, topics []common.Hash, logData []byte) error {
core, err := UnpackSendWarpEventDataToMessage(logData)
msg, err := UnpackSendWarpEventDataToMessage(logData)
if err != nil {
return fmt.Errorf("failed to parse warp log data into signed core (TxHash: %s, LogIndex: %d): %w", txHash, logIndex, err)
}
@@ -133,9 +133,9 @@ func (c *Config) Accept(acceptCtx *precompileconfig.AcceptContext, blockHash com
"txHash", txHash,
"logIndex", logIndex,
"logData", common.Bytes2Hex(logData),
"warpMessageID", core.ID(),
"warpMessageID", msg.ID(),
)
if err := acceptCtx.Warp.AddMessage(core); err != nil {
if err := acceptCtx.Warp.AddMessage(msg); err != nil {
return fmt.Errorf("failed to add warp message during accept (TxHash: %s, LogIndex: %d): %w", txHash, logIndex, err)
}
return nil
@@ -168,7 +168,7 @@ func (c *Config) PredicateGas(predicateBytes []byte) (uint64, error) {
if err != nil {
return 0, fmt.Errorf("%w: %s", errInvalidWarpMsg, err)
}
_, err = payload.ParsePayload(warpMessage.Core.Payload)
_, err = payload.ParsePayload(warpMessage.Message.Payload)
if err != nil {
return 0, fmt.Errorf("%w: %s", errInvalidWarpMsgPayload, err)
}
@@ -213,8 +213,8 @@ func (c *Config) VerifyPredicate(predicateContext *precompileconfig.PredicateCon
// matching warp.VerifyEnvelope. The bespoke verify path must enforce the same
// checks (one and one way); D folds NetworkID, so this is defense in depth
// against cross-network replay.
if localNetworkID := consensuscontext.GetNetworkID(predicateContext.ConsensusCtx); warpMsg.Core.NetworkID != localNetworkID {
return fmt.Errorf("%w: message network ID %d does not match local network ID %d", errFailedVerification, warpMsg.Core.NetworkID, localNetworkID)
if localNetworkID := consensuscontext.GetNetworkID(predicateContext.ConsensusCtx); warpMsg.Message.NetworkID != localNetworkID {
return fmt.Errorf("%w: message network ID %d does not match local network ID %d", errFailedVerification, warpMsg.Message.NetworkID, localNetworkID)
}
quorumNumerator := WarpDefaultQuorumNumerator
@@ -229,7 +229,7 @@ func (c *Config) VerifyPredicate(predicateContext *precompileconfig.PredicateCon
}
// Get the source chain ID from the warp message
sourceChainID := warpMsg.Core.SourceChainID
sourceChainID := warpMsg.Message.SourceChainID
// Get network ID from validator state for the source chain
sourceNetworkID, err := validatorState.GetNetworkID(sourceChainID)
@@ -382,10 +382,10 @@ func (c *Config) VerifyPredicate(predicateContext *precompileconfig.PredicateCon
return fmt.Errorf("%w: %w", errFailedVerification, err)
}
// Verify the BLS Beam over the ZAP digest D = warpMsg.Core.ID(). The Beam
// signs warp.BeamSigningBytes(D), authenticating the entire Core
// Verify the BLS Beam over the ZAP digest D = warpMsg.Message.ID(). The Beam
// signs warp.BeamSigningBytes(D), authenticating the entire Message
// (network ID, source chain, PQ lineage, payload) — not stale RLP bytes.
err = verifyBeam(beam, warpMsg.Core.ID(), canonicalValidators)
err = verifyBeam(beam, warpMsg.Message.ID(), canonicalValidators)
if err != nil {
return fmt.Errorf("%w: %w", errFailedVerification, err)
}
+7 -7
View File
@@ -265,7 +265,7 @@ func sendWarpMessage(accessibleState contract.AccessibleState, caller common.Add
if err != nil {
return nil, remainingGas, err
}
core, err := warp.NewCore(
msg, err := warp.NewMessage(
consensuscontext.GetNetworkID(ctx),
sourceChainID,
addressedPayload.Bytes(),
@@ -277,8 +277,8 @@ func sendWarpMessage(accessibleState contract.AccessibleState, caller common.Add
// Add a log to be handled if this action is finalized.
topics, data, err := PackSendWarpMessageEvent(
sourceAddress,
common.Hash(core.ID()),
core.Bytes(),
common.Hash(msg.ID()),
msg.Bytes(),
)
if err != nil {
return nil, remainingGas, err
@@ -290,7 +290,7 @@ func sendWarpMessage(accessibleState contract.AccessibleState, caller common.Add
BlockNumber: accessibleState.GetBlockContext().Number().Uint64(),
})
packed, err := PackSendWarpMessageOutput(common.Hash(core.ID()))
packed, err := PackSendWarpMessageOutput(common.Hash(msg.ID()))
if err != nil {
return nil, remainingGas, err
}
@@ -305,15 +305,15 @@ func PackSendWarpMessageEvent(sourceAddress common.Address, unsignedMessageID co
}
// UnpackSendWarpEventDataToMessage attempts to unpack event [data] as a
// warp.Core (the ZAP canonical core, replacing the deleted RLP
// warp.Message (the ZAP canonical core, replacing the deleted RLP
// unsigned-message type).
func UnpackSendWarpEventDataToMessage(data []byte) (*warp.Core, error) {
func UnpackSendWarpEventDataToMessage(data []byte) (*warp.Message, error) {
event := SendWarpMessageEventData{}
err := WarpABI.UnpackIntoInterface(&event, "SendWarpMessage", data)
if err != nil {
return nil, err
}
return warp.ParseCore(event.Message)
return warp.ParseMessage(event.Message)
}
// createWarpPrecompile returns a StatefulPrecompiledContract with getters and setters for the precompile.
+6 -6
View File
@@ -107,7 +107,7 @@ func TestSendWarpMessage(t *testing.T) {
sendWarpMessagePayload,
)
require.NoError(t, err)
unsignedWarpMessage, err := warp.NewCore(
unsignedWarpMessage, err := warp.NewMessage(
context.GetNetworkID(defaultConsensusCtx),
blockchainID,
sendWarpMessageAddressedPayload.Bytes(),
@@ -201,7 +201,7 @@ func TestGetVerifiedWarpMessage(t *testing.T) {
packagedPayloadBytes,
)
require.NoError(t, err)
unsignedWarpMsg, err := warp.NewCore(networkID, sourceChainID, addressedPayload.Bytes())
unsignedWarpMsg, err := warp.NewMessage(networkID, sourceChainID, addressedPayload.Bytes())
require.NoError(t, err)
warpMessage, err := warp.NewEnvelope(unsignedWarpMsg, warp.BitSetSignature{}, nil, nil) // Create message with empty signature for testing
require.NoError(t, err)
@@ -407,7 +407,7 @@ func TestGetVerifiedWarpMessage(t *testing.T) {
Caller: callerAddr,
InputFn: func(t testing.TB) []byte { return getVerifiedWarpMsg },
Predicates: func() [][]byte {
unsignedMessage, err := warp.NewCore(networkID, sourceChainID, []byte{1, 2, 3}) // Invalid addressed payload
unsignedMessage, err := warp.NewMessage(networkID, sourceChainID, []byte{1, 2, 3}) // Invalid addressed payload
require.NoError(t, err)
warpMessage, err := warp.NewEnvelope(unsignedMessage, warp.BitSetSignature{}, nil, nil)
require.NoError(t, err)
@@ -465,7 +465,7 @@ func TestGetVerifiedWarpBlockHash(t *testing.T) {
blockHash := ids.GenerateTestID()
blockHashPayload, err := payload.NewHash(blockHash[:])
require.NoError(t, err)
unsignedWarpMsg, err := warp.NewCore(networkID, sourceChainID, blockHashPayload.Bytes())
unsignedWarpMsg, err := warp.NewMessage(networkID, sourceChainID, blockHashPayload.Bytes())
require.NoError(t, err)
warpMessage, err := warp.NewEnvelope(unsignedWarpMsg, warp.BitSetSignature{}, nil, nil) // Create message with empty signature for testing
require.NoError(t, err)
@@ -668,7 +668,7 @@ func TestGetVerifiedWarpBlockHash(t *testing.T) {
Caller: callerAddr,
InputFn: func(t testing.TB) []byte { return getVerifiedWarpBlockHash },
Predicates: func() [][]byte {
unsignedMessage, err := warp.NewCore(networkID, sourceChainID, []byte{1, 2, 3}) // Invalid block hash payload
unsignedMessage, err := warp.NewMessage(networkID, sourceChainID, []byte{1, 2, 3}) // Invalid block hash payload
require.NoError(t, err)
warpMessage, err := warp.NewEnvelope(unsignedMessage, warp.BitSetSignature{}, nil, nil)
require.NoError(t, err)
@@ -731,7 +731,7 @@ func TestPackEvents(t *testing.T) {
)
require.NoError(t, err)
unsignedWarpMessage, err := warp.NewCore(
unsignedWarpMessage, err := warp.NewMessage(
networkID,
sourceChainID,
addressedPayload.Bytes(),
@@ -111,7 +111,7 @@ func (addressedPayloadHandler) packFailed() []byte {
}
func (addressedPayloadHandler) handleMessage(warpMessage *warp.Envelope) ([]byte, error) {
addressedPayload, err := payload.ParsePayload(warpMessage.Core.Payload)
addressedPayload, err := payload.ParsePayload(warpMessage.Message.Payload)
if err != nil {
return nil, fmt.Errorf("%w: %s", errInvalidAddressedPayload, err)
}
@@ -122,7 +122,7 @@ func (addressedPayloadHandler) handleMessage(warpMessage *warp.Envelope) ([]byte
}
return PackGetVerifiedWarpMessageOutput(GetVerifiedWarpMessageOutput{
Message: WarpMessage{
SourceChainID: common.BytesToHash(warpMessage.Core.SourceChainID[:]),
SourceChainID: common.BytesToHash(warpMessage.Message.SourceChainID[:]),
OriginSenderAddress: common.BytesToAddress(addressedCall.SourceAddress),
Payload: addressedCall.Payload,
},
@@ -137,7 +137,7 @@ func (blockHashHandler) packFailed() []byte {
}
func (blockHashHandler) handleMessage(warpMessage *warp.Envelope) ([]byte, error) {
parsedPayload, err := payload.ParsePayload(warpMessage.Core.Payload)
parsedPayload, err := payload.ParsePayload(warpMessage.Message.Payload)
if err != nil {
return nil, fmt.Errorf("%w: %s", errInvalidBlockHashPayload, err)
}
@@ -148,7 +148,7 @@ func (blockHashHandler) handleMessage(warpMessage *warp.Envelope) ([]byte, error
}
return PackGetVerifiedWarpBlockHashOutput(GetVerifiedWarpBlockHashOutput{
WarpBlockHash: WarpBlockHash{
SourceChainID: common.BytesToHash(warpMessage.Core.SourceChainID[:]),
SourceChainID: common.BytesToHash(warpMessage.Message.SourceChainID[:]),
BlockHash: common.BytesToHash(blockHashPayload.Hash[:]),
},
Valid: true,
+16 -16
View File
@@ -39,7 +39,7 @@ var (
sourceNetworkID = ids.GenerateTestID()
// valid signed core used throughout testing
core *warp.Core
msg *warp.Message
// valid addressed payload
addressedPayload *payload.AddressedCall
addressedPayloadBytes []byte
@@ -86,13 +86,13 @@ func init() {
panic(err)
}
addressedPayloadBytes = addressedPayload.Bytes()
core, err = warp.NewCore(constants.UnitTestID, sourceChainID, addressedPayload.Bytes())
msg, err = warp.NewMessage(constants.UnitTestID, sourceChainID, addressedPayload.Bytes())
if err != nil {
panic(err)
}
// Post-ZAP the BLS Beam signs BeamSigningBytes(core.ID()), not raw bytes.
beamMsg := warp.BeamSigningBytes(core.ID())
beamMsg := warp.BeamSigningBytes(msg.ID())
for _, testVdr := range testVdrs {
blsSignature, err := testVdr.sk.Sign(beamMsg)
if err != nil {
@@ -159,7 +159,7 @@ func createWarpMessage(numKeys int) *warp.Envelope {
}
copy(beam.Signature[:], bls.SignatureToBytes(aggregateSignature))
env, err := warp.NewEnvelope(core, beam, nil, nil)
env, err := warp.NewEnvelope(msg, beam, nil, nil)
if err != nil {
panic(err)
}
@@ -234,7 +234,7 @@ func newPredicateConsensusCtx(tb testing.TB, state consensuscontext.ValidatorSta
rt := utilstest.NewTestRuntime(tb, ids.GenerateTestID())
rt.ValidatorState = state
// Align the node's network ID with the cores the tests build via
// warp.NewCore(constants.UnitTestID, ...) so VerifyPredicate's network-ID
// warp.NewMessage(constants.UnitTestID, ...) so VerifyPredicate's network-ID
// check (parity with warp.VerifyEnvelope) accepts them.
rt.NetworkID = constants.UnitTestID
return consensuscontext.WithContext(context.Background(), rt)
@@ -299,10 +299,10 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
cChainID := ids.GenerateTestID()
addressedCall, err := payload.NewAddressedCall(agoUtils.RandomBytes(20), agoUtils.RandomBytes(100))
require.NoError(err)
msgCore, err := warp.NewCore(constants.UnitTestID, cChainID, addressedCall.Bytes())
msg, err := warp.NewMessage(constants.UnitTestID, cChainID, addressedCall.Bytes())
require.NoError(err)
beamMsg := warp.BeamSigningBytes(msgCore.ID())
beamMsg := warp.BeamSigningBytes(msg.ID())
getValidatorsOutput := make(map[ids.NodeID]*validators.GetValidatorOutput)
blsSignatures := make([]*bls.Signature, 0, numKeys)
for i := 0; i < numKeys; i++ {
@@ -327,7 +327,7 @@ func testWarpMessageFromPrimaryNetwork(t *testing.T, requirePrimaryNetworkSigner
Signers: bitSet,
}
copy(beam.Signature[:], bls.SignatureToBytes(aggregateSignature))
warpMsg, err := warp.NewEnvelope(msgCore, beam, nil, nil)
warpMsg, err := warp.NewEnvelope(msg, beam, nil, nil)
require.NoError(err)
envBytes, err := warpMsg.Bytes()
@@ -461,9 +461,9 @@ func TestInvalidAddressedPayload(t *testing.T) {
}
copy(beam.Signature[:], bls.SignatureToBytes(aggregateSignature))
// Create a signed core with an invalid addressed payload
msgCore, err := warp.NewCore(constants.UnitTestID, sourceChainID, []byte{1, 2, 3})
msg, err := warp.NewMessage(constants.UnitTestID, sourceChainID, []byte{1, 2, 3})
require.NoError(t, err)
warpMsg, err := warp.NewEnvelope(msgCore, beam, nil, nil)
warpMsg, err := warp.NewEnvelope(msg, beam, nil, nil)
require.NoError(t, err)
warpMsgBytes, err := warpMsg.Bytes()
require.NoError(t, err)
@@ -488,14 +488,14 @@ func TestInvalidAddressedPayload(t *testing.T) {
func TestInvalidBitSet(t *testing.T) {
addressedCall, err := payload.NewAddressedCall(agoUtils.RandomBytes(20), agoUtils.RandomBytes(100))
require.NoError(t, err)
msgCore, err := warp.NewCore(
msg, err := warp.NewMessage(
constants.UnitTestID,
sourceChainID,
addressedCall.Bytes(),
)
require.NoError(t, err)
msg, err := warp.NewEnvelope(msgCore, warp.BitSetSignature{
env, err := warp.NewEnvelope(msg, warp.BitSetSignature{
Signers: make([]byte, 1),
Signature: [bls.SignatureLen]byte{},
}, nil, nil)
@@ -510,7 +510,7 @@ func TestInvalidBitSet(t *testing.T) {
publicKey: true,
},
})
msgBytes, err := msg.Bytes()
msgBytes, err := env.Bytes()
require.NoError(t, err)
predicateBytes := predicate.PackPredicate(msgBytes)
test := precompiletest.PredicateTest{
@@ -529,7 +529,7 @@ func TestInvalidBitSet(t *testing.T) {
test.Run(t)
}
// TestWarpWrongNetworkID proves VerifyPredicate rejects a message whose Core
// TestWarpWrongNetworkID proves VerifyPredicate rejects a message whose Message
// is stamped with a network ID different from the verifying node's — parity
// with warp.VerifyEnvelope. The rejection happens before any signature work,
// so the (unsigned) message still passes PredicateGas.
@@ -546,13 +546,13 @@ func TestWarpWrongNetworkID(t *testing.T) {
addressedCall, err := payload.NewAddressedCall(agoUtils.RandomBytes(20), agoUtils.RandomBytes(100))
require.NoError(t, err)
// constants.UnitTestID+1 != the test runtime's UnitTestID.
msgCore, err := warp.NewCore(constants.UnitTestID+1, sourceChainID, addressedCall.Bytes())
msg, err := warp.NewMessage(constants.UnitTestID+1, sourceChainID, addressedCall.Bytes())
require.NoError(t, err)
bitSet := warp.NewBitSet()
for i := 0; i < numKeys; i++ {
bitSet.Add(i)
}
warpMsg, err := warp.NewEnvelope(msgCore, warp.BitSetSignature{Signers: bitSet}, nil, nil)
warpMsg, err := warp.NewEnvelope(msg, warp.BitSetSignature{Signers: bitSet}, nil, nil)
require.NoError(t, err)
warpMsgBytes, err := warpMsg.Bytes()
require.NoError(t, err)
+3 -3
View File
@@ -55,11 +55,11 @@ type Predicater interface {
// WarpMessageWriter queues a precompile-emitted cross-chain message for the
// validator set to attest. Post-ZAP hard fork the unsigned subject is the
// warp.Core (whose D = keccak256(DST ‖ zap_c14n) the BLS Beam / Pulsar
// warp.Message (whose D = keccak256(DST ‖ zap_c14n) the BLS Beam / Pulsar
// Pulse / ML-DSA lanes sign), replacing the deleted RLP unsigned-message type.
// Build a core via warp.NewCore(networkID, sourceChainID, payload).
// Build a core via warp.NewMessage(networkID, sourceChainID, payload).
type WarpMessageWriter interface {
AddMessage(core *warp.Core) error
AddMessage(msg *warp.Message) error
}
// AcceptContext defines the context passed in to a precompileconfig's Accepter
+33 -33
View File
@@ -37,24 +37,24 @@ type BlockClient interface {
// Backend tracks signature-eligible warp messages and provides an interface to fetch them.
// The backend is also used to query for warp message signatures by the signature request handler.
//
// Post-ZAP the signed subject is the warp.Core (its D = ID() is what the
// Post-ZAP the signed subject is the warp.Message (its D = ID() is what the
// BLS Beam signs via warp.BeamSigningBytes(D)); the deleted RLP
// unsigned-message type is gone.
type Backend interface {
// AddMessage signs [core] and adds it to the warp backend database.
AddMessage(core *warp.Core) error
AddMessage(msg *warp.Message) error
// GetMessageSignature validates the message and returns the signature of the requested message.
GetMessageSignature(ctx context.Context, core *warp.Core) ([]byte, error)
GetMessageSignature(ctx context.Context, msg *warp.Message) ([]byte, error)
// GetBlockSignature returns the signature of a hash payload containing blockID if it's the ID of an accepted block.
GetBlockSignature(ctx context.Context, blockID ids.ID) ([]byte, error)
// GetMessage retrieves the [core] from the warp backend database if available.
GetMessage(messageHash ids.ID) (*warp.Core, error)
GetMessage(messageHash ids.ID) (*warp.Message, error)
// Verify verifies the signature of the message.
Verify(ctx context.Context, core *warp.Core, _ []byte) error
Verify(ctx context.Context, msg *warp.Message, _ []byte) error
}
// backend implements Backend, keeps track of warp messages, and generates message signatures.
@@ -66,8 +66,8 @@ type backend struct {
blockClient BlockClient
validatorReader interfaces.ValidatorReader
signatureCache cache.Cacher[ids.ID, []byte]
messageCache *lru.Cache[ids.ID, *warp.Core]
offchainAddressedCallMsgs map[string]*warp.Core
messageCache *lru.Cache[ids.ID, *warp.Message]
offchainAddressedCallMsgs map[string]*warp.Message
stats *verifierStats
}
@@ -90,61 +90,61 @@ func NewBackend(
blockClient: blockClient,
signatureCache: signatureCache,
validatorReader: validatorReader,
messageCache: lru.NewCache[ids.ID, *warp.Core](messageCacheSize),
messageCache: lru.NewCache[ids.ID, *warp.Message](messageCacheSize),
stats: newVerifierStats(),
offchainAddressedCallMsgs: make(map[string]*warp.Core),
offchainAddressedCallMsgs: make(map[string]*warp.Message),
}
return b, b.initOffChainMessages(offchainMessages)
}
func (b *backend) initOffChainMessages(offchainMessages [][]byte) error {
for i, offchainMsg := range offchainMessages {
core, err := warp.ParseCore(offchainMsg)
msg, err := warp.ParseMessage(offchainMsg)
if err != nil {
return fmt.Errorf("%w at index %d: %w", errParsingOffChainMessage, i, err)
}
if core.NetworkID != b.networkID {
if msg.NetworkID != b.networkID {
return fmt.Errorf("wrong network ID at index %d", i)
}
// Compare source chain IDs
if !bytes.Equal(core.SourceChainID[:], b.sourceChainID[:]) {
if !bytes.Equal(msg.SourceChainID[:], b.sourceChainID[:]) {
return fmt.Errorf("wrong source chain ID at index %d", i)
}
_, err = payload.ParsePayload(core.Payload)
_, err = payload.ParsePayload(msg.Payload)
if err != nil {
return fmt.Errorf("%w at index %d as AddressedCall: %w", errParsingOffChainMessage, i, err)
}
messageID := core.ID()
messageID := msg.ID()
msgIDHash := ids.ID(crypto.Keccak256Hash(messageID[:]))
b.offchainAddressedCallMsgs[msgIDHash.String()] = core
b.offchainAddressedCallMsgs[msgIDHash.String()] = msg
}
return nil
}
func (b *backend) AddMessage(core *warp.Core) error {
coreID := core.ID()
func (b *backend) AddMessage(msg *warp.Message) error {
coreID := msg.ID()
messageID := ids.ID(crypto.Keccak256Hash(coreID[:]))
log.Debug("Adding warp message to backend", "messageID", messageID)
// In the case when a node restarts, and possibly changes its bls key, the cache gets emptied but the database does not.
// So to avoid having incorrect signatures saved in the database after a bls key change, we save the full message in the database.
// Whereas for the cache, after the node restart, the cache would be emptied so we can directly save the signatures.
if err := b.db.Put(messageID[:], core.Bytes()); err != nil {
if err := b.db.Put(messageID[:], msg.Bytes()); err != nil {
return fmt.Errorf("failed to put warp signature in db: %w", err)
}
if _, err := b.signMessage(core); err != nil {
if _, err := b.signMessage(msg); err != nil {
return fmt.Errorf("failed to sign warp message: %w", err)
}
return nil
}
func (b *backend) GetMessageSignature(ctx context.Context, core *warp.Core) ([]byte, error) {
coreID := core.ID()
func (b *backend) GetMessageSignature(ctx context.Context, msg *warp.Message) ([]byte, error) {
coreID := msg.ID()
messageID := ids.ID(crypto.Keccak256Hash(coreID[:]))
log.Debug("Getting warp message from backend", "messageID", messageID)
@@ -152,10 +152,10 @@ func (b *backend) GetMessageSignature(ctx context.Context, core *warp.Core) ([]b
return sig, nil
}
if err := b.Verify(ctx, core, nil); err != nil {
if err := b.Verify(ctx, msg, nil); err != nil {
return nil, fmt.Errorf("failed to validate warp message: %w", err)
}
return b.signMessage(core)
return b.signMessage(msg)
}
func (b *backend) GetBlockSignature(ctx context.Context, blockID ids.ID) ([]byte, error) {
@@ -166,12 +166,12 @@ func (b *backend) GetBlockSignature(ctx context.Context, blockID ids.ID) ([]byte
return nil, fmt.Errorf("failed to create new block hash payload: %w", err)
}
core, err := warp.NewCore(b.networkID, b.sourceChainID, blockHashPayload.Bytes())
msg, err := warp.NewMessage(b.networkID, b.sourceChainID, blockHashPayload.Bytes())
if err != nil {
return nil, fmt.Errorf("failed to create new signed core: %w", err)
}
coreID := core.ID()
coreID := msg.ID()
messageID := ids.ID(crypto.Keccak256Hash(coreID[:]))
if sig, ok := b.signatureCache.Get(messageID); ok {
return sig, nil
@@ -181,14 +181,14 @@ func (b *backend) GetBlockSignature(ctx context.Context, blockID ids.ID) ([]byte
return nil, fmt.Errorf("failed to validate block message: %w", err)
}
sig, err := b.signMessage(core)
sig, err := b.signMessage(msg)
if err != nil {
return nil, fmt.Errorf("failed to sign block message: %w", err)
}
return sig, nil
}
func (b *backend) GetMessage(messageID ids.ID) (*warp.Core, error) {
func (b *backend) GetMessage(messageID ids.ID) (*warp.Message, error) {
if message, ok := b.messageCache.Get(messageID); ok {
return message, nil
}
@@ -202,26 +202,26 @@ func (b *backend) GetMessage(messageID ids.ID) (*warp.Core, error) {
return nil, err
}
core, err := warp.ParseCore(coreBytes)
msg, err := warp.ParseMessage(coreBytes)
if err != nil {
return nil, fmt.Errorf("failed to parse signed core %s: %w", messageID.String(), err)
}
b.messageCache.Put(messageID, core)
b.messageCache.Put(messageID, msg)
return core, nil
return msg, nil
}
func (b *backend) signMessage(core *warp.Core) ([]byte, error) {
func (b *backend) signMessage(msg *warp.Message) ([]byte, error) {
if b.warpSigner == nil {
return nil, errors.New("warp signer not configured")
}
sig, err := b.warpSigner.Sign(core)
sig, err := b.warpSigner.Sign(msg)
if err != nil {
return nil, fmt.Errorf("failed to sign message: %w", err)
}
coreID := core.ID()
coreID := msg.ID()
messageID := ids.ID(crypto.Keccak256Hash(coreID[:]))
b.signatureCache.Put(messageID, sig)
return sig, nil
+20 -20
View File
@@ -26,7 +26,7 @@ var (
sourceChainID = ids.GenerateTestID()
testSourceAddress []byte
testPayload = []byte("test")
testCore *warp.Core
testMsg *warp.Message
)
func init() {
@@ -37,7 +37,7 @@ func init() {
if err != nil {
panic(err)
}
testCore, err = warp.NewCore(networkID, sourceChainID, testAddressedCallPayload.Bytes())
testMsg, err = warp.NewMessage(networkID, sourceChainID, testAddressedCallPayload.Bytes())
if err != nil {
panic(err)
}
@@ -45,8 +45,8 @@ func init() {
// evmMessageID derives the backend's storage/lookup key for a core, matching
// the keying used by AddMessage/Verify/GetMessageSignature: Keccak256(core.ID()).
func evmMessageID(core *warp.Core) ids.ID {
id := core.ID()
func evmMessageID(msg *warp.Message) ids.ID {
id := msg.ID()
return ids.ID(crypto.Keccak256Hash(id[:]))
}
@@ -60,14 +60,14 @@ func TestAddAndGetValidMessage(t *testing.T) {
backend, err := NewBackend(networkID, sourceChainID, warpSigner, nil, &warptest.NoOpValidatorReader{}, db, messageSignatureCache, nil)
require.NoError(t, err)
// Add testCore to the warp backend
require.NoError(t, backend.AddMessage(testCore))
// Add testMsg to the warp backend
require.NoError(t, backend.AddMessage(testMsg))
// Verify that a signature is returned successfully, and compare to expected signature.
signature, err := backend.GetMessageSignature(context.TODO(), testCore)
signature, err := backend.GetMessageSignature(context.TODO(), testMsg)
require.NoError(t, err)
expectedSig, err := warpSigner.Sign(testCore)
expectedSig, err := warpSigner.Sign(testMsg)
require.NoError(t, err)
require.Equal(t, expectedSig, signature[:])
}
@@ -83,7 +83,7 @@ func TestAddAndGetUnknownMessage(t *testing.T) {
require.NoError(t, err)
// Try getting a signature for a message that was not added.
_, err = backend.GetMessageSignature(context.TODO(), testCore)
_, err = backend.GetMessageSignature(context.TODO(), testMsg)
require.Error(t, err)
}
@@ -103,9 +103,9 @@ func TestGetBlockSignature(t *testing.T) {
blockHashPayload, err := payload.NewHash(blkID[:])
require.NoError(err)
core, err := warp.NewCore(networkID, sourceChainID, blockHashPayload.Bytes())
msg, err := warp.NewMessage(networkID, sourceChainID, blockHashPayload.Bytes())
require.NoError(err)
expectedSig, err := warpSigner.Sign(core)
expectedSig, err := warpSigner.Sign(msg)
require.NoError(err)
signature, err := backend.GetBlockSignature(context.TODO(), blkID)
@@ -128,14 +128,14 @@ func TestZeroSizedCache(t *testing.T) {
backend, err := NewBackend(networkID, sourceChainID, warpSigner, nil, &warptest.NoOpValidatorReader{}, db, messageSignatureCache, nil)
require.NoError(t, err)
// Add testCore to the warp backend
require.NoError(t, backend.AddMessage(testCore))
// Add testMsg to the warp backend
require.NoError(t, backend.AddMessage(testMsg))
// Verify that a signature is returned successfully, and compare to expected signature.
signature, err := backend.GetMessageSignature(context.TODO(), testCore)
signature, err := backend.GetMessageSignature(context.TODO(), testMsg)
require.NoError(t, err)
expectedSig, err := warpSigner.Sign(testCore)
expectedSig, err := warpSigner.Sign(testMsg)
require.NoError(t, err)
require.Equal(t, expectedSig, signature[:])
}
@@ -154,14 +154,14 @@ func TestOffChainMessages(t *testing.T) {
"no offchain messages": {},
"single off-chain message": {
offchainMessages: [][]byte{
testCore.Bytes(),
testMsg.Bytes(),
},
check: func(require *require.Assertions, b Backend) {
msg, err := b.GetMessage(evmMessageID(testCore))
msg, err := b.GetMessage(evmMessageID(testMsg))
require.NoError(err)
require.Equal(testCore.Bytes(), msg.Bytes())
require.Equal(testMsg.Bytes(), msg.Bytes())
signature, err := b.GetMessageSignature(context.TODO(), testCore)
signature, err := b.GetMessageSignature(context.TODO(), testMsg)
require.NoError(err)
expectedSignatureBytes, err := warpSigner.Sign(msg)
require.NoError(err)
@@ -170,7 +170,7 @@ func TestOffChainMessages(t *testing.T) {
},
"unknown message": {
check: func(require *require.Assertions, b Backend) {
_, err := b.GetMessage(evmMessageID(testCore))
_, err := b.GetMessage(evmMessageID(testMsg))
require.ErrorIs(err, database.ErrNotFound)
},
},
+9 -9
View File
@@ -50,11 +50,11 @@ func (a *API) GetMessage(ctx context.Context, messageID ids.ID) (hexutil.Bytes,
// GetMessageSignature returns the BLS signature associated with a messageID.
func (a *API) GetMessageSignature(ctx context.Context, messageID ids.ID) (hexutil.Bytes, error) {
core, err := a.backend.GetMessage(messageID)
msg, err := a.backend.GetMessage(messageID)
if err != nil {
return nil, fmt.Errorf("failed to get message %s with error %w", messageID, err)
}
signature, err := a.backend.GetMessageSignature(ctx, core)
signature, err := a.backend.GetMessageSignature(ctx, msg)
if err != nil {
return nil, fmt.Errorf("failed to get signature for message %s with error %w", messageID, err)
}
@@ -72,11 +72,11 @@ func (a *API) GetBlockSignature(ctx context.Context, blockID ids.ID) (hexutil.By
// GetMessageAggregateSignature fetches the aggregate signature for the requested [messageID]
func (a *API) GetMessageAggregateSignature(ctx context.Context, messageID ids.ID, quorumNum uint64, chainIDStr string) (signedMessageBytes hexutil.Bytes, err error) {
core, err := a.backend.GetMessage(messageID)
msg, err := a.backend.GetMessage(messageID)
if err != nil {
return nil, err
}
return a.aggregateSignatures(ctx, core, quorumNum, chainIDStr)
return a.aggregateSignatures(ctx, msg, quorumNum, chainIDStr)
}
// GetBlockAggregateSignature fetches the aggregate signature for the requested [blockID]
@@ -86,15 +86,15 @@ func (a *API) GetBlockAggregateSignature(ctx context.Context, blockID ids.ID, qu
return nil, err
}
chainID := a.runtimeCtx.GetChainID()
core, err := warp.NewCore(a.runtimeCtx.GetNetworkID(), chainID, blockHashPayload.Bytes())
msg, err := warp.NewMessage(a.runtimeCtx.GetNetworkID(), chainID, blockHashPayload.Bytes())
if err != nil {
return nil, err
}
return a.aggregateSignatures(ctx, core, quorumNum, chainIDStr)
return a.aggregateSignatures(ctx, msg, quorumNum, chainIDStr)
}
func (a *API) aggregateSignatures(ctx context.Context, core *warp.Core, quorumNum uint64, chainIDStr string) (hexutil.Bytes, error) {
func (a *API) aggregateSignatures(ctx context.Context, msg *warp.Message, quorumNum uint64, chainIDStr string) (hexutil.Bytes, error) {
chainID := a.runtimeCtx.GetChainID()
if len(chainIDStr) > 0 {
cid, err := ids.FromString(chainIDStr)
@@ -118,7 +118,7 @@ func (a *API) aggregateSignatures(ctx context.Context, core *warp.Core, quorumNu
// Create validator state wrapper for warp messaging
// This handles the special case for Primary Network messages
sourceChainID := core.SourceChainID
sourceChainID := msg.SourceChainID
wrappedState := warpvalidators.NewState(
validatorState,
a.runtimeCtx.GetChainID(),
@@ -165,7 +165,7 @@ func (a *API) aggregateSignatures(ctx context.Context, core *warp.Core, quorumNu
Signers: warp.NewBitSet(),
Signature: [bls.SignatureLen]byte{},
}
initialEnvelope, err := warp.NewEnvelope(core, emptyBeam, nil, nil)
initialEnvelope, err := warp.NewEnvelope(msg, emptyBeam, nil, nil)
if err != nil {
return nil, fmt.Errorf("failed to create initial envelope: %w", err)
}
+3 -3
View File
@@ -24,8 +24,8 @@ const (
// Verify verifies the signature of the message
// It implements the warp.Verifier interface
func (b *backend) Verify(ctx context.Context, core *warp.Core, _ []byte) error {
coreID := core.ID()
func (b *backend) Verify(ctx context.Context, msg *warp.Message, _ []byte) error {
coreID := msg.ID()
messageID := ids.ID(crypto.Keccak256Hash(coreID[:]))
// Known on-chain messages should be signed
if _, err := b.GetMessage(messageID); err == nil {
@@ -34,7 +34,7 @@ func (b *backend) Verify(ctx context.Context, core *warp.Core, _ []byte) error {
return fmt.Errorf("failed to get message %s: %w", messageID, err)
}
parsed, err := payload.ParsePayload(core.Payload)
parsed, err := payload.ParsePayload(msg.Payload)
if err != nil {
b.stats.IncMessageParseFail()
return fmt.Errorf("failed to parse payload: %w", err)