Skip to content

Commit

Permalink
Merge pull request #289 from BoostryJP/fix/#282
Browse files Browse the repository at this point in the history
fix: Spend UTXO when Redeem
  • Loading branch information
YoshihitoAso committed Apr 4, 2022
2 parents bf405c6 + b86e722 commit e0d10fa
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 1 deletion.
58 changes: 58 additions & 0 deletions batch/processor_create_utxo.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ def process(self):
block_from=block_from,
block_to=block_to
)
event_triggered = event_triggered | self.__process_redeem(
db_session=db_session,
token_contract=token_contract,
block_from=block_from,
block_to=block_to
)
self.__process_event_triggered(
db_session=db_session,
token_contract=token_contract,
Expand Down Expand Up @@ -294,6 +300,58 @@ def __process_issue(self, db_session: Session, token_contract: Contract, block_f
LOG.exception(e)
return False

def __process_redeem(self, db_session: Session, token_contract: Contract, block_from: int, block_to: int):
"""Process Redeem Event
- The process of updating UTXO data by capturing the following events
- `Redeem` event on Token contracts
:param db_session: database session
:param token_contract: Token contract
:param block_from: Block from
:param block_to: Block to
:return: Whether events have occurred or not
"""
try:
# Get "Redeem" events from token contract
events = ContractUtils.get_event_logs(
contract=token_contract,
event="Redeem",
block_from=block_from,
block_to=block_to
)

# Sink
event_triggered = False
for event in events:
args = event["args"]
account = args.get("targetAddress", ZERO_ADDRESS)
amount = args.get("amount")

transaction_hash = event["transactionHash"].hex()
block_number = event["blockNumber"]
block_timestamp = datetime.utcfromtimestamp(web3.eth.get_block(block_number)["timestamp"]) # UTC

if amount is not None and amount <= sys.maxsize:
event_triggered = True

# Update UTXO
self.__sink_on_utxo(
db_session=db_session,
spent=True,
transaction_hash=transaction_hash,
token_address=token_contract.address,
account_address=account,
amount=amount,
block_number=block_number,
block_timestamp=block_timestamp
)

return event_triggered
except Exception as e:
LOG.exception(e)
return False

def __process_event_triggered(self, db_session: Session, token_contract: Contract, event_triggered: bool):
try:
if event_triggered is True:
Expand Down
140 changes: 139 additions & 1 deletion tests/test_batch_processor_create_utxo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
ANY
)
import time
from datetime import datetime

from web3 import Web3
from web3.middleware import geth_poa_middleware
Expand All @@ -50,7 +51,9 @@
IbetStraightBondUpdate,
IbetShareUpdate,
IbetStraightBondAdditionalIssue,
IbetShareAdditionalIssue
IbetShareAdditionalIssue,
IbetStraightBondRedeem,
IbetShareRedeem,
)
from app.utils.contract_utils import ContractUtils
from batch.processor_create_utxo import Processor
Expand Down Expand Up @@ -579,6 +582,141 @@ def test_normal_5(self, mock_func, processor, db):
_utox_block_number = db.query(UTXOBlockNumber).first()
assert _utox_block_number.latest_block_number == latest_block

# <Normal_6>
# Redeem
@mock.patch("batch.processor_create_utxo.create_ledger")
def test_normal_6(self, mock_func, processor, db):
user_1 = config_eth_account("user1")
issuer_address = user_1["address"]
issuer_private_key = decode_keyfile_json(
raw_keyfile_json=user_1["keyfile_json"],
password="password".encode("utf-8")
)
user_2 = config_eth_account("user2")
user_address_1 = user_2["address"]
user_3 = config_eth_account("user3")
user_address_2 = user_3["address"]

# prepare data
token_address_1 = deploy_bond_token_contract(issuer_address, issuer_private_key)
_token_1 = Token()
_token_1.type = TokenType.IBET_STRAIGHT_BOND
_token_1.tx_hash = ""
_token_1.issuer_address = issuer_address
_token_1.token_address = token_address_1
_token_1.abi = {}
db.add(_token_1)

