Skip to content

Commit 9de4f61

Browse files
authored
refactor: operations parsing refak (#649)
2 parents 9778ea5 + d59b99c commit 9de4f61

27 files changed

+1905
-853
lines changed

.github/workflows/pr-preprod-tests.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,8 @@ jobs:
210210
# Output test result
211211
echo "construction_result=${CONSTRUCTION_RESULT:-0}" >> $GITHUB_OUTPUT
212212
213-
# Don't fail the whole job if construction tests fail
214-
# These are informational for now
215-
exit 0
213+
# Fail if construction tests failed
214+
exit ${CONSTRUCTION_RESULT:-0}
216215
env:
217216
ROSETTA_URL: http://localhost:8082
218217
CARDANO_NETWORK: preprod

api/src/main/java/org/cardanofoundation/rosetta/api/account/mapper/AccountMapperUtil.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import java.math.BigInteger;
1919
import java.util.*;
2020

21+
import static org.cardanofoundation.rosetta.common.util.Constants.ADA;
22+
import static org.cardanofoundation.rosetta.common.util.Constants.ADA_DECIMALS;
23+
2124
@Component
2225
@RequiredArgsConstructor
2326
public class AccountMapperUtil {
@@ -76,7 +79,7 @@ public List<Coin> mapUtxosToCoins(List<Utxo> utxos,
7679
Amt adaAsset = utxo.getAmounts().stream()
7780
.filter(amt -> Constants.LOVELACE.equals(amt.getUnit()))
7881
.findFirst()
79-
.orElseGet(() -> new Amt(null, Constants.ADA, BigInteger.ZERO));
82+
.orElseGet(() -> new Amt(null, ADA, BigInteger.ZERO));
8083

8184
String coinIdentifier = "%s:%d".formatted(utxo.getTxHash(), utxo.getOutputIndex());
8285

@@ -144,8 +147,8 @@ private static int getDecimalsWithFallback(@NotNull TokenRegistryCurrencyData me
144147

145148
private CurrencyResponse getAdaCurrency() {
146149
return CurrencyResponse.builder()
147-
.symbol(Constants.ADA)
148-
.decimals(Constants.ADA_DECIMALS)
150+
.symbol(ADA)
151+
.decimals(ADA_DECIMALS)
149152
.build();
150153
}
151154

api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/CardanoConstructionServiceImpl.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public class CardanoConstructionServiceImpl implements CardanoConstructionServic
7373

7474
private final LedgerBlockService ledgerBlockService;
7575
private final ProtocolParamService protocolParamService;
76-
private final OperationService operationService;
76+
private final TransactionOperationParser transactionOperationParser;
7777
private final RestTemplate restTemplate;
7878
private final OfflineSlotService offlineSlotService;
7979

@@ -89,22 +89,27 @@ public class CardanoConstructionServiceImpl implements CardanoConstructionServic
8989
@Override
9090
public TransactionParsed parseTransaction(Network network, String transaction, boolean signed) {
9191
Array decodeTransaction = decodeTransaction(transaction);
92+
9293
try {
9394
TransactionData convertedTr = CborArrayToTransactionData.convert(decodeTransaction, signed);
94-
List<Operation> operations = operationService.getOperationsFromTransactionData(convertedTr, network);
95+
List<Operation> operations = transactionOperationParser.getOperationsFromTransactionData(convertedTr, network);
9596
List<AccountIdentifier> accountIdentifierSigners = new ArrayList<>();
97+
9698
if (signed) {
9799
log.info("[parseSignedTransaction] About to get signatures from parsed transaction");
98100
List<String> accumulator = convertedTr.transactionExtraData().operations().stream()
99-
.map(o -> operationService.getSignerFromOperation(network, o))
101+
.map(o -> transactionOperationParser.getSignerFromOperation(network, o))
100102
.flatMap(List::stream)
101103
.toList();
104+
102105
accountIdentifierSigners = getUniqueAccountIdentifiers(accumulator);
103106
}
107+
104108
return new TransactionParsed(operations, accountIdentifierSigners);
105109
} catch (CborException | CborDeserializationException | CborSerializationException error) {
106110
log.error("{} [parseTransaction] Cant instantiate transaction from transaction bytes",
107111
error.getMessage(), error);
112+
108113
throw ExceptionFactory.invalidTransactionError();
109114
}
110115
}
@@ -624,7 +629,7 @@ private TransactionBody deserializeTransactionBody(String unsignedTransaction) {
624629
private List<AccountIdentifier> getUniqueAccountIdentifiers(List<String> addresses) {
625630
return new HashSet<>(addresses)
626631
.stream()
627-
.map(s -> new AccountIdentifier(s, null, null))
632+
.map(address -> new AccountIdentifier(address, null, null))
628633
.toList();
629634
}
630635

api/src/main/java/org/cardanofoundation/rosetta/api/construction/service/OperationService.java

Lines changed: 0 additions & 192 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package org.cardanofoundation.rosetta.api.construction.service;
2+
3+
import co.nstant.in.cbor.CborException;
4+
import com.bloxbean.cardano.client.common.model.Network;
5+
import com.bloxbean.cardano.client.exception.CborDeserializationException;
6+
import com.bloxbean.cardano.client.exception.CborSerializationException;
7+
import org.cardanofoundation.rosetta.common.model.cardano.transaction.TransactionData;
8+
import org.openapitools.client.model.Operation;
9+
10+
import java.util.List;
11+
12+
/**
13+
* Parser interface for extracting Rosetta operations from Cardano transactions.
14+
* <p>
15+
* This parser handles the conversion between Cardano transaction structures and Rosetta API
16+
* operations, including inputs, outputs, certificates (staking, pool, governance), and withdrawals.
17+
* </p>
18+
*/
19+
public interface TransactionOperationParser {
20+
21+
/**
22+
* Extracts and constructs a complete list of Rosetta operations from transaction data.
23+
* <p>
24+
* This method processes all operation types from a Cardano transaction, including:
25+
* <ul>
26+
* <li>Input operations - UTxO consumption</li>
27+
* <li>Output operations - UTxO creation</li>
28+
* <li>Certificate operations - Staking registrations, delegations, pool operations</li>
29+
* <li>Governance operations - DRep vote delegations, pool governance votes</li>
30+
* <li>Withdrawal operations - Staking reward withdrawals</li>
31+
* </ul>
32+
* </p>
33+
*
34+
* @param data the transaction data containing the transaction body and extra metadata
35+
* @param network the Cardano network (mainnet/testnet) for address generation
36+
* @return a list of Rosetta operations representing all transaction activities
37+
* @throws CborDeserializationException if CBOR deserialization fails
38+
* @throws CborException if CBOR processing encounters an error
39+
* @throws CborSerializationException if CBOR serialization fails
40+
*/
41+
List<Operation> getOperationsFromTransactionData(TransactionData data, Network network)
42+
throws CborDeserializationException, CborException, CborSerializationException;
43+
44+
/**
45+
* Determines the required signers for a given operation.
46+
* <p>
47+
* Different operation types require different signers:
48+
* <ul>
49+
* <li>Pool operations - Pool owners, reward address, and optionally payment address</li>
50+
* <li>Staking operations - Stake address derived from staking credential</li>
51+
* <li>Regular operations - Account address from the operation</li>
52+
* </ul>
53+
* </p>
54+
*
55+
* @param network the Cardano network for address generation
56+
* @param operation the operation to extract signers from
57+
* @return list of addresses that must sign this operation
58+
*/
59+
List<String> getSignerFromOperation(Network network, Operation operation);
60+
61+
}

0 commit comments

Comments
 (0)