-
Notifications
You must be signed in to change notification settings - Fork 34
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
feat: Initial V2 E2E Prototype #260
base: eigenda_v2
Are you sure you want to change the base?
Conversation
* fix(#251): better error logging for RPC lookup errors against service manager (#254) * chore: modify verifier to not require eth archive node (#241) * chore: force verifier's EthConfirmationDepth to be <64 We panic in the flag's action, as well as in the verifier's constructor when this condition is not respected. This will make sure that an archival node is not required. * chore: modify verifier to load quorum parameters only once at initialization This removes the need for running with an eth archive node. * style: fix minor lint issue * docs: update README to mention that archival node is no longer needed * docs: clean-up README archival node requirement explanation * docs: fix verify/cert.go comment typo Co-authored-by: Ethen <[email protected]> * docs: for eg -> e.g. * style(cert): remove unecessary bound checks from inside loop * style: create consts package with EthHappyPathFinalizationDepthBlocks = 64 * style: change panic into error return * docs: change op reference for eth reference * docs: make flag comment simpler * Update verify/cert.go Co-authored-by: EthenNotEthan <[email protected]> --------- Co-authored-by: Ethen <[email protected]> * docs: pimp out readme with blob lifecycle diagrams (#233) * chore: move pull_request_template.md under .github/ dir * docs: reorder README sections to feel more natural (move flags to bottom) * docs (wip): add blob lifecycle diagrams to README * docs: remove Sidecar from README title (proxy is not necessarily a side) * docs: add blob lifecycle section to README * docs: add TOC to README * style(routing): rename raw_commitment -> payload We changed the name in README so should be consistent in the code * docs: update README sections to use Payload instead of Blob Posting Blobs -> Posting Payloads Retrieving Blobs -> Retrieving Payloads * docs: remove "obviously" word * Required quorums glitch (#255) * Avoid quorum 1 check on range of Holesky blocks * Improve SVC address check * Update verify/verifier.go Co-authored-by: Samuel Laferriere <[email protected]> * Update verify/verifier.go Co-authored-by: Samuel Laferriere <[email protected]> * Avoid unnecessary cast * Rename constant * Fix lint --------- Co-authored-by: Samuel Laferriere <[email protected]> * docs: update README posting payload image (#256) * fix: remove last eth_call that required archive node (#259) Forgot this one in #241 * docs: update SECURITY.md with audit commit + fix small typos (#263) * docs: update SECURITY.md * docs: update SECURITY.md with audited release number + release where findings were addressed * feat: EigenDAV2 commitment processing and generation * feat: EigenDAV2 commitment processing and generation - add note describing follow up todo --------- Co-authored-by: Samuel Laferriere <[email protected]> Co-authored-by: Gaston Ponti <[email protected]>
…sk--feat-init-v2-scaffolds
…bs/eigenda-proxy into epociask--feat-init-v2-scaffolds
…g with G2 point ingestion
…sk--feat-init-v2-scaffolds
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.
FIrst pass. Still need to review load_store and eigenda_v2 code
"ENV_PATH": "../../.env", | ||
"EIGENDA_PROXY_EIGENDA_CERT_VERIFICATION_DISABLED": "true", | ||
"EIGENDA_PROXY_EIGENDA_TARGET_KZG_G1_PATH": "../../resources/g1.point", | ||
"EIGENDA_PROXY_EIGENDA_TARGET_KZG_G2_POWER_OF_2_PATH": "../../resources/g2.point.powerOf2" |
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 ../..? Which folder is this being run from?
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.
cmd/server
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.
This is kind of weird though no? Typically a binary is ran from root, like go run cmd/server
? Is this something specific to how vscode launches the binary?
How does this work actually? Does this add a button on the main() function in cmd/server/main.go on the vscode UI?
EdaV1ClientConfig clients.EigenDAClientConfig | ||
MemstoreConfig memstore.Config | ||
StorageConfig store.Config | ||
VerifierConfig verify.Config | ||
PutRetries uint | ||
|
||
MemstoreEnabled bool | ||
|
||
EigenDAV2Enabled bool | ||
V2DispersalConfig clients_v2.PayloadDisperserConfig | ||
V2RetrievalConfig clients_v2.RelayPayloadRetrieverConfig |
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.
Can you clean up this config a bit?
Like put all the memstore fields together.
Make the eigenda v1 and v2 close to each other.
etc
MemstoreConfig memstore.Config | ||
StorageConfig store.Config | ||
VerifierConfig verify.Config | ||
PutRetries uint |
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.
Can we add a comment here? Why is this a standalone config and not part of the other configs?
verify/v1/cli.go
Outdated
// &cli.StringFlag{ | ||
// Name: G2PathFlagName, | ||
// Usage: "Directory path to g2.point file.", | ||
// EnvVars: []string{withEnvPrefix(envPrefix, "TARGET_KZG_G2_PATH")}, | ||
// Value: "resources/g2.point", | ||
// Category: category, | ||
// }, |
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 comment this out?
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.
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.
wrong diff? its pointing to a merge commit.
I'm still confused as to why this is commented out. Is it because you're trying to hide it from clients given that its broken? Is this flag only for v2? Why is it under verify/v1/cli.go then?
Also if you're trying to hide prob best to not comment bu instead literally hide the flag (Hide: true
). And also add a comment pointing to that issue and saying that its only hidden/commented because g2 generation is broken, and we should uncomment once its fixed.
// dependencies migrate to using EigenDA V2 network | ||
V2Enabled = withFlagPrefix("v2-enabled") | ||
|
||
// disperser specific flags (interoperable && mutex for (v1 && v2)) |
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.
what does "interoperable && mutex" mean?
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.
I think v1 and v2 should have completely independent flags. possibly one might want to set a different confirmation timeout for v1 and v2 (which makes sense given that there's no bridging on v2 for eg)
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.
But if we use a different flag namespace (e.g, v2
) then we'd have to kill that namespace eventually in the future when we migrate to V2 which would cause eventual deprecation. Nbd but something to take into account
@@ -163,10 +181,96 @@ func CLIFlags(envPrefix, category string) []cli.Flag { | |||
EnvVars: []string{withEnvPrefix(envPrefix, "PUT_RETRIES")}, | |||
Category: category, | |||
}, | |||
}, | |||
v2Flags(envPrefix, category)..., |
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.
think we should use a separate v2 category
}, | ||
&cli.DurationFlag{ | ||
Name: RelayTimeoutName, | ||
Usage: "Timeout used when querying a relay for blob contents.", |
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.
Usage: "Timeout used when querying a relay for blob contents.", | |
Usage: "Timeout used when querying a relay for blobs.", |
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.
technically we should change this to payload
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.
Technically what's being retrieved from the relay is the blob, and that's what the timeout applies to. Conversion from a blob to a payload happens after a successful blob retrieval.
We had discussed letting users be ignorant of the concept of a blob
, though... so I'm a bit torn on technical correctness vs. simple mental model for users here
&cli.DurationFlag{ | ||
Name: ContractCallTimeoutName, | ||
Usage: "Timeout used when performing smart contract eth_calls", | ||
EnvVars: []string{withEnvPrefix(envPrefix, "CONTRACT_CALL_TIMEOUT")}, |
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.
is the only contract call verifyCertDAV2?
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.
no we also call the RelayRegistry
during bootstrap to read urls for payload fetching
}, | ||
&cli.UintFlag{ | ||
Name: BlobVersionName, | ||
Usage: "Blob version used when dispersing. Currently only supports (0)", |
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.
what is a blob version? Is this the encoding version?
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.
no this is the params version that's controlled via EigenDA governance
…bs/eigenda-proxy into epociask--feat-init-v2-scaffolds
}, | ||
&cli.StringFlag{ | ||
Name: CertVerifierAddrName, | ||
Usage: "Address of the EigenDABlobVerifier contract. Required for performing eth_calls to verify EigenDA certificates.", |
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.
Usage string is out of date
"EigenDABlobVerifier" -> "EigenDACertVerifier"
noPolynomial := ctx.Bool(DisablePointVerificationModeFlagName) | ||
polyMode := codecs.PolynomialFormCoeff | ||
|
||
// if point verification mode is disabled then blob is treated as evaluations and |
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.
I think you have this reversed.
PolynomialFormEval
is to be understood like this: "The encoded payload is interpreted as a polynomial in eval form. Blobs must be in coeff form, therefore we must take the IFFT to turn our encoded payload into the correct form".
And the other side of the coin, PolynomialFormCoeff
is to be understood like this: "The encoded payload is interpreted as a polynomial in coeff form. Blobs must be in coeff form, therefore we don't need to do any IFFT encoding, the bytes can be sent as-is"
Originally I had understood the meaning of these terms as you wrote here, but talking with @bxue-l2 and @samlaf, we came to an agreement on the descriptions I wrote above. I'm still not super happy with our terminology here, but a perfect solution has proven elusive.
@@ -52,12 +64,103 @@ func populateTargets(targets []string, s3 common.PrecomputedKeyStore, redis *red | |||
return stores | |||
} | |||
|
|||
func loadEigenDAV2Store(ctx context.Context, cfg CLIConfig, log logging.Logger) (*eigendav2.Store, error) { | |||
// TODO: Replace with real logger once dependency PRs are merged |
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.
is this comment still relevant?
cfg.EigenDAConfig.V2DispersalConfig.SignerPaymentKey = cfg.EigenDAConfig.EdaV1ClientConfig.SignerPrivateKeyHex | ||
|
||
cfg.EigenDAConfig.V2DispersalConfig.BlobCertifiedTimeout = time.Second * 100 | ||
cfg.EigenDAConfig.V2DispersalConfig.Quorums = []uint8{0, 1, 2} |
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 is 2
in this list?
UseSecureGrpcFlag: !cfg.EigenDAConfig.EdaV1ClientConfig.DisableTLS, | ||
}, | ||
&gethCfg, | ||
nil, |
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.
Is there a reason you must use a nil
prover, or is this just a WIP?
|
||
var _ common.GeneratedKeyStore = (*Store)(nil) | ||
|
||
func NewStore(log log.Logger, cfg *Config, |
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.
should this use logging.Logger
instead of log.Logger
?
return e.disperser.SendPayload(ctx, value, salt) | ||
}, | ||
retry.RetryIf(func(err error) bool { | ||
salt++ // increment salt before retrying |
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.
Should we actually increment salt on failures? My limited understanding was that we'd only need to increment salt if there is a success, and then a reorg happens that requires blob resubmission
return rlp.EncodeToBytes(cert) | ||
} | ||
|
||
// Backend returns the backend type for EigenDA Store |
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.
nit: it seems the method was renamed from Backend
to BackendType
, but the doc wasn't updated
data, err := m.eigendaV2.Get(ctx, key) | ||
if err == nil { | ||
// verify v2 (payload, cert) | ||
err = m.eigendaV2.Verify(ctx, key, data) |
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.
I think we ought to have a different order of operations here (since cert verification will likely be faster than retrieval of the full blob, right?):
- Verify the cert on chain
- If the cert is verified, only then proceed to try to retrieve the blob, from the available backend sources in order of priority
// Key is used to recover certificate fields and that verifies blob | ||
// against commitment to ensure data is valid and non-tampered. | ||
// TODO: tap into actual verification | ||
func (e Store) Verify(_ context.Context, _ []byte, _ []byte) error { |
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.
I don't think this method signature will need to accept the actual blob bytes. It should just need to verify the certificate on chain, and then the blob bytes will be checked against the certificate inside the eigenDA client code, while doing the fetch
Fixes Issue
Changes proposed
Introduces a working MVP for integration with EigenDA V2.
Known Issues
blob already exists
error #278Screenshots (Optional)
Note to reviewers