Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/test-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
fi
else
# For push/workflow_dispatch, use the fixed commit
COMMIT="5921c65d96e674b742080ceb5d19acc0e83ed0a9"
COMMIT="346e6c76bce576f29300a7de2d3b6efca09d9fdb"
echo "Using fixed kurtosis-cdk commit: ${COMMIT}"
fi
echo "commit=${COMMIT}" >> $GITHUB_OUTPUT
Expand Down
2 changes: 1 addition & 1 deletion agglayer/grpc/conversion_to_agglayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func grpcAggchainDataToAgglayer(
aggchainData *v1types.AggchainData,
) (agglayertypes.AggchainData, error) {
if aggchainData == nil || aggchainData.Data == nil {
return nil, fmt.Errorf("grpcAggchainDataToAgglayer. aggchain data is nil. %w", ErrNilCertificate)
return nil, nil
}

switch ad := aggchainData.Data.(type) {
Expand Down
7 changes: 3 additions & 4 deletions agglayer/grpc/conversion_to_agglayer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,13 @@ func TestConvertProtoCertToAgglayer(t *testing.T) {
require.ErrorContains(t, err, "has nil L1InfoTreeLeafCount")
})

t.Run("nil AggchainData", func(t *testing.T) {
t.Run("undefined AggchainData", func(t *testing.T) {
protoCert, err := ConvertCertToProtoCertificate(exampleTestAgglayerCert)
require.NoError(t, err)
protoCert.AggchainData = nil
result, err := ConvertProtoCertToAgglayer(protoCert)
require.Nil(t, result)
require.ErrorIs(t, err, ErrNilCertificate)
require.ErrorContains(t, err, "aggchain data is nil")
require.NoError(t, err)
require.Nil(t, result.AggchainData)
})

t.Run("successful conversion", func(t *testing.T) {
Expand Down
16 changes: 16 additions & 0 deletions agglayer/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,22 @@ func (c *Certificate) CertificateID() common.Hash {
)
}

// ExtractAggchainParams extracts the aggchain params field from the certificate
// with handling different types of aggchain data.
func (c *Certificate) ExtractAggchainParams() []byte {
switch data := c.AggchainData.(type) {
case *AggchainDataProof:
return data.AggchainParams.Bytes()

case *AggchainDataMultisigWithProof:
if data.AggchainProof != nil {
return data.AggchainProof.AggchainParams.Bytes()
}
}

return aggkitcommon.ZeroHash.Bytes()
}

// SignedCertificate is the struct that contains the certificate and the signature of the signer
// NOTE: this is an old and deprecated struct, only to be used for backward compatibility
type SignedCertificate struct {
Expand Down
52 changes: 51 additions & 1 deletion agglayer/types/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestCertificateHeaderString(t *testing.T) {
require.Equal(t, "nil", certNil.String())
}

func TestMarshalJSON(t *testing.T) {
func TestCertificateMarshalJSON(t *testing.T) {
t.Parallel()

t.Run("MarshalJSON with empty proofs", func(t *testing.T) {
Expand Down Expand Up @@ -269,6 +269,56 @@ func TestMarshalJSON(t *testing.T) {
})
}

func TestCertificate_ExtractAggchainParams(t *testing.T) {
hash1 := common.HexToHash("0x1111")
hash2 := common.HexToHash("0x2222")

tests := []struct {
name string
data AggchainData
expected []byte
}{
{
name: "AggchainDataProof returns its params",
data: &AggchainDataProof{
AggchainParams: hash1,
},
expected: hash1.Bytes(),
},
{
name: "AggchainDataMultisigWithProof returns nested params",
data: &AggchainDataMultisigWithProof{
AggchainProof: &AggchainDataProof{
AggchainParams: hash2,
},
},
expected: hash2.Bytes(),
},
{
name: "AggchainDataMultisigWithProof with nil proof returns ZeroHash",
data: &AggchainDataMultisigWithProof{
AggchainProof: nil,
},
expected: aggkitcommon.ZeroHash.Bytes(),
},
{
name: "Nil AggchainData returns ZeroHash",
data: nil,
expected: aggkitcommon.ZeroHash.Bytes(),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cert := &Certificate{
AggchainData: tt.data,
}
actual := cert.ExtractAggchainParams()
require.Equal(t, tt.expected, actual)
})
}
}

func TestGlobalIndex_UnmarshalFromMap(t *testing.T) {
t.Parallel()

Expand Down
21 changes: 10 additions & 11 deletions aggsender/flows/flow_aggchain_prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,28 +328,27 @@ func (a *AggchainProverFlow) BuildCertificate(ctx context.Context,
return cert, nil
}

// UpdateAggchainData updates the AggchainData field in certificate with the multisig if needed
// UpdateAggchainData updates the AggchainData field in certificate with the multisig if provided.
func (a *AggchainProverFlow) UpdateAggchainData(
cert *agglayertypes.Certificate,
multisig *agglayertypes.Multisig,
) error {
if multisig == nil {
// multisig not turned on, we don't need to update the certificate
// Multisig not enabled, nothing to do
return nil
}

proof, ok := cert.AggchainData.(*agglayertypes.AggchainDataProof)
if !ok {
proofWithMultisig, ok := cert.AggchainData.(*agglayertypes.AggchainDataMultisigWithProof)
if !ok {
return errors.New("aggchainProverFlow - aggchain data field not " +
"AggchainDataProof nor AggchainDataMultisigWithProof")
}
var proof *agglayertypes.AggchainDataProof

proof = proofWithMultisig.AggchainProof
switch data := cert.AggchainData.(type) {
case *agglayertypes.AggchainDataProof:
proof = data
case *agglayertypes.AggchainDataMultisigWithProof:
proof = data.AggchainProof
default:
return fmt.Errorf("aggchainProverFlow: AggchainData of unknown type %T received", data)
}

// update the agchain data with multisig
cert.AggchainData = &agglayertypes.AggchainDataMultisigWithProof{
Multisig: multisig,
AggchainProof: proof,
Expand Down
2 changes: 1 addition & 1 deletion aggsender/flows/flow_aggchain_prover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -899,7 +899,7 @@ func Test_AggchainProverFlow_UpdateAggchainData(t *testing.T) {
AggchainData: &agglayertypes.AggchainDataSignature{}, // wrong type
},
multisig: &agglayertypes.Multisig{},
expectedError: "aggchainProverFlow - aggchain data field not AggchainDataProof",
expectedError: "aggchainProverFlow: AggchainData of unknown type *types.AggchainDataSignature received",
},
{
name: "successful update - wraps proof with multisig",
Expand Down
28 changes: 18 additions & 10 deletions aggsender/query/certificate_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,28 @@ func (c *certificateQuerier) GetNewCertificateToBlock(
return max(lastBridgeExitBlock, lastImportedBridgeExitBlock), nil
}

// CalculateCertificateType determines the type of certificate based on the last block number in certificate
// CalculateCertificateType determines the type of certificate.
// If AggchainData is present, the type is inferred from its variant (PP or FEP).
// Otherwise, it is derived from the last block number in certificate
func (c *certificateQuerier) CalculateCertificateType(
cert *agglayertypes.Certificate, certToBlock uint64) types.CertificateType {
if cert.AggchainData != nil {
// if AggchainData is present, we can use it to determine the certificate type
_, ok := cert.AggchainData.(*agglayertypes.AggchainDataProof)
if !ok {
return types.CertificateTypeFEP
}

cert *agglayertypes.Certificate, certToBlock uint64,
) types.CertificateType {
switch cert.AggchainData.(type) {
case *agglayertypes.AggchainDataSignature:
// AggchainDataSignature β†’ PP type
return types.CertificateTypePP
case *agglayertypes.AggchainDataMultisig:
// AggchainDataMultisig β†’ PP type
return types.CertificateTypePP
case *agglayertypes.AggchainDataProof:
// AggchainDataProof β†’ FEP type
return types.CertificateTypeFEP
case *agglayertypes.AggchainDataMultisigWithProof:
// AggchainDataMultisigWithProof β†’ FEP type
return types.CertificateTypeFEP
}

// if AggchainData is not present, must try to determine the type based on the block number
// no AggchainData β†’ fallback on block-based logic
return c.CalculateCertificateTypeFromToBlock(certToBlock)
}

Expand Down
24 changes: 20 additions & 4 deletions aggsender/query/certificate_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,21 +504,37 @@ func TestCalculateCertificateType(t *testing.T) {
expectedCertType types.CertificateType
}{
{
name: "AggchainData is AggchainDataProof - returns PP",
name: "AggchainData is AggchainDataProof - returns FEP",
certificate: &agglayertypes.Certificate{
AggchainData: &agglayertypes.AggchainDataProof{},
},
certToBlock: 100,
expectedCertType: types.CertificateTypePP,
expectedCertType: types.CertificateTypeFEP,
},
{
name: "AggchainData is not AggchainDataProof - returns FEP",
name: "AggchainData is AggchainDataMultisigWithProof - returns FEP",
certificate: &agglayertypes.Certificate{
AggchainData: &agglayertypes.AggchainDataSignature{},
AggchainData: &agglayertypes.AggchainDataMultisigWithProof{},
},
certToBlock: 100,
expectedCertType: types.CertificateTypeFEP,
},
{
name: "AggchainData is AggchainDataSignature - returns PP",
certificate: &agglayertypes.Certificate{
AggchainData: &agglayertypes.AggchainDataSignature{},
},
certToBlock: 100,
expectedCertType: types.CertificateTypePP,
},
{
name: "AggchainData is AggchainDataMultisig - returns PP",
certificate: &agglayertypes.Certificate{
AggchainData: &agglayertypes.AggchainDataMultisig{},
},
certToBlock: 100,
expectedCertType: types.CertificateTypePP,
},
{
name: "AggchainData is nil - falls back to CalculateCertificateTypeFromToBlock with FEP network and block before start",
certificate: &agglayertypes.Certificate{
Expand Down
19 changes: 1 addition & 18 deletions aggsender/validator/cert_hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ func HashCertificateToSign(cert *agglayertypes.Certificate) (common.Hash, error)
}

claimsHash := crypto.Keccak256(claimsRawMetadata)

aggchainParams := getAggchainParams(cert)
aggchainParams := cert.ExtractAggchainParams()

return crypto.Keccak256Hash(
cert.NewLocalExitRoot.Bytes(),
Expand All @@ -33,19 +32,3 @@ func HashCertificateToSign(cert *agglayertypes.Certificate) (common.Hash, error)
cert.CertificateID().Bytes(),
), nil
}

// getAggchainParams extracts the aggchain params field from the certificate
// with handling different types of aggchain data.
func getAggchainParams(cert *agglayertypes.Certificate) []byte {
aggchainDataProof, ok := cert.AggchainData.(*agglayertypes.AggchainDataProof)
if ok {
return aggchainDataProof.AggchainParams.Bytes()
}

aggchainDataProofWithMultisig, ok := cert.AggchainData.(*agglayertypes.AggchainDataMultisigWithProof)
if ok && aggchainDataProofWithMultisig.AggchainProof != nil {
return aggchainDataProofWithMultisig.AggchainProof.AggchainParams.Bytes()
}

return aggkitcommon.ZeroHash.Bytes()
}
Loading