Skip to content

Commit

Permalink
feat: live validator stats from L1 Rollup-contract (#251)
Browse files Browse the repository at this point in the history
  • Loading branch information
FilipHarald authored Jan 11, 2025
1 parent e08ebfe commit 52ff9c3
Show file tree
Hide file tree
Showing 46 changed files with 1,388 additions and 207 deletions.
4 changes: 2 additions & 2 deletions k8s/local/aztec-listener/remote_aztec_deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ spec:
- name: AZTEC_DISABLED
value: "false"
- name: AZTEC_GENESIS_CATCHUP
value: "true"
value: "false"
- name: AZTEC_LISTEN_FOR_BLOCKS
value: "true"
- name: AZTEC_LISTEN_FOR_PENDING_TXS
value: "true"
value: "false"
- name: AZTEC_RPC_URL
valueFrom:
secretKeyRef:
Expand Down
47 changes: 47 additions & 0 deletions k8s/local/ethereum-listener/remote_ethereum_deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ethereum-listener
name: ethereum-listener
namespace: chicmoz
spec:
replicas: 1
selector:
matchLabels:
app: ethereum-listener
strategy: {}
template:
metadata:
labels:
app: ethereum-listener
spec:
containers:
- image: ethereum-listener:latest
resources:
limits:
memory: 750Mi
cpu: 250m
name: ethereum-listener
env:
- name: NODE_ENV
value: "development"
- name: BLOCK_POLL_INTERVAL_MS
value: "5000"
- name: LISTENER_DISABLED
value: "false"
- name: GENESIS_CATCHUP
value: "true"
- name: LISTEN_FOR_BLOCKS
value: "true"
- name: ETHEREUM_HTTP_RPC_URL
valueFrom:
secretKeyRef:
name: global
key: CHICMOZ_ETHEREUM_RPC_HTTP
- name: ETHEREUM_WS_RPC_URL
valueFrom:
secretKeyRef:
name: global
key: CHICMOZ_ETHEREUM_RPC_WS
status: {}
3 changes: 2 additions & 1 deletion k8s/local/skaffold.only_ethereum-listener.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ deploy:
apply: ["--force"]
manifests:
rawYaml:
- k8s/local/ethereum-listener/deployment.yaml
#- k8s/local/ethereum-listener/deployment.yaml
- k8s/local/ethereum-listener/remote_ethereum_deployment.yaml
2 changes: 2 additions & 0 deletions k8s/local/skaffold.remote_aztec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ requires:
- path: ./websocket-event-publisher/image.yaml
- path: ./auth/image.yaml
- path: ./aztec-listener/image.yaml
- path: ./ethereum-listener/image.yaml
deploy:
kubectl:
flags:
Expand All @@ -28,6 +29,7 @@ manifests:
- k8s/local/auth/deployment.yaml
- k8s/local/auth/service.yaml
- k8s/local/aztec-listener/remote_aztec_deployment.yaml
- k8s/local/ethereum-listener/remote_ethereum_deployment.yaml
helm:
releases:
- name: ingress-nginx
Expand Down
7 changes: 6 additions & 1 deletion packages/message-registry/src/ethereum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EthAddress } from "@chicmoz-pkg/types";
import { ChicmozL1L2Validator, EthAddress } from "@chicmoz-pkg/types";

