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:
ckeun 2022-11-23 10:24:06 -06:00 committed by GitHub
parent effde7f756
commit 1406d29ff6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 197 additions and 0 deletions

View File

@ -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();
});

View File

@ -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);
}