Skip to content

Commit 263d0ce

Browse files
merge: cherry pick from develop (#4867)
2 parents c4d44df + a0bc16f commit 263d0ce

13 files changed

Lines changed: 198 additions & 14 deletions

File tree

‎__tests__/unit/core-transactions/handlers/__support__/app.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,23 @@ export const buildMultiSignatureWallet = (): Wallets.Wallet => {
262262

263263
return wallet;
264264
};
265+
266+
export const buildMultiSignatureRecipientWallet = (): Wallets.Wallet => {
267+
const multiSignatureAsset: IMultiSignatureAsset = {
268+
publicKeys: [
269+
Identities.PublicKey.fromPassphrase(passphrases[1]),
270+
Identities.PublicKey.fromPassphrase(passphrases[2]),
271+
Identities.PublicKey.fromPassphrase(passphrases[3]),
272+
],
273+
min: 2,
274+
};
275+
276+
const wallet = new Wallets.Wallet(
277+
Identities.Address.fromMultiSignatureAsset(multiSignatureAsset),
278+
new Services.Attributes.AttributeMap(getWalletAttributeSet()),
279+
);
280+
wallet.setPublicKey(Identities.PublicKey.fromMultiSignatureAsset(multiSignatureAsset));
281+
wallet.setAttribute("multiSignature", multiSignatureAsset);
282+
283+
return wallet;
284+
};

‎__tests__/unit/core-transactions/handlers/two/htlc-lock.test.ts‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ import { Mapper, Mocks } from "@packages/core-test-framework";
88
import { Generators } from "@packages/core-test-framework/src";
99
import { Factories, FactoryBuilder } from "@packages/core-test-framework/src/factories";
1010
import passphrases from "@packages/core-test-framework/src/internal/passphrases.json";
11-
import { HtlcLockExpiredError, InsufficientBalanceError } from "@packages/core-transactions/src/errors";
11+
import {
12+
HtlcLockExpiredError,
13+
InsufficientBalanceError,
14+
DisabledMultiSignatureSending,
15+
} from "@packages/core-transactions/src/errors";
1216
import { TransactionHandler } from "@packages/core-transactions/src/handlers";
1317
import { TransactionHandlerRegistry } from "@packages/core-transactions/src/handlers/handler-registry";
1418
import { Crypto, Enums, Interfaces, Managers, Transactions, Utils } from "@packages/crypto";
@@ -229,12 +233,20 @@ describe("Htlc lock", () => {
229233
).toResolve();
230234
});
231235

