From d2573077a7e8810a3a818a7f65d2580af901462f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Schwert?= Date: Mon, 12 Oct 2020 16:47:36 +0200 Subject: [PATCH] Fix HTLC conversion to and from plain format (#568) * Encode hash algorithm in plain HTLC * Add test for HTLC conversion to and from plain format * Update types --- dist/types.d.ts | 2 ++ .../base/account/HashedTimeLockedContract.js | 3 ++- .../generic/consensus/base/primitive/Hash.js | 14 +++++++++++ .../account/HashedTimeLockedContract.spec.js | 23 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/dist/types.d.ts b/dist/types.d.ts index 891edad6a..73092b8ec 100644 --- a/dist/types.d.ts +++ b/dist/types.d.ts @@ -1015,6 +1015,7 @@ export class Hash extends Serializable { SHA256: 3; SHA512: 4; toString(hashAlgorithm: Hash.Algorithm): string; + fromString(str: string): Hash.Algorithm; }; public static light(arr: Uint8Array): Hash; public static blake2b(arr: Uint8Array): Hash; @@ -1408,6 +1409,7 @@ export class HashedTimeLockedContract extends Contract { balance: number, sender: string, recipient: string, + hashAlgorithm: string, hashRoot: string, hashCount: number, timeout: number, diff --git a/src/main/generic/consensus/base/account/HashedTimeLockedContract.js b/src/main/generic/consensus/base/account/HashedTimeLockedContract.js index 3af610960..7fced28ae 100644 --- a/src/main/generic/consensus/base/account/HashedTimeLockedContract.js +++ b/src/main/generic/consensus/base/account/HashedTimeLockedContract.js @@ -73,7 +73,7 @@ class HashedTimeLockedContract extends Contract { */ static fromPlain(plain) { if (!plain) throw new Error('Invalid account'); - return new HashedTimeLockedContract(plain.balance, Address.fromAny(plain.sender), Address.fromAny(plain.recipient), Hash.fromAny(plain.hashRoot), plain.hashCount, plain.timeout, plain.totalAmount); + return new HashedTimeLockedContract(plain.balance, Address.fromAny(plain.sender), Address.fromAny(plain.recipient), Hash.fromAny(plain.hashRoot, Hash.Algorithm.fromString(plain.hashAlgorithm)), plain.hashCount, plain.timeout, plain.totalAmount); } @@ -150,6 +150,7 @@ class HashedTimeLockedContract extends Contract { const plain = super.toPlain(); plain.sender = this.sender.toPlain(); plain.recipient = this.recipient.toPlain(); + plain.hashAlgorithm = Hash.Algorithm.toString(this.hashRoot.algorithm); plain.hashRoot = this.hashRoot.toPlain(); plain.hashCount = this.hashCount; plain.timeout = this.timeout; diff --git a/src/main/generic/consensus/base/primitive/Hash.js b/src/main/generic/consensus/base/primitive/Hash.js index 6530a43d3..4e774d92d 100644 --- a/src/main/generic/consensus/base/primitive/Hash.js +++ b/src/main/generic/consensus/base/primitive/Hash.js @@ -334,6 +334,20 @@ Hash.Algorithm.toString = function(hashAlgorithm) { throw new Error('Invalid hash algorithm'); }; +/** + * @param {string} str + * @returns {Hash.Algorithm} + */ +Hash.Algorithm.fromString = function (str) { + switch (str) { + case 'blake2b': return Hash.Algorithm.BLAKE2B; + case 'argon2d': return Hash.Algorithm.ARGON2D; + case 'sha256': return Hash.Algorithm.SHA256; + case 'sha512': return Hash.Algorithm.SHA512; + } + throw new Error('Invalid string'); +} + /** * @type {Map} */ diff --git a/src/test/specs/generic/consensus/base/account/HashedTimeLockedContract.spec.js b/src/test/specs/generic/consensus/base/account/HashedTimeLockedContract.spec.js index 70e20683c..ac7be31a0 100644 --- a/src/test/specs/generic/consensus/base/account/HashedTimeLockedContract.spec.js +++ b/src/test/specs/generic/consensus/base/account/HashedTimeLockedContract.spec.js @@ -531,4 +531,27 @@ describe('HashedTimeLockedContract', () => { expect(plain.creatorPublicKey).toEqual(keyPair.publicKey.toHex()); expect(plain.creatorPathLength).toEqual(0); }); + + it('can convert itself to and from plain', () => { + const keyPair1 = KeyPair.generate(); + const addr1 = keyPair1.publicKey.toAddress(); + const keyPair2 = KeyPair.generate(); + const addr2 = keyPair2.publicKey.toAddress(); + + const hashRoot = Hash.sha256(Hash.NULL.array); + + const htlc = new HashedTimeLockedContract(1e5, addr1, addr2, hashRoot, 1, 1000); + const plain = htlc.toPlain(); + const revived = HashedTimeLockedContract.fromPlain(plain); + + expect(revived.sender.equals(addr1)).toBe(true); + expect(revived.recipient.equals(addr2)).toBe(true); + expect(revived.balance).toBe(1e5); + expect(revived.hashRoot.equals(hashRoot)).toBe(true); + expect(revived.hashRoot.algorithm).toBe(Hash.Algorithm.SHA256); + expect(revived.hashCount).toBe(1); + expect(revived.totalAmount).toBe(1e5); + + expect(htlc.equals(revived)).toBe(true); + }); });