Skip to content

Commit

Permalink
track and use free recipient as string instead of ExecutionAddress
Browse files Browse the repository at this point in the history
  • Loading branch information
g11tech committed May 20, 2022
1 parent 81d6cc2 commit e6d6d3d
Show file tree
Hide file tree
Showing 12 changed files with 43 additions and 76 deletions.
22 changes: 10 additions & 12 deletions packages/api/src/routes/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
ssz,
UintNum64,
ValidatorIndex,
ExecutionAddress,
} from "@chainsafe/lodestar-types";
import {
RoutesData,
Expand All @@ -24,6 +23,7 @@ import {
WithVersion,
reqOnlyBody,
ReqSerializers,
jsonType,
} from "../utils";

// See /packages/api/src/routes/index.ts for reasoning and instructions to add new routes
Expand All @@ -46,8 +46,8 @@ export type SyncCommitteeSubscription = {
};

export type ProposerPreparationData = {
validatorIndex: ValidatorIndex;
feeRecipient: ExecutionAddress;
validatorIndex: string;
feeRecipient: string;
};

export type ProposerDuty = {
Expand Down Expand Up @@ -264,14 +264,6 @@ export function getReqSerializers(): ReqSerializers<Api, ReqTypes> {
{jsonCase: "eth2"}
);

const ProposerPreparationData = new ContainerType(
{
validatorIndex: ssz.ValidatorIndex,
feeRecipient: ssz.ExecutionAddress,
},
{jsonCase: "eth2"}
);

const produceBlock: ReqSerializers<Api, ReqTypes>["produceBlock"] = {
writeReq: (slot, randaoReveal, grafitti) => ({
params: {slot},
Expand Down Expand Up @@ -348,7 +340,13 @@ export function getReqSerializers(): ReqSerializers<Api, ReqTypes> {
publishContributionAndProofs: reqOnlyBody(ArrayOf(ssz.altair.SignedContributionAndProof), Schema.ObjectArray),
prepareBeaconCommitteeSubnet: reqOnlyBody(ArrayOf(BeaconCommitteeSubscription), Schema.ObjectArray),
prepareSyncCommitteeSubnets: reqOnlyBody(ArrayOf(SyncCommitteeSubscription), Schema.ObjectArray),
prepareBeaconProposer: reqOnlyBody(ArrayOf(ProposerPreparationData), Schema.ObjectArray),
prepareBeaconProposer: {
writeReq: (items: ProposerPreparationData[]) => ({body: items.map((item) => jsonType("snake").toJson(item))}),
parseReq: ({body}) => [
(body as Record<string, unknown>[]).map((item) => jsonType("snake").fromJson(item) as ProposerPreparationData),
],
schema: {body: Schema.ObjectArray},
},
};
}

Expand Down
7 changes: 2 additions & 5 deletions packages/cli/src/util/feeRecipient.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {ExecutionAddress} from "@chainsafe/lodestar-types";
import {fromHex} from "@chainsafe/lodestar-utils";

export function parseFeeRecipient(feeRecipientHex: string): ExecutionAddress {
export function parseFeeRecipient(feeRecipientHex: string): string {
if (!/^0x[a-fA-F0-9]{40}$/i.test(feeRecipientHex)) {
throw Error(`Invalid feeRecipient= ${feeRecipientHex}, expected format: ^0x[a-fA-F0-9]{40}$`);
}
return fromHex(feeRecipientHex.toLowerCase());
return feeRecipientHex.toLowerCase();
}
2 changes: 1 addition & 1 deletion packages/cli/test/unit/validator/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe("validator / parseFeeRecipient", () => {
const testCases: string[] = [`0x${feeRecipientString}`, `0X${feeRecipientString}`];
for (const testCase of testCases) {
it(`parse ${testCase}`, () => {
expect(feeRecipient).to.be.deep.equal(parseFeeRecipient(testCase));
expect(`0x${feeRecipientString}`).to.be.deep.equal(parseFeeRecipient(testCase));
});
}
});
Expand Down
20 changes: 5 additions & 15 deletions packages/lodestar/src/chain/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,8 @@ import {
} from "@chainsafe/lodestar-beacon-state-transition";
import {IBeaconConfig} from "@chainsafe/lodestar-config";
import {IForkChoice} from "@chainsafe/lodestar-fork-choice";
import {
allForks,
UintNum64,
Root,
phase0,
Slot,
RootHex,
ValidatorIndex,
ExecutionAddress,
Epoch,
} from "@chainsafe/lodestar-types";
import {ILogger, fromHex} from "@chainsafe/lodestar-utils";
import {allForks, UintNum64, Root, phase0, Slot, RootHex, Epoch} from "@chainsafe/lodestar-types";
import {ILogger} from "@chainsafe/lodestar-utils";
import {fromHexString} from "@chainsafe/ssz";
import {AbortController} from "@chainsafe/abort-controller";
import {GENESIS_EPOCH, ZERO_HASH} from "../constants";
Expand Down Expand Up @@ -100,7 +90,7 @@ export class BeaconChain implements IBeaconChain {
readonly pubkey2index: PubkeyIndexMap;
readonly index2pubkey: Index2PubkeyCache;

readonly beaconProposerCache: MapDef<ValidatorIndex, {epoch: Epoch; feeRecipient: ExecutionAddress}>;
readonly beaconProposerCache: MapDef<string, {epoch: Epoch; feeRecipient: string}>;

protected readonly blockProcessor: BlockProcessor;
protected readonly db: IBeaconDb;
Expand Down Expand Up @@ -156,9 +146,9 @@ export class BeaconChain implements IBeaconChain {
this.pubkey2index = new PubkeyIndexMap();
this.index2pubkey = [];

this.beaconProposerCache = new MapDef<ValidatorIndex, {epoch: Epoch; feeRecipient: ExecutionAddress}>(() => ({
this.beaconProposerCache = new MapDef<string, {epoch: Epoch; feeRecipient: string}>(() => ({
epoch: 0,
feeRecipient: fromHex(opts.defaultFeeRecipient),
feeRecipient: opts.defaultFeeRecipient,
}));

// Restore state caches
Expand Down
5 changes: 2 additions & 3 deletions packages/lodestar/src/chain/factory/block/body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
RootHex,
Slot,
ssz,
ExecutionAddress,
ValidatorIndex,
} from "@chainsafe/lodestar-types";
import {
Expand Down Expand Up @@ -90,7 +89,7 @@ export async function assembleBody(
// - Call prepareExecutionPayload again if parameters change

const finalizedBlockHash = chain.forkChoice.getFinalizedBlock().executionPayloadBlockHash;
const feeRecipient = chain.beaconProposerCache.getOrDefault(proposerIndex).feeRecipient;
const feeRecipient = chain.beaconProposerCache.getOrDefault(`${proposerIndex}`).feeRecipient;

// prepareExecutionPayload will throw error via notifyForkchoiceUpdate if
// the EL returns Syncing on this request to prepare a payload
Expand Down Expand Up @@ -134,7 +133,7 @@ async function prepareExecutionPayload(
chain: IBeaconChain,
finalizedBlockHash: RootHex,
state: CachedBeaconStateBellatrix,
suggestedFeeRecipient: ExecutionAddress
suggestedFeeRecipient: string
): Promise<PayloadId | null> {
// Use different POW block hash parent for block production based on merge status.
// Returned value of null == using an empty ExecutionPayload value
Expand Down
18 changes: 4 additions & 14 deletions packages/lodestar/src/chain/interface.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
import {
allForks,
UintNum64,
Root,
phase0,
Slot,
RootHex,
ValidatorIndex,
ExecutionAddress,
Epoch,
} from "@chainsafe/lodestar-types";
import {allForks, UintNum64, Root, phase0, Slot, RootHex, Epoch} from "@chainsafe/lodestar-types";
import {CachedBeaconStateAllForks} from "@chainsafe/lodestar-beacon-state-transition";
import {IForkChoice} from "@chainsafe/lodestar-fork-choice";
import {IBeaconConfig} from "@chainsafe/lodestar-config";
Expand Down Expand Up @@ -41,8 +31,8 @@ export type Eth2Context = {
};

export type ProposerPreparationData = {
validatorIndex: ValidatorIndex;
feeRecipient: ExecutionAddress;
validatorIndex: string;
feeRecipient: string;
};

/**
Expand Down Expand Up @@ -84,7 +74,7 @@ export interface IBeaconChain {
readonly seenSyncCommitteeMessages: SeenSyncCommitteeMessages;
readonly seenContributionAndProof: SeenContributionAndProof;

readonly beaconProposerCache: MapDef<ValidatorIndex, {epoch: Epoch; feeRecipient: ExecutionAddress}>;
readonly beaconProposerCache: MapDef<string, {epoch: Epoch; feeRecipient: string}>;

/** Stop beacon chain processing */
close(): void;
Expand Down
2 changes: 1 addition & 1 deletion packages/lodestar/src/executionEngine/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
? {
timestamp: numToQuantity(payloadAttributes.timestamp),
prevRandao: bytesToData(payloadAttributes.prevRandao),
suggestedFeeRecipient: bytesToData(payloadAttributes.suggestedFeeRecipient),
suggestedFeeRecipient: payloadAttributes.suggestedFeeRecipient,
}
: undefined;

Expand Down
4 changes: 3 additions & 1 deletion packages/lodestar/src/executionEngine/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export type ForkChoiceUpdateStatus =
export type PayloadAttributes = {
timestamp: number;
prevRandao: Uint8Array;
suggestedFeeRecipient: Uint8Array;
// DATA is anyway a hex string, so we can just track it as a hex string to
// avoid any conversions
suggestedFeeRecipient: string;
};

export type ApiPayloadAttributes = {
Expand Down
4 changes: 2 additions & 2 deletions packages/lodestar/src/executionEngine/mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import crypto from "node:crypto";
import {bellatrix, RootHex, Root} from "@chainsafe/lodestar-types";
import {toHexString} from "@chainsafe/ssz";
import {toHexString, fromHexString} from "@chainsafe/ssz";
import {BYTES_PER_LOGS_BLOOM} from "@chainsafe/lodestar-params";

import {ZERO_HASH, ZERO_HASH_HEX} from "../constants";
Expand Down Expand Up @@ -107,7 +107,7 @@ export class ExecutionEngineMock implements IExecutionEngine {
const payloadId = this.payloadId++;
const payload: bellatrix.ExecutionPayload = {
parentHash: headBlockHash,
feeRecipient: payloadAttributes.suggestedFeeRecipient,
feeRecipient: fromHexString(payloadAttributes.suggestedFeeRecipient),
stateRoot: crypto.randomBytes(32),
receiptsRoot: crypto.randomBytes(32),
logsBloom: crypto.randomBytes(BYTES_PER_LOGS_BLOOM),
Expand Down
18 changes: 3 additions & 15 deletions packages/lodestar/test/utils/mocks/chain/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,11 @@ import {AbortController} from "@chainsafe/abort-controller";
import sinon from "sinon";

import {toHexString} from "@chainsafe/ssz";
import {
allForks,
UintNum64,
Root,
Slot,
ssz,
Uint16,
UintBn64,
ValidatorIndex,
Epoch,
ExecutionAddress,
} from "@chainsafe/lodestar-types";
import {allForks, UintNum64, Root, Slot, ssz, Uint16, UintBn64, Epoch} from "@chainsafe/lodestar-types";
import {IBeaconConfig} from "@chainsafe/lodestar-config";
import {BeaconStateAllForks, CachedBeaconStateAllForks} from "@chainsafe/lodestar-beacon-state-transition";
import {phase0} from "@chainsafe/lodestar-beacon-state-transition";
import {CheckpointWithHex, IForkChoice, IProtoBlock, ExecutionStatus} from "@chainsafe/lodestar-fork-choice";
import {fromHex} from "@chainsafe/lodestar-utils";

import {ChainEventEmitter, IBeaconChain} from "../../../../src/chain";
import {IBeaconClock} from "../../../../src/chain/clock/interface";
Expand Down Expand Up @@ -96,9 +84,9 @@ export class MockBeaconChain implements IBeaconChain {
readonly seenSyncCommitteeMessages = new SeenSyncCommitteeMessages();
readonly seenContributionAndProof = new SeenContributionAndProof();

readonly beaconProposerCache = new MapDef<ValidatorIndex, {epoch: Epoch; feeRecipient: ExecutionAddress}>(() => ({
readonly beaconProposerCache = new MapDef<string, {epoch: Epoch; feeRecipient: string}>(() => ({
epoch: 0,
feeRecipient: fromHex(defaultDefaultFeeRecipient),
feeRecipient: defaultDefaultFeeRecipient,
}));

private state: BeaconStateAllForks;
Expand Down
13 changes: 8 additions & 5 deletions packages/validator/src/services/prepareBeaconProposer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {ValidatorIndex, ExecutionAddress, Epoch} from "@chainsafe/lodestar-types";
import {Epoch} from "@chainsafe/lodestar-types";
import {Api} from "@chainsafe/lodestar-api";

import {ValidatorStore} from "./validatorStore";
Expand All @@ -7,8 +7,8 @@ import {IClock, ILoggerVc} from "../util";
import {Metrics} from "../metrics";

type ProposerPreparationData = {
validatorIndex: ValidatorIndex;
feeRecipient: ExecutionAddress;
validatorIndex: string;
feeRecipient: string;
};

/**
Expand All @@ -22,7 +22,7 @@ export class PrepareBeaconProposerService {
private readonly api: Api,
private clock: IClock,
private readonly validatorStore: ValidatorStore,
private readonly defaultFeeRecipient: ExecutionAddress,
private readonly defaultFeeRecipient: string,
private readonly indicesService: IndicesService,
private readonly metrics: Metrics | null
) {
Expand All @@ -49,6 +49,9 @@ export class PrepareBeaconProposerService {
};

private getProposerData(indices: number[]): ProposerPreparationData[] {
return indices.map((validatorIndex) => ({validatorIndex, feeRecipient: this.defaultFeeRecipient}));
return indices.map((validatorIndex) => ({
validatorIndex: validatorIndex.toString(),
feeRecipient: this.defaultFeeRecipient,
}));
}
}
4 changes: 2 additions & 2 deletions packages/validator/src/validator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {AbortController, AbortSignal} from "@chainsafe/abort-controller";
import {IDatabaseApiOptions} from "@chainsafe/lodestar-db";
import {ssz, ExecutionAddress} from "@chainsafe/lodestar-types";
import {ssz} from "@chainsafe/lodestar-types";
import {createIBeaconConfig, IBeaconConfig} from "@chainsafe/lodestar-config";
import {Genesis} from "@chainsafe/lodestar-types/phase0";
import {ILogger} from "@chainsafe/lodestar-utils";
Expand Down Expand Up @@ -31,7 +31,7 @@ export type ValidatorOptions = {
logger: ILogger;
afterBlockDelaySlotFraction?: number;
graffiti?: string;
defaultFeeRecipient?: ExecutionAddress;
defaultFeeRecipient?: string;
};

// TODO: Extend the timeout, and let it be customizable
Expand Down

0 comments on commit e6d6d3d

Please sign in to comment.