Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port latest changes from go-nitro till commit 7bea5bf on September 14 #126

Merged
merged 15 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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