Skip to content
Open
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
46 changes: 44 additions & 2 deletions common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export interface ContractConfig {
lastUploadedCodeId?: number;
}

export interface InstantiatedContractConfig extends ContractConfig {
address: string;
}

export interface ContractsChainInfo {
address: string;
codeId: number;
Expand Down Expand Up @@ -125,6 +129,8 @@ export interface GatewayChainConfig {
address?: string;
}

const AMPLIFIER_PROTOCOL_CONTRACTS = ['ServiceRegistry', 'Router', 'Coordinator', 'Multisig', 'Rewards'] as const;

export class ConfigManager implements FullConfig {
private environment: string;

Expand All @@ -146,6 +152,7 @@ export class ConfigManager implements FullConfig {
this.chains = fullConfig.chains;

this.validateConfig();
this.validateAmplifierProtocolContracts();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should be part of the validateConfig. Note that currently we print warnings instead of errors, since axelarate devnet setup workflow does not produce a full valid config. The validation methods gathers all the errors and then produce a report instead

}

private validateConfig(): void {
Expand Down Expand Up @@ -333,6 +340,21 @@ export class ConfigManager implements FullConfig {
printWarn('');
}

private validateAmplifierProtocolContracts(): void {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, this method should be used as a part of validateConfig. It should return errors that are relevant to its validation checks

const missing: string[] = [];

for (const contractName of AMPLIFIER_PROTOCOL_CONTRACTS) {
const config = this.getContractConfig(contractName);
if (!config.address) {
missing.push(contractName);
}
}

if (missing.length > 0) {
throw new Error(`Amplifier Protocol contracts missing addresses in ${this.environment} config: ${missing.join(', ')}.`);
}
}

private isValidGasPrice(price: string): boolean {
const numericOnlyPattern = /^\d+$/;
const withDenominationPattern = /^\d+(\.\d+)?[a-zA-Z]+$/;
Expand Down Expand Up @@ -424,6 +446,27 @@ export class ConfigManager implements FullConfig {
return contractConfig[chainName];
}

public getContractAddress(name: string): string {
const config = this.getContractConfig(name);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const config = this.getContractConfig(name);
const config = this.getInstantiatedContractConfig(name);

To be really certain about the address presence

return config.address!;
}

public getInstantiatedContractConfig(name: string): InstantiatedContractConfig {
const config = this.getContractConfig(name);
if (!config.address) {
throw new Error(`Contract '${name}' has not been instantiated`);
}
Comment on lines +456 to +458

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the existing validation method, also used in this file

return config as InstantiatedContractConfig;
}

public getInstantiatedContractByChain(name: string, chainName: string): InstantiatedContractConfig {
const config = this.getContractConfigByChain(name, chainName);
if (!config.address) {
throw new Error(`Contract '${name}' for chain '${chainName}' has not been instantiated`);
}
Comment on lines +464 to +466

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use the existing validation method, also used in this file

return config as InstantiatedContractConfig;
}

public validateRequired<T>(value: T | undefined | null, configPath: string, type?: string): T {
if (value === undefined || value === null || (typeof value === 'string' && value.trim() === '')) {
throw new Error(`Missing required configuration for the chain. Please configure it in ${configPath}.`);
Expand Down Expand Up @@ -535,8 +578,7 @@ export class ConfigManager implements FullConfig {

public getChainCodecAddress(chainType: string): string {
const chainCodec = this.getChainCodecContractForChainType(chainType);
const chainCodecConfig = this.getContractConfig(chainCodec);
return this.validateRequired(chainCodecConfig.address, `${chainCodec}.address`);
return this.getInstantiatedContractConfig(chainCodec).address;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return this.getInstantiatedContractConfig(chainCodec).address;
return this.getContractAddress(chainCodec);

}

public getVotingVerifierContract(chainName: string): VotingVerifierChainConfig {
Expand Down
25 changes: 12 additions & 13 deletions cosmwasm/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ const executeContractMessage = async (
throw new Error('At least one message is required');
}

const contractAddress = config.validateRequired(config.getContractConfig(contractName).address, `${contractName}.address`);
const contractAddress = config.getInstantiatedContractConfig(contractName).address;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const contractAddress = config.getInstantiatedContractConfig(contractName).address;
const contractAddress = config.getContractAddress(contractName);


if (options.governance) {
validateGovernanceMode(config, contractName, chainName);
Expand Down Expand Up @@ -138,9 +138,9 @@ const registerProtocol = async (
_args?: string[],
fee?: string | StdFee,
): Promise<void> => {
const serviceRegistry = config.validateRequired(config.getContractConfig('ServiceRegistry').address, 'ServiceRegistry.address');
const router = config.validateRequired(config.getContractConfig('Router').address, 'Router.address');
const multisig = config.validateRequired(config.getContractConfig('Multisig').address, 'Multisig.address');
const serviceRegistry = config.getContractAddress('ServiceRegistry');
const router = config.getContractAddress('Router');
const multisig = config.getContractAddress('Multisig');

const msg = [
{
Expand Down Expand Up @@ -186,11 +186,10 @@ const createRewardPools = async (

const threshold: string[] = config.parseThreshold(participationThreshold, '--participationThreshold');

const votingVerifierAddress = config.validateRequired(
config.getVotingVerifierContract(chainName).address,
`VotingVerifier[${chainName}].address`,
);
const multisigAddress = config.validateRequired(config.getContractConfig('Multisig').address, 'Multisig.address');
const chainConfig = config.getChainConfig(chainName);
const verifierContractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);
const votingVerifierAddress = config.getInstantiatedContractByChain(verifierContractName, chainName).address;
const multisigAddress = config.getContractAddress('Multisig');

const messages = [
{
Expand Down Expand Up @@ -245,7 +244,7 @@ const routerFreezeChain = async (
throw new Error('Router freeze_chain can only be executed by Admin EOA, not via governance');
}

const contractAddress = config.validateRequired(config.getContractConfig('Router').address, 'Router.address');
const contractAddress = config.getContractAddress('Router');
printDirectExecutionInfo(msg, contractAddress);
return executeDirectly(client, contractAddress, msg, fee);
};
Expand All @@ -265,7 +264,7 @@ const routerUnfreezeChain = async (
throw new Error('Router unfreeze_chain can only be executed by Admin EOA, not via governance');
}

const contractAddress = config.validateRequired(config.getContractConfig('Router').address, 'Router.address');
const contractAddress = config.getContractAddress('Router');
printDirectExecutionInfo(msg, contractAddress);
return executeDirectly(client, contractAddress, msg, fee);
};
Expand All @@ -283,7 +282,7 @@ const routerDisableRouting = async (
throw new Error('Router disable_routing can only be executed by Admin EOA, not via governance');
}

const contractAddress = config.validateRequired(config.getContractConfig('Router').address, 'Router.address');
const contractAddress = config.getContractAddress('Router');
printDirectExecutionInfo(msg, contractAddress);
return executeDirectly(client, contractAddress, msg, fee);
};
Expand All @@ -301,7 +300,7 @@ const routerEnableRouting = async (
throw new Error('Router enable_routing can only be executed by Admin EOA, not via governance');
}

const contractAddress = config.validateRequired(config.getContractConfig('Router').address, 'Router.address');
const contractAddress = config.getContractAddress('Router');
printDirectExecutionInfo(msg, contractAddress);
return executeDirectly(client, contractAddress, msg, fee);
};
Expand Down
9 changes: 3 additions & 6 deletions cosmwasm/coordinator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,7 @@ export class CoordinatorManager {
public constructExecuteMessage(chainName: string, salt: string, admin: string): InstantiateChainContractsMsg {
try {
const chainConfig = this.configManager.getChainConfig(chainName);
const rewardsConfig = this.configManager.getContractConfig('Rewards');
const multisigConfig = this.configManager.getContractConfig('Multisig');
const routerConfig = this.configManager.getContractConfig('Router');
const multisigAddress = this.configManager.validateRequired(multisigConfig.address, `Multisig.address`);
const multisigAddress = this.configManager.getContractAddress('Multisig');

const proverContractName = this.configManager.getMultisigProverContractForChainType(chainConfig.chainType);
const verifierContractName = this.configManager.getVotingVerifierContractForChainType(chainConfig.chainType);
Expand All @@ -97,8 +94,8 @@ export class CoordinatorManager {
`${proverContractName}.${chainName}.codeId`,
);
const deploymentName = this.generateDeploymentName(chainName, `${gatewayCodeId}-${verifierCodeId}-${proverCodeId}`);
const rewardsAddress = this.configManager.validateRequired(rewardsConfig.address, `Rewards.address`);
const routerAddress = this.configManager.validateRequired(routerConfig.address, `Router.address`);
const rewardsAddress = this.configManager.getContractAddress('Rewards');
const routerAddress = this.configManager.getContractAddress('Router');
const domainSeparator = calculateDomainSeparator(chainName, routerAddress, this.configManager.axelar.chainId);
if (!isKeccak256Hash(domainSeparator)) {
throw new Error(`Invalid ${proverContractName}[${chainName}].domainSeparator in axelar info`);
Expand Down
16 changes: 8 additions & 8 deletions cosmwasm/migrate/chain-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,16 @@ async function migrate(client: ClientManager, config: ConfigManager, options: Mi
}

// migration data for MultisigProver contract
const multisigProver = config.getMultisigProverContract(chainName);
const multisigProverAddress = config.validateRequired(multisigProver.address, `MultisigProver[${chainName}].address`);
const proverConfig = config.getContractConfig('MultisigProver');
const proverCodeId = config.validateRequired(proverConfig.lastUploadedCodeId, `MultisigProver.lastUploadedCodeId`);
const proverContractName = config.getMultisigProverContractForChainType(chainConfig.chainType);
const multisigProverAddress = config.getInstantiatedContractByChain(proverContractName, chainName).address;
const proverConfig = config.getContractConfig(proverContractName);
const proverCodeId = config.validateRequired(proverConfig.lastUploadedCodeId, `${proverContractName}.lastUploadedCodeId`);

// migration data for VotingVerifier contract
const votingVerifier = config.getVotingVerifierContract(chainName);
const votingVerifierAddress = config.validateRequired(votingVerifier.address, `VotingVerifier[${chainName}].address`);
const verifierConfig = config.getContractConfig('VotingVerifier');
const verifierCodeId = config.validateRequired(verifierConfig.lastUploadedCodeId, `VotingVerifier.lastUploadedCodeId`);
const verifierContractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);
const votingVerifierAddress = config.getInstantiatedContractByChain(verifierContractName, chainName).address;
const verifierConfig = config.getContractConfig(verifierContractName);
const verifierCodeId = config.validateRequired(verifierConfig.lastUploadedCodeId, `${verifierContractName}.lastUploadedCodeId`);

migrations.push({
proverAddress: multisigProverAddress,
Expand Down
20 changes: 9 additions & 11 deletions cosmwasm/migrate/sdk50.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ async function migrateAllVotingVerifiers(
const votingVerifiers: Array<{ chainName: string; address: string; contractName: string }> = [];

for (const { name: chainName, config: chainConfig } of chains) {
const votingVerifierConfig = config.getVotingVerifierContract(chainName);
const contractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);
config.validateRequired(votingVerifierConfig.address, 'votingVerifierConfig.address');
const address = config.getInstantiatedContractByChain(contractName, chainName).address;

votingVerifiers.push({
chainName,
address: votingVerifierConfig.address,
address,
contractName,
});
printInfo(`Added ${chainName} voting verifier (address: ${votingVerifierConfig.address})`);
printInfo(`Added ${chainName} voting verifier (address: ${address})`);
}

printInfo(`Found ${votingVerifiers.length} voting verifier(s) to migrate`);
Expand Down Expand Up @@ -80,9 +79,10 @@ async function updateBlockTimeRelatedParameters(
chains.map(async ({ name: chainName, config: chainConfig }) => {
try {
const votingVerifierConfig = config.getVotingVerifierContract(chainName);
config.validateRequired(votingVerifierConfig.address, 'votingVerifierConfig.address');
const contractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);
const address = config.getInstantiatedContractByChain(contractName, chainName).address;
Comment on lines +82 to +83

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: This change complicates that part, maybe leave the way it was


const { block_expiry } = await client.queryContractSmart(votingVerifierConfig.address, 'voting_parameters');
const { block_expiry } = await client.queryContractSmart(address, 'voting_parameters');

const message = {
update_voting_parameters: {
Expand All @@ -99,12 +99,10 @@ async function updateBlockTimeRelatedParameters(
`Current voting parameters for ${chainName}: block_expiry: ${block_expiry}. New proposed block_expiry: ${message.update_voting_parameters.block_expiry}`,
);

const contractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);

return {
chainName,
contractName,
address: votingVerifierConfig.address,
address,
message,
};
} catch (error) {
Expand Down Expand Up @@ -147,10 +145,10 @@ async function updateSigningParametersForMultisig(
fee: string | StdFee,
): Promise<void> {
const multisigConfig = config.getContractConfig('Multisig');
config.validateRequired(multisigConfig.address, 'axelar.contracts.Multisig.address', 'string');
const multisigAddress = config.getContractAddress('Multisig');
config.validateRequired(multisigConfig.blockExpiry, 'axelar.contracts.Multisig.blockExpiry', 'number');

const { block_expiry } = await client.queryContractSmart(multisigConfig.address, 'signing_parameters');
const { block_expiry } = await client.queryContractSmart(multisigAddress, 'signing_parameters');
printInfo(`Current signing parameters: block_expiry: ${block_expiry}. New proposed block_expiry: ${multisigConfig.blockExpiry}`);

const msg = {
Expand Down
6 changes: 2 additions & 4 deletions cosmwasm/migrate/update-rewards-pool-epoch-duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ interface UpdatePoolParamsMessage {

async function queryAllRewardsPools(client: CosmWasmClient, configManager: ConfigManager): Promise<PoolParams[]> {
const poolParams: PoolParams[] = [];
const rewardsConfig = configManager.getContractConfig('Rewards');
const rewardsAddress = configManager.validateRequired(rewardsConfig.address, 'Rewards.address');
const rewardsAddress = configManager.getContractAddress('Rewards');

const amplifierChains = getAmplifierChains(configManager.chains);

if (amplifierChains.length === 0) {
throw new Error('No amplifier chains found');
}

const multisigConfig = configManager.getContractConfig('Multisig');
const multisigAddress = configManager.validateRequired(multisigConfig.address, 'Multisig.address');
const multisigAddress = configManager.getContractAddress('Multisig');

for (const { name: chainName } of amplifierChains) {
const chainPools: PoolParams[] = [];
Expand Down
9 changes: 5 additions & 4 deletions cosmwasm/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,14 @@ export async function queryRewardsPool(

async function rewards(client, config, _options, args) {
const [chainName] = args;
const rewardsAddress = config.getContractConfig('Rewards').address;
const rewardsAddress = config.getContractAddress('Rewards');

const votingVerifier = config.getVotingVerifierContract(chainName);
const votingVerifierAddress = config.validateRequired(votingVerifier.address, `VotingVerifier.${chainName}.address`);
const chainConfig = config.getChainConfig(chainName);
const verifierContractName = config.getVotingVerifierContractForChainType(chainConfig.chainType);
const votingVerifierAddress = config.getInstantiatedContractByChain(verifierContractName, chainName).address;

const rewardsContractAddresses = {
multisig: config.getContractConfig('Multisig').address,
multisig: config.getContractAddress('Multisig'),
voting_verifier: votingVerifierAddress,
};

Expand Down
4 changes: 1 addition & 3 deletions cosmwasm/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -915,9 +915,7 @@ const itsHubChainParams = (config, chainConfig) => {

const key = chainConfig.axelarId.toLowerCase();
const chainParams = config.axelar.contracts.InterchainTokenService[key];
const itsMsgTranslator =
chainParams?.msgTranslator ||
config.validateRequired(config.getContractConfig('ItsAbiTranslator').address, 'ItsAbiTranslator.address');
const itsMsgTranslator = chainParams?.msgTranslator || config.getInstantiatedContractConfig('ItsAbiTranslator').address;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const itsMsgTranslator = chainParams?.msgTranslator || config.getInstantiatedContractConfig('ItsAbiTranslator').address;
const itsMsgTranslator = chainParams?.msgTranslator || config.getContractAddress('ItsAbiTranslator');


return {
itsEdgeContractAddress,
Expand Down