chainsafe / ssz-js Goto Github PK
View Code? Open in Web Editor NEWSimple Serialize in TypeScript
License: Other
Simple Serialize in TypeScript
License: Other
ethereum/consensus-specs#455 got merged
Remove/refactor hash and address encoding into bytesN
encoding.
hashN
is equivalent to bytesN
.
address
is equivalent to bytes20
.
Currently, the library lexographically sorts the container fields and serialized the values in that order.
The ssz spec has changed to require containers (js objects) to be serialized in the order which the container's fields are defined. (see the PR here and the spec here)
We should assume that type.fields
is a list and use that ordering here
Examples on how to use this ssz library.
We should add examples on how to serialize and deserialize data and be explicit on how have conforming inputs into these functions.
Adding usage examples will help people wanting to use this library in their projects.
The reference implementation now supports uint's and int's explicitly. The serialize and deserialize functionality should follow.
##Serialize
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L10
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L14
##Deserialize
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L38
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L43
Boolean serialisation and deserialisation.
It is not in the Python implementation yet but is in the spec.
https://github.com/ethereum/eth2.0-specs/pull/68/files
Is your feature request related to a problem? Please describe.
It would be nice to have typings available so lodestar development could take advantage of it.
Describe the solution you'd like
Add type declaration file according to https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html
Please make sure that the license does not contain right or left arrows. If you search the license for it you'll find something like the below: <some_content_that_needs_to_be_replaced>
Fix BN imports so that users do not need non-standard typescript settings.
I have an initial PoC for the serialize function in index.js.
The only portion that is missing is the following:
elif isinstance(typ, type):
length = int.from_bytes(data[start:start+4], 'big')
values = {}
pos = start + 4
for k in sorted(typ.fields.keys()):
values[k], pos = _deserialize(data, pos, typ.fields[k])
assert pos == start + 4 + length
return typ(**values), pos
The above portion needs to be implemented in JS and can be found here: https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py.
Add tests for utilities in src/util/hash
and src/util/types
Add support for the tree hashing algorithm.
https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree_hash
assertValidValue
is a useful function that should be exported for use in eg: lodestar test utilities
Is your feature request related to a problem? Please describe.
This feature request is not related to a problem.
Describe the solution you'd like
Currently, this library works only in node.js. It makes use of node.js features that don't necessarily work in the browser. In order to get people using this library in their projects, it needs to be able to work in the browser.
Describe alternatives you've considered
Not applicable.
Additional context
Not applicable.
Is your feature request related to a problem? Please describe.
Its annoying to have to unwrap a deserialized value from an object whenever deserializing.
Describe the solution you'd like
It would be nice to have an option to deserialize directly to a value, rather than deserializing to an object containing the value.
Bonus points for still allowing the "extended form", { deserializedValue, offset }
eg:
const myValue: uint64 = deserialize(buf, uint64);
vs.
const myValue: uint64 = deserialize(buf, uint64).deserializedValue;
We'll want to do something like
add an optional parameter to deserialize
to return the "extended form" of the deserialized output, (the extended form being whats returned currently)
eg:
const myValue: uint64 = deserialize(buf, uint64 /*, 0, false */ );
const extended: uint64 = deserialize(buf, uint64, 0, true); // <- note the optional param set to true
extended.deserializedValue == myValue
Describe the solution you'd like
Are there any thoughts about the usage of BigInt instead of BN.js?
Additional context
Open discussion in the Web3.js repository: (web3/web3.js#2171)
Is your feature request related to a problem? Please describe.
From @wemeetagain (#35):
After doing some digging, it appears that, contrary to the exact language in #33, the standard way of dealing with Buffer (allowing it to work in the browser) is to let the 'last step' of the build process do the polyfill. This makes more sense than I originally thought, rationale below.
What that means, is that most libraries relying on Buffer (eg: our dependency @polkadot/util included) use Buffer assuming its availability, and then later consumers of these libraries (for web) would bundle in a polyfill as a step of the bundling process.
The reason for this approach is that it simplifies larger projects from unintended hackiness surrounding Buffer, specifically when running on node.
Imagine library B uses library A. If library A hardcodes the feross/buffer dependency, library B, (and even all consumers of library B), are bound to use that implementation, which is really meant as a browser polyfill.It makes more sense for the bundler, which is already collating the tree of a project's dependencies, to have more information about the run-time environment, and make the appropriate choice at the end.
That way, all references to Buffer can either be linked at once, or all of them left alone.
Describe the solution you'd like
Configured bundler that includes a Buffer polyfill
Describe alternatives you've considered
See #33 #16
Additional context
N/A
Implementation of the deserialize functionality of SSZ. Does the reverse of the serialize function for all supported types.
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L33
https://github.com/ethereum/beacon_chain/blob/master/ssz/ssz.py#L72
Add tests for hashTreeRoot
We currently support unsigned/signed integers up to 256-bits. However, we forgot (u)int24 and its supporting tests.
It is specified in the official ssz specification here: https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#uint-816243264256-1
https://github.com/ethereum/beacon_chain/blob/ccf75cc679601b53e03fb5a410fc3262c503ace1/ssz/ssz.py#L10
Based on discussion here we settled on representing byte arrays as Uint8Array
s rather than Buffer
s.
We may want to align this library in that direction or revisit the discussion in the context of a Chainsafe-wide consistent approach.
Add tests for signedRoot
As mentioned in gitter:
Import buffer
library to allow for Buffer
use in the browser.
Currently, the library assumes the value is a javascript number
if the type is uintX
.
It looks like we'll need bignum support for signatures, etc. (see ProposerSlashing data structure for example of uint384
)
This should ensure bitSize > 0
. Should probably also be called byteSize
.
readme still refers to 0.4.x calling convention, should be updated for 0.5.x
In the python reference implementation of ssz, there is a function to_dict()
that converts a class or a list to a python dictionary.
I think we don't need to implement all of the details of that function because Js classes are objects. Thus, we would only need to convert an array to an object.
Any thoughts?
Is your feature request related to a problem? Please describe.
The parameter order of deserialize
differs minorly from serialize
and treeHash
, in that type
is the third parameter, instead of the second.
Describe the solution you'd like
Swap the start
and type
parameters. This would maintain greater consistency between our function signatures and allow us to more practically make start
an optional parameter, with a default of 0 (since in most cases you can assume wanting to deserialize from the beginning).
now:
let x: BeaconBlock = deserialize(data, 0, BeaconBlock);
proposed:
let x: BeaconBlock = deserialize(data, BeaconBlock);
Describe alternatives you've considered
start
and type
, but keep start
a required parameterAdditional context
noticed this during #31
as it is in TS we should consider renaming or dropping -js entirely from it.
currently there is more shell than JS in the project according to github lol.
Should serialise hash96/7 for BLS pubkeys
It is referenced in the spec:
https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#hash96
https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#hash97
@Mikerah: A little food for thought: Would it be valuable to have the option to encode integers in big endian? SSZ has some really nice properties that others might want to leverage in other projects that may or may not be related to Ethereum. They might require integers encoded in big endian. This could be a future feature and will not be a priority within the next few months.
After closing #25 i valid point was made by Mikerah to add support for big-endian. It would require a bit of a re-write of logic, but testing for it would be fairly straight forward. We could cherry-pick the previous test suite for big-endian and then create two test directories:
ethereum/consensus-specs#139 got merged.
Integers should now be encoded in little-endian format.
This includes prefixed lengths and encoded integers.
What is your question?
Currently when checking if some ssz type is equal we serialize it and compare serialized buffer, which is time and memory consuming. To avoid it we could add method equals
to ssz library which would compare every field of type natively (exmp. BN.equals(BN)
, buffer.equals(buffer)
)
The beacon chain state includes data types currently not supported by ssz-js, in particular uint64 and uint256. These should be implemented to be able to serialize the beacon chain state.
Currently we simply return null if the type is not recognized. Since we are using strings for types mistakes should be expected and thus we should at least warn the user that the type is not valid.
No specific mention afaik. Other implementations seem to throw errors on invalid types (eg. https://github.com/prysmaticlabs/prysm/blob/c5b196006d939ac2392a3b131a2b35a8a21cf45c/shared/ssz/encode.go#L101)
As mentioned in #2, serialize() is almost completed. We will need to write a test for it to make sure it coincides with the python implementation. Several core developers such as Danny Ryan are working on interoperability tests so that we can all check our implementations.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.