From acfd40753a7cf486cc7b235552584bfe60a3b760 Mon Sep 17 00:00:00 2001 From: Lincon Vidal Date: Thu, 11 Sep 2025 07:55:29 -0300 Subject: [PATCH 1/5] fix: update expected error codes in DRep delegation test cases + enhancements (#592) - Changed expected error code from 5040 to 5000 in multiple DRep delegation JSON test files to reflect updated error handling. - Added new integration test cases for DRep vote delegation, covering scenarios with matching and mismatching types, as well as handling of CIP-129 prefixes. - Revised existing test cases to ensure correct DRep id handling and error messages. - Updated DRep delegation guide to clarify the requirement of the `type` field for both key_hash and script_hash formats. --- docs/docs/user-guides/drep-delegation.md | 7 +- .../cip129_key_hash_with_matching_type.json | 103 ++++++++++++++++++ .../cip129_mismatch_type.json | 16 +-- ...cip129_script_hash_with_matching_type.json | 103 ++++++++++++++++++ ...gation_script_hash_with_cip129_prefix.json | 15 ++- .../drep_delegation_with_cip129_prefix.json | 15 ++- .../drep_id_provided_for_abstain.json | 6 +- .../invalid_cip129_prefix.json | 15 +-- .../cip129_mismatch_type.json | 12 +- ...cip129_script_hash_with_matching_type.json | 2 +- ...gation_script_hash_with_cip129_prefix.json | 17 +-- .../drep_delegation_with_cip129_prefix.json | 17 +-- .../drep_id_provided_for_abstain.json | 6 +- .../invalid_drep_id_length.json | 74 ------------- 14 files changed, 277 insertions(+), 131 deletions(-) create mode 100644 tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_key_hash_with_matching_type.json create mode 100644 tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_script_hash_with_matching_type.json delete mode 100644 tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/invalid_drep_id_length.json diff --git a/docs/docs/user-guides/drep-delegation.md b/docs/docs/user-guides/drep-delegation.md index 3ea709d34..c27d49e26 100644 --- a/docs/docs/user-guides/drep-delegation.md +++ b/docs/docs/user-guides/drep-delegation.md @@ -39,10 +39,11 @@ A DRep vote delegation operation requires a staking credential and the DRep info **Important:** The `type` field is always required regardless of hash format. _Examples:_ -- With prefix: `"id": "0374984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da1"` (prefix `03` will be stripped) -- Without prefix: `"id": "74984fae4ca1715fa1f8759f9d871015ac87f449a85dea6cf9956da1"` +- With prefix (key hash): `"id": "22abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"` (header `0x22` indicates DRep key_hash) +- With prefix (script hash): `"id": "23abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"` (header `0x23` indicates DRep script_hash) +- Without prefix: `"id": "abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"` -Both examples require `"type": "key_hash"` to be specified. +Both prefixed and raw formats still require a `"type"` to be specified (`"key_hash"` or `"script_hash"`). The API automatically detects the format and handles the prefix internally. When returning data, the API maintains the 28-byte format with separate type field for consistency. ::: diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_key_hash_with_matching_type.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_key_hash_with_matching_type.json new file mode 100644 index 000000000..b33416c8f --- /dev/null +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_key_hash_with_matching_type.json @@ -0,0 +1,103 @@ +{ + "test_name": "CIP-129 key_hash with matching type", + "description": "Positive: CIP-129 prefix (0x22=key_hash) with matching type declaration", + "request_body": { + "network_identifier": { + "blockchain": "cardano", + "network": "{{networkId}}" + }, + "operations": [ + { + "operation_identifier": { + "index": 0 + }, + "type": "input", + "account": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "amount": { + "value": "-2000000", + "currency": { + "symbol": "ADA", + "decimals": 6 + } + }, + "coin_change": { + "coin_identifier": { + "identifier": "4f25fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f:0" + }, + "coin_action": "coin_spent" + } + }, + { + "operation_identifier": { + "index": 1 + }, + "type": "output", + "account": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "amount": { + "value": "1626887", + "currency": { + "symbol": "ADA", + "decimals": 6 + } + } + }, + { + "operation_identifier": { + "index": 2 + }, + "type": "dRepVoteDelegation", + "account": { + "address": "stake_test1uql3k2h9kskfma8y53vth7wmptmlw8zxx67cx7c3pwj8sqs6zl0wr" + }, + "metadata": { + "staking_credential": { + "hex_bytes": "fdbee86a702c49d23f45ab80e697b93ec48b744d5f413ef59c338c3f7b2d2de8", + "curve_type": "edwards25519" + }, + "drep": { + "id": "22f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", + "type": "key_hash" + } + } + } + ], + "metadata": { + "ttl": 100454286, + "protocol_parameters": { + "coinsPerUtxoSize": "4310", + "maxTxSize": 16384, + "maxValSize": 5000, + "keyDeposit": "2000000", + "maxCollateralInputs": 3, + "minFeeCoefficient": 44, + "minFeeConstant": 155381, + "minPoolCost": "170000000", + "poolDeposit": "500000000", + "protocol": 10 + } + } + }, + "expected_response": { + "unsigned_transaction": "82790180613530306439303130323831383235383230346632356664386363613833356166323166336163333735626163363031663937656164373566326537393134336264663731666532633462653034336538663030303138313832353833393030386630373563626466326431643766333461663961316136623237366438346364376234393963383063616636323137643131633666303033663162326165356234326339646634653461343538626266396462306166376637316334363336626438333762313130626134373830323161303031386433303730323161303030356231373930333161303566636366386530346439303130323831383330393832303035383163336631623261653562343263396466346534613435386262663964623061663766373163343633366264383337623131306261343738303238323030353831636637323035306161323532636363366266373537343731383439313063306239333836323938313637363536663933356436623663323661a16a6f7065726174696f6e7383a5746f7065726174696f6e5f6964656e746966696572a165696e64657800676163636f756e74a16761646472657373786c616464725f7465737431717a38737768396137746761307536326c78733664766e6b6d707864306479656571783237637368367977783771706c72763477746470766e68367766667a63683075616b7a68683775777976643461736461337a7a61793071707163706c77683066616d6f756e74a26863757272656e6379a26673796d626f6c6341444168646563696d616c73066576616c7565682d323030303030306b636f696e5f6368616e6765a26f636f696e5f6964656e746966696572a16a6964656e7469666965727842346632356664386363613833356166323166336163333735626163363031663937656164373566326537393134336264663731666532633462653034336538663a306b636f696e5f616374696f6e6a636f696e5f7370656e74647479706565696e707574a4746f7065726174696f6e5f6964656e746966696572a165696e64657801676163636f756e74a16761646472657373786c616464725f7465737431717a38737768396137746761307536326c78733664766e6b6d707864306479656571783237637368367977783771706c72763477746470766e68367766667a63683075616b7a68683775777976643461736461337a7a61793071707163706c77683066616d6f756e74a26863757272656e6379a26673796d626f6c6341444168646563696d616c73066576616c756567313632363838376474797065666f7574707574a4746f7065726174696f6e5f6964656e746966696572a165696e64657802676163636f756e74a1676164647265737378407374616b655f746573743175716c336b3268396b736b666d613879353376746837776d70746d6c77387a78783637637837633370776a38737173367a6c307772686d65746164617461a2727374616b696e675f63726564656e7469616ca2696865785f62797465737840666462656538366137303263343964323366343561623830653639376239336563343862373434643566343133656635396333333863336637623264326465386a63757276655f747970656c6564776172647332353531396464726570a2626964783866373230353061613235326363633662663735373437313834393130633062393338363239383136373635366639333564366236633236616474797065686b65795f6861736864747970657264526570566f746544656c65676174696f6e", + "payloads": [ + { + "account_identifier": { + "address": "stake_test1uql3k2h9kskfma8y53vth7wmptmlw8zxx67cx7c3pwj8sqs6zl0wr" + }, + "hex_bytes": "a7bce1c91f9e676f55c95755b9fd9903e702d5ae4fd1d5d5c89fec1fe5b1dfbe", + "signature_type": "ed25519" + }, + { + "account_identifier": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "hex_bytes": "a7bce1c91f9e676f55c95755b9fd9903e702d5ae4fd1d5d5c89fec1fe5b1dfbe", + "signature_type": "ed25519" + } + ] + } +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_mismatch_type.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_mismatch_type.json index 732f24a7f..951a984e0 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_mismatch_type.json +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_mismatch_type.json @@ -1,6 +1,6 @@ { - "test_name": "(-) cip129 mismatch type", - "description": "Negative test: Test case: (-) cip129 mismatch type", + "test_name": "(-) CIP-129 header type mismatch", + "description": "Negative: DRep id header indicates script-hash but declared drep.type is key_hash", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,8 +59,8 @@ "curve_type": "edwards25519" }, "drep": { - "id": "03f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", - "type": "script_hash" + "id": "23f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", + "type": "key_hash" } } } @@ -82,8 +82,8 @@ } }, "expected_error": { - "code": 5037, - "message": "Invalid drep type", - "description": "This should fail due to invalid operations" + "code": 5045, + "message": "There is a mismatch in the drep id header and drep type. Drep id header type and drep type should match.", + "retriable": false } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_script_hash_with_matching_type.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_script_hash_with_matching_type.json new file mode 100644 index 000000000..9ff3bf828 --- /dev/null +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/cip129_script_hash_with_matching_type.json @@ -0,0 +1,103 @@ +{ + "test_name": "CIP-129 script_hash with matching type", + "description": "Positive: CIP-129 prefix (0x23=script_hash) with matching type declaration", + "request_body": { + "network_identifier": { + "blockchain": "cardano", + "network": "{{networkId}}" + }, + "operations": [ + { + "operation_identifier": { + "index": 0 + }, + "type": "input", + "account": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "amount": { + "value": "-2000000", + "currency": { + "symbol": "ADA", + "decimals": 6 + } + }, + "coin_change": { + "coin_identifier": { + "identifier": "5f26fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f:0" + }, + "coin_action": "coin_spent" + } + }, + { + "operation_identifier": { + "index": 1 + }, + "type": "output", + "account": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "amount": { + "value": "1626887", + "currency": { + "symbol": "ADA", + "decimals": 6 + } + } + }, + { + "operation_identifier": { + "index": 2 + }, + "type": "dRepVoteDelegation", + "account": { + "address": "stake_test1uql3k2h9kskfma8y53vth7wmptmlw8zxx67cx7c3pwj8sqs6zl0wr" + }, + "metadata": { + "staking_credential": { + "hex_bytes": "fdbee86a702c49d23f45ab80e697b93ec48b744d5f413ef59c338c3f7b2d2de8", + "curve_type": "edwards25519" + }, + "drep": { + "id": "232d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953", + "type": "script_hash" + } + } + } + ], + "metadata": { + "ttl": 100454286, + "protocol_parameters": { + "coinsPerUtxoSize": "4310", + "maxTxSize": 16384, + "maxValSize": 5000, + "keyDeposit": "2000000", + "maxCollateralInputs": 3, + "minFeeCoefficient": 44, + "minFeeConstant": 155381, + "minPoolCost": "170000000", + "poolDeposit": "500000000", + "protocol": 10 + } + } + }, + "expected_response": { + "unsigned_transaction": "82790180613530306439303130323831383235383230356632366664386363613833356166323166336163333735626163363031663937656164373566326537393134336264663731666532633462653034336538663030303138313832353833393030386630373563626466326431643766333461663961316136623237366438346364376234393963383063616636323137643131633666303033663162326165356234326339646634653461343538626266396462306166376637316334363336626438333762313130626134373830323161303031386433303730323161303030356231373930333161303566636366386530346439303130323831383330393832303035383163336631623261653562343263396466346534613435386262663964623061663766373163343633366264383337623131306261343738303238323031353831633264346362363830623566343030643335323164323732623432393564363131353065306566663339353065663432383534303661393533a16a6f7065726174696f6e7383a5746f7065726174696f6e5f6964656e746966696572a165696e64657800676163636f756e74a16761646472657373786c616464725f7465737431717a38737768396137746761307536326c78733664766e6b6d707864306479656571783237637368367977783771706c72763477746470766e68367766667a63683075616b7a68683775777976643461736461337a7a61793071707163706c77683066616d6f756e74a26863757272656e6379a26673796d626f6c6341444168646563696d616c73066576616c7565682d323030303030306b636f696e5f6368616e6765a26f636f696e5f6964656e746966696572a16a6964656e7469666965727842356632366664386363613833356166323166336163333735626163363031663937656164373566326537393134336264663731666532633462653034336538663a306b636f696e5f616374696f6e6a636f696e5f7370656e74647479706565696e707574a4746f7065726174696f6e5f6964656e746966696572a165696e64657801676163636f756e74a16761646472657373786c616464725f7465737431717a38737768396137746761307536326c78733664766e6b6d707864306479656571783237637368367977783771706c72763477746470766e68367766667a63683075616b7a68683775777976643461736461337a7a61793071707163706c77683066616d6f756e74a26863757272656e6379a26673796d626f6c6341444168646563696d616c73066576616c756567313632363838376474797065666f7574707574a4746f7065726174696f6e5f6964656e746966696572a165696e64657802676163636f756e74a1676164647265737378407374616b655f746573743175716c336b3268396b736b666d613879353376746837776d70746d6c77387a78783637637837633370776a38737173367a6c307772686d65746164617461a2727374616b696e675f63726564656e7469616ca2696865785f62797465737840666462656538366137303263343964323366343561623830653639376239336563343862373434643566343133656635396333333863336637623264326465386a63757276655f747970656c6564776172647332353531396464726570a26269647838326434636236383062356634303064333532316432373262343239356436313135306530656666333935306566343238353430366139353364747970656b7363726970745f6861736864747970657264526570566f746544656c65676174696f6e", + "payloads": [ + { + "account_identifier": { + "address": "stake_test1uql3k2h9kskfma8y53vth7wmptmlw8zxx67cx7c3pwj8sqs6zl0wr" + }, + "hex_bytes": "faa688aa32419d2b371c8e1025d5d52b02f17606e47bbbb742e2e57ac0bb0dce", + "signature_type": "ed25519" + }, + { + "account_identifier": { + "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" + }, + "hex_bytes": "faa688aa32419d2b371c8e1025d5d52b02f17606e47bbbb742e2e57ac0bb0dce", + "signature_type": "ed25519" + } + ] + } +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json index e886876e7..81c524bf3 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json @@ -1,6 +1,6 @@ { - "test_name": "drep delegation script hash with cip129 prefix", - "description": "Test: Test case: drep delegation script hash with cip129 prefix", + "test_name": "(-) CIP-129 script prefix without type", + "description": "Negative: DRep id includes CIP-129 script-hash prefix but omits required drep.type", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,7 +59,7 @@ "curve_type": "edwards25519" }, "drep": { - "id": "042d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953" + "id": "232d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953" } } } @@ -81,8 +81,11 @@ } }, "expected_error": { - "code": 5040, - "message": "Missing drep type", + "code": 5000, + "message": "An error occurred", + "details": { + "message": "An error occurred for request [ID]: [operations[2].metadata.drep.type must not be null]" + }, "description": "This test case may fail due to specific operation requirements" } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_with_cip129_prefix.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_with_cip129_prefix.json index 0cc309117..db44f80dd 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_with_cip129_prefix.json +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_delegation_with_cip129_prefix.json @@ -1,6 +1,6 @@ { - "test_name": "drep delegation with cip129 prefix", - "description": "Test: Test case: drep delegation with cip129 prefix", + "test_name": "(-) CIP-129 key prefix without type", + "description": "Negative: DRep id includes CIP-129 key-hash prefix but omits required drep.type", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,7 +59,7 @@ "curve_type": "edwards25519" }, "drep": { - "id": "03f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a" + "id": "22f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a" } } } @@ -81,8 +81,11 @@ } }, "expected_error": { - "code": 5040, - "message": "Missing drep type", + "code": 5000, + "message": "An error occurred", + "details": { + "message": "An error occurred for request [ID]: [operations[2].metadata.drep.type must not be null]" + }, "description": "This test case may fail due to specific operation requirements" } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_id_provided_for_abstain.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_id_provided_for_abstain.json index c1c50639d..08ecc06e3 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_id_provided_for_abstain.json +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/drep_id_provided_for_abstain.json @@ -1,6 +1,6 @@ { - "test_name": "(-) drep id provided for abstain", - "description": "Payloads for (-) drep id provided for abstain", + "test_name": "drep id provided for abstain (allowed)", + "description": "Providing a DRep id with abstain is allowed; id is ignored", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -100,4 +100,4 @@ } ] } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/invalid_cip129_prefix.json b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/invalid_cip129_prefix.json index 46e148028..f862bcec8 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/invalid_cip129_prefix.json +++ b/tests/integration/golden_examples/rosetta_java/construction/payloads/drep_vote_delegation/invalid_cip129_prefix.json @@ -1,6 +1,6 @@ { - "test_name": "(-) invalid cip129 prefix", - "description": "Negative test: Test case: (-) invalid cip129 prefix", + "test_name": "(-) invalid CIP-129 prefix", + "description": "Negative: DRep id has an invalid CIP-129 header byte (not key or script)", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,7 +59,8 @@ "curve_type": "edwards25519" }, "drep": { - "id": "01f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a" + "id": "01f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", + "type": "key_hash" } } } @@ -81,8 +82,8 @@ } }, "expected_error": { - "code": 5040, - "message": "Missing drep type", - "description": "This should fail due to invalid operations" + "code": 5037, + "message": "Invalid drep type", + "retriable": false } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_mismatch_type.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_mismatch_type.json index 9883808db..3f2b97257 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_mismatch_type.json +++ b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_mismatch_type.json @@ -1,6 +1,6 @@ { - "test_name": "(-) cip129 mismatch type", - "description": "Test case: (-) cip129 mismatch type", + "test_name": "(-) CIP-129 header type mismatch", + "description": "Negative: DRep id header indicates key-hash but declared drep.type is script_hash", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,7 +59,7 @@ "curve_type": "edwards25519" }, "drep": { - "id": "03f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", + "id": "22f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", "type": "script_hash" } } @@ -67,8 +67,8 @@ ] }, "expected_error": { - "code": 5037, - "message": "Invalid drep type", + "code": 5045, + "message": "There is a mismatch in the drep id header and drep type. Drep id header type and drep type should match.", "retriable": false } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_script_hash_with_matching_type.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_script_hash_with_matching_type.json index 64078079b..f2c0b885a 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_script_hash_with_matching_type.json +++ b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/cip129_script_hash_with_matching_type.json @@ -59,7 +59,7 @@ "curve_type": "edwards25519" }, "drep": { - "id": "23f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a", + "id": "232d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953", "type": "script_hash" } } diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json index 0ed4f063f..d2ecb49ee 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json +++ b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_script_hash_with_cip129_prefix.json @@ -1,6 +1,6 @@ { - "test_name": "drep delegation script hash with cip129 prefix", - "description": "Test case: drep delegation script hash with cip129 prefix", + "test_name": "(-) CIP-129 script prefix without type", + "description": "Negative: DRep id includes CIP-129 script-hash prefix but omits required drep.type", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,15 +59,18 @@ "curve_type": "edwards25519" }, "drep": { - "id": "042d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953" + "id": "232d4cb680b5f400d3521d272b4295d61150e0eff3950ef4285406a953" } } } ] }, "expected_error": { - "code": 5040, - "message": "Missing drep type", - "retriable": false + "code": 5000, + "message": "An error occurred", + "retriable": false, + "details": { + "message": "An error occurred for request [ID]: [operations[2].metadata.drep.type must not be null]" + } } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_with_cip129_prefix.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_with_cip129_prefix.json index 3d02ce989..943e9298a 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_with_cip129_prefix.json +++ b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_delegation_with_cip129_prefix.json @@ -1,6 +1,6 @@ { - "test_name": "drep delegation with cip129 prefix", - "description": "Test case: drep delegation with cip129 prefix", + "test_name": "(-) CIP-129 key prefix without type", + "description": "Negative: DRep id includes CIP-129 key-hash prefix but omits required drep.type", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -59,15 +59,18 @@ "curve_type": "edwards25519" }, "drep": { - "id": "03f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a" + "id": "22f72050aa252ccc6bf75747184910c0b9386298167656f935d6b6c26a" } } } ] }, "expected_error": { - "code": 5040, - "message": "Missing drep type", - "retriable": false + "code": 5000, + "message": "An error occurred", + "retriable": false, + "details": { + "message": "An error occurred for request [ID]: [operations[2].metadata.drep.type must not be null]" + } } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_id_provided_for_abstain.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_id_provided_for_abstain.json index 64f14351d..b798a51cf 100644 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_id_provided_for_abstain.json +++ b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/drep_id_provided_for_abstain.json @@ -1,6 +1,6 @@ { - "test_name": "(-) drep id provided for abstain", - "description": "Test case: (-) drep id provided for abstain", + "test_name": "drep id provided for abstain (allowed)", + "description": "Providing a DRep id with abstain is allowed; id is ignored", "request_body": { "network_identifier": { "blockchain": "cardano", @@ -72,4 +72,4 @@ "relative_ttl": 1000 } } -} \ No newline at end of file +} diff --git a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/invalid_drep_id_length.json b/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/invalid_drep_id_length.json deleted file mode 100644 index e8b638cbe..000000000 --- a/tests/integration/golden_examples/rosetta_java/construction/preprocess/drep_vote_delegation/invalid_drep_id_length.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "test_name": "(-) invalid drep id length", - "description": "Test case: (-) invalid drep id length", - "request_body": { - "network_identifier": { - "blockchain": "cardano", - "network": "{{networkId}}" - }, - "operations": [ - { - "operation_identifier": { - "index": 0 - }, - "type": "input", - "account": { - "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" - }, - "amount": { - "value": "-2000000", - "currency": { - "symbol": "ADA", - "decimals": 6 - } - }, - "coin_change": { - "coin_identifier": { - "identifier": "2f38fd8cca835af21f3ac375bac601f97ead75f2e79143bdf71fe2c4be043e8f:0" - }, - "coin_action": "coin_spent" - } - }, - { - "operation_identifier": { - "index": 1 - }, - "type": "output", - "account": { - "address": "addr_test1qz8swh9a7tga0u62lxs6dvnkmpxd0dyeeqx27csh6ywx7qplrv4wtdpvnh6wffzch0uakzhh7uwyvd4asda3zzay0qpqcplwh0" - }, - "amount": { - "value": "1800000", - "currency": { - "symbol": "ADA", - "decimals": 6 - } - } - }, - { - "operation_identifier": { - "index": 2 - }, - "type": "dRepVoteDelegation", - "account": { - "address": "stake_test1uql3k2h9kskfma8y53vth7wmptmlw8zxx67cx7c3pwj8sqs6zl0wr" - }, - "metadata": { - "staking_credential": { - "hex_bytes": "fdbee86a702c49d23f45ab80e697b93ec48b744d5f413ef59c338c3f7b2d2de8", - "curve_type": "edwards25519" - }, - "drep": { - "id": "f72050aa252ccc6bf757", - "type": "key_hash" - } - } - } - ] - }, - "expected_error": { - "code": 5046, - "message": "Invalid drep id length. Should be 28 or 29 bytes", - "retriable": false - } -} \ No newline at end of file From 7019b1f5b21c262c3a92629b7c222d06766ce4c9 Mon Sep 17 00:00:00 2001 From: Lincon Vidal Date: Fri, 12 Sep 2025 08:57:42 -0300 Subject: [PATCH 2/5] fix: update schema validation to use Draft4Validator and improve code formatting (#605) - Replaced Draft7Validator with Draft4Validator in the schema validation logic. - Enhanced code readability by formatting with ruff. --- tests/integration/test_construction_api.py | 64 ++++++++++++++-------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/tests/integration/test_construction_api.py b/tests/integration/test_construction_api.py index ec1380fdd..f45d07358 100644 --- a/tests/integration/test_construction_api.py +++ b/tests/integration/test_construction_api.py @@ -38,10 +38,10 @@ try: import jsonschema # type: ignore - from jsonschema import Draft7Validator # type: ignore + from jsonschema import Draft4Validator # type: ignore except Exception: # pragma: no cover jsonschema = None # type: ignore - Draft7Validator = None # type: ignore + Draft4Validator = None # type: ignore try: from rich.console import Console # type: ignore @@ -93,7 +93,7 @@ # Fields that should be ignored when diffing VOLATILE_FIELDS = { "metadata": ["metadata.ttl"], - "preprocess": ["options.transaction_size"] + "preprocess": ["options.transaction_size"], } # Stats @@ -276,9 +276,9 @@ def validate_response( return self._basic_sanity(instance) try: d = self._deref(schema) - if Draft7Validator: + if Draft4Validator: errs: List[str] = [] - for e in Draft7Validator(d).iter_errors(instance): + for e in Draft4Validator(d).iter_errors(instance): loc = ".".join([str(p) for p in e.path]) or "" errs.append(f"{loc}: {e.message}") return errs @@ -292,24 +292,24 @@ def validate_response( def replace_network_placeholder(payload: Dict[str, Any]) -> Tuple[Dict[str, Any], bool]: """Replace {{networkId}} placeholders with actual network_id value. Uses 'preprod' as default if no network_id is provided. - + Returns: Tuple of (modified_payload, has_placeholder) """ try: # Convert to JSON string for safe replacement json_str = json.dumps(payload) - + # Check if placeholder exists has_placeholder = "{{networkId}}" in json_str - + if has_placeholder: # Use provided network_id or default to 'preprod' network_value = NETWORK_ID if NETWORK_ID is not None else "preprod" json_str = json_str.replace("{{networkId}}", network_value) # Parse back to dict return json.loads(json_str), True - + return payload, False except Exception: # If anything goes wrong, return original payload @@ -540,8 +540,9 @@ def validate_file(file_path: Path) -> Dict[str, Any]: return res has_ok, has_err = ("expected_response" in test), ("expected_error" in test) if not (has_ok or has_err): - skip_reason = test.get("description", - "No expected_response or expected_error found") + skip_reason = test.get( + "description", "No expected_response or expected_error found" + ) res.update( { "status": "skipped", @@ -812,13 +813,16 @@ def main() -> None: help="Show concise schema details per test", ) parser.add_argument( - "-j", "--workers", + "-j", + "--workers", type=int, default=10, help="Number of parallel workers for test execution (default: 10)", ) parser.add_argument( - "-n", "--network-id", + "-n", + "--network-id", + default="preprod", help="Network ID to replace {{networkId}} placeholders in test files (e.g., 'devkit', 'preprod', 'mainnet')", ) args = parser.parse_args() @@ -969,16 +973,18 @@ def main() -> None: with Live(root, console=RICH_CONSOLE, refresh_per_second=8): # Process files in parallel, maintain order for display with ThreadPoolExecutor(max_workers=WORKERS) as executor: - future_to_fp = {executor.submit(validate_file, fp): fp for fp in gfiles} + future_to_fp = { + executor.submit(validate_file, fp): fp for fp in gfiles + } results = [] for future in as_completed(future_to_fp): fp = future_to_fp[future] r = future.result() results.append((fp, r)) - + # Sort results back to original order for consistent display results.sort(key=lambda x: gfiles.index(x[0])) - + # Process results in order for fp, r in results: stats["files_tested"] += 1 @@ -991,7 +997,10 @@ def main() -> None: ep_failed += 1 ( ep_failures.append( - (r["file"], (r.get("differences") or [""])[0]) + ( + r["file"], + (r.get("differences") or [""])[0], + ) ) if r.get("differences") else None @@ -1008,7 +1017,9 @@ def main() -> None: ep_error_cases.append( (r["file"], r.get("error") or "error") ) - row = print_result(r, verbose=VERBOSE, rich_collect=True) + row = print_result( + r, verbose=VERBOSE, rich_collect=True + ) if row is not None: rt.add_row( fp.name, @@ -1068,7 +1079,9 @@ def main() -> None: print(f"\n {DIM}[{name}/{gname}]{RESET}") # Process files in parallel with ThreadPoolExecutor(max_workers=WORKERS) as executor: - future_to_fp = {executor.submit(validate_file, fp): fp for fp in gfiles} + future_to_fp = { + executor.submit(validate_file, fp): fp for fp in gfiles + } for future in as_completed(future_to_fp): fp = future_to_fp[future] r = future.result() @@ -1090,7 +1103,9 @@ def main() -> None: elif r["status"] == "skipped": stats["files_skipped"] += 1 ep_skipped += 1 - ep_skips.append((r["file"], r.get("error") or "skipped")) + ep_skips.append( + (r["file"], r.get("error") or "skipped") + ) else: stats["errors_by_endpoint"][name] += 1 ep_errors += 1 @@ -1209,10 +1224,15 @@ def main() -> None: elapsed = time.time() - start_time print_summary(elapsed) - + # Exit with proper code based on test results failed = stats["files_failed"] - errors = stats["files_tested"] - stats["files_passed"] - stats["files_failed"] - stats["files_skipped"] + errors = ( + stats["files_tested"] + - stats["files_passed"] + - stats["files_failed"] + - stats["files_skipped"] + ) if failed > 0 or errors > 0: sys.exit(1) # Fail CI when tests fail or have errors finally: From 12359dc73fe1f85933403117a17644b285e55f96 Mon Sep 17 00:00:00 2001 From: Kartiiyer12 <106822766+Kartiiyer12@users.noreply.github.com> Date: Tue, 9 Sep 2025 16:56:49 +0100 Subject: [PATCH 3/5] add utxo store variables for interval and logging --- yaci-indexer/src/main/resources/application.properties | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/yaci-indexer/src/main/resources/application.properties b/yaci-indexer/src/main/resources/application.properties index dd33cf59e..5bfb6f6fb 100644 --- a/yaci-indexer/src/main/resources/application.properties +++ b/yaci-indexer/src/main/resources/application.properties @@ -106,7 +106,11 @@ store.admin.health-check-interval=20 store.utxo.pruning-enabled=${REMOVE_SPENT_UTXOS:false} store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} -store.utxo.pruning-interval=600 +store.utxo.pruning-interval=3600 +store.utxo.pruning-batch-size=${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} +logging.level.com.bloxbean.cardano.yaci.store=${LOG:error} + + store.epoch.endpoints.epoch.local.enabled=true From aeac1bdfd4b6a93e2d33b56acea65f5228a5bd93 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Tien Date: Tue, 9 Sep 2025 18:54:34 +0200 Subject: [PATCH 4/5] adding REMOVE_SPENT_UTXOS_BATCH_SIZE and increading the pruning interval --- .env.docker-compose | 1 + .env.docker-compose-preprod | 1 + .env.h2 | 2 ++ .env.h2-testdata | 2 ++ api/src/main/resources/config/application.yaml | 1 + .../test/resources/config/application-test-integration.yaml | 1 + docker-compose-indexer.yaml | 2 ++ docker-compose-integration-test-indexer.yaml | 2 ++ docker/.env.dockerfile | 1 + .../src/test/resources/application-test-integration.properties | 3 ++- 10 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.env.docker-compose b/.env.docker-compose index 7dd56957c..90a85a607 100644 --- a/.env.docker-compose +++ b/.env.docker-compose @@ -62,6 +62,7 @@ INDEXER_DOCKER_IMAGE_TAG=main REMOVE_SPENT_UTXOS=false #The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 YACI_SPRING_PROFILES=postgres,n2c-socket diff --git a/.env.docker-compose-preprod b/.env.docker-compose-preprod index fa22a5875..935f9cd11 100644 --- a/.env.docker-compose-preprod +++ b/.env.docker-compose-preprod @@ -62,6 +62,7 @@ INDEXER_DOCKER_IMAGE_TAG=main REMOVE_SPENT_UTXOS=false #The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 YACI_SPRING_PROFILES=postgres,n2c-socket diff --git a/.env.h2 b/.env.h2 index f41b041ce..2cb879ead 100644 --- a/.env.h2 +++ b/.env.h2 @@ -42,6 +42,8 @@ SEARCH_LIMIT=100 INDEXER_DOCKER_IMAGE_TAG=main REMOVE_SPENT_UTXOS=false REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS_BATCH_SIZE:3000 + BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 YACI_SPRING_PROFILES=h2,n2c-socket diff --git a/.env.h2-testdata b/.env.h2-testdata index bac08714e..95f486600 100644 --- a/.env.h2-testdata +++ b/.env.h2-testdata @@ -43,6 +43,8 @@ INDEXER_DOCKER_IMAGE_TAG=main REMOVE_SPENT_UTXOS=false #The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS_BATCH_SIZE:3000 + BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 YACI_SPRING_PROFILES=h2-testdata,n2c-socket diff --git a/api/src/main/resources/config/application.yaml b/api/src/main/resources/config/application.yaml index 929a5ba91..a695647fb 100644 --- a/api/src/main/resources/config/application.yaml +++ b/api/src/main/resources/config/application.yaml @@ -42,6 +42,7 @@ cardano: SYNC_GRACE_SLOTS_COUNT: ${SYNC_GRACE_SLOTS_COUNT:100} REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:false} REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} + REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS:5} YACI_HTTP_BASE_URL: ${YACI_HTTP_BASE_URL:http://localhost:9095} diff --git a/api/src/test/resources/config/application-test-integration.yaml b/api/src/test/resources/config/application-test-integration.yaml index d1ebb73fa..41d443ae4 100644 --- a/api/src/test/resources/config/application-test-integration.yaml +++ b/api/src/test/resources/config/application-test-integration.yaml @@ -56,6 +56,7 @@ cardano: SYNC_GRACE_SLOTS_COUNT: ${SYNC_GRACE_SLOTS_COUNT:100} REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:false} REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} + REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS:5} YACI_HTTP_BASE_URL: http://localhost:9095/api/v1 diff --git a/docker-compose-indexer.yaml b/docker-compose-indexer.yaml index e8210012a..e16f27405 100644 --- a/docker-compose-indexer.yaml +++ b/docker-compose-indexer.yaml @@ -23,6 +23,7 @@ services: GENESIS_CONWAY_PATH: ${GENESIS_CONWAY_PATH} REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS} REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT} + REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS} CARDANO_NODE_SOCKET_PATH: ${CARDANO_NODE_SOCKET_PATH} HOST_N2C_SOCAT_HOST: ${HOST_N2C_SOCAT_HOST} @@ -30,6 +31,7 @@ services: SEARCH_LIMIT: ${LIMIT} CONTINUE_PARSING_ON_ERROR: ${CONTINUE_PARSING_ON_ERROR} PEER_DISCOVERY: ${PEER_DISCOVERY} + LOG: ${LOG} volumes: - ${CARDANO_CONFIG}:/config - ${CARDANO_NODE_DIR}:${CARDANO_NODE_DIR} diff --git a/docker-compose-integration-test-indexer.yaml b/docker-compose-integration-test-indexer.yaml index e44d145ab..2f9537a5b 100644 --- a/docker-compose-integration-test-indexer.yaml +++ b/docker-compose-integration-test-indexer.yaml @@ -23,6 +23,7 @@ services: GENESIS_CONWAY_PATH: ${GENESIS_CONWAY_PATH} REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS} REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT} + REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS} CARDANO_NODE_SOCKET_PATH: ${CARDANO_NODE_SOCKET_PATH} HOST_N2C_SOCAT_HOST: ${HOST_N2C_SOCAT_HOST} @@ -30,6 +31,7 @@ services: SEARCH_LIMIT: ${LIMIT} CONTINUE_PARSING_ON_ERROR: ${CONTINUE_PARSING_ON_ERROR} PEER_DISCOVERY: ${PEER_DISCOVERY} + LOG: ${LOG} volumes: - ${CARDANO_CONFIG}:/config - ${CARDANO_NODE_DIR}:${CARDANO_NODE_DIR} diff --git a/docker/.env.dockerfile b/docker/.env.dockerfile index c950f737c..e0663e630 100644 --- a/docker/.env.dockerfile +++ b/docker/.env.dockerfile @@ -55,6 +55,7 @@ YACI_SPRING_PROFILES=postgres,n2c-socket REMOVE_SPENT_UTXOS=false REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 +REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 # database profiles: h2, h2-testdata, postgres MEMPOOL_ENABLED=false diff --git a/yaci-indexer/src/test/resources/application-test-integration.properties b/yaci-indexer/src/test/resources/application-test-integration.properties index 78f6aa44c..48f6e317c 100644 --- a/yaci-indexer/src/test/resources/application-test-integration.properties +++ b/yaci-indexer/src/test/resources/application-test-integration.properties @@ -13,5 +13,6 @@ spring.h2.console.enabled=true store.cardano.host=${CARDANO_NODE_HOST:localhost} store.cardano.port=${CARDANO_NODE_PORT:8090} -store.utxo.pruning-interval=600 +store.utxo.pruning-interval=3600 store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} +store.utxo.pruning-batch-size=${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} \ No newline at end of file From fb9caac5c42d3cc90548f0aabddadcad662930e4 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Tien Date: Mon, 15 Sep 2025 10:36:54 +0200 Subject: [PATCH 5/5] REMOVE_SPENT_UTXOS enabled by default and block grace count set to 30 days --- .env.docker-compose | 6 +++--- .env.docker-compose-preprod | 6 +++--- .env.docker-compose-profile-advanced-level | 3 ++- .env.docker-compose-profile-mid-level | 3 ++- .env.h2 | 6 +++--- .env.h2-testdata | 8 ++++---- .../api/block/service/LedgerBlockServiceImpl.java | 4 ++-- .../rosetta/api/network/service/NetworkServiceImpl.java | 2 +- api/src/main/resources/config/application-offline.yaml | 2 +- api/src/main/resources/config/application.yaml | 4 ++-- .../resources/config/application-test-integration.yaml | 4 ++-- docker/.env.dockerfile | 4 ++-- yaci-indexer/src/main/resources/application.properties | 9 +++++---- .../resources/application-test-integration.properties | 2 +- 14 files changed, 33 insertions(+), 30 deletions(-) diff --git a/.env.docker-compose b/.env.docker-compose index 90a85a607..7d8cee635 100644 --- a/.env.docker-compose +++ b/.env.docker-compose @@ -59,9 +59,9 @@ SEARCH_LIMIT=100 ## Yaci Indexer env INDEXER_DOCKER_IMAGE_TAG=main -REMOVE_SPENT_UTXOS=false -#The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. -REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS=true +#The number of safe blocks to keep in the store. 129600 blocks *(20 seconds/block in average)=30 days. +REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=129600 REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 diff --git a/.env.docker-compose-preprod b/.env.docker-compose-preprod index 935f9cd11..dff3a7312 100644 --- a/.env.docker-compose-preprod +++ b/.env.docker-compose-preprod @@ -59,9 +59,9 @@ SEARCH_LIMIT=100 ## Yaci Indexer env INDEXER_DOCKER_IMAGE_TAG=main -REMOVE_SPENT_UTXOS=false -#The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. -REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS=true +#The number of safe blocks to keep in the store. 129600 blocks *(20 seconds/block in average)=30 days +REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=129600 REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 diff --git a/.env.docker-compose-profile-advanced-level b/.env.docker-compose-profile-advanced-level index 03854b4d5..c866ff775 100644 --- a/.env.docker-compose-profile-advanced-level +++ b/.env.docker-compose-profile-advanced-level @@ -15,7 +15,8 @@ DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER=8 DB_POSTGRES_MAX_PARALLEL_WORKERS=16 DB_POSTGRES_SEQ_PAGE_COST=0.5 DB_POSTGRES_JIT=off -DB_POSTGRES_BGWRITER_LRU_MAXPAGES=100 +DB_POSTGRES_BGWRITER_LRU_MAXPAGES=300 DB_POSTGRES_BGWRITER_DELAY=200ms DB_POSTGRES_WAL_BUFFERS=512MB DB_POSTGRES_CHECKPOINT_COMPLETION_TARGET=0.9 +DB_POSTGRES_AUTOVACUUM_MAX_WORKERS=5 diff --git a/.env.docker-compose-profile-mid-level b/.env.docker-compose-profile-mid-level index 82a09e0a3..2f8b91943 100644 --- a/.env.docker-compose-profile-mid-level +++ b/.env.docker-compose-profile-mid-level @@ -17,5 +17,6 @@ DB_POSTGRES_MAX_PARALLEL_WORKERS_PER_GATHER=4 DB_POSTGRES_MAX_PARALLEL_WORKERS=8 DB_POSTGRES_SEQ_PAGE_COST=1.0 DB_POSTGRES_JIT=off -DB_POSTGRES_BGWRITER_LRU_MAXPAGES=100 +DB_POSTGRES_BGWRITER_LRU_MAXPAGES=200 DB_POSTGRES_BGWRITER_DELAY=200ms +DB_POSTGRES_AUTOVACUUM_MAX_WORKERS=5 diff --git a/.env.h2 b/.env.h2 index 2cb879ead..87c9f4c4e 100644 --- a/.env.h2 +++ b/.env.h2 @@ -40,9 +40,9 @@ SEARCH_LIMIT=100 ## Yaci Indexer env INDEXER_DOCKER_IMAGE_TAG=main -REMOVE_SPENT_UTXOS=false -REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 -REMOVE_SPENT_UTXOS_BATCH_SIZE:3000 +REMOVE_SPENT_UTXOS=true +REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=129600 +REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 diff --git a/.env.h2-testdata b/.env.h2-testdata index 95f486600..a470c07b2 100644 --- a/.env.h2-testdata +++ b/.env.h2-testdata @@ -40,10 +40,10 @@ SEARCH_LIMIT=100 ## Yaci Indexer env INDEXER_DOCKER_IMAGE_TAG=main -REMOVE_SPENT_UTXOS=false -#The number of safe blocks to keep in the store. 2160 blocks *(20 seconds/block in average)=4320 seconds=12 hours. -REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 -REMOVE_SPENT_UTXOS_BATCH_SIZE:3000 +REMOVE_SPENT_UTXOS=true +#The number of safe blocks to keep in the store. 129600 blocks *(20 seconds/block in average)=30 days. +REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=129600 +REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/block/service/LedgerBlockServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/block/service/LedgerBlockServiceImpl.java index 4adb41b3d..3691e5705 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/block/service/LedgerBlockServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/block/service/LedgerBlockServiceImpl.java @@ -64,10 +64,10 @@ public class LedgerBlockServiceImpl implements LedgerBlockService { @Value("${cardano.rosetta.BLOCK_TRANSACTION_API_TIMEOUT_SECS:5}") private int blockTransactionApiTimeoutSecs; - @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS:false}") + @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS:true}") private boolean isRemovalOfSpentUTxOsEnabled; - @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160}") + @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:129600}") private int removeSpentUTxOsLastBlocksGraceCount; @PostConstruct diff --git a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java index 672fdce79..f7a0bca0d 100644 --- a/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java +++ b/api/src/main/java/org/cardanofoundation/rosetta/api/network/service/NetworkServiceImpl.java @@ -56,7 +56,7 @@ public class NetworkServiceImpl implements NetworkService { @Value("${cardano.rosetta.SYNC_GRACE_SLOTS_COUNT:100}") private int allowedSlotsDelta; - @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS:false}") + @Value("${cardano.rosetta.REMOVE_SPENT_UTXOS:true}") private boolean isRemovalOfSpentUTxOsEnabled; @PostConstruct diff --git a/api/src/main/resources/config/application-offline.yaml b/api/src/main/resources/config/application-offline.yaml index 3b12803e2..c9cd54998 100644 --- a/api/src/main/resources/config/application-offline.yaml +++ b/api/src/main/resources/config/application-offline.yaml @@ -13,7 +13,7 @@ cardano: rosetta: OFFLINE_MODE: true SYNC_GRACE_SLOTS_COUNT: ${SYNC_GRACE_SLOTS_COUNT:100} - REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:false} + REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:true} YACI_HTTP_BASE_URL: ${YACI_HTTP_BASE_URL:http://localhost:9095} HTTP_CONNECT_TIMEOUT_SECONDS: ${HTTP_CONNECT_TIMEOUT_SECONDS:5} diff --git a/api/src/main/resources/config/application.yaml b/api/src/main/resources/config/application.yaml index a695647fb..15db0ff47 100644 --- a/api/src/main/resources/config/application.yaml +++ b/api/src/main/resources/config/application.yaml @@ -40,8 +40,8 @@ cardano: OFFLINE_MODE: ${OFFLINE_MODE:false} SYNC_GRACE_SLOTS_COUNT: ${SYNC_GRACE_SLOTS_COUNT:100} - REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:false} - REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} + REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:true} + REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:129600} REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS:5} diff --git a/api/src/test/resources/config/application-test-integration.yaml b/api/src/test/resources/config/application-test-integration.yaml index 41d443ae4..022b0ad82 100644 --- a/api/src/test/resources/config/application-test-integration.yaml +++ b/api/src/test/resources/config/application-test-integration.yaml @@ -54,8 +54,8 @@ cardano: SEARCH_LIMIT: ${SEARCH_LIMIT:100} OFFLINE_MODE: ${OFFLINE_MODE:false} SYNC_GRACE_SLOTS_COUNT: ${SYNC_GRACE_SLOTS_COUNT:100} - REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:false} - REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} + REMOVE_SPENT_UTXOS: ${REMOVE_SPENT_UTXOS:true} + REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT: ${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:129600} REMOVE_SPENT_UTXOS_BATCH_SIZE: ${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} BLOCK_TRANSACTION_API_TIMEOUT_SECS: ${BLOCK_TRANSACTION_API_TIMEOUT_SECS:5} diff --git a/docker/.env.dockerfile b/docker/.env.dockerfile index e0663e630..89ee016b3 100644 --- a/docker/.env.dockerfile +++ b/docker/.env.dockerfile @@ -52,8 +52,8 @@ PRINT_EXCEPTION=true ## Yaci Indexer env YACI_SPRING_PROFILES=postgres,n2c-socket -REMOVE_SPENT_UTXOS=false -REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=2160 +REMOVE_SPENT_UTXOS=true +REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT=129600 BLOCK_TRANSACTION_API_TIMEOUT_SECS=5 REMOVE_SPENT_UTXOS_BATCH_SIZE=3000 diff --git a/yaci-indexer/src/main/resources/application.properties b/yaci-indexer/src/main/resources/application.properties index 5bfb6f6fb..f5bfdb97c 100644 --- a/yaci-indexer/src/main/resources/application.properties +++ b/yaci-indexer/src/main/resources/application.properties @@ -104,12 +104,13 @@ logging.level.com.bloxbean.cardano.yaci.core.protocol.keepalive=debug store.admin.auto-recovery-enabled=true store.admin.health-check-interval=20 -store.utxo.pruning-enabled=${REMOVE_SPENT_UTXOS:false} -store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} -store.utxo.pruning-interval=3600 +store.utxo.pruning-enabled=${REMOVE_SPENT_UTXOS:true} +store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:129600} +store.utxo.pruning-interval=10800 store.utxo.pruning-batch-size=${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} logging.level.com.bloxbean.cardano.yaci.store=${LOG:error} - +spring.datasource.hikari.maximum-pool-size=20 +spring.datasource.hikari.minimum-idle=5 store.epoch.endpoints.epoch.local.enabled=true diff --git a/yaci-indexer/src/test/resources/application-test-integration.properties b/yaci-indexer/src/test/resources/application-test-integration.properties index 48f6e317c..278dd46b2 100644 --- a/yaci-indexer/src/test/resources/application-test-integration.properties +++ b/yaci-indexer/src/test/resources/application-test-integration.properties @@ -14,5 +14,5 @@ store.cardano.host=${CARDANO_NODE_HOST:localhost} store.cardano.port=${CARDANO_NODE_PORT:8090} store.utxo.pruning-interval=3600 -store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:2160} +store.utxo.pruning-safe-blocks=${REMOVE_SPENT_UTXOS_LAST_BLOCKS_GRACE_COUNT:129600} store.utxo.pruning-batch-size=${REMOVE_SPENT_UTXOS_BATCH_SIZE:3000} \ No newline at end of file