Skip to content

Commit

Permalink
Merge pull request #2575 from CounterpartyXCP/fixcomposedispense
Browse files Browse the repository at this point in the history
[v10.6.0] Only Require One Valid Dispenser in Validation Logic
  • Loading branch information
adamkrellenstein authored Oct 24, 2024
2 parents abf64c2 + ef82d8a commit cf1f80d
Show file tree
Hide file tree
Showing 11 changed files with 5,212 additions and 4,734 deletions.
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

0 comments on commit cf1f80d

Please sign in to comment.