Skip to content

Commit afb2be1

Browse files
committed
get most recent resolution entry
1 parent a2e0dd4 commit afb2be1

16 files changed

+356
-151
lines changed

e2e/service/TransactionService.spec.ts

Lines changed: 183 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ import { MosaicDefinitionTransaction } from '../../src/model/transaction/MosaicD
4040
import { MosaicMetadataTransaction } from '../../src/model/transaction/MosaicMetadataTransaction';
4141
import { MosaicSupplyChangeTransaction } from '../../src/model/transaction/MosaicSupplyChangeTransaction';
4242
import { NamespaceRegistrationTransaction } from '../../src/model/transaction/NamespaceRegistrationTransaction';
43+
import { SignedTransaction } from '../../src/model/transaction/SignedTransaction';
4344
import { TransferTransaction } from '../../src/model/transaction/TransferTransaction';
4445
import { UInt64 } from '../../src/model/UInt64';
4546
import { TransactionService } from '../../src/service/TransactionService';
4647

4748
describe('TransactionService', () => {
4849
let account: Account;
4950
let account2: Account;
51+
let account3: Account;
52+
let account4: Account;
5053
let url: string;
5154
let generationHash: string;
5255
let namespaceHttp: NamespaceHttp;
@@ -57,6 +60,7 @@ describe('TransactionService', () => {
5760
let transactionHttp: TransactionHttp;
5861
let config;
5962
let transactionHashes: string[];
63+
let transactionHashesMultiple: string[];
6064

6165
before((done) => {
6266
const path = require('path');
@@ -68,11 +72,14 @@ describe('TransactionService', () => {
6872
config = json;
6973
account = Account.createFromPrivateKey(json.testAccount.privateKey, NetworkType.MIJIN_TEST);
7074
account2 = Account.createFromPrivateKey(json.testAccount2.privateKey, NetworkType.MIJIN_TEST);
75+
account3 = Account.createFromPrivateKey(json.testAccount3.privateKey, NetworkType.MIJIN_TEST);
76+
account4 = Account.createFromPrivateKey(json.cosignatory4Account.privateKey, NetworkType.MIJIN_TEST);
7177
url = json.apiUrl;
7278
generationHash = json.generationHash;
7379
namespaceHttp = new NamespaceHttp(json.apiUrl);
7480
transactionHttp = new TransactionHttp(json.apiUrl);
7581
transactionHashes = [];
82+
transactionHashesMultiple = [];
7683
done();
7784
});
7885
});
@@ -96,7 +103,7 @@ describe('TransactionService', () => {
96103
const registerNamespaceTransaction = NamespaceRegistrationTransaction.createRootNamespace(
97104
Deadline.create(),
98105
namespaceName,
99-
UInt64.fromUint(9),
106+
UInt64.fromUint(20),
100107
NetworkType.MIJIN_TEST,
101108
);
102109
addressAlias = new NamespaceId(namespaceName);
@@ -128,7 +135,7 @@ describe('TransactionService', () => {
128135
const registerNamespaceTransaction = NamespaceRegistrationTransaction.createRootNamespace(
129136
Deadline.create(),
130137
namespaceName,
131-
UInt64.fromUint(20),
138+
UInt64.fromUint(50),
132139
NetworkType.MIJIN_TEST,
133140
);
134141
mosaicAlias = new NamespaceId(namespaceName);
@@ -196,7 +203,7 @@ describe('TransactionService', () => {
196203
mosaicId,
197204
MosaicFlags.create(true, true, false),
198205
3,
199-
UInt64.fromUint(0),
206+
UInt64.fromUint(50),
200207
NetworkType.MIJIN_TEST,
201208
);
202209
const signedTransaction = mosaicDefinitionTransaction.signWith(account, generationHash);
@@ -222,7 +229,7 @@ describe('TransactionService', () => {
222229
Deadline.create(),
223230
mosaicId,
224231
MosaicSupplyChangeAction.Increase,
225-
UInt64.fromUint(10),
232+
UInt64.fromUint(200000),
226233
NetworkType.MIJIN_TEST,
227234
);
228235
const signedTransaction = mosaicSupplyChangeTransaction.signWith(account, generationHash);
@@ -323,80 +330,119 @@ describe('TransactionService', () => {
323330
return listener.close();
324331
});
325332
it('aggregate', (done) => {
333+
const signedTransaction = buildAggregateTransaction().signWith(account, generationHash);
334+
transactionHashes.push(signedTransaction.hash);
335+
listener.confirmed(account.address).subscribe(() => {
336+
done();
337+
});
338+
listener.status(account.address).subscribe((error) => {
339+
console.log('Error:', error);
340+
assert(false);
341+
done();
342+
});
343+
transactionHttp.announce(signedTransaction);
344+
});
345+
});
346+
347+
/**
348+
* =====================================
349+
* Setup test Multiple transaction on same block
350+
* =====================================
351+
*/
352+
353+
describe('Transfer mosaic to account 3', () => {
354+
let listener: Listener;
355+
before (() => {
356+
listener = new Listener(config.apiUrl);
357+
return listener.open();
358+
});
359+
after(() => {
360+
return listener.close();
361+
});
362+
363+
it('Announce TransferTransaction', (done) => {
326364
const transferTransaction = TransferTransaction.create(
327365
Deadline.create(),
328-
addressAlias,
366+
account3.address,
329367
[
330-
NetworkCurrencyMosaic.createAbsolute(1),
331-
new Mosaic(mosaicAlias, UInt64.fromUint(1)),
368+
new Mosaic(mosaicAlias, UInt64.fromUint(200)),
332369
],
333370
PlainMessage.create('test-message'),
334371
NetworkType.MIJIN_TEST,
335372
);
336-
// Unlink MosaicAlias
337-
const mosaicAliasTransactionUnlink = MosaicAliasTransaction.create(
338-
Deadline.create(),
339-
AliasAction.Unlink,
340-
mosaicAlias,
341-
mosaicId,
342-
NetworkType.MIJIN_TEST,
343-
);
373+
const signedTransaction = transferTransaction.signWith(account, generationHash);
344374

345-
// Create a new Mosaic
346-
const nonce = MosaicNonce.createRandom();
347-
newMosaicId = MosaicId.createFromNonce(nonce, account.publicAccount);
348-
const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create(
349-
Deadline.create(),
350-
nonce,
351-
newMosaicId,
352-
MosaicFlags.create(true, true, false),
353-
3,
354-
UInt64.fromUint(0),
355-
NetworkType.MIJIN_TEST,
356-
);
375+
transactionHashes.push(signedTransaction.hash);
376+
377+
listener.confirmed(account.address).subscribe(() => {
378+
done();
379+
});
380+
listener.status(account.address).subscribe((error) => {
381+
console.log('Error:', error);
382+
assert(false);
383+
done();
384+
});
385+
transactionHttp.announce(signedTransaction);
386+
});
387+
});
388+
389+
describe('Create multiple transfers with alias', () => {
390+
let listener: Listener;
391+
before (() => {
392+
listener = new Listener(config.apiUrl);
393+
return listener.open();
394+
});
395+
after(() => {
396+
return listener.close();
397+
});
357398

358-
// Link namespace with new MosaicId
359-
const mosaicAliasTransactionRelink = MosaicAliasTransaction.create(
399+
it('Announce TransferTransaction', (done) => {
400+
const transactions: SignedTransaction[] = [];
401+
// 1. Transfer A -> B
402+
const transaction1 = TransferTransaction.create(
360403
Deadline.create(),
361-
AliasAction.Link,
362-
mosaicAlias,
363-
newMosaicId,
404+
account2.address,
405+
[
406+
new Mosaic(mosaicAlias, UInt64.fromUint(1)),
407+
],
408+
PlainMessage.create('test-message'),
364409
NetworkType.MIJIN_TEST,
365410
);
411+
transactions.push(transaction1.signWith(account, generationHash));
366412

367-
// Use new mosaicAlias in metadata
368-
const mosaicMetadataTransaction = MosaicMetadataTransaction.create(
413+
// 2. Transfer C -> D
414+
const transaction2 = TransferTransaction.create(
369415
Deadline.create(),
370-
account.publicKey,
371-
UInt64.fromUint(5),
372-
mosaicAlias,
373-
10,
374-
Convert.uint8ToUtf8(new Uint8Array(10)),
375-
NetworkType.MIJIN_TEST,
376-
);
377-
const aggregateTransaction = AggregateTransaction.createComplete(Deadline.create(),
416+
account4.address,
378417
[
379-
transferTransaction.toAggregate(account.publicAccount),
380-
mosaicAliasTransactionUnlink.toAggregate(account.publicAccount),
381-
mosaicDefinitionTransaction.toAggregate(account.publicAccount),
382-
mosaicAliasTransactionRelink.toAggregate(account.publicAccount),
383-
mosaicMetadataTransaction.toAggregate(account.publicAccount),
384-
418+
new Mosaic(mosaicAlias, UInt64.fromUint(1)),
385419
],
420+
PlainMessage.create('test-message'),
386421
NetworkType.MIJIN_TEST,
387-
[],
388422
);
389-
const signedTransaction = aggregateTransaction.signWith(account, generationHash);
390-
transactionHashes.push(signedTransaction.hash);
391-
listener.confirmed(account.address).subscribe(() => {
423+
transactions.push(transaction2.signWith(account3, generationHash));
424+
425+
// 3. Aggregate
426+
const lastSignedTx = buildAggregateTransaction().signWith(account, generationHash);
427+
transactions.push(lastSignedTx);
428+
429+
transactions.forEach((tx) => {
430+
transactionHashesMultiple.push(tx.hash);
431+
transactionHttp.announce(tx);
432+
});
433+
listener.confirmed(account.address, lastSignedTx.hash).subscribe(() => {
392434
done();
393435
});
394436
listener.status(account.address).subscribe((error) => {
395437
console.log('Error:', error);
396438
assert(false);
397439
done();
398440
});
399-
transactionHttp.announce(signedTransaction);
441+
listener.status(account3.address).subscribe((error) => {
442+
console.log('Error:', error);
443+
assert(false);
444+
done();
445+
});
400446
});
401447
});
402448

@@ -409,7 +455,7 @@ describe('TransactionService', () => {
409455
describe('should return resolved transaction', () => {
410456
it('call transaction service', (done) => {
411457
const transactionService = new TransactionService(url);
412-
return transactionService.resolveAliases(transactionHashes).subscribe((transactions) => {
458+
transactionService.resolveAliases(transactionHashes).subscribe((transactions) => {
413459
expect(transactions.length).to.be.equal(8);
414460
transactions.map((tx) => {
415461
if (tx instanceof TransferTransaction) {
@@ -427,7 +473,89 @@ describe('TransactionService', () => {
427473
.targetMosaicId.toHex() === newMosaicId.toHex()).to.be.true;
428474
}
429475
});
430-
});
476+
},
477+
done());
478+
});
479+
});
480+
481+
describe('Test resolve alias with multiple transaction in single block', () => {
482+
it('call transaction service', (done) => {
483+
const transactionService = new TransactionService(url);
484+
transactionService.resolveAliases(transactionHashesMultiple).subscribe((tx) => {
485+
expect(tx.length).to.be.equal(3);
486+
expect((tx[0] as TransferTransaction).mosaics[0].id.toHex()).to.be.equal(mosaicId.toHex());
487+
expect((tx[1] as TransferTransaction).mosaics[0].id.toHex()).to.be.equal(mosaicId.toHex());
488+
expect(((tx[2] as AggregateTransaction).innerTransactions[4] as MosaicMetadataTransaction)
489+
.targetMosaicId.toHex()).to.be.equal(newMosaicId.toHex());
490+
},
491+
done());
431492
});
432493
});
494+
495+
function buildAggregateTransaction(): AggregateTransaction {
496+
const transferTransaction = TransferTransaction.create(
497+
Deadline.create(),
498+
addressAlias,
499+
[
500+
NetworkCurrencyMosaic.createAbsolute(1),
501+
new Mosaic(mosaicAlias, UInt64.fromUint(1)),
502+
],
503+
PlainMessage.create('test-message'),
504+
NetworkType.MIJIN_TEST,
505+
);
506+
// Unlink MosaicAlias
507+
const mosaicAliasTransactionUnlink = MosaicAliasTransaction.create(
508+
Deadline.create(),
509+
AliasAction.Unlink,
510+
mosaicAlias,
511+
mosaicId,
512+
NetworkType.MIJIN_TEST,
513+
);
514+
515+
// Create a new Mosaic
516+
const nonce = MosaicNonce.createRandom();
517+
newMosaicId = MosaicId.createFromNonce(nonce, account.publicAccount);
518+
const mosaicDefinitionTransaction = MosaicDefinitionTransaction.create(
519+
Deadline.create(),
520+
nonce,
521+
newMosaicId,
522+
MosaicFlags.create(true, true, false),
523+
3,
524+
UInt64.fromUint(0),
525+
NetworkType.MIJIN_TEST,
526+
);
527+
528+
// Link namespace with new MosaicId
529+
const mosaicAliasTransactionRelink = MosaicAliasTransaction.create(
530+
Deadline.create(),
531+
AliasAction.Link,
532+
mosaicAlias,
533+
newMosaicId,
534+
NetworkType.MIJIN_TEST,
535+
);
536+
537+
// Use new mosaicAlias in metadata
538+
const mosaicMetadataTransaction = MosaicMetadataTransaction.create(
539+
Deadline.create(),
540+
account.publicKey,
541+
UInt64.fromUint(5),
542+
mosaicAlias,
543+
10,
544+
Convert.uint8ToUtf8(new Uint8Array(10)),
545+
NetworkType.MIJIN_TEST,
546+
);
547+
return AggregateTransaction.createComplete(Deadline.create(),
548+
[
549+
transferTransaction.toAggregate(account.publicAccount),
550+
mosaicAliasTransactionUnlink.toAggregate(account.publicAccount),
551+
mosaicDefinitionTransaction.toAggregate(account.publicAccount),
552+
mosaicAliasTransactionRelink.toAggregate(account.publicAccount),
553+
mosaicMetadataTransaction.toAggregate(account.publicAccount),
554+
555+
],
556+
NetworkType.MIJIN_TEST,
557+
[],
558+
);
559+
}
560+
433561
});

src/infrastructure/Listener.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,15 +239,18 @@ export class Listener {
239239
* it emits a new Transaction in the event stream.
240240
*
241241
* @param address address we listen when a transaction is in confirmed state
242+
* @param transactionHash transaction hash for the filter
242243
* @return an observable stream of Transaction with state confirmed
243244
*/
244-
public confirmed(address: Address): Observable<Transaction> {
245+
public confirmed(address: Address, transactionHash?: string): Observable<Transaction> {
245246
this.subscribeTo(`confirmedAdded/${address.plain()}`);
246247
return this.messageSubject.asObservable().pipe(
247248
filter((_) => _.channelName === ListenerChannelName.confirmedAdded),
248249
filter((_) => _.message instanceof Transaction),
249250
map((_) => _.message as Transaction),
250-
filter((_) => this.transactionFromAddress(_, address)));
251+
filter((_) => this.transactionFromAddress(_, address)),
252+
filter((_) => _.transactionInfo!.hash === transactionHash || transactionHash === undefined),
253+
);
251254
}
252255

253256
/**
@@ -289,15 +292,18 @@ export class Listener {
289292
* it emits a new {@link AggregateTransaction} in the event stream.
290293
*
291294
* @param address address we listen when a transaction with missing signatures state
295+
* @param transactionHash transaction hash for the filter
292296
* @return an observable stream of AggregateTransaction with missing signatures state
293297
*/
294-
public aggregateBondedAdded(address: Address): Observable<AggregateTransaction> {
298+
public aggregateBondedAdded(address: Address, transactionHash?: string): Observable<AggregateTransaction> {
295299
this.subscribeTo(`partialAdded/${address.plain()}`);
296300
return this.messageSubject.asObservable().pipe(
297301
filter((_) => _.channelName === ListenerChannelName.aggregateBondedAdded),
298302
filter((_) => _.message instanceof AggregateTransaction),
299303
map((_) => _.message as AggregateTransaction),
300-
filter((_) => this.transactionFromAddress(_, address)));
304+
filter((_) => this.transactionFromAddress(_, address)),
305+
filter((_) => _.transactionInfo!.hash === transactionHash || transactionHash === undefined),
306+
);
301307
}
302308

303309
/**

0 commit comments

Comments
 (0)