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

feat!: mantaray 1.0 #30

Open
wants to merge 60 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5c9032d
refactor: move serializeVersion to utility
nugaon Feb 2, 2022
2ab88bf
feat: add 1.0 version to types
nugaon Feb 2, 2022
2e4b34e
feat: node 1.0 init
nugaon Feb 2, 2022
76cb9d5
feat(test): separate mantaray 1.0 and 0.2 utilities
nugaon Feb 2, 2022
3e6d12b
test: create distinct projects for unit and intergration tests
nugaon Feb 2, 2022
79e83d9
test(refactor): integration test
nugaon Feb 2, 2022
22b4054
test(refactor): mantaray 0.2 tests
nugaon Feb 2, 2022
6c7b441
test: mantaray 1.0 unit test init
nugaon Feb 2, 2022
f5b60f4
refactor: index exportables
nugaon Feb 2, 2022
ecc30f0
ci: bump bee version
nugaon Feb 3, 2022
dfd7a28
test(refactor): separate sample nodes for mantaray versions
nugaon Feb 3, 2022
45896f4
refactor: utility functions of mantaray node
nugaon Feb 3, 2022
1674165
refactor: initManifestNode typing
nugaon Feb 3, 2022
0d91ddc
refactor: metadata handling
nugaon Feb 7, 2022
d19a19e
fix: metadataMapping type
nugaon Feb 7, 2022
d73636e
feat: serialiseMetadata utility
nugaon Feb 7, 2022
e700a86
test: finalise mantaray unit tests
nugaon Feb 7, 2022
199c0d9
style: eslint
nugaon Feb 7, 2022
427e294
test: mantaray 0.2 integration
nugaon Feb 7, 2022
a8906be
test: style of mantaray 1.0
nugaon Feb 7, 2022
905bfac
test: add descrive to mantaray 0.2 integration test
nugaon Feb 7, 2022
81e7c10
fix: node metadata serialisation
nugaon Feb 7, 2022
e720853
fix: equalNodes negation at entry comparisation
nugaon Feb 7, 2022
44ace8d
refactor: node comparisation error always gives back path
nugaon Feb 7, 2022
fe9f777
style: eslint
nugaon Feb 7, 2022
e7c865d
fix: obfuscation key nullcheck
nugaon Feb 8, 2022
da5daa8
fix: setEntry instead of contentaddress + fork serialisation size calc
nugaon Feb 8, 2022
8c4e40a
fix: use contentAddress on fork fetch instead entry + forkmetadata deser
nugaon Feb 8, 2022
0b6b2b5
fix: json serialisation padding
nugaon Feb 8, 2022
75334bd
test: mantaray 1.0 integration
nugaon Feb 8, 2022
2f8ad15
chore: remove old code comments
nugaon Feb 8, 2022
83afe41
fix: json marshalling
nugaon Feb 8, 2022
97fc1d0
fix: contentaddress assignment at the end of the serialisation
nugaon Feb 8, 2022
e2ab39a
fix: forkserialisation
nugaon Feb 10, 2022
fc5e498
chore: remove auto segmentsize
nugaon Feb 10, 2022
fef6972
refactor: getters setters naming
nugaon Feb 10, 2022
bea15d1
refactor: move mantaray 1.0 equalNodes to test utility
nugaon Feb 10, 2022
c7c6368
refactor: remove not used method parameter
nugaon Feb 10, 2022
c21d061
test: add obfuscation key test
nugaon Feb 10, 2022
baf7a8f
test: add test for continuous node check
nugaon Feb 10, 2022
5e5654e
fix: prefixLength adjustment for continuousnode flag
nugaon Feb 10, 2022
0ad89cc
refactor: renaming mantaray classes
nugaon Feb 10, 2022
584da95
refactor: renaming mantaray classes again
nugaon Feb 10, 2022
4e8e40e
refactor: remove random32Bytes utility function
nugaon Feb 11, 2022
cbf46ad
test: generator function check on addfork for obfuscation key
nugaon Feb 11, 2022
e0fd39b
feat: exposing hexToBytes from Utility
nugaon Feb 11, 2022
546fdf2
refactor: initManifestNode typing
nugaon Feb 11, 2022
cbfbd53
docs: update README
nugaon Feb 11, 2022
9c1ebcc
feat: continuous node handling on addFork
nugaon Feb 11, 2022
c4c7d51
test: continuous node handling on addFork
nugaon Feb 11, 2022
a7fedb1
refactor: renamings and comments
nugaon Mar 7, 2022
f194274
test: utils, serializeMetadataInSegment
nugaon Mar 7, 2022
f812371
refactor: assertions
nugaon Mar 7, 2022
88aee31
docs: fork metadata
nugaon Mar 7, 2022
4d2ab68
fix: mantaray remove path
nugaon Mar 7, 2022
0a576bf
refactor: isPrefixBy
nugaon Mar 7, 2022
2a276e2
refactor: replace findIndexOfArray with isPrefixedBy
nugaon Mar 7, 2022
d48b801
refactor: remove autoForkMetadataSize
nugaon Mar 7, 2022
95ea78d
fix: handling segmentsize bigger than the limit
nugaon Mar 8, 2022
e90f778
refactor: indexbytes as a generator function
nugaon Mar 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- '**'

