-
Notifications
You must be signed in to change notification settings - Fork 124
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
Paritytech/trie proofs are incompatible with gossamer/lib/trie #2329
Comments
Adding some additional notes here.
So the key of the leaf node in the example given should be: If we look side by side we get:
It's almost a match but as we can see above the key we're attempting to search for is much longer. |
So i decoded all the nodes in rust and here's their structure:
|
Hmm, looks like there's a leaf node in the Pasting logs from a lookup operation in
Looks like the key is a perfect match above, yielding a found value. We're directly calling |
Ah, makes more sense now after additional logs. The leaf data is inlined haha 🤦♂️. We lookup the last branch node and decode node data for that node and then the inlined leaf node data on the next iteration.
|
Hmm I think the issue is that inlined leaf node key/value aren't being properly decoded from the proof payload? gossamer/internal/trie/node/decode.go Lines 101 to 110 in 567c1ab
It looks like it assumes that the leaf node is hashed and not inlined. |
Pasting leaf node plan for decoding. /// A `NodePlan` is a blueprint for decoding a node from a byte slice. The `NodePlan` is created
/// by parsing an encoded node and can be reused multiple times. This is useful as a `Node` borrows
/// from a byte slice and this struct does not.
///
/// The enum values mirror those of `Node` except that instead of byte slices, this struct stores
/// ranges that can be used to index into a large byte slice.
#[derive(Eq, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum NodePlan {
/// Leaf node; has a partial key plan and value.
Leaf { partial: NibbleSlicePlan, value: ValuePlan },
}
impl NodePlan {
/// Build a node by decoding a byte slice according to the node plan. It is the responsibility
/// of the caller to ensure that the node plan was created for the argument data, otherwise the
/// call may decode incorrectly or panic.
pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> Node<'b> {
match self {
NodePlan::Leaf { partial, value } => Node::Leaf(partial.build(data), value.build(data)),
}
}
}
/// A `NibbleSlicePlan` is a blueprint for decoding a nibble slice from a byte slice. The
/// `NibbleSlicePlan` is created by parsing a byte slice and can be reused multiple times.
#[derive(Eq, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub struct NibbleSlicePlan {
bytes: Range<usize>,
offset: usize,
}
impl NibbleSlicePlan {
/// Construct a nibble slice decode plan.
pub fn new(bytes: Range<usize>, offset: usize) -> Self {
NibbleSlicePlan { bytes, offset }
}
/// Returns the nibble length of the slice.
pub fn len(&self) -> usize {
(self.bytes.end - self.bytes.start) * nibble_ops::NIBBLE_PER_BYTE - self.offset
}
/// Build a nibble slice by decoding a byte slice according to the plan. It is the
/// responsibility of the caller to ensure that the node plan was created for the argument
/// data, otherwise the call may decode incorrectly or panic.
pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> NibbleSlice<'b> {
NibbleSlice::new_offset(&data[self.bytes.clone()], self.offset)
}
}
/// Plan for value representation in `NodePlan`.
#[derive(Eq, PartialEq, Clone)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum ValuePlan {
/// Range for byte representation in encoded node.
Inline(Range<usize>),
/// Range for hash in encoded node and original
/// value size.
Node(Range<usize>),
}
impl ValuePlan {
/// Build a value slice by decoding a byte slice according to the plan.
pub fn build<'a, 'b>(&'a self, data: &'b [u8]) -> Value<'b> {
match self {
ValuePlan::Inline(range) => Value::Inline(&data[range.clone()]),
ValuePlan::Node(range) => Value::Node(&data[range.clone()], None),
}
}
} |
…e with gossamer/lib/trie ChainSafe#2329
…e with gossamer/lib/trie ChainSafe#2329
…e with gossamer/lib/trie ChainSafe#2329
…e with gossamer/lib/trie ChainSafe#2329
This is related to #2418 which I'm working on now. I'll update here soon. |
@seunlanlege @notbdu I've been checking this tests again and it's working now, probably related with my fix regarding the issue #3346 I'll close this issue |
Describe the bug
Read proofs generated by the rust implementation of the substrate node don't seem to work with the
lib/trie
library.Expected Behavior
The text was updated successfully, but these errors were encountered: