Skip to content

Commit

Permalink
feat: Prover node stakes to escrow contract
Browse files Browse the repository at this point in the history
  • Loading branch information
spalladino committed Oct 3, 2024
1 parent 1c3cb63 commit 2025085
Show file tree
Hide file tree
Showing 33 changed files with 533 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Create a basic ERC20 contract that can mint tokens to anyone. We will use this t

Create a file `TestERC20.sol` in the same folder and add:

#include_code contract /l1-contracts/test/TestERC20.sol solidity
#include_code contract /l1-contracts/src/mock/TestERC20.sol solidity

Replace the openzeppelin import with this:

Expand Down Expand Up @@ -81,7 +81,7 @@ Here we want to send a message to mint tokens privately on Aztec! Some key diffe
- The content hash uses a different function name - `mint_private`. This is done to make it easy to separate concerns. If the contentHash between the public and private message was the same, then an attacker could consume a private message publicly!
- Since we want to mint tokens privately, we shouldn’t specify a `to` Aztec address (remember that Ethereum is completely public). Instead, we will use a secret hash - `secretHashForRedeemingMintedNotes`. Only he who knows the preimage to the secret hash can actually mint the notes. This is similar to the mechanism we use for message consumption on L2
- Like with the public flow, we move the user’s funds to the portal
- We now send the message to the inbox with the `recipient` (the sister contract on L2 along with the version of aztec the message is intended for) and the `secretHashForL2MessageConsumption` (such that on L2, the consumption of the message can be private).
- We now send the message to the inbox with the `recipient` (the sister contract on L2 along with the version of aztec the message is intended for) and the `secretHashForL2MessageConsumption` (such that on L2, the consumption of the message can be private).

Note that because L1 is public, everyone can inspect and figure out the contentHash and the recipient contract address.