export type ConnectedToEthereumEvent = {
something: string;
Expand All @@ -10,6 +10,10 @@ export type NewL1Event = {
data: unknown;
};

export type L1L2ValidatorEvent = {
validator: ChicmozL1L2Validator;
};

export function generateEthereumTopicName(
networkId: string,
topic: keyof ETHEREUM_MESSAGES
Expand All @@ -20,4 +24,5 @@ export function generateEthereumTopicName(
export type ETHEREUM_MESSAGES = {
CONNECTED_TO_ETHEREUM_EVENT: ConnectedToEthereumEvent;
NEW_L1_EVENT: NewL1Event;
L1_L2_VALIDATOR_EVENT: L1L2ValidatorEvent;
};
10 changes: 10 additions & 0 deletions packages/message-registry/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
import { AZTEC_MESSAGES } from "./aztec.js";
import { ETHEREUM_MESSAGES } from "./ethereum.js";

export * from "./aztec.js";
export * from "./ethereum.js";
export * from "./metric.js";
export * from "./subscription.js";

export const generateTopicName = (
networkId: string,
topic: keyof AZTEC_MESSAGES | keyof ETHEREUM_MESSAGES
): string => {
return `${networkId}_${topic}`;
};
84 changes: 44 additions & 40 deletions packages/types/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,51 @@ import {
hexStringSchema,
} from "../index.js";

export const chicmozSearchQuerySchema = z.object({
q: z.preprocess((val: unknown) => {
if (typeof val === "string") {
if (val.startsWith("0x")) return val;
else if (val.match(/^\d+$/)?.length) return parseInt(val);
else return `0x${val}`;
}
return val;
}, hexStringSchema.or(chicmozL2BlockSchema.shape.height)),
});
export const chicmozSearchQuerySchema = z.lazy(() =>
z.object({
q: z.preprocess((val: unknown) => {
if (typeof val === "string") {
if (val.startsWith("0x")) return val;
else if (val.match(/^\d+$/)?.length) return parseInt(val);
else return `0x${val}`;
}
return val;
}, hexStringSchema.or(chicmozL2BlockSchema.shape.height)),
})
);

export const chicmozSearchResultsSchema = z.object({
searchPhrase: z.string(),
results: z.object({
blocks: z.array(
z.object({
hash: chicmozL2BlockSchema.shape.hash,
})
),
txEffects: z.array(
z.object({
txHash: chicmozL2TxEffectSchema.shape.txHash,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
registeredContractClasses: z.array(
z.object({
contractClassId:
chicmozL2ContractClassRegisteredEventSchema.shape.contractClassId,
version: chicmozL2ContractClassRegisteredEventSchema.shape.version,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
contractInstances: z.array(
z.object({
address: chicmozL2ContractInstanceDeployedEventSchema.shape.address,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
}),
});
export const chicmozSearchResultsSchema = z.lazy(() =>
z.object({
searchPhrase: z.string(),
results: z.object({
blocks: z.array(
z.object({
hash: chicmozL2BlockSchema.shape.hash,
})
),
txEffects: z.array(
z.object({
txHash: chicmozL2TxEffectSchema.shape.txHash,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
registeredContractClasses: z.array(
z.object({
contractClassId:
chicmozL2ContractClassRegisteredEventSchema.shape.contractClassId,
version: chicmozL2ContractClassRegisteredEventSchema.shape.version,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
contractInstances: z.array(
z.object({
address: chicmozL2ContractInstanceDeployedEventSchema.shape.address,
partOfBlockWithHash: chicmozL2BlockSchema.shape.hash.optional(),
})
),
}),
})
);

export type ChicmozSearchResults = z.infer<typeof chicmozSearchResultsSchema>;
export type ChicmozSearchQuery = z.infer<typeof chicmozSearchQuerySchema>;
12 changes: 12 additions & 0 deletions packages/types/src/aztec/fee-recipient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { z } from "zod";
import { aztecAddressSchema } from "../index.js";

export const chicmozFeeRecipientSchema = z.object({
l2Address: aztecAddressSchema,
feesReceived: z.coerce.bigint(),
nbrOfBlocks: z.number(),
calculatedForNumberOfBlocks: z.number(),
partOfTotalFeesReceived: z.number().optional(),
});

export type ChicmozFeeRecipient = z.infer<typeof chicmozFeeRecipientSchema>;
1 change: 1 addition & 0 deletions packages/types/src/aztec/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { type NodeInfo };
export * from "./l2Block.js";
export * from "./l2Contract.js";
export * from "./l2TxEffect.js";
export * from "./fee-recipient.js";
export * from "./special.js";
export { frNumberSchema } from "./utils.js";

Expand Down
14 changes: 8 additions & 6 deletions packages/types/src/aztec/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const frToHexString = (val: unknown) => {
else return val;
};

// TODO: frSchema should be replaced with
// z.coerce.bigint().nonnegative()
export const frSchema = z.preprocess(
frToHexString,
z
Expand All @@ -44,12 +46,12 @@ const frPointToObj = (val: unknown) => {

export const frPointSchema = z.preprocess(
frPointToObj,
z.object({
x: frSchema,
y: frSchema,
isInfinite: z.boolean(),
kind: z.enum(["point"]),
})
z.object({
x: frSchema,
y: frSchema,
isInfinite: z.boolean(),
kind: z.enum(["point"]),
})
);

export const frNumberSchema = z.preprocess((val) => {
Expand Down
50 changes: 50 additions & 0 deletions packages/types/src/ethereum/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ethAddressSchema } from "../general.js";
import { z } from "zod";

// NOTE: explaination copied from aztec-packages: l1-contracts/src/core/interfaces/IStaking.sol
// None -> Does not exist in our setup
// Validating -> Participating as validator
// Living -> Not participating as validator, but have funds in setup,
// hit if slashes and going below the minimum
// Exiting -> In the process of exiting the system
export enum L1L2ValidatorStatus {
NONE,
VALIDATING,
LIVING,
EXITING,
}

export const chicmozL1L2ValidatorSchema = z.object({
attester: ethAddressSchema,
stake: z.coerce.bigint().nonnegative(), // TODO: this is not Fr but it might as well be. It is a uint256
withdrawer: ethAddressSchema,
proposer: ethAddressSchema,
status: z.nativeEnum(L1L2ValidatorStatus),
// NOTE: we could use createdAt and updatedAt, but I want to emphasize that this is the first time we saw this validator. It can be way off from the actual creation time (on chain).
firstSeenAt: z.coerce.date().default(() => new Date()),
latestSeenChangeAt: z.coerce.date().default(() => new Date()),
});

export type ChicmozL1L2Validator = z.infer<typeof chicmozL1L2ValidatorSchema>;

const timestampSchema = z.coerce.date();
const keyChangedSchema = z.coerce.string();
const newValueSchema = z.coerce.string();

export const chicmozL1L2ValidatorHistoryEntrySchema = z.tuple([
timestampSchema,
keyChangedSchema,
newValueSchema,
]);

export type ChicmozL1L2ValidatorHistoryEntry = z.infer<
typeof chicmozL1L2ValidatorHistoryEntrySchema
>;

export const chicmozL1L2ValidatorHistorySchema = z.array(
chicmozL1L2ValidatorHistoryEntrySchema
);

export type ChicmozL1L2ValidatorHistory = z.infer<
typeof chicmozL1L2ValidatorHistorySchema
>;
19 changes: 9 additions & 10 deletions packages/types/src/general.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { z } from "zod";
import { frSchema } from "./aztec/utils.js";
import { ChicmozL2Block, ChicmozL2PendingTx, chicmozL2BlockSchema } from "./index.js";
import {
ChicmozL2Block,
ChicmozL2PendingTx,
chicmozL2BlockSchema,
} from "./index.js";

export const hexStringSchema = z.custom<`0x${string}`>(
(value) => {
Expand All @@ -13,15 +17,10 @@ export const hexStringSchema = z.custom<`0x${string}`>(

export type HexString = z.infer<typeof hexStringSchema>;

export const ethAddressSchema = z.custom<`0x${string}`>((value) => {
if (!value) return false;
if (!(value as string).length) return false;
if (!(value as string).match) return false;
return (
(value as string).length === 42 &&
(value as string).match(/^0x[0-9a-fA-F]+$/) !== null
);
});
export const ethAddressSchema = z
.string()
.length(42)
.regex(/^0x[0-9a-fA-F]+$/)
export type EthAddress = z.infer<typeof ethAddressSchema>;

// NOTE: it's technically not the same as Fr but practically it is
Expand Down
5 changes: 3 additions & 2 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./events.js";
export * from "./aztec/index.js";
export * from "./api/index.js";
export * from "./aztec/index.js";
export * from "./ethereum/index.js";
export * from "./events.js";
export * from "./general.js";
2 changes: 1 addition & 1 deletion services/ethereum-listener/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const ETHEREUM_WS_RPC_URL = process.env.ETHEREUM_WS_RPC_URL ?? "ws://anvi
export const AZTEC_CHAIN_NAME = process.env.AZTEC_CHAIN_NAME ?? "AZTEC";
export const AZTEC_NETWORK_NAME = process.env.AZTEC_NETWORK_NAME ?? "SANDBOX";
export const ETHEREUM_CHAIN_NAME = process.env.ETHEREUM_CHAIN_NAME ?? "LOCAL_ETHEREUM";
export const ETHEREUM_NETWORK_ID = Number(process.env.ETHEREUM_NETWORK_NAME) ?? 31337;
export const ETHEREUM_NETWORK_ID = Number(process.env.ETHEREUM_NETWORK_NAME) || 31337;

export const KAFKA_CONNECTION = process.env.KAFKA_CONNECTION ?? "kafka:9092";
export const KAFKA_SASL_USERNAME = process.env.KAFKA_SASL_USERNAME ?? "controller_user";
Expand Down
Loading

0 comments on commit 52ff9c3

Please sign in to comment.