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
10 changes: 9 additions & 1 deletion contracts/src/consensus/ConsensusV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,15 @@ contract ConsensusV1 is UUPSUpgradeable, OwnableUpgradeable {
emit ValidatorRegistered(addr, blsPublicKey);
}

function addVote(address voter, address validator) external onlyOwner {
function addVotes(address[] calldata voters, address[] calldata validators) external onlyOwner {
require(voters.length == validators.length, "input length mismatch");

for (uint256 i = 0; i < voters.length; i++) {
_addVote(voters[i], validators[i]);
}
}

function _addVote(address voter, address validator) internal {
if (_rounds.length > 0) {
revert ImportIsNotAllowed();
}
Expand Down
84 changes: 69 additions & 15 deletions contracts/test/consensus/Consensus-VoteAdd.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ contract ConsensusTest is Base {
// Vote
vm.expectEmit(address(consensus));
emit ConsensusV1.Voted(voterAddr, addr);
consensus.addVote(voterAddr, addr);
address[] memory voters = new address[](1);
voters[0] = voterAddr;
address[] memory validators = new address[](1);
validators[0] = addr;

consensus.addVotes(voters, validators);

// Assert validator
ConsensusV1.Validator memory validator = consensus.getValidator(addr);
Expand Down Expand Up @@ -60,7 +65,11 @@ contract ConsensusTest is Base {
// Vote
vm.expectEmit(address(consensus));
emit ConsensusV1.Voted(voterAddr, addr);
consensus.addVote(voterAddr, addr);
address[] memory voters = new address[](1);
voters[0] = voterAddr;
address[] memory validators = new address[](1);
validators[0] = addr;
consensus.addVotes(voters, validators);

// Assert validator
ConsensusV1.Validator memory validator = consensus.getValidator(addr);
Expand Down Expand Up @@ -95,7 +104,11 @@ contract ConsensusTest is Base {
// Vote
vm.expectEmit(address(consensus));
emit ConsensusV1.Voted(voterAddr, addr);
consensus.addVote(voterAddr, addr);
address[] memory voters = new address[](1);
voters[0] = voterAddr;
address[] memory validators = new address[](1);
validators[0] = addr;
consensus.addVotes(voters, validators);

// Assert validator
ConsensusV1.Validator memory validator = consensus.getValidator(addr);
Expand All @@ -115,19 +128,30 @@ contract ConsensusTest is Base {

function test_add_vote_revert_if_caller_is_not_owner() public {
address addr = address(1);
address[] memory voters = new address[](1);
voters[0] = addr;
address[] memory validators = new address[](1);
validators[0] = addr;

vm.startPrank(addr);
vm.expectRevert(abi.encodeWithSelector(OwnableUpgradeable.OwnableUnauthorizedAccount.selector, addr));
consensus.addVote(addr, addr);
consensus.addVotes(voters, validators);
}

function test_add_vote_revert_if_round_already_calculated() public {
address addr = address(1);
address[] memory voters = new address[](1);
voters[0] = addr;
address[] memory validators = new address[](1);
validators[0] = addr;

consensus.addValidator(addr, prepareBLSKey(addr), false);

consensus.calculateActiveValidators(1);

vm.expectRevert(ConsensusV1.ImportIsNotAllowed.selector);
consensus.addVote(addr, addr);

consensus.addVotes(voters, validators);
}

function test_add_vote_allow_self_vote() public {
Expand All @@ -147,7 +171,12 @@ contract ConsensusTest is Base {
// Vote
vm.expectEmit(address(consensus));
emit ConsensusV1.Voted(voterAddr, addr);
consensus.addVote(voterAddr, addr);

address[] memory voters = new address[](1);
voters[0] = voterAddr;
address[] memory validators = new address[](1);
validators[0] = addr;
consensus.addVotes(voters, validators);
vm.stopPrank();

// Assert voteBalance
Expand All @@ -173,19 +202,30 @@ contract ConsensusTest is Base {
// Prepare voter
address voterAddr = address(2);

address[] memory voters = new address[](1);
voters[0] = voterAddr;
address[] memory validators = new address[](1);
validators[0] = addr;

vm.expectEmit(address(consensus));
emit ConsensusV1.Voted(voterAddr, addr);
consensus.addVote(voterAddr, addr);

consensus.addVotes(voters, validators);

vm.expectRevert(ConsensusV1.AlreadyVoted.selector);
consensus.addVote(voterAddr, addr);
consensus.addVotes(voters, validators);
}

function test_add_vote_prevent_vote_for_unregistered_validator() public {
address addr = address(1);

address[] memory voters = new address[](1);
voters[0] = addr;
address[] memory validators = new address[](1);
validators[0] = addr;

vm.expectRevert(ConsensusV1.ValidatorNotRegistered.selector);
consensus.addVote(addr, addr);
consensus.addVotes(voters, validators);
}

function test_multiple_voted_different_validators() public {
Expand All @@ -205,17 +245,24 @@ contract ConsensusTest is Base {
// Vote 1
address voterAddr1 = address(11);
vm.deal(voterAddr1, 100 ether);
consensus.addVote(voterAddr1, validatorAddr1);

// Vote 2
address voterAddr2 = address(12);
vm.deal(voterAddr2, 100 ether);
consensus.addVote(voterAddr2, validatorAddr2);

// Vote 3
address voterAddr3 = address(13);
vm.deal(voterAddr3, 100 ether);
consensus.addVote(voterAddr3, validatorAddr3);

address[] memory voters = new address[](3);
voters[0] = voterAddr1;
voters[1] = voterAddr2;
voters[2] = voterAddr3;
address[] memory validators = new address[](3);
validators[0] = validatorAddr1;
validators[1] = validatorAddr2;
validators[2] = validatorAddr3;
consensus.addVotes(voters, validators);

// Assert validators 1
ConsensusV1.Validator memory validator1 = consensus.getValidator(validatorAddr1);
Expand Down Expand Up @@ -258,17 +305,24 @@ contract ConsensusTest is Base {
// Vote 1
address voterAddr1 = address(11);
vm.deal(voterAddr1, 100 ether);
consensus.addVote(voterAddr1, validatorAddr1);

// Vote 2
address voterAddr2 = address(12);
vm.deal(voterAddr2, 100 ether);
consensus.addVote(voterAddr2, validatorAddr1);

// Vote 3
address voterAddr3 = address(13);
vm.deal(voterAddr3, 100 ether);
consensus.addVote(voterAddr3, validatorAddr1);

address[] memory voters = new address[](3);
voters[0] = voterAddr1;
voters[1] = voterAddr2;
voters[2] = voterAddr3;
address[] memory validators = new address[](3);
validators[0] = validatorAddr1;
validators[1] = validatorAddr1;
validators[2] = validatorAddr1;
consensus.addVotes(voters, validators);

// Assert validators 1
ConsensusV1.Validator memory validator1 = consensus.getValidator(validatorAddr1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { readFileSync } from "node:fs";

import { Container } from "@mainsail/container";
import { Contracts, Identifiers } from "@mainsail/contracts";
import { ServiceProvider as CoreCryptoAddressBase58 } from "@mainsail/crypto-address-base58";
Expand All @@ -20,6 +22,7 @@ import { Application, Providers } from "@mainsail/kernel";
import { ServiceProvider as CoreSerializer } from "@mainsail/serializer";
import { ServiceProvider as CoreSnapshotLegacyImporter } from "@mainsail/snapshot-legacy-importer";
import { ServiceProvider as CoreValidation } from "@mainsail/validation";
import { readJSONSync } from "fs-extra/esm";
import { dirSync, setGracefulCleanup } from "tmp";

import { ConfigurationGenerator } from "./configuration-generator.js";
Expand Down Expand Up @@ -50,10 +53,10 @@ export const makeApplication = async (configurationPath: string, options: Record
warning: (message: string) => console.log(message),
});
// Used for evm instance
const fsExtra = await import("fs-extra/esm");
app.bind(Identifiers.Services.Filesystem.Service).toConstantValue({
existsSync: () => true,
readJSONSync: (file: string, options?: Record<string, any>) => fsExtra.readJSONSync(file, options),
get: (path: string) => readFileSync(path),
readJSONSync: (file: string, options?: Record<string, any>) => readJSONSync(file, options),
});
setGracefulCleanup();
app.rebind("path.data").toConstantValue(dirSync().name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@
}

ensureDirSync(join(this.configurationPath, "snapshot"));
this.configurationWriter.writeSnapshot(options.snapshot.path, options.snapshot.snapshotHash);
this.configurationWriter.writeSnapshot(options.snapshot.path);

Check warning on line 215 in packages/configuration-generator/source/configuration-generator.ts

View check run for this annotation

Codecov / codecov/patch

packages/configuration-generator/source/configuration-generator.ts#L215

Added line #L215 was not covered by tests
},
title: `Writing snapshot.json in core config path.`,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
);
}

writeSnapshot(snapshotPath: string, snapshotHash: string): void {
writeSnapshot(snapshotPath: string): void {
snapshotPath = resolve(snapshotPath);
copyFileSync(snapshotPath, path.join(this.configurationPath, "snapshot", `${snapshotHash}.json`));
copyFileSync(snapshotPath, path.join(this.configurationPath, "snapshot", path.basename(snapshotPath)));

Check warning on line 74 in packages/configuration-generator/source/configuration-writer.ts

View check run for this annotation

Codecov / codecov/patch

packages/configuration-generator/source/configuration-writer.ts#L74

Added line #L74 was not covered by tests
}
}
4 changes: 2 additions & 2 deletions packages/contracts/source/contracts/evm/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
initializeGenesis(commit: GenesisInfo): Promise<void>;
getAccountInfo(address: string, height?: bigint): Promise<AccountInfo>;
getAccountInfoExtended(address: string, legacyAddress?: string): Promise<AccountInfoExtended>;
importAccountInfo(info: AccountInfoExtended): Promise<void>;
importLegacyColdWallet(wallet: ImportLegacyColdWallet): Promise<void>;
importAccountInfos(infos: AccountInfoExtended[]): Promise<void>;
importLegacyColdWallets(wallets: ImportLegacyColdWallet[]): Promise<void>;

Check warning on line 33 in packages/contracts/source/contracts/evm/instance.ts

View check run for this annotation

Codecov / codecov/patch

packages/contracts/source/contracts/evm/instance.ts#L32-L33

Added lines #L32 - L33 were not covered by tests
getAccounts(offset: bigint, limit: bigint): Promise<GetAccountsResult>;
getLegacyAttributes(address: string, legacyAddress?: string): Promise<LegacyAttributes | null>;
getLegacyColdWallets(offset: bigint, limit: bigint): Promise<GetLegacyColdWalletsResult>;
Expand Down
52 changes: 26 additions & 26 deletions packages/evm-contracts/source/abis/ConsensusV1.json

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions packages/evm-service/source/instances/evm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,13 @@ describe<{

// Import legacy cold wallet with 10n balance
await instance.prepareNextCommit({ commitKey });
await instance.importLegacyColdWallet({
address: legacyAddress,
balance: 10n,
legacyAttributes: {},
});
await instance.importLegacyColdWallets([
{
address: legacyAddress,
balance: 10n,
legacyAttributes: {},
},
]);
await commit(commitKey);

assert.undefined((await instance.getLegacyColdWallets(0n, 100n)).wallets[0].mergeInfo);
Expand Down Expand Up @@ -358,11 +360,13 @@ describe<{
} as any);

await instance.prepareNextCommit({ commitKey });
await instance.importLegacyColdWallet({
address: legacyAddress,
balance: 999n,
legacyAttributes: {},
});
await instance.importLegacyColdWallets([
{
address: legacyAddress,
balance: 999n,
legacyAttributes: {},
},
]);
await commit(commitKey);

let { wallets } = await instance.getLegacyColdWallets(0n, 100n);
Expand Down
8 changes: 4 additions & 4 deletions packages/evm-service/source/instances/evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@
return this.#evm.getAccountInfoExtended(address, legacyAddress);
}

public async importAccountInfo(info: Contracts.Evm.AccountInfoExtended): Promise<void> {
return this.#evm.importAccountInfo(info);
public async importAccountInfos(infos: Contracts.Evm.AccountInfoExtended[]): Promise<void> {
return this.#evm.importAccountInfos(infos);

Check warning on line 112 in packages/evm-service/source/instances/evm.ts

View check run for this annotation

Codecov / codecov/patch

packages/evm-service/source/instances/evm.ts#L112

Added line #L112 was not covered by tests
}

public async importLegacyColdWallet(wallet: Contracts.Evm.ImportLegacyColdWallet): Promise<void> {
return this.#evm.importLegacyColdWallet({ ...wallet, mergeInfo: undefined });
public async importLegacyColdWallets(wallets: Contracts.Evm.ImportLegacyColdWallet[]): Promise<void> {
return this.#evm.importLegacyColdWallets(wallets);
}

public async getAccounts(offset: bigint, limit: bigint): Promise<Contracts.Evm.GetAccountsResult> {
Expand Down
Loading
Loading