Skip to content

Commit 90de311

Browse files
authored
Fixed #659 (#665)
- Added HashLockRepo and SecretLockRepo
1 parent 0a35a46 commit 90de311

38 files changed

+1377
-16
lines changed
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
/*
2+
* Copyright 2018 NEM
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { expect } from 'chai';
18+
import { Account } from '../../src/model/account/Account';
19+
import { Address } from '../../src/model/account/Address';
20+
import { PlainMessage } from '../../src/model/message/PlainMessage';
21+
import { NetworkType } from '../../src/model/network/NetworkType';
22+
import { AggregateTransaction } from '../../src/model/transaction/AggregateTransaction';
23+
import { Deadline } from '../../src/model/transaction/Deadline';
24+
import { MultisigAccountModificationTransaction } from '../../src/model/transaction/MultisigAccountModificationTransaction';
25+
import { TransferTransaction } from '../../src/model/transaction/TransferTransaction';
26+
import { UInt64 } from '../../src/model/UInt64';
27+
import { IntegrationTestHelper } from './IntegrationTestHelper';
28+
import { toArray, take } from 'rxjs/operators';
29+
import { deepEqual } from 'assert';
30+
import { Order, HashLockPaginationStreamer } from '../../src/infrastructure/infrastructure';
31+
import { Mosaic } from '../../src/model/mosaic/Mosaic';
32+
import { LockFundsTransaction } from '../../src/model/transaction/LockFundsTransaction';
33+
import { ChronoUnit } from 'js-joda';
34+
import { SignedTransaction } from '../../src/model/transaction/SignedTransaction';
35+
import { UnresolvedMosaicId } from '../../src/model/mosaic/UnresolvedMosaicId';
36+
import { HashLockRepository } from '../../src/infrastructure/HashLockRepository';
37+
38+
describe('HashLockHttp', () => {
39+
const helper = new IntegrationTestHelper();
40+
let account: Account;
41+
let account2: Account;
42+
let multisigAccount: Account;
43+
let cosignAccount1: Account;
44+
let cosignAccount2: Account;
45+
let cosignAccount3: Account;
46+
let hashLockRepo: HashLockRepository;
47+
let hash: string;
48+
let generationHash: string;
49+
let networkType: NetworkType;
50+
51+
before(() => {
52+
return helper.start().then(() => {
53+
account = helper.account;
54+
account2 = helper.account2;
55+
multisigAccount = helper.multisigAccount;
56+
cosignAccount1 = helper.cosignAccount1;
57+
cosignAccount2 = helper.cosignAccount2;
58+
cosignAccount3 = helper.cosignAccount3;
59+
generationHash = helper.generationHash;
60+
networkType = helper.networkType;
61+
hashLockRepo = helper.repositoryFactory.createHashLockRepository();
62+
});
63+
});
64+
before(() => {
65+
return helper.listener.open();
66+
});
67+
68+
after(() => {
69+
helper.listener.close();
70+
});
71+
72+
const createSignedAggregatedBondTransaction = (aggregatedTo: Account, signer: Account, recipient: Address): SignedTransaction => {
73+
const transferTransaction = TransferTransaction.create(
74+
Deadline.create(),
75+
recipient,
76+
[],
77+
PlainMessage.create('test-message'),
78+
networkType,
79+
helper.maxFee,
80+
);
81+
82+
const aggregateTransaction = AggregateTransaction.createBonded(
83+
Deadline.create(2, ChronoUnit.MINUTES),
84+
[transferTransaction.toAggregate(aggregatedTo.publicAccount)],
85+
networkType,
86+
[],
87+
helper.maxFee,
88+
);
89+
return signer.sign(aggregateTransaction, generationHash);
90+
};
91+
92+
const createHashLockTransactionAndAnnounce = (
93+
signedAggregatedTransaction: SignedTransaction,
94+
signer: Account,
95+
mosaicId: UnresolvedMosaicId,
96+
): void => {
97+
const lockFundsTransaction = LockFundsTransaction.create(
98+
Deadline.create(),
99+
new Mosaic(mosaicId, UInt64.fromUint(10 * Math.pow(10, helper.networkCurrencyDivisibility))),
100+
UInt64.fromUint(1000),
101+
signedAggregatedTransaction,
102+
networkType,
103+
helper.maxFee,
104+
);
105+
const signedLockFundsTransaction = signer.sign(lockFundsTransaction, generationHash);
106+
hash = signedLockFundsTransaction.hash;
107+
helper.announce(signedLockFundsTransaction);
108+
};
109+
110+
/**
111+
* =========================
112+
* Setup test data
113+
* =========================
114+
*/
115+
116+
describe('Setup test multisig account', () => {
117+
it('Announce MultisigAccountModificationTransaction', () => {
118+
const modifyMultisigAccountTransaction = MultisigAccountModificationTransaction.create(
119+
Deadline.create(),
120+
2,
121+
1,
122+
[cosignAccount1.address, cosignAccount2.address, cosignAccount3.address],
123+
[],
124+
networkType,
125+
helper.maxFee,
126+
);
127+
128+
const aggregateTransaction = AggregateTransaction.createComplete(
129+
Deadline.create(),
130+
[modifyMultisigAccountTransaction.toAggregate(multisigAccount.publicAccount)],
131+
networkType,
132+
[],
133+
helper.maxFee,
134+
);
135+
const signedTransaction = aggregateTransaction.signTransactionWithCosignatories(
136+
multisigAccount,
137+
[cosignAccount1, cosignAccount2, cosignAccount3],
138+
generationHash,
139+
);
140+
141+
return helper.announce(signedTransaction);
142+
});
143+
});
144+
145+
describe('Create a hash lock', () => {
146+
it('Announce HashLockTransaction', () => {
147+
const signedAggregatedTx = createSignedAggregatedBondTransaction(multisigAccount, account, account2.address);
148+
return createHashLockTransactionAndAnnounce(signedAggregatedTx, account, helper.networkCurrencyNamespaceId);
149+
});
150+
});
151+
152+
/**
153+
* =========================
154+
* Tests
155+
* =========================
156+
*/
157+
158+
describe('getHashLock', () => {
159+
it('should return hash lock info given hash', async () => {
160+
const info = await hashLockRepo.getHashLock(hash).toPromise();
161+
expect(info.ownerAddress.plain()).to.be.equal(account.address.plain());
162+
expect(info.amount.toString()).to.be.equal('1000');
163+
});
164+
});
165+
166+
describe('searchHashLock', () => {
167+
it('should return hash lock page info', async () => {
168+
const info = await hashLockRepo.search({ address: account.address }).toPromise();
169+
expect(info.data.length).to.be.greaterThan(0);
170+
});
171+
});
172+
173+
describe('searchHashLock with streamer', () => {
174+
it('should return hash lock page info', async () => {
175+
const streamer = new HashLockPaginationStreamer(hashLockRepo);
176+
const infoStreamer = await streamer
177+
.search({ address: account.address, pageSize: 20, order: Order.Asc })
178+
.pipe(take(20), toArray())
179+
.toPromise();
180+
const info = await hashLockRepo.search({ address: account.address, pageSize: 20, order: Order.Asc }).toPromise();
181+
expect(infoStreamer.length).to.be.greaterThan(0);
182+
deepEqual(infoStreamer[0], info.data[0]);
183+
});
184+
});
185+
186+
/**
187+
* =========================
188+
* House Keeping
189+
* =========================
190+
*/
191+
192+
describe('Restore test multisig Accounts', () => {
193+
it('Announce MultisigAccountModificationTransaction', () => {
194+
const removeCosigner1 = MultisigAccountModificationTransaction.create(
195+
Deadline.create(),
196+
-1,
197+
0,
198+
[],
199+
[cosignAccount1.address],
200+
networkType,
201+
helper.maxFee,
202+
);
203+
const removeCosigner2 = MultisigAccountModificationTransaction.create(
204+
Deadline.create(),
205+
0,
206+
0,
207+
[],
208+
[cosignAccount2.address],
209+
networkType,
210+
helper.maxFee,
211+
);
212+
213+
const removeCosigner3 = MultisigAccountModificationTransaction.create(
214+
Deadline.create(),
215+
-1,
216+
-1,
217+
[],
218+
[cosignAccount3.address],
219+
networkType,
220+
helper.maxFee,
221+
);
222+
223+
const aggregateTransaction = AggregateTransaction.createComplete(
224+
Deadline.create(),
225+
[
226+
removeCosigner1.toAggregate(multisigAccount.publicAccount),
227+
removeCosigner2.toAggregate(multisigAccount.publicAccount),
228+
removeCosigner3.toAggregate(multisigAccount.publicAccount),
229+
],
230+
networkType,
231+
[],
232+
helper.maxFee,
233+
);
234+
const signedTransaction = aggregateTransaction.signTransactionWithCosignatories(
235+
cosignAccount1,
236+
[cosignAccount2, cosignAccount3],
237+
generationHash,
238+
);
239+
return helper.announce(signedTransaction);
240+
});
241+
});
242+
});
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Copyright 2018 NEM
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { expect } from 'chai';
18+
import { Account } from '../../src/model/account/Account';
19+
import { NetworkType } from '../../src/model/network/NetworkType';
20+
import { Deadline } from '../../src/model/transaction/Deadline';
21+
import { UInt64 } from '../../src/model/UInt64';
22+
import { IntegrationTestHelper } from './IntegrationTestHelper';
23+
import { toArray, take } from 'rxjs/operators';
24+
import { deepEqual } from 'assert';
25+
import { Order, SecretLockPaginationStreamer } from '../../src/infrastructure/infrastructure';
26+
import { SecretLockRepository } from '../../src/infrastructure/SecretLockRepository';
27+
import { SecretLockTransaction } from '../../src/model/transaction/SecretLockTransaction';
28+
import { LockHashAlgorithm } from '../../src/model/lock/LockHashAlgorithm';
29+
import { sha3_256 } from 'js-sha3';
30+
import { Crypto } from '../../src/core/crypto';
31+
32+
describe('SecretLockHttp', () => {
33+
const helper = new IntegrationTestHelper();
34+
let account: Account;
35+
let account2: Account;
36+
let SecretLockRepo: SecretLockRepository;
37+
let generationHash: string;
38+
let networkType: NetworkType;
39+
let secret: string;
40+
41+
before(() => {
42+
return helper.start().then(() => {
43+
account = helper.account;
44+
account2 = helper.account2;
45+
networkType = helper.networkType;
46+
SecretLockRepo = helper.repositoryFactory.createSecretLockRepository();
47+
secret = sha3_256.create().update(Crypto.randomBytes(20)).hex();
48+
});
49+
});
50+
before(() => {
51+
return helper.listener.open();
52+
});
53+
54+
after(() => {
55+
helper.listener.close();
56+
});
57+
58+
/**
59+
* =========================
60+
* Setup test data
61+
* =========================
62+
*/
63+
64+
describe('Create a hash lock', () => {
65+
it('Announce SecretLockTransaction', () => {
66+
const secretLockTransaction = SecretLockTransaction.create(
67+
Deadline.create(),
68+
helper.createNetworkCurrency(10, false),
69+
UInt64.fromUint(100),
70+
LockHashAlgorithm.Op_Sha3_256,
71+
secret,
72+
account2.address,
73+
networkType,
74+
helper.maxFee,
75+
);
76+
const signedTransaction = secretLockTransaction.signWith(account, generationHash);
77+
return helper.announce(signedTransaction).then((transaction: SecretLockTransaction) => {
78+
expect(transaction.mosaic, 'Mosaic').not.to.be.undefined;
79+
expect(transaction.duration, 'Duration').not.to.be.undefined;
80+
expect(transaction.hashAlgorithm, 'HashAlgorithm').not.to.be.undefined;
81+
expect(transaction.secret, 'Secret').not.to.be.undefined;
82+
expect(transaction.recipientAddress, 'RecipientAddress').not.to.be.undefined;
83+
});
84+
});
85+
});
86+
87+
/**
88+
* =========================
89+
* Tests
90+
* =========================
91+
*/
92+
93+
describe('getSecretLock', () => {
94+
it('should return hash lock info given hash', async () => {
95+
const info = await SecretLockRepo.getSecretLock(secret).toPromise();
96+
expect(info.ownerAddress.plain()).to.be.equal(account.address.plain());
97+
expect(info.recipientAddress.plain()).to.be.equal(account2.address.plain());
98+
expect(info.amount.toString()).to.be.equal('100');
99+
});
100+
});
101+
102+
describe('searchSecretLock', () => {
103+
it('should return hash lock page info', async () => {
104+
const info = await SecretLockRepo.search({ address: account.address }).toPromise();
105+
expect(info.data.length).to.be.greaterThan(0);
106+
});
107+
});
108+
109+
describe('searchSecretLock with streamer', () => {
110+
it('should return hash lock page info', async () => {
111+
const streamer = new SecretLockPaginationStreamer(SecretLockRepo);
112+
const infoStreamer = await streamer
113+
.search({ address: account.address, pageSize: 20, order: Order.Asc })
114+
.pipe(take(20), toArray())
115+
.toPromise();
116+
const info = await SecretLockRepo.search({ address: account.address, pageSize: 20, order: Order.Asc }).toPromise();
117+
expect(infoStreamer.length).to.be.greaterThan(0);
118+
deepEqual(infoStreamer[0], info.data[0]);
119+
});
120+
});
121+
});

