Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LICENSE
CODE_OF_CONDUCT.md

packages/p2p/source/socket-server/codecs/proto/protos.*
packages/core/bin/config

/.nx/cache
/.nx/workspace-data
Expand Down
11 changes: 8 additions & 3 deletions contracts/src/consensus/BLSPoP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@ library BLSPoP {
error InvalidInputLength();
error PrecompileCallFailed();

function verify(bytes calldata compressedPubkeyG1, bytes calldata compressedProofG2) internal view returns (bool) {
function verify(address registrantAddress, bytes calldata compressedPubkeyG1, bytes calldata compressedProofG2)
internal
view
returns (bool)
{
if (compressedPubkeyG1.length != 48) {
revert InvalidInputLength();
}
if (compressedProofG2.length != 96) {
revert InvalidInputLength();
}

bytes memory input = bytes.concat(compressedPubkeyG1, compressedProofG2);
bytes memory input =
bytes.concat(bytes32(block.chainid), bytes20(registrantAddress), compressedPubkeyG1, compressedProofG2);

(bool ok, bytes memory out) = POP_VERIFY.staticcall(input);
if (!ok || out.length != 32) {
revert PrecompileCallFailed();
}

return uint256(bytes32(out)) == 1;
return abi.decode(out, (uint256)) == 1;
}
}
4 changes: 2 additions & 2 deletions contracts/src/consensus/ConsensusV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ contract ConsensusV1 is UUPSUpgradeable, OwnableUpgradeable {
revert ValidatorAlreadyRegistered();
}

if (!BLSPoP.verify(blsPublicKey, proofOfPossession)) {
if (!BLSPoP.verify(msg.sender, blsPublicKey, proofOfPossession)) {
revert InvalidProofOfPossession();
}

Expand All @@ -232,7 +232,7 @@ contract ConsensusV1 is UUPSUpgradeable, OwnableUpgradeable {
revert ValidatorNotRegistered();
}

if (!BLSPoP.verify(blsPublicKey, proofOfPossession)) {
if (!BLSPoP.verify(msg.sender, blsPublicKey, proofOfPossession)) {
revert InvalidProofOfPossession();
}

Expand Down
15 changes: 15 additions & 0 deletions contracts/test/consensus/Consensus-ValidatoUpdate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ import {Base} from "./Base.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract ConsensusTest is Base {
function test_validator_update_binds_pop_to_chain_and_sender() public {
bytes memory pop = createValidPop();
address addr = address(1);
bytes memory newBlsKey = prepareBLSKey(address(2));

vm.startPrank(addr);
consensus.registerValidator(prepareBLSKey(addr), pop);

vm.chainId(10000);
vm.expectCall(BLS_POP_PRECOMPILE, abi.encodePacked(uint256(10000), addr, newBlsKey, pop));

consensus.updateValidator(newBlsKey, pop);
vm.stopPrank();
}

function test_updateBlsPublicKey_should_pass() public {
bytes memory pop = createValidPop();

Expand Down
12 changes: 12 additions & 0 deletions contracts/test/consensus/Consensus-ValidatorRegistration.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ import {Base} from "./Base.sol";
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

contract ConsensusTest is Base {
function test_validator_registration_binds_pop_to_chain_and_sender() public {
bytes memory pop = createValidPop();
address addr = address(1);
bytes memory blsKey = prepareBLSKey(addr);

vm.chainId(10000);
vm.expectCall(BLS_POP_PRECOMPILE, abi.encodePacked(uint256(10000), addr, blsKey, pop));

vm.prank(addr);
consensus.registerValidator(blsKey, pop);
}

function test_validator_registration_pass_with_default_fee() public {
bytes memory pop = createValidPop();

Expand Down
2 changes: 1 addition & 1 deletion contracts/test/consensus/MockBlsPopVerify.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pragma solidity ^0.8.13;
contract MockBlsPopVerify {
fallback(bytes calldata input) external returns (bytes memory) {
// Real precompile halts on bad length; we revert so tests can detect it.
if (input.length != 48 + 96) {
if (input.length != 32 + 20 + 48 + 96) {
assembly { revert(0, 0) }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,10 @@ describe<{
// would, so the generator itself never needs the validator secrets.
const presignRegistration = async (app: Application, wallet: Wallet): Promise<string> => {
const consensusContract = app.get<string>(AppIdentifiers.EvmConsensus.Contracts.Consensus);
const { pop } = buildProofOfPossession(Buffer.from(wallet.consensusKeys.privateKey, "hex"));
const { pop } = buildProofOfPossession(Buffer.from(wallet.consensusKeys.privateKey, "hex"), {
chainId: 123,
registrantAddress: wallet.address,
});

const registration = await (
await app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ export class GenesisBlockGenerator {
const result: Contracts.Crypto.Transaction[] = [];

for (const [index, sender] of senders.entries()) {
const { pop } = buildProofOfPossession(Buffer.from(sender.consensusKeys.privateKey, "hex"));
const { pop } = buildProofOfPossession(Buffer.from(sender.consensusKeys.privateKey, "hex"), {
chainId,
registrantAddress: sender.address,
});
const data = encodeFunctionData({
abi: ConsensusAbi.abi,
args: [`0x${sender.consensusKeys.publicKey}`, bytesToHex(pop)],
Expand Down
Loading
Loading