Skip to content

Commit

Permalink
implement getValidatorRounds for consensus contract
Browse files Browse the repository at this point in the history
  • Loading branch information
oXtxNt9U committed Oct 30, 2024
1 parent 718ef1c commit 151bc37
Show file tree
Hide file tree
Showing 5 changed files with 728 additions and 118 deletions.
26 changes: 26 additions & 0 deletions contracts/src/consensus/Consensus.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ struct VoteResult {
address validator;
}

struct ValidatorRoundValidator {
address validatorAddress;
uint256 voteBalance;
}

struct ValidatorRound {
uint256 round;
ValidatorRoundValidator[] validators;
}

event ValidatorRegistered(address addr, bytes bls12_381_public_key);

event ValidatorResigned(address addr);
Expand Down Expand Up @@ -72,6 +82,8 @@ contract Consensus {
uint256 private _topValidatorsCount = 0;
address[] private _calculatedTopValidators;

ValidatorRound[] private _validatorRounds;

constructor() {
_owner = msg.sender;
}
Expand Down Expand Up @@ -148,6 +160,8 @@ contract Consensus {
}
}

// TODO: update _validatorRounds

address next = _topValidatorsHead;
delete _calculatedTopValidators;
_calculatedTopValidators = new address[](top);
Expand Down Expand Up @@ -399,6 +413,18 @@ contract Consensus {
}
}

// TODO: allow passing limit to cap maximum number of returned items in case validator count is very high.
// the caller can paginate to retrieve all items.
function getValidatorRounds() public view onlyOwner returns (ValidatorRound[] memory) {
ValidatorRound[] memory result = new ValidatorRound[](_validatorRounds.length);
for (uint256 i = 0; i < _validatorRounds.length; i++) {
ValidatorRound storage data = _validatorRounds[i];
result[i] = data;
}

return result;
}

function _updateVoter(address addr) private {
Vote storage voter = _voters[addr];
if (voter.validator == address(0)) {
Expand Down
21 changes: 21 additions & 0 deletions contracts/test/consensus/Consensus-ValidatorRounds.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GNU GENERAL PUBLIC LICENSE
pragma solidity ^0.8.13;

import {Test, console} from "@forge-std/Test.sol";
import {Consensus, ValidatorRound, ValidatorRoundValidator} from "@contracts/consensus/Consensus.sol";

contract ConsensusTest is Test {
Consensus public consensus;

function setUp() public {
consensus = new Consensus();
}

function test_getValidatorRounds() public view {
ValidatorRound[] memory validatorRounds = new ValidatorRound[](0);

validatorRounds = consensus.getValidatorRounds();

assertEq(validatorRounds.length, 0);
}
}
12 changes: 12 additions & 0 deletions packages/contracts/source/contracts/evm/contract-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,21 @@ export interface Vote {
voterAddress: string;
}

export interface ValidatorRoundValidator {
readonly voteBalance: bigint;
readonly address: string;
}

export interface ValidatorRound {
readonly round: number;
readonly roundHeight: number;
readonly validators: ValidatorRoundValidator[];
}

export interface ConsensusContractService {
getActiveValidators(): Promise<ValidatorWallet[]>;
getAllValidators(): Promise<ValidatorWallet[]>;
getVotesCount(): Promise<number>;
getVotes(): AsyncIterable<Vote>;
getValidatorRounds(): Promise<ValidatorRound[]>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,48 @@ export class ConsensusContractService implements Contracts.Evm.ConsensusContract
return validatorWallets;
}

async getValidatorRounds(): Promise<Contracts.Evm.ValidatorRound[]> {
const consensusContractAddress = this.app.get<string>(EvmConsensusIdentifiers.Contracts.Addresses.Consensus);
const deployerAddress = this.app.get<string>(EvmConsensusIdentifiers.Internal.Addresses.Deployer);
const { evmSpec } = this.configuration.getMilestone();

const iface = new ethers.Interface(ConsensusAbi.abi);
const data = iface.encodeFunctionData("getValidatorRounds").slice(2);

const result = await this.evm.view({
caller: deployerAddress,
data: Buffer.from(data, "hex"),
recipient: consensusContractAddress,
specId: evmSpec,
});

if (!result.success) {
await this.app.terminate("getValidatorRounds failed");
}

const [results] = iface.decodeFunctionResult("getValidatorRounds", result.output!);

const validatorRounds: Contracts.Evm.ValidatorRound[] = [];
for (const [, validatorRound] of results.entries()) {
const [round, [validators]] = validatorRound;

validatorRounds.push({
round,
roundHeight: round, // TODO
validators: validators.map((validator) => {
const [validatorAddress, voteBalance] = validator;

return {
address: validatorAddress,
voteBalance,
};
}),
});
}

return validatorRounds;
}

async getVotesCount(): Promise<number> {
const consensusContractAddress = this.app.get<string>(EvmConsensusIdentifiers.Contracts.Addresses.Consensus);
const deployerAddress = this.app.get<string>(EvmConsensusIdentifiers.Internal.Addresses.Deployer);
Expand Down
Loading

0 comments on commit 151bc37

Please sign in to comment.