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

get() Root should not return a sub Tree #83

Closed
dapplion opened this issue Mar 21, 2021 · 3 comments
Closed

get() Root should not return a sub Tree #83

dapplion opened this issue Mar 21, 2021 · 3 comments

Comments

@dapplion
Copy link
Contributor

When getting a property from a tree backed ssz type this if decides to return the "raw" value or tree backed.

if (!isCompositeType(fieldType)) {

In my opinion I would assume that a Root will not return a sub Tree, but just the raw value. However this is not the case

const stateTree = config.types.phase0.BeaconState.tree.deserialize(stateBytes);
console.log({
      epoch: stateTree.finalizedCheckpoint.epoch,
      root: stateTree.finalizedCheckpoint.root,
});
// stdout of above code
{
  epoch: 0,
  root: Tree { _node: LeafNode { _root: [Uint8Array] }, hook: [Function] }
}

Due to the Tree hook anyone that holds any root part of a state will prevent to garbage collect that state, causing this memory issues ChainSafe/lodestar#2181 (comment)

@dapplion
Copy link
Contributor Author

I propose to add constructor options to composite types so you can choose not to return a Tree (using shouldNotReturnSubTree for clarity, but we should use a better name)

export abstract class CompositeType<T extends object> extends Type<T> {
  shouldNotReturnSubTree: boolean;
  constructor(opts) {
    this.shouldNotReturnSubTree = opts.shouldNotReturnSubTree ?? false
  }

Then tree backing can use that info to not return a tree for those types

// ssz/src/backings/tree/container.ts:138
if (!isCompositeType(fieldType) || fieldType.shouldNotReturnSubTree) {
   // return raw value
} else {
  // return tree
}

This behavior can be customized in lodestar-types for roots, and won't affect other users.

export const Root = new ByteVectorType({length: 32, shouldNotReturnSubTree: true});

@wemeetagain
Copy link
Member

right now, we use valueOf to return the primitive value. We use this a lot to get an actual Uint8Array from a Root.

{
  root: stateTree.finalizedCheckpoint.root.valueOf(),
}

I agree that a Root should always return a Uint8Array, since roots are treated as basic types and never partially updated. IMO we can just update RootType.tree_getProperty to return a Uint8Array.

@philknows
Copy link
Member

SSZ has been refactored since this time, no longer relevant.

@philknows philknows closed this as not planned Won't fix, can't repro, duplicate, stale Oct 8, 2024
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

No branches or pull requests

3 participants