-
Notifications
You must be signed in to change notification settings - Fork 127
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
proof: add new IgnoreChecker proof rejection cache #1400
Conversation
Pull Request Test Coverage Report for Build 13563480812Details
💛 - Coveralls |
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.
Thanks for the refactor, that was definitely needed!
I think this changes the caching behavior quite a bit, so we might want to revert small parts of it (see inline comment).
ctx, headerVerifier, merkleVerifier, groupVerifier, | ||
chainLookupGen.GenFileChainLookup(&proofFile), | ||
) | ||
return proofFile.Verify(ctx, vCtx) |
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 changes the semantics on the use of ProofChainLookup
. Before, we passed in the whole file, which actually made it useful as a cache, since it could look up TxBlockHeight
in a previous proof of the file. Now that we always just pass in a single proof (within verifyAssetStateTransition
), this caching effect isn't there anymore and we always need to hit the DB...
Perhaps we can keep the old signature on Proof.Verify()
and just change the signature of the Verifier.Verify
?
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.
Ah, makes sense. I had an initial second thought once I needed to make those additional calls deeper in the proof verification sections.
I went back and forth a bit w.r.t if it should accept the ChainLookupGen
, or just the ChainLookup
interface.
Perhaps we can keep the old signature on Proof.Verify() and just change the signature of the Verifier.Verify?
I still think it's useful to be able to aggregate the set of dependent interfaces in a single place. One change I want to size up is if we can just have a global VerifierCtx
in one place, so we don't need to re-create it in so many areas (ontriduces the chance that we forgot to populate some important, but optional interface).
Can you help me to understand this caching a bit better? Looking at ProofChainLookup
, I see that we'll hit the assetStore
to fetch the height of a given txid. I don't see how this portion was cached before. IIUC, my changes here amount to creating new sub-instance of ProofChainLookup
when needed (no db calls in the constructor), vs passing around a pre-created instance.
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 the chain lookup is used for three different things during (relative) lock time validation:
- Get the current block height (easy, just a "cheap" call to the backend, no caching required)
- Block mean time ("expensive" and not really cacheable, multiple calls to the backend required, but only required for unix timestamp based lock times)
- Get block height of input transaction (requires txindex or chain re-scan, so considered too expensive), see
Line 586 in e2107c8
inputConfirmHeight, err := chainLookup.TxBlockHeight(
The third one is the problem, as with Neutrino for example we can't do it in a reasonable time. BUT, that's where the proof file comes in: The previous proof in the file contains exactly the transaction we need plus its mined height. That's why we cache the full file whenever possible.
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.
Thanks, for that explanation.
Pushed up a new version. I landed somewhere in the middle: VerifierCtx
is still in place, but for proof.Verify
it accepts the ChainLookup
as another arg.
I considered making a new fn.Either[ChainLookup, ChainLookupGen]
to make it clearer that they're used un a mutually exclusive way. Wasn't sure how people would feel about the ergonomics of that kind of approach though. I think we can mask some of the boiler plate with some helper methods. I lean towards this approach myself as it's less ambiguous which you should use (the generator or the ready instance).
proof/verifier.go
Outdated
Index: p.InclusionProof.OutputIndex, | ||
}, | ||
Asset: &p.Asset, | ||
OutPoint: anchorOutPoint, |
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 commit doesn't compile, this variable doesn't exist yet.
7c3f579
to
3d8b464
Compare
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.
interesting aider approach, left some comments on the topic
CONVENTIONS.md
Outdated
• Include a prefix indicating the affected package (e.g. “lnwallet:” or “multi:” for changes spanning several packages). | ||
|
||
- **Ideal Git Commit Structure** | ||
• Make small, self-contained commits so that every commit builds on the previous one. |
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 need to expand and emphasize a bit more on git commit structure
need to revolve more around small scope commits that build / make sense etc
didn't do a great job in this PR, everything is kind of mixed up
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.
Removed as wasn't meant to be committed.
I had to do a big first commit, as it changed an interface that was widely used. If everything wasn't updated, then the commit wouldn't compile.
fb3f5c2
to
5b68d1d
Compare
In this commit, we introduce a new proof.VerifierCtx struct to cut down on line noise when verifying single proofs and proof files. This also lets us centralize the creation of the various interfaces we need to verify a proof. Finally, this is a prep for an upcoming change where we'll add a new interface to the validation context.
In this commit, we add a new interface, the IgnoreChecker. This is to be used as a proof rejection cache, which allows us to ensure that we don't continue to validate proofs that we already know to be invalid. The underlying cache implementation is also intended to support its own invalidation to handle re-org edge cases. A concrete implementation will be added in an upcoming PR.
5b68d1d
to
1cfbe7c
Compare
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.
Pushed up a couple of fixes. With that, LGTM 🎉
proof/proof_stitching_test.go
Outdated
context.Background(), verifier.VerifyHeader, | ||
DefaultMerkleVerifier, MockGroupVerifier, | ||
MockChainLookup, | ||
context.Background(), vCtx, |
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.
Here we actually switch to the DefaultMerkleVerifier
instead of the MockMerkleVerifier
, since we now have a valid merkle proof (which IIRC is part of the test case).
proof/verifier.go
Outdated
@@ -304,6 +308,12 @@ func (p *Proof) verifyAssetStateTransition(ctx context.Context, | |||
splitAssets = append(splitAssets, splitAsset) | |||
} | |||
|
|||
chainLookup, err := vCtx.ChainLookupGen.GenProofChainLookup(p) |
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.
We should actually pass in the chainLookup
from Verify
. Otherwise the caching still doesn't work.
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.
Lgtm
looking forward to the implementation
In this PR, we introduce a new proof.VerifierCtx struct to cut down
on line noise when verifying single proofs and proof files. This also
lets us centralize the creation of the various interfaces we need to
verify a proof.
We then add a new interface, the IgnoreChecker. This is to be
used as a proof rejection cache, which allows us to ensure that we don't
continue to validate proofs that we already know to be invalid. The
underlying cache implementation is also intended to support its own
invalidation to handle re-org edge cases.