Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix: Various pessimistic proofs fixes and adaption to kurtosis-cdk pessimistic proof branch #165

Merged
merged 27 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c26a5ac
fix: certificate with no importedBridges set '[]' instead of 'null'
joanestebanr Nov 5, 2024
2e1e18f
fix: certificate with no importedBridges set '[]' instead of 'null'
joanestebanr Nov 5, 2024
77d12dd
feat: adapt to kurtosis-cdk pp
joanestebanr Nov 5, 2024
6d775da
feat: change para SaveCertificatesToFiles to SaveCertificatesToFilesPath
joanestebanr Nov 6, 2024
210ef4b
fix: get candidate and proven certificates as well
goran-ethernal Nov 6, 2024
73dfe95
fix: remove test
goran-ethernal Nov 6, 2024
ef4fe29
fix: small changes
goran-ethernal Nov 7, 2024
5e44136
fix: db tx rollback
goran-ethernal Nov 7, 2024
70aaaaf
fix: replace existing certificate
goran-ethernal Nov 7, 2024
4c22558
fix: lint and coverage
goran-ethernal Nov 7, 2024
f623931
feat: check for nil fields in certificate
goran-ethernal Nov 7, 2024
7623316
feat: no claims test
goran-ethernal Nov 7, 2024
e2ff575
fix: comments
goran-ethernal Nov 7, 2024
a6e0778
fix: lint
goran-ethernal Nov 7, 2024
0d5f454
fix: shallow copy imported bridge exits and bridge exits
goran-ethernal Nov 7, 2024
c432bab
fix: local_config for debug
joanestebanr Nov 7, 2024
eb4bc3a
fix: cdk-erigon-node-001 rename to cdk-erigon-rpc-001
joanestebanr Nov 7, 2024
82ff40a
feat: add logs to check cert
joanestebanr Nov 8, 2024
c221101
feat: store hash as text, add logs
joanestebanr Nov 8, 2024
3a8f991
fix: lint
joanestebanr Nov 8, 2024
824d6ed
fix: bump kurtosis-cdk version to 0.2.18
joanestebanr Nov 8, 2024
db602e6
fix: comments
goran-ethernal Nov 8, 2024
ef1b9bf
fix: string conversion error on BridgeExit
joanestebanr Nov 8, 2024
6254a2c
fix: lint
goran-ethernal Nov 8, 2024
d20473a
fix: update minter key
vcastellm Nov 8, 2024
dcbd607
fix: e2e
joanestebanr Nov 8, 2024
a80899a
fix: e2e tests
goran-ethernal Nov 8, 2024
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 @@ -70,7 +70,7 @@ jobs:
with:
repository: 0xPolygon/kurtosis-cdk
path: "kurtosis-cdk"
ref: "v0.2.15"
ref: "v0.2.18"

- name: Setup Bats and bats libs
uses: bats-core/bats-action@2.0.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-resequence.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
run: |
mkdir -p ci_logs
cd ci_logs
kurtosis service logs cdk-v1 cdk-erigon-node-001 --all > cdk-erigon-node-001.log
kurtosis service logs cdk-v1 cdk-erigon-rpc-001 --all > cdk-erigon-rpc-001.log
kurtosis service logs cdk-v1 cdk-erigon-sequencer-001 --all > cdk-erigon-sequencer-001.log
kurtosis service logs cdk-v1 zkevm-agglayer-001 --all > zkevm-agglayer-001.log
kurtosis service logs cdk-v1 zkevm-prover-001 --all > zkevm-prover-001.log
Expand Down
4 changes: 3 additions & 1 deletion agglayer/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ func (c *AggLayerClient) WaitTxToBeMined(hash common.Hash, ctx context.Context)

