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/*"
|
||||
],
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"command": {
|
||||
|
2
packages/cache/package.json
vendored
2
packages/cache/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/cache",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "Generic object cache",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/cli",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
@ -12,11 +12,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.1",
|
||||
"@cerc-io/cache": "^0.2.56",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
||||
"@cerc-io/peer": "^0.2.56",
|
||||
"@cerc-io/rpc-eth-client": "^0.2.56",
|
||||
"@cerc-io/util": "^0.2.56",
|
||||
"@cerc-io/cache": "^0.2.57",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||
"@cerc-io/libp2p": "^0.42.2-laconic-0.1.4",
|
||||
"@cerc-io/nitro-node": "^0.1.10",
|
||||
"@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",
|
||||
"@graphql-tools/utils": "^9.1.1",
|
||||
"@ipld/dag-cbor": "^8.0.0",
|
||||
|
@ -11,10 +11,10 @@ import path from 'path';
|
||||
|
||||
import {
|
||||
PeerInitConfig,
|
||||
PeerIdObj
|
||||
PeerIdObj,
|
||||
PubsubType
|
||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||
} from '@cerc-io/peer';
|
||||
import { PubsubType } from '@cerc-io/util';
|
||||
|
||||
import { readPeerId } from './utils';
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
//
|
||||
|
||||
import debug from 'debug';
|
||||
import path from 'path';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
import 'reflect-metadata';
|
||||
@ -25,17 +26,21 @@ import {
|
||||
EventWatcher,
|
||||
GraphWatcherInterface,
|
||||
Config,
|
||||
P2PConfig,
|
||||
PaymentsManager
|
||||
PaymentsManager,
|
||||
Consensus,
|
||||
readParty
|
||||
} from '@cerc-io/util';
|
||||
import { TypeSource } from '@graphql-tools/utils';
|
||||
import {
|
||||
import type {
|
||||
RelayNodeInitConfig,
|
||||
PeerInitConfig,
|
||||
PeerIdObj,
|
||||
Peer
|
||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||
} 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 { readPeerId } from './utils/index';
|
||||
@ -50,6 +55,8 @@ export class ServerCmd {
|
||||
_argv?: Arguments;
|
||||
_baseCmd: BaseCmd;
|
||||
_peer?: Peer;
|
||||
_nitro?: NitroNode;
|
||||
_consensus?: Consensus;
|
||||
|
||||
constructor () {
|
||||
this._baseCmd = new BaseCmd();
|
||||
@ -75,6 +82,14 @@ export class ServerCmd {
|
||||
return this._peer;
|
||||
}
|
||||
|
||||
get nitro (): NitroNode | undefined {
|
||||
return this._nitro;
|
||||
}
|
||||
|
||||
get consensus (): Consensus | undefined {
|
||||
return this._consensus;
|
||||
}
|
||||
|
||||
async initConfig<ConfigType> (): Promise<ConfigType> {
|
||||
this._argv = this._getArgv();
|
||||
assert(this._argv);
|
||||
@ -109,53 +124,15 @@ export class ServerCmd {
|
||||
await this._baseCmd.initEventWatcher();
|
||||
}
|
||||
|
||||
async exec (
|
||||
createResolvers: (indexer: IndexerInterface, eventWatcher: EventWatcher) => Promise<any>,
|
||||
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;
|
||||
async initP2P (): Promise<{ relayNode?: Libp2p, peer?: Peer }> {
|
||||
let relayNode: Libp2p | undefined;
|
||||
|
||||
// Start P2P nodes if config provided
|
||||
if (p2pConfig) {
|
||||
await this._startP2PNodes(p2pConfig, parseLibp2pMessage);
|
||||
const p2pConfig = this._baseCmd.config.server.p2p;
|
||||
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 {
|
||||
RELAY_DEFAULT_HOST,
|
||||
@ -190,7 +167,8 @@ export class ServerCmd {
|
||||
pubsub: relayConfig.pubsub,
|
||||
enableDebugInfo: relayConfig.enableDebugInfo
|
||||
};
|
||||
await createRelayNode(relayNodeInit);
|
||||
|
||||
relayNode = await createRelayNode(relayNodeInit);
|
||||
}
|
||||
|
||||
// Run a peer node if enabled
|
||||
@ -218,14 +196,110 @@ export class ServerCmd {
|
||||
};
|
||||
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()}`);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/codegen",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "Code generator",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
@ -20,7 +20,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@cerc-io/util": "^0.2.56",
|
||||
"@cerc-io/util": "^0.2.57",
|
||||
"@graphql-tools/load-files": "^6.5.2",
|
||||
"@poanet/solidity-flattener": "https://github.com/vulcanize/solidity-flattener.git",
|
||||
"@solidity-parser/parser": "^0.13.2",
|
||||
|
@ -41,12 +41,12 @@
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.3.19",
|
||||
"@cerc-io/cli": "^0.2.56",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
||||
"@cerc-io/util": "^0.2.56",
|
||||
"@cerc-io/cli": "^0.2.57",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||
"@cerc-io/solidity-mapper": "^0.2.57",
|
||||
"@cerc-io/util": "^0.2.57",
|
||||
{{#if (subgraphPath)}}
|
||||
"@cerc-io/graph-node": "^0.2.56",
|
||||
"@cerc-io/graph-node": "^0.2.57",
|
||||
{{/if}}
|
||||
"@ethersproject/providers": "^5.4.4",
|
||||
"apollo-type-bigint": "^0.1.3",
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@cerc-io/graph-node",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
||||
"@cerc-io/solidity-mapper": "^0.2.57",
|
||||
"@ethersproject/providers": "^5.4.4",
|
||||
"@graphprotocol/graph-ts": "^0.22.0",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
@ -51,9 +51,9 @@
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.3.19",
|
||||
"@cerc-io/assemblyscript": "0.19.10-watcher-ts-0.1.2",
|
||||
"@cerc-io/cache": "^0.2.56",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
||||
"@cerc-io/util": "^0.2.56",
|
||||
"@cerc-io/cache": "^0.2.57",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||
"@cerc-io/util": "^0.2.57",
|
||||
"@types/json-diff": "^0.5.2",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"bn.js": "^4.11.9",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/ipld-eth-client",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "IPLD ETH Client",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
@ -20,7 +20,7 @@
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.1",
|
||||
"@cerc-io/cache": "^0.2.56",
|
||||
"@cerc-io/cache": "^0.2.57",
|
||||
"cross-fetch": "^3.1.4",
|
||||
"debug": "^4.3.1",
|
||||
"ethers": "^5.4.4",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/peer",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "libp2p module",
|
||||
"main": "dist/index.js",
|
||||
"exports": "./dist/index.js",
|
||||
@ -28,9 +28,8 @@
|
||||
"test": "mocha dist/peer.test.js --bail"
|
||||
},
|
||||
"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/util": "^0.2.56",
|
||||
"@chainsafe/libp2p-gossipsub": "^6.0.0",
|
||||
"@chainsafe/libp2p-noise": "^11.0.0",
|
||||
"@libp2p/floodsub": "^6.0.0",
|
||||
|
@ -3,8 +3,6 @@ import { hideBin } from 'yargs/helpers';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { PubsubType } from '@cerc-io/util';
|
||||
|
||||
import { RelayNodeInitConfig, createRelayNode } from '../relay.js';
|
||||
import { PeerIdObj } from '../peer.js';
|
||||
import {
|
||||
@ -15,6 +13,7 @@ import {
|
||||
DEFAULT_PING_INTERVAL,
|
||||
DIAL_TIMEOUT
|
||||
} from '../constants.js';
|
||||
import { PubsubType } from '../utils/index.js';
|
||||
|
||||
interface Arguments {
|
||||
host: string;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
export { Peer, PeerIdObj, PeerInitConfig, createPeerId } from './peer.js';
|
||||
export { RelayNodeInitConfig, createRelayNode } from './relay.js';
|
||||
export { getPseudonymForPeerId } from './utils/index.js';
|
||||
export { getPseudonymForPeerId, PubsubType } from './utils/index.js';
|
||||
export {
|
||||
RELAY_DEFAULT_HOST,
|
||||
RELAY_DEFAULT_PORT,
|
||||
|
@ -12,7 +12,6 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
||||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
||||
import debug from 'debug';
|
||||
|
||||
import { PubsubType } from '@cerc-io/util';
|
||||
import { createLibp2p, Libp2p, Libp2pInit } from '@cerc-io/libp2p';
|
||||
import { webSockets } from '@libp2p/websockets';
|
||||
import { noise } from '@chainsafe/libp2p-noise';
|
||||
@ -42,7 +41,7 @@ import {
|
||||
P2P_WEBRTC_STAR_ID
|
||||
} from './constants.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';
|
||||
|
||||
const log = debug('laconic:peer');
|
||||
|
@ -6,7 +6,6 @@ import debug from 'debug';
|
||||
import assert from 'assert';
|
||||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
|
||||
|
||||
import { PubsubType } from '@cerc-io/util';
|
||||
import { Libp2p, createLibp2p } from '@cerc-io/libp2p';
|
||||
import { noise } from '@chainsafe/libp2p-noise';
|
||||
import { mplex } from '@libp2p/mplex';
|
||||
@ -27,7 +26,7 @@ import {
|
||||
DEBUG_INFO_TOPIC
|
||||
} from './constants.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 { 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 { DEBUG_INFO_TOPIC, DEFAULT_PUBSUB_TYPE, P2P_WEBRTC_STAR_ID, PUBSUB_SIGNATURE_POLICY } from '../constants.js';
|
||||
import { PeerHearbeatChecker } from '../peer-heartbeat-checker.js';
|
||||
import { PubsubType } from '@cerc-io/util';
|
||||
|
||||
const log = debug('laconic:utils');
|
||||
|
||||
@ -28,6 +27,8 @@ export const CODE_CIRCUIT = 290;
|
||||
|
||||
const ERR_INVALID_PUBSUB_TYPE = 'Invalid pubsub type';
|
||||
|
||||
export type PubsubType = 'floodsub' | 'gossipsub';
|
||||
|
||||
interface DialWithRetryOptions {
|
||||
redialInterval: number
|
||||
maxRetry: number
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/rpc-eth-client",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "RPC ETH Client",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
@ -19,9 +19,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/cerc-io/watcher-ts#readme",
|
||||
"dependencies": {
|
||||
"@cerc-io/cache": "^0.2.56",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
||||
"@cerc-io/util": "^0.2.56",
|
||||
"@cerc-io/cache": "^0.2.57",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||
"@cerc-io/util": "^0.2.57",
|
||||
"chai": "^4.3.4",
|
||||
"ethers": "^5.4.4",
|
||||
"left-pad": "^1.3.0",
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@cerc-io/solidity-mapper",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"@cerc-io/ipld-eth-client": "^0.2.56",
|
||||
"@cerc-io/ipld-eth-client": "^0.2.57",
|
||||
"@ethersproject/abi": "^5.3.0",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/test",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"private": true,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@cerc-io/tracing-client",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"description": "ETH VM tracing client",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
@ -1,20 +1,25 @@
|
||||
{
|
||||
"name": "@cerc-io/util",
|
||||
"version": "0.2.56",
|
||||
"version": "0.2.57",
|
||||
"main": "dist/index.js",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@apollo/utils.keyvaluecache": "^1.0.1",
|
||||
"@cerc-io/nitro-node": "^0.1.8",
|
||||
"@cerc-io/solidity-mapper": "^0.2.56",
|
||||
"@cerc-io/nitro-node": "^0.1.10",
|
||||
"@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",
|
||||
"@ethersproject/providers": "^5.4.4",
|
||||
"@graphql-tools/schema": "^9.0.10",
|
||||
"@graphql-tools/utils": "^9.1.1",
|
||||
"@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-express": "^3.11.1",
|
||||
"apollo-server-plugin-response-cache": "^3.8.1",
|
||||
"bunyan": "^1.8.15",
|
||||
"debug": "^4.3.1",
|
||||
"decimal.js": "^10.3.1",
|
||||
"ethers": "^5.4.4",
|
||||
@ -25,10 +30,14 @@
|
||||
"graphql-subscriptions": "^2.0.0",
|
||||
"graphql-ws": "^5.11.2",
|
||||
"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",
|
||||
"json-bigint": "^1.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lru-cache": "^10.0.0",
|
||||
"mokka": "^1.4.2",
|
||||
"multiformats": "^9.4.8",
|
||||
"pg": "^8.5.1",
|
||||
"pg-boss": "^6.1.0",
|
||||
@ -40,8 +49,9 @@
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cerc-io/cache": "^0.2.56",
|
||||
"@cerc-io/cache": "^0.2.57",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"@types/bunyan": "^1.8.8",
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/fs-extra": "^9.0.11",
|
||||
"@types/js-yaml": "^4.0.4",
|
||||
|
@ -9,11 +9,11 @@ import debug from 'debug';
|
||||
import { ConnectionOptions } from 'typeorm';
|
||||
|
||||
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');
|
||||
|
||||
export type PubsubType = 'floodsub' | 'gossipsub';
|
||||
|
||||
export interface JobQueueConfig {
|
||||
dbConnectionString: string;
|
||||
maxCompletionLagInSecs: number;
|
||||
@ -162,6 +162,14 @@ export interface NitroConfig {
|
||||
payments: PaymentsConfig;
|
||||
}
|
||||
|
||||
// Consensus config
|
||||
export interface ConsensusConfig {
|
||||
enabled: boolean;
|
||||
publicKey: string;
|
||||
privateKey: string;
|
||||
watcherPartyFile: string;
|
||||
}
|
||||
|
||||
// P2P config
|
||||
export interface P2PConfig {
|
||||
// Enable relay node
|
||||
@ -172,7 +180,9 @@ export interface P2PConfig {
|
||||
enablePeer: boolean;
|
||||
peer: PeerConfig;
|
||||
|
||||
nitro: NitroConfig
|
||||
nitro: NitroConfig;
|
||||
|
||||
consensus: ConsensusConfig;
|
||||
}
|
||||
|
||||
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[]> {
|
||||
const repo = queryRunner.manager.getRepository(entity);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entity);
|
||||
|
||||
const entities = await repo.find(findConditions);
|
||||
return entities;
|
||||
|
@ -222,7 +222,7 @@ export class GraphDatabase {
|
||||
selections: ReadonlyArray<SelectionNode> = []
|
||||
): Promise<Entity | undefined> {
|
||||
let { hash: blockHash, number: blockNumber } = block;
|
||||
const repo = queryRunner.manager.getRepository(entityType);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const whereOptions: any = { id };
|
||||
|
||||
if (blockNumber) {
|
||||
@ -419,7 +419,7 @@ export class GraphDatabase {
|
||||
where: Where = {},
|
||||
queryOptions: QueryOptions = {}
|
||||
): Promise<Entity[]> {
|
||||
const repo = queryRunner.manager.getRepository(entityType);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const { tableName } = repo.metadata;
|
||||
|
||||
let subQuery = repo.createQueryBuilder('subTable')
|
||||
@ -483,7 +483,7 @@ export class GraphDatabase {
|
||||
where: Where = {},
|
||||
queryOptions: QueryOptions = {}
|
||||
): Promise<Entity[]> {
|
||||
const repo = queryRunner.manager.getRepository(entityType);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
|
||||
let subQuery = repo.createQueryBuilder('subTable')
|
||||
.distinctOn(['subTable.id'])
|
||||
@ -546,7 +546,7 @@ export class GraphDatabase {
|
||||
block: BlockHeight,
|
||||
where: Where = {}
|
||||
): Promise<Entity[]> {
|
||||
const repo = queryRunner.manager.getRepository(entityType);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const { tableName } = repo.metadata;
|
||||
|
||||
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
||||
@ -582,7 +582,7 @@ export class GraphDatabase {
|
||||
where: Where = {},
|
||||
queryOptions: QueryOptions = {}
|
||||
): Promise<Entity[]> {
|
||||
const repo = queryRunner.manager.getRepository(entityType);
|
||||
const repo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const { tableName } = repo.metadata;
|
||||
|
||||
let selectQueryBuilder = repo.createQueryBuilder(tableName)
|
||||
@ -623,7 +623,7 @@ export class GraphDatabase {
|
||||
return entities as Entity[];
|
||||
}
|
||||
|
||||
async getEntitiesLatest<Entity> (
|
||||
async getEntitiesLatest<Entity extends ObjectLiteral> (
|
||||
queryRunner: QueryRunner,
|
||||
entityType: new () => Entity,
|
||||
latestEntity: new () => any,
|
||||
@ -631,8 +631,8 @@ export class GraphDatabase {
|
||||
queryOptions: QueryOptions = {},
|
||||
selections: ReadonlyArray<SelectionNode> = []
|
||||
): Promise<Entity[]> {
|
||||
const entityRepo = queryRunner.manager.getRepository(entityType);
|
||||
const latestEntityRepo = queryRunner.manager.getRepository(latestEntity);
|
||||
const entityRepo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const latestEntityRepo = queryRunner.manager.getRepository<any>(latestEntity);
|
||||
const latestEntityFields = latestEntityRepo.metadata.columns.map(column => column.propertyName);
|
||||
|
||||
const selectionNotInLatestEntity = selections.filter(selection => selection.kind === 'Field' && selection.name.value !== '__typename')
|
||||
@ -685,8 +685,8 @@ export class GraphDatabase {
|
||||
where: Where = {},
|
||||
queryOptions: QueryOptions = {}
|
||||
): Promise<Entity[]> {
|
||||
const entityRepo = queryRunner.manager.getRepository(entityType);
|
||||
const latestEntityRepo = queryRunner.manager.getRepository(latestEntity);
|
||||
const entityRepo = queryRunner.manager.getRepository<Entity>(entityType);
|
||||
const latestEntityRepo = queryRunner.manager.getRepository<any>(latestEntity);
|
||||
|
||||
let subQuery = entityRepo.createQueryBuilder('subTable')
|
||||
.where('latest.id = subTable.id')
|
||||
|
@ -844,7 +844,7 @@ export const afterEntityInsertOrUpdate = async<Entity> (
|
||||
}
|
||||
|
||||
// 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');
|
||||
|
||||
// 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 './payments';
|
||||
export * from './eth';
|
||||
export * from './consensus';
|
||||
|
@ -9,6 +9,7 @@ import JSONbig from 'json-bigint';
|
||||
import { ethers } from 'ethers';
|
||||
import _ from 'lodash';
|
||||
|
||||
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||
import * as codec from '@ipld/dag-cbor';
|
||||
import { GetStorageAt, getStorageValue, StorageLayout } from '@cerc-io/solidity-mapper';
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
// @ts-expect-error TODO: Resolve (Not able to find the type declarations)
|
||||
import { create, IPFSHTTPClient } from 'ipfs-http-client';
|
||||
|
||||
export class IPFSClient {
|
||||
|
@ -1,3 +1,7 @@
|
||||
//
|
||||
// Copyright 2023 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import debug from 'debug';
|
||||
import { LRUCache } from 'lru-cache';
|
||||
import { FieldNode } from 'graphql';
|
||||
|
@ -1,8 +1,9 @@
|
||||
import _ from 'lodash';
|
||||
import debug from 'debug';
|
||||
import { sha256 } from 'multiformats/hashes/sha2';
|
||||
import { CID } from 'multiformats/cid';
|
||||
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1319854183
|
||||
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 { BlockProgressInterface, GraphDatabaseInterface, StateInterface, StateKind } from './types';
|
||||
@ -116,7 +117,7 @@ export const getResultState = (state: StateInterface): ResultState => {
|
||||
export const createOrUpdateStateData = async (
|
||||
data: StateData,
|
||||
meta?: StateDataMeta
|
||||
): Promise<{ cid: CID, data: StateData, bytes: codec.ByteView<StateData> }> => {
|
||||
): Promise<{ cid: CIDType, data: StateData, bytes: codec.ByteView<StateData> }> => {
|
||||
if (meta) {
|
||||
data.meta = meta;
|
||||
}
|
||||
@ -124,9 +125,13 @@ export const createOrUpdateStateData = async (
|
||||
// Encoding the data using dag-cbor codec.
|
||||
const bytes = codec.encode(data);
|
||||
|
||||
const { sha256 } = await import('multiformats/hashes/sha2');
|
||||
|
||||
// Calculating sha256 (multi)hash of the encoded data.
|
||||
const hash = await sha256.digest(bytes);
|
||||
|
||||
const { CID } = await import('multiformats/cid');
|
||||
|
||||
// Calculating the CID: v1, code: dag-cbor, hash.
|
||||
const cid = CID.create(1, codec.code, hash);
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/* Basic Options */
|
||||
// "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'. */
|
||||
"lib": [ "ES5", "ES6", "ES2020" ], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
@ -44,7 +44,7 @@
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
|
||||
|
||||
/* 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. */
|
||||
// "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. */
|
||||
|
148
yarn.lock
148
yarn.lock
@ -278,79 +278,7 @@
|
||||
binaryen "101.0.0-nightly.20210723"
|
||||
long "^4.0.0"
|
||||
|
||||
"@cerc-io/libp2p@0.42.2-laconic-0.1.3":
|
||||
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":
|
||||
"@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.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"
|
||||
integrity sha512-gTC62YvkK3P7cWlaH8gQ6lDbqusNiaYI1q7y/+vQ/1s35uStwRn7fvXHC0aY9s36L4S3p1S0sxDzGXM8rtg6+w==
|
||||
@ -422,37 +350,48 @@
|
||||
wherearewe "^2.0.0"
|
||||
xsalsa20 "^1.1.0"
|
||||
|
||||
"@cerc-io/nitro-node@^0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-node/-/0.1.8/nitro-node-0.1.8.tgz#d2e90f4464645f3dab1ded8aa14e912c3f31ddcf"
|
||||
integrity sha512-NAZ0miZkA+fBjlUg+7bjj8CWT4y0U7fgmkRFQ0JjyuP5o+bXvac+FtsH5ICeazGmG7Q5BQTQ6bUMiDfz2IuaDw==
|
||||
"@cerc-io/nitro-node@^0.1.10":
|
||||
version "0.1.10"
|
||||
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-kiP4ik5eCw/jM/+3ZOlXi7POMcabgJxup0AoOw2Gqz35lMfGL6QTzdAYU1lgDfq2zDOzKx0G3hcEnfIQ6lRMtA==
|
||||
dependencies:
|
||||
"@cerc-io/libp2p" "0.42.2-laconic-0.1.3"
|
||||
"@cerc-io/nitro-util" "^0.1.8"
|
||||
"@cerc-io/peer" "^0.2.52"
|
||||
"@cerc-io/libp2p" "0.42.2-laconic-0.1.4"
|
||||
"@cerc-io/nitro-protocol" "^2.0.0-alpha.4-ts-port-0.1.2"
|
||||
"@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"
|
||||
"@jpwilliams/waitgroup" "^2.1.0"
|
||||
"@libp2p/crypto" "^1.0.4"
|
||||
"@libp2p/tcp" "^6.0.0"
|
||||
"@multiformats/multiaddr" "^11.1.4"
|
||||
"@statechannels/exit-format" "^0.2.0"
|
||||
"@statechannels/nitro-protocol" "^2.0.0-alpha.4"
|
||||
assert "^2.0.0"
|
||||
async-mutex "^0.4.0"
|
||||
debug "^4.3.4"
|
||||
ethers "^5.7.2"
|
||||
heap "^0.2.7"
|
||||
it-pipe "^2.0.5"
|
||||
level "^8.0.0"
|
||||
lodash "^4.17.21"
|
||||
promjs "^0.4.2"
|
||||
uint8arrays "^4.0.3"
|
||||
|
||||
"@cerc-io/nitro-util@^0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://git.vdb.to/api/packages/cerc-io/npm/%40cerc-io%2Fnitro-util/-/0.1.8/nitro-util-0.1.8.tgz#bdbfd9568a5878aeb1480c3145262ef7beab390c"
|
||||
integrity sha512-v3wW0rHLkpigp4PiQDixxokTeegx9sPfBzEfZJoEl+/90N8mTweXVNgQFy5IlwbhPBfKUZ8L1kWICMiPjrnI2Q==
|
||||
"@cerc-io/nitro-protocol@^2.0.0-alpha.4-ts-port-0.1.2":
|
||||
version "2.0.0-alpha.4-ts-port-0.1.2"
|
||||
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-Cyx2+S/6BlAzvl+LZxwLjK2Y0H01f/kvTYUktdsGHx1eTWXTzS6FQ0nTVwJkKEcO8V/Y50+dc2PwvFXvk8iG9w==
|
||||
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"
|
||||
"@statechannels/nitro-protocol" "^2.0.0-alpha.4"
|
||||
assert "^2.0.0"
|
||||
debug "^4.3.4"
|
||||
ethers "^5.7.2"
|
||||
@ -3807,15 +3746,6 @@
|
||||
ethers "^5.1.4"
|
||||
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":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
|
||||
@ -3902,6 +3832,13 @@
|
||||
"@types/connect" "*"
|
||||
"@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":
|
||||
version "1.0.3"
|
||||
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"
|
||||
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:
|
||||
version "1.3.3"
|
||||
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"
|
||||
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
|
||||
|
||||
bunyan@^1.8.12:
|
||||
bunyan@^1.8.12, bunyan@^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==
|
||||
optionalDependencies:
|
||||
dtrace-provider "~0.8"
|
||||
@ -9569,7 +9513,7 @@ heap@0.2.6:
|
||||
resolved "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz"
|
||||
integrity sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw=
|
||||
|
||||
"heap@>= 0.2.0":
|
||||
"heap@>= 0.2.0", heap@^0.2.7:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc"
|
||||
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"
|
||||
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:
|
||||
version "2.29.1"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
||||
|
Loading…
Reference in New Issue
Block a user