token_address_2 = deploy_share_token_contract(issuer_address, issuer_private_key)
_token_2 = Token()
_token_2.type = TokenType.IBET_SHARE
_token_2.tx_hash = ""
_token_2.issuer_address = issuer_address
_token_2.token_address = token_address_2
_token_2.abi = {}
db.add(_token_2)

db.commit()

# Execute Issue Event
# Share
_additional_issue_1 = IbetShareAdditionalIssue(
account_address=user_address_1,
amount=10
)
IbetShareContract.additional_issue(token_address_1, _additional_issue_1, issuer_address, issuer_private_key)
time.sleep(1)
_additional_issue_2 = IbetShareAdditionalIssue(
account_address=user_address_1,
amount=20
)
IbetShareContract.additional_issue(token_address_1, _additional_issue_2, issuer_address, issuer_private_key)
time.sleep(1)

# Bond
_additional_issue_3 = IbetStraightBondAdditionalIssue(
account_address=user_address_2,
amount=30
)
IbetStraightBondContract.additional_issue(token_address_2, _additional_issue_3, issuer_address, issuer_private_key)
time.sleep(1)
_additional_issue_4 = IbetStraightBondAdditionalIssue(
account_address=user_address_2,
amount=40
)
IbetStraightBondContract.additional_issue(token_address_2, _additional_issue_4, issuer_address, issuer_private_key)
time.sleep(1)

# Before execute
processor.process()
_utox_list = db.query(UTXO).order_by(UTXO.created).all()
assert len(_utox_list) == 4
_utox = _utox_list[0]
assert _utox.transaction_hash is not None
assert _utox.account_address == user_address_1
assert _utox.token_address == token_address_1
assert _utox.amount == 10
_utox = _utox_list[1]
assert _utox.transaction_hash is not None
assert _utox.account_address == user_address_1
assert _utox.token_address == token_address_1
assert _utox.amount == 20
_utox = _utox_list[2]
assert _utox.transaction_hash is not None
assert _utox.account_address == user_address_2
assert _utox.token_address == token_address_2
assert _utox.amount == 30
_utox = _utox_list[3]
assert _utox.transaction_hash is not None
assert _utox.account_address == user_address_2
assert _utox.token_address == token_address_2
assert _utox.amount == 40

# Execute Redeem Event
# Share
_redeem_1 = IbetShareRedeem(
account_address=user_address_1,
amount=20
)
IbetShareContract.redeem(token_address_1, _redeem_1, issuer_address, issuer_private_key)
time.sleep(1)

# Bond
_redeem_2 = IbetStraightBondRedeem(
account_address=user_address_2,
amount=40
)
IbetStraightBondContract.redeem(token_address_2, _redeem_2, issuer_address, issuer_private_key)
time.sleep(1)

# Execute batch
latest_block = web3.eth.blockNumber
processor.process()

# assertion
db.rollback()
_utox_list = db.query(UTXO).order_by(UTXO.created).all()
assert len(_utox_list) == 4
_utox = _utox_list[0]
assert _utox.account_address == user_address_1
assert _utox.token_address == token_address_1
assert _utox.amount == 0
_utox = _utox_list[1]
assert _utox.account_address == user_address_1
assert _utox.token_address == token_address_1
assert _utox.amount == 10
_utox = _utox_list[2]
assert _utox.account_address == user_address_2
assert _utox.token_address == token_address_2
assert _utox.amount == 0
_utox = _utox_list[3]
assert _utox.account_address == user_address_2
assert _utox.token_address == token_address_2
assert _utox.amount == 30

_utox_block_number = db.query(UTXOBlockNumber).first()
assert _utox_block_number.latest_block_number == latest_block

###########################################################################
# Error Case
###########################################################################
Expand Down

0 comments on commit e0d10fa

Please sign in to comment.