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

Draft: IPLD Timestamp Proof #168

Merged

Conversation

zachferland
Copy link
Contributor

Create and verify IPLD based blockchain timestamp proofs.

@bumblefudge
Copy link
Collaborator

surely there's a codec for filecoin? should i ask CASA's fil rep or in the filecoin open slack?

@bumblefudge
Copy link
Collaborator

i also wonder if there's a link worth adding to the references section at the end pointing to info on how FVM means filecoin nodes can connect to a testnet/quorum/etc "out of the box"...

@oed
Copy link
Collaborator

oed commented Nov 8, 2022

@bumblefudge why is filecoin's codec and FVM relevant in particular here? This is a general way of representing a timestamp from any blockchain.

@bumblefudge
Copy link
Collaborator

Neither required nor especially relevant, just wondering if a third example would be nice. Since some ipfs gateways are also fil nodes, might be an appealing option for some users since it's one-stop shopping in that case!

@oed
Copy link
Collaborator

oed commented Nov 10, 2022

I'm not familiar enough with Filecoin to say how easy it would be to add an example from there.


A Merkle proof allows verification that a given piece of data or “leaf” was included in the set of data for the given Merkle Tree. A typical proof includes a Merkle root of the tree and a subset list of tree node hashes that allow verification by reconstructing the Merkle root starting from the data or "leaf" you are interested in.

In IPLD a Merkle root (CID) and a “path” are provided that allows you to traverse the tree from the root to the piece of data your interested in. Paths are strings and refer to [Pathing in IPLD](https://ipld.io/docs/data-model/pathing/). Following an IPLD path, and ultimately resolving the data or "leaf" you are interested in from the root, is equivalent to a standard proof.
Copy link

Choose a reason for hiding this comment

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

is equivalent to a standard proof

Yeah, if you're willing to deal with the resolution of the intermediates. The approach of just providing a root and a path is fine if you expect the verifier to navigate through the data but the simple form of a Merkle proof provides the intermediate dependent hashes all the way up to the root so you can reconstruct it from just the data you have. You could do that here if you're just going to build a standard Merkle tree where intermediates are tuples of hashes (as you've suggested above) by providing the paired CIDs that couple with the derived CIDs of the leaf you want to prove - so leaf + CIDs of all non-relevant branches on the way up to the root. Then you can reencode those intermediates from the leaf you have and couple it with the provided CIDs to the original Merkle root which, if it matches is the "proof".
But that's not the approach being taken here, which is fine but assumes the availability and navigability of all intermediates. Is that correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah roughly but the intention is to not assume anything about the network (ie just IPLD, not IPFS), this just describing the data structure in IPLD and in IPLD a natural way to verify is just to traverse the path. The data could already be local, over another network, or an implementation may not rely on any intermediaries by packing the entire proof and path subset of the tree (all necessary ipld blocks) in a CAR file if they choose. Probably makes sense to change wording a bit (ie resolving) and maybe add a note. thanks for commenting

@chunningham
Copy link

chunningham commented Nov 21, 2022

I like this proposal, it is simple and directly addresses a common need. I think that it may be preferable to define additional multicodec values for different type of blocks even within a chain, i.e. a codec for eth-raw and a codec for eth-contract, than to use a string discriminant. Although I acknowledge that may be bloat in the codec list and a breaking change to multicodec I think it would simplify the discriminant and prevent certain possible-but-illegal objects (in general I think string discriminant values are prone to accidents). Overall I think this is as appropriately straightforward as is possible.

@oed
Copy link
Collaborator

oed commented Nov 21, 2022

@chunningham Why would using strings be prone to errors? These strings needs to be registered within the Chain namespace for this CAIP. So each string would map to a description of how to interpret it.
If we use multicodec there wouldn't be a canonical place to describe what each code does.

@oed
Copy link
Collaborator

oed commented Nov 21, 2022

For example, I'm planning to register f(bytes32) for the eip155 namespace, which would map to: "The bytes32 param is the multihash of a dag-cbor CID".

@chunningham
Copy link

If there's a registry then that's fine, I was kind of thinking that the role of discriminant would be duplicated here between codec and string, but I suppose that the string is more an indicator of which links in the block actually point to/include the root of the merkle tree than of the structure of the block? By 'errors' I meant blocks with e.g. codec is raw but the discriminant says eth-contract then that's allowed but nonsensical, or at least hard to parse correctly.

@bumblefudge
Copy link
Collaborator

bumblefudge commented Nov 29, 2022

Todo before merge as Draft (as discussed on today's call):

  • Adding language to specify that per-namespace profiles are needed.
  • Add an eip155 profile to namespaces/eip155/caip168
  • Tell @bumblefudge on discord or here when ground is broken on the sample implementation to bump to Review

@bumblefudge
Copy link
Collaborator

bumblefudge commented Dec 7, 2022

NB @benediktwoelk as per our convo last night

@zachferland
Copy link
Contributor Author

Minor edits made, references to namespace, txType added, and eip155 namespace PR opened - ChainAgnostic/namespaces#42 cc @bumblefudge

@oed
Copy link
Collaborator

oed commented Dec 8, 2022

Also an implementation of validation of this CAIP can be seen here:
https://github.com/ceramicnetwork/js-ceramic/blob/develop/packages/core/src/anchor/ethereum/ethereum-anchor-validator.ts

Should address all of your points above @bumblefudge :)

Signed-off-by: bumblefudge <[email protected]>
@bumblefudge
Copy link
Collaborator

bumblefudge commented Dec 8, 2022

Hey guys! Sorry for the delay, I did an editorial pass on both CAIP and Namespaces/eip155/CAIP168. I had to open new PRs against Ceramic's fork, so if you merge those two there I'll merge this PR here and we're GTG

Also note: if there's working code that works against this final version of the spec, we can skip draft and go straight to Review 🎉

@zachferland
Copy link
Contributor Author

editorial pass merged

@bumblefudge
Copy link
Collaborator

oh sorry I didn't link this one, also needed: ceramicnetwork/namespaces#1

@zachferland
Copy link
Contributor Author

thanks, merged the namespace pass as well now

@bumblefudge bumblefudge merged commit dc2ad96 into ChainAgnostic:master Dec 21, 2022
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.

5 participants