sdk/js: added vaa repair script to utils (#1935)
* sdk/js: Added repairVaa & test * fixed unnecessary comments * Separated rpc call from base repairVaa function. removed console logs and added throws * removed unncessary else statement * removed unnecessary async * Skipping rpc call test for current guardian set * Clean up minor formatting
This commit is contained in:
parent
effde7f756
commit
1406d29ff6
|
@ -0,0 +1,82 @@
|
|||
import { expect, test } from "@jest/globals";
|
||||
import { ethers } from "ethers";
|
||||
import { repairVaa, repairVaaWithCurrentGuardianSet } from "./repairVaa";
|
||||
|
||||
const guardianSetData = {
|
||||
index: 2,
|
||||
keys: [
|
||||
"0x58CC3AE5C097b213cE3c81979e1B9f9570746AA5",
|
||||
"0xfF6CB952589BDE862c25Ef4392132fb9D4A42157",
|
||||
"0x114De8460193bdf3A2fCf81f86a09765F4762fD1",
|
||||
"0x107A0086b32d7A0977926A205131d8731D39cbEB",
|
||||
"0x8C82B2fd82FaeD2711d59AF0F2499D16e726f6b2",
|
||||
"0x11b39756C042441BE6D8650b69b54EbE715E2343",
|
||||
"0x54Ce5B4D348fb74B958e8966e2ec3dBd4958a7cd",
|
||||
"0x66B9590e1c41e0B226937bf9217D1d67Fd4E91F5",
|
||||
"0x74a3bf913953D695260D88BC1aA25A4eeE363ef0",
|
||||
"0x000aC0076727b35FBea2dAc28fEE5cCB0fEA768e",
|
||||
"0xAF45Ced136b9D9e24903464AE889F5C8a723FC14",
|
||||
"0xf93124b7c738843CBB89E864c862c38cddCccF95",
|
||||
"0xD2CC37A4dc036a8D232b48f62cDD4731412f4890",
|
||||
"0xDA798F6896A3331F64b48c12D1D57Fd9cbe70811",
|
||||
"0x71AA1BE1D36CaFE3867910F99C09e347899C19C3",
|
||||
"0x8192b6E7387CCd768277c17DAb1b7a5027c0b3Cf",
|
||||
"0x178e21ad2E77AE06711549CFBB1f9c7a9d8096e8",
|
||||
"0x5E1487F35515d02A92753504a8D75471b9f49EdB",
|
||||
"0x6FbEBc898F403E4773E95feB15E80C9A99c8348d",
|
||||
],
|
||||
expiry: 0,
|
||||
};
|
||||
|
||||
test("vaa has enough signatures to repair", () => {
|
||||
// has 14 signatures, Signature at index #1 has been altered
|
||||
const vaa =
|
||||
"01000000010e00489871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000181123e985106659001cd9edb9e5db954443fc532e4cabf4f1c3b215e2a935cbd123ce1ee267618d685dc7c4379892327d0fddb729eb1e0f0611f825bfe871b68010295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000";
|
||||
const repairedVaa = repairVaa(vaa, guardianSetData);
|
||||
expect(repairedVaa).toBe(
|
||||
"01000000020d00489871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000"
|
||||
);
|
||||
});
|
||||
|
||||
test("vaa does not have enough signatures to repair", () => {
|
||||
// has 13 signatures. Signature at index #0 has been altered
|
||||
const vaa =
|
||||
"01000000010d00249871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000";
|
||||
expect(() => {
|
||||
repairVaa(vaa, guardianSetData);
|
||||
}).toThrow("There are not enough valid signatures to repair.");
|
||||
});
|
||||
|
||||
test("number of vaa signatures does not match parse signatures", () => {
|
||||
// Attempting to parse vaa with fake # of signatures. error thrown by parseVaa function
|
||||
const vaa =
|
||||
"01000000011100249871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000";
|
||||
expect(() => {
|
||||
repairVaa(vaa, guardianSetData);
|
||||
}).toThrow("Attempt to access memory outside buffer bounds");
|
||||
});
|
||||
|
||||
test.skip("Use current guardian set", async () => {
|
||||
const rpcUrl = "https://rpc.ankr.com/eth";
|
||||
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
|
||||
// Grab current guardian set and successfully repair.
|
||||
const vaa =
|
||||
"01000000010e00489871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000181123e985106659001cd9edb9e5db954443fc532e4cabf4f1c3b215e2a935cbd123ce1ee267618d685dc7c4379892327d0fddb729eb1e0f0611f825bfe871b68010295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
const repairedVaa = await repairVaaWithCurrentGuardianSet(vaa, provider);
|
||||
expect(repairedVaa).toBe(
|
||||
"01000000020d00489871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000"
|
||||
);
|
||||
});
|
||||
|
||||
test.skip("Grab current guardian set with bad rpc", async () => {
|
||||
const rpcUrl = "https://rkc.ankr.com/eth";
|
||||
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
|
||||
// Try to grab current guardian set with bad rpc. Should throw error
|
||||
const vaa =
|
||||
"01000000010e00489871e73fc73a19ed47d9d6c39551b1b2e92f5fc76546b4c2d790845563b3aa6b413553d633fb2ede0b6491d6b8b55738bb89a648e01077eb29ad452bc32de6000181123e985106659001cd9edb9e5db954443fc532e4cabf4f1c3b215e2a935cbd123ce1ee267618d685dc7c4379892327d0fddb729eb1e0f0611f825bfe871b68010295f8bfb0394d23826fecba81f73af18278dac42b665efb148e0a8b380532f2403a6e776851d6f4d2c0f6ae61f8efa699c856802f707a64b4f9e320f4483017cc0003397afeaba4e9c064fd99c79caac2bff7c9c147cde9286b26b242afe0367bd9fe227b345ad0f7d51cbcfd63b5d8593ce65918bfe8c1794b6316869638fc73cf530104df5411869d2e7c5de5de5f1e199db371ac40e7e8adb00cc8a2ed999fe2d02b75278fe8442306203206ec45efdffa5208fe70a3eeaa8125b4fb435aac103037860106106e85c3fcb8ebf231e176e8854f9b04a6ae777cbbbda3f0f1bcd1e08cecc9da420c4af21145972d7d538e28cdd957dfe6ff048d6a403393ed5ca44dd9f1180b000730c77ea4586080203329cda5b74022f1f53bc56fad600cb89f73c75457fd963271d9ff0425b7cdff2e013598a58ac413163b0e878bf01979104d67d9a4e85e0a010948f3dd5a01023936384410fd31c3e58c6b808dfe0826b7eb6af695884d20e95e47bbe093af574ed2640cfe32b6171a7957cede3bbf9d8e5374547f49ca00cbc8010c1b194773d701095798252c356ee224e8ba188b8f8d09975687efc3b376b2cf496e07c267c6b54f2ce98cc262c4c3bc28229ff1e257afe7d78cc9569a660eb04c000d61e3e135c605ba4b3d39b178f0dfc0db6497291b29c97afed6f6feedcd7fbe052795861e4ef05f7d715f313c4cafca443ad1ca69d61aecde7b1aee9e3cf520f2000e617900cb13db3eb68bdbbc159bcced7a064cdbcc7253d10a1a6ea5cd6f5d9fa87b2b1f7d474180da2534db5f478607ad3c82d0b7cc30734f3a480e77a80d13e6010fb84790f4637d4f78612f7b734daa1a085fc21ebcca4f89279a26a12e8836c6a7437342392a034dda85d3a0330f425207132df39d49688a05e0f316d8cc4c721e0010c77c0979a9034a129ed211e5c720a1df2d024cc7d45ae174f779127a089900142b144b5ce6513d19df1e1528d574a528300c06229abb1ec50fc58c0fac7dc7400012090fcaf1f83cee46756e3a9c370fe2a6c7c421bc7cfa5920c044d36b6c2130204e819edd895249c2686d3330565c583f53b89cfdc4275fd56baa570bb442fc4701637431d7a33b000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000001685e010100000000000000000000000000000000000000000000000000000001d5a977820000000000000000000000001f9840a85d5af5bf1d1762f925bdaddc4201f984000200000000000000000000000027ec3715bc5e419df98689bd301c17661c73c2c300040000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
await expect(
|
||||
repairVaaWithCurrentGuardianSet(vaa, provider)
|
||||
).rejects.toThrow();
|
||||
});
|
|
@ -0,0 +1,115 @@
|
|||
import { ethers } from "ethers";
|
||||
import { CONTRACTS } from "./consts";
|
||||
import { Implementation__factory } from "../ethers-contracts";
|
||||
import { parseVaa, GuardianSignature } from "../vaa";
|
||||
import { hexToUint8Array } from "./array";
|
||||
import { keccak256 } from "../utils";
|
||||
|
||||
const ETHEREUM_CORE_BRIDGE = CONTRACTS["MAINNET"].ethereum.core;
|
||||
|
||||
function hex(x: string): string {
|
||||
return ethers.utils.hexlify(x, { allowMissingPrefix: true });
|
||||
}
|
||||
interface GuardianSetData {
|
||||
index: number;
|
||||
keys: string[];
|
||||
expiry: number;
|
||||
}
|
||||
|
||||
export async function getCurrentGuardianSet(
|
||||
provider: ethers.providers.JsonRpcProvider
|
||||
): Promise<GuardianSetData> {
|
||||
let result: GuardianSetData = {
|
||||
index: 0,
|
||||
keys: [],
|
||||
expiry: 0,
|
||||
};
|
||||
const core = Implementation__factory.connect(ETHEREUM_CORE_BRIDGE, provider);
|
||||
const index = await core.getCurrentGuardianSetIndex();
|
||||
const guardianSet = await core.getGuardianSet(index);
|
||||
result.index = index;
|
||||
result.keys = guardianSet[0];
|
||||
result.expiry = guardianSet[1];
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Takes in a hexstring representation of a signed vaa and a guardian set.
|
||||
* Attempts to remove invalid guardian signatures, update total remaining
|
||||
* valid signatures, and update the guardian set index
|
||||
* @throws if not enough valid signatures remain
|
||||
**/
|
||||
|
||||
export function repairVaa(
|
||||
vaaHex: string,
|
||||
guardianSetData: GuardianSetData
|
||||
): string {
|
||||
const guardianSetIndex = guardianSetData.index;
|
||||
const currentGuardianSet = guardianSetData.keys;
|
||||
const minNumSignatures =
|
||||
Math.floor((2.0 * currentGuardianSet.length) / 3.0) + 1;
|
||||
const version = vaaHex.slice(0, 2);
|
||||
const parsedVaa = parseVaa(hexToUint8Array(vaaHex));
|
||||
const numSignatures = parsedVaa.guardianSignatures.length;
|
||||
const digest = keccak256(parsedVaa.hash).toString("hex");
|
||||
|
||||
var validSignatures: GuardianSignature[] = [];
|
||||
|
||||
// take each signature, check if valid against hash & current guardian set
|
||||
parsedVaa.guardianSignatures.forEach((signature) => {
|
||||
try {
|
||||
const vaaGuardianPublicKey = ethers.utils.recoverAddress(
|
||||
hex(digest),
|
||||
hex(signature.signature.toString("hex"))
|
||||
);
|
||||
const currentIndex = signature.index;
|
||||
const currentGuardianPublicKey = currentGuardianSet[currentIndex];
|
||||
|
||||
if (currentGuardianPublicKey === vaaGuardianPublicKey) {
|
||||
validSignatures.push(signature);
|
||||
}
|
||||
} catch (_) {}
|
||||
});
|
||||
|
||||
// re-construct vaa with signatures that remain
|
||||
const numRepairedSignatures = validSignatures.length;
|
||||
if (numRepairedSignatures < minNumSignatures) {
|
||||
throw new Error(`There are not enough valid signatures to repair.`);
|
||||
}
|
||||
const repairedSignatures = validSignatures
|
||||
.sort(function (a, b) {
|
||||
return a.index - b.index;
|
||||
})
|
||||
.map((signature) => {
|
||||
return `${signature.index
|
||||
.toString(16)
|
||||
.padStart(2, "0")}${signature.signature.toString("hex")}`;
|
||||
})
|
||||
.join("");
|
||||
const newSignatureBody = `${version}${guardianSetIndex
|
||||
.toString(16)
|
||||
.padStart(8, "0")}${numRepairedSignatures
|
||||
.toString(16)
|
||||
.padStart(2, "0")}${repairedSignatures}`;
|
||||
|
||||
const repairedVaa = `${newSignatureBody}${vaaHex.slice(
|
||||
12 + numSignatures * 132
|
||||
)}`;
|
||||
return repairedVaa;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Takes in a hexstring representation of a signed vaa and an eth provider.
|
||||
* Attempts to query eth core contract and retrieve current guardian set.
|
||||
* Then attempts to repair the vaa.
|
||||
**/
|
||||
|
||||
export async function repairVaaWithCurrentGuardianSet(
|
||||
vaaHex: string,
|
||||
provider: ethers.providers.JsonRpcProvider
|
||||
): Promise<string> {
|
||||
const guardianSetData = await getCurrentGuardianSet(provider);
|
||||
return repairVaa(vaaHex, guardianSetData);
|
||||
}
|
Loading…
Reference in New Issue