-
Notifications
You must be signed in to change notification settings - Fork 114
feat: multichain interfaces #477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| /// @notice A contract that calculates the weights for all operators in a given operatorSet | ||
| /// @notice This is a base interface to send operator weights to the `IOperatorTableCalculator` | ||
| /// @notice We separate this out to be able to plug-in different operator weight calculators for each operatorSet | ||
| interface IOperatorWeightCalculator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Separate external calculator contract per operatorSet. The TableCalculator is global for all operatorSets. The IOperatorWeightCalculator is for a single operatorSet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So many contracts :( can we just put it all in this thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes we can, but leaving decoupled for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like we want abstract contracts rather than interfaces? maybe im being pedantic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the current impl has abstract contracts. We definitely can implement it that way
| /// @notice the address of the entity that can eject operators | ||
| function ejector() external returns (address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Curious why the Ejector is in this contract vs something like the AVSRegistrar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to eject on L2s, and the AVSRegistrar isn't there
**Motivation:**
Initial interfaces for multi chain.
**Modifications:**
***TableCalculator***
The separation here is designed to decouple
- Curve-Specific Calculation
- Generic Table Calculation Getters (applicable for all curve types)
- Weighting. `IOperatorWeightCalculator` is a calculation contract that
defines how to weigh stakes of an operatorSet. This contract may or may
not be stateless. In practice, this can be an external contract or
library.
```mermaid
classDiagram
IOperatorWeightCalculator <-- IOperatorTableCalculator : uses many
IOperatorTableCalculator <|-- IECDSATableCalculator : implements
IOperatorTableCalculator <|-- IBN254TableCalculator : implements
class IOperatorWeightCalculator {
+getOperatorWeights(OperatorSet)
}
class IOperatorTableCalculator {
+setOperatorWeightCalculator(OperatorSet, IOperatorWeightCalculator)
+calculateOperatorTableBytes(OperatorSet) returns (bytes)
+getOperatorWeightCalculator(OperatorSet) returns (IOperatorWeightCalculator)
}
class IECDSATableCalculator {
+calculateOperatorTable(OperatorSet) returns (ECDSAOperatorInfo[])
}
class IBN254TableCalculator {
+calculateOperatorTable(OperatorSet) returns (BN254OperatorSetInfo)
+getOperatorInfos(OperatorSet) returns (BN254OperatorInfo[])
}
```
***CertificateVerifier***
The `CertificateVerifier` decouples setting of the table and
verification. See below:
```mermaid
classDiagram
ICertificateVerifier <|-- IBN254CertificateVerifier: implements
IBN254TableManager <|-- IBN254CertificateVerifier: implements
class ICertificateVerifier {
<<interface>>
+setOperatorTableUpdater(address)
+setEjector(address)
+setMaxOperatorTableStaleness(uint32)
+operatorSet() returns (OperatorSet)
+operatorTableUpdater() returns (address)
+ejector() returns (address)
+maxOperatorTableStaleness() returns (uint32)
+latestReferenceTimestamp() returns (uint32)
}
class IBN254TableManager {
<<interface>>
+updateOperatorTable(OperatorSet, uint32, BN254OperatorSetInfo)
+ejectOperators(OperatorSet, uint32, uint32[], BN254OperatorInfoWitness[])
}
class IBN254CertificateVerifier {
<<interface>>
+verifyCertificate(BN254Certificate) returns (uint96[])
+verifyCertificateProportion(BN254Certificate, uint16[]) returns (bool)
+verifyCertificateNominal(BN254Certificate, uint96[]) returns (bool)
}
```
***Migration Story***
We want a migration path to store all tables in a singleton core
contract. In order to do so, we future-proofed the _transportation_
interface to pass in an `operatorSet` when updating an operatorTable.
Permissions setting can be done by an EOA, so we don't need to make that
forwards compatible. If all the tables live in a single contract, then
for Bn254 caching, the verification must cache stakes in the singleton.
**Result:**
Initial Interfaces. I see these changing for the following reasons:
- Encoding leafs with a salt
- Table generation-based trusted operator table updates
- Multiquorum sig support (but EigenDA can build their own)
Motivation:
Initial interfaces for multi chain.
Modifications:
TableCalculator
The separation here is designed to decouple
IOperatorWeightCalculatoris a calculation contract that defines how to weigh stakes of an operatorSet. This contract may or may not be stateless. In practice, this can be an external contract or library.classDiagram IOperatorWeightCalculator <-- IOperatorTableCalculator : uses many IOperatorTableCalculator <|-- IECDSATableCalculator : implements IOperatorTableCalculator <|-- IBN254TableCalculator : implements class IOperatorWeightCalculator { +getOperatorWeights(OperatorSet) } class IOperatorTableCalculator { +setOperatorWeightCalculator(OperatorSet, IOperatorWeightCalculator) +calculateOperatorTableBytes(OperatorSet) returns (bytes) +getOperatorWeightCalculator(OperatorSet) returns (IOperatorWeightCalculator) } class IECDSATableCalculator { +calculateOperatorTable(OperatorSet) returns (ECDSAOperatorInfo[]) } class IBN254TableCalculator { +calculateOperatorTable(OperatorSet) returns (BN254OperatorSetInfo) +getOperatorInfos(OperatorSet) returns (BN254OperatorInfo[]) }CertificateVerifier
The
CertificateVerifierdecouples setting of the table and verification. See below:classDiagram ICertificateVerifier <|-- IBN254CertificateVerifier: implements IBN254TableManager <|-- IBN254CertificateVerifier: implements class ICertificateVerifier { <<interface>> +setOperatorTableUpdater(address) +setEjector(address) +setMaxOperatorTableStaleness(uint32) +operatorSet() returns (OperatorSet) +operatorTableUpdater() returns (address) +ejector() returns (address) +maxOperatorTableStaleness() returns (uint32) +latestReferenceTimestamp() returns (uint32) } class IBN254TableManager { <<interface>> +updateOperatorTable(OperatorSet, uint32, BN254OperatorSetInfo) +ejectOperators(OperatorSet, uint32, uint32[], BN254OperatorInfoWitness[]) } class IBN254CertificateVerifier { <<interface>> +verifyCertificate(BN254Certificate) returns (uint96[]) +verifyCertificateProportion(BN254Certificate, uint16[]) returns (bool) +verifyCertificateNominal(BN254Certificate, uint96[]) returns (bool) }Migration Story
We want a migration path to store all tables in a singleton core contract. In order to do so, we future-proofed the transportation interface to pass in an
operatorSetwhen updating an operatorTable. Permissions setting can be done by an EOA, so we don't need to make that forwards compatible. If all the tables live in a single contract, then for Bn254 caching, the verification must cache stakes in the singleton.Result:
Initial Interfaces. I see these changing for the following reasons: