Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v10.6.0] Only Require One Valid Dispenser in Validation Logic #2575

Merged
merged 8 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,021 changes: 2,580 additions & 2,441 deletions apiary.apib

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions counterparty-core/counterpartycore/lib/messages/dispense.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,36 @@ def get_must_give(db, dispenser, btc_amount, block_index=None):

def validate(db, _source, destination, quantity):
problems = []

if not util.enabled("enable_dispense_tx"):
problems.append("dispense tx is not enabled")
return problems

dispensers = ledger.get_dispensers(db, address=destination)
if len(dispensers) == 0:
problems.append("address doesn't have any open dispenser")
return problems

for dispenser in dispensers:
dispenser_problems = []
if dispenser["status"] != dispenser_module.STATUS_OPEN:
problems.append("dispenser is not open")
dispenser_problems.append(f"dispenser for {dispenser['asset']} is not open")
if dispenser["give_remaining"] == 0:
problems.append("dispenser is empty")
dispenser_problems.append(f"dispenser for {dispenser['asset']} is empty")
else:
try:
must_give = get_must_give(db, dispenser, quantity) * dispenser["give_quantity"]
logger.debug("must_give: %s", must_give)
if must_give > dispenser["give_remaining"]:
problems.append("dispenser doesn't have enough asset to give")
dispenser_problems.append(
f"dispenser for {dispenser['asset']} doesn't have enough asset to give"
)
except exceptions.NoPriceError as e:
problems.append(str(e))
dispenser_problems.append(str(e))
# no error if at least one dispenser is valid
if len(dispenser_problems) == 0 and util.enabled("accept_only_one_valid_dispenser"):
return []
problems += dispenser_problems
return problems


Expand Down
7 changes: 7 additions & 0 deletions counterparty-core/counterpartycore/protocol_changes.json
Original file line number Diff line number Diff line change
Expand Up @@ -637,5 +637,12 @@
}
}
}
},
"accept_only_one_valid_dispenser": {
"minimum_version_major": 10,
"minimum_version_minor": 6,
"minimum_version_revision": 0,
"block_index": 868200,
"testnet_block_index": 3195137
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@
"error": (
exceptions.ComposeError,
[
"dispenser doesn't have enough asset to give",
"dispenser doesn't have enough asset to give",
"dispenser for XCP doesn't have enough asset to give",
"dispenser for TESTDISP doesn't have enough asset to give",
],
),
},
Expand Down
4,613 changes: 2,376 additions & 2,237 deletions counterparty-core/counterpartycore/test/regtest/apidoc/apicache.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ def start(self):
_bg=True,
_out=self.server_out,
_err_to_out=True,
_bg_exc=False,
)
self.wait_for_counterparty_follower()

Expand Down Expand Up @@ -380,6 +381,7 @@ def check_node_state(self, command, previous_state):
_bg=True,
_out=self.server_out,
_err_to_out=True,
_bg_exc=False,
)
self.wait_for_counterparty_follower()
self.wait_for_counterparty_watcher()
Expand All @@ -399,6 +401,7 @@ def test_command(self, command):
150, # avoid tx using `disable_protocol_changes` params (scenario_6_dispenser.py)
_out=sys.stdout,
_err_to_out=True,
_bg_exc=False,
)
self.check_node_state(command, state_before)
print(f"`{command}` successful")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
SCENARIO = [
{
"title": "Create Dispenser 6",
"transaction": "dispenser",
"source": "$ADDRESS_1",
"params": {
"asset": "TESTLOCKDESC",
"give_quantity": 1,
"escrow_quantity": 10000,
"mainchainrate": 1, # 1 BTC for 1 XCP
"status": 0,
},
"set_variables": {
"DISPENSER_6_TX_HASH": "$TX_HASH",
},
"controls": [
{
"url": "blocks/$BLOCK_INDEX/events?event_name=OPEN_DISPENSER,DEBIT",
"result": [
{
"event": "OPEN_DISPENSER",
"event_index": "$EVENT_INDEX_4",
"params": {
"asset": "TESTLOCKDESC",
"block_index": "$BLOCK_INDEX",
"dispense_count": 0,
"escrow_quantity": 10000,
"give_quantity": 1,
"give_remaining": 10000,
"oracle_address": None,
"origin": "$ADDRESS_1",
"satoshirate": 1,
"source": "$ADDRESS_1",
"status": 0,
"tx_hash": "$TX_HASH",
"tx_index": "$TX_INDEX",
},
"tx_hash": "$TX_HASH",
},
{
"event": "DEBIT",
"event_index": "$EVENT_INDEX_3",
"params": {
"action": "open dispenser",
"address": "$ADDRESS_1",
"asset": "TESTLOCKDESC",
"block_index": "$BLOCK_INDEX",
"event": "$TX_HASH",
"quantity": 10000,
"tx_index": "$TX_INDEX",
"utxo": None,
"utxo_address": None,
},
"tx_hash": "$TX_HASH",
},
],
},
{
"url": "addresses/$ADDRESS_1/dispensers",
"result": [
{
"asset": "TESTLOCKDESC",
"block_index": "$BLOCK_INDEX",
"close_block_index": None,
"confirmed": True,
"dispense_count": 0,
"escrow_quantity": 10000,
"give_quantity": 1,
"give_remaining": 10000,
"last_status_tx_hash": None,
"last_status_tx_source": None,
"oracle_address": None,
"origin": "$ADDRESS_1",
"satoshirate": 1,
"source": "$ADDRESS_1",
"status": 0,
"tx_hash": "$TX_HASH",
"tx_index": 62,
},
{
"asset": "XCP",
"block_index": "$DISPENSER_1_LAST_UPDATE_BLOCK_INDEX",
"close_block_index": None,
"confirmed": True,
"dispense_count": 2,
"escrow_quantity": 10000,
"give_quantity": 1,
"give_remaining": 0,
"last_status_tx_hash": None,
"last_status_tx_source": None,
"oracle_address": None,
"origin": "$ADDRESS_1",
"satoshirate": 1,
"source": "$ADDRESS_1",
"status": 10,
"tx_hash": "$DISPENSER_1_TX_HASH",
"tx_index": "$DISPENSER_1_TX_INDEX",
},
],
},
],
},
{
"title": "Dispense on address with two dispensers, one of them is closed",
"transaction": "dispense",
"source": "$ADDRESS_2",
"params": {
"dispenser": "$ADDRESS_1",
"quantity": 4000,
},
"controls": [
{
"url": "blocks/$BLOCK_INDEX/events?event_name=DISPENSE,DISPENSER_UPDATE,CREDIT",
"result": [
{
"event": "DISPENSE",
"event_index": "$EVENT_INDEX_6",
"params": {
"asset": "TESTLOCKDESC",
"block_index": "$BLOCK_INDEX",
"btc_amount": 4000,
"destination": "$ADDRESS_2",
"dispense_index": 0,
"dispense_quantity": 4000,
"dispenser_tx_hash": "$DISPENSER_6_TX_HASH",
"source": "$ADDRESS_1",
"tx_hash": "$TX_HASH",
"tx_index": "$TX_INDEX",
},
"tx_hash": "$TX_HASH",
},
{
"event": "DISPENSER_UPDATE",
"event_index": "$EVENT_INDEX_5",
"params": {
"asset": "TESTLOCKDESC",
"dispense_count": 1,
"give_remaining": 6000,
"source": "$ADDRESS_1",
"status": 0,
"tx_hash": "$DISPENSER_6_TX_HASH",
},
"tx_hash": "$TX_HASH",
},
{
"event": "CREDIT",
"event_index": "$EVENT_INDEX_4",
"params": {
"address": "$ADDRESS_2",
"asset": "TESTLOCKDESC",
"block_index": "$BLOCK_INDEX",
"calling_function": "dispense",
"event": "$TX_HASH",
"quantity": 4000,
"tx_index": "$TX_INDEX",
"utxo": None,
"utxo_address": None,
},
"tx_hash": "$TX_HASH",
},
],
}
],
},
]
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
},
"set_variables": {
"DISPENSER_1_TX_HASH": "$TX_HASH",
"DISPENSER_1_TX_INDEX": "$TX_INDEX",
"DISPENSER_1_BLOCK_INDEX": "$BLOCK_INDEX",
},
"controls": [
{
Expand Down Expand Up @@ -158,7 +160,7 @@
"dispenser": "$ADDRESS_1",
"quantity": 4001,
},
"expected_error": ["dispenser doesn't have enough asset to give"],
"expected_error": ["dispenser for XCP doesn't have enough asset to give"],
},
{
"title": "Dispense 3: no dispenser error",
Expand All @@ -178,6 +180,9 @@
"dispenser": "$ADDRESS_1",
"quantity": 4000,
},
"set_variables": {
"DISPENSER_1_LAST_UPDATE_BLOCK_INDEX": "$BLOCK_INDEX",
},
"controls": [
{
"url": "blocks/$BLOCK_INDEX/events?event_name=NEW_TRANSACTION,NEW_TRANSACTION_OUTPUT,CREDIT,DISPENSER_UPDATE,DISPENSE",
Expand Down Expand Up @@ -271,7 +276,7 @@
"dispenser": "$ADDRESS_1",
"quantity": 4001,
},
"expected_error": ["dispenser is not open", "dispenser is empty"],
"expected_error": ["dispenser for XCP is not open", "dispenser for XCP is empty"],
},
{
"title": "Create Dispenser 2: dispenser must be created by source",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
scenario_14_sweep,
scenario_15_destroy,
scenario_16_fairminter,
scenario_17_dispenser,
scenario_last_mempool,
)
from termcolor import colored
Expand All @@ -47,6 +48,7 @@
SCENARIOS += scenario_13_cancel.SCENARIO
SCENARIOS += scenario_14_sweep.SCENARIO
SCENARIOS += scenario_15_destroy.SCENARIO
SCENARIOS += scenario_17_dispenser.SCENARIO
# more scenarios before this one
SCENARIOS += scenario_last_mempool.SCENARIO

Expand Down Expand Up @@ -152,14 +154,14 @@ def control_result(item, node, context, block_hash, block_time, tx_hash, data, r
try:
assert result["result"] == expected_result
print(f"{item['title']}: " + colored("Success", "green"))
except AssertionError as e:
except AssertionError:
print(colored(f"Failed: {item['title']}", "red"))
expected_result_str = json.dumps(expected_result, indent=4, sort_keys=True)
got_result_str = json.dumps(result["result"], indent=4, sort_keys=True)
print(f"Expected: {expected_result_str}")
print(f"Got: {got_result_str}")
compare_strings(expected_result_str, got_result_str)
raise e
# raise e


def run_item(node, item, context):
Expand Down
46 changes: 0 additions & 46 deletions release-notes/release-notes-v10.5.1.md

This file was deleted.

Loading
Loading