Skip to content

Commit

Permalink
Port latest changes from go-nitro till commit 7bea5bf on September …
Browse files Browse the repository at this point in the history
…14 (#126)

* Implement checkForMissedEvents method

* Implement Ticker class and add unit test

* Refactor lastBlockNumSeen methods of memstore

* Add isNewChainEvent check in updateWithChainEvent

* Handle lastBlockNum in engine

* Set initial value of lastChainUpdate property

* Add chainStartBlock param to setupNode

* Handle lastBlockNumSeen in durable store

* Use @statechannels/nitro-protocol verion 2.0.0-alpha.5

* Use @cerc-io/peer version 0.2.60

* Refactor newEthChainServiceWithProvider

* Implement method to print nested error logs

* Refactor WrappedError to print nested errors

* Handle review comments

* Use constant LEVEL_NOT_FOUND

---------

Co-authored-by: neeraj <[email protected]>
  • Loading branch information
nikugogoi and neerajvijay1997 authored Oct 3, 2023
1 parent 9ea5521 commit d675a0d
Show file tree
Hide file tree
Showing 40 changed files with 573 additions and 243 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"test:node": "lerna run test --stream --parallel --ignore @cerc-io/example-web-app",
"prepare": "husky install",
"chain": "lerna run chain --scope=@cerc-io/server",
"test:deploy-contracts": "lerna run test:deploy-contracts --scope=@cerc-io/nitro-util",
"test:copy-addresses": "lerna run test:copy-addresses --scope=@cerc-io/nitro-util",
"test:deploy-contracts": "lerna run test:deploy-contracts --scope=@cerc-io/nitro-node",
"test:copy-addresses": "lerna run test:copy-addresses --scope=@cerc-io/nitro-node",
"build:contracts": "lerna run build:contracts --scope=@cerc-io/nitro-util",
"test:deploy-token": "lerna run test:deploy-token --scope=@cerc-io/nitro-util",
"version:set": "lerna version --no-git-tag-version"
Expand Down
11 changes: 7 additions & 4 deletions packages/nitro-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"build:update-package-name": "yarn ts-node scripts/update-package-name.ts",
"dev": "webpack --watch --config webpack.dev.ts",
"lint": "eslint .",
"test": "mocha"
"test": "mocha",
"test:deploy-contracts": "DEBUG=ts-nitro:* yarn ts-node scripts/deploy-contracts.ts",
"test:copy-addresses": "cp ./nitro-addresses.json ../server/src/ && cp ./nitro-addresses.json ../example-web-app/src/"
},
"devDependencies": {
"@libp2p/interface-peer-store": "1.2.9",
Expand Down Expand Up @@ -47,13 +49,14 @@
"typescript": "^5.0.4",
"webpack": "^5.83.1",
"webpack-cli": "^5.1.1",
"webpack-merge": "^5.8.0"
"webpack-merge": "^5.8.0",
"yargs": "^17.7.2"
},
"dependencies": {
"@cerc-io/libp2p": "0.42.2-laconic-0.1.4",
"@cerc-io/nitro-protocol": "^2.0.0-alpha.4-ts-port-0.1.3",
"@statechannels/nitro-protocol": "^2.0.0-alpha.5",
"@cerc-io/nitro-util": "^0.1.11",
"@cerc-io/peer": "^0.2.58",
"@cerc-io/peer": "^0.2.60",
"@cerc-io/ts-channel": "1.0.3-ts-nitro-0.1.1",
"@jpwilliams/waitgroup": "^2.1.0",
"@libp2p/crypto": "^1.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import yargs from 'yargs';
import fs from 'fs';
import path from 'path';
import debug from 'debug';
import { ethers, providers } from 'ethers';

import { DEFAULT_CHAIN_URL } from '../src/constants';
import { deployContracts } from '../src/deploy-contracts';
import { DEFAULT_CHAIN_URL } from '@cerc-io/nitro-util/src/constants';

const log = debug('ts-nitro:util');
import { deployContracts } from '../src/internal/chain/chain';

const log = debug('ts-nitro:node');

const getArgv = () => yargs.parserConfiguration({
'parse-numbers': false,
Expand All @@ -34,14 +34,11 @@ const getArgv = () => yargs.parserConfiguration({
async function main() {
const argv = getArgv();

const provider = new providers.JsonRpcProvider(argv.chainurl);
const signer = argv.key ? new ethers.Wallet(argv.key, provider) : provider.getSigner();

const [
nitroAdjudicatorAddress,
virtualPaymentAppAddress,
consensusAppAddress,
] = await deployContracts(signer);
] = await deployContracts(argv.chainurl, argv.key);

const output = {
nitroAdjudicatorAddress,
Expand All @@ -55,7 +52,7 @@ async function main() {
}

main()
.then(() => {})
.then(() => { })
.catch((err) => {
log(err);
});
Expand Down
1 change: 1 addition & 0 deletions packages/nitro-node/src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export { Voucher } from './payments/vouchers';
export {
Signature, recoverEthereumMessageSigner, getSignatureFromEthersSignature, signEthereumMessage,
} from './crypto/signatures';
export { deployContracts } from './internal/chain/chain';

export * as utils from './utils';

Expand Down
25 changes: 24 additions & 1 deletion packages/nitro-node/src/channel/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ethers } from 'ethers';
import {
fromJSON, toJSON, FieldDescription, Uint, Uint64, NitroSigner,
} from '@cerc-io/nitro-util';
import { Bytes32 } from '@cerc-io/nitro-protocol';
import { Bytes32 } from '@statechannels/nitro-protocol';

import { Signature } from '../crypto/signatures';
import { Destination } from '../types/destination';
Expand Down Expand Up @@ -39,6 +39,11 @@ interface OffChainDataConstructorOptions {
latestSupportedStateTurnNum?: Uint64;
}

interface ChainUpdateData {
blockNum: Uint64;
txIndex: Uint;
}

class OnChainData {
holdings: Funds = new Funds();

Expand Down Expand Up @@ -103,6 +108,8 @@ export class Channel extends FixedPart {

offChain: OffChainData = new OffChainData({});

lastChainUpdate: ChainUpdateData = { blockNum: BigInt(0), txIndex: BigInt(0) };

static jsonEncodingMap: Record<string, FieldDescription> = {
id: { type: 'class', value: Destination },
myIndex: { type: 'uint' },
Expand Down Expand Up @@ -132,6 +139,14 @@ export class Channel extends FixedPart {
Object.assign(this, params);
}

// isNewChainEvent returns true if the event has a greater block number (or equal blocknumber but with greater tx index)
// than prior chain events process by the receiver.
isNewChainEvent(event: ChainEvent): boolean {
assert(this.lastChainUpdate);
return event.blockNum() > this.lastChainUpdate.blockNum
|| (event.blockNum() === this.lastChainUpdate.blockNum && event.txIndex() > this.lastChainUpdate.txIndex);
}

// new constructs a new Channel from the supplied state.
static new(s: State, myIndex: Uint): Channel {
const c = new Channel({});
Expand Down Expand Up @@ -394,6 +409,11 @@ export class Channel extends FixedPart {

// UpdateWithChainEvent mutates the receiver with the supplied chain event, replacing the relevant data fields.
updateWithChainEvent(event: ChainEvent): Channel {
if (!this.isNewChainEvent(event)) {
throw new Error("chain event older than channel's last update");
}
// Process event

switch (event.constructor) {
case AllocationUpdatedEvent: {
const e = event as AllocationUpdatedEvent;
Expand Down Expand Up @@ -424,6 +444,9 @@ export class Channel extends FixedPart {
}
}

// Update Channel.LastChainUpdate
this.lastChainUpdate.blockNum = event.blockNum();
this.lastChainUpdate.txIndex = event.txIndex();
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ethers } from 'ethers';
import {
FieldDescription, NitroSigner, Uint, Uint64, fromJSON, toJSON, JSONbigNative,
} from '@cerc-io/nitro-util';
import { Bytes32 } from '@cerc-io/nitro-protocol';
import { Bytes32 } from '@statechannels/nitro-protocol';

import { Signature } from '../../crypto/signatures';
import { getAddressFromSecretKeyBytes } from '../../crypto/keys';
Expand Down
2 changes: 1 addition & 1 deletion packages/nitro-node/src/channel/state/outcome/guarantee.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Buffer } from 'buffer';

import { decodeGuaranteeData, encodeGuaranteeData } from '@cerc-io/nitro-protocol/dist/src/contract/outcome';
import { decodeGuaranteeData, encodeGuaranteeData } from '@statechannels/nitro-protocol/dist/src/contract/outcome';

import { Destination } from '../../../types/destination';

Expand Down
2 changes: 1 addition & 1 deletion packages/nitro-node/src/channel/state/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
State as NitroState,
hashState as utilHashState,
Bytes32,
} from '@cerc-io/nitro-protocol';
} from '@statechannels/nitro-protocol';
import {
FieldDescription, NitroSigner, Uint64, bytes2Hex, fromJSON, hex2Bytes, toJSON,
} from '@cerc-io/nitro-util';
Expand Down
65 changes: 38 additions & 27 deletions packages/nitro-node/src/internal/chain/chain.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
import debug from 'debug';
import assert from 'assert';
import { providers } from 'ethers';
import {
BytesLike, ContractFactory, ContractInterface, Signer, ethers, providers,
} from 'ethers';

import nitroAdjudicatorArtifact from '@statechannels/nitro-protocol/dist/artifacts/contracts/NitroAdjudicator.sol/NitroAdjudicator.json';
import consensusAppArtifact from '@statechannels/nitro-protocol/dist/artifacts/contracts/ConsensusApp.sol/ConsensusApp.json';
import virtualPaymentAppArtifact from '@statechannels/nitro-protocol/dist/artifacts/contracts/VirtualPaymentApp.sol/VirtualPaymentApp.json';
import { Uint64 } from '@cerc-io/nitro-util';

import { Address } from '../../types/types';
import { EthChainService } from '../../node/engine/chainservice/eth-chainservice';

const log = debug('ts-nitro:chain');

export interface ChainOpts {
chainUrl?: string
chainStartBlock: Uint64
chainPk?: string
provider?: providers.JsonRpcProvider,
naAddress: Address
vpaAddress: Address
caAddress: Address
provider?: providers.JsonRpcProvider,
chainUrl?: string
chainPk?: string
}

const log = debug('ts-nitro:chain');
// deployContract deploys a contract and waits for the transaction to be mined.
async function deployContract(name: string, signer: Signer, contractInterface: ContractInterface, bytecode: BytesLike): Promise<string> {
const contractFactory = new ContractFactory(contractInterface, bytecode).connect(signer);

const contract = await contractFactory.deploy();
log(`Waiting for ${name} deployment confirmation`);

await contract.deployTransaction.wait();
log(`${name} successfully deployed to ${contract.address}`);

return contract.address;
}

// DeployContracts deploys the NitroAdjudicator, VirtualPaymentApp and ConsensusApp contracts.
export async function deployContracts(chainURL: string, chainPK?: string): Promise<[string, string, string]> {
const provider = new providers.JsonRpcProvider(chainURL);
const signer = chainPK ? new ethers.Wallet(chainPK, provider) : provider.getSigner();

const na = await deployContract('NitroAdjudicator', signer, nitroAdjudicatorArtifact.abi, nitroAdjudicatorArtifact.bytecode);

const vpa = await deployContract('VirtualPaymentApp', signer, virtualPaymentAppArtifact.abi, virtualPaymentAppArtifact.bytecode);

const ca = await deployContract('ConsensusApp', signer, consensusAppArtifact.abi, consensusAppArtifact.bytecode);

export async function initializeEthChainService(chainOpts: ChainOpts): Promise<EthChainService> {
if (chainOpts.provider) {
log(`Initializing chain service and connecting to ${chainOpts.provider.connection.url}...`);

return EthChainService.newEthChainServiceWithProvider(
chainOpts.provider,
chainOpts.naAddress,
chainOpts.caAddress,
chainOpts.vpaAddress,
);
}

assert(chainOpts.chainUrl && chainOpts.chainPk);
log(`Initializing chain service and connecting to ${chainOpts.chainUrl}...`);
return EthChainService.newEthChainService(
chainOpts.chainUrl,
chainOpts.chainPk,
chainOpts.naAddress,
chainOpts.caAddress,
chainOpts.vpaAddress,
);
return [na, vpa, ca];
}
19 changes: 16 additions & 3 deletions packages/nitro-node/src/internal/node/node.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import debug from 'debug';
import assert from 'assert';

// @ts-expect-error
import type { Peer } from '@cerc-io/peer';
import { NitroSigner } from '@cerc-io/nitro-util';

import { EthChainService } from '../../node/engine/chainservice/eth-chainservice';
import { ChainService } from '../../node/engine/chainservice/chainservice';
import { P2PMessageService } from '../../node/engine/messageservice/p2p-message-service/service';
import { newStore } from '../../node/engine/store/utils';
import { setupNode } from '../../utils/helpers';
import { MetricsApi } from '../../node/engine/metrics';
import { Store } from '../../node/engine/store/store';
import { Node } from '../../node/node';
import { initializeEthChainService, ChainOpts } from '../chain/chain';
import { ChainOpts } from '../chain/chain';

const log = debug('ts-nitro:node');

Expand All @@ -21,13 +23,24 @@ export async function initializeNode(
chainOpts: ChainOpts,
durableStoreFolder?: string,
metricsApi?: MetricsApi,
): Promise<[Node, Store, P2PMessageService, EthChainService]> {
): Promise<[Node, Store, P2PMessageService, ChainService]> {
const ourStore = await newStore(signer, durableStoreFolder);

log('Initializing message service...');
const msgService = await P2PMessageService.newMessageService(ourStore.getAddress(), peer);

const ourChain = await initializeEthChainService(chainOpts);
// Compare chainOpts.ChainStartBlock to lastBlockNum seen in store. The larger of the two
// gets passed as an argument when creating NewEthChainService
const storeBlockNum = await ourStore.getLastBlockNumSeen();

if (storeBlockNum > chainOpts.chainStartBlock) {
// eslint-disable-next-line no-param-reassign
chainOpts.chainStartBlock = storeBlockNum;
}

log('Initializing chain service...');

const ourChain = await EthChainService.newEthChainService(chainOpts);

const node = await setupNode(
msgService,
Expand Down
1 change: 1 addition & 0 deletions packages/nitro-node/src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ export {
LedgerChannelInfo, PaymentChannelInfo, LedgerChannelBalance, ChannelStatus, PaymentChannelBalance,
} from './node/query/types';
export { ObjectiveResponse } from './protocols/directfund/directfund';
export { deployContracts } from './internal/chain/chain';

export * as utils from './utils';
Loading

0 comments on commit d675a0d

Please sign in to comment.