Skip to content

Commit

Permalink
feat: tx verification & peer scoring on p2p layer. bot support for Ea…
Browse files Browse the repository at this point in the history
…syPrivateToken (#8298)
  • Loading branch information
spypsy authored Sep 17, 2024
1 parent ee21583 commit beb651f
Show file tree
Hide file tree
Showing 52 changed files with 892 additions and 256 deletions.
9 changes: 1 addition & 8 deletions .github/workflows/sepolia-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ env:
TF_VAR_L1_CHAIN_ID: 11155111
TF_VAR_ETHEREUM_HOST: https://sepolia.infura.io/v3/${{ secrets.SEPOLIA_API_KEY }}
TF_VAR_PROVING_ENABLED: false
TF_VAR_BOT_TOKEN_CONTRACT: EasyPrivateTokenContract
TF_VAR_API_KEY: ${{ secrets.SEPOLIANET_API_KEY }}
# Node / Sequencer
TF_VAR_BOOTSTRAP_NODES: ""
Expand All @@ -39,15 +40,7 @@ env:
TF_VAR_PROVER_PRIVATE_KEYS: '["${{ secrets.SEPOLIA_PROVER_PRIVATE_KEY }}"]'

jobs:
setup:
uses: ./.github/workflows/setup-runner.yml
with:
username: ${{ github.event.pull_request.user.login || github.actor }}
runner_type: builder-x86
secrets: inherit

deploy:
needs: setup
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec-node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"scripts": {
"start": "node --no-warnings ./dest/bin",
"start:debug": "node --no-warnings --inspect ./dest/bin",
"build": "yarn clean && tsc -b",
"build:dev": "tsc -b --watch",
"clean": "rm -rf ./dest .tsbuildinfo",
Expand Down
66 changes: 8 additions & 58 deletions yarn-project/aztec-node/src/aztec-node/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import {
type L2LogsSource,
type MerkleTreeAdminOperations,
MerkleTreeId,
type WorldStateSynchronizer,
mockTxForRollup,
} from '@aztec/circuit-types';
import { AztecAddress, EthAddress, Fr, GasFees, GlobalVariables, MaxBlockNumber } from '@aztec/circuits.js';
import { EthAddress, Fr, MaxBlockNumber } from '@aztec/circuits.js';
import { type P2P } from '@aztec/p2p';
import { type GlobalVariableBuilder } from '@aztec/sequencer-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
import { type ContractDataSource } from '@aztec/types/contracts';
import { type WorldStateSynchronizer } from '@aztec/world-state';

import { type MockProxy, mock, mockFn } from 'jest-mock-extended';
import { type MockProxy, mock } from 'jest-mock-extended';

import { type AztecNodeConfig, getConfigEnvVars } from './config.js';
import { AztecNodeService } from './server.js';
Expand All @@ -30,10 +30,6 @@ describe('aztec node', () => {
let node: AztecNode;

const chainId = new Fr(12345);
const version = Fr.ZERO;
const coinbase = EthAddress.random();
const feeRecipient = AztecAddress.random();
const gasFees = GasFees.empty();

beforeEach(() => {
lastBlockNumber = 0;
Expand All @@ -48,7 +44,7 @@ describe('aztec node', () => {
});

const l2BlockSource = mock<L2BlockSource>({
getBlockNumber: mockFn().mockResolvedValue(lastBlockNumber),
getBlockNumber: () => Promise.resolve(lastBlockNumber),
});

const l2LogsSource = mock<L2LogsSource>();
Expand Down Expand Up @@ -79,7 +75,7 @@ describe('aztec node', () => {
l1ToL2MessageSource,
worldState,
undefined,
31337,
12345,
1,
globalVariablesBuilder,
new TestCircuitVerifier(),
Expand All @@ -95,21 +91,7 @@ describe('aztec node', () => {
});
const doubleSpendTx = txs[0];
const doubleSpendWithExistingTx = txs[1];

const mockedGlobalVariables = new GlobalVariables(
chainId,
version,
new Fr(lastBlockNumber + 1),
new Fr(1),
Fr.ZERO,
coinbase,
feeRecipient,
gasFees,
);

globalVariablesBuilder.buildGlobalVariables
.mockResolvedValueOnce(mockedGlobalVariables)
.mockResolvedValueOnce(mockedGlobalVariables);
lastBlockNumber += 1;

expect(await node.isValidTx(doubleSpendTx)).toBe(true);

Expand All @@ -118,10 +100,6 @@ describe('aztec node', () => {

expect(await node.isValidTx(doubleSpendTx)).toBe(false);

globalVariablesBuilder.buildGlobalVariables
.mockResolvedValueOnce(mockedGlobalVariables)
.mockResolvedValueOnce(mockedGlobalVariables);

expect(await node.isValidTx(doubleSpendWithExistingTx)).toBe(true);

// We make a nullifier from `doubleSpendWithExistingTx` a part of the nullifier tree, so it gets rejected as double spend
Expand All @@ -133,27 +111,13 @@ describe('aztec node', () => {
});

expect(await node.isValidTx(doubleSpendWithExistingTx)).toBe(false);
lastBlockNumber = 0;
});

it('tests that the node correctly validates chain id', async () => {
const tx = mockTxForRollup(0x10000);
tx.data.constants.txContext.chainId = chainId;

const mockedGlobalVariables = new GlobalVariables(
chainId,
version,
new Fr(lastBlockNumber + 1),
new Fr(1),
Fr.ZERO,
coinbase,
feeRecipient,
gasFees,
);

globalVariablesBuilder.buildGlobalVariables
.mockResolvedValueOnce(mockedGlobalVariables)
.mockResolvedValueOnce(mockedGlobalVariables);

expect(await node.isValidTx(tx)).toBe(true);

// We make the chain id on the tx not equal to the configured chain id
Expand Down Expand Up @@ -184,21 +148,7 @@ describe('aztec node', () => {
toBuffer: () => Fr.ZERO.toBuffer(),
};

const mockedGlobalVariables = new GlobalVariables(
chainId,
version,
new Fr(lastBlockNumber + 5),
new Fr(1),
Fr.ZERO,
coinbase,
feeRecipient,
gasFees,
);

globalVariablesBuilder.buildGlobalVariables
.mockResolvedValueOnce(mockedGlobalVariables)
.mockResolvedValueOnce(mockedGlobalVariables)
.mockResolvedValueOnce(mockedGlobalVariables);
lastBlockNumber = 3;

// Default tx with no max block number should be valid
expect(await node.isValidTx(noMaxBlockNumberMetadata)).toBe(true);
Expand Down
50 changes: 25 additions & 25 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
TxReceipt,
TxStatus,
type TxValidator,
type WorldStateSynchronizer,
partitionReverts,
} from '@aztec/circuit-types';
import {
Expand All @@ -52,20 +53,22 @@ import { createDebugLogger } from '@aztec/foundation/log';
import { Timer } from '@aztec/foundation/timer';
import { openTmpStore } from '@aztec/kv-store/utils';
import { SHA256Trunc, StandardTree, UnbalancedTree } from '@aztec/merkle-tree';
import { InMemoryAttestationPool, type P2P, createP2PClient } from '@aztec/p2p';
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry';
import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
import {
AggregateTxValidator,
DataTxValidator,
DoubleSpendTxValidator,
GlobalVariableBuilder,
InMemoryAttestationPool,
MetadataTxValidator,
SequencerClient,
} from '@aztec/sequencer-client';
type P2P,
TxProofValidator,
createP2PClient,
} from '@aztec/p2p';
import { getCanonicalClassRegisterer } from '@aztec/protocol-contracts/class-registerer';
import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
import { getCanonicalInstanceDeployer } from '@aztec/protocol-contracts/instance-deployer';
import { getCanonicalKeyRegistryAddress } from '@aztec/protocol-contracts/key-registry';
import { getCanonicalMultiCallEntrypointAddress } from '@aztec/protocol-contracts/multi-call-entrypoint';
import { GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
import { PublicProcessorFactory, WASMSimulator, WorldStateDB, createSimulationProvider } from '@aztec/simulator';
import { type TelemetryClient } from '@aztec/telemetry-client';
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
Expand All @@ -76,11 +79,10 @@ import {
type ProtocolContractAddresses,
} from '@aztec/types/contracts';
import { createValidatorClient } from '@aztec/validator-client';
import { type WorldStateSynchronizer, createWorldStateSynchronizer } from '@aztec/world-state';
import { createWorldStateSynchronizer } from '@aztec/world-state';

import { type AztecNodeConfig, getPackageInfo } from './config.js';
import { NodeMetrics } from './node_metrics.js';
import { TxProofValidator } from './tx_validator/tx_proof_validator.js';

/**
* The aztec node.
Expand Down Expand Up @@ -144,17 +146,23 @@ export class AztecNodeService implements AztecNode {
// this may well change in future
config.transactionProtocol = `/aztec/tx/${config.l1Contracts.rollupAddress.toString()}`;

// create the tx pool and the p2p client, which will need the l2 block source
const p2pClient = await createP2PClient(config, new InMemoryAttestationPool(), archiver, telemetry);

// now create the merkle trees and the world state synchronizer
const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, telemetry);
const proofVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();

// create the tx pool and the p2p client, which will need the l2 block source
const p2pClient = await createP2PClient(
config,
new InMemoryAttestationPool(),
archiver,
proofVerifier,
worldStateSynchronizer,
telemetry,
);

// start both and wait for them to sync from the block source
await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);

const proofVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();

const simulationProvider = await createSimulationProvider(config, log);

const validatorClient = createValidatorClient(config, p2pClient);
Expand Down Expand Up @@ -748,20 +756,12 @@ export class AztecNodeService implements AztecNode {

public async isValidTx(tx: Tx, isSimulation: boolean = false): Promise<boolean> {
const blockNumber = (await this.blockSource.getBlockNumber()) + 1;

const newGlobalVariables = await this.globalVariableBuilder.buildGlobalVariables(
new Fr(blockNumber),
// We only need chainId and block number, thus coinbase and fee recipient can be set to 0.
EthAddress.ZERO,
AztecAddress.ZERO,
);

// These validators are taken from the sequencer, and should match.
// The reason why `phases` and `gas` tx validator is in the sequencer and not here is because
// those tx validators are customizable by the sequencer.
const txValidators: TxValidator<Tx | ProcessedTx>[] = [
new DataTxValidator(),
new MetadataTxValidator(newGlobalVariables),
new MetadataTxValidator(new Fr(this.l1ChainId), new Fr(blockNumber)),
new DoubleSpendTxValidator(new WorldStateDB(this.worldStateSynchronizer.getLatest())),
];

Expand Down
1 change: 1 addition & 0 deletions yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export {
type ContractStorageLayout,
DefaultWaitOpts,
DeployMethod,
DeployOptions,
DeploySentTx,
type SendMethodOptions,
SentTx,
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/aztec/terraform/bot/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ resource "aws_ecs_task_definition" "aztec-bot" {
{ name = "BOT_SKIP_PUBLIC_SIMULATION", value = tostring(var.BOT_SKIP_PUBLIC_SIMULATION) },
{ name = "BOT_L2_GAS_LIMIT", value = var.BOT_L2_GAS_LIMIT },
{ name = "BOT_DA_GAS_LIMIT", value = var.BOT_DA_GAS_LIMIT },
{ name = "LOG_JSON", value = "1" }
{ name = "LOG_JSON", value = "1" },
{ name = "BOT_TOKEN_CONTRACT", value = var.BOT_TOKEN_CONTRACT }
]
logConfiguration = {
logDriver = "awslogs"
Expand Down
4 changes: 4 additions & 0 deletions yarn-project/aztec/terraform/bot/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,8 @@ variable "BOT_DA_GAS_LIMIT" {
type = string
}

variable "BOT_TOKEN_CONTRACT" {
type = string
default = "TokenContract"
}

36 changes: 32 additions & 4 deletions yarn-project/aztec/terraform/node/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ resource "aws_ecs_task_definition" "aztec-node" {
name = "DEPLOY_TAG"
value = var.DEPLOY_TAG
},
{
name = "L1_CHAIN_ID"
value = var.L1_CHAIN_ID
},
{
name = "DEPLOY_AZTEC_CONTRACTS"
value = "false"
Expand Down Expand Up @@ -352,10 +356,6 @@ resource "aws_ecs_task_definition" "aztec-node" {
name = "P2P_ENABLED"
value = tostring(var.P2P_ENABLED)
},
{
name = "L1_CHAIN_ID"
value = var.L1_CHAIN_ID
},
{
name = "PEER_ID_PRIVATE_KEY"
value = local.node_p2p_private_keys[count.index]
Expand All @@ -380,6 +380,34 @@ resource "aws_ecs_task_definition" "aztec-node" {
name = "P2P_TX_POOL_KEEP_PROVEN_FOR",
value = tostring(var.P2P_TX_POOL_KEEP_PROVEN_FOR)
},
{
name = "P2P_SEVERE_PEER_PENALTY_BLOCK_LENGTH"
value = tostring(var.P2P_SEVERE_PEER_PENALTY_BLOCK_LENGTH)
},
{
name = "P2P_GOSSIPSUB_INTERVAL_MS"
value = tostring(var.P2P_GOSSIPSUB_INTERVAL_MS)
},
{
name = "P2P_GOSSIPSUB_D"
value = tostring(var.P2P_GOSSIPSUB_D)
},
{
name = "P2P_GOSSIPSUB_DLO"
value = tostring(var.P2P_GOSSIPSUB_DLO)
},
{
name = "P2P_GOSSIPSUB_DHI"
value = tostring(var.P2P_GOSSIPSUB_DHI)
},
{
name = "P2P_GOSSIPSUB_MCACHE_LENGTH"
value = tostring(var.P2P_GOSSIPSUB_MCACHE_LENGTH)
},
{
name = "P2P_GOSSIPSUB_MCACHE_GOSSIP"
value = tostring(var.P2P_GOSSIPSUB_MCACHE_GOSSIP)
},
{
name = "PROVER_AGENT_ENABLED"
value = "false"
Expand Down
35 changes: 35 additions & 0 deletions yarn-project/aztec/terraform/node/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,41 @@ variable "P2P_TX_POOL_KEEP_PROVEN_FOR" {
default = 64
}

variable "P2P_GOSSIPSUB_INTERVAL_MS" {
type = number
default = 1000
}

variable "P2P_GOSSIPSUB_D" {
type = number
default = 8
}

variable "P2P_GOSSIPSUB_DLO" {
type = number
default = 4
}

variable "P2P_GOSSIPSUB_DHI" {
type = number
default = 12
}

variable "P2P_GOSSIPSUB_MCACHE_LENGTH" {
type = number
default = 5
}

variable "P2P_GOSSIPSUB_MCACHE_GOSSIP" {
type = number
default = 3
}

variable "P2P_SEVERE_PEER_PENALTY_BLOCK_LENGTH" {
type = number
default = 30
}

variable "PROVING_ENABLED" {
type = bool
default = false
Expand Down
Loading

0 comments on commit beb651f

Please sign in to comment.