env:
BEE_VERSION: '1.1.0'
BEE_VERSION: '1.4.1'
BLOCKCHAIN_VERSION: '1.2.0'
BEE_ENV_PREFIX: 'swarm-test'
BEE_IMAGE_PREFIX: 'docker.pkg.github.com/ethersphere/bee-factory'
Expand Down
92 changes: 52 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
# Description

The `mantaray` data-structure is widely used whithin the Swarm ecosystem; just to mention one, `manifests` are built on the mantaray data-structure, which consist of paths and file mappings of all dApps live on Ethereum Swarm.

With this package you can manipulate and interpret mantaray data via `MantarayNode` and `MantarayFork` abstractions.

# Exported Functions and Classes

You can import the followings directly from `mantaray-js`:

* MantarayV0_2 # legacy implementation of the mantaray data-structure, supported by the Bee client.
* MantarayV1 # recent implementation of the mantaray data-structure, currently not supported by the Bee client. This codebase is the reference implementation for [the Mantaray 1.0 SWIP](https://github.com/ethersphere/SWIPs/pull/37).
* initManifestNode # initialize a manifest node (either `0.2` or `1.0`)
* Utils # all used utility functions in the library. Mostly operating on `Uint8Array` objects.
* types* # not callable, referring all types exported and reachable from the index

The `MantarayV1` and `MantarayV0_2` versions have similar exposables:

* MantarayNode # class abstracting and manipulating Mantaray Node data
* MantarayFork # class abstracting and manipulating Mantaray Fork data
* checkForSeparator # checks for separator character in the node and its descendants prefixes
* initManifestNode # initialize a manifest node
* loadAllNodes # loads all mantaray nodes recursively from the storage
* equalNodes # checks whether the two given Mantaray Nodes objects are equal in the in-memory abstraction level
* Utils # all used utility functions in the library. Mostly operating on `Uint8Array` objects.
* types* # not callable, referring all types exported and reachable from the index
* checkForSeparator # _(only v0.2)_ checks for separator character in the node and its descendants prefixes
* equalNodes # _(only v0.2)_ checks whether the two given Mantaray Node objects are equal in the in-memory abstraction level

# Basic usage

Expand All @@ -22,32 +29,46 @@ You can import the followings directly from `mantaray-js`:
```ts
import { initManifestNode, Utils } from 'mantaray-js'

const node = initManifestNode()
const address1 = Utils.gen32Bytes() // instead of `gen32Bytes` some 32 bytes identifier that later could be retrieved from the storage
const address2 = Utils.gen32Bytes()
const address3 = Utils.gen32Bytes()
const address4 = Utils.gen32Bytes()
const address5 = Utils.gen32Bytes()
const node = initManifestNode() // by default it gives back 1.0 version of Mantaray
const address1 = Utils.hexToBytes<32>('4a07606f59562544dd37d26a219a65144e8cf3321b21276d8ea8de4af3ecee63')
const address2 = Utils.hexToBytes<32>('0bf983d3bf7d46afad391856f302805cea6d1bdb2df0341a00ae29db42b1eb45')
const address3 = Utils.hexToBytes<32>('5b5a1de0cdbf277446bdfc2b5f03ef12e5da8dfbd5d74ea608b0ff5544d584bd')
const address4 = Utils.hexToBytes<32>('4f64abff074c90d37c82e3e21e4d18fee52eb887a8b163eab167248e1197459e')
const address5 = Utils.hexToBytes<32>('0d7d218dfce224c1b53d7af8fd9cf88e7f053fe978716a768a88a853bd5f1bc7')
const path1 = new TextEncoder().encode('path1/valami/elso')
const path2 = new TextEncoder().encode('path1/valami/masodik')
const path3 = new TextEncoder().encode('path1/valami/masodik.ext')
const path4 = new TextEncoder().encode('path1/valami')
const path5 = new TextEncoder().encode('path2')
node.addFork(path1, address1)
node.addFork(path2, address2, { vmi: 'elso' }) // here 'vmi' is a key of metadata and 'elso' is its value
node.addFork(path3, address3)
node.addFork(path4, address4, { vmi: 'negy' })
node.addFork(path5, address5)
node.addFork(path1, {
entry: address1, // keccak256 hash of any content that can be load from Storage. it acts as reference on the Path.
})
node.addFork(path2, {
entry: address2,
nodeMetadata: { vmi: 'elso' } // JSON metadata about the node that will be serialized on node level
})
node.addFork(path3, {
entry: address3,
forkMetadata: { vmi2: 'masodik' } // JSON metadata about the node that will be serialized on fork level
})
node.addFork(path4, {
entry: address4,
nodeMetadata: { vmi3: '3' },
forkMetadata: { vmi3: 'harmadik', vmi: '3!' }
})
node.addFork(path5, {
nodeMetadata: { metadataAboutPath: 'it is not necessary to save entry for the new node' }
})
node.removePath(path3)
// (...)
```

