mirror of
https://github.com/cerc-io/watcher-ts
synced 2024-11-19 12:26:19 +00:00
Implement consensus mechanism using mokka (#412)
* Add Consensus class with placeholders * Implement Consensus constructor * Move PubsubType to peer package * Implement remaining methods in Consensus class * Use existing consensus stream if it exists * Setup send and receive pipes on consensus streams * Refactor P2P and consensus setup in server command * Add Nitro node initialization in server command * Return objects from server initializations * Use dynamic imports for ES modules in util package * Fix util deps * Change target to es6 to allow creating a Mokka instance * Set moduleResolution to node16 in util for dynamic imports * Upgrade @cerc-io/nitro-node package * Implement retries while sending consensus messages * Use bunyan for consensus logs and subscribe to state changes * Use debug for logging state change events * Handle empty watcher party file path * Return object from initP2P * Upgrade @cerc-io/nitro-node package * Update package versions
This commit is contained in:
parent
c80e4d0ab7
commit
bd73dae1b1
@ -2,7 +2,7 @@
|
|||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"command": {
|
"command": {
|
||||||
|
2
packages/cache/package.json
vendored
2
packages/cache/package.json
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/cache",
|
"name": "@cerc-io/cache",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "Generic object cache",
|
"description": "Generic object cache",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/cli",
|
"name": "@cerc-io/cli",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -12,11 +12,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.7.1",
|
"@apollo/client": "^3.7.1",
|
||||||
"@cerc-io/cache": "^0.2.56",
|
"@cerc-io/cache": "^0.2.57",
|
||||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||||
"@cerc-io/peer": "^0.2.56",
|
"@cerc-io/libp2p": "^0.42.2-laconic-0.1.4",
|
||||||
"@cerc-io/rpc-eth-client": "^0.2.56",
|
"@cerc-io/nitro-node": "^0.1.10",
|
||||||
"@cerc-io/util": "^0.2.56",
|
"@cerc-io/peer": "^0.2.57",
|
||||||
|
"@cerc-io/rpc-eth-client": "^0.2.57",
|
||||||
|
"@cerc-io/util": "^0.2.57",
|
||||||
"@ethersproject/providers": "^5.4.4",
|
"@ethersproject/providers": "^5.4.4",
|
||||||
"@graphql-tools/utils": "^9.1.1",
|
"@graphql-tools/utils": "^9.1.1",
|
||||||
"@ipld/dag-cbor": "^8.0.0",
|
"@ipld/dag-cbor": "^8.0.0",
|
||||||
|
@ -11,10 +11,10 @@ import path from 'path';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
PeerInitConfig,
|
PeerInitConfig,
|
||||||
PeerIdObj
|
PeerIdObj,
|
||||||
|
PubsubType
|
||||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
} from '@cerc-io/peer';
|
} from '@cerc-io/peer';
|
||||||
import { PubsubType } from '@cerc-io/util';
|
|
||||||
|
|
||||||
import { readPeerId } from './utils';
|
import { readPeerId } from './utils';
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
|
import path from 'path';
|
||||||
import yargs from 'yargs';
|
import yargs from 'yargs';
|
||||||
import { hideBin } from 'yargs/helpers';
|
import { hideBin } from 'yargs/helpers';
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
@ -25,17 +26,21 @@ import {
|
|||||||
EventWatcher,
|
EventWatcher,
|
||||||
GraphWatcherInterface,
|
GraphWatcherInterface,
|
||||||
Config,
|
Config,
|
||||||
P2PConfig,
|
PaymentsManager,
|
||||||
PaymentsManager
|
Consensus,
|
||||||
|
readParty
|
||||||
} from '@cerc-io/util';
|
} from '@cerc-io/util';
|
||||||
import { TypeSource } from '@graphql-tools/utils';
|
import { TypeSource } from '@graphql-tools/utils';
|
||||||
import {
|
import type {
|
||||||
RelayNodeInitConfig,
|
RelayNodeInitConfig,
|
||||||
PeerInitConfig,
|
PeerInitConfig,
|
||||||
PeerIdObj,
|
PeerIdObj,
|
||||||
Peer
|
Peer
|
||||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
} from '@cerc-io/peer';
|
} from '@cerc-io/peer';
|
||||||
|
import { Node as NitroNode, utils } from '@cerc-io/nitro-node';
|
||||||
|
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||||
|
import type { Libp2p } from '@cerc-io/libp2p';
|
||||||
|
|
||||||
import { BaseCmd } from './base';
|
import { BaseCmd } from './base';
|
||||||
import { readPeerId } from './utils/index';
|
import { readPeerId } from './utils/index';
|
||||||
@ -50,6 +55,8 @@ export class ServerCmd {
|
|||||||
_argv?: Arguments;
|
_argv?: Arguments;
|
||||||
_baseCmd: BaseCmd;
|
_baseCmd: BaseCmd;
|
||||||
_peer?: Peer;
|
_peer?: Peer;
|
||||||
|
_nitro?: NitroNode;
|
||||||
|
_consensus?: Consensus;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this._baseCmd = new BaseCmd();
|
this._baseCmd = new BaseCmd();
|
||||||
@ -75,6 +82,14 @@ export class ServerCmd {
|
|||||||
return this._peer;
|
return this._peer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get nitro (): NitroNode | undefined {
|
||||||
|
return this._nitro;
|
||||||
|
}
|
||||||
|
|
||||||
|
get consensus (): Consensus | undefined {
|
||||||
|
return this._consensus;
|
||||||
|
}
|
||||||
|
|
||||||
async initConfig<ConfigType> (): Promise<ConfigType> {
|
async initConfig<ConfigType> (): Promise<ConfigType> {
|
||||||
this._argv = this._getArgv();
|
this._argv = this._getArgv();
|
||||||
assert(this._argv);
|
assert(this._argv);
|
||||||
@ -109,53 +124,15 @@ export class ServerCmd {
|
|||||||
await this._baseCmd.initEventWatcher();
|
await this._baseCmd.initEventWatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
async exec (
|
async initP2P (): Promise<{ relayNode?: Libp2p, peer?: Peer }> {
|
||||||
createResolvers: (indexer: IndexerInterface, eventWatcher: EventWatcher) => Promise<any>,
|
let relayNode: Libp2p | undefined;
|
||||||
typeDefs: TypeSource,
|
|
||||||
parseLibp2pMessage?: (peerId: string, data: any) => void,
|
|
||||||
paymentsManager?: PaymentsManager
|
|
||||||
): Promise<{
|
|
||||||
app: Application,
|
|
||||||
server: ApolloServer
|
|
||||||
}> {
|
|
||||||
const config = this._baseCmd.config;
|
|
||||||
const jobQueue = this._baseCmd.jobQueue;
|
|
||||||
const indexer = this._baseCmd.indexer;
|
|
||||||
const eventWatcher = this._baseCmd.eventWatcher;
|
|
||||||
|
|
||||||
assert(config);
|
|
||||||
assert(jobQueue);
|
|
||||||
assert(indexer);
|
|
||||||
assert(eventWatcher);
|
|
||||||
|
|
||||||
if (config.server.kind === KIND_ACTIVE) {
|
|
||||||
// Delete jobs to prevent creating jobs after completion of processing previous block.
|
|
||||||
await jobQueue.deleteAllJobs();
|
|
||||||
await eventWatcher.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
const resolvers = await createResolvers(indexer, eventWatcher);
|
|
||||||
|
|
||||||
// Create an Express app
|
|
||||||
const app: Application = express();
|
|
||||||
const server = await createAndStartServer(app, typeDefs, resolvers, config.server, paymentsManager);
|
|
||||||
|
|
||||||
await startGQLMetricsServer(config);
|
|
||||||
|
|
||||||
const p2pConfig = config.server.p2p;
|
|
||||||
|
|
||||||
// Start P2P nodes if config provided
|
// Start P2P nodes if config provided
|
||||||
if (p2pConfig) {
|
const p2pConfig = this._baseCmd.config.server.p2p;
|
||||||
await this._startP2PNodes(p2pConfig, parseLibp2pMessage);
|
if (!p2pConfig) {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return { app, server };
|
|
||||||
}
|
|
||||||
|
|
||||||
async _startP2PNodes (
|
|
||||||
p2pConfig: P2PConfig,
|
|
||||||
parseLibp2pMessage?: (peerId: string, data: any) => void
|
|
||||||
): Promise<void> {
|
|
||||||
const { createRelayNode, Peer } = await import('@cerc-io/peer');
|
const { createRelayNode, Peer } = await import('@cerc-io/peer');
|
||||||
const {
|
const {
|
||||||
RELAY_DEFAULT_HOST,
|
RELAY_DEFAULT_HOST,
|
||||||
@ -190,7 +167,8 @@ export class ServerCmd {
|
|||||||
pubsub: relayConfig.pubsub,
|
pubsub: relayConfig.pubsub,
|
||||||
enableDebugInfo: relayConfig.enableDebugInfo
|
enableDebugInfo: relayConfig.enableDebugInfo
|
||||||
};
|
};
|
||||||
await createRelayNode(relayNodeInit);
|
|
||||||
|
relayNode = await createRelayNode(relayNodeInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run a peer node if enabled
|
// Run a peer node if enabled
|
||||||
@ -218,14 +196,110 @@ export class ServerCmd {
|
|||||||
};
|
};
|
||||||
await this._peer.init(peerNodeInit, peerIdObj);
|
await this._peer.init(peerNodeInit, peerIdObj);
|
||||||
|
|
||||||
this._peer.subscribeTopic(peerConfig.pubSubTopic, (peerId, data) => {
|
|
||||||
if (parseLibp2pMessage) {
|
|
||||||
parseLibp2pMessage(peerId.toString(), data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
log(`Peer ID: ${this._peer.peerId?.toString()}`);
|
log(`Peer ID: ${this._peer.peerId?.toString()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return { relayNode, peer: this._peer };
|
||||||
|
}
|
||||||
|
|
||||||
|
async initConsensus (): Promise<Consensus | undefined> {
|
||||||
|
const p2pConfig = this._baseCmd.config.server.p2p;
|
||||||
|
const { consensus: consensusConfig } = p2pConfig;
|
||||||
|
|
||||||
|
// Setup consensus engine if enabled
|
||||||
|
// Consensus requires p2p peer to be enabled
|
||||||
|
if (!p2pConfig.enablePeer || !consensusConfig.enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(this.peer);
|
||||||
|
const watcherPartyPeers = readParty(consensusConfig.watcherPartyFile);
|
||||||
|
|
||||||
|
// Create and initialize the consensus engine
|
||||||
|
this._consensus = new Consensus({
|
||||||
|
peer: this.peer,
|
||||||
|
publicKey: consensusConfig.publicKey,
|
||||||
|
privateKey: consensusConfig.privateKey,
|
||||||
|
party: watcherPartyPeers
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect registers the required p2p protocol handlers and starts the engine
|
||||||
|
this._consensus.connect();
|
||||||
|
log('Consensus engine started');
|
||||||
|
|
||||||
|
return this._consensus;
|
||||||
|
}
|
||||||
|
|
||||||
|
async initNitro (nitroContractAddresses: { [key: string]: string }): Promise<NitroNode | undefined> {
|
||||||
|
// Start a Nitro node
|
||||||
|
const {
|
||||||
|
server: {
|
||||||
|
p2p: {
|
||||||
|
enablePeer,
|
||||||
|
nitro: nitroConfig
|
||||||
|
}
|
||||||
|
},
|
||||||
|
upstream: {
|
||||||
|
ethServer: {
|
||||||
|
rpcProviderEndpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} = this._baseCmd.config;
|
||||||
|
|
||||||
|
// Nitro requires p2p peer to be enabled
|
||||||
|
if (!enablePeer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(this.peer);
|
||||||
|
const nitro = await utils.Nitro.setupNode(
|
||||||
|
nitroConfig.privateKey,
|
||||||
|
rpcProviderEndpoint,
|
||||||
|
nitroConfig.chainPrivateKey,
|
||||||
|
nitroContractAddresses,
|
||||||
|
this.peer,
|
||||||
|
path.resolve(nitroConfig.store)
|
||||||
|
);
|
||||||
|
|
||||||
|
this._nitro = nitro.node;
|
||||||
|
log(`Nitro node started with address: ${this._nitro.address}`);
|
||||||
|
|
||||||
|
return this._nitro;
|
||||||
|
}
|
||||||
|
|
||||||
|
async exec (
|
||||||
|
createResolvers: (indexer: IndexerInterface, eventWatcher: EventWatcher) => Promise<any>,
|
||||||
|
typeDefs: TypeSource,
|
||||||
|
paymentsManager?: PaymentsManager
|
||||||
|
): Promise<{
|
||||||
|
app: Application,
|
||||||
|
server: ApolloServer
|
||||||
|
}> {
|
||||||
|
const config = this._baseCmd.config;
|
||||||
|
const jobQueue = this._baseCmd.jobQueue;
|
||||||
|
const indexer = this._baseCmd.indexer;
|
||||||
|
const eventWatcher = this._baseCmd.eventWatcher;
|
||||||
|
|
||||||
|
assert(config);
|
||||||
|
assert(jobQueue);
|
||||||
|
assert(indexer);
|
||||||
|
assert(eventWatcher);
|
||||||
|
|
||||||
|
if (config.server.kind === KIND_ACTIVE) {
|
||||||
|
// Delete jobs to prevent creating jobs after completion of processing previous block.
|
||||||
|
await jobQueue.deleteAllJobs();
|
||||||
|
await eventWatcher.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
const resolvers = await createResolvers(indexer, eventWatcher);
|
||||||
|
|
||||||
|
// Create an Express app
|
||||||
|
const app: Application = express();
|
||||||
|
const server = await createAndStartServer(app, typeDefs, resolvers, config.server, paymentsManager);
|
||||||
|
|
||||||
|
await startGQLMetricsServer(config);
|
||||||
|
|
||||||
|
return { app, server };
|
||||||
}
|
}
|
||||||
|
|
||||||
_getArgv (): any {
|
_getArgv (): any {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/codegen",
|
"name": "@cerc-io/codegen",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "Code generator",
|
"description": "Code generator",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cerc-io/util": "^0.2.56",
|
"@cerc-io/util": "^0.2.57",
|
||||||
"@graphql-tools/load-files": "^6.5.2",
|
"@graphql-tools/load-files": "^6.5.2",
|
||||||
"@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git",
|
"@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git",
|
||||||
"@solidity-parser/parser": "^0.13.2",
|
"@solidity-parser/parser": "^0.13.2",
|
||||||
|
@ -41,12 +41,12 @@
|
|||||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.3.19",
|
"@apollo/client": "^3.3.19",
|
||||||
"@cerc-io/cli": "^0.2.56",
|
"@cerc-io/cli": "^0.2.57",
|
||||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
"@cerc-io/solidity-mapper": "^0.2.57",
|
||||||
"@cerc-io/util": "^0.2.56",
|
"@cerc-io/util": "^0.2.57",
|
||||||
{{#if (subgraphPath)}}
|
{{#if (subgraphPath)}}
|
||||||
"@cerc-io/graph-node": "^0.2.56",
|
"@cerc-io/graph-node": "^0.2.57",
|
||||||
{{/if}}
|
{{/if}}
|
||||||
"@ethersproject/providers": "^5.4.4",
|
"@ethersproject/providers": "^5.4.4",
|
||||||
"apollo-type-bigint": "^0.1.3",
|
"apollo-type-bigint": "^0.1.3",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/graph-node",
|
"name": "@cerc-io/graph-node",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
"@cerc-io/solidity-mapper": "^0.2.57",
|
||||||
"@ethersproject/providers": "^5.4.4",
|
"@ethersproject/providers": "^5.4.4",
|
||||||
"@graphprotocol/graph-ts": "^0.22.0",
|
"@graphprotocol/graph-ts": "^0.22.0",
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
@ -51,9 +51,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.3.19",
|
"@apollo/client": "^3.3.19",
|
||||||
"@cerc-io/assemblyscript": "0.19.10-watcher-ts-0.1.2",
|
"@cerc-io/assemblyscript": "0.19.10-watcher-ts-0.1.2",
|
||||||
"@cerc-io/cache": "^0.2.56",
|
"@cerc-io/cache": "^0.2.57",
|
||||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||||
"@cerc-io/util": "^0.2.56",
|
"@cerc-io/util": "^0.2.57",
|
||||||
"@types/json-diff": "^0.5.2",
|
"@types/json-diff": "^0.5.2",
|
||||||
"@types/yargs": "^17.0.0",
|
"@types/yargs": "^17.0.0",
|
||||||
"bn.js": "^4.11.9",
|
"bn.js": "^4.11.9",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/ipld-eth-client",
|
"name": "@cerc-io/ipld-eth-client",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "IPLD ETH Client",
|
"description": "IPLD ETH Client",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/client": "^3.7.1",
|
"@apollo/client": "^3.7.1",
|
||||||
"@cerc-io/cache": "^0.2.56",
|
"@cerc-io/cache": "^0.2.57",
|
||||||
"cross-fetch": "^3.1.4",
|
"cross-fetch": "^3.1.4",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"ethers": "^5.4.4",
|
"ethers": "^5.4.4",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/peer",
|
"name": "@cerc-io/peer",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "libp2p module",
|
"description": "libp2p module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"exports": "./dist/index.js",
|
"exports": "./dist/index.js",
|
||||||
@ -28,9 +28,8 @@
|
|||||||
"test": "mocha dist/peer.test.js --bail"
|
"test": "mocha dist/peer.test.js --bail"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cerc-io/libp2p": "0.42.2-laconic-0.1.4",
|
"@cerc-io/libp2p": "^0.42.2-laconic-0.1.4",
|
||||||
"@cerc-io/prometheus-metrics": "1.1.4",
|
"@cerc-io/prometheus-metrics": "1.1.4",
|
||||||
"@cerc-io/util": "^0.2.56",
|
|
||||||
"@chainsafe/libp2p-gossipsub": "^6.0.0",
|
"@chainsafe/libp2p-gossipsub": "^6.0.0",
|
||||||
"@chainsafe/libp2p-noise": "^11.0.0",
|
"@chainsafe/libp2p-noise": "^11.0.0",
|
||||||
"@libp2p/floodsub": "^6.0.0",
|
"@libp2p/floodsub": "^6.0.0",
|
||||||
|
@ -3,8 +3,6 @@ import { hideBin } from 'yargs/helpers';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { PubsubType } from '@cerc-io/util';
|
|
||||||
|
|
||||||
import { RelayNodeInitConfig, createRelayNode } from '../relay.js';
|
import { RelayNodeInitConfig, createRelayNode } from '../relay.js';
|
||||||
import { PeerIdObj } from '../peer.js';
|
import { PeerIdObj } from '../peer.js';
|
||||||
import {
|
import {
|
||||||
@ -15,6 +13,7 @@ import {
|
|||||||
DEFAULT_PING_INTERVAL,
|
DEFAULT_PING_INTERVAL,
|
||||||
DIAL_TIMEOUT
|
DIAL_TIMEOUT
|
||||||
} from '../constants.js';
|
} from '../constants.js';
|
||||||
|
import { PubsubType } from '../utils/index.js';
|
||||||
|
|
||||||
interface Arguments {
|
interface Arguments {
|
||||||
host: string;
|
host: string;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
export { Peer, PeerIdObj, PeerInitConfig, createPeerId } from './peer.js';
|
export { Peer, PeerIdObj, PeerInitConfig, createPeerId } from './peer.js';
|
||||||
export { RelayNodeInitConfig, createRelayNode } from './relay.js';
|
export { RelayNodeInitConfig, createRelayNode } from './relay.js';
|
||||||
export { getPseudonymForPeerId } from './utils/index.js';
|
export { getPseudonymForPeerId, PubsubType } from './utils/index.js';
|
||||||
export {
|
export {
|
||||||
RELAY_DEFAULT_HOST,
|
RELAY_DEFAULT_HOST,
|
||||||
RELAY_DEFAULT_PORT,
|
RELAY_DEFAULT_PORT,
|
||||||
|
@ -12,7 +12,6 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|||||||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
|
|
||||||
import { PubsubType } from '@cerc-io/util';
|
|
||||||
import { createLibp2p, Libp2p, Libp2pInit } from '@cerc-io/libp2p';
|
import { createLibp2p, Libp2p, Libp2pInit } from '@cerc-io/libp2p';
|
||||||
import { webSockets } from '@libp2p/websockets';
|
import { webSockets } from '@libp2p/websockets';
|
||||||
import { noise } from '@chainsafe/libp2p-noise';
|
import { noise } from '@chainsafe/libp2p-noise';
|
||||||
@ -42,7 +41,7 @@ import {
|
|||||||
P2P_WEBRTC_STAR_ID
|
P2P_WEBRTC_STAR_ID
|
||||||
} from './constants.js';
|
} from './constants.js';
|
||||||
import { PeerHearbeatChecker } from './peer-heartbeat-checker.js';
|
import { PeerHearbeatChecker } from './peer-heartbeat-checker.js';
|
||||||
import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, initPubsub, isMultiaddrBlacklisted, wsPeerFilter } from './utils/index.js';
|
import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, initPubsub, isMultiaddrBlacklisted, PubsubType, wsPeerFilter } from './utils/index.js';
|
||||||
import { ConnectionType, DebugPeerInfo, DebugRequest, PeerConnectionInfo, PeerSelfInfo } from './types/debug-info.js';
|
import { ConnectionType, DebugPeerInfo, DebugRequest, PeerConnectionInfo, PeerSelfInfo } from './types/debug-info.js';
|
||||||
|
|
||||||
const log = debug('laconic:peer');
|
const log = debug('laconic:peer');
|
||||||
|
@ -6,7 +6,6 @@ import debug from 'debug';
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
||||||
|
|
||||||
import { PubsubType } from '@cerc-io/util';
|
|
||||||
import { Libp2p, createLibp2p } from '@cerc-io/libp2p';
|
import { Libp2p, createLibp2p } from '@cerc-io/libp2p';
|
||||||
import { noise } from '@chainsafe/libp2p-noise';
|
import { noise } from '@chainsafe/libp2p-noise';
|
||||||
import { mplex } from '@libp2p/mplex';
|
import { mplex } from '@libp2p/mplex';
|
||||||
@ -27,7 +26,7 @@ import {
|
|||||||
DEBUG_INFO_TOPIC
|
DEBUG_INFO_TOPIC
|
||||||
} from './constants.js';
|
} from './constants.js';
|
||||||
import { PeerHearbeatChecker } from './peer-heartbeat-checker.js';
|
import { PeerHearbeatChecker } from './peer-heartbeat-checker.js';
|
||||||
import { debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, initPubsub, isMultiaddrBlacklisted } from './utils/index.js';
|
import { PubsubType, debugInfoRequestHandler, dialWithRetry, getConnectionsInfo, getPseudonymForPeerId, getSelfInfo, initPubsub, isMultiaddrBlacklisted } from './utils/index.js';
|
||||||
import { PeerIdObj } from './peer.js';
|
import { PeerIdObj } from './peer.js';
|
||||||
import { SelfInfo, ConnectionInfo } from './types/debug-info.js';
|
import { SelfInfo, ConnectionInfo } from './types/debug-info.js';
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|||||||
import { ConnectionInfo, ConnectionType, DebugMsg, DebugPeerInfo, DebugResponse, SelfInfo } from '../types/debug-info.js';
|
import { ConnectionInfo, ConnectionType, DebugMsg, DebugPeerInfo, DebugResponse, SelfInfo } from '../types/debug-info.js';
|
||||||
import { DEBUG_INFO_TOPIC, DEFAULT_PUBSUB_TYPE, P2P_WEBRTC_STAR_ID, PUBSUB_SIGNATURE_POLICY } from '../constants.js';
|
import { DEBUG_INFO_TOPIC, DEFAULT_PUBSUB_TYPE, P2P_WEBRTC_STAR_ID, PUBSUB_SIGNATURE_POLICY } from '../constants.js';
|
||||||
import { PeerHearbeatChecker } from '../peer-heartbeat-checker.js';
|
import { PeerHearbeatChecker } from '../peer-heartbeat-checker.js';
|
||||||
import { PubsubType } from '@cerc-io/util';
|
|
||||||
|
|
||||||
const log = debug('laconic:utils');
|
const log = debug('laconic:utils');
|
||||||
|
|
||||||
@ -28,6 +27,8 @@ export const CODE_CIRCUIT = 290;
|
|||||||
|
|
||||||
const ERR_INVALID_PUBSUB_TYPE = 'Invalid pubsub type';
|
const ERR_INVALID_PUBSUB_TYPE = 'Invalid pubsub type';
|
||||||
|
|
||||||
|
export type PubsubType = 'floodsub' | 'gossipsub';
|
||||||
|
|
||||||
interface DialWithRetryOptions {
|
interface DialWithRetryOptions {
|
||||||
redialInterval: number
|
redialInterval: number
|
||||||
maxRetry: number
|
maxRetry: number
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/rpc-eth-client",
|
"name": "@cerc-io/rpc-eth-client",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "RPC ETH Client",
|
"description": "RPC ETH Client",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -19,9 +19,9 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cerc-io/cache": "^0.2.56",
|
"@cerc-io/cache": "^0.2.57",
|
||||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||||
"@cerc-io/util": "^0.2.56",
|
"@cerc-io/util": "^0.2.57",
|
||||||
"chai": "^4.3.4",
|
"chai": "^4.3.4",
|
||||||
"ethers": "^5.4.4",
|
"ethers": "^5.4.4",
|
||||||
"left-pad": "^1.3.0",
|
"left-pad": "^1.3.0",
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/solidity-mapper",
|
"name": "@cerc-io/solidity-mapper",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||||
"@ethersproject/abi": "^5.3.0",
|
"@ethersproject/abi": "^5.3.0",
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/test",
|
"name": "@cerc-io/test",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/tracing-client",
|
"name": "@cerc-io/tracing-client",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"description": "ETH VM tracing client",
|
"description": "ETH VM tracing client",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "@cerc-io/util",
|
"name": "@cerc-io/util",
|
||||||
"version": "0.2.56",
|
"version": "0.2.57",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/utils.keyvaluecache": "^1.0.1",
|
"@apollo/utils.keyvaluecache": "^1.0.1",
|
||||||
"@cerc-io/nitro-node": "^0.1.8",
|
"@cerc-io/nitro-node": "^0.1.10",
|
||||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
"@cerc-io/peer": "^0.2.57",
|
||||||
|
"@cerc-io/solidity-mapper": "^0.2.57",
|
||||||
"@cerc-io/ts-channel": "1.0.3-ts-nitro-0.1.1",
|
"@cerc-io/ts-channel": "1.0.3-ts-nitro-0.1.1",
|
||||||
"@ethersproject/providers": "^5.4.4",
|
"@ethersproject/providers": "^5.4.4",
|
||||||
"@graphql-tools/schema": "^9.0.10",
|
"@graphql-tools/schema": "^9.0.10",
|
||||||
"@graphql-tools/utils": "^9.1.1",
|
"@graphql-tools/utils": "^9.1.1",
|
||||||
"@ipld/dag-cbor": "^6.0.12",
|
"@ipld/dag-cbor": "^6.0.12",
|
||||||
|
"@libp2p/interface-connection": "^3.0.2",
|
||||||
|
"@libp2p/interface-peer-id": "^2.0.0",
|
||||||
|
"@libp2p/peer-id": "^2.0.0",
|
||||||
"apollo-server-core": "^3.11.1",
|
"apollo-server-core": "^3.11.1",
|
||||||
"apollo-server-express": "^3.11.1",
|
"apollo-server-express": "^3.11.1",
|
||||||
"apollo-server-plugin-response-cache": "^3.8.1",
|
"apollo-server-plugin-response-cache": "^3.8.1",
|
||||||
|
"bunyan": "^1.8.15",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"decimal.js": "^10.3.1",
|
"decimal.js": "^10.3.1",
|
||||||
"ethers": "^5.4.4",
|
"ethers": "^5.4.4",
|
||||||
@ -25,10 +30,14 @@
|
|||||||
"graphql-subscriptions": "^2.0.0",
|
"graphql-subscriptions": "^2.0.0",
|
||||||
"graphql-ws": "^5.11.2",
|
"graphql-ws": "^5.11.2",
|
||||||
"ipfs-http-client": "^56.0.3",
|
"ipfs-http-client": "^56.0.3",
|
||||||
|
"it-length-prefixed": "^8.0.4",
|
||||||
|
"it-pipe": "^2.0.5",
|
||||||
|
"it-pushable": "^3.1.2",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"json-bigint": "^1.0.0",
|
"json-bigint": "^1.0.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"lru-cache": "^10.0.0",
|
"lru-cache": "^10.0.0",
|
||||||
|
"mokka": "^1.4.2",
|
||||||
"multiformats": "^9.4.8",
|
"multiformats": "^9.4.8",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
"pg-boss": "^6.1.0",
|
"pg-boss": "^6.1.0",
|
||||||
@ -40,8 +49,9 @@
|
|||||||
"yargs": "^17.0.1"
|
"yargs": "^17.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cerc-io/cache": "^0.2.56",
|
"@cerc-io/cache": "^0.2.57",
|
||||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||||
|
"@types/bunyan": "^1.8.8",
|
||||||
"@types/express": "^4.17.14",
|
"@types/express": "^4.17.14",
|
||||||
"@types/fs-extra": "^9.0.11",
|
"@types/fs-extra": "^9.0.11",
|
||||||
"@types/js-yaml": "^4.0.4",
|
"@types/js-yaml": "^4.0.4",
|
||||||
|
@ -9,11 +9,11 @@ import debug from 'debug';
|
|||||||
import { ConnectionOptions } from 'typeorm';
|
import { ConnectionOptions } from 'typeorm';
|
||||||
|
|
||||||
import { Config as CacheConfig } from '@cerc-io/cache';
|
import { Config as CacheConfig } from '@cerc-io/cache';
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
|
import type { PubsubType } from '@cerc-io/peer';
|
||||||
|
|
||||||
const log = debug('vulcanize:config');
|
const log = debug('vulcanize:config');
|
||||||
|
|
||||||
export type PubsubType = 'floodsub' | 'gossipsub';
|
|
||||||
|
|
||||||
export interface JobQueueConfig {
|
export interface JobQueueConfig {
|
||||||
dbConnectionString: string;
|
dbConnectionString: string;
|
||||||
maxCompletionLagInSecs: number;
|
maxCompletionLagInSecs: number;
|
||||||
@ -162,6 +162,14 @@ export interface NitroConfig {
|
|||||||
payments: PaymentsConfig;
|
payments: PaymentsConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consensus config
|
||||||
|
export interface ConsensusConfig {
|
||||||
|
enabled: boolean;
|
||||||
|
publicKey: string;
|
||||||
|
privateKey: string;
|
||||||
|
watcherPartyFile: string;
|
||||||
|
}
|
||||||
|
|
||||||
// P2P config
|
// P2P config
|
||||||
export interface P2PConfig {
|
export interface P2PConfig {
|
||||||
// Enable relay node
|
// Enable relay node
|
||||||
@ -172,7 +180,9 @@ export interface P2PConfig {
|
|||||||
enablePeer: boolean;
|
enablePeer: boolean;
|
||||||
peer: PeerConfig;
|
peer: PeerConfig;
|
||||||
|
|
||||||
nitro: NitroConfig
|
nitro: NitroConfig;
|
||||||
|
|
||||||
|
consensus: ConsensusConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServerConfig {
|
export interface ServerConfig {
|
||||||
|
238
packages/util/src/consensus.ts
Normal file
238
packages/util/src/consensus.ts
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import assert from 'assert';
|
||||||
|
import debug from 'debug';
|
||||||
|
import * as bunyan from 'bunyan';
|
||||||
|
import { Mokka } from 'mokka';
|
||||||
|
import * as MokkaStates from 'mokka/dist/consensus/constants/NodeStates';
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
|
import type { Pushable } from 'it-pushable';
|
||||||
|
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
|
import type { Peer } from '@cerc-io/peer';
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
|
import type { Stream as P2PStream } from '@libp2p/interface-connection';
|
||||||
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
|
import type { PeerId } from '@libp2p/interface-peer-id';
|
||||||
|
|
||||||
|
const LOG_NAMESPACE = 'laconic:consensus';
|
||||||
|
const CONSENSUS_LOG_LEVEL = 'debug';
|
||||||
|
const log = debug(LOG_NAMESPACE);
|
||||||
|
|
||||||
|
const CONSENSUS_PROTOCOL = '/consensus/1.0.0';
|
||||||
|
|
||||||
|
const NUM_WRITE_ATTEMPTS = 20;
|
||||||
|
const RETRY_SLEEP_DURATION = 15 * 1000; // 15 seconds
|
||||||
|
|
||||||
|
const DEFAULT_HEARTBEAT = 300;
|
||||||
|
const DEFAULT_ELECTION_TIMEOUT = 1000;
|
||||||
|
const DEFAULT_PROOF_EXPIRATION = 20000;
|
||||||
|
const DEFAULT_CRASH_MODEL = 'BFT';
|
||||||
|
|
||||||
|
const consensusStates: Record<number, string> = {
|
||||||
|
[MokkaStates.default.STOPPED]: 'STOPPED',
|
||||||
|
[MokkaStates.default.LEADER]: 'LEADER',
|
||||||
|
[MokkaStates.default.CANDIDATE]: 'CANDIDATE',
|
||||||
|
[MokkaStates.default.FOLLOWER]: 'FOLLOWER'
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface PartyPeer {
|
||||||
|
peerId: string;
|
||||||
|
publicKey: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConsensusOptions {
|
||||||
|
peer: Peer;
|
||||||
|
|
||||||
|
publicKey: string;
|
||||||
|
privateKey: string;
|
||||||
|
|
||||||
|
party: PartyPeer[];
|
||||||
|
|
||||||
|
// For Mokka options (ISettingsInterface)
|
||||||
|
heartbeat?: number;
|
||||||
|
electionTimeout?: number;
|
||||||
|
proofExpiration?: number;
|
||||||
|
crashModel?: 'CFT' | 'BFT';
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Consensus extends Mokka {
|
||||||
|
peer: Peer;
|
||||||
|
party: PartyPeer[];
|
||||||
|
|
||||||
|
private messageStreamMap: Map<string, Pushable<any>> = new Map();
|
||||||
|
|
||||||
|
constructor (options: ConsensusOptions) {
|
||||||
|
const heartbeat = options.heartbeat ?? DEFAULT_HEARTBEAT;
|
||||||
|
const electionTimeout = options.electionTimeout ?? DEFAULT_ELECTION_TIMEOUT;
|
||||||
|
const proofExpiration = options.proofExpiration ?? DEFAULT_PROOF_EXPIRATION;
|
||||||
|
const crashModel = options.crashModel ?? DEFAULT_CRASH_MODEL;
|
||||||
|
|
||||||
|
// address format: 'libp2p_peerid/node_publickey'
|
||||||
|
// See:
|
||||||
|
// https://github.com/ega-forever/mokka#new-mokka-options
|
||||||
|
// https://github.com/ega-forever/mokka/blob/master/src/consensus/models/NodeModel.ts#L46
|
||||||
|
const peerId = options.peer.peerId;
|
||||||
|
const address = `${peerId?.toString()}/${options.publicKey}`;
|
||||||
|
|
||||||
|
const logger = bunyan.createLogger({ name: LOG_NAMESPACE, level: CONSENSUS_LOG_LEVEL });
|
||||||
|
|
||||||
|
super({
|
||||||
|
address,
|
||||||
|
privateKey: options.privateKey,
|
||||||
|
heartbeat,
|
||||||
|
electionTimeout,
|
||||||
|
proofExpiration,
|
||||||
|
crashModel,
|
||||||
|
// TODO: Improve logging
|
||||||
|
logger
|
||||||
|
});
|
||||||
|
|
||||||
|
// Subscribe to state changes
|
||||||
|
this.on('state', () => {
|
||||||
|
log(`State changed to ${this.state} (${consensusStates[this.state]}) with term ${this.term}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peer = options.peer;
|
||||||
|
this.party = options.party;
|
||||||
|
|
||||||
|
// Add peer nodes in the party
|
||||||
|
// TODO: Skip initialization if party not provided?
|
||||||
|
for (const partyPeer of options.party) {
|
||||||
|
const address = `${partyPeer.peerId}/${partyPeer.publicKey}`;
|
||||||
|
this.nodeApi.join(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isLeader (): boolean {
|
||||||
|
return this.state === MokkaStates.default.LEADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
initialize (): void {
|
||||||
|
assert(this.peer.node);
|
||||||
|
|
||||||
|
this.peer.node.handle(CONSENSUS_PROTOCOL, async ({ stream, connection }) => {
|
||||||
|
// Setup send and receive pipes
|
||||||
|
this.handleStream(connection.remotePeer, stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
connect (): void {
|
||||||
|
this.initialize();
|
||||||
|
|
||||||
|
// TODO: Handle errors when peers don't join
|
||||||
|
super.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
async write (address: string, packet: Buffer): Promise<void> {
|
||||||
|
assert(this.peer.node);
|
||||||
|
|
||||||
|
// TODO: Use a different strategy for retries?
|
||||||
|
for (let i = 0; i < NUM_WRITE_ATTEMPTS; i += 1) {
|
||||||
|
try {
|
||||||
|
let messageStream = this.messageStreamMap.get(address);
|
||||||
|
if (!messageStream) {
|
||||||
|
const { peerIdFromString } = await import('@libp2p/peer-id');
|
||||||
|
const peerId = peerIdFromString(address);
|
||||||
|
|
||||||
|
// Dial to the peer over consensus protocol
|
||||||
|
const p2pStream = await this.peer.node.dialProtocol(peerId, CONSENSUS_PROTOCOL);
|
||||||
|
|
||||||
|
// Setup send and receive pipes
|
||||||
|
messageStream = await this.handleStream(peerId, p2pStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
messageStream.push(packet);
|
||||||
|
return;
|
||||||
|
} catch (err) {
|
||||||
|
log(`Attempt ${i} - Could not open consensus stream to ${address}: ${err}`);
|
||||||
|
if (i === NUM_WRITE_ATTEMPTS) {
|
||||||
|
log('Write attempts exhausted');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retry after a set interval
|
||||||
|
await new Promise((resolve) => { setTimeout(resolve, RETRY_SLEEP_DURATION); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async disconnect (): Promise<void> {
|
||||||
|
assert(this.peer.node);
|
||||||
|
await super.disconnect();
|
||||||
|
|
||||||
|
const { peerIdFromString } = await import('@libp2p/peer-id');
|
||||||
|
|
||||||
|
// Close all consensus protocol streams
|
||||||
|
for (const partyPeer of this.party) {
|
||||||
|
for (const conn of this.peer.node.getConnections(peerIdFromString(partyPeer.peerId))) {
|
||||||
|
conn.streams.forEach(stream => {
|
||||||
|
if (stream.stat.protocol === CONSENSUS_PROTOCOL) {
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async handleStream (peerId: PeerId, stream: P2PStream): Promise<Pushable<any>> {
|
||||||
|
const { pushable } = await import('it-pushable');
|
||||||
|
const { pipe } = await import('it-pipe');
|
||||||
|
const lp = await import('it-length-prefixed');
|
||||||
|
|
||||||
|
const messageStream = pushable({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send message to stream
|
||||||
|
pipe(
|
||||||
|
// Read from messageStream (the source)
|
||||||
|
messageStream,
|
||||||
|
// Encode with length prefix (so receiving side knows how much data is coming)
|
||||||
|
lp.encode(),
|
||||||
|
// Write to the stream (the sink)
|
||||||
|
stream.sink
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
// TODO: Implement retries / handle breakage
|
||||||
|
log(`Could not send consensus message to ${peerId.toString()}: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Handle message from stream
|
||||||
|
pipe(
|
||||||
|
// Read from the stream (the source)
|
||||||
|
stream.source,
|
||||||
|
// Decode length-prefixed data
|
||||||
|
lp.decode(),
|
||||||
|
// Sink function
|
||||||
|
async (source) => {
|
||||||
|
// For each chunk of data
|
||||||
|
for await (const msg of source) {
|
||||||
|
await this.emitPacket(Buffer.from(msg.subarray()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
log(`Error on consensus message from ${peerId.toString()}: ${err}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.messageStreamMap.set(peerId.toString(), messageStream);
|
||||||
|
return messageStream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const readParty = (filePath: string): PartyPeer[] => {
|
||||||
|
if (!filePath || filePath === '') {
|
||||||
|
log('Party peers file path not provided');
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const partyFilePath = path.resolve(filePath);
|
||||||
|
log(`Reading party peers from file ${partyFilePath}`);
|
||||||
|
|
||||||
|
const partyJson = fs.readFileSync(partyFilePath, 'utf-8');
|
||||||
|
return JSON.parse(partyJson);
|
||||||
|
};
|
@ -318,7 +318,7 @@ export class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getEntities<Entity> (queryRunner: QueryRunner, entity: new () => Entity, findConditions?: FindManyOptions<Entity>): Promise<Entity[]> {
|
async getEntities<Entity> (queryRunner: QueryRunner, entity: new () => Entity, findConditions?: FindManyOptions<Entity>): Promise<Entity[]> {
|
||||||
const repo = queryRunner.manager.getRepository(entity);
|
const repo = queryRunner.manager.getRepository<Entity>(entity);
|
||||||
|
|
||||||
const entities = await repo.find(findConditions);
|
const entities = await repo.find(findConditions);
|
||||||
return entities;
|
return entities;
|
||||||
|
@ -222,7 +222,7 @@ export class GraphDatabase {
|
|||||||
selections: ReadonlyArray<SelectionNode> = []
|
selections: ReadonlyArray<SelectionNode> = []
|
||||||
): Promise<Entity | undefined> {
|
): Promise<Entity | undefined> {
|
||||||
let { hash: blockHash, number: blockNumber } = block;
|
let { hash: blockHash, number: blockNumber } = block;
|
||||||
const repo = queryRunner.manager.getRepository(entityType);
|
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const whereOptions: any = { id };
|
const whereOptions: any = { id };
|
||||||
|
|
||||||
if (blockNumber) {
|
if (blockNumber) {
|
||||||
@ -419,7 +419,7 @@ export class GraphDatabase {
|
|||||||
where: Where = {},
|
where: Where = {},
|
||||||
queryOptions: QueryOptions = {}
|
queryOptions: QueryOptions = {}
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const repo = queryRunner.manager.getRepository(entityType);
|
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const { tableName } = repo.metadata;
|
const { tableName } = repo.metadata;
|
||||||
|
|
||||||
let subQuery = repo.createQueryBuilder('subTable')
|
let subQuery = repo.createQueryBuilder('subTable')
|
||||||
@ -483,7 +483,7 @@ export class GraphDatabase {
|
|||||||
where: Where = {},
|
where: Where = {},
|
||||||
queryOptions: QueryOptions = {}
|
queryOptions: QueryOptions = {}
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const repo = queryRunner.manager.getRepository(entityType);
|
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
|
|
||||||
let subQuery = repo.createQueryBuilder('subTable')
|
let subQuery = repo.createQueryBuilder('subTable')
|
||||||
.distinctOn(['subTable.id'])
|
.distinctOn(['subTable.id'])
|
||||||
@ -546,7 +546,7 @@ export class GraphDatabase {
|
|||||||
block: BlockHeight,
|
block: BlockHeight,
|
||||||
where: Where = {}
|
where: Where = {}
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const repo = queryRunner.manager.getRepository(entityType);
|
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const { tableName } = repo.metadata;
|
const { tableName } = repo.metadata;
|
||||||
|
|
||||||
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
||||||
@ -582,7 +582,7 @@ export class GraphDatabase {
|
|||||||
where: Where = {},
|
where: Where = {},
|
||||||
queryOptions: QueryOptions = {}
|
queryOptions: QueryOptions = {}
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const repo = queryRunner.manager.getRepository(entityType);
|
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const { tableName } = repo.metadata;
|
const { tableName } = repo.metadata;
|
||||||
|
|
||||||
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
||||||
@ -623,7 +623,7 @@ export class GraphDatabase {
|
|||||||
return entities as Entity[];
|
return entities as Entity[];
|
||||||
}
|
}
|
||||||
|
|
||||||
async getEntitiesLatest<Entity> (
|
async getEntitiesLatest<Entity extends ObjectLiteral> (
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
entityType: new () => Entity,
|
entityType: new () => Entity,
|
||||||
latestEntity: new () => any,
|
latestEntity: new () => any,
|
||||||
@ -631,8 +631,8 @@ export class GraphDatabase {
|
|||||||
queryOptions: QueryOptions = {},
|
queryOptions: QueryOptions = {},
|
||||||
selections: ReadonlyArray<SelectionNode> = []
|
selections: ReadonlyArray<SelectionNode> = []
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const entityRepo = queryRunner.manager.getRepository(entityType);
|
const entityRepo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const latestEntityRepo = queryRunner.manager.getRepository(latestEntity);
|
const latestEntityRepo = queryRunner.manager.getRepository<any>(latestEntity);
|
||||||
const latestEntityFields = latestEntityRepo.metadata.columns.map(column => column.propertyName);
|
const latestEntityFields = latestEntityRepo.metadata.columns.map(column => column.propertyName);
|
||||||
|
|
||||||
const selectionNotInLatestEntity = selections.filter(selection => selection.kind === 'Field' && selection.name.value !== '__typename')
|
const selectionNotInLatestEntity = selections.filter(selection => selection.kind === 'Field' && selection.name.value !== '__typename')
|
||||||
@ -685,8 +685,8 @@ export class GraphDatabase {
|
|||||||
where: Where = {},
|
where: Where = {},
|
||||||
queryOptions: QueryOptions = {}
|
queryOptions: QueryOptions = {}
|
||||||
): Promise<Entity[]> {
|
): Promise<Entity[]> {
|
||||||
const entityRepo = queryRunner.manager.getRepository(entityType);
|
const entityRepo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||||
const latestEntityRepo = queryRunner.manager.getRepository(latestEntity);
|
const latestEntityRepo = queryRunner.manager.getRepository<any>(latestEntity);
|
||||||
|
|
||||||
let subQuery = entityRepo.createQueryBuilder('subTable')
|
let subQuery = entityRepo.createQueryBuilder('subTable')
|
||||||
.where('latest.id = subTable.id')
|
.where('latest.id = subTable.id')
|
||||||
|
@ -844,7 +844,7 @@ export const afterEntityInsertOrUpdate = async<Entity> (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get latest entity's fields to be updated
|
// Get latest entity's fields to be updated
|
||||||
const latestEntityRepo = event.manager.getRepository(entityTarget);
|
const latestEntityRepo = event.manager.getRepository<any>(entityTarget);
|
||||||
const fieldsToUpdate = latestEntityRepo.metadata.columns.map(column => column.databaseName).filter(val => val !== 'id');
|
const fieldsToUpdate = latestEntityRepo.metadata.columns.map(column => column.databaseName).filter(val => val !== 'id');
|
||||||
|
|
||||||
// Create a latest entity instance and upsert in the db
|
// Create a latest entity instance and upsert in the db
|
||||||
|
@ -25,3 +25,4 @@ export * from './graph/state-utils';
|
|||||||
export * from './graph/types';
|
export * from './graph/types';
|
||||||
export * from './payments';
|
export * from './payments';
|
||||||
export * from './eth';
|
export * from './eth';
|
||||||
|
export * from './consensus';
|
||||||
|
@ -9,6 +9,7 @@ import JSONbig from 'json-bigint';
|
|||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||||
import * as codec from '@ipld/dag-cbor';
|
import * as codec from '@ipld/dag-cbor';
|
||||||
import { GetStorageAt, getStorageValue, StorageLayout } from '@cerc-io/solidity-mapper';
|
import { GetStorageAt, getStorageValue, StorageLayout } from '@cerc-io/solidity-mapper';
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Copyright 2021 Vulcanize, Inc.
|
// Copyright 2021 Vulcanize, Inc.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||||
import { create, IPFSHTTPClient } from 'ipfs-http-client';
|
import { create, IPFSHTTPClient } from 'ipfs-http-client';
|
||||||
|
|
||||||
export class IPFSClient {
|
export class IPFSClient {
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 Vulcanize, Inc.
|
||||||
|
//
|
||||||
|
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import { LRUCache } from 'lru-cache';
|
import { LRUCache } from 'lru-cache';
|
||||||
import { FieldNode } from 'graphql';
|
import { FieldNode } from 'graphql';
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import { sha256 } from 'multiformats/hashes/sha2';
|
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||||
import { CID } from 'multiformats/cid';
|
import type { CID as CIDType } from 'multiformats/cid';
|
||||||
|
|
||||||
|
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||||
import * as codec from '@ipld/dag-cbor';
|
import * as codec from '@ipld/dag-cbor';
|
||||||
|
|
||||||
import { BlockProgressInterface, GraphDatabaseInterface, StateInterface, StateKind } from './types';
|
import { BlockProgressInterface, GraphDatabaseInterface, StateInterface, StateKind } from './types';
|
||||||
@ -116,7 +117,7 @@ export const getResultState = (state: StateInterface): ResultState => {
|
|||||||
export const createOrUpdateStateData = async (
|
export const createOrUpdateStateData = async (
|
||||||
data: StateData,
|
data: StateData,
|
||||||
meta?: StateDataMeta
|
meta?: StateDataMeta
|
||||||
): Promise<{ cid: CID, data: StateData, bytes: codec.ByteView<StateData> }> => {
|
): Promise<{ cid: CIDType, data: StateData, bytes: codec.ByteView<StateData> }> => {
|
||||||
if (meta) {
|
if (meta) {
|
||||||
data.meta = meta;
|
data.meta = meta;
|
||||||
}
|
}
|
||||||
@ -124,9 +125,13 @@ export const createOrUpdateStateData = async (
|
|||||||
// Encoding the data using dag-cbor codec.
|
// Encoding the data using dag-cbor codec.
|
||||||
const bytes = codec.encode(data);
|
const bytes = codec.encode(data);
|
||||||
|
|
||||||
|
const { sha256 } = await import('multiformats/hashes/sha2');
|
||||||
|
|
||||||
// Calculating sha256 (multi)hash of the encoded data.
|
// Calculating sha256 (multi)hash of the encoded data.
|
||||||
const hash = await sha256.digest(bytes);
|
const hash = await sha256.digest(bytes);
|
||||||
|
|
||||||
|
const { CID } = await import('multiformats/cid');
|
||||||
|
|
||||||
// Calculating the CID: v1, code: dag-cbor, hash.
|
// Calculating the CID: v1, code: dag-cbor, hash.
|
||||||
const cid = CID.create(1, codec.code, hash);
|
const cid = CID.create(1, codec.code, hash);
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/* Basic Options */
|
/* Basic Options */
|
||||||
// "incremental": true, /* Enable incremental compilation */
|
// "incremental": true, /* Enable incremental compilation */
|
||||||
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
|
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
|
||||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
||||||
"lib": [ "ES5", "ES6", "ES2020" ], /* Specify library files to be included in the compilation. */
|
"lib": [ "ES5", "ES6", "ES2020" ], /* Specify library files to be included in the compilation. */
|
||||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||||
@ -44,7 +44,7 @@
|
|||||||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
|
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
|
||||||
|
|
||||||
/* Module Resolution Options */
|
/* Module Resolution Options */
|
||||||
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
"moduleResolution": "Node16", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||||
|
148
yarn.lock
148
yarn.lock
@ -278,79 +278,7 @@
|
|||||||
binaryen "101.0.0-nightly.20210723"
|
binaryen "101.0.0-nightly.20210723"
|
||||||
long "^4.0.0"
|
long "^4.0.0"
|
||||||
|
|
||||||
"@cerc-io/libp2p@0.42.2-laconic-0.1.3":
|
"@cerc-io/libp2p@0.42.2-laconic-0.1.4", "@cerc-io/libp2p@^0.42.2-laconic-0.1.4":
|
||||||
version "0.42.2-laconic-0.1.3"
|
|
||||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Flibp2p/-/0.42.2-laconic-0.1.3/libp2p-0.42.2-laconic-0.1.3.tgz#482c88e135141788fdd201fc27fb4f1bdc954f53"
|
|
||||||
integrity sha512-D8nBtFVB2xUN/QRCSHQVSoJBAk2nH4caqROpWUipRxiDgeoBVpTqYEM9fBzOln6/Yl3BtBxR/fgyaZPTSJQdrg==
|
|
||||||
dependencies:
|
|
||||||
"@achingbrain/nat-port-mapper" "^1.0.3"
|
|
||||||
"@libp2p/crypto" "^1.0.4"
|
|
||||||
"@libp2p/interface-address-manager" "^2.0.0"
|
|
||||||
"@libp2p/interface-connection" "^3.0.2"
|
|
||||||
"@libp2p/interface-connection-encrypter" "^3.0.1"
|
|
||||||
"@libp2p/interface-connection-manager" "^1.1.1"
|
|
||||||
"@libp2p/interface-content-routing" "^2.0.0"
|
|
||||||
"@libp2p/interface-dht" "^2.0.0"
|
|
||||||
"@libp2p/interface-keychain" "^2.0.4"
|
|
||||||
"@libp2p/interface-libp2p" "^1.0.0"
|
|
||||||
"@libp2p/interface-metrics" "^4.0.0"
|
|
||||||
"@libp2p/interface-peer-discovery" "^1.0.1"
|
|
||||||
"@libp2p/interface-peer-id" "^2.0.0"
|
|
||||||
"@libp2p/interface-peer-info" "^1.0.3"
|
|
||||||
"@libp2p/interface-peer-routing" "^1.0.1"
|
|
||||||
"@libp2p/interface-peer-store" "^1.2.2"
|
|
||||||
"@libp2p/interface-pubsub" "^3.0.0"
|
|
||||||
"@libp2p/interface-registrar" "^2.0.3"
|
|
||||||
"@libp2p/interface-stream-muxer" "^3.0.0"
|
|
||||||
"@libp2p/interface-transport" "^2.1.0"
|
|
||||||
"@libp2p/interfaces" "^3.0.3"
|
|
||||||
"@libp2p/keychain" "^1.0.0"
|
|
||||||
"@libp2p/logger" "^2.0.1"
|
|
||||||
"@libp2p/multistream-select" "^3.0.0"
|
|
||||||
"@libp2p/peer-collections" "^3.0.0"
|
|
||||||
"@libp2p/peer-id" "^2.0.0"
|
|
||||||
"@libp2p/peer-id-factory" "^2.0.0"
|
|
||||||
"@libp2p/peer-record" "^5.0.0"
|
|
||||||
"@libp2p/peer-store" "^6.0.0"
|
|
||||||
"@libp2p/tracked-map" "^3.0.0"
|
|
||||||
"@libp2p/utils" "^3.0.2"
|
|
||||||
"@libp2p/webrtc-peer" "^2.0.2"
|
|
||||||
"@multiformats/mafmt" "^11.0.2"
|
|
||||||
"@multiformats/multiaddr" "^11.0.0"
|
|
||||||
abortable-iterator "^4.0.2"
|
|
||||||
any-signal "^3.0.0"
|
|
||||||
datastore-core "^8.0.1"
|
|
||||||
err-code "^3.0.1"
|
|
||||||
interface-datastore "^7.0.0"
|
|
||||||
it-all "^2.0.0"
|
|
||||||
it-drain "^2.0.0"
|
|
||||||
it-filter "^2.0.0"
|
|
||||||
it-first "^2.0.0"
|
|
||||||
it-handshake "^4.1.2"
|
|
||||||
it-length-prefixed "^8.0.2"
|
|
||||||
it-map "^2.0.0"
|
|
||||||
it-merge "^2.0.0"
|
|
||||||
it-pair "^2.0.2"
|
|
||||||
it-pipe "^2.0.3"
|
|
||||||
it-pushable "^3.1.2"
|
|
||||||
it-sort "^2.0.1"
|
|
||||||
it-stream-types "^1.0.4"
|
|
||||||
merge-options "^3.0.4"
|
|
||||||
multiformats "^11.0.0"
|
|
||||||
p-fifo "^1.0.0"
|
|
||||||
p-settle "^5.0.0"
|
|
||||||
private-ip "^3.0.0"
|
|
||||||
protons-runtime "^4.0.1"
|
|
||||||
rate-limiter-flexible "^2.3.11"
|
|
||||||
retimer "^3.0.0"
|
|
||||||
set-delayed-interval "^1.0.0"
|
|
||||||
timeout-abort-controller "^3.0.0"
|
|
||||||
uint8arraylist "^2.3.2"
|
|
||||||
uint8arrays "^4.0.2"
|
|
||||||
wherearewe "^2.0.0"
|
|
||||||
xsalsa20 "^1.1.0"
|
|
||||||
|
|
||||||
"@cerc-io/libp2p@0.42.2-laconic-0.1.4":
|
|
||||||
version "0.42.2-laconic-0.1.4"
|
version "0.42.2-laconic-0.1.4"
|
||||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Flibp2p/-/0.42.2-laconic-0.1.4/libp2p-0.42.2-laconic-0.1.4.tgz#ac9347e70d6d3cee040ad02074cae3070b91a8fb"
|
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Flibp2p/-/0.42.2-laconic-0.1.4/libp2p-0.42.2-laconic-0.1.4.tgz#ac9347e70d6d3cee040ad02074cae3070b91a8fb"
|
||||||
integrity sha512-gTC62YvkK3P7cWlaH8gQ6lDbqusNiaYI1q7y/+vQ/1s35uStwRn7fvXHC0aY9s36L4S3p1S0sxDzGXM8rtg6+w==
|
integrity sha512-gTC62YvkK3P7cWlaH8gQ6lDbqusNiaYI1q7y/+vQ/1s35uStwRn7fvXHC0aY9s36L4S3p1S0sxDzGXM8rtg6+w==
|
||||||
@ -422,37 +350,48 @@
|
|||||||
wherearewe "^2.0.0"
|
wherearewe "^2.0.0"
|
||||||
xsalsa20 "^1.1.0"
|
xsalsa20 "^1.1.0"
|
||||||
|
|
||||||
"@cerc-io/nitro-node@^0.1.8":
|
"@cerc-io/nitro-node@^0.1.10":
|
||||||
version "0.1.8"
|
version "0.1.10"
|
||||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-node/-/0.1.8/nitro-node-0.1.8.tgz#d2e90f4464645f3dab1ded8aa14e912c3f31ddcf"
|
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-node/-/0.1.10/nitro-node-0.1.10.tgz#6b37ca555e6ff4c111d68bf1cccc97c12c1905c8"
|
||||||
integrity sha512-NAZ0miZkA+fBjlUg+7bjj8CWT4y0U7fgmkRFQ0JjyuP5o+bXvac+FtsH5ICeazGmG7Q5BQTQ6bUMiDfz2IuaDw==
|
integrity sha512-kiP4ik5eCw/jM/+3ZOlXi7POMcabgJxup0AoOw2Gqz35lMfGL6QTzdAYU1lgDfq2zDOzKx0G3hcEnfIQ6lRMtA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cerc-io/libp2p" "0.42.2-laconic-0.1.3"
|
"@cerc-io/libp2p" "0.42.2-laconic-0.1.4"
|
||||||
"@cerc-io/nitro-util" "^0.1.8"
|
"@cerc-io/nitro-protocol" "^2.0.0-alpha.4-ts-port-0.1.2"
|
||||||
"@cerc-io/peer" "^0.2.52"
|
"@cerc-io/nitro-util" "^0.1.10"
|
||||||
|
"@cerc-io/peer" "^0.2.56"
|
||||||
"@cerc-io/ts-channel" "1.0.3-ts-nitro-0.1.1"
|
"@cerc-io/ts-channel" "1.0.3-ts-nitro-0.1.1"
|
||||||
"@jpwilliams/waitgroup" "^2.1.0"
|
"@jpwilliams/waitgroup" "^2.1.0"
|
||||||
"@libp2p/crypto" "^1.0.4"
|
"@libp2p/crypto" "^1.0.4"
|
||||||
"@libp2p/tcp" "^6.0.0"
|
"@libp2p/tcp" "^6.0.0"
|
||||||
"@multiformats/multiaddr" "^11.1.4"
|
"@multiformats/multiaddr" "^11.1.4"
|
||||||
"@statechannels/exit-format" "^0.2.0"
|
"@statechannels/exit-format" "^0.2.0"
|
||||||
"@statechannels/nitro-protocol" "^2.0.0-alpha.4"
|
|
||||||
assert "^2.0.0"
|
assert "^2.0.0"
|
||||||
|
async-mutex "^0.4.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
ethers "^5.7.2"
|
ethers "^5.7.2"
|
||||||
|
heap "^0.2.7"
|
||||||
it-pipe "^2.0.5"
|
it-pipe "^2.0.5"
|
||||||
level "^8.0.0"
|
level "^8.0.0"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
promjs "^0.4.2"
|
promjs "^0.4.2"
|
||||||
uint8arrays "^4.0.3"
|
uint8arrays "^4.0.3"
|
||||||
|
|
||||||
"@cerc-io/nitro-util@^0.1.8":
|
"@cerc-io/nitro-protocol@^2.0.0-alpha.4-ts-port-0.1.2":
|
||||||
version "0.1.8"
|
version "2.0.0-alpha.4-ts-port-0.1.2"
|
||||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-util/-/0.1.8/nitro-util-0.1.8.tgz#bdbfd9568a5878aeb1480c3145262ef7beab390c"
|
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-protocol/-/2.0.0-alpha.4-ts-port-0.1.2/nitro-protocol-2.0.0-alpha.4-ts-port-0.1.2.tgz#6d2f893f5aa08dd5550447f04967b908f3f6d469"
|
||||||
integrity sha512-v3wW0rHLkpigp4PiQDixxokTeegx9sPfBzEfZJoEl+/90N8mTweXVNgQFy5IlwbhPBfKUZ8L1kWICMiPjrnI2Q==
|
integrity sha512-Cyx2+S/6BlAzvl+LZxwLjK2Y0H01f/kvTYUktdsGHx1eTWXTzS6FQ0nTVwJkKEcO8V/Y50+dc2PwvFXvk8iG9w==
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@openzeppelin/contracts" "^4.7.3"
|
||||||
|
"@statechannels/exit-format" "^0.2.0"
|
||||||
|
"@typechain/ethers-v5" "^9.0.0"
|
||||||
|
|
||||||
|
"@cerc-io/nitro-util@^0.1.10":
|
||||||
|
version "0.1.10"
|
||||||
|
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-util/-/0.1.10/nitro-util-0.1.10.tgz#a185fe98ec12c9b7c67b7e882045bf358b803fc2"
|
||||||
|
integrity sha512-X7jRB8fp6EuUSb0HxReeHxYGWgUa7YgoDwpyHkTbWezlpkj8DmMs5hu/94b+oHmKZtxWxOEnhGfCPIc3soPhsg==
|
||||||
|
dependencies:
|
||||||
|
"@cerc-io/nitro-protocol" "^2.0.0-alpha.4-ts-port-0.1.2"
|
||||||
"@cerc-io/ts-channel" "1.0.3-ts-nitro-0.1.1"
|
"@cerc-io/ts-channel" "1.0.3-ts-nitro-0.1.1"
|
||||||
"@statechannels/nitro-protocol" "^2.0.0-alpha.4"
|
|
||||||
assert "^2.0.0"
|
assert "^2.0.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
ethers "^5.7.2"
|
ethers "^5.7.2"
|
||||||
@ -3807,15 +3746,6 @@
|
|||||||
ethers "^5.1.4"
|
ethers "^5.1.4"
|
||||||
lodash "^4.17.21"
|
lodash "^4.17.21"
|
||||||
|
|
||||||
"@statechannels/nitro-protocol@^2.0.0-alpha.4":
|
|
||||||
version "2.0.0-alpha.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/@statechannels/nitro-protocol/-/nitro-protocol-2.0.0-alpha.4.tgz#ff252e5cd7e73740ad25a35b2af7953b499db63d"
|
|
||||||
integrity sha512-Nmiyu0h7VjzoYPmzUOVWb7KzzdRRTjnF1YYVqsiHiCEVkjZVBtSK/J8RDL4Ozzn2MwyOIiA90Wlrl4KB+tB43g==
|
|
||||||
dependencies:
|
|
||||||
"@openzeppelin/contracts" "^4.7.3"
|
|
||||||
"@statechannels/exit-format" "^0.2.0"
|
|
||||||
"@typechain/ethers-v5" "^9.0.0"
|
|
||||||
|
|
||||||
"@szmarczak/http-timer@^1.1.2":
|
"@szmarczak/http-timer@^1.1.2":
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
||||||
@ -3902,6 +3832,13 @@
|
|||||||
"@types/connect" "*"
|
"@types/connect" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/bunyan@^1.8.8":
|
||||||
|
version "1.8.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/bunyan/-/bunyan-1.8.8.tgz#8d6d33f090f37c07e2a80af30ae728450a101008"
|
||||||
|
integrity sha512-Cblq+Yydg3u+sGiz2mjHjC5MPmdjY+No4qvHrF+BUhblsmSfMvsHLbOG62tPbonsqBj6sbWv1LHcsoe5Jw+/Ow==
|
||||||
|
dependencies:
|
||||||
|
"@types/node" "*"
|
||||||
|
|
||||||
"@types/chai-spies@^1.0.3":
|
"@types/chai-spies@^1.0.3":
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.npmjs.org/@types/chai-spies/-/chai-spies-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/@types/chai-spies/-/chai-spies-1.0.3.tgz"
|
||||||
@ -4970,6 +4907,13 @@ async-limiter@~1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz"
|
||||||
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==
|
||||||
|
|
||||||
|
async-mutex@^0.4.0:
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.0.tgz#ae8048cd4d04ace94347507504b3cf15e631c25f"
|
||||||
|
integrity sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.4.0"
|
||||||
|
|
||||||
async-retry@^1.2.1:
|
async-retry@^1.2.1:
|
||||||
version "1.3.3"
|
version "1.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280"
|
resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280"
|
||||||
@ -5954,9 +5898,9 @@ builtins@^1.0.3:
|
|||||||
resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz"
|
resolved "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz"
|
||||||
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
|
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
|
||||||
|
|
||||||
bunyan@^1.8.12:
|
bunyan@^1.8.12, bunyan@^1.8.15:
|
||||||
version "1.8.15"
|
version "1.8.15"
|
||||||
resolved "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz"
|
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46"
|
||||||
integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==
|
integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
dtrace-provider "~0.8"
|
dtrace-provider "~0.8"
|
||||||
@ -9569,7 +9513,7 @@ heap@0.2.6:
|
|||||||
resolved "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz"
|
resolved "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz"
|
||||||
integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=
|
integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=
|
||||||
|
|
||||||
"heap@>= 0.2.0":
|
"heap@>= 0.2.0", heap@^0.2.7:
|
||||||
version "0.2.7"
|
version "0.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
|
resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
|
||||||
integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==
|
integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==
|
||||||
@ -12145,6 +12089,14 @@ module-error@^1.0.1, module-error@^1.0.2:
|
|||||||
resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86"
|
resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86"
|
||||||
integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==
|
integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==
|
||||||
|
|
||||||
|
mokka@^1.4.2:
|
||||||
|
version "1.4.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/mokka/-/mokka-1.4.2.tgz#b0d7117e216672ff2deda6ef2212bcfa0edb8114"
|
||||||
|
integrity sha512-Vgki/Fr9fqUMZzChGC1yH64AQg+qkMdZZe3xKrTwYBVGEuq8j2GdnDg8voYXwWl+MLfNzWBnNiejq2xZ8PmojA==
|
||||||
|
dependencies:
|
||||||
|
bn.js "^5.2.0"
|
||||||
|
elliptic "^6.5.4"
|
||||||
|
|
||||||
moment@^2.19.3:
|
moment@^2.19.3:
|
||||||
version "2.29.1"
|
version "2.29.1"
|
||||||
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user