From def15ae50ff2b0320f809bdee66dcc2ca7a0bc34 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 11 Mar 2020 11:28:38 +1100 Subject: [PATCH 001/145] Remove some noise from the e2e test declarations We have several layers of function calls here that can be reduced. Unfortunately, it does not reduce the indentation yet but I think this is a step in the right direction. Anyway, we can remove a layer of indirection that is unnecessary. --- api_tests/lib/actor_test.ts | 65 ++++---- api_tests/tests/dry/lightning_routes.ts | 36 +++-- api_tests/tests/dry/multiple_peers.ts | 9 +- api_tests/tests/dry/peers_using_ip.ts | 27 ++-- api_tests/tests/dry/rfc003_schema.ts | 46 +++--- api_tests/tests/dry/sanity.ts | 87 ++++++----- api_tests/tests/e2e/bitcoin_ethereum.ts | 198 +++++++++++++----------- 7 files changed, 264 insertions(+), 204 deletions(-) diff --git a/api_tests/lib/actor_test.ts b/api_tests/lib/actor_test.ts index 42e2514616..e8cc6acbd6 100644 --- a/api_tests/lib/actor_test.ts +++ b/api_tests/lib/actor_test.ts @@ -2,59 +2,68 @@ import { Actors } from "./actors"; import { createActors } from "./create_actors"; import JasmineSmacker from "smack-my-jasmine-up"; import { timeout } from "./utils"; +import ProvidesCallback = jest.ProvidesCallback; /* * This test function will take care of instantiating the actors and tearing them down again * after the test, regardless if the test succeeded or failed. */ -async function nActorTest( +function nActorTest( actorNames: ["alice", "bob", "charlie"] | ["alice", "bob"] | ["alice"], testFn: (actors: Actors) => Promise -) { - const name = JasmineSmacker.getCurrentTestName(); - if (!name.match(/[A-z0-9\-]+/)) { - // We use the test name as a file name for the log and hence need to restrict it. - throw new Error( - `Testname '${name}' is invalid. Only A-z, 0-9 and dashes are allowed.` - ); - } +): ProvidesCallback { + return async done => { + const name = JasmineSmacker.getCurrentTestName(); + if (!name.match(/[A-z0-9\-]+/)) { + // We use the test name as a file name for the log and hence need to restrict it. + throw new Error( + `Testname '${name}' is invalid. Only A-z, 0-9 and dashes are allowed.` + ); + } - const actors = await createActors(name, actorNames); + const actors = await createActors(name, actorNames); - try { - await timeout(60_000, testFn(actors)); - } catch (e) { - for (const actorName of actorNames) { - await actors.getActorByName(actorName).dumpState(); - } - throw e; - } finally { - for (const actorName of actorNames) { - actors.getActorByName(actorName).stop(); + try { + await timeout(60_000, testFn(actors)); + } catch (e) { + for (const actorName of actorNames) { + await actors.getActorByName(actorName).dumpState(); + } + throw e; + } finally { + for (const actorName of actorNames) { + actors.getActorByName(actorName).stop(); + } } - } + + done(); + }; } /* * Instantiates a new e2e test based on three actors * */ -export async function threeActorTest( +export function threeActorTest( testFn: (actors: Actors) => Promise -) { - await nActorTest(["alice", "bob", "charlie"], testFn); +): ProvidesCallback { + return nActorTest(["alice", "bob", "charlie"], testFn); } /* * Instantiates a new e2e test based on two actors */ -export async function twoActorTest(testFn: (actors: Actors) => Promise) { - await nActorTest(["alice", "bob"], testFn); +export function twoActorTest( + testFn: (actors: Actors) => Promise +): ProvidesCallback { + return nActorTest(["alice", "bob"], testFn); } /* * Instantiates a new e2e test based on one actor */ -export async function oneActorTest(testFn: (actors: Actors) => Promise) { - await nActorTest(["alice"], testFn); +export function oneActorTest( + testFn: (actors: Actors) => Promise +): ProvidesCallback { + return nActorTest(["alice"], testFn); } diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index 94e704dfdc..c8834cfdae 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -9,8 +9,9 @@ import { oneActorTest } from "../../lib/actor_test"; // Lightning routes // // ******************************************** // describe("Lightning routes tests", () => { - it("lightning-routes-post-eth-lnbtc-return-400", async function() { - await oneActorTest(async function({ alice }) { + it( + "lightning-routes-post-eth-lnbtc-return-400", + oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHanEthereumEtherHalightLightningBitcoin(); return expect(promise).to.eventually.be.rejected.then(error => { expect(error).to.have.property( @@ -18,11 +19,12 @@ describe("Lightning routes tests", () => { "Request failed with status code 400" ); }); - }); - }); + }) + ); - it("lightning-routes-post-erc20-lnbtc-return-400", async function() { - await oneActorTest(async function({ alice }) { + it( + "lightning-routes-post-erc20-lnbtc-return-400", + oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin(); return expect(promise).to.eventually.be.rejected.then(error => { expect(error).to.have.property( @@ -30,11 +32,12 @@ describe("Lightning routes tests", () => { "Request failed with status code 400" ); }); - }); - }); + }) + ); - it("lightning-routes-post-lnbtc-eth-return-400", async function() { - await oneActorTest(async function({ alice }) { + it( + "lightning-routes-post-lnbtc-eth-return-400", + oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther(); return expect(promise).to.eventually.be.rejected.then(error => { expect(error).to.have.property( @@ -42,11 +45,12 @@ describe("Lightning routes tests", () => { "Request failed with status code 400" ); }); - }); - }); + }) + ); - it("lightning-routes-post-lnbtc-erc20-return-400", async function() { - await oneActorTest(async function({ alice }) { + it( + "lightning-routes-post-lnbtc-erc20-return-400", + oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20(); return expect(promise).to.eventually.be.rejected.then(error => { expect(error).to.have.property( @@ -54,6 +58,6 @@ describe("Lightning routes tests", () => { "Request failed with status code 400" ); }); - }); - }); + }) + ); }); diff --git a/api_tests/tests/dry/multiple_peers.ts b/api_tests/tests/dry/multiple_peers.ts index decda7fcbe..12e4a195cb 100644 --- a/api_tests/tests/dry/multiple_peers.ts +++ b/api_tests/tests/dry/multiple_peers.ts @@ -25,8 +25,9 @@ function toMatch(swapDetail: SwapDetails): MatchInterface { // Multiple peers // // ******************************************** // describe("Multiple peers tests", () => { - it("alice-sends-swap-request-to-bob-and-charlie", async function() { - await threeActorTest(async function({ alice, bob, charlie }) { + it( + "alice-sends-swap-request-to-bob-and-charlie", + threeActorTest(async ({ alice, bob, charlie }) => { // Alice send swap request to Bob const aliceToBobSwapUrl = await alice.cnd.postSwap( await createDefaultSwapRequest(bob) @@ -72,6 +73,6 @@ describe("Multiple peers tests", () => { toMatch(bobSwapDetails), toMatch(charlieSwapDetails), ]); - }); - }); + }) + ); }); diff --git a/api_tests/tests/dry/peers_using_ip.ts b/api_tests/tests/dry/peers_using_ip.ts index d0f0c27097..93153ec813 100644 --- a/api_tests/tests/dry/peers_using_ip.ts +++ b/api_tests/tests/dry/peers_using_ip.ts @@ -30,17 +30,19 @@ async function assertPeersAvailable(alice: Actor, bob: Actor, message: string) { } describe("Peers using IP tests", () => { - it("alice-empty-peer-list", async function() { - await twoActorTest(async function({ alice }) { + it( + "alice-empty-peer-list", + twoActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/peers"); expect(res.status).to.equal(200); expect(res.body.peers).to.be.empty; - }); - }); + }) + ); - it("alice-send-request-wrong-peer-id", async function() { - await threeActorTest(async function({ alice, bob, charlie }) { + it( + "alice-send-request-wrong-peer-id", + threeActorTest(async ({ alice, bob, charlie }) => { await assertNoPeersAvailable( alice, "[Alice] Should not yet see Bob's nor Charlie's peer id in her list of peers" @@ -74,11 +76,12 @@ describe("Peers using IP tests", () => { charlie, "[Charlie] Should not see Alice's PeerID because there was no communication so far" ); - }); - }); + }) + ); - it("alice-send-swap-request-to-charlie", async function() { - await threeActorTest(async function({ alice, bob, charlie }) { + it( + "alice-send-swap-request-to-charlie", + threeActorTest(async ({ alice, bob, charlie }) => { await assertNoPeersAvailable( alice, "[Alice] Should not yet see Bob's nor Charlie's peer id in her list of peers" @@ -105,6 +108,6 @@ describe("Peers using IP tests", () => { alice, "[Charlie] Should see Alice's peer ID in his list of peers after receiving a swap request from Alice" ); - }); - }); + }) + ); }); diff --git a/api_tests/tests/dry/rfc003_schema.ts b/api_tests/tests/dry/rfc003_schema.ts index eb471533bc..dd76615854 100644 --- a/api_tests/tests/dry/rfc003_schema.ts +++ b/api_tests/tests/dry/rfc003_schema.ts @@ -36,15 +36,18 @@ async function assertValidSirenDocument( } describe("Rfc003 schema tests", () => { - it("get-all-swaps-is-valid-siren", async function() { - await twoActorTest(async function({ alice }) { + it( + "get-all-swaps-is-valid-siren", + twoActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/swaps"); expect(res.body).to.be.jsonSchema(sirenJsonSchema); - }); - }); - it("get-single-swap-is-valid-siren", async function() { - await twoActorTest(async function({ alice, bob }) { + }) + ); + + it( + "get-single-swap-is-valid-siren", + twoActorTest(async ({ alice, bob }) => { // Alice send swap request to Bob await alice.cnd.postSwap(await createDefaultSwapRequest(bob)); @@ -70,11 +73,12 @@ describe("Rfc003 schema tests", () => { bob, "[Bob] Response for GET /swaps/rfc003/{} is a valid siren document and properties match the json schema" ); - }); - }); + }) + ); - it("get-single-swap-contains-link-to-rfc", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "get-single-swap-contains-link-to-rfc", + twoActorTest(async ({ alice, bob }) => { // Alice send swap request to Bob await alice.cnd.postSwap(await createDefaultSwapRequest(bob)); @@ -95,8 +99,8 @@ describe("Rfc003 schema tests", () => { href: "https://github.com/comit-network/RFCs/blob/master/RFC-003-SWAP-Basic.adoc", }); - }); - }); + }) + ); }); // ******************************************** // @@ -114,8 +118,9 @@ async function assertSwapsInProgress(actor: Actor, message: string) { } describe("Rfc003 schema swap reject tests", () => { - it("alice-can-make-default-swap-request", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "alice-can-make-default-swap-request", + twoActorTest(async ({ alice, bob }) => { // Alice should be able to send two swap requests to Bob const url1 = await alice.cnd.postSwap({ ...(await createDefaultSwapRequest(bob)), @@ -146,11 +151,12 @@ describe("Rfc003 schema swap reject tests", () => { bob, "[Bob] Shows the swaps as IN_PROGRESS in /swaps" ); - }); - }); + }) + ); - it("bob-can-decline-swap", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "bob-can-decline-swap", + twoActorTest(async ({ alice, bob }) => { // Alice should be able to send two swap requests to Bob const aliceReasonableSwap = await alice.cnd.postSwap({ ...(await createDefaultSwapRequest(bob)), @@ -221,6 +227,6 @@ describe("Rfc003 schema swap reject tests", () => { .status, "[Alice] Should be in the SENT State for the other swap request" ).to.eq("SENT"); - }); - }); + }) + ); }); diff --git a/api_tests/tests/dry/sanity.ts b/api_tests/tests/dry/sanity.ts index 80604d1b80..6c4616f880 100644 --- a/api_tests/tests/dry/sanity.ts +++ b/api_tests/tests/dry/sanity.ts @@ -12,8 +12,9 @@ import * as sirenJsonSchema from "../../siren.schema.json"; // ******************************************** // describe("Sanity - peers using IP", () => { - it("invalid-swap-yields-404", async function() { - await oneActorTest(async function({ alice }) { + it( + "invalid-swap-yields-404", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get( "/swaps/rfc003/deadbeef-dead-beef-dead-deadbeefdead" ); @@ -23,21 +24,23 @@ describe("Sanity - peers using IP", () => { "content-type", "application/problem+json" ); - }); - }); + }) + ); - it("empty-swap-list-after-startup", async function() { - await oneActorTest(async function({ alice }) { + it( + "empty-swap-list-after-startup", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/swaps"); const body = res.body as Entity; expect(body.entities).to.have.lengthOf(0); - }); - }); + }) + ); - it("bad-request-for-invalid-swap-combination", async function() { - await oneActorTest(async function({ alice }) { + it( + "bad-request-for-invalid-swap-combination", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()) .post("/swaps/rfc003") .send({ @@ -68,10 +71,12 @@ describe("Sanity - peers using IP", () => { "application/problem+json" ); expect(res.body.title).to.equal("Invalid body."); - }); - }); - it("returns-invalid-body-for-bad-json", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "returns-invalid-body-for-bad-json", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()) .post("/swaps/rfc003") .send({ @@ -84,36 +89,44 @@ describe("Sanity - peers using IP", () => { "application/problem+json" ); expect(res.body.title).to.equal("Invalid body."); - }); - }); - it("alice-has-empty-peer-list", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "alice-has-empty-peer-list", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/peers"); expect(res).to.have.status(200); expect(res.body.peers).to.have.length(0); - }); - }); - it("returns-listen-addresses-on-root-document", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "returns-listen-addresses-on-root-document", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/"); expect(res.body.id).to.be.a("string"); expect(res.body.listen_addresses).to.be.an("array"); // At least 2 ipv4 addresses, lookup and external interface expect(res.body.listen_addresses.length).to.be.greaterThan(1); - }); - }); - it("can-fetch-root-document-as-siren", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "can-fetch-root-document-as-siren", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()).get("/"); expect(res).to.have.status(200); expect(res.body).to.be.jsonSchema(sirenJsonSchema); - }); - }); - it("returns-listen-addresses-on-root-document-as-siren", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "returns-listen-addresses-on-root-document-as-siren", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()) .get("/") .set("accept", "application/vnd.siren+json"); @@ -124,10 +137,12 @@ describe("Sanity - peers using IP", () => { expect( res.body.properties.listen_addresses.length ).to.be.greaterThan(1); - }); - }); - it("returns-links-to-create-swap-endpoints-on-root-document-as-siren", async function() { - await oneActorTest(async function({ alice }) { + }) + ); + + it( + "returns-links-to-create-swap-endpoints-on-root-document-as-siren", + oneActorTest(async ({ alice }) => { const res = await request(alice.cndHttpApiUrl()) .get("/") .set("accept", "application/vnd.siren+json"); @@ -162,6 +177,6 @@ describe("Sanity - peers using IP", () => { class: ["swaps", "rfc003"], href: "/swaps/rfc003", }); - }); - }); + }) + ); }); diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index 51724daca1..03c9c3ca1a 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -13,8 +13,9 @@ import { LedgerKind } from "../../lib/ledgers/ledger"; // Lightning Sanity Test // // ******************************************** // describe("E2E: Sanity - LND Alice pays Bob", () => { - it.skip("sanity-lnd-alice-pays-bob", async function() { - await twoActorTest(async function({ alice, bob }) { + it.skip( + "sanity-lnd-alice-pays-bob", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest( { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } @@ -24,11 +25,12 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { ); await alice.lnPayInvoiceWithRequest(paymentRequest); await bob.lnAssertInvoiceSettled(rHash); - }); - }); + }) + ); - it.skip("sanity-lnd-alice-pays-bob-using-hold-invoice", async function() { - await twoActorTest(async function({ alice, bob }) { + it.skip( + "sanity-lnd-alice-pays-bob-using-hold-invoice", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest( { ledger: LedgerKind.Lightning, asset: AssetKind.Bitcoin }, { ledger: LedgerKind.Bitcoin, asset: AssetKind.Bitcoin } @@ -57,8 +59,8 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { expect(pay.paymentPreimage.toString("hex")).equals(secret); await bob.lnAssertInvoiceSettled(secretHash); - }); - }); + }) + ); }); // ******************************************** // @@ -66,8 +68,9 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { // Ethereum/ether Beta Ledger/Beta Asset // // ******************************************** // describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { - it("rfc003-btc-eth-alice-redeems-bob-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -79,15 +82,16 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); // ************************ // // Refund test // // ************************ // - it("rfc003-btc-eth-bob-refunds-alice-refunds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -99,11 +103,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await bob.assertRefunded(); await alice.assertRefunded(); - }); - }); + }) + ); - it("rfc003-btc-eth-alice-refunds-bob-refunds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-alice-refunds-bob-refunds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -115,15 +120,16 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertRefunded(); await bob.assertRefunded(); - }); - }); + }) + ); // ************************ // // Restart cnd test // // ************************ // - it("rfc003-btc-eth-cnd-can-be-restarted", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-cnd-can-be-restarted", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -135,15 +141,16 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.currentSwapIsAccepted(); await bob.currentSwapIsAccepted(); - }); - }); + }) + ); // ************************ // // Resume cnd test // // ************************ // - it("rfc003-btc-eth-resume-alice-down-bob-funds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-resume-alice-down-bob-funds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -163,11 +170,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); - it("rfc003-btc-eth-resume-alice-down-bob-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-resume-alice-down-bob-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -187,11 +195,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); - it("rfc003-btc-eth-resume-bob-down-alice-funds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-resume-bob-down-alice-funds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -215,11 +224,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); - it("rfc003-btc-eth-resume-bob-down-alice-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-resume-bob-down-alice-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -240,15 +250,16 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); // ************************ // // Underfunding test // // ************************ // - it("rfc003-btc-eth-alice-underfunds-bob-aborts", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-alice-underfunds-bob-aborts", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -263,11 +274,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertRefunded(); await bob.assertBetaNotDeployed(); - }); - }); + }) + ); - it("rfc003-btc-eth-bob-underfunds-both-refund", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-bob-underfunds-both-refund", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); await alice.fund(); @@ -284,15 +296,16 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await bob.assertRefunded(); await alice.refund(); await alice.assertRefunded(); - }); - }); + }) + ); // ************************ // // Overfund test // // ************************ // - it("rfc003-btc-eth-alice-overfunds-bob-aborts", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-alice-overfunds-bob-aborts", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); @@ -307,11 +320,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.assertRefunded(); await bob.assertBetaNotDeployed(); - }); - }); + }) + ); - it("rfc003-btc-eth-bob-overfunds-both-refund", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-bob-overfunds-both-refund", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Ether); await bob.accept(); await alice.fund(); @@ -328,8 +342,8 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await bob.assertRefunded(); await alice.refund(); await alice.assertRefunded(); - }); - }); + }) + ); }); // ******************************************** // @@ -337,8 +351,9 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { // Bitcoin/bitcoin Beta Ledger/Beta Asset // // ******************************************** // describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { - it("rfc003-eth-btc-alice-redeems-bob-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-btc-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); await bob.accept(); @@ -350,15 +365,16 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); // ************************ // // Ignore Failed ETH TX // // ************************ // - it("rfc003-eth-btc-alpha-deploy-fails", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-btc-alpha-deploy-fails", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); await bob.accept(); @@ -368,15 +384,16 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { await bob.assertAlphaNotDeployed(); await bob.assertBetaNotDeployed(); await alice.assertBetaNotDeployed(); - }); - }); + }) + ); // ************************ // // Refund tests // // ************************ // - it("rfc003-eth-btc-bob-refunds-alice-refunds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-btc-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); await bob.accept(); @@ -388,15 +405,16 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { await bob.assertRefunded(); await alice.assertRefunded(); - }); - }); + }) + ); // ************************ // // Bitcoin High Fees // // ************************ // - it("rfc003-eth-btc-alice-redeems-with-high-fee", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-btc-alice-redeems-with-high-fee", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Ether, AssetKind.Bitcoin); await bob.accept(); @@ -406,8 +424,8 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { const responsePromise = alice.redeemWithHighFee(); return expect(responsePromise).to.be.rejected; - }); - }); + }) + ); }); // ******************************************** // @@ -415,8 +433,9 @@ describe("E2E: Ethereum/ether - Bitcoin/bitcoin", () => { // Ethereum/erc20 Beta Ledger/Beta Asset // // ******************************************** // describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { - it("rfc003-btc-eth-erc20-alice-redeems-bob-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-erc20-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); await bob.accept(); @@ -429,11 +448,12 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); - it("rfc003-btc-eth-erc20-bob-refunds-alice-refunds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-btc-eth-erc20-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Bitcoin, AssetKind.Erc20); await bob.accept(); @@ -446,8 +466,8 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { await alice.assertRefunded(); await bob.assertRefunded(); - }); - }); + }) + ); }); // ******************************************** // @@ -455,8 +475,9 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/erc20", () => { // Bitcoin/bitcoin Beta Ledger/Beta Asset // // ******************************************** // describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { - it("rfc003-eth-erc20_btc-alice-redeems-bob-redeems", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-erc20_btc-alice-redeems-bob-redeems", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); await bob.accept(); @@ -469,11 +490,12 @@ describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { await alice.assertSwapped(); await bob.assertSwapped(); - }); - }); + }) + ); - it("rfc003-eth-erc20_btc-bob-refunds-alice-refunds", async function() { - await twoActorTest(async function({ alice, bob }) { + it( + "rfc003-eth-erc20_btc-bob-refunds-alice-refunds", + twoActorTest(async ({ alice, bob }) => { await alice.sendRequest(AssetKind.Erc20, AssetKind.Bitcoin); await bob.accept(); @@ -486,6 +508,6 @@ describe("E2E: Ethereum/erc20 - Bitcoin/bitcoin", () => { await alice.assertRefunded(); await bob.assertRefunded(); - }); - }); + }) + ); }); From 1e343ee16033c4e106fc24d88abf7dce09163196 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2020 14:13:19 +0000 Subject: [PATCH 002/145] Bump derivative from 2.0.1 to 2.0.2 Bumps [derivative](https://github.com/mcarton/rust-derivative) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/mcarton/rust-derivative/releases) - [Changelog](https://github.com/mcarton/rust-derivative/blob/master/CHANGELOG.md) - [Commits](https://github.com/mcarton/rust-derivative/commits) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b6b77a47f..fd4084f109 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,7 +528,7 @@ dependencies = [ "blockchain_contracts", "chrono", "config", - "derivative 2.0.1", + "derivative 2.0.2", "diesel", "diesel_migrations", "directories", @@ -771,9 +771,9 @@ dependencies = [ [[package]] name = "derivative" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c1f2732657d77ebc4e52a04dcf529ffb72e46e78d2e113b9016d5c01598649" +checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" dependencies = [ "proc-macro2 1.0.8", "quote 1.0.2", @@ -1661,7 +1661,7 @@ name = "libp2p-comit" version = "0.1.0" dependencies = [ "bytes 0.5.4", - "derivative 2.0.1", + "derivative 2.0.2", "futures 0.3.4", "futures_codec 0.4.0", "libp2p", From 47f3ec125848b5e00452124a53d893d93d9adbc0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2020 14:14:43 +0000 Subject: [PATCH 003/145] Bump @types/urijs from 1.19.6 to 1.19.7 in /api_tests Bumps [@types/urijs](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/urijs) from 1.19.6 to 1.19.7. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/urijs) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 34f783141f..cc13e79d4d 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -35,7 +35,7 @@ "@types/scrypt": "^6.0.0", "@types/tail": "^2.0.0", "@types/tempfile": "^3.0.0", - "@types/urijs": "^1.19.6", + "@types/urijs": "^1.19.7", "async-mutex": "^0.1.4", "bcoin": "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001", "bignumber.js": "^9.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ecebf55c94..ad68f9f022 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -718,10 +718,10 @@ resolved "https://registry.yarnpkg.com/@types/tv4/-/tv4-1.2.29.tgz#4c6d2222b03245dd2104f4fd67f54d1658985911" integrity sha512-NtJmi+XbYocrLb5Au4Q64srX4FlCPDvrSF/OnK3H0QJwrw40tIUoQPDoUHnZ5wpAB2KThtVyeS+kOEQyZabORg== -"@types/urijs@^1.19.6": - version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.6.tgz#4cee39e4e5ad8d276d617d159ffcb423ca2fd9f1" - integrity sha512-kdnK+JtEiUgnpB7r99SAZjjz9nhZ/7MWo/hxTSNfvslAa4r8jpDXDEJ2cQrjemes4eX2Y5Om3udmcc8QalPzOA== +"@types/urijs@^1.19.7": + version "1.19.7" + resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.7.tgz#94dae48b40300135db8cc3796b12252850383193" + integrity sha512-0YN0GGB2Xab5cuHerBQw/NvWUnkdVfDNdBjXtTr+2AE1c9t29HVvV+IkXwp+fwqN8/05U/XjaQ7pk+jP41ypqA== "@types/yargs-parser@*": version "15.0.0" From c585f2868460428731c8458ae0f0f70a05261d77 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 12:09:20 +1100 Subject: [PATCH 004/145] Use combinators instead of `match` expressions --- cnd/src/main.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 3e6dd64aef..e45cba1fff 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -74,16 +74,16 @@ fn main() -> anyhow::Result<()> { )) }; - match runtime.block_on(validate_blockchain_config(&bitcoin_connector.connector, settings.bitcoin.network)) { - Ok(_) => (), - Err(e) => { - if e.is::() { - tracing::warn!("Could not validate Bitcoin node config: {}", e) - } else { - return Err(e) - } - } - }; + runtime.block_on(async { + validate_blockchain_config(&bitcoin_connector.connector, settings.bitcoin.network) + .await + .or_else::(|e| { + let conn_error = e.downcast::()?; + tracing::warn!("Could not validate Bitcoin node config: {}", conn_error); + + Ok(()) + }) + })?; const ETHEREUM_BLOCK_CACHE_CAPACITY: usize = 720; const ETHEREUM_RECEIPT_CACHE_CAPACITY: usize = 720; @@ -93,16 +93,16 @@ fn main() -> anyhow::Result<()> { ETHEREUM_RECEIPT_CACHE_CAPACITY, )); - match runtime.block_on(validate_blockchain_config(ðereum_connector.connector, settings.ethereum.chain_id)) { - Ok(_) => (), - Err(e) => { - if e.is::() { - tracing::warn!("Could not validate Ethereum node config: {}", e) - } else { - return Err(e) - } - } - }; + runtime.block_on(async { + validate_blockchain_config(ðereum_connector.connector, settings.ethereum.chain_id) + .await + .or_else::(|e| { + let conn_error = e.downcast::()?; + tracing::warn!("Could not validate Ethereum node config: {}", conn_error); + + Ok(()) + }) + })?; let state_store = Arc::new(InMemoryStateStore::default()); From ecfa0c59f9db54ad49e1d4c3453075dda83a11ea Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 15:03:33 +1100 Subject: [PATCH 005/145] Group construction and validation of connectors into one block This avoids the need for reaching into the Cache struct for the connector. We also really shouldn't be using the connector for anything before we validated the network they are connected to. --- cnd/src/main.rs | 76 ++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/cnd/src/main.rs b/cnd/src/main.rs index e45cba1fff..1c5631e432 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -65,44 +65,50 @@ fn main() -> anyhow::Result<()> { .thread_stack_size(1024 * 1024 * 8) // the default is 2MB but that causes a segfault for some reason .build()?; - const BITCOIN_BLOCK_CACHE_CAPACITY: usize = 144; let bitcoin_connector = { - let config::Bitcoin { network, bitcoind } = settings.clone().bitcoin; - Arc::new(bitcoin::Cache::new( - BitcoindConnector::new(bitcoind.node_url, network)?, - BITCOIN_BLOCK_CACHE_CAPACITY, - )) + let config::Bitcoin { bitcoind, network } = &settings.bitcoin; + let connector = BitcoindConnector::new(bitcoind.node_url.clone(), *network)?; + + runtime.block_on(async { + validate_blockchain_config(&connector, *network) + .await + .or_else::(|e| { + let conn_error = e.downcast::()?; + tracing::warn!("Could not validate Bitcoin node config: {}", conn_error); + + Ok(()) + }) + })?; + + const BITCOIN_BLOCK_CACHE_CAPACITY: usize = 144; + + Arc::new(bitcoin::Cache::new(connector, BITCOIN_BLOCK_CACHE_CAPACITY)) }; - runtime.block_on(async { - validate_blockchain_config(&bitcoin_connector.connector, settings.bitcoin.network) - .await - .or_else::(|e| { - let conn_error = e.downcast::()?; - tracing::warn!("Could not validate Bitcoin node config: {}", conn_error); - - Ok(()) - }) - })?; - - const ETHEREUM_BLOCK_CACHE_CAPACITY: usize = 720; - const ETHEREUM_RECEIPT_CACHE_CAPACITY: usize = 720; - let ethereum_connector = Arc::new(ethereum::Cache::new( - Web3Connector::new(settings.clone().ethereum.parity.node_url), - ETHEREUM_BLOCK_CACHE_CAPACITY, - ETHEREUM_RECEIPT_CACHE_CAPACITY, - )); - - runtime.block_on(async { - validate_blockchain_config(ðereum_connector.connector, settings.ethereum.chain_id) - .await - .or_else::(|e| { - let conn_error = e.downcast::()?; - tracing::warn!("Could not validate Ethereum node config: {}", conn_error); - - Ok(()) - }) - })?; + let ethereum_connector = { + let config::Ethereum { parity, chain_id } = &settings.ethereum; + let connector = Web3Connector::new(parity.node_url.clone()); + + runtime.block_on(async { + validate_blockchain_config(&connector, *chain_id) + .await + .or_else::(|e| { + let conn_error = e.downcast::()?; + tracing::warn!("Could not validate Ethereum node config: {}", conn_error); + + Ok(()) + }) + })?; + + const ETHEREUM_BLOCK_CACHE_CAPACITY: usize = 720; + const ETHEREUM_RECEIPT_CACHE_CAPACITY: usize = 720; + + Arc::new(ethereum::Cache::new( + connector, + ETHEREUM_BLOCK_CACHE_CAPACITY, + ETHEREUM_RECEIPT_CACHE_CAPACITY, + )) + }; let state_store = Arc::new(InMemoryStateStore::default()); From 5b58665abecd304b9ec6b319318561b1910b1559 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 13:25:31 +1100 Subject: [PATCH 006/145] Simplify Makefile to always run rustfmt and tomlfmt Those two tools are fast, we only need an optimization for prettier. --- Makefile | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Makefile b/Makefile index 661451f02d..11ae3c7b27 100644 --- a/Makefile +++ b/Makefile @@ -86,39 +86,27 @@ e2e: download_bc_nodes build check_format: check_rust_format check_toml_format check_ts_format MODIFIED_FILES = $(shell git status --untracked-files=no --short) -MODIFIED_RUST_FILES = $(filter %.rs,$(MODIFIED_FILES)) -MODIFIED_TOML_FILES = $(filter %.toml,$(MODIFIED_FILES)) MODIFIED_TYPESCRIPT_FILES = $(filter %.ts %.json %.yml,$(MODIFIED_FILES)) format: install_rustfmt install_tomlfmt -ifneq (,$(MODIFIED_RUST_FILES)) $(CARGO_NIGHTLY) fmt -- --files-with-diff | xargs -I{} git add {} -endif -ifneq (,$(MODIFIED_TOML_FILES)) $(CARGO) tomlfmt -p Cargo.toml && git add Cargo.toml $(CARGO) tomlfmt -p cnd/Cargo.toml && git add cnd/Cargo.toml $(CARGO) tomlfmt -p libp2p-comit/Cargo.toml && git add libp2p-comit/Cargo.toml -endif ifneq (,$(MODIFIED_TYPESCRIPT_FILES)) (cd ./api_tests; yarn install; yarn run fix) endif STAGED_FILES = $(shell git diff --staged --name-only) -STAGED_RUST_FILES = $(filter %.rs,$(STAGED_FILES)) -STAGED_TOML_FILES = $(filter %.toml,$(STAGED_FILES)) STAGED_TYPESCRIPT_FILES = $(filter %.ts %.json %.yml,$(STAGED_FILES)) check_rust_format: install_rustfmt -ifneq (,$(STAGED_RUST_FILES)) $(CARGO_NIGHTLY) fmt -- --check -endif check_toml_format: install_tomlfmt -ifneq (,$(STAGED_TOML_FILES)) $(CARGO) tomlfmt -d -p Cargo.toml $(CARGO) tomlfmt -d -p cnd/Cargo.toml $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml -endif check_ts_format: ifneq (,$(STAGED_TYPESCRIPT_FILES)) From 7d27ef47a2d08118ff61bc3cc23bc8a05940393a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 13:26:11 +1100 Subject: [PATCH 007/145] Always check formatting of TS files in CI If we are not in CI, we continue to only check TS files if some where modified and are about to be committed. --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 11ae3c7b27..687133f533 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,8 @@ check_toml_format: install_tomlfmt $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml check_ts_format: -ifneq (,$(STAGED_TYPESCRIPT_FILES)) +ifeq ($(CI),true) + (cd ./api_tests; yarn install; yarn run check) +else ifneq (,$(STAGED_TYPESCRIPT_FILES)) (cd ./api_tests; yarn install; yarn run check) endif From 11f0b44e68af97e0100f3aaf9e25dbb290a9cc64 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 13:29:22 +1100 Subject: [PATCH 008/145] Silence tomlfmt --- Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 687133f533..3ce0728c68 100644 --- a/Makefile +++ b/Makefile @@ -90,9 +90,9 @@ MODIFIED_TYPESCRIPT_FILES = $(filter %.ts %.json %.yml,$(MODIFIED_FILES)) format: install_rustfmt install_tomlfmt $(CARGO_NIGHTLY) fmt -- --files-with-diff | xargs -I{} git add {} - $(CARGO) tomlfmt -p Cargo.toml && git add Cargo.toml - $(CARGO) tomlfmt -p cnd/Cargo.toml && git add cnd/Cargo.toml - $(CARGO) tomlfmt -p libp2p-comit/Cargo.toml && git add libp2p-comit/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -p Cargo.toml && git add Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -p cnd/Cargo.toml && git add cnd/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -p libp2p-comit/Cargo.toml && git add libp2p-comit/Cargo.toml ifneq (,$(MODIFIED_TYPESCRIPT_FILES)) (cd ./api_tests; yarn install; yarn run fix) endif @@ -104,9 +104,9 @@ check_rust_format: install_rustfmt $(CARGO_NIGHTLY) fmt -- --check check_toml_format: install_tomlfmt - $(CARGO) tomlfmt -d -p Cargo.toml - $(CARGO) tomlfmt -d -p cnd/Cargo.toml - $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -d -p Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -d -p cnd/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml check_ts_format: ifeq ($(CI),true) From f07d4445f85c98a253ae8cdfb9f98270cc43d365 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 13:29:37 +1100 Subject: [PATCH 009/145] Apply rustfmt --- cnd/src/btsieve/bitcoin/bitcoind_connector.rs | 6 +++--- cnd/src/btsieve/ethereum/mod.rs | 5 +---- cnd/src/btsieve/ethereum/web3_connector.rs | 4 ++-- cnd/src/config/validation.rs | 10 +++++----- cnd/src/main.rs | 9 ++------- 5 files changed, 13 insertions(+), 21 deletions(-) diff --git a/cnd/src/btsieve/bitcoin/bitcoind_connector.rs b/cnd/src/btsieve/bitcoin/bitcoind_connector.rs index 853d044008..517ce122dc 100644 --- a/cnd/src/btsieve/bitcoin/bitcoind_connector.rs +++ b/cnd/src/btsieve/bitcoin/bitcoind_connector.rs @@ -1,11 +1,11 @@ -use crate::btsieve::{ - bitcoin::bitcoin_http_request_for_hex_encoded_object, BlockByHash, LatestBlock, +use crate::{ + btsieve::{bitcoin::bitcoin_http_request_for_hex_encoded_object, BlockByHash, LatestBlock}, + config::validation::FetchNetworkId, }; use async_trait::async_trait; use bitcoin::{BlockHash, Network}; use reqwest::{Client, Url}; use serde::Deserialize; -use crate::config::validation::FetchNetworkId; #[derive(Copy, Clone, Debug, Deserialize)] pub struct ChainInfo { diff --git a/cnd/src/btsieve/ethereum/mod.rs b/cnd/src/btsieve/ethereum/mod.rs index 5430aa2fd3..92823d186b 100644 --- a/cnd/src/btsieve/ethereum/mod.rs +++ b/cnd/src/btsieve/ethereum/mod.rs @@ -1,10 +1,7 @@ mod cache; mod web3_connector; -pub use self::{ - cache::Cache, - web3_connector::{Web3Connector}, -}; +pub use self::{cache::Cache, web3_connector::Web3Connector}; use crate::{ btsieve::{ find_relevant_blocks, BlockByHash, BlockHash, LatestBlock, Predates, PreviousBlockHash, diff --git a/cnd/src/btsieve/ethereum/web3_connector.rs b/cnd/src/btsieve/ethereum/web3_connector.rs index f0af1f9ddc..565d73771b 100644 --- a/cnd/src/btsieve/ethereum/web3_connector.rs +++ b/cnd/src/btsieve/ethereum/web3_connector.rs @@ -1,11 +1,11 @@ use crate::{ btsieve::{ethereum::ReceiptByHash, BlockByHash, LatestBlock}, + config::validation::FetchNetworkId, ethereum::{TransactionReceipt, H256}, jsonrpc, + swap_protocols::ledger::ethereum::ChainId, }; -use crate::swap_protocols::ledger::ethereum::ChainId; use async_trait::async_trait; -use crate::config::validation::FetchNetworkId; #[derive(Debug)] pub struct Web3Connector { diff --git a/cnd/src/config/validation.rs b/cnd/src/config/validation.rs index d5140b79bc..1ac7fe2a46 100644 --- a/cnd/src/config/validation.rs +++ b/cnd/src/config/validation.rs @@ -1,6 +1,6 @@ -use thiserror::Error; -use std::fmt::Debug; use async_trait::async_trait; +use std::fmt::Debug; +use thiserror::Error; #[derive(Error, Debug)] pub enum Error { @@ -11,9 +11,9 @@ pub enum Error { }, } pub async fn validate_blockchain_config(connector: &C, specified: S) -> anyhow::Result<()> - where - C: FetchNetworkId, - S: PartialEq + Debug + Send + Sync + 'static, +where + C: FetchNetworkId, + S: PartialEq + Debug + Send + Sync + 'static, { let actual = connector.network_id().await?; if actual == specified { diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 1c5631e432..1af2502b98 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -19,15 +19,10 @@ use cnd::{ bitcoin::{self, BitcoindConnector}, ethereum::{self, Web3Connector}, }, - config::{ - self, - validation::{validate_blockchain_config}, - Settings, - }, + config::{self, validation::validate_blockchain_config, Settings}, db::Sqlite, http_api::route_factory, - jsonrpc, - load_swaps, + jsonrpc, load_swaps, network::Swarm, seed::RootSeed, swap_protocols::{state_store::InMemoryStateStore, Facade}, From 367e67c55f6e0c75c1cd75cadf8fc1fc0ba22881 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2020 14:16:27 +0000 Subject: [PATCH 010/145] Bump ln-service from 47.15.2 to 47.15.3 in /api_tests Bumps [ln-service](https://github.com/alexbosworth/ln-service) from 47.15.2 to 47.15.3. - [Release notes](https://github.com/alexbosworth/ln-service/releases) - [Changelog](https://github.com/alexbosworth/ln-service/blob/master/CHANGELOG.md) - [Commits](https://github.com/alexbosworth/ln-service/commits) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 35 +++++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index cc13e79d4d..e2d6469b89 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -57,7 +57,7 @@ "jest": "^25.1.0", "js-sha256": "^0.9.0", "json-schema-to-typescript": "^8.1.0", - "ln-service": "^47.15.2", + "ln-service": "^47.15.3", "log4js": "^6.1.2", "multiaddr": "^7.4.0", "pem-ts": "^2.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ad68f9f022..5b886a3c3a 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -193,10 +193,17 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@datastructures-js/priority-queue@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@datastructures-js/priority-queue/-/priority-queue-1.0.2.tgz#3511cb9cd7fb03be057afb7874cd8839d1ac91f8" - integrity sha512-HrSXJy5QPBn7DyF5ubjR6g88zW4SXDcYf732MKXTwRYf/MSVc8C1oM7UkDpaIc9OoC4r8kwpYa6oWndQZykd1w== +"@datastructures-js/heap@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@datastructures-js/heap/-/heap-1.2.0.tgz#d5bc5f36127630e922d3342e71da9bc81944f5f2" + integrity sha512-4dexQMQB2S6VXjtwI2px/Y2oIrfqOq2QkZKXFzaXizVA5FgAHlWNZ50/PF7SpjKgkMR1E1vPtY5eaxFwuPanFQ== + +"@datastructures-js/priority-queue@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@datastructures-js/priority-queue/-/priority-queue-2.0.0.tgz#5d8255e0e772c2ed06ff206636948d4f1fd3155d" + integrity sha512-PPtv7nZaDFO/3D0mWd/99iVYqyl7sKY8ZNQMKbS8x92OJ9Qw0yrpWz6KX/i8bSlGlTBx3oTUx8gZeKqaUDXZRg== + dependencies: + "@datastructures-js/heap" "^1.2.0" "@grpc/proto-loader@0.5.3": version "0.5.3" @@ -4033,13 +4040,13 @@ lightning@1.2.4: invoices "1.0.0" is-base64 "1.1.0" -ln-service@^47.15.2: - version "47.15.2" - resolved "https://registry.yarnpkg.com/ln-service/-/ln-service-47.15.2.tgz#d90095340b4479811ea97216fdc4d2c4b68fe29b" - integrity sha512-sydFwqsSYYe/tFg/lnKloAgGO/DKXhlWbUzDE1mI0bz9nXAX0EdTVyZhRiSA9NCbyPj8hFj+sU2sws5XOdG04A== +ln-service@^47.15.3: + version "47.15.3" + resolved "https://registry.yarnpkg.com/ln-service/-/ln-service-47.15.3.tgz#c508b107126eca864da229f8a47f01e87df915be" + integrity sha512-kbBCIxS8MqemXxp9r79NaBYtXHbxPvtvw8jhLyBwlViF/uKST2+3jU0ckh/Zinw+Wh7c7ydpEiPW3Y5FzlESIg== dependencies: "@alexbosworth/request" "2.88.3" - "@datastructures-js/priority-queue" "1.0.2" + "@datastructures-js/priority-queue" "2.0.0" "@grpc/proto-loader" "0.5.3" async "3.2.0" asyncjs-util "1.1.3" @@ -4063,7 +4070,7 @@ ln-service@^47.15.2: promptly "3.0.3" safe-compare "1.1.4" secp256k1 "4.0.0" - ws "7.2.1" + ws "7.2.3" loady@~0.0.1: version "0.0.1" @@ -6581,10 +6588,10 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@7.2.1, ws@^7.0.0: - version "7.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.1.tgz#03ed52423cd744084b2cf42ed197c8b65a936b8e" - integrity sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A== +ws@7.2.3, ws@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== xml-name-validator@^3.0.0: version "3.0.0" From 8155af8f54f540a15fd58741f498d96cc4cfea38 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2020 14:17:30 +0000 Subject: [PATCH 011/145] Bump tslint from 6.0.0 to 6.1.0 in /api_tests Bumps [tslint](https://github.com/palantir/tslint) from 6.0.0 to 6.1.0. - [Release notes](https://github.com/palantir/tslint/releases) - [Changelog](https://github.com/palantir/tslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/palantir/tslint/compare/6.0.0...6.1.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 42 +++++++----------------------------------- 2 files changed, 8 insertions(+), 36 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index cc13e79d4d..f030b28cd4 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -72,7 +72,7 @@ "tmp": "^0.1.0", "ts-jest": "^25.2.1", "ts-node": "^8.6.2", - "tslint": "^6.0.0", + "tslint": "^6.1.0", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", "typescript": "^3.8.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ad68f9f022..c0cc715803 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -28,14 +28,7 @@ tunnel-agent "0.6.0" uuid "3.4.0" -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== @@ -110,15 +103,6 @@ "@babel/traverse" "^7.8.4" "@babel/types" "^7.8.3" -"@babel/highlight@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" - integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - "@babel/highlight@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" @@ -5342,20 +5326,13 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@1.x: +resolve@1.x, resolve@^1.3.2: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" -resolve@^1.3.2: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== - dependencies: - path-parse "^1.0.6" - ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -5482,12 +5459,7 @@ secp256k1@4.0.0: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" - integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== - -semver@^5.4.1, semver@^5.5: +semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -6235,10 +6207,10 @@ tslint-no-unused-expression-chai@^0.1.4: dependencies: tsutils "^3.0.0" -tslint@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.0.0.tgz#1c0148beac4779924216302f192cdaa153618310" - integrity sha512-9nLya8GBtlFmmFMW7oXXwoXS1NkrccqTqAtwXzdPV9e2mqSEvCki6iHL/Fbzi5oqbugshzgGPk7KBb2qNP1DSA== +tslint@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" + integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" From 6a57fb9e48bc6224cea1fd9afe6ad84c05c749c7 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 15:14:34 +1100 Subject: [PATCH 012/145] Digest on a String --- Cargo.lock | 27 +++++++++++++++++++++++++++ cnd/Cargo.toml | 1 + cnd/src/lib.rs | 1 + cnd/src/swap_digest.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 cnd/src/swap_digest.rs diff --git a/Cargo.lock b/Cargo.lock index 3b854dd0e5..91610ae408 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -334,6 +334,17 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "blake2s_simd" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9e07352b829279624ceb7c64adb4f585dacdb81d35cafae81139ccd617cf44" +dependencies = [ + "arrayref", + "arrayvec 0.5.1", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.7.3" @@ -546,6 +557,7 @@ dependencies = [ "log 0.4.8", "lru", "matches", + "multihash", "num 0.2.1", "paste", "pem", @@ -2224,6 +2236,21 @@ dependencies = [ "ws2_32-sys", ] +[[package]] +name = "multihash" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fbc227f7e2b1cb701f95404579ecb2668abbdd3c7ef7a6cbb3cc0d3b236869" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "digest", + "sha-1", + "sha2", + "sha3", + "unsigned-varint", +] + [[package]] name = "multimap" version = "0.8.0" diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 98e621a33a..2545c3fe52 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -31,6 +31,7 @@ libp2p-comit = { path = "../libp2p-comit" } libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } lru = "0.4.3" +multihash = "0.10" num = "0.2" paste = "0.1" pem = "0.7" diff --git a/cnd/src/lib.rs b/cnd/src/lib.rs index e122a83dc7..753913f376 100644 --- a/cnd/src/lib.rs +++ b/cnd/src/lib.rs @@ -47,6 +47,7 @@ pub mod seed; pub mod jsonrpc; #[cfg(test)] pub mod spectral_ext; +pub mod swap_digest; pub mod swap_protocols; pub mod timestamp; diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs new file mode 100644 index 0000000000..bb79016633 --- /dev/null +++ b/cnd/src/swap_digest.rs @@ -0,0 +1,26 @@ +use multihash::Multihash; + +trait Digest { + fn digest(&self) -> Multihash; +} + +impl Digest for String { + fn digest(&self) -> Multihash { + let bytes = self.as_bytes(); + // Time the tests and take fastest hash? + multihash::Sha3_256::digest(bytes) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn given_same_strings_return_same_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("simple string"); + + assert_eq!(str1.digest(), str2.digest()) + } +} From acecd0fbeb9a748cd8b55ffb5403fa080c953b79 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 15:48:26 +1100 Subject: [PATCH 013/145] Implement for new type --- cnd/src/swap_digest.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index bb79016633..a61736f8f0 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -12,6 +12,14 @@ impl Digest for String { } } +struct NewType(String); + +impl Digest for NewType { + fn digest(&self) -> Multihash { + self.0.digest() + } +} + #[cfg(test)] mod tests { use super::*; @@ -23,4 +31,28 @@ mod tests { assert_eq!(str1.digest(), str2.digest()) } + + #[test] + fn given_differemt_strings_return_different_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("longer string."); + + assert_ne!(str1.digest(), str2.digest()) + } + + #[test] + fn given_same_newtypes_return_same_multihash() { + let new_type1 = NewType("simple string".into()); + let new_type2 = NewType("simple string".into()); + + assert_eq!(new_type1.digest(), new_type2.digest()) + } + + #[test] + fn given_different_newtypes_return_different_multihash() { + let new_type1 = NewType("simple string".into()); + let new_type2 = NewType("longer string.".into()); + + assert_ne!(new_type1.digest(), new_type2.digest()) + } } From 2825effcc4d642376665e172d3d35f337c81820a Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 16:15:25 +1100 Subject: [PATCH 014/145] Single Field Struct --- cnd/src/swap_digest.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index a61736f8f0..8cf0b652b5 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -20,6 +20,18 @@ impl Digest for NewType { } } +struct SingleFieldStruct { + field: String, +} + +impl Digest for SingleFieldStruct { + fn digest(&self) -> Multihash { + let mut str = String::from("field: "); + str += &self.field; + str.digest() + } +} + #[cfg(test)] mod tests { use super::*; @@ -55,4 +67,26 @@ mod tests { assert_ne!(new_type1.digest(), new_type2.digest()) } + + #[test] + fn given_same_single_field_struct_return_same_multihash() { + let struct1 = SingleFieldStruct { + field: "foo".into(), + }; + let struct2 = SingleFieldStruct { + field: "foo".into(), + }; + + assert_eq!(struct1.digest(), struct2.digest()) + } + + #[test] + fn given_single_field_struct_and_new_type_with_same_inner_return_different_multihash() { + let single_field_struct = SingleFieldStruct { + field: "foo".into(), + }; + let new_type = NewType("foo".into()); + + assert_ne!(single_field_struct.digest(), new_type.digest()) + } } From 2e7421d1cc91b5d532dd3ea71d2cd116742be90f Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 16:31:20 +1100 Subject: [PATCH 015/145] Double Field Struct --- cnd/src/swap_digest.rs | 69 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 8cf0b652b5..92a1b29b0f 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -1,5 +1,10 @@ use multihash::Multihash; +fn digest(bytes: &[u8]) -> Multihash { + // Time the tests and take fastest hash? + multihash::Sha3_256::digest(bytes) +} + trait Digest { fn digest(&self) -> Multihash; } @@ -7,8 +12,13 @@ trait Digest { impl Digest for String { fn digest(&self) -> Multihash { let bytes = self.as_bytes(); - // Time the tests and take fastest hash? - multihash::Sha3_256::digest(bytes) + digest(bytes) + } +} + +impl Digest for Vec { + fn digest(&self) -> Multihash { + digest(&self) } } @@ -32,6 +42,33 @@ impl Digest for SingleFieldStruct { } } +struct DoubleFieldStruct { + foo: String, + bar: String, +} + +impl Digest for DoubleFieldStruct { + fn digest(&self) -> Multihash { + let mut foo = String::from("foo: "); + foo += &self.foo; + let foo = foo.digest(); + + let mut bar = String::from("bar: "); + bar += &self.bar; + let bar = bar.digest(); + + if foo < bar { + let mut res = foo.into_bytes(); + res.append(&mut bar.into_bytes()); + res.digest() + } else { + let mut res = bar.into_bytes(); + res.append(&mut foo.into_bytes()); + res.digest() + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -89,4 +126,32 @@ mod tests { assert_ne!(single_field_struct.digest(), new_type.digest()) } + + #[test] + fn given_same_double_field_struct_return_same_multihash() { + let struct1 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + let struct2 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + + assert_eq!(struct1.digest(), struct2.digest()) + } + + #[test] + fn given_different_double_field_struct_return_different_multihash() { + let struct1 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + let struct2 = DoubleFieldStruct { + foo: "first field".into(), + bar: "different field".into(), + }; + + assert_ne!(struct1.digest(), struct2.digest()) + } } From 704fb7b6308b32b36a3820709f22aa6619d80271 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 16:37:01 +1100 Subject: [PATCH 016/145] Similar structs produce same hash --- cnd/src/swap_digest.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 92a1b29b0f..dd373205a9 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -69,6 +69,33 @@ impl Digest for DoubleFieldStruct { } } +struct OtherStruct { + bar: String, + foo: String, +} + +impl Digest for OtherStruct { + fn digest(&self) -> Multihash { + let mut foo = String::from("foo: "); + foo += &self.foo; + let foo = foo.digest(); + + let mut bar = String::from("bar: "); + bar += &self.bar; + let bar = bar.digest(); + + if foo < bar { + let mut res = foo.into_bytes(); + res.append(&mut bar.into_bytes()); + res.digest() + } else { + let mut res = bar.into_bytes(); + res.append(&mut foo.into_bytes()); + res.digest() + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -154,4 +181,18 @@ mod tests { assert_ne!(struct1.digest(), struct2.digest()) } + + #[test] + fn given_two_double_field_struct_with_same_data_return_same_multihash() { + let struct1 = DoubleFieldStruct { + foo: "foo field".into(), + bar: "bar field".into(), + }; + let struct2 = OtherStruct { + bar: "bar field".into(), + foo: "foo field".into(), + }; + + assert_eq!(struct1.digest(), struct2.digest()) + } } From af86b1e1e8977a48e8f5a629520de2d6edc82c6e Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 20:21:21 +1100 Subject: [PATCH 017/145] Separate digest of fields and root digest, create new crate --- Cargo.lock | 26 ++++++---- Cargo.toml | 2 +- cnd/Cargo.toml | 1 + cnd/src/swap_digest.rs | 109 ++++++++++++++++++----------------------- digest/Cargo.toml | 8 +++ digest/src/lib.rs | 37 ++++++++++++++ 6 files changed, 111 insertions(+), 72 deletions(-) create mode 100644 digest/Cargo.toml create mode 100644 digest/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 91610ae408..55bfa8c1e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,7 +309,7 @@ checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" dependencies = [ "byte-tools", "crypto-mac", - "digest", + "digest 0.8.1", "opaque-debug", ] @@ -542,6 +542,7 @@ dependencies = [ "derivative 2.0.2", "diesel", "diesel_migrations", + "digest 0.1.0", "directories", "ethbloom", "fern", @@ -758,7 +759,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" dependencies = [ "byteorder 1.3.4", - "digest", + "digest 0.8.1", "rand_core 0.5.1", "subtle 2.2.2", "zeroize", @@ -825,6 +826,13 @@ dependencies = [ "migrations_macros", ] +[[package]] +name = "digest" +version = "0.1.0" +dependencies = [ + "multihash", +] + [[package]] name = "digest" version = "0.8.1" @@ -1336,7 +1344,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dcb5e64cda4c23119ab41ba960d1e170a774c8e4b9d9e6a9bc18aabf5e59695" dependencies = [ "crypto-mac", - "digest", + "digest 0.8.1", ] [[package]] @@ -1345,7 +1353,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6e570451493f10f6581b48cdd530413b63ea9e780f544bfd3bdcaa0d89d1a7b" dependencies = [ - "digest", + "digest 0.8.1", "generic-array", "hmac", ] @@ -2047,7 +2055,7 @@ checksum = "1fc1e2c808481a63dc6da2074752fdd4336a3c8fcc68b83db6f1fd5224ae7962" dependencies = [ "arrayref", "crunchy", - "digest", + "digest 0.8.1", "hmac-drbg", "rand 0.7.3", "sha2", @@ -2244,7 +2252,7 @@ checksum = "47fbc227f7e2b1cb701f95404579ecb2668abbdd3c7ef7a6cbb3cc0d3b236869" dependencies = [ "blake2b_simd", "blake2s_simd", - "digest", + "digest 0.8.1", "sha-1", "sha2", "sha3", @@ -3351,7 +3359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ "block-buffer", - "digest", + "digest 0.8.1", "fake-simd", "opaque-debug", ] @@ -3363,7 +3371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0" dependencies = [ "block-buffer", - "digest", + "digest 0.8.1", "fake-simd", "opaque-debug", ] @@ -3376,7 +3384,7 @@ checksum = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" dependencies = [ "block-buffer", "byte-tools", - "digest", + "digest 0.8.1", "keccak", "opaque-debug", ] diff --git a/Cargo.toml b/Cargo.toml index ee538c5617..5a47dae6e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["cnd", "libp2p-comit"] +members = ["cnd", "digest", "libp2p-comit"] diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 2545c3fe52..52035829ec 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -17,6 +17,7 @@ config = { version = "0.10", features = ["toml"], default-features = false } derivative = "2" diesel = { version = "1.4", features = ["sqlite", "chrono"] } diesel_migrations = "1.4.0" +digest = { path = "../digest" } directories = "2.0" ethbloom = "0.8.1" fern = { version = "0.6", features = ["colored"] } diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index dd373205a9..6c8c61c193 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -1,32 +1,12 @@ -use multihash::Multihash; - -fn digest(bytes: &[u8]) -> Multihash { - // Time the tests and take fastest hash? - multihash::Sha3_256::digest(bytes) -} - -trait Digest { - fn digest(&self) -> Multihash; -} +use digest::{digest, DigestField, DigestRoot}; -impl Digest for String { - fn digest(&self) -> Multihash { - let bytes = self.as_bytes(); - digest(bytes) - } -} - -impl Digest for Vec { - fn digest(&self) -> Multihash { - digest(&self) - } -} +use multihash::Multihash; struct NewType(String); -impl Digest for NewType { - fn digest(&self) -> Multihash { - self.0.digest() +impl DigestRoot for NewType { + fn digest_root(self) -> Multihash { + self.0.digest_field("".into()) } } @@ -34,11 +14,9 @@ struct SingleFieldStruct { field: String, } -impl Digest for SingleFieldStruct { - fn digest(&self) -> Multihash { - let mut str = String::from("field: "); - str += &self.field; - str.digest() +impl DigestRoot for SingleFieldStruct { + fn digest_root(self) -> Multihash { + self.field.digest_field("field".into()) } } @@ -47,24 +25,19 @@ struct DoubleFieldStruct { bar: String, } -impl Digest for DoubleFieldStruct { - fn digest(&self) -> Multihash { - let mut foo = String::from("foo: "); - foo += &self.foo; - let foo = foo.digest(); - - let mut bar = String::from("bar: "); - bar += &self.bar; - let bar = bar.digest(); +impl DigestRoot for DoubleFieldStruct { + fn digest_root(self) -> Multihash { + let bar = self.bar.digest_field("bar".into()); + let foo = self.foo.digest_field("foo".into()); if foo < bar { let mut res = foo.into_bytes(); res.append(&mut bar.into_bytes()); - res.digest() + digest(&res) } else { let mut res = bar.into_bytes(); res.append(&mut foo.into_bytes()); - res.digest() + digest(&res) } } } @@ -74,24 +47,19 @@ struct OtherStruct { foo: String, } -impl Digest for OtherStruct { - fn digest(&self) -> Multihash { - let mut foo = String::from("foo: "); - foo += &self.foo; - let foo = foo.digest(); - - let mut bar = String::from("bar: "); - bar += &self.bar; - let bar = bar.digest(); +impl DigestRoot for OtherStruct { + fn digest_root(self) -> Multihash { + let foo = self.foo.digest_field("foo".into()); + let bar = self.bar.digest_field("bar".into()); if foo < bar { let mut res = foo.into_bytes(); res.append(&mut bar.into_bytes()); - res.digest() + digest(&res) } else { let mut res = bar.into_bytes(); res.append(&mut foo.into_bytes()); - res.digest() + digest(&res) } } } @@ -105,15 +73,32 @@ mod tests { let str1 = String::from("simple string"); let str2 = String::from("simple string"); - assert_eq!(str1.digest(), str2.digest()) + assert_eq!( + str1.digest_field("foo".into()), + str2.digest_field("foo".into()) + ) + } + + #[test] + fn given_same_strings_different_names_return_diff_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("simple string"); + + assert_ne!( + str1.digest_field("foo".into()), + str2.digest_field("bar".into()) + ) } #[test] - fn given_differemt_strings_return_different_multihash() { + fn given_different_strings_return_different_multihash() { let str1 = String::from("simple string"); let str2 = String::from("longer string."); - assert_ne!(str1.digest(), str2.digest()) + assert_ne!( + str1.digest_field("foo".into()), + str2.digest_field("foo".into()) + ) } #[test] @@ -121,7 +106,7 @@ mod tests { let new_type1 = NewType("simple string".into()); let new_type2 = NewType("simple string".into()); - assert_eq!(new_type1.digest(), new_type2.digest()) + assert_eq!(new_type1.digest_root(), new_type2.digest_root()) } #[test] @@ -129,7 +114,7 @@ mod tests { let new_type1 = NewType("simple string".into()); let new_type2 = NewType("longer string.".into()); - assert_ne!(new_type1.digest(), new_type2.digest()) + assert_ne!(new_type1.digest_root(), new_type2.digest_root()) } #[test] @@ -141,7 +126,7 @@ mod tests { field: "foo".into(), }; - assert_eq!(struct1.digest(), struct2.digest()) + assert_eq!(struct1.digest_root(), struct2.digest_root()) } #[test] @@ -151,7 +136,7 @@ mod tests { }; let new_type = NewType("foo".into()); - assert_ne!(single_field_struct.digest(), new_type.digest()) + assert_ne!(single_field_struct.digest_root(), new_type.digest_root()) } #[test] @@ -165,7 +150,7 @@ mod tests { bar: "second field".into(), }; - assert_eq!(struct1.digest(), struct2.digest()) + assert_eq!(struct1.digest_root(), struct2.digest_root()) } #[test] @@ -179,7 +164,7 @@ mod tests { bar: "different field".into(), }; - assert_ne!(struct1.digest(), struct2.digest()) + assert_ne!(struct1.digest_root(), struct2.digest_root()) } #[test] @@ -193,6 +178,6 @@ mod tests { foo: "foo field".into(), }; - assert_eq!(struct1.digest(), struct2.digest()) + assert_eq!(struct1.digest_root(), struct2.digest_root()) } } diff --git a/digest/Cargo.toml b/digest/Cargo.toml new file mode 100644 index 0000000000..d24ca1f5b2 --- /dev/null +++ b/digest/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "digest" +version = "0.1.0" +authors = ["CoBloX "] +edition = "2018" + +[dependencies] +multihash = "0.10" diff --git a/digest/src/lib.rs b/digest/src/lib.rs new file mode 100644 index 0000000000..59781cdf22 --- /dev/null +++ b/digest/src/lib.rs @@ -0,0 +1,37 @@ +use multihash::Multihash; + +pub fn digest(bytes: &[u8]) -> Multihash { + // Time the tests and take fastest hash? + multihash::Sha3_256::digest(bytes) +} + +pub trait DigestRoot { + fn digest_root(self) -> Multihash; +} + +pub trait DigestField { + fn digest_field(self, field_name: String) -> Multihash; +} + +impl DigestField for String { + fn digest_field(self, field_name: String) -> Multihash { + let mut bytes = field_name.into_bytes(); + let mut separator = b": ".to_vec(); + bytes.append(&mut separator); + let mut value = self.into_bytes(); + bytes.append(&mut value); + + digest(&bytes) + } +} + +impl DigestField for Vec { + fn digest_field(mut self, field_name: String) -> Multihash { + let mut bytes = field_name.into_bytes(); + let mut separator = b": ".to_vec(); + bytes.append(&mut separator); + bytes.append(&mut self); + + digest(&self) + } +} From 2ebcb64ad483843682651bbf3892a4664ff82494 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 20:27:28 +1100 Subject: [PATCH 018/145] Put separator in a const --- digest/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 59781cdf22..4328e819c4 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,5 +1,7 @@ use multihash::Multihash; +const SEPARATOR: &[u8; 1] = b":"; + pub fn digest(bytes: &[u8]) -> Multihash { // Time the tests and take fastest hash? multihash::Sha3_256::digest(bytes) @@ -16,7 +18,7 @@ pub trait DigestField { impl DigestField for String { fn digest_field(self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); - let mut separator = b": ".to_vec(); + let mut separator = SEPARATOR.to_vec(); bytes.append(&mut separator); let mut value = self.into_bytes(); bytes.append(&mut value); @@ -28,7 +30,7 @@ impl DigestField for String { impl DigestField for Vec { fn digest_field(mut self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); - let mut separator = b": ".to_vec(); + let mut separator = SEPARATOR.to_vec(); bytes.append(&mut separator); bytes.append(&mut self); From 8f7885d7e993382769b19aef9820d32262a8404c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 20:30:56 +1100 Subject: [PATCH 019/145] Make clippy happy --- cnd/src/swap_digest.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 6c8c61c193..7b2749d0e0 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -27,16 +27,16 @@ struct DoubleFieldStruct { impl DigestRoot for DoubleFieldStruct { fn digest_root(self) -> Multihash { - let bar = self.bar.digest_field("bar".into()); - let foo = self.foo.digest_field("foo".into()); + let bar_digest = self.bar.digest_field("bar".into()); + let foo_digest = self.foo.digest_field("foo".into()); - if foo < bar { - let mut res = foo.into_bytes(); - res.append(&mut bar.into_bytes()); + if foo_digest < bar_digest { + let mut res = foo_digest.into_bytes(); + res.append(&mut bar_digest.into_bytes()); digest(&res) } else { - let mut res = bar.into_bytes(); - res.append(&mut foo.into_bytes()); + let mut res = bar_digest.into_bytes(); + res.append(&mut foo_digest.into_bytes()); digest(&res) } } @@ -49,16 +49,16 @@ struct OtherStruct { impl DigestRoot for OtherStruct { fn digest_root(self) -> Multihash { - let foo = self.foo.digest_field("foo".into()); - let bar = self.bar.digest_field("bar".into()); + let foo_digest = self.foo.digest_field("foo".into()); + let bar_digest = self.bar.digest_field("bar".into()); - if foo < bar { - let mut res = foo.into_bytes(); - res.append(&mut bar.into_bytes()); + if foo_digest < bar_digest { + let mut res = foo_digest.into_bytes(); + res.append(&mut bar_digest.into_bytes()); digest(&res) } else { - let mut res = bar.into_bytes(); - res.append(&mut foo.into_bytes()); + let mut res = bar_digest.into_bytes(); + res.append(&mut foo_digest.into_bytes()); digest(&res) } } From 58f69251d13b86a1c4a83c1287f8c878a3c2ccc1 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 21:12:32 +1100 Subject: [PATCH 020/145] More programmatic way to calculate digest root --- cnd/src/swap_digest.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 7b2749d0e0..091c784a36 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -49,18 +49,20 @@ struct OtherStruct { impl DigestRoot for OtherStruct { fn digest_root(self) -> Multihash { + let mut digests = vec![]; let foo_digest = self.foo.digest_field("foo".into()); + digests.push(foo_digest); let bar_digest = self.bar.digest_field("bar".into()); + digests.push(bar_digest); - if foo_digest < bar_digest { - let mut res = foo_digest.into_bytes(); - res.append(&mut bar_digest.into_bytes()); - digest(&res) - } else { - let mut res = bar_digest.into_bytes(); - res.append(&mut foo_digest.into_bytes()); - digest(&res) - } + digests.sort(); + + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); + + digest(&res) } } From 40b3e1f219fba606e1d7e57bfbd4c7c3ef01eb59 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 11 Mar 2020 21:21:14 +1100 Subject: [PATCH 021/145] Implement proc macro DigestRootMacro --- Cargo.lock | 9 ++++++ Cargo.toml | 2 +- cnd/Cargo.toml | 1 + cnd/src/swap_digest.rs | 19 ++----------- digest-macro-derive/Cargo.toml | 12 ++++++++ digest-macro-derive/src/lib.rs | 50 ++++++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 digest-macro-derive/Cargo.toml create mode 100644 digest-macro-derive/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 55bfa8c1e6..66cacf2853 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -543,6 +543,7 @@ dependencies = [ "diesel", "diesel_migrations", "digest 0.1.0", + "digest-macro-derive", "directories", "ethbloom", "fern", @@ -842,6 +843,14 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest-macro-derive" +version = "0.1.0" +dependencies = [ + "quote 1.0.2", + "syn 1.0.15", +] + [[package]] name = "directories" version = "2.0.2" diff --git a/Cargo.toml b/Cargo.toml index 5a47dae6e2..dc6decb659 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["cnd", "digest", "libp2p-comit"] +members = ["cnd", "digest", "digest-macro-derive", "libp2p-comit"] diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 52035829ec..a7e554cd02 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -18,6 +18,7 @@ derivative = "2" diesel = { version = "1.4", features = ["sqlite", "chrono"] } diesel_migrations = "1.4.0" digest = { path = "../digest" } +digest-macro-derive = { path = "../digest-macro-derive" } directories = "2.0" ethbloom = "0.8.1" fern = { version = "0.6", features = ["colored"] } diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 091c784a36..2f7091e2e8 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -1,4 +1,5 @@ use digest::{digest, DigestField, DigestRoot}; +use digest_macro_derive::DigestRootMacro; use multihash::Multihash; @@ -20,28 +21,12 @@ impl DigestRoot for SingleFieldStruct { } } +#[derive(DigestRootMacro)] struct DoubleFieldStruct { foo: String, bar: String, } -impl DigestRoot for DoubleFieldStruct { - fn digest_root(self) -> Multihash { - let bar_digest = self.bar.digest_field("bar".into()); - let foo_digest = self.foo.digest_field("foo".into()); - - if foo_digest < bar_digest { - let mut res = foo_digest.into_bytes(); - res.append(&mut bar_digest.into_bytes()); - digest(&res) - } else { - let mut res = bar_digest.into_bytes(); - res.append(&mut foo_digest.into_bytes()); - digest(&res) - } - } -} - struct OtherStruct { bar: String, foo: String, diff --git a/digest-macro-derive/Cargo.toml b/digest-macro-derive/Cargo.toml new file mode 100644 index 0000000000..476276d0d9 --- /dev/null +++ b/digest-macro-derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "digest-macro-derive" +version = "0.1.0" +authors = ["CoBloX "] +edition = "2018" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0" +syn = "1.0" diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs new file mode 100644 index 0000000000..9fdce92d41 --- /dev/null +++ b/digest-macro-derive/src/lib.rs @@ -0,0 +1,50 @@ +extern crate proc_macro; + +use crate::proc_macro::TokenStream; +use quote::quote; +use syn::{Data, Fields}; + +#[proc_macro_derive(DigestRootMacro)] +pub fn digest_root_macro_fn(input: TokenStream) -> TokenStream { + let ast = syn::parse(input).unwrap(); + impl_digest_root_macro(&ast) +} + +fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { + let name = &ast.ident; + if let Data::Struct(data) = &ast.data { + if let Fields::Named(fields) = &data.fields { + let idents = fields + .named + .iter() + .map(|field| field.ident.as_ref().expect("Named field")); + + let types = fields.named.iter().map(|field| &field.ty); + + let gen = quote! { + impl DigestRoot for #name + where #(#types: DigestField),* + { + fn digest_root(self) -> Multihash { + let mut digests = vec![]; + #(digests.push(self.#idents.digest_field(stringify!(#idents).into())););* + + digests.sort(); + + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); + + digest(&res) + } + } + }; + gen.into() + } else { + panic!("DigestRootMacro does not support new types."); + } + } else { + panic!("DigestRootMacro only supports structs."); + } +} From c5333611b40ff9d6c786bdd3f3835f9c1e8a05a4 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:08:15 +1100 Subject: [PATCH 022/145] Re-export multihash to avoid maintaining in two Cargo.toml files --- Cargo.lock | 1 - cnd/Cargo.toml | 1 - cnd/src/swap_digest.rs | 2 +- digest/src/lib.rs | 1 + 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66cacf2853..c961e12e56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -559,7 +559,6 @@ dependencies = [ "log 0.4.8", "lru", "matches", - "multihash", "num 0.2.1", "paste", "pem", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index a7e554cd02..dad2522a41 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -33,7 +33,6 @@ libp2p-comit = { path = "../libp2p-comit" } libsqlite3-sys = { version = ">=0.8.0, <0.13.0", features = ["bundled"] } log = { version = "0.4", features = ["serde"] } lru = "0.4.3" -multihash = "0.10" num = "0.2" paste = "0.1" pem = "0.7" diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 2f7091e2e8..7be06e21e0 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -1,7 +1,7 @@ use digest::{digest, DigestField, DigestRoot}; use digest_macro_derive::DigestRootMacro; -use multihash::Multihash; +use digest::multihash::Multihash; struct NewType(String); diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 4328e819c4..de5831735b 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,3 +1,4 @@ +pub use multihash; use multihash::Multihash; const SEPARATOR: &[u8; 1] = b":"; From ba454617df837806ea13bed191916ed513372285 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:16:27 +1100 Subject: [PATCH 023/145] Move all code under #[cfg(test)] --- cnd/src/swap_digest.rs | 82 +++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs index 7be06e21e0..e527408c1e 100644 --- a/cnd/src/swap_digest.rs +++ b/cnd/src/swap_digest.rs @@ -1,59 +1,57 @@ -use digest::{digest, DigestField, DigestRoot}; -use digest_macro_derive::DigestRootMacro; +#[cfg(test)] +mod tests { + use digest::{digest, DigestField, DigestRoot}; + use digest_macro_derive::DigestRootMacro; -use digest::multihash::Multihash; + use digest::multihash::Multihash; -struct NewType(String); + struct NewType(String); -impl DigestRoot for NewType { - fn digest_root(self) -> Multihash { - self.0.digest_field("".into()) + impl DigestRoot for NewType { + fn digest_root(self) -> Multihash { + self.0.digest_field("".into()) + } } -} -struct SingleFieldStruct { - field: String, -} + struct SingleFieldStruct { + field: String, + } -impl DigestRoot for SingleFieldStruct { - fn digest_root(self) -> Multihash { - self.field.digest_field("field".into()) + impl DigestRoot for SingleFieldStruct { + fn digest_root(self) -> Multihash { + self.field.digest_field("field".into()) + } } -} -#[derive(DigestRootMacro)] -struct DoubleFieldStruct { - foo: String, - bar: String, -} + #[derive(DigestRootMacro)] + struct DoubleFieldStruct { + foo: String, + bar: String, + } -struct OtherStruct { - bar: String, - foo: String, -} + struct OtherStruct { + bar: String, + foo: String, + } -impl DigestRoot for OtherStruct { - fn digest_root(self) -> Multihash { - let mut digests = vec![]; - let foo_digest = self.foo.digest_field("foo".into()); - digests.push(foo_digest); - let bar_digest = self.bar.digest_field("bar".into()); - digests.push(bar_digest); + impl DigestRoot for OtherStruct { + fn digest_root(self) -> Multihash { + let mut digests = vec![]; + let foo_digest = self.foo.digest_field("foo".into()); + digests.push(foo_digest); + let bar_digest = self.bar.digest_field("bar".into()); + digests.push(bar_digest); - digests.sort(); + digests.sort(); - let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); - res - }); + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); - digest(&res) + digest(&res) + } } -} - -#[cfg(test)] -mod tests { - use super::*; #[test] fn given_same_strings_return_same_multihash() { From 9c6b8eec722799073455b683d2e6ab8487058109 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:22:22 +1100 Subject: [PATCH 024/145] Move `swap_digest.rs` under `digest` crate --- Cargo.lock | 1 + cnd/src/lib.rs | 1 - cnd/src/swap_digest.rs | 168 ------------------------------------ digest/Cargo.toml | 3 + digest/tests/swap_digest.rs | 165 +++++++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+), 169 deletions(-) delete mode 100644 cnd/src/swap_digest.rs create mode 100644 digest/tests/swap_digest.rs diff --git a/Cargo.lock b/Cargo.lock index c961e12e56..a5cf36a295 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -830,6 +830,7 @@ dependencies = [ name = "digest" version = "0.1.0" dependencies = [ + "digest-macro-derive", "multihash", ] diff --git a/cnd/src/lib.rs b/cnd/src/lib.rs index 753913f376..e122a83dc7 100644 --- a/cnd/src/lib.rs +++ b/cnd/src/lib.rs @@ -47,7 +47,6 @@ pub mod seed; pub mod jsonrpc; #[cfg(test)] pub mod spectral_ext; -pub mod swap_digest; pub mod swap_protocols; pub mod timestamp; diff --git a/cnd/src/swap_digest.rs b/cnd/src/swap_digest.rs deleted file mode 100644 index e527408c1e..0000000000 --- a/cnd/src/swap_digest.rs +++ /dev/null @@ -1,168 +0,0 @@ -#[cfg(test)] -mod tests { - use digest::{digest, DigestField, DigestRoot}; - use digest_macro_derive::DigestRootMacro; - - use digest::multihash::Multihash; - - struct NewType(String); - - impl DigestRoot for NewType { - fn digest_root(self) -> Multihash { - self.0.digest_field("".into()) - } - } - - struct SingleFieldStruct { - field: String, - } - - impl DigestRoot for SingleFieldStruct { - fn digest_root(self) -> Multihash { - self.field.digest_field("field".into()) - } - } - - #[derive(DigestRootMacro)] - struct DoubleFieldStruct { - foo: String, - bar: String, - } - - struct OtherStruct { - bar: String, - foo: String, - } - - impl DigestRoot for OtherStruct { - fn digest_root(self) -> Multihash { - let mut digests = vec![]; - let foo_digest = self.foo.digest_field("foo".into()); - digests.push(foo_digest); - let bar_digest = self.bar.digest_field("bar".into()); - digests.push(bar_digest); - - digests.sort(); - - let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); - res - }); - - digest(&res) - } - } - - #[test] - fn given_same_strings_return_same_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("simple string"); - - assert_eq!( - str1.digest_field("foo".into()), - str2.digest_field("foo".into()) - ) - } - - #[test] - fn given_same_strings_different_names_return_diff_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("simple string"); - - assert_ne!( - str1.digest_field("foo".into()), - str2.digest_field("bar".into()) - ) - } - - #[test] - fn given_different_strings_return_different_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("longer string."); - - assert_ne!( - str1.digest_field("foo".into()), - str2.digest_field("foo".into()) - ) - } - - #[test] - fn given_same_newtypes_return_same_multihash() { - let new_type1 = NewType("simple string".into()); - let new_type2 = NewType("simple string".into()); - - assert_eq!(new_type1.digest_root(), new_type2.digest_root()) - } - - #[test] - fn given_different_newtypes_return_different_multihash() { - let new_type1 = NewType("simple string".into()); - let new_type2 = NewType("longer string.".into()); - - assert_ne!(new_type1.digest_root(), new_type2.digest_root()) - } - - #[test] - fn given_same_single_field_struct_return_same_multihash() { - let struct1 = SingleFieldStruct { - field: "foo".into(), - }; - let struct2 = SingleFieldStruct { - field: "foo".into(), - }; - - assert_eq!(struct1.digest_root(), struct2.digest_root()) - } - - #[test] - fn given_single_field_struct_and_new_type_with_same_inner_return_different_multihash() { - let single_field_struct = SingleFieldStruct { - field: "foo".into(), - }; - let new_type = NewType("foo".into()); - - assert_ne!(single_field_struct.digest_root(), new_type.digest_root()) - } - - #[test] - fn given_same_double_field_struct_return_same_multihash() { - let struct1 = DoubleFieldStruct { - foo: "first field".into(), - bar: "second field".into(), - }; - let struct2 = DoubleFieldStruct { - foo: "first field".into(), - bar: "second field".into(), - }; - - assert_eq!(struct1.digest_root(), struct2.digest_root()) - } - - #[test] - fn given_different_double_field_struct_return_different_multihash() { - let struct1 = DoubleFieldStruct { - foo: "first field".into(), - bar: "second field".into(), - }; - let struct2 = DoubleFieldStruct { - foo: "first field".into(), - bar: "different field".into(), - }; - - assert_ne!(struct1.digest_root(), struct2.digest_root()) - } - - #[test] - fn given_two_double_field_struct_with_same_data_return_same_multihash() { - let struct1 = DoubleFieldStruct { - foo: "foo field".into(), - bar: "bar field".into(), - }; - let struct2 = OtherStruct { - bar: "bar field".into(), - foo: "foo field".into(), - }; - - assert_eq!(struct1.digest_root(), struct2.digest_root()) - } -} diff --git a/digest/Cargo.toml b/digest/Cargo.toml index d24ca1f5b2..11b11adf09 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -6,3 +6,6 @@ edition = "2018" [dependencies] multihash = "0.10" + +[dev-dependencies] +digest-macro-derive = { path = "../digest-macro-derive" } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs new file mode 100644 index 0000000000..4e992bd900 --- /dev/null +++ b/digest/tests/swap_digest.rs @@ -0,0 +1,165 @@ +use digest::{digest, DigestField, DigestRoot}; +use digest_macro_derive::DigestRootMacro; + +use digest::multihash::Multihash; + +struct NewType(String); + +impl DigestRoot for NewType { + fn digest_root(self) -> Multihash { + self.0.digest_field("".into()) + } +} + +struct SingleFieldStruct { + field: String, +} + +impl DigestRoot for SingleFieldStruct { + fn digest_root(self) -> Multihash { + self.field.digest_field("field".into()) + } +} + +#[derive(DigestRootMacro)] +struct DoubleFieldStruct { + foo: String, + bar: String, +} + +struct OtherStruct { + bar: String, + foo: String, +} + +impl DigestRoot for OtherStruct { + fn digest_root(self) -> Multihash { + let mut digests = vec![]; + let foo_digest = self.foo.digest_field("foo".into()); + digests.push(foo_digest); + let bar_digest = self.bar.digest_field("bar".into()); + digests.push(bar_digest); + + digests.sort(); + + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); + + digest(&res) + } +} + +#[test] +fn given_same_strings_return_same_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("simple string"); + + assert_eq!( + str1.digest_field("foo".into()), + str2.digest_field("foo".into()) + ) +} + +#[test] +fn given_same_strings_different_names_return_diff_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("simple string"); + + assert_ne!( + str1.digest_field("foo".into()), + str2.digest_field("bar".into()) + ) +} + +#[test] +fn given_different_strings_return_different_multihash() { + let str1 = String::from("simple string"); + let str2 = String::from("longer string."); + + assert_ne!( + str1.digest_field("foo".into()), + str2.digest_field("foo".into()) + ) +} + +#[test] +fn given_same_newtypes_return_same_multihash() { + let new_type1 = NewType("simple string".into()); + let new_type2 = NewType("simple string".into()); + + assert_eq!(new_type1.digest_root(), new_type2.digest_root()) +} + +#[test] +fn given_different_newtypes_return_different_multihash() { + let new_type1 = NewType("simple string".into()); + let new_type2 = NewType("longer string.".into()); + + assert_ne!(new_type1.digest_root(), new_type2.digest_root()) +} + +#[test] +fn given_same_single_field_struct_return_same_multihash() { + let struct1 = SingleFieldStruct { + field: "foo".into(), + }; + let struct2 = SingleFieldStruct { + field: "foo".into(), + }; + + assert_eq!(struct1.digest_root(), struct2.digest_root()) +} + +#[test] +fn given_single_field_struct_and_new_type_with_same_inner_return_different_multihash() { + let single_field_struct = SingleFieldStruct { + field: "foo".into(), + }; + let new_type = NewType("foo".into()); + + assert_ne!(single_field_struct.digest_root(), new_type.digest_root()) +} + +#[test] +fn given_same_double_field_struct_return_same_multihash() { + let struct1 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + let struct2 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + + assert_eq!(struct1.digest_root(), struct2.digest_root()) +} + +#[test] +fn given_different_double_field_struct_return_different_multihash() { + let struct1 = DoubleFieldStruct { + foo: "first field".into(), + bar: "second field".into(), + }; + let struct2 = DoubleFieldStruct { + foo: "first field".into(), + bar: "different field".into(), + }; + + assert_ne!(struct1.digest_root(), struct2.digest_root()) +} + +#[test] +fn given_two_double_field_struct_with_same_data_return_same_multihash() { + let struct1 = DoubleFieldStruct { + foo: "foo field".into(), + bar: "bar field".into(), + }; + let struct2 = OtherStruct { + bar: "bar field".into(), + foo: "foo field".into(), + }; + + assert_eq!(struct1.digest_root(), struct2.digest_root()) +} From 692e7c7e5de3f7f0f7cc22bde23f940f610d83d5 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:30:33 +1100 Subject: [PATCH 025/145] Use absolute path to avoid consumer having to do imports --- digest-macro-derive/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 9fdce92d41..d37382bcb3 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -22,8 +22,8 @@ fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); let gen = quote! { - impl DigestRoot for #name - where #(#types: DigestField),* + impl ::digest::DigestRoot for #name + where #(#types: ::digest::DigestField),* { fn digest_root(self) -> Multihash { let mut digests = vec![]; From 96480f9ed86e7a5facd44dd885ab932d8862b9a1 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:33:00 +1100 Subject: [PATCH 026/145] Improve panic message --- digest-macro-derive/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index d37382bcb3..1dea85ea08 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -42,7 +42,7 @@ fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { }; gen.into() } else { - panic!("DigestRootMacro does not support new types."); + panic!("DigestRootMacro only supports named filed, ie, no new types, tuples structs/variants or unit struct/variants."); } } else { panic!("DigestRootMacro only supports structs."); From 85ca60f1b2a93fad0b0b87e55a05f40967aa9acb Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:38:58 +1100 Subject: [PATCH 027/145] Improve trait names --- digest-macro-derive/src/lib.rs | 4 ++-- digest/src/lib.rs | 8 ++++---- digest/tests/swap_digest.rs | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 1dea85ea08..97e6635e37 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -22,8 +22,8 @@ fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); let gen = quote! { - impl ::digest::DigestRoot for #name - where #(#types: ::digest::DigestField),* + impl ::digest::RootDigest for #name + where #(#types: ::digest::FieldDigest),* { fn digest_root(self) -> Multihash { let mut digests = vec![]; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index de5831735b..1adb3f9f0f 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -8,15 +8,15 @@ pub fn digest(bytes: &[u8]) -> Multihash { multihash::Sha3_256::digest(bytes) } -pub trait DigestRoot { +pub trait RootDigest { fn digest_root(self) -> Multihash; } -pub trait DigestField { +pub trait FieldDigest { fn digest_field(self, field_name: String) -> Multihash; } -impl DigestField for String { +impl FieldDigest for String { fn digest_field(self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); let mut separator = SEPARATOR.to_vec(); @@ -28,7 +28,7 @@ impl DigestField for String { } } -impl DigestField for Vec { +impl FieldDigest for Vec { fn digest_field(mut self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); let mut separator = SEPARATOR.to_vec(); diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 4e992bd900..4dcb99106d 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,11 +1,11 @@ -use digest::{digest, DigestField, DigestRoot}; +use digest::{digest, FieldDigest, RootDigest}; use digest_macro_derive::DigestRootMacro; use digest::multihash::Multihash; struct NewType(String); -impl DigestRoot for NewType { +impl RootDigest for NewType { fn digest_root(self) -> Multihash { self.0.digest_field("".into()) } @@ -15,7 +15,7 @@ struct SingleFieldStruct { field: String, } -impl DigestRoot for SingleFieldStruct { +impl RootDigest for SingleFieldStruct { fn digest_root(self) -> Multihash { self.field.digest_field("field".into()) } @@ -32,7 +32,7 @@ struct OtherStruct { foo: String, } -impl DigestRoot for OtherStruct { +impl RootDigest for OtherStruct { fn digest_root(self) -> Multihash { let mut digests = vec![]; let foo_digest = self.foo.digest_field("foo".into()); From bf4289d0100716c40c4e79127273696bb1e7c3c2 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 10:44:29 +1100 Subject: [PATCH 028/145] Rolling with Sha256 for now --- digest/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 1adb3f9f0f..93b6a556ad 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -4,7 +4,6 @@ use multihash::Multihash; const SEPARATOR: &[u8; 1] = b":"; pub fn digest(bytes: &[u8]) -> Multihash { - // Time the tests and take fastest hash? multihash::Sha3_256::digest(bytes) } From 57245fab917a1a16482f7dfa5797c6a5bfb7f00d Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 12:04:53 +1100 Subject: [PATCH 029/145] For new types, still use a field name --- digest/tests/swap_digest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 4dcb99106d..2dc0cf4395 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -7,7 +7,7 @@ struct NewType(String); impl RootDigest for NewType { fn digest_root(self) -> Multihash { - self.0.digest_field("".into()) + self.0.digest_field("0".into()) } } From c0d7a47c8e689811370d41535d792f5ca1563230 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 13:23:29 +1100 Subject: [PATCH 030/145] Also rename trait function --- digest-macro-derive/src/lib.rs | 4 ++-- digest/src/lib.rs | 8 +++---- digest/tests/swap_digest.rs | 40 +++++++++++++++++----------------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 97e6635e37..ec9710edaa 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -25,9 +25,9 @@ fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { impl ::digest::RootDigest for #name where #(#types: ::digest::FieldDigest),* { - fn digest_root(self) -> Multihash { + fn root_digest(self) -> Multihash { let mut digests = vec![]; - #(digests.push(self.#idents.digest_field(stringify!(#idents).into())););* + #(digests.push(self.#idents.field_digest(stringify!(#idents).into())););* digests.sort(); diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 93b6a556ad..4eb3b04c0a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -8,15 +8,15 @@ pub fn digest(bytes: &[u8]) -> Multihash { } pub trait RootDigest { - fn digest_root(self) -> Multihash; + fn root_digest(self) -> Multihash; } pub trait FieldDigest { - fn digest_field(self, field_name: String) -> Multihash; + fn field_digest(self, field_name: String) -> Multihash; } impl FieldDigest for String { - fn digest_field(self, field_name: String) -> Multihash { + fn field_digest(self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); let mut separator = SEPARATOR.to_vec(); bytes.append(&mut separator); @@ -28,7 +28,7 @@ impl FieldDigest for String { } impl FieldDigest for Vec { - fn digest_field(mut self, field_name: String) -> Multihash { + fn field_digest(mut self, field_name: String) -> Multihash { let mut bytes = field_name.into_bytes(); let mut separator = SEPARATOR.to_vec(); bytes.append(&mut separator); diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 2dc0cf4395..1dcb950ee8 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -6,8 +6,8 @@ use digest::multihash::Multihash; struct NewType(String); impl RootDigest for NewType { - fn digest_root(self) -> Multihash { - self.0.digest_field("0".into()) + fn root_digest(self) -> Multihash { + self.0.field_digest("0".into()) } } @@ -16,8 +16,8 @@ struct SingleFieldStruct { } impl RootDigest for SingleFieldStruct { - fn digest_root(self) -> Multihash { - self.field.digest_field("field".into()) + fn root_digest(self) -> Multihash { + self.field.field_digest("field".into()) } } @@ -33,11 +33,11 @@ struct OtherStruct { } impl RootDigest for OtherStruct { - fn digest_root(self) -> Multihash { + fn root_digest(self) -> Multihash { let mut digests = vec![]; - let foo_digest = self.foo.digest_field("foo".into()); + let foo_digest = self.foo.field_digest("foo".into()); digests.push(foo_digest); - let bar_digest = self.bar.digest_field("bar".into()); + let bar_digest = self.bar.field_digest("bar".into()); digests.push(bar_digest); digests.sort(); @@ -57,8 +57,8 @@ fn given_same_strings_return_same_multihash() { let str2 = String::from("simple string"); assert_eq!( - str1.digest_field("foo".into()), - str2.digest_field("foo".into()) + str1.field_digest("foo".into()), + str2.field_digest("foo".into()) ) } @@ -68,8 +68,8 @@ fn given_same_strings_different_names_return_diff_multihash() { let str2 = String::from("simple string"); assert_ne!( - str1.digest_field("foo".into()), - str2.digest_field("bar".into()) + str1.field_digest("foo".into()), + str2.field_digest("bar".into()) ) } @@ -79,8 +79,8 @@ fn given_different_strings_return_different_multihash() { let str2 = String::from("longer string."); assert_ne!( - str1.digest_field("foo".into()), - str2.digest_field("foo".into()) + str1.field_digest("foo".into()), + str2.field_digest("foo".into()) ) } @@ -89,7 +89,7 @@ fn given_same_newtypes_return_same_multihash() { let new_type1 = NewType("simple string".into()); let new_type2 = NewType("simple string".into()); - assert_eq!(new_type1.digest_root(), new_type2.digest_root()) + assert_eq!(new_type1.root_digest(), new_type2.root_digest()) } #[test] @@ -97,7 +97,7 @@ fn given_different_newtypes_return_different_multihash() { let new_type1 = NewType("simple string".into()); let new_type2 = NewType("longer string.".into()); - assert_ne!(new_type1.digest_root(), new_type2.digest_root()) + assert_ne!(new_type1.root_digest(), new_type2.root_digest()) } #[test] @@ -109,7 +109,7 @@ fn given_same_single_field_struct_return_same_multihash() { field: "foo".into(), }; - assert_eq!(struct1.digest_root(), struct2.digest_root()) + assert_eq!(struct1.root_digest(), struct2.root_digest()) } #[test] @@ -119,7 +119,7 @@ fn given_single_field_struct_and_new_type_with_same_inner_return_different_multi }; let new_type = NewType("foo".into()); - assert_ne!(single_field_struct.digest_root(), new_type.digest_root()) + assert_ne!(single_field_struct.root_digest(), new_type.root_digest()) } #[test] @@ -133,7 +133,7 @@ fn given_same_double_field_struct_return_same_multihash() { bar: "second field".into(), }; - assert_eq!(struct1.digest_root(), struct2.digest_root()) + assert_eq!(struct1.root_digest(), struct2.root_digest()) } #[test] @@ -147,7 +147,7 @@ fn given_different_double_field_struct_return_different_multihash() { bar: "different field".into(), }; - assert_ne!(struct1.digest_root(), struct2.digest_root()) + assert_ne!(struct1.root_digest(), struct2.root_digest()) } #[test] @@ -161,5 +161,5 @@ fn given_two_double_field_struct_with_same_data_return_same_multihash() { foo: "foo field".into(), }; - assert_eq!(struct1.digest_root(), struct2.digest_root()) + assert_eq!(struct1.root_digest(), struct2.root_digest()) } From 2cd3d242d2a5b86a8cc6c432a5972b590e20b454 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 13:31:41 +1100 Subject: [PATCH 031/145] Re-export derive macro --- digest/Cargo.toml | 3 +-- digest/src/lib.rs | 2 ++ digest/tests/swap_digest.rs | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 11b11adf09..4aa526dd06 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -6,6 +6,5 @@ edition = "2018" [dependencies] multihash = "0.10" - -[dev-dependencies] digest-macro-derive = { path = "../digest-macro-derive" } + diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 4eb3b04c0a..e0be005258 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,3 +1,5 @@ +pub use digest_macro_derive::DigestRootMacro; + pub use multihash; use multihash::Multihash; diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 1dcb950ee8..a5928825b9 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,5 +1,4 @@ -use digest::{digest, FieldDigest, RootDigest}; -use digest_macro_derive::DigestRootMacro; +use digest::{digest, DigestRootMacro, FieldDigest, RootDigest}; use digest::multihash::Multihash; From 933c9acb4716235aa1156456c74e538eb1ac1533 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 14:03:19 +1100 Subject: [PATCH 032/145] Align macro name with trait name --- digest-macro-derive/src/lib.rs | 8 ++++---- digest/src/lib.rs | 2 +- digest/tests/swap_digest.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index ec9710edaa..aa2566e16d 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -4,13 +4,13 @@ use crate::proc_macro::TokenStream; use quote::quote; use syn::{Data, Fields}; -#[proc_macro_derive(DigestRootMacro)] -pub fn digest_root_macro_fn(input: TokenStream) -> TokenStream { +#[proc_macro_derive(RootDigestMacro)] +pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); - impl_digest_root_macro(&ast) + impl_root_digest_macro(&ast) } -fn impl_digest_root_macro(ast: &syn::DeriveInput) -> TokenStream { +fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; if let Data::Struct(data) = &ast.data { if let Fields::Named(fields) = &data.fields { diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e0be005258..e8411e254d 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,4 +1,4 @@ -pub use digest_macro_derive::DigestRootMacro; +pub use digest_macro_derive::RootDigestMacro; pub use multihash; use multihash::Multihash; diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index a5928825b9..5407ad1216 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,4 +1,4 @@ -use digest::{digest, DigestRootMacro, FieldDigest, RootDigest}; +use digest::{digest, FieldDigest, RootDigest, RootDigestMacro}; use digest::multihash::Multihash; @@ -20,7 +20,7 @@ impl RootDigest for SingleFieldStruct { } } -#[derive(DigestRootMacro)] +#[derive(RootDigestMacro)] struct DoubleFieldStruct { foo: String, bar: String, From 4d2bb5023670ebe9654803b9e77a9a727ba95242 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 16:59:05 +1100 Subject: [PATCH 033/145] Specify bytes to digest for fields via macro attribute --- Cargo.lock | 2 ++ digest-macro-derive/Cargo.toml | 1 + digest-macro-derive/src/lib.rs | 24 +++++++++++++++++++++--- digest/Cargo.toml | 1 + digest/src/lib.rs | 18 ++++++++++-------- digest/tests/swap_digest.rs | 6 ++++-- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5cf36a295..62a3742b28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -831,6 +831,7 @@ name = "digest" version = "0.1.0" dependencies = [ "digest-macro-derive", + "hex 0.4.2", "multihash", ] @@ -847,6 +848,7 @@ dependencies = [ name = "digest-macro-derive" version = "0.1.0" dependencies = [ + "hex 0.4.2", "quote 1.0.2", "syn 1.0.15", ] diff --git a/digest-macro-derive/Cargo.toml b/digest-macro-derive/Cargo.toml index 476276d0d9..ca9ee59b87 100644 --- a/digest-macro-derive/Cargo.toml +++ b/digest-macro-derive/Cargo.toml @@ -8,5 +8,6 @@ edition = "2018" proc-macro = true [dependencies] +hex = "0.4" quote = "1.0" syn = "1.0" diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index aa2566e16d..3ac6d8329f 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -2,9 +2,9 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; use quote::quote; -use syn::{Data, Fields}; +use syn::{Data, Fields, Lit, Meta}; -#[proc_macro_derive(RootDigestMacro)] +#[proc_macro_derive(RootDigestMacro, attributes(digest_bytes))] pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); impl_root_digest_macro(&ast) @@ -21,13 +21,31 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); + let bytes_str = fields.named.iter().map(|field| { + let attr = field + .attrs + .get(0) + .expect("digest_byte attribute must be present on all fields"); + let meta = attr.parse_meta().expect("Attribute is malformed"); + + if let Meta::NameValue(name_value) = meta { + if name_value.path.is_ident("digest_bytes") { + if let Lit::Str(lit_str) = name_value.lit { + return lit_str.value(); + } + } + } + panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); + }); + let gen = quote! { impl ::digest::RootDigest for #name where #(#types: ::digest::FieldDigest),* { fn root_digest(self) -> Multihash { + use ::digest::hex; let mut digests = vec![]; - #(digests.push(self.#idents.field_digest(stringify!(#idents).into())););* + #(digests.push(self.#idents.field_digest(hex::decode(#bytes_str).unwrap())););* digests.sort(); diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 4aa526dd06..72de82275c 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -5,6 +5,7 @@ authors = ["CoBloX "] edition = "2018" [dependencies] +hex = "0.4" multihash = "0.10" digest-macro-derive = { path = "../digest-macro-derive" } diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e8411e254d..2be5b5b65f 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,9 +1,10 @@ pub use digest_macro_derive::RootDigestMacro; +pub use hex; pub use multihash; use multihash::Multihash; -const SEPARATOR: &[u8; 1] = b":"; +const SEPARATOR: u8 = 0u8; pub fn digest(bytes: &[u8]) -> Multihash { multihash::Sha3_256::digest(bytes) @@ -14,14 +15,15 @@ pub trait RootDigest { } pub trait FieldDigest { - fn field_digest(self, field_name: String) -> Multihash; + fn field_digest(self, suffix: Vec) -> Multihash; } impl FieldDigest for String { - fn field_digest(self, field_name: String) -> Multihash { - let mut bytes = field_name.into_bytes(); - let mut separator = SEPARATOR.to_vec(); + fn field_digest(self, suffix: Vec) -> Multihash { + let mut bytes = suffix; + let mut separator = [SEPARATOR].to_vec(); bytes.append(&mut separator); + // String::into_bytes return the bytes for UTF-8 encoding let mut value = self.into_bytes(); bytes.append(&mut value); @@ -30,9 +32,9 @@ impl FieldDigest for String { } impl FieldDigest for Vec { - fn field_digest(mut self, field_name: String) -> Multihash { - let mut bytes = field_name.into_bytes(); - let mut separator = SEPARATOR.to_vec(); + fn field_digest(mut self, suffix: Vec) -> Multihash { + let mut bytes = suffix; + let mut separator = [SEPARATOR].to_vec(); bytes.append(&mut separator); bytes.append(&mut self); diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 5407ad1216..c7c710c409 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -22,7 +22,9 @@ impl RootDigest for SingleFieldStruct { #[derive(RootDigestMacro)] struct DoubleFieldStruct { + #[digest_bytes = "00"] foo: String, + #[digest_bytes = "FF"] bar: String, } @@ -34,9 +36,9 @@ struct OtherStruct { impl RootDigest for OtherStruct { fn root_digest(self) -> Multihash { let mut digests = vec![]; - let foo_digest = self.foo.field_digest("foo".into()); + let foo_digest = self.foo.field_digest([0u8].to_vec()); digests.push(foo_digest); - let bar_digest = self.bar.field_digest("bar".into()); + let bar_digest = self.bar.field_digest([0xFFu8].to_vec()); digests.push(bar_digest); digests.sort(); From c720d4a837ab55d837d3903dfc483344a44247fc Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 17:06:16 +1100 Subject: [PATCH 034/145] Ensure that digest_bytes value is correctly formatted It is not possible to pass `Vec` to `quote!` because it does not implement the `ToTokens` trait. So we pass the bytes as `String` instead. To be sure we do not have a runtime error, we try decoding the value at compilation time first. --- digest-macro-derive/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 3ac6d8329f..702b6e39b6 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -25,13 +25,17 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let attr = field .attrs .get(0) - .expect("digest_byte attribute must be present on all fields"); + .expect("digest_bytes attribute must be present on all fields"); let meta = attr.parse_meta().expect("Attribute is malformed"); if let Meta::NameValue(name_value) = meta { if name_value.path.is_ident("digest_bytes") { if let Lit::Str(lit_str) = name_value.lit { - return lit_str.value(); + let str = lit_str.value(); + // Ensure it is a correct format + let _ = ::hex::decode(&str) + .expect("digest_bytes value should be in hex format"); + return str; } } } From ac64ce6d2bd3af217e61e6ca9052ca1587a5fb72 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 12 Mar 2020 17:08:46 +1100 Subject: [PATCH 035/145] Remove separator --- digest/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 2be5b5b65f..e5629226f7 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -4,8 +4,6 @@ pub use hex; pub use multihash; use multihash::Multihash; -const SEPARATOR: u8 = 0u8; - pub fn digest(bytes: &[u8]) -> Multihash { multihash::Sha3_256::digest(bytes) } @@ -21,8 +19,6 @@ pub trait FieldDigest { impl FieldDigest for String { fn field_digest(self, suffix: Vec) -> Multihash { let mut bytes = suffix; - let mut separator = [SEPARATOR].to_vec(); - bytes.append(&mut separator); // String::into_bytes return the bytes for UTF-8 encoding let mut value = self.into_bytes(); bytes.append(&mut value); @@ -34,8 +30,6 @@ impl FieldDigest for String { impl FieldDigest for Vec { fn field_digest(mut self, suffix: Vec) -> Multihash { let mut bytes = suffix; - let mut separator = [SEPARATOR].to_vec(); - bytes.append(&mut separator); bytes.append(&mut self); digest(&self) From 662e4a18a54c5e44a216d3d6884e40de098f4741 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 13 Mar 2020 13:52:46 +1100 Subject: [PATCH 036/145] Remove runtime decoding error --- Cargo.lock | 1 + digest-macro-derive/Cargo.toml | 1 + digest-macro-derive/src/lib.rs | 37 +++++++++++++++++++++++++++------- digest/tests/swap_digest.rs | 8 ++++---- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62a3742b28..b5490590fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -849,6 +849,7 @@ name = "digest-macro-derive" version = "0.1.0" dependencies = [ "hex 0.4.2", + "proc-macro2 1.0.8", "quote 1.0.2", "syn 1.0.15", ] diff --git a/digest-macro-derive/Cargo.toml b/digest-macro-derive/Cargo.toml index ca9ee59b87..c606271b03 100644 --- a/digest-macro-derive/Cargo.toml +++ b/digest-macro-derive/Cargo.toml @@ -11,3 +11,4 @@ proc-macro = true hex = "0.4" quote = "1.0" syn = "1.0" +proc-macro2 = "1.0" diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 702b6e39b6..a817697af1 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -1,7 +1,8 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; -use quote::quote; +use proc_macro2::{Delimiter, Group, Punct, Spacing}; +use quote::{quote, ToTokens, TokenStreamExt}; use syn::{Data, Fields, Lit, Meta}; #[proc_macro_derive(RootDigestMacro, attributes(digest_bytes))] @@ -21,7 +22,7 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); - let bytes_str = fields.named.iter().map(|field| { + let bytes = fields.named.iter().map(|field| { let attr = field .attrs .get(0) @@ -32,10 +33,9 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { if name_value.path.is_ident("digest_bytes") { if let Lit::Str(lit_str) = name_value.lit { let str = lit_str.value(); - // Ensure it is a correct format - let _ = ::hex::decode(&str) + let bytes = ::hex::decode(&str) .expect("digest_bytes value should be in hex format"); - return str; + return Bytes(bytes); } } } @@ -47,9 +47,8 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { where #(#types: ::digest::FieldDigest),* { fn root_digest(self) -> Multihash { - use ::digest::hex; let mut digests = vec![]; - #(digests.push(self.#idents.field_digest(hex::decode(#bytes_str).unwrap())););* + #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* digests.sort(); @@ -70,3 +69,27 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { panic!("DigestRootMacro only supports structs."); } } + +struct Bytes(Vec); + +impl ToTokens for Bytes { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let mut inner_tokens = proc_macro2::TokenStream::new(); + inner_tokens.append_separated(&self.0, Punct::new(',', Spacing::Alone)); + let group = Group::new(Delimiter::Bracket, inner_tokens); + tokens.append(group); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn implement_to_token() { + let bytes = Bytes(vec![0u8, 1u8, 2u8, 3u8]); + + let tokens = quote!(#bytes); + assert_eq!(tokens.to_string(), "[ 0u8 , 1u8 , 2u8 , 3u8 ]"); + } +} diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index c7c710c409..980ef1e1e3 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -22,9 +22,9 @@ impl RootDigest for SingleFieldStruct { #[derive(RootDigestMacro)] struct DoubleFieldStruct { - #[digest_bytes = "00"] + #[digest_bytes = "0011"] foo: String, - #[digest_bytes = "FF"] + #[digest_bytes = "FFAA"] bar: String, } @@ -36,9 +36,9 @@ struct OtherStruct { impl RootDigest for OtherStruct { fn root_digest(self) -> Multihash { let mut digests = vec![]; - let foo_digest = self.foo.field_digest([0u8].to_vec()); + let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); digests.push(foo_digest); - let bar_digest = self.bar.field_digest([0xFFu8].to_vec()); + let bar_digest = self.bar.field_digest([0xFFu8, 0xAAu8].to_vec()); digests.push(bar_digest); digests.sort(); From 4a6605e27ab2411705d7da1f0e725111434f9895 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 13 Mar 2020 14:20:34 +1100 Subject: [PATCH 037/145] Format new Cargo.toml files --- Makefile | 4 ++++ digest-macro-derive/Cargo.toml | 2 +- digest/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3ce0728c68..6e7ba1db5d 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,8 @@ format: install_rustfmt install_tomlfmt RUST_LOG=error $(CARGO) tomlfmt -p Cargo.toml && git add Cargo.toml RUST_LOG=error $(CARGO) tomlfmt -p cnd/Cargo.toml && git add cnd/Cargo.toml RUST_LOG=error $(CARGO) tomlfmt -p libp2p-comit/Cargo.toml && git add libp2p-comit/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -p digest/Cargo.toml && git add digest/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -p digest-macro-derive/Cargo.toml && git add digest-macro-derive/Cargo.toml ifneq (,$(MODIFIED_TYPESCRIPT_FILES)) (cd ./api_tests; yarn install; yarn run fix) endif @@ -107,6 +109,8 @@ check_toml_format: install_tomlfmt RUST_LOG=error $(CARGO) tomlfmt -d -p Cargo.toml RUST_LOG=error $(CARGO) tomlfmt -d -p cnd/Cargo.toml RUST_LOG=error $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -d -p digest/Cargo.toml + RUST_LOG=error $(CARGO) tomlfmt -d -p digest-macro-derive/Cargo.toml check_ts_format: ifeq ($(CI),true) diff --git a/digest-macro-derive/Cargo.toml b/digest-macro-derive/Cargo.toml index c606271b03..c8fa155bc2 100644 --- a/digest-macro-derive/Cargo.toml +++ b/digest-macro-derive/Cargo.toml @@ -9,6 +9,6 @@ proc-macro = true [dependencies] hex = "0.4" +proc-macro2 = "1.0" quote = "1.0" syn = "1.0" -proc-macro2 = "1.0" diff --git a/digest/Cargo.toml b/digest/Cargo.toml index 72de82275c..0f04cdea1e 100644 --- a/digest/Cargo.toml +++ b/digest/Cargo.toml @@ -5,7 +5,7 @@ authors = ["CoBloX "] edition = "2018" [dependencies] +digest-macro-derive = { path = "../digest-macro-derive" } hex = "0.4" multihash = "0.10" -digest-macro-derive = { path = "../digest-macro-derive" } From a0ccdd5b36a1625de9888adf9aab115cf930f049 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 13 Mar 2020 15:11:24 +1100 Subject: [PATCH 038/145] Transform `let if` to `match` --- digest-macro-derive/src/lib.rs | 64 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index a817697af1..3ef9bb90d9 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -14,38 +14,43 @@ pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; if let Data::Struct(data) = &ast.data { - if let Fields::Named(fields) = &data.fields { - let idents = fields - .named - .iter() - .map(|field| field.ident.as_ref().expect("Named field")); + let (idents, types, bytes) = match &data.fields { + Fields::Named(fields) => { + let idents = fields + .named + .iter() + .map(|field| field.ident.as_ref().expect("Named field")); - let types = fields.named.iter().map(|field| &field.ty); + let types = fields.named.iter().map(|field| &field.ty); - let bytes = fields.named.iter().map(|field| { - let attr = field - .attrs - .get(0) - .expect("digest_bytes attribute must be present on all fields"); - let meta = attr.parse_meta().expect("Attribute is malformed"); + let bytes = fields.named.iter().map(|field| { + let attr = field + .attrs + .get(0) + .expect("digest_bytes attribute must be present on all fields"); + let meta = attr.parse_meta().expect("Attribute is malformed"); - if let Meta::NameValue(name_value) = meta { - if name_value.path.is_ident("digest_bytes") { - if let Lit::Str(lit_str) = name_value.lit { - let str = lit_str.value(); - let bytes = ::hex::decode(&str) - .expect("digest_bytes value should be in hex format"); - return Bytes(bytes); + if let Meta::NameValue(name_value) = meta { + if name_value.path.is_ident("digest_bytes") { + if let Lit::Str(lit_str) = name_value.lit { + let str = lit_str.value(); + let bytes = ::hex::decode(&str) + .expect("digest_bytes value should be in hex format"); + return Bytes(bytes); + } } } - } - panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); - }); + panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); + }); + (idents, types, bytes) + } + _ => panic!("Only supporting named fields."), + }; - let gen = quote! { - impl ::digest::RootDigest for #name - where #(#types: ::digest::FieldDigest),* - { + let gen = quote! { + impl ::digest::RootDigest for #name + where #(#types: ::digest::FieldDigest),* + { fn root_digest(self) -> Multihash { let mut digests = vec![]; #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* @@ -60,11 +65,8 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { digest(&res) } } - }; - gen.into() - } else { - panic!("DigestRootMacro only supports named filed, ie, no new types, tuples structs/variants or unit struct/variants."); - } + }; + gen.into() } else { panic!("DigestRootMacro only supports structs."); } From 322bb480ad77b70ea1e85a0c3db5a7d9a88b14d5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Sat, 14 Mar 2020 18:49:11 +1100 Subject: [PATCH 039/145] Update to Rust 1.42 Rust 1.42 already ships with the matches! macro by default, so we can remove that dependency. --- Cargo.lock | 1 - cnd/Cargo.toml | 1 - rust-toolchain | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5490590fa..db3c5b2a94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -558,7 +558,6 @@ dependencies = [ "libsqlite3-sys", "log 0.4.8", "lru", - "matches", "num 0.2.1", "paste", "pem", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index dad2522a41..b661ac8795 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -65,7 +65,6 @@ warp = { version = "0.2", default-features = false } [dev-dependencies] base64 = "0.12" bitcoincore-rpc = "0.9.1" -matches = "0.1.8" quickcheck = "0.9.2" regex = "1.3" serde_urlencoded = "0.6" diff --git a/rust-toolchain b/rust-toolchain index f86fb9cbcf..a50908ca3d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.41.1 +1.42.0 From f6ba2de39d1d91d5d540b4b75ed8f1a1699748cc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:13:43 +0000 Subject: [PATCH 040/145] Bump commander from 4.1.1 to 5.0.0 in /api_tests Bumps [commander](https://github.com/tj/commander.js) from 4.1.1 to 5.0.0. - [Release notes](https://github.com/tj/commander.js/releases) - [Changelog](https://github.com/tj/commander.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/tj/commander.js/compare/v4.1.1...v5.0.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 07932531ea..0412d8e8b3 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -50,7 +50,7 @@ "chai-string": "^1.5.0", "chai-subset": "^1.6.0", "comit-sdk": "^0.14.0", - "commander": "^4.1.1", + "commander": "^5.0.0", "ethers": "^4.0.45", "get-port": "^5.1.1", "glob": "^7.1.6", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 296067ff3a..b8aed319e4 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1928,10 +1928,10 @@ commander@^2.12.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== -commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== +commander@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0" + integrity sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ== component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.3.0" From 760176286f8b9365045a46f4d43ec9dac8dbf590 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:13:45 +0000 Subject: [PATCH 041/145] Bump proc-macro2 from 1.0.8 to 1.0.9 Bumps [proc-macro2](https://github.com/alexcrichton/proc-macro2) from 1.0.8 to 1.0.9. - [Release notes](https://github.com/alexcrichton/proc-macro2/releases) - [Commits](https://github.com/alexcrichton/proc-macro2/compare/1.0.8...1.0.9) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 64 +++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5490590fa..8d3a560fda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,7 +64,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61874b33258f18ca7923047c12887078ccfe95c2811b03c1a09e309c19b7e50b" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -174,7 +174,7 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -788,7 +788,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -811,7 +811,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -849,7 +849,7 @@ name = "digest-macro-derive" version = "0.1.0" dependencies = [ "hex 0.4.2", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -1094,7 +1094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -1199,7 +1199,7 @@ checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738" dependencies = [ "proc-macro-error", "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -1530,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e20558cac9252437815e7231074926454f1d59d9797fff4840d135a30c930a49" dependencies = [ "itertools", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2175,7 +2175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719ef0bc7f531428764c9b70661c14abd50a7f3d21f355752d9985aa21251c9e" dependencies = [ "migrations_internals", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2652,7 +2652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" dependencies = [ "proc-macro-hack", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2705,7 +2705,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2753,7 +2753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "rustversion", "syn 1.0.15", @@ -2765,7 +2765,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "rustversion", "syn 1.0.15", @@ -2778,7 +2778,7 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2800,9 +2800,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435" dependencies = [ "unicode-xid 0.2.0", ] @@ -2843,7 +2843,7 @@ checksum = "537aa19b95acde10a12fec4301466386f757403de4cd4e5b4fa78fb5ecb18f72" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -2902,7 +2902,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", ] [[package]] @@ -2999,7 +2999,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9fd3125016eb3257fe8038dcafaa5fbecc081bcd46defe9ccb98ceae0175219" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3158,7 +3158,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3315,7 +3315,7 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3529,7 +3529,7 @@ checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3547,7 +3547,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3592,7 +3592,7 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a0294dc449adc58bb6592fff1a23d3e5e6e235afc6a0ffca2657d19e7bbffe5" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "unicode-xid 0.2.0", ] @@ -3603,7 +3603,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3614,7 +3614,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", "unicode-xid 0.2.0", @@ -3674,7 +3674,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -3753,7 +3753,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", ] @@ -4137,7 +4137,7 @@ dependencies = [ "bumpalo", "lazy_static", "log 0.4.8", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", "wasm-bindgen-shared", @@ -4171,7 +4171,7 @@ version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", "wasm-bindgen-backend", @@ -4193,7 +4193,7 @@ dependencies = [ "anyhow", "heck", "log 0.4.8", - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", "wasm-bindgen-backend", @@ -4341,7 +4341,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ - "proc-macro2 1.0.8", + "proc-macro2 1.0.9", "quote 1.0.2", "syn 1.0.15", "synstructure", From 74a00d87d9a0b4f3ceeac5311d3e95256344947c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:14:18 +0000 Subject: [PATCH 042/145] Bump @types/chai from 4.2.10 to 4.2.11 in /api_tests Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.2.10 to 4.2.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 07932531ea..def26a67ed 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -21,7 +21,7 @@ "@iarna/toml": "^2.2.3", "@radar/lnrpc": "^0.9.0-beta", "@types/bitcoinjs-lib": "^5.0.0", - "@types/chai": "^4.2.10", + "@types/chai": "^4.2.11", "@types/chai-as-promised": "^7.1.2", "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 296067ff3a..5db6efc14b 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -524,10 +524,10 @@ dependencies: "@types/chai" "*" -"@types/chai@*", "@types/chai@4", "@types/chai@^4.2.10": - version "4.2.10" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.10.tgz#1122da40faabb81795580dc9f06c1e71e2ebbbe4" - integrity sha512-TlWWgb21+0LdkuFqEqfmy7NEgfB/7Jjux15fWQAh3P93gbmXuwTM/vxEdzW89APIcI2BgKR48yjeAkdeH+4qvQ== +"@types/chai@*", "@types/chai@4", "@types/chai@^4.2.11": + version "4.2.11" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.11.tgz#d3614d6c5f500142358e6ed24e1bf16657536c50" + integrity sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw== "@types/color-name@^1.1.1": version "1.1.1" From 32b58c8e753b7432b09c3126014136bf52917f02 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:14:26 +0000 Subject: [PATCH 043/145] Bump anyhow from 1.0.26 to 1.0.27 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.26 to 1.0.27. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.26...1.0.27) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5490590fa..6cba169b71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" +checksum = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785" [[package]] name = "array-init" From 5fb95234ef081e03360b8e4f496757ce6d50a6ed Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:14:51 +0000 Subject: [PATCH 044/145] Bump json-schema-to-typescript from 8.1.0 to 8.2.0 in /api_tests Bumps [json-schema-to-typescript](https://github.com/bcherny/json-schema-to-typescript) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/bcherny/json-schema-to-typescript/releases) - [Changelog](https://github.com/bcherny/json-schema-to-typescript/blob/master/CHANGELOG.md) - [Commits](https://github.com/bcherny/json-schema-to-typescript/commits) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 07932531ea..cea1bb8be4 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -56,7 +56,7 @@ "glob": "^7.1.6", "jest": "^25.1.0", "js-sha256": "^0.9.0", - "json-schema-to-typescript": "^8.1.0", + "json-schema-to-typescript": "^8.2.0", "ln-service": "^47.15.3", "log4js": "^6.1.2", "multiaddr": "^7.4.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 296067ff3a..cf32b9ebc6 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -565,6 +565,11 @@ resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.7.2.tgz#cd8a360c193ce4d672575a20a79f49ba036d38d2" integrity sha512-ifFemzjNchFBCtHS6bZNhSZCBu7tbtOe0e8qY0z2J4HtFXmPJjm6fXSaQsTG7yhShBEZtt2oP/bkwu5k+emlkQ== +"@types/is-glob@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.1.tgz#a93eec1714172c8eb3225a1cc5eb88c2477b7d00" + integrity sha512-k3RS5HyBPu4h+5hTmIEfPB2rl5P3LnGdQEZrV2b9OWTJVtsUQ2VBcedqYKGqxvZqle5UALUXdSfVA8nf3HfyWQ== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -624,7 +629,14 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*", "@types/node@>=4.5.0": +"@types/mkdirp@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" + integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== + dependencies: + "@types/node" "*" + +"@types/node@*": version "13.7.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== @@ -3287,6 +3299,11 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -3309,6 +3326,13 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + is-ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-2.0.0.tgz#68eea07e8a0a0a94c2d080dd674c731ab2a461ab" @@ -3891,19 +3915,23 @@ json-schema-ref-parser@^6.1.0: js-yaml "^3.12.1" ono "^4.0.11" -json-schema-to-typescript@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-8.1.0.tgz#c92174a3f70d5eb68646c1ab16cb6bcba6d1cbee" - integrity sha512-SGGX82OofMggPDUIO6+GYc14g8bew4ETtEif9G8I9SSXYFVHPSfoNE0AaNcfTFwI/xHSepHRse4aMurAtc8+mw== +json-schema-to-typescript@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-8.2.0.tgz#a859f836df89db63c5f17a6c9c2f1dea93e8dd9b" + integrity sha512-yvi4v9oLeJzJCktt+Zta6kOgEu8R93gNMZUJYo83aAPxoG0qB+cXIxVg5xa6gmdNkyffjH9Ebw1rvyaJKIor5A== dependencies: + "@types/is-glob" "^4.0.1" "@types/json-schema" "^7.0.3" - "@types/node" ">=4.5.0" + "@types/mkdirp" "^0.5.2" "@types/prettier" "^1.16.1" cli-color "^1.4.0" + glob "^7.1.4" + is-glob "^4.0.1" json-schema-ref-parser "^6.1.0" json-stringify-safe "^5.0.1" lodash "^4.17.11" minimist "^1.2.0" + mkdirp "^0.5.1" mz "^2.7.0" prettier "^1.19.1" stdin "0.0.1" From 328b88a0fd292d51543aed25fe05bb825113404d Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 14:15:05 +0000 Subject: [PATCH 045/145] Bump regex from 1.3.4 to 1.3.5 Bumps [regex](https://github.com/rust-lang/regex) from 1.3.4 to 1.3.5. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.3.4...1.3.5) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b5490590fa..9e46c5ccca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3023,9 +3023,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.4" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322cf97724bea3ee221b78fe25ac9c46114ebb51747ad5babd51a2fc6a8235a8" +checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048" dependencies = [ "aho-corasick", "memchr", @@ -3046,9 +3046,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.14" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" +checksum = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" [[package]] name = "remove_dir_all" From 0302d4e30caf04ce238d8d17297c89e3a4ebb5b8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 16:42:10 +0000 Subject: [PATCH 046/145] Bump @types/node from 13.9.0 to 13.9.1 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.0 to 13.9.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 2fec1584d1..995bc85707 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -636,10 +636,10 @@ dependencies: "@types/node" "*" -"@types/node@*": - version "13.7.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" - integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== +"@types/node@*", "@types/node@^13.9": + version "13.9.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" + integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== "@types/node@10.12.18": version "10.12.18" @@ -651,11 +651,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== -"@types/node@^13.9": - version "13.9.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.0.tgz#5b6ee7a77faacddd7de719017d0bc12f52f81589" - integrity sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ== - "@types/parse5@*": version "5.0.2" resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.2.tgz#a877a4658f8238c8266faef300ae41c84d72ec8a" From 0c13dd34d35fb5d088b1ac76a27a5952c14fcad8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 17:54:09 +0000 Subject: [PATCH 047/145] Bump quote from 1.0.2 to 1.0.3 Bumps [quote](https://github.com/dtolnay/quote) from 1.0.2 to 1.0.3. - [Release notes](https://github.com/dtolnay/quote/releases) - [Commits](https://github.com/dtolnay/quote/compare/1.0.2...1.0.3) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 70 +++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 368d0b0128..d56d2f98dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61874b33258f18ca7923047c12887078ccfe95c2811b03c1a09e309c19b7e50b" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -129,7 +129,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -175,7 +175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -789,7 +789,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -812,7 +812,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -850,7 +850,7 @@ version = "0.1.0" dependencies = [ "hex 0.4.2", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -1095,7 +1095,7 @@ checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -1200,7 +1200,7 @@ dependencies = [ "proc-macro-error", "proc-macro-hack", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -1531,7 +1531,7 @@ checksum = "e20558cac9252437815e7231074926454f1d59d9797fff4840d135a30c930a49" dependencies = [ "itertools", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -1744,7 +1744,7 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2176,7 +2176,7 @@ checksum = "719ef0bc7f531428764c9b70661c14abd50a7f3d21f355752d9985aa21251c9e" dependencies = [ "migrations_internals", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2653,7 +2653,7 @@ checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2706,7 +2706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2754,7 +2754,7 @@ checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" dependencies = [ "proc-macro-error-attr", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "rustversion", "syn 1.0.15", ] @@ -2766,7 +2766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "rustversion", "syn 1.0.15", "syn-mid", @@ -2779,7 +2779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2844,7 +2844,7 @@ dependencies = [ "anyhow", "itertools", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -2898,9 +2898,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" dependencies = [ "proc-macro2 1.0.9", ] @@ -3000,7 +3000,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9fd3125016eb3257fe8038dcafaa5fbecc081bcd46defe9ccb98ceae0175219" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3159,7 +3159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3316,7 +3316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3530,7 +3530,7 @@ dependencies = [ "heck", "proc-macro-error", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3548,7 +3548,7 @@ checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ "heck", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3593,7 +3593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a0294dc449adc58bb6592fff1a23d3e5e6e235afc6a0ffca2657d19e7bbffe5" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "unicode-xid 0.2.0", ] @@ -3604,7 +3604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3615,7 +3615,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", "unicode-xid 0.2.0", ] @@ -3675,7 +3675,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3754,7 +3754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -3814,7 +3814,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", ] @@ -4138,7 +4138,7 @@ dependencies = [ "lazy_static", "log 0.4.8", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", "wasm-bindgen-shared", ] @@ -4161,7 +4161,7 @@ version = "0.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" dependencies = [ - "quote 1.0.2", + "quote 1.0.3", "wasm-bindgen-macro-support", ] @@ -4172,7 +4172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", @@ -4194,7 +4194,7 @@ dependencies = [ "heck", "log 0.4.8", "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", "wasm-bindgen-backend", "weedle", @@ -4342,7 +4342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2 1.0.9", - "quote 1.0.2", + "quote 1.0.3", "syn 1.0.15", "synstructure", ] From 7f08fa03bfef6f17b7a98d29a1fbb27a55b79764 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 15 Mar 2020 19:14:01 +0000 Subject: [PATCH 048/145] Bump syn from 1.0.15 to 1.0.16 Bumps [syn](https://github.com/dtolnay/syn) from 1.0.15 to 1.0.16. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.15...1.0.16) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 66 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d56d2f98dd..ce3e68fe7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,7 +66,7 @@ checksum = "61874b33258f18ca7923047c12887078ccfe95c2811b03c1a09e309c19b7e50b" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -130,7 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -176,7 +176,7 @@ checksum = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -790,7 +790,7 @@ checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -813,7 +813,7 @@ checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -851,7 +851,7 @@ dependencies = [ "hex 0.4.2", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -1096,7 +1096,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -1201,7 +1201,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -1532,7 +1532,7 @@ dependencies = [ "itertools", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -1745,7 +1745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2177,7 +2177,7 @@ dependencies = [ "migrations_internals", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2654,7 +2654,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2707,7 +2707,7 @@ checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2756,7 +2756,7 @@ dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", "rustversion", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2768,7 +2768,7 @@ dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", "rustversion", - "syn 1.0.15", + "syn 1.0.16", "syn-mid", ] @@ -2780,7 +2780,7 @@ checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -2845,7 +2845,7 @@ dependencies = [ "itertools", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3001,7 +3001,7 @@ checksum = "c9fd3125016eb3257fe8038dcafaa5fbecc081bcd46defe9ccb98ceae0175219" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3160,7 +3160,7 @@ checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3317,7 +3317,7 @@ checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3531,7 +3531,7 @@ dependencies = [ "proc-macro-error", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3549,7 +3549,7 @@ dependencies = [ "heck", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3588,9 +3588,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0294dc449adc58bb6592fff1a23d3e5e6e235afc6a0ffca2657d19e7bbffe5" +checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", @@ -3605,7 +3605,7 @@ checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3616,7 +3616,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", "unicode-xid 0.2.0", ] @@ -3676,7 +3676,7 @@ checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3755,7 +3755,7 @@ checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -3815,7 +3815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", ] [[package]] @@ -4139,7 +4139,7 @@ dependencies = [ "log 0.4.8", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", "wasm-bindgen-shared", ] @@ -4173,7 +4173,7 @@ checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4195,7 +4195,7 @@ dependencies = [ "log 0.4.8", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", "wasm-bindgen-backend", "weedle", ] @@ -4343,6 +4343,6 @@ checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.15", + "syn 1.0.16", "synstructure", ] From 14ece4738f6a68caea4e2575978977f9aa6f382d Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 11 Mar 2020 10:44:49 +1100 Subject: [PATCH 049/145] Rename test environment to reflect actual usage --- api_tests/src/dry_test_environment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 3b74cb71d2..0af2863758 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -14,7 +14,7 @@ import path from "path"; // Setting global variables // // ************************ // -export default class E2ETestEnvironment extends NodeEnvironment { +export default class DryTestEnvironment extends NodeEnvironment { private docblockPragmas: Record; private projectRoot: string; private testRoot: string; @@ -55,7 +55,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { const { logDir } = this.extractDocblockPragmas(this.docblockPragmas); this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); - await E2ETestEnvironment.cleanLogDir(this.logDir); + await DryTestEnvironment.cleanLogDir(this.logDir); this.global.logRoot = this.logDir; } From 010191ba377e4414a2e7378ee3b46c134416f1ec Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 11 Mar 2020 10:45:21 +1100 Subject: [PATCH 050/145] Enable lnd tests --- api_tests/tests/e2e/bitcoin_ethereum.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index 03c9c3ca1a..0ffa403b5a 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -13,7 +13,7 @@ import { LedgerKind } from "../../lib/ledgers/ledger"; // Lightning Sanity Test // // ******************************************** // describe("E2E: Sanity - LND Alice pays Bob", () => { - it.skip( + it( "sanity-lnd-alice-pays-bob", twoActorTest(async ({ alice, bob }) => { await alice.sendRequest( @@ -28,7 +28,7 @@ describe("E2E: Sanity - LND Alice pays Bob", () => { }) ); - it.skip( + it( "sanity-lnd-alice-pays-bob-using-hold-invoice", twoActorTest(async ({ alice, bob }) => { await alice.sendRequest( From 93208a88ecf828669279ef86e7be9ad6424b44fd Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 11 Mar 2020 14:07:35 +1100 Subject: [PATCH 051/145] Start Lnd instances from E2ETestEnvironment --- api_tests/lib/actors/actor.ts | 63 ++----------- api_tests/lib/config.ts | 6 +- api_tests/lib/ledgers/ledger_runner.ts | 110 +++++++++++++++------- api_tests/lib/ledgers/lnd_instance.ts | 119 ++++++++++++++---------- api_tests/lib/utils.ts | 5 + api_tests/lib/wallets/bitcoin.ts | 2 +- api_tests/lib/wallets/index.ts | 33 ++++--- api_tests/lib/wallets/lightning.ts | 25 +++-- api_tests/src/e2e_test_environment.ts | 45 ++++++++- api_tests/tests/e2e/bitcoin_ethereum.ts | 2 +- 10 files changed, 227 insertions(+), 183 deletions(-) diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index f00965f565..2113034b33 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -42,9 +42,7 @@ export class Actor { const actorConfig = new E2ETestActorConfig( await getPort(), await getPort(), - name, - await getPort(), - await getPort() + name ); const cndInstance = new CndInstance( @@ -64,7 +62,7 @@ export class Actor { JSON.stringify(actorConfig.generateCndConfigFile(ledgerConfig)) ); - return new Actor(logger, cndInstance, logRoot, actorConfig, name); + return new Actor(logger, cndInstance, name); } public actors: Actors; @@ -88,8 +86,6 @@ export class Actor { constructor( private readonly logger: Logger, private readonly cndInstance: CndInstance, - private readonly logRoot: string, - private readonly config: E2ETestActorConfig, private name: string ) { this.wallets = new Wallets({}); @@ -193,38 +189,6 @@ export class Actor { to.betaAsset, ]); - const isLightning = - this.alphaLedger.name === "lightning" || - this.betaLedger.name === "lightning"; - - if (isLightning) { - this.logger.debug(`Initialising lightning for ${this.config.name}`); - const thisLightningWallet = this.wallets.getWalletForLedger( - "lightning" - ); - const toLightningWallet = to.wallets.getWalletForLedger( - "lightning" - ); - - await thisLightningWallet.connectPeer(toLightningWallet); - - if (this.alphaLedger.name === "lightning") { - // Alpha Ledger is lightning so Alice will be sending assets over lightning - const quantity = parseInt(this.alphaAsset.quantity, 10); - await thisLightningWallet.openChannel( - toLightningWallet, - quantity * 1.5 // Similarly to minting, we open a channel with a bit more than what is needed for the swap - ); - } else { - // Beta Ledger is lightning so Bob will be sending assets over lightning - const quantity = parseInt(this.betaAsset.quantity, 10); - await toLightningWallet.openChannel( - thisLightningWallet, - quantity * 1.5 // Similarly to minting, we open a channel with a bit more than what is needed for the swap - ); - } - } - this.expectedBalanceChanges.set( toKey(this.betaAsset), new BigNumber(this.betaAsset.quantity) @@ -234,6 +198,10 @@ export class Actor { new BigNumber(to.alphaAsset.quantity) ); + const isLightning = + this.alphaLedger.name === "lightning" || + this.betaLedger.name === "lightning"; + if (isLightning) { this.logger.debug("Using lightning routes on cnd REST API"); return; @@ -745,30 +713,13 @@ export class Actor { this.alphaLedger.name === "lightning" || this.betaLedger.name === "lightning"; - if (lightningNeeded) { - this.lndInstance = new LndInstance( - this.logger, - this.logRoot, - this.config, - global.ledgerConfigs.bitcoin.dataDir - ); - await this.lndInstance.start(); - } - const walletPromises: Promise[] = []; for (const ledgerName of [ this.alphaLedger.name, this.betaLedger.name, ]) { - let lnd; - if (this.lndInstance) { - lnd = { - lnd: this.lndInstance.lnd, - lndP2pSocket: this.lndInstance.getLightningSocket(), - }; - } walletPromises.push( - this.wallets.initializeForLedger(ledgerName, this.logger, lnd) + this.wallets.initializeForLedger(ledgerName, this.name) ); } diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 9aacb85c8e..5b64ca3fd4 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -1,6 +1,6 @@ import * as tmp from "tmp"; -import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { LedgerConfig } from "./ledgers/ledger_runner"; +import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; export interface CndConfigFile { @@ -20,9 +20,7 @@ export class E2ETestActorConfig { constructor( public readonly httpApiPort: number, public readonly comitPort: number, - public readonly name: string, - public readonly lndP2pPort: number, - public readonly lndRpcPort: number + public readonly name: string ) { this.httpApiPort = httpApiPort; this.comitPort = comitPort; diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index 731286dd9e..2a3b31a144 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -1,15 +1,19 @@ import getPort from "get-port"; import * as bitcoin from "./bitcoin"; -import { BitcoinNodeConfig } from "./bitcoin"; import { BitcoindInstance } from "./bitcoind_instance"; import { ParityInstance } from "./parity_instance"; import { EthereumWallet } from "../wallets/ethereum"; import { HarnessGlobal } from "../utils"; +import { LndInstance } from "./lnd_instance"; +import * as path from "path"; import { EthereumNodeConfig } from "./ethereum"; +import { BitcoinNodeConfig } from "./bitcoin"; export interface LedgerConfig { bitcoin?: BitcoinNodeConfig; ethereum?: EthereumNodeConfig; + lndAlice?: LndInstance; + lndBob?: LndInstance; } export interface LedgerInstance { @@ -35,7 +39,7 @@ export class LedgerRunner { ): Promise { const toBeStarted = ledgers.filter(name => !this.runningLedgers[name]); - const returnValue: LedgerConfig = {}; + const ledgerConfig: LedgerConfig = {}; const promises = toBeStarted.map(async ledger => { console.log(`Starting ledger ${ledger}`); @@ -65,8 +69,30 @@ export class LedgerRunner { instance: await instance.start(), }; } + case "lnd-alice": { + const instance = await LndInstance.new( + this.logDir, + "lnd-alice", + path.join(this.logDir, "bitcoind") + ); + return { + ledger, + instance: await instance.start(), + }; + } + case "lnd-bob": { + const instance = await LndInstance.new( + this.logDir, + "lnd-bob", + path.join(this.logDir, "bitcoind") + ); + return { + ledger, + instance: await instance.start(), + }; + } default: { - throw new Error(`Ledgerrunner does not support ${ledger}`); + throw new Error(`LedgerRunner does not support ${ledger}`); } } }); @@ -76,46 +102,60 @@ export class LedgerRunner { for (const { ledger, instance } of startedContainers) { this.runningLedgers[ledger] = instance; - if (ledger === "bitcoin") { - if (this.harnessGlobal.verbose) { - console.log( - "Bitcoin: initialization after ledger is running." + switch (ledger) { + case "bitcoin": { + if (this.harnessGlobal.verbose) { + console.log( + "Bitcoin: initialization after ledger is running." + ); + } + bitcoin.init(await this.getBitcoinClientConfig()); + await bitcoin.ensureFunding(); + this.blockTimers.bitcoin = this.harnessGlobal.setInterval( + async () => { + await bitcoin.generate(); + }, + 1000 + ); + ledgerConfig.bitcoin = await this.getBitcoinClientConfig().catch( + () => undefined ); + break; } - bitcoin.init(await this.getBitcoinClientConfig()); - await bitcoin.ensureFunding(); - this.blockTimers.bitcoin = this.harnessGlobal.setInterval( - async () => { - await bitcoin.generate(); - }, - 1000 - ); - returnValue.bitcoin = await this.getBitcoinClientConfig().catch( - () => undefined - ); - } - if (ledger === "ethereum") { - const ethereumNodeUrl = await this.getEthereumNodeUrl().catch( - () => undefined - ); - const erc20Wallet = new EthereumWallet(ethereumNodeUrl); - returnValue.ethereum = { - rpc_url: ethereumNodeUrl, - tokenContract: await erc20Wallet.deployErc20TokenContract( - this.projectRoot - ), - }; - if (this.harnessGlobal.verbose) { - console.log( - "Ethereum: deployed Erc20 contract at %s", - returnValue.ethereum.tokenContract + case "ethereum": { + const ethereumNodeUrl = await this.getEthereumNodeUrl().catch( + () => undefined ); + const erc20Wallet = new EthereumWallet(ethereumNodeUrl); + ledgerConfig.ethereum = { + rpc_url: ethereumNodeUrl, + tokenContract: await erc20Wallet.deployErc20TokenContract( + this.projectRoot + ), + }; + if (this.harnessGlobal.verbose) { + console.log( + "Ethereum: deployed Erc20 contract at %s", + ledgerConfig.ethereum.tokenContract + ); + } + break; + } + + case "lnd-alice": { + ledgerConfig.lndAlice = instance as LndInstance; + break; + } + + case "lnd-bob": { + ledgerConfig.lndBob = instance as LndInstance; + break; } } } - return returnValue; + return ledgerConfig; } public stopLedgers() { diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 11ef55103d..4af95762ce 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -1,8 +1,6 @@ import { ChildProcess, spawn } from "child_process"; -import { E2ETestActorConfig } from "../config"; import { mkdirAsync, waitUntilFileExists, writeFileAsync } from "../utils"; import * as path from "path"; -import { Logger } from "log4js"; import getPort from "get-port"; import { LogReader } from "./log_reader"; import { Lnd } from "comit-sdk"; @@ -11,100 +9,119 @@ export class LndInstance { private process: ChildProcess; private lndDir: string; public lnd: Lnd; - private publicKey?: string; + // private publicKey?: string; + + public static async new( + testLogDir: string, + name: string, + bitcoindDataDir: string + ) { + const lndP2pPort = await getPort(); + const lndRpcPort = await getPort(); + + return new LndInstance( + testLogDir, + name, + bitcoindDataDir, + lndP2pPort, + lndRpcPort + ); + } - constructor( - private readonly logger: Logger, + private constructor( private readonly testLogDir: string, - private readonly actorConfig: E2ETestActorConfig, - private readonly bitcoindDataDir: string + private readonly name: string, + private readonly bitcoindDataDir: string, + private readonly lndP2pPort: number, + private readonly lndRpcPort: number ) {} public async start() { - this.lndDir = path.join( - this.testLogDir, - "lnd-" + this.actorConfig.name - ); + this.lndDir = path.join(this.testLogDir, "lnd-" + this.name); await mkdirAsync(this.lndDir, "755"); await this.createConfigFile(); this.execBinary(); - this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); + // this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); await waitUntilFileExists(this.logPath()); - this.logger.debug("Waiting for lnd password RPC server"); + // this.logger.debug("Waiting for lnd password RPC server"); await this.logReader().waitForLogMessage( "RPCS: password RPC server listening" ); await this.initWallet(); - this.logger.debug("Waiting for lnd unlocked RPC server"); + // this.logger.debug("Waiting for lnd unlocked RPC server"); await this.logReader().waitForLogMessage("RPCS: RPC server listening"); - this.logger.debug( - "Waiting for admin macaroon file to exist:", - this.adminMacaroonPath() - ); + // this.logger.debug( + // "Waiting for admin macaroon file to exist:", + // this.adminMacaroonPath() + // ); await waitUntilFileExists(this.adminMacaroonPath()); - this.logger.debug("Waiting for lnd to catch up with blocks"); + // this.logger.debug("Waiting for lnd to catch up with blocks"); await this.logReader().waitForLogMessage( "LNWL: Done catching up block hashes" ); await this.initAuthenticatedLndConnection(); - this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; - this.logger.info("lnd is ready:", this.publicKey); + // this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; + // this.logger.info("lnd is ready:", this.publicKey); + + return this; } private execBinary() { const bin = process.env.LND_BIN ? process.env.LND_BIN : "lnd"; - this.logger.debug(`Using binary ${bin}`); + // this.logger.debug(`Using binary ${bin}`); this.process = spawn(bin, ["--lnddir", this.lndDir], { stdio: ["ignore", "ignore", "ignore"], // stdin, stdout, stderr. These are all logged already. }); - this.logger.debug(`Process spawned LND with PID ${this.process.pid}`); + // this.logger.debug(`Process spawned LND with PID ${this.process.pid}`); - this.process.on("exit", (code: number, signal: number) => { - this.logger.debug(`lnd exited with ${code || `signal ${signal}`}`); - }); + // this.process.on("exit", (code: number, signal: number) => { + // this.logger.debug(`lnd exited with ${code || `signal ${signal}`}`); + // }); } private async initWallet() { const config = { - server: this.getGrpcSocket(), + server: this.grpcSocket, tls: this.tlsCertPath(), }; - this.logger.debug("Instantiating lnd connection:", config); + // this.logger.debug("Instantiating lnd connection:", config); const lnd = await Lnd.init(config); - this.logger.debug("Calling genSeed"); - const { cipherSeedMnemonic } = await lnd.lnrpc.genSeed({}); + // this.logger.debug("Calling genSeed"); + const { cipherSeedMnemonic } = await lnd.lnrpc.genSeed({ + seedEntropy: this.name, + }); const walletPassword = Buffer.from("password", "utf8"); - this.logger.debug( - "Initialize wallet", - cipherSeedMnemonic, - walletPassword - ); + // this.logger.debug( + // "Initialize wallet", + // cipherSeedMnemonic, + // walletPassword + // ); await lnd.lnrpc.initWallet({ cipherSeedMnemonic, walletPassword }); - this.logger.debug("Wallet initialized!"); + // this.logger.debug("Wallet initialized!"); } private async initAuthenticatedLndConnection() { const config = { - server: this.getGrpcSocket(), + server: this.grpcSocket, tls: this.tlsCertPath(), macaroonPath: this.adminMacaroonPath(), }; - this.logger.debug("Instantiating lnd connection:", config); + // this.logger.debug("Instantiating lnd connection:", config); this.lnd = await Lnd.init(config); } public stop() { - this.logger.debug("Stopping lnd instance"); + // this.logger.debug("Stopping lnd instance"); this.process.kill("SIGTERM"); this.process = null; } @@ -132,28 +149,28 @@ export class LndInstance { ); } - public getGrpcSocket() { - return `${this.getGrpcHost()}:${this.getGrpcPort()}`; + get grpcSocket() { + return `${this.grpcHost}:${this.grpcPort}`; } - public getGrpcHost() { + get grpcHost() { return "127.0.0.1"; } - public getGrpcPort() { - return this.actorConfig.lndRpcPort; + get grpcPort() { + return this.lndRpcPort; } - public getLightningSocket() { - return `${this.getLightningHost()}:${this.getLightningPort()}`; + get p2pSocket() { + return `${this.p2pHost}:${this.p2pPort}`; } - public getLightningHost() { + get p2pHost() { return "127.0.0.1"; } - public getLightningPort() { - return this.actorConfig.lndP2pPort; + get p2pPort() { + return this.lndP2pPort; } private async createConfigFile() { @@ -163,10 +180,10 @@ export class LndInstance { debuglevel=trace ; peer to peer port -listen=127.0.0.1:${this.actorConfig.lndP2pPort} +listen=127.0.0.1:${this.lndP2pPort} ; gRPC -rpclisten=127.0.0.1:${this.actorConfig.lndRpcPort} +rpclisten=127.0.0.1:${this.lndRpcPort} ; REST interface restlisten=127.0.0.1:${restPort} diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index 0d3a133522..5f346605e8 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -8,9 +8,14 @@ import { LedgerConfig } from "./ledgers/ledger_runner"; import rimraf from "rimraf"; import { Mutex } from "async-mutex"; import { exec } from "child_process"; +import { LightningWallet } from "./wallets/lightning"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; + lndWallets: { + alice?: LightningWallet; + bob?: LightningWallet; + }; testRoot: string; projectRoot: string; logRoot: string; diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/lib/wallets/bitcoin.ts index e07f549640..8e872a29fa 100644 --- a/api_tests/lib/wallets/bitcoin.ts +++ b/api_tests/lib/wallets/bitcoin.ts @@ -6,8 +6,8 @@ import { InMemoryBitcoinWallet as BitcoinWalletSdk, } from "comit-sdk"; import { toBitcoin, toSatoshi } from "satoshi-bitcoin"; -import { BitcoinNodeConfig } from "../ledgers/bitcoin"; import { pollUntilMinted, Wallet } from "./index"; +import { BitcoinNodeConfig } from "../ledgers/bitcoin"; export class BitcoinWallet implements Wallet { public static async newInstance(config: BitcoinNodeConfig) { diff --git a/api_tests/lib/wallets/index.ts b/api_tests/lib/wallets/index.ts index 639c540431..83da0181e4 100644 --- a/api_tests/lib/wallets/index.ts +++ b/api_tests/lib/wallets/index.ts @@ -1,9 +1,8 @@ -import { Asset, BigNumber, Lnd } from "comit-sdk"; +import { Asset, BigNumber } from "comit-sdk"; import { HarnessGlobal, sleep } from "../utils"; import { BitcoinWallet } from "./bitcoin"; import { EthereumWallet } from "./ethereum"; import { LightningWallet } from "./lightning"; -import { Logger } from "log4js"; declare var global: HarnessGlobal; @@ -49,8 +48,7 @@ export class Wallets { public async initializeForLedger( name: K, - logger: Logger, - lnd: { lnd: Lnd; lndP2pSocket: string } | undefined + actor?: string ) { switch (name) { case "ethereum": @@ -64,20 +62,21 @@ export class Wallets { ); break; case "lightning": - if (!lnd) { - throw new Error( - "Lnd is needed to instantiate lightning wallet." - ); + switch (actor) { + case "alice": { + this.wallets.lightning = global.lndWallets.alice; + break; + } + case "bob": { + this.wallets.lightning = global.lndWallets.bob; + break; + } + default: { + throw new Error( + `Cannot initialize Lightning wallet for actor: '${actor}'` + ); + } } - this.wallets.lightning = await LightningWallet.newInstance( - await BitcoinWallet.newInstance( - global.ledgerConfigs.bitcoin - ), - logger, - lnd.lnd, - lnd.lndP2pSocket - ); - break; } } } diff --git a/api_tests/lib/wallets/lightning.ts b/api_tests/lib/wallets/lightning.ts index d1a0e9dfac..36d921c4db 100644 --- a/api_tests/lib/wallets/lightning.ts +++ b/api_tests/lib/wallets/lightning.ts @@ -1,7 +1,6 @@ import { pollUntilMinted, Wallet } from "./index"; import { Asset } from "../asset"; import BigNumber from "bignumber.js"; -import { Logger } from "log4js"; import { BitcoinWallet } from "./bitcoin"; import { sleep } from "../utils"; import { @@ -14,7 +13,7 @@ import { AddressType } from "@radar/lnrpc"; export class LightningWallet implements Wallet { public static async newInstance( bitcoinWallet: BitcoinWallet, - logger: Logger, + // logger: Logger, lnd: Lnd, lndp2pSocket: string ) { @@ -25,16 +24,16 @@ export class LightningWallet implements Wallet { lndp2pSocket ); - logger.debug("lnd getinfo:", await inner.lnd.lnrpc.getInfo()); + // logger.debug("lnd getinfo:", await inner.lnd.lnrpc.getInfo()); - return new LightningWallet(inner, logger, bitcoinWallet); + return new LightningWallet(inner, bitcoinWallet); } public MaximumFee = 0; private constructor( public readonly inner: LightningWalletSdk, - private readonly logger: Logger, + // private readonly logger: Logger, private readonly bitcoinWallet: BitcoinWallet ) {} @@ -48,10 +47,10 @@ export class LightningWallet implements Wallet { const startingBalance = new BigNumber( await this.getBalanceByAsset(asset) ); - this.logger.debug("starting: ", startingBalance.toString()); + // this.logger.debug("starting: ", startingBalance.toString()); const minimumExpectedBalance = new BigNumber(asset.quantity); - this.logger.debug("min expected: ", minimumExpectedBalance.toString()); + // this.logger.debug("min expected: ", minimumExpectedBalance.toString()); await this.bitcoinWallet.mintToAddress( minimumExpectedBalance, @@ -113,9 +112,9 @@ export class LightningWallet implements Wallet { let toIsSynced = (await toWallet.inner.getInfo()).syncedToChain; while (!thisIsSynced || !toIsSynced) { - this.logger.info( - `One of the lnd node is not yet synced, waiting. this: ${thisIsSynced}, to: ${toIsSynced}` - ); + // this.logger.info( + // `One of the lnd node is not yet synced, waiting. this: ${thisIsSynced}, to: ${toIsSynced}` + // ); await sleep(500); thisIsSynced = (await this.inner.getInfo()).syncedToChain; @@ -126,7 +125,7 @@ export class LightningWallet implements Wallet { await toWallet.inner.getPubkey(), quantity ); - this.logger.debug("Channel opened, waiting for confirmations"); + // this.logger.debug("Channel opened, waiting for confirmations"); await this.pollUntilChannelIsOpen(outpoint); } @@ -162,9 +161,9 @@ export class LightningWallet implements Wallet { const channels = await this.getChannels(); if (channels) { for (const channel of channels) { - this.logger.debug(`Looking for channel ${txId}:${vout}`); + // this.logger.debug(`Looking for channel ${txId}:${vout}`); if (channel.channelPoint === `${txId}:${vout}`) { - this.logger.debug("Found a channel:", channel); + // this.logger.debug("Found a channel:", channel); return; } } diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 074f456671..234dba6ecc 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -9,6 +9,8 @@ import { import NodeEnvironment from "jest-environment-node"; import { Mutex } from "async-mutex"; import path from "path"; +import { LightningWallet } from "../lib/wallets/lightning"; +import { BitcoinWallet } from "../lib/wallets/bitcoin"; // ************************ // // Setting global variables // @@ -42,6 +44,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.global.projectRoot = this.projectRoot; this.global.testRoot = this.testRoot; this.global.ledgerConfigs = {}; + this.global.lndWallets = {}; this.global.verbose = this.global.process.argv.find(item => item.includes("verbose")) !== undefined; @@ -73,12 +76,44 @@ export default class E2ETestEnvironment extends NodeEnvironment { const ledgerConfig = await this.ledgerRunner.ensureLedgersRunning( ledgers ); - this.global.tokenContract = ledgerConfig.ethereum.tokenContract; - this.global.ledgerConfigs = { - bitcoin: ledgerConfig.bitcoin, - ethereum: ledgerConfig.ethereum, - }; + + const ethereum = ledgerConfig.ethereum; + if (ethereum) { + this.global.tokenContract = ethereum.tokenContract; + this.global.ledgerConfigs.ethereum = ethereum; + } + + const bitcoin = ledgerConfig.bitcoin; + if (bitcoin) { + this.global.ledgerConfigs.bitcoin = bitcoin; + } + + const lndAlice = ledgerConfig.lndAlice; + const lndBob = ledgerConfig.lndBob; + + if (lndAlice && lndBob && bitcoin) { + this.global.ledgerConfigs.lndAlice = lndAlice; + this.global.ledgerConfigs.lndBob = lndBob; + + const aliceWallet = await LightningWallet.newInstance( + await BitcoinWallet.newInstance(bitcoin), + lndAlice.lnd, + lndAlice.p2pSocket + ); + const bobWallet = await LightningWallet.newInstance( + await BitcoinWallet.newInstance(bitcoin), + lndBob.lnd, + lndBob.p2pSocket + ); + this.global.lndWallets = { + alice: aliceWallet, + bob: bobWallet, + }; + + await aliceWallet.connectPeer(bobWallet); + } } + this.global.logRoot = this.logDir; } diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index 0ffa403b5a..ad399b1132 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -1,5 +1,5 @@ /** - * @ledgers ethereum,bitcoin + * @ledgers ethereum,bitcoin,lnd-alice,lnd-bob * @logDir e2e */ From 15d4e3b0d638f0c9034791596682ff804c76721c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 15:25:21 +1100 Subject: [PATCH 052/145] Pass 16 bytes to lnd Otherwise, the genseed call fails --- api_tests/lib/ledgers/lnd_instance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 4af95762ce..8c1613941d 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -98,7 +98,7 @@ export class LndInstance { // this.logger.debug("Calling genSeed"); const { cipherSeedMnemonic } = await lnd.lnrpc.genSeed({ - seedEntropy: this.name, + seedEntropy: Buffer.alloc(16, this.name), }); const walletPassword = Buffer.from("password", "utf8"); // this.logger.debug( From 950573c4620adfd242836a7a1d7877aed9145d82 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 15:25:53 +1100 Subject: [PATCH 053/145] Start ledgers sequentially lnd needs bitcoind to be up, otherwise it fails to start --- api_tests/lib/ledgers/ledger_runner.ts | 29 +++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index 2a3b31a144..078c5f7d1f 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -39,8 +39,11 @@ export class LedgerRunner { ): Promise { const toBeStarted = ledgers.filter(name => !this.runningLedgers[name]); + const startedContainers = []; + const ledgerConfig: LedgerConfig = {}; - const promises = toBeStarted.map(async ledger => { + + for (const ledger of toBeStarted) { console.log(`Starting ledger ${ledger}`); switch (ledger) { @@ -53,10 +56,11 @@ export class LedgerRunner { await getPort({ port: 28332 }), await getPort({ port: 28333 }) ); - return { + startedContainers.push({ ledger, instance: await instance.start(), - }; + }); + break; } case "ethereum": { const instance = new ParityInstance( @@ -64,10 +68,11 @@ export class LedgerRunner { this.logDir, await getPort({ port: 8545 }) ); - return { + startedContainers.push({ ledger, instance: await instance.start(), - }; + }); + break; } case "lnd-alice": { const instance = await LndInstance.new( @@ -75,10 +80,11 @@ export class LedgerRunner { "lnd-alice", path.join(this.logDir, "bitcoind") ); - return { + startedContainers.push({ ledger, instance: await instance.start(), - }; + }); + break; } case "lnd-bob": { const instance = await LndInstance.new( @@ -86,18 +92,17 @@ export class LedgerRunner { "lnd-bob", path.join(this.logDir, "bitcoind") ); - return { + startedContainers.push({ ledger, instance: await instance.start(), - }; + }); + break; } default: { throw new Error(`LedgerRunner does not support ${ledger}`); } } - }); - - const startedContainers = await Promise.all(promises); + } for (const { ledger, instance } of startedContainers) { this.runningLedgers[ledger] = instance; From 82c99a51549e45538a45c508499eaa2bb03ba924 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 12 Mar 2020 18:14:01 +1100 Subject: [PATCH 054/145] Open channel in test environment --- api_tests/lib/actors/actor.ts | 1 + api_tests/src/e2e_test_environment.ts | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index 2113034b33..c9820373a6 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -755,6 +755,7 @@ export class Actor { const ledgerName = ledger.name; this.logger.debug("Minting %s on %s", asset.name, ledgerName); + await this.wallets.getWalletForLedger(ledgerName).mint(asset); const balance = await this.wallets[ledgerName].getBalanceByAsset( diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 234dba6ecc..be02243270 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -11,6 +11,8 @@ import { Mutex } from "async-mutex"; import path from "path"; import { LightningWallet } from "../lib/wallets/lightning"; import { BitcoinWallet } from "../lib/wallets/bitcoin"; +import { AssetKind } from "../lib/asset"; +import { LedgerKind } from "../lib/ledgers/ledger"; // ************************ // // Setting global variables // @@ -111,6 +113,14 @@ export default class E2ETestEnvironment extends NodeEnvironment { }; await aliceWallet.connectPeer(bobWallet); + + await aliceWallet.mint({ + name: AssetKind.Bitcoin, + ledger: LedgerKind.Lightning, + quantity: "15000000", + }); + + await aliceWallet.openChannel(bobWallet, 15000000); } } From 26b6375730d5003ac2019381f86b10a083549b1c Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 13:21:04 +1100 Subject: [PATCH 055/145] Try to get full path to lnd before executing it --- api_tests/lib/ledgers/lnd_instance.ts | 9 ++++++--- api_tests/package.json | 1 + api_tests/types/@wcjiang__whereis/index.d.ts | 3 +++ api_tests/yarn.lock | 5 +++++ 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 api_tests/types/@wcjiang__whereis/index.d.ts diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 8c1613941d..19db0ee23e 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -4,6 +4,7 @@ import * as path from "path"; import getPort from "get-port"; import { LogReader } from "./log_reader"; import { Lnd } from "comit-sdk"; +import whereis from "@wcjiang/whereis"; export class LndInstance { private process: ChildProcess; @@ -41,7 +42,7 @@ export class LndInstance { await mkdirAsync(this.lndDir, "755"); await this.createConfigFile(); - this.execBinary(); + await this.execBinary(); // this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); await waitUntilFileExists(this.logPath()); @@ -75,8 +76,10 @@ export class LndInstance { return this; } - private execBinary() { - const bin = process.env.LND_BIN ? process.env.LND_BIN : "lnd"; + private async execBinary() { + const bin = process.env.LND_BIN + ? process.env.LND_BIN + : await whereis("lnd"); // this.logger.debug(`Using binary ${bin}`); this.process = spawn(bin, ["--lnddir", this.lndDir], { stdio: ["ignore", "ignore", "ignore"], // stdin, stdout, stderr. These are all logged already. diff --git a/api_tests/package.json b/api_tests/package.json index bac9c42ee5..ab814ca848 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -36,6 +36,7 @@ "@types/tail": "^2.0.0", "@types/tempfile": "^3.0.0", "@types/urijs": "^1.19.7", + "@wcjiang/whereis": "^1.0.0", "async-mutex": "^0.1.4", "bcoin": "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001", "bignumber.js": "^9.0.0", diff --git a/api_tests/types/@wcjiang__whereis/index.d.ts b/api_tests/types/@wcjiang__whereis/index.d.ts new file mode 100644 index 0000000000..876126f8fa --- /dev/null +++ b/api_tests/types/@wcjiang__whereis/index.d.ts @@ -0,0 +1,3 @@ +declare module "@wcjiang/whereis" { + export default async function whereis(cmd: string): Promise; +} diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index b3c6386a20..380a61703e 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -740,6 +740,11 @@ dependencies: uuid "^3.0.1" +"@wcjiang/whereis@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@wcjiang/whereis/-/whereis-1.0.0.tgz#0e6c0020634784eba683a677660307a24fdc3f8a" + integrity sha512-WwYgGSo0krJvcmHHTdif9ooQJW154vEhq6uAGT1PDMsZv5eTsuzYtLl1jojQZKzHRIgIptOM5MCLMg/0verHxw== + JSONStream@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" From 39eb53afc239b7045e17726fd07f788fca334666 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 13:28:51 +1100 Subject: [PATCH 056/145] Aquire necessary ports inside factory fn of BitcoindInstance This simplifies constructing the instance. --- api_tests/lib/ledgers/bitcoind_instance.ts | 12 ++++++++++++ api_tests/lib/ledgers/ledger_runner.ts | 8 ++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index e7e5eb3a65..ead8e59d9b 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -4,6 +4,7 @@ import { LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import * as path from "path"; import { openAsync, mkdirAsync, writeFileAsync } from "../utils"; +import getPort from "get-port"; export class BitcoindInstance implements LedgerInstance { private process: ChildProcess; @@ -11,6 +12,17 @@ export class BitcoindInstance implements LedgerInstance { private username: string; private password: string; + public static async new(projectRoot: string, logDir: string) { + return new BitcoindInstance( + projectRoot, + logDir, + await getPort({ port: 18444 }), + await getPort({ port: 18443 }), + await getPort({ port: 28332 }), + await getPort({ port: 28333 }) + ); + } + constructor( private readonly projectRoot: string, private readonly logDir: string, diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index 078c5f7d1f..5960c8884a 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -48,13 +48,9 @@ export class LedgerRunner { switch (ledger) { case "bitcoin": { - const instance = new BitcoindInstance( + const instance = await BitcoindInstance.new( this.projectRoot, - this.logDir, - await getPort({ port: 18444 }), - await getPort({ port: 18443 }), - await getPort({ port: 28332 }), - await getPort({ port: 28333 }) + this.logDir ); startedContainers.push({ ledger, From fb7c2de0ec2d9313cfff8b1f5c912e6d248103f7 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 13:31:20 +1100 Subject: [PATCH 057/145] Aquire ports inside factory fn of ParityInstance --- api_tests/lib/ledgers/ledger_runner.ts | 6 ++---- api_tests/lib/ledgers/parity_instance.ts | 9 +++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index 5960c8884a..d3898e022e 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -1,4 +1,3 @@ -import getPort from "get-port"; import * as bitcoin from "./bitcoin"; import { BitcoindInstance } from "./bitcoind_instance"; import { ParityInstance } from "./parity_instance"; @@ -59,10 +58,9 @@ export class LedgerRunner { break; } case "ethereum": { - const instance = new ParityInstance( + const instance = await ParityInstance.new( this.projectRoot, - this.logDir, - await getPort({ port: 8545 }) + this.logDir ); startedContainers.push({ ledger, diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index 1c497bd95e..05c957b087 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -5,6 +5,7 @@ import { LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import { promisify } from "util"; import { sleep } from "../utils"; +import getPort from "get-port"; const openAsync = promisify(fs.open); @@ -12,6 +13,14 @@ export class ParityInstance implements LedgerInstance { private process: ChildProcess; private dbDir: any; + public static async new(projectRoot: string, logDir: string) { + return new ParityInstance( + projectRoot, + logDir, + await getPort({ port: 8545 }) + ); + } + constructor( private readonly projectRoot: string, private readonly logDir: string, From 7d53da8b6df334cade468e8d826b149e32f75da5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 13:36:32 +1100 Subject: [PATCH 058/145] Merge new and start into one function We always start the instance right after we construct it, this saves the caller a separate call to `start`. --- api_tests/lib/ledgers/bitcoind_instance.ts | 10 +++--- api_tests/lib/ledgers/ledger_runner.ts | 41 ++++++++++------------ api_tests/lib/ledgers/lnd_instance.ts | 10 +++--- api_tests/lib/ledgers/parity_instance.ts | 9 +++-- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index ead8e59d9b..d64f6ccf23 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -12,8 +12,8 @@ export class BitcoindInstance implements LedgerInstance { private username: string; private password: string; - public static async new(projectRoot: string, logDir: string) { - return new BitcoindInstance( + public static async start(projectRoot: string, logDir: string) { + const instance = new BitcoindInstance( projectRoot, logDir, await getPort({ port: 18444 }), @@ -21,6 +21,10 @@ export class BitcoindInstance implements LedgerInstance { await getPort({ port: 28332 }), await getPort({ port: 28333 }) ); + + await instance.start(); + + return instance; } constructor( @@ -73,8 +77,6 @@ export class BitcoindInstance implements LedgerInstance { this.username = username; this.password = password; - - return this; } public stop() { diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index d3898e022e..d1e8044184 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -16,7 +16,6 @@ export interface LedgerConfig { } export interface LedgerInstance { - start(): Promise; stop(): void; } @@ -47,48 +46,44 @@ export class LedgerRunner { switch (ledger) { case "bitcoin": { - const instance = await BitcoindInstance.new( - this.projectRoot, - this.logDir - ); startedContainers.push({ ledger, - instance: await instance.start(), + instance: await BitcoindInstance.start( + this.projectRoot, + this.logDir + ), }); break; } case "ethereum": { - const instance = await ParityInstance.new( - this.projectRoot, - this.logDir - ); startedContainers.push({ ledger, - instance: await instance.start(), + instance: await ParityInstance.start( + this.projectRoot, + this.logDir + ), }); break; } case "lnd-alice": { - const instance = await LndInstance.new( - this.logDir, - "lnd-alice", - path.join(this.logDir, "bitcoind") - ); startedContainers.push({ ledger, - instance: await instance.start(), + instance: await LndInstance.start( + this.logDir, + "lnd-alice", + path.join(this.logDir, "bitcoind") + ), }); break; } case "lnd-bob": { - const instance = await LndInstance.new( - this.logDir, - "lnd-bob", - path.join(this.logDir, "bitcoind") - ); startedContainers.push({ ledger, - instance: await instance.start(), + instance: await LndInstance.start( + this.logDir, + "lnd-bob", + path.join(this.logDir, "bitcoind") + ), }); break; } diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 19db0ee23e..c393be52e8 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -12,7 +12,7 @@ export class LndInstance { public lnd: Lnd; // private publicKey?: string; - public static async new( + public static async start( testLogDir: string, name: string, bitcoindDataDir: string @@ -20,13 +20,17 @@ export class LndInstance { const lndP2pPort = await getPort(); const lndRpcPort = await getPort(); - return new LndInstance( + const instance = new LndInstance( testLogDir, name, bitcoindDataDir, lndP2pPort, lndRpcPort ); + + await instance.start(); + + return instance; } private constructor( @@ -72,8 +76,6 @@ export class LndInstance { // this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; // this.logger.info("lnd is ready:", this.publicKey); - - return this; } private async execBinary() { diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index 05c957b087..6d040d87c1 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -13,12 +13,16 @@ export class ParityInstance implements LedgerInstance { private process: ChildProcess; private dbDir: any; - public static async new(projectRoot: string, logDir: string) { - return new ParityInstance( + public static async start(projectRoot: string, logDir: string) { + const instance = new ParityInstance( projectRoot, logDir, await getPort({ port: 8545 }) ); + + await instance.start(); + + return instance; } constructor( @@ -59,7 +63,6 @@ export class ParityInstance implements LedgerInstance { }); const logReader = new LogReader(this.logDir + "/parity.log"); await logReader.waitForLogMessage("Public node URL:"); - return this; } public async stop() { From 4aba4ced1691a79703d888622133f73fc5dd9328 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 13:59:35 +1100 Subject: [PATCH 059/145] Initialize Bitcoind after starting it This should always go together anyway! --- api_tests/lib/config.ts | 2 +- api_tests/lib/ledgers/bitcoin.ts | 56 ---------------------- api_tests/lib/ledgers/bitcoind_instance.ts | 39 ++++++++++++++- api_tests/lib/ledgers/ledger_runner.ts | 56 ++++------------------ api_tests/lib/wallets/bitcoin.ts | 2 +- 5 files changed, 49 insertions(+), 106 deletions(-) delete mode 100644 api_tests/lib/ledgers/bitcoin.ts diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 5b64ca3fd4..50a9df4557 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -1,7 +1,7 @@ import * as tmp from "tmp"; import { LedgerConfig } from "./ledgers/ledger_runner"; -import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; +import { BitcoinNodeConfig } from "./ledgers/bitcoind_instance"; export interface CndConfigFile { http_api: HttpApi; diff --git a/api_tests/lib/ledgers/bitcoin.ts b/api_tests/lib/ledgers/bitcoin.ts deleted file mode 100644 index b48d76bc43..0000000000 --- a/api_tests/lib/ledgers/bitcoin.ts +++ /dev/null @@ -1,56 +0,0 @@ -import BitcoinRpcClient from "bitcoin-core"; - -export interface BitcoinNodeConfig { - network: string; - username: string; - password: string; - host: string; - rpcPort: number; - p2pPort: number; - dataDir: string; -} - -let bitcoinRpcClient: BitcoinRpcClient; -let bitcoinConfig: BitcoinNodeConfig; - -export function init(btcConfig: BitcoinNodeConfig) { - createBitcoinRpcClient(btcConfig); -} - -function createBitcoinRpcClient(btcConfig?: BitcoinNodeConfig) { - if (!btcConfig && !bitcoinConfig) { - throw new Error("bitcoin configuration is needed"); - } - - if (!bitcoinRpcClient || btcConfig !== bitcoinConfig) { - bitcoinRpcClient = new BitcoinRpcClient({ - network: btcConfig.network, - port: btcConfig.rpcPort, - host: btcConfig.host, - username: btcConfig.username, - password: btcConfig.password, - }); - bitcoinConfig = btcConfig; - } - return bitcoinRpcClient; -} - -export async function generate(num: number = 1) { - const client = createBitcoinRpcClient(bitcoinConfig); - - return client.generateToAddress(num, await client.getNewAddress()); -} - -export async function ensureFunding() { - const blockHeight = await createBitcoinRpcClient( - bitcoinConfig - ).getBlockCount(); - if (blockHeight < 101) { - const client = createBitcoinRpcClient(bitcoinConfig); - - await client.generateToAddress( - 101 - blockHeight, - await client.getNewAddress() - ); - } -} diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index d64f6ccf23..63d1175312 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -5,6 +5,17 @@ import { LogReader } from "./log_reader"; import * as path from "path"; import { openAsync, mkdirAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; +import BitcoinRpcClient from "bitcoin-core"; + +export interface BitcoinNodeConfig { + network: string; + username: string; + password: string; + host: string; + rpcPort: number; + p2pPort: number; + dataDir: string; +} export class BitcoindInstance implements LedgerInstance { private process: ChildProcess; @@ -24,6 +35,20 @@ export class BitcoindInstance implements LedgerInstance { await instance.start(); + const client = new BitcoinRpcClient({ + network: "regtest", + host: "localhost", + port: instance.rpcPort, + username: instance.username, + password: instance.password, + }); + + await client.generateToAddress(101, await client.getNewAddress()); + + setInterval(async () => { + await client.generateToAddress(1, await client.getNewAddress()); + }, 1000); + return instance; } @@ -67,7 +92,7 @@ export class BitcoindInstance implements LedgerInstance { }); const logReader = new LogReader(this.logPath()); - await logReader.waitForLogMessage("Wallet completed loading"); + await logReader.waitForLogMessage("init message: Done loading"); const result = fs.readFileSync( path.join(this.dataDir, "regtest", ".cookie"), @@ -79,6 +104,18 @@ export class BitcoindInstance implements LedgerInstance { this.password = password; } + public get config(): BitcoinNodeConfig { + return { + network: "regtest", + host: "localhost", + rpcPort: this.rpcPort, + p2pPort: this.p2pPort, + username: this.username, + password: this.password, + dataDir: this.getDataDir(), + }; + } + public stop() { this.process.kill("SIGINT"); } diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index d1e8044184..f0466ae842 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -1,12 +1,10 @@ -import * as bitcoin from "./bitcoin"; -import { BitcoindInstance } from "./bitcoind_instance"; +import { BitcoindInstance, BitcoinNodeConfig } from "./bitcoind_instance"; import { ParityInstance } from "./parity_instance"; import { EthereumWallet } from "../wallets/ethereum"; import { HarnessGlobal } from "../utils"; import { LndInstance } from "./lnd_instance"; import * as path from "path"; import { EthereumNodeConfig } from "./ethereum"; -import { BitcoinNodeConfig } from "./bitcoin"; export interface LedgerConfig { bitcoin?: BitcoinNodeConfig; @@ -46,12 +44,16 @@ export class LedgerRunner { switch (ledger) { case "bitcoin": { + const instance = await BitcoindInstance.start( + this.projectRoot, + this.logDir + ); + + ledgerConfig.bitcoin = instance.config; + startedContainers.push({ ledger, - instance: await BitcoindInstance.start( - this.projectRoot, - this.logDir - ), + instance, }); break; } @@ -97,26 +99,6 @@ export class LedgerRunner { this.runningLedgers[ledger] = instance; switch (ledger) { - case "bitcoin": { - if (this.harnessGlobal.verbose) { - console.log( - "Bitcoin: initialization after ledger is running." - ); - } - bitcoin.init(await this.getBitcoinClientConfig()); - await bitcoin.ensureFunding(); - this.blockTimers.bitcoin = this.harnessGlobal.setInterval( - async () => { - await bitcoin.generate(); - }, - 1000 - ); - ledgerConfig.bitcoin = await this.getBitcoinClientConfig().catch( - () => undefined - ); - break; - } - case "ethereum": { const ethereumNodeUrl = await this.getEthereumNodeUrl().catch( () => undefined @@ -163,26 +145,6 @@ export class LedgerRunner { }); } - private async getBitcoinClientConfig(): Promise { - const instance = this.runningLedgers.bitcoin as BitcoindInstance; - - if (instance) { - const { username, password } = instance.getUsernamePassword(); - - return { - network: "regtest", - host: "localhost", - rpcPort: instance.rpcPort, - p2pPort: instance.p2pPort, - username, - password, - dataDir: instance.getDataDir(), - }; - } else { - return Promise.reject("bitcoin not yet started"); - } - } - private async getEthereumNodeUrl(): Promise { const instance = this.runningLedgers.ethereum as ParityInstance; diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/lib/wallets/bitcoin.ts index 8e872a29fa..420a18d198 100644 --- a/api_tests/lib/wallets/bitcoin.ts +++ b/api_tests/lib/wallets/bitcoin.ts @@ -7,7 +7,7 @@ import { } from "comit-sdk"; import { toBitcoin, toSatoshi } from "satoshi-bitcoin"; import { pollUntilMinted, Wallet } from "./index"; -import { BitcoinNodeConfig } from "../ledgers/bitcoin"; +import { BitcoinNodeConfig } from "../ledgers/bitcoind_instance"; export class BitcoinWallet implements Wallet { public static async newInstance(config: BitcoinNodeConfig) { From b33df8b43c6beb0fe3561ef49d2555d01ffa4d15 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 14:12:43 +1100 Subject: [PATCH 060/145] Initialize ERC20 token contract as part of starting ParityInstance This makes it symmetric with BitcoindInstance. --- api_tests/lib/config.ts | 8 ++- api_tests/lib/ledgers/bitcoind_instance.ts | 12 +--- api_tests/lib/ledgers/ethereum.ts | 4 -- api_tests/lib/ledgers/ledger_runner.ts | 65 +++++++++------------- api_tests/lib/ledgers/parity_instance.ts | 20 ++++++- api_tests/lib/wallets/bitcoin.ts | 2 +- api_tests/lib/wallets/ethereum.ts | 7 +-- api_tests/lib/wallets/index.ts | 2 +- api_tests/src/e2e_test_environment.ts | 6 +- 9 files changed, 56 insertions(+), 70 deletions(-) delete mode 100644 api_tests/lib/ledgers/ethereum.ts diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 50a9df4557..3880126b9c 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -1,7 +1,9 @@ import * as tmp from "tmp"; -import { LedgerConfig } from "./ledgers/ledger_runner"; -import { EthereumNodeConfig } from "./ledgers/ethereum"; -import { BitcoinNodeConfig } from "./ledgers/bitcoind_instance"; +import { + LedgerConfig, + BitcoinNodeConfig, + EthereumNodeConfig, +} from "./ledgers/ledger_runner"; export interface CndConfigFile { http_api: HttpApi; diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index 63d1175312..cec529499d 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -1,22 +1,12 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; -import { LedgerInstance } from "./ledger_runner"; +import { BitcoinNodeConfig, LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import * as path from "path"; import { openAsync, mkdirAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import BitcoinRpcClient from "bitcoin-core"; -export interface BitcoinNodeConfig { - network: string; - username: string; - password: string; - host: string; - rpcPort: number; - p2pPort: number; - dataDir: string; -} - export class BitcoindInstance implements LedgerInstance { private process: ChildProcess; private dataDir: string; diff --git a/api_tests/lib/ledgers/ethereum.ts b/api_tests/lib/ledgers/ethereum.ts deleted file mode 100644 index 3390989309..0000000000 --- a/api_tests/lib/ledgers/ethereum.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface EthereumNodeConfig { - rpc_url: string; - tokenContract: string; -} diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index f0466ae842..72f353163f 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -1,10 +1,7 @@ -import { BitcoindInstance, BitcoinNodeConfig } from "./bitcoind_instance"; +import { BitcoindInstance } from "./bitcoind_instance"; import { ParityInstance } from "./parity_instance"; -import { EthereumWallet } from "../wallets/ethereum"; -import { HarnessGlobal } from "../utils"; import { LndInstance } from "./lnd_instance"; import * as path from "path"; -import { EthereumNodeConfig } from "./ethereum"; export interface LedgerConfig { bitcoin?: BitcoinNodeConfig; @@ -13,6 +10,21 @@ export interface LedgerConfig { lndBob?: LndInstance; } +export interface BitcoinNodeConfig { + network: string; + username: string; + password: string; + host: string; + rpcPort: number; + p2pPort: number; + dataDir: string; +} + +export interface EthereumNodeConfig { + rpc_url: string; + tokenContract: string; +} + export interface LedgerInstance { stop(): void; } @@ -23,8 +35,7 @@ export class LedgerRunner { constructor( private readonly projectRoot: string, - private readonly logDir: string, - private harnessGlobal: HarnessGlobal + private readonly logDir: string ) { this.runningLedgers = {}; this.blockTimers = {}; @@ -58,12 +69,16 @@ export class LedgerRunner { break; } case "ethereum": { + const parity = await ParityInstance.start( + this.projectRoot, + this.logDir + ); + + ledgerConfig.ethereum = parity.config; + startedContainers.push({ ledger, - instance: await ParityInstance.start( - this.projectRoot, - this.logDir - ), + instance: parity, }); break; } @@ -99,26 +114,6 @@ export class LedgerRunner { this.runningLedgers[ledger] = instance; switch (ledger) { - case "ethereum": { - const ethereumNodeUrl = await this.getEthereumNodeUrl().catch( - () => undefined - ); - const erc20Wallet = new EthereumWallet(ethereumNodeUrl); - ledgerConfig.ethereum = { - rpc_url: ethereumNodeUrl, - tokenContract: await erc20Wallet.deployErc20TokenContract( - this.projectRoot - ), - }; - if (this.harnessGlobal.verbose) { - console.log( - "Ethereum: deployed Erc20 contract at %s", - ledgerConfig.ethereum.tokenContract - ); - } - break; - } - case "lnd-alice": { ledgerConfig.lndAlice = instance as LndInstance; break; @@ -144,14 +139,4 @@ export class LedgerRunner { delete this.runningLedgers[ledger]; }); } - - private async getEthereumNodeUrl(): Promise { - const instance = this.runningLedgers.ethereum as ParityInstance; - - if (instance) { - return `http://localhost:${instance.rpcPort}`; - } else { - return Promise.reject("ethereum not yet started"); - } - } } diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index 6d040d87c1..d471688c58 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -1,17 +1,19 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import tmp from "tmp"; -import { LedgerInstance } from "./ledger_runner"; +import { EthereumNodeConfig, LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import { promisify } from "util"; import { sleep } from "../utils"; import getPort from "get-port"; +import { EthereumWallet } from "../wallets/ethereum"; const openAsync = promisify(fs.open); export class ParityInstance implements LedgerInstance { private process: ChildProcess; private dbDir: any; + private erc20TokenContract: string; public static async start(projectRoot: string, logDir: string) { const instance = new ParityInstance( @@ -22,6 +24,11 @@ export class ParityInstance implements LedgerInstance { await instance.start(); + const erc20Wallet = new EthereumWallet(instance.rpcUrl); + instance.erc20TokenContract = await erc20Wallet.deployErc20TokenContract( + projectRoot + ); + return instance; } @@ -65,6 +72,17 @@ export class ParityInstance implements LedgerInstance { await logReader.waitForLogMessage("Public node URL:"); } + public get config(): EthereumNodeConfig { + return { + rpc_url: this.rpcUrl, + tokenContract: this.erc20TokenContract, + }; + } + + private get rpcUrl() { + return `http://localhost:${this.rpcPort}`; + } + public async stop() { this.process.kill("SIGTERM"); await sleep(3000); diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/lib/wallets/bitcoin.ts index 420a18d198..045740f914 100644 --- a/api_tests/lib/wallets/bitcoin.ts +++ b/api_tests/lib/wallets/bitcoin.ts @@ -7,7 +7,7 @@ import { } from "comit-sdk"; import { toBitcoin, toSatoshi } from "satoshi-bitcoin"; import { pollUntilMinted, Wallet } from "./index"; -import { BitcoinNodeConfig } from "../ledgers/bitcoind_instance"; +import { BitcoinNodeConfig } from "../ledgers/ledger_runner"; export class BitcoinWallet implements Wallet { public static async newInstance(config: BitcoinNodeConfig) { diff --git a/api_tests/lib/wallets/ethereum.ts b/api_tests/lib/wallets/ethereum.ts index 7ff66a61ee..60c5bf1c27 100644 --- a/api_tests/lib/wallets/ethereum.ts +++ b/api_tests/lib/wallets/ethereum.ts @@ -6,7 +6,6 @@ import { pollUntilMinted, Wallet } from "./index"; import { TransactionRequest } from "ethers/providers"; import * as fs from "fs"; import { HarnessGlobal, sleep } from "../utils"; -import { EthereumNodeConfig } from "../ledgers/ethereum"; declare var global: HarnessGlobal; @@ -17,15 +16,15 @@ export class EthereumWallet implements Wallet { private readonly parity: ethers.Wallet; private readonly jsonRpcProvider: ethers.providers.JsonRpcProvider; - constructor(config: EthereumNodeConfig) { - const provider = new ethers.providers.JsonRpcProvider(config.rpc_url); + constructor(rpcUrl: string) { + const provider = new ethers.providers.JsonRpcProvider(rpcUrl); this.parity = new ethers.Wallet( "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7", provider ); this.jsonRpcProvider = provider; - this.inner = new EthereumWalletSdk(config.rpc_url); + this.inner = new EthereumWalletSdk(rpcUrl); } public async mint(asset: Asset): Promise { diff --git a/api_tests/lib/wallets/index.ts b/api_tests/lib/wallets/index.ts index 83da0181e4..d8d7ff924e 100644 --- a/api_tests/lib/wallets/index.ts +++ b/api_tests/lib/wallets/index.ts @@ -53,7 +53,7 @@ export class Wallets { switch (name) { case "ethereum": this.wallets.ethereum = new EthereumWallet( - global.ledgerConfigs.ethereum + global.ledgerConfigs.ethereum.rpc_url ); break; case "bitcoin": diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index be02243270..c540ad8f7b 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -66,11 +66,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { if (ledgers.length > 0) { // setup ledgers - this.ledgerRunner = new LedgerRunner( - this.projectRoot, - this.logDir, - this.global - ); + this.ledgerRunner = new LedgerRunner(this.projectRoot, this.logDir); if (this.global.verbose) { console.log(`Initializing ledgers : ${ledgers}`); From 7c969d92c596be519365840a38db851626b10319 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 14:35:04 +1100 Subject: [PATCH 061/145] Inline ERC20 token contract into EthereumWallet This allows us to avoid the dependency on the project root variable. --- api_tests/erc20_token_contract.asm.hex | 1 - api_tests/lib/ledgers/parity_instance.ts | 4 +--- api_tests/lib/wallets/ethereum.ts | 13 ++----------- 3 files changed, 3 insertions(+), 15 deletions(-) delete mode 100644 api_tests/erc20_token_contract.asm.hex diff --git a/api_tests/erc20_token_contract.asm.hex b/api_tests/erc20_token_contract.asm.hex deleted file mode 100644 index 34a5adbe3c..0000000000 --- a/api_tests/erc20_token_contract.asm.hex +++ /dev/null @@ -1 +0,0 @@ -60806040526000600760006101000a81548160ff0219169083151502179055503480156200002c57600080fd5b506040805190810160405280600b81526020017f50726f666974546f6b656e0000000000000000000000000000000000000000008152506040805190810160405280600381526020017f505254000000000000000000000000000000000000000000000000000000000081525060128260039080519060200190620000b3929190620001b0565b508160049080519060200190620000cc929190620001b0565b5080600560006101000a81548160ff021916908360ff1602179055505050506200010f336006620001156401000000000262001779179091906401000000009004565b6200025f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156200015257600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001f357805160ff191683800117855562000224565b8280016001018555821562000224579182015b828111156200022357825182559160200191906001019062000206565b5b50905062000233919062000237565b5090565b6200025c91905b80821115620002585760008160009055506001016200023e565b5090565b90565b61196d806200026f6000396000f3006080604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305d2035b146100f657806306fdde0314610125578063095ea7b3146101b557806318160ddd1461021a57806323b872dd14610245578063313ce567146102ca57806339509351146102fb57806340c10f191461036057806370a08231146103c55780637d64bcb41461041c57806395d89b411461044b578063983b2d56146104db578063986502751461051e578063a457c2d714610535578063a9059cbb1461059a578063aa271e1a146105ff578063dd62ed3e1461065a575b600080fd5b34801561010257600080fd5b5061010b6106d1565b604051808215151515815260200191505060405180910390f35b34801561013157600080fd5b5061013a6106e8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017a57808201518184015260208101905061015f565b50505050905090810190601f1680156101a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101c157600080fd5b50610200600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061078a565b604051808215151515815260200191505060405180910390f35b34801561022657600080fd5b5061022f6108b7565b6040518082815260200191505060405180910390f35b34801561025157600080fd5b506102b0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108c1565b604051808215151515815260200191505060405180910390f35b3480156102d657600080fd5b506102df610c7c565b604051808260ff1660ff16815260200191505060405180910390f35b34801561030757600080fd5b50610346600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c93565b604051808215151515815260200191505060405180910390f35b34801561036c57600080fd5b506103ab600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eca565b604051808215151515815260200191505060405180910390f35b3480156103d157600080fd5b50610406600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f10565b6040518082815260200191505060405180910390f35b34801561042857600080fd5b50610431610f58565b604051808215151515815260200191505060405180910390f35b34801561045757600080fd5b50610460610fd8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104a0578082015181840152602081019050610485565b50505050905090810190601f1680156104cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104e757600080fd5b5061051c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061107a565b005b34801561052a57600080fd5b506105336110e8565b005b34801561054157600080fd5b50610580600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506110fe565b604051808215151515815260200191505060405180910390f35b3480156105a657600080fd5b506105e5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611335565b604051808215151515815260200191505060405180910390f35b34801561060b57600080fd5b50610640600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611555565b604051808215151515815260200191505060405180910390f35b34801561066657600080fd5b506106bb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611572565b6040518082815260200191505060405180910390f35b6000600760009054906101000a900460ff16905090565b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107805780601f1061075557610100808354040283529160200191610780565b820191906000526020600020905b81548152906001019060200180831161076357829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156107c757600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600254905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561091057600080fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561099b57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156109d757600080fd5b610a28826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610abb826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b8c82600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b6000600560009054906101000a900460ff16905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cd057600080fd5b610d5f82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000610ed533611555565b1515610ee057600080fd5b600760009054906101000a900460ff16151515610efc57600080fd5b610f06838361163b565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610f6333611555565b1515610f6e57600080fd5b600760009054906101000a900460ff16151515610f8a57600080fd5b6001600760006101000a81548160ff0219169083151502179055507fb828d9b5c78095deeeeff2eca2e5d4fe046ce3feb4c99702624a3fd384ad2dbc60405160405180910390a16001905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110705780601f1061104557610100808354040283529160200191611070565b820191906000526020600020905b81548152906001019060200180831161105357829003601f168201915b5050505050905090565b61108333611555565b151561108e57600080fd5b6110a281600661177990919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b6110fc33600661181390919063ffffffff16565b565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561113b57600080fd5b6111ca82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561138457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156113c057600080fd5b611411826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506114a4826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b600061156b8260066118ad90919063ffffffff16565b9050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008083831115151561160b57600080fd5b82840390508091505092915050565b600080828401905083811015151561163157600080fd5b8091505092915050565b60008273ffffffffffffffffffffffffffffffffffffffff161415151561166157600080fd5b6116768160025461161a90919063ffffffff16565b6002819055506116cd816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156117b557600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561184f57600080fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156118ea57600080fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050929150505600a165627a7a72305820cc38c3be3baa4284d7d1551695c68e8cc7c3d0dfbd17d5fe2d47c1dbe9b52b320029 diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index d471688c58..12c2371308 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -25,9 +25,7 @@ export class ParityInstance implements LedgerInstance { await instance.start(); const erc20Wallet = new EthereumWallet(instance.rpcUrl); - instance.erc20TokenContract = await erc20Wallet.deployErc20TokenContract( - projectRoot - ); + instance.erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); return instance; } diff --git a/api_tests/lib/wallets/ethereum.ts b/api_tests/lib/wallets/ethereum.ts index 60c5bf1c27..cb403c6c7c 100644 --- a/api_tests/lib/wallets/ethereum.ts +++ b/api_tests/lib/wallets/ethereum.ts @@ -4,7 +4,6 @@ import { ethers } from "ethers"; import { BigNumber as BigNumberEthers } from "ethers/utils"; import { pollUntilMinted, Wallet } from "./index"; import { TransactionRequest } from "ethers/providers"; -import * as fs from "fs"; import { HarnessGlobal, sleep } from "../utils"; declare var global: HarnessGlobal; @@ -107,17 +106,9 @@ export class EthereumWallet implements Wallet { return this.inner.getAccount(); } - public async deployErc20TokenContract( - projectRoot: string - ): Promise { + public async deployErc20TokenContract(): Promise { const data = - "0x" + - fs - .readFileSync( - projectRoot + "/api_tests/erc20_token_contract.asm.hex", - "utf8" - ) - .trim(); + "0x60806040526000600760006101000a81548160ff0219169083151502179055503480156200002c57600080fd5b506040805190810160405280600b81526020017f50726f666974546f6b656e0000000000000000000000000000000000000000008152506040805190810160405280600381526020017f505254000000000000000000000000000000000000000000000000000000000081525060128260039080519060200190620000b3929190620001b0565b508160049080519060200190620000cc929190620001b0565b5080600560006101000a81548160ff021916908360ff1602179055505050506200010f336006620001156401000000000262001779179091906401000000009004565b6200025f565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156200015257600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001f357805160ff191683800117855562000224565b8280016001018555821562000224579182015b828111156200022357825182559160200191906001019062000206565b5b50905062000233919062000237565b5090565b6200025c91905b80821115620002585760008160009055506001016200023e565b5090565b90565b61196d806200026f6000396000f3006080604052600436106100f1576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305d2035b146100f657806306fdde0314610125578063095ea7b3146101b557806318160ddd1461021a57806323b872dd14610245578063313ce567146102ca57806339509351146102fb57806340c10f191461036057806370a08231146103c55780637d64bcb41461041c57806395d89b411461044b578063983b2d56146104db578063986502751461051e578063a457c2d714610535578063a9059cbb1461059a578063aa271e1a146105ff578063dd62ed3e1461065a575b600080fd5b34801561010257600080fd5b5061010b6106d1565b604051808215151515815260200191505060405180910390f35b34801561013157600080fd5b5061013a6106e8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561017a57808201518184015260208101905061015f565b50505050905090810190601f1680156101a75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101c157600080fd5b50610200600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061078a565b604051808215151515815260200191505060405180910390f35b34801561022657600080fd5b5061022f6108b7565b6040518082815260200191505060405180910390f35b34801561025157600080fd5b506102b0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506108c1565b604051808215151515815260200191505060405180910390f35b3480156102d657600080fd5b506102df610c7c565b604051808260ff1660ff16815260200191505060405180910390f35b34801561030757600080fd5b50610346600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c93565b604051808215151515815260200191505060405180910390f35b34801561036c57600080fd5b506103ab600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610eca565b604051808215151515815260200191505060405180910390f35b3480156103d157600080fd5b50610406600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610f10565b6040518082815260200191505060405180910390f35b34801561042857600080fd5b50610431610f58565b604051808215151515815260200191505060405180910390f35b34801561045757600080fd5b50610460610fd8565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156104a0578082015181840152602081019050610485565b50505050905090810190601f1680156104cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104e757600080fd5b5061051c600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061107a565b005b34801561052a57600080fd5b506105336110e8565b005b34801561054157600080fd5b50610580600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506110fe565b604051808215151515815260200191505060405180910390f35b3480156105a657600080fd5b506105e5600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611335565b604051808215151515815260200191505060405180910390f35b34801561060b57600080fd5b50610640600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611555565b604051808215151515815260200191505060405180910390f35b34801561066657600080fd5b506106bb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611572565b6040518082815260200191505060405180910390f35b6000600760009054906101000a900460ff16905090565b606060038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107805780601f1061075557610100808354040283529160200191610780565b820191906000526020600020905b81548152906001019060200180831161076357829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156107c757600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600254905090565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561091057600080fd5b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561099b57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156109d757600080fd5b610a28826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610abb826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610b8c82600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b6000600560009054906101000a900460ff16905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cd057600080fd5b610d5f82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000610ed533611555565b1515610ee057600080fd5b600760009054906101000a900460ff16151515610efc57600080fd5b610f06838361163b565b6001905092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610f6333611555565b1515610f6e57600080fd5b600760009054906101000a900460ff16151515610f8a57600080fd5b6001600760006101000a81548160ff0219169083151502179055507fb828d9b5c78095deeeeff2eca2e5d4fe046ce3feb4c99702624a3fd384ad2dbc60405160405180910390a16001905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156110705780601f1061104557610100808354040283529160200191611070565b820191906000526020600020905b81548152906001019060200180831161105357829003601f168201915b5050505050905090565b61108333611555565b151561108e57600080fd5b6110a281600661177990919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b6110fc33600661181390919063ffffffff16565b565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561113b57600080fd5b6111ca82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561138457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141515156113c057600080fd5b611411826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546115f990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506114a4826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b600061156b8260066118ad90919063ffffffff16565b9050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008083831115151561160b57600080fd5b82840390508091505092915050565b600080828401905083811015151561163157600080fd5b8091505092915050565b60008273ffffffffffffffffffffffffffffffffffffffff161415151561166157600080fd5b6116768160025461161a90919063ffffffff16565b6002819055506116cd816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461161a90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156117b557600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561184f57600080fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156118ea57600080fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050929150505600a165627a7a72305820cc38c3be3baa4284d7d1551695c68e8cc7c3d0dfbd17d5fe2d47c1dbe9b52b320029"; const tx: TransactionRequest = { gasLimit: "0x3D0900", value: "0x0", From 678ada21c38530740682a1db5ebeed31af655e34 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 14:57:57 +1100 Subject: [PATCH 062/145] Introduce abstraction layer between ledgers and their instances This allows us to easily replace for example the BitcoindInstance with a docker container and still keep the initialization logic. --- api_tests/lib/actor_test.ts | 3 +- api_tests/lib/actors/actor.ts | 6 +- api_tests/lib/config.ts | 8 +- api_tests/lib/ledgers/bitcoin.ts | 62 ++++++++++++++ api_tests/lib/ledgers/bitcoind_instance.ts | 38 ++------- api_tests/lib/ledgers/ethereum.ts | 53 ++++++++++++ api_tests/lib/ledgers/ledger_runner.ts | 98 ++++++++++------------ api_tests/lib/ledgers/lightning.ts | 42 ++++++++++ api_tests/lib/ledgers/lnd_instance.ts | 27 +++--- api_tests/lib/ledgers/parity_instance.ts | 26 ++---- api_tests/lib/wallets/bitcoin.ts | 2 +- api_tests/src/dry_test_environment.ts | 6 +- api_tests/src/e2e_test_environment.ts | 6 +- api_tests/tests/e2e/bitcoin_ethereum.ts | 8 +- 14 files changed, 245 insertions(+), 140 deletions(-) create mode 100644 api_tests/lib/ledgers/bitcoin.ts create mode 100644 api_tests/lib/ledgers/ethereum.ts create mode 100644 api_tests/lib/ledgers/lightning.ts diff --git a/api_tests/lib/actor_test.ts b/api_tests/lib/actor_test.ts index e8cc6acbd6..fddc33d83c 100644 --- a/api_tests/lib/actor_test.ts +++ b/api_tests/lib/actor_test.ts @@ -32,10 +32,9 @@ function nActorTest( throw e; } finally { for (const actorName of actorNames) { - actors.getActorByName(actorName).stop(); + await actors.getActorByName(actorName).stop(); } } - done(); }; } diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index c9820373a6..c82350b1d9 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -567,16 +567,16 @@ export class Actor { await this.cndInstance.start(); } - public stop() { + public async stop() { this.logger.debug("Stopping actor"); this.cndInstance.stop(); if (this.lndInstance && this.lndInstance.isRunning()) { - this.lndInstance.stop(); + await this.lndInstance.stop(); } } public async restart() { - this.stop(); + await this.stop(); await this.start(); } diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 3880126b9c..5b64ca3fd4 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -1,9 +1,7 @@ import * as tmp from "tmp"; -import { - LedgerConfig, - BitcoinNodeConfig, - EthereumNodeConfig, -} from "./ledgers/ledger_runner"; +import { LedgerConfig } from "./ledgers/ledger_runner"; +import { BitcoinNodeConfig } from "./ledgers/bitcoin"; +import { EthereumNodeConfig } from "./ledgers/ethereum"; export interface CndConfigFile { http_api: HttpApi; diff --git a/api_tests/lib/ledgers/bitcoin.ts b/api_tests/lib/ledgers/bitcoin.ts new file mode 100644 index 0000000000..92c4a69c9d --- /dev/null +++ b/api_tests/lib/ledgers/bitcoin.ts @@ -0,0 +1,62 @@ +import { LedgerInstance } from "./ledger_runner"; +import BitcoinRpcClient from "bitcoin-core"; + +/** + * An instance of the Bitcoin ledger for use in the e2e tests. + * + * This class is compatible with anything that implements {@link BitcoinInstance}. + * + * For the e2e tests to work properly, we need to continuously mine bitcoin blocks. + * This class takes care of spawning a miner after the Bitcoin blockchain has + * been setup, regardless of how that is achieved (Docker container, bitcoind instance, etc). + */ +export default class BitcoinLedger implements LedgerInstance { + public static async start(instance: BitcoinInstance) { + await instance.start(); + + const { rpcPort, username, password } = instance.config; + + const client = new BitcoinRpcClient({ + network: "regtest", + host: "localhost", + port: rpcPort, + username, + password, + }); + + await client.generateToAddress(101, await client.getNewAddress()); + + setInterval(async () => { + await client.generateToAddress(1, await client.getNewAddress()); + }, 1000); + + return new BitcoinLedger(instance); + } + + constructor(private readonly instance: BitcoinInstance) {} + + public async stop(): Promise { + await this.instance.stop(); + } + + public get config(): BitcoinNodeConfig { + return this.instance.config; + } +} + +export interface BitcoinInstance { + config: BitcoinNodeConfig; + + start(): Promise; + stop(): Promise; +} + +export interface BitcoinNodeConfig { + network: string; + username: string; + password: string; + host: string; + rpcPort: number; + p2pPort: number; + dataDir: string; +} diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index cec529499d..2aa3ffc188 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -1,20 +1,22 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; -import { BitcoinNodeConfig, LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import * as path from "path"; -import { openAsync, mkdirAsync, writeFileAsync } from "../utils"; +import { mkdirAsync, openAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; -import BitcoinRpcClient from "bitcoin-core"; +import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; -export class BitcoindInstance implements LedgerInstance { +export class BitcoindInstance implements BitcoinInstance { private process: ChildProcess; private dataDir: string; private username: string; private password: string; - public static async start(projectRoot: string, logDir: string) { - const instance = new BitcoindInstance( + public static async new( + projectRoot: string, + logDir: string + ): Promise { + return new BitcoindInstance( projectRoot, logDir, await getPort({ port: 18444 }), @@ -22,24 +24,6 @@ export class BitcoindInstance implements LedgerInstance { await getPort({ port: 28332 }), await getPort({ port: 28333 }) ); - - await instance.start(); - - const client = new BitcoinRpcClient({ - network: "regtest", - host: "localhost", - port: instance.rpcPort, - username: instance.username, - password: instance.password, - }); - - await client.generateToAddress(101, await client.getNewAddress()); - - setInterval(async () => { - await client.generateToAddress(1, await client.getNewAddress()); - }, 1000); - - return instance; } constructor( @@ -106,7 +90,7 @@ export class BitcoindInstance implements LedgerInstance { }; } - public stop() { + public async stop() { this.process.kill("SIGINT"); } @@ -118,10 +102,6 @@ export class BitcoindInstance implements LedgerInstance { return this.dataDir; } - public getUsernamePassword() { - return { username: this.username, password: this.password }; - } - private async createConfigFile(dataDir: string) { const output = `regtest=1 server=1 diff --git a/api_tests/lib/ledgers/ethereum.ts b/api_tests/lib/ledgers/ethereum.ts new file mode 100644 index 0000000000..22bcb973b1 --- /dev/null +++ b/api_tests/lib/ledgers/ethereum.ts @@ -0,0 +1,53 @@ +import { LedgerInstance } from "./ledger_runner"; +import { EthereumWallet } from "../wallets/ethereum"; + +/** + * An instance of the Ethereum ledger for use in the e2e tests. + * + * This class is compatible with anything that implements {@link EthereumInstance}. + * + * Some of the e2e tests need an ERC20 token deployed to work properly. + * This class takes care of deploying such contract after the Ethereum + * blockchain is up and running. + * + * This class serves as an abstraction layer on top of Ethereum, regardless + * of which implementation is used (Docker container, parity, geth, etc). + */ +export default class EthereumLedger implements LedgerInstance { + public static async start(instance: EthereumInstance) { + await instance.start(); + + const erc20Wallet = new EthereumWallet(instance.rpcUrl); + const erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); + + return new EthereumLedger(instance, erc20TokenContract); + } + + constructor( + private readonly instance: EthereumInstance, + private readonly erc20TokenContract: string + ) {} + + public async stop(): Promise { + await this.instance.stop(); + } + + public get config(): EthereumNodeConfig { + return { + rpc_url: this.instance.rpcUrl, + tokenContract: this.erc20TokenContract, + }; + } +} + +export interface EthereumInstance { + rpcUrl: string; + + start(): Promise; + stop(): Promise; +} + +export interface EthereumNodeConfig { + rpc_url: string; + tokenContract: string; +} diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts index 72f353163f..1c8dedebd9 100644 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ b/api_tests/lib/ledgers/ledger_runner.ts @@ -2,31 +2,19 @@ import { BitcoindInstance } from "./bitcoind_instance"; import { ParityInstance } from "./parity_instance"; import { LndInstance } from "./lnd_instance"; import * as path from "path"; +import BitcoinLedger, { BitcoinNodeConfig } from "./bitcoin"; +import EthereumLedger, { EthereumNodeConfig } from "./ethereum"; +import LightningLedger, { LightningNodeConfig } from "./lightning"; export interface LedgerConfig { bitcoin?: BitcoinNodeConfig; ethereum?: EthereumNodeConfig; - lndAlice?: LndInstance; - lndBob?: LndInstance; -} - -export interface BitcoinNodeConfig { - network: string; - username: string; - password: string; - host: string; - rpcPort: number; - p2pPort: number; - dataDir: string; -} - -export interface EthereumNodeConfig { - rpc_url: string; - tokenContract: string; + lndAlice?: LightningNodeConfig; + lndBob?: LightningNodeConfig; } export interface LedgerInstance { - stop(): void; + stop(): Promise; } export class LedgerRunner { @@ -55,73 +43,71 @@ export class LedgerRunner { switch (ledger) { case "bitcoin": { - const instance = await BitcoindInstance.start( - this.projectRoot, - this.logDir + const bitcoin = await BitcoinLedger.start( + await BitcoindInstance.new( + this.projectRoot, + this.logDir + ) ); - ledgerConfig.bitcoin = instance.config; + ledgerConfig.bitcoin = bitcoin.config; startedContainers.push({ ledger, - instance, + instance: bitcoin, }); break; } case "ethereum": { - const parity = await ParityInstance.start( - this.projectRoot, - this.logDir + const ethereum = await EthereumLedger.start( + await ParityInstance.new(this.projectRoot, this.logDir) ); - ledgerConfig.ethereum = parity.config; + ledgerConfig.ethereum = ethereum.config; startedContainers.push({ ledger, - instance: parity, + instance: ethereum, }); break; } case "lnd-alice": { - startedContainers.push({ - ledger, - instance: await LndInstance.start( + const lightning = await LightningLedger.start( + await LndInstance.new( this.logDir, "lnd-alice", path.join(this.logDir, "bitcoind") - ), + ) + ); + + ledgerConfig.lndAlice = lightning.config; + + startedContainers.push({ + ledger, + instance: lightning, }); + break; } case "lnd-bob": { - startedContainers.push({ - ledger, - instance: await LndInstance.start( + const lightning = await LightningLedger.start( + await LndInstance.new( this.logDir, "lnd-bob", path.join(this.logDir, "bitcoind") - ), + ) + ); + startedContainers.push({ + ledger, + instance: lightning, }); - break; - } - default: { - throw new Error(`LedgerRunner does not support ${ledger}`); - } - } - } - for (const { ledger, instance } of startedContainers) { - this.runningLedgers[ledger] = instance; + ledgerConfig.lndBob = lightning.config; - switch (ledger) { - case "lnd-alice": { - ledgerConfig.lndAlice = instance as LndInstance; break; } - - case "lnd-bob": { - ledgerConfig.lndBob = instance as LndInstance; - break; + default: { + throw new Error(`LedgerRunner does not support ${ledger}`); } } } @@ -129,14 +115,14 @@ export class LedgerRunner { return ledgerConfig; } - public stopLedgers() { + public async stopLedgers() { const ledgers = Object.entries(this.runningLedgers); - ledgers.map(([ledger, ledgerInstance]) => { + for (const [ledger, instance] of ledgers) { console.log(`Stopping ledger ${ledger}`); clearInterval(this.blockTimers[ledger]); - ledgerInstance.stop(); + await instance.stop(); delete this.runningLedgers[ledger]; - }); + } } } diff --git a/api_tests/lib/ledgers/lightning.ts b/api_tests/lib/ledgers/lightning.ts new file mode 100644 index 0000000000..acb7468c65 --- /dev/null +++ b/api_tests/lib/ledgers/lightning.ts @@ -0,0 +1,42 @@ +import { LedgerInstance } from "./ledger_runner"; +import { Lnd } from "comit-sdk"; + +/** + * An instance of the Lightning ledger for use in the e2e tests. + * + * This class is compatible with anything that implements {@link LightningInstance}. + * + * Compared to {@link BitcoinLedger} and {@link EthereumLedger}, there is nothing + * to be done after a {@link LightningInstance} is started. If this ever changes, + * this class is the place where to put this information. + */ +export default class LightningLedger implements LedgerInstance { + public static async start(instance: LightningInstance) { + await instance.start(); + + return new LightningLedger(instance); + } + + constructor(private readonly instance: LightningInstance) {} + + async stop(): Promise { + return this.instance.stop(); + } + + get config(): LightningNodeConfig { + return this.instance.config; + } +} + +export interface LightningInstance { + config: LightningNodeConfig; + + start(): Promise; + stop(): Promise; +} + +export interface LightningNodeConfig { + p2pSocket: string; + // sucks that we have to leak here that the instance is LND under the hood but we can't do much about that :) + lnd: Lnd; +} diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index c393be52e8..54ffa7b1d5 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -5,32 +5,26 @@ import getPort from "get-port"; import { LogReader } from "./log_reader"; import { Lnd } from "comit-sdk"; import whereis from "@wcjiang/whereis"; +import { LightningInstance, LightningNodeConfig } from "./lightning"; -export class LndInstance { +export class LndInstance implements LightningInstance { private process: ChildProcess; private lndDir: string; public lnd: Lnd; // private publicKey?: string; - public static async start( + public static async new( testLogDir: string, name: string, bitcoindDataDir: string ) { - const lndP2pPort = await getPort(); - const lndRpcPort = await getPort(); - - const instance = new LndInstance( + return new LndInstance( testLogDir, name, bitcoindDataDir, - lndP2pPort, - lndRpcPort + await getPort(), + await getPort() ); - - await instance.start(); - - return instance; } private constructor( @@ -125,7 +119,7 @@ export class LndInstance { this.lnd = await Lnd.init(config); } - public stop() { + public async stop() { // this.logger.debug("Stopping lnd instance"); this.process.kill("SIGTERM"); this.process = null; @@ -178,6 +172,13 @@ export class LndInstance { return this.lndP2pPort; } + get config(): LightningNodeConfig { + return { + p2pSocket: this.p2pSocket, + lnd: this.lnd, + }; + } + private async createConfigFile() { // We don't use REST but want a random port so we don't get used port errors. const restPort = await getPort(); diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index 12c2371308..b430c55e96 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -1,33 +1,24 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import tmp from "tmp"; -import { EthereumNodeConfig, LedgerInstance } from "./ledger_runner"; import { LogReader } from "./log_reader"; import { promisify } from "util"; import { sleep } from "../utils"; import getPort from "get-port"; -import { EthereumWallet } from "../wallets/ethereum"; +import { EthereumInstance } from "./ethereum"; const openAsync = promisify(fs.open); -export class ParityInstance implements LedgerInstance { +export class ParityInstance implements EthereumInstance { private process: ChildProcess; private dbDir: any; - private erc20TokenContract: string; - public static async start(projectRoot: string, logDir: string) { - const instance = new ParityInstance( + public static async new(projectRoot: string, logDir: string) { + return new ParityInstance( projectRoot, logDir, await getPort({ port: 8545 }) ); - - await instance.start(); - - const erc20Wallet = new EthereumWallet(instance.rpcUrl); - instance.erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); - - return instance; } constructor( @@ -70,14 +61,7 @@ export class ParityInstance implements LedgerInstance { await logReader.waitForLogMessage("Public node URL:"); } - public get config(): EthereumNodeConfig { - return { - rpc_url: this.rpcUrl, - tokenContract: this.erc20TokenContract, - }; - } - - private get rpcUrl() { + public get rpcUrl() { return `http://localhost:${this.rpcPort}`; } diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/lib/wallets/bitcoin.ts index 045740f914..8e872a29fa 100644 --- a/api_tests/lib/wallets/bitcoin.ts +++ b/api_tests/lib/wallets/bitcoin.ts @@ -7,7 +7,7 @@ import { } from "comit-sdk"; import { toBitcoin, toSatoshi } from "satoshi-bitcoin"; import { pollUntilMinted, Wallet } from "./index"; -import { BitcoinNodeConfig } from "../ledgers/ledger_runner"; +import { BitcoinNodeConfig } from "../ledgers/bitcoin"; export class BitcoinWallet implements Wallet { public static async newInstance(config: BitcoinNodeConfig) { diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 0af2863758..2161e6df99 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -70,16 +70,16 @@ export default class DryTestEnvironment extends NodeEnvironment { if (this.global.verbose) { console.log(`Tearing down test environment.`); } - this.cleanupAll(); + await this.cleanupAll(); if (this.global.verbose) { console.log(`All teared down.`); } } - cleanupAll() { + async cleanupAll() { try { if (this.ledgerRunner) { - this.ledgerRunner.stopLedgers(); + await this.ledgerRunner.stopLedgers(); } } catch (e) { console.error("Failed to clean up resources", e); diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index c540ad8f7b..c59bb988d4 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -133,16 +133,16 @@ export default class E2ETestEnvironment extends NodeEnvironment { if (this.global.verbose) { console.log(`Tearing down test environment.`); } - this.cleanupAll(); + await this.cleanupAll(); if (this.global.verbose) { console.log(`All teared down.`); } } - cleanupAll() { + async cleanupAll() { try { if (this.ledgerRunner) { - this.ledgerRunner.stopLedgers(); + await this.ledgerRunner.stopLedgers(); } } catch (e) { console.error("Failed to clean up resources", e); diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index ad399b1132..45ba121928 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -155,7 +155,7 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await bob.accept(); await alice.fund(); - alice.stop(); + await alice.stop(); // Action happens while alice is down. await bob.fund(); @@ -183,7 +183,7 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await bob.fund(); await alice.redeem(); - alice.stop(); + await alice.stop(); // Action happens while alice is down. await bob.redeem(); @@ -207,7 +207,7 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { // Wait for Alice to receive the accept message before stopping Bob's cnd. await alice.currentSwapIsAccepted(); - bob.stop(); + await bob.stop(); // Action happens while bob is down. await alice.fund(); @@ -236,7 +236,7 @@ describe("E2E: Bitcoin/bitcoin - Ethereum/ether", () => { await alice.fund(); await bob.fund(); - bob.stop(); + await bob.stop(); // Action happens while bob is down. await alice.redeem(); From 526276728c907cac50a389ae7eb9d33586e662aa Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 17:14:37 +1100 Subject: [PATCH 063/145] Ditch LedgerRunner and start everything in parallel --- api_tests/lib/actors/actor.ts | 3 +- api_tests/lib/cnd/cnd_instance.ts | 3 +- api_tests/lib/config.ts | 2 +- api_tests/lib/ledgers/bitcoin.ts | 14 +- api_tests/lib/ledgers/bitcoind_instance.ts | 2 + api_tests/lib/ledgers/ethereum.ts | 2 +- api_tests/lib/ledgers/ledger_instance.ts | 11 ++ api_tests/lib/ledgers/ledger_runner.ts | 128 ------------ api_tests/lib/ledgers/lightning.ts | 2 +- api_tests/lib/ledgers/lnd_instance.ts | 2 + api_tests/lib/ledgers/parity_instance.ts | 10 +- api_tests/lib/utils.ts | 8 +- api_tests/src/dry_test_environment.ts | 19 -- api_tests/src/e2e_test_environment.ts | 215 +++++++++++++++------ api_tests/tests/e2e/bitcoin_ethereum.ts | 2 +- 15 files changed, 200 insertions(+), 223 deletions(-) create mode 100644 api_tests/lib/ledgers/ledger_instance.ts delete mode 100644 api_tests/lib/ledgers/ledger_runner.ts diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index c82350b1d9..588a3a5237 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -11,12 +11,11 @@ import { parseEther } from "ethers/utils"; import getPort from "get-port"; import { Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; -import { LedgerConfig } from "../ledgers/ledger_runner"; import "../setup_chai"; import { Asset, AssetKind, toKey, toKind } from "../asset"; import { CndInstance } from "../cnd/cnd_instance"; import { Ledger, LedgerKind } from "../ledgers/ledger"; -import { HarnessGlobal, sleep } from "../utils"; +import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; import { Wallet, Wallets } from "../wallets"; import { Actors } from "./index"; import { Entity } from "../../gen/siren"; diff --git a/api_tests/lib/cnd/cnd_instance.ts b/api_tests/lib/cnd/cnd_instance.ts index ea6384cdfb..c8b5116681 100644 --- a/api_tests/lib/cnd/cnd_instance.ts +++ b/api_tests/lib/cnd/cnd_instance.ts @@ -4,8 +4,7 @@ import * as fs from "fs"; import tempWrite from "temp-write"; import { promisify } from "util"; import { CndConfigFile, E2ETestActorConfig } from "../config"; -import { LedgerConfig } from "../ledgers/ledger_runner"; -import { HarnessGlobal, sleep } from "../utils"; +import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; import path from "path"; import { LogReader } from "../ledgers/log_reader"; diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 5b64ca3fd4..7a4baf0223 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -1,7 +1,7 @@ import * as tmp from "tmp"; -import { LedgerConfig } from "./ledgers/ledger_runner"; import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; +import { LedgerConfig } from "./utils"; export interface CndConfigFile { http_api: HttpApi; diff --git a/api_tests/lib/ledgers/bitcoin.ts b/api_tests/lib/ledgers/bitcoin.ts index 92c4a69c9d..cc5f79f4da 100644 --- a/api_tests/lib/ledgers/bitcoin.ts +++ b/api_tests/lib/ledgers/bitcoin.ts @@ -1,5 +1,5 @@ -import { LedgerInstance } from "./ledger_runner"; import BitcoinRpcClient from "bitcoin-core"; +import LedgerInstance from "./ledger_instance"; /** * An instance of the Bitcoin ledger for use in the e2e tests. @@ -26,17 +26,23 @@ export default class BitcoinLedger implements LedgerInstance { await client.generateToAddress(101, await client.getNewAddress()); - setInterval(async () => { + const miner = setInterval(async () => { await client.generateToAddress(1, await client.getNewAddress()); }, 1000); - return new BitcoinLedger(instance); + console.log("Bitcoin miner initialized"); + + return new BitcoinLedger(instance, miner); } - constructor(private readonly instance: BitcoinInstance) {} + constructor( + private readonly instance: BitcoinInstance, + private readonly miner: NodeJS.Timeout + ) {} public async stop(): Promise { await this.instance.stop(); + clearInterval(this.miner); } public get config(): BitcoinNodeConfig { diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index 2aa3ffc188..a9c2084db6 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -76,6 +76,8 @@ export class BitcoindInstance implements BitcoinInstance { this.username = username; this.password = password; + + console.log(`bitcoind started with PID ${this.process.pid}`); } public get config(): BitcoinNodeConfig { diff --git a/api_tests/lib/ledgers/ethereum.ts b/api_tests/lib/ledgers/ethereum.ts index 22bcb973b1..6980806dbc 100644 --- a/api_tests/lib/ledgers/ethereum.ts +++ b/api_tests/lib/ledgers/ethereum.ts @@ -1,5 +1,5 @@ -import { LedgerInstance } from "./ledger_runner"; import { EthereumWallet } from "../wallets/ethereum"; +import LedgerInstance from "./ledger_instance"; /** * An instance of the Ethereum ledger for use in the e2e tests. diff --git a/api_tests/lib/ledgers/ledger_instance.ts b/api_tests/lib/ledgers/ledger_instance.ts new file mode 100644 index 0000000000..c977a89b29 --- /dev/null +++ b/api_tests/lib/ledgers/ledger_instance.ts @@ -0,0 +1,11 @@ +/** + * Defines an instance of a ledger + */ +export default interface LedgerInstance { + /** + * Stop the underlying ledger. + * + * This method must never fail. + */ + stop(): Promise; +} diff --git a/api_tests/lib/ledgers/ledger_runner.ts b/api_tests/lib/ledgers/ledger_runner.ts deleted file mode 100644 index 1c8dedebd9..0000000000 --- a/api_tests/lib/ledgers/ledger_runner.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { BitcoindInstance } from "./bitcoind_instance"; -import { ParityInstance } from "./parity_instance"; -import { LndInstance } from "./lnd_instance"; -import * as path from "path"; -import BitcoinLedger, { BitcoinNodeConfig } from "./bitcoin"; -import EthereumLedger, { EthereumNodeConfig } from "./ethereum"; -import LightningLedger, { LightningNodeConfig } from "./lightning"; - -export interface LedgerConfig { - bitcoin?: BitcoinNodeConfig; - ethereum?: EthereumNodeConfig; - lndAlice?: LightningNodeConfig; - lndBob?: LightningNodeConfig; -} - -export interface LedgerInstance { - stop(): Promise; -} - -export class LedgerRunner { - public readonly runningLedgers: { [key: string]: LedgerInstance }; - private readonly blockTimers: { [key: string]: NodeJS.Timeout }; - - constructor( - private readonly projectRoot: string, - private readonly logDir: string - ) { - this.runningLedgers = {}; - this.blockTimers = {}; - } - - public async ensureLedgersRunning( - ledgers: string[] - ): Promise { - const toBeStarted = ledgers.filter(name => !this.runningLedgers[name]); - - const startedContainers = []; - - const ledgerConfig: LedgerConfig = {}; - - for (const ledger of toBeStarted) { - console.log(`Starting ledger ${ledger}`); - - switch (ledger) { - case "bitcoin": { - const bitcoin = await BitcoinLedger.start( - await BitcoindInstance.new( - this.projectRoot, - this.logDir - ) - ); - - ledgerConfig.bitcoin = bitcoin.config; - - startedContainers.push({ - ledger, - instance: bitcoin, - }); - break; - } - case "ethereum": { - const ethereum = await EthereumLedger.start( - await ParityInstance.new(this.projectRoot, this.logDir) - ); - - ledgerConfig.ethereum = ethereum.config; - - startedContainers.push({ - ledger, - instance: ethereum, - }); - break; - } - case "lnd-alice": { - const lightning = await LightningLedger.start( - await LndInstance.new( - this.logDir, - "lnd-alice", - path.join(this.logDir, "bitcoind") - ) - ); - - ledgerConfig.lndAlice = lightning.config; - - startedContainers.push({ - ledger, - instance: lightning, - }); - - break; - } - case "lnd-bob": { - const lightning = await LightningLedger.start( - await LndInstance.new( - this.logDir, - "lnd-bob", - path.join(this.logDir, "bitcoind") - ) - ); - startedContainers.push({ - ledger, - instance: lightning, - }); - - ledgerConfig.lndBob = lightning.config; - - break; - } - default: { - throw new Error(`LedgerRunner does not support ${ledger}`); - } - } - } - - return ledgerConfig; - } - - public async stopLedgers() { - const ledgers = Object.entries(this.runningLedgers); - - for (const [ledger, instance] of ledgers) { - console.log(`Stopping ledger ${ledger}`); - clearInterval(this.blockTimers[ledger]); - await instance.stop(); - delete this.runningLedgers[ledger]; - } - } -} diff --git a/api_tests/lib/ledgers/lightning.ts b/api_tests/lib/ledgers/lightning.ts index acb7468c65..74cc301b2f 100644 --- a/api_tests/lib/ledgers/lightning.ts +++ b/api_tests/lib/ledgers/lightning.ts @@ -1,5 +1,5 @@ -import { LedgerInstance } from "./ledger_runner"; import { Lnd } from "comit-sdk"; +import LedgerInstance from "./ledger_instance"; /** * An instance of the Lightning ledger for use in the e2e tests. diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 54ffa7b1d5..b326f87d0e 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -70,6 +70,8 @@ export class LndInstance implements LightningInstance { // this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; // this.logger.info("lnd is ready:", this.publicKey); + + console.log(`lnd started with PID ${this.process.pid}`); } private async execBinary() { diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index b430c55e96..d3b3cd90d2 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -17,14 +17,16 @@ export class ParityInstance implements EthereumInstance { return new ParityInstance( projectRoot, logDir, - await getPort({ port: 8545 }) + await getPort({ port: 8545 }), + await getPort() ); } constructor( private readonly projectRoot: string, private readonly logDir: string, - public readonly rpcPort: number + public readonly rpcPort: number, + public readonly p2pPort: number ) {} public async start() { @@ -42,6 +44,8 @@ export class ParityInstance implements EthereumInstance { `--db-path=${this.dbDir.name}`, `--password=${this.projectRoot}/blockchain_nodes/parity/home/parity/authorities/authority.pwd`, `--jsonrpc-port=${this.rpcPort}`, + `--port=${this.p2pPort}`, + `--no-ws`, ], { @@ -59,6 +63,8 @@ export class ParityInstance implements EthereumInstance { }); const logReader = new LogReader(this.logDir + "/parity.log"); await logReader.waitForLogMessage("Public node URL:"); + + console.log(`parity started with PID ${this.process.pid}`); } public get rpcUrl() { diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index 5f346605e8..fac7a46cca 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -4,11 +4,12 @@ import { SwapRequest } from "comit-sdk"; import * as fs from "fs"; import { promisify } from "util"; import { Global } from "@jest/types"; -import { LedgerConfig } from "./ledgers/ledger_runner"; import rimraf from "rimraf"; import { Mutex } from "async-mutex"; import { exec } from "child_process"; import { LightningWallet } from "./wallets/lightning"; +import { BitcoinNodeConfig } from "./ledgers/bitcoin"; +import { EthereumNodeConfig } from "./ledgers/ethereum"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; @@ -24,6 +25,11 @@ export interface HarnessGlobal extends Global.Global { parityAccountMutex: Mutex; } +export interface LedgerConfig { + bitcoin?: BitcoinNodeConfig; + ethereum?: EthereumNodeConfig; +} + export const unlinkAsync = promisify(fs.unlink); export const existsAsync = promisify(fs.exists); export const openAsync = promisify(fs.open); diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 2161e6df99..7a959b4dbb 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -1,5 +1,4 @@ import { Config } from "@jest/types"; -import { LedgerRunner } from "../lib/ledgers/ledger_runner"; import { execAsync, HarnessGlobal, @@ -19,7 +18,6 @@ export default class DryTestEnvironment extends NodeEnvironment { private projectRoot: string; private testRoot: string; private logDir: string; - private ledgerRunner: LedgerRunner; public global: HarnessGlobal; constructor(config: Config.ProjectConfig, context: any) { @@ -67,23 +65,6 @@ export default class DryTestEnvironment extends NodeEnvironment { async teardown() { await super.teardown(); - if (this.global.verbose) { - console.log(`Tearing down test environment.`); - } - await this.cleanupAll(); - if (this.global.verbose) { - console.log(`All teared down.`); - } - } - - async cleanupAll() { - try { - if (this.ledgerRunner) { - await this.ledgerRunner.stopLedgers(); - } - } catch (e) { - console.error("Failed to clean up resources", e); - } } private extractDocblockPragmas( diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index c59bb988d4..d55608ed1d 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -1,5 +1,4 @@ import { Config } from "@jest/types"; -import { LedgerRunner } from "../lib/ledgers/ledger_runner"; import { execAsync, HarnessGlobal, @@ -13,6 +12,12 @@ import { LightningWallet } from "../lib/wallets/lightning"; import { BitcoinWallet } from "../lib/wallets/bitcoin"; import { AssetKind } from "../lib/asset"; import { LedgerKind } from "../lib/ledgers/ledger"; +import BitcoinLedger from "../lib/ledgers/bitcoin"; +import { BitcoindInstance } from "../lib/ledgers/bitcoind_instance"; +import EthereumLedger from "../lib/ledgers/ethereum"; +import LightningLedger from "../lib/ledgers/lightning"; +import { ParityInstance } from "../lib/ledgers/parity_instance"; +import { LndInstance } from "../lib/ledgers/lnd_instance"; // ************************ // // Setting global variables // @@ -23,9 +28,13 @@ export default class E2ETestEnvironment extends NodeEnvironment { private projectRoot: string; private testRoot: string; private logDir: string; - private ledgerRunner: LedgerRunner; public global: HarnessGlobal; + private bitcoinLedger?: BitcoinLedger; + private ethereumLedger?: EthereumLedger; + private aliceLightning?: LightningLedger; + private bobLightning?: LightningLedger; + constructor(config: Config.ProjectConfig, context: any) { super(config); @@ -64,63 +73,135 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); await E2ETestEnvironment.cleanLogDir(this.logDir); - if (ledgers.length > 0) { - // setup ledgers - this.ledgerRunner = new LedgerRunner(this.projectRoot, this.logDir); + await this.startLedgers(ledgers); - if (this.global.verbose) { - console.log(`Initializing ledgers : ${ledgers}`); - } - const ledgerConfig = await this.ledgerRunner.ensureLedgersRunning( - ledgers - ); + this.global.logRoot = this.logDir; + } + + /** + * Initializes all required ledgers with as much parallelism as possible. + * + * @param ledgers The list of ledgers to initialize + */ + private async startLedgers(ledgers: string[]) { + const startEthereum = ledgers.includes("ethereum"); + const startBitcoin = ledgers.includes("bitcoin"); + const startLightning = ledgers.includes("lightning"); + + const tasks = []; - const ethereum = ledgerConfig.ethereum; - if (ethereum) { - this.global.tokenContract = ethereum.tokenContract; - this.global.ledgerConfigs.ethereum = ethereum; - } - - const bitcoin = ledgerConfig.bitcoin; - if (bitcoin) { - this.global.ledgerConfigs.bitcoin = bitcoin; - } - - const lndAlice = ledgerConfig.lndAlice; - const lndBob = ledgerConfig.lndBob; - - if (lndAlice && lndBob && bitcoin) { - this.global.ledgerConfigs.lndAlice = lndAlice; - this.global.ledgerConfigs.lndBob = lndBob; - - const aliceWallet = await LightningWallet.newInstance( - await BitcoinWallet.newInstance(bitcoin), - lndAlice.lnd, - lndAlice.p2pSocket - ); - const bobWallet = await LightningWallet.newInstance( - await BitcoinWallet.newInstance(bitcoin), - lndBob.lnd, - lndBob.p2pSocket - ); - this.global.lndWallets = { - alice: aliceWallet, - bob: bobWallet, - }; - - await aliceWallet.connectPeer(bobWallet); - - await aliceWallet.mint({ - name: AssetKind.Bitcoin, - ledger: LedgerKind.Lightning, - quantity: "15000000", - }); - - await aliceWallet.openChannel(bobWallet, 15000000); - } + if (startEthereum) { + tasks.push(this.startEthereum()); } - this.global.logRoot = this.logDir; + if (startBitcoin && !startLightning) { + tasks.push(this.startBitcoin()); + } + + if (startBitcoin && startLightning) { + tasks.push(this.startBitcoinAndLightning()); + } + + await Promise.all(tasks); + } + + /** + * Start the Bitcoin Ledger + * + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startBitcoin() { + this.bitcoinLedger = await BitcoinLedger.start( + await BitcoindInstance.new(this.projectRoot, this.logDir) + ); + this.global.ledgerConfigs.bitcoin = this.bitcoinLedger.config; + } + /** + * Start the Ethereum Ledger + * + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startEthereum() { + this.ethereumLedger = await EthereumLedger.start( + await ParityInstance.new(this.projectRoot, this.logDir) + ); + this.global.ledgerConfigs.ethereum = this.ethereumLedger.config; + this.global.tokenContract = this.ethereumLedger.config.tokenContract; + } + + /** + * First starts the Bitcoin and then the Lightning ledgers. + * + * The Lightning ledgers depend on Bitcoin to be up and running. + */ + private async startBitcoinAndLightning() { + await this.startBitcoin(); + + // Lightning nodes can be started in parallel + await Promise.all([ + this.startAliceLightning(), + this.startBobLightning(), + ]); + + await this.setupLightningChannels(); + } + + private async setupLightningChannels() { + const { alice, bob } = this.global.lndWallets; + + await alice.connectPeer(bob); + + await alice.mint({ + name: AssetKind.Bitcoin, + ledger: LedgerKind.Lightning, + quantity: "15000000", + }); + + await alice.openChannel(bob, 15000000); + } + + /** + * Start the Lightning Ledger for Alice + * + * This function assumes that the Bitcoin ledger is initialized. + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startAliceLightning() { + this.aliceLightning = await LightningLedger.start( + await LndInstance.new( + this.logDir, + "lnd-alice", + path.join(this.logDir, "bitcoind") + ) + ); + + this.global.lndWallets.alice = await LightningWallet.newInstance( + await BitcoinWallet.newInstance(this.bitcoinLedger.config), + this.aliceLightning.config.lnd, + this.aliceLightning.config.p2pSocket + ); + } + + /** + * Start the Lightning Ledger for Bob + * + * This function assumes that the Bitcoin ledger is initialized. + * Once this function returns, the necessary configuration values have been set inside the test environment. + */ + private async startBobLightning() { + this.bobLightning = await LightningLedger.start( + await LndInstance.new( + this.logDir, + "lnd-bob", + path.join(this.logDir, "bitcoind") + ) + ); + + this.global.lndWallets.bob = await LightningWallet.newInstance( + await BitcoinWallet.newInstance(this.bitcoinLedger.config), + this.bobLightning.config.lnd, + this.bobLightning.config.p2pSocket + ); } private static async cleanLogDir(logDir: string) { @@ -140,13 +221,25 @@ export default class E2ETestEnvironment extends NodeEnvironment { } async cleanupAll() { - try { - if (this.ledgerRunner) { - await this.ledgerRunner.stopLedgers(); - } - } catch (e) { - console.error("Failed to clean up resources", e); + const tasks = []; + + if (this.bitcoinLedger) { + tasks.push(this.bitcoinLedger.stop); + } + + if (this.ethereumLedger) { + tasks.push(this.ethereumLedger.stop); } + + if (this.aliceLightning) { + tasks.push(this.aliceLightning.stop); + } + + if (this.bobLightning) { + tasks.push(this.bobLightning.stop); + } + + await Promise.all(tasks); } private extractDocblockPragmas( diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index 45ba121928..b080615b0e 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -1,5 +1,5 @@ /** - * @ledgers ethereum,bitcoin,lnd-alice,lnd-bob + * @ledgers ethereum,bitcoin,lightning * @logDir e2e */ From 55717c8da25b86725440c03c8ece9ad78004d1c2 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 17:52:46 +1100 Subject: [PATCH 064/145] Use a logger for everything instead of console.log --- api_tests/lib/actors/actor.ts | 15 +++--- api_tests/lib/cnd/cnd_instance.ts | 19 +++---- api_tests/lib/config.ts | 2 +- api_tests/lib/create_actor.ts | 16 ------ api_tests/lib/ledgers/bitcoin.ts | 10 ++-- api_tests/lib/ledgers/bitcoind_instance.ts | 19 +++++-- api_tests/lib/ledgers/ethereum.ts | 11 +++- api_tests/lib/ledgers/lnd_instance.ts | 61 +++++++++++---------- api_tests/lib/ledgers/parity_instance.ts | 24 +++++++-- api_tests/lib/wallets/bitcoin.ts | 18 ++++--- api_tests/lib/wallets/ethereum.ts | 18 ++++--- api_tests/lib/wallets/index.ts | 8 ++- api_tests/lib/wallets/lightning.ts | 25 ++++----- api_tests/src/e2e_test_environment.ts | 63 +++++++++++++++++----- 14 files changed, 195 insertions(+), 114 deletions(-) diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index 588a3a5237..f3d7628106 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -9,7 +9,7 @@ import { } from "comit-sdk"; import { parseEther } from "ethers/utils"; import getPort from "get-port"; -import { Logger } from "log4js"; +import { getLogger, Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; import "../setup_chai"; import { Asset, AssetKind, toKey, toKind } from "../asset"; @@ -32,7 +32,6 @@ export class Actor { }; public static async newInstance( - loggerFactory: (name: string) => Logger, name: string, ledgerConfig: LedgerConfig, projectRoot: string, @@ -44,18 +43,18 @@ export class Actor { name ); + const logger = getLogger(`${logRoot}/${name}`); + const cndInstance = new CndInstance( projectRoot, logRoot, + logger, actorConfig, ledgerConfig ); await cndInstance.start(); - const logger = loggerFactory(name); - logger.level = "debug"; - logger.info( "Created new actor with config %s", JSON.stringify(actorConfig.generateCndConfigFile(ledgerConfig)) @@ -718,7 +717,11 @@ export class Actor { this.betaLedger.name, ]) { walletPromises.push( - this.wallets.initializeForLedger(ledgerName, this.name) + this.wallets.initializeForLedger( + ledgerName, + this.logger, + this.name + ) ); } diff --git a/api_tests/lib/cnd/cnd_instance.ts b/api_tests/lib/cnd/cnd_instance.ts index c8b5116681..c16900392c 100644 --- a/api_tests/lib/cnd/cnd_instance.ts +++ b/api_tests/lib/cnd/cnd_instance.ts @@ -7,6 +7,7 @@ import { CndConfigFile, E2ETestActorConfig } from "../config"; import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; import path from "path"; import { LogReader } from "../ledgers/log_reader"; +import { Logger } from "log4js"; declare var global: HarnessGlobal; @@ -19,6 +20,7 @@ export class CndInstance { constructor( private readonly projectRoot: string, private readonly logDir: string, + private readonly logger: Logger, private readonly actorConfig: E2ETestActorConfig, private readonly ledgerConfig: LedgerConfig ) {} @@ -32,9 +34,7 @@ export class CndInstance { ? process.env.CND_BIN : this.projectRoot + "/target/debug/cnd"; - if (global.verbose) { - console.log(`[${this.actorConfig.name}] using binary ${bin}`); - } + this.logger.info("Using binary", bin); this.configFile = this.actorConfig.generateCndConfigFile( this.ledgerConfig @@ -59,23 +59,18 @@ export class CndInstance { ], }); - if (global.verbose) { - console.log( - `[${this.actorConfig.name}] process spawned with PID ${this.process.pid}` - ); - } - const logReader = new LogReader(logFile); await logReader.waitForLogMessage("Starting HTTP server on"); // we emit the log _before_ we start the http server, let's make sure it actually starts up await sleep(1000); + + this.logger.info("cnd started with PID", this.process.pid); } public stop() { - if (global.verbose) { - console.log(`terminating cnd ${this.actorConfig.name}`); - } + this.logger.info("Stopping cnd instance"); + this.process.kill("SIGINT"); this.process = null; } diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 7a4baf0223..84900550bf 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -90,7 +90,7 @@ function createLedgerConnectors(ledgerConfig: LedgerConfig): LedgerConnectors { function bitcoinConnector(nodeConfig: BitcoinNodeConfig): BitcoinConnector { return { bitcoind: { - node_url: `http://${nodeConfig.host}:${nodeConfig.rpcPort}`, + node_url: nodeConfig.rpcUrl, }, network: nodeConfig.network, }; diff --git a/api_tests/lib/create_actor.ts b/api_tests/lib/create_actor.ts index ff9da6d758..2d6fc0f999 100644 --- a/api_tests/lib/create_actor.ts +++ b/api_tests/lib/create_actor.ts @@ -1,7 +1,5 @@ -import { configure } from "log4js"; import { Actor } from "./actors/actor"; import { HarnessGlobal } from "./utils"; -import path from "path"; declare var global: HarnessGlobal; @@ -9,21 +7,7 @@ export async function createActor( testFolderName: string, name: string ): Promise { - const loggerFactory = (whoAmI: string) => - configure({ - appenders: { - file: { - type: "file", - filename: path.join(testFolderName, "test.log"), - }, - }, - categories: { - default: { appenders: ["file"], level: "debug" }, - }, - }).getLogger(whoAmI); - return Actor.newInstance( - loggerFactory, name, global.ledgerConfigs, global.projectRoot, diff --git a/api_tests/lib/ledgers/bitcoin.ts b/api_tests/lib/ledgers/bitcoin.ts index cc5f79f4da..819cfb71f9 100644 --- a/api_tests/lib/ledgers/bitcoin.ts +++ b/api_tests/lib/ledgers/bitcoin.ts @@ -1,5 +1,6 @@ import BitcoinRpcClient from "bitcoin-core"; import LedgerInstance from "./ledger_instance"; +import { Logger } from "log4js"; /** * An instance of the Bitcoin ledger for use in the e2e tests. @@ -11,10 +12,12 @@ import LedgerInstance from "./ledger_instance"; * been setup, regardless of how that is achieved (Docker container, bitcoind instance, etc). */ export default class BitcoinLedger implements LedgerInstance { - public static async start(instance: BitcoinInstance) { + public static async start(instance: BitcoinInstance, logger: Logger) { await instance.start(); - const { rpcPort, username, password } = instance.config; + const { rpcPort, username, password, rpcUrl } = instance.config; + + logger.info("Bitcoin instance started at", rpcUrl); const client = new BitcoinRpcClient({ network: "regtest", @@ -30,7 +33,7 @@ export default class BitcoinLedger implements LedgerInstance { await client.generateToAddress(1, await client.getNewAddress()); }, 1000); - console.log("Bitcoin miner initialized"); + logger.info("Bitcoin miner initialized"); return new BitcoinLedger(instance, miner); } @@ -63,6 +66,7 @@ export interface BitcoinNodeConfig { password: string; host: string; rpcPort: number; + rpcUrl: string; p2pPort: number; dataDir: string; } diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index a9c2084db6..19fcfd596c 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -5,6 +5,7 @@ import * as path from "path"; import { mkdirAsync, openAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; +import { Logger } from "log4js"; export class BitcoindInstance implements BitcoinInstance { private process: ChildProcess; @@ -14,11 +15,13 @@ export class BitcoindInstance implements BitcoinInstance { public static async new( projectRoot: string, - logDir: string + logDir: string, + logger: Logger ): Promise { return new BitcoindInstance( projectRoot, logDir, + logger, await getPort({ port: 18444 }), await getPort({ port: 18443 }), await getPort({ port: 28332 }), @@ -29,6 +32,7 @@ export class BitcoindInstance implements BitcoinInstance { constructor( private readonly projectRoot: string, private readonly logDir: string, + private readonly logger: Logger, public readonly p2pPort: number, public readonly rpcPort: number, public readonly zmqPubRawBlockPort: number, @@ -46,6 +50,7 @@ export class BitcoindInstance implements BitcoinInstance { "bin", "bitcoind" ); + this.logger.info("Using binary", bin); this.dataDir = path.join(this.logDir, "bitcoind"); await mkdirAsync(this.dataDir, "755"); @@ -62,7 +67,12 @@ export class BitcoindInstance implements BitcoinInstance { }); this.process.on("exit", (code: number, signal: number) => { - console.log(`bitcoind exited with ${code || `signal ${signal}`}`); + this.logger.info( + "binary exited with code", + code, + "after signal", + signal + ); }); const logReader = new LogReader(this.logPath()); @@ -77,7 +87,7 @@ export class BitcoindInstance implements BitcoinInstance { this.username = username; this.password = password; - console.log(`bitcoind started with PID ${this.process.pid}`); + this.logger.info("bitcoind started with PID", this.process.pid); } public get config(): BitcoinNodeConfig { @@ -89,10 +99,13 @@ export class BitcoindInstance implements BitcoinInstance { username: this.username, password: this.password, dataDir: this.getDataDir(), + rpcUrl: `http://localhost:${this.rpcPort}`, }; } public async stop() { + this.logger.info("Stopping bitcoind instance"); + this.process.kill("SIGINT"); } diff --git a/api_tests/lib/ledgers/ethereum.ts b/api_tests/lib/ledgers/ethereum.ts index 6980806dbc..1e15244bc1 100644 --- a/api_tests/lib/ledgers/ethereum.ts +++ b/api_tests/lib/ledgers/ethereum.ts @@ -1,5 +1,6 @@ import { EthereumWallet } from "../wallets/ethereum"; import LedgerInstance from "./ledger_instance"; +import { Logger } from "log4js"; /** * An instance of the Ethereum ledger for use in the e2e tests. @@ -14,12 +15,18 @@ import LedgerInstance from "./ledger_instance"; * of which implementation is used (Docker container, parity, geth, etc). */ export default class EthereumLedger implements LedgerInstance { - public static async start(instance: EthereumInstance) { + public static async start(instance: EthereumInstance, logger: Logger) { await instance.start(); - const erc20Wallet = new EthereumWallet(instance.rpcUrl); + const rpcUrl = instance.rpcUrl; + + logger.info("Ethereum node started at", rpcUrl); + + const erc20Wallet = new EthereumWallet(rpcUrl, logger); const erc20TokenContract = await erc20Wallet.deployErc20TokenContract(); + logger.info("ERC20 token contract deployed at", erc20TokenContract); + return new EthereumLedger(instance, erc20TokenContract); } diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index b326f87d0e..3fd45d40f5 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -6,21 +6,24 @@ import { LogReader } from "./log_reader"; import { Lnd } from "comit-sdk"; import whereis from "@wcjiang/whereis"; import { LightningInstance, LightningNodeConfig } from "./lightning"; +import { Logger } from "log4js"; export class LndInstance implements LightningInstance { private process: ChildProcess; private lndDir: string; public lnd: Lnd; - // private publicKey?: string; + private publicKey?: string; public static async new( testLogDir: string, name: string, + logger: Logger, bitcoindDataDir: string ) { return new LndInstance( testLogDir, name, + logger, bitcoindDataDir, await getPort(), await getPort() @@ -30,6 +33,7 @@ export class LndInstance implements LightningInstance { private constructor( private readonly testLogDir: string, private readonly name: string, + private readonly logger: Logger, private readonly bitcoindDataDir: string, private readonly lndP2pPort: number, private readonly lndRpcPort: number @@ -42,51 +46,55 @@ export class LndInstance implements LightningInstance { await this.execBinary(); - // this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); + this.logger.debug("Waiting for lnd log file to exist:", this.logPath()); await waitUntilFileExists(this.logPath()); - // this.logger.debug("Waiting for lnd password RPC server"); + this.logger.debug("Waiting for lnd password RPC server"); await this.logReader().waitForLogMessage( "RPCS: password RPC server listening" ); await this.initWallet(); - // this.logger.debug("Waiting for lnd unlocked RPC server"); + this.logger.debug("Waiting for lnd unlocked RPC server"); await this.logReader().waitForLogMessage("RPCS: RPC server listening"); - // this.logger.debug( - // "Waiting for admin macaroon file to exist:", - // this.adminMacaroonPath() - // ); + this.logger.debug( + "Waiting for admin macaroon file to exist:", + this.adminMacaroonPath() + ); await waitUntilFileExists(this.adminMacaroonPath()); - // this.logger.debug("Waiting for lnd to catch up with blocks"); + this.logger.debug("Waiting for lnd to catch up with blocks"); await this.logReader().waitForLogMessage( "LNWL: Done catching up block hashes" ); await this.initAuthenticatedLndConnection(); - // this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; - // this.logger.info("lnd is ready:", this.publicKey); + this.publicKey = (await this.lnd.lnrpc.getInfo()).identityPubkey; + this.logger.info("lnd is ready:", this.publicKey); - console.log(`lnd started with PID ${this.process.pid}`); + this.logger.debug("lnd started with PID", this.process.pid); } private async execBinary() { const bin = process.env.LND_BIN ? process.env.LND_BIN : await whereis("lnd"); - // this.logger.debug(`Using binary ${bin}`); + this.logger.debug(`Using binary ${bin}`); this.process = spawn(bin, ["--lnddir", this.lndDir], { stdio: ["ignore", "ignore", "ignore"], // stdin, stdout, stderr. These are all logged already. }); - // this.logger.debug(`Process spawned LND with PID ${this.process.pid}`); - // this.process.on("exit", (code: number, signal: number) => { - // this.logger.debug(`lnd exited with ${code || `signal ${signal}`}`); - // }); + this.process.on("exit", (code: number, signal: number) => { + this.logger.info( + "lnd exited with code", + code, + "after signal", + signal + ); + }); } private async initWallet() { @@ -94,21 +102,20 @@ export class LndInstance implements LightningInstance { server: this.grpcSocket, tls: this.tlsCertPath(), }; - // this.logger.debug("Instantiating lnd connection:", config); + this.logger.debug("Instantiating lnd connection:", config); const lnd = await Lnd.init(config); - // this.logger.debug("Calling genSeed"); const { cipherSeedMnemonic } = await lnd.lnrpc.genSeed({ seedEntropy: Buffer.alloc(16, this.name), }); const walletPassword = Buffer.from("password", "utf8"); - // this.logger.debug( - // "Initialize wallet", - // cipherSeedMnemonic, - // walletPassword - // ); + this.logger.debug( + "Initialize wallet", + cipherSeedMnemonic, + walletPassword + ); await lnd.lnrpc.initWallet({ cipherSeedMnemonic, walletPassword }); - // this.logger.debug("Wallet initialized!"); + this.logger.debug("Lnd wallet initialized!"); } private async initAuthenticatedLndConnection() { @@ -117,12 +124,12 @@ export class LndInstance implements LightningInstance { tls: this.tlsCertPath(), macaroonPath: this.adminMacaroonPath(), }; - // this.logger.debug("Instantiating lnd connection:", config); + this.lnd = await Lnd.init(config); } public async stop() { - // this.logger.debug("Stopping lnd instance"); + this.logger.debug("Stopping lnd instance"); this.process.kill("SIGTERM"); this.process = null; } diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index d3b3cd90d2..104857420e 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -6,6 +6,7 @@ import { promisify } from "util"; import { sleep } from "../utils"; import getPort from "get-port"; import { EthereumInstance } from "./ethereum"; +import { Logger } from "log4js"; const openAsync = promisify(fs.open); @@ -13,10 +14,15 @@ export class ParityInstance implements EthereumInstance { private process: ChildProcess; private dbDir: any; - public static async new(projectRoot: string, logDir: string) { + public static async new( + projectRoot: string, + logDir: string, + logger: Logger + ) { return new ParityInstance( projectRoot, logDir, + logger, await getPort({ port: 8545 }), await getPort() ); @@ -25,6 +31,7 @@ export class ParityInstance implements EthereumInstance { constructor( private readonly projectRoot: string, private readonly logDir: string, + private readonly logger: Logger, public readonly rpcPort: number, public readonly p2pPort: number ) {} @@ -33,6 +40,9 @@ export class ParityInstance implements EthereumInstance { const bin = process.env.PARITY_BIN ? process.env.PARITY_BIN : this.projectRoot + "/blockchain_nodes/parity/parity"; + + this.logger.info("Using binary", bin); + this.dbDir = tmp.dirSync(); this.process = spawn( @@ -59,12 +69,18 @@ export class ParityInstance implements EthereumInstance { ); this.process.on("exit", (code: number, signal: number) => { - console.log(`parity exited with ${code || `signal ${signal}`}`); + this.logger.info( + "parity exited with code", + code, + "after signal", + signal + ); }); + const logReader = new LogReader(this.logDir + "/parity.log"); await logReader.waitForLogMessage("Public node URL:"); - console.log(`parity started with PID ${this.process.pid}`); + this.logger.info("parity started with PID", this.process.pid); } public get rpcUrl() { @@ -72,6 +88,8 @@ export class ParityInstance implements EthereumInstance { } public async stop() { + this.logger.info("Stopping parity instance"); + this.process.kill("SIGTERM"); await sleep(3000); this.process.kill("SIGKILL"); diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/lib/wallets/bitcoin.ts index 8e872a29fa..bbb29ef634 100644 --- a/api_tests/lib/wallets/bitcoin.ts +++ b/api_tests/lib/wallets/bitcoin.ts @@ -1,3 +1,4 @@ +import { Logger } from "log4js"; import * as bcoin from "bcoin"; import BitcoinRpcClient from "bitcoin-core"; import { @@ -10,7 +11,7 @@ import { pollUntilMinted, Wallet } from "./index"; import { BitcoinNodeConfig } from "../ledgers/bitcoin"; export class BitcoinWallet implements Wallet { - public static async newInstance(config: BitcoinNodeConfig) { + public static async newInstance(config: BitcoinNodeConfig, logger: Logger) { const hdKey = bcoin.HDPrivateKey.generate().xprivkey(config.network); const wallet = await BitcoinWalletSdk.newInstance( config.network, @@ -27,14 +28,15 @@ export class BitcoinWallet implements Wallet { password: config.password, }); - return new BitcoinWallet(wallet, bitcoinRpcClient); + return new BitcoinWallet(wallet, bitcoinRpcClient, logger); } public MaximumFee = 100000; private constructor( public readonly inner: BitcoinWalletSdk, - private readonly bitcoinRpcClient: BitcoinRpcClient + private readonly bitcoinRpcClient: BitcoinRpcClient, + private readonly logger: Logger ) {} public async mintToAddress( @@ -48,10 +50,12 @@ export class BitcoinWallet implements Wallet { ); } - await this.bitcoinRpcClient.sendToAddress( - toAddress, - toBitcoin(minimumExpectedBalance.times(2).toString()) // make sure we have at least twice as much - ); + // make sure we have at least twice as much + const amount = toBitcoin(minimumExpectedBalance.times(2).toString()); + + await this.bitcoinRpcClient.sendToAddress(toAddress, amount); + + this.logger.info("Minted", amount, "bitcoin for", toAddress); } public async mint(asset: Asset): Promise { diff --git a/api_tests/lib/wallets/ethereum.ts b/api_tests/lib/wallets/ethereum.ts index cb403c6c7c..3917f2ae6e 100644 --- a/api_tests/lib/wallets/ethereum.ts +++ b/api_tests/lib/wallets/ethereum.ts @@ -5,6 +5,7 @@ import { BigNumber as BigNumberEthers } from "ethers/utils"; import { pollUntilMinted, Wallet } from "./index"; import { TransactionRequest } from "ethers/providers"; import { HarnessGlobal, sleep } from "../utils"; +import { Logger } from "log4js"; declare var global: HarnessGlobal; @@ -15,7 +16,7 @@ export class EthereumWallet implements Wallet { private readonly parity: ethers.Wallet; private readonly jsonRpcProvider: ethers.providers.JsonRpcProvider; - constructor(rpcUrl: string) { + constructor(rpcUrl: string, private readonly logger: Logger) { const provider = new ethers.providers.JsonRpcProvider(rpcUrl); this.parity = new ethers.Wallet( "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7", @@ -67,11 +68,14 @@ export class EthereumWallet implements Wallet { ); } - if (global.verbose) { - console.log( - `Minted ${asset.quantity} erc20 tokens (${asset.token_contract}) for ${toAddress}` - ); - } + this.logger.info( + "Minted", + asset.quantity, + "erc20 tokens (", + asset.token_contract, + ") for", + toAddress + ); } private async sendTransaction(tx: TransactionRequest) { @@ -100,6 +104,8 @@ export class EthereumWallet implements Wallet { startingBalance.minus(new BigNumber(minimumExpectedBalance)), asset ); + + this.logger.info("Minted", asset.quantity, "ether for", this.account()); } public account(): string { diff --git a/api_tests/lib/wallets/index.ts b/api_tests/lib/wallets/index.ts index d8d7ff924e..13e283cf76 100644 --- a/api_tests/lib/wallets/index.ts +++ b/api_tests/lib/wallets/index.ts @@ -3,6 +3,7 @@ import { HarnessGlobal, sleep } from "../utils"; import { BitcoinWallet } from "./bitcoin"; import { EthereumWallet } from "./ethereum"; import { LightningWallet } from "./lightning"; +import { Logger } from "log4js"; declare var global: HarnessGlobal; @@ -48,17 +49,20 @@ export class Wallets { public async initializeForLedger( name: K, + logger: Logger, actor?: string ) { switch (name) { case "ethereum": this.wallets.ethereum = new EthereumWallet( - global.ledgerConfigs.ethereum.rpc_url + global.ledgerConfigs.ethereum.rpc_url, + logger ); break; case "bitcoin": this.wallets.bitcoin = await BitcoinWallet.newInstance( - global.ledgerConfigs.bitcoin + global.ledgerConfigs.bitcoin, + logger ); break; case "lightning": diff --git a/api_tests/lib/wallets/lightning.ts b/api_tests/lib/wallets/lightning.ts index 36d921c4db..b5540d1a24 100644 --- a/api_tests/lib/wallets/lightning.ts +++ b/api_tests/lib/wallets/lightning.ts @@ -9,11 +9,12 @@ import { Outpoint, } from "comit-sdk"; import { AddressType } from "@radar/lnrpc"; +import { Logger } from "log4js"; export class LightningWallet implements Wallet { public static async newInstance( bitcoinWallet: BitcoinWallet, - // logger: Logger, + logger: Logger, lnd: Lnd, lndp2pSocket: string ) { @@ -24,16 +25,16 @@ export class LightningWallet implements Wallet { lndp2pSocket ); - // logger.debug("lnd getinfo:", await inner.lnd.lnrpc.getInfo()); + logger.debug("lnd getinfo:", await inner.lnd.lnrpc.getInfo()); - return new LightningWallet(inner, bitcoinWallet); + return new LightningWallet(inner, logger, bitcoinWallet); } public MaximumFee = 0; private constructor( public readonly inner: LightningWalletSdk, - // private readonly logger: Logger, + private readonly logger: Logger, private readonly bitcoinWallet: BitcoinWallet ) {} @@ -47,10 +48,10 @@ export class LightningWallet implements Wallet { const startingBalance = new BigNumber( await this.getBalanceByAsset(asset) ); - // this.logger.debug("starting: ", startingBalance.toString()); + this.logger.debug("starting: ", startingBalance.toString()); const minimumExpectedBalance = new BigNumber(asset.quantity); - // this.logger.debug("min expected: ", minimumExpectedBalance.toString()); + this.logger.debug("min expected: ", minimumExpectedBalance.toString()); await this.bitcoinWallet.mintToAddress( minimumExpectedBalance, @@ -112,9 +113,9 @@ export class LightningWallet implements Wallet { let toIsSynced = (await toWallet.inner.getInfo()).syncedToChain; while (!thisIsSynced || !toIsSynced) { - // this.logger.info( - // `One of the lnd node is not yet synced, waiting. this: ${thisIsSynced}, to: ${toIsSynced}` - // ); + this.logger.info( + `One of the lnd node is not yet synced, waiting. this: ${thisIsSynced}, to: ${toIsSynced}` + ); await sleep(500); thisIsSynced = (await this.inner.getInfo()).syncedToChain; @@ -125,7 +126,7 @@ export class LightningWallet implements Wallet { await toWallet.inner.getPubkey(), quantity ); - // this.logger.debug("Channel opened, waiting for confirmations"); + this.logger.debug("Channel opened, waiting for confirmations"); await this.pollUntilChannelIsOpen(outpoint); } @@ -161,9 +162,9 @@ export class LightningWallet implements Wallet { const channels = await this.getChannels(); if (channels) { for (const channel of channels) { - // this.logger.debug(`Looking for channel ${txId}:${vout}`); + this.logger.debug(`Looking for channel ${txId}:${vout}`); if (channel.channelPoint === `${txId}:${vout}`) { - // this.logger.debug("Found a channel:", channel); + this.logger.debug("Found a channel:", channel); return; } } diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index d55608ed1d..29e26c9d9b 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -18,6 +18,7 @@ import EthereumLedger from "../lib/ledgers/ethereum"; import LightningLedger from "../lib/ledgers/lightning"; import { ParityInstance } from "../lib/ledgers/parity_instance"; import { LndInstance } from "../lib/ledgers/lnd_instance"; +import { configure, getLogger, Logger } from "log4js"; // ************************ // // Setting global variables // @@ -35,6 +36,8 @@ export default class E2ETestEnvironment extends NodeEnvironment { private aliceLightning?: LightningLedger; private bobLightning?: LightningLedger; + private logger: Logger; + constructor(config: Config.ProjectConfig, context: any) { super(config); @@ -62,15 +65,30 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.global.parityAccountMutex = new Mutex(); - if (this.global.verbose) { - console.log(`Starting up test environment`); - } - const { ledgers, logDir } = this.extractDocblockPragmas( this.docblockPragmas ); this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); + + configure({ + appenders: { + multi: { + type: "multiFile", + base: this.logDir, + property: "categoryName", + extension: ".log", + }, + }, + categories: { + default: { appenders: ["multi"], level: "debug" }, + }, + }); + + this.logger = getLogger("test-environment"); + + this.logger.info("Starting up test environment"); + await E2ETestEnvironment.cleanLogDir(this.logDir); await this.startLedgers(ledgers); @@ -112,7 +130,12 @@ export default class E2ETestEnvironment extends NodeEnvironment { */ private async startBitcoin() { this.bitcoinLedger = await BitcoinLedger.start( - await BitcoindInstance.new(this.projectRoot, this.logDir) + await BitcoindInstance.new( + this.projectRoot, + this.logDir, + this.logger + ), + this.logger ); this.global.ledgerConfigs.bitcoin = this.bitcoinLedger.config; } @@ -123,7 +146,12 @@ export default class E2ETestEnvironment extends NodeEnvironment { */ private async startEthereum() { this.ethereumLedger = await EthereumLedger.start( - await ParityInstance.new(this.projectRoot, this.logDir) + await ParityInstance.new( + this.projectRoot, + this.logDir, + this.logger + ), + this.logger ); this.global.ledgerConfigs.ethereum = this.ethereumLedger.config; this.global.tokenContract = this.ethereumLedger.config.tokenContract; @@ -171,12 +199,17 @@ export default class E2ETestEnvironment extends NodeEnvironment { await LndInstance.new( this.logDir, "lnd-alice", + this.logger, path.join(this.logDir, "bitcoind") ) ); this.global.lndWallets.alice = await LightningWallet.newInstance( - await BitcoinWallet.newInstance(this.bitcoinLedger.config), + await BitcoinWallet.newInstance( + this.bitcoinLedger.config, + this.logger + ), + this.logger, this.aliceLightning.config.lnd, this.aliceLightning.config.p2pSocket ); @@ -193,12 +226,17 @@ export default class E2ETestEnvironment extends NodeEnvironment { await LndInstance.new( this.logDir, "lnd-bob", + this.logger, path.join(this.logDir, "bitcoind") ) ); this.global.lndWallets.bob = await LightningWallet.newInstance( - await BitcoinWallet.newInstance(this.bitcoinLedger.config), + await BitcoinWallet.newInstance( + this.bitcoinLedger.config, + this.logger + ), + this.logger, this.bobLightning.config.lnd, this.bobLightning.config.p2pSocket ); @@ -211,13 +249,10 @@ export default class E2ETestEnvironment extends NodeEnvironment { async teardown() { await super.teardown(); - if (this.global.verbose) { - console.log(`Tearing down test environment.`); - } + this.logger.info("Tearing down test environment"); + await this.cleanupAll(); - if (this.global.verbose) { - console.log(`All teared down.`); - } + this.logger.info("Tearing down complete"); } async cleanupAll() { From ed51007dd2cd0d57496ac0df997c1bac2444c3ff Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 18:59:15 +1100 Subject: [PATCH 065/145] Simplify actor logging Instead of passing all kinds of information down, we construct all the necessary paths right at the top and pass the fully constructed paths and loggers down. This reduces the complexity of downstream components like CndInstance quite a bit as they no longer have to know, where the logs actually end up. --- api_tests/lib/actors/actor.ts | 14 ++++++------ api_tests/lib/cnd/cnd_instance.ts | 26 ++++++---------------- api_tests/lib/create_actor.ts | 16 -------------- api_tests/lib/create_actors.ts | 31 +++++++++++++++++---------- api_tests/lib/utils.ts | 2 ++ api_tests/src/e2e_test_environment.ts | 10 ++++----- 6 files changed, 40 insertions(+), 59 deletions(-) delete mode 100644 api_tests/lib/create_actor.ts diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index f3d7628106..cfbaa8c88a 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -9,7 +9,7 @@ import { } from "comit-sdk"; import { parseEther } from "ethers/utils"; import getPort from "get-port"; -import { getLogger, Logger } from "log4js"; +import { Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; import "../setup_chai"; import { Asset, AssetKind, toKey, toKind } from "../asset"; @@ -35,7 +35,8 @@ export class Actor { name: string, ledgerConfig: LedgerConfig, projectRoot: string, - logRoot: string + cndLogFile: string, + logger: Logger ) { const actorConfig = new E2ETestActorConfig( await getPort(), @@ -43,21 +44,20 @@ export class Actor { name ); - const logger = getLogger(`${logRoot}/${name}`); + const cndConfigFile = actorConfig.generateCndConfigFile(ledgerConfig); const cndInstance = new CndInstance( projectRoot, - logRoot, + cndLogFile, logger, - actorConfig, - ledgerConfig + cndConfigFile ); await cndInstance.start(); logger.info( "Created new actor with config %s", - JSON.stringify(actorConfig.generateCndConfigFile(ledgerConfig)) + JSON.stringify(cndConfigFile) ); return new Actor(logger, cndInstance, name); diff --git a/api_tests/lib/cnd/cnd_instance.ts b/api_tests/lib/cnd/cnd_instance.ts index c16900392c..fac2bccee0 100644 --- a/api_tests/lib/cnd/cnd_instance.ts +++ b/api_tests/lib/cnd/cnd_instance.ts @@ -3,9 +3,8 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import tempWrite from "temp-write"; import { promisify } from "util"; -import { CndConfigFile, E2ETestActorConfig } from "../config"; -import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; -import path from "path"; +import { CndConfigFile } from "../config"; +import { HarnessGlobal, sleep } from "../utils"; import { LogReader } from "../ledgers/log_reader"; import { Logger } from "log4js"; @@ -15,14 +14,12 @@ const openAsync = promisify(fs.open); export class CndInstance { private process: ChildProcess; - private configFile?: CndConfigFile; constructor( private readonly projectRoot: string, - private readonly logDir: string, + private readonly logFile: string, private readonly logger: Logger, - private readonly actorConfig: E2ETestActorConfig, - private readonly ledgerConfig: LedgerConfig + private readonly configFile: CndConfigFile ) {} public getConfigFile() { @@ -36,30 +33,21 @@ export class CndInstance { this.logger.info("Using binary", bin); - this.configFile = this.actorConfig.generateCndConfigFile( - this.ledgerConfig - ); - const configFile = await tempWrite( stringify((this.configFile as unknown) as JsonMap), "config.toml" ); - const logFile = path.join( - this.logDir, - `cnd-${this.actorConfig.name}.log` - ); - this.process = spawn(bin, ["--config", configFile], { cwd: this.projectRoot, stdio: [ "ignore", // stdin - await openAsync(logFile, "w"), // stdout - await openAsync(logFile, "w"), // stderr + await openAsync(this.logFile, "w"), // stdout + await openAsync(this.logFile, "w"), // stderr ], }); - const logReader = new LogReader(logFile); + const logReader = new LogReader(this.logFile); await logReader.waitForLogMessage("Starting HTTP server on"); // we emit the log _before_ we start the http server, let's make sure it actually starts up diff --git a/api_tests/lib/create_actor.ts b/api_tests/lib/create_actor.ts deleted file mode 100644 index 2d6fc0f999..0000000000 --- a/api_tests/lib/create_actor.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Actor } from "./actors/actor"; -import { HarnessGlobal } from "./utils"; - -declare var global: HarnessGlobal; - -export async function createActor( - testFolderName: string, - name: string -): Promise { - return Actor.newInstance( - name, - global.ledgerConfigs, - global.projectRoot, - testFolderName - ); -} diff --git a/api_tests/lib/create_actors.ts b/api_tests/lib/create_actors.ts index 661e2564ed..796723b64e 100644 --- a/api_tests/lib/create_actors.ts +++ b/api_tests/lib/create_actors.ts @@ -1,7 +1,6 @@ import { Actors } from "./actors"; import { Actor } from "./actors/actor"; -import { createActor } from "./create_actor"; -import { HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; +import { HarnessGlobal } from "./utils"; import path from "path"; declare var global: HarnessGlobal; @@ -11,13 +10,28 @@ export async function createActors( actorNames: string[] ): Promise { const actorsMap = new Map(); - const testFolderName = path.join(global.logRoot, "tests", testName); - - await resetLogs(testFolderName); const listPromises: Promise[] = []; for (const name of actorNames) { - listPromises.push(createActor(testFolderName, name)); + const cndLogFile = path.join( + global.logRoot, + "tests", + testName, + `cnd-${name}.log` + ); + const actorLogger = global.log4js.getLogger( + `tests/${testName}/${name}` + ); + + listPromises.push( + Actor.newInstance( + name, + global.ledgerConfigs, + global.projectRoot, + cndLogFile, + actorLogger + ) + ); } const createdActors = await Promise.all(listPromises); for (const actor of createdActors) { @@ -32,8 +46,3 @@ export async function createActors( return actors; } - -async function resetLogs(logDir: string) { - await rimrafAsync(logDir); - await mkdirAsync(logDir, { recursive: true }); -} diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index fac7a46cca..c1357526c8 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -10,6 +10,7 @@ import { exec } from "child_process"; import { LightningWallet } from "./wallets/lightning"; import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; +import { Log4js } from "log4js"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; @@ -23,6 +24,7 @@ export interface HarnessGlobal extends Global.Global { verbose: boolean; tokenContract: string; parityAccountMutex: Mutex; + log4js: Log4js; } export interface LedgerConfig { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 29e26c9d9b..124d9bd1df 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -18,7 +18,7 @@ import EthereumLedger from "../lib/ledgers/ethereum"; import LightningLedger from "../lib/ledgers/lightning"; import { ParityInstance } from "../lib/ledgers/parity_instance"; import { LndInstance } from "../lib/ledgers/lnd_instance"; -import { configure, getLogger, Logger } from "log4js"; +import { configure, Logger } from "log4js"; // ************************ // // Setting global variables // @@ -70,8 +70,9 @@ export default class E2ETestEnvironment extends NodeEnvironment { ); this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); + await E2ETestEnvironment.cleanLogDir(this.logDir); - configure({ + this.global.log4js = configure({ appenders: { multi: { type: "multiFile", @@ -84,13 +85,10 @@ export default class E2ETestEnvironment extends NodeEnvironment { default: { appenders: ["multi"], level: "debug" }, }, }); - - this.logger = getLogger("test-environment"); + this.logger = this.global.log4js.getLogger("test_environment"); this.logger.info("Starting up test environment"); - await E2ETestEnvironment.cleanLogDir(this.logDir); - await this.startLedgers(ledgers); this.global.logRoot = this.logDir; From 425417efc4f79462c12f5a62d84efccee009fc61 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 19:02:55 +1100 Subject: [PATCH 066/145] Make it easier to construct an instance of E2ETestActorConfig --- api_tests/lib/actors/actor.ts | 8 +------- api_tests/lib/config.ts | 5 +++++ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/api_tests/lib/actors/actor.ts b/api_tests/lib/actors/actor.ts index cfbaa8c88a..0779ed9ad4 100644 --- a/api_tests/lib/actors/actor.ts +++ b/api_tests/lib/actors/actor.ts @@ -8,7 +8,6 @@ import { SwapDetails, } from "comit-sdk"; import { parseEther } from "ethers/utils"; -import getPort from "get-port"; import { Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; import "../setup_chai"; @@ -38,12 +37,7 @@ export class Actor { cndLogFile: string, logger: Logger ) { - const actorConfig = new E2ETestActorConfig( - await getPort(), - await getPort(), - name - ); - + const actorConfig = await E2ETestActorConfig.for(name); const cndConfigFile = actorConfig.generateCndConfigFile(ledgerConfig); const cndInstance = new CndInstance( diff --git a/api_tests/lib/config.ts b/api_tests/lib/config.ts index 84900550bf..cd82a79017 100644 --- a/api_tests/lib/config.ts +++ b/api_tests/lib/config.ts @@ -2,6 +2,7 @@ import * as tmp from "tmp"; import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; import { LedgerConfig } from "./utils"; +import getPort from "get-port"; export interface CndConfigFile { http_api: HttpApi; @@ -17,6 +18,10 @@ export interface HttpApi { export class E2ETestActorConfig { public readonly data: string; + public static async for(name: string) { + return new E2ETestActorConfig(await getPort(), await getPort(), name); + } + constructor( public readonly httpApiPort: number, public readonly comitPort: number, From 4cac73d06d59ae42b62ed384370a04bdd0ef72c3 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 19:25:26 +1100 Subject: [PATCH 067/145] Abstract away log files paths and data directories Instead of constructing the same paths over and over again in different places, we provide functions on the global object that allow any component to get a specific path like a data directory. --- api_tests/lib/create_actors.ts | 12 ++---- api_tests/lib/ledgers/bitcoind_instance.ts | 11 ++---- api_tests/lib/ledgers/lnd_instance.ts | 21 +++++----- api_tests/lib/ledgers/parity_instance.ts | 12 +++--- api_tests/lib/utils.ts | 8 ++-- api_tests/src/dry_test_environment.ts | 40 +++++++++++++++---- api_tests/src/e2e_test_environment.ts | 45 +++++++++++++--------- 7 files changed, 88 insertions(+), 61 deletions(-) diff --git a/api_tests/lib/create_actors.ts b/api_tests/lib/create_actors.ts index 796723b64e..0d6435d5e5 100644 --- a/api_tests/lib/create_actors.ts +++ b/api_tests/lib/create_actors.ts @@ -1,7 +1,6 @@ import { Actors } from "./actors"; import { Actor } from "./actors/actor"; import { HarnessGlobal } from "./utils"; -import path from "path"; declare var global: HarnessGlobal; @@ -13,15 +12,12 @@ export async function createActors( const listPromises: Promise[] = []; for (const name of actorNames) { - const cndLogFile = path.join( - global.logRoot, + const cndLogFile = global.getLogFile([ "tests", testName, - `cnd-${name}.log` - ); - const actorLogger = global.log4js.getLogger( - `tests/${testName}/${name}` - ); + `cnd-${name}.log`, + ]); + const actorLogger = global.getLogger(`tests/${testName}/${name}`); listPromises.push( Actor.newInstance( diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index 19fcfd596c..1f10eb9720 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -2,25 +2,24 @@ import { ChildProcess, spawn } from "child_process"; import * as fs from "fs"; import { LogReader } from "./log_reader"; import * as path from "path"; -import { mkdirAsync, openAsync, writeFileAsync } from "../utils"; +import { openAsync, writeFileAsync } from "../utils"; import getPort from "get-port"; import { BitcoinInstance, BitcoinNodeConfig } from "./bitcoin"; import { Logger } from "log4js"; export class BitcoindInstance implements BitcoinInstance { private process: ChildProcess; - private dataDir: string; private username: string; private password: string; public static async new( projectRoot: string, - logDir: string, + dataDir: string, logger: Logger ): Promise { return new BitcoindInstance( projectRoot, - logDir, + dataDir, logger, await getPort({ port: 18444 }), await getPort({ port: 18443 }), @@ -31,7 +30,7 @@ export class BitcoindInstance implements BitcoinInstance { constructor( private readonly projectRoot: string, - private readonly logDir: string, + private readonly dataDir: string, private readonly logger: Logger, public readonly p2pPort: number, public readonly rpcPort: number, @@ -52,8 +51,6 @@ export class BitcoindInstance implements BitcoinInstance { ); this.logger.info("Using binary", bin); - this.dataDir = path.join(this.logDir, "bitcoind"); - await mkdirAsync(this.dataDir, "755"); await this.createConfigFile(this.dataDir); const log = this.logPath(); diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/lib/ledgers/lnd_instance.ts index 3fd45d40f5..30c55d64b6 100644 --- a/api_tests/lib/ledgers/lnd_instance.ts +++ b/api_tests/lib/ledgers/lnd_instance.ts @@ -1,5 +1,5 @@ import { ChildProcess, spawn } from "child_process"; -import { mkdirAsync, waitUntilFileExists, writeFileAsync } from "../utils"; +import { waitUntilFileExists, writeFileAsync } from "../utils"; import * as path from "path"; import getPort from "get-port"; import { LogReader } from "./log_reader"; @@ -10,18 +10,17 @@ import { Logger } from "log4js"; export class LndInstance implements LightningInstance { private process: ChildProcess; - private lndDir: string; public lnd: Lnd; private publicKey?: string; public static async new( - testLogDir: string, + dataDir: string, name: string, logger: Logger, bitcoindDataDir: string ) { return new LndInstance( - testLogDir, + dataDir, name, logger, bitcoindDataDir, @@ -31,7 +30,7 @@ export class LndInstance implements LightningInstance { } private constructor( - private readonly testLogDir: string, + private readonly dataDir: string, private readonly name: string, private readonly logger: Logger, private readonly bitcoindDataDir: string, @@ -40,8 +39,6 @@ export class LndInstance implements LightningInstance { ) {} public async start() { - this.lndDir = path.join(this.testLogDir, "lnd-" + this.name); - await mkdirAsync(this.lndDir, "755"); await this.createConfigFile(); await this.execBinary(); @@ -83,7 +80,7 @@ export class LndInstance implements LightningInstance { ? process.env.LND_BIN : await whereis("lnd"); this.logger.debug(`Using binary ${bin}`); - this.process = spawn(bin, ["--lnddir", this.lndDir], { + this.process = spawn(bin, ["--lnddir", this.dataDir], { stdio: ["ignore", "ignore", "ignore"], // stdin, stdout, stderr. These are all logged already. }); @@ -139,16 +136,16 @@ export class LndInstance implements LightningInstance { } public logPath() { - return path.join(this.lndDir, "logs", "bitcoin", "regtest", "lnd.log"); + return path.join(this.dataDir, "logs", "bitcoin", "regtest", "lnd.log"); } public tlsCertPath() { - return path.join(this.lndDir, "tls.cert"); + return path.join(this.dataDir, "tls.cert"); } public adminMacaroonPath() { return path.join( - this.lndDir, + this.dataDir, "data", "chain", "bitcoin", @@ -219,7 +216,7 @@ bitcoin.node=bitcoind bitcoind.dir=${this.bitcoindDataDir} `; - const config = path.join(this.lndDir, "lnd.conf"); + const config = path.join(this.dataDir, "lnd.conf"); await writeFileAsync(config, output); } diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/lib/ledgers/parity_instance.ts index 104857420e..79d1081ed2 100644 --- a/api_tests/lib/ledgers/parity_instance.ts +++ b/api_tests/lib/ledgers/parity_instance.ts @@ -16,12 +16,12 @@ export class ParityInstance implements EthereumInstance { public static async new( projectRoot: string, - logDir: string, + logFile: string, logger: Logger ) { return new ParityInstance( projectRoot, - logDir, + logFile, logger, await getPort({ port: 8545 }), await getPort() @@ -30,7 +30,7 @@ export class ParityInstance implements EthereumInstance { constructor( private readonly projectRoot: string, - private readonly logDir: string, + private readonly logFile: string, private readonly logger: Logger, public readonly rpcPort: number, public readonly p2pPort: number @@ -62,8 +62,8 @@ export class ParityInstance implements EthereumInstance { cwd: this.projectRoot, stdio: [ "ignore", // stdin - await openAsync(this.logDir + "/parity.log", "w"), // stdout - await openAsync(this.logDir + "/parity.log", "w"), // stderr + await openAsync(this.logFile, "w"), // stdout + await openAsync(this.logFile, "w"), // stderr ], } ); @@ -77,7 +77,7 @@ export class ParityInstance implements EthereumInstance { ); }); - const logReader = new LogReader(this.logDir + "/parity.log"); + const logReader = new LogReader(this.logFile); await logReader.waitForLogMessage("Public node URL:"); this.logger.info("parity started with PID", this.process.pid); diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index c1357526c8..d86de0e29b 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -10,7 +10,7 @@ import { exec } from "child_process"; import { LightningWallet } from "./wallets/lightning"; import { BitcoinNodeConfig } from "./ledgers/bitcoin"; import { EthereumNodeConfig } from "./ledgers/ethereum"; -import { Log4js } from "log4js"; +import { Logger } from "log4js"; export interface HarnessGlobal extends Global.Global { ledgerConfigs: LedgerConfig; @@ -20,11 +20,13 @@ export interface HarnessGlobal extends Global.Global { }; testRoot: string; projectRoot: string; - logRoot: string; verbose: boolean; tokenContract: string; parityAccountMutex: Mutex; - log4js: Log4js; + + getDataDir: (program: string) => Promise; + getLogFile: (pathElements: string[]) => string; + getLogger: (category: string) => Logger; } export interface LedgerConfig { diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 7a959b4dbb..e832343673 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -8,6 +8,7 @@ import { import NodeEnvironment from "jest-environment-node"; import { Mutex } from "async-mutex"; import path from "path"; +import { configure } from "log4js"; // ************************ // // Setting global variables // @@ -17,7 +18,6 @@ export default class DryTestEnvironment extends NodeEnvironment { private docblockPragmas: Record; private projectRoot: string; private testRoot: string; - private logDir: string; public global: HarnessGlobal; constructor(config: Config.ProjectConfig, context: any) { @@ -50,12 +50,38 @@ export default class DryTestEnvironment extends NodeEnvironment { console.log(`Starting up test environment`); } - const { logDir } = this.extractDocblockPragmas(this.docblockPragmas); - - this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); - await DryTestEnvironment.cleanLogDir(this.logDir); - - this.global.logRoot = this.logDir; + const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); + const logDir = path.join( + this.projectRoot, + "api_tests", + "log", + suiteConfig.logDir + ); + + await DryTestEnvironment.cleanLogDir(logDir); + + const log4js = configure({ + appenders: { + multi: { + type: "multiFile", + base: logDir, + property: "categoryName", + extension: ".log", + }, + }, + categories: { + default: { appenders: ["multi"], level: "debug" }, + }, + }); + this.global.getLogFile = pathElements => + path.join(logDir, ...pathElements); + this.global.getDataDir = async program => { + const dir = path.join(logDir, program); + await mkdirAsync(dir, { recursive: true }); + + return dir; + }; + this.global.getLogger = category => log4js.getLogger(category); } private static async cleanLogDir(logDir: string) { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 124d9bd1df..07e986164a 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -28,7 +28,6 @@ export default class E2ETestEnvironment extends NodeEnvironment { private docblockPragmas: Record; private projectRoot: string; private testRoot: string; - private logDir: string; public global: HarnessGlobal; private bitcoinLedger?: BitcoinLedger; @@ -65,18 +64,21 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.global.parityAccountMutex = new Mutex(); - const { ledgers, logDir } = this.extractDocblockPragmas( - this.docblockPragmas - ); + const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); - this.logDir = path.join(this.projectRoot, "api_tests", "log", logDir); - await E2ETestEnvironment.cleanLogDir(this.logDir); + const logDir = path.join( + this.projectRoot, + "api_tests", + "log", + suiteConfig.logDir + ); + await E2ETestEnvironment.cleanLogDir(logDir); - this.global.log4js = configure({ + const log4js = configure({ appenders: { multi: { type: "multiFile", - base: this.logDir, + base: logDir, property: "categoryName", extension: ".log", }, @@ -85,13 +87,20 @@ export default class E2ETestEnvironment extends NodeEnvironment { default: { appenders: ["multi"], level: "debug" }, }, }); - this.logger = this.global.log4js.getLogger("test_environment"); + this.global.getLogFile = pathElements => + path.join(logDir, ...pathElements); + this.global.getDataDir = async program => { + const dir = path.join(logDir, program); + await mkdirAsync(dir, { recursive: true }); - this.logger.info("Starting up test environment"); + return dir; + }; + this.global.getLogger = category => log4js.getLogger(category); - await this.startLedgers(ledgers); + this.logger = log4js.getLogger("test_environment"); + this.logger.info("Starting up test environment"); - this.global.logRoot = this.logDir; + await this.startLedgers(suiteConfig.ledgers); } /** @@ -130,7 +139,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.bitcoinLedger = await BitcoinLedger.start( await BitcoindInstance.new( this.projectRoot, - this.logDir, + await this.global.getDataDir("bitcoind"), this.logger ), this.logger @@ -146,7 +155,7 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.ethereumLedger = await EthereumLedger.start( await ParityInstance.new( this.projectRoot, - this.logDir, + this.global.getLogFile(["parity.log"]), this.logger ), this.logger @@ -195,10 +204,10 @@ export default class E2ETestEnvironment extends NodeEnvironment { private async startAliceLightning() { this.aliceLightning = await LightningLedger.start( await LndInstance.new( - this.logDir, + await this.global.getDataDir("lnd-alice"), "lnd-alice", this.logger, - path.join(this.logDir, "bitcoind") + await this.global.getDataDir("bitcoind") ) ); @@ -222,10 +231,10 @@ export default class E2ETestEnvironment extends NodeEnvironment { private async startBobLightning() { this.bobLightning = await LightningLedger.start( await LndInstance.new( - this.logDir, + await this.global.getDataDir("lnd-bob"), "lnd-bob", this.logger, - path.join(this.logDir, "bitcoind") + await this.global.getDataDir("bitcoind") ) ); From fdd3b26c0844894a2df0b90bb4048df13a120021 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 19:26:45 +1100 Subject: [PATCH 068/145] Remove testRoot variable No component is actually using this, we can delete it. --- api_tests/lib/utils.ts | 1 - api_tests/src/dry_test_environment.ts | 3 --- api_tests/src/e2e_test_environment.ts | 3 --- 3 files changed, 7 deletions(-) diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index d86de0e29b..b31de51f90 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -18,7 +18,6 @@ export interface HarnessGlobal extends Global.Global { alice?: LightningWallet; bob?: LightningWallet; }; - testRoot: string; projectRoot: string; verbose: boolean; tokenContract: string; diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index e832343673..9fb2a41091 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -17,7 +17,6 @@ import { configure } from "log4js"; export default class DryTestEnvironment extends NodeEnvironment { private docblockPragmas: Record; private projectRoot: string; - private testRoot: string; public global: HarnessGlobal; constructor(config: Config.ProjectConfig, context: any) { @@ -34,11 +33,9 @@ export default class DryTestEnvironment extends NodeEnvironment { encoding: "utf8", }); this.projectRoot = stdout.trim(); - this.testRoot = path.join(this.projectRoot, "api_tests"); // setup global variables this.global.projectRoot = this.projectRoot; - this.global.testRoot = this.testRoot; this.global.ledgerConfigs = {}; this.global.verbose = this.global.process.argv.find(item => item.includes("verbose")) !== diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 07e986164a..be01245386 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -27,7 +27,6 @@ import { configure, Logger } from "log4js"; export default class E2ETestEnvironment extends NodeEnvironment { private docblockPragmas: Record; private projectRoot: string; - private testRoot: string; public global: HarnessGlobal; private bitcoinLedger?: BitcoinLedger; @@ -51,11 +50,9 @@ export default class E2ETestEnvironment extends NodeEnvironment { encoding: "utf8", }); this.projectRoot = stdout.trim(); - this.testRoot = path.join(this.projectRoot, "api_tests"); // setup global variables this.global.projectRoot = this.projectRoot; - this.global.testRoot = this.testRoot; this.global.ledgerConfigs = {}; this.global.lndWallets = {}; this.global.verbose = From 86555fbfdc255325535d96ec03f41c9699c6c871 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 19:28:57 +1100 Subject: [PATCH 069/145] Remove verbose flag from global context Nothing is using this flag anymore, we can just remove it. --- api_tests/lib/utils.ts | 1 - api_tests/src/dry_test_environment.ts | 12 ++++-------- api_tests/src/e2e_test_environment.ts | 4 ---- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/api_tests/lib/utils.ts b/api_tests/lib/utils.ts index b31de51f90..24c9ea9224 100644 --- a/api_tests/lib/utils.ts +++ b/api_tests/lib/utils.ts @@ -19,7 +19,6 @@ export interface HarnessGlobal extends Global.Global { bob?: LightningWallet; }; projectRoot: string; - verbose: boolean; tokenContract: string; parityAccountMutex: Mutex; diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 9fb2a41091..baa50c5115 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -37,16 +37,8 @@ export default class DryTestEnvironment extends NodeEnvironment { // setup global variables this.global.projectRoot = this.projectRoot; this.global.ledgerConfigs = {}; - this.global.verbose = - this.global.process.argv.find(item => item.includes("verbose")) !== - undefined; - this.global.parityAccountMutex = new Mutex(); - if (this.global.verbose) { - console.log(`Starting up test environment`); - } - const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); const logDir = path.join( this.projectRoot, @@ -70,6 +62,10 @@ export default class DryTestEnvironment extends NodeEnvironment { default: { appenders: ["multi"], level: "debug" }, }, }); + + const logger = log4js.getLogger("test_environment"); + logger.info("Starting up test environment"); + this.global.getLogFile = pathElements => path.join(logDir, ...pathElements); this.global.getDataDir = async program => { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index be01245386..3371ffdf06 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -55,10 +55,6 @@ export default class E2ETestEnvironment extends NodeEnvironment { this.global.projectRoot = this.projectRoot; this.global.ledgerConfigs = {}; this.global.lndWallets = {}; - this.global.verbose = - this.global.process.argv.find(item => item.includes("verbose")) !== - undefined; - this.global.parityAccountMutex = new Mutex(); const suiteConfig = this.extractDocblockPragmas(this.docblockPragmas); From 8fb79ecc8fa67503729f02af54f4fa979886a403 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 13 Mar 2020 19:31:01 +1100 Subject: [PATCH 070/145] Remove unnecessary global declaration --- api_tests/lib/cnd/cnd_instance.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api_tests/lib/cnd/cnd_instance.ts b/api_tests/lib/cnd/cnd_instance.ts index fac2bccee0..00a6927c56 100644 --- a/api_tests/lib/cnd/cnd_instance.ts +++ b/api_tests/lib/cnd/cnd_instance.ts @@ -4,12 +4,10 @@ import * as fs from "fs"; import tempWrite from "temp-write"; import { promisify } from "util"; import { CndConfigFile } from "../config"; -import { HarnessGlobal, sleep } from "../utils"; +import { sleep } from "../utils"; import { LogReader } from "../ledgers/log_reader"; import { Logger } from "log4js"; -declare var global: HarnessGlobal; - const openAsync = promisify(fs.open); export class CndInstance { From a74a25034bd2ace36231160c9870909996f2280a Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 11 Mar 2020 12:05:15 +1100 Subject: [PATCH 071/145] Add oneshot libp2p secret hash protocol --- cnd/src/network/behaviour.rs | 101 +++++++++++++++++++++ cnd/src/network/mod.rs | 7 +- cnd/src/network/protocol.rs | 167 +++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 cnd/src/network/behaviour.rs create mode 100644 cnd/src/network/protocol.rs diff --git a/cnd/src/network/behaviour.rs b/cnd/src/network/behaviour.rs new file mode 100644 index 0000000000..66686b2e23 --- /dev/null +++ b/cnd/src/network/behaviour.rs @@ -0,0 +1,101 @@ +use crate::network::protocol::{InboundProtocolConfig, Message, OutboundProtocolConfig}; +use libp2p::{ + core::{ConnectedPoint, Multiaddr, PeerId}, + swarm::{ + NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, ProtocolsHandler, + }, +}; +use std::{ + collections::VecDeque, + task::{Context, Poll}, +}; +use tracing::trace; + +/// Network behaviour that handles the secret hash protocol. +#[derive(Debug)] +pub struct Behaviour { + /// Events that need to be yielded to the outside when polling. + events: VecDeque>, +} + +impl Default for Behaviour { + fn default() -> Self { + Behaviour { + events: VecDeque::new(), + } + } +} + +/// Event generated by the NetworkBehaviour and that the swarm will report back. +#[derive(Clone, Copy, Debug)] +pub enum OutEvent { + Received(Message), // OutEvent containing secret hash message. + Sent, // Empty/nil OutEvent i.e., `()`. +} + +/// OutEvent when a peer sends us a message. +impl From for OutEvent { + fn from(msg: Message) -> OutEvent { + OutEvent::Received(msg) + } +} + +/// OutEvent that occurs when we send a message. +impl From<()> for OutEvent { + fn from(_: ()) -> Self { + OutEvent::Sent + } +} + +impl NetworkBehaviour for Behaviour { + type ProtocolsHandler = OneShotHandler; + type OutEvent = OutEvent; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + Default::default() + } + + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { + Vec::new() // Announce protocol takes care of this. + } + + fn inject_connected(&mut self, _: PeerId, _: ConnectedPoint) { + // Do nothing, announce protocol is going to take care of connections. + } + + fn inject_disconnected(&mut self, _: &PeerId, _: ConnectedPoint) { + // Do nothing, announce protocol is going to take care of connections. + } + + fn inject_node_event(&mut self, peer_id: PeerId, event: OutEvent) { + match event { + OutEvent::Received(message) => { + trace!("Received message event from {}: {:?}", peer_id, message); + + // Add the message to be dispatched to the user. + self.events + .push_back(NetworkBehaviourAction::GenerateEvent(OutEvent::Received( + message, + ))); + } + OutEvent::Sent => trace!("Received 'sent' event from {}", peer_id), + } + } + + fn poll( + &mut self, + _: &mut Context<'_>, + _: &mut impl PollParameters, + ) -> Poll< + NetworkBehaviourAction< + ::InEvent, + Self::OutEvent, + >, + > { + if let Some(event) = self.events.pop_front() { + return Poll::Ready(event); + } + + Poll::Pending + } +} diff --git a/cnd/src/network/mod.rs b/cnd/src/network/mod.rs index 62a818c80d..a944f69a1c 100644 --- a/cnd/src/network/mod.rs +++ b/cnd/src/network/mod.rs @@ -1,3 +1,5 @@ +pub mod behaviour; +mod protocol; pub mod transport; pub use transport::ComitTransport; @@ -42,7 +44,7 @@ use libp2p::{ }; use libp2p_comit::{ frame::{OutboundRequest, Response, ValidatedInboundRequest}, - handler::{self, ComitHandler, ProtocolInEvent, ProtocolOutEvent}, + handler::{ComitHandler, ProtocolInEvent, ProtocolOutEvent}, BehaviourOutEvent, Comit, PendingInboundRequest, }; use serde::{de::DeserializeOwned, Serialize}; @@ -65,7 +67,7 @@ type ExpandedSwarm = libp2p::swarm::ExpandedSwarm< EitherOutput, EitherOutput, IntoProtocolsHandlerSelect, - EitherError, + EitherError, >; #[derive(Clone, derivative::Derivative)] @@ -152,6 +154,7 @@ fn derive_key_pair(seed: &RootSeed) -> Keypair { Keypair::Ed25519(key.into()) } +/// A `NetworkBehaviour` that delegates to the `Comit` and `Mdns` behaviours. #[derive(NetworkBehaviour)] #[allow(missing_debug_implementations)] pub struct ComitNode { diff --git a/cnd/src/network/protocol.rs b/cnd/src/network/protocol.rs new file mode 100644 index 0000000000..d47c53b329 --- /dev/null +++ b/cnd/src/network/protocol.rs @@ -0,0 +1,167 @@ +use crate::swap_protocols::{rfc003::SecretHash, SwapId}; +use futures::{future::BoxFuture, AsyncRead, AsyncWrite}; +use libp2p::core::{upgrade, InboundUpgrade, OutboundUpgrade, UpgradeInfo}; +use serde::{Deserialize, Serialize}; +use std::{io, iter}; +use tracing::trace; + +const INFO: &str = "/comit/swap/secret_hash/1.0.0"; + +/// The secret hash sharing protocol works in the following way: +/// +/// - Dialer (Alice) writes the `Message` to the substream. +/// - Listener (Bob) reads the `Message` from the substream. + +/// Data sent to peer in secret hash protocol. +#[derive(Clone, Copy, Deserialize, Debug, Serialize, PartialEq)] +pub struct Message { + swap_id: SwapId, + secret_hash: SecretHash, +} + +/// Represents a prototype for an upgrade to handle the sender side of the +/// secret hash sharing protocol. Config contains the `Message`, once the +/// outbound upgrade is complete peer node has been sent the message. +#[derive(Clone, Copy, Debug)] +pub struct OutboundProtocolConfig { + msg: Message, +} + +impl UpgradeInfo for OutboundProtocolConfig { + type Info = &'static [u8]; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(INFO.as_bytes()) + } +} + +impl OutboundUpgrade for OutboundProtocolConfig +where + C: AsyncWrite + Unpin + Send + 'static, +{ + type Output = (); + type Error = Error; + type Future = BoxFuture<'static, Result>; + + fn upgrade_outbound(self, mut socket: C, info: Self::Info) -> Self::Future { + trace!( + "Upgrading outbound connection: {}", + String::from_utf8_lossy(info) + ); + Box::pin(async move { + let bytes = serde_json::to_vec(&self.msg)?; + upgrade::write_one(&mut socket, &bytes).await?; + + Ok(()) + }) + } +} + +/// Represents a prototype for an upgrade to handle the receiver side of the +/// secret hash sharing protocol. +#[derive(Clone, Copy, Debug)] +pub struct InboundProtocolConfig; + +impl Default for InboundProtocolConfig { + fn default() -> Self { + Self {} + } +} + +impl UpgradeInfo for InboundProtocolConfig { + type Info = &'static [u8]; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(INFO.as_bytes()) + } +} + +impl InboundUpgrade for InboundProtocolConfig +where + C: AsyncRead + Unpin + Send + 'static, +{ + type Output = Message; + type Error = Error; + type Future = BoxFuture<'static, Result>; + + fn upgrade_inbound(self, mut socket: C, info: Self::Info) -> Self::Future { + trace!( + "Upgrading inbound connection: {}", + String::from_utf8_lossy(info) + ); + Box::pin(async move { + let message = upgrade::read_one(&mut socket, 1024).await?; + let mut de = serde_json::Deserializer::from_slice(&message); + let info = Message::deserialize(&mut de)?; + + Ok(info) + }) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("read from socket: ")] + Read(#[from] upgrade::ReadOneError), + #[error("write to socket: ")] + Write(#[from] io::Error), + #[error("serde: ")] + Serde(#[from] serde_json::Error), +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::prelude::*; + use libp2p::core::{ + multiaddr::multiaddr, + transport::{memory::MemoryTransport, ListenerEvent, Transport}, + upgrade, + }; + use rand::{thread_rng, Rng}; + use std::str::FromStr; + + #[tokio::test] + async fn correct_transfer() { + let send_msg = Message { + swap_id: SwapId::from_str("ad2652ca-ecf2-4cc6-b35c-b4351ac28a34").unwrap(), + secret_hash: SecretHash::from_str( + "bfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbf\ + bfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbf", + ) + .unwrap(), + }; + + let mem_addr = multiaddr![Memory(thread_rng().gen::())]; + let mut listener = MemoryTransport.listen_on(mem_addr).unwrap(); + + let listener_addr = + if let Some(Some(Ok(ListenerEvent::NewAddress(a)))) = listener.next().now_or_never() { + a + } else { + panic!("MemoryTransport not listening on an address!"); + }; + + tokio::task::spawn({ + async move { + let listener_event = listener.next().await.unwrap(); + let (listener_upgrade, _) = listener_event.unwrap().into_upgrade().unwrap(); + let conn = listener_upgrade.await.unwrap(); + + let config = OutboundProtocolConfig { msg: send_msg }; + upgrade::apply_outbound(conn, config, upgrade::Version::V1) + .await + .unwrap(); + } + }); + + let conn = MemoryTransport.dial(listener_addr).unwrap().await.unwrap(); + + let config = InboundProtocolConfig {}; + let received_msg = upgrade::apply_inbound(conn, config).await.unwrap(); + + assert_eq!(received_msg, send_msg) + } +} From 77e028246c03e0185fd04f2115b83aa7ac10f66a Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 16 Mar 2020 12:59:03 +1100 Subject: [PATCH 072/145] Ensure that bitcoind binds to the custom ports --- api_tests/lib/ledgers/bitcoind_instance.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index 1f10eb9720..0f0b6e6443 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -118,14 +118,16 @@ export class BitcoindInstance implements BitcoinInstance { const output = `regtest=1 server=1 printtoconsole=1 -bind=0.0.0.0:${this.p2pPort} -rpcbind=0.0.0.0:${this.rpcPort} rpcallowip=0.0.0.0/0 nodebug=1 rest=1 acceptnonstdtxn=0 zmqpubrawblock=tcp://127.0.0.1:${this.zmqPubRawBlockPort} zmqpubrawtx=tcp://127.0.0.1:${this.zmqPubRawTxPort} + +[regtest] +bind=0.0.0.0:${this.p2pPort} +rpcbind=0.0.0.0:${this.rpcPort} `; const config = path.join(dataDir, "bitcoin.conf"); await writeFileAsync(config, output); From a5d679c633a694405d05e1ac406690970437c0e7 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 13 Mar 2020 14:34:49 +1100 Subject: [PATCH 073/145] Do not keep track of Cargo.toml files to avoid missing new ones --- Makefile | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index 6e7ba1db5d..24be904c37 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ INSTALLED_COMPONENTS = $(shell $(RUSTUP) component list --installed --toolchain INSTALLED_NIGHTLY_COMPONENTS = $(shell $(RUSTUP) component list --installed --toolchain $(NIGHTLY_TOOLCHAIN)) AVAILABLE_CARGO_COMMANDS = $(shell $(CARGO) --list) +CARGO_TOML_FILES = $(shell ls **/Cargo.toml) + # All our targets go into .PHONY because none of them actually create files .PHONY: init_git_hooks default install_rust install_rust_nightly install_clippy install_rustfmt install_tomlfmt install clean all ci build clippy test doc e2e check_format format check_rust_format check_toml_format check_ts_format @@ -90,11 +92,7 @@ MODIFIED_TYPESCRIPT_FILES = $(filter %.ts %.json %.yml,$(MODIFIED_FILES)) format: install_rustfmt install_tomlfmt $(CARGO_NIGHTLY) fmt -- --files-with-diff | xargs -I{} git add {} - RUST_LOG=error $(CARGO) tomlfmt -p Cargo.toml && git add Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -p cnd/Cargo.toml && git add cnd/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -p libp2p-comit/Cargo.toml && git add libp2p-comit/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -p digest/Cargo.toml && git add digest/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -p digest-macro-derive/Cargo.toml && git add digest-macro-derive/Cargo.toml + @$(foreach file,$(CARGO_TOML_FILES),$(CARGO) tomlfmt -p $(file) && git add $(file);) ifneq (,$(MODIFIED_TYPESCRIPT_FILES)) (cd ./api_tests; yarn install; yarn run fix) endif @@ -106,11 +104,7 @@ check_rust_format: install_rustfmt $(CARGO_NIGHTLY) fmt -- --check check_toml_format: install_tomlfmt - RUST_LOG=error $(CARGO) tomlfmt -d -p Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -d -p cnd/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -d -p libp2p-comit/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -d -p digest/Cargo.toml - RUST_LOG=error $(CARGO) tomlfmt -d -p digest-macro-derive/Cargo.toml + @$(foreach file,$(CARGO_TOML_FILES),$(CARGO) tomlfmt -d -p $(file);) check_ts_format: ifeq ($(CI),true) From 38a52ba673a560791b26807f74e7319021a5cfbc Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 16 Mar 2020 13:57:28 +1100 Subject: [PATCH 074/145] Transform if let to match --- digest-macro-derive/src/lib.rs | 110 +++++++++++++++++---------------- digest/tests/swap_digest.rs | 32 ++++++++++ 2 files changed, 89 insertions(+), 53 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 3ef9bb90d9..5940267bfe 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -13,62 +13,66 @@ pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; - if let Data::Struct(data) = &ast.data { - let (idents, types, bytes) = match &data.fields { - Fields::Named(fields) => { - let idents = fields - .named - .iter() - .map(|field| field.ident.as_ref().expect("Named field")); - - let types = fields.named.iter().map(|field| &field.ty); - - let bytes = fields.named.iter().map(|field| { - let attr = field - .attrs - .get(0) - .expect("digest_bytes attribute must be present on all fields"); - let meta = attr.parse_meta().expect("Attribute is malformed"); - - if let Meta::NameValue(name_value) = meta { - if name_value.path.is_ident("digest_bytes") { - if let Lit::Str(lit_str) = name_value.lit { - let str = lit_str.value(); - let bytes = ::hex::decode(&str) - .expect("digest_bytes value should be in hex format"); - return Bytes(bytes); + + match &ast.data { + Data::Struct(data) => { + let (idents, types, bytes) = match &data.fields { + Fields::Named(fields) => { + let idents = fields + .named + .iter() + .map(|field| field.ident.as_ref().expect("Named field")); + + let types = fields.named.iter().map(|field| &field.ty); + + let bytes = fields.named.iter().map(|field| { + let attr = field + .attrs + .get(0) + .expect("digest_bytes attribute must be present on all fields"); + let meta = attr.parse_meta().expect("Attribute is malformed"); + + if let Meta::NameValue(name_value) = meta { + if name_value.path.is_ident("digest_bytes") { + if let Lit::Str(lit_str) = name_value.lit { + let str = lit_str.value(); + let bytes = ::hex::decode(&str) + .expect("digest_bytes value should be in hex format"); + return Bytes(bytes); + } } } - } - panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); - }); - (idents, types, bytes) - } - _ => panic!("Only supporting named fields."), - }; - - let gen = quote! { - impl ::digest::RootDigest for #name - where #(#types: ::digest::FieldDigest),* - { - fn root_digest(self) -> Multihash { - let mut digests = vec![]; - #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* - - digests.sort(); - - let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); - res - }); - - digest(&res) - } + panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); + }); + (idents, types, bytes) } - }; - gen.into() - } else { - panic!("DigestRootMacro only supports structs."); + _ => panic!("Only supporting named fields."), + }; + + let gen = quote! { + impl ::digest::RootDigest for #name + where #(#types: ::digest::FieldDigest),* + { + fn root_digest(self) -> Multihash { + let mut digests = vec![]; + #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* + + digests.sort(); + + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); + + digest(&res) + } + } + }; + gen.into() + } + _ => { + panic!("DigestRootMacro only supports structs."); + } } } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 980ef1e1e3..b612e007ec 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -52,6 +52,30 @@ impl RootDigest for OtherStruct { } } +#[derive(RootDigestMacro)] +enum Enum { + #[digest_bytes = "0011"] + Foo, + #[digest_bytes = "0E0F"] + Bar, +} + +enum OtherEnum { + Foo, + Bar, +} + +impl RootDigest for OtherEnum { + fn root_digest(self) -> Multihash { + let bytes = match self { + OtherEnum::Foo => digest(vec![0x00u8, 0x11u8]), + OtherEnum::Bar => digest(vec![0x0Eu8, 0x0Fu8]), + }; + + digest(&bytes) + } +} + #[test] fn given_same_strings_return_same_multihash() { let str1 = String::from("simple string"); @@ -164,3 +188,11 @@ fn given_two_double_field_struct_with_same_data_return_same_multihash() { assert_eq!(struct1.root_digest(), struct2.root_digest()) } + +#[test] +fn given_two_enums_with_same_bytes_per_variant_return_same_multihash() { + let enum1 = Enum::Foo; + let enum2 = OtherEnum::Foo; + + assert_eq!(enum1.root_digest(), enum2.root_digest()) +} From d963697b34f4e19e45ecbae982ec8eb76cd0d28f Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 14:15:43 +1100 Subject: [PATCH 075/145] Make log statement about bitcoind exiting unambigous We have one global logger for the whole test environment, hence we need to be explicit, which binary exited. --- api_tests/lib/ledgers/bitcoind_instance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/lib/ledgers/bitcoind_instance.ts index 1f10eb9720..41e763d69e 100644 --- a/api_tests/lib/ledgers/bitcoind_instance.ts +++ b/api_tests/lib/ledgers/bitcoind_instance.ts @@ -65,7 +65,7 @@ export class BitcoindInstance implements BitcoinInstance { this.process.on("exit", (code: number, signal: number) => { this.logger.info( - "binary exited with code", + "bitcoind exited with code", code, "after signal", signal From bc2d57a9ca8d5a88e40ce9485e706a41869a73d1 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 15:02:52 +1100 Subject: [PATCH 076/145] Make it easy to create OneShot protocols without any duplication --- cnd/src/network/mod.rs | 5 +- .../{behaviour.rs => oneshot_behaviour.rs} | 46 +++++--- .../{protocol.rs => oneshot_protocol.rs} | 105 ++++++++++-------- cnd/src/network/secret_hash.rs | 21 ++++ 4 files changed, 109 insertions(+), 68 deletions(-) rename cnd/src/network/{behaviour.rs => oneshot_behaviour.rs} (68%) rename cnd/src/network/{protocol.rs => oneshot_protocol.rs} (63%) create mode 100644 cnd/src/network/secret_hash.rs diff --git a/cnd/src/network/mod.rs b/cnd/src/network/mod.rs index a944f69a1c..b12215069a 100644 --- a/cnd/src/network/mod.rs +++ b/cnd/src/network/mod.rs @@ -1,5 +1,6 @@ -pub mod behaviour; -mod protocol; +pub mod oneshot_behaviour; +mod oneshot_protocol; +mod secret_hash; pub mod transport; pub use transport::ComitTransport; diff --git a/cnd/src/network/behaviour.rs b/cnd/src/network/oneshot_behaviour.rs similarity index 68% rename from cnd/src/network/behaviour.rs rename to cnd/src/network/oneshot_behaviour.rs index 66686b2e23..ee9d58d692 100644 --- a/cnd/src/network/behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -1,24 +1,26 @@ -use crate::network::protocol::{InboundProtocolConfig, Message, OutboundProtocolConfig}; +use crate::network::oneshot_protocol; use libp2p::{ core::{ConnectedPoint, Multiaddr, PeerId}, swarm::{ NetworkBehaviour, NetworkBehaviourAction, OneShotHandler, PollParameters, ProtocolsHandler, }, }; +use serde::{de::DeserializeOwned, Serialize}; use std::{ collections::VecDeque, + fmt::Debug, task::{Context, Poll}, }; use tracing::trace; -/// Network behaviour that handles the secret hash protocol. +/// Generic network behaviour for handling oneshot protocols. #[derive(Debug)] -pub struct Behaviour { +pub struct Behaviour { /// Events that need to be yielded to the outside when polling. - events: VecDeque>, + events: VecDeque, OutEvent>>, } -impl Default for Behaviour { +impl Default for Behaviour { fn default() -> Self { Behaviour { events: VecDeque::new(), @@ -28,28 +30,38 @@ impl Default for Behaviour { /// Event generated by the NetworkBehaviour and that the swarm will report back. #[derive(Clone, Copy, Debug)] -pub enum OutEvent { - Received(Message), // OutEvent containing secret hash message. - Sent, // Empty/nil OutEvent i.e., `()`. +pub enum OutEvent { + /// Emitted once we receive a message from the other peer. + Received(M), + /// Emitted once we successfully sent a message to the other peer. + Sent, } -/// OutEvent when a peer sends us a message. -impl From for OutEvent { - fn from(msg: Message) -> OutEvent { +impl From for OutEvent +where + M: oneshot_protocol::Message, +{ + fn from(msg: M) -> Self { OutEvent::Received(msg) } } -/// OutEvent that occurs when we send a message. -impl From<()> for OutEvent { +impl From<()> for OutEvent { fn from(_: ()) -> Self { OutEvent::Sent } } -impl NetworkBehaviour for Behaviour { - type ProtocolsHandler = OneShotHandler; - type OutEvent = OutEvent; +impl NetworkBehaviour for Behaviour +where + M: oneshot_protocol::Message + Serialize + DeserializeOwned + Clone + Debug + Send + 'static, +{ + type ProtocolsHandler = OneShotHandler< + oneshot_protocol::InboundConfig, + oneshot_protocol::OutboundConfig, + OutEvent, + >; + type OutEvent = OutEvent; fn new_handler(&mut self) -> Self::ProtocolsHandler { Default::default() @@ -67,7 +79,7 @@ impl NetworkBehaviour for Behaviour { // Do nothing, announce protocol is going to take care of connections. } - fn inject_node_event(&mut self, peer_id: PeerId, event: OutEvent) { + fn inject_node_event(&mut self, peer_id: PeerId, event: OutEvent) { match event { OutEvent::Received(message) => { trace!("Received message event from {}: {:?}", peer_id, message); diff --git a/cnd/src/network/protocol.rs b/cnd/src/network/oneshot_protocol.rs similarity index 63% rename from cnd/src/network/protocol.rs rename to cnd/src/network/oneshot_protocol.rs index d47c53b329..735a508c09 100644 --- a/cnd/src/network/protocol.rs +++ b/cnd/src/network/oneshot_protocol.rs @@ -1,52 +1,47 @@ -use crate::swap_protocols::{rfc003::SecretHash, SwapId}; use futures::{future::BoxFuture, AsyncRead, AsyncWrite}; use libp2p::core::{upgrade, InboundUpgrade, OutboundUpgrade, UpgradeInfo}; -use serde::{Deserialize, Serialize}; -use std::{io, iter}; -use tracing::trace; +use serde::{de::DeserializeOwned, Serialize}; +use std::{io, iter, marker::PhantomData}; -const INFO: &str = "/comit/swap/secret_hash/1.0.0"; - -/// The secret hash sharing protocol works in the following way: -/// -/// - Dialer (Alice) writes the `Message` to the substream. -/// - Listener (Bob) reads the `Message` from the substream. - -/// Data sent to peer in secret hash protocol. -#[derive(Clone, Copy, Deserialize, Debug, Serialize, PartialEq)] -pub struct Message { - swap_id: SwapId, - secret_hash: SecretHash, +/// A trait for defining the message in a oneshot protocol. +pub trait Message { + /// The identifier of the oneshot protocol. + const INFO: &'static str; } -/// Represents a prototype for an upgrade to handle the sender side of the -/// secret hash sharing protocol. Config contains the `Message`, once the -/// outbound upgrade is complete peer node has been sent the message. +/// Represents a prototype for an upgrade to handle the sender side of a oneshot +/// protocol. +/// +/// This struct contains the message that should be sent to the other peer. #[derive(Clone, Copy, Debug)] -pub struct OutboundProtocolConfig { - msg: Message, +pub struct OutboundConfig { + msg: M, } -impl UpgradeInfo for OutboundProtocolConfig { +impl UpgradeInfo for OutboundConfig +where + M: Message, +{ type Info = &'static [u8]; type InfoIter = iter::Once; fn protocol_info(&self) -> Self::InfoIter { - iter::once(INFO.as_bytes()) + iter::once(M::INFO.as_bytes()) } } -impl OutboundUpgrade for OutboundProtocolConfig +impl OutboundUpgrade for OutboundConfig where C: AsyncWrite + Unpin + Send + 'static, + M: Serialize + Message + Send + 'static, { type Output = (); type Error = Error; type Future = BoxFuture<'static, Result>; fn upgrade_outbound(self, mut socket: C, info: Self::Info) -> Self::Future { - trace!( - "Upgrading outbound connection: {}", + tracing::trace!( + "Upgrading outbound connection for {}", String::from_utf8_lossy(info) ); Box::pin(async move { @@ -59,42 +54,52 @@ where } /// Represents a prototype for an upgrade to handle the receiver side of the -/// secret hash sharing protocol. +/// oneshot protocol. +/// +/// The type parameter M is the message you are expecting to receive. #[derive(Clone, Copy, Debug)] -pub struct InboundProtocolConfig; +pub struct InboundConfig { + msg_type: PhantomData, +} -impl Default for InboundProtocolConfig { +impl Default for InboundConfig { fn default() -> Self { - Self {} + Self { + msg_type: PhantomData, + } } } -impl UpgradeInfo for InboundProtocolConfig { +impl UpgradeInfo for InboundConfig +where + M: Message, +{ type Info = &'static [u8]; type InfoIter = iter::Once; fn protocol_info(&self) -> Self::InfoIter { - iter::once(INFO.as_bytes()) + iter::once(M::INFO.as_bytes()) } } -impl InboundUpgrade for InboundProtocolConfig +impl InboundUpgrade for InboundConfig where C: AsyncRead + Unpin + Send + 'static, + M: DeserializeOwned + Message, { - type Output = Message; + type Output = M; type Error = Error; type Future = BoxFuture<'static, Result>; fn upgrade_inbound(self, mut socket: C, info: Self::Info) -> Self::Future { - trace!( - "Upgrading inbound connection: {}", + tracing::trace!( + "Upgrading inbound connection for {}", String::from_utf8_lossy(info) ); Box::pin(async move { let message = upgrade::read_one(&mut socket, 1024).await?; let mut de = serde_json::Deserializer::from_slice(&message); - let info = Message::deserialize(&mut de)?; + let info = M::deserialize(&mut de)?; Ok(info) }) @@ -121,18 +126,20 @@ mod tests { upgrade, }; use rand::{thread_rng, Rng}; - use std::str::FromStr; + use serde::Deserialize; + + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Copy)] + struct DummyMessage { + content: u32, + } + + impl Message for DummyMessage { + const INFO: &'static str = "/foo/bar/test/1.0.0"; + } #[tokio::test] async fn correct_transfer() { - let send_msg = Message { - swap_id: SwapId::from_str("ad2652ca-ecf2-4cc6-b35c-b4351ac28a34").unwrap(), - secret_hash: SecretHash::from_str( - "bfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbf\ - bfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbf", - ) - .unwrap(), - }; + let sent_msg = DummyMessage { content: 42 }; let mem_addr = multiaddr![Memory(thread_rng().gen::())]; let mut listener = MemoryTransport.listen_on(mem_addr).unwrap(); @@ -150,7 +157,7 @@ mod tests { let (listener_upgrade, _) = listener_event.unwrap().into_upgrade().unwrap(); let conn = listener_upgrade.await.unwrap(); - let config = OutboundProtocolConfig { msg: send_msg }; + let config = OutboundConfig { msg: sent_msg }; upgrade::apply_outbound(conn, config, upgrade::Version::V1) .await .unwrap(); @@ -159,9 +166,9 @@ mod tests { let conn = MemoryTransport.dial(listener_addr).unwrap().await.unwrap(); - let config = InboundProtocolConfig {}; + let config = InboundConfig::::default(); let received_msg = upgrade::apply_inbound(conn, config).await.unwrap(); - assert_eq!(received_msg, send_msg) + assert_eq!(received_msg, sent_msg) } } diff --git a/cnd/src/network/secret_hash.rs b/cnd/src/network/secret_hash.rs new file mode 100644 index 0000000000..75ffed3b21 --- /dev/null +++ b/cnd/src/network/secret_hash.rs @@ -0,0 +1,21 @@ +use crate::{ + network::oneshot_protocol, + swap_protocols::{rfc003::SecretHash, SwapId}, +}; +use serde::{Deserialize, Serialize}; + +/// The secret hash sharing protocol works in the following way: +/// +/// - Dialer (Alice) writes the `Message` to the substream. +/// - Listener (Bob) reads the `Message` from the substream. + +/// Data sent to peer in secret hash protocol. +#[derive(Clone, Copy, Deserialize, Debug, Serialize, PartialEq)] +pub struct Message { + swap_id: SwapId, + secret_hash: SecretHash, +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/secret_hash/1.0.0"; +} From da5328b757dbc6685a166b128ed8d54dce56d2aa Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 15:22:45 +1100 Subject: [PATCH 077/145] Improve log messages to include protocol --- cnd/src/network/oneshot_behaviour.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cnd/src/network/oneshot_behaviour.rs b/cnd/src/network/oneshot_behaviour.rs index ee9d58d692..942828f55a 100644 --- a/cnd/src/network/oneshot_behaviour.rs +++ b/cnd/src/network/oneshot_behaviour.rs @@ -82,7 +82,12 @@ where fn inject_node_event(&mut self, peer_id: PeerId, event: OutEvent) { match event { OutEvent::Received(message) => { - trace!("Received message event from {}: {:?}", peer_id, message); + trace!( + "Received message from {} on protocol {}: {:?}", + peer_id, + M::INFO, + message + ); // Add the message to be dispatched to the user. self.events @@ -90,7 +95,7 @@ where message, ))); } - OutEvent::Sent => trace!("Received 'sent' event from {}", peer_id), + OutEvent::Sent => trace!("Sent message to {} on protocol {}", peer_id, M::INFO), } } From 840ae16c4fe20039464802d53dc8e7d4df85a76e Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 15:23:00 +1100 Subject: [PATCH 078/145] Improve error messages during upgrades --- cnd/src/network/oneshot_protocol.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cnd/src/network/oneshot_protocol.rs b/cnd/src/network/oneshot_protocol.rs index 735a508c09..834f4f38cf 100644 --- a/cnd/src/network/oneshot_protocol.rs +++ b/cnd/src/network/oneshot_protocol.rs @@ -108,11 +108,11 @@ where #[derive(Debug, thiserror::Error)] pub enum Error { - #[error("read from socket: ")] + #[error("failed to read a message from the socket")] Read(#[from] upgrade::ReadOneError), - #[error("write to socket: ")] + #[error("failed to write the message to the socket")] Write(#[from] io::Error), - #[error("serde: ")] + #[error("failed to serialize/deserialize the message")] Serde(#[from] serde_json::Error), } From a13eaa5964e536d49bc7c8586e04dc6a8f2ad843 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 16 Mar 2020 16:24:17 +1100 Subject: [PATCH 079/145] Use GNU Make wildcard feature --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 24be904c37..ffc4cc8260 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ INSTALLED_COMPONENTS = $(shell $(RUSTUP) component list --installed --toolchain INSTALLED_NIGHTLY_COMPONENTS = $(shell $(RUSTUP) component list --installed --toolchain $(NIGHTLY_TOOLCHAIN)) AVAILABLE_CARGO_COMMANDS = $(shell $(CARGO) --list) -CARGO_TOML_FILES = $(shell ls **/Cargo.toml) +CARGO_TOML_FILES = $(wildcard **/Cargo.toml) # All our targets go into .PHONY because none of them actually create files .PHONY: init_git_hooks default install_rust install_rust_nightly install_clippy install_rustfmt install_tomlfmt install clean all ci build clippy test doc e2e check_format format check_rust_format check_toml_format check_ts_format From 9493e0d458e5fe2b7dacf44f94eb04e547e72d53 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 16:39:27 +1100 Subject: [PATCH 080/145] Remove category from log message With the multiFile appender approach, every category is a different file. We don't need to print the category again the log files. --- api_tests/src/dry_test_environment.ts | 4 ++++ api_tests/src/e2e_test_environment.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index baa50c5115..68e99df070 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -56,6 +56,10 @@ export default class DryTestEnvironment extends NodeEnvironment { base: logDir, property: "categoryName", extension: ".log", + layout: { + type: "pattern", + pattern: "%d %5.10p: %m", + }, }, }, categories: { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index 3371ffdf06..ad2b8a9cc1 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -74,6 +74,10 @@ export default class E2ETestEnvironment extends NodeEnvironment { base: logDir, property: "categoryName", extension: ".log", + layout: { + type: "pattern", + pattern: "%d %5.10p: %m", + }, }, }, categories: { From 2db2992bf197a6ab6c8e99a3f4644fa4980201ca Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 16 Mar 2020 16:49:16 +1100 Subject: [PATCH 081/145] Add enum support --- digest-macro-derive/src/lib.rs | 60 +++++++++++++++++++++++++--------- digest/tests/swap_digest.rs | 4 +-- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 5940267bfe..6645545303 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -3,7 +3,7 @@ extern crate proc_macro; use crate::proc_macro::TokenStream; use proc_macro2::{Delimiter, Group, Punct, Spacing}; use quote::{quote, ToTokens, TokenStreamExt}; -use syn::{Data, Fields, Lit, Meta}; +use syn::{Attribute, Data, Fields, Lit, Meta}; #[proc_macro_derive(RootDigestMacro, attributes(digest_bytes))] pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { @@ -30,19 +30,8 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { .attrs .get(0) .expect("digest_bytes attribute must be present on all fields"); - let meta = attr.parse_meta().expect("Attribute is malformed"); - - if let Meta::NameValue(name_value) = meta { - if name_value.path.is_ident("digest_bytes") { - if let Lit::Str(lit_str) = name_value.lit { - let str = lit_str.value(); - let bytes = ::hex::decode(&str) - .expect("digest_bytes value should be in hex format"); - return Bytes(bytes); - } - } - } - panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); + + attr_to_bytes(attr) }); (idents, types, bytes) } @@ -70,8 +59,33 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { }; gen.into() } + Data::Enum(data) => { + let idents = data.variants.iter().map(|variant| &variant.ident); + + let bytes = data.variants.iter().map(|variant| { + let attr = variant + .attrs + .get(0) + .expect("digest_bytes attribute must be present on all fields"); + attr_to_bytes(attr) + }); + + let gen = quote! { + impl ::digest::RootDigest for #name + { + fn root_digest(self) -> Multihash { + let bytes = match self { + #(Self::#idents => #bytes.to_vec()),* + }; + + digest(&bytes) + } + } + }; + gen.into() + } _ => { - panic!("DigestRootMacro only supports structs."); + panic!("DigestRootMacro only supports structs & enums."); } } } @@ -87,6 +101,22 @@ impl ToTokens for Bytes { } } +fn attr_to_bytes(attr: &Attribute) -> Bytes { + let meta = attr.parse_meta().expect("Attribute is malformed"); + + if let Meta::NameValue(name_value) = meta { + if name_value.path.is_ident("digest_bytes") { + if let Lit::Str(lit_str) = name_value.lit { + let str = lit_str.value(); + let bytes = + ::hex::decode(&str).expect("digest_bytes value should be in hex format"); + return Bytes(bytes); + } + } + } + panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); +} + #[cfg(test)] mod tests { use super::*; diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index b612e007ec..74abd49297 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -68,8 +68,8 @@ enum OtherEnum { impl RootDigest for OtherEnum { fn root_digest(self) -> Multihash { let bytes = match self { - OtherEnum::Foo => digest(vec![0x00u8, 0x11u8]), - OtherEnum::Bar => digest(vec![0x0Eu8, 0x0Fu8]), + OtherEnum::Foo => vec![0x00u8, 0x11u8], + OtherEnum::Bar => vec![0x00u8, 0x11u8], }; digest(&bytes) From 36d0c362f4606d57ec32064196f9335a5aa678ef Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 16:50:33 +1100 Subject: [PATCH 082/145] Add the remaining oneshot protocols These protocols are all defined through the generic oneshot protocol abstraction. We define the messages of those protocols to contain byte arrays instead of the actual types in our codebase. This is to ensure we don't accidentially break the serialization. --- cnd/src/network/mod.rs | 7 +-- cnd/src/network/oneshot_protocol.rs | 7 +++ cnd/src/network/protocols/bitcoin_identity.rs | 46 ++++++++++++++++++ .../network/protocols/ethereum_identity.rs | 45 ++++++++++++++++++ cnd/src/network/protocols/finalize.rs | 37 +++++++++++++++ .../network/protocols/lightning_identity.rs | 43 +++++++++++++++++ cnd/src/network/protocols/mod.rs | 5 ++ cnd/src/network/protocols/secret_hash.rs | 47 +++++++++++++++++++ cnd/src/network/secret_hash.rs | 21 --------- 9 files changed, 234 insertions(+), 24 deletions(-) create mode 100644 cnd/src/network/protocols/bitcoin_identity.rs create mode 100644 cnd/src/network/protocols/ethereum_identity.rs create mode 100644 cnd/src/network/protocols/finalize.rs create mode 100644 cnd/src/network/protocols/lightning_identity.rs create mode 100644 cnd/src/network/protocols/mod.rs create mode 100644 cnd/src/network/protocols/secret_hash.rs delete mode 100644 cnd/src/network/secret_hash.rs diff --git a/cnd/src/network/mod.rs b/cnd/src/network/mod.rs index b12215069a..a46c66f194 100644 --- a/cnd/src/network/mod.rs +++ b/cnd/src/network/mod.rs @@ -1,6 +1,7 @@ -pub mod oneshot_behaviour; -mod oneshot_protocol; -mod secret_hash; +mod oneshot_behaviour; + +pub mod oneshot_protocol; +pub mod protocols; pub mod transport; pub use transport::ComitTransport; diff --git a/cnd/src/network/oneshot_protocol.rs b/cnd/src/network/oneshot_protocol.rs index 834f4f38cf..3bc71a88f6 100644 --- a/cnd/src/network/oneshot_protocol.rs +++ b/cnd/src/network/oneshot_protocol.rs @@ -4,6 +4,13 @@ use serde::{de::DeserializeOwned, Serialize}; use std::{io, iter, marker::PhantomData}; /// A trait for defining the message in a oneshot protocol. +/// +/// The oneshot protocol works in a "push" manner, i.e. +/// the dialer sends the message and the listener receives +/// it. +/// +/// Hence, if you want to send a message using a certain oneshot +/// protocol, you have to open a substream with a specific protocol. pub trait Message { /// The identifier of the oneshot protocol. const INFO: &'static str; diff --git a/cnd/src/network/protocols/bitcoin_identity.rs b/cnd/src/network/protocols/bitcoin_identity.rs new file mode 100644 index 0000000000..70f2d52a93 --- /dev/null +++ b/cnd/src/network/protocols/bitcoin_identity.rs @@ -0,0 +1,46 @@ +use crate::{identity, network::oneshot_protocol, swap_protocols::SwapId}; +use serde::{Deserialize, Serialize}; +use serde_hex::{SerHex, Strict}; +use serdebug::SerDebug; + +/// The message for the Bitcoin identity sharing protocol. +#[derive(Clone, Copy, Deserialize, Serialize, SerDebug)] +pub struct Message { + swap_id: SwapId, + /// A compressed Bitcoin public key, serialized as hex without a `0x` prefix + /// as per convention in the Bitcoin ecosystem. + #[serde(with = "SerHex::")] + pubkey: [u8; 33], +} + +impl Message { + pub fn new(swap_id: SwapId, pubkey: identity::Bitcoin) -> Self { + Self { + swap_id, + pubkey: bitcoin::PublicKey::from(pubkey).key.serialize(), + } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/identity/bitcoin/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + pubkey: [0u8; 33], + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","pubkey":"000000000000000000000000000000000000000000000000000000000000000000"}"#.to_owned()) + } +} diff --git a/cnd/src/network/protocols/ethereum_identity.rs b/cnd/src/network/protocols/ethereum_identity.rs new file mode 100644 index 0000000000..eb37b59f38 --- /dev/null +++ b/cnd/src/network/protocols/ethereum_identity.rs @@ -0,0 +1,45 @@ +use crate::{identity, network::oneshot_protocol, swap_protocols::SwapId}; +use serde::{Deserialize, Serialize}; +use serde_hex::{SerHex, StrictPfx}; + +/// The message for the Ethereum identity sharing protocol. +#[derive(Clone, Copy, Deserialize, Debug, Serialize)] +pub struct Message { + swap_id: SwapId, + /// An Ethereum address, serialized with a `0x` prefix as per convention in + /// the Ethereum ecosystem. + #[serde(with = "SerHex::")] + address: [u8; 20], +} + +impl Message { + pub fn new(swap_id: SwapId, address: identity::Ethereum) -> Self { + Self { + swap_id, + address: address.0, + } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/identity/ethereum/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + address: [0u8; 20], + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","address":"0x0000000000000000000000000000000000000000"}"#.to_owned()) + } +} diff --git a/cnd/src/network/protocols/finalize.rs b/cnd/src/network/protocols/finalize.rs new file mode 100644 index 0000000000..1cc9c63c15 --- /dev/null +++ b/cnd/src/network/protocols/finalize.rs @@ -0,0 +1,37 @@ +use crate::{network::oneshot_protocol, swap_protocols::SwapId}; +use serde::{Deserialize, Serialize}; + +/// The message for the finalize protocol. +#[derive(Clone, Copy, Deserialize, Debug, Serialize)] +pub struct Message { + swap_id: SwapId, +} + +impl Message { + pub fn new(swap_id: SwapId) -> Self { + Self { swap_id } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/finalize/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual) + .is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000"}"#.to_owned()) + } +} diff --git a/cnd/src/network/protocols/lightning_identity.rs b/cnd/src/network/protocols/lightning_identity.rs new file mode 100644 index 0000000000..7a0dbab152 --- /dev/null +++ b/cnd/src/network/protocols/lightning_identity.rs @@ -0,0 +1,43 @@ +use crate::{network::oneshot_protocol, swap_protocols::SwapId}; +use serde::{Deserialize, Serialize}; +use serde_hex::{SerHex, Strict}; +use serdebug::SerDebug; + +/// The message for the Lightning identity sharing protocol. +#[derive(Clone, Copy, Deserialize, Serialize, SerDebug)] +pub struct Message { + swap_id: SwapId, + /// A Lightning node identifier is a compressed secp256k1 public key, + /// serialized without a `0x` prefix. + #[serde(with = "SerHex::")] + pubkey: [u8; 33], +} + +impl Message { + pub fn new(swap_id: SwapId, pubkey: [u8; 33]) -> Self { + Self { swap_id, pubkey } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/identity/lightning/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + pubkey: [0u8; 33], + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","pubkey":"000000000000000000000000000000000000000000000000000000000000000000"}"#.to_owned()) + } +} diff --git a/cnd/src/network/protocols/mod.rs b/cnd/src/network/protocols/mod.rs new file mode 100644 index 0000000000..62c717ba50 --- /dev/null +++ b/cnd/src/network/protocols/mod.rs @@ -0,0 +1,5 @@ +pub mod bitcoin_identity; +pub mod ethereum_identity; +pub mod finalize; +pub mod lightning_identity; +pub mod secret_hash; diff --git a/cnd/src/network/protocols/secret_hash.rs b/cnd/src/network/protocols/secret_hash.rs new file mode 100644 index 0000000000..c59200a247 --- /dev/null +++ b/cnd/src/network/protocols/secret_hash.rs @@ -0,0 +1,47 @@ +use crate::{ + network::oneshot_protocol, + swap_protocols::{rfc003::SecretHash, SwapId}, +}; +use serde::{Deserialize, Serialize}; +use serde_hex::{SerHex, Strict}; + +/// The message for the secret hash sharing protocol. +#[derive(Clone, Copy, Deserialize, Debug, Serialize)] +pub struct Message { + swap_id: SwapId, + /// A SHA-256 hash, serialized as hex without a `0x` prefix. + #[serde(with = "SerHex::")] + secret_hash: [u8; 32], +} + +impl Message { + pub fn new(swap_id: SwapId, secret_hash: SecretHash) -> Self { + Self { + swap_id, + secret_hash: secret_hash.into_raw(), + } + } +} + +impl oneshot_protocol::Message for Message { + const INFO: &'static str = "/comit/swap/secret_hash/1.0.0"; +} + +#[cfg(test)] +mod tests { + use super::*; + use spectral::prelude::*; + use uuid::Uuid; + + #[test] + fn serialization_format_stability_test() { + let given = Message { + swap_id: SwapId(Uuid::nil()), + secret_hash: [0u8; 32], + }; + + let actual = serde_json::to_string(&given); + + assert_that(&actual).is_ok_containing(r#"{"swap_id":"00000000-0000-0000-0000-000000000000","secret_hash":"0000000000000000000000000000000000000000000000000000000000000000"}"#.to_owned()) + } +} diff --git a/cnd/src/network/secret_hash.rs b/cnd/src/network/secret_hash.rs deleted file mode 100644 index 75ffed3b21..0000000000 --- a/cnd/src/network/secret_hash.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::{ - network::oneshot_protocol, - swap_protocols::{rfc003::SecretHash, SwapId}, -}; -use serde::{Deserialize, Serialize}; - -/// The secret hash sharing protocol works in the following way: -/// -/// - Dialer (Alice) writes the `Message` to the substream. -/// - Listener (Bob) reads the `Message` from the substream. - -/// Data sent to peer in secret hash protocol. -#[derive(Clone, Copy, Deserialize, Debug, Serialize, PartialEq)] -pub struct Message { - swap_id: SwapId, - secret_hash: SecretHash, -} - -impl oneshot_protocol::Message for Message { - const INFO: &'static str = "/comit/swap/secret_hash/1.0.0"; -} From 383d5a466d5682017c36aa75f347100fd89640d6 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 16 Mar 2020 17:36:32 +1100 Subject: [PATCH 083/145] Remove non-functional mergify rule Dependabot doesn't allow to recreate PRs from users that don't have write-access. Mergify doesn't have this so this always fails anyway. In addition, I checked with dependabot and it actually has a feature to automatically rebase on conflicts, which I now enabled. --- .mergify.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index 18be9772ee..08f2ea5d1d 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -32,15 +32,6 @@ pull_request_rules: actions: comment: message: "bors r+" - - name: recreate dependabot PRs with merge conflicts - conditions: - - "status-success=ci/circleci: debug-build-test" - - "author=dependabot-preview[bot]" - - conflict - - label!=no-mergify - actions: - comment: - message: "@dependabot recreate" - name: Delete branch if the pull request is merged conditions: - merged From 10a897cc04d50626ab57df759246ea6717fd5ffc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2020 17:18:17 +0000 Subject: [PATCH 084/145] Bump multiaddr from 7.4.0 to 7.4.1 in /api_tests Bumps [multiaddr](https://github.com/multiformats/js-multiaddr) from 7.4.0 to 7.4.1. - [Release notes](https://github.com/multiformats/js-multiaddr/releases) - [Changelog](https://github.com/multiformats/js-multiaddr/blob/master/CHANGELOG.md) - [Commits](https://github.com/multiformats/js-multiaddr/compare/v7.4.0...v7.4.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 63 ++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index ab814ca848..19a130efb8 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -60,7 +60,7 @@ "json-schema-to-typescript": "^8.2.0", "ln-service": "^47.15.3", "log4js": "^6.1.2", - "multiaddr": "^7.4.0", + "multiaddr": "^7.4.1", "pem-ts": "^2.0.0", "prettier": "^1.19.1", "readline-promise": "^1.0.4", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 380a61703e..3877a8a4eb 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1055,13 +1055,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base-x@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" - integrity sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA== - dependencies: - safe-buffer "^5.0.1" - base-x@^3.0.2: version "3.0.5" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" @@ -1069,7 +1062,14 @@ base-x@^3.0.2: dependencies: safe-buffer "^5.0.1" -base64-js@^1.3.1: +base-x@^3.0.8: + version "3.0.8" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" + integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2, base64-js@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== @@ -1583,6 +1583,14 @@ buffer-map@~0.0.7: resolved "https://registry.yarnpkg.com/buffer-map/-/buffer-map-0.0.7.tgz#5c2db65f7b3a723a2d9dff8e896fada3d2dc1c5d" integrity sha512-95try3p/vMRkIAAnJDaGkFhGpT/65NoeW6XelEPjAomWYR58RQtW4khn0SwKj34kZoE7uxL7w2koZSwbnszvQQ== +buffer@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" + integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + bufio@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.6.tgz#e0eb6d70b2efcc997b6f8872173540967f90fa4d" @@ -3046,11 +3054,6 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hi-base32@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.0.tgz#61329f76a31f31008533f1c36f2473e259d64571" - integrity sha512-DDRmxSyoYuvjUb9EnXdoiMChBZ7ZcUVJsK5Frd3kqMhuBxvmZdnBeynAVfj7/ECbn++CekcoprvC/rprHPAtow== - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3124,6 +3127,11 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" +ieee754@^1.1.4: + version "1.1.13" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" + integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== + ignore-walk@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" @@ -3194,11 +3202,6 @@ ip-regex@^4.0.0: resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.1.0.tgz#5ad62f685a14edb421abebc2fff8db94df67b455" integrity sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA== -ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - ipaddr.js@1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" @@ -4427,25 +4430,25 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -multiaddr@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/multiaddr/-/multiaddr-7.4.0.tgz#29356287b2ee3c7f1a670a4d1d40990c12b06c08" - integrity sha512-SooWP6eVhfMdf8ftyTmstZhrwMm7CUk3T5yU6naTjJ2cwTekciBjOjG4Pa8Sy3p+U0trJmZuILkqxtJ0Zpm9vQ== +multiaddr@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/multiaddr/-/multiaddr-7.4.1.tgz#b71cba8629364a35576fda2d01e8d6deca1cbb57" + integrity sha512-OK4CMgAwE1TeLw++vdfe8baDYYoG5rBHVxDe5lj2gfU28citvYBEaj1qq950HplgCqfFAlv9w/AitlrV7HUOIg== dependencies: - bs58 "^4.0.1" + buffer "^5.5.0" cids "~0.7.1" class-is "^1.1.0" - hi-base32 "~0.5.0" - ip "^1.1.5" is-ip "^3.1.0" + multibase "^0.6.0" varint "^5.0.0" -multibase@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.0.tgz#0216e350614c7456da5e8e5b20d3fcd4c9104f56" - integrity sha512-R9bNLQhbD7MsitPm1NeY7w9sDgu6d7cuj25snAWH7k5PSNPSwIQQBpcpj8jx1W96dLbdigZqmUWOdQRMnAmgjA== +multibase@^0.6.0, multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== dependencies: - base-x "3.0.4" + base-x "^3.0.8" + buffer "^5.5.0" multicodec@~0.5.1: version "0.5.5" From b60f986c37c718ad85d7df235c79d54cd3c4cafc Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 09:53:02 +1100 Subject: [PATCH 085/145] Standardize terminology --- digest/tests/swap_digest.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 74abd49297..9c92d8bd9d 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -28,12 +28,12 @@ struct DoubleFieldStruct { bar: String, } -struct OtherStruct { +struct OtherDoubleFieldStruct { bar: String, foo: String, } -impl RootDigest for OtherStruct { +impl RootDigest for OtherDoubleFieldStruct { fn root_digest(self) -> Multihash { let mut digests = vec![]; let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); @@ -181,7 +181,7 @@ fn given_two_double_field_struct_with_same_data_return_same_multihash() { foo: "foo field".into(), bar: "bar field".into(), }; - let struct2 = OtherStruct { + let struct2 = OtherDoubleFieldStruct { bar: "bar field".into(), foo: "foo field".into(), }; From c0ad47ab15b3f2cdaa83b356767c448f4b5d7e08 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 10:07:41 +1100 Subject: [PATCH 086/145] Refactor extraction of attributes --- digest-macro-derive/src/lib.rs | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 6645545303..bfd804d3d5 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -25,14 +25,7 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let types = fields.named.iter().map(|field| &field.ty); - let bytes = fields.named.iter().map(|field| { - let attr = field - .attrs - .get(0) - .expect("digest_bytes attribute must be present on all fields"); - - attr_to_bytes(attr) - }); + let bytes = fields.named.iter().map(|field| attr_to_bytes(&field.attrs)); (idents, types, bytes) } _ => panic!("Only supporting named fields."), @@ -62,13 +55,10 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { Data::Enum(data) => { let idents = data.variants.iter().map(|variant| &variant.ident); - let bytes = data.variants.iter().map(|variant| { - let attr = variant - .attrs - .get(0) - .expect("digest_bytes attribute must be present on all fields"); - attr_to_bytes(attr) - }); + let bytes = data + .variants + .iter() + .map(|variant| attr_to_bytes(&variant.attrs)); let gen = quote! { impl ::digest::RootDigest for #name @@ -101,7 +91,10 @@ impl ToTokens for Bytes { } } -fn attr_to_bytes(attr: &Attribute) -> Bytes { +fn attr_to_bytes(attrs: &[Attribute]) -> Bytes { + let attr = attrs + .get(0) + .expect("digest_bytes attribute must be the only attribute present on all fields"); let meta = attr.parse_meta().expect("Attribute is malformed"); if let Meta::NameValue(name_value) = meta { From 45138901c29c5101394edf8dd14d39ad7d37b355 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 10:09:14 +1100 Subject: [PATCH 087/145] Allow deadcode --- digest/tests/swap_digest.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 9c92d8bd9d..7de66a35e8 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -60,6 +60,7 @@ enum Enum { Bar, } +#[allow(dead_code)] enum OtherEnum { Foo, Bar, From 744050c6cf4695c82d78cb61f2509846d095ed0d Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 10:35:27 +1100 Subject: [PATCH 088/145] Remove unneeded test Only keep test that verifies the macro's behaviour --- digest/tests/swap_digest.rs | 56 ------------------------------------- 1 file changed, 56 deletions(-) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 7de66a35e8..10aad3c8b7 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -2,24 +2,6 @@ use digest::{digest, FieldDigest, RootDigest, RootDigestMacro}; use digest::multihash::Multihash; -struct NewType(String); - -impl RootDigest for NewType { - fn root_digest(self) -> Multihash { - self.0.field_digest("0".into()) - } -} - -struct SingleFieldStruct { - field: String, -} - -impl RootDigest for SingleFieldStruct { - fn root_digest(self) -> Multihash { - self.field.field_digest("field".into()) - } -} - #[derive(RootDigestMacro)] struct DoubleFieldStruct { #[digest_bytes = "0011"] @@ -110,44 +92,6 @@ fn given_different_strings_return_different_multihash() { ) } -#[test] -fn given_same_newtypes_return_same_multihash() { - let new_type1 = NewType("simple string".into()); - let new_type2 = NewType("simple string".into()); - - assert_eq!(new_type1.root_digest(), new_type2.root_digest()) -} - -#[test] -fn given_different_newtypes_return_different_multihash() { - let new_type1 = NewType("simple string".into()); - let new_type2 = NewType("longer string.".into()); - - assert_ne!(new_type1.root_digest(), new_type2.root_digest()) -} - -#[test] -fn given_same_single_field_struct_return_same_multihash() { - let struct1 = SingleFieldStruct { - field: "foo".into(), - }; - let struct2 = SingleFieldStruct { - field: "foo".into(), - }; - - assert_eq!(struct1.root_digest(), struct2.root_digest()) -} - -#[test] -fn given_single_field_struct_and_new_type_with_same_inner_return_different_multihash() { - let single_field_struct = SingleFieldStruct { - field: "foo".into(), - }; - let new_type = NewType("foo".into()); - - assert_ne!(single_field_struct.root_digest(), new_type.root_digest()) -} - #[test] fn given_same_double_field_struct_return_same_multihash() { let struct1 = DoubleFieldStruct { From 943f2a9c5ec7311816c78d9bb711f688d878ce11 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 14:38:21 +1100 Subject: [PATCH 089/145] Rename RootDigest trait --- digest-macro-derive/src/lib.rs | 16 ++++++++-------- digest/src/lib.rs | 6 +++--- digest/tests/swap_digest.rs | 22 +++++++++++----------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index bfd804d3d5..dd0c991660 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -5,13 +5,13 @@ use proc_macro2::{Delimiter, Group, Punct, Spacing}; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{Attribute, Data, Fields, Lit, Meta}; -#[proc_macro_derive(RootDigestMacro, attributes(digest_bytes))] -pub fn root_digest_macro_fn(input: TokenStream) -> TokenStream { +#[proc_macro_derive(DigestMacro, attributes(digest_bytes))] +pub fn digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); - impl_root_digest_macro(&ast) + impl_digest_macro(&ast) } -fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { +fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let name = &ast.ident; match &ast.data { @@ -32,10 +32,10 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { }; let gen = quote! { - impl ::digest::RootDigest for #name + impl ::digest::Digest for #name where #(#types: ::digest::FieldDigest),* { - fn root_digest(self) -> Multihash { + fn digest(self) -> Multihash { let mut digests = vec![]; #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* @@ -61,9 +61,9 @@ fn impl_root_digest_macro(ast: &syn::DeriveInput) -> TokenStream { .map(|variant| attr_to_bytes(&variant.attrs)); let gen = quote! { - impl ::digest::RootDigest for #name + impl ::digest::Digest for #name { - fn root_digest(self) -> Multihash { + fn digest(self) -> Multihash { let bytes = match self { #(Self::#idents => #bytes.to_vec()),* }; diff --git a/digest/src/lib.rs b/digest/src/lib.rs index e5629226f7..04b4d58772 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,4 +1,4 @@ -pub use digest_macro_derive::RootDigestMacro; +pub use digest_macro_derive::DigestMacro; pub use hex; pub use multihash; @@ -8,8 +8,8 @@ pub fn digest(bytes: &[u8]) -> Multihash { multihash::Sha3_256::digest(bytes) } -pub trait RootDigest { - fn root_digest(self) -> Multihash; +pub trait Digest { + fn digest(self) -> Multihash; } pub trait FieldDigest { diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 10aad3c8b7..e676941c8c 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,8 +1,8 @@ -use digest::{digest, FieldDigest, RootDigest, RootDigestMacro}; +use digest::{digest, Digest, DigestMacro, FieldDigest}; use digest::multihash::Multihash; -#[derive(RootDigestMacro)] +#[derive(DigestMacro)] struct DoubleFieldStruct { #[digest_bytes = "0011"] foo: String, @@ -15,8 +15,8 @@ struct OtherDoubleFieldStruct { foo: String, } -impl RootDigest for OtherDoubleFieldStruct { - fn root_digest(self) -> Multihash { +impl Digest for OtherDoubleFieldStruct { + fn digest(self) -> Multihash { let mut digests = vec![]; let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); digests.push(foo_digest); @@ -34,7 +34,7 @@ impl RootDigest for OtherDoubleFieldStruct { } } -#[derive(RootDigestMacro)] +#[derive(DigestMacro)] enum Enum { #[digest_bytes = "0011"] Foo, @@ -48,8 +48,8 @@ enum OtherEnum { Bar, } -impl RootDigest for OtherEnum { - fn root_digest(self) -> Multihash { +impl Digest for OtherEnum { + fn digest(self) -> Multihash { let bytes = match self { OtherEnum::Foo => vec![0x00u8, 0x11u8], OtherEnum::Bar => vec![0x00u8, 0x11u8], @@ -103,7 +103,7 @@ fn given_same_double_field_struct_return_same_multihash() { bar: "second field".into(), }; - assert_eq!(struct1.root_digest(), struct2.root_digest()) + assert_eq!(struct1.digest(), struct2.digest()) } #[test] @@ -117,7 +117,7 @@ fn given_different_double_field_struct_return_different_multihash() { bar: "different field".into(), }; - assert_ne!(struct1.root_digest(), struct2.root_digest()) + assert_ne!(struct1.digest(), struct2.digest()) } #[test] @@ -131,7 +131,7 @@ fn given_two_double_field_struct_with_same_data_return_same_multihash() { foo: "foo field".into(), }; - assert_eq!(struct1.root_digest(), struct2.root_digest()) + assert_eq!(struct1.digest(), struct2.digest()) } #[test] @@ -139,5 +139,5 @@ fn given_two_enums_with_same_bytes_per_variant_return_same_multihash() { let enum1 = Enum::Foo; let enum2 = OtherEnum::Foo; - assert_eq!(enum1.root_digest(), enum2.root_digest()) + assert_eq!(enum1.digest(), enum2.digest()) } From 3727b7c6ab06eee2f066dee380f0d7a7617b13d8 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 14:42:12 +1100 Subject: [PATCH 090/145] Rename suffix to prefix --- digest/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 04b4d58772..0ea3e3eddf 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -13,12 +13,12 @@ pub trait Digest { } pub trait FieldDigest { - fn field_digest(self, suffix: Vec) -> Multihash; + fn field_digest(self, prefix: Vec) -> Multihash; } impl FieldDigest for String { - fn field_digest(self, suffix: Vec) -> Multihash { - let mut bytes = suffix; + fn field_digest(self, prefix: Vec) -> Multihash { + let mut bytes = prefix; // String::into_bytes return the bytes for UTF-8 encoding let mut value = self.into_bytes(); bytes.append(&mut value); @@ -28,8 +28,8 @@ impl FieldDigest for String { } impl FieldDigest for Vec { - fn field_digest(mut self, suffix: Vec) -> Multihash { - let mut bytes = suffix; + fn field_digest(mut self, prefix: Vec) -> Multihash { + let mut bytes = prefix; bytes.append(&mut self); digest(&self) From 16f0c62cec75908f46c676cff9c24c6ea69325bd Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 14:45:24 +1100 Subject: [PATCH 091/145] Implement FieldDigest for T: Digest --- digest/src/lib.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 0ea3e3eddf..3a3e544a0c 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -16,6 +16,19 @@ pub trait FieldDigest { fn field_digest(self, prefix: Vec) -> Multihash; } +impl FieldDigest for T +where + T: Digest, +{ + fn field_digest(self, prefix: Vec) -> Multihash { + let mut bytes = prefix; + let field_digest = self.digest(); + bytes.append(&mut field_digest.into_bytes()); + + digest(&bytes) + } +} + impl FieldDigest for String { fn field_digest(self, prefix: Vec) -> Multihash { let mut bytes = prefix; From 38c3d80c3f94859111fccab3d303a655801c7832 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 15:03:38 +1100 Subject: [PATCH 092/145] Support nested structs --- digest/tests/swap_digest.rs | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index e676941c8c..0de0269721 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -59,6 +59,38 @@ impl Digest for OtherEnum { } } +#[derive(DigestMacro)] +struct NestedStruct { + #[digest_bytes = "0011"] + foo: String, + #[digest_bytes = "AA00"] + nest: DoubleFieldStruct, +} + +struct OtherNestedStruct { + foo: String, + nest: OtherDoubleFieldStruct, +} + +impl Digest for OtherNestedStruct { + fn digest(self) -> Multihash { + let mut digests = vec![]; + let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); + digests.push(foo_digest); + let nest_digest = self.nest.field_digest([0xAAu8, 0x00u8].to_vec()); + digests.push(nest_digest); + + digests.sort(); + + let res = digests.into_iter().fold(vec![], |mut res, digest| { + res.append(&mut digest.into_bytes()); + res + }); + + digest(&res) + } +} + #[test] fn given_same_strings_return_same_multihash() { let str1 = String::from("simple string"); @@ -141,3 +173,23 @@ fn given_two_enums_with_same_bytes_per_variant_return_same_multihash() { assert_eq!(enum1.digest(), enum2.digest()) } + +#[test] +fn given_two_nested_structs_with_same_value_return_same_multihash() { + let struct1 = NestedStruct { + foo: "foo".to_string(), + nest: DoubleFieldStruct { + foo: "phou".to_string(), + bar: "pub".to_string(), + }, + }; + let struct2 = OtherNestedStruct { + foo: "foo".to_string(), + nest: OtherDoubleFieldStruct { + foo: "phou".to_string(), + bar: "pub".to_string(), + }, + }; + + assert_eq!(struct1.digest(), struct2.digest()) +} From fef1c5a02d9019cd6c3db8130cc8f592387e7846 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 15:07:02 +1100 Subject: [PATCH 093/145] Rename `digest_bytes` to `digest_prefix` --- digest-macro-derive/src/lib.rs | 10 +++++----- digest/tests/swap_digest.rs | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index dd0c991660..8f4a691d22 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -5,7 +5,7 @@ use proc_macro2::{Delimiter, Group, Punct, Spacing}; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{Attribute, Data, Fields, Lit, Meta}; -#[proc_macro_derive(DigestMacro, attributes(digest_bytes))] +#[proc_macro_derive(DigestMacro, attributes(digest_prefix))] pub fn digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); impl_digest_macro(&ast) @@ -94,20 +94,20 @@ impl ToTokens for Bytes { fn attr_to_bytes(attrs: &[Attribute]) -> Bytes { let attr = attrs .get(0) - .expect("digest_bytes attribute must be the only attribute present on all fields"); + .expect("digest_prefix attribute must be the only attribute present on all fields"); let meta = attr.parse_meta().expect("Attribute is malformed"); if let Meta::NameValue(name_value) = meta { - if name_value.path.is_ident("digest_bytes") { + if name_value.path.is_ident("digest_prefix") { if let Lit::Str(lit_str) = name_value.lit { let str = lit_str.value(); let bytes = - ::hex::decode(&str).expect("digest_bytes value should be in hex format"); + ::hex::decode(&str).expect("digest_prefix value should be in hex format"); return Bytes(bytes); } } } - panic!("Only `digest_bytes = \"0102..0A\"` attributes are supported"); + panic!("Only `digest_prefix = \"0102..0A\"` attributes are supported"); } #[cfg(test)] diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 0de0269721..b2b1cd05c7 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -4,9 +4,9 @@ use digest::multihash::Multihash; #[derive(DigestMacro)] struct DoubleFieldStruct { - #[digest_bytes = "0011"] + #[digest_prefix = "0011"] foo: String, - #[digest_bytes = "FFAA"] + #[digest_prefix = "FFAA"] bar: String, } @@ -36,9 +36,9 @@ impl Digest for OtherDoubleFieldStruct { #[derive(DigestMacro)] enum Enum { - #[digest_bytes = "0011"] + #[digest_prefix = "0011"] Foo, - #[digest_bytes = "0E0F"] + #[digest_prefix = "0E0F"] Bar, } @@ -61,9 +61,9 @@ impl Digest for OtherEnum { #[derive(DigestMacro)] struct NestedStruct { - #[digest_bytes = "0011"] + #[digest_prefix = "0011"] foo: String, - #[digest_bytes = "AA00"] + #[digest_prefix = "AA00"] nest: DoubleFieldStruct, } From a2f77a410f0648e30d4363d25491a6dc3ebe4ff8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Mar 2020 15:50:39 +1100 Subject: [PATCH 094/145] Merge lib directory into src directory Up until now, only the test environments were in the src directory. There is actually no reason for this and merging them reduces the noise in the directory structure. --- api_tests/{lib => src}/actor_test.ts | 0 api_tests/{lib => src}/actors/actor.ts | 0 api_tests/{lib => src}/actors/index.ts | 0 api_tests/{lib => src}/asset.ts | 0 api_tests/{lib => src}/cnd/cnd_instance.ts | 0 api_tests/{lib => src}/config.ts | 0 api_tests/{lib => src}/create_actors.ts | 0 api_tests/src/dry_test_environment.ts | 7 +---- api_tests/src/e2e_test_environment.ts | 27 ++++++++----------- api_tests/{lib => src}/ledgers/bitcoin.ts | 0 .../{lib => src}/ledgers/bitcoind_instance.ts | 0 api_tests/{lib => src}/ledgers/ethereum.ts | 0 api_tests/{lib => src}/ledgers/ledger.ts | 0 .../{lib => src}/ledgers/ledger_instance.ts | 0 api_tests/{lib => src}/ledgers/lightning.ts | 0 .../{lib => src}/ledgers/lnd_instance.ts | 0 api_tests/{lib => src}/ledgers/log_reader.ts | 0 .../{lib => src}/ledgers/parity_instance.ts | 0 api_tests/{lib => src}/setup_chai.ts | 0 api_tests/{lib => src}/utils.ts | 0 api_tests/{lib => src}/wallets/bitcoin.ts | 0 api_tests/{lib => src}/wallets/ethereum.ts | 0 api_tests/{lib => src}/wallets/index.ts | 0 api_tests/{lib => src}/wallets/lightning.ts | 0 api_tests/tests/dry/lightning_routes.ts | 2 +- api_tests/tests/dry/multiple_peers.ts | 4 +-- api_tests/tests/dry/peers_using_ip.ts | 6 ++--- api_tests/tests/dry/rfc003_schema.ts | 8 +++--- api_tests/tests/dry/sanity.ts | 2 +- api_tests/tests/e2e/bitcoin_ethereum.ts | 8 +++--- 30 files changed, 27 insertions(+), 37 deletions(-) rename api_tests/{lib => src}/actor_test.ts (100%) rename api_tests/{lib => src}/actors/actor.ts (100%) rename api_tests/{lib => src}/actors/index.ts (100%) rename api_tests/{lib => src}/asset.ts (100%) rename api_tests/{lib => src}/cnd/cnd_instance.ts (100%) rename api_tests/{lib => src}/config.ts (100%) rename api_tests/{lib => src}/create_actors.ts (100%) rename api_tests/{lib => src}/ledgers/bitcoin.ts (100%) rename api_tests/{lib => src}/ledgers/bitcoind_instance.ts (100%) rename api_tests/{lib => src}/ledgers/ethereum.ts (100%) rename api_tests/{lib => src}/ledgers/ledger.ts (100%) rename api_tests/{lib => src}/ledgers/ledger_instance.ts (100%) rename api_tests/{lib => src}/ledgers/lightning.ts (100%) rename api_tests/{lib => src}/ledgers/lnd_instance.ts (100%) rename api_tests/{lib => src}/ledgers/log_reader.ts (100%) rename api_tests/{lib => src}/ledgers/parity_instance.ts (100%) rename api_tests/{lib => src}/setup_chai.ts (100%) rename api_tests/{lib => src}/utils.ts (100%) rename api_tests/{lib => src}/wallets/bitcoin.ts (100%) rename api_tests/{lib => src}/wallets/ethereum.ts (100%) rename api_tests/{lib => src}/wallets/index.ts (100%) rename api_tests/{lib => src}/wallets/lightning.ts (100%) diff --git a/api_tests/lib/actor_test.ts b/api_tests/src/actor_test.ts similarity index 100% rename from api_tests/lib/actor_test.ts rename to api_tests/src/actor_test.ts diff --git a/api_tests/lib/actors/actor.ts b/api_tests/src/actors/actor.ts similarity index 100% rename from api_tests/lib/actors/actor.ts rename to api_tests/src/actors/actor.ts diff --git a/api_tests/lib/actors/index.ts b/api_tests/src/actors/index.ts similarity index 100% rename from api_tests/lib/actors/index.ts rename to api_tests/src/actors/index.ts diff --git a/api_tests/lib/asset.ts b/api_tests/src/asset.ts similarity index 100% rename from api_tests/lib/asset.ts rename to api_tests/src/asset.ts diff --git a/api_tests/lib/cnd/cnd_instance.ts b/api_tests/src/cnd/cnd_instance.ts similarity index 100% rename from api_tests/lib/cnd/cnd_instance.ts rename to api_tests/src/cnd/cnd_instance.ts diff --git a/api_tests/lib/config.ts b/api_tests/src/config.ts similarity index 100% rename from api_tests/lib/config.ts rename to api_tests/src/config.ts diff --git a/api_tests/lib/create_actors.ts b/api_tests/src/create_actors.ts similarity index 100% rename from api_tests/lib/create_actors.ts rename to api_tests/src/create_actors.ts diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index 68e99df070..c8a18685ce 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -1,10 +1,5 @@ import { Config } from "@jest/types"; -import { - execAsync, - HarnessGlobal, - mkdirAsync, - rimrafAsync, -} from "../lib/utils"; +import { execAsync, HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; import NodeEnvironment from "jest-environment-node"; import { Mutex } from "async-mutex"; import path from "path"; diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index ad2b8a9cc1..e24b7b64c5 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -1,23 +1,18 @@ import { Config } from "@jest/types"; -import { - execAsync, - HarnessGlobal, - mkdirAsync, - rimrafAsync, -} from "../lib/utils"; +import { execAsync, HarnessGlobal, mkdirAsync, rimrafAsync } from "./utils"; import NodeEnvironment from "jest-environment-node"; import { Mutex } from "async-mutex"; import path from "path"; -import { LightningWallet } from "../lib/wallets/lightning"; -import { BitcoinWallet } from "../lib/wallets/bitcoin"; -import { AssetKind } from "../lib/asset"; -import { LedgerKind } from "../lib/ledgers/ledger"; -import BitcoinLedger from "../lib/ledgers/bitcoin"; -import { BitcoindInstance } from "../lib/ledgers/bitcoind_instance"; -import EthereumLedger from "../lib/ledgers/ethereum"; -import LightningLedger from "../lib/ledgers/lightning"; -import { ParityInstance } from "../lib/ledgers/parity_instance"; -import { LndInstance } from "../lib/ledgers/lnd_instance"; +import { LightningWallet } from "./wallets/lightning"; +import { BitcoinWallet } from "./wallets/bitcoin"; +import { AssetKind } from "./asset"; +import { LedgerKind } from "./ledgers/ledger"; +import BitcoinLedger from "./ledgers/bitcoin"; +import { BitcoindInstance } from "./ledgers/bitcoind_instance"; +import EthereumLedger from "./ledgers/ethereum"; +import LightningLedger from "./ledgers/lightning"; +import { ParityInstance } from "./ledgers/parity_instance"; +import { LndInstance } from "./ledgers/lnd_instance"; import { configure, Logger } from "log4js"; // ************************ // diff --git a/api_tests/lib/ledgers/bitcoin.ts b/api_tests/src/ledgers/bitcoin.ts similarity index 100% rename from api_tests/lib/ledgers/bitcoin.ts rename to api_tests/src/ledgers/bitcoin.ts diff --git a/api_tests/lib/ledgers/bitcoind_instance.ts b/api_tests/src/ledgers/bitcoind_instance.ts similarity index 100% rename from api_tests/lib/ledgers/bitcoind_instance.ts rename to api_tests/src/ledgers/bitcoind_instance.ts diff --git a/api_tests/lib/ledgers/ethereum.ts b/api_tests/src/ledgers/ethereum.ts similarity index 100% rename from api_tests/lib/ledgers/ethereum.ts rename to api_tests/src/ledgers/ethereum.ts diff --git a/api_tests/lib/ledgers/ledger.ts b/api_tests/src/ledgers/ledger.ts similarity index 100% rename from api_tests/lib/ledgers/ledger.ts rename to api_tests/src/ledgers/ledger.ts diff --git a/api_tests/lib/ledgers/ledger_instance.ts b/api_tests/src/ledgers/ledger_instance.ts similarity index 100% rename from api_tests/lib/ledgers/ledger_instance.ts rename to api_tests/src/ledgers/ledger_instance.ts diff --git a/api_tests/lib/ledgers/lightning.ts b/api_tests/src/ledgers/lightning.ts similarity index 100% rename from api_tests/lib/ledgers/lightning.ts rename to api_tests/src/ledgers/lightning.ts diff --git a/api_tests/lib/ledgers/lnd_instance.ts b/api_tests/src/ledgers/lnd_instance.ts similarity index 100% rename from api_tests/lib/ledgers/lnd_instance.ts rename to api_tests/src/ledgers/lnd_instance.ts diff --git a/api_tests/lib/ledgers/log_reader.ts b/api_tests/src/ledgers/log_reader.ts similarity index 100% rename from api_tests/lib/ledgers/log_reader.ts rename to api_tests/src/ledgers/log_reader.ts diff --git a/api_tests/lib/ledgers/parity_instance.ts b/api_tests/src/ledgers/parity_instance.ts similarity index 100% rename from api_tests/lib/ledgers/parity_instance.ts rename to api_tests/src/ledgers/parity_instance.ts diff --git a/api_tests/lib/setup_chai.ts b/api_tests/src/setup_chai.ts similarity index 100% rename from api_tests/lib/setup_chai.ts rename to api_tests/src/setup_chai.ts diff --git a/api_tests/lib/utils.ts b/api_tests/src/utils.ts similarity index 100% rename from api_tests/lib/utils.ts rename to api_tests/src/utils.ts diff --git a/api_tests/lib/wallets/bitcoin.ts b/api_tests/src/wallets/bitcoin.ts similarity index 100% rename from api_tests/lib/wallets/bitcoin.ts rename to api_tests/src/wallets/bitcoin.ts diff --git a/api_tests/lib/wallets/ethereum.ts b/api_tests/src/wallets/ethereum.ts similarity index 100% rename from api_tests/lib/wallets/ethereum.ts rename to api_tests/src/wallets/ethereum.ts diff --git a/api_tests/lib/wallets/index.ts b/api_tests/src/wallets/index.ts similarity index 100% rename from api_tests/lib/wallets/index.ts rename to api_tests/src/wallets/index.ts diff --git a/api_tests/lib/wallets/lightning.ts b/api_tests/src/wallets/lightning.ts similarity index 100% rename from api_tests/lib/wallets/lightning.ts rename to api_tests/src/wallets/lightning.ts diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index c8834cfdae..74f2fb39d7 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -3,7 +3,7 @@ */ import { expect } from "chai"; -import { oneActorTest } from "../../lib/actor_test"; +import { oneActorTest } from "../../src/actor_test"; // ******************************************** // // Lightning routes // diff --git a/api_tests/tests/dry/multiple_peers.ts b/api_tests/tests/dry/multiple_peers.ts index 12e4a195cb..38f5d132ba 100644 --- a/api_tests/tests/dry/multiple_peers.ts +++ b/api_tests/tests/dry/multiple_peers.ts @@ -2,8 +2,8 @@ * @logDir multiple_peers */ -import { threeActorTest } from "../../lib/actor_test"; -import { createDefaultSwapRequest } from "../../lib/utils"; +import { threeActorTest } from "../../src/actor_test"; +import { createDefaultSwapRequest } from "../../src/utils"; import { expect } from "chai"; import { SwapDetails } from "comit-sdk"; diff --git a/api_tests/tests/dry/peers_using_ip.ts b/api_tests/tests/dry/peers_using_ip.ts index 93153ec813..c3e40d8f51 100644 --- a/api_tests/tests/dry/peers_using_ip.ts +++ b/api_tests/tests/dry/peers_using_ip.ts @@ -2,10 +2,10 @@ * @logDir peers_ip */ -import { threeActorTest, twoActorTest } from "../../lib/actor_test"; -import { createDefaultSwapRequest, sleep } from "../../lib/utils"; +import { threeActorTest, twoActorTest } from "../../src/actor_test"; +import { createDefaultSwapRequest, sleep } from "../../src/utils"; import { expect, request } from "chai"; -import { Actor } from "../../lib/actors/actor"; +import { Actor } from "../../src/actors/actor"; // ******************************************** // // Peers using ips // diff --git a/api_tests/tests/dry/rfc003_schema.ts b/api_tests/tests/dry/rfc003_schema.ts index dd76615854..de9a965470 100644 --- a/api_tests/tests/dry/rfc003_schema.ts +++ b/api_tests/tests/dry/rfc003_schema.ts @@ -3,14 +3,14 @@ */ import { EmbeddedRepresentationSubEntity, Entity, Link } from "../../gen/siren"; -import { Actor } from "../../lib/actors/actor"; +import { Actor } from "../../src/actors/actor"; import { expect, request } from "chai"; import "chai/register-should"; -import "../../lib/setup_chai"; +import "../../src/setup_chai"; import * as sirenJsonSchema from "../../siren.schema.json"; import * as swapPropertiesJsonSchema from "../../swap.schema.json"; -import { twoActorTest } from "../../lib/actor_test"; -import { createDefaultSwapRequest, DEFAULT_ALPHA } from "../../lib/utils"; +import { twoActorTest } from "../../src/actor_test"; +import { createDefaultSwapRequest, DEFAULT_ALPHA } from "../../src/utils"; import { Action } from "comit-sdk"; // ******************************************** // diff --git a/api_tests/tests/dry/sanity.ts b/api_tests/tests/dry/sanity.ts index 6c4616f880..544de34287 100644 --- a/api_tests/tests/dry/sanity.ts +++ b/api_tests/tests/dry/sanity.ts @@ -2,7 +2,7 @@ * @logDir sanity */ -import { oneActorTest } from "../../lib/actor_test"; +import { oneActorTest } from "../../src/actor_test"; import { expect, request } from "chai"; import { Entity, Link } from "../../gen/siren"; import * as sirenJsonSchema from "../../siren.schema.json"; diff --git a/api_tests/tests/e2e/bitcoin_ethereum.ts b/api_tests/tests/e2e/bitcoin_ethereum.ts index b080615b0e..4b224d1ab6 100644 --- a/api_tests/tests/e2e/bitcoin_ethereum.ts +++ b/api_tests/tests/e2e/bitcoin_ethereum.ts @@ -3,11 +3,11 @@ * @logDir e2e */ -import { twoActorTest } from "../../lib/actor_test"; -import { AssetKind } from "../../lib/asset"; -import { sleep } from "../../lib/utils"; +import { twoActorTest } from "../../src/actor_test"; +import { AssetKind } from "../../src/asset"; +import { sleep } from "../../src/utils"; import { expect } from "chai"; -import { LedgerKind } from "../../lib/ledgers/ledger"; +import { LedgerKind } from "../../src/ledgers/ledger"; // ******************************************** // // Lightning Sanity Test // From 539674ec70f426ed1c63d91482737795bf697eef Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Mar 2020 16:17:57 +1100 Subject: [PATCH 095/145] Remove unnecessary dependencies from the e2e tests --- api_tests/package.json | 22 +- api_tests/types/readline-promise/index.d.ts | 7 - api_tests/yarn.lock | 1078 +------------------ 3 files changed, 44 insertions(+), 1063 deletions(-) delete mode 100644 api_tests/types/readline-promise/index.d.ts diff --git a/api_tests/package.json b/api_tests/package.json index 19a130efb8..c7ff27b73f 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -20,28 +20,21 @@ "dependencies": { "@iarna/toml": "^2.2.3", "@radar/lnrpc": "^0.9.0-beta", - "@types/bitcoinjs-lib": "^5.0.0", "@types/chai": "^4.2.11", "@types/chai-as-promised": "^7.1.2", "@types/chai-json-schema": "^1.4.5", "@types/chai-subset": "^1.3.3", - "@types/dockerode": "^2.5.24", - "@types/glob": "^7.1.1", "@types/jest": "^25.1.4", - "@types/jsdom": "^16.1.0", "@types/log4js": "^2.3.5", "@types/node": "^13.9", "@types/rimraf": "^2.0.3", - "@types/scrypt": "^6.0.0", "@types/tail": "^2.0.0", - "@types/tempfile": "^3.0.0", - "@types/urijs": "^1.19.7", + "@types/tmp": "^0.1.0", "@wcjiang/whereis": "^1.0.0", "async-mutex": "^0.1.4", "bcoin": "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001", "bignumber.js": "^9.0.0", "bitcoin-core": "^3.0.0", - "bitcoinjs-lib": "^5.1.7", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "chai-bignumber": "^3.0.0", @@ -51,39 +44,28 @@ "chai-string": "^1.5.0", "chai-subset": "^1.6.0", "comit-sdk": "^0.14.0", - "commander": "^5.0.0", "ethers": "^4.0.45", "get-port": "^5.1.1", - "glob": "^7.1.6", "jest": "^25.1.0", "js-sha256": "^0.9.0", "json-schema-to-typescript": "^8.2.0", - "ln-service": "^47.15.3", "log4js": "^6.1.2", - "multiaddr": "^7.4.1", - "pem-ts": "^2.0.0", "prettier": "^1.19.1", - "readline-promise": "^1.0.4", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", "smack-my-jasmine-up": "^0.0.3", "tail": "^2.0.3", "temp-write": "^4.0.0", - "testcontainers": "^2.6.0", "tmp": "^0.1.0", "ts-jest": "^25.2.1", "ts-node": "^8.6.2", "tslint": "^6.1.0", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", - "typescript": "^3.8.3", - "urijs": "^1.19.2" + "typescript": "^3.8.3" }, "prettier": { "trailingComma": "es5", "tabWidth": 4 - }, - "devDependencies": { - "@types/tmp": "^0.1.0" } } diff --git a/api_tests/types/readline-promise/index.d.ts b/api_tests/types/readline-promise/index.d.ts deleted file mode 100644 index 72e72cdaf8..0000000000 --- a/api_tests/types/readline-promise/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare module "readline-promise" { - interface ReadLine { - questionAsync(value: string): Promise; - } - - function createInterface(options: any): ReadLine; -} diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 3877a8a4eb..c2d733e2e4 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -2,32 +2,6 @@ # yarn lockfile v1 -"@alexbosworth/request@2.88.3": - version "2.88.3" - resolved "https://registry.yarnpkg.com/@alexbosworth/request/-/request-2.88.3.tgz#b408e685c722b116c6b6352cbc5561d3de2691bd" - integrity sha512-51/Y5x0SncVGQc274YckWMo9CooUGp7XppgV9K8v5eBwcXnw9sM/j0LpAvUFE7gjJcmZVYXDmLxtOYtgC0f2dg== - dependencies: - aws-sign2 "0.7.0" - aws4 "1.9.1" - caseless "0.12.0" - combined-stream "1.0.8" - extend "3.0.2" - forever-agent "0.6.1" - form-data "3.0.0" - har-validator "5.1.3" - http-signature "1.3.1" - is-typedarray "1.0.0" - isstream "0.1.2" - json-stringify-safe "5.0.1" - mime-types "2.1.26" - oauth-sign "0.9.0" - performance-now "2.1.0" - qs "6.9.1" - safe-buffer "5.2.0" - tough-cookie "3.0.1" - tunnel-agent "0.6.0" - uuid "3.4.0" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -177,26 +151,6 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@datastructures-js/heap@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@datastructures-js/heap/-/heap-1.2.0.tgz#d5bc5f36127630e922d3342e71da9bc81944f5f2" - integrity sha512-4dexQMQB2S6VXjtwI2px/Y2oIrfqOq2QkZKXFzaXizVA5FgAHlWNZ50/PF7SpjKgkMR1E1vPtY5eaxFwuPanFQ== - -"@datastructures-js/priority-queue@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@datastructures-js/priority-queue/-/priority-queue-2.0.0.tgz#5d8255e0e772c2ed06ff206636948d4f1fd3155d" - integrity sha512-PPtv7nZaDFO/3D0mWd/99iVYqyl7sKY8ZNQMKbS8x92OJ9Qw0yrpWz6KX/i8bSlGlTBx3oTUx8gZeKqaUDXZRg== - dependencies: - "@datastructures-js/heap" "^1.2.0" - -"@grpc/proto-loader@0.5.3": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.5.3.tgz#a233070720bf7560c4d70e29e7950c72549a132c" - integrity sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ== - dependencies: - lodash.camelcase "^4.3.0" - protobufjs "^6.8.6" - "@grpc/proto-loader@^0.4.0": version "0.4.0" resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.4.0.tgz#a823a51eb2fde58369bef1deb5445fd808d70901" @@ -488,13 +442,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/bitcoinjs-lib@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/bitcoinjs-lib/-/bitcoinjs-lib-5.0.0.tgz#f2905d673d1c4b42a91d64d95f1c464f1a48cb56" - integrity sha512-9zXjgmH2E8qEZ9gQ9GH+I6Cze3bweQbyXtR/X4RD3SdR5I4jdRPvmBrKmjegV3HZG03KNricjEoq+lQUtIXCKQ== - dependencies: - bitcoinjs-lib "*" - "@types/bytebuffer@^5.0.40": version "5.0.40" resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.40.tgz#d6faac40dcfb09cd856cdc4c01d3690ba536d3ee" @@ -539,19 +486,12 @@ resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.1.tgz#90b68446364baf9efd8e8349bb36bd3852b75b80" integrity sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw== -"@types/dockerode@^2.5.24": - version "2.5.24" - resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-2.5.24.tgz#702fb8827b260ec28e2702d7e2848bf24ec1ff25" - integrity sha512-2iwkmqjc6viw40KnAcyLW1sp9mptb6CPARvpRQDAzKsf0y6dphK0qzgouLiI2gaoNB0iiumZGd2nduGypKk9Aw== - dependencies: - "@types/node" "*" - "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== -"@types/glob@*", "@types/glob@^7.1.1": +"@types/glob@*": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== @@ -598,15 +538,6 @@ jest-diff "^25.1.0" pretty-format "^25.1.0" -"@types/jsdom@^16.1.0": - version "16.1.0" - resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-16.1.0.tgz#89d0ad0707eceb223c0db9b76611f8d487dd7d1b" - integrity sha512-GiBD8K4tFb0ah+rFAqkoP4tCc6DpCy96lITCCCAf1yqgvmpWNHh4S49sPIBXn4KIfvbVEcDRK+jgDHAbfVFdOw== - dependencies: - "@types/node" "*" - "@types/parse5" "*" - "@types/tough-cookie" "*" - "@types/json-schema@^7.0.3": version "7.0.3" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" @@ -641,21 +572,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== -"@types/node@10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== - "@types/node@^10.1.0": version "10.17.17" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== -"@types/parse5@*": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.2.tgz#a877a4658f8238c8266faef300ae41c84d72ec8a" - integrity sha512-BOl+6KDs4ItndUWUFchy3aEqGdHhw0BC4Uu+qoDonN/f0rbUnJbm71Ulj8Tt9jLFRaAxPLKvdS1bBLfx1qXR9g== - "@types/prettier@^1.16.1": version "1.18.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.18.2.tgz#069e7d132024d436fd1f5771f6932426a695f230" @@ -669,13 +590,6 @@ "@types/glob" "*" "@types/node" "*" -"@types/scrypt@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/scrypt/-/scrypt-6.0.0.tgz#167ddad830b1138fa4af9f0cb15d555facbd0bbf" - integrity sha512-kiQtYPL3YOOliArRkiE58O5DK7NyURo81hU4G43+wyQp4UiqGfM7muHGAZ/nHOU8LdAICiwcm28y5BPBZXWIYg== - dependencies: - "@types/node" "*" - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -694,33 +608,16 @@ resolved "https://registry.yarnpkg.com/@types/tail/-/tail-2.0.0.tgz#d1d035cd0caa5a2ed4a5b805acc6596fc6a233a2" integrity sha512-TYTfnILhrZUAZKGNgot5+sBDap7oPIzV3818p7g4VhKGc81+/eoEZ93wKBTGnSg/tpDjzWSb8Wx5E737FCH/Sw== -"@types/tempfile@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/tempfile/-/tempfile-3.0.0.tgz#26f58c2cb81a481b0a400b8aa9de23718fd05863" - integrity sha512-b9zw4A8PEZQobQ2i+e9R33Cj9wc6xeOrcte1/t6CviEhzCVgMiHlmdGQvn3h03H1OOlut1DqBIHCdPawJHzJDQ== - dependencies: - tempfile "*" - "@types/tmp@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.1.0.tgz#19cf73a7bcf641965485119726397a096f0049bd" integrity sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA== -"@types/tough-cookie@*": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.6.tgz#c880579e087d7a0db13777ff8af689f4ffc7b0d5" - integrity sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ== - "@types/tv4@*": version "1.2.29" resolved "https://registry.yarnpkg.com/@types/tv4/-/tv4-1.2.29.tgz#4c6d2222b03245dd2104f4fd67f54d1658985911" integrity sha512-NtJmi+XbYocrLb5Au4Q64srX4FlCPDvrSF/OnK3H0QJwrw40tIUoQPDoUHnZ5wpAB2KThtVyeS+kOEQyZabORg== -"@types/urijs@^1.19.7": - version "1.19.7" - resolved "https://registry.yarnpkg.com/@types/urijs/-/urijs-1.19.7.tgz#94dae48b40300135db8cc3796b12252850383193" - integrity sha512-0YN0GGB2Xab5cuHerBQw/NvWUnkdVfDNdBjXtTr+2AE1c9t29HVvV+IkXwp+fwqN8/05U/XjaQ7pk+jP41ypqA== - "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -745,14 +642,6 @@ resolved "https://registry.yarnpkg.com/@wcjiang/whereis/-/whereis-1.0.0.tgz#0e6c0020634784eba683a677660307a24fdc3f8a" integrity sha512-WwYgGSo0krJvcmHHTdif9ooQJW154vEhq6uAGT1PDMsZv5eTsuzYtLl1jojQZKzHRIgIptOM5MCLMg/0verHxw== -JSONStream@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.2.tgz#c102371b6ec3a7cf3b847ca00c20bb0fce4c6dea" - integrity sha1-wQI3G27Dp887hHygDCC7D85Mbeo= - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - abab@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" @@ -763,7 +652,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.5, accepts@~1.3.7: +accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -851,7 +740,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -any-promise@^1.0.0, any-promise@^1.1.0: +any-promise@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= @@ -967,16 +856,6 @@ async-mutex@^0.1.4: resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.1.4.tgz#a47d1eebf584f7dcdd760e3642dc2c58613bef5c" integrity sha512-zVWTmAnxxHaeB2B1te84oecI8zTDJ/8G49aVBblRX6be0oq6pAybNcUSxwfgVOmOjSCvN4aYZAqwtyNI8e1YGw== -async@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== - -asyncjs-util@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/asyncjs-util/-/asyncjs-util-1.1.3.tgz#514758a32a70fcde1eb092fe5b28b55d4315a732" - integrity sha512-iOd9KndvLYO5vSDsNFa16VOkMKTDMvM2RU7pBLGqOlA5YzVxjIUGWXmPlx1yZR4y9+19s1a3yvVPOurGi8kGlA== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -987,16 +866,11 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -aws-sign2@0.7.0, aws-sign2@~0.7.0: +aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= -aws4@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - aws4@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" @@ -1055,25 +929,6 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base-x@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" - integrity sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA== - dependencies: - safe-buffer "^5.0.1" - -base-x@^3.0.8: - version "3.0.8" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" - integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.0.2, base64-js@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - base@^0.11.1: version "0.11.2" resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" @@ -1087,20 +942,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@^2.0.0, basic-auth@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" - integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== - dependencies: - safe-buffer "5.1.2" - -basicauth-middleware@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/basicauth-middleware/-/basicauth-middleware-3.1.0.tgz#8bb6e4cb9cdab37e5c8be71b6277da5e3c04927a" - integrity sha512-sDy0dfIxDUKrJRqmBgekGc9I+C7HkwF9+T1lRGy6W4hQjugJYMAwQCtvdPOXK77GbgwdN9ShYaXo2QknX0Yftw== - dependencies: - basic-auth "^2.0.0" - bcfg@~0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/bcfg/-/bcfg-0.1.6.tgz#f77a6323bddef14f3886222e7ef8ccc0bc2143ec" @@ -1181,11 +1022,6 @@ bdns@~0.1.5: dependencies: bsert "~0.0.10" -bech32@1.1.3, bech32@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.3.tgz#bd47a8986bbb3eec34a56a097a84b8d3e9a2dfcd" - integrity sha512-yuVFUvrNcoJi0sv5phmqc6P+Fl1HjRDRNOOkHY2X/3LBy2bIGNSFx4fZ95HMaXHupuS7cZR15AsvtmCIF4UEyg== - bevent@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/bevent/-/bevent-0.1.5.tgz#c43a8d48a7037a97209c92c5fcf5a11f35a746b1" @@ -1229,13 +1065,6 @@ bignumber.js@^9.0.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== -bindings@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - binet@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/binet/-/binet-0.3.5.tgz#bf4f2a1859d08bb5de55fce9faa34274b18cce0b" @@ -1244,31 +1073,6 @@ binet@~0.3.5: bs32 "~0.1.5" bsert "~0.0.10" -bip174@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bip174/-/bip174-1.0.1.tgz#858a587f9529e22ee9b0572fd884e5783696824d" - integrity sha512-Mq2aFs1TdMfxBpYPg7uzjhsiXbAtoVq44TNjEWtvuZBiBgc3m7+n55orYMtTAxdg7jWbL4DtH0MKocJER4xERQ== - -bip32@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.4.tgz#b662bd28710d4676fb351ba8a13be45cb4d85d01" - integrity sha512-ioPytarPDIrWckWMuK4RNUtvwhvWEc2fvuhnO0WEwu732k5OLjUXv4rXi2c/KJHw9ZMNQMkYRJrBw81RujShGQ== - dependencies: - "@types/node" "10.12.18" - bs58check "^2.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - tiny-secp256k1 "^1.1.0" - typeforce "^1.11.5" - wif "^2.0.6" - -bip66@^1.1.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" - integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= - dependencies: - safe-buffer "^5.0.1" - bitcoin-core@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/bitcoin-core/-/bitcoin-core-2.3.0.tgz#ad63de13e163f3dc05d0287eb191cb4578563cb1" @@ -1296,47 +1100,6 @@ bitcoin-core@^3.0.0: semver "^5.1.0" standard-error "^1.1.0" -bitcoin-ops@^1.3.0, bitcoin-ops@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz#e45de620398e22fd4ca6023de43974ff42240278" - integrity sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow== - -bitcoinjs-lib@*, bitcoinjs-lib@5.1.7, bitcoinjs-lib@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/bitcoinjs-lib/-/bitcoinjs-lib-5.1.7.tgz#dfa023d6ad887eaef8249513d708c9ecd2673a08" - integrity sha512-sNlTQuvhaoIjOdIdyENsX74Dlikv7l6AzO0/uZQscuvfBID6aMANoCz1rooCTH5upTV5rKCj4z3BXBmXJxq23g== - dependencies: - bech32 "^1.1.2" - bip174 "^1.0.1" - bip32 "^2.0.4" - bip66 "^1.1.0" - bitcoin-ops "^1.4.0" - bs58check "^2.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.3" - merkle-lib "^2.0.10" - pushdata-bitcoin "^1.0.1" - randombytes "^2.0.1" - tiny-secp256k1 "^1.1.1" - typeforce "^1.11.3" - varuint-bitcoin "^1.0.4" - wif "^2.0.1" - -bl@^1.0.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" - integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== - dependencies: - readable-stream "^2.3.5" - safe-buffer "^5.1.1" - -bl@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88" - integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A== - dependencies: - readable-stream "^3.0.1" - blgr@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/blgr/-/blgr-0.1.7.tgz#69ed054282e5d3be7b6b19b03962a397227ab498" @@ -1370,17 +1133,7 @@ bmutex@~0.1.6: dependencies: bsert "~0.0.10" -bn.js@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.0.0.tgz#5c3d398021b3ddb548c1296a16f857e908f35c70" - integrity sha512-bVwDX8AF+72fIUNuARelKAlQUNtPOfG2fRxorbVvFk4zpHbqLrPdOGfVg5vrKwVzLLePqPBiATaOZNELQzmS0A== - -bn.js@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.1.tgz#48efc4031a9c4041b9c99c6941d903463ab62eb5" - integrity sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA== - -bn.js@^4.11.8, bn.js@^4.4.0: +bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== @@ -1401,25 +1154,6 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" -bolt07@1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/bolt07/-/bolt07-1.4.4.tgz#d4c875b507b795e2525d3d9804a24acd4c772ec6" - integrity sha512-1jn3ef9lhhcd4uC9JcOHQXtFgOMuN8AEBMRnWNO/zTVOOkl0zLKEkv30PrBfwdr0i/OAIEbhTHIR/2PCGLVfxQ== - dependencies: - bn.js "5.0.0" - -bolt07@1.4.5: - version "1.4.5" - resolved "https://registry.yarnpkg.com/bolt07/-/bolt07-1.4.5.tgz#e4c1cfac71f76a52ac4d5e830bed07fb3893c290" - integrity sha512-cthfbW9W4zyhhhNykWRe+QukrMM8WOq9p3g40i1zP0XNKNvJNYOTziV9AXqYWPZ4BV39PY33YsJzIhuEjNfp7Q== - dependencies: - bn.js "5.1.1" - -bolt09@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/bolt09/-/bolt09-0.0.1.tgz#cd62d5022928fed776ed1ecc59f3cf2e4176a258" - integrity sha512-o9In+fstEAq3jdWZv5CJ9D5EXr3Q5y0giGfXYJvmHw3HhSeocO211XvcWl+4iX7SeflL7b1GYXOY6G/5LQMA5Q== - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1489,22 +1223,6 @@ bs32@~0.1.5: dependencies: bsert "~0.0.10" -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= - dependencies: - base-x "^3.0.2" - -bs58check@<3.0.0, bs58check@^2.0.0, bs58check@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -1555,24 +1273,6 @@ btcp@~0.1.5: resolved "https://registry.yarnpkg.com/btcp/-/btcp-0.1.5.tgz#f76262415a0f6eaa592cdbb91c8b18386530ac28" integrity sha512-tkrtMDxeJorn5p0KxaLXELneT8AbfZMpOFeoKYZ5qCCMMSluNuwut7pGccLC5YOJqmuk0DR774vNVQLC9sNq/A== -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== - dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= - buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1583,14 +1283,6 @@ buffer-map@~0.0.7: resolved "https://registry.yarnpkg.com/buffer-map/-/buffer-map-0.0.7.tgz#5c2db65f7b3a723a2d9dff8e896fada3d2dc1c5d" integrity sha512-95try3p/vMRkIAAnJDaGkFhGpT/65NoeW6XelEPjAomWYR58RQtW4khn0SwKj34kZoE7uxL7w2koZSwbnszvQQ== -buffer@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" - integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - bufio@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.0.6.tgz#e0eb6d70b2efcc997b6f8872173540967f90fa4d" @@ -1635,11 +1327,6 @@ bweb@~0.1.9: bsert "~0.0.10" bsock "~0.1.8" -byline@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" - integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= - bytebuffer@~5: version "5.0.1" resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" @@ -1647,11 +1334,6 @@ bytebuffer@~5: dependencies: long "~3" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" @@ -1699,19 +1381,11 @@ capture-exit@^2.0.0: dependencies: rsvp "^4.8.4" -caseless@0.12.0, caseless@~0.12.0: +caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -cbor@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.0.1.tgz#243eea46b19c6e54ffb18fb07fa52c1c627a6f05" - integrity sha512-l4ghwqioCyuAaD3LvY4ONwv8NMuERz62xjbMHGdWBqERJPygVmoFER1b4+VS6iW0rXwoVGuKZPPPTofwWOg3YQ== - dependencies: - bignumber.js "^9.0.0" - nofilter "^1.0.3" - chai-as-promised@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" @@ -1794,7 +1468,7 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= -chownr@^1.0.1, chownr@^1.1.1: +chownr@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6" integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A== @@ -1804,29 +1478,6 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cids@~0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.1.tgz#d8bba49a35a0e82110879b5001abf1039c62347f" - integrity sha512-qEM4j2GKE/BiT6WdUi6cfW8dairhSLTUE8tIdxJG6SvY33Mp/UPjw+xcO0n1zsllgo72BupzKF/44v+Bg8YPPg== - dependencies: - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "~0.5.1" - multihashes "~0.4.14" - -cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" - integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== - class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -1919,7 +1570,7 @@ colour@~0.7.1: resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778" integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g= -combined-stream@1.0.8, combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -1948,51 +1599,16 @@ commander@^2.12.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== -commander@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0" - integrity sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ== - component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@~1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - console-control-strings@^1.0.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -2042,38 +1658,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cors@2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -create-hash@^1.1.0, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.3, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2206,13 +1791,6 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -default-gateway@^5.0.2: - version "5.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-5.0.3.tgz#18434c9430a18035a2861f7839bf7669b3436e6f" - integrity sha512-zW+ld9xtN0+q48wIwhitUzhfERJN7BPgvijPhuCKG6bfWqnoqtSNSnrXfvAME2ZJLpgYpz6UorpBddGfLzrJBw== - dependencies: - execa "^2.0.3" - define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2282,25 +1860,6 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== -docker-modem@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-1.0.9.tgz#a1f13e50e6afb6cf3431b2d5e7aac589db6aaba8" - integrity sha512-lVjqCSCIAUDZPAZIeyM125HXfNvOmYYInciphNrLrylUtKyW66meAjSPXWchKVzoIYZx69TPnAepVSSkeawoIw== - dependencies: - JSONStream "1.3.2" - debug "^3.2.6" - readable-stream "~1.0.26-4" - split-ca "^1.0.0" - -dockerode@^2.5.8: - version "2.5.8" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-2.5.8.tgz#1b661e36e1e4f860e25f56e0deabe9f87f1d0acc" - integrity sha512-+7iOUYBeDTScmOmQqpUYQaE7F4vvIt6+gIZNHWhqAQEI887tiPFB9OvXI/HzQYqfUNvukMK+9myLW63oTJPZpw== - dependencies: - concat-stream "~1.6.2" - docker-modem "^1.0.8" - tar-fs "~1.16.3" - domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" @@ -2308,11 +1867,6 @@ domexception@^1.0.1: dependencies: webidl-conversions "^4.0.2" -dotenv@8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a" - integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw== - dtrace-provider@~0.8: version "0.8.7" resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" @@ -2333,7 +1887,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -elliptic@6.5.2, elliptic@^6.4.0, elliptic@^6.5.2: +elliptic@6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== @@ -2356,7 +1910,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0: version "1.4.1" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== @@ -2508,21 +2062,6 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.4.tgz#2f5cc589c81db316628627004ea4e37b93391d8e" - integrity sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ== - dependencies: - cross-spawn "^6.0.5" - get-stream "^5.0.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^3.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - execa@^3.2.0: version "3.4.0" resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" @@ -2569,7 +2108,7 @@ expect@^25.1.0: jest-message-util "^25.1.0" jest-regex-util "^25.1.0" -express@4.17.1, express@^4.17.1: +express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -2620,7 +2159,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@3.0.2, extend@^3.0.0, extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -2676,11 +2215,6 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -2743,20 +2277,11 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= -forever-agent@0.6.1, forever-agent@~0.6.1: +forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -form-data@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682" - integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^2.3.1, form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -2793,11 +2318,6 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -2858,11 +2378,6 @@ get-func-name@^2.0.0: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= -get-port@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" - integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== - get-port@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" @@ -2905,7 +2420,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -2942,7 +2457,7 @@ growly@^1.3.0: resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= -grpc@1.24.2, grpc@^1.24.2: +grpc@^1.24.2: version "1.24.2" resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.24.2.tgz#76d047bfa7b05b607cbbe3abb99065dcefe0c099" integrity sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw== @@ -2959,7 +2474,7 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@5.1.3, har-validator@~5.1.0, har-validator@~5.1.3: +har-validator@~5.1.0, har-validator@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -3030,14 +2545,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hash-base@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - hash.js@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" @@ -3097,15 +2604,6 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-signature@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.3.1.tgz#739fe2f8897ba84798e3e54b699a9008a8724ff9" - integrity sha512-Y29YKEc8MQsjch/VzkUVJ+2MXd9WcR42fK5u36CZf4G8bXw2DXMTWuESiB0R6m59JAWxlPPw5/Fri/t/AyyueA== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.14.1" - http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3127,11 +2625,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - ignore-walk@^3.0.1: version "3.0.3" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" @@ -3160,7 +2653,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -3180,28 +2673,11 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= -invoices@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invoices/-/invoices-1.0.0.tgz#08368d96a7074bd29fa0459803cb727dc5600e74" - integrity sha512-blukVcU2sw3Vs6La0E4JHY/YNCpq3UyQXm2HR2WUtgMI0XzaZBOohVteja3FMXTO5BYFkV+OAs+1QQ5bybr5lA== - dependencies: - bech32 "1.1.3" - bitcoinjs-lib "5.1.7" - bn.js "5.1.1" - bolt07 "1.4.4" - bolt09 "0.0.1" - secp256k1 "4.0.0" - ip-regex@^2.0.0, ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= -ip-regex@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.1.0.tgz#5ad62f685a14edb421abebc2fff8db94df67b455" - integrity sha512-pKnZpbgCTfH/1NLIlOduP/V+WRXzC2MOz3Qo8xmxk8C5GudJLgK5QyLVXOSWy3ParAH7Eemurl3xjv/WXYFvMA== - ipaddr.js@1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65" @@ -3221,11 +2697,6 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-base64@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-base64/-/is-base64-1.1.0.tgz#8ce1d719895030a457c59a7dcaf39b66d99d56b4" - integrity sha512-Nlhg7Z2dVC4/PTvIFkgVVNvPHSO2eR/Yd0XzhGiXCXEvWnptXlXa/clQ8aePPiMuxEGcWfzWbGw2Fe3d+Y3v1g== - is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3343,13 +2814,6 @@ is-ip@^2.0.0: dependencies: ip-regex "^2.0.0" -is-ip@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" - integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== - dependencies: - ip-regex "^4.0.0" - is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" @@ -3398,7 +2862,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" -is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -3413,11 +2877,6 @@ is-wsl@^2.1.1: resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d" integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog== -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -3440,7 +2899,7 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@0.1.2, isstream@~0.1.2: +isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= @@ -3949,7 +3408,7 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= -json-stringify-safe@5.0.1, json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -3968,11 +3427,6 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - jsonpointer.js@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/jsonpointer.js/-/jsonpointer.js-0.4.0.tgz#002cb123f767aafdeb0196132ce5c4f9941ccaba" @@ -4037,56 +3491,6 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lightning@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lightning/-/lightning-1.2.4.tgz#1debec35da84d8fabced378d191e6fc392394af2" - integrity sha512-J3NWINK2lE3NwtXpY1dsqUwZdosDymDsimEops56nuqeD09LENeQY4zBXD3WWS0ckYXh/Ar8LnCO2E/qMpXjyg== - dependencies: - "@grpc/proto-loader" "0.5.3" - async "3.2.0" - asyncjs-util "1.1.3" - bn.js "5.1.1" - body-parser "1.19.0" - bolt07 "1.4.5" - bolt09 "0.0.1" - cbor "5.0.1" - express "4.17.1" - grpc "1.24.2" - invoices "1.0.0" - is-base64 "1.1.0" - -ln-service@^47.15.3: - version "47.15.3" - resolved "https://registry.yarnpkg.com/ln-service/-/ln-service-47.15.3.tgz#c508b107126eca864da229f8a47f01e87df915be" - integrity sha512-kbBCIxS8MqemXxp9r79NaBYtXHbxPvtvw8jhLyBwlViF/uKST2+3jU0ckh/Zinw+Wh7c7ydpEiPW3Y5FzlESIg== - dependencies: - "@alexbosworth/request" "2.88.3" - "@datastructures-js/priority-queue" "2.0.0" - "@grpc/proto-loader" "0.5.3" - async "3.2.0" - asyncjs-util "1.1.3" - basicauth-middleware "3.1.0" - bech32 "1.1.3" - bitcoinjs-lib "5.1.7" - bn.js "5.1.1" - body-parser "1.19.0" - bolt07 "1.4.5" - bolt09 "0.0.1" - compression "1.7.4" - cors "2.8.5" - dotenv "8.2.0" - express "4.17.1" - grpc "1.24.2" - is-base64 "1.1.0" - lightning "1.2.4" - lodash "4.17.15" - macaroon "3.0.4" - morgan "1.9.1" - promptly "3.0.3" - safe-compare "1.1.4" - secp256k1 "4.0.0" - ws "7.2.3" - loady@~0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/loady/-/loady-0.0.1.tgz#24a99c14cfed9cd0bffed365b1836035303f7e5d" @@ -4127,7 +3531,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@4.17.15, lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -4167,15 +3571,6 @@ lru-queue@0.1: dependencies: es5-ext "~0.10.2" -macaroon@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/macaroon/-/macaroon-3.0.4.tgz#dac1a4b17cd973c1000703f40b19bdbb1d6191ce" - integrity sha512-Tja2jvupseKxltPZbu5RPSz2Pgh6peYA3O46YCTcYL8PI1VqtGwDqRhGfP8pows26xx9wTiygk+en62Bq+Y8JA== - dependencies: - sjcl "^1.0.6" - tweetnacl "^1.0.0" - tweetnacl-util "^0.15.0" - make-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" @@ -4212,15 +3607,6 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -4250,11 +3636,6 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merkle-lib@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/merkle-lib/-/merkle-lib-2.0.10.tgz#82b8dbae75e27a7785388b73f9d7725d0f6f3326" - integrity sha1-grjbrnXieneFOItz+ddyXQ9vMyY= - methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -4297,18 +3678,6 @@ mime-db@1.42.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== -mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - -mime-types@2.1.26: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== - dependencies: - mime-db "1.43.0" - mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.24" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" @@ -4395,17 +3764,6 @@ moment@^2.10.6, moment@^2.24.0: resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== -morgan@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" - integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== - dependencies: - basic-auth "~2.0.0" - debug "2.6.9" - depd "~1.1.2" - on-finished "~2.3.0" - on-headers "~1.0.1" - mrmr@~0.1.6, mrmr@~0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/mrmr/-/mrmr-0.1.8.tgz#206b7975157543d2cffe762eec23966000b3fd12" @@ -4430,46 +3788,6 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -multiaddr@^7.4.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/multiaddr/-/multiaddr-7.4.1.tgz#b71cba8629364a35576fda2d01e8d6deca1cbb57" - integrity sha512-OK4CMgAwE1TeLw++vdfe8baDYYoG5rBHVxDe5lj2gfU28citvYBEaj1qq950HplgCqfFAlv9w/AitlrV7HUOIg== - dependencies: - buffer "^5.5.0" - cids "~0.7.1" - class-is "^1.1.0" - is-ip "^3.1.0" - multibase "^0.6.0" - varint "^5.0.0" - -multibase@^0.6.0, multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" - integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.5.tgz#55c2535b44eca9ea40a13771420153fe075bb36d" - integrity sha512-1kOifvwAqp9IdiiTKmpK2tS+LY6GHZdKpk3S2EvW4T32vlwDyA3hJoZtGauzqdedUPVNGChnTksEotVOCVlC+Q== - dependencies: - varint "^5.0.0" - -multihashes@~0.4.14: - version "0.4.15" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.15.tgz#6dbc55f7f312c6782f5367c03c9783681589d8a6" - integrity sha512-G/Smj1GWqw1RQP3dRuRRPe3oyLqvPqUaEDIaoi7JF7Loxl4WAWvhJNk84oyDEodSucv0MmSW/ZT0RKUrsIFD3g== - dependencies: - bs58 "^4.0.1" - varint "^5.0.0" - -mute-stream@~0.0.4: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - mv@~2: version "2.1.1" resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" @@ -4549,21 +3867,6 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-addon-api@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" - integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== - -node-duration@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/node-duration/-/node-duration-1.0.4.tgz#3e94ecc0e473691c89c4560074503362071cecac" - integrity sha512-eUXYNSY7DL53vqfTosggWkvyIW3bhAcqBDIlolgNYlZhianXTrCL50rlUJWD1eRqkIxMppXTfiFbp+9SjpPrgA== - -node-gyp-build@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.0.tgz#2c2b05f461f4178641a6ce2d7159f04094e9376d" - integrity sha512-4oiumOLhCDU9Rronz8PZ5S4IvT39H5+JEv/hps9V8s7RSLhsac0TCP78ulnHXOo8X1wdpPiTayGlM1jr4IbnaQ== - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -4601,11 +3904,6 @@ node-pre-gyp@^0.14.0: semver "^5.3.0" tar "^4.4.2" -nofilter@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.3.tgz#34e54b4cc9757de0cad38cc0d19462489b1b7f5d" - integrity sha512-FlUlqwRK6reQCaFLAhMcF+6VkVG2caYjKQY3YsRDTl4/SEch595Qb3oLjJRDr8dkHAAOVj2pOx3VknfnSgkE5g== - nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -4654,13 +3952,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" - integrity sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg== - dependencies: - path-key "^3.0.0" - npm-run-path@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -4688,12 +3979,12 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@0.9.0, oauth-sign@~0.9.0: +oauth-sign@~0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -4756,11 +4047,6 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.1, on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -4951,14 +4237,7 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= -pem-ts@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pem-ts/-/pem-ts-2.0.0.tgz#bb2c58f52528047283ef25f5941ede223e5c2c54" - integrity sha512-yS2U3SFf/+MIOh7BANBDUwvFYcpVlHuUKbHcBZxsoPHDfX/cdq61nQ2sNNifeWxCjPhtbh3zZBDSECsQE20j8Q== - dependencies: - base64-js "^1.3.1" - -performance-now@2.1.0, performance-now@^2.1.0: +performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= @@ -4968,11 +4247,6 @@ picomatch@^2.0.4, picomatch@^2.0.5: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -5029,14 +4303,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== -promptly@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/promptly/-/promptly-3.0.3.tgz#e178f722e73d82c60d019462044bccfdd9872f42" - integrity sha512-EWnzOsxVKUjqKeE6SStH1/cO4+DE44QolaoJ4ojGd9z6pcNkpgfJKr1ncwxrOFHSTIzoudo7jG8y0re30/LO1g== - dependencies: - pify "^3.0.0" - read "^1.0.4" - prompts@^2.0.1: version "2.3.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.1.tgz#b63a9ce2809f106fa9ae1277c275b167af46ea05" @@ -5092,14 +4358,6 @@ psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== -pump@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" - integrity sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -5118,35 +4376,16 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pushdata-bitcoin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz#15931d3cd967ade52206f523aa7331aef7d43af7" - integrity sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc= - dependencies: - bitcoin-ops "^1.3.0" - qs@6.7.0, qs@^6.5.1: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -qs@6.9.1: - version "6.9.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" - integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== - qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -randombytes@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -5177,13 +4416,6 @@ react-is@^16.12.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== -read@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" - integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= - dependencies: - mute-stream "~0.0.4" - readable-stream@^2.0.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -5197,7 +4429,7 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: +readable-stream@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== @@ -5210,30 +4442,6 @@ readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.1, readable-stream@^3.1.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@~1.0.26-4: - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readline-promise@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/readline-promise/-/readline-promise-1.0.4.tgz#c22190438642da6fb99462cfbbfb6232b4edb9bd" - integrity sha512-b6fycDK7CZWpVXbTl8qnW2jovXPduWKpZGyVZbjK/V4A9iiTU4gur+JEkjjgGKLiDZOftkRCT/dxGLG6hR9HyA== - realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -5402,36 +4610,16 @@ rimraf@~2.4.0: dependencies: glob "^6.0.1" -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== -safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.0, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-compare@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/safe-compare/-/safe-compare-1.1.4.tgz#5e0128538a82820e2e9250cd78e45da6786ba593" - integrity sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ== - dependencies: - buffer-alloc "^1.2.0" - safe-json-stringify@~1: version "1.2.0" resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" @@ -5488,15 +4676,6 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== -secp256k1@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.0.tgz#1c5def3be9f86c679839110fd6be30d53f34f1a9" - integrity sha512-0w0zse+Iku13O58SVE9/DhyCKWNsKb+n/vMqLOGICgSqxWuXZs+eajBf9uVOgk5QfNvTY/mx0QSqYxkcz802dw== - dependencies: - elliptic "^6.5.2" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5, semver@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -5566,14 +4745,6 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5613,11 +4784,6 @@ sisteransi@^1.0.4: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.4.tgz#386713f1ef688c7c0304dc4c0632898941cad2e3" integrity sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig== -sjcl@^1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/sjcl/-/sjcl-1.0.8.tgz#f2ec8d7dc1f0f21b069b8914a41a8f236b0e252a" - integrity sha512-LzIjEQ0S0DpIgnxMEayM1rq9aGwGRG4OnZhCdjx7glTaJtf4zRfpg87ImfjSJjoW9vKpagd82McDOwbRT5kQKQ== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -5697,11 +4863,6 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -split-ca@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" - integrity sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY= - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -5714,7 +4875,7 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.14.1, sshpk@^1.7.0: +sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== @@ -5762,13 +4923,6 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= -stream-to-array@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/stream-to-array/-/stream-to-array-2.3.0.tgz#bbf6b39f5f43ec30bc71babcb37557acecf34353" - integrity sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M= - dependencies: - any-promise "^1.1.0" - streamroller@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-2.2.3.tgz#b95c9fad44e2e89005d242141486b3b4962c2d28" @@ -5828,18 +4982,6 @@ string.prototype.trimright@^2.1.1: define-properties "^1.1.3" function-bind "^1.1.1" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -5943,50 +5085,6 @@ tail@^2.0.3: resolved "https://registry.yarnpkg.com/tail/-/tail-2.0.3.tgz#37567adc4624a70b35f1d146c3376fa3d6ef7c04" integrity sha512-s9NOGkLqqiDEtBttQZI7acLS8ycYK5sTlDwNjGnpXG9c8AWj0cfAtwEIzo/hVRMMiC5EYz+bXaJWC1u1u0GPpQ== -tar-fs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad" - integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== - dependencies: - chownr "^1.1.1" - mkdirp "^0.5.1" - pump "^3.0.0" - tar-stream "^2.0.0" - -tar-fs@~1.16.3: - version "1.16.3" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-1.16.3.tgz#966a628841da2c4010406a82167cbd5e0c72d509" - integrity sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw== - dependencies: - chownr "^1.0.1" - mkdirp "^0.5.1" - pump "^1.0.0" - tar-stream "^1.1.2" - -tar-stream@^1.1.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" - integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== - dependencies: - bl "^1.0.0" - buffer-alloc "^1.2.0" - end-of-stream "^1.0.0" - fs-constants "^1.0.0" - readable-stream "^2.3.0" - to-buffer "^1.1.1" - xtend "^4.0.0" - -tar-stream@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3" - integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw== - dependencies: - bl "^3.0.0" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - tar@^4.4.2: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" @@ -6005,11 +5103,6 @@ temp-dir@^1.0.0: resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== - temp-write@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-4.0.0.tgz#cd2e0825fc826ae72d201dc26eef3bf7e6fc9320" @@ -6021,14 +5114,6 @@ temp-write@^4.0.0: temp-dir "^1.0.0" uuid "^3.3.2" -tempfile@*: - version "3.0.0" - resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-3.0.0.tgz#5376a3492de7c54150d0cc0612c3f00e2cdaf76c" - integrity sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw== - dependencies: - temp-dir "^2.0.0" - uuid "^3.3.2" - terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -6046,20 +5131,6 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -testcontainers@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-2.6.0.tgz#0f444d97e0d037880fcffe10ee7cb9f0d5e149f0" - integrity sha512-kRO9+pXz8w5JQfbsyTFIlqU6Ooic3XflhsCDE+LavoFUmhAvOkF/ycafPHU2RR5GZ42TwRUXask0PJZEvpcCTg== - dependencies: - byline "^5.0.0" - debug "^4.1.1" - default-gateway "^5.0.2" - dockerode "^2.5.8" - get-port "^4.2.0" - node-duration "^1.0.4" - stream-to-array "^2.3.0" - tar-fs "^2.0.0" - thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" @@ -6079,11 +5150,6 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== -"through@>=2.2.7 <3": - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - timers-ext@^0.1.5: version "0.1.7" resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" @@ -6092,17 +5158,6 @@ timers-ext@^0.1.5: es5-ext "~0.10.46" next-tick "1" -tiny-secp256k1@^1.1.0, tiny-secp256k1@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.3.tgz#e93b1e1bf62e9bd1ad3ab24af27ff6127ce0e077" - integrity sha512-ZpobrhOtHP98VYEN51IYQH1YcrbFpnxFhI6ceWa3OEbJn7eHvSd8YFjGPxbedGCy7PNYU1v/+BRsdvyr5uRd4g== - dependencies: - bindings "^1.3.0" - bn.js "^4.11.8" - create-hmac "^1.1.7" - elliptic "^6.4.0" - nan "^2.13.2" - tmp@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" @@ -6115,11 +5170,6 @@ tmpl@1.0.x: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= -to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -6162,15 +5212,6 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== -tough-cookie@3.0.1, tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -6179,6 +5220,15 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tough-cookie@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" + integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== + dependencies: + ip-regex "^2.1.0" + psl "^1.1.28" + punycode "^2.1.1" + tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -6278,7 +5328,7 @@ tsutils@^3.0.0: dependencies: tslib "^1.8.1" -tunnel-agent@0.6.0, tunnel-agent@^0.6.0: +tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= @@ -6290,21 +5340,11 @@ tv4@^1.3.0: resolved "https://registry.yarnpkg.com/tv4/-/tv4-1.3.0.tgz#d020c846fadd50c855abb25ebaecc68fc10f7963" integrity sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM= -tweetnacl-util@^0.15.0: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= -tweetnacl@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -6337,16 +5377,6 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -typeforce@^1.11.3, typeforce@^1.11.5: - version "1.18.0" - resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" - integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== - typescript@^3.8.3: version "3.8.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" @@ -6402,7 +5432,7 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= @@ -6427,7 +5457,7 @@ uuid@2.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" integrity sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w= -uuid@3.4.0, uuid@^3.0.1, uuid@^3.3.2: +uuid@^3.0.1, uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -6441,19 +5471,7 @@ v8-to-istanbul@^4.0.1: convert-source-map "^1.6.0" source-map "^0.7.3" -varint@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf" - integrity sha1-2Ca4n3SQcy+rwMDtaT7Uddyynr8= - -varuint-bitcoin@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.0.tgz#7a343f50537607af6a3059312b9782a170894540" - integrity sha512-jCEPG+COU/1Rp84neKTyDJQr478/hAfVp5xxYn09QEH0yBjbmPeMfuuQIrp+BUD83hybtYZKhr5elV3bvdV1bA== - dependencies: - safe-buffer "^5.1.1" - -vary@^1, vary@~1.1.2: +vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= @@ -6542,13 +5560,6 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -wif@^2.0.1, wif@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" - integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= - dependencies: - bs58check "<3.0.0" - window-size@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" @@ -6591,7 +5602,7 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@7.2.3, ws@^7.0.0: +ws@^7.0.0: version "7.2.3" resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== @@ -6611,11 +5622,6 @@ xmlhttprequest@1.8.0: resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw= -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - y18n@^3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" From f572806bb54e1bad5257b64a55c703bf0216e62e Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Thu, 12 Mar 2020 10:27:42 +1100 Subject: [PATCH 096/145] Split swap state into multiple stores COMIT's core provides updates on the state of the ledgers during a swap. These updates used to be applied directly on a struct which held all the information pertaining to the swap: offer, communication state, ledger state and error state. Storing everything together is convenient but creates dependencies which cause pain. The code can be simplified by splitting up this state into multiple stores. Primarily, a generic ledger store (instantiated twice, for alpha and beta) can be used to fulfil the core of COMIT's principal task. The communication state also needs to be saved and updated given the current communication protocol. Since this protocol is going away soon, it is not that appealing to invest a lot of effort into improving the design, so it is simply stored in a separate `HashMap`. This is not ideal because once the swap is accepted the information can also be obtained from the database layer, meaning that we are storing redundant information. Since it is easier to add another `HashMap` than adding APIs to the database to store and load proposed swaps, and this communication protocol is on the way out, incurring in this technical debt is justified. In terms of the error state, it turns out that we were never setting the state of the swap to failed if watching a particular ledger had resulted in an error. Since this was the apparent intention when introducing these APIs, the functionality has been kept. It has also been implemented using a `HashMap`, but a better design may come in the future. --- cnd/src/db/load_swaps.rs | 2 +- cnd/src/db/with_swap_types.rs | 4 +- .../routes/index/handlers/get_swaps.rs | 5 +- .../http_api/routes/rfc003/handlers/action.rs | 51 ++-- .../routes/rfc003/handlers/get_swap.rs | 8 +- .../routes/rfc003/handlers/post_swap.rs | 44 +-- cnd/src/http_api/routes/rfc003/swap_state.rs | 10 +- cnd/src/http_api/swap_resource.rs | 54 ++-- cnd/src/init_swap.rs | 96 +++---- cnd/src/load_swaps.rs | 5 +- cnd/src/main.rs | 18 +- cnd/src/network/mod.rs | 160 ++++++++--- cnd/src/swap_protocols/facade.rs | 51 ++-- cnd/src/swap_protocols/ledger_states.rs | 114 ++++++++ cnd/src/swap_protocols/mod.rs | 9 +- cnd/src/swap_protocols/rfc003/actor_state.rs | 26 -- .../rfc003/alice/actions/generic_impl.rs | 11 +- cnd/src/swap_protocols/rfc003/alice/mod.rs | 92 +----- .../rfc003/bitcoin/htlc_events.rs | 21 +- cnd/src/swap_protocols/rfc003/bob/mod.rs | 100 +------ cnd/src/swap_protocols/rfc003/create_swap.rs | 262 ++++-------------- .../rfc003/ethereum/htlc_events.rs | 32 ++- cnd/src/swap_protocols/rfc003/events/mod.rs | 6 +- cnd/src/swap_protocols/rfc003/ledger_state.rs | 61 ++-- cnd/src/swap_protocols/rfc003/mod.rs | 4 +- cnd/src/swap_protocols/state.rs | 17 ++ cnd/src/swap_protocols/state_store.rs | 212 -------------- .../swap_communication_states.rs | 40 +++ cnd/src/swap_protocols/swap_error_states.rs | 25 ++ 29 files changed, 669 insertions(+), 871 deletions(-) create mode 100644 cnd/src/swap_protocols/ledger_states.rs delete mode 100644 cnd/src/swap_protocols/rfc003/actor_state.rs create mode 100644 cnd/src/swap_protocols/state.rs delete mode 100644 cnd/src/swap_protocols/state_store.rs create mode 100644 cnd/src/swap_protocols/swap_communication_states.rs create mode 100644 cnd/src/swap_protocols/swap_error_states.rs diff --git a/cnd/src/db/load_swaps.rs b/cnd/src/db/load_swaps.rs index a16c854ddc..955f92b5a2 100644 --- a/cnd/src/db/load_swaps.rs +++ b/cnd/src/db/load_swaps.rs @@ -1,5 +1,5 @@ use crate::{ - asset::{self}, + asset, db::{ schema, wrapper_types::{ diff --git a/cnd/src/db/with_swap_types.rs b/cnd/src/db/with_swap_types.rs index 416c982b3b..c4b27c33e9 100644 --- a/cnd/src/db/with_swap_types.rs +++ b/cnd/src/db/with_swap_types.rs @@ -9,12 +9,12 @@ macro_rules! _match_role { match $role { Role::Alice => { #[allow(dead_code)] - type ROLE = alice::State; + type RoleState = alice::State; $fn } Role::Bob => { #[allow(dead_code)] - type ROLE = bob::State; + type RoleState = bob::State; $fn } } diff --git a/cnd/src/http_api/routes/index/handlers/get_swaps.rs b/cnd/src/http_api/routes/index/handlers/get_swaps.rs index 74873ce896..506d95d5ac 100644 --- a/cnd/src/http_api/routes/index/handlers/get_swaps.rs +++ b/cnd/src/http_api/routes/index/handlers/get_swaps.rs @@ -11,12 +11,13 @@ pub async fn handle_get_swaps(dependencies: Facade) -> anyhow::Result = dependencies + .get(&swap_id) + .await? + .ok_or_else(|| anyhow::anyhow!("swap communication state not found for {}", swap_id))?; + let alpha_ledger_state: LedgerState = dependencies + .alpha_ledger_state + .get(&swap_id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", swap_id))?; + let beta_ledger_state: LedgerState = dependencies + .beta_ledger_state + .get(&swap_id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", swap_id))?; + let secret_source = dependencies.derive_swap_seed(swap_id); + + let state = RoleState::new( + swap_communication, + alpha_ledger_state, + beta_ledger_state, + secret_source, + ); let action = state .actions() @@ -86,11 +105,9 @@ pub async fn handle_action( &swap_id, ) .await?; - init_accepted_swap::<_, _, _, _, _, AH, BH, _, _, AT, BT>( - &dependencies, - accepted, - types.role, - )?; + + init_accepted_swap::<_, _, _, _, AH, BH, _, _, AT, BT>(&dependencies, accepted) + .await?; Ok(ActionResponseBody::None) } @@ -121,14 +138,12 @@ pub async fn handle_action( ) })?; - let swap_request = state.request(); - let seed = dependencies.derive_swap_seed(swap_id); - let state = State::::declined( - swap_request.clone(), - decline_message, - seed, - ); - dependencies.insert(swap_id, state); + dependencies + .insert(swap_id, SwapCommunication::Declined { + request: state.request().clone(), + response: decline_message, + }) + .await; Ok(ActionResponseBody::None) } diff --git a/cnd/src/http_api/routes/rfc003/handlers/get_swap.rs b/cnd/src/http_api/routes/rfc003/handlers/get_swap.rs index c3667f2c3b..f919902390 100644 --- a/cnd/src/http_api/routes/rfc003/handlers/get_swap.rs +++ b/cnd/src/http_api/routes/rfc003/handlers/get_swap.rs @@ -8,11 +8,5 @@ pub async fn handle_get_swap(dependencies: Facade, id: SwapId) -> anyhow::Result let swap = Retrieve::get(&dependencies, &id).await?; let types = dependencies.determine_types(&id).await?; - build_rfc003_siren_entity( - dependencies.state_store.as_ref(), - swap, - types, - IncludeState::Yes, - OnFail::Error, - ) + build_rfc003_siren_entity(&dependencies, swap, types, IncludeState::Yes, OnFail::Error).await } diff --git a/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs b/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs index aebaa14ddf..f222548589 100644 --- a/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs +++ b/cnd/src/http_api/routes/rfc003/handlers/post_swap.rs @@ -8,11 +8,12 @@ use crate::{ seed::DeriveSwapSeed, swap_protocols::{ rfc003::{ - self, alice, + self, events::{HtlcDeployed, HtlcFunded, HtlcRedeemed, HtlcRefunded}, - Accept, Decline, DeriveIdentities, DeriveSecret, Request, SecretHash, + Accept, Decline, DeriveIdentities, DeriveSecret, LedgerState, Request, SecretHash, + SwapCommunication, }, - state_store::Insert, + state::Insert, Facade, HashFunction, Role, SwapId, }, timestamp::Timestamp, @@ -60,14 +61,23 @@ where tracing::trace!("initiating new request: {}", swap_request.swap_id); let counterparty = peer.peer_id.clone(); - let seed = dependencies.derive_swap_seed(id); Save::save(&dependencies, Swap::new(id, Role::Alice, counterparty)).await?; Save::save(&dependencies, swap_request.clone()).await?; - let state = - alice::State::<_, _, _, _, AH, BH, _, _, AT, BT>::proposed(swap_request.clone(), seed); - dependencies.insert(id, state); + dependencies + .insert(id, SwapCommunication::Proposed { + request: swap_request.clone(), + }) + .await; + dependencies + .alpha_ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; + dependencies + .beta_ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; let future = { async move { @@ -84,20 +94,18 @@ where &id, ) .await?; - init_accepted_swap::<_, _, _, _, _, AH, BH, _, _, AT, BT>( - &dependencies, - accepted, - Role::Alice, - )?; + + init_accepted_swap::<_, _, _, _, AH, BH, _, _, AT, BT>(&dependencies, accepted) + .await?; } Err(decline) => { tracing::info!("Swap declined: {}", decline.swap_id); - let state = alice::State::<_, _, _, _, AH, BH, _, _, AT, BT>::declined( - swap_request.clone(), - decline, - seed, - ); - dependencies.insert(id, state); + let swap_communication_state = SwapCommunication::Declined { + request: swap_request, + response: decline, + }; + + dependencies.insert(id, swap_communication_state).await; Save::save(&dependencies, decline).await?; } }; diff --git a/cnd/src/http_api/routes/rfc003/swap_state.rs b/cnd/src/http_api/routes/rfc003/swap_state.rs index 199f985b6b..726979a961 100644 --- a/cnd/src/http_api/routes/rfc003/swap_state.rs +++ b/cnd/src/http_api/routes/rfc003/swap_state.rs @@ -16,7 +16,7 @@ pub struct SwapState { pub beta_ledger: LedgerState, } -#[derive(Debug, Serialize)] +#[derive(Clone, Debug, Serialize)] #[serde(bound = "Http: Serialize, Http: Serialize")] pub struct SwapCommunication { pub status: SwapCommunicationState, @@ -110,7 +110,7 @@ where refund_tx: None, redeem_tx: None, }, - IncorrectlyFunded { + Funded { htlc_location, deploy_transaction, fund_transaction, @@ -120,10 +120,10 @@ where htlc_location: Some(Http(htlc_location)), deploy_tx: Some(Http(deploy_transaction)), fund_tx: Some(Http(fund_transaction)), - redeem_tx: None, refund_tx: None, + redeem_tx: None, }, - Funded { + IncorrectlyFunded { htlc_location, deploy_transaction, fund_transaction, @@ -133,8 +133,8 @@ where htlc_location: Some(Http(htlc_location)), deploy_tx: Some(Http(deploy_transaction)), fund_tx: Some(Http(fund_transaction)), - refund_tx: None, redeem_tx: None, + refund_tx: None, }, Redeemed { htlc_location, diff --git a/cnd/src/http_api/swap_resource.rs b/cnd/src/http_api/swap_resource.rs index 7280322aed..8b56ed7b84 100644 --- a/cnd/src/http_api/swap_resource.rs +++ b/cnd/src/http_api/swap_resource.rs @@ -8,11 +8,9 @@ use crate::{ routes::rfc003::{LedgerState, SwapCommunication, SwapState}, Http, HttpAsset, HttpLedger, }, + seed::DeriveSwapSeed, swap_protocols::{ - actions::Actions, - rfc003::{self, ActorState}, - state_store::{Get, InMemoryStateStore}, - HashFunction, SwapId, SwapProtocol, + actions::Actions, rfc003, state::Get, Facade, HashFunction, SwapId, SwapProtocol, }, }; use anyhow::anyhow; @@ -81,8 +79,8 @@ pub enum OnFail { // This is due to the introduction of a trust per Bitcoin network in the // `with_swap_types!` macro and can be iteratively improved #[allow(clippy::cognitive_complexity)] -pub fn build_rfc003_siren_entity( - state_store: &InMemoryStateStore, +pub async fn build_rfc003_siren_entity( + dependencies: &Facade, swap: Swap, types: SwapTypes, include_state: IncludeState, @@ -91,21 +89,45 @@ pub fn build_rfc003_siren_entity( let id = swap.swap_id; with_swap_types!(types, { - let state: ROLE = state_store - .get(&id)? - .ok_or_else(|| anyhow!("state store did not contain an entry for {}", id))?; + let swap_has_failed = dependencies.swap_error_states.has_failed(&id).await; - if state.swap_failed() && on_fail == OnFail::Error { + if swap_has_failed && on_fail == OnFail::Error { return Err(anyhow!(HttpApiProblem::with_title_and_type_from_status( StatusCode::INTERNAL_SERVER_ERROR, ))); } - let communication = SwapCommunication::from(state.swap_communication.clone()); - let alpha_ledger = LedgerState::from(state.alpha_ledger_state.clone()); - let beta_ledger = LedgerState::from(state.beta_ledger_state.clone()); - let parameters = SwapParameters::from(state.request().clone()); - let actions = state.actions(); + let swap_communication: rfc003::SwapCommunication = dependencies + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("swap communication state not found for {}", id))?; + let alpha_ledger_state: rfc003::LedgerState = dependencies + .alpha_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("alpha ledger state not found for {}", id))?; + let beta_ledger_state: rfc003::LedgerState = dependencies + .beta_ledger_state + .get(&id) + .await? + .ok_or_else(|| anyhow::anyhow!("beta ledger state not found for {}", id))?; + + let communication = SwapCommunication::from(swap_communication.clone()); + let alpha_ledger = LedgerState::from(alpha_ledger_state.clone()); + let beta_ledger = LedgerState::from(beta_ledger_state.clone()); + let parameters = SwapParameters::from(swap_communication.request().clone()); + + let secret_source = dependencies.derive_swap_seed(id); + + let actions = { + let state = RoleState::new( + swap_communication, + alpha_ledger_state, + beta_ledger_state, + secret_source, + ); + state.actions() + }; let status = SwapStatus::new( communication.status, @@ -147,7 +169,7 @@ pub fn build_rfc003_siren_entity( .with_class_member("protocol-spec"), ); - if state.swap_failed() && on_fail == OnFail::NoAction { + if swap_has_failed && on_fail == OnFail::NoAction { return Ok(entity); } diff --git a/cnd/src/init_swap.rs b/cnd/src/init_swap.rs index 9b275cf928..90d85a7978 100644 --- a/cnd/src/init_swap.rs +++ b/cnd/src/init_swap.rs @@ -1,36 +1,24 @@ use crate::{ db::AcceptedSwap, - seed::DeriveSwapSeed, swap_protocols::{ rfc003::{ - alice, bob, create_alpha_watcher, - create_swap::{create_beta_watcher, SwapEvent}, + create_swap::{create_watcher, OngoingSwap}, events::{HtlcDeployed, HtlcFunded, HtlcRedeemed, HtlcRefunded}, - Accept, Request, + Accept, Request, SwapCommunication, }, - state_store::{Insert, Update}, - Role, + state::Insert, + Facade, }, }; +use tracing_futures::Instrument; #[allow(clippy::cognitive_complexity)] -pub fn init_accepted_swap( - dependencies: &D, +pub async fn init_accepted_swap( + dependencies: &Facade, accepted: AcceptedSwap, - role: Role, ) -> anyhow::Result<()> where - D: Insert> - + Insert> - + Update< - alice::State, - SwapEvent, - > + Update< - bob::State, - SwapEvent, - > + Clone - + DeriveSwapSeed - + HtlcFunded + Facade: HtlcFunded + HtlcFunded + HtlcDeployed + HtlcDeployed @@ -51,51 +39,41 @@ where Request: Clone, Accept: Copy, { - let (request, accept, _) = &accepted; - + let (request, accept, accepted_at) = accepted; let id = request.swap_id; - let seed = dependencies.derive_swap_seed(id); - tracing::trace!("initialising accepted swap: {}", id); - match role { - Role::Alice => { - let state = alice::State::accepted(request.clone(), *accept, seed); - dependencies.insert(id, state); + dependencies + .insert(id, SwapCommunication::Accepted { + request: request.clone(), + response: accept, + }) + .await; - tokio::task::spawn(create_alpha_watcher::< - D, - alice::State, - AI, - BI, - >(dependencies.clone(), accepted.clone())); + let swap = OngoingSwap::new(request, accept); - tokio::task::spawn(create_beta_watcher::< - D, - alice::State, - AI, - BI, - >(dependencies.clone(), accepted)); - } - Role::Bob => { - let state: bob::State = - bob::State::accepted(request.clone(), *accept, seed); - dependencies.insert(id, state); + tracing::trace!("initialising accepted swap: {}", id); - tokio::task::spawn(create_alpha_watcher::< - D, - bob::State, - AI, - BI, - >(dependencies.clone(), accepted.clone())); + tokio::task::spawn( + create_watcher::<_, _, _, _, AH, _, AT>( + dependencies.clone(), + dependencies.alpha_ledger_state.clone(), + id, + swap.alpha_htlc_params(), + accepted_at, + ) + .instrument(tracing::info_span!("alpha")), + ); - tokio::task::spawn(create_beta_watcher::< - D, - bob::State, - AI, - BI, - >(dependencies.clone(), accepted)); - } - }; + tokio::task::spawn( + create_watcher::<_, _, _, _, BH, _, BT>( + dependencies.clone(), + dependencies.beta_ledger_state.clone(), + id, + swap.beta_htlc_params(), + accepted_at, + ) + .instrument(tracing::info_span!("beta")), + ); Ok(()) } diff --git a/cnd/src/load_swaps.rs b/cnd/src/load_swaps.rs index 2e259f36ac..486e0c7441 100644 --- a/cnd/src/load_swaps.rs +++ b/cnd/src/load_swaps.rs @@ -22,9 +22,8 @@ pub async fn load_swaps_from_database(facade: Facade) -> anyhow::Result<()> { match accepted { Ok(accepted) => { - init_accepted_swap::<_, _, _, _, _, AH, BH, _, _, AT, BT>( - &facade, accepted, types.role, - )?; + init_accepted_swap::<_, _, _, _, AH, BH, _, _, AT, BT>(&facade, accepted) + .await?; } Err(e) => tracing::error!("failed to load swap: {}, continuing ...", e), }; diff --git a/cnd/src/main.rs b/cnd/src/main.rs index 1af2502b98..91a351218b 100644 --- a/cnd/src/main.rs +++ b/cnd/src/main.rs @@ -25,7 +25,7 @@ use cnd::{ jsonrpc, load_swaps, network::Swarm, seed::RootSeed, - swap_protocols::{state_store::InMemoryStateStore, Facade}, + swap_protocols::{Facade, LedgerStates, SwapCommunicationStates, SwapErrorStates}, }; use rand::rngs::OsRng; use std::{process, sync::Arc}; @@ -105,7 +105,12 @@ fn main() -> anyhow::Result<()> { )) }; - let state_store = Arc::new(InMemoryStateStore::default()); + let alpha_ledger_state = Arc::new(LedgerStates::default()); + let beta_ledger_state = Arc::new(LedgerStates::default()); + + let swap_communication_states = Arc::new(SwapCommunicationStates::default()); + + let swap_error_states = Arc::new(SwapErrorStates::default()); let database = Sqlite::new_in_dir(&settings.data.dir)?; @@ -115,14 +120,19 @@ fn main() -> anyhow::Result<()> { &mut runtime, Arc::clone(&bitcoin_connector), Arc::clone(ðereum_connector), - Arc::clone(&state_store), + Arc::clone(&swap_communication_states), + Arc::clone(&alpha_ledger_state), + Arc::clone(&beta_ledger_state), &database, )?; let deps = Facade { bitcoin_connector, ethereum_connector, - state_store, + alpha_ledger_state, + beta_ledger_state, + swap_communication_states, + swap_error_states, seed, swarm, db: database, diff --git a/cnd/src/network/mod.rs b/cnd/src/network/mod.rs index b12215069a..6434dc1bb4 100644 --- a/cnd/src/network/mod.rs +++ b/cnd/src/network/mod.rs @@ -16,15 +16,16 @@ use crate::{ db::{Save, Sqlite, Swap}, htlc_location, libp2p_comit_ext::{FromHeader, ToHeader}, - seed::{DeriveSwapSeed, RootSeed}, + seed::RootSeed, swap_protocols::{ ledger, rfc003::{ - self, bob, + self, messages::{Decision, DeclineResponseBody, Request, RequestBody, SwapDeclineReason}, + LedgerState, SwapCommunication, }, - state_store::{InMemoryStateStore, Insert}, - HashFunction, Role, SwapId, SwapProtocol, + state::Insert, + HashFunction, LedgerStates, Role, SwapCommunicationStates, SwapId, SwapProtocol, }, transaction, }; @@ -81,13 +82,16 @@ pub struct Swarm { } impl Swarm { + #[allow(clippy::too_many_arguments)] pub fn new( settings: &Settings, seed: RootSeed, runtime: &mut Runtime, bitcoin_connector: Arc>, ethereum_connector: Arc>, - state_store: Arc, + swap_communication_states: Arc, + alpha_ledger_state: Arc, + beta_ledger_state: Arc, database: &Sqlite, ) -> anyhow::Result { let local_key_pair = derive_key_pair(&seed); @@ -98,7 +102,9 @@ impl Swarm { let behaviour = ComitNode::new( bitcoin_connector, ethereum_connector, - state_store, + swap_communication_states, + alpha_ledger_state, + beta_ledger_state, seed, database.clone(), runtime.handle().clone(), @@ -167,7 +173,11 @@ pub struct ComitNode { #[behaviour(ignore)] pub ethereum_connector: Arc>, #[behaviour(ignore)] - pub state_store: Arc, + pub swap_communication_states: Arc, + #[behaviour(ignore)] + pub alpha_ledger_state: Arc, + #[behaviour(ignore)] + pub beta_ledger_state: Arc, #[behaviour(ignore)] pub seed: RootSeed, #[behaviour(ignore)] @@ -211,10 +221,13 @@ pub struct Reason { } impl ComitNode { + #[allow(clippy::too_many_arguments)] pub fn new( bitcoin_connector: Arc>, ethereum_connector: Arc>, - state_store: Arc, + swap_communication_states: Arc, + alpha_ledger_state: Arc, + beta_ledger_state: Arc, seed: RootSeed, db: Sqlite, task_executor: Handle, @@ -235,7 +248,9 @@ impl ComitNode { mdns: Mdns::new()?, bitcoin_connector, ethereum_connector, - state_store, + alpha_ledger_state, + beta_ledger_state, + swap_communication_states, seed, db, response_channels: Arc::new(Mutex::new(HashMap::new())), @@ -258,8 +273,9 @@ impl ComitNode { #[allow(clippy::cognitive_complexity)] async fn handle_request( db: Sqlite, - seed: RootSeed, - state_store: Arc, + swap_communication_states: Arc, + alpha_ledger_state: Arc, + beta_ledger_state: Arc, counterparty: PeerId, mut request: ValidatedInboundRequest, ) -> Result { @@ -313,7 +329,12 @@ async fn handle_request( transaction::Ethereum, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -347,7 +368,12 @@ async fn handle_request( transaction::Ethereum, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -381,7 +407,12 @@ async fn handle_request( transaction::Ethereum, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -415,7 +446,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -449,7 +485,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -483,7 +524,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -517,7 +563,12 @@ async fn handle_request( transaction::Ethereum, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -552,7 +603,12 @@ async fn handle_request( transaction::Ethereum, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -587,7 +643,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -622,7 +683,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -656,7 +722,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -690,7 +761,12 @@ async fn handle_request( transaction::Bitcoin, _, >( - db.clone(), seed, state_store.clone(), counterparty, request + db.clone(), + swap_communication_states.clone(), + alpha_ledger_state.clone(), + beta_ledger_state.clone(), + counterparty, + request, ) .await .expect("Could not save state to db"); @@ -741,8 +817,9 @@ async fn handle_request( #[allow(clippy::type_complexity)] async fn insert_state_for_bob( db: DB, - seed: RootSeed, - state_store: Arc, + swap_communication_states: Arc, + alpha_ledger_state: Arc, + beta_ledger_state: Arc, counterparty: PeerId, swap_request: Request, ) -> anyhow::Result<()> @@ -759,17 +836,24 @@ where BT: Send + 'static, DB: Save> + Save, Request: Clone, - bob::State: Clone + Sync, { let id = swap_request.swap_id; - let seed = seed.derive_swap_seed(id); Save::save(&db, Swap::new(id, Role::Bob, counterparty)).await?; Save::save(&db, swap_request.clone()).await?; - let state = - bob::State::<_, _, _, _, AH, BH, _, _, AT, BT>::proposed(swap_request.clone(), seed); - state_store.insert(id, state); + swap_communication_states + .insert(id, SwapCommunication::Proposed { + request: swap_request, + }) + .await; + + alpha_ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; + beta_ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; Ok(()) } @@ -950,11 +1034,21 @@ impl NetworkBehaviourEventProcess for ComitNode { let response_channels = self.response_channels.clone(); let db = self.db.clone(); - let state_store = self.state_store.clone(); - let seed = self.seed; + let swap_communication_states = self.swap_communication_states.clone(); + let alpha_ledger_state = self.alpha_ledger_state.clone(); + let beta_ledger_state = self.beta_ledger_state.clone(); self.task_executor.spawn(async move { - match handle_request(db, seed, state_store, peer_id, request).await { + match handle_request( + db, + swap_communication_states, + alpha_ledger_state, + beta_ledger_state, + peer_id, + request, + ) + .await + { Ok(id) => { let mut response_channels = response_channels.lock().await; response_channels.insert(id, channel); diff --git a/cnd/src/swap_protocols/facade.rs b/cnd/src/swap_protocols/facade.rs index 281e10a575..ddd1e6918b 100644 --- a/cnd/src/swap_protocols/facade.rs +++ b/cnd/src/swap_protocols/facade.rs @@ -16,15 +16,14 @@ use crate::{ ledger::{bitcoin, Ethereum}, rfc003::{ self, - create_swap::{HtlcParams, SwapEvent}, + create_swap::HtlcParams, events::{ Deployed, Funded, HtlcDeployed, HtlcFunded, HtlcRedeemed, HtlcRefunded, Redeemed, Refunded, }, - ActorState, + SwapCommunication, }, - state_store::{self, Get, InMemoryStateStore, Insert, Update}, - SwapId, + state, InsertFailedSwap, LedgerStates, SwapCommunicationStates, SwapErrorStates, SwapId, }, transaction, }; @@ -51,43 +50,43 @@ use std::{convert::TryInto, fmt::Debug, sync::Arc}; pub struct Facade { pub bitcoin_connector: Arc>, pub ethereum_connector: Arc>, - pub state_store: Arc, + pub alpha_ledger_state: Arc, + pub beta_ledger_state: Arc, + pub swap_communication_states: Arc, + pub swap_error_states: Arc, pub seed: RootSeed, pub swarm: Swarm, pub db: Sqlite, } -impl Insert for Facade +#[async_trait] +impl state::Insert> for Facade where - S: Send + 'static, + SwapCommunication: Send + 'static, { - fn insert(&self, key: SwapId, value: S) { - self.state_store.insert(key, value) + async fn insert(&self, key: SwapId, value: SwapCommunication) { + self.swap_communication_states.insert(key, value).await } } -impl Get for Facade +#[async_trait] +impl state::Get> for Facade where - S: Clone + Send + 'static, + SwapCommunication: Clone + Send + 'static, { - fn get(&self, key: &SwapId) -> Result, state_store::Error> { - self.state_store.get(key) + #[allow(clippy::type_complexity)] + async fn get( + &self, + key: &SwapId, + ) -> anyhow::Result>> { + self.swap_communication_states.get(key).await } } -impl Update> for Facade -where - S: ActorState + Send, - S::AA: Ord, - S::BA: Ord, -{ - #[allow(clippy::type_complexity)] - fn update(&self, key: &SwapId, update: SwapEvent) { - Update::>::update( - self.state_store.as_ref(), - key, - update, - ) +#[async_trait] +impl InsertFailedSwap for Facade { + async fn insert_failed_swap(&self, id: &SwapId) { + self.swap_error_states.insert_failed_swap(&id).await } } diff --git a/cnd/src/swap_protocols/ledger_states.rs b/cnd/src/swap_protocols/ledger_states.rs new file mode 100644 index 0000000000..e7550cb532 --- /dev/null +++ b/cnd/src/swap_protocols/ledger_states.rs @@ -0,0 +1,114 @@ +use crate::swap_protocols::{ + rfc003::{create_swap::SwapEvent, LedgerState}, + state::{Get, Insert, Update}, + swap_id::SwapId, +}; +use async_trait::async_trait; +use std::{ + any::Any, + collections::HashMap, + ops::{Deref, DerefMut}, +}; +use tokio::sync::Mutex; + +#[derive(Default, Debug)] +pub struct LedgerStates { + states: Mutex>>, +} + +#[async_trait] +impl Insert for L +where + L: DerefMut>>> + Send + Sync + 'static, + S: Send + 'static, +{ + async fn insert(&self, key: SwapId, value: S) { + let mut states = self.lock().await; + states.insert(key, Box::new(value)); + } +} + +#[async_trait] +impl Get for L +where + L: DerefMut>>> + Send + Sync + 'static, + S: Clone + Send + 'static, +{ + async fn get(&self, key: &SwapId) -> anyhow::Result> { + let states = self.lock().await; + match states.get(key) { + Some(state) => match state.downcast_ref::() { + Some(state) => Ok(Some(state.clone())), + None => Err(anyhow::anyhow!("invalid type")), + }, + None => Ok(None), + } + } +} + +#[async_trait] +impl Update, SwapEvent> for L +where + L: DerefMut>>> + Send + Sync + 'static, + LedgerState: 'static, + A: Send, + H: Send, + T: Send, +{ + async fn update(&self, key: &SwapId, event: SwapEvent) { + let mut states = self.lock().await; + let ledger_state = match states + .get_mut(key) + .and_then(|state| state.downcast_mut::>()) + { + Some(state) => state, + None => { + tracing::warn!("Value not found for key {}", key); + return; + } + }; + + match event { + SwapEvent::Deployed(deployed) => ledger_state.transition_to_deployed(deployed), + SwapEvent::Funded(funded) => ledger_state.transition_to_funded(funded), + SwapEvent::Redeemed(redeemed) => { + // what if redeemed.secret.hash() != secret_hash in request ?? + + ledger_state.transition_to_redeemed(redeemed); + } + SwapEvent::Refunded(refunded) => ledger_state.transition_to_refunded(refunded), + } + } +} + +impl Deref for LedgerStates { + type Target = Mutex>>; + fn deref(&self) -> &Self::Target { + &self.states + } +} + +impl DerefMut for LedgerStates { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.states + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{asset, htlc_location, transaction}; + use spectral::prelude::*; + + #[tokio::test] + async fn insert_and_get_ledger_state() { + let ledger_states = LedgerStates::default(); + let id = SwapId::default(); + + ledger_states.insert(id, LedgerState::::NotDeployed).await; + + let res: Option> = + ledger_states.get(&id).await.unwrap(); + assert_that(&res).contains_value(&LedgerState::NotDeployed); + } +} diff --git a/cnd/src/swap_protocols/mod.rs b/cnd/src/swap_protocols/mod.rs index 2fa1e9e8ab..8241b145bd 100644 --- a/cnd/src/swap_protocols/mod.rs +++ b/cnd/src/swap_protocols/mod.rs @@ -1,11 +1,16 @@ pub mod actions; mod facade; pub mod ledger; +pub mod ledger_states; pub mod rfc003; -pub mod state_store; +pub mod state; +pub mod swap_communication_states; +mod swap_error_states; mod swap_id; -pub use self::{facade::*, swap_id::*}; +pub use self::{ + facade::*, ledger_states::*, swap_communication_states::*, swap_error_states::*, swap_id::*, +}; use serde::{Deserialize, Serialize}; diff --git a/cnd/src/swap_protocols/rfc003/actor_state.rs b/cnd/src/swap_protocols/rfc003/actor_state.rs deleted file mode 100644 index 0c3fd8a38f..0000000000 --- a/cnd/src/swap_protocols/rfc003/actor_state.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::swap_protocols::rfc003::ledger_state::LedgerState; - -pub trait ActorState: 'static { - type AL; - type BL; - type AA; - type BA; - type AH; - type BH; - type AT; - type BT; - - fn expected_alpha_asset(&self) -> &Self::AA; - fn expected_beta_asset(&self) -> &Self::BA; - - fn alpha_ledger_mut(&mut self) -> &mut LedgerState; - fn beta_ledger_mut(&mut self) -> &mut LedgerState; - - /// Returns true if the current swap failed at some stage. - fn swap_failed(&self) -> bool; - - /// An error during swap execution results in this being called. We - /// specifically do not support setting this to `false` because currently a - /// failed swap cannot be restarted. - fn set_swap_failed(&mut self); -} diff --git a/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs b/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs index 3e79e47afd..57f959f287 100644 --- a/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs +++ b/cnd/src/swap_protocols/rfc003/alice/actions/generic_impl.rs @@ -52,17 +52,12 @@ where NotDeployed => vec![Action::Fund(<(AL, AA)>::fund_action( HtlcParams::new_alpha_params(request, response), ))], - IncorrectlyFunded { + Funded { htlc_location, fund_transaction, .. - } => vec![Action::Refund(<(AL, AA)>::refund_action( - HtlcParams::new_alpha_params(request, response), - htlc_location.clone(), - &self.secret_source, - fund_transaction, - ))], - Funded { + } + | IncorrectlyFunded { htlc_location, fund_transaction, .. diff --git a/cnd/src/swap_protocols/rfc003/alice/mod.rs b/cnd/src/swap_protocols/rfc003/alice/mod.rs index a85c19ca2f..da5af4bde5 100644 --- a/cnd/src/swap_protocols/rfc003/alice/mod.rs +++ b/cnd/src/swap_protocols/rfc003/alice/mod.rs @@ -4,7 +4,7 @@ pub use self::actions::*; use crate::{ seed::SwapSeed, - swap_protocols::rfc003::{ledger_state::LedgerState, messages, ActorState, SwapCommunication}, + swap_protocols::rfc003::{ledger_state::LedgerState, messages, SwapCommunication}, }; use derivative::Derivative; @@ -16,48 +16,20 @@ pub struct State { pub beta_ledger_state: LedgerState, #[derivative(Debug = "ignore", PartialEq = "ignore")] pub secret_source: SwapSeed, // Used to derive identities and also to generate the secret. - pub failed: bool, } impl State { - pub fn proposed( - request: messages::Request, + pub fn new( + swap_communication: SwapCommunication, + alpha_ledger_state: LedgerState, + beta_ledger_state: LedgerState, secret_source: SwapSeed, ) -> Self { Self { - swap_communication: SwapCommunication::Proposed { request }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, + swap_communication, + alpha_ledger_state, + beta_ledger_state, secret_source, - failed: false, - } - } - - pub fn accepted( - request: messages::Request, - response: messages::Accept, - secret_source: SwapSeed, - ) -> Self { - Self { - swap_communication: SwapCommunication::Accepted { request, response }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, - secret_source, - failed: false, - } - } - - pub fn declined( - request: messages::Request, - response: messages::Decline, - secret_source: SwapSeed, - ) -> Self { - Self { - swap_communication: SwapCommunication::Declined { request, response }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, - secret_source, - failed: false, } } @@ -65,51 +37,3 @@ impl State ActorState - for State -where - AL: 'static, - BL: 'static, - AA: 'static, - BA: 'static, - AH: 'static, - BH: 'static, - AI: 'static, - BI: 'static, - AT: 'static, - BT: 'static, -{ - type AL = AL; - type BL = BL; - type AA = AA; - type BA = BA; - type AH = AH; - type BH = BH; - type AT = AT; - type BT = BT; - - fn expected_alpha_asset(&self) -> &Self::AA { - &self.swap_communication.request().alpha_asset - } - - fn expected_beta_asset(&self) -> &Self::BA { - &self.swap_communication.request().beta_asset - } - - fn alpha_ledger_mut(&mut self) -> &mut LedgerState { - &mut self.alpha_ledger_state - } - - fn beta_ledger_mut(&mut self) -> &mut LedgerState { - &mut self.beta_ledger_state - } - - fn swap_failed(&self) -> bool { - self.failed - } - - fn set_swap_failed(&mut self) { - self.failed = true; - } -} diff --git a/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs b/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs index 8eef52643f..d414808e9e 100644 --- a/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/bitcoin/htlc_events.rs @@ -18,6 +18,7 @@ use crate::{ transaction, }; use chrono::NaiveDateTime; +use std::cmp::Ordering; use tracing_futures::Instrument; #[async_trait::async_trait] @@ -29,18 +30,28 @@ where { async fn htlc_funded( &self, - _htlc_params: &HtlcParams, + htlc_params: &HtlcParams, htlc_deployment: &Deployed, _start_of_swap: NaiveDateTime, ) -> anyhow::Result> { + let expected_asset = htlc_params.asset; + let tx = &htlc_deployment.transaction; let asset = asset::Bitcoin::from_sat(tx.output[htlc_deployment.location.vout as usize].value); - Ok(Funded { - transaction: tx.clone(), - asset, - }) + let event = match expected_asset.cmp(&asset) { + Ordering::Equal => Funded::Correctly { + transaction: tx.clone(), + asset, + }, + _ => Funded::Incorrectly { + transaction: tx.clone(), + asset, + }, + }; + + Ok(event) } } diff --git a/cnd/src/swap_protocols/rfc003/bob/mod.rs b/cnd/src/swap_protocols/rfc003/bob/mod.rs index 2d38e4cd3b..ed1b11c520 100644 --- a/cnd/src/swap_protocols/rfc003/bob/mod.rs +++ b/cnd/src/swap_protocols/rfc003/bob/mod.rs @@ -1,8 +1,10 @@ pub mod actions; -use crate::swap_protocols::rfc003::{ - ledger_state::LedgerState, messages::Request, Accept, ActorState, Decline, DeriveIdentities, - SwapCommunication, +use crate::{ + seed::SwapSeed, + swap_protocols::rfc003::{ + ledger_state::LedgerState, messages::Request, DeriveIdentities, SwapCommunication, + }, }; use derivative::Derivative; use std::sync::Arc; @@ -15,48 +17,20 @@ pub struct State { pub beta_ledger_state: LedgerState, #[derivative(Debug = "ignore")] pub secret_source: Arc, - pub failed: bool, // Gets set on any error during the execution of a swap. } impl State { - pub fn proposed( - request: Request, - secret_source: impl DeriveIdentities, + pub fn new( + swap_communication: SwapCommunication, + alpha_ledger_state: LedgerState, + beta_ledger_state: LedgerState, + secret_source: SwapSeed, ) -> Self { Self { - swap_communication: SwapCommunication::Proposed { request }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, + swap_communication, + alpha_ledger_state, + beta_ledger_state, secret_source: Arc::new(secret_source), - failed: false, - } - } - - pub fn accepted( - request: Request, - response: Accept, - secret_source: impl DeriveIdentities, - ) -> Self { - Self { - swap_communication: SwapCommunication::Accepted { request, response }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, - secret_source: Arc::new(secret_source), - failed: false, - } - } - - pub fn declined( - request: Request, - response: Decline, - secret_source: impl DeriveIdentities, - ) -> Self { - Self { - swap_communication: SwapCommunication::Declined { request, response }, - alpha_ledger_state: LedgerState::NotDeployed, - beta_ledger_state: LedgerState::NotDeployed, - secret_source: Arc::new(secret_source), - failed: false, } } @@ -68,51 +42,3 @@ impl State ActorState - for State -where - AL: 'static, - BL: 'static, - AA: 'static, - BA: 'static, - AH: 'static, - BH: 'static, - AI: 'static, - BI: 'static, - AT: 'static, - BT: 'static, -{ - type AL = AL; - type BL = BL; - type AA = AA; - type BA = BA; - type AH = AH; - type BH = BH; - type AT = AT; - type BT = BT; - - fn expected_alpha_asset(&self) -> &Self::AA { - &self.swap_communication.request().alpha_asset - } - - fn expected_beta_asset(&self) -> &Self::BA { - &self.swap_communication.request().beta_asset - } - - fn alpha_ledger_mut(&mut self) -> &mut LedgerState { - &mut self.alpha_ledger_state - } - - fn beta_ledger_mut(&mut self) -> &mut LedgerState { - &mut self.beta_ledger_state - } - - fn swap_failed(&self) -> bool { - self.failed - } - - fn set_swap_failed(&mut self) { - self.failed = true; - } -} diff --git a/cnd/src/swap_protocols/rfc003/create_swap.rs b/cnd/src/swap_protocols/rfc003/create_swap.rs index 6a89cda145..660904d72f 100644 --- a/cnd/src/swap_protocols/rfc003/create_swap.rs +++ b/cnd/src/swap_protocols/rfc003/create_swap.rs @@ -1,5 +1,4 @@ use crate::{ - db::AcceptedSwap, swap_protocols::{ rfc003::{ self, @@ -7,10 +6,9 @@ use crate::{ Deployed, Funded, HtlcDeployed, HtlcFunded, HtlcRedeemed, HtlcRefunded, Redeemed, Refunded, }, - Accept, ActorState, Request, SecretHash, + Accept, LedgerState, Request, SecretHash, }, - state_store::Update, - HashFunction, + state, HashFunction, InsertFailedSwap, SwapId, }, timestamp::Timestamp, }; @@ -20,136 +18,47 @@ use genawaiter::{ sync::{Co, Gen}, GeneratorState, }; +use std::sync::Arc; /// Returns a future that tracks the swap negotiated from the given request and -/// accept response on alpha ledger. +/// accept response on a ledger. /// /// The current implementation is naive in the sense that it does not take into /// account situations where it is clear that no more events will happen even /// though in theory, there could. For example: -/// - alpha funded -/// - alpha refunded +/// - funded +/// - refunded /// /// It is highly unlikely for Bob to fund the HTLC now, yet the current /// implementation is still waiting for that. -pub async fn create_alpha_watcher( +pub async fn create_watcher( dependencies: D, - accepted: AcceptedSwap, + ledger_state: Arc, + id: SwapId, + htlc_params: HtlcParams, + accepted_at: NaiveDateTime, ) where - D: Update> - + HtlcFunded - + HtlcFunded - + HtlcDeployed - + HtlcDeployed - + HtlcRedeemed - + HtlcRedeemed - + HtlcRefunded - + HtlcRefunded, - A::AL: Clone, - A::BL: Clone, - A::AA: Ord + Clone, - A::BA: Ord + Clone, - A::AH: Clone, - A::BH: Clone, - AI: Clone, - BI: Clone, - A::AT: Clone, - A::BT: Clone, - A: ActorState + Clone + Send, - AcceptedSwap: Clone, -{ - let (request, accept, at) = accepted; - - let id = request.swap_id; - let swap = OngoingSwap::new(request, accept); - - // construct a generator that watches alpha and beta ledger concurrently - let mut generator = Gen::new({ - |co| async { - watch_alpha_ledger::<_, A::AL, A::BL, A::AA, A::BA, A::AH, A::BH, AI, BI, A::AT, A::BT>( - &dependencies, - co, - swap.alpha_htlc_params(), - at, - ) - .await - } - }); - - loop { - // wait for events to be emitted as the generator executes - match generator.async_resume().await { - // every event that is yielded is passed on - GeneratorState::Yielded(event) => { - tracing::info!("swap {} yielded event {}", id, event); - dependencies.update(&id, event); - } - // the generator stopped executing, this means there are no more events that can be - // watched. - GeneratorState::Complete(Ok(_)) => { - tracing::info!("swap {} finished", id); - return; - } - GeneratorState::Complete(Err(e)) => { - tracing::error!("swap {} failed with {:?}", id, e); - return; - } - } - } -} - -/// Returns a future that tracks the swap negotiated from the given request and -/// accept response on beta ledger. -/// -/// The current implementation is naive in the sense that it does not take into -/// account situations where it is clear that no more events will happen even -/// though in theory, there could. For example: -/// - alpha funded -/// - alpha refunded -/// -/// It is highly unlikely for Bob to fund the HTLC now, yet the current -/// implementation is still waiting for that. -pub async fn create_beta_watcher( - dependencies: D, - accepted: AcceptedSwap, -) where - D: Update> - + HtlcFunded - + HtlcFunded - + HtlcDeployed - + HtlcDeployed - + HtlcRedeemed - + HtlcRedeemed - + HtlcRefunded - + HtlcRefunded, - A::AL: Clone, - A::BL: Clone, - A::AA: Ord + Clone, - A::BA: Ord + Clone, - A::AH: Clone, - A::BH: Clone, - A::AT: Clone, - A::BT: Clone, - AI: Clone, - BI: Clone, - A: ActorState + Clone + Send, - AcceptedSwap: Clone, + D: InsertFailedSwap + + HtlcFunded + + HtlcDeployed + + HtlcRedeemed + + HtlcRefunded, + S: state::Update, SwapEvent> + + state::Insert>, + L: Clone, + A: Ord + Clone, + H: Clone, + I: Clone, + T: Clone, { - let (request, accept, at) = accepted.clone(); - - let id = request.swap_id; - let swap = OngoingSwap::new(request, accept); + ledger_state + .insert(id, LedgerState::::NotDeployed) + .await; // construct a generator that watches alpha and beta ledger concurrently let mut generator = Gen::new({ |co| async { - watch_beta_ledger::<_, A::AL, A::BL, A::AA, A::BA, A::AH, A::BH, AI, BI, A::AT, A::BT>( - &dependencies, - co, - swap.beta_htlc_params(), - at, - ) - .await + watch_ledger::(&dependencies, co, htlc_params, accepted_at).await } }); @@ -159,7 +68,7 @@ pub async fn create_beta_watcher( // every event that is yielded is passed on GeneratorState::Yielded(event) => { tracing::info!("swap {} yielded event {}", id, event); - dependencies.update(&id, event); + ledger_state.update(&id, event).await; } // the generator stopped executing, this means there are no more events that can be // watched. @@ -169,39 +78,40 @@ pub async fn create_beta_watcher( } GeneratorState::Complete(Err(e)) => { tracing::error!("swap {} failed with {:?}", id, e); + dependencies.insert_failed_swap(&id); return; } } } } -/// Returns a future that waits for events on alpha ledger to happen. +/// Returns a future that waits for events to happen on a ledger. /// /// Each event is yielded through the controller handle (co) of the coroutine. -async fn watch_alpha_ledger( +async fn watch_ledger( dependencies: &D, - co: Co>, - htlc_params: HtlcParams, + co: Co>, + htlc_params: HtlcParams, start_of_swap: NaiveDateTime, ) -> anyhow::Result<()> where - D: HtlcFunded - + HtlcDeployed - + HtlcRedeemed - + HtlcRefunded, - Deployed: Clone, - Redeemed: Clone, - Refunded: Clone, + D: HtlcFunded + + HtlcDeployed + + HtlcRedeemed + + HtlcRefunded, + Deployed: Clone, + Redeemed: Clone, + Refunded: Clone, { let deployed = dependencies .htlc_deployed(&htlc_params, start_of_swap) .await?; - co.yield_(SwapEvent::AlphaDeployed(deployed.clone())).await; + co.yield_(SwapEvent::Deployed(deployed.clone())).await; let funded = dependencies .htlc_funded(&htlc_params, &deployed, start_of_swap) .await?; - co.yield_(SwapEvent::AlphaFunded(funded)).await; + co.yield_(SwapEvent::Funded(funded)).await; let redeemed = dependencies.htlc_redeemed(&htlc_params, &deployed, start_of_swap); @@ -209,59 +119,10 @@ where match future::try_select(redeemed, refunded).await { Ok(Either::Left((redeemed, _))) => { - co.yield_(SwapEvent::AlphaRedeemed(redeemed.clone())).await; + co.yield_(SwapEvent::Redeemed(redeemed.clone())).await; } Ok(Either::Right((refunded, _))) => { - co.yield_(SwapEvent::AlphaRefunded(refunded.clone())).await; - } - Err(either) => { - let (error, _other_future) = either.factor_first(); - - return Err(error); - } - } - - Ok(()) -} - -/// Returns a future that waits for events on beta ledger to happen. -/// -/// Each event is yielded through the controller handle (co) of the coroutine. -async fn watch_beta_ledger( - dependencies: &D, - co: Co>, - htlc_params: HtlcParams, - start_of_swap: NaiveDateTime, -) -> anyhow::Result<()> -where - D: HtlcFunded - + HtlcDeployed - + HtlcRedeemed - + HtlcRefunded, - Deployed: Clone, - Redeemed: Clone, - Refunded: Clone, -{ - let deployed = dependencies - .htlc_deployed(&htlc_params, start_of_swap) - .await?; - co.yield_(SwapEvent::BetaDeployed(deployed.clone())).await; - - let funded = dependencies - .htlc_funded(&htlc_params, &deployed, start_of_swap) - .await?; - co.yield_(SwapEvent::BetaFunded(funded)).await; - - let redeemed = dependencies.htlc_redeemed(&htlc_params, &deployed, start_of_swap); - - let refunded = dependencies.htlc_refunded(&htlc_params, &deployed, start_of_swap); - - match future::try_select(redeemed, refunded).await { - Ok(Either::Left((redeemed, _))) => { - co.yield_(SwapEvent::BetaRedeemed(redeemed.clone())).await; - } - Ok(Either::Right((refunded, _))) => { - co.yield_(SwapEvent::BetaRefunded(refunded.clone())).await; + co.yield_(SwapEvent::Refunded(refunded.clone())).await; } Err(either) => { let (error, _other_future) = either.factor_first(); @@ -390,16 +251,11 @@ where } #[derive(Debug, Clone, PartialEq, strum_macros::Display)] -pub enum SwapEvent { - AlphaDeployed(Deployed), - AlphaFunded(Funded), - AlphaRedeemed(Redeemed), - AlphaRefunded(Refunded), - - BetaDeployed(Deployed), - BetaFunded(Funded), - BetaRedeemed(Redeemed), - BetaRefunded(Refunded), +pub enum SwapEvent { + Deployed(Deployed), + Funded(Funded), + Redeemed(Redeemed), + Refunded(Refunded), } #[cfg(test)] @@ -409,20 +265,16 @@ mod tests { #[test] fn swap_event_should_render_to_nice_string() { - let event = SwapEvent::< - asset::Bitcoin, - asset::Ether, - htlc_location::Bitcoin, - htlc_location::Ethereum, - transaction::Bitcoin, - transaction::Ethereum, - >::BetaDeployed(Deployed { - location: htlc_location::Ethereum::default(), - transaction: transaction::Ethereum::default(), - }); + let event = + SwapEvent::::Deployed( + Deployed { + location: htlc_location::Ethereum::default(), + transaction: transaction::Ethereum::default(), + }, + ); let formatted = format!("{}", event); - assert_eq!(formatted, "BetaDeployed") + assert_eq!(formatted, "Deployed") } } diff --git a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs index ab0c0cac6c..63bd684da1 100644 --- a/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs +++ b/cnd/src/swap_protocols/rfc003/ethereum/htlc_events.rs @@ -20,6 +20,7 @@ use crate::{ transaction, }; use chrono::NaiveDateTime; +use std::cmp::Ordering; use tracing_futures::Instrument; lazy_static::lazy_static! { @@ -41,14 +42,26 @@ impl { async fn htlc_funded( &self, - _htlc_params: &HtlcParams, + htlc_params: &HtlcParams, deploy_transaction: &Deployed, _start_of_swap: NaiveDateTime, ) -> anyhow::Result> { - Ok(Funded { - asset: Ether::from_wei(deploy_transaction.transaction.value), - transaction: deploy_transaction.transaction.clone(), - }) + let expected_asset = &htlc_params.asset; + + let asset = Ether::from_wei(deploy_transaction.transaction.value); + + let event = match expected_asset.cmp(&asset) { + Ordering::Equal => Funded::Correctly { + transaction: deploy_transaction.transaction.clone(), + asset, + }, + _ => Funded::Incorrectly { + transaction: deploy_transaction.transaction.clone(), + asset, + }, + }; + + Ok(event) } } @@ -173,10 +186,17 @@ impl .instrument(tracing::info_span!("htlc_funded")) .await?; + let expected_asset = &htlc_params.asset; + let quantity = Erc20Quantity::from_wei(U256::from_big_endian(log.data.0.as_ref())); let asset = Erc20::new(log.address, quantity); - Ok(Funded { asset, transaction }) + let event = match expected_asset.cmp(&asset) { + Ordering::Equal => Funded::Correctly { transaction, asset }, + _ => Funded::Incorrectly { transaction, asset }, + }; + + Ok(event) } } diff --git a/cnd/src/swap_protocols/rfc003/events/mod.rs b/cnd/src/swap_protocols/rfc003/events/mod.rs index 30967e9b52..b5cb439b45 100644 --- a/cnd/src/swap_protocols/rfc003/events/mod.rs +++ b/cnd/src/swap_protocols/rfc003/events/mod.rs @@ -3,9 +3,9 @@ use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] -pub struct Funded { - pub asset: A, - pub transaction: T, +pub enum Funded { + Correctly { asset: A, transaction: T }, + Incorrectly { asset: A, transaction: T }, } #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] diff --git a/cnd/src/swap_protocols/rfc003/ledger_state.rs b/cnd/src/swap_protocols/rfc003/ledger_state.rs index 5efcd02619..49b3ff11f1 100644 --- a/cnd/src/swap_protocols/rfc003/ledger_state.rs +++ b/cnd/src/swap_protocols/rfc003/ledger_state.rs @@ -23,25 +23,25 @@ pub enum LedgerState { fund_transaction: T, asset: A, }, - Redeemed { + IncorrectlyFunded { htlc_location: H, deploy_transaction: T, fund_transaction: T, - redeem_transaction: T, asset: A, - secret: Secret, }, - Refunded { + Redeemed { htlc_location: H, deploy_transaction: T, fund_transaction: T, - refund_transaction: T, + redeem_transaction: T, asset: A, + secret: Secret, }, - IncorrectlyFunded { + Refunded { htlc_location: H, deploy_transaction: T, fund_transaction: T, + refund_transaction: T, asset: A, }, } @@ -65,39 +65,28 @@ impl LedgerState { } pub fn transition_to_funded(&mut self, funded: Funded) { - let Funded { transaction, asset } = funded; - match std::mem::replace(self, LedgerState::NotDeployed) { LedgerState::Deployed { deploy_transaction, htlc_location, - } => { - *self = LedgerState::Funded { - deploy_transaction, - htlc_location, - fund_transaction: transaction, - asset, + } => match funded { + Funded::Correctly { asset, transaction } => { + *self = LedgerState::Funded { + deploy_transaction, + htlc_location, + fund_transaction: transaction, + asset, + } } - } - other => panic!("expected state Deployed, got {}", HtlcState::from(other)), - } - } - - pub fn transition_to_incorrectly_funded(&mut self, funded: Funded) { - let Funded { transaction, asset } = funded; - - match std::mem::replace(self, LedgerState::NotDeployed) { - LedgerState::Deployed { - deploy_transaction, - htlc_location, - } => { - *self = LedgerState::IncorrectlyFunded { - deploy_transaction, - htlc_location, - fund_transaction: transaction, - asset, + Funded::Incorrectly { asset, transaction } => { + *self = LedgerState::IncorrectlyFunded { + deploy_transaction, + htlc_location, + fund_transaction: transaction, + asset, + } } - } + }, other => panic!("expected state Deployed, got {}", HtlcState::from(other)), } } @@ -173,9 +162,9 @@ impl quickcheck::Arbitrary for HtlcState { 0 => HtlcState::NotDeployed, 1 => HtlcState::Deployed, 2 => HtlcState::Funded, - 3 => HtlcState::Redeemed, - 4 => HtlcState::Refunded, - 5 => HtlcState::IncorrectlyFunded, + 3 => HtlcState::IncorrectlyFunded, + 4 => HtlcState::Redeemed, + 5 => HtlcState::Refunded, _ => unreachable!(), } } diff --git a/cnd/src/swap_protocols/rfc003/mod.rs b/cnd/src/swap_protocols/rfc003/mod.rs index 8a4e926539..020e89a6ec 100644 --- a/cnd/src/swap_protocols/rfc003/mod.rs +++ b/cnd/src/swap_protocols/rfc003/mod.rs @@ -8,12 +8,10 @@ pub mod ledger_state; pub mod messages; pub mod actions; -mod actor_state; mod secret; pub use self::{ - actor_state::ActorState, - create_swap::create_alpha_watcher, + create_swap::create_watcher, ledger_state::{HtlcState, LedgerState}, secret::{FromErr, Secret, SecretHash}, }; diff --git a/cnd/src/swap_protocols/state.rs b/cnd/src/swap_protocols/state.rs new file mode 100644 index 0000000000..6ce3469777 --- /dev/null +++ b/cnd/src/swap_protocols/state.rs @@ -0,0 +1,17 @@ +use crate::swap_protocols::swap_id::SwapId; +use async_trait::async_trait; + +#[async_trait] +pub trait Insert: Send + Sync + 'static { + async fn insert(&self, key: SwapId, value: S); +} + +#[async_trait] +pub trait Get: Send + Sync + 'static { + async fn get(&self, key: &SwapId) -> anyhow::Result>; +} + +#[async_trait] +pub trait Update: Send + Sync + 'static { + async fn update(&self, key: &SwapId, update: E); +} diff --git a/cnd/src/swap_protocols/state_store.rs b/cnd/src/swap_protocols/state_store.rs deleted file mode 100644 index 60dc361872..0000000000 --- a/cnd/src/swap_protocols/state_store.rs +++ /dev/null @@ -1,212 +0,0 @@ -use crate::swap_protocols::{ - rfc003::{create_swap::SwapEvent, ActorState}, - swap_id::SwapId, -}; -use std::{any::Any, cmp::Ordering, collections::HashMap, sync::Mutex}; - -#[derive(Debug, Clone, Copy, thiserror::Error)] -pub enum Error { - #[error("invalid type")] - InvalidType, -} - -#[allow(clippy::type_complexity)] -pub trait Insert: Send + Sync + 'static { - fn insert(&self, key: SwapId, value: S); -} - -#[allow(clippy::type_complexity)] -pub trait Get: Send + Sync + 'static { - fn get(&self, key: &SwapId) -> Result, Error>; -} - -#[allow(clippy::type_complexity)] -pub trait Update: Send + Sync + 'static { - fn update(&self, key: &SwapId, update: E); -} - -#[derive(Default, Debug)] -pub struct InMemoryStateStore { - states: Mutex>>, -} - -impl Insert for InMemoryStateStore -where - S: Send + 'static, -{ - fn insert(&self, key: SwapId, value: S) { - let mut states = self.states.lock().unwrap(); - states.insert(key, Box::new(value)); - } -} - -impl Get for InMemoryStateStore -where - S: Clone + Send + 'static, -{ - fn get(&self, key: &SwapId) -> Result, Error> { - let states = self.states.lock().unwrap(); - match states.get(key) { - Some(state) => match state.downcast_ref::() { - Some(state) => Ok(Some(state.clone())), - None => Err(Error::InvalidType), - }, - None => Ok(None), - } - } -} - -impl Update> for InMemoryStateStore -where - S: ActorState + Send, - S::AA: Ord, - S::BA: Ord, -{ - #[allow(clippy::type_complexity)] - fn update(&self, key: &SwapId, event: SwapEvent) { - let mut states = self.states.lock().unwrap(); - let actor_state = match states - .get_mut(key) - .and_then(|state| state.downcast_mut::()) - { - Some(state) => state, - None => { - tracing::warn!("Value not found for key {}", key); - return; - } - }; - - match event { - SwapEvent::AlphaDeployed(deployed) => actor_state - .alpha_ledger_mut() - .transition_to_deployed(deployed), - SwapEvent::AlphaFunded(funded) => { - let expected_asset = actor_state.expected_alpha_asset(); - - match expected_asset.cmp(&funded.asset) { - Ordering::Equal => actor_state.alpha_ledger_mut().transition_to_funded(funded), - _ => actor_state - .alpha_ledger_mut() - .transition_to_incorrectly_funded(funded), - } - } - SwapEvent::AlphaRedeemed(redeemed) => { - // what if redeemed.secret.hash() != secret_hash in request ?? - - actor_state - .alpha_ledger_mut() - .transition_to_redeemed(redeemed); - } - SwapEvent::AlphaRefunded(refunded) => actor_state - .alpha_ledger_mut() - .transition_to_refunded(refunded), - SwapEvent::BetaDeployed(deployed) => actor_state - .beta_ledger_mut() - .transition_to_deployed(deployed), - SwapEvent::BetaFunded(funded) => { - let expected_asset = actor_state.expected_beta_asset(); - - match expected_asset.cmp(&funded.asset) { - Ordering::Equal => actor_state.beta_ledger_mut().transition_to_funded(funded), - _ => actor_state - .beta_ledger_mut() - .transition_to_incorrectly_funded(funded), - } - } - SwapEvent::BetaRedeemed(redeemed) => { - actor_state - .beta_ledger_mut() - .transition_to_redeemed(redeemed); - } - SwapEvent::BetaRefunded(refunded) => actor_state - .beta_ledger_mut() - .transition_to_refunded(refunded), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - asset::{self, ethereum::FromWei}, - ethereum::Address, - htlc_location, identity, - seed::{DeriveSwapSeed, RootSeed}, - swap_protocols::{ - ledger::{bitcoin, Ethereum}, - rfc003::{alice, messages::Request, Accept, Secret}, - HashFunction, - }, - timestamp::Timestamp, - transaction, - }; - use spectral::prelude::*; - use std::str::FromStr; - - #[test] - fn insert_and_get_state() { - let state_store = InMemoryStateStore::default(); - - let bitcoin_pub_key = identity::Bitcoin::from_str( - "02c2a8efce029526d364c2cf39d89e3cdda05e5df7b2cbfc098b4e3d02b70b5275", - ) - .unwrap(); - let ethereum_address = - Address::from_str("8457037fcd80a8650c4692d7fcfc1d0a96b92867").unwrap(); - - let request = Request { - swap_id: SwapId::default(), - alpha_ledger: bitcoin::Regtest {}, - beta_ledger: Ethereum::default(), - alpha_asset: asset::Bitcoin::from_sat(100_000_000), - beta_asset: asset::Ether::from_wei(10_000_000_000_000_000_000u64), - hash_function: HashFunction::Sha256, - alpha_ledger_refund_identity: bitcoin_pub_key, - beta_ledger_redeem_identity: ethereum_address, - alpha_expiry: Timestamp::from(2_000_000_000), - beta_expiry: Timestamp::from(2_000_000_000), - secret_hash: Secret::from(*b"hello world, you are beautiful!!").hash(), - }; - let accept = Accept { - swap_id: SwapId::default(), - beta_ledger_refund_identity: ethereum_address, - alpha_ledger_redeem_identity: bitcoin_pub_key, - }; - - let id = SwapId::default(); - let seed = RootSeed::from(*b"hello world, you are beautiful!!"); - let secret_source = seed.derive_swap_seed(id); - let state: alice::State< - bitcoin::Regtest, - Ethereum, - asset::Bitcoin, - asset::Ether, - htlc_location::Bitcoin, - htlc_location::Ethereum, - identity::Bitcoin, - identity::Ethereum, - transaction::Bitcoin, - transaction::Ethereum, - > = alice::State::accepted(request, accept, secret_source); - - state_store.insert(id, state.clone()); - - #[allow(clippy::type_complexity)] - let res: Option< - alice::State< - bitcoin::Regtest, - Ethereum, - asset::Bitcoin, - asset::Ether, - htlc_location::Bitcoin, - htlc_location::Ethereum, - identity::Bitcoin, - identity::Ethereum, - transaction::Bitcoin, - transaction::Ethereum, - >, - > = state_store.get(&id).unwrap(); - assert_that(&res).contains_value(&state); - } -} diff --git a/cnd/src/swap_protocols/swap_communication_states.rs b/cnd/src/swap_protocols/swap_communication_states.rs new file mode 100644 index 0000000000..c703d7a1dc --- /dev/null +++ b/cnd/src/swap_protocols/swap_communication_states.rs @@ -0,0 +1,40 @@ +use crate::swap_protocols::{ + state::{Get, Insert}, + swap_id::SwapId, +}; +use async_trait::async_trait; +use std::{any::Any, clone::Clone, collections::HashMap}; +use tokio::sync::Mutex; + +#[derive(Default, Debug)] +pub struct SwapCommunicationStates { + states: Mutex>>, +} + +#[async_trait] +impl Insert for SwapCommunicationStates +where + S: Send + 'static, +{ + async fn insert(&self, key: SwapId, value: S) { + let mut states = self.states.lock().await; + states.insert(key, Box::new(value)); + } +} + +#[async_trait] +impl Get for SwapCommunicationStates +where + S: Clone + Send + 'static, +{ + async fn get(&self, key: &SwapId) -> anyhow::Result> { + let states = self.states.lock().await; + match states.get(key) { + Some(state) => match state.downcast_ref::() { + Some(state) => Ok(Some(state.clone())), + None => Err(anyhow::anyhow!("invalid type")), + }, + None => Ok(None), + } + } +} diff --git a/cnd/src/swap_protocols/swap_error_states.rs b/cnd/src/swap_protocols/swap_error_states.rs new file mode 100644 index 0000000000..827184060e --- /dev/null +++ b/cnd/src/swap_protocols/swap_error_states.rs @@ -0,0 +1,25 @@ +use crate::swap_protocols::swap_id::SwapId; +use async_trait::async_trait; +use std::collections::HashMap; +use tokio::sync::Mutex; + +#[derive(Default, Debug)] +pub struct SwapErrorStates(Mutex>); + +impl SwapErrorStates { + pub async fn has_failed(&self, id: &SwapId) -> bool { + *self.0.lock().await.get(id).unwrap_or(&false) + } +} + +#[async_trait] +pub trait InsertFailedSwap { + async fn insert_failed_swap(&self, id: &SwapId); +} + +#[async_trait] +impl InsertFailedSwap for SwapErrorStates { + async fn insert_failed_swap(&self, id: &SwapId) { + let _ = self.0.lock().await.insert(*id, true); + } +} From f8bbb43254e36b62d23d62371d62c34db48c7285 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2020 14:12:46 +0000 Subject: [PATCH 097/145] Bump ethbloom from 0.8.1 to 0.9.0 Bumps [ethbloom](https://github.com/paritytech/parity-common) from 0.8.1 to 0.9.0. - [Release notes](https://github.com/paritytech/parity-common/releases) - [Commits](https://github.com/paritytech/parity-common/compare/ethbloom-0.8.1...ethbloom-v0.9.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 49 +++++++++++++++++++++---------------------------- cnd/Cargo.toml | 2 +- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4995557b4f..6faa5b0d5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,7 +389,7 @@ dependencies = [ "regex", "serde", "serde_json", - "tiny-keccak 2.0.1", + "tiny-keccak", ] [[package]] @@ -580,7 +580,7 @@ dependencies = [ "tempfile", "testcontainers", "thiserror", - "tiny-keccak 2.0.1", + "tiny-keccak", "tokio", "toml", "tracing", @@ -930,15 +930,15 @@ dependencies = [ [[package]] name = "ethbloom" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cfe1c169414b709cf28aa30c74060bdb830a03a8ba473314d079ac79d80a5f" +checksum = "9e7abcddbdd5db30aeed4deb586adc4824e6c247e2f7238d1187f752893f096b" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.6.0", "impl-rlp", - "impl-serde 0.2.3", - "tiny-keccak 1.5.0", + "impl-serde", + "tiny-keccak", ] [[package]] @@ -964,7 +964,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" dependencies = [ "byteorder 1.3.4", - "libc", + "rand 0.7.3", + "rustc-hex", + "static_assertions 1.1.0", +] + +[[package]] +name = "fixed-hash" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32529fc42e86ec06e5047092082aab9ad459b070c5d2a76b14f4f5ce70bf2e84" +dependencies = [ + "byteorder 1.3.4", "rand 0.7.3", "rustc-hex", "static_assertions 1.1.0", @@ -1504,15 +1515,6 @@ dependencies = [ "rlp", ] -[[package]] -name = "impl-serde" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e3cae7e99c7ff5a995da2cf78dd0a5383740eda71d98cf7b1910c301ac69b8" -dependencies = [ - "serde", -] - [[package]] name = "impl-serde" version = "0.3.0" @@ -2739,9 +2741,9 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" dependencies = [ - "fixed-hash", + "fixed-hash 0.5.2", "impl-codec", - "impl-serde 0.3.0", + "impl-serde", "uint", ] @@ -3698,15 +3700,6 @@ dependencies = [ "winapi 0.3.8", ] -[[package]] -name = "tiny-keccak" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" -dependencies = [ - "crunchy", -] - [[package]] name = "tiny-keccak" version = "2.0.1" diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index b661ac8795..4c73998e5b 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -20,7 +20,7 @@ diesel_migrations = "1.4.0" digest = { path = "../digest" } digest-macro-derive = { path = "../digest-macro-derive" } directories = "2.0" -ethbloom = "0.8.1" +ethbloom = "0.9.0" fern = { version = "0.6", features = ["colored"] } futures = { version = "0.3", features = ["async-await"], default-features = false } genawaiter = "0.99" From 981f3900c28f7c31dbf1f0a6e2c95836507bbeaa Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 17 Mar 2020 15:38:35 +0000 Subject: [PATCH 098/145] Bump primitive-types from 0.6.2 to 0.7.0 Bumps [primitive-types](https://github.com/paritytech/parity-common) from 0.6.2 to 0.7.0. - [Release notes](https://github.com/paritytech/parity-common/releases) - [Commits](https://github.com/paritytech/parity-common/compare/primitive-types-v0.6.2...primitive-types-v0.7.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 20 ++++---------------- cnd/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6faa5b0d5f..8a4700b396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -935,7 +935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e7abcddbdd5db30aeed4deb586adc4824e6c247e2f7238d1187f752893f096b" dependencies = [ "crunchy", - "fixed-hash 0.6.0", + "fixed-hash", "impl-rlp", "impl-serde", "tiny-keccak", @@ -957,18 +957,6 @@ dependencies = [ "log 0.4.8", ] -[[package]] -name = "fixed-hash" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3367952ceb191f4ab95dd5685dc163ac539e36202f9fcfd0cb22f9f9c542fefc" -dependencies = [ - "byteorder 1.3.4", - "rand 0.7.3", - "rustc-hex", - "static_assertions 1.1.0", -] - [[package]] name = "fixed-hash" version = "0.6.0" @@ -2737,11 +2725,11 @@ checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" [[package]] name = "primitive-types" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4336f4f5d5524fa60bcbd6fe626f9223d8142a50e7053e979acdf0da41ab975" +checksum = "e5e4b9943a2da369aec5e96f7c10ebc74fcf434d39590d974b0a3460e6f67fbb" dependencies = [ - "fixed-hash 0.5.2", + "fixed-hash", "impl-codec", "impl-serde", "uint", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 4c73998e5b..1462b513a9 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -36,7 +36,7 @@ lru = "0.4.3" num = "0.2" paste = "0.1" pem = "0.7" -primitive-types = { version = "0.6.2", features = ["serde"] } +primitive-types = { version = "0.7.0", features = ["serde"] } rand = "0.7" reqwest = { version = "0.10", default-features = false, features = ["json", "native-tls"] } serde = { version = "1", features = ["derive"] } From 737e15a9a7fbb77bf1f11526338d9453de8bdba9 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 18 Mar 2020 09:33:33 +1100 Subject: [PATCH 099/145] Introduce `IntoDigestInput` trait and make `FieldDigest` sealed --- digest/src/lib.rs | 32 ++++++++++++----------- digest/tests/swap_digest.rs | 52 +++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 3a3e544a0c..3db5b43f5d 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -12,39 +12,41 @@ pub trait Digest { fn digest(self) -> Multihash; } -pub trait FieldDigest { +pub trait IntoDigestInput { + fn into_digest_input(self) -> Vec; +} + +#[doc(hidden)] +pub trait FieldDigest: private::Sealed { fn field_digest(self, prefix: Vec) -> Multihash; } -impl FieldDigest for T +impl IntoDigestInput for T where T: Digest, { - fn field_digest(self, prefix: Vec) -> Multihash { - let mut bytes = prefix; + fn into_digest_input(self) -> Vec { let field_digest = self.digest(); - bytes.append(&mut field_digest.into_bytes()); - digest(&bytes) + field_digest.into_bytes() } } -impl FieldDigest for String { +impl FieldDigest for T +where + T: IntoDigestInput, +{ fn field_digest(self, prefix: Vec) -> Multihash { let mut bytes = prefix; - // String::into_bytes return the bytes for UTF-8 encoding - let mut value = self.into_bytes(); + let mut value = self.into_digest_input(); bytes.append(&mut value); digest(&bytes) } } -impl FieldDigest for Vec { - fn field_digest(mut self, prefix: Vec) -> Multihash { - let mut bytes = prefix; - bytes.append(&mut self); +mod private { + pub trait Sealed {} - digest(&self) - } + impl Sealed for T where T: super::IntoDigestInput {} } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index b2b1cd05c7..b5edd980e8 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,18 +1,32 @@ -use digest::{digest, Digest, DigestMacro, FieldDigest}; +use digest::{digest, Digest, DigestMacro, FieldDigest, IntoDigestInput}; use digest::multihash::Multihash; +struct MyString(String); + +impl IntoDigestInput for MyString { + fn into_digest_input(self) -> Vec { + self.0.into_bytes() + } +} + +impl From<&str> for MyString { + fn from(str: &str) -> MyString { + MyString(str.to_owned()) + } +} + #[derive(DigestMacro)] struct DoubleFieldStruct { #[digest_prefix = "0011"] - foo: String, + foo: MyString, #[digest_prefix = "FFAA"] - bar: String, + bar: MyString, } struct OtherDoubleFieldStruct { - bar: String, - foo: String, + bar: MyString, + foo: MyString, } impl Digest for OtherDoubleFieldStruct { @@ -62,13 +76,13 @@ impl Digest for OtherEnum { #[derive(DigestMacro)] struct NestedStruct { #[digest_prefix = "0011"] - foo: String, + foo: MyString, #[digest_prefix = "AA00"] nest: DoubleFieldStruct, } struct OtherNestedStruct { - foo: String, + foo: MyString, nest: OtherDoubleFieldStruct, } @@ -93,8 +107,8 @@ impl Digest for OtherNestedStruct { #[test] fn given_same_strings_return_same_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("simple string"); + let str1: MyString = "simple string".into(); + let str2: MyString = "simple string".into(); assert_eq!( str1.field_digest("foo".into()), @@ -104,8 +118,8 @@ fn given_same_strings_return_same_multihash() { #[test] fn given_same_strings_different_names_return_diff_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("simple string"); + let str1: MyString = "simple string".into(); + let str2: MyString = "simple string".into(); assert_ne!( str1.field_digest("foo".into()), @@ -115,8 +129,8 @@ fn given_same_strings_different_names_return_diff_multihash() { #[test] fn given_different_strings_return_different_multihash() { - let str1 = String::from("simple string"); - let str2 = String::from("longer string."); + let str1: MyString = "simple string".into(); + let str2: MyString = "longer string".into(); assert_ne!( str1.field_digest("foo".into()), @@ -177,17 +191,17 @@ fn given_two_enums_with_same_bytes_per_variant_return_same_multihash() { #[test] fn given_two_nested_structs_with_same_value_return_same_multihash() { let struct1 = NestedStruct { - foo: "foo".to_string(), + foo: "foo".into(), nest: DoubleFieldStruct { - foo: "phou".to_string(), - bar: "pub".to_string(), + foo: "phou".into(), + bar: "pub".into(), }, }; let struct2 = OtherNestedStruct { - foo: "foo".to_string(), + foo: "foo".into(), nest: OtherDoubleFieldStruct { - foo: "phou".to_string(), - bar: "pub".to_string(), + foo: "phou".into(), + bar: "pub".into(), }, }; From 78daae4a5a91eba10bad7a91852c82ea72bdd5d0 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 15:42:21 +1100 Subject: [PATCH 100/145] Add test for enum --- digest/tests/swap_digest.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index b5edd980e8..68a4c93d5a 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -56,7 +56,6 @@ enum Enum { Bar, } -#[allow(dead_code)] enum OtherEnum { Foo, Bar, @@ -188,6 +187,14 @@ fn given_two_enums_with_same_bytes_per_variant_return_same_multihash() { assert_eq!(enum1.digest(), enum2.digest()) } +#[test] +fn given_two_enums_with_differnt_variant_return_different_multihash() { + let enum1 = Enum::Foo; + let enum2 = OtherEnum::Bar; + + assert_eq!(enum1.digest(), enum2.digest()) +} + #[test] fn given_two_nested_structs_with_same_value_return_same_multihash() { let struct1 = NestedStruct { From 8ef0420feaa2f57d9399067c1d4bcbd424fa3dba Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 16:32:04 +1100 Subject: [PATCH 101/145] Add support for enums with tuples --- digest-macro-derive/src/lib.rs | 34 ++++++++++++++++++++--- digest/tests/swap_digest.rs | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 8f4a691d22..d5334ddbc0 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -53,11 +53,34 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { gen.into() } Data::Enum(data) => { - let idents = data.variants.iter().map(|variant| &variant.ident); + let unit_variant_idents = data + .variants + .iter() + .filter(|variant| variant.fields.is_empty()) + .map(|variant| &variant.ident); + + let unit_variant_bytes = data + .variants + .iter() + .filter(|variant| variant.fields.is_empty()) + .map(|variant| attr_to_bytes(&variant.attrs)); + + let tuple_variant_idents = data + .variants + .iter() + .filter(|variant| match variant.fields { + Fields::Unnamed(_) => true, + _ => false, + }) + .map(|variant| &variant.ident); - let bytes = data + let tuple_variant_bytes = data .variants .iter() + .filter(|variant| match variant.fields { + Fields::Unnamed(_) => true, + _ => false, + }) .map(|variant| attr_to_bytes(&variant.attrs)); let gen = quote! { @@ -65,7 +88,12 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { { fn digest(self) -> Multihash { let bytes = match self { - #(Self::#idents => #bytes.to_vec()),* + #(Self::#unit_variant_idents => #unit_variant_bytes.to_vec()),*, + #(Self::#tuple_variant_idents(data) => { + let mut bytes = #tuple_variant_bytes.to_vec(); + bytes.append(&mut data.digest().into_bytes()); + bytes + }),* }; digest(&bytes) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 68a4c93d5a..6974ceeb33 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -104,6 +104,35 @@ impl Digest for OtherNestedStruct { } } +#[derive(DigestMacro)] +enum NestedEnum { + #[digest_prefix = "DEAD"] + Foo, + #[digest_prefix = "BEEF"] + Bar(NestedStruct), +} + +#[allow(dead_code)] +enum OtherNestedEnum { + Foo, + Bar(OtherNestedStruct), +} + +impl Digest for OtherNestedEnum { + fn digest(self) -> Multihash { + let bytes = match self { + OtherNestedEnum::Foo => vec![0xDEu8, 0xADu8], + OtherNestedEnum::Bar(other_nested_struct) => { + let mut bytes = vec![0xBEu8, 0xEFu8]; + bytes.append(&mut other_nested_struct.digest().into_bytes()); + bytes + } + }; + + digest(&bytes) + } +} + #[test] fn given_same_strings_return_same_multihash() { let str1: MyString = "simple string".into(); @@ -214,3 +243,23 @@ fn given_two_nested_structs_with_same_value_return_same_multihash() { assert_eq!(struct1.digest(), struct2.digest()) } + +#[test] +fn given_two_nested_enums_with_same_value_return_same_multihash() { + let enum1 = NestedEnum::Bar(NestedStruct { + foo: "foo".into(), + nest: DoubleFieldStruct { + foo: "faa".into(), + bar: "restaurant".into(), + }, + }); + let enum2 = OtherNestedEnum::Bar(OtherNestedStruct { + foo: "foo".into(), + nest: OtherDoubleFieldStruct { + foo: "faa".into(), + bar: "restaurant".into(), + }, + }); + + assert_eq!(enum1.digest(), enum2.digest()); +} From e3b9918bbd523033cad93ea67ef74aaa6693dca1 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 16:32:30 +1100 Subject: [PATCH 102/145] Add test for nested struct --- digest/tests/swap_digest.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 6974ceeb33..571c944188 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -244,6 +244,26 @@ fn given_two_nested_structs_with_same_value_return_same_multihash() { assert_eq!(struct1.digest(), struct2.digest()) } +#[test] +fn given_two_nested_structs_with_diff_value_return_diff_multihash() { + let struct1 = NestedStruct { + foo: "phou".into(), + nest: DoubleFieldStruct { + foo: "foo".into(), + bar: "pub".into(), + }, + }; + let struct2 = OtherNestedStruct { + foo: "phou".into(), + nest: OtherDoubleFieldStruct { + foo: "foo".into(), + bar: "pub".into(), + }, + }; + + assert_eq!(struct1.digest(), struct2.digest()) +} + #[test] fn given_two_nested_enums_with_same_value_return_same_multihash() { let enum1 = NestedEnum::Bar(NestedStruct { From c049d83dbdf265dd74ae2f1b472524335015ae7e Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 18 Mar 2020 09:35:06 +1100 Subject: [PATCH 103/145] Rename macro to `Digest` --- digest-macro-derive/src/lib.rs | 2 +- digest/src/lib.rs | 2 +- digest/tests/swap_digest.rs | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index d5334ddbc0..40ad6bd7c1 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -5,7 +5,7 @@ use proc_macro2::{Delimiter, Group, Punct, Spacing}; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{Attribute, Data, Fields, Lit, Meta}; -#[proc_macro_derive(DigestMacro, attributes(digest_prefix))] +#[proc_macro_derive(Digest, attributes(digest_prefix))] pub fn digest_macro_fn(input: TokenStream) -> TokenStream { let ast = syn::parse(input).unwrap(); impl_digest_macro(&ast) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 3db5b43f5d..f1a2f8646a 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,4 +1,4 @@ -pub use digest_macro_derive::DigestMacro; +pub use digest_macro_derive::Digest; pub use hex; pub use multihash; diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 571c944188..41aade2d8f 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,4 +1,4 @@ -use digest::{digest, Digest, DigestMacro, FieldDigest, IntoDigestInput}; +use digest::{digest, Digest, FieldDigest, IntoDigestInput}; use digest::multihash::Multihash; @@ -16,7 +16,7 @@ impl From<&str> for MyString { } } -#[derive(DigestMacro)] +#[derive(Digest)] struct DoubleFieldStruct { #[digest_prefix = "0011"] foo: MyString, @@ -48,7 +48,7 @@ impl Digest for OtherDoubleFieldStruct { } } -#[derive(DigestMacro)] +#[derive(Digest)] enum Enum { #[digest_prefix = "0011"] Foo, @@ -72,7 +72,7 @@ impl Digest for OtherEnum { } } -#[derive(DigestMacro)] +#[derive(Digest)] struct NestedStruct { #[digest_prefix = "0011"] foo: MyString, @@ -104,7 +104,7 @@ impl Digest for OtherNestedStruct { } } -#[derive(DigestMacro)] +#[derive(Digest)] enum NestedEnum { #[digest_prefix = "DEAD"] Foo, From 791d56cc150e8077606768398cf187ec199cacf4 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 18 Mar 2020 09:37:13 +1100 Subject: [PATCH 104/145] Use absolute path and import multihash So that consumer does not have to do it. --- digest-macro-derive/src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 40ad6bd7c1..261d0de7ad 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -35,7 +35,9 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { impl ::digest::Digest for #name where #(#types: ::digest::FieldDigest),* { - fn digest(self) -> Multihash { + fn digest(self) -> ::multihash::Multihash { + use ::digest::FieldDigest; + let mut digests = vec![]; #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* @@ -46,7 +48,7 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { res }); - digest(&res) + ::digest::digest(&res) } } }; @@ -86,7 +88,7 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl ::digest::Digest for #name { - fn digest(self) -> Multihash { + fn digest(self) -> ::multihash::Multihash { let bytes = match self { #(Self::#unit_variant_idents => #unit_variant_bytes.to_vec()),*, #(Self::#tuple_variant_idents(data) => { @@ -96,7 +98,7 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { }),* }; - digest(&bytes) + ::digest::digest(&bytes) } } }; From 2a7e3a9e4b1739c085224d63ddd35d995a2e09ea Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 17 Mar 2020 15:03:50 +1100 Subject: [PATCH 105/145] Document digest trait --- digest/src/lib.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/digest/src/lib.rs b/digest/src/lib.rs index f1a2f8646a..5309c6da5e 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,3 +1,52 @@ +/// This crate brings two traits: `Digest` and `FieldDigest` +/// +/// `Digest` should be implemented on data structures using the `Digest` +/// derive macro. +/// The attribute `digest_prefix` must be applied on each field. It plays the +/// role of an identifier to ensure that fields with same data but different +/// meaning do not result to the same digest. +/// +/// Elementary data types should implement `IntoDigestInput`, this allows you to +/// control how the data is transformed to a byte array. +/// +/// ``` +/// use digest::{Digest, IntoDigestInput}; +/// +/// struct MyType(Vec); +/// +/// impl IntoDigestInput for MyType { +/// fn into_digest_input(self) -> Vec { +/// self.0 +/// } +/// } +/// +/// #[derive(Digest)] +/// struct MyStruct { +/// #[digest_prefix = "00AA"] +/// foo: MyType, +/// #[digest_prefix = "1122"] +/// bar: MyType, +/// } +/// ``` +/// +/// The digest algorithm goes as follow: +/// 1. Compute `field_digest(prefix)` for all fields of the struct, +/// 2. Lexically order the field digests, +/// 3. Concatenate the result, +/// 4. Hash the result. +/// +/// The field digest algorithm goes as follow: +/// For elementary types: +/// 1. Transform the data in a byte array (if there is +/// any data) using `IntoDigestInput` trait, +/// 2. Concatenate prefix and the resulting byte array, +/// 3. Hash the result. +/// For data structures: +/// 1. Calculate the root digest of the struct, +/// 2. Concatenate prefix and resulting root digest, +/// 3. Hash the result. +/// +/// For unit variants of enums, only the prefix as input to the hash function. pub use digest_macro_derive::Digest; pub use hex; From 926e4618c16a782fdddd2ffcfd22e0b172b2a46a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Tue, 17 Mar 2020 15:56:35 +1100 Subject: [PATCH 106/145] Don't generate siren type definitions automatically We now have types in the SDK for Siren for quite a while. We can use them in our e2e tests instead of generating the types from the schema. --- api_tests/package.json | 2 - api_tests/src/actors/actor.ts | 2 +- api_tests/tests/dry/rfc003_schema.ts | 8 +- api_tests/tests/dry/sanity.ts | 2 +- api_tests/yarn.lock | 226 +-------------------------- 5 files changed, 13 insertions(+), 227 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index c7ff27b73f..f186aa592a 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -5,7 +5,6 @@ "main": "index.js", "scripts": { "check": "tsc && prettier --check '**/*.{ts,json,yml}' && tslint --project .", - "postinstall": "mkdir -p ./gen && json2ts -i ./siren.schema.json -o ./gen/siren.d.ts", "pretest": "cargo build --bin cnd && tsc", "dry": "jest --config jest.config-dry.js --maxWorkers=4", "e2e": "yarn jest --config jest.config-e2e.js --runInBand --forceExit --bail", @@ -48,7 +47,6 @@ "get-port": "^5.1.1", "jest": "^25.1.0", "js-sha256": "^0.9.0", - "json-schema-to-typescript": "^8.2.0", "log4js": "^6.1.2", "prettier": "^1.19.1", "rimraf": "^3.0.2", diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 0779ed9ad4..f9116094db 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -3,6 +3,7 @@ import { BigNumber, Cnd, ComitClient, + Entity, LedgerAction, Swap, SwapDetails, @@ -17,7 +18,6 @@ import { Ledger, LedgerKind } from "../ledgers/ledger"; import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; import { Wallet, Wallets } from "../wallets"; import { Actors } from "./index"; -import { Entity } from "../../gen/siren"; import { LndInstance } from "../ledgers/lnd_instance"; import { sha256 } from "js-sha256"; import { InvoiceState } from "@radar/lnrpc"; diff --git a/api_tests/tests/dry/rfc003_schema.ts b/api_tests/tests/dry/rfc003_schema.ts index de9a965470..f4fd15e3b4 100644 --- a/api_tests/tests/dry/rfc003_schema.ts +++ b/api_tests/tests/dry/rfc003_schema.ts @@ -2,7 +2,6 @@ * @logDir rfc003 */ -import { EmbeddedRepresentationSubEntity, Entity, Link } from "../../gen/siren"; import { Actor } from "../../src/actors/actor"; import { expect, request } from "chai"; import "chai/register-should"; @@ -11,7 +10,12 @@ import * as sirenJsonSchema from "../../siren.schema.json"; import * as swapPropertiesJsonSchema from "../../swap.schema.json"; import { twoActorTest } from "../../src/actor_test"; import { createDefaultSwapRequest, DEFAULT_ALPHA } from "../../src/utils"; -import { Action } from "comit-sdk"; +import { + Action, + EmbeddedRepresentationSubEntity, + Entity, + Link, +} from "comit-sdk"; // ******************************************** // // RFC003 schema tests // diff --git a/api_tests/tests/dry/sanity.ts b/api_tests/tests/dry/sanity.ts index 544de34287..b617b1ea63 100644 --- a/api_tests/tests/dry/sanity.ts +++ b/api_tests/tests/dry/sanity.ts @@ -4,8 +4,8 @@ import { oneActorTest } from "../../src/actor_test"; import { expect, request } from "chai"; -import { Entity, Link } from "../../gen/siren"; import * as sirenJsonSchema from "../../siren.schema.json"; +import { Entity, Link } from "comit-sdk"; // ******************************************** // // Sanity tests // diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index c2d733e2e4..8b4b4a8151 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -505,11 +505,6 @@ resolved "https://registry.yarnpkg.com/@types/google-protobuf/-/google-protobuf-3.7.2.tgz#cd8a360c193ce4d672575a20a79f49ba036d38d2" integrity sha512-ifFemzjNchFBCtHS6bZNhSZCBu7tbtOe0e8qY0z2J4HtFXmPJjm6fXSaQsTG7yhShBEZtt2oP/bkwu5k+emlkQ== -"@types/is-glob@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/is-glob/-/is-glob-4.0.1.tgz#a93eec1714172c8eb3225a1cc5eb88c2477b7d00" - integrity sha512-k3RS5HyBPu4h+5hTmIEfPB2rl5P3LnGdQEZrV2b9OWTJVtsUQ2VBcedqYKGqxvZqle5UALUXdSfVA8nf3HfyWQ== - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -538,11 +533,6 @@ jest-diff "^25.1.0" pretty-format "^25.1.0" -"@types/json-schema@^7.0.3": - version "7.0.3" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" - integrity sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A== - "@types/log4js@^2.3.5": version "2.3.5" resolved "https://registry.yarnpkg.com/@types/log4js/-/log4js-2.3.5.tgz#4d1e56da53d3c1820c08e9cd5092e68c3e1e822f" @@ -560,13 +550,6 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/mkdirp@^0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" - integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== - dependencies: - "@types/node" "*" - "@types/node@*", "@types/node@^13.9": version "13.9.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" @@ -577,11 +560,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== -"@types/prettier@^1.16.1": - version "1.18.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.18.2.tgz#069e7d132024d436fd1f5771f6932426a695f230" - integrity sha512-2JBasa5Qaj81Qsp/dxX2Njy+MdKC767WytHUDsRM7TYEfQvKPxsnGpnCBlBS1i2Aiv1YwCpmKSbQ6O6v8TpiKg== - "@types/rimraf@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.3.tgz#0199a46af106729ba14213fda7b981278d8c84f2" @@ -705,7 +683,7 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.11.0" -ansi-regex@^2.0.0, ansi-regex@^2.1.1: +ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= @@ -740,11 +718,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= - anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1354,11 +1327,6 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-me-maybe@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" - integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1488,18 +1456,6 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -cli-color@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.4.0.tgz#7d10738f48526824f8fe7da51857cb0f572fe01f" - integrity sha512-xu6RvQqqrWEo6MPR1eixqGPywhYBHRs653F9jfXB2Hx4jdM/3WxiNE1vppRmxtMIfl16SFYTpYlrnqH/HsK/2w== - dependencies: - ansi-regex "^2.1.1" - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - memoizee "^0.4.14" - timers-ext "^0.1.5" - cliui@^3.0.3: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -1695,13 +1651,6 @@ cssstyle@^2.0.0: dependencies: cssom "~0.3.6" -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= - dependencies: - es5-ext "^0.10.9" - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1943,42 +1892,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.50" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" - integrity sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw== - dependencies: - es6-iterator "~2.0.3" - es6-symbol "~3.1.1" - next-tick "^1.0.0" - -es6-iterator@^2.0.3, es6-iterator@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2036,14 +1949,6 @@ ethers@^4.0.38, ethers@^4.0.45: uuid "2.0.1" xmlhttprequest "1.8.0" -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= - dependencies: - d "1" - es5-ext "~0.10.14" - exec-sh@^0.3.2: version "0.3.4" resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" @@ -2291,11 +2196,6 @@ form-data@^2.3.1, form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" -format-util@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.3.tgz#032dca4a116262a12c43f4c3ec8566416c5b2d95" - integrity sha1-Ay3KShFiYqEsQ/TD7IVmQWxbLZU= - formidable@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" @@ -2773,11 +2673,6 @@ is-extendable@^1.0.1: dependencies: is-plain-object "^2.0.4" -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -2800,13 +2695,6 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - is-ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-2.0.0.tgz#68eea07e8a0a0a94c2d080dd674c731ab2a461ab" @@ -2833,11 +2721,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-promise@^2.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - is-regex@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" @@ -3311,7 +3194,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.12.1, js-yaml@^3.13.1: +js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -3368,36 +3251,6 @@ json-bigint@^0.2.0: dependencies: bignumber.js "^4.0.0" -json-schema-ref-parser@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/json-schema-ref-parser/-/json-schema-ref-parser-6.1.0.tgz#30af34aeab5bee0431da805dac0eb21b574bf63d" - integrity sha512-pXe9H1m6IgIpXmE5JSb8epilNTGsmTb2iPohAXpOdhqGFbQjNeHHsZxU+C8w6T81GZxSPFLeUoqDJmzxx5IGuw== - dependencies: - call-me-maybe "^1.0.1" - js-yaml "^3.12.1" - ono "^4.0.11" - -json-schema-to-typescript@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-8.2.0.tgz#a859f836df89db63c5f17a6c9c2f1dea93e8dd9b" - integrity sha512-yvi4v9oLeJzJCktt+Zta6kOgEu8R93gNMZUJYo83aAPxoG0qB+cXIxVg5xa6gmdNkyffjH9Ebw1rvyaJKIor5A== - dependencies: - "@types/is-glob" "^4.0.1" - "@types/json-schema" "^7.0.3" - "@types/mkdirp" "^0.5.2" - "@types/prettier" "^1.16.1" - cli-color "^1.4.0" - glob "^7.1.4" - is-glob "^4.0.1" - json-schema-ref-parser "^6.1.0" - json-stringify-safe "^5.0.1" - lodash "^4.17.11" - minimist "^1.2.0" - mkdirp "^0.5.1" - mz "^2.7.0" - prettier "^1.19.1" - stdin "0.0.1" - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3408,7 +3261,7 @@ json-schema@0.2.3: resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -3531,7 +3384,7 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15: +lodash@^4.0.0, lodash@^4.17.13, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== @@ -3564,13 +3417,6 @@ long@~3: resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= -lru-queue@0.1: - version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= - dependencies: - es5-ext "~0.10.2" - make-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" @@ -3612,20 +3458,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -memoizee@^0.4.14: - version "0.4.14" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" - integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== - dependencies: - d "1" - es5-ext "^0.10.45" - es6-weak-map "^2.0.2" - event-emitter "^0.3.5" - is-promise "^2.1" - lru-queue "0.1" - next-tick "1" - timers-ext "^0.1.5" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -3797,15 +3629,6 @@ mv@~2: ncp "~2.0.0" rimraf "~2.4.0" -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - n64@~0.2.10: version "0.2.10" resolved "https://registry.yarnpkg.com/n64/-/n64-0.2.10.tgz#e5831073dd527e6934b880231a43f3a8e36c096a" @@ -3857,11 +3680,6 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -next-tick@1, next-tick@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" - integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -3984,7 +3802,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -4061,13 +3879,6 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" -ono@^4.0.11: - version "4.0.11" - resolved "https://registry.yarnpkg.com/ono/-/ono-4.0.11.tgz#c7f4209b3e396e8a44ef43b9cedc7f5d791d221d" - integrity sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g== - dependencies: - format-util "^1.0.3" - optionator@^0.8.1: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" @@ -4913,11 +4724,6 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stdin@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/stdin/-/stdin-0.0.1.tgz#d3041981aaec3dfdbc77a1b38d6372e38f5fb71e" - integrity sha1-0wQZgarsPf28d6GzjWNy449ftx4= - stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -5131,33 +4937,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.0" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" - integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= - dependencies: - any-promise "^1.0.0" - throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== -timers-ext@^0.1.5: - version "0.1.7" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== - dependencies: - es5-ext "~0.10.46" - next-tick "1" - tmp@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" From db6d30643cb57f6d63f40133a15b90f2ab7aff16 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 18 Mar 2020 11:38:33 +1100 Subject: [PATCH 107/145] Remove support of Nested structs --- digest-macro-derive/src/lib.rs | 6 +- digest/src/lib.rs | 63 ++++----------- digest/tests/swap_digest.rs | 139 +++------------------------------ 3 files changed, 25 insertions(+), 183 deletions(-) diff --git a/digest-macro-derive/src/lib.rs b/digest-macro-derive/src/lib.rs index 261d0de7ad..a924fe3e33 100644 --- a/digest-macro-derive/src/lib.rs +++ b/digest-macro-derive/src/lib.rs @@ -33,13 +33,11 @@ fn impl_digest_macro(ast: &syn::DeriveInput) -> TokenStream { let gen = quote! { impl ::digest::Digest for #name - where #(#types: ::digest::FieldDigest),* + where #(#types: ::digest::IntoDigestInput),* { fn digest(self) -> ::multihash::Multihash { - use ::digest::FieldDigest; - let mut digests = vec![]; - #(digests.push(self.#idents.field_digest(#bytes.to_vec())););* + #(digests.push(::digest::field_digest(self.#idents, #bytes.to_vec())););* digests.sort(); diff --git a/digest/src/lib.rs b/digest/src/lib.rs index 5309c6da5e..16462e9072 100644 --- a/digest/src/lib.rs +++ b/digest/src/lib.rs @@ -1,4 +1,4 @@ -/// This crate brings two traits: `Digest` and `FieldDigest` +/// This crate brings two traits: `Digest` and `IntoDigestInput` /// /// `Digest` should be implemented on data structures using the `Digest` /// derive macro. @@ -6,8 +6,8 @@ /// role of an identifier to ensure that fields with same data but different /// meaning do not result to the same digest. /// -/// Elementary data types should implement `IntoDigestInput`, this allows you to -/// control how the data is transformed to a byte array. +/// Data types within the data structure should implement `IntoDigestInput`, +/// this allows you to control how the data is transformed to a byte array. /// /// ``` /// use digest::{Digest, IntoDigestInput}; @@ -30,23 +30,15 @@ /// ``` /// /// The digest algorithm goes as follow: -/// 1. Compute `field_digest(prefix)` for all fields of the struct, -/// 2. Lexically order the field digests, -/// 3. Concatenate the result, +/// 1. For each field in the struct: +/// a. Concatenate `digest_prefix` + `self.into_digest_input`, +/// b. Hash the result. +/// 2. Lexically order the resulting field digests, +/// 3. Concatenate the list, /// 4. Hash the result. /// -/// The field digest algorithm goes as follow: -/// For elementary types: -/// 1. Transform the data in a byte array (if there is -/// any data) using `IntoDigestInput` trait, -/// 2. Concatenate prefix and the resulting byte array, -/// 3. Hash the result. -/// For data structures: -/// 1. Calculate the root digest of the struct, -/// 2. Concatenate prefix and resulting root digest, -/// 3. Hash the result. -/// /// For unit variants of enums, only the prefix as input to the hash function. +/// Note that Nested structures are not supported. pub use digest_macro_derive::Digest; pub use hex; @@ -65,37 +57,10 @@ pub trait IntoDigestInput { fn into_digest_input(self) -> Vec; } -#[doc(hidden)] -pub trait FieldDigest: private::Sealed { - fn field_digest(self, prefix: Vec) -> Multihash; -} - -impl IntoDigestInput for T -where - T: Digest, -{ - fn into_digest_input(self) -> Vec { - let field_digest = self.digest(); - - field_digest.into_bytes() - } -} - -impl FieldDigest for T -where - T: IntoDigestInput, -{ - fn field_digest(self, prefix: Vec) -> Multihash { - let mut bytes = prefix; - let mut value = self.into_digest_input(); - bytes.append(&mut value); - - digest(&bytes) - } -} - -mod private { - pub trait Sealed {} +pub fn field_digest(field: T, prefix: Vec) -> Multihash { + let mut bytes = prefix; + let mut value = field.into_digest_input(); + bytes.append(&mut value); - impl Sealed for T where T: super::IntoDigestInput {} + digest(&bytes) } diff --git a/digest/tests/swap_digest.rs b/digest/tests/swap_digest.rs index 41aade2d8f..b5582a9d6e 100644 --- a/digest/tests/swap_digest.rs +++ b/digest/tests/swap_digest.rs @@ -1,4 +1,4 @@ -use digest::{digest, Digest, FieldDigest, IntoDigestInput}; +use digest::{digest, field_digest, Digest, IntoDigestInput}; use digest::multihash::Multihash; @@ -32,9 +32,9 @@ struct OtherDoubleFieldStruct { impl Digest for OtherDoubleFieldStruct { fn digest(self) -> Multihash { let mut digests = vec![]; - let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); + let foo_digest = field_digest(self.foo, [0x00u8, 0x11u8].to_vec()); digests.push(foo_digest); - let bar_digest = self.bar.field_digest([0xFFu8, 0xAAu8].to_vec()); + let bar_digest = field_digest(self.bar, [0xFFu8, 0xAAu8].to_vec()); digests.push(bar_digest); digests.sort(); @@ -72,75 +72,14 @@ impl Digest for OtherEnum { } } -#[derive(Digest)] -struct NestedStruct { - #[digest_prefix = "0011"] - foo: MyString, - #[digest_prefix = "AA00"] - nest: DoubleFieldStruct, -} - -struct OtherNestedStruct { - foo: MyString, - nest: OtherDoubleFieldStruct, -} - -impl Digest for OtherNestedStruct { - fn digest(self) -> Multihash { - let mut digests = vec![]; - let foo_digest = self.foo.field_digest([0x00u8, 0x11u8].to_vec()); - digests.push(foo_digest); - let nest_digest = self.nest.field_digest([0xAAu8, 0x00u8].to_vec()); - digests.push(nest_digest); - - digests.sort(); - - let res = digests.into_iter().fold(vec![], |mut res, digest| { - res.append(&mut digest.into_bytes()); - res - }); - - digest(&res) - } -} - -#[derive(Digest)] -enum NestedEnum { - #[digest_prefix = "DEAD"] - Foo, - #[digest_prefix = "BEEF"] - Bar(NestedStruct), -} - -#[allow(dead_code)] -enum OtherNestedEnum { - Foo, - Bar(OtherNestedStruct), -} - -impl Digest for OtherNestedEnum { - fn digest(self) -> Multihash { - let bytes = match self { - OtherNestedEnum::Foo => vec![0xDEu8, 0xADu8], - OtherNestedEnum::Bar(other_nested_struct) => { - let mut bytes = vec![0xBEu8, 0xEFu8]; - bytes.append(&mut other_nested_struct.digest().into_bytes()); - bytes - } - }; - - digest(&bytes) - } -} - #[test] fn given_same_strings_return_same_multihash() { let str1: MyString = "simple string".into(); let str2: MyString = "simple string".into(); assert_eq!( - str1.field_digest("foo".into()), - str2.field_digest("foo".into()) + field_digest(str1, "foo".into()), + field_digest(str2, "foo".into()) ) } @@ -150,8 +89,8 @@ fn given_same_strings_different_names_return_diff_multihash() { let str2: MyString = "simple string".into(); assert_ne!( - str1.field_digest("foo".into()), - str2.field_digest("bar".into()) + field_digest(str1, "foo".into()), + field_digest(str2, "bar".into()) ) } @@ -161,8 +100,8 @@ fn given_different_strings_return_different_multihash() { let str2: MyString = "longer string".into(); assert_ne!( - str1.field_digest("foo".into()), - str2.field_digest("foo".into()) + field_digest(str1, "foo".into()), + field_digest(str2, "foo".into()) ) } @@ -223,63 +162,3 @@ fn given_two_enums_with_differnt_variant_return_different_multihash() { assert_eq!(enum1.digest(), enum2.digest()) } - -#[test] -fn given_two_nested_structs_with_same_value_return_same_multihash() { - let struct1 = NestedStruct { - foo: "foo".into(), - nest: DoubleFieldStruct { - foo: "phou".into(), - bar: "pub".into(), - }, - }; - let struct2 = OtherNestedStruct { - foo: "foo".into(), - nest: OtherDoubleFieldStruct { - foo: "phou".into(), - bar: "pub".into(), - }, - }; - - assert_eq!(struct1.digest(), struct2.digest()) -} - -#[test] -fn given_two_nested_structs_with_diff_value_return_diff_multihash() { - let struct1 = NestedStruct { - foo: "phou".into(), - nest: DoubleFieldStruct { - foo: "foo".into(), - bar: "pub".into(), - }, - }; - let struct2 = OtherNestedStruct { - foo: "phou".into(), - nest: OtherDoubleFieldStruct { - foo: "foo".into(), - bar: "pub".into(), - }, - }; - - assert_eq!(struct1.digest(), struct2.digest()) -} - -#[test] -fn given_two_nested_enums_with_same_value_return_same_multihash() { - let enum1 = NestedEnum::Bar(NestedStruct { - foo: "foo".into(), - nest: DoubleFieldStruct { - foo: "faa".into(), - bar: "restaurant".into(), - }, - }); - let enum2 = OtherNestedEnum::Bar(OtherNestedStruct { - foo: "foo".into(), - nest: OtherDoubleFieldStruct { - foo: "faa".into(), - bar: "restaurant".into(), - }, - }); - - assert_eq!(enum1.digest(), enum2.digest()); -} From c0ba6f6f71cf1087c912cec2bd9368ac7ab90310 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 18 Mar 2020 14:32:14 +0000 Subject: [PATCH 108/145] Bump ethers from 4.0.45 to 4.0.46 in /api_tests Bumps [ethers](https://github.com/ethers-io/ethers.js) from 4.0.45 to 4.0.46. - [Release notes](https://github.com/ethers-io/ethers.js/releases) - [Changelog](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md) - [Commits](https://github.com/ethers-io/ethers.js/commits) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index f186aa592a..1ecd6e6c29 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -43,7 +43,7 @@ "chai-string": "^1.5.0", "chai-subset": "^1.6.0", "comit-sdk": "^0.14.0", - "ethers": "^4.0.45", + "ethers": "^4.0.46", "get-port": "^5.1.1", "jest": "^25.1.0", "js-sha256": "^0.9.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 8b4b4a8151..bd46af5095 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1934,10 +1934,10 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -ethers@^4.0.38, ethers@^4.0.45: - version "4.0.45" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.45.tgz#8d4cd764d7c7690836b583d4849203c225eb56e2" - integrity sha512-N/Wmc6Mw4pQO+Sss1HnKDCSS6KSCx0luoBMiPNq+1GbOaO3YaZOyplBEhj+NEoYsizZYODtkITg2oecPeNnidQ== +ethers@^4.0.38, ethers@^4.0.46: + version "4.0.46" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.46.tgz#13cd3ed099487f43ece00194b89a8a8781f71507" + integrity sha512-/dPMzzpInhtiip4hKFvsDiJKeRk64IhyA+Po7CtNXneQFSOCYXg8eBFt+jXbxUQyApgWnWOtYxWdfn9+CvvxDA== dependencies: aes-js "3.0.0" bn.js "^4.4.0" From 188e9fbb37a7d9bdaad153c4e660056023248add Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 17 Mar 2020 10:38:51 +1100 Subject: [PATCH 109/145] Add skeleton API function for controller/swarm interface In order to be able to utilise the new communication protocol we need an interface between the controller and the swarm. Add an API function that allows the controller (acting as Alice) to call the swarm (libp2p layer) and trigger execution of the new communication protocols (by calling through to the underlying swarm) in order to announce the created swap, send the known parameters, and receive the remaining required swap parameters back from Bob. Fixes: #2170 --- cnd/src/network/mod.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cnd/src/network/mod.rs b/cnd/src/network/mod.rs index 4316fd70c0..f8e99b4ed1 100644 --- a/cnd/src/network/mod.rs +++ b/cnd/src/network/mod.rs @@ -136,6 +136,30 @@ impl Swarm { local_peer_id, }) } + + /// This is the API for Alice to call in order to execute the appropriate + /// communication protocols to announce a swap to Bob (i.e., to send the + /// known swap parameters and receive the remaining swap parameters) in + /// order to finalize this swap. + /// + /// `id` is an identifier use to access the database to get the known swap + /// parameters. + // Identifier type will be defined in ticket: https://github.com/comit-network/comit-rs/issues/2173 + pub async fn finalize_announce_swap(&mut self, _id: String) -> anyhow::Result<()> { + // 1. Load parameters for the swap from the database and call down to + // the swarm to execute the required communication protocols. + // + // 2. Write the remaining parameters to the database (keyed by swap_id). + // + // 3. Spawn the swap using `swap_id` as an argument. `spawn()` can then + // load the swap from the database and spawn it. + + unimplemented!() + } + + // On Bob's side, when an announce message is received execute the required + // communication protocols and write the finalized swap to the database. Then + // spawn the same as is done for Alice. } struct SwarmWorker { From 5b2a4db2209b390bad761bb59f96298e2f2bac92 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Thu, 19 Mar 2020 09:39:10 +1100 Subject: [PATCH 110/145] Add trigger to sync labels --- .github/workflows/trigger-sync-labels.yml | 28 +++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/trigger-sync-labels.yml diff --git a/.github/workflows/trigger-sync-labels.yml b/.github/workflows/trigger-sync-labels.yml new file mode 100644 index 0000000000..b3a8c63088 --- /dev/null +++ b/.github/workflows/trigger-sync-labels.yml @@ -0,0 +1,28 @@ +name: Sync labels + +on: + repository_dispatch: + types: + - sync-labels + +jobs: + sync: + runs-on: ubuntu-latest + name: Sync labels from coblox/admin + steps: + - name: Download label file + env: + REPO_TOKEN: ${{ secrets.GITHUB_REPO_TOKEN }} + run: | + curl --header "Authorization: token ${REPO_TOKEN}" \ + --header 'Accept: application/vnd.github.v3.raw' \ + --location 'https://api.github.com/repos/coblox/admin/contents/.github/labels.yml' \ + --output labels.yml + # For debug purposes + ls; cat labels.yml + - name: Sync label locally + uses: micnncim/action-label-syncer@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + manifest: labels.yml From 855dcd00f238727741facb7ed153119a12cf59ec Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:13:05 +0000 Subject: [PATCH 111/145] Bump serde from 1.0.104 to 1.0.105 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.104 to 1.0.105. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.104...v1.0.105) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a4700b396..f8a0cb8a6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3280,9 +3280,9 @@ checksum = "a0eddf2e8f50ced781f288c19f18621fa72a3779e3cb58dbf23b07469b0abeb4" [[package]] name = "serde" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +checksum = "e707fbbf255b8fc8c3b99abb91e7257a622caeb20a9818cbadbeeede4e0932ff" dependencies = [ "serde_derive", ] @@ -3300,9 +3300,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", From 4948bb8bf4ffa0fe83f7f1d6f7dff0f752b353f7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:13:25 +0000 Subject: [PATCH 112/145] Bump structopt from 0.3.11 to 0.3.12 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.11 to 0.3.12. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.11...v0.3.12) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a4700b396..a9e2f064ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3501,9 +3501,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.11" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" +checksum = "c8faa2719539bbe9d77869bfb15d4ee769f99525e707931452c97b693b3f159d" dependencies = [ "clap", "lazy_static", @@ -3512,9 +3512,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" +checksum = "3f88b8e18c69496aad6f9ddf4630dd7d585bcaf765786cb415b9aec2fe5a0430" dependencies = [ "heck", "proc-macro-error", From dfb2485cf190cb8ddf1054b4eacc03173c22cc66 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:22:27 +0000 Subject: [PATCH 113/145] Bump ts-node from 8.6.2 to 8.7.0 in /api_tests Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 8.6.2 to 8.7.0. - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Commits](https://github.com/TypeStrong/ts-node/compare/v8.6.2...v8.7.0) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index f186aa592a..9533d49306 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -56,7 +56,7 @@ "temp-write": "^4.0.0", "tmp": "^0.1.0", "ts-jest": "^25.2.1", - "ts-node": "^8.6.2", + "ts-node": "^8.7.0", "tslint": "^6.1.0", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 8b4b4a8151..5f6a3825ff 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -3424,16 +3424,11 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" -make-error@1.x: +make-error@1.x, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-error@^1.1.1: - version "1.3.5" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" - integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== - makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -5044,10 +5039,10 @@ ts-jest@^25.2.1: semver "^5.5" yargs-parser "^16.1.0" -ts-node@^8.6.2: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35" - integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg== +ts-node@^8.7.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.7.0.tgz#266186947596bef9f3a034687595b30e31b20976" + integrity sha512-s659CsHrsxaRVDEleuOkGvbsA0rWHtszUNEt1r0CgAFN5ZZTQtDzpsluS7W5pOGJIa1xZE8R/zK4dEs+ldFezg== dependencies: arg "^4.1.0" diff "^4.0.1" From 82094416db935eafa8bb98e6dff4bf1079c0cc22 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 19 Mar 2020 14:23:02 +0000 Subject: [PATCH 114/145] Bump @types/node from 13.9.1 to 13.9.2 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.1 to 13.9.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 8b4b4a8151..3756e9f211 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -551,9 +551,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.9": - version "13.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72" - integrity sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ== + version "13.9.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" + integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== "@types/node@^10.1.0": version "10.17.17" From 703a4dc007fce2024116e81105650dcf3601e7c6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 14:13:06 +0000 Subject: [PATCH 115/145] Bump @types/node from 13.9.2 to 13.9.3 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.2 to 13.9.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 6613f44885..a14ee01e3e 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -551,9 +551,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.9": - version "13.9.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" - integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== + version "13.9.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.3.tgz#6356df2647de9eac569f9a52eda3480fa9e70b4d" + integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA== "@types/node@^10.1.0": version "10.17.17" From a03d955db57a1dfaae4994a937bfbecba6db2716 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 14:13:10 +0000 Subject: [PATCH 116/145] Bump thiserror from 1.0.11 to 1.0.12 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.11 to 1.0.12. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.11...1.0.12) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cfa6c6831..082c3acf7d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3650,18 +3650,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +checksum = "268c0f167625b8b0cc90a91787b158a372b4edadb31d6e20479dc787309defad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +checksum = "9a3ecbaa927a1d5a73d14a20af52463fa433c0727d07ef5e208f0546841d2efd" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", From d243ae4fee16b334083ac0f851bf636f57aad473 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 14:13:30 +0000 Subject: [PATCH 117/145] Bump @types/rimraf from 2.0.3 to 3.0.0 in /api_tests Bumps [@types/rimraf](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/rimraf) from 2.0.3 to 3.0.0. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/rimraf) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index ef3e06f013..03aeb8f6c4 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -26,7 +26,7 @@ "@types/jest": "^25.1.4", "@types/log4js": "^2.3.5", "@types/node": "^13.9", - "@types/rimraf": "^2.0.3", + "@types/rimraf": "^3.0.0", "@types/tail": "^2.0.0", "@types/tmp": "^0.1.0", "@wcjiang/whereis": "^1.0.0", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 6613f44885..a60ae95c68 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -560,10 +560,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.17.tgz#7a183163a9e6ff720d86502db23ba4aade5999b8" integrity sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q== -"@types/rimraf@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-2.0.3.tgz#0199a46af106729ba14213fda7b981278d8c84f2" - integrity sha512-dZfyfL/u9l/oi984hEXdmAjX3JHry7TLWw43u1HQ8HhPv6KtfxnrZ3T/bleJ0GEvnk9t5sM7eePkgMqz3yBcGg== +"@types/rimraf@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.0.tgz#b9d03f090ece263671898d57bb7bb007023ac19f" + integrity sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ== dependencies: "@types/glob" "*" "@types/node" "*" From ec164c73b21f7ef922fb708aaea66d76bc41ad51 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 14:13:31 +0000 Subject: [PATCH 118/145] Bump syn from 1.0.16 to 1.0.17 Bumps [syn](https://github.com/dtolnay/syn) from 1.0.16 to 1.0.17. - [Release notes](https://github.com/dtolnay/syn/releases) - [Commits](https://github.com/dtolnay/syn/compare/1.0.16...1.0.17) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 66 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cfa6c6831..e768a4682e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,7 +66,7 @@ checksum = "61874b33258f18ca7923047c12887078ccfe95c2811b03c1a09e309c19b7e50b" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -130,7 +130,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d0864d84b8e07b145449be9a8537db86bf9de5ce03b913214694643b4743502" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -176,7 +176,7 @@ checksum = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -789,7 +789,7 @@ checksum = "1b94d2eb97732ec84b4e25eaf37db890e317b80e921f168c82cb5282473f8151" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -812,7 +812,7 @@ checksum = "45f5098f628d02a7a0f68ddba586fb61e80edec3bdc1be3b921f4ceec60858d3" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -850,7 +850,7 @@ dependencies = [ "hex 0.4.2", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1094,7 +1094,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1199,7 +1199,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1521,7 +1521,7 @@ dependencies = [ "itertools", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -1734,7 +1734,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d472e9d522f588805c77801de10b957be84e10f019ca5f869fa1825b15ea9b" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2166,7 +2166,7 @@ dependencies = [ "migrations_internals", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2643,7 +2643,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2696,7 +2696,7 @@ checksum = "385322a45f2ecf3410c68d2a549a4a2685e8051d0f278e39743ff4e451cb9b3f" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2745,7 +2745,7 @@ dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", "rustversion", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2757,7 +2757,7 @@ dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", "rustversion", - "syn 1.0.16", + "syn 1.0.17", "syn-mid", ] @@ -2769,7 +2769,7 @@ checksum = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2834,7 +2834,7 @@ dependencies = [ "itertools", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -2990,7 +2990,7 @@ checksum = "c9fd3125016eb3257fe8038dcafaa5fbecc081bcd46defe9ccb98ceae0175219" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3149,7 +3149,7 @@ checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3306,7 +3306,7 @@ checksum = "ac5d00fc561ba2724df6758a17de23df5914f20e41cb00f94d5b7ae42fffaff8" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3520,7 +3520,7 @@ dependencies = [ "proc-macro-error", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3538,7 +3538,7 @@ dependencies = [ "heck", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3577,9 +3577,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859" +checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", @@ -3594,7 +3594,7 @@ checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3605,7 +3605,7 @@ checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "unicode-xid 0.2.0", ] @@ -3665,7 +3665,7 @@ checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3735,7 +3735,7 @@ checksum = "f4b1e7ed7d5d4c2af3d999904b0eebe76544897cdbfb2b9684bed2174ab20f7c" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -3795,7 +3795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fbad39da2f9af1cae3016339ad7f2c7a9e870f12e8fd04c4fd7ef35b30c0d2b" dependencies = [ "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", ] [[package]] @@ -4119,7 +4119,7 @@ dependencies = [ "log 0.4.8", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "wasm-bindgen-shared", ] @@ -4153,7 +4153,7 @@ checksum = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4175,7 +4175,7 @@ dependencies = [ "log 0.4.8", "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "wasm-bindgen-backend", "weedle", ] @@ -4323,6 +4323,6 @@ checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", - "syn 1.0.16", + "syn 1.0.17", "synstructure", ] From fe452fbaf28f5dc87837ce76f88cd551d5cee741 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 14:14:30 +0000 Subject: [PATCH 119/145] Bump ts-node from 8.7.0 to 8.8.1 in /api_tests Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 8.7.0 to 8.8.1. - [Release notes](https://github.com/TypeStrong/ts-node/releases) - [Commits](https://github.com/TypeStrong/ts-node/compare/v8.7.0...v8.8.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index ef3e06f013..fec7548110 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -56,7 +56,7 @@ "temp-write": "^4.0.0", "tmp": "^0.1.0", "ts-jest": "^25.2.1", - "ts-node": "^8.7.0", + "ts-node": "^8.8.1", "tslint": "^6.1.0", "tslint-config-prettier": "^1.18.0", "tslint-no-unused-expression-chai": "^0.1.4", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 6613f44885..bde8bebd50 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -5039,10 +5039,10 @@ ts-jest@^25.2.1: semver "^5.5" yargs-parser "^16.1.0" -ts-node@^8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.7.0.tgz#266186947596bef9f3a034687595b30e31b20976" - integrity sha512-s659CsHrsxaRVDEleuOkGvbsA0rWHtszUNEt1r0CgAFN5ZZTQtDzpsluS7W5pOGJIa1xZE8R/zK4dEs+ldFezg== +ts-node@^8.8.1: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.8.1.tgz#7c4d3e9ed33aa703b64b28d7f9d194768be5064d" + integrity sha512-10DE9ONho06QORKAaCBpPiFCdW+tZJuY/84tyypGtl6r+/C7Asq0dhqbRZURuUlLQtZxxDvT8eoj8cGW0ha6Bg== dependencies: arg "^4.1.0" diff "^4.0.1" From 9907716ffde098f912bdecdbc1b657082b8e3445 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 22 Mar 2020 16:16:31 +0000 Subject: [PATCH 120/145] Bump prettier from 1.19.1 to 2.0.1 in /api_tests Bumps [prettier](https://github.com/prettier/prettier) from 1.19.1 to 2.0.1. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/1.19.1...2.0.1) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 4a492aea35..7537161709 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "jest": "^25.1.0", "js-sha256": "^0.9.0", "log4js": "^6.1.2", - "prettier": "^1.19.1", + "prettier": "^2.0.1", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", "smack-my-jasmine-up": "^0.0.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index ff8a2edfcc..dce64d1a51 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -4089,10 +4089,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== +prettier@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.1.tgz#3f00ac71263be34684b2b2c8d7e7f63737592dac" + integrity sha512-piXGBcY1zoFOG0MvHpNE5reAGseLmaCRifQ/fmfF49BcYkInEs/naD/unxGNAeOKFA5+JxVrPyMvMlpzcd20UA== pretty-format@^25.1.0: version "25.1.0" From 44ed36070ef39f39797443cf7b94925bab81f411 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 23 Mar 2020 16:59:57 +1100 Subject: [PATCH 121/145] Run prettier --- api_tests/src/actor_test.ts | 2 +- api_tests/src/actors/actor.ts | 2 +- api_tests/src/dry_test_environment.ts | 6 +++--- api_tests/src/e2e_test_environment.ts | 6 +++--- api_tests/src/utils.ts | 4 ++-- api_tests/tests/dry/lightning_routes.ts | 8 ++++---- api_tests/tests/dry/multiple_peers.ts | 2 +- api_tests/tests/dry/peers_using_ip.ts | 2 +- api_tests/tests/dry/rfc003_schema.ts | 19 +++++++++++-------- 9 files changed, 27 insertions(+), 24 deletions(-) diff --git a/api_tests/src/actor_test.ts b/api_tests/src/actor_test.ts index fddc33d83c..96eff5b2c0 100644 --- a/api_tests/src/actor_test.ts +++ b/api_tests/src/actor_test.ts @@ -12,7 +12,7 @@ function nActorTest( actorNames: ["alice", "bob", "charlie"] | ["alice", "bob"] | ["alice"], testFn: (actors: Actors) => Promise ): ProvidesCallback { - return async done => { + return async (done) => { const name = JasmineSmacker.getCurrentTestName(); if (!name.match(/[A-z0-9\-]+/)) { // We use the test name as a file name for the log and hence need to restrict it. diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index f9116094db..273738f82b 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -209,7 +209,7 @@ export class Actor { peer_id: await to.cnd.getPeerId(), address_hint: await to.cnd .getPeerListenAddresses() - .then(addresses => addresses[0]), + .then((addresses) => addresses[0]), }, ...(await this.additionalIdentities(alphaAssetKind, betaAssetKind)), ...defaultExpiryTimes(), diff --git a/api_tests/src/dry_test_environment.ts b/api_tests/src/dry_test_environment.ts index c8a18685ce..eda1943bb6 100644 --- a/api_tests/src/dry_test_environment.ts +++ b/api_tests/src/dry_test_environment.ts @@ -65,15 +65,15 @@ export default class DryTestEnvironment extends NodeEnvironment { const logger = log4js.getLogger("test_environment"); logger.info("Starting up test environment"); - this.global.getLogFile = pathElements => + this.global.getLogFile = (pathElements) => path.join(logDir, ...pathElements); - this.global.getDataDir = async program => { + this.global.getDataDir = async (program) => { const dir = path.join(logDir, program); await mkdirAsync(dir, { recursive: true }); return dir; }; - this.global.getLogger = category => log4js.getLogger(category); + this.global.getLogger = (category) => log4js.getLogger(category); } private static async cleanLogDir(logDir: string) { diff --git a/api_tests/src/e2e_test_environment.ts b/api_tests/src/e2e_test_environment.ts index e24b7b64c5..eecf121c33 100644 --- a/api_tests/src/e2e_test_environment.ts +++ b/api_tests/src/e2e_test_environment.ts @@ -79,15 +79,15 @@ export default class E2ETestEnvironment extends NodeEnvironment { default: { appenders: ["multi"], level: "debug" }, }, }); - this.global.getLogFile = pathElements => + this.global.getLogFile = (pathElements) => path.join(logDir, ...pathElements); - this.global.getDataDir = async program => { + this.global.getDataDir = async (program) => { const dir = path.join(logDir, program); await mkdirAsync(dir, { recursive: true }); return dir; }; - this.global.getLogger = category => log4js.getLogger(category); + this.global.getLogger = (category) => log4js.getLogger(category); this.logger = log4js.getLogger("test_environment"); this.logger.info("Starting up test environment"); diff --git a/api_tests/src/utils.ts b/api_tests/src/utils.ts index 24c9ea9224..69bfece21b 100644 --- a/api_tests/src/utils.ts +++ b/api_tests/src/utils.ts @@ -41,7 +41,7 @@ export const rimrafAsync = promisify(rimraf); export const execAsync = promisify(exec); export async function sleep(time: number) { - return new Promise(res => { + return new Promise((res) => { setTimeout(res, time); }); } @@ -116,7 +116,7 @@ export async function createDefaultSwapRequest(counterParty: Actor) { peer_id: await counterParty.cnd.getPeerId(), address_hint: await counterParty.cnd .getPeerListenAddresses() - .then(addresses => addresses[0]), + .then((addresses) => addresses[0]), }, }; return swapRequest; diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index 74f2fb39d7..ae5e4743f0 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -13,7 +13,7 @@ describe("Lightning routes tests", () => { "lightning-routes-post-eth-lnbtc-return-400", oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHanEthereumEtherHalightLightningBitcoin(); - return expect(promise).to.eventually.be.rejected.then(error => { + return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", "Request failed with status code 400" @@ -26,7 +26,7 @@ describe("Lightning routes tests", () => { "lightning-routes-post-erc20-lnbtc-return-400", oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin(); - return expect(promise).to.eventually.be.rejected.then(error => { + return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", "Request failed with status code 400" @@ -39,7 +39,7 @@ describe("Lightning routes tests", () => { "lightning-routes-post-lnbtc-eth-return-400", oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther(); - return expect(promise).to.eventually.be.rejected.then(error => { + return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", "Request failed with status code 400" @@ -52,7 +52,7 @@ describe("Lightning routes tests", () => { "lightning-routes-post-lnbtc-erc20-return-400", oneActorTest(async ({ alice }) => { const promise = alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20(); - return expect(promise).to.eventually.be.rejected.then(error => { + return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", "Request failed with status code 400" diff --git a/api_tests/tests/dry/multiple_peers.ts b/api_tests/tests/dry/multiple_peers.ts index 38f5d132ba..8ef7101729 100644 --- a/api_tests/tests/dry/multiple_peers.ts +++ b/api_tests/tests/dry/multiple_peers.ts @@ -68,7 +68,7 @@ describe("Multiple peers tests", () => { [ aliceToBobSwapDetails, aliceToCharlieSwapDetails, - ].map(swapDetail => toMatch(swapDetail)) + ].map((swapDetail) => toMatch(swapDetail)) ).to.have.deep.members([ toMatch(bobSwapDetails), toMatch(charlieSwapDetails), diff --git a/api_tests/tests/dry/peers_using_ip.ts b/api_tests/tests/dry/peers_using_ip.ts index c3e40d8f51..330259997e 100644 --- a/api_tests/tests/dry/peers_using_ip.ts +++ b/api_tests/tests/dry/peers_using_ip.ts @@ -56,7 +56,7 @@ describe("Peers using IP tests", () => { peer_id: "QmXfGiwNESAFWUvDVJ4NLaKYYVopYdV5HbpDSgz5TSypkb", // Random peer id on purpose to see if Bob still appears in GET /swaps using the multiaddress address_hint: await bob.cnd .getPeerListenAddresses() - .then(addresses => addresses[0]), + .then((addresses) => addresses[0]), }, }); diff --git a/api_tests/tests/dry/rfc003_schema.ts b/api_tests/tests/dry/rfc003_schema.ts index f4fd15e3b4..62ed3b07aa 100644 --- a/api_tests/tests/dry/rfc003_schema.ts +++ b/api_tests/tests/dry/rfc003_schema.ts @@ -56,9 +56,10 @@ describe("Rfc003 schema tests", () => { await alice.cnd.postSwap(await createDefaultSwapRequest(bob)); const aliceSwapEntity = await alice - .pollCndUntil("/swaps", body => body.entities.length > 0) + .pollCndUntil("/swaps", (body) => body.entities.length > 0) .then( - body => body.entities[0] as EmbeddedRepresentationSubEntity + (body) => + body.entities[0] as EmbeddedRepresentationSubEntity ); await assertValidSirenDocument( @@ -68,9 +69,10 @@ describe("Rfc003 schema tests", () => { ); const bobsSwapEntity = await bob - .pollCndUntil("/swaps", body => body.entities.length > 0) + .pollCndUntil("/swaps", (body) => body.entities.length > 0) .then( - body => body.entities[0] as EmbeddedRepresentationSubEntity + (body) => + body.entities[0] as EmbeddedRepresentationSubEntity ); await assertValidSirenDocument( bobsSwapEntity, @@ -87,9 +89,10 @@ describe("Rfc003 schema tests", () => { await alice.cnd.postSwap(await createDefaultSwapRequest(bob)); const aliceSwapEntity = await alice - .pollCndUntil("/swaps", body => body.entities.length > 0) + .pollCndUntil("/swaps", (body) => body.entities.length > 0) .then( - body => body.entities[0] as EmbeddedRepresentationSubEntity + (body) => + body.entities[0] as EmbeddedRepresentationSubEntity ); const protocolLink = aliceSwapEntity.links.find((link: Link) => @@ -116,7 +119,7 @@ async function assertSwapsInProgress(actor: Actor, message: string) { const swapEntities = res.body.entities as EmbeddedRepresentationSubEntity[]; - expect(swapEntities.map(entity => entity.properties, message)) + expect(swapEntities.map((entity) => entity.properties, message)) .to.each.have.property("status") .that.is.equal("IN_PROGRESS"); } @@ -207,7 +210,7 @@ describe("Rfc003 schema swap reject tests", () => { expect( await bob.pollCndUntil( aliceStingySwap, - entity => + (entity) => entity.properties.state.communication.status === "DECLINED" ), From 9be18abe60679c663e97cbe06250a959a512a63b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 17 Mar 2020 11:57:31 +1100 Subject: [PATCH 122/145] Add announce protocol --- .../network/protocols/announce/behaviour.rs | 157 ++++++++++++++++++ cnd/src/network/protocols/announce/handler.rs | 136 +++++++++++++++ cnd/src/network/protocols/announce/mod.rs | 29 ++++ .../network/protocols/announce/protocol.rs | 146 ++++++++++++++++ cnd/src/network/protocols/mod.rs | 1 + 5 files changed, 469 insertions(+) create mode 100644 cnd/src/network/protocols/announce/behaviour.rs create mode 100644 cnd/src/network/protocols/announce/handler.rs create mode 100644 cnd/src/network/protocols/announce/mod.rs create mode 100644 cnd/src/network/protocols/announce/protocol.rs diff --git a/cnd/src/network/protocols/announce/behaviour.rs b/cnd/src/network/protocols/announce/behaviour.rs new file mode 100644 index 0000000000..1ee9009801 --- /dev/null +++ b/cnd/src/network/protocols/announce/behaviour.rs @@ -0,0 +1,157 @@ +use crate::{ + network::protocols::announce::{ + handler::{self, Handler, HandlerEvent}, + protocol::{OutboundConfig, ReplySubstream}, + SwapDigest, + }, + swap_protocols::SwapId, +}; +use libp2p::{ + core::{ConnectedPoint, Multiaddr, PeerId}, + swarm::{ + NegotiatedSubstream, NetworkBehaviour, NetworkBehaviourAction, PollParameters, + ProtocolsHandler, + }, +}; +use std::{ + collections::{HashMap, VecDeque}, + task::{Context, Poll}, +}; + +/// Network behaviour that announces a swap to peer by sending a `swap_digest` +/// and receives the `swap_id` back. +#[derive(Debug)] +pub struct Announce { + /// Pending events to be emitted when polled. + events: VecDeque>, + address_book: HashMap, +} + +impl Announce { + /// This is how data flows into the network behaviour from the application + /// when acting in the Role of Alice. + pub fn start_announce_protocol(&mut self, swap_digest: &SwapDigest, peer_id: &PeerId) { + self.events.push_back(NetworkBehaviourAction::SendEvent { + peer_id: peer_id.clone(), + event: OutboundConfig::new(swap_digest.clone()), + }); + } + + pub fn add_peer(&mut self, peer_id: PeerId, addr: Multiaddr) { + self.address_book.insert(peer_id, addr); + } +} + +impl Default for Announce { + fn default() -> Self { + Announce { + events: VecDeque::new(), + address_book: HashMap::new(), + } + } +} + +impl NetworkBehaviour for Announce { + type ProtocolsHandler = Handler; + type OutEvent = BehaviourEvent; + + fn new_handler(&mut self) -> Self::ProtocolsHandler { + Handler::default() + } + + fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { + if let Some(addr) = self.address_book.get(peer_id) { + vec![addr.clone()] + } else { + vec![] + } + } + + fn inject_connected(&mut self, _peer_id: PeerId, _endpoint: ConnectedPoint) {} + + fn inject_disconnected(&mut self, _peer_id: &PeerId, _: ConnectedPoint) {} + + fn inject_node_event(&mut self, peer_id: PeerId, event: HandlerEvent) { + match event { + HandlerEvent::ReceivedConfirmation(confirmed) => { + self.events.push_back(NetworkBehaviourAction::GenerateEvent( + BehaviourEvent::ReceivedConfirmation { + peer: peer_id, + swap_id: confirmed.swap_id, + swap_digest: confirmed.swap_digest, + }, + )); + } + HandlerEvent::AwaitingConfirmation(sender) => { + self.events.push_back(NetworkBehaviourAction::GenerateEvent( + BehaviourEvent::AwaitingConfirmation { + peer: peer_id, + io: sender, + }, + )); + } + HandlerEvent::Error(error) => { + self.events.push_back(NetworkBehaviourAction::GenerateEvent( + BehaviourEvent::Error { + peer: peer_id, + error, + }, + )); + } + } + } + + fn poll( + &mut self, + _cx: &mut Context<'_>, + _params: &mut impl PollParameters, + ) -> Poll< + NetworkBehaviourAction< + ::InEvent, + Self::OutEvent, + >, + > { + if let Some(event) = self.events.pop_front() { + return Poll::Ready(event); + } + + Poll::Pending + } +} + +/// Event emitted by the `Announce` behaviour. +#[derive(Debug)] +pub enum BehaviourEvent { + /// This event created when a confirmation message containing a `swap_id` is + /// received in response to an announce message containing a + /// `swap_digest`. The Event contains both the swap id and + /// the swap digest. The announce message is sent by Alice to Bob. + ReceivedConfirmation { + /// The peer (Bob) that the swap has been announced to. + peer: PeerId, + /// The swap_id returned by the peer (Bob). + swap_id: SwapId, + /// The swap_digest + swap_digest: SwapDigest, + }, + + /// The event is created when a remote sends a `swap_digest`. The event + /// contains a reply substream for the receiver to send back the + /// `swap_id` that corresponds to the swap digest. Bob sends the + /// confirmations message to Alice using the the reply substream. + AwaitingConfirmation { + /// The peer (Alice) that the reply substream is connected to. + peer: PeerId, + /// The substream (inc. `swap_digest`) to reply on (i.e., send + /// `swap_id`). + io: ReplySubstream, + }, + + /// Error while attempting to announce swap to the remote. + Error { + /// The peer with whom the error originated. + peer: PeerId, + /// The error that occurred. + error: handler::Error, + }, +} diff --git a/cnd/src/network/protocols/announce/handler.rs b/cnd/src/network/protocols/announce/handler.rs new file mode 100644 index 0000000000..dacb21876e --- /dev/null +++ b/cnd/src/network/protocols/announce/handler.rs @@ -0,0 +1,136 @@ +use crate::network::protocols::announce::protocol::{ + self, Confirmed, InboundConfig, OutboundConfig, ReplySubstream, +}; +use libp2p::{ + core::upgrade::{InboundUpgrade, OutboundUpgrade}, + swarm::{ + KeepAlive, NegotiatedSubstream, ProtocolsHandler, ProtocolsHandlerEvent, + ProtocolsHandlerUpgrErr, SubstreamProtocol, + }, +}; +use std::{ + collections::VecDeque, + task::{Context, Poll}, +}; + +/// Protocol handler for sending and receiving announce protocol messages. +#[derive(derivative::Derivative)] +#[derivative(Debug)] +pub struct Handler { + /// Pending events to yield. + #[derivative(Debug = "ignore")] + events: Vec, + /// Queue of outbound substreams to open. + dial_queue: VecDeque, +} + +impl Default for Handler { + fn default() -> Self { + Handler { + events: vec![], + dial_queue: VecDeque::new(), + } + } +} + +/// Event produced by the `Handler`. +#[derive(Debug)] +pub enum HandlerEvent { + /// This event created when a confirmation message containing a `swap_id` is + /// received in response to an announce message containing a + /// `swap_digest`. The Event contains both the swap id and + /// the swap digest. + ReceivedConfirmation(Confirmed), + + /// The event is created when a remote sends a `swap_digest`. The event + /// contains a reply substream for the receiver to send back the + /// `swap_id` that corresponds to the swap digest. + AwaitingConfirmation(ReplySubstream), + + /// Failed to announce swap to peer. + Error(Error), +} + +impl ProtocolsHandler for Handler { + type InEvent = OutboundConfig; + type OutEvent = HandlerEvent; + type Error = Error; + type InboundProtocol = InboundConfig; + type OutboundProtocol = OutboundConfig; + type OutboundOpenInfo = (); + + fn listen_protocol(&self) -> SubstreamProtocol { + SubstreamProtocol::new(InboundConfig::default()) + } + + fn inject_fully_negotiated_inbound( + &mut self, + sender: >::Output, + ) { + self.events.push(HandlerEvent::AwaitingConfirmation(sender)) + } + + fn inject_fully_negotiated_outbound( + &mut self, + confirmed: >::Output, + _info: Self::OutboundOpenInfo, + ) { + self.events + .push(HandlerEvent::ReceivedConfirmation(confirmed)); + } + + fn inject_event(&mut self, event: Self::InEvent) { + self.dial_queue.push_front(event); + } + + fn inject_dial_upgrade_error( + &mut self, + _info: Self::OutboundOpenInfo, + err: ProtocolsHandlerUpgrErr< + >::Error, + >, + ) { + self.events.push(HandlerEvent::Error(Error::Upgrade(err))); + } + + fn connection_keep_alive(&self) -> KeepAlive { + KeepAlive::Yes + } + + fn poll( + &mut self, + _: &mut Context<'_>, + ) -> Poll< + ProtocolsHandlerEvent< + Self::OutboundProtocol, + Self::OutboundOpenInfo, + HandlerEvent, + Self::Error, + >, + > { + if !self.events.is_empty() { + let event = self.events.remove(0); + if let HandlerEvent::Error(err) = event { + return Poll::Ready(ProtocolsHandlerEvent::Close(err)); + }; + return Poll::Ready(ProtocolsHandlerEvent::Custom(event)); + } + + if !self.dial_queue.is_empty() { + if let Some(upgrade) = self.dial_queue.remove(0) { + return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { + protocol: SubstreamProtocol::new(upgrade), + info: (), + }); + } + } + + Poll::Pending + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("outbound upgrade failed")] + Upgrade(#[from] ProtocolsHandlerUpgrErr), +} diff --git a/cnd/src/network/protocols/announce/mod.rs b/cnd/src/network/protocols/announce/mod.rs new file mode 100644 index 0000000000..ffa7558291 --- /dev/null +++ b/cnd/src/network/protocols/announce/mod.rs @@ -0,0 +1,29 @@ +pub mod behaviour; +pub mod handler; +pub mod protocol; + +use libp2p::multihash::Multihash; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[derive(Clone, Debug, PartialEq)] +pub struct SwapDigest { + inner: Multihash, +} + +impl Serialize for SwapDigest { + fn serialize(&self, _serializer: S) -> Result + where + S: Serializer, + { + unimplemented!() + } +} + +impl<'de> Deserialize<'de> for SwapDigest { + fn deserialize(_deserializer: D) -> Result>::Error> + where + D: Deserializer<'de>, + { + unimplemented!() + } +} diff --git a/cnd/src/network/protocols/announce/protocol.rs b/cnd/src/network/protocols/announce/protocol.rs new file mode 100644 index 0000000000..b402654015 --- /dev/null +++ b/cnd/src/network/protocols/announce/protocol.rs @@ -0,0 +1,146 @@ +use crate::{network::protocols::announce::SwapDigest, swap_protocols::SwapId}; +use futures::prelude::*; +use libp2p::core::upgrade::{self, InboundUpgrade, OutboundUpgrade, UpgradeInfo}; +use serde::Deserialize; +use std::{io, iter, pin::Pin}; + +const INFO: &str = "/comit/swap/announce/1.0.0"; + +/// Configuration for an upgrade to the `Announce` protocol on the outbound +/// side. +#[derive(Debug, Clone)] +pub struct OutboundConfig { + swap_digest: SwapDigest, +} + +impl OutboundConfig { + pub fn new(swap_digest: SwapDigest) -> Self { + OutboundConfig { swap_digest } + } +} + +impl UpgradeInfo for OutboundConfig { + type Info = &'static [u8]; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(INFO.as_bytes()) + } +} + +impl OutboundUpgrade for OutboundConfig +where + C: AsyncRead + AsyncWrite + Unpin + Send + 'static, +{ + type Output = Confirmed; + type Error = Error; + type Future = Pin> + Send>>; + + fn upgrade_outbound(self, mut socket: C, info: Self::Info) -> Self::Future { + tracing::trace!( + "Upgrading outbound connection for {}", + String::from_utf8_lossy(info) + ); + Box::pin(async move { + let bytes = serde_json::to_vec(&self.swap_digest)?; + upgrade::write_one(&mut socket, &bytes).await?; + socket.close().await?; + + let message = upgrade::read_one(&mut socket, 1024).await?; + let mut de = serde_json::Deserializer::from_slice(&message); + let swap_id = SwapId::deserialize(&mut de)?; + tracing::trace!("Received: {}", swap_id); + + Ok(Confirmed { + swap_digest: self.swap_digest.clone(), + swap_id, + }) + }) + } +} + +#[derive(Debug)] +pub struct Confirmed { + pub swap_digest: SwapDigest, + pub swap_id: SwapId, +} + +/// Configuration for an upgrade to the `Announce` protocol on the inbound side. +#[derive(Debug, Clone, Copy)] +pub struct InboundConfig {} + +impl Default for InboundConfig { + fn default() -> Self { + InboundConfig {} + } +} + +impl UpgradeInfo for InboundConfig { + type Info = &'static [u8]; + type InfoIter = iter::Once; + + fn protocol_info(&self) -> Self::InfoIter { + iter::once(INFO.as_bytes()) + } +} + +impl InboundUpgrade for InboundConfig +where + C: AsyncRead + Unpin + Send + 'static, +{ + type Output = ReplySubstream; + type Error = Error; + type Future = Pin> + Send>>; + + fn upgrade_inbound(self, mut socket: C, info: Self::Info) -> Self::Future { + tracing::trace!( + "Upgrading inbound connection for {}", + String::from_utf8_lossy(info) + ); + + Box::pin(async move { + let message = upgrade::read_one(&mut socket, 1024).await?; + let mut de = serde_json::Deserializer::from_slice(&message); + let swap_digest = SwapDigest::deserialize(&mut de)?; + Ok(ReplySubstream { + io: socket, + swap_digest, + }) + }) + } +} + +/// The substream on which a reply is expected to be sent. +#[derive(Debug)] +pub struct ReplySubstream { + pub io: T, + pub swap_digest: SwapDigest, +} + +impl ReplySubstream +where + T: AsyncWrite + Unpin, +{ + /// Sends back the requested information on the substream i.e., the + /// `swap_id`. + /// + /// Consumes the substream, returning a reply future that resolves + /// when the reply has been sent on the underlying connection. + pub async fn send(mut self, swap_id: SwapId) -> impl Future> { + tracing::trace!("Sending: {}", swap_id); + async move { + let bytes = serde_json::to_vec(&swap_id)?; + Ok(upgrade::write_one(&mut self.io, &bytes).await?) + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("failed to read a message from the socket")] + Read(#[from] upgrade::ReadOneError), + #[error("failed to write the message to the socket")] + Write(#[from] io::Error), + #[error("failed to serialize/deserialize the message")] + Serde(#[from] serde_json::Error), +} diff --git a/cnd/src/network/protocols/mod.rs b/cnd/src/network/protocols/mod.rs index 62c717ba50..aad90493ad 100644 --- a/cnd/src/network/protocols/mod.rs +++ b/cnd/src/network/protocols/mod.rs @@ -1,3 +1,4 @@ +pub mod announce; pub mod bitcoin_identity; pub mod ethereum_identity; pub mod finalize; From 119efdee7b116bab63d2ba2ca11d5706018a2a95 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 14:13:36 +0000 Subject: [PATCH 123/145] Bump diesel from 1.4.3 to 1.4.4 Bumps [diesel](https://github.com/diesel-rs/diesel) from 1.4.3 to 1.4.4. - [Release notes](https://github.com/diesel-rs/diesel/releases) - [Changelog](https://github.com/diesel-rs/diesel/blob/v1.4.4/CHANGELOG.md) - [Commits](https://github.com/diesel-rs/diesel/compare/v1.4.3...v1.4.4) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b85afc4214..6d6e07bb84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -794,9 +794,9 @@ dependencies = [ [[package]] name = "diesel" -version = "1.4.3" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d7cc03b910de9935007861dce440881f69102aaaedfd4bc5a6f40340ca5840c" +checksum = "33d7ca63eb2efea87a7f56a283acc49e2ce4b2bd54adf7465dc1d81fef13d8fc" dependencies = [ "byteorder 1.3.4", "chrono", From 1b70c1fc74141a51441507c9303e63ee4ea89eaa Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 14:14:17 +0000 Subject: [PATCH 124/145] Bump async-trait from 0.1.24 to 0.1.25 Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.24 to 0.1.25. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.24...0.1.25) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b85afc4214..5aa063ccec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,9 +170,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "750b1c38a1dfadd108da0f01c08f4cdc7ff1bb39b325f9c82cc972361780a6e1" +checksum = "77e07b5570f31843d05dc82384ea9da01c04fe0839e24f34134c649c09b904ee" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", From 785843f74c391955047f55e71eec11f02481cc0e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 14:14:57 +0000 Subject: [PATCH 125/145] Bump thiserror from 1.0.12 to 1.0.13 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.12 to 1.0.13. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.12...1.0.13) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b85afc4214..02f8bbdaef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3650,18 +3650,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "268c0f167625b8b0cc90a91787b158a372b4edadb31d6e20479dc787309defad" +checksum = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3ecbaa927a1d5a73d14a20af52463fa433c0727d07ef5e208f0546841d2efd" +checksum = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233" dependencies = [ "proc-macro2 1.0.9", "quote 1.0.3", From 35e835cc76b1e485b6f9bcef5ec1053ae77543b4 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 24 Mar 2020 15:50:20 +1100 Subject: [PATCH 126/145] Fix clippy type complexity warnings Disable clippy type complexity for function defined by libp2p. For the futures we use, add a type that aliases all the pin/box/dyn stuff. --- cnd/src/network/protocols/announce/handler.rs | 1 + cnd/src/network/protocols/announce/protocol.rs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cnd/src/network/protocols/announce/handler.rs b/cnd/src/network/protocols/announce/handler.rs index dacb21876e..0489a84ffc 100644 --- a/cnd/src/network/protocols/announce/handler.rs +++ b/cnd/src/network/protocols/announce/handler.rs @@ -97,6 +97,7 @@ impl ProtocolsHandler for Handler { KeepAlive::Yes } + #[allow(clippy::type_complexity)] fn poll( &mut self, _: &mut Context<'_>, diff --git a/cnd/src/network/protocols/announce/protocol.rs b/cnd/src/network/protocols/announce/protocol.rs index b402654015..bb1a0d3ca0 100644 --- a/cnd/src/network/protocols/announce/protocol.rs +++ b/cnd/src/network/protocols/announce/protocol.rs @@ -28,13 +28,15 @@ impl UpgradeInfo for OutboundConfig { } } +type UpgradeFuture = Pin + Send>>; + impl OutboundUpgrade for OutboundConfig where C: AsyncRead + AsyncWrite + Unpin + Send + 'static, { type Output = Confirmed; type Error = Error; - type Future = Pin> + Send>>; + type Future = UpgradeFuture>; fn upgrade_outbound(self, mut socket: C, info: Self::Info) -> Self::Future { tracing::trace!( @@ -90,7 +92,7 @@ where { type Output = ReplySubstream; type Error = Error; - type Future = Pin> + Send>>; + type Future = UpgradeFuture>; fn upgrade_inbound(self, mut socket: C, info: Self::Info) -> Self::Future { tracing::trace!( From 20df0ac433a28b24cbea3868343cb8852ca34c68 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 24 Mar 2020 17:10:16 +1100 Subject: [PATCH 127/145] Remove `mod.rs` from modules The Rust community favours using a file and directory for modules instead of a directory and a `mod.rs` i.e., We use: ``` path/to/module/foo/mod.rs path/to/module/foo/* // Other module files ``` Prefer: ``` path/to/module/foo.rs path/to/module/foo/* // Other module files ``` Move all modules to use the preferred naming scheme. Done using shell: ``` for path in $(find . -name mod.rs); do new=$(dirname $path) mv "$path" "$new.rs" done ``` --- cnd/src/{asset/mod.rs => asset.rs} | 0 cnd/src/asset/{ethereum/mod.rs => ethereum.rs} | 0 cnd/src/{btsieve/mod.rs => btsieve.rs} | 0 cnd/src/btsieve/{bitcoin/mod.rs => bitcoin.rs} | 0 cnd/src/btsieve/{ethereum/mod.rs => ethereum.rs} | 0 cnd/src/{comit_api/mod.rs => comit_api.rs} | 0 cnd/src/{config/mod.rs => config.rs} | 0 cnd/src/{db/mod.rs => db.rs} | 0 cnd/src/db/{integration_tests/mod.rs => integration_tests.rs} | 0 cnd/src/db/{wrapper_types/mod.rs => wrapper_types.rs} | 0 cnd/src/{ethereum/mod.rs => ethereum.rs} | 0 cnd/src/{http_api/mod.rs => http_api.rs} | 0 cnd/src/http_api/{routes/mod.rs => routes.rs} | 0 cnd/src/http_api/routes/{index/mod.rs => index.rs} | 0 cnd/src/http_api/routes/index/{handlers/mod.rs => handlers.rs} | 0 cnd/src/http_api/routes/{peers/mod.rs => peers.rs} | 0 cnd/src/http_api/routes/{rfc003/mod.rs => rfc003.rs} | 0 cnd/src/http_api/routes/rfc003/{handlers/mod.rs => handlers.rs} | 0 cnd/src/{network/mod.rs => network.rs} | 0 cnd/src/network/{protocols/mod.rs => protocols.rs} | 0 cnd/src/network/protocols/{announce/mod.rs => announce.rs} | 0 cnd/src/{swap_protocols/mod.rs => swap_protocols.rs} | 0 cnd/src/swap_protocols/{ledger/mod.rs => ledger.rs} | 0 cnd/src/swap_protocols/{rfc003/mod.rs => rfc003.rs} | 0 cnd/src/swap_protocols/rfc003/{actions/mod.rs => actions.rs} | 0 cnd/src/swap_protocols/rfc003/{alice/mod.rs => alice.rs} | 0 .../swap_protocols/rfc003/alice/{actions/mod.rs => actions.rs} | 0 cnd/src/swap_protocols/rfc003/{bitcoin/mod.rs => bitcoin.rs} | 0 cnd/src/swap_protocols/rfc003/{bob/mod.rs => bob.rs} | 0 cnd/src/swap_protocols/rfc003/bob/{actions/mod.rs => actions.rs} | 0 cnd/src/swap_protocols/rfc003/{ethereum/mod.rs => ethereum.rs} | 0 cnd/src/swap_protocols/rfc003/{events/mod.rs => events.rs} | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename cnd/src/{asset/mod.rs => asset.rs} (100%) rename cnd/src/asset/{ethereum/mod.rs => ethereum.rs} (100%) rename cnd/src/{btsieve/mod.rs => btsieve.rs} (100%) rename cnd/src/btsieve/{bitcoin/mod.rs => bitcoin.rs} (100%) rename cnd/src/btsieve/{ethereum/mod.rs => ethereum.rs} (100%) rename cnd/src/{comit_api/mod.rs => comit_api.rs} (100%) rename cnd/src/{config/mod.rs => config.rs} (100%) rename cnd/src/{db/mod.rs => db.rs} (100%) rename cnd/src/db/{integration_tests/mod.rs => integration_tests.rs} (100%) rename cnd/src/db/{wrapper_types/mod.rs => wrapper_types.rs} (100%) rename cnd/src/{ethereum/mod.rs => ethereum.rs} (100%) rename cnd/src/{http_api/mod.rs => http_api.rs} (100%) rename cnd/src/http_api/{routes/mod.rs => routes.rs} (100%) rename cnd/src/http_api/routes/{index/mod.rs => index.rs} (100%) rename cnd/src/http_api/routes/index/{handlers/mod.rs => handlers.rs} (100%) rename cnd/src/http_api/routes/{peers/mod.rs => peers.rs} (100%) rename cnd/src/http_api/routes/{rfc003/mod.rs => rfc003.rs} (100%) rename cnd/src/http_api/routes/rfc003/{handlers/mod.rs => handlers.rs} (100%) rename cnd/src/{network/mod.rs => network.rs} (100%) rename cnd/src/network/{protocols/mod.rs => protocols.rs} (100%) rename cnd/src/network/protocols/{announce/mod.rs => announce.rs} (100%) rename cnd/src/{swap_protocols/mod.rs => swap_protocols.rs} (100%) rename cnd/src/swap_protocols/{ledger/mod.rs => ledger.rs} (100%) rename cnd/src/swap_protocols/{rfc003/mod.rs => rfc003.rs} (100%) rename cnd/src/swap_protocols/rfc003/{actions/mod.rs => actions.rs} (100%) rename cnd/src/swap_protocols/rfc003/{alice/mod.rs => alice.rs} (100%) rename cnd/src/swap_protocols/rfc003/alice/{actions/mod.rs => actions.rs} (100%) rename cnd/src/swap_protocols/rfc003/{bitcoin/mod.rs => bitcoin.rs} (100%) rename cnd/src/swap_protocols/rfc003/{bob/mod.rs => bob.rs} (100%) rename cnd/src/swap_protocols/rfc003/bob/{actions/mod.rs => actions.rs} (100%) rename cnd/src/swap_protocols/rfc003/{ethereum/mod.rs => ethereum.rs} (100%) rename cnd/src/swap_protocols/rfc003/{events/mod.rs => events.rs} (100%) diff --git a/cnd/src/asset/mod.rs b/cnd/src/asset.rs similarity index 100% rename from cnd/src/asset/mod.rs rename to cnd/src/asset.rs diff --git a/cnd/src/asset/ethereum/mod.rs b/cnd/src/asset/ethereum.rs similarity index 100% rename from cnd/src/asset/ethereum/mod.rs rename to cnd/src/asset/ethereum.rs diff --git a/cnd/src/btsieve/mod.rs b/cnd/src/btsieve.rs similarity index 100% rename from cnd/src/btsieve/mod.rs rename to cnd/src/btsieve.rs diff --git a/cnd/src/btsieve/bitcoin/mod.rs b/cnd/src/btsieve/bitcoin.rs similarity index 100% rename from cnd/src/btsieve/bitcoin/mod.rs rename to cnd/src/btsieve/bitcoin.rs diff --git a/cnd/src/btsieve/ethereum/mod.rs b/cnd/src/btsieve/ethereum.rs similarity index 100% rename from cnd/src/btsieve/ethereum/mod.rs rename to cnd/src/btsieve/ethereum.rs diff --git a/cnd/src/comit_api/mod.rs b/cnd/src/comit_api.rs similarity index 100% rename from cnd/src/comit_api/mod.rs rename to cnd/src/comit_api.rs diff --git a/cnd/src/config/mod.rs b/cnd/src/config.rs similarity index 100% rename from cnd/src/config/mod.rs rename to cnd/src/config.rs diff --git a/cnd/src/db/mod.rs b/cnd/src/db.rs similarity index 100% rename from cnd/src/db/mod.rs rename to cnd/src/db.rs diff --git a/cnd/src/db/integration_tests/mod.rs b/cnd/src/db/integration_tests.rs similarity index 100% rename from cnd/src/db/integration_tests/mod.rs rename to cnd/src/db/integration_tests.rs diff --git a/cnd/src/db/wrapper_types/mod.rs b/cnd/src/db/wrapper_types.rs similarity index 100% rename from cnd/src/db/wrapper_types/mod.rs rename to cnd/src/db/wrapper_types.rs diff --git a/cnd/src/ethereum/mod.rs b/cnd/src/ethereum.rs similarity index 100% rename from cnd/src/ethereum/mod.rs rename to cnd/src/ethereum.rs diff --git a/cnd/src/http_api/mod.rs b/cnd/src/http_api.rs similarity index 100% rename from cnd/src/http_api/mod.rs rename to cnd/src/http_api.rs diff --git a/cnd/src/http_api/routes/mod.rs b/cnd/src/http_api/routes.rs similarity index 100% rename from cnd/src/http_api/routes/mod.rs rename to cnd/src/http_api/routes.rs diff --git a/cnd/src/http_api/routes/index/mod.rs b/cnd/src/http_api/routes/index.rs similarity index 100% rename from cnd/src/http_api/routes/index/mod.rs rename to cnd/src/http_api/routes/index.rs diff --git a/cnd/src/http_api/routes/index/handlers/mod.rs b/cnd/src/http_api/routes/index/handlers.rs similarity index 100% rename from cnd/src/http_api/routes/index/handlers/mod.rs rename to cnd/src/http_api/routes/index/handlers.rs diff --git a/cnd/src/http_api/routes/peers/mod.rs b/cnd/src/http_api/routes/peers.rs similarity index 100% rename from cnd/src/http_api/routes/peers/mod.rs rename to cnd/src/http_api/routes/peers.rs diff --git a/cnd/src/http_api/routes/rfc003/mod.rs b/cnd/src/http_api/routes/rfc003.rs similarity index 100% rename from cnd/src/http_api/routes/rfc003/mod.rs rename to cnd/src/http_api/routes/rfc003.rs diff --git a/cnd/src/http_api/routes/rfc003/handlers/mod.rs b/cnd/src/http_api/routes/rfc003/handlers.rs similarity index 100% rename from cnd/src/http_api/routes/rfc003/handlers/mod.rs rename to cnd/src/http_api/routes/rfc003/handlers.rs diff --git a/cnd/src/network/mod.rs b/cnd/src/network.rs similarity index 100% rename from cnd/src/network/mod.rs rename to cnd/src/network.rs diff --git a/cnd/src/network/protocols/mod.rs b/cnd/src/network/protocols.rs similarity index 100% rename from cnd/src/network/protocols/mod.rs rename to cnd/src/network/protocols.rs diff --git a/cnd/src/network/protocols/announce/mod.rs b/cnd/src/network/protocols/announce.rs similarity index 100% rename from cnd/src/network/protocols/announce/mod.rs rename to cnd/src/network/protocols/announce.rs diff --git a/cnd/src/swap_protocols/mod.rs b/cnd/src/swap_protocols.rs similarity index 100% rename from cnd/src/swap_protocols/mod.rs rename to cnd/src/swap_protocols.rs diff --git a/cnd/src/swap_protocols/ledger/mod.rs b/cnd/src/swap_protocols/ledger.rs similarity index 100% rename from cnd/src/swap_protocols/ledger/mod.rs rename to cnd/src/swap_protocols/ledger.rs diff --git a/cnd/src/swap_protocols/rfc003/mod.rs b/cnd/src/swap_protocols/rfc003.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/mod.rs rename to cnd/src/swap_protocols/rfc003.rs diff --git a/cnd/src/swap_protocols/rfc003/actions/mod.rs b/cnd/src/swap_protocols/rfc003/actions.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/actions/mod.rs rename to cnd/src/swap_protocols/rfc003/actions.rs diff --git a/cnd/src/swap_protocols/rfc003/alice/mod.rs b/cnd/src/swap_protocols/rfc003/alice.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/alice/mod.rs rename to cnd/src/swap_protocols/rfc003/alice.rs diff --git a/cnd/src/swap_protocols/rfc003/alice/actions/mod.rs b/cnd/src/swap_protocols/rfc003/alice/actions.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/alice/actions/mod.rs rename to cnd/src/swap_protocols/rfc003/alice/actions.rs diff --git a/cnd/src/swap_protocols/rfc003/bitcoin/mod.rs b/cnd/src/swap_protocols/rfc003/bitcoin.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/bitcoin/mod.rs rename to cnd/src/swap_protocols/rfc003/bitcoin.rs diff --git a/cnd/src/swap_protocols/rfc003/bob/mod.rs b/cnd/src/swap_protocols/rfc003/bob.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/bob/mod.rs rename to cnd/src/swap_protocols/rfc003/bob.rs diff --git a/cnd/src/swap_protocols/rfc003/bob/actions/mod.rs b/cnd/src/swap_protocols/rfc003/bob/actions.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/bob/actions/mod.rs rename to cnd/src/swap_protocols/rfc003/bob/actions.rs diff --git a/cnd/src/swap_protocols/rfc003/ethereum/mod.rs b/cnd/src/swap_protocols/rfc003/ethereum.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/ethereum/mod.rs rename to cnd/src/swap_protocols/rfc003/ethereum.rs diff --git a/cnd/src/swap_protocols/rfc003/events/mod.rs b/cnd/src/swap_protocols/rfc003/events.rs similarity index 100% rename from cnd/src/swap_protocols/rfc003/events/mod.rs rename to cnd/src/swap_protocols/rfc003/events.rs From 7dddc07deae9c17b27e389a1c121e9b4ac9ec5ca Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2020 14:13:00 +0000 Subject: [PATCH 128/145] Bump paste from 0.1.7 to 0.1.8 Bumps [paste](https://github.com/dtolnay/paste) from 0.1.7 to 0.1.8. - [Release notes](https://github.com/dtolnay/paste/releases) - [Commits](https://github.com/dtolnay/paste/compare/0.1.7...0.1.8) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4eb2d389f6..947cef4135 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2626,9 +2626,9 @@ dependencies = [ [[package]] name = "paste" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e1afe738d71b1ebab5f1207c055054015427dbfc7bbe9ee1266894156ec046" +checksum = "8292c1e1e81ddb552c4c90c36af201a0ce7e34995f55f0480f01052f242811c9" dependencies = [ "paste-impl", "proc-macro-hack", @@ -2636,9 +2636,9 @@ dependencies = [ [[package]] name = "paste-impl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4dc4a7f6f743211c5aab239640a65091535d97d43d92a52bca435a640892bb" +checksum = "5e9c43f2645f06ee452544ad032886a75f3d1797b9487dcadcae9100ba58a51c" dependencies = [ "proc-macro-hack", "proc-macro2 1.0.9", From cd6f08822787ed3212686607d42b11d23790a75b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2020 16:07:14 +0000 Subject: [PATCH 129/145] Bump prettier from 2.0.1 to 2.0.2 in /api_tests Bumps [prettier](https://github.com/prettier/prettier) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.0.1...2.0.2) Signed-off-by: dependabot-preview[bot] --- api_tests/package.json | 2 +- api_tests/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index 7537161709..0918c4f776 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -48,7 +48,7 @@ "jest": "^25.1.0", "js-sha256": "^0.9.0", "log4js": "^6.1.2", - "prettier": "^2.0.1", + "prettier": "^2.0.2", "rimraf": "^3.0.2", "satoshi-bitcoin": "^1.0.4", "smack-my-jasmine-up": "^0.0.3", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index dce64d1a51..bcc32c86e3 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -4089,10 +4089,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prettier@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.1.tgz#3f00ac71263be34684b2b2c8d7e7f63737592dac" - integrity sha512-piXGBcY1zoFOG0MvHpNE5reAGseLmaCRifQ/fmfF49BcYkInEs/naD/unxGNAeOKFA5+JxVrPyMvMlpzcd20UA== +prettier@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" + integrity sha512-5xJQIPT8BraI7ZnaDwSbu5zLrB6vvi8hVV58yHQ+QK64qrY40dULy0HSRlQ2/2IdzeBpjhDkqdcFBnFeDEMVdg== pretty-format@^25.1.0: version "25.1.0" From 9cdc8acebfbd4b86671976569869f2ec3288fd25 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 24 Mar 2020 15:57:19 +1100 Subject: [PATCH 130/145] Upgrade SDK to 0.15.0 --- api_tests/package.json | 2 +- api_tests/src/actors/actor.ts | 41 ++++--- api_tests/src/actors/defaults.ts | 135 ++++++++++++++++++++++++ api_tests/tests/dry/lightning_routes.ts | 30 +++++- api_tests/yarn.lock | 21 +++- 5 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 api_tests/src/actors/defaults.ts diff --git a/api_tests/package.json b/api_tests/package.json index 7537161709..ac7d87d88f 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -42,7 +42,7 @@ "chai-json-schema": "^1.5.0", "chai-string": "^1.5.0", "chai-subset": "^1.6.0", - "comit-sdk": "^0.14.0", + "comit-sdk": "^0.15.0", "ethers": "^4.0.46", "get-port": "^5.1.1", "jest": "^25.1.0", diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 273738f82b..d4312caf1c 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -7,8 +7,9 @@ import { LedgerAction, Swap, SwapDetails, + TransactionStatus, + Transaction, } from "comit-sdk"; -import { parseEther } from "ethers/utils"; import { Logger } from "log4js"; import { E2ETestActorConfig } from "../config"; import "../setup_chai"; @@ -21,6 +22,7 @@ import { Actors } from "./index"; import { LndInstance } from "../ledgers/lnd_instance"; import { sha256 } from "js-sha256"; import { InvoiceState } from "@radar/lnrpc"; +import { parseEther } from "ethers/utils"; declare var global: HarnessGlobal; @@ -238,11 +240,22 @@ export class Actor { throw new Error("Cannot deploy htlc for nonexistent swap"); } - const txid = await this.swap.deploy(Actor.defaultActionConfig); + const transaction = await this.swap.deploy(Actor.defaultActionConfig); + let transactionId; + if (transaction instanceof Transaction) { + const status = await transaction.status(); + transactionId = transaction.id; + if (status === TransactionStatus.Failed) { + throw new Error(`Transaction ${transactionId} failed`); + } + } else { + transactionId = transaction; + } + this.logger.debug( "Deployed htlc for swap %s in %s", this.swap.self, - txid + transactionId ); const entity = await this.swap.fetchDetails(); @@ -296,16 +309,18 @@ export class Actor { } ); response.data.payload.gas_limit = hexGasLimit; - const txid = await this.swap.doLedgerAction(response.data); - this.logger.debug( - "Deployed with low gas swap %s in %s", - this.swap.self, - txid - ); - - const status = await this.wallets.ethereum.getTransactionStatus(txid); - if (status !== 0) { - throw new Error("Deploy with low gas transaction was successful."); + const transaction = await this.swap.doLedgerAction(response.data); + if (transaction instanceof Transaction) { + const status = await transaction.status(); + if (status !== TransactionStatus.Failed) { + throw new Error( + "Deploy with low gas transaction was successful." + ); + } + } else { + throw new Error( + "Internal error: Transaction class expected for Ethereum." + ); } } diff --git a/api_tests/src/actors/defaults.ts b/api_tests/src/actors/defaults.ts new file mode 100644 index 0000000000..277f0c5a24 --- /dev/null +++ b/api_tests/src/actors/defaults.ts @@ -0,0 +1,135 @@ +import { HarnessGlobal } from "../utils"; +import { + HalightLightningBitcoinHanEthereumEtherRequestBody, + HalightLightningBitcoinHerc20EthereumErc20RequestBody, + HanEthereumEtherHalightLightningBitcoinRequestBody, + Herc20EthereumErc20HalightLightningBitcoinRequestBody, + HanEthereumEtherRequestParams, + HalightLightningBitcoinRequestParams, + Herc20EthereumErc20RequestParams, + Peer, +} from "comit-sdk"; + +declare var global: HarnessGlobal; + +function defaultHanEthereumEtherRequestParams( + absoluteExpiry: number +): HanEthereumEtherRequestParams { + return { + amount: "5000000000000000000", + chain_id: 17, + identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", + absolute_expiry: absoluteExpiry, + }; +} + +function defaultHalightLightningBitcoinRequestParams( + cltvExpiry: number, + lndPubkey: string +): HalightLightningBitcoinRequestParams { + return { + amount: "10000000", + network: "regtest", + identity: lndPubkey, + cltv_expiry: cltvExpiry, + }; +} + +function defaultHerc20EthereumErc20RequestParams( + absoluteExpiry: number +): Herc20EthereumErc20RequestParams { + return { + amount: "9000000000000000000", + contract_address: "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280", + chain_id: 17, + identity: "0x00a329c0648769a73afac7f9381e08fb43dbea72", + absolute_expiry: absoluteExpiry, + }; +} +export function defaultHanEthereumEtherHalightLightningBitcoin( + lndPubkey: string, + peer: Peer +): HanEthereumEtherHalightLightningBitcoinRequestBody { + const { + alphaAbsoluteExpiry, + betaCltvExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHanEthereumEtherRequestParams(alphaAbsoluteExpiry), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + lndPubkey + ), + role: "Alice", + peer, + }; +} + +export function defaultHerc20EthereumErc20HalightLightningBitcoin( + lndPubkey: string, + peer: Peer +): Herc20EthereumErc20HalightLightningBitcoinRequestBody { + const { + alphaAbsoluteExpiry, + betaCltvExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHerc20EthereumErc20RequestParams(alphaAbsoluteExpiry), + beta: defaultHalightLightningBitcoinRequestParams( + betaCltvExpiry, + lndPubkey + ), + role: "Alice", + peer, + }; +} + +export function defaultHalightLightningBitcoinHanEthereumEther( + lndPubkey: string, + peer: Peer +): HalightLightningBitcoinHanEthereumEtherRequestBody { + const { + alphaCltvExpiry, + betaAbsoluteExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHalightLightningBitcoinRequestParams( + alphaCltvExpiry, + lndPubkey + ), + beta: defaultHanEthereumEtherRequestParams(betaAbsoluteExpiry), + role: "Alice", + peer, + }; +} + +export function defaultHalightLightningBitcoinHerc20EthereumErc20( + lndPubkey: string, + peer: Peer +): HalightLightningBitcoinHerc20EthereumErc20RequestBody { + const { + alphaCltvExpiry, + betaAbsoluteExpiry, + } = defaultHalightHanHerc20Expiries(); + return { + alpha: defaultHalightLightningBitcoinRequestParams( + alphaCltvExpiry, + lndPubkey + ), + beta: defaultHerc20EthereumErc20RequestParams(betaAbsoluteExpiry), + role: "Alice", + peer, + }; +} + +function defaultHalightHanHerc20Expiries() { + const alphaAbsoluteExpiry = Math.round(Date.now() / 1000) + 8; + const betaAbsoluteExpiry = Math.round(Date.now() / 1000) + 3; + + return { + alphaAbsoluteExpiry, + betaAbsoluteExpiry, + alphaCltvExpiry: 35, + betaCltvExpiry: 35, + }; +} diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index ae5e4743f0..9041f452a2 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -4,6 +4,12 @@ import { expect } from "chai"; import { oneActorTest } from "../../src/actor_test"; +import { + defaultHalightLightningBitcoinHanEthereumEther, + defaultHalightLightningBitcoinHerc20EthereumErc20, + defaultHanEthereumEtherHalightLightningBitcoin, + defaultHerc20EthereumErc20HalightLightningBitcoin, +} from "../../src/actors/defaults"; // ******************************************** // // Lightning routes // @@ -12,7 +18,11 @@ describe("Lightning routes tests", () => { it( "lightning-routes-post-eth-lnbtc-return-400", oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHanEthereumEtherHalightLightningBitcoin(); + const promise = alice.cnd.createHanEthereumEtherHalightLightningBitcoin( + defaultHanEthereumEtherHalightLightningBitcoin("", { + peer_id: "", + }) + ); return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", @@ -25,7 +35,11 @@ describe("Lightning routes tests", () => { it( "lightning-routes-post-erc20-lnbtc-return-400", oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin(); + const promise = alice.cnd.createHerc20EthereumErc20HalightLightningBitcoin( + defaultHerc20EthereumErc20HalightLightningBitcoin("", { + peer_id: "", + }) + ); return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", @@ -38,7 +52,11 @@ describe("Lightning routes tests", () => { it( "lightning-routes-post-lnbtc-eth-return-400", oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther(); + const promise = alice.cnd.createHalightLightningBitcoinHanEthereumEther( + defaultHalightLightningBitcoinHanEthereumEther("", { + peer_id: "", + }) + ); return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", @@ -51,7 +69,11 @@ describe("Lightning routes tests", () => { it( "lightning-routes-post-lnbtc-erc20-return-400", oneActorTest(async ({ alice }) => { - const promise = alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20(); + const promise = alice.cnd.createHalightLightningBitcoinHerc20EthereumErc20( + defaultHalightLightningBitcoinHerc20EthereumErc20("", { + peer_id: "", + }) + ); return expect(promise).to.eventually.be.rejected.then((error) => { expect(error).to.have.property( "message", diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index dce64d1a51..3af039d302 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -402,6 +402,17 @@ pkg-dir "^2.0.0" ts-protoc-gen "^0.8.0" +"@radar/lnrpc@^0.9.1-beta": + version "0.9.1-beta" + resolved "https://registry.yarnpkg.com/@radar/lnrpc/-/lnrpc-0.9.1-beta.tgz#96283000a737a70fdf893e029d664e9845363585" + integrity sha512-W81HcTUAc1MyO96oiUscIXJpDH+CTHPZLr3WObte/fPuCDbre3NkIo3njfD7WTzo2hkLy9LgqcYx6aYD1ex/yQ== + dependencies: + "@grpc/proto-loader" "^0.4.0" + "@types/google-protobuf" "^3.2.7" + grpc "^1.24.2" + pkg-dir "^2.0.0" + ts-protoc-gen "^0.8.0" + "@sinonjs/commons@^1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" @@ -1533,12 +1544,12 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comit-sdk@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.14.0.tgz#8183e92ab6543b32a19883372bee61ece3faf741" - integrity sha512-cyGw0yvDIQJUntuV5h4+XckInZ6iu6NqS8dnw3QIiQjXz7AskFfF5WotTeRt7LnqYtbZWz2fnRTEChvf2/R3Bg== +comit-sdk@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.0.tgz#d825b19e89bd5920bb5c7f1b0907259d6b9f93af" + integrity sha512-JsBkboA2gI4HT/2zCKqU9vV4rBKxX9PkJsM8RmH2EPXIgpeSZ4S7+jRha88k0Kiu7RvdHp84HvkqrVjmDbWfFw== dependencies: - "@radar/lnrpc" "^0.9.0-beta" + "@radar/lnrpc" "^0.9.1-beta" axios "^0.19.0" bcoin "https://github.com/bcoin-org/bcoin#2496acc7a98a43f00a7b5728eb256877c1bbf001" bignumber.js "^9.0.0" From 6a68a20fbfbde2bb2a00d9620ebdecfe8f288f3e Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Tue, 24 Mar 2020 16:00:23 +1100 Subject: [PATCH 131/145] Move defaults to common file --- api_tests/src/actors/actor.ts | 86 +++----------------------------- api_tests/src/actors/defaults.ts | 81 ++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index d4312caf1c..58e7519f9a 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -16,15 +16,18 @@ import "../setup_chai"; import { Asset, AssetKind, toKey, toKind } from "../asset"; import { CndInstance } from "../cnd/cnd_instance"; import { Ledger, LedgerKind } from "../ledgers/ledger"; -import { HarnessGlobal, LedgerConfig, sleep } from "../utils"; +import { LedgerConfig, sleep } from "../utils"; import { Wallet, Wallets } from "../wallets"; import { Actors } from "./index"; import { LndInstance } from "../ledgers/lnd_instance"; import { sha256 } from "js-sha256"; import { InvoiceState } from "@radar/lnrpc"; -import { parseEther } from "ethers/utils"; - -declare var global: HarnessGlobal; +import { + defaultAssetDescription, + defaultExpiryTimes, + defaultLedgerDescriptionForLedger, + defaultLedgerKindForAsset, +} from "./defaults"; export class Actor { public static defaultActionConfig = { @@ -966,78 +969,3 @@ export class Actor { } } } - -function defaultLedgerKindForAsset(asset: AssetKind): LedgerKind { - switch (asset) { - case AssetKind.Bitcoin: - return LedgerKind.Bitcoin; - case AssetKind.Ether: - return LedgerKind.Ethereum; - case AssetKind.Erc20: - return LedgerKind.Ethereum; - } -} - -/** - * WIP as the cnd REST API routes for lightning are not yet defined. - * @param ledger - * @returns The ledger formatted as needed for the request body to cnd HTTP API on the lightning route. - */ -function defaultLedgerDescriptionForLedger(ledger: LedgerKind): Ledger { - switch (ledger) { - case LedgerKind.Lightning: { - return { - name: LedgerKind.Lightning, - }; - } - case LedgerKind.Bitcoin: { - return { - name: LedgerKind.Bitcoin, - network: "regtest", - }; - } - case LedgerKind.Ethereum: { - return { - name: LedgerKind.Ethereum, - chain_id: 17, - }; - } - } -} - -function defaultAssetDescription(asset: AssetKind, ledger: LedgerKind): Asset { - switch (asset) { - case AssetKind.Bitcoin: { - return { - name: AssetKind.Bitcoin, - ledger, - quantity: "10000000", - }; - } - case AssetKind.Ether: { - return { - name: AssetKind.Ether, - ledger, - quantity: parseEther("10").toString(), - }; - } - case AssetKind.Erc20: { - return { - name: AssetKind.Erc20, - ledger, - quantity: parseEther("100").toString(), - token_contract: global.tokenContract, - }; - } - } -} - -function defaultExpiryTimes() { - const alphaExpiry = Math.round(Date.now() / 1000) + 8; - const betaExpiry = Math.round(Date.now() / 1000) + 3; - - return { - alpha_expiry: alphaExpiry, - beta_expiry: betaExpiry, - }; -} diff --git a/api_tests/src/actors/defaults.ts b/api_tests/src/actors/defaults.ts index 277f0c5a24..ecd14c98f6 100644 --- a/api_tests/src/actors/defaults.ts +++ b/api_tests/src/actors/defaults.ts @@ -9,6 +9,9 @@ import { Herc20EthereumErc20RequestParams, Peer, } from "comit-sdk"; +import { Asset, AssetKind } from "../asset"; +import { Ledger, LedgerKind } from "../ledgers/ledger"; +import { parseEther } from "ethers/utils"; declare var global: HarnessGlobal; @@ -133,3 +136,81 @@ function defaultHalightHanHerc20Expiries() { betaCltvExpiry: 35, }; } + +export function defaultLedgerKindForAsset(asset: AssetKind): LedgerKind { + switch (asset) { + case AssetKind.Bitcoin: + return LedgerKind.Bitcoin; + case AssetKind.Ether: + return LedgerKind.Ethereum; + case AssetKind.Erc20: + return LedgerKind.Ethereum; + } +} + +/** + * WIP as the cnd REST API routes for lightning are not yet defined. + * @param ledger + * @returns The ledger formatted as needed for the request body to cnd HTTP API on the lightning route. + */ +export function defaultLedgerDescriptionForLedger(ledger: LedgerKind): Ledger { + switch (ledger) { + case LedgerKind.Lightning: { + return { + name: LedgerKind.Lightning, + }; + } + case LedgerKind.Bitcoin: { + return { + name: LedgerKind.Bitcoin, + network: "regtest", + }; + } + case LedgerKind.Ethereum: { + return { + name: LedgerKind.Ethereum, + chain_id: 17, + }; + } + } +} + +export function defaultAssetDescription( + asset: AssetKind, + ledger: LedgerKind +): Asset { + switch (asset) { + case AssetKind.Bitcoin: { + return { + name: AssetKind.Bitcoin, + ledger, + quantity: "10000000", + }; + } + case AssetKind.Ether: { + return { + name: AssetKind.Ether, + ledger, + quantity: parseEther("10").toString(), + }; + } + case AssetKind.Erc20: { + return { + name: AssetKind.Erc20, + ledger, + quantity: parseEther("100").toString(), + token_contract: global.tokenContract, + }; + } + } +} + +export function defaultExpiryTimes() { + const alphaExpiry = Math.round(Date.now() / 1000) + 8; + const betaExpiry = Math.round(Date.now() / 1000) + 3; + + return { + alpha_expiry: alphaExpiry, + beta_expiry: betaExpiry, + }; +} From f71a85bb485d59d1e4a870b7e4e9185aa08b87ea Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 25 Mar 2020 11:33:19 +1100 Subject: [PATCH 132/145] SDK now returns the http problem, use it --- api_tests/tests/dry/lightning_routes.ts | 36 +++++++++---------------- 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index 9041f452a2..d5c92ab8bc 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -23,12 +23,9 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejected.then((error) => { - expect(error).to.have.property( - "message", - "Request failed with status code 400" - ); - }); + return expect(promise).to.eventually.be.rejectedWith( + "Route not yet supported" + ); }) ); @@ -40,12 +37,9 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejected.then((error) => { - expect(error).to.have.property( - "message", - "Request failed with status code 400" - ); - }); + return expect(promise).to.eventually.be.rejectedWith( + "Route not yet supported" + ); }) ); @@ -57,12 +51,9 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejected.then((error) => { - expect(error).to.have.property( - "message", - "Request failed with status code 400" - ); - }); + return expect(promise).to.eventually.be.rejectedWith( + "Route not yet supported" + ); }) ); @@ -74,12 +65,9 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejected.then((error) => { - expect(error).to.have.property( - "message", - "Request failed with status code 400" - ); - }); + return expect(promise).to.eventually.be.rejectedWith( + "Route not yet supported" + ); }) ); }); From 709935c7f43a3a354edc4892d60db9f43ab7130b Mon Sep 17 00:00:00 2001 From: rishflab Date: Mon, 16 Mar 2020 16:34:46 +1100 Subject: [PATCH 133/145] Fix ethereum config validation Add custom deserialisation to handle string returned from Ethereum's "json-rpc" API. Log details of Ethereum connection errors. Closes #2256 --- cnd/src/btsieve/ethereum/web3_connector.rs | 6 +++--- cnd/src/jsonrpc.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cnd/src/btsieve/ethereum/web3_connector.rs b/cnd/src/btsieve/ethereum/web3_connector.rs index 565d73771b..ad1b3e44f8 100644 --- a/cnd/src/btsieve/ethereum/web3_connector.rs +++ b/cnd/src/btsieve/ethereum/web3_connector.rs @@ -81,13 +81,13 @@ impl ReceiptByHash for Web3Connector { #[async_trait] impl FetchNetworkId for Web3Connector { async fn network_id(&self) -> anyhow::Result { - let chain_id: ChainId = self + let chain_id: String = self .client - .send::, ChainId>(jsonrpc::Request::new("net_version", vec![])) + .send::, String>(jsonrpc::Request::new("net_version", vec![])) .await?; tracing::debug!("Fetched net_version from web3: {:?}", chain_id); - Ok(chain_id) + Ok(ChainId::from(chain_id.parse::()?)) } } diff --git a/cnd/src/jsonrpc.rs b/cnd/src/jsonrpc.rs index dcb2e560a7..d9db1a52bf 100644 --- a/cnd/src/jsonrpc.rs +++ b/cnd/src/jsonrpc.rs @@ -11,7 +11,7 @@ pub struct Client { pub enum Error { #[error("json-rpc request failed with code {code}: {message}")] JsonRpc { code: i64, message: String }, - #[error("connection error")] + #[error("connection error: {0}")] Connection(#[from] reqwest::Error), } From dcd3a6eb3de963ec587d9153d8911e4c9f1afcff Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 25 Mar 2020 13:30:21 +1100 Subject: [PATCH 134/145] Use jest's `expect` --- api_tests/tests/dry/lightning_routes.ts | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/api_tests/tests/dry/lightning_routes.ts b/api_tests/tests/dry/lightning_routes.ts index d5c92ab8bc..21ff118bb6 100644 --- a/api_tests/tests/dry/lightning_routes.ts +++ b/api_tests/tests/dry/lightning_routes.ts @@ -2,7 +2,6 @@ * @logDir lightning_routes */ -import { expect } from "chai"; import { oneActorTest } from "../../src/actor_test"; import { defaultHalightLightningBitcoinHanEthereumEther, @@ -23,9 +22,7 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejectedWith( - "Route not yet supported" - ); + await expect(promise).rejects.toThrow("Route not yet supported"); }) ); @@ -37,9 +34,7 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejectedWith( - "Route not yet supported" - ); + await expect(promise).rejects.toThrow("Route not yet supported"); }) ); @@ -51,9 +46,7 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejectedWith( - "Route not yet supported" - ); + await expect(promise).rejects.toThrow("Route not yet supported"); }) ); @@ -65,9 +58,7 @@ describe("Lightning routes tests", () => { peer_id: "", }) ); - return expect(promise).to.eventually.be.rejectedWith( - "Route not yet supported" - ); + await expect(promise).rejects.toThrow("Route not yet supported"); }) ); }); From 8066d399dcac981d46a51fc4636b5d44de45b602 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 25 Mar 2020 14:33:34 +1100 Subject: [PATCH 135/145] Temporary hack to stop SDK throwing when checking status --- api_tests/src/actors/actor.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 58e7519f9a..0a8b4b170b 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -246,6 +246,12 @@ export class Actor { const transaction = await this.swap.deploy(Actor.defaultActionConfig); let transactionId; if (transaction instanceof Transaction) { + { + // Temporary hack until comit-sdk can return a status for unconfirmed failed transactions + await this.wallets.ethereum.getTransactionStatus( + transaction.id + ); + } const status = await transaction.status(); transactionId = transaction.id; if (status === TransactionStatus.Failed) { @@ -314,6 +320,12 @@ export class Actor { response.data.payload.gas_limit = hexGasLimit; const transaction = await this.swap.doLedgerAction(response.data); if (transaction instanceof Transaction) { + { + // Temporary hack until comit-sdk can return a status for unconfirmed failed transactions + await this.wallets.ethereum.getTransactionStatus( + transaction.id + ); + } const status = await transaction.status(); if (status !== TransactionStatus.Failed) { throw new Error( From 9c3313c2771ee734fff85b0be8ed831b50ce0d3a Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Mar 2020 17:06:50 +1100 Subject: [PATCH 136/145] Don't implement Deref and DerefMut on LedgerStates We don't need to do this if we only implement the traits on one struct anyway. --- cnd/src/swap_protocols/ledger_states.rs | 34 +++++-------------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/cnd/src/swap_protocols/ledger_states.rs b/cnd/src/swap_protocols/ledger_states.rs index e7550cb532..9e794a68b3 100644 --- a/cnd/src/swap_protocols/ledger_states.rs +++ b/cnd/src/swap_protocols/ledger_states.rs @@ -4,11 +4,7 @@ use crate::swap_protocols::{ swap_id::SwapId, }; use async_trait::async_trait; -use std::{ - any::Any, - collections::HashMap, - ops::{Deref, DerefMut}, -}; +use std::{any::Any, collections::HashMap}; use tokio::sync::Mutex; #[derive(Default, Debug)] @@ -17,25 +13,23 @@ pub struct LedgerStates { } #[async_trait] -impl Insert for L +impl Insert for LedgerStates where - L: DerefMut>>> + Send + Sync + 'static, S: Send + 'static, { async fn insert(&self, key: SwapId, value: S) { - let mut states = self.lock().await; + let mut states = self.states.lock().await; states.insert(key, Box::new(value)); } } #[async_trait] -impl Get for L +impl Get for LedgerStates where - L: DerefMut>>> + Send + Sync + 'static, S: Clone + Send + 'static, { async fn get(&self, key: &SwapId) -> anyhow::Result> { - let states = self.lock().await; + let states = self.states.lock().await; match states.get(key) { Some(state) => match state.downcast_ref::() { Some(state) => Ok(Some(state.clone())), @@ -47,16 +41,15 @@ where } #[async_trait] -impl Update, SwapEvent> for L +impl Update, SwapEvent> for LedgerStates where - L: DerefMut>>> + Send + Sync + 'static, LedgerState: 'static, A: Send, H: Send, T: Send, { async fn update(&self, key: &SwapId, event: SwapEvent) { - let mut states = self.lock().await; + let mut states = self.states.lock().await; let ledger_state = match states .get_mut(key) .and_then(|state| state.downcast_mut::>()) @@ -81,19 +74,6 @@ where } } -impl Deref for LedgerStates { - type Target = Mutex>>; - fn deref(&self) -> &Self::Target { - &self.states - } -} - -impl DerefMut for LedgerStates { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.states - } -} - #[cfg(test)] mod tests { use super::*; From e169b9edae5a8f450151b572cce5839baefed950 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Wed, 25 Mar 2020 17:08:50 +1100 Subject: [PATCH 137/145] Remove S type parameter from state::Update trait The trait itself never references this type parameter, hence it doesn't need to include it. --- cnd/src/swap_protocols/ledger_states.rs | 2 +- cnd/src/swap_protocols/rfc003/create_swap.rs | 3 +-- cnd/src/swap_protocols/state.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cnd/src/swap_protocols/ledger_states.rs b/cnd/src/swap_protocols/ledger_states.rs index 9e794a68b3..61e65c9ae2 100644 --- a/cnd/src/swap_protocols/ledger_states.rs +++ b/cnd/src/swap_protocols/ledger_states.rs @@ -41,7 +41,7 @@ where } #[async_trait] -impl Update, SwapEvent> for LedgerStates +impl Update> for LedgerStates where LedgerState: 'static, A: Send, diff --git a/cnd/src/swap_protocols/rfc003/create_swap.rs b/cnd/src/swap_protocols/rfc003/create_swap.rs index 660904d72f..45f3771f97 100644 --- a/cnd/src/swap_protocols/rfc003/create_swap.rs +++ b/cnd/src/swap_protocols/rfc003/create_swap.rs @@ -43,8 +43,7 @@ pub async fn create_watcher( + HtlcDeployed + HtlcRedeemed + HtlcRefunded, - S: state::Update, SwapEvent> - + state::Insert>, + S: state::Update> + state::Insert>, L: Clone, A: Ord + Clone, H: Clone, diff --git a/cnd/src/swap_protocols/state.rs b/cnd/src/swap_protocols/state.rs index 6ce3469777..6ffd26af6d 100644 --- a/cnd/src/swap_protocols/state.rs +++ b/cnd/src/swap_protocols/state.rs @@ -12,6 +12,6 @@ pub trait Get: Send + Sync + 'static { } #[async_trait] -pub trait Update: Send + Sync + 'static { +pub trait Update: Send + Sync + 'static { async fn update(&self, key: &SwapId, update: E); } From fb2b15ea1f672c438de031f50ec4eafd0a1451bc Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2020 14:12:31 +0000 Subject: [PATCH 138/145] Bump regex from 1.3.5 to 1.3.6 Bumps [regex](https://github.com/rust-lang/regex) from 1.3.5 to 1.3.6. - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.3.5...1.3.6) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 947cef4135..52e9528b5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3012,9 +3012,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.3.5" +version = "1.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8900ebc1363efa7ea1c399ccc32daed870b4002651e0bed86e72d501ebbe0048" +checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3" dependencies = [ "aho-corasick", "memchr", From 9ce08b3e9c1cf4a02563254dde06a8f4823f4013 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2020 15:12:28 +0000 Subject: [PATCH 139/145] Bump @types/node from 13.9.3 to 13.9.4 in /api_tests Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 13.9.3 to 13.9.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot-preview[bot] --- api_tests/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 181ee731c9..e4c5b9d040 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -562,9 +562,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*", "@types/node@^13.9": - version "13.9.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.3.tgz#6356df2647de9eac569f9a52eda3480fa9e70b4d" - integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA== + version "13.9.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.4.tgz#63c58e67999bfbfa688dd49ed84639b01b543606" + integrity sha512-uzaaDXey/NI2l7kU+xCgWu852Dh/zmf6ZKApc0YQEQpY4DaiZFmLN29E6SLHJfSedj3iNWAndSwfSBpEDadJfg== "@types/node@^10.1.0": version "10.17.17" From fdb2508c49cebdca95234745c56eb04101fa471b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 26 Mar 2020 10:14:21 +1100 Subject: [PATCH 140/145] Fix handler queueing We currently have a mix of queue'ing logic in the handler. Fix to use `VecDeque` for both the `events` queue and the `dial_queue`. Use these queues as FIFO, push to the back and pop from the front. --- cnd/src/network/protocols/announce/handler.rs | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/cnd/src/network/protocols/announce/handler.rs b/cnd/src/network/protocols/announce/handler.rs index 0489a84ffc..b7b997add0 100644 --- a/cnd/src/network/protocols/announce/handler.rs +++ b/cnd/src/network/protocols/announce/handler.rs @@ -19,7 +19,7 @@ use std::{ pub struct Handler { /// Pending events to yield. #[derivative(Debug = "ignore")] - events: Vec, + events: VecDeque, /// Queue of outbound substreams to open. dial_queue: VecDeque, } @@ -27,7 +27,7 @@ pub struct Handler { impl Default for Handler { fn default() -> Self { Handler { - events: vec![], + events: VecDeque::new(), dial_queue: VecDeque::new(), } } @@ -67,7 +67,8 @@ impl ProtocolsHandler for Handler { &mut self, sender: >::Output, ) { - self.events.push(HandlerEvent::AwaitingConfirmation(sender)) + self.events + .push_back(HandlerEvent::AwaitingConfirmation(sender)) } fn inject_fully_negotiated_outbound( @@ -76,11 +77,11 @@ impl ProtocolsHandler for Handler { _info: Self::OutboundOpenInfo, ) { self.events - .push(HandlerEvent::ReceivedConfirmation(confirmed)); + .push_back(HandlerEvent::ReceivedConfirmation(confirmed)); } fn inject_event(&mut self, event: Self::InEvent) { - self.dial_queue.push_front(event); + self.dial_queue.push_back(event); } fn inject_dial_upgrade_error( @@ -90,7 +91,8 @@ impl ProtocolsHandler for Handler { >::Error, >, ) { - self.events.push(HandlerEvent::Error(Error::Upgrade(err))); + self.events + .push_back(HandlerEvent::Error(Error::Upgrade(err))); } fn connection_keep_alive(&self) -> KeepAlive { @@ -109,21 +111,18 @@ impl ProtocolsHandler for Handler { Self::Error, >, > { - if !self.events.is_empty() { - let event = self.events.remove(0); + if let Some(event) = self.events.pop_front() { if let HandlerEvent::Error(err) = event { return Poll::Ready(ProtocolsHandlerEvent::Close(err)); }; return Poll::Ready(ProtocolsHandlerEvent::Custom(event)); } - if !self.dial_queue.is_empty() { - if let Some(upgrade) = self.dial_queue.remove(0) { - return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { - protocol: SubstreamProtocol::new(upgrade), - info: (), - }); - } + if let Some(upgrade) = self.dial_queue.pop_front() { + return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { + protocol: SubstreamProtocol::new(upgrade), + info: (), + }); } Poll::Pending From 0918d991589aa2e6f21a7d37ff04755ac7e7b39a Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Wed, 25 Mar 2020 15:21:07 +1100 Subject: [PATCH 141/145] Upgrade to comit-sdk 0.15.1 --- api_tests/package.json | 2 +- api_tests/src/actors/actor.ts | 16 ++-------------- api_tests/yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/api_tests/package.json b/api_tests/package.json index ac7d87d88f..582fd67fc0 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -42,7 +42,7 @@ "chai-json-schema": "^1.5.0", "chai-string": "^1.5.0", "chai-subset": "^1.6.0", - "comit-sdk": "^0.15.0", + "comit-sdk": "^0.15.1", "ethers": "^4.0.46", "get-port": "^5.1.1", "jest": "^25.1.0", diff --git a/api_tests/src/actors/actor.ts b/api_tests/src/actors/actor.ts index 0a8b4b170b..95fbdb20d6 100644 --- a/api_tests/src/actors/actor.ts +++ b/api_tests/src/actors/actor.ts @@ -246,13 +246,7 @@ export class Actor { const transaction = await this.swap.deploy(Actor.defaultActionConfig); let transactionId; if (transaction instanceof Transaction) { - { - // Temporary hack until comit-sdk can return a status for unconfirmed failed transactions - await this.wallets.ethereum.getTransactionStatus( - transaction.id - ); - } - const status = await transaction.status(); + const status = await transaction.status(1); transactionId = transaction.id; if (status === TransactionStatus.Failed) { throw new Error(`Transaction ${transactionId} failed`); @@ -320,13 +314,7 @@ export class Actor { response.data.payload.gas_limit = hexGasLimit; const transaction = await this.swap.doLedgerAction(response.data); if (transaction instanceof Transaction) { - { - // Temporary hack until comit-sdk can return a status for unconfirmed failed transactions - await this.wallets.ethereum.getTransactionStatus( - transaction.id - ); - } - const status = await transaction.status(); + const status = await transaction.status(1); if (status !== TransactionStatus.Failed) { throw new Error( "Deploy with low gas transaction was successful." diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock index 3af039d302..e82821a535 100644 --- a/api_tests/yarn.lock +++ b/api_tests/yarn.lock @@ -1544,10 +1544,10 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -comit-sdk@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.0.tgz#d825b19e89bd5920bb5c7f1b0907259d6b9f93af" - integrity sha512-JsBkboA2gI4HT/2zCKqU9vV4rBKxX9PkJsM8RmH2EPXIgpeSZ4S7+jRha88k0Kiu7RvdHp84HvkqrVjmDbWfFw== +comit-sdk@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/comit-sdk/-/comit-sdk-0.15.1.tgz#2ccc262a9ba5ee86999284c773f34d659b967b8d" + integrity sha512-5oKJ1Ns4/9qei9AzzeeZOrb36Qb0yewpKQyvV/odCBQrMqbXHhcrGl0ArC6X5N7dED0IDEAI7J4G2qrVCsG1Cg== dependencies: "@radar/lnrpc" "^0.9.1-beta" axios "^0.19.0" From 8a965a9ba2195cb3bc1067d3b13408662c3452ba Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Thu, 26 Mar 2020 11:29:58 +1100 Subject: [PATCH 142/145] Don't do double async functions --- cnd/src/network/protocols/announce/protocol.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/cnd/src/network/protocols/announce/protocol.rs b/cnd/src/network/protocols/announce/protocol.rs index bb1a0d3ca0..b2334f98db 100644 --- a/cnd/src/network/protocols/announce/protocol.rs +++ b/cnd/src/network/protocols/announce/protocol.rs @@ -128,12 +128,13 @@ where /// /// Consumes the substream, returning a reply future that resolves /// when the reply has been sent on the underlying connection. - pub async fn send(mut self, swap_id: SwapId) -> impl Future> { + pub async fn send(mut self, swap_id: SwapId) -> Result<(), Error> { tracing::trace!("Sending: {}", swap_id); - async move { - let bytes = serde_json::to_vec(&swap_id)?; - Ok(upgrade::write_one(&mut self.io, &bytes).await?) - } + + let bytes = serde_json::to_vec(&swap_id)?; + upgrade::write_one(&mut self.io, &bytes).await?; + + Ok(()) } } From 4933acdfc9e36b506e03394668bac55080bfb214 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Thu, 26 Mar 2020 11:58:36 +1100 Subject: [PATCH 143/145] Add connection logic Add logic for managing connections from within the announce behaviour. Fixes: #2311 --- .../network/protocols/announce/behaviour.rs | 193 +++++++++++++++--- 1 file changed, 164 insertions(+), 29 deletions(-) diff --git a/cnd/src/network/protocols/announce/behaviour.rs b/cnd/src/network/protocols/announce/behaviour.rs index 1ee9009801..d15daf0fd4 100644 --- a/cnd/src/network/protocols/announce/behaviour.rs +++ b/cnd/src/network/protocols/announce/behaviour.rs @@ -1,8 +1,11 @@ use crate::{ - network::protocols::announce::{ - handler::{self, Handler, HandlerEvent}, - protocol::{OutboundConfig, ReplySubstream}, - SwapDigest, + network::{ + protocols::announce::{ + handler::{self, Handler, HandlerEvent}, + protocol::{OutboundConfig, ReplySubstream}, + SwapDigest, + }, + DialInformation, }, swap_protocols::SwapId, }; @@ -14,7 +17,7 @@ use libp2p::{ }, }; use std::{ - collections::{HashMap, VecDeque}, + collections::{hash_map::Entry, HashMap, HashSet, VecDeque}, task::{Context, Poll}, }; @@ -24,29 +27,74 @@ use std::{ pub struct Announce { /// Pending events to be emitted when polled. events: VecDeque>, - address_book: HashMap, -} - -impl Announce { - /// This is how data flows into the network behaviour from the application - /// when acting in the Role of Alice. - pub fn start_announce_protocol(&mut self, swap_digest: &SwapDigest, peer_id: &PeerId) { - self.events.push_back(NetworkBehaviourAction::SendEvent { - peer_id: peer_id.clone(), - event: OutboundConfig::new(swap_digest.clone()), - }); - } - - pub fn add_peer(&mut self, peer_id: PeerId, addr: Multiaddr) { - self.address_book.insert(peer_id, addr); - } + /// Stores connection state for nodes we connect to. + connections: HashMap, } impl Default for Announce { fn default() -> Self { - Announce { + Self { events: VecDeque::new(), - address_book: HashMap::new(), + connections: HashMap::new(), + } + } +} + +impl Announce { + /// Start the announce protocol. + /// + /// This is the entry point for Alice when wishing to start the announce + /// protocol to announce a swap to Bob. In libp2p parlance Alice is the + /// dialer and Bob is the listener, `dial_info` is what is used to dial Bob. + /// + /// # Arguments + /// + /// * `swap_digest` - The swap to announce. + /// * `dial_info` - The `PeerId` and address hint to dial to Bob's node. + pub fn start_announce_protocol(&mut self, swap_digest: SwapDigest, dial_info: DialInformation) { + match self.connections.entry(dial_info.peer_id.clone()) { + Entry::Vacant(entry) => { + self.events.push_back(NetworkBehaviourAction::DialPeer { + peer_id: dial_info.peer_id.clone(), + }); + + let mut address_hints = VecDeque::new(); + if let Some(address) = dial_info.address_hint { + address_hints.push_back(address); + } + + let pending_events = vec![OutboundConfig::new(swap_digest)]; + + entry.insert(ConnectionState::Connecting { + pending_events, + address_hints, + }); + } + Entry::Occupied(mut entry) => { + let connection_state = entry.get_mut(); + + match connection_state { + ConnectionState::Connecting { + pending_events, + address_hints, + } => { + pending_events.push(OutboundConfig::new(swap_digest)); + if let Some(address) = dial_info.address_hint { + // We push to the front because we consider the new address to be the + // most likely one to succeed. The order of this queue is important + // when returning it from `addresses_of_peer()` because it will be tried + // by libp2p in the returned order. + address_hints.push_front(address); + } + } + ConnectionState::Connected { .. } => { + self.events.push_back(NetworkBehaviourAction::SendEvent { + peer_id: dial_info.peer_id.clone(), + event: OutboundConfig::new(swap_digest), + }); + } + } + } } } } @@ -60,16 +108,89 @@ impl NetworkBehaviour for Announce { } fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { - if let Some(addr) = self.address_book.get(peer_id) { - vec![addr.clone()] - } else { - vec![] + self.connections + .iter() + .find_map(|(candidate, addresses)| { + if candidate == peer_id { + Some(addresses) + } else { + None + } + }) + .map(|connection_state| match connection_state { + ConnectionState::Connecting { address_hints, .. } => { + let addresses: Vec = address_hints.clone().into(); + addresses + } + ConnectionState::Connected { addresses } => addresses.iter().cloned().collect(), + }) + .unwrap_or_else(Vec::new) + } + + fn inject_connected(&mut self, peer_id: PeerId, endpoint: ConnectedPoint) { + tracing::debug!("connected to {} at {:?}", peer_id, endpoint); + + let address = match endpoint { + ConnectedPoint::Dialer { address } => address, + ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, + }; + + match self.connections.entry(peer_id.clone()) { + Entry::Occupied(entry) => { + let connection_state = entry.remove(); + + match connection_state { + ConnectionState::Connected { mut addresses } => { + addresses.insert(address); + self.connections + .insert(peer_id, ConnectionState::Connected { addresses }); + } + ConnectionState::Connecting { + pending_events, + address_hints: _we_no_longer_care_at_this_stage, + } => { + for event in pending_events { + self.events.push_back(NetworkBehaviourAction::SendEvent { + peer_id: peer_id.clone(), + event, + }) + } + + let mut addresses = HashSet::new(); + addresses.insert(address); + + self.connections + .insert(peer_id, ConnectionState::Connected { addresses }); + } + } + } + Entry::Vacant(entry) => { + let mut addresses = HashSet::new(); + addresses.insert(address); + + entry.insert(ConnectionState::Connected { addresses }); + } } } - fn inject_connected(&mut self, _peer_id: PeerId, _endpoint: ConnectedPoint) {} + fn inject_disconnected(&mut self, peer_id: &PeerId, endpoint: ConnectedPoint) { + tracing::debug!("disconnected from {} at {:?}", peer_id, endpoint); + + let address = match endpoint { + ConnectedPoint::Dialer { address } => address, + ConnectedPoint::Listener { send_back_addr, .. } => send_back_addr, + }; - fn inject_disconnected(&mut self, _peer_id: &PeerId, _: ConnectedPoint) {} + if let Some(ConnectionState::Connected { mut addresses }) = self.connections.remove(peer_id) + { + addresses.remove(&address); + + if !addresses.is_empty() { + self.connections + .insert(peer_id.clone(), ConnectionState::Connected { addresses }); + } + } + } fn inject_node_event(&mut self, peer_id: PeerId, event: HandlerEvent) { match event { @@ -115,10 +236,24 @@ impl NetworkBehaviour for Announce { return Poll::Ready(event); } + // We trust in libp2p to poll us. Poll::Pending } } +#[derive(Debug)] +enum ConnectionState { + Connected { + addresses: HashSet, + }, + Connecting { + // Vec is fine here, we iterate over this to remove items. + pending_events: Vec, + // VecDeque because we push new addresses to the front. + address_hints: VecDeque, + }, +} + /// Event emitted by the `Announce` behaviour. #[derive(Debug)] pub enum BehaviourEvent { From 505b57980b06028b9bf362824c892d9e8163c2f3 Mon Sep 17 00:00:00 2001 From: Philipp Hoenisch Date: Thu, 26 Mar 2020 14:41:30 +1100 Subject: [PATCH 144/145] Install libssl-dev inside the container --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e1568b1948..8bb6a598a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM debian:buster RUN apt-get update && \ apt-get install -y \ - tini \ + tini libssl-dev \ && rm -rf /var/lib/apt/lists/* RUN useradd --create-home --shell /bin/bash cnd From f1070ea4aa9a6a9350b13ce5b375924363b5a2e5 Mon Sep 17 00:00:00 2001 From: GitHub actions Date: Thu, 26 Mar 2020 04:22:16 +0000 Subject: [PATCH 145/145] Prepare release 0.7.2 --- CHANGELOG.md | 6 +++++- Cargo.lock | 2 +- cnd/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d70c29c20..5eca4521dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.7.2] - 2020-03-26 + ## [0.7.1] - 2020-03-12 ### Fixed @@ -109,7 +111,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Move config files to standard location based on platform (OSX, Windows, Linux). - Align implementation with RFC-002 to use the decision header instead of status codes. -[Unreleased]: https://github.com/comit-network/comit-rs/compare/0.7.1...HEAD +[Unreleased]: https://github.com/comit-network/comit-rs/compare/0.7.2...HEAD + +[0.7.2]: https://github.com/comit-network/comit-rs/compare/0.7.1...0.7.2 [0.7.0]: https://github.com/comit-network/comit-rs/compare/0.7.0...0.7.1 diff --git a/Cargo.lock b/Cargo.lock index 52e9528b5e..6a96e83f1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -527,7 +527,7 @@ dependencies = [ [[package]] name = "cnd" -version = "0.7.0" +version = "0.7.2" dependencies = [ "ambassador", "anyhow", diff --git a/cnd/Cargo.toml b/cnd/Cargo.toml index 1462b513a9..db189bb33d 100644 --- a/cnd/Cargo.toml +++ b/cnd/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["CoBloX developers "] name = "cnd" -version = "0.7.0" +version = "0.7.2" edition = "2018" description = "Reference implementation of a COMIT network daemon."