Skip to content

Commit bd3a892

Browse files
committed
Merge branch 'development' into ws-custom-subscriptions
2 parents f5a598c + 1412ef0 commit bd3a892

7 files changed

Lines changed: 95 additions & 3 deletions

File tree

config/config.devnet.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ features:
7373
stakingV5:
7474
enabled: true
7575
activationEpoch: 4817
76+
deprecatedRelayedV1V2:
77+
enabled: true
78+
activationEpoch: 4569
7679
nodeEpochsLeft:
7780
enabled: false
7881
transactionProcessor:

config/config.mainnet.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ features:
7171
stakingV5:
7272
enabled: true
7373
activationEpoch: 1951
74+
deprecatedRelayedV1V2:
75+
enabled: true
76+
activationEpoch: 1918
7477
nodeEpochsLeft:
7578
enabled: false
7679
transactionProcessor:

config/config.testnet.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ features:
7070
stakingV5:
7171
enabled: true
7272
activationEpoch: 2519
73+
deprecatedRelayedV1V2:
74+
enabled: true
75+
activationEpoch: 2038
7376
nodeEpochsLeft:
7477
enabled: false
7578
transactionProcessor:

src/common/api-config/api.config.service.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,23 @@ export class ApiConfigService {
907907
return this.configService.get<number>('features.stakingV5.activationEpoch') ?? 99999;
908908
}
909909

910+
isDeprecatedRelayedV1V2Enabled(): boolean {
911+
return this.configService.get<boolean>('features.deprecatedRelayedV1V2.enabled') ?? false;
912+
}
913+
914+
getDeprecatedRelayedV1V2ActivationEpoch(): number {
915+
return this.configService.get<number>('features.deprecatedRelayedV1V2.activationEpoch') ?? 99999;
916+
}
917+
918+
shouldDeprecateRelayedV1V2(epoch: number): boolean {
919+
const isEnabled = this.isDeprecatedRelayedV1V2Enabled();
920+
if (!isEnabled) {
921+
return false;
922+
}
923+
924+
return epoch >= this.getDeprecatedRelayedV1V2ActivationEpoch();
925+
}
926+
910927
isAssetsCdnFeatureEnabled(): boolean {
911928
return this.configService.get<boolean>('features.assetsFetch.enabled') ?? false;
912929
}

src/endpoints/transactions/transaction-action/entities/transaction.action.category.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export enum TransactionActionCategory {
44
stake = 'stake',
55
scCall = 'scCall',
66
scDeploy = 'scDeploy',
7+
deprecatedRelayedV1V2 = 'deprecatedRelayedV1V2',
78
}

src/endpoints/transactions/transaction.service.ts

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import { NetworkService } from 'src/endpoints/network/network.service';
4242
import { TransactionWithPpu } from './entities/transaction.with.ppu';
4343
import { GasBucket } from './entities/gas.bucket';
4444
import { GasBucketConstants } from './constants/gas.bucket.constants';
45+
import { TransactionAction } from "./transaction-action/entities/transaction.action";
46+
import { TransactionActionCategory } from "./transaction-action/entities/transaction.action.category";
4547

