Skip to content
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

Open
wants to merge 21 commits into
base: eigenda_v2
Choose a base branch
from

Conversation

ethenotethan
Copy link
Collaborator

@ethenotethan ethenotethan commented Jan 24, 2025

@ethenotethan ethenotethan changed the base branch from main to eigenda_v2 January 30, 2025 01:52
* 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]>
@ethenotethan ethenotethan changed the title feat: Initial V2 scaffolds feat: Initial V2 E2E Prototype Jan 30, 2025
@ethenotethan ethenotethan changed the base branch from eigenda_v2 to main January 30, 2025 05:28
@ethenotethan ethenotethan marked this pull request as ready for review February 6, 2025 19:05
@ethenotethan ethenotethan changed the base branch from main to eigenda_v2 February 6, 2025 19:07
@ethenotethan ethenotethan requested review from samlaf and litt3 February 6, 2025 19:08
Copy link
Collaborator

@samlaf samlaf left a 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

Comment on lines +13 to +16
"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"
Copy link
Collaborator

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?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmd/server

Copy link
Collaborator

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?

Comment on lines +23 to +33
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
Copy link
Collaborator

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
Copy link
Collaborator

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
Comment on lines 64 to 70
// &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,
// },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why comment this out?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

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.

verify/v1/cli.go Outdated Show resolved Hide resolved
// dependencies migrate to using EigenDA V2 network
V2Enabled = withFlagPrefix("v2-enabled")

// disperser specific flags (interoperable && mutex for (v1 && v2))
Copy link
Collaborator

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?

Copy link
Collaborator

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)

Copy link
Collaborator Author

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)...,
Copy link
Collaborator

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.",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Usage: "Timeout used when querying a relay for blob contents.",
Usage: "Timeout used when querying a relay for blobs.",

Copy link
Collaborator Author

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

Copy link
Collaborator

@litt3 litt3 Feb 10, 2025

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")},
Copy link
Collaborator

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?

Copy link
Collaborator Author

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)",
Copy link
Collaborator

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?

Copy link
Collaborator Author

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

},
&cli.StringFlag{
Name: CertVerifierAddrName,
Usage: "Address of the EigenDABlobVerifier contract. Required for performing eth_calls to verify EigenDA certificates.",
Copy link
Collaborator

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
Copy link
Collaborator

@litt3 litt3 Feb 10, 2025

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
Copy link
Collaborator

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}
Copy link
Collaborator

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,
Copy link
Collaborator

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,
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link
Collaborator

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)
Copy link
Collaborator

@litt3 litt3 Feb 10, 2025

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?):

  1. Verify the cert on chain
  2. 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 {
Copy link
Collaborator

@litt3 litt3 Feb 10, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants