Skip to content

Commit 2199628

Browse files
authored
Merge branch 'master' into task/g294_mosaic_ordering
2 parents 873d583 + d09b224 commit 2199628

File tree

8 files changed

+72
-12
lines changed

8 files changed

+72
-12
lines changed

src/model/transaction/AccountRestrictionTransaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class AccountRestrictionTransaction {
102102
): AccountOperationRestrictionTransaction {
103103
if (![AccountRestrictionType.AllowIncomingTransactionType,
104104
AccountRestrictionType.AllowOutgoingTransactionType,
105-
AccountRestrictionType.BlockOutgoingTransactionType,
105+
AccountRestrictionType.BlockIncomingTransactionType,
106106
AccountRestrictionType.BlockOutgoingTransactionType].includes(restrictionType)) {
107107
throw new Error ('Restriction type is not allowed.');
108108
}

src/model/transaction/AddressAliasTransaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class AddressAliasTransaction extends Transaction {
9393
*/
9494
public readonly namespaceId: NamespaceId,
9595
/**
96-
* The mosaic id.
96+
* The address.
9797
*/
9898
public readonly address: Address,
9999
signature?: string,

src/model/transaction/AggregateTransaction.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,19 @@ export class AggregateTransaction extends Transaction {
289289
* @internal
290290
* @returns {Uint8Array}
291291
*/
292-
protected generateBytes(): Uint8Array {
292+
protected generateBytes(signer?: PublicAccount): Uint8Array {
293293
const signerBuffer = new Uint8Array(32);
294294
const signatureBuffer = new Uint8Array(64);
295-
296295
let transactions = Uint8Array.from([]);
297296
this.innerTransactions.forEach((transaction) => {
297+
if (!transaction.signer) {
298+
if (this.type === TransactionType.AGGREGATE_COMPLETE) {
299+
transaction = Object.assign({__proto__: Object.getPrototypeOf(transaction)}, transaction, {signer});
300+
} else {
301+
throw new Error(
302+
'InnerTransaction signer must be provide. Only AggregateComplete transaction can use delegated signer.');
303+
}
304+
}
298305
const transactionByte = transaction.toAggregateTransactionBytes();
299306
transactions = GeneratorUtils.concatTypedArrays(transactions, transactionByte);
300307
});

src/model/transaction/InnerTransaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ import {Transaction} from './Transaction';
2020
/**
2121
* Transaction with signer included, used when adding signer to transactions included in an aggregate transaction.
2222
*/
23-
export type InnerTransaction = Transaction & {signer: PublicAccount};
23+
export type InnerTransaction = Transaction & {signer?: PublicAccount};

src/model/transaction/Transaction.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ export abstract class Transaction {
105105

106106
/**
107107
* @internal
108+
* @param singer Optional singer for delegated aggregate complete transaction only.
108109
*/
109-
protected abstract generateBytes(): Uint8Array;
110+
protected abstract generateBytes(signer?: PublicAccount): Uint8Array;
110111

111112
/**
112113
* @internal
@@ -123,7 +124,7 @@ export abstract class Transaction {
123124
public signWith(account: Account, generationHash: string): SignedTransaction {
124125
const generationHashBytes = Array.from(Convert.hexToUint8(generationHash));
125126
const signSchema = SHA3Hasher.resolveSignSchema(account.networkType);
126-
const byteBuffer = Array.from(this.generateBytes());
127+
const byteBuffer = Array.from(this.generateBytes(account.publicAccount));
127128
const signingBytes = generationHashBytes.concat(byteBuffer.slice(4 + 64 + 32));
128129
const keyPairEncoded = KeyPair.createKeyPairFromPrivateKeyString(account.privateKey, signSchema);
129130
const signature = Array.from(KeyPair.sign(account, new Uint8Array(signingBytes), signSchema));
@@ -162,10 +163,12 @@ export abstract class Transaction {
162163

163164
/**
164165
* Convert an aggregate transaction to an inner transaction including transaction signer.
165-
* @param signer - Transaction signer.
166+
* Signer is optional for `AggregateComplete` transaction `ONLY`.
167+
* If no signer provided, aggregate transaction signer will be delegated on signing
168+
* @param signer - Innre transaction signer. (Optional for `AggregateComplete` transaction `ONLY`)
166169
* @returns InnerTransaction
167170
*/
168-
public toAggregate(signer: PublicAccount): InnerTransaction {
171+
public toAggregate(signer?: PublicAccount): InnerTransaction {
169172
if (this.type === TransactionType.AGGREGATE_BONDED || this.type === TransactionType.AGGREGATE_COMPLETE) {
170173
throw new Error('Inner transaction cannot be an aggregated transaction.');
171174
}

src/service/AggregateTransactionService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export class AggregateTransactionService {
5353
signers.push(signedTransaction.signerPublicKey);
5454
}
5555
return observableFrom(aggregateTransaction.innerTransactions).pipe(
56-
mergeMap((innerTransaction) => this.accountHttp.getMultisigAccountInfo(innerTransaction.signer.address)
56+
mergeMap((innerTransaction) => this.accountHttp.getMultisigAccountInfo(innerTransaction.signer!.address)
5757
.pipe(
5858
/**
5959
* For multisig account, we need to get the graph info in case it has multiple levels

test/model/transaction/AccountRestrictionTransaction.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
import {expect} from 'chai';
1818
import {Account} from '../../../src/model/account/Account';
19-
import { AccountRestrictionModificationAction } from '../../../src/model/restriction/AccountRestrictionModificationAction';
20-
import { AccountRestrictionType } from '../../../src/model/restriction/AccountRestrictionType';
2119
import {Address} from '../../../src/model/account/Address';
2220
import {NetworkType} from '../../../src/model/blockchain/NetworkType';
2321
import {MosaicId} from '../../../src/model/mosaic/MosaicId';
22+
import { AccountRestrictionModificationAction } from '../../../src/model/restriction/AccountRestrictionModificationAction';
23+
import { AccountRestrictionType } from '../../../src/model/restriction/AccountRestrictionType';
2424
import { AccountRestrictionModification } from '../../../src/model/transaction/AccountRestrictionModification';
2525
import {AccountRestrictionTransaction} from '../../../src/model/transaction/AccountRestrictionTransaction';
2626
import {Deadline} from '../../../src/model/transaction/Deadline';

test/model/transaction/AggregateTransaction.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {expect} from 'chai';
1818
import {ChronoUnit} from 'js-joda';
1919
import { TransactionMapping } from '../../../src/core/utils/TransactionMapping';
2020
import {CreateTransactionFromDTO} from '../../../src/infrastructure/transaction/CreateTransactionFromDTO';
21+
import { CreateTransactionFromPayload } from '../../../src/infrastructure/transaction/CreateTransactionFromPayload';
2122
import {Account} from '../../../src/model/account/Account';
2223
import {Address} from '../../../src/model/account/Address';
2324
import {PublicAccount} from '../../../src/model/account/PublicAccount';
@@ -116,6 +117,55 @@ describe('AggregateTransaction', () => {
116117
)).to.be.equal('019054419050B9837EFAB4BBE8A4B9BB32D812F9885C00D8FC1650E1420D000000746573742D6D657373616765');
117118
});
118119

120+
it('should createComplete an AggregateTransaction object with delegated signer', () => {
121+
const transferTransaction = TransferTransaction.create(
122+
Deadline.create(1, ChronoUnit.HOURS),
123+
Address.createFromRawAddress('SBILTA367K2LX2FEXG5TFWAS7GEFYAGY7QLFBYKC'),
124+
[],
125+
PlainMessage.create('test-message'),
126+
NetworkType.MIJIN_TEST,
127+
);
128+
129+
const aggregateTransaction = AggregateTransaction.createComplete(
130+
Deadline.create(),
131+
[transferTransaction.toAggregate()],
132+
NetworkType.MIJIN_TEST,
133+
[]);
134+
expect(aggregateTransaction.innerTransactions[0].signer).to.be.undefined;
135+
136+
const signedTransaction = aggregateTransaction.signWith(account, generationHash);
137+
138+
expect(signedTransaction.payload.substring(0, 8)).to.be.equal('CD000000');
139+
expect(signedTransaction.payload.substring(240, 256)).to.be.equal('5100000051000000');
140+
expect(signedTransaction.payload.substring(
141+
320,
142+
signedTransaction.payload.length,
143+
)).to.be.equal('019054419050B9837EFAB4BBE8A4B9BB32D812F9885C00D8FC1650E1420D000000746573742D6D657373616765');
144+
145+
const createdFromPayload = CreateTransactionFromPayload(signedTransaction.payload);
146+
expect((createdFromPayload as AggregateTransaction).innerTransactions[0].signer!.publicKey)
147+
.to.be.equal(account.publicKey);
148+
});
149+
150+
it('should throw exception with delegated signer', () => {
151+
expect(() => {
152+
const transferTransaction = TransferTransaction.create(
153+
Deadline.create(1, ChronoUnit.HOURS),
154+
Address.createFromRawAddress('SBILTA367K2LX2FEXG5TFWAS7GEFYAGY7QLFBYKC'),
155+
[],
156+
PlainMessage.create('test-message'),
157+
NetworkType.MIJIN_TEST,
158+
);
159+
const aggregateTransaction = AggregateTransaction.createBonded(
160+
Deadline.create(),
161+
[transferTransaction.toAggregate()],
162+
NetworkType.MIJIN_TEST,
163+
[]);
164+
165+
aggregateTransaction.signWith(account, generationHash);
166+
}).to.throw(Error, 'InnerTransaction signer must be provide. Only AggregateComplete transaction can use delegated signer.');
167+
});
168+
119169
it('should createComplete an AggregateTransaction object with NamespaceRegistrationTransaction', () => {
120170
const registerNamespaceTransaction = NamespaceRegistrationTransaction.createRootNamespace(
121171
Deadline.create(),

0 commit comments

Comments
 (0)