Aere Network public source. Everything here can be checked against the live chain (chain id 2800, https://rpc.aere.network). Scope note, stated up front rather than buried: consensus on chain 2800 is classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at the signature, precompile, account and transport layers. Nothing here makes the consensus post-quantum, and no document in it should be read as claiming so.
81 lines
2.9 KiB
Solidity
81 lines
2.9 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.23;
|
|
|
|
import "../AereStateRootAnchor.sol";
|
|
|
|
/**
|
|
* @dev Test-only subclass that lets a test inject a canonical block hash for a
|
|
* given block number. This is used to exercise the FULL anchor logic
|
|
* (keccak match + RLP state-root decode + record) against a REAL AERE
|
|
* canonical block (the genesis block) whose hash is outside the live
|
|
* 256-block BLOCKHASH window. Production always uses the real BLOCKHASH
|
|
* opcode via the un-overridden AereStateRootAnchor._blockHashOf.
|
|
*/
|
|
contract MockBlockhashAnchor is AereStateRootAnchor {
|
|
mapping(uint256 => bytes32) public injected;
|
|
|
|
constructor(address verifier) AereStateRootAnchor(verifier) {}
|
|
|
|
function setBlockHash(uint256 blockNumber, bytes32 h) external {
|
|
injected[blockNumber] = h;
|
|
}
|
|
|
|
function _blockHashOf(uint256 blockNumber) internal view override returns (bytes32) {
|
|
return injected[blockNumber];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @dev Faithful stand-in for the LIVE AereStorageProofVerifier's two entry
|
|
* points used by the anchor. It decodes the SAME 192-byte public-values
|
|
* convention and enforces the SAME expected-root check, so the
|
|
* proveAgainstAnchor end-to-end path is exercised exactly as it would be
|
|
* against the real verifier (whose SP1 pairing check we do not re-run in a
|
|
* unit test). `shouldValidate=false` simulates an invalid SP1 proof.
|
|
*/
|
|
contract MockStorageProofVerifier is IAereStorageProofVerifier {
|
|
bool public shouldValidate = true;
|
|
|
|
/// @notice keccak256(publicValues) => recorded, for assertions.
|
|
mapping(bytes32 => bool) public recorded;
|
|
|
|
function setValidate(bool v) external {
|
|
shouldValidate = v;
|
|
}
|
|
|
|
function verify(bytes calldata publicValues, bytes calldata /*proof*/)
|
|
external
|
|
view
|
|
returns (
|
|
uint256 blockNumber,
|
|
bytes32 stateRoot,
|
|
address account,
|
|
bytes32 slot,
|
|
bytes32 value
|
|
)
|
|
{
|
|
require(shouldValidate, "InvalidProof");
|
|
require(publicValues.length == 192, "BadPublicValuesLength");
|
|
(, blockNumber, stateRoot, account, slot, value) = abi.decode(
|
|
publicValues,
|
|
(uint256, uint256, bytes32, address, bytes32, bytes32)
|
|
);
|
|
}
|
|
|
|
function submitProofWithExpectedRoot(
|
|
bytes calldata publicValues,
|
|
bytes calldata /*proof*/,
|
|
bytes32 expectedStateRoot
|
|
) external returns (bytes32 value) {
|
|
require(shouldValidate, "InvalidProof");
|
|
require(publicValues.length == 192, "BadPublicValuesLength");
|
|
(, , bytes32 stateRoot, , , bytes32 v) = abi.decode(
|
|
publicValues,
|
|
(uint256, uint256, bytes32, address, bytes32, bytes32)
|
|
);
|
|
require(stateRoot == expectedStateRoot, "StateRootMismatch");
|
|
recorded[keccak256(publicValues)] = true;
|
|
return v;
|
|
}
|
|
}
|