Skip to content

Commit

Permalink
Refactor update beacon set mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
hiletmis committed Aug 9, 2024
1 parent 427a051 commit 5477b44
Showing 1 changed file with 91 additions and 85 deletions.
176 changes: 91 additions & 85 deletions deploy/2_update_beacon_set.ts
Original file line number Diff line number Diff line change
@@ -1,99 +1,105 @@
import { deployments, ethers, network } from 'hardhat';

import { chainsSupportedByDapis } from '../data/chain-support.json';
import type { Api3ServerV1 } from '../src/index';
import { Api3ServerV1__factory } from '../src/index';

type Address = string | `0x${string}`;
type BytesLike = string | Uint8Array;

module.exports = async () => {
const { log } = deployments;
const [deployer] = await ethers.getSigners();
const EXPECTED_DEPLOYER_ADDRESS = ethers.getAddress('0x07b589f06bD0A5324c4E2376d66d2F4F25921DE1');
const airnodeAddress = '0x07b589f06bD0A5324c4E2376d66d2F4F25921DE1' as Address;
const BEACON_SET_BEACON_COUNT = 7;

if (chainsSupportedByDapis.includes(network.name)) {
if (deployer!.address === EXPECTED_DEPLOYER_ADDRESS) {
const Api3ServerV1 = await deployments.get('Api3ServerV1');
const api3ServerV1 = new ethers.Contract(
Api3ServerV1.address,
Api3ServerV1.abi,
deployer
) as unknown as Api3ServerV1;
const airnodeAddress = deployer?.address;
const templateIds = [...Array.from({ length: BEACON_SET_BEACON_COUNT }).keys()].map(
(index) => `0x${(index + 1).toString(16).padStart(64, '0')}`
);
const beaconIds = templateIds.map((templateId) =>
ethers.solidityPackedKeccak256(['address', 'bytes32'], [airnodeAddress, templateId])
);
const beaconSetId = ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32[]'], [beaconIds]));
const dataFeedReadings = await api3ServerV1.multicall.staticCall([
...beaconIds.map((beaconId) => api3ServerV1.interface.encodeFunctionData('dataFeeds', [beaconId])),
api3ServerV1.interface.encodeFunctionData('dataFeeds', [beaconSetId]),
if (!chainsSupportedByDapis.includes(network.name)) {
log(`Skipping Beacon set update for ${network.name}`);
return;
}

const Api3ServerV1 = await deployments.get('Api3ServerV1');
const api3ServerV1 = Api3ServerV1__factory.connect(Api3ServerV1.address, deployer);

const templateIds = [...Array.from({ length: BEACON_SET_BEACON_COUNT }).keys()].map(
(index) => `0x${(index + 1).toString(16).padStart(64, '0')}`
) as BytesLike[];
const beaconIds = templateIds.map((templateId) =>
ethers.solidityPackedKeccak256(['address', 'bytes32'], [airnodeAddress, templateId])
);
const beaconSetId = ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['bytes32[]'], [beaconIds]));
const dataFeedReadings = await api3ServerV1.multicall.staticCall([
...beaconIds.map((beaconId) => api3ServerV1.interface.encodeFunctionData('dataFeeds', [beaconId])),
api3ServerV1.interface.encodeFunctionData('dataFeeds', [beaconSetId]),
]);

const updateMulticallData = [] as BytesLike[];

const updateSignatures = [
'0x3149d2642658ca2bbf08a47bce005ef5edb8d6c084a154638f4acff14bd9dc77110b54243126ed6cea05eaf810d825b5b4d816e0c254f6160ff97abab67919ee1b',
'0x4da679af6915f03bf9c2865cedba81ac141c9ed40952fba7a9f827b3fba0236949d9bf3a3a468eb7a146f95369aed60998d0123afbb6260427d3e9140c8fbeda1b',
'0xb44989a9afb4b0f1a7cc21964c8f3bdfcf42f707823ab40771a473f3d2b8288468a1677d5c509233362ca73ef9e17653216ea72cff163a1a3246428fb02410971b',
'0xbbb946b391ac46ccf0bbd5f549a01cfcb36471525bfd80e8eef8bc62ea5ee1215adb7a4b3aa6a22cc9db3ac44837c765330d7660b1136edd0fdc30ec1a8a48ce1c',
'0x620db08a26b8acba0108a4e6be834aa5aefc8a7304581b2117ed775df40aedbf75ae190d7f000dd152f921df44469690b816834e68eef2bac2ea6daa8e94960b1b',
'0x94f32241043cda7efbb3aeff88e460eb46bce8d6b8df784621cd47a39790f7e80f7aca6567b2e656cdf4fd7277d3fd4522bafbfaeb2c31b6e837dd71af7869931c',
'0x2c25ed17835336f80d1a4705817685069e3d1b93108469e330766ae6921d27262a66ee6318e6aec3d58ce5fcfcd12fa3a528f2a3e042bbda6c9eba7b322099a01c',
];
for (const [ind, templateId] of templateIds.entries()) {
if (dataFeedReadings[ind] === ethers.AbiCoder.defaultAbiCoder().encode(['int224', 'uint32'], [0, 0])) {
const signature = updateSignatures[ind] as BytesLike;
const data = `0x${(ind + 1).toString().padStart(64, '0')}` as BytesLike;
const callData = api3ServerV1.interface.encodeFunctionData('updateBeaconWithSignedData', [
airnodeAddress,
templateId,
ind + 1,
data,
signature,
]);
const updateMulticallData = [];
for (const [ind, templateId] of templateIds.entries()) {
if (dataFeedReadings[ind] === ethers.AbiCoder.defaultAbiCoder().encode(['int224', 'uint32'], [0, 0])) {
updateMulticallData.push(
api3ServerV1.interface.encodeFunctionData('updateBeaconWithSignedData', [
airnodeAddress,
templateId,
ind + 1,
`0x${(ind + 1).toString().padStart(64, '0')}`,
await deployer?.signMessage(
ethers.getBytes(
ethers.solidityPackedKeccak256(
['bytes32', 'uint256', 'bytes'],
[templateId, ind + 1, `0x${(ind + 1).toString().padStart(64, '0')}`]
)
)
),
])
);
}
}
if (
dataFeedReadings[BEACON_SET_BEACON_COUNT] ===
ethers.AbiCoder.defaultAbiCoder().encode(['int224', 'uint32'], [0, 0])
) {
updateMulticallData.push(api3ServerV1.interface.encodeFunctionData('updateBeaconSetWithBeacons', [beaconIds]));
}
if (updateMulticallData.length > 0) {
const transaction = await api3ServerV1.multicall(updateMulticallData);
await transaction.wait();
log('Executed Beacon set update');
} else {
log('Beacon set update already executed');
}
const estimateGasMulticallData = [];
for (const [ind, templateId] of templateIds.entries()) {
estimateGasMulticallData.push(
api3ServerV1.interface.encodeFunctionData('updateBeaconWithSignedData', [
airnodeAddress,
templateId,
ind + 101,
`0x${(ind + 101).toString().padStart(64, '0')}`,
await deployer?.signMessage(
ethers.getBytes(
ethers.solidityPackedKeccak256(
['bytes32', 'uint256', 'bytes'],
[templateId, ind + 101, `0x${(ind + 101).toString().padStart(64, '0')}`]
)
)
),
])
);
}
estimateGasMulticallData.push(
api3ServerV1.interface.encodeFunctionData('updateBeaconSetWithBeacons', [beaconIds])
);
const estimateGasCalldata = api3ServerV1.interface.encodeFunctionData('multicall', [estimateGasMulticallData]);
// log(`Beacon set update estimate gas calldata:\n${estimateGasCalldata}`);
const voidSigner = new ethers.VoidSigner(EXPECTED_DEPLOYER_ADDRESS, ethers.provider);
log(
`Estimated Beacon set update gas cost: ${await voidSigner?.estimateGas({ to: api3ServerV1.getAddress(), data: estimateGasCalldata })}`
);
} else {
log(`Skipping Beacon set update because deployer is not ${EXPECTED_DEPLOYER_ADDRESS}`);
updateMulticallData.push(callData);
}
}

if (
dataFeedReadings[BEACON_SET_BEACON_COUNT] === ethers.AbiCoder.defaultAbiCoder().encode(['int224', 'uint32'], [0, 0])
) {
updateMulticallData.push(api3ServerV1.interface.encodeFunctionData('updateBeaconSetWithBeacons', [beaconIds]));
}
if (updateMulticallData.length > 0) {
const transaction = await api3ServerV1.multicall(updateMulticallData);
await transaction.wait();
log('Executed Beacon set update');
} else {
log('Beacon set update already executed');
}
const estimateGasMulticallData = [] as BytesLike[];

const gasEstimationSignatures = [
'0xc536e13f74384d8cfcfee6a9f96bdc2572208fc71dec8b95cb08f535776237af7adbf9eaf217483c60f5fabfaf601d5d620d37894cc0ed4e6d30a763790bb2ba1c',
'0x414969811706716036ce99f8abbeeedadef376e3d4c83ebcd75f5d60391ff5cb4250e0d70b37acce9fc33d6bdd12816dd6154ab8bf76ef2a5bb9ce667af527f01c',
'0xca9b15bb0e6502c3ee845b207fc3421baaf56a570ef19dc1aadbfa0f2c4773780908bb8fc4b42b0b51b3bde37a115d90049c9a05adf9eab21610b17c7e6308081b',
'0xf6acb06f80e13ebaee53d48759a2790cff8dcbf1505c1c16702b370714b8dda4768bf84e1ffc0b1cca239b47f100870968b22072e4e3037dc5d4e1b9255aae301b',
'0xcf9b9ed2a24cb84077f04b5c668df943171cdede356a9573ac253c2f2fe225392098eeef1c1a8ffd4b8fe118790f78d1c2317fc56ce28c30711d5262523f11a81c',
'0x141e0ac1537e7e82bb6c524ae66978753ea4786995b3cdb8fac32731dabdb5257934ca1a728e7128419dcd8797955c37d20373a3230a64959f63c6d787d305681c',
'0xef3c28334bfbc669cb73135536dd32a0115766376dfa2c6237926da6a81dd4240c67b12c1232e15b0cd1a6fb569d8f85fa608e549b871ccc9aa69e5112b7f10b1c',
];

for (const [ind, templateId] of templateIds.entries()) {
const signature = gasEstimationSignatures[ind] as BytesLike;
const data = `0x${(ind + 101).toString().padStart(64, '0')}` as BytesLike;
const callData = api3ServerV1.interface.encodeFunctionData('updateBeaconWithSignedData', [
airnodeAddress,
templateId,
ind + 101,
data,
signature,
]);
estimateGasMulticallData.push(callData);
}

estimateGasMulticallData.push(api3ServerV1.interface.encodeFunctionData('updateBeaconSetWithBeacons', [beaconIds]));
const estimateGasCalldata = api3ServerV1.interface.encodeFunctionData('multicall', [estimateGasMulticallData]);
// log(`Beacon set update estimate gas calldata:\n${estimateGasCalldata}`);
const voidSigner = new ethers.VoidSigner(airnodeAddress, ethers.provider);
const gasCost = await voidSigner?.estimateGas({ to: api3ServerV1.getAddress(), data: estimateGasCalldata });
log(`Estimated Beacon set update gas cost: ${gasCost}`);
};
module.exports.tags = ['update'];

0 comments on commit 5477b44

Please sign in to comment.