From 52be7d2d1a6042afaae384c12697a59d705e1ab9 Mon Sep 17 00:00:00 2001 From: Priyank <3169068+rdlrt@users.noreply.github.com> Date: Thu, 24 Aug 2023 14:14:28 +1000 Subject: [PATCH] Align *_txs to return consistent data --- files/grest/rpc/account/account_txs.sql | 53 ++++++++++++++ files/grest/rpc/account/account_utxos.sql | 17 ++--- files/grest/rpc/address/address_txs.sql | 39 ++++------ files/grest/rpc/address/credential_txs.sql | 44 +++++------- files/grest/rpc/address/credential_utxos.sql | 75 +++++++++++++++++--- files/grest/rpc/assets/asset_txs.sql | 26 +++---- files/grest/rpc/blocks/block_txs.sql | 19 +++-- 7 files changed, 182 insertions(+), 91 deletions(-) create mode 100644 files/grest/rpc/account/account_txs.sql diff --git a/files/grest/rpc/account/account_txs.sql b/files/grest/rpc/account/account_txs.sql new file mode 100644 index 00000000..bcf8c76b --- /dev/null +++ b/files/grest/rpc/account/account_txs.sql @@ -0,0 +1,53 @@ +CREATE OR REPLACE FUNCTION grest.account_txs(_stake_address text, _after_block_height integer DEFAULT 0) +RETURNS TABLE ( + tx_hash text, + epoch_no word31type, + block_height word31type, + block_time integer +) +LANGUAGE plpgsql +AS $$ +DECLARE + _tx_id_min bigint; + _tx_id_list bigint[]; +BEGIN + SELECT INTO _tx_id_min id + FROM tx + WHERE block_id >= (SELECT id FROM block WHERE block_no >= _after_block_height ORDER BY id limit 1) + ORDER BY id limit 1; + + -- all tx_out & tx_in tx ids + SELECT INTO _tx_id_list ARRAY_AGG(tx_id) + FROM ( + SELECT tx_id + FROM tx_out + WHERE stake_address_id = ANY(SELECT id FROM stake_address WHERE view = _stake_address) + AND tx_id >= _tx_id_min + -- + UNION + -- + SELECT tx_in_id AS tx_id + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE + tx_in.tx_in_id IS NOT NULL + AND tx_out.stake_address_id = ANY(SELECT id FROM stake_address WHERE view = _stake_address) + AND tx_in.tx_in_id >= _tx_id_min + ) AS tmp; + + RETURN QUERY + SELECT + DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) + AND block.block_no >= _after_block_height + ORDER BY block.block_no DESC; +END; +$$; + +COMMENT ON FUNCTION grest.account_txs IS 'Get transactions associated with a given stake address'; -- noqa: LT01 diff --git a/files/grest/rpc/account/account_utxos.sql b/files/grest/rpc/account/account_utxos.sql index 2692104d..ae98a752 100644 --- a/files/grest/rpc/account/account_utxos.sql +++ b/files/grest/rpc/account/account_utxos.sql @@ -18,16 +18,13 @@ BEGIN tx_out.value::text AS value, b.block_no AS block_height, EXTRACT(EPOCH FROM b.time)::integer AS block_time - FROM - tx_out - LEFT JOIN tx_in ON tx_in.tx_out_id = tx_out.tx_id - AND tx_in.tx_out_index = tx_out.index - INNER JOIN tx ON tx.id = tx_out.tx_id - LEFT JOIN block AS b ON b.id = tx.block_id - WHERE - tx_in.tx_out_id IS NULL - AND - tx_out.stake_address_id = (SELECT id FROM stake_address WHERE view = _stake_address); + FROM tx_out + LEFT JOIN tx_in ON tx_in.tx_out_id = tx_out.tx_id + AND tx_in.tx_out_index = tx_out.index + INNER JOIN tx ON tx.id = tx_out.tx_id + LEFT JOIN block AS b ON b.id = tx.block_id + WHERE tx_in.tx_out_id IS NULL + AND tx_out.stake_address_id = (SELECT id FROM stake_address WHERE view = _stake_address); END; $$; diff --git a/files/grest/rpc/address/address_txs.sql b/files/grest/rpc/address/address_txs.sql index 840be398..743ea71f 100644 --- a/files/grest/rpc/address/address_txs.sql +++ b/files/grest/rpc/address/address_txs.sql @@ -19,24 +19,18 @@ BEGIN -- all tx_out & tx_in tx ids SELECT INTO _tx_id_list ARRAY_AGG(tx_id) FROM ( - SELECT - tx_id - FROM - tx_out - WHERE - address = ANY(_addresses) + SELECT tx_id + FROM tx_out + WHERE address = ANY(_addresses) AND tx_id >= _tx_id_min -- UNION -- - SELECT - tx_in_id AS tx_id - FROM - tx_out - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index - WHERE - tx_in.tx_in_id IS NOT NULL + SELECT tx_in_id AS tx_id + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE tx_in.tx_in_id IS NOT NULL AND tx_out.address = ANY(_addresses) AND tx_in.tx_in_id >= _tx_id_min ) AS tmp; @@ -44,17 +38,14 @@ BEGIN RETURN QUERY SELECT DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, - block.epoch_no, - block.block_no, - EXTRACT(EPOCH FROM block.time)::integer - FROM - public.tx - INNER JOIN public.block ON block.id = tx.block_id - WHERE - tx.id = ANY(_tx_id_list) + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) AND block.block_no >= _after_block_height - ORDER BY - block.block_no DESC; + ORDER BY block.block_no DESC; END; $$; diff --git a/files/grest/rpc/address/credential_txs.sql b/files/grest/rpc/address/credential_txs.sql index d581858a..e3ad6a4e 100644 --- a/files/grest/rpc/address/credential_txs.sql +++ b/files/grest/rpc/address/credential_txs.sql @@ -16,34 +16,29 @@ BEGIN SELECT INTO _payment_cred_bytea ARRAY_AGG(cred_bytea) FROM ( SELECT DECODE(cred_hex, 'hex') AS cred_bytea - FROM - UNNEST(_payment_credentials) AS cred_hex + FROM UNNEST(_payment_credentials) AS cred_hex ) AS tmp; SELECT INTO _tx_id_min id - FROM tx - WHERE block_id >= (SELECT id FROM block WHERE block_no = _after_block_height) - ORDER BY id limit 1; + FROM tx + WHERE block_id >= (SELECT id FROM block WHERE block_no >= _after_block_height ORDER BY id limit 1) + ORDER BY id limit 1; -- all tx_out & tx_in tx ids SELECT INTO _tx_id_list ARRAY_AGG(tx_id) FROM ( SELECT tx_id - FROM - tx_out - WHERE - payment_cred = ANY(_payment_cred_bytea) + FROM tx_out + WHERE payment_cred = ANY(_payment_cred_bytea) AND tx_id >= _tx_id_min -- UNION -- SELECT tx_in_id AS tx_id - FROM - tx_out - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index - WHERE - tx_in.tx_in_id IS NOT NULL + FROM tx_out + LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id + AND tx_out.index = tx_in.tx_out_index + WHERE tx_in.tx_in_id IS NOT NULL AND tx_out.payment_cred = ANY(_payment_cred_bytea) AND tx_in.tx_in_id >= _tx_id_min ) AS tmp; @@ -51,18 +46,15 @@ BEGIN RETURN QUERY SELECT DISTINCT(ENCODE(tx.hash, 'hex')) AS tx_hash, - block.epoch_no, - block.block_no, - EXTRACT(EPOCH FROM block.time)::integer - FROM - public.tx - INNER JOIN public.block ON block.id = tx.block_id - WHERE - tx.id = ANY(_tx_id_list) + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.tx + INNER JOIN public.block AS b ON b.id = tx.block_id + WHERE tx.id = ANY(_tx_id_list) AND block.block_no >= _after_block_height - ORDER BY - block.block_no DESC; + ORDER BY block.block_no DESC; END; $$; -COMMENT ON FUNCTION grest.address_txs IS 'Get the transaction hash list of a payment credentials array, optionally filtering after specified block height (inclusive).'; --noqa: LT01 +COMMENT ON FUNCTION grest.credential_txs IS 'Get the transaction hash list of a payment credentials array, optionally filtering after specified block height (inclusive).'; --noqa: LT01 diff --git a/files/grest/rpc/address/credential_utxos.sql b/files/grest/rpc/address/credential_utxos.sql index 6d9d4677..685b8105 100644 --- a/files/grest/rpc/address/credential_utxos.sql +++ b/files/grest/rpc/address/credential_utxos.sql @@ -1,8 +1,19 @@ -CREATE OR REPLACE FUNCTION grest.credential_utxos(_payment_credentials text []) +CREATE OR REPLACE FUNCTION grest.credential_utxos(_payment_credentials text [], _extended boolean DEFAULT false) RETURNS TABLE ( tx_hash text, tx_index smallint, - value text + address text, + value text, + stake_address text, + payment_cred text, + epoch_no word31type, + block_height word31type, + block_time integer, + datum_hash text, + inline_datum jsonb, + reference_script jsonb, + asset_list jsonb, + is_spent boolean ) LANGUAGE plpgsql AS $$ @@ -12,23 +23,65 @@ DECLARE BEGIN SELECT INTO _payment_cred_bytea ARRAY_AGG(cred_bytea) FROM ( - SELECT - DECODE(cred_hex, 'hex') AS cred_bytea - FROM - UNNEST(_payment_credentials) AS cred_hex + SELECT DECODE(cred_hex, 'hex') AS cred_bytea + FROM UNNEST(_payment_credentials) AS cred_hex ) AS tmp; RETURN QUERY SELECT ENCODE(tx.hash, 'hex')::text AS tx_hash, tx_out.index::smallint, - tx_out.value::text AS balance + tx_out.address::text, + tx_out.value::text, + sa.view::text as stake_address, + ENCODE(tx_out.payment_cred, 'hex') AS payment_cred, + b.epoch_no, + b.block_no, + EXTRACT(EPOCH FROM b.time)::integer AS block_time, + ENCODE(tx_out.data_hash, 'hex') AS datum_hash, + (CASE + WHEN _extended = false OR tx_out.inline_datum_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'bytes', ENCODE(datum.bytes, 'hex'), + 'value', datum.value + ) + END) AS inline_datum, + (CASE + WHEN _extended = false OR tx_out.reference_script_id IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'hash', ENCODE(script.hash, 'hex'), + 'bytes', ENCODE(script.bytes, 'hex'), + 'value', script.json, + 'type', script.type::text, + 'size', script.serialised_size + ) + END) AS reference_script, + (CASE + WHEN _extended = false OR ma.policy IS NULL THEN NULL + ELSE JSONB_BUILD_OBJECT( + 'policy_id', ENCODE(ma.policy, 'hex'), + 'asset_name', ENCODE(ma.name, 'hex'), + 'fingerprint', ma.fingerprint, + 'decimals', aic.decimals, + 'quantity', mto.quantity::text + ) + END + ) AS asset_list, + (CASE + WHEN tx_out.consumed_by_tx_in_id IS NULL THEN false + ELSE true + END) AS is_spent FROM tx_out - INNER JOIN tx ON tx_out.tx_id = tx.id - LEFT JOIN tx_in ON tx_out.tx_id = tx_in.tx_out_id - AND tx_out.index = tx_in.tx_out_index + INNER JOIN tx ON tx_out.tx_id = tx.id + LEFT JOIN stake_address AS sa ON tx_out.stake_address_id = sa.id + LEFT JOIN block AS b ON b.id = tx.block_id + LEFT JOIN ma_tx_out AS mto ON mto.tx_out_id = tx_out.id + LEFT JOIN multi_asset AS ma ON ma.id = mto.ident + LEFT JOIN grest.asset_info_cache AS aic ON aic.asset_id = ma.id + LEFT JOIN datum ON datum.id = tx_out.inline_datum_id + LEFT JOIN script ON script.id = tx_out.reference_script_id WHERE payment_cred = ANY(_payment_cred_bytea) - AND tx_in.tx_out_id IS NULL; + ; END; $$; diff --git a/files/grest/rpc/assets/asset_txs.sql b/files/grest/rpc/assets/asset_txs.sql index e34fc924..01d950f2 100644 --- a/files/grest/rpc/assets/asset_txs.sql +++ b/files/grest/rpc/assets/asset_txs.sql @@ -19,14 +19,15 @@ DECLARE BEGIN SELECT DECODE(_asset_policy, 'hex') INTO _asset_policy_decoded; SELECT DECODE( - CASE WHEN _asset_name IS NULL - THEN '' - ELSE - _asset_name + CASE + WHEN _asset_name IS NULL THEN '' + ELSE _asset_name END, 'hex' ) INTO _asset_name_decoded; - SELECT id INTO _asset_id FROM multi_asset AS ma WHERE ma.policy = _asset_policy_decoded AND ma.name = _asset_name_decoded; + SELECT id INTO _asset_id + FROM multi_asset AS ma + WHERE ma.policy = _asset_policy_decoded AND ma.name = _asset_name_decoded; RETURN QUERY SELECT @@ -35,18 +36,17 @@ BEGIN tx_hashes.block_no, EXTRACT(EPOCH FROM tx_hashes.time)::integer FROM ( - SELECT DISTINCT ON (tx.hash) + SELECT DISTINCT ON (tx.hash,txo.index::smallint) tx.hash, block.epoch_no, block.block_no, block.time - FROM - ma_tx_out AS mto - INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id - INNER JOIN tx ON tx.id = txo.tx_id - INNER JOIN block ON block.id = tx.block_id - LEFT JOIN tx_in AS txi ON txo.tx_id = txi.tx_out_id - AND txo.index::smallint = txi.tx_out_index::smallint + FROM ma_tx_out AS mto + INNER JOIN tx_out AS txo ON txo.id = mto.tx_out_id + INNER JOIN tx ON tx.id = txo.tx_id + INNER JOIN block ON block.id = tx.block_id + LEFT JOIN tx_in AS txi ON txo.tx_id = txi.tx_out_id + AND txo.index::smallint = txi.tx_out_index::smallint WHERE mto.ident = _asset_id AND block.block_no >= _after_block_height diff --git a/files/grest/rpc/blocks/block_txs.sql b/files/grest/rpc/blocks/block_txs.sql index 8bdeeaf6..daf45adf 100644 --- a/files/grest/rpc/blocks/block_txs.sql +++ b/files/grest/rpc/blocks/block_txs.sql @@ -1,7 +1,10 @@ CREATE OR REPLACE FUNCTION grest.block_txs(_block_hashes text []) RETURNS TABLE ( block_hash text, - tx_hashes text [] + tx_hash text, + epoch_no word31type, + block_height word31type, + block_time integer ) LANGUAGE plpgsql AS $$ @@ -21,13 +24,15 @@ BEGIN RETURN QUERY SELECT - encode(b.hash, 'hex'), - ARRAY_AGG(ENCODE(tx.hash::bytea, 'hex')) - FROM - public.block AS b - INNER JOIN public.tx ON tx.block_id = b.id + ENCODE(b.hash, 'hex'), + ENCODE(tx.hash, 'hex') AS tx_hash, + b.epoch_no, + b.block_no AS block_height, + EXTRACT(EPOCH FROM b.time)::integer AS block_time + FROM public.block AS b + INNER JOIN public.tx ON tx.block_id = b.id WHERE b.id = ANY(_block_ids) - GROUP BY b.hash; + ; END; $$;