Skip to content

Commit 7db66cf

Browse files
authored
Allow subtracting assets if not existing before (#317)
* Allow subtracting assets if not existing before Negative values were allowed before as well so it is only consequential to allow subtracting from 0 * Fix testcases
1 parent efbc2d2 commit 7db66cf

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

pycardano/transaction.py

+4-17
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from pycardano.address import Address
1616
from pycardano.certificate import Certificate
17-
from pycardano.exception import InvalidDataException, InvalidOperationException
17+
from pycardano.exception import InvalidDataException
1818
from pycardano.hash import (
1919
TRANSACTION_HASH_SIZE,
2020
AuxiliaryDataHash,
@@ -95,14 +95,7 @@ def __iadd__(self, other: Asset) -> Asset:
9595
def __sub__(self, other: Asset) -> Asset:
9696
new_asset = deepcopy(self)
9797
for n in other:
98-
if n not in new_asset:
99-
raise InvalidOperationException(
100-
f"Asset: {new_asset} does not have asset with name: {n}"
101-
)
102-
# According to ledger rule, the value of an asset could be negative, so we don't check the value here and
103-
# will leave the check to users when necessary.
104-
# https://github.com/input-output-hk/cardano-ledger/blob/master/eras/alonzo/test-suite/cddl-files/alonzo.cddl#L378
105-
new_asset[n] -= other[n]
98+
new_asset[n] = new_asset.get(n, 0) - other[n]
10699
return new_asset
107100

108101
def __eq__(self, other):
@@ -135,9 +128,7 @@ def union(self, other: MultiAsset) -> MultiAsset:
135128
def __add__(self, other):
136129
new_multi_asset = deepcopy(self)
137130
for p in other:
138-
if p not in new_multi_asset:
139-
new_multi_asset[p] = Asset()
140-
new_multi_asset[p] += other[p]
131+
new_multi_asset[p] = new_multi_asset.get(p, Asset()) + other[p]
141132
return new_multi_asset
142133

143134
def __iadd__(self, other):
@@ -148,11 +139,7 @@ def __iadd__(self, other):
148139
def __sub__(self, other: MultiAsset) -> MultiAsset:
149140
new_multi_asset = deepcopy(self)
150141
for p in other:
151-
if p not in new_multi_asset:
152-
raise InvalidOperationException(
153-
f"MultiAsset: {new_multi_asset} doesn't have policy: {p}"
154-
)
155-
new_multi_asset[p] -= other[p]
142+
new_multi_asset[p] = new_multi_asset.get(p, Asset()) - other[p]
156143
return new_multi_asset
157144

158145
def __eq__(self, other):

test/pycardano/test_transaction.py

+24-6
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,12 @@ def test_multi_asset_subtraction():
311311
}
312312
)
313313

314-
with pytest.raises(InvalidOperationException):
315-
a - b
314+
assert a - b == MultiAsset.from_primitive(
315+
{
316+
b"1" * SCRIPT_HASH_SIZE: {b"Token1": -9, b"Token2": -18},
317+
b"2" * SCRIPT_HASH_SIZE: {b"Token1": -1, b"Token2": -2},
318+
}
319+
)
316320

317321

318322
def test_asset_comparison():
@@ -427,11 +431,25 @@ def test_values():
427431
[101, {b"1" * SCRIPT_HASH_SIZE: {b"Token1": 1, b"Token2": 2}}]
428432
)
429433

430-
with pytest.raises(InvalidOperationException):
431-
a - c
434+
assert a - c == Value.from_primitive(
435+
[
436+
-10,
437+
{
438+
b"1" * SCRIPT_HASH_SIZE: {b"Token1": -10, b"Token2": -20},
439+
b"2" * SCRIPT_HASH_SIZE: {b"Token1": -11, b"Token2": -22},
440+
},
441+
]
442+
)
432443

433-
with pytest.raises(InvalidOperationException):
434-
b - c
444+
assert b - c == Value.from_primitive(
445+
[
446+
0,
447+
{
448+
b"1" * SCRIPT_HASH_SIZE: {b"Token1": 0, b"Token2": 0},
449+
b"2" * SCRIPT_HASH_SIZE: {b"Token1": -11, b"Token2": -22},
450+
},
451+
]
452+
)
435453

436454

437455
def test_inline_datum_serdes():

0 commit comments

Comments
 (0)