e2e/infrastructure/TransactionHttp.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import { CosignatureSignedTransaction } from '../../src/model/transaction/Cosign
4646
import { CosignatureTransaction } from '../../src/model/transaction/CosignatureTransaction';
4747
import { Deadline } from '../../src/model/transaction/Deadline';
4848
import { HashLockTransaction } from '../../src/model/transaction/HashLockTransaction';
49-
import { LockHashAlgorithm } from '../../src/model/transaction/LockHashAlgorithm';
49+
import { LockHashAlgorithm } from '../../src/model/lock/LockHashAlgorithm';
5050
import { LinkAction } from '../../src/model/transaction/LinkAction';
5151
import { LockFundsTransaction } from '../../src/model/transaction/LockFundsTransaction';
5252
import { MosaicAddressRestrictionTransaction } from '../../src/model/transaction/MosaicAddressRestrictionTransaction';

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
"ripemd160": "^2.0.2",
102102
"rxjs": "^6.5.3",
103103
"rxjs-compat": "^6.5.3",
104-
"symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009041234",
104+
"symbol-openapi-typescript-fetch-client": "0.9.7-SNAPSHOT.202009100936",
105105
"tweetnacl": "^1.0.3",
106106
"utf8": "^3.0.0",
107107
"ws": "^7.2.3"

0 commit comments

Comments
 (0)