## Mantaray Storage Operations

```ts
import { MantarayNode } from 'mantaray-js'
import { MantarayV1 } from 'mantaray-js'

const node = new MantarayNode()
const node = new MantarayV1.MantarayNode()
// here `reference` parameter is a `Reference` type which can be a 32 or 64 bytes Uint8Array
// and `loadFunction` is a [loadFunction: async (address: Reference): Promise<Uint8Array>] typed function
// that returns the serialised raw data of a MantarayNode of the given reference
Expand All @@ -68,9 +89,9 @@ The following describes the format of a node binary format.
┌────────────────────────────────┐
│ obfuscationKey <32 byte> │
├────────────────────────────────┤
│ hash("mantaray:0.1") <31 byte> │
│ hash("mantaray:1.0") <31 byte> │
├────────────────────────────────┤
refBytesSize <1 byte>
nodeFeatures <1 byte> │
├────────────────────────────────┤
│ entry <32/64 byte> │
├────────────────────────────────┤
Expand All @@ -81,36 +102,27 @@ The following describes the format of a node binary format.
│ ├────────────────────────────┤ │
│ │ ... │ │
│ ├────────────────────────────┤ │
│ │ Fork N │ │
│ │ Fork N │ │ -> where N maximum is 256
│ └────────────────────────────┘ │
├────────────────────────────────┤
│ nodeMetadata <varlen> │
└────────────────────────────────┘
```

## Fork

```
┌───────────────────┬───────────────────────┬──────────────────┐
nugaon marked this conversation as resolved.
Show resolved Hide resolved
│ nodeType <1 byte> │ prefixLength <1 byte> │ prefix <30 byte> │
├───────────────────┴───────────────────────┴──────────────────┤
│ reference <32/64 bytes> │
│ │
┌───────────────────────────────┬──────────────────────────────┐
│ prefixLength <1 byte> │ prefix <31 byte> │
├───────────────────────────────┴──────────────────────────────┤
│ reference <32/64 byte> │
├──────────────────────────────────────────────────────────────┤
│ forkMetadata <forkMetadataSegmentSize * 32 byte> │
└──────────────────────────────────────────────────────────────┘
```

### Fork with metadata

```
┌───────────────────┬───────────────────────┬──────────────────┐
│ nodeType <1 byte> │ prefixLength <1 byte> │ prefix <30 byte> │
├───────────────────┴───────────────────────┴──────────────────┤
│ reference <32/64 bytes> │
│ │
├─────────────────────────────┬────────────────────────────────┤
│ metadataBytesSize <2 bytes> │ metadataBytes <varlen> │
├─────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
```
If `forkMetadataSegmentSize` is 0, then `forkMetadata` is omitted.
`forkMetadata` has the same length for each fork under one Mantaray node.

# Testing

Expand Down
36 changes: 15 additions & 21 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,10 @@
/* eslint-disable no-console */
/*
* For a detailed explanation regarding each configuration property and type check, visit:
* https://jestjs.io/docs/en/configuration.html
*/
import { BeeDebug } from '@ethersphere/bee-js'
import type { Config } from '@jest/types'

export default async (): Promise<Config.InitialOptions> => {
if (!process.env.BEE_POSTAGE) {
try {
console.log('Creating postage stamps...')
const beeDebugUrl = process.env.BEE_DEBUG_API_URL || 'http://localhost:1635'
const bee = new BeeDebug(beeDebugUrl)
process.env.BEE_POSTAGE = await bee.createPostageBatch('1', 20)
console.log('Queen stamp: ', process.env.BEE_POSTAGE)
// sleep for 11 seconds (10 blocks with ganache block time = 1s)
// needed for postage batches to become usable
// FIXME: sleep should be imported for this, but then we fail with
// Could not find a declaration file for module 'tar-js'
await new Promise<void>(resolve => setTimeout(() => resolve(), 11_000))
} catch (e) {
// It is possible that for unit tests the Bee nodes does not run
// so we are only logging errors and not leaving them to propagate
console.error(e)
}
}

return {
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
Expand All @@ -47,5 +26,20 @@ export default async (): Promise<Config.InitialOptions> => {

// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
testPathIgnorePatterns: ['/node_modules/'],

// Run tests from one or more projects
projects: [
{
displayName: 'node:unit',
testEnvironment: 'node',
testRegex: 'test/unit/((?!\\.browser).)*\\.spec\\.ts',
},
{
displayName: 'node:integration',
testEnvironment: 'node',
testRegex: 'test/integration/((?!\\.browser).)*\\.spec\\.ts',
globalSetup: '<rootDir>/test/test-setup.ts'
},
] as unknown[] as string[], // bad types
}
}
Loading