Skip to content

Commit

Permalink
fix(generate): update for chain addition
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxMustermann2 committed Dec 6, 2024
1 parent 5eea872 commit fb61569
Showing 1 changed file with 81 additions and 49 deletions.
130 changes: 81 additions & 49 deletions script/generate.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@

// global constants include the chain information
const clientChainInfo = {
'name': 'Sepolia',
'meta_info': 'Ethereum-testnet known as Sepolia',
'name': 'Holesky',
'meta_info': 'Ethereum-testnet known as Holesky',
'finalization_blocks': 10,
'layer_zero_chain_id': 40161,
'layer_zero_chain_id': 40217,
'address_length': 20,
};
// this must be in the same order as whitelistTokens
const tokenMetaInfos = [
'Exocore Holesky ETH',
'Staked ETH',
'Exocore testnet ETH',
'Lido wrapped staked ETH',
];
// this must be in the same order as whitelistTokens
// they are provided because the symbol may not match what we are using from the price feeder.
// for example, exoETH is not a real token and we are using the price feed for ETH.
// the script will take care of mapping the nstETH asset_id to the ETH asset_id in the oracle
// tokens list.
const tokenNamesForOracle = [
'nstETH', 'ETH', 'wstETH' // not case sensitive
'ETH', 'nstETH' // not case sensitive
]
const nativeChain = {
"name": "Exocore",
Expand Down Expand Up @@ -162,6 +161,7 @@ async function updateGenesisFile() {

const bootstrapped = await myContract.methods.bootstrapped().call();
if (bootstrapped) {
// after bootstrapping, some information is deleted.
throw new Error('The contract has already been bootstrapped.');
}

Expand Down Expand Up @@ -209,19 +209,11 @@ async function updateGenesisFile() {
throw new Error(
'The tokens section is missing from the oracle params.'
);
} else if (genesisJSON.app_state.oracle.params.tokens.length > 1) {
// remove the ETH default token
genesisJSON.app_state.oracle.params.tokens = genesisJSON.app_state.oracle.params.tokens.slice(0, 1);
}
if (!genesisJSON.app_state.oracle.params.token_feeders) {
throw new Error(
'The token_feeders section is missing from the oracle params.'
);
} else if (genesisJSON.app_state.oracle.params.token_feeders.length > 1) {
// remove the ETH default token
genesisJSON.app_state.oracle.params.token_feeders = genesisJSON.app_state.oracle.params.token_feeders.slice(
0, 1
);
}
const supportedTokensCount = await myContract.methods.getWhitelistedTokensCount().call();
if (supportedTokensCount != tokenMetaInfos.length) {
Expand All @@ -237,8 +229,8 @@ async function updateGenesisFile() {
);
}
const decimals = [];
const supportedTokens = [];
const assetIds = [];
const supportedTokens = genesisJSON.app_state.assets.tokens;
const assetIds = genesisJSON.app_state.dogfood.params.asset_ids;
// start with the initial value
const oracleTokens = genesisJSON.app_state.oracle.params.tokens;
const oracleTokenFeeders = genesisJSON.app_state.oracle.params.token_feeders;
Expand All @@ -259,12 +251,12 @@ async function updateGenesisFile() {
staking_total_amount: deposit_amount.toString(),
};

supportedTokens[i] = tokenCleaned;
supportedTokens.push(tokenCleaned);
decimals.push(token.decimals);
assetIds.push(token.tokenAddress.toLowerCase() + clientChainSuffix);
let oracleToken;
const oracleTokenFeeder = {
token_id: (i + 1).toString(), // first is reserved
token_id: oracleTokenFeeders.length.toString(),
rule_id: "1",
start_round_id: "1",
start_base_block: (height + 20).toString(),
Expand Down Expand Up @@ -296,8 +288,19 @@ async function updateGenesisFile() {
decimal: 8,
};
}
oracleTokens.push(oracleToken);
oracleTokenFeeders.push(oracleTokenFeeder);
// check that the same token name exists already. if so, append to it.
let found = false;
for (let j = 0; j < oracleTokens.length; j++) {
if (oracleTokens[j].name == oracleToken.name) {
oracleTokens[j].asset_id += "," + oracleToken.asset_id;
found = true;
break;
}
}
if (!found) {
oracleTokens.push(oracleToken);
oracleTokenFeeders.push(oracleTokenFeeder);
}
if (oracleToken.name.toLowerCase().startsWith('nst')) {
if (hasNst.status) {
throw new Error('Multiple NST tokens found.');
Expand Down Expand Up @@ -341,7 +344,15 @@ async function updateGenesisFile() {
end_block: "0",
});
}
genesisJSON.app_state.oracle.params.token_feeders = oracleTokenFeeders;
genesisJSON.app_state.oracle.params.token_feeders = oracleTokenFeeders.map((feeder) => {
if (feeder.token_id == "0") {
// first position is reserved
return feeder;
}
// update the height for the past ones too
feeder.start_base_block = (height + 20).toString();
return feeder;
});
supportedTokens.sort((a, b) => {
if (a.asset_basic_info.symbol < b.asset_basic_info.symbol) {
return -1;
Expand All @@ -360,7 +371,7 @@ async function updateGenesisFile() {
genesisJSON.app_state.assets.deposits = [];
}
const depositorsCount = await myContract.methods.getDepositorsCount().call();
const deposits = [];
const deposits = genesisJSON.app_state.assets.deposits;
const nativeTokenDepositors = [];
const staker_infos = [];
let slashProportions = [];
Expand Down Expand Up @@ -630,7 +641,7 @@ async function updateGenesisFile() {

// x/assets: assets state of the operators
const validatorCount = await myContract.methods.getValidatorsCount().call();
const operator_assets = [];
const operator_assets = genesisJSON.app_state.assets.operator_assets;
for (let i = 0; i < validatorCount; i++) {
const validatorEthAddress = await myContract.methods.registeredValidators(i).call();
const validatorExoAddress = await myContract.methods.ethToExocoreAddress(validatorEthAddress).call();
Expand Down Expand Up @@ -724,15 +735,21 @@ async function updateGenesisFile() {
if (!genesisJSON.app_state.delegation.associations) {
genesisJSON.app_state.delegation.associations = [];
}
let validators = [];
const operators = [];
const associations = [];
let validators = genesisJSON.app_state.dogfood.val_set.map((validator) => {
return {
public_key: validator.public_key,
// from string to Decimal, these are all already truncated.
power: new Decimal(validator.power),
}
});
const operators = genesisJSON.app_state.operator.operators;
const associations = genesisJSON.app_state.delegation.associations;
const operatorsCount = await myContract.methods.getValidatorsCount().call();
let dogfoodUSDValue = ZERO_DECIMAL;
const operator_records = [];
const opt_states = [];
const avs_usd_values = [];
const operator_usd_values = [];
const operator_records = genesisJSON.app_state.operator.operator_records;
const opt_states = genesisJSON.app_state.operator.opt_states;
const avs_usd_values = genesisJSON.app_state.operator.avs_usd_values;
const operator_usd_values = genesisJSON.app_state.operator.operator_usd_values;
const chain_id_without_revision = getChainIDWithoutPrevision(genesisJSON.chain_id);
const dogfoodAddr = generateAVSAddr(chain_id_without_revision);

Expand Down Expand Up @@ -786,13 +803,13 @@ async function updateGenesisFile() {
// at genesis.
let amount = ZERO_DECIMAL;
let totalAmount = ZERO_DECIMAL;
if (exchangeRates.length != supportedTokens.length) {
if (exchangeRates.length != supportedTokensCount) {
throw new Error(
`The number of exchange rates (${exchangeRates.length})
does not match the number of supported tokens (${supportedTokens.length}).`
does not match the number of supported tokens (${supportedTokensCount}).`
);
}
for (let j = 0; j < supportedTokens.length; j++) {
for (let j = 0; j < supportedTokensCount; j++) {
const tokenAddress =
(await myContract.methods.getWhitelistedTokenAtIndex(j).call()).tokenAddress;
let selfDelegationAmount = new Decimal((await myContract.methods.delegations(
Expand Down Expand Up @@ -911,12 +928,18 @@ async function updateGenesisFile() {
return 0;
});
// avs_usd_values
avs_usd_values.push({
avs_addr: dogfoodAddr,
value: {
amount: dogfoodUSDValue.toFixed(),
},
});
const existingItem = avs_usd_values.find(item => item.avs_addr === dogfoodAddr);
if (existingItem) {
existingItem.value.amount = (new Decimal(existingItem.value.amount).plus(dogfoodUSDValue)).toFixed();
} else {
avs_usd_values.push({
avs_addr: dogfoodAddr,
value: {
amount: dogfoodUSDValue.toFixed(),
},
});
}

// operator_usd_values
operator_usd_values.sort((a, b) => {
if (a.key < b.key) {
Expand Down Expand Up @@ -974,14 +997,14 @@ async function updateGenesisFile() {
genesisJSON.app_state.delegation.associations = associations;

// iterate over all stakers, then all assets, then all operators
const delegation_states = [];
const stakers_by_operator = [];
const delegation_states = genesisJSON.app_state.delegation.delegation_states;
const stakers_by_operator = genesisJSON.app_state.delegation.stakers_by_operator;
const stakerListMap = new Map();
for (let i = 0; i < depositorsCount; i++) {
const staker = await myContract.methods.depositors(i).call();
const stakerId = staker.toLowerCase() + clientChainSuffix;

for (let j = 0; j < supportedTokens.length; j++) {
for (let j = 0; j < supportedTokensCount; j++) {
const tokenAddress =
(await myContract.methods.getWhitelistedTokenAtIndex(j).call()).tokenAddress;
const assetId = tokenAddress.toLowerCase() + clientChainSuffix;
Expand Down Expand Up @@ -1075,13 +1098,22 @@ async function updateGenesisFile() {
}];

// add the native chain and at the end so that count-related issues don't arise.
genesisJSON.app_state.assets.client_chains.push(nativeChain);
genesisJSON.app_state.assets.tokens.push(nativeAsset);
// TODO: copy the staking data over from the previous genesis, if any.
genesisJSON.app_state.dogfood.params.asset_ids.push(
nativeAsset.asset_basic_info.address.toLowerCase() + '_0x' +
nativeAsset.asset_basic_info.layer_zero_chain_id.toString(16)
);
// but first, check that it doesn't already exist.
let nativeChainExists = false;
for (let i = 0; i < genesisJSON.app_state.assets.client_chains.length; i++) {
if (genesisJSON.app_state.assets.client_chains[i].chain_id == clientChainInfo.chain_id) {
nativeChainExists = true;
break;
}
}
if (!nativeChainExists) {
genesisJSON.app_state.assets.client_chains.push(nativeChain);
genesisJSON.app_state.assets.tokens.push(nativeAsset);
genesisJSON.app_state.dogfood.params.asset_ids.push(
nativeAsset.asset_basic_info.address.toLowerCase() + '_0x' +
nativeAsset.asset_basic_info.layer_zero_chain_id.toString(16)
);
}

await fs.writeFile(
INTEGRATION_RESULT_GENESIS_FILE_PATH,
Expand Down

0 comments on commit fb61569

Please sign in to comment.