232-
it("should not throw - multi sign", async () => {
236+
it("should not throw - multi sign if and multiSignatureSendingEnabled=true", async () => {
237+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = true;
233238
await expect(
234239
handler.throwIfCannotBeApplied(multiSignatureHtlcLockTransaction, multiSignatureWallet),
235240
).toResolve();
236241
});
237242

243+
it("should throw - multi sign if and multiSignatureSendingEnabled=false", async () => {
244+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = false;
245+
await expect(
246+
handler.throwIfCannotBeApplied(multiSignatureHtlcLockTransaction, multiSignatureWallet),
247+
).rejects.toThrow(DisabledMultiSignatureSending);
248+
});
249+
238250
it("should throw if asset is undefined", async () => {
239251
htlcLockTransaction.data.asset = undefined;
240252

‎__tests__/unit/core-transactions/handlers/two/ipfs.test.ts‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Factories, FactoryBuilder } from "@packages/core-test-framework/src/fac
99
import passphrases from "@packages/core-test-framework/src/internal/passphrases.json";
1010
import { Mempool } from "@packages/core-transaction-pool";
1111
import { MempoolIndexes } from "@packages/core-transactions/src/enums";
12-
import { InsufficientBalanceError, IpfsHashAlreadyExists } from "@packages/core-transactions/src/errors";
12+
import { InsufficientBalanceError, IpfsHashAlreadyExists, DisabledMultiSignatureSending } from "@packages/core-transactions/src/errors";
1313
import { TransactionHandler } from "@packages/core-transactions/src/handlers";
1414
import { TransactionHandlerRegistry } from "@packages/core-transactions/src/handlers/handler-registry";
1515
import { Crypto, Enums, Interfaces, Managers, Transactions, Utils } from "@packages/crypto";
@@ -309,12 +309,20 @@ describe("Ipfs", () => {
309309
).toResolve();
310310
});
311311

312-
it("should not throw - multi sign", async () => {
312+
it("should not throw - multi sign if and multiSignatureSendingEnabled=true", async () => {
313+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = true;
313314
await expect(
314315
handler.throwIfCannotBeApplied(multiSignatureIpfsTransaction, multiSignatureWallet),
315316
).toResolve();
316317
});
317318

319+
it("should throw - multi sign if and multiSignatureSendingEnabled=false", async () => {
320+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = false;
321+
await expect(
322+
handler.throwIfCannotBeApplied(multiSignatureIpfsTransaction, multiSignatureWallet),
323+
).rejects.toThrow(DisabledMultiSignatureSending);
324+
});
325+
318326
it("should throw if wallet has insufficient funds", async () => {
319327
senderWallet.setBalance(Utils.BigNumber.ZERO);
320328

‎__tests__/unit/core-transactions/handlers/two/multi-payment.test.ts‎

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { StateStore } from "@packages/core-state/src/stores/state";
77
import { Generators } from "@packages/core-test-framework/src";
88
import { Factories, FactoryBuilder } from "@packages/core-test-framework/src/factories";
99
import passphrases from "@packages/core-test-framework/src/internal/passphrases.json";
10-
import { InsufficientBalanceError } from "@packages/core-transactions/src/errors";
10+
import { InsufficientBalanceError, DisabledMultiSignatureSending, DisabledMultiSignatureReceiving } from "@packages/core-transactions/src/errors";
1111
import { TransactionHandler } from "@packages/core-transactions/src/handlers";
1212
import { TransactionHandlerRegistry } from "@packages/core-transactions/src/handlers/handler-registry";
1313
import { Crypto, Enums, Interfaces, Managers, Transactions, Utils } from "@packages/crypto";
@@ -18,6 +18,7 @@ import {
1818
buildMultiSignatureWallet,
1919
buildRecipientWallet,
2020
buildSecondSignatureWallet,
21+
buildMultiSignatureRecipientWallet,
2122
buildSenderWallet,
2223
initApp,
2324
} from "../__support__/app";
@@ -26,6 +27,7 @@ let app: Application;
2627
let senderWallet: Wallets.Wallet;
2728
let secondSignatureWallet: Wallets.Wallet;
2829
let multiSignatureWallet: Wallets.Wallet;
30+
let multiSignatureRecipientWallet: Wallets.Wallet;
2931
let recipientWallet: Wallets.Wallet;
3032
let walletRepository: Contracts.State.WalletRepository;
3133
let factoryBuilder: FactoryBuilder;
@@ -59,11 +61,13 @@ beforeEach(() => {
5961
senderWallet = buildSenderWallet(factoryBuilder);
6062
secondSignatureWallet = buildSecondSignatureWallet(factoryBuilder);
6163
multiSignatureWallet = buildMultiSignatureWallet();
64+
multiSignatureRecipientWallet = buildMultiSignatureRecipientWallet();
6265
recipientWallet = buildRecipientWallet(factoryBuilder);
6366

6467
walletRepository.index(senderWallet);
6568
walletRepository.index(secondSignatureWallet);
6669
walletRepository.index(multiSignatureWallet);
70+
walletRepository.index(multiSignatureRecipientWallet);
6771
walletRepository.index(recipientWallet);
6872
});
6973

@@ -156,12 +160,22 @@ describe("MultiPaymentTransaction", () => {
156160
).toResolve();
157161
});
158162

159-
it("should not throw - multi sign", async () => {
163+
it("should not throw - multi sign if and multiSignatureSendingEnabled=true", async () => {
164+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = true;
160165
await expect(
161166
handler.throwIfCannotBeApplied(multiSignatureMultiPaymentTransaction, multiSignatureWallet),
162167
).toResolve();
163168
});
164169

170+
it("should throw - multi sign if and multiSignatureSendingEnabled=false", async () => {
171+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = false;
172+
await expect(
173+
handler.throwIfCannotBeApplied(multiSignatureMultiPaymentTransaction, multiSignatureWallet),
174+
).rejects.toThrow(
175+
DisabledMultiSignatureSending,
176+
);
177+
});
178+
165179
it("should throw if asset is undefined", async () => {
166180
multiPaymentTransaction.data.asset = undefined;
167181

@@ -183,6 +197,35 @@ describe("MultiPaymentTransaction", () => {
183197
InsufficientBalanceError,
184198
);
185199
});
200+
201+
it("should not throw if recipient is multisignature wallet and multiSignatureReceivingEnabled=true", async () => {
202+
Managers.configManager.getMilestone().multiSignatureReceivingEnabled = true;
203+
const multiPaymentTransaction = BuilderFactory.multiPayment()
204+
.addPayment("ARYJmeYHSUTgbxaiqsgoPwf6M3CYukqdKN", "10")
205+
.addPayment("AFyjB5jULQiYNsp37wwipCm9c7V1xEzTJD", "20")
206+
.addPayment(multiSignatureRecipientWallet.getAddress(), "20")
207+
.nonce("1")
208+
.sign(passphrases[0])
209+
.build();
210+
211+
await expect(handler.throwIfCannotBeApplied(multiPaymentTransaction, senderWallet)).toResolve();
212+
});
213+
214+
it("should throw if recipient is multisignature wallet and multiSignatureReceivingEnabled=false", async () => {
215+
Managers.configManager.getMilestone().multiSignatureReceivingEnabled = false;
216+
const multiPaymentTransaction = BuilderFactory.multiPayment()
217+
.addPayment("ARYJmeYHSUTgbxaiqsgoPwf6M3CYukqdKN", "10")
218+
.addPayment("AFyjB5jULQiYNsp37wwipCm9c7V1xEzTJD", "20")
219+
.addPayment(multiSignatureRecipientWallet.getAddress(), "20")
220+
.nonce("1")
221+
.sign(passphrases[0])
222+
.build();
223+
224+
await expect(handler.throwIfCannotBeApplied(multiPaymentTransaction, senderWallet)).rejects.toThrow(
225+
DisabledMultiSignatureReceiving,
226+
);
227+
});
228+
186229
});
187230

188231
describe("apply", () => {

‎__tests__/unit/core-transactions/handlers/two/transfer.test.ts‎

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {
1212
ColdWalletError,
1313
InsufficientBalanceError,
1414
SenderWalletMismatchError,
15+
DisabledMultiSignatureReceiving,
16+
DisabledMultiSignatureSending,
1517
} from "@packages/core-transactions/src/errors";
1618
import { TransactionHandler } from "@packages/core-transactions/src/handlers";
1719
import { TransactionHandlerRegistry } from "@packages/core-transactions/src/handlers/handler-registry";
@@ -24,6 +26,7 @@ import {
2426
buildMultiSignatureWallet,
2527
buildRecipientWallet,
2628
buildSecondSignatureWallet,
29+
buildMultiSignatureRecipientWallet,
2730
buildSenderWallet,
2831
initApp,
2932
} from "../__support__/app";
@@ -32,6 +35,7 @@ let app: Application;
3235
let senderWallet: Wallets.Wallet;
3336
let secondSignatureWallet: Wallets.Wallet;
3437
let multiSignatureWallet: Wallets.Wallet;
38+
let multiSignatureRecipientWallet: Wallets.Wallet;
3539
let recipientWallet: Wallets.Wallet;
3640
let walletRepository: Contracts.State.WalletRepository;
3741
let factoryBuilder: FactoryBuilder;
@@ -59,11 +63,13 @@ beforeEach(() => {
5963
senderWallet = buildSenderWallet(factoryBuilder);
6064
secondSignatureWallet = buildSecondSignatureWallet(factoryBuilder);
6165
multiSignatureWallet = buildMultiSignatureWallet();
66+
multiSignatureRecipientWallet = buildMultiSignatureRecipientWallet();
6267
recipientWallet = buildRecipientWallet(factoryBuilder);
6368

6469
walletRepository.index(senderWallet);
6570
walletRepository.index(secondSignatureWallet);
6671
walletRepository.index(multiSignatureWallet);
72+
walletRepository.index(multiSignatureRecipientWallet);
6773
walletRepository.index(recipientWallet);
6874
});
6975

@@ -116,6 +122,7 @@ describe("TransferTransaction", () => {
116122

117123
afterEach(async () => {
118124
Managers.configManager.set("network.pubKeyHash", pubKeyHash);
125+
119126
});
120127

121128
describe("bootstrap", () => {
@@ -142,12 +149,23 @@ describe("TransferTransaction", () => {
142149
).toResolve();
143150
});
144151

145-
it("should not throw - multi sign", async () => {
152+
it("should not throw - multi sign if and multiSignatureSendingEnabled=true", async () => {
153+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = true;
146154
await expect(
147155
handler.throwIfCannotBeApplied(multiSignatureTransferTransaction, multiSignatureWallet),
148156
).toResolve();
149157
});
150158

159+
160+
it("should throw - multi sign if and multiSignatureSendingEnabled=false", async () => {
161+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = false;
162+
await expect(
163+
handler.throwIfCannotBeApplied(multiSignatureTransferTransaction, multiSignatureWallet),
164+
).rejects.toThrow(
165+
DisabledMultiSignatureSending,
166+
);
167+
});
168+
151169
it("should throw", async () => {
152170
transferTransaction.data.senderPublicKey = "a".repeat(66);
153171
await expect(handler.throwIfCannotBeApplied(transferTransaction, senderWallet)).rejects.toThrow(
@@ -185,6 +203,34 @@ describe("TransferTransaction", () => {
185203
);
186204
});
187205

206+
it("should pass if recipient is multi signature wallet and multiSignatureReceivingEnabled=true", async () => {
207+
Managers.configManager.getMilestone().multiSignatureReceivingEnabled = true;
208+
209+
transferTransaction = BuilderFactory.transfer()
210+
.recipientId(multiSignatureRecipientWallet.getAddress())
211+
.amount("10000000")
212+
.sign(passphrases[0])
213+
.nonce("1")
214+
.build();
215+
216+
await expect(handler.throwIfCannotBeApplied(transferTransaction, senderWallet)).toResolve();
217+
});
218+
219+
it("should throw if recipient is multi signature wallet and multiSignatureReceivingEnabled=false", async () => {
220+
Managers.configManager.getMilestone().multiSignatureReceivingEnabled = false;
221+
222+
transferTransaction = BuilderFactory.transfer()
223+
.recipientId(multiSignatureRecipientWallet.getAddress())
224+
.amount("10000000")
225+
.sign(passphrases[0])
226+
.nonce("1")
227+
.build();
228+
229+
await expect(handler.throwIfCannotBeApplied(transferTransaction, senderWallet)).rejects.toThrow(
230+
DisabledMultiSignatureReceiving,
231+
);
232+
});
233+
188234
it("should not throw if recipient is cold wallet", async () => {
189235
const coldWallet: Wallets.Wallet = factoryBuilder
190236
.get("Wallet")

‎__tests__/unit/core-transactions/handlers/two/vote.test.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
InsufficientBalanceError,
1414
NoVoteError,
1515
UnvoteMismatchError,
16+
DisabledMultiSignatureSending,
1617
VotedForNonDelegateError,
1718
} from "@packages/core-transactions/src/errors";
1819
import { TransactionHandler } from "@packages/core-transactions/src/handlers";
@@ -297,12 +298,20 @@ describe("VoteTransaction", () => {
297298
).toResolve();
298299
});
299300

300-
it("should not throw - multi sign vote", async () => {
301+
it("should not throw - multi sign if and multiSignatureSendingEnabled=true", async () => {
302+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = true;
301303
await expect(
302304
handler.throwIfCannotBeApplied(multiSignatureVoteTransaction, multiSignatureWallet),
303305
).toResolve();
304306
});
305307

308+
it("should throw - multi sign if and multiSignatureSendingEnabled=false", async () => {
309+
Managers.configManager.getMilestone().multiSignatureSendingEnabled = false;
310+
await expect(
311+
handler.throwIfCannotBeApplied(multiSignatureVoteTransaction, multiSignatureWallet),
312+
).rejects.toThrow(DisabledMultiSignatureSending);
313+
});
314+
306315
it("should not throw if the unvote is valid and the wallet has voted", async () => {
307316
senderWallet.setAttribute("vote", delegateWallet1.getPublicKey());
308317
await expect(handler.throwIfCannotBeApplied(unvoteTransaction, senderWallet)).toResolve();

‎packages/core-test-framework/src/app/generators/crypto.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ export class CryptoGenerator extends Generator {
128128
blockBurnAddress: true,
129129
blsPublicKeyRegistrationEnabled: true,
130130
multiSignatureRegistrationEnabled: true,
131+
multiSignatureSendingEnabled: true,
132+
multiSignatureReceivingEnabled: true,
131133
},
132134
{
133135
height: rewardHeight,

‎packages/core-transactions/src/errors.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ export class UnsupportedMultiSignatureTransactionError extends TransactionError
9595
}
9696
}
9797

98+
export class DisabledMultiSignatureSending extends TransactionError {
99+
public constructor() {
100+
super(`Failed to apply transaction, because sending from multi signature wallets is disabled.`);
101+
}
102+
}
103+
104+
export class DisabledMultiSignatureReceiving extends TransactionError {
105+
public constructor() {
106+
super(`Failed to apply transaction, because receiving on multi signature wallets is disabled.`);
107+
}
108+
}
109+
110+
98111
export class InvalidSecondSignatureError extends TransactionError {
99112
public constructor() {
100113
super(`Failed to apply transaction, because the second signature could not be verified.`);

‎packages/core-transactions/src/handlers/one/transfer.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { Interfaces, Managers, Transactions } from "@arkecosystem/crypto";
33

44
import { isRecipientOnActiveNetwork } from "../../utils";
55
import { TransactionHandler, TransactionHandlerConstructor } from "../transaction";
6+
import {
7+
DisabledMultiSignatureReceiving,
8+
} from "../../errors";
69

710
// todo: revisit the implementation, container usage and arguments after core-database rework
811
// todo: replace unnecessary function arguments with dependency injection to avoid passing around references
@@ -30,6 +33,16 @@ export class TransferTransactionHandler extends TransactionHandler {
3033
transaction: Interfaces.ITransaction,
3134
sender: Contracts.State.Wallet,
3235
): Promise<void> {
36+
Utils.assert.defined<string>(transaction.data.recipientId);
37+
const recipient: Contracts.State.Wallet = this.walletRepository.findByAddress(transaction.data.recipientId);
38+
39+
if (recipient.hasMultiSignature()) {
40+
const milestone = Managers.configManager.getMilestone();
41+
if (milestone.multiSignatureReceivingEnabled !== true) {
42+
throw new DisabledMultiSignatureReceiving();
43+
}
44+
}
45+
3346
return super.throwIfCannotBeApplied(transaction, sender);
3447
}
3548

0 commit comments

Comments
 (0)