Skip to content

Commit

Permalink
Merge branch 'master' into sync-noir
Browse files Browse the repository at this point in the history
* master:
  chore: fix sync scripts (#9423)
  feat: ownable sysstia (#9398)
  feat: `bytes_to_fields` requiring only 1 generic param (#9417)
  feat: implement encryption to an address point and decryption from an address secret (#9272)
  git subrepo push --branch=master noir-projects/aztec-nr
  git_subrepo.sh: Fix parent in .gitrepo file. [skip ci]
  chore: replace relative paths to noir-protocol-circuits
  git subrepo push --branch=master barretenberg
  test: node follow prune and extend chain (#9328)
  feat: initial block reward + external libraries (#9297)
  feat: Print finalized size and log dyadic size during Ultra proof construction (#9411)
  feat: fee pricing to 0 for old instances (#9296)
  fix: allow more resources for 4epochs tests (#9418)
  • Loading branch information
TomAFrench committed Oct 25, 2024
2 parents 9829968 + 7766c8e commit 626530e
Show file tree
Hide file tree
Showing 79 changed files with 1,263 additions and 378 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ jobs:
needs: [build, configure]
runs-on: ${{ needs.configure.outputs.username }}-x86
strategy:
max-parallel: 1
fail-fast: false
matrix:
test: [test-transfer.sh, test-4epochs.sh]
Expand Down Expand Up @@ -659,7 +660,7 @@ jobs:
env:
USERNAME: ${{ needs.configure.outputs.username }}
with:
runner_type: 8core-tester-x86
runner_type: 16core-tester-x86
spot_strategy: None # use on-demand machines
builder_type: builder-x86
# these are copied to the tester and expected by the earthly command below
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/.gitrepo
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[subrepo]
remote = https://github.com/AztecProtocol/barretenberg
branch = master
commit = 54bcb59eeabbbaaa0e2ddc2b6c7c40502e1145a1
parent = cb58490eed9cc46a7b2039d93645a9456ee9c834
commit = e1ff295392d634bacb0945db77ffc15589ed3578
parent = a653fd3a11b47862b5f6cac646296bff3d2ac8f4
method = merge
cmdver = 0.4.6
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {

circuit.finalize_circuit(/* ensure_nonzero = */ true);

info("Finalized circuit size: ", circuit.num_gates);

// If using a structured trace, set fixed block sizes, check their validity, and set the dyadic circuit size
if (is_structured) {
circuit.blocks.set_fixed_block_sizes(trace_structure); // set the fixed sizes for each block
Expand All @@ -65,6 +67,8 @@ template <IsHonkFlavor Flavor> class DeciderProvingKey_ {
dyadic_circuit_size = compute_dyadic_size(circuit); // set dyadic size directly from circuit block sizes
}

info("Log dyadic circuit size: ", numeric::get_msb(dyadic_circuit_size));

// Complete the public inputs execution trace block from circuit.public_inputs
Trace::populate_public_inputs_block(circuit);
circuit.blocks.compute_offsets(is_structured);
Expand Down
56 changes: 33 additions & 23 deletions l1-contracts/src/core/FeeJuicePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,24 @@ import {Errors} from "@aztec/core/libraries/Errors.sol";
import {Hash} from "@aztec/core/libraries/crypto/Hash.sol";
import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol";

import {Ownable} from "@oz/access/Ownable.sol";

contract FeeJuicePortal is IFeeJuicePortal, Ownable {
contract FeeJuicePortal is IFeeJuicePortal {
using SafeERC20 for IERC20;

IRegistry public registry;
IERC20 public underlying;
bytes32 public l2TokenAddress;
IRegistry public immutable REGISTRY;
IERC20 public immutable UNDERLYING;
bytes32 public immutable L2_TOKEN_ADDRESS;

constructor(address _owner, address _registry, address _underlying, bytes32 _l2TokenAddress)
Ownable(_owner)
{
bool public initialized;

constructor(address _registry, address _underlying, bytes32 _l2TokenAddress) {
require(
_registry != address(0) && _underlying != address(0) && _l2TokenAddress != 0,
Errors.FeeJuicePortal__InvalidInitialization()
);

registry = IRegistry(_registry);
underlying = IERC20(_underlying);
l2TokenAddress = _l2TokenAddress;
REGISTRY = IRegistry(_registry);
UNDERLYING = IERC20(_underlying);
L2_TOKEN_ADDRESS = _l2TokenAddress;
}

/**
Expand All @@ -44,16 +42,16 @@ contract FeeJuicePortal is IFeeJuicePortal, Ownable {
* @dev Must be funded with FEE_JUICE_INITIAL_MINT tokens before initialization to
* ensure that the L2 contract is funded and able to pay for its deployment.
*/
function initialize() external override(IFeeJuicePortal) onlyOwner {
require(owner() != address(0), Errors.FeeJuicePortal__AlreadyInitialized());
function initialize() external override(IFeeJuicePortal) {
require(!initialized, Errors.FeeJuicePortal__AlreadyInitialized());

uint256 balance = underlying.balanceOf(address(this));
uint256 balance = UNDERLYING.balanceOf(address(this));
if (balance < Constants.FEE_JUICE_INITIAL_MINT) {
underlying.safeTransferFrom(
UNDERLYING.safeTransferFrom(
msg.sender, address(this), Constants.FEE_JUICE_INITIAL_MINT - balance
);
}
_transferOwnership(address(0));
initialized = true;
}

/**
Expand All @@ -69,18 +67,24 @@ contract FeeJuicePortal is IFeeJuicePortal, Ownable {
returns (bytes32)
{
// Preamble
IInbox inbox = IRollup(registry.getRollup()).INBOX();
DataStructures.L2Actor memory actor = DataStructures.L2Actor(l2TokenAddress, 1);
address rollup = canonicalRollup();
uint256 version = REGISTRY.getVersionFor(rollup);
IInbox inbox = IRollup(rollup).INBOX();
DataStructures.L2Actor memory actor = DataStructures.L2Actor(L2_TOKEN_ADDRESS, version);

// Hash the message content to be reconstructed in the receiving contract
bytes32 contentHash =
Hash.sha256ToField(abi.encodeWithSignature("claim(bytes32,uint256)", _to, _amount));

// Hold the tokens in the portal
underlying.safeTransferFrom(msg.sender, address(this), _amount);
UNDERLYING.safeTransferFrom(msg.sender, address(this), _amount);

// Send message to rollup
return inbox.sendL2Message(actor, contentHash, _secretHash);
bytes32 key = inbox.sendL2Message(actor, contentHash, _secretHash);

emit DepositToAztecPublic(_to, _amount, _secretHash, key);

return key;
}

/**
Expand All @@ -94,7 +98,13 @@ contract FeeJuicePortal is IFeeJuicePortal, Ownable {
* @param _amount - The amount to pay them
*/
function distributeFees(address _to, uint256 _amount) external override(IFeeJuicePortal) {
require(msg.sender == registry.getRollup(), Errors.FeeJuicePortal__Unauthorized());
underlying.safeTransfer(_to, _amount);
require(msg.sender == canonicalRollup(), Errors.FeeJuicePortal__Unauthorized());
UNDERLYING.safeTransfer(_to, _amount);

emit FeesDistributed(_to, _amount);
}

function canonicalRollup() public view returns (address) {
return REGISTRY.getRollup();
}
}
86 changes: 75 additions & 11 deletions l1-contracts/src/core/Rollup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
pragma solidity >=0.8.27;

import {EIP712} from "@oz/utils/cryptography/EIP712.sol";
import {ECDSA} from "@oz/utils/cryptography/ECDSA.sol";

import {IProofCommitmentEscrow} from "@aztec/core/interfaces/IProofCommitmentEscrow.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 {IRollup, ITestRollup} from "@aztec/core/interfaces/IRollup.sol";
import {IVerifier} from "@aztec/core/interfaces/IVerifier.sol";
import {ISysstia} from "@aztec/governance/interfaces/ISysstia.sol";
import {IERC20} from "@oz/token/ERC20/IERC20.sol";

import {Constants} from "@aztec/core/libraries/ConstantsGen.sol";
import {DataStructures} from "@aztec/core/libraries/DataStructures.sol";
Expand All @@ -21,6 +22,8 @@ import {TxsDecoder} from "@aztec/core/libraries/TxsDecoder.sol";
import {MerkleLib} from "@aztec/core/libraries/crypto/MerkleLib.sol";
import {SignatureLib} from "@aztec/core/libraries/crypto/SignatureLib.sol";
import {SafeCast} from "@oz/utils/math/SafeCast.sol";
import {Math} from "@oz/utils/math/Math.sol";
import {SafeERC20} from "@oz/token/ERC20/utils/SafeERC20.sol";

import {Inbox} from "@aztec/core/messagebridge/Inbox.sol";
import {Leonidas} from "@aztec/core/Leonidas.sol";
Expand All @@ -40,6 +43,7 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
using SafeCast for uint256;
using SlotLib for Slot;
using EpochLib for Epoch;
using SafeERC20 for IERC20;

struct ChainTips {
uint256 pendingBlockNumber;
Expand All @@ -64,6 +68,8 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
IProofCommitmentEscrow public immutable PROOF_COMMITMENT_ESCROW;
uint256 public immutable VERSION;
IFeeJuicePortal public immutable FEE_JUICE_PORTAL;
ISysstia public immutable SYSSTIA;
IERC20 public immutable ASSET;
IVerifier public epochProofVerifier;

ChainTips public tips;
Expand All @@ -85,14 +91,17 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {

constructor(
IFeeJuicePortal _fpcJuicePortal,
ISysstia _sysstia,
bytes32 _vkTreeRoot,
bytes32 _protocolContractTreeRoot,
address _ares,
address[] memory _validators
) Leonidas(_ares) {
epochProofVerifier = new MockVerifier();
FEE_JUICE_PORTAL = _fpcJuicePortal;
PROOF_COMMITMENT_ESCROW = new ProofCommitmentEscrow(_fpcJuicePortal.underlying(), address(this));
SYSSTIA = _sysstia;
ASSET = _fpcJuicePortal.UNDERLYING();
PROOF_COMMITMENT_ESCROW = new ProofCommitmentEscrow(ASSET, address(this));
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 Expand Up @@ -260,15 +269,53 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {

tips.provenBlockNumber = endBlockNumber;

for (uint256 i = 0; i < Constants.AZTEC_EPOCH_DURATION; i++) {
address coinbase = address(uint160(uint256(publicInputs[9 + i * 2])));
uint256 fees = uint256(publicInputs[10 + i * 2]);
// @note Only if the rollup is the canonical will it be able to meaningfully claim fees
// Otherwise, the fees are unbacked #7938.
bool isFeeCanonical = address(this) == FEE_JUICE_PORTAL.canonicalRollup();
bool isSysstiaCanonical = address(this) == SYSSTIA.canonicalRollup();

uint256 totalProverReward = 0;

if (isFeeCanonical || isSysstiaCanonical) {
for (uint256 i = 0; i < _epochSize; i++) {
address coinbase = address(uint160(uint256(publicInputs[9 + i * 2])));
uint256 reward = 0;
uint256 toProver = 0;

if (isFeeCanonical) {
uint256 fees = uint256(publicInputs[10 + i * 2]);
if (fees > 0) {
reward += fees;
FEE_JUICE_PORTAL.distributeFees(address(this), fees);
}
}

if (isSysstiaCanonical) {
reward += SYSSTIA.claim(address(this));
}

if (coinbase == address(0)) {
toProver = reward;
} else {
// @note We are getting value from the `proofClaim`, which are not cleared.
// So if someone is posting the proof before a new claim is made,
// the reward will calculated based on the previous values.
toProver = Math.mulDiv(reward, proofClaim.basisPointFee, 10_000);
}

uint256 toCoinbase = reward - toProver;
if (toCoinbase > 0) {
ASSET.safeTransfer(coinbase, toCoinbase);
}

totalProverReward += toProver;
}

if (coinbase != address(0) && fees > 0) {
// @note This will currently fail if there are insufficient funds in the bridge
// which WILL happen for the old version after an upgrade where the bridge follow.
// Consider allowing a failure. See #7938.
FEE_JUICE_PORTAL.distributeFees(coinbase, fees);
if (totalProverReward > 0) {
// If there is a bond-provider give him the reward, otherwise give it to the submitter.
address proofRewardRecipient =
proofClaim.bondProvider == address(0) ? msg.sender : proofClaim.bondProvider;
ASSET.safeTransfer(proofRewardRecipient, totalProverReward);
}
}

Expand Down Expand Up @@ -481,12 +528,18 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
if (blockNumber <= assumeProvenThroughBlockNumber) {
fakeBlockNumberAsProven(blockNumber);

if (header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
bool isFeeCanonical = address(this) == FEE_JUICE_PORTAL.canonicalRollup();
bool isSysstiaCanonical = address(this) == SYSSTIA.canonicalRollup();

if (isFeeCanonical && header.globalVariables.coinbase != address(0) && header.totalFees > 0) {
// @note This will currently fail if there are insufficient funds in the bridge
// which WILL happen for the old version after an upgrade where the bridge follow.
// Consider allowing a failure. See #7938.
FEE_JUICE_PORTAL.distributeFees(header.globalVariables.coinbase, header.totalFees);
}
if (isSysstiaCanonical && header.globalVariables.coinbase != address(0)) {
SYSSTIA.claim(header.globalVariables.coinbase);
}

emit L2ProofVerified(blockNumber, "CHEAT");
}
Expand Down Expand Up @@ -642,6 +695,11 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
address currentProposer = getCurrentProposer();
Epoch epochToProve = getEpochToProve();

require(
_quote.quote.basisPointFee <= 10_000,
Errors.Rollup__InvalidBasisPointFee(_quote.quote.basisPointFee)
);

require(
currentProposer == address(0) || currentProposer == msg.sender,
Errors.Leonidas__InvalidProposer(currentProposer, msg.sender)
Expand Down Expand Up @@ -921,5 +979,11 @@ contract Rollup is EIP712("Aztec Rollup", "1"), Leonidas, IRollup, ITestRollup {
_flags.ignoreDA || _header.contentCommitment.txsEffectsHash == _txsEffectsHash,
Errors.Rollup__UnavailableTxs(_header.contentCommitment.txsEffectsHash)
);

// If not canonical rollup, require that the fees are zero
if (address(this) != FEE_JUICE_PORTAL.canonicalRollup()) {
require(_header.globalVariables.gasFees.feePerDaGas == 0, Errors.Rollup__NonZeroDaFee());
require(_header.globalVariables.gasFees.feePerL2Gas == 0, Errors.Rollup__NonZeroL2Fee());
}
}
}
10 changes: 9 additions & 1 deletion l1-contracts/src/core/interfaces/IFeeJuicePortal.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
pragma solidity >=0.8.27;

import {IERC20} from "@oz/token/ERC20/IERC20.sol";
import {IRegistry} from "@aztec/governance/interfaces/IRegistry.sol";

interface IFeeJuicePortal {
event DepositToAztecPublic(bytes32 indexed to, uint256 amount, bytes32 secretHash, bytes32 key);
event FeesDistributed(address indexed to, uint256 amount);

function initialize() external;
function distributeFees(address _to, uint256 _amount) external;
function depositToAztecPublic(bytes32 _to, uint256 _amount, bytes32 _secretHash)
external
returns (bytes32);
function underlying() external view returns (IERC20);
function canonicalRollup() external view returns (address);

function UNDERLYING() external view returns (IERC20);
function L2_TOKEN_ADDRESS() external view returns (bytes32);
function REGISTRY() external view returns (IRegistry);
}
3 changes: 3 additions & 0 deletions l1-contracts/src/core/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ library Errors {
error Rollup__TimestampTooOld(); // 0x72ed9c81
error Rollup__TryingToProveNonExistingBlock(); // 0x34ef4954
error Rollup__UnavailableTxs(bytes32 txsHash); // 0x414906c3
error Rollup__NonZeroDaFee(); // 0xd9c75f52
error Rollup__NonZeroL2Fee(); // 0x7e728abc
error Rollup__InvalidBasisPointFee(uint256 basisPointFee); // 0x4292d136

//TxsDecoder
error TxsDecoder__InvalidLogsLength(uint256 expected, uint256 actual); // 0x829ca981
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/src/core/libraries/TxsDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ library TxsDecoder {
* @param _body - The L2 block body calldata.
* @return The txs effects hash.
*/
function decode(bytes calldata _body) internal pure returns (bytes32) {
function decode(bytes calldata _body) external pure returns (bytes32) {
ArrayOffsets memory offsets;
Counts memory counts;
ConsumablesVars memory vars;
Expand Down
Loading

0 comments on commit 626530e

Please sign in to comment.