4648
@Injectable()
4749
export class TransactionService {
@@ -96,6 +98,32 @@ export class TransactionService {
9698
return await this.indexerService.getTransactionCount(filter, address);
9799
}
98100

101+
public reorderAccountSentTransactionsByNonce(transactions: TransactionDetailed[], accountAddress: string): TransactionDetailed[] {
102+
const sentPositions: number[] = [];
103+
const sentTransactions: TransactionDetailed[] = [];
104+
105+
transactions.forEach((tx, index) => {
106+
if (tx.sender === accountAddress) {
107+
sentPositions.push(index);
108+
sentTransactions.push(tx);
109+
}
110+
});
111+
112+
sentTransactions.sort((a, b) => {
113+
const nonceA = a.nonce ?? 0;
114+
const nonceB = b.nonce ?? 0;
115+
return nonceB - nonceA;
116+
});
117+
118+
const result = [...transactions];
119+
120+
sentPositions.forEach((position, index) => {
121+
result[position] = sentTransactions[index];
122+
});
123+
124+
return result;
125+
}
126+
99127
private getDistinctUserAddressesFromTransactions(transactions: Transaction[]): string[] {
100128
const allAddresses = [];
101129
for (const transaction of transactions) {
@@ -169,6 +197,13 @@ export class TransactionService {
169197
let transactions: TransactionDetailed[] = [];
170198
transactions = elasticTransactions.map(x => ApiUtils.mergeObjects(new TransactionDetailed(), x));
171199

200+
const hasSenderFilter = filter.sender || (filter.senders && filter.senders.length > 0);
201+
const hasReceiverFilter = filter.receivers && filter.receivers.length > 0;
202+
203+
if (address && !hasSenderFilter && !hasReceiverFilter) {
204+
transactions = this.reorderAccountSentTransactionsByNonce(transactions, address);
205+
}
206+
172207
if (filter.hashes) {
173208
const txHashes: string[] = filter.hashes;
174209
const elasticHashes = elasticTransactions.map(({ txHash }: any) => txHash);
@@ -193,7 +228,6 @@ export class TransactionService {
193228

194229
for (const transaction of transactions) {
195230
transaction.type = undefined;
196-
transaction.relayedVersion = this.extractRelayedVersion(transaction);
197231
}
198232

199233
await this.processTransactions(transactions, {
@@ -202,6 +236,8 @@ export class TransactionService {
202236
withActionTransferValue: queryOptions?.withActionTransferValue ?? false,
203237
});
204238

239+
this.processRelayedInfo(transactions);
240+
205241
return transactions;
206242
}
207243

@@ -225,9 +261,9 @@ export class TransactionService {
225261

226262
if (transaction !== null) {
227263
transaction.price = await this.getTransactionPrice(transaction);
228-
transaction.relayedVersion = this.extractRelayedVersion(transaction);
229264

230265
await this.processTransactions([transaction], { withScamInfo: true, withUsername: true, withActionTransferValue });
266+
this.processRelayedInfo([transaction]);
231267

232268
if (transaction.pendingResults === true && transaction.results) {
233269
for (const result of transaction.results) {
@@ -347,6 +383,26 @@ export class TransactionService {
347383
}
348384
}
349385

386+
public processRelayedInfo(transactions: TransactionDetailed[]) {
387+
for (const transaction of transactions) {
388+
transaction.relayedVersion = this.extractRelayedVersion(transaction);
389+
if (transaction.relayedVersion && ["v1", "v2"].includes(transaction.relayedVersion)) {
390+
const shouldSkip = this.apiConfigService.shouldDeprecateRelayedV1V2(transaction.epoch ?? 0);
391+
if (shouldSkip) {
392+
transaction.function = undefined;
393+
transaction.action = new TransactionAction({
394+
category: TransactionActionCategory.deprecatedRelayedV1V2,
395+
name: "Deprecated transaction action",
396+
description: `Relayed v1/v2 transactions are deprecated`,
397+
});
398+
}
399+
}
400+
if (!transaction.isRelayed) {
401+
transaction.relayedVersion = undefined;
402+
}
403+
}
404+
}
405+
350406
async processTransactions(transactions: Transaction[], options: { withScamInfo: boolean, withUsername: boolean, withActionTransferValue: boolean }): Promise<void> {
351407

352408
this.normalizeTimestampMs(transactions);
@@ -587,7 +643,7 @@ export class TransactionService {
587643
}
588644

589645
private extractRelayedVersion(transaction: TransactionDetailed): string | undefined {
590-
if (transaction.isRelayed == true && transaction.data) {
646+
if (transaction.data) {
591647
const decodedData = BinaryUtils.base64Decode(transaction.data);
592648

593649
if (decodedData.startsWith('relayedTx@')) {

src/endpoints/transfers/transfer.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ export class TransferService {
142142
transactions.push(transaction);
143143
}
144144

145+
const hasSenderFilter = filter.sender || (filter.senders && filter.senders.length > 0);
146+
const hasReceiverFilter = filter.receivers && filter.receivers.length > 0;
147+
148+
if (filter.address && !hasSenderFilter && !hasReceiverFilter) {
149+
transactions = this.transactionService.reorderAccountSentTransactionsByNonce(transactions, filter.address);
150+
}
151+
145152
if (queryOptions.withBlockInfo || (fields && fields.includesSome(['senderBlockHash', 'receiverBlockHash', 'senderBlockNonce', 'receiverBlockNonce']))) {
146153
await this.transactionService.applyBlockInfo(transactions);
147154
}
@@ -157,6 +164,8 @@ export class TransferService {
157164
withActionTransferValue: queryOptions.withActionTransferValue ?? false,
158165
});
159166

167+
this.transactionService.processRelayedInfo(transactions);
168+
160169
return transactions;
161170
}
162171

0 commit comments

Comments
 (0)