Expand Down
3 changes: 2 additions & 1 deletion l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,14 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {

constructor(
IFeeJuicePortal _fpcJuicePortal,
IProofCommitmentEscrow _proofCommitmentEscrow,
bytes32 _vkTreeRoot,
address _ares,
address[] memory _validators
) Leonidas(_ares) {
epochProofVerifier = new MockVerifier();
FEE_JUICE_PORTAL = _fpcJuicePortal;
PROOF_COMMITMENT_ESCROW = new MockProofCommitmentEscrow();
PROOF_COMMITMENT_ESCROW = _proofCommitmentEscrow;
INBOX = IInbox(address(new Inbox(address(this), Constants.L1_TO_L2_MSG_SUBTREE_HEIGHT)));
OUTBOX = IOutbox(address(new Outbox(address(this))));
vkTreeRoot = _vkTreeRoot;
Expand Down
3 changes: 3 additions & 0 deletions l1-contracts/src/core/interfaces/IProofCommitmentEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pragma solidity >=0.8.27;

import {Timestamp} from "@aztec/core/libraries/TimeMath.sol";
import {IERC20} from "@oz/token/ERC20/IERC20.sol";

interface IProofCommitmentEscrow {
event Deposit(address indexed depositor, uint256 amount);
Expand All @@ -17,4 +18,6 @@ interface IProofCommitmentEscrow {
function stakeBond(address _prover, uint256 _amount) external;
function unstakeBond(address _prover, uint256 _amount) external;
function minBalanceAtTime(Timestamp _timestamp, address _prover) external view returns (uint256);
function deposits(address) external view returns (uint256);
function token() external view returns (IERC20);
}
12 changes: 11 additions & 1 deletion l1-contracts/src/mock/MockProofCommitmentEscrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@ pragma solidity >=0.8.27;

import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";
import {Timestamp} from "@aztec/core/libraries/TimeMath.sol";
import {IERC20} from "@oz/token/ERC20/IERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";

contract MockProofCommitmentEscrow is IProofCommitmentEscrow {
mapping(address => uint256) public deposits;

IERC20 public immutable token;

constructor() {
token = new TestERC20();
}

function deposit(uint256 _amount) external override {
// do nothing
deposits[msg.sender] += _amount;
}

function startWithdraw(uint256 _amount) external override {
Expand Down
File renamed without changes.
9 changes: 7 additions & 2 deletions l1-contracts/test/Rollup.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import {Outbox} from "@aztec/core/messagebridge/Outbox.sol";
import {Errors} from "@aztec/core/libraries/Errors.sol";
import {Rollup} from "@aztec/core/Rollup.sol";
import {IRollup} from "@aztec/core/interfaces/IRollup.sol";
import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";
import {FeeJuicePortal} from "@aztec/core/FeeJuicePortal.sol";
import {Leonidas} from "@aztec/core/Leonidas.sol";
import {NaiveMerkle} from "./merkle/Naive.sol";
import {MerkleTestUtil} from "./merkle/TestUtil.sol";
import {TestERC20} from "./TestERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";
import {MockProofCommitmentEscrow} from "@aztec/mock/MockProofCommitmentEscrow.sol";

import {TxsDecoderHelper} from "./decoders/helpers/TxsDecoderHelper.sol";
import {IERC20Errors} from "@oz/interfaces/draft-IERC6093.sol";
Expand All @@ -44,6 +46,7 @@ contract RollupTest is DecoderBase {
TxsDecoderHelper internal txsHelper;
TestERC20 internal testERC20;
FeeJuicePortal internal feeJuicePortal;
IProofCommitmentEscrow internal proofCommitmentEscrow;

SignatureLib.Signature[] internal signatures;

Expand All @@ -70,7 +73,9 @@ contract RollupTest is DecoderBase {
feeJuicePortal.initialize(
address(registry), address(testERC20), bytes32(Constants.FEE_JUICE_ADDRESS)
);
rollup = new Rollup(feeJuicePortal, bytes32(0), address(this), new address[](0));
proofCommitmentEscrow = new MockProofCommitmentEscrow();
rollup =
new Rollup(feeJuicePortal, proofCommitmentEscrow, bytes32(0), address(this), new address[](0));
inbox = Inbox(address(rollup.INBOX()));
outbox = Outbox(address(rollup.OUTBOX()));

Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/test/TestERC20.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pragma solidity ^0.8.18;

import "forge-std/Test.sol";
import {TestERC20} from "./TestERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";

contract TestERC20Test is Test {
TestERC20 testERC20;
Expand Down
11 changes: 9 additions & 2 deletions l1-contracts/test/portals/TokenPortal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import {Hash} from "@aztec/core/libraries/crypto/Hash.sol";
import {IInbox} from "@aztec/core/interfaces/messagebridge/IInbox.sol";
import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol";
import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol";
import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";

// Portal tokens
import {TokenPortal} from "./TokenPortal.sol";
import {TestERC20} from "../TestERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";

import {NaiveMerkle} from "../merkle/Naive.sol";

Expand Down Expand Up @@ -60,7 +61,13 @@ contract TokenPortalTest is Test {
function setUp() public {
registry = new Registry(address(this));
testERC20 = new TestERC20();
rollup = new Rollup(IFeeJuicePortal(address(0)), bytes32(0), address(this), new address[](0));
rollup = new Rollup(
IFeeJuicePortal(address(0)),
IProofCommitmentEscrow(address(0)),
bytes32(0),
address(this),
new address[](0)
);
inbox = rollup.INBOX();
outbox = rollup.OUTBOX();

Expand Down
9 changes: 8 additions & 1 deletion l1-contracts/test/portals/UniswapPortal.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {IERC20} from "@oz/token/ERC20/IERC20.sol";
import {IOutbox} from "@aztec/core/interfaces/messagebridge/IOutbox.sol";
import {NaiveMerkle} from "../merkle/Naive.sol";
import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol";
import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";

// Portals
import {TokenPortal} from "./TokenPortal.sol";
Expand Down Expand Up @@ -52,7 +53,13 @@ contract UniswapPortalTest is Test {
vm.selectFork(forkId);

registry = new Registry(address(this));
rollup = new Rollup(IFeeJuicePortal(address(0)), bytes32(0), address(this), new address[](0));
rollup = new Rollup(
IFeeJuicePortal(address(0)),
IProofCommitmentEscrow(address(0)),
bytes32(0),
address(this),
new address[](0)
);
registry.upgrade(address(rollup));

daiTokenPortal = new TokenPortal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {ProofCommitmentEscrow} from "@aztec/core/ProofCommitmentEscrow.sol";
import {Errors} from "@aztec/core/libraries/Errors.sol";
import {Timestamp} from "@aztec/core/libraries/TimeMath.sol";

import {TestERC20} from "../TestERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";

// solhint-disable comprehensive-interface

Expand Down
11 changes: 9 additions & 2 deletions l1-contracts/test/sparta/Sparta.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import {Rollup} from "@aztec/core/Rollup.sol";
import {Leonidas} from "@aztec/core/Leonidas.sol";
import {NaiveMerkle} from "../merkle/Naive.sol";
import {MerkleTestUtil} from "../merkle/TestUtil.sol";
import {TestERC20} from "../TestERC20.sol";
import {TestERC20} from "@aztec/mock/TestERC20.sol";
import {TxsDecoderHelper} from "../decoders/helpers/TxsDecoderHelper.sol";
import {IFeeJuicePortal} from "@aztec/core/interfaces/IFeeJuicePortal.sol";
import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.sol";
import {MessageHashUtils} from "@oz/utils/cryptography/MessageHashUtils.sol";

import {Slot, Epoch, SlotLib, EpochLib} from "@aztec/core/libraries/TimeMath.sol";
Expand Down Expand Up @@ -74,7 +75,13 @@ contract SpartaTest is DecoderBase {
}

testERC20 = new TestERC20();
rollup = new Rollup(IFeeJuicePortal(address(0)), bytes32(0), address(this), initialValidators);
rollup = new Rollup(
IFeeJuicePortal(address(0)),
IProofCommitmentEscrow(address(0)),
bytes32(0),
address(this),
initialValidators
);
inbox = Inbox(address(rollup.INBOX()));
outbox = Outbox(address(rollup.OUTBOX()));

Expand Down
6 changes: 6 additions & 0 deletions yarn-project/aztec/src/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
FeeJuicePortalBytecode,
InboxAbi,
InboxBytecode,
MockProofCommitmentEscrowAbi,
MockProofCommitmentEscrowBytecode,
OutboxAbi,
OutboxBytecode,
RegistryAbi,
Expand Down Expand Up @@ -115,6 +117,10 @@ export async function deployContractsToL1(
contractAbi: FeeJuicePortalAbi,
contractBytecode: FeeJuicePortalBytecode,
},
proofCommitmentEscrow: {
contractAbi: MockProofCommitmentEscrowAbi,
contractBytecode: MockProofCommitmentEscrowBytecode,
},
};

const chain = aztecNodeConfig.l1RpcUrl
Expand Down
7 changes: 6 additions & 1 deletion yarn-project/cli/src/utils/aztec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ export async function deployAztecContracts(
RegistryBytecode,
RollupAbi,
RollupBytecode,

MockProofCommitmentEscrowAbi,
MockProofCommitmentEscrowBytecode,
FeeJuicePortalAbi,
FeeJuicePortalBytecode,
TestERC20Abi,
Expand Down Expand Up @@ -107,6 +108,10 @@ export async function deployAztecContracts(
contractAbi: FeeJuicePortalAbi,
contractBytecode: FeeJuicePortalBytecode,
},
proofCommitmentEscrow: {
contractAbi: MockProofCommitmentEscrowAbi,
contractBytecode: MockProofCommitmentEscrowBytecode,
},
};
const { getVKTreeRoot } = await import('@aztec/noir-protocol-circuits-types');

Expand Down
22 changes: 19 additions & 3 deletions yarn-project/end-to-end/src/e2e_prover/e2e_prover_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import {
type UltraKeccakHonkProtocolArtifact,
} from '@aztec/bb-prover';
import { compileContract } from '@aztec/ethereum';
import { RollupAbi } from '@aztec/l1-artifacts';
import { Buffer32 } from '@aztec/foundation/buffer';
import { RollupAbi, TestERC20Abi } from '@aztec/l1-artifacts';
import { TokenContract } from '@aztec/noir-contracts.js';
import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node';
import { type PXEService } from '@aztec/pxe';
Expand All @@ -33,7 +34,8 @@ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
// TODO(#7373): Deploy honk solidity verifier
// @ts-expect-error solc-js doesn't publish its types https://github.com/ethereum/solc-js/issues/689
import solc from 'solc';
import { getContract } from 'viem';
import { type Hex, getContract } from 'viem';
import { privateKeyToAddress } from 'viem/accounts';

import { waitRegisteredAccountSynced } from '../benchmarks/utils.js';
import { getACVMConfig } from '../fixtures/get_acvm_config.js';
Expand Down Expand Up @@ -94,7 +96,7 @@ export class FullProverTest {
`full_prover_integration/${testName}`,
dataPath,
{},
{ assumeProvenThrough: undefined },
{ assumeProvenThrough: undefined, useRealProofCommitmentEscrow: true },
);
}

Expand Down Expand Up @@ -258,6 +260,10 @@ export class FullProverTest {

// The simulated prover node (now shutdown) used private key index 2
const proverNodePrivateKey = getPrivateKeyFromIndex(2);
const proverNodeSenderAddress = privateKeyToAddress(new Buffer32(proverNodePrivateKey!).to0xString());

this.logger.verbose(`Funding prover node at ${proverNodeSenderAddress}`);
await this.mintL1ERC20(proverNodeSenderAddress, 100_000_000n);

this.logger.verbose('Starting prover node');
const proverConfig: ProverNodeConfig = {
Expand All @@ -272,6 +278,8 @@ export class FullProverTest {
proverNodePollingIntervalMs: 100,
quoteProviderBasisPointFee: 100,
quoteProviderBondAmount: 1000n,
proverMinimumStakeAmount: 3000n,
proverTargetStakeAmount: 6000n,
};
this.proverNode = await createProverNode(proverConfig, {
aztecNodeTxProvider: this.aztecNode,
Expand All @@ -283,6 +291,14 @@ export class FullProverTest {
return this;
}

private async mintL1ERC20(recipient: Hex, amount: bigint) {
const erc20Address = this.context.deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress;
const client = this.context.deployL1ContractsValues.walletClient;
const erc20 = getContract({ abi: TestERC20Abi, address: erc20Address.toString(), client });
const hash = await erc20.write.mint([recipient, amount]);
await this.context.deployL1ContractsValues.publicClient.waitForTransactionReceipt({ hash });
}

snapshot = <T>(
name: string,
apply: (context: SubsystemsContext) => Promise<T>,
Expand Down
12 changes: 11 additions & 1 deletion yarn-project/end-to-end/src/fixtures/setup_l1_contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import {
FeeJuicePortalBytecode,
InboxAbi,
InboxBytecode,
MockProofCommitmentEscrowAbi,
MockProofCommitmentEscrowBytecode,
OutboxAbi,
OutboxBytecode,
ProofCommitmentEscrowAbi,
ProofCommitmentEscrowBytecode,
RegistryAbi,
RegistryBytecode,
RollupAbi,
Expand All @@ -26,7 +30,7 @@ export const setupL1Contracts = async (
l1RpcUrl: string,
account: HDAccount | PrivateKeyAccount,
logger: DebugLogger,
args: Pick<DeployL1ContractsArgs, 'assumeProvenThrough' | 'initialValidators'>,
args: Pick<DeployL1ContractsArgs, 'assumeProvenThrough' | 'initialValidators' | 'useRealProofCommitmentEscrow'>,
) => {
const l1Artifacts: L1ContractArtifactsForDeployment = {
registry: {
Expand All @@ -53,6 +57,12 @@ export const setupL1Contracts = async (
contractAbi: FeeJuicePortalAbi,
contractBytecode: FeeJuicePortalBytecode,
},
proofCommitmentEscrow: {
contractAbi: args.useRealProofCommitmentEscrow ? ProofCommitmentEscrowAbi : MockProofCommitmentEscrowAbi,
contractBytecode: args.useRealProofCommitmentEscrow
? ProofCommitmentEscrowBytecode
: MockProofCommitmentEscrowBytecode,
},
};

const l1Data = await deployL1Contracts(l1RpcUrl, account, foundry, logger, l1Artifacts, {
Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/fixtures/snapshot_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ export async function createAndSyncProverNode(
proverNodePollingIntervalMs: 200,
quoteProviderBasisPointFee: 100,
quoteProviderBondAmount: 1000n,
proverMinimumStakeAmount: 0n,
proverTargetStakeAmount: 0n,
};
const proverNode = await createProverNode(proverConfig, {
aztecNodeTxProvider: aztecNode,
Expand Down
17 changes: 16 additions & 1 deletion yarn-project/end-to-end/src/fixtures/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ import {
FeeJuicePortalBytecode,
InboxAbi,
InboxBytecode,
MockProofCommitmentEscrowAbi,
MockProofCommitmentEscrowBytecode,
OutboxAbi,
OutboxBytecode,
ProofCommitmentEscrowAbi,
ProofCommitmentEscrowBytecode,
RegistryAbi,
RegistryBytecode,
RollupAbi,
Expand Down Expand Up @@ -113,7 +117,12 @@ export const setupL1Contracts = async (
l1RpcUrl: string,
account: HDAccount | PrivateKeyAccount,
logger: DebugLogger,
args: { salt?: number; initialValidators?: EthAddress[]; assumeProvenThrough?: number } = {
args: {
salt?: number;
initialValidators?: EthAddress[];
assumeProvenThrough?: number;
useRealProofCommitmentEscrow?: boolean;
} = {
assumeProvenThrough: Number.MAX_SAFE_INTEGER,
},
chain: Chain = foundry,
Expand Down Expand Up @@ -143,6 +152,12 @@ export const setupL1Contracts = async (
contractAbi: FeeJuicePortalAbi,
contractBytecode: FeeJuicePortalBytecode,
},
proofCommitmentEscrow: {
contractAbi: args.useRealProofCommitmentEscrow ? ProofCommitmentEscrowAbi : MockProofCommitmentEscrowAbi,
contractBytecode: args.useRealProofCommitmentEscrow
? ProofCommitmentEscrowBytecode
: MockProofCommitmentEscrowBytecode,
},
};

const l1Data = await deployL1Contracts(l1RpcUrl, account, chain, logger, l1Artifacts, {
Expand Down
Loading

0 comments on commit 2025085

Please sign in to comment.