Documentation
¶
Index ¶
- func BridgeExitLeafHash(be *agglayertypes.BridgeExit) common.Hash
- func BridgeExitToLeafData(be *agglayertypes.BridgeExit) bridgesync.LeafData
- func BridgeResponseLeafHash(br *bridgeservicetypes.BridgeResponse) common.Hash
- func BridgeResponseToLeafData(br *bridgeservicetypes.BridgeResponse) bridgesync.LeafData
- func ComputeBackwardLETParams(allLeafHashes []common.Hash, targetIndex uint32) (frontier [32]common.Hash, nextLeaf common.Hash, proof [32]common.Hash, ...)
- func ComputeLERForNewLeaves(existingLeafHashes []common.Hash, newLeafHashes []common.Hash) (common.Hash, error)
- func ExecuteRecovery(ctx context.Context, env *Env, diagnosis *DiagnosisResult) (retErr error)
- func PrintDiagnosis(w io.Writer, result *DiagnosisResult)
- func Run(c *cli.Context) error
- func RunCraftCert(c *cli.Context) error
- func RunSendCert(c *cli.Context) error
- type BackwardForwardLETConfig
- type BridgeExitsOverride
- type Config
- type CraftCertAggsenderConfig
- type DiagnosisResult
- type Env
- type MissingCertInfo
- type RecoveryCase
- type UndercollateralizedToken
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BridgeExitLeafHash ¶
func BridgeExitLeafHash(be *agglayertypes.BridgeExit) common.Hash
BridgeExitLeafHash returns the leaf hash for a BridgeExit using BridgeExit.Hash().
func BridgeExitToLeafData ¶
func BridgeExitToLeafData(be *agglayertypes.BridgeExit) bridgesync.LeafData
BridgeExitToLeafData converts an agglayer BridgeExit to a bridgesync.LeafData.
func BridgeResponseLeafHash ¶
func BridgeResponseLeafHash(br *bridgeservicetypes.BridgeResponse) common.Hash
BridgeResponseLeafHash computes the leaf hash for a BridgeResponse using the same algorithm as BridgeExit.Hash(). The bridge service stores raw metadata (from the BridgeEvent). The contract's getLeafValue takes keccak256(rawMetadata), so we hash it here — matching convertBridgeMetadata in aggsender.
func BridgeResponseToLeafData ¶
func BridgeResponseToLeafData(br *bridgeservicetypes.BridgeResponse) bridgesync.LeafData
BridgeResponseToLeafData converts a bridge service BridgeResponse to a bridgesync.LeafData.
func ComputeBackwardLETParams ¶
func ComputeBackwardLETParams( allLeafHashes []common.Hash, targetIndex uint32, ) (frontier [32]common.Hash, nextLeaf common.Hash, proof [32]common.Hash, err error)
ComputeBackwardLETParams computes the three parameters required for a BackwardLET call:
- frontier: the append-only tree frontier after inserting leaves 0..targetIndex-1
- nextLeaf: the hash of the leaf at targetIndex (the leaf being "rolled back from")
- proof: a Merkle proof that nextLeaf is at targetIndex in the full tree
func ComputeLERForNewLeaves ¶
func ComputeLERForNewLeaves(existingLeafHashes []common.Hash, newLeafHashes []common.Hash) (common.Hash, error)
ComputeLERForNewLeaves computes the LET Merkle root after appending newLeafHashes to an existing tree described by existingLeafHashes.
func ExecuteRecovery ¶
func ExecuteRecovery(ctx context.Context, env *Env, diagnosis *DiagnosisResult) (retErr error)
ExecuteRecovery performs the on-chain recovery steps for the given diagnosis. It activates emergency state (if not already active), runs BackwardLET and/or ForwardLET as required by the case, and deactivates emergency state when done.
func PrintDiagnosis ¶
func PrintDiagnosis(w io.Writer, result *DiagnosisResult)
PrintDiagnosis prints a human-readable diagnosis summary to w.
func RunCraftCert ¶
RunCraftCert is the CLI action for the craft-cert subcommand. It builds a signed malicious certificate JSON for staging drills.
func RunSendCert ¶
RunSendCert is the CLI action for the send-cert subcommand. It reads a certificate from JSON (--cert-json or --cert-file), sends it to the agglayer, and optionally stores it in the aggsender SQLite DB.
Types ¶
type BackwardForwardLETConfig ¶
type BackwardForwardLETConfig struct {
// GERRemoverKey is the signing key used for GER-removal and bridge admin operations.
GERRemoverKey signertypes.SignerConfig `mapstructure:"GERRemoverKey"`
// EmergencyPauserKey is the signing key with activateEmergencyState privileges.
EmergencyPauserKey signertypes.SignerConfig `mapstructure:"EmergencyPauserKey"`
// EmergencyUnpauserKey is the signing key with deactivateEmergencyState privileges.
EmergencyUnpauserKey signertypes.SignerConfig `mapstructure:"EmergencyUnpauserKey"`
// BridgeServiceURL is the URL of the aggkit bridge service REST API (required).
BridgeServiceURL string `mapstructure:"BridgeServiceURL"`
// AggsenderRPCURL is the JSON-RPC URL of the running aggsender (required for certificate queries).
AggsenderRPCURL string `mapstructure:"AggsenderRPCURL"`
// L2NetworkID is the network ID of the L2 chain.
L2NetworkID uint32 `mapstructure:"L2NetworkID"`
// CertificateExitsFile is an optional path to a JSON override file containing
// pre-extracted bridge exits keyed by certificate height. When set, used as a
// fallback if the aggsender RPC cannot supply bridge exits for a height.
// Obtain the file by calling admin_getCertificate on the agglayer for each
// cert ID reported in the tool's missing-cert output.
CertificateExitsFile string `mapstructure:"CertificateExitsFile"`
}
BackwardForwardLETConfig contains configuration specific to the backward/forward LET tool.
type BridgeExitsOverride ¶
type BridgeExitsOverride struct {
NetworkID uint32
Description string
// contains filtered or unexported fields
}
BridgeExitsOverride holds pre-extracted certificate bridge exits keyed by height. Load via LoadBridgeExitsOverride. Use GetExits to retrieve exits for a specific height.
NOTE: the JSON field names follow the Go agglayertypes.BridgeExit json tags (e.g., "dest_network", "dest_address"). The agglayer Rust serde may use different names (e.g., "destination_network"); if so, build the file by marshaling the Certificate.BridgeExits value obtained via json.Unmarshal from the admin API response, not from the raw Rust JSON text.
func LoadBridgeExitsOverride ¶
func LoadBridgeExitsOverride(filePath string) (*BridgeExitsOverride, error)
LoadBridgeExitsOverride reads and validates a JSON override file containing pre-extracted certificate bridge exits keyed by certificate height.
Expected file format (heights are string-keyed; amount is a decimal string):
{
"network_id": 1,
"description": "optional description",
"heights": {
"0": [
{
"leaf_type": 0,
"token_info": { "origin_network": 0, "origin_token_address": "0x..." },
"dest_network": 0,
"dest_address": "0x...",
"amount": "0",
"metadata": null
}
],
"1": []
}
}
Returns an error when:
- the file cannot be read
- the JSON is malformed
- network_id is zero
- the heights map is absent
- any height key is not a non-negative integer
func (*BridgeExitsOverride) GetExits ¶
func (o *BridgeExitsOverride) GetExits(height uint64) ([]*agglayertypes.BridgeExit, bool)
GetExits returns the bridge exits for the given certificate height. The second return value is false when the height has no entry in the override.
type Config ¶
type Config struct {
// Common contains shared settings such as the L2 RPC URL.
Common ethermanconfig.CommonConfig `mapstructure:"Common"`
// BridgeL2Sync contains the L2 bridge contract address used to initialize the binding.
BridgeL2Sync bridgesync.Config `mapstructure:"BridgeL2Sync"`
// AgglayerClient is the AggLayer gRPC client configuration.
AgglayerClient agglayer.ClientConfig `mapstructure:"AgglayerClient"`
// AggSender contains the subset of aggsender config reused by craft-cert signer resolution.
AggSender CraftCertAggsenderConfig `mapstructure:"AggSender"`
// BackwardForwardLET contains tool-specific settings.
BackwardForwardLET BackwardForwardLETConfig `mapstructure:"BackwardForwardLET"`
}
Config holds the subset of aggkit configuration fields required by the backward/forward LET tool.
type CraftCertAggsenderConfig ¶
type CraftCertAggsenderConfig struct {
// AggsenderPrivateKey is the shared signer config used to sign certificates.
AggsenderPrivateKey signertypes.SignerConfig `mapstructure:"AggsenderPrivateKey"`
}
CraftCertAggsenderConfig contains the aggsender signer settings reused by craft-cert.
type DiagnosisResult ¶
type DiagnosisResult struct {
Case RecoveryCase
// L1 settled state (from AggLayer NetworkInfo).
L1SettledLER common.Hash
L1SettledDepositCount uint32 // = SettledLETLeafCount from NetworkInfo
L1SettledHeight uint64
L1SettledCertificateID common.Hash
// L2 on-chain bridge state.
L2CurrentLER common.Hash
L2CurrentDepositCount uint32
// DivergencePoint is the number of leading leaves that match between
// L1 settled and L2 bridge. It is also the target deposit count for BackwardLET.
DivergencePoint uint32
// ExtraL2Bridges contains real L2 bridges (bridgesync.LeafData) after DivergencePoint.
// Populated for Cases 2 and 4.
ExtraL2Bridges []bridgesync.LeafData
// DivergentLeaves are the bridge exits settled on L1 that are absent or different on L2.
DivergentLeaves []*agglayertypes.BridgeExit
// Undercollateralization summarises token under-collateralization from DivergentLeaves.
Undercollateralization []UndercollateralizedToken
// IsEmergencyState reports whether the L2 bridge is already paused.
IsEmergencyState bool
// AggsenderAPIFailed is set when the aggsender RPC was unreachable during the divergence walk.
AggsenderAPIFailed bool
// MissingCerts lists the certificate heights for which no bridge exit data
// was available. Populated when AggsenderAPIFailed is true.
// The operator should fetch each cert from the agglayer admin API using
// the provided CertID, then supply a JSON override file.
MissingCerts []MissingCertInfo
// Deprecated: use MissingCerts instead. FailedCertHeight is the first height
// for which no bridge exit data was available.
FailedCertHeight uint64
// Deprecated: use MissingCerts instead. FailedCertID is the cert ID for
// FailedCertHeight, if it could be resolved.
FailedCertID common.Hash
}
DiagnosisResult holds the complete output of the diagnosis phase.
func Diagnose ¶
func Diagnose(ctx context.Context, env *Env) (*DiagnosisResult, error)
Diagnose compares the AggLayer's settled L1 state against L2's on-chain bridge state, classifies the divergence into one of 4 runbook cases, and returns a DiagnosisResult.
func (*DiagnosisResult) IsCompleteNoDivergence ¶
func (d *DiagnosisResult) IsCompleteNoDivergence() bool
IsCompleteNoDivergence reports whether diagnosis completed successfully and confirmed there is no divergence between settled L1 state and the L2 bridge.
type Env ¶
type Env struct {
// L2Client is the L2 Ethereum RPC client.
L2Client *ethclient.Client
// BridgeService is the aggkit bridge service REST client.
BridgeService bridgeServiceClient
// AgglayerClient is the gRPC client for the AggLayer node.
AgglayerClient agglayer.AgglayerClientInterface
// AggsenderRPC is the JSON-RPC client for the running aggsender process.
AggsenderRPC aggsenderRPCClient
// BridgeExitsOverride is loaded from CertificateExitsFile if configured.
// nil when no override file is specified.
BridgeExitsOverride *BridgeExitsOverride
// L2Bridge is the bound L2 bridge contract.
L2Bridge l2BridgeContract
// L2NetworkID is the network ID of the L2 chain.
L2NetworkID uint32
// Config holds the loaded configuration.
Config *Config
// contains filtered or unexported fields
}
Env holds all connections and contract bindings needed by the backward/forward LET tool.
type MissingCertInfo ¶
type MissingCertInfo struct {
// Height is the certificate height that is missing.
Height uint64
// CertID is the agglayer CertificateId for this height, if it could be
// resolved via the public gRPC. Zero-value when not resolvable.
CertID common.Hash
// CertIDResolved is true when CertID was successfully resolved.
// When false, the operator must contact the agglayer admin.
CertIDResolved bool
}
MissingCertInfo describes a certificate height for which bridge exits could not be obtained from any available source.
type RecoveryCase ¶
type RecoveryCase string
RecoveryCase classifies the divergence between the L1 settled LET and the L2 bridge state.
const ( // NoDivergence indicates L1 settled state and L2 on-chain state are in sync. NoDivergence RecoveryCase = "NoDivergence" // Case1 is ForwardLET only — a single divergent leaf batch, no extra L2 bridges. Case1 RecoveryCase = "Case1" // Case2 is BackwardLET + ForwardLET — single divergent leaf + extra real L2 bridges. Case2 RecoveryCase = "Case2" // Case3 is ForwardLET only — multiple divergent leaf batches, no extra L2 bridges. Case3 RecoveryCase = "Case3" // Case4 is BackwardLET + ForwardLET — multiple divergent leaves + extra real L2 bridges. Case4 RecoveryCase = "Case4" )