Skip to content

Commit

Permalink
feat: epoch cache, do not attest if not in committee or from current …
Browse files Browse the repository at this point in the history
…proposer (#10327)

some of: #7962
fixes: #8721

---------

Co-authored-by: Mitch <[email protected]>
Co-authored-by: just-mitch <[email protected]>
  • Loading branch information
3 people authored Dec 6, 2024
1 parent e7ebef8 commit 9ebaa65
Show file tree
Hide file tree
Showing 48 changed files with 899 additions and 143 deletions.
54 changes: 46 additions & 8 deletions l1-contracts/src/core/Leonidas.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,42 @@ contract Leonidas is Staking, TimeFns, ILeonidas {
);
}

function deposit(address _attester, address _proposer, address _withdrawer, uint256 _amount)
public
override(Staking)
/**
* @notice Get the committee for a given timestamp
*
* @param _ts - The timestamp to get the committee for
*
* @return The committee for the given timestamp
*/
function getCommitteeAt(Timestamp _ts)
external
view
override(ILeonidas)
returns (address[] memory)
{
setupEpoch();
require(
_attester != address(0) && _proposer != address(0),
Errors.Leonidas__InvalidDeposit(_attester, _proposer)
return LeonidasLib.getCommitteeAt(
leonidasStore, stakingStore, getEpochAt(_ts), TARGET_COMMITTEE_SIZE
);
super.deposit(_attester, _proposer, _withdrawer, _amount);
}

/**
* @notice Get the sample seed for a given timestamp
*
* @param _ts - The timestamp to get the sample seed for
*
* @return The sample seed for the given timestamp
*/
function getSampleSeedAt(Timestamp _ts) external view override(ILeonidas) returns (uint256) {
return LeonidasLib.getSampleSeed(leonidasStore, getEpochAt(_ts));
}

/**
* @notice Get the sample seed for the current epoch
*
* @return The sample seed for the current epoch
*/
function getCurrentSampleSeed() external view override(ILeonidas) returns (uint256) {
return LeonidasLib.getSampleSeed(leonidasStore, getCurrentEpoch());
}

function initiateWithdraw(address _attester, address _recipient)
Expand All @@ -106,6 +132,18 @@ contract Leonidas is Staking, TimeFns, ILeonidas {
return super.initiateWithdraw(_attester, _recipient);
}

function deposit(address _attester, address _proposer, address _withdrawer, uint256 _amount)
public
override(Staking)
{
setupEpoch();
require(
_attester != address(0) && _proposer != address(0),
Errors.Leonidas__InvalidDeposit(_attester, _proposer)
);
super.deposit(_attester, _proposer, _withdrawer, _amount);
}

/**
* @notice Performs a setup of an epoch if needed. The setup will
* - Sample the validator set for the epoch
Expand Down
4 changes: 4 additions & 0 deletions l1-contracts/src/core/interfaces/ILeonidas.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ interface ILeonidas {
// Likely removal of these to replace with a size and indiviual getter
// Get the current epoch committee
function getCurrentEpochCommittee() external view returns (address[] memory);
function getCommitteeAt(Timestamp _ts) external view returns (address[] memory);
function getEpochCommittee(Epoch _epoch) external view returns (address[] memory);
function getAttesters() external view returns (address[] memory);

function getSampleSeedAt(Timestamp _ts) external view returns (uint256);
function getCurrentSampleSeed() external view returns (uint256);

function getEpochAt(Timestamp _ts) external view returns (Epoch);
function getSlotAt(Timestamp _ts) external view returns (Slot);
function getEpochAtSlot(Slot _slotNumber) external view returns (Epoch);
Expand Down
4 changes: 3 additions & 1 deletion scripts/run_interleaved.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ trap cleanup SIGINT SIGTERM EXIT
# Function to run a command and prefix the output with color
function run_command() {
local cmd="$1"
# Take first 3 parts of command to display inline
local cmd_prefix=$(echo "$cmd" | awk '{print $1" "$2" "$3}')
local color="$2"
$cmd 2>&1 | while IFS= read -r line; do
echo -e "${color}[$cmd]\e[0m $line"
echo -e "${color}[$cmd_prefix]\e[0m $line"
done
}

Expand Down
3 changes: 2 additions & 1 deletion scripts/run_native_testnet.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ PROVER_SCRIPT="\"./prover-node.sh 8078 false\""
NUM_VALIDATORS=3
INTERLEAVED=false
METRICS=false
LOG_LEVEL="info"
OTEL_COLLECTOR_ENDPOINT=${OTEL_COLLECTOR_ENDPOINT:-"http://localhost:4318"}

# Function to display help message
Expand Down Expand Up @@ -120,7 +121,7 @@ cd $(git rev-parse --show-toplevel)
# Base command
BASE_CMD="INTERLEAVED=$INTERLEAVED ./yarn-project/end-to-end/scripts/native_network_test.sh \
$TEST_SCRIPT \
./deploy-l1-contracts.sh \
\"./deploy-l1-contracts.sh $NUM_VALIDATORS\" \
./deploy-l2-contracts.sh \
./boot-node.sh \
./ethereum.sh \
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ network-test:
ENV LOG_LEVEL=verbose
RUN INTERLEAVED=true end-to-end/scripts/native_network_test.sh \
"$test" \
./deploy-l1-contracts.sh \
"./deploy-l1-contracts.sh $validators" \
./deploy-l2-contracts.sh \
./boot-node.sh \
./ethereum.sh \
Expand Down
19 changes: 5 additions & 14 deletions yarn-project/archiver/src/archiver/archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
type GetUnencryptedLogsResponse,
type InBlock,
type InboxLeaf,
type L1RollupConstants,
type L1ToL2MessageSource,
type L2Block,
type L2BlockId,
Expand All @@ -15,6 +16,10 @@ import {
type TxReceipt,
type TxScopedL2Log,
type UnencryptedL2Log,
getEpochNumberAtTimestamp,
getSlotAtTimestamp,
getSlotRangeForEpoch,
getTimestampRangeForEpoch,
} from '@aztec/circuit-types';
import {
type ContractClassPublic,
Expand Down Expand Up @@ -62,12 +67,6 @@ import {
import { type ArchiverDataStore, type ArchiverL1SynchPoint } from './archiver_store.js';
import { type ArchiverConfig } from './config.js';
import { retrieveBlocksFromRollup, retrieveL1ToL2Messages } from './data_retrieval.js';
import {
getEpochNumberAtTimestamp,
getSlotAtTimestamp,
getSlotRangeForEpoch,
getTimestampRangeForEpoch,
} from './epoch_helpers.js';
import { ArchiverInstrumentation } from './instrumentation.js';
import { type DataRetrieval } from './structs/data_retrieval.js';
import { type L1Published } from './structs/published.js';
Expand Down Expand Up @@ -1100,11 +1099,3 @@ class ArchiverStoreHelper
return this.store.estimateSize();
}
}

type L1RollupConstants = {
l1StartBlock: bigint;
l1GenesisTime: bigint;
slotDuration: number;
epochDuration: number;
ethereumSlotDuration: number;
};
3 changes: 1 addition & 2 deletions yarn-project/archiver/src/test/mock_l2_block_source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import {
TxReceipt,
TxStatus,
} from '@aztec/circuit-types';
import { getSlotRangeForEpoch } from '@aztec/circuit-types';
import { EthAddress, type Header } from '@aztec/circuits.js';
import { DefaultL1ContractsConfig } from '@aztec/ethereum';
import { createDebugLogger } from '@aztec/foundation/log';

import { getSlotRangeForEpoch } from '../archiver/epoch_helpers.js';

/**
* A mocked implementation of L2BlockSource to be used in tests.
*/
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export class AztecNodeService implements AztecNode {
// start both and wait for them to sync from the block source
await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);

const validatorClient = createValidatorClient(config, p2pClient, telemetry);
const validatorClient = await createValidatorClient(config, config.l1Contracts.rollupAddress, p2pClient, telemetry);

// now create the sequencer
const sequencer = config.disableValidator
Expand Down
8 changes: 5 additions & 3 deletions yarn-project/aztec.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export {
type ContractNotes,
type ContractStorageLayout,
type DeployOptions,
type ProfileResult,
type SendMethodOptions,
type WaitOpts,
type ProfileResult,
} from './contract/index.js';

export { ContractDeployer } from './deployment/index.js';
Expand All @@ -59,8 +59,8 @@ export {
type FieldLike,
type FunctionSelectorLike,
type L2AmountClaim,
type L2Claim,
type L2AmountClaimWithRecipient,
type L2Claim,
type WrappedFieldLike,
} from './utils/index.js';

Expand Down Expand Up @@ -138,10 +138,12 @@ export {
UnencryptedL2Log,
UniqueNote,
createAztecNodeClient,
getTimestampRangeForEpoch,
merkleTreeIds,
mockEpochProofQuote,
mockTx,
type AztecNode,
type EpochConstants,
type LogFilter,
type PXE,
type PartialAddress,
Expand All @@ -164,7 +166,7 @@ export { elapsed } from '@aztec/foundation/timer';
export { type FieldsOf } from '@aztec/foundation/types';
export { fileURLToPath } from '@aztec/foundation/url';

export { type DeployL1Contracts, EthCheatCodes, deployL1Contract, deployL1Contracts } from '@aztec/ethereum';
export { EthCheatCodes, deployL1Contract, deployL1Contracts, type DeployL1Contracts } from '@aztec/ethereum';

// Start of section that exports public api via granular api.
// Here you *can* do `export *` as the granular api defacto exports things explicitly.
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,4 @@
"engines": {
"node": ">=18"
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
// REFACTOR: This file should go in a package lower in the dependency graph.
export type L1RollupConstants = {
l1StartBlock: bigint;
l1GenesisTime: bigint;
slotDuration: number;
epochDuration: number;
ethereumSlotDuration: number;
};

export const EmptyL1RollupConstants: L1RollupConstants = {
l1StartBlock: 0n,
l1GenesisTime: 0n,
epochDuration: 1, // Not 0 to pervent division by zero
slotDuration: 1,
ethereumSlotDuration: 1,
};

export type EpochConstants = {
l1GenesisBlock: bigint;
Expand Down
1 change: 1 addition & 0 deletions yarn-project/circuit-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export * from './tx_execution_request.js';
export * from './in_block.js';
export * from './nullifier_with_block_source.js';
export * from './proving_error.js';
export * from './epoch-helpers/index.js';
4 changes: 4 additions & 0 deletions yarn-project/circuit-types/src/p2p/block_proposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export class BlockProposal extends Gossipable {
return this.payload.archive;
}

get slotNumber(): Fr {
return this.payload.header.globalVariables.slotNumber;
}

static async createProposalFromSigner(
payload: ConsensusPayload,
payloadSigner: (payload: Buffer32) => Promise<Signature>,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/cli-wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@
"engines": {
"node": ">=18"
}
}
}
3 changes: 2 additions & 1 deletion yarn-project/end-to-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
"devDependencies": {
"0x": "^5.7.0",
"@jest/globals": "^29.5.0",
"@sinonjs/fake-timers": "^13.0.5",
"@types/jest": "^29.5.0",
"@types/js-yaml": "^4.0.9",
"@types/lodash.chunk": "^4.2.9",
Expand Down Expand Up @@ -156,4 +157,4 @@
"testRegex": "./src/.*\\.test\\.(js|mjs|ts)$",
"rootDir": "./src"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Get the name of the script without the path and extension
SCRIPT_NAME=$(basename "$0" .sh)
REPO=$(git rev-parse --show-toplevel)

# Redirect stdout and stderr to <script_name>.log while also printing to the console
exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2)
Expand All @@ -13,7 +14,9 @@ set -eu
# Check for validator addresses
if [ $# -gt 0 ]; then
INIT_VALIDATORS="true"
VALIDATOR_ADDRESSES="$1"
NUMBER_OF_VALIDATORS="$1"
# Generate validator keys, this will set the VALIDATOR_ADDRESSES variable
source $REPO/yarn-project/end-to-end/scripts/native-network/generate-aztec-validator-keys.sh $NUMBER_OF_VALIDATORS
else
INIT_VALIDATORS="false"
fi
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

# Generate Aztec validator keys

NUMBER_OF_KEYS=${1:-16}
MNEMONIC=${2:-"test test test test test test test test test test test junk"}

# Initialize arrays to store private keys and addresses
declare -a VALIDATOR_PRIVATE_KEYS
declare -a VALIDATOR_ADDRESSES_LIST

for i in $(seq 0 $(($NUMBER_OF_KEYS - 1))); do
# Get private key and store it in array
PRIVATE_KEY=$(cast wallet private-key "$MNEMONIC" --mnemonic-index $i)
VALIDATOR_PRIVATE_KEYS+=("$PRIVATE_KEY")

# Get address from private key and store it in array
ADDRESS=$(cast wallet address "$PRIVATE_KEY")
VALIDATOR_ADDRESSES_LIST+=("$ADDRESS")
done

# Join addresses with commas
VALIDATOR_ADDRESSES=$(IFS=, ; echo "${VALIDATOR_ADDRESSES_LIST[*]}")

# Optionally, if you need the arrays for further use, you can export them:
export VALIDATOR_PRIVATE_KEYS
export VALIDATOR_ADDRESSES_LIST
export VALIDATOR_ADDRESSES
9 changes: 5 additions & 4 deletions yarn-project/end-to-end/scripts/native-network/validator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ else
node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js add-l1-validator --validator $ADDRESS --rollup $ROLLUP_CONTRACT_ADDRESS && break
sleep 1
done
fi

# Fast forward epochs if we're on an anvil chain
if [ "$IS_ANVIL" = "true" ]; then
node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js fast-forward-epochs --rollup $ROLLUP_CONTRACT_ADDRESS --count 1
# Fast forward epochs if we're on an anvil chain
if [ "$IS_ANVIL" = "true" ]; then
node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js fast-forward-epochs --rollup $ROLLUP_CONTRACT_ADDRESS --count 1
fi
fi

# Start the Validator Node with the sequencer and archiver
node --no-warnings "$REPO"/yarn-project/aztec/dest/bin/index.js start --port="$PORT" --node --archiver --sequencer
13 changes: 7 additions & 6 deletions yarn-project/end-to-end/scripts/native-network/validators.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -eu

# Get the name of the script without the path and extension
SCRIPT_NAME=$(basename "$0" .sh)
REPO=$(git rev-parse --show-toplevel)

# Redirect stdout and stderr to <script_name>.log while also printing to the console
exec > >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log") 2> >(tee -a "$(dirname $0)/logs/${SCRIPT_NAME}.log" >&2)
Expand All @@ -15,17 +16,17 @@ cd "$(dirname "${BASH_SOURCE[0]}")"

CMD=()

# Generate validator private keys
source $REPO/yarn-project/end-to-end/scripts/native-network/generate-aztec-validator-keys.sh $NUM_VALIDATORS

# Generate validator commands
for ((i = 0; i < NUM_VALIDATORS; i++)); do
PORT=$((8081 + i))
P2P_PORT=$((40401 + i))
IDX=$((i + 1))

# These variables should be set in public networks if we have funded validators already. Leave empty for test environments.
ADDRESS_VAR="ADDRESS_${IDX}"
PRIVATE_KEY_VAR="VALIDATOR_PRIVATE_KEY_${IDX}"
ADDRESS="${!ADDRESS_VAR:-}"
VALIDATOR_PRIVATE_KEY="${!PRIVATE_KEY_VAR:-}"
# Use the arrays generated from generate-aztec-validator-keys.sh
ADDRESS="${VALIDATOR_ADDRESSES_LIST[$i]}"
VALIDATOR_PRIVATE_KEY="${VALIDATOR_PRIVATE_KEYS[$i]}"

CMD+=("./validator.sh $PORT $P2P_PORT $ADDRESS $VALIDATOR_PRIVATE_KEY")
done
Expand Down
Loading

0 comments on commit 9ebaa65

Please sign in to comment.