Skip to content

Commit

Permalink
feat: add registrations to transaction query
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Cruz committed Nov 24, 2020
1 parent 5b3583f commit 3016a39
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 6 deletions.
32 changes: 28 additions & 4 deletions cardano-rosetta-server/src/server/db/blockchain-repository.ts
Expand Up @@ -7,7 +7,8 @@ import Queries, {
FindTransactionsInputs,
FindTransactionsOutputs,
FindTransactionWithdrawals,
FindUtxo
FindUtxo,
FindTransactionRegistrations
} from './queries/blockchain-queries';
import { Logger } from 'fastify';
import { Block, GenesisBlock, Transaction, PopulatedTransaction, Utxo } from '../models';
Expand Down Expand Up @@ -95,7 +96,8 @@ const mapTransactionsToDict = (transactions: Transaction[]): TransactionsMap =>
size: transaction.size,
inputs: [],
outputs: [],
withdrawals: []
withdrawals: [],
registrations: []
}
};
}, {});
Expand Down Expand Up @@ -152,10 +154,10 @@ const parseOutputsRow = (transaction: PopulatedTransaction, output: FindTransact
});

/**
* Updates the transaction appending outputs
* Updates the transaction appending withdrawals
*
* @param transaction
* @param output
* @param withdrawal
*/
const parseWithdrawalsRow = (
transaction: PopulatedTransaction,
Expand All @@ -168,6 +170,23 @@ const parseWithdrawalsRow = (
})
});

/**
* Updates the transaction appending registrations
*
* @param transaction
* @param registration
*/
const parseRegistrationsRow = (
transaction: PopulatedTransaction,
registration: FindTransactionRegistrations
): PopulatedTransaction => ({
...transaction,
registrations: transaction.registrations.concat({
stakeAddress: registration.address,
amount: registration.amount
})
});

const populateTransactions = async (
databaseInstance: Pool,
transactionsMap: TransactionsMap
Expand All @@ -184,9 +203,14 @@ const populateTransactions = async (
Queries.findTransactionWithdrawals,
[transactionsHashes]
);
const registrations: QueryResult<FindTransactionRegistrations> = await databaseInstance.query(
Queries.findTransactionRegistrations,
[transactionsHashes]
);
transactionsMap = populateTransactionField(transactionsMap, inputs.rows, parseInputsRow);
transactionsMap = populateTransactionField(transactionsMap, outputs.rows, parseOutputsRow);
transactionsMap = populateTransactionField(transactionsMap, withdrawals.rows, parseWithdrawalsRow);
transactionsMap = populateTransactionField(transactionsMap, registrations.rows, parseRegistrationsRow);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore it will never be undefined
return Object.values(transactionsMap);
Expand Down
18 changes: 18 additions & 0 deletions cardano-rosetta-server/src/server/db/queries/blockchain-queries.ts
Expand Up @@ -129,6 +129,11 @@ export interface FindTransactionWithdrawals extends FindTransactionFieldResult {
amount: string;
}

export interface FindTransactionRegistrations extends FindTransactionFieldResult {
address: string;
amount: string;
}

const findTransactionWithdrawals = `
SELECT
amount,
Expand All @@ -141,6 +146,18 @@ WHERE
tx.hash = ANY ($1)
`;

const findTransactionRegistrations = `
SELECT
tx.deposit as "amount",
sa.view as "address",
tx.hash as "txHash"
FROM stake_registration sr
INNER JOIN tx on tx.id = sr.tx_id
INNER JOIN stake_address sa on sr.addr_id = sa.id
WHERE
tx.hash = ANY ($1)
`;

const findLatestBlockNumber = `
SELECT
block_no as "blockHeight"
Expand Down Expand Up @@ -192,6 +209,7 @@ const Queries = {
findTransactionsInputs,
findTransactionsOutputs,
findTransactionWithdrawals,
findTransactionRegistrations,
findLatestBlockNumber,
findGenesisBlock,
findUtxoByAddressAndBlock
Expand Down
6 changes: 6 additions & 0 deletions cardano-rosetta-server/src/server/models.ts
Expand Up @@ -45,6 +45,11 @@ export interface Withdrawal {
amount: string;
}

export interface Registration {
stakeAddress: string;
amount: string;
}

export interface Transaction {
hash: string;
blockHash: string;
Expand All @@ -56,6 +61,7 @@ export interface PopulatedTransaction extends Transaction {
inputs: TransactionInput[];
outputs: TransactionOutput[];
withdrawals: Withdrawal[];
registrations: Registration[];
}

export interface Network {
Expand Down
4 changes: 4 additions & 0 deletions cardano-rosetta-server/src/server/openApi.json
Expand Up @@ -916,6 +916,10 @@
"description": "If it's a withdrawal operation, the amount will re returned here.",
"$ref": "#/components/schemas/Amount"
},
"depositAmount": {
"description": "If it's a registration operation, the amount will re returned here.",
"$ref": "#/components/schemas/Amount"
},
"staking_credential": {
"$ref": "#/components/schemas/PublicKey"
},
Expand Down
24 changes: 22 additions & 2 deletions cardano-rosetta-server/src/server/utils/data-mapper.ts
Expand Up @@ -99,6 +99,23 @@ export const mapToRosettaTransaction = (transaction: PopulatedTransaction): Comp
withdrawalAmount: mapAmount(`-${withdrawal.amount}`)
}
}));

const registrationsAsOperations: Components.Schemas.Operation[] = transaction.registrations.map(
(registration, index) => ({
operation_identifier: {
index: inputsAsOperations.length + withdrawalsAsOperations.length + index
},
type: operationType.STAKE_KEY_REGISTRATION,
status: SUCCESS_STATUS,
account: {
address: registration.stakeAddress
},
metadata: {
depositAmount: mapAmount(registration.amount)
}
})
);

// Output related operations are all the inputs.This will iterate over the collection again
// but it's better for the sake of clarity and tx are bounded by block size (it can be
// refactored to use a reduce)
Expand All @@ -108,7 +125,7 @@ export const mapToRosettaTransaction = (transaction: PopulatedTransaction): Comp

const outputsAsOperations = transaction.outputs.map((output, index) =>
createOperation(
inputsAsOperations.length + withdrawalsAsOperations.length + index,
inputsAsOperations.length + withdrawalsAsOperations.length + registrationsAsOperations.length + index,
operationType.OUTPUT,
SUCCESS_STATUS,
output.address,
Expand All @@ -123,7 +140,10 @@ export const mapToRosettaTransaction = (transaction: PopulatedTransaction): Comp
transaction_identifier: {
hash: transaction.hash
},
operations: inputsAsOperations.concat(withdrawalsAsOperations).concat(outputsAsOperations)
operations: inputsAsOperations
.concat(withdrawalsAsOperations)
.concat(registrationsAsOperations)
.concat(outputsAsOperations)
};
};

Expand Down
4 changes: 4 additions & 0 deletions cardano-rosetta-server/src/types/rosetta-types.d.ts
Expand Up @@ -554,6 +554,10 @@ declare namespace Components {
withdrawalAmount?: /* Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. */ Amount;
staking_credential?: /* PublicKey contains a public key byte array for a particular CurveType encoded in hex. Note that there is no PrivateKey struct as this is NEVER the concern of an implementation. */ PublicKey;
pool_key_hash?: string;
/**
* If it's a registration operation, the amount will re returned here.
*/
depositAmount?: /* Amount is some Value of a Currency. It is considered invalid to specify a Value without a Currency. */ Amount;
}
/**
* OperationStatus is utilized to indicate which Operation status are considered successful.
Expand Down

0 comments on commit 3016a39

Please sign in to comment.