Skip to content

Commit

Permalink
Dev -> Main (#764)
Browse files Browse the repository at this point in the history
* fix import path (#748) (#749)

Co-authored-by: haryu703 <34744512+haryu703@users.noreply.github.com>

* Added from / to height in receipt search (#750)

* Notification multisig (#752)

* - Subscribe multisig account from cosigner subscription
- Fixed #751

* Lint fix

* 0.23.1 release (#755)

* 0.23.1 release node

* updated versions

* fixes finalizationEpoch (#758)

* Fixed #754 (#757)

* smal fix on mosaic restriction service

* Fixed #760 (#761)

- Removed NamespaceName api call
- filter transaction by unrsolved address

* Sub NamespaceId generation bug fix (#763)

* Fixed #753

* Removed unused var

* Add more unit tests

Co-authored-by: fboucquez <fboucquez@gmail.com>

* v0.23.2 release change log

Co-authored-by: haryu703 <34744512+haryu703@users.noreply.github.com>
Co-authored-by: Anthony Law <yc-law1015@hotmail.com>
Co-authored-by: fboucquez <fboucquez@gmail.com>
  • Loading branch information
4 people committed Feb 15, 2021
1 parent d96aa90 commit ef0e3d1
Show file tree
Hide file tree
Showing 37 changed files with 254 additions and 315 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.

The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [0.23.2] - 15-Feb-2021

**Milestone**: Catapult-server main(0.10.0.6)
Package | Version | Link
---|---|---
SDK Core| v0.23.2 | [symbol-sdk](https://www.npmjs.com/package/symbol-sdk)
Catbuffer | v0.1.1 | [catbuffer-typescript](https://www.npmjs.com/package/catbuffer-typescript)
Client Library | v0.11.1 | [symbol-openapi-typescript-fetch-client](https://www.npmjs.com/package/symbol-openapi-typescript-fetch-client)

- Fixed subnamespaceId generation issue in `NamespaceRegistrationTransaction`.
- Fixed `mosaicRestrictionTransactionService` error handling issue.
- Fixed `finalizationEpoch` issue in the dto model.
- Changed WebSocket listener subscription to use `UnresolvedAddress` without querying the rest-gateway.

## [0.23.1] - 02-Feb-2021

**Milestone**: Catapult-server main(0.10.0.6)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -9,9 +9,9 @@ The Symbol SDK for TypeScript / JavaScript allows you to develop web, mobile, an

## Important Notes

### _Catapult-Server_ Network Compatibility (catapult-server@0.10.0.6)
### _Catapult-Server_ Network Compatibility (catapult-server@0.10.0.7)

Symbol network pre-launch [catapult-server](https://github.com/nemtech/catapult-server/releases/tag/v0.10.0.6), **it is recommended to use this package's 0.23.1 version and upwards for the upcoming pre-release versions and final release**.
Symbol network pre-launch [catapult-server](https://github.com/nemtech/catapult-server/releases/tag/v0.10.0.7), **it is recommended to use this package's 0.23.2 version and upwards for the upcoming pre-release versions and final release**.

Find the complete release notes [here](CHANGELOG.md).

Expand Down
2 changes: 1 addition & 1 deletion src/infrastructure/ChainHttp.ts
Expand Up @@ -60,7 +60,7 @@ export class ChainHttp extends Http implements ChainRepository {
UInt64.fromNumericString(body.latestFinalizedBlock.height),
body.latestFinalizedBlock.hash,
body.latestFinalizedBlock.finalizationPoint,
body.latestFinalizedBlock.finalizationPoint,
body.latestFinalizedBlock.finalizationEpoch,
),
),
);
Expand Down
139 changes: 51 additions & 88 deletions src/infrastructure/Listener.ts
Expand Up @@ -14,16 +14,15 @@
* limitations under the License.
*/

import { Observable, of, OperatorFunction, Subject } from 'rxjs';
import { catchError, filter, flatMap, map, mergeMap, share, switchMap } from 'rxjs/operators';
import { Observable, of, Subject } from 'rxjs';
import { catchError, filter, map, mergeMap, share, switchMap } from 'rxjs/operators';
import { BlockInfoDTO } from 'symbol-openapi-typescript-fetch-client';
import * as WebSocket from 'ws';
import { UnresolvedAddress } from '../model';
import { Address } from '../model/account/Address';
import { PublicAccount } from '../model/account/PublicAccount';
import { FinalizedBlock } from '../model/blockchain/FinalizedBlock';
import { NewBlock } from '../model/blockchain/NewBlock';
import { NamespaceName } from '../model/namespace/NamespaceName';
import { AggregateTransaction } from '../model/transaction/AggregateTransaction';
import { CosignatureSignedTransaction } from '../model/transaction/CosignatureSignedTransaction';
import { Deadline } from '../model/transaction/Deadline';
Expand Down Expand Up @@ -335,24 +334,25 @@ export class Listener implements IListener {
transactionHash?: string,
subscribeMultisig = false,
): Observable<T> {
return this.getResolvedAddress(unresolvedAddress).pipe(
mergeMap((address: Address) => {
return this.subscribeWithMultig(address, channel, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((listenerMessage) => listenerMessage.channelName === channel),
filter((listenerMessage) => listenerMessage.message instanceof Transaction),
switchMap((_) => {
const transactionObservable = of(_.message as T).pipe(
filter((transaction) => this.filterHash(transaction, transactionHash)),
);
if (subscribers.includes(_.channelParam.toUpperCase())) {
return transactionObservable;
} else {
return transactionObservable.pipe(this.filterByNotifyAccount(address));
}
}),
return this.subscribeWithMultig(unresolvedAddress, channel, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((listenerMessage) => listenerMessage.channelName === channel),
filter((listenerMessage) => listenerMessage.message instanceof Transaction),
switchMap((_) => {
const transactionObservable = of(_.message as T).pipe(
filter((transaction) => this.filterHash(transaction, transactionHash)),
);
if (subscribers.includes(_.channelParam.toUpperCase())) {
return transactionObservable;
} else {
return transactionObservable.pipe(
filter(
(transaction) =>
transaction.isSigned(unresolvedAddress) || transaction.shouldNotifyAccount(unresolvedAddress),
),
);
}
}),
);
}),
Expand Down Expand Up @@ -414,18 +414,14 @@ export class Listener implements IListener {
transactionHash: string | undefined,
subscribeMultisig = false,
): Observable<string> {
return this.getResolvedAddress(unresolvedAddress).pipe(
mergeMap((address: Address) => {
return this.subscribeWithMultig(address, channel, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((_) => _.channelName === channel),
filter((_) => typeof _.message === 'string'),
filter((_) => subscribers.includes(_.channelParam.toUpperCase())),
map((_) => _.message as string),
filter((_) => !transactionHash || _.toUpperCase() == transactionHash.toUpperCase()),
);
}),
return this.subscribeWithMultig(unresolvedAddress, channel, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((_) => _.channelName === channel),
filter((_) => typeof _.message === 'string'),
filter((_) => subscribers.includes(_.channelParam.toUpperCase())),
map((_) => _.message as string),
filter((_) => !transactionHash || _.toUpperCase() == transactionHash.toUpperCase()),
);
}),
);
Expand Down Expand Up @@ -469,39 +465,6 @@ export class Listener implements IListener {
}
}

/**
* It filters a transaction by address using the aliases.
*
* This method delegates the rest loading as much as possible. It tries to filter by signer first.
*
* Note: this filter performs one extra rest call and it should be down in the pipeline.
*
* @param address the address.
* @return an observable filter.
*/
private filterByNotifyAccount<T extends Transaction>(address: Address): OperatorFunction<T, T> {
return (transactionObservable): Observable<T> => {
return transactionObservable.pipe(
flatMap((transaction) => {
if (transaction.isSigned(address)) {
return of(transaction);
}
const namespaceIdsObservable = this.namespaceRepository.getAccountsNames([address]).pipe(
map((names) => {
return ([] as NamespaceName[])
.concat(...Array.from(names.map((accountName) => accountName.names)))
.map((name) => name.namespaceId);
}),
);
return namespaceIdsObservable.pipe(
filter((namespaceIds) => transaction.shouldNotifyAccount(address, namespaceIds)),
map(() => transaction),
);
}),
);
};
}

/**
* Returns an observable stream of {@link CosignatureSignedTransaction} for specific address.
* Each time a cosigner signs a transaction the address initialized,
Expand All @@ -512,17 +475,13 @@ export class Listener implements IListener {
* @return an observable stream of {@link CosignatureSignedTransaction}
*/
public cosignatureAdded(unresolvedAddress: UnresolvedAddress, subscribeMultisig = false): Observable<CosignatureSignedTransaction> {
return this.getResolvedAddress(unresolvedAddress).pipe(
mergeMap((address: Address) => {
return this.subscribeWithMultig(address, ListenerChannelName.cosignature, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((_) => _.channelName.toUpperCase() === ListenerChannelName.cosignature.toUpperCase()),
filter((_) => _.message instanceof CosignatureSignedTransaction),
filter((_) => subscribers.includes(_.channelParam.toUpperCase())),
map((_) => _.message as CosignatureSignedTransaction),
);
}),
return this.subscribeWithMultig(unresolvedAddress, ListenerChannelName.cosignature, subscribeMultisig).pipe(
switchMap((subscribers) => {
return this.messageSubject.asObservable().pipe(
filter((_) => _.channelName.toUpperCase() === ListenerChannelName.cosignature.toUpperCase()),
filter((_) => _.message instanceof CosignatureSignedTransaction),
filter((_) => subscribers.includes(_.channelParam.toUpperCase())),
map((_) => _.message as CosignatureSignedTransaction),
);
}),
);
Expand Down Expand Up @@ -604,22 +563,26 @@ export class Listener implements IListener {
* @param multisig subscribe multisig account
* @returns {string[]}
*/
private subscribeWithMultig(cosigner: Address, channel: ListenerChannelName, multisig = false): Observable<string[]> {
private subscribeWithMultig(cosigner: UnresolvedAddress, channel: ListenerChannelName, multisig = false): Observable<string[]> {
if (!multisig) {
this.subscribeTo(`${channel.toString()}/${cosigner.plain()}`);
return of([cosigner.plain()]);
}
return this.multisigRepository!.getMultisigAccountInfo(cosigner).pipe(
map((multisigInfo) => {
const subscribers = [cosigner].concat(multisigInfo.multisigAddresses);
subscribers.forEach((m) => {
this.subscribeTo(`${channel.toString()}/${m.plain()}`);
});
return subscribers.map((m) => m.plain());
}),
catchError(() => {
this.subscribeTo(`${channel.toString()}/${cosigner.plain()}`);
return of([cosigner.plain()]);
return this.getResolvedAddress(cosigner).pipe(
mergeMap((address: Address) => {
return this.multisigRepository!.getMultisigAccountInfo(address).pipe(
map((multisigInfo) => {
const subscribers = [cosigner].concat(multisigInfo.multisigAddresses);
subscribers.forEach((m) => {
this.subscribeTo(`${channel.toString()}/${m.plain()}`);
});
return subscribers.map((m) => m.plain());
}),
catchError(() => {
this.subscribeTo(`${channel.toString()}/${cosigner.plain()}`);
return of([cosigner.plain()]);
}),
);
}),
);
}
Expand Down
Expand Up @@ -16,7 +16,7 @@

import { Address } from '../../model/account/Address';
import { MosaicId } from '../../model/mosaic/MosaicId';
import { MosaicRestrictionType } from '../../model/restriction/MosaicRestrictionType';
import { MosaicRestrictionEntryType } from '../../model/restriction/MosaicRestrictionEntryType';
import { SearchCriteria } from './SearchCriteria';

/**
Expand All @@ -32,7 +32,7 @@ export interface RestrictionMosaicSearchCriteria extends SearchCriteria {
/**
* Mosaic restriction entity type. (optional)
*/
entryType?: MosaicRestrictionType;
entryType?: MosaicRestrictionEntryType;

/**
* Mosaic restriction target address. (optional)
Expand Down
1 change: 0 additions & 1 deletion src/model/UInt64.ts
Expand Up @@ -94,7 +94,6 @@ export class UInt64 {
/**
* Get DTO representation with format: `[lower, higher]`
*
* @internal
* @returns {[number,number]}
*/
public toDTO(): number[] {
Expand Down
8 changes: 8 additions & 0 deletions src/model/namespace/NamespaceId.ts
Expand Up @@ -106,4 +106,12 @@ export class NamespaceId {
public encodeUnresolvedAddress(networkType: NetworkType): Uint8Array {
return RawAddress.aliasToRecipient(Convert.hexToUint8(this.toHex()), networkType);
}

/**
* Get string value of id
* @returns {string}
*/
public plain(): string {
return this.toHex();
}
}
10 changes: 4 additions & 6 deletions src/model/transaction/AccountAddressRestrictionTransaction.ts
Expand Up @@ -27,8 +27,7 @@ import {
} from 'catbuffer-typescript';
import { Convert } from '../../core/format';
import { DtoMapping, UnresolvedMapping } from '../../core/utils';
import { Address, PublicAccount, UnresolvedAddress } from '../account';
import { NamespaceId } from '../namespace';
import { PublicAccount, UnresolvedAddress } from '../account';
import { NetworkType } from '../network';
import { Statement } from '../receipt';
import { AddressRestrictionFlag } from '../restriction';
Expand Down Expand Up @@ -201,14 +200,13 @@ export class AccountAddressRestrictionTransaction extends Transaction {
* @internal
* Check a given address should be notified in websocket channels
* @param address address to be notified
* @param alias address alias (names)
* @returns {boolean}
*/
public shouldNotifyAccount(address: Address, alias: NamespaceId[]): boolean {
public shouldNotifyAccount(address: UnresolvedAddress): boolean {
return (
super.isSigned(address) ||
this.restrictionAdditions.find((_) => _.equals(address) || alias.find((a) => _.equals(a)) !== undefined) !== undefined ||
this.restrictionDeletions.find((_) => _.equals(address) || alias.find((a) => _.equals(a)) !== undefined) !== undefined
this.restrictionAdditions.find((_) => _.equals(address)) !== undefined ||
this.restrictionDeletions.find((_) => _.equals(address)) !== undefined
);
}
}
4 changes: 2 additions & 2 deletions src/model/transaction/AccountKeyLinkTransaction.ts
Expand Up @@ -24,7 +24,7 @@ import {
TransactionBuilder,
} from 'catbuffer-typescript';
import { Convert } from '../../core/format';
import { Address, PublicAccount } from '../account';
import { Address, PublicAccount, UnresolvedAddress } from '../account';
import { NetworkType } from '../network';
import { UInt64 } from '../UInt64';
import { Deadline } from './Deadline';
Expand Down Expand Up @@ -178,7 +178,7 @@ export class AccountKeyLinkTransaction extends Transaction {
* @param address address to be notified
* @returns {boolean}
*/
public shouldNotifyAccount(address: Address): boolean {
public shouldNotifyAccount(address: UnresolvedAddress): boolean {
return super.isSigned(address) || Address.createFromPublicKey(this.linkedPublicKey, this.networkType).equals(address);
}
}
11 changes: 2 additions & 9 deletions src/model/transaction/AccountMetadataTransaction.ts
Expand Up @@ -25,10 +25,8 @@ import {
} from 'catbuffer-typescript';
import { Convert } from '../../core/format';
import { UnresolvedMapping } from '../../core/utils/UnresolvedMapping';
import { Address } from '../account/Address';
import { PublicAccount } from '../account/PublicAccount';
import { UnresolvedAddress } from '../account/UnresolvedAddress';
import { NamespaceId } from '../namespace/NamespaceId';
import { NetworkType } from '../network/NetworkType';
import { UInt64 } from '../UInt64';
import { Deadline } from './Deadline';
Expand Down Expand Up @@ -203,14 +201,9 @@ export class AccountMetadataTransaction extends Transaction {
* @internal
* Check a given address should be notified in websocket channels
* @param address address to be notified
* @param alias address alias (names)
* @returns {boolean}
*/
public shouldNotifyAccount(address: Address, alias: NamespaceId[]): boolean {
return (
super.isSigned(address) ||
this.targetAddress.equals(address) ||
alias.find((name) => this.targetAddress.equals(name)) !== undefined
);
public shouldNotifyAccount(address: UnresolvedAddress): boolean {
return super.isSigned(address) || this.targetAddress.equals(address);
}
}
9 changes: 3 additions & 6 deletions src/model/transaction/AggregateTransaction.ts
Expand Up @@ -31,8 +31,7 @@ import { KeyPair, MerkleHashBuilder, SHA3Hasher } from '../../core/crypto';
import { Convert } from '../../core/format';
import { DtoMapping } from '../../core/utils';
import { CreateTransactionFromPayload } from '../../infrastructure/transaction';
import { Account, Address, PublicAccount } from '../account';
import { NamespaceId } from '../namespace';
import { Account, PublicAccount, UnresolvedAddress } from '../account';
import { NetworkType } from '../network';
import { Statement } from '../receipt';
import { UInt64 } from '../UInt64';
Expand Down Expand Up @@ -396,15 +395,13 @@ export class AggregateTransaction extends Transaction {
* @internal
* Check a given address should be notified in websocket channels
* @param address address to be notified
* @param alias address alias (names)
* @returns {boolean}
*/
public shouldNotifyAccount(address: Address, alias: NamespaceId[]): boolean {
public shouldNotifyAccount(address: UnresolvedAddress): boolean {
return (
super.isSigned(address) ||
this.cosignatures.find((_) => _.signer.address.equals(address)) !== undefined ||
this.innerTransactions.find((innerTransaction: InnerTransaction) => innerTransaction.shouldNotifyAccount(address, alias)) !==
undefined
this.innerTransactions.find((innerTransaction: InnerTransaction) => innerTransaction.shouldNotifyAccount(address)) !== undefined
);
}
}
9 changes: 2 additions & 7 deletions src/model/transaction/MosaicAddressRestrictionTransaction.ts
Expand Up @@ -253,14 +253,9 @@ export class MosaicAddressRestrictionTransaction extends Transaction {
* @internal
* Check a given address should be notified in websocket channels
* @param address address to be notified
* @param alias address alias (names)
* @returns {boolean}
*/
public shouldNotifyAccount(address: Address, alias: NamespaceId[]): boolean {
return (
super.isSigned(address) ||
this.targetAddress.equals(address) ||
alias.find((name) => this.targetAddress.equals(name)) !== undefined
);
public shouldNotifyAccount(address: UnresolvedAddress): boolean {
return super.isSigned(address) || this.targetAddress.equals(address);
}
}

0 comments on commit ef0e3d1

Please sign in to comment.