// SendCertificate sends a certificate to the AggLayer
func (c *AggLayerClient) SendCertificate(certificate *SignedCertificate) (common.Hash, error) {
response, err := rpc.JSONRPCCall(c.url, "interop_sendCertificate", certificate)
certificateToSend := certificate.CopyWithDefaulting()

response, err := rpc.JSONRPCCall(c.url, "interop_sendCertificate", certificateToSend)
if err != nil {
return common.Hash{}, err
}
Expand Down
127 changes: 127 additions & 0 deletions agglayer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ type Certificate struct {
Metadata common.Hash `json:"metadata"`
}

func (c *Certificate) String() string {
res := fmt.Sprintf("NetworkID: %d, Height: %d, PrevLocalExitRoot: %s, NewLocalExitRoot: %s, Metadata: %s\n",
c.NetworkID, c.Height, common.Bytes2Hex(c.PrevLocalExitRoot[:]),
common.Bytes2Hex(c.NewLocalExitRoot[:]), common.Bytes2Hex(c.Metadata[:]))

if c.BridgeExits == nil {
res += " BridgeExits: nil\n"
} else {
for i, bridgeExit := range c.BridgeExits {
res += fmt.Sprintf(", BridgeExit[%d]: %s\n", i, bridgeExit.String())
}
}

if c.ImportedBridgeExits == nil {
res += " ImportedBridgeExits: nil\n"
} else {
for i, importedBridgeExit := range c.ImportedBridgeExits {
res += fmt.Sprintf(" ImportedBridgeExit[%d]: %s\n", i, importedBridgeExit.String())
}
}

return res
}

// Hash returns a hash that uniquely identifies the certificate
func (c *Certificate) Hash() common.Hash {
bridgeExitsHashes := make([][]byte, len(c.BridgeExits))
Expand Down Expand Up @@ -131,19 +155,54 @@ type SignedCertificate struct {
Signature *Signature `json:"signature"`
}

func (s *SignedCertificate) String() string {
return fmt.Sprintf("Certificate:%s,\nSignature: %s", s.Certificate.String(), s.Signature.String())
}

// CopyWithDefaulting returns a shallow copy of the signed certificate
func (s *SignedCertificate) CopyWithDefaulting() *SignedCertificate {
certificateCopy := *s.Certificate

if certificateCopy.BridgeExits == nil {
certificateCopy.BridgeExits = make([]*BridgeExit, 0)
}

if certificateCopy.ImportedBridgeExits == nil {
certificateCopy.ImportedBridgeExits = make([]*ImportedBridgeExit, 0)
}

signature := s.Signature
if signature == nil {
signature = &Signature{}
}

return &SignedCertificate{
Certificate: &certificateCopy,
Signature: signature,
}
}

// Signature is the data structure that will hold the signature of the given certificate
type Signature struct {
R common.Hash `json:"r"`
S common.Hash `json:"s"`
OddParity bool `json:"odd_y_parity"`
}

func (s *Signature) String() string {
return fmt.Sprintf("R: %s, S: %s, OddParity: %t", s.R.String(), s.S.String(), s.OddParity)
}

// TokenInfo encapsulates the information to uniquely identify a token on the origin network.
type TokenInfo struct {
OriginNetwork uint32 `json:"origin_network"`
OriginTokenAddress common.Address `json:"origin_token_address"`
}

func (t *TokenInfo) String() string {
return fmt.Sprintf("OriginNetwork: %d, OriginTokenAddress: %s", t.OriginNetwork, t.OriginTokenAddress.String())
}

// GlobalIndex represents the global index of an imported bridge exit
type GlobalIndex struct {
MainnetFlag bool `json:"mainnet_flag"`
Expand All @@ -159,6 +218,11 @@ func (g *GlobalIndex) Hash() common.Hash {
)
}

func (g *GlobalIndex) String() string {
return fmt.Sprintf("MainnetFlag: %t, RollupIndex: %d, LeafIndex: %d",
g.MainnetFlag, g.RollupIndex, g.LeafIndex)
}

// BridgeExit represents a token bridge exit
type BridgeExit struct {
LeafType LeafType `json:"leaf_type"`
Expand All @@ -169,6 +233,20 @@ type BridgeExit struct {
Metadata []byte `json:"metadata"`
}

func (b *BridgeExit) String() string {
res := fmt.Sprintf("LeafType: %s, DestinationNetwork: %d, DestinationAddress: %s, Amount: %s, Metadata: %s",
b.LeafType.String(), b.DestinationNetwork, b.DestinationAddress.String(),
b.Amount.String(), common.Bytes2Hex(b.Metadata))

if b.TokenInfo == nil {
res += ", TokenInfo: nil"
} else {
res += fmt.Sprintf(", TokenInfo: %s", b.TokenInfo.String())
}

return res
}

// Hash returns a hash that uniquely identifies the bridge exit
func (b *BridgeExit) Hash() common.Hash {
if b.Amount == nil {
Expand Down Expand Up @@ -252,6 +330,10 @@ func (m *MerkleProof) Hash() common.Hash {
)
}

func (m *MerkleProof) String() string {
return fmt.Sprintf("Root: %s, Proof: %v", m.Root.String(), m.Proof)
}

// L1InfoTreeLeafInner represents the inner part of the L1 info tree leaf
type L1InfoTreeLeafInner struct {
GlobalExitRoot common.Hash `json:"global_exit_root"`
Expand Down Expand Up @@ -281,6 +363,11 @@ func (l *L1InfoTreeLeafInner) MarshalJSON() ([]byte, error) {
})
}

func (l *L1InfoTreeLeafInner) String() string {
return fmt.Sprintf("GlobalExitRoot: %s, BlockHash: %s, Timestamp: %d",
l.GlobalExitRoot.String(), l.BlockHash.String(), l.Timestamp)
}

// L1InfoTreeLeaf represents the leaf of the L1 info tree
type L1InfoTreeLeaf struct {
L1InfoTreeIndex uint32 `json:"l1_info_tree_index"`
Expand All @@ -294,11 +381,21 @@ func (l *L1InfoTreeLeaf) Hash() common.Hash {
return l.Inner.Hash()
}

func (l *L1InfoTreeLeaf) String() string {
return fmt.Sprintf("L1InfoTreeIndex: %d, RollupExitRoot: %s, MainnetExitRoot: %s, Inner: %s",
l.L1InfoTreeIndex,
common.Bytes2Hex(l.RollupExitRoot[:]),
common.Bytes2Hex(l.MainnetExitRoot[:]),
l.Inner.String(),
)
}

// Claim is the interface that will be implemented by the different types of claims
type Claim interface {
Type() string
Hash() common.Hash
MarshalJSON() ([]byte, error)
String() string
}

// ClaimFromMainnnet represents a claim originating from the mainnet
Expand Down Expand Up @@ -335,6 +432,11 @@ func (c *ClaimFromMainnnet) Hash() common.Hash {
)
}

func (c *ClaimFromMainnnet) String() string {
return fmt.Sprintf("ProofLeafMER: %s, ProofGERToL1Root: %s, L1Leaf: %s",
c.ProofLeafMER.String(), c.ProofGERToL1Root.String(), c.L1Leaf.String())
}

// ClaimFromRollup represents a claim originating from a rollup
type ClaimFromRollup struct {
ProofLeafLER *MerkleProof `json:"proof_leaf_ler"`
Expand Down Expand Up @@ -372,13 +474,38 @@ func (c *ClaimFromRollup) Hash() common.Hash {
)
}

func (c *ClaimFromRollup) String() string {
return fmt.Sprintf("ProofLeafLER: %s, ProofLERToRER: %s, ProofGERToL1Root: %s, L1Leaf: %s",
c.ProofLeafLER.String(), c.ProofLERToRER.String(), c.ProofGERToL1Root.String(), c.L1Leaf.String())
}

// ImportedBridgeExit represents a token bridge exit originating on another network but claimed on the current network.
type ImportedBridgeExit struct {
BridgeExit *BridgeExit `json:"bridge_exit"`
ClaimData Claim `json:"claim_data"`
GlobalIndex *GlobalIndex `json:"global_index"`
}

func (c *ImportedBridgeExit) String() string {
var res string

if c.BridgeExit == nil {
res = "BridgeExit: nil"
} else {
res = fmt.Sprintf("BridgeExit: %s", c.BridgeExit.String())
}

if c.GlobalIndex == nil {
res += ", GlobalIndex: nil"
} else {
res += fmt.Sprintf(", GlobalIndex: %s", c.GlobalIndex.String())
}

res += fmt.Sprintf("ClaimData: %s", c.ClaimData.String())

return res
}

// Hash returns a hash that uniquely identifies the imported bridge exit
func (c *ImportedBridgeExit) Hash() common.Hash {
return crypto.Keccak256Hash(
Expand Down
88 changes: 88 additions & 0 deletions agglayer/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,91 @@ func TestMarshalJSON(t *testing.T) {
log.Info(string(data))
require.Equal(t, expectedSignedCertificateyMetadataJSON, string(data))
}

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

t.Run("copy with non-nil fields", func(t *testing.T) {
t.Parallel()

original := &SignedCertificate{
Certificate: &Certificate{
NetworkID: 1,
Height: 100,
PrevLocalExitRoot: [32]byte{0x01},
NewLocalExitRoot: [32]byte{0x02},
BridgeExits: []*BridgeExit{
{
LeafType: LeafTypeAsset,
TokenInfo: &TokenInfo{OriginNetwork: 1, OriginTokenAddress: common.HexToAddress("0x123")},
DestinationNetwork: 2,
DestinationAddress: common.HexToAddress("0x456"),
Amount: big.NewInt(1000),
Metadata: []byte{0x01, 0x02},
},
},
ImportedBridgeExits: []*ImportedBridgeExit{
{
BridgeExit: &BridgeExit{
LeafType: LeafTypeMessage,
TokenInfo: &TokenInfo{OriginNetwork: 1, OriginTokenAddress: common.HexToAddress("0x789")},
DestinationNetwork: 3,
DestinationAddress: common.HexToAddress("0xabc"),
Amount: big.NewInt(2000),
Metadata: []byte{0x03, 0x04},
},
ClaimData: &ClaimFromMainnnet{},
GlobalIndex: &GlobalIndex{MainnetFlag: true, RollupIndex: 1, LeafIndex: 2},
},
},
Metadata: common.HexToHash("0xdef"),
},
Signature: &Signature{
R: common.HexToHash("0x111"),
S: common.HexToHash("0x222"),
OddParity: true,
},
}

certificateCopy := original.CopyWithDefaulting()

require.NotNil(t, certificateCopy)
require.NotSame(t, original, certificateCopy)
require.NotSame(t, original.Certificate, certificateCopy.Certificate)
require.Same(t, original.Signature, certificateCopy.Signature)
require.Equal(t, original, certificateCopy)
})

t.Run("copy with nil BridgeExits, ImportedBridgeExits and Signature", func(t *testing.T) {
t.Parallel()

original := &SignedCertificate{
Certificate: &Certificate{
NetworkID: 1,
Height: 100,
PrevLocalExitRoot: [32]byte{0x01},
NewLocalExitRoot: [32]byte{0x02},
BridgeExits: nil,
ImportedBridgeExits: nil,
Metadata: common.HexToHash("0xdef"),
},
Signature: nil,
}

certificateCopy := original.CopyWithDefaulting()

require.NotNil(t, certificateCopy)
require.NotSame(t, original, certificateCopy)
require.NotSame(t, original.Certificate, certificateCopy.Certificate)
require.NotNil(t, certificateCopy.Signature)
require.Equal(t, original.NetworkID, certificateCopy.NetworkID)
require.Equal(t, original.Height, certificateCopy.Height)
require.Equal(t, original.PrevLocalExitRoot, certificateCopy.PrevLocalExitRoot)
require.Equal(t, original.NewLocalExitRoot, certificateCopy.NewLocalExitRoot)
require.Equal(t, original.Metadata, certificateCopy.Metadata)
require.NotNil(t, certificateCopy.BridgeExits)
require.NotNil(t, certificateCopy.ImportedBridgeExits)
require.Empty(t, certificateCopy.BridgeExits)
require.Empty(t, certificateCopy.ImportedBridgeExits)
})
}
Loading
Loading