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

Greg/validator/rpc #185

Merged
merged 12 commits into from
May 5, 2019
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"rules": {
"@typescript-eslint/indent": ["error", 2],
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-unused-vars": ["warn", {
"varsIgnorePattern": "^_"
Expand Down
2 changes: 2 additions & 0 deletions src/chain/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {getBlockRoot, getEpochStartSlot} from "./stateTransition/util";
*/
export class BeaconChain extends EventEmitter {
public chain: string;
public genesisTime: number64;
private db: DB;
private eth1: Eth1Notifier;
private _latestBlock: BeaconBlock;
Expand Down Expand Up @@ -57,6 +58,7 @@ export class BeaconChain extends EventEmitter {
const genesisState = getGenesisBeaconState(genesisDeposits, genesisTime, genesisEth1Data);
const genesisBlock = getEmptyBlock();
genesisBlock.stateRoot = hashTreeRoot(genesisState, BeaconState);
this.genesisTime = genesisTime;
await this.db.setBlock(genesisBlock);
await this.db.setChainHead(genesisState, genesisBlock);
await this.db.setJustifiedBlock(genesisBlock);
Expand Down
4 changes: 2 additions & 2 deletions src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {BeaconChain} from "../chain";
import {OpPool} from "../opPool";
import {JSONRPC} from "../rpc/protocol";
import {WSServer} from "../rpc/transport";
import {BeaconAPI} from "../rpc/api";
import {ValidatorApi} from "../rpc/api";

interface Service {
start(): Promise<void>;
Expand Down Expand Up @@ -65,7 +65,7 @@ class BeaconNode {
});
this.rpc = new JSONRPC(this.conf.rpc, {
transport: new WSServer(this.conf.rpc),
api: new BeaconAPI(this.conf.rpc, {
api: new ValidatorApi(this.conf.rpc, {
chain: this.chain,
db: this.db,
opPool: this.opPool,
Expand Down
52 changes: 0 additions & 52 deletions src/rpc/api/api.ts

This file was deleted.

4 changes: 1 addition & 3 deletions src/rpc/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export * from "./interface";
export * from "./mock";
export * from "./api";
export * from "./validator";
46 changes: 0 additions & 46 deletions src/rpc/api/interface.ts

This file was deleted.

55 changes: 0 additions & 55 deletions src/rpc/api/mock.ts

This file was deleted.

7 changes: 7 additions & 0 deletions src/rpc/api/validator/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {ValidatorApi} from "./validator";
import {IValidatorApi} from "./interface";

export {
ValidatorApi,
IValidatorApi
};
71 changes: 71 additions & 0 deletions src/rpc/api/validator/interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* The API interface defines the calls that can be made from a Validator
*/
import {
Attestation, AttestationData,
BeaconBlock, bytes, bytes32, bytes48, Fork, IndexedAttestation, number64, Shard, Slot, SyncingStatus, uint64,
ValidatorDuty
} from "../../../types/index";

export interface IValidatorApi {
/**
* Requests that the BeaconNode identify information about its implementation in a format similar to a HTTP User-Agent field.
* @returns {Promise<bytes32>} An ASCII-encoded hex string which uniquely defines the implementation of the BeaconNode and its current software version.
*/
getClientVersion(): Promise<bytes32>;

/**
* Requests the BeaconNode to provide which fork version it is currently on.
* @returns {Promise<{fork: Fork; chainId: uint64}>}
*/
getFork(): Promise<Fork>;

/**
* Requests the genesis_time parameter from the BeaconNode, which should be consistent across all BeaconNodes that follow the same beacon chain.
* @returns {Promise<uint64>} The genesis_time, which is a fairly static configuration option for the BeaconNode.
*/
getGenesisTime(): Promise<number64>;

/**
* Requests the BeaconNode to describe if it's currently syncing or not, and if it is, what block it is up to. This is modelled after the Eth1.0 JSON-RPC eth_syncing call.
* @returns {Promise<boolean | SyncingStatus>} Either false if the node is not syncing, or a SyncingStatus object if it is.
*/
getSyncingStatus(): Promise<boolean | SyncingStatus>;

/**
* Requests the BeaconNode to provide a set of “duties”, which are actions that should be performed by ValidatorClients. This API call should be polled at every slot, to ensure that any chain reorganisations are catered for, and to ensure that the currently connected BeaconNode is properly synchronised.
* @param {bytes48[]} validatorPubkey
* @returns {Promise<{currentVersion: bytes4; validatorDuty: ValidatorDuty}>} A list of unique validator public keys, where each item is a 0x encoded hex string.
*/
getDuties(validatorPubkey: bytes48): Promise<{currentVersion: Fork; validatorDuty: ValidatorDuty}>;

/**
* Requests a BeaconNode to produce a valid block, which can then be signed by a ValidatorClient.
* @param {Slot} slot
* @param {bytes} randaoReveal
* @returns {Promise<BeaconBlock>} A proposed BeaconBlock object, but with the signature field left blank.
*/
produceBlock(slot: Slot, randaoReveal: bytes): Promise<BeaconBlock>;

/**
* Requests that the BeaconNode produce an IndexedAttestation, with a blank signature field, which the ValidatorClient will then sign.
* @param {Slot} slot
* @param {Shard} shard
* @returns {Promise<Attestation>}
*/
produceAttestation(slot: Slot, shard: Shard): Promise<AttestationData>;

/**
* Instructs the BeaconNode to publish a newly signed beacon block to the beacon network, to be included in the beacon chain.
* @param {BeaconBlock} beaconBlock
* @returns {Promise<void>}
*/
publishBlock(beaconBlock: BeaconBlock): Promise<void>;

/**
* Instructs the BeaconNode to publish a newly signed IndexedAttestation object, to be incorporated into the beacon chain.
* @param {Attestation} attestation
* @returns {Promise<void>}
*/
publishAttestation(attestation: Attestation): Promise<void>;
}
62 changes: 62 additions & 0 deletions src/rpc/api/validator/validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
Attestation, AttestationData, BeaconBlock, bytes32, Deposit, Shard, Slot, Eth1Data, uint64,
Fork, SyncingStatus, ValidatorDuty, bytes48, bytes, IndexedAttestation, number64, BeaconState
} from "../../../types";
import {DB} from "../../../db";
import {BeaconChain} from "../../../chain";
import {OpPool} from "../../../opPool";

import {IValidatorApi} from "./interface";

export class ValidatorApi implements IValidatorApi {
private chain: BeaconChain;
private db: DB;
private opPool: OpPool;

public constructor(opts, {chain, db, opPool}) {
this.chain = chain;
this.db = db;
this.opPool = opPool;
}

public async getClientVersion(): Promise<bytes32> {
return Buffer.alloc(32);
}

public async getFork(): Promise<Fork> {
const state: BeaconState = await this.db.getState();
return state.fork;
}

public async getGenesisTime(): Promise<number64> {
return await this.chain.genesisTime;
}

public async getSyncingStatus(): Promise<boolean | SyncingStatus> {
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
return {} as boolean | SyncingStatus;
}

public async getDuties(validatorPubkey: bytes48): Promise<{currentVersion: Fork; validatorDuty: ValidatorDuty}> {
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
return {} as {currentVersion: Fork; validatorDuty: ValidatorDuty};
}

public async produceBlock(slot: Slot, randaoReveal: bytes): Promise<BeaconBlock> {
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
return {} as BeaconBlock;
}

public async produceAttestation(slot: Slot, shard: Shard): Promise<AttestationData> {
// eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
return {} as AttestationData;
}

public async publishBlock(block: BeaconBlock): Promise<void> {
await this.chain.receiveBlock(block);
}

public async publishAttestation(attestation: Attestation): Promise<void> {
await this.opPool.receiveAttestation(attestation);
}
}
8 changes: 4 additions & 4 deletions src/rpc/protocol/jsonRpc.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as jsonRpc from "noice-json-rpc";


import {API} from "../api";
import {IValidatorApi} from "../api";

export interface LikeSocketServer extends jsonRpc.LikeSocketServer {
start(): Promise<void>;
Expand All @@ -10,15 +10,13 @@ export interface LikeSocketServer extends jsonRpc.LikeSocketServer {

/**
* JSON-RPC over some transport
*
*
*/
export class JSONRPC {
private rpcServer: jsonRpc.Server;
private transport: LikeSocketServer;
private jsonRpcApi;

public constructor(opts, {transport, api}: {transport: LikeSocketServer; api: API}) {
public constructor(opts, {transport, api}: {transport: LikeSocketServer; api: IValidatorApi}) {
this.transport = transport;
// attach the json-rpc server to underlying transport
this.rpcServer = new jsonRpc.Server(this.transport);
Expand All @@ -32,9 +30,11 @@ export class JSONRPC {
}
this.jsonRpcApi.BeaconChain.expose(methods);
}

public async start(): Promise<void> {
await this.transport.start();
}

public async stop(): Promise<void> {
await this.transport.stop();
}
Expand Down
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export * from "./misc";
export * from "./operations";
export * from "./block";
export * from "./state";
export * from "./validator";
Loading