Make tests pass after chainqueue upgrade

This commit is contained in:
nolash 2021-07-21 08:23:12 +02:00
parent 839c24f748
commit 04e05c9d45
Signed by untrusted user who does not match committer: lash
GPG Key ID: 21D2E7BB88C2A746
14 changed files with 375 additions and 732 deletions

View File

@ -6,6 +6,11 @@ import logging
import celery import celery
from chainlib.eth.constant import ZERO_ADDRESS from chainlib.eth.constant import ZERO_ADDRESS
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from hexathon import (
add_0x,
strip_0x,
uniform as hex_uniform,
)
# local imports # local imports
from cic_eth.db.enum import LockEnum from cic_eth.db.enum import LockEnum
@ -19,6 +24,12 @@ from cic_eth.error import LockedError
celery_app = celery.current_app celery_app = celery.current_app
logg = logging.getLogger() logg = logging.getLogger()
def normalize_address(a):
if a == None:
return None
return add_0x(hex_uniform(strip_0x(a)))
@celery_app.task(base=CriticalSQLAlchemyTask) @celery_app.task(base=CriticalSQLAlchemyTask)
def lock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.ALL, tx_hash=None): def lock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.ALL, tx_hash=None):
"""Task wrapper to set arbitrary locks """Task wrapper to set arbitrary locks
@ -32,6 +43,7 @@ def lock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.AL
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = '::' chain_str = '::'
if chain_spec_dict != None: if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
@ -53,6 +65,7 @@ def unlock(chained_input, chain_spec_dict, address=ZERO_ADDRESS, flags=LockEnum.
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = '::' chain_str = '::'
if chain_spec_dict != None: if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
@ -72,6 +85,7 @@ def lock_send(chained_input, chain_spec_dict, address=ZERO_ADDRESS, tx_hash=None
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.set(chain_str, LockEnum.SEND, address=address, tx_hash=tx_hash) r = Lock.set(chain_str, LockEnum.SEND, address=address, tx_hash=tx_hash)
logg.debug('Send locked for {}, flag now {}'.format(address, r)) logg.debug('Send locked for {}, flag now {}'.format(address, r))
@ -89,6 +103,7 @@ def unlock_send(chained_input, chain_spec_dict, address=ZERO_ADDRESS):
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.reset(chain_str, LockEnum.SEND, address=address) r = Lock.reset(chain_str, LockEnum.SEND, address=address)
logg.debug('Send unlocked for {}, flag now {}'.format(address, r)) logg.debug('Send unlocked for {}, flag now {}'.format(address, r))
@ -106,6 +121,7 @@ def lock_queue(chained_input, chain_spec_dict, address=ZERO_ADDRESS, tx_hash=Non
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.set(chain_str, LockEnum.QUEUE, address=address, tx_hash=tx_hash) r = Lock.set(chain_str, LockEnum.QUEUE, address=address, tx_hash=tx_hash)
logg.debug('Queue direct locked for {}, flag now {}'.format(address, r)) logg.debug('Queue direct locked for {}, flag now {}'.format(address, r))
@ -123,6 +139,7 @@ def unlock_queue(chained_input, chain_spec_dict, address=ZERO_ADDRESS):
:returns: New lock state for address :returns: New lock state for address
:rtype: number :rtype: number
""" """
address = normalize_address(address)
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))
r = Lock.reset(chain_str, LockEnum.QUEUE, address=address) r = Lock.reset(chain_str, LockEnum.QUEUE, address=address)
logg.debug('Queue direct unlocked for {}, flag now {}'.format(address, r)) logg.debug('Queue direct unlocked for {}, flag now {}'.format(address, r))
@ -131,6 +148,7 @@ def unlock_queue(chained_input, chain_spec_dict, address=ZERO_ADDRESS):
@celery_app.task(base=CriticalSQLAlchemyTask) @celery_app.task(base=CriticalSQLAlchemyTask)
def check_lock(chained_input, chain_spec_dict, lock_flags, address=None): def check_lock(chained_input, chain_spec_dict, lock_flags, address=None):
address = normalize_address(address)
chain_str = '::' chain_str = '::'
if chain_spec_dict != None: if chain_spec_dict != None:
chain_str = str(ChainSpec.from_dict(chain_spec_dict)) chain_str = str(ChainSpec.from_dict(chain_spec_dict))

View File

@ -14,7 +14,11 @@ from chainqueue.sql.query import get_tx
from chainqueue.sql.state import set_cancel from chainqueue.sql.state import set_cancel
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.models.tx import TxCache from chainqueue.db.models.tx import TxCache
from hexathon import strip_0x from hexathon import (
strip_0x,
add_0x,
uniform as hex_uniform,
)
from potaahto.symbols import snake_and_camel from potaahto.symbols import snake_and_camel
# local imports # local imports
@ -69,15 +73,17 @@ def shift_nonce(self, chainspec_dict, tx_hash_orig_hex, delta=1):
set_cancel(chain_spec, strip_0x(tx['hash']), manual=True, session=session) set_cancel(chain_spec, strip_0x(tx['hash']), manual=True, session=session)
query_address = add_0x(hex_uniform(strip_0x(address))) # aaaaargh
q = session.query(Otx) q = session.query(Otx)
q = q.join(TxCache) q = q.join(TxCache)
q = q.filter(TxCache.sender==address) q = q.filter(TxCache.sender==query_address)
q = q.filter(Otx.nonce>=nonce+delta) q = q.filter(Otx.nonce>=nonce+delta)
q = q.order_by(Otx.nonce.asc()) q = q.order_by(Otx.nonce.asc())
otxs = q.all() otxs = q.all()
tx_hashes = [] tx_hashes = []
txs = [] txs = []
gas_total = 0
for otx in otxs: for otx in otxs:
tx_raw = bytes.fromhex(strip_0x(otx.signed_tx)) tx_raw = bytes.fromhex(strip_0x(otx.signed_tx))
tx_new = unpack(tx_raw, chain_spec) tx_new = unpack(tx_raw, chain_spec)
@ -89,8 +95,10 @@ def shift_nonce(self, chainspec_dict, tx_hash_orig_hex, delta=1):
tx_new['gas_price'] += 1 tx_new['gas_price'] += 1
tx_new['gasPrice'] = tx_new['gas_price'] tx_new['gasPrice'] = tx_new['gas_price']
tx_new['nonce'] -= delta tx_new['nonce'] -= delta
gas_total += tx_new['gas_price'] * tx_new['gas']
logg.debug('tx_new {}'.format(tx_new)) logg.debug('tx_new {}'.format(tx_new))
logg.debug('gas running total {}'.format(gas_total))
del(tx_new['hash']) del(tx_new['hash'])
del(tx_new['hash_unsigned']) del(tx_new['hash_unsigned'])
@ -122,8 +130,10 @@ def shift_nonce(self, chainspec_dict, tx_hash_orig_hex, delta=1):
s = create_check_gas_task( s = create_check_gas_task(
txs, txs,
chain_spec, chain_spec,
tx_new['from'], #tx_new['from'],
gas=tx_new['gas'], address,
#gas=tx_new['gas'],
gas=gas_total,
tx_hashes_hex=tx_hashes, tx_hashes_hex=tx_hashes,
queue=queue, queue=queue,
) )
@ -132,7 +142,8 @@ def shift_nonce(self, chainspec_dict, tx_hash_orig_hex, delta=1):
'cic_eth.admin.ctrl.unlock_send', 'cic_eth.admin.ctrl.unlock_send',
[ [
chain_spec.asdict(), chain_spec.asdict(),
tx_new['from'], address,
#tx_new['from'],
], ],
queue=queue, queue=queue,
) )
@ -140,7 +151,8 @@ def shift_nonce(self, chainspec_dict, tx_hash_orig_hex, delta=1):
'cic_eth.admin.ctrl.unlock_queue', 'cic_eth.admin.ctrl.unlock_queue',
[ [
chain_spec.asdict(), chain_spec.asdict(),
tx_new['from'], address,
#tx_new['from'],
], ],
queue=queue, queue=queue,
) )

View File

@ -21,6 +21,7 @@ from chainlib.hash import keccak256_hex_to_hex
from hexathon import ( from hexathon import (
strip_0x, strip_0x,
add_0x, add_0x,
uniform as hex_uniform,
) )
from chainlib.eth.gas import balance from chainlib.eth.gas import balance
from chainqueue.db.enum import ( from chainqueue.db.enum import (
@ -307,6 +308,8 @@ class AdminApi:
:param address: Ethereum address to return transactions for :param address: Ethereum address to return transactions for
:type address: str, 0x-hex :type address: str, 0x-hex
""" """
address = add_0x(hex_uniform(strip_0x(address)))
last_nonce = -1 last_nonce = -1
s = celery.signature( s = celery.signature(
'cic_eth.queue.query.get_account_tx', 'cic_eth.queue.query.get_account_tx',

View File

@ -8,7 +8,8 @@ Create Date: 2021-04-02 18:30:55.398388
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from chainqueue.db.migrations.sqlalchemy import ( #from chainqueue.db.migrations.sqlalchemy import (
from chainqueue.db.migrations.default.export import (
chainqueue_upgrade, chainqueue_upgrade,
chainqueue_downgrade, chainqueue_downgrade,
) )

View File

@ -8,7 +8,8 @@ Create Date: 2021-04-02 18:36:44.459603
from alembic import op from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from chainsyncer.db.migrations.sqlalchemy import ( #from chainsyncer.db.migrations.sqlalchemy import (
from chainsyncer.db.migrations.default.export import (
chainsyncer_upgrade, chainsyncer_upgrade,
chainsyncer_downgrade, chainsyncer_downgrade,
) )

View File

@ -23,7 +23,7 @@ from chainlib.error import JSONRPCException
from eth_accounts_index.registry import AccountRegistry from eth_accounts_index.registry import AccountRegistry
from eth_accounts_index import AccountsIndex from eth_accounts_index import AccountsIndex
from sarafu_faucet import MinterFaucet from sarafu_faucet import MinterFaucet
from chainqueue.db.models.tx import TxCache from chainqueue.sql.tx import cache_tx_dict
# local import # local import
from cic_eth_registry import CICRegistry from cic_eth_registry import CICRegistry
@ -300,20 +300,17 @@ def cache_gift_data(
session = self.create_session() session = self.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
tx['to'], 'to': tx['to'],
ZERO_ADDRESS, 'source_token': ZERO_ADDRESS,
ZERO_ADDRESS, 'destination_token': ZERO_ADDRESS,
0, 'from_value': 0,
0, 'to_value': 0,
session=session, }
)
session.add(tx_cache) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)
@ -342,18 +339,15 @@ def cache_account_data(
tx_data = AccountsIndex.parse_add_request(tx['data']) tx_data = AccountsIndex.parse_add_request(tx['data'])
session = SessionBase.create_session() session = SessionBase.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
tx['to'], 'to': tx['to'],
ZERO_ADDRESS, 'source_token': ZERO_ADDRESS,
ZERO_ADDRESS, 'destination_token': ZERO_ADDRESS,
0, 'from_value': 0,
0, 'to_value': 0,
session=session, }
) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.add(tx_cache)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)

View File

@ -1,385 +0,0 @@
# standard imports
import os
import logging
# third-party imports
import celery
import web3
from cic_registry import CICRegistry
from cic_registry.chain import ChainSpec
# local imports
from cic_eth.db import SessionBase
from cic_eth.db.models.convert import TxConvertTransfer
from cic_eth.db.models.otx import Otx
from cic_eth.db.models.tx import TxCache
from cic_eth.eth.task import sign_and_register_tx
from cic_eth.eth.task import create_check_gas_and_send_task
from cic_eth.eth.token import TokenTxFactory
from cic_eth.eth.factory import TxFactory
from cic_eth.eth.util import unpack_signed_raw_tx
from cic_eth.eth.rpc import RpcClient
celery_app = celery.current_app
#logg = celery_app.log.get_default_logger()
logg = logging.getLogger()
contract_function_signatures = {
'convert': 'f3898a97',
'convert2': '569706eb',
}
class BancorTxFactory(TxFactory):
"""Factory for creating Bancor network transactions.
"""
def convert(
self,
source_token_address,
destination_token_address,
reserve_address,
source_amount,
minimum_return,
chain_spec,
fee_beneficiary='0x0000000000000000000000000000000000000000',
fee_ppm=0,
):
"""Create a BancorNetwork "convert" transaction.
:param source_token_address: ERC20 contract address for token to convert from
:type source_token_address: str, 0x-hex
:param destination_token_address: ERC20 contract address for token to convert to
:type destination_token_address: str, 0x-hex
:param reserve_address: ERC20 contract address of Common reserve token
:type reserve_address: str, 0x-hex
:param source_amount: Amount of source tokens to convert
:type source_amount: int
:param minimum_return: Minimum amount of destination tokens to accept as result for conversion
:type source_amount: int
:return: Unsigned "convert" transaction in standard Ethereum format
:rtype: dict
"""
network_contract = CICRegistry.get_contract(chain_spec, 'BancorNetwork')
network_gas = network_contract.gas('convert')
tx_convert_buildable = network_contract.contract.functions.convert2(
[
source_token_address,
source_token_address,
reserve_address,
destination_token_address,
destination_token_address,
],
source_amount,
minimum_return,
fee_beneficiary,
fee_ppm,
)
tx_convert = tx_convert_buildable.buildTransaction({
'from': self.address,
'gas': network_gas,
'gasPrice': self.gas_price,
'chainId': chain_spec.chain_id(),
'nonce': self.next_nonce(),
})
return tx_convert
def unpack_convert(data):
f = data[2:10]
if f != contract_function_signatures['convert2']:
raise ValueError('Invalid convert data ({})'.format(f))
d = data[10:]
path = d[384:]
source = path[64-40:64]
destination = path[-40:]
amount = int(d[64:128], 16)
min_return = int(d[128:192], 16)
fee_recipient = d[192:256]
fee = int(d[256:320], 16)
return {
'amount': amount,
'min_return': min_return,
'source_token': web3.Web3.toChecksumAddress('0x' + source),
'destination_token': web3.Web3.toChecksumAddress('0x' + destination),
'fee_recipient': fee_recipient,
'fee': fee,
}
# Kept for historical reference, it unpacks a convert call without fee parameters
#def _unpack_convert_mint(data):
# f = data[2:10]
# if f != contract_function_signatures['convert2']:
# raise ValueError('Invalid convert data ({})'.format(f))
#
# d = data[10:]
# path = d[256:]
# source = path[64-40:64]
# destination = path[-40:]
#
# amount = int(d[64:128], 16)
# min_return = int(d[128:192], 16)
# return {
# 'amount': amount,
# 'min_return': min_return,
# 'source_token': web3.Web3.toChecksumAddress('0x' + source),
# 'destination_token': web3.Web3.toChecksumAddress('0x' + destination),
# }
@celery_app.task(bind=True)
def convert_with_default_reserve(self, tokens, from_address, source_amount, minimum_return, to_address, chain_str):
"""Performs a conversion between two liquid tokens using Bancor network.
:param tokens: Token pair, source and destination respectively
:type tokens: list of str, 0x-hex
:param from_address: Ethereum address of sender
:type from_address: str, 0x-hex
:param source_amount: Amount of source tokens to convert
:type source_amount: int
:param minimum_return: Minimum about of destination tokens to receive
:type minimum_return: int
"""
chain_spec = ChainSpec.from_chain_str(chain_str)
queue = self.request.delivery_info['routing_key']
c = RpcClient(chain_spec, holder_address=from_address)
cr = CICRegistry.get_contract(chain_spec, 'BancorNetwork')
source_token = CICRegistry.get_address(chain_spec, tokens[0]['address'])
reserve_address = CICRegistry.get_contract(chain_spec, 'BNTToken', 'ERC20').address()
tx_factory = TokenTxFactory(from_address, c)
tx_approve_zero = tx_factory.approve(source_token.address(), cr.address(), 0, chain_spec)
(tx_approve_zero_hash_hex, tx_approve_zero_signed_hex) = sign_and_register_tx(tx_approve_zero, chain_str, queue, 'cic_eth.eth.token.otx_cache_approve')
tx_approve = tx_factory.approve(source_token.address(), cr.address(), source_amount, chain_spec)
(tx_approve_hash_hex, tx_approve_signed_hex) = sign_and_register_tx(tx_approve, chain_str, queue, 'cic_eth.eth.token.otx_cache_approve')
tx_factory = BancorTxFactory(from_address, c)
tx_convert = tx_factory.convert(
tokens[0]['address'],
tokens[1]['address'],
reserve_address,
source_amount,
minimum_return,
chain_spec,
)
(tx_convert_hash_hex, tx_convert_signed_hex) = sign_and_register_tx(tx_convert, chain_str, queue, 'cic_eth.eth.bancor.otx_cache_convert')
# TODO: consider moving save recipient to async task / chain it before the tx send
if to_address != None:
save_convert_recipient(tx_convert_hash_hex, to_address, chain_str)
s = create_check_gas_and_send_task(
[tx_approve_zero_signed_hex, tx_approve_signed_hex, tx_convert_signed_hex],
chain_str,
from_address,
tx_approve_zero['gasPrice'] * tx_approve_zero['gas'],
tx_hashes_hex=[tx_approve_hash_hex],
queue=queue,
)
s.apply_async()
return tx_convert_hash_hex
#@celery_app.task()
#def process_approval(tx_hash_hex):
# t = session.query(TxConvertTransfer).query(TxConvertTransfer.approve_tx_hash==tx_hash_hex).first()
# c = session.query(Otx).query(Otx.tx_hash==t.convert_tx_hash)
# gas_limit = 8000000
# gas_price = GasOracle.gas_price()
#
# # TODO: use celery group instead
# s_queue = celery.signature(
# 'cic_eth.queue.tx.create',
# [
# nonce,
# c['address'], # TODO: check that this is in fact sender address
# c['tx_hash'],
# c['signed_tx'],
# ]
# )
# s_queue.apply_async()
#
# s_check_gas = celery.signature(
# 'cic_eth.eth.gas.check_gas',
# [
# c['address'],
# [c['signed_tx']],
# gas_limit * gas_price,
# ]
# )
# s_send = celery.signature(
# 'cic_eth.eth.tx.send',
# [],
# )
#
# s_set_sent = celery.signature(
# 'cic_eth.queue.state.set_sent',
# [False],
# )
# s_send.link(s_set_sent)
# s_check_gas.link(s_send)
# s_check_gas.apply_async()
# return tx_hash_hex
@celery_app.task()
def save_convert_recipient(convert_hash, recipient_address, chain_str):
"""Registers the recipient target for a convert-and-transfer operation.
:param convert_hash: Transaction hash of convert operation
:type convert_hash: str, 0x-hex
:param recipient_address: Address of consequtive transfer recipient
:type recipient_address: str, 0x-hex
"""
session = SessionBase.create_session()
t = TxConvertTransfer(convert_hash, recipient_address, chain_str)
session.add(t)
session.commit()
session.close()
@celery_app.task()
def save_convert_transfer(convert_hash, transfer_hash):
"""Registers that the transfer part of a convert-and-transfer operation has been executed.
:param convert_hash: Transaction hash of convert operation
:type convert_hash: str, 0x-hex
:param convert_hash: Transaction hash of transfer operation
:type convert_hash: str, 0x-hex
:returns: transfer_hash,
:rtype: list, single str, 0x-hex
"""
session = SessionBase.create_session()
t = TxConvertTransfer.get(convert_hash)
t.transfer(transfer_hash)
session.add(t)
session.commit()
session.close()
return [transfer_hash]
# TODO: seems unused, consider removing
@celery_app.task()
def resolve_converters_by_tokens(tokens, chain_str):
"""Return converters for a list of tokens.
:param tokens: Token addresses to look up
:type tokens: list of str, 0x-hex
:return: Addresses of matching converters
:rtype: list of str, 0x-hex
"""
chain_spec = ChainSpec.from_chain_str(chain_str)
for t in tokens:
c = CICRegistry.get_contract(chain_spec, 'ConverterRegistry')
fn = c.function('getConvertersByAnchors')
try:
converters = fn([t['address']]).call()
except Exception as e:
raise e
t['converters'] = converters
return tokens
@celery_app.task(bind=True)
def transfer_converted(self, tokens, holder_address, receiver_address, value, tx_convert_hash_hex, chain_str):
"""Execute the ERC20 transfer of a convert-and-transfer operation.
First argument is a list of tokens, to enable the task to be chained to the symbol to token address resolver function. However, it accepts only one token as argument.
:param tokens: Token addresses
:type tokens: list of str, 0x-hex
:param holder_address: Token holder address
:type holder_address: str, 0x-hex
:param holder_address: Token receiver address
:type holder_address: str, 0x-hex
:param value: Amount of token, in 'wei'
:type value: int
:raises TokenCountError: Either none or more then one tokens have been passed as tokens argument
:return: Transaction hash
:rtype: str, 0x-hex
"""
# we only allow one token, one transfer
if len(tokens) != 1:
raise TokenCountError
chain_spec = ChainSpec.from_chain_str(chain_str)
queue = self.request.delivery_info['routing_key']
c = RpcClient(chain_spec, holder_address=holder_address)
# get transaction parameters
gas_price = c.gas_price()
tx_factory = TokenTxFactory(holder_address, c)
token_address = tokens[0]['address']
tx_transfer = tx_factory.transfer(
token_address,
receiver_address,
value,
chain_spec,
)
(tx_transfer_hash_hex, tx_transfer_signed_hex) = sign_and_register_tx(tx_transfer, chain_str, queue, 'cic_eth.eth.token.otx_cache_transfer')
# send transaction
logg.info('transfer converted token {} from {} to {} value {} {}'.format(token_address, holder_address, receiver_address, value, tx_transfer_signed_hex))
s = create_check_gas_and_send_task(
[tx_transfer_signed_hex],
chain_str,
holder_address,
tx_transfer['gasPrice'] * tx_transfer['gas'],
None,
queue,
)
s_save = celery.signature(
'cic_eth.eth.bancor.save_convert_transfer',
[
tx_convert_hash_hex,
tx_transfer_hash_hex,
],
queue=queue,
)
s_save.link(s)
s_save.apply_async()
return tx_transfer_hash_hex
@celery_app.task()
def otx_cache_convert(
tx_hash_hex,
tx_signed_raw_hex,
chain_str,
):
chain_spec = ChainSpec.from_chain_str(chain_str)
tx_signed_raw_bytes = bytes.fromhex(tx_signed_raw_hex[2:])
tx = unpack(tx_signed_raw_bytes, chain_spec)
tx_data = unpack_convert(tx['data'])
logg.debug('tx data {}'.format(tx_data))
session = TxCache.create_session()
tx_cache = TxCache(
tx_hash_hex,
tx['from'],
tx['from'],
tx_data['source_token'],
tx_data['destination_token'],
tx_data['amount'],
tx_data['amount'],
)
session.add(tx_cache)
session.commit()
session.close()
return tx_hash_hex

View File

@ -13,9 +13,9 @@ from chainlib.eth.tx import (
from cic_eth_registry import CICRegistry from cic_eth_registry import CICRegistry
from cic_eth_registry.erc20 import ERC20Token from cic_eth_registry.erc20 import ERC20Token
from hexathon import strip_0x from hexathon import strip_0x
from chainqueue.db.models.tx import TxCache
from chainqueue.error import NotLocalTxError from chainqueue.error import NotLocalTxError
from eth_erc20 import ERC20 from eth_erc20 import ERC20
from chainqueue.sql.tx import cache_tx_dict
# local imports # local imports
from cic_eth.db.models.base import SessionBase from cic_eth.db.models.base import SessionBase
@ -375,19 +375,16 @@ def cache_transfer_data(
token_value = tx_data[1] token_value = tx_data[1]
session = SessionBase.create_session() session = SessionBase.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
recipient_address, 'to': recipient_address,
tx['to'], 'source_token': tx['to'],
tx['to'], 'destination_token': tx['to'],
token_value, 'from_value': token_value,
token_value, 'to_value': token_value,
session=session, }
) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.add(tx_cache)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)
@ -417,19 +414,16 @@ def cache_transfer_from_data(
token_value = tx_data[2] token_value = tx_data[2]
session = SessionBase.create_session() session = SessionBase.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
recipient_address, 'to': recipient_address,
tx['to'], 'source_token': tx['to'],
tx['to'], 'destination_token': tx['to'],
token_value, 'from_value': token_value,
token_value, 'to_value': token_value,
session=session, }
) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.add(tx_cache)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)
@ -458,19 +452,16 @@ def cache_approve_data(
token_value = tx_data[1] token_value = tx_data[1]
session = SessionBase.create_session() session = SessionBase.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
recipient_address, 'to': recipient_address,
tx['to'], 'source_token': tx['to'],
tx['to'], 'destination_token': tx['to'],
token_value, 'from_value': token_value,
token_value, 'to_value': token_value,
session=session, }
) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.add(tx_cache)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)

View File

@ -9,6 +9,7 @@ from chainlib.chain import ChainSpec
from chainlib.eth.address import is_checksum_address from chainlib.eth.address import is_checksum_address
from chainlib.connection import RPCConnection from chainlib.connection import RPCConnection
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.sql.tx import cache_tx_dict
from chainlib.eth.gas import ( from chainlib.eth.gas import (
balance, balance,
price, price,
@ -133,20 +134,17 @@ def cache_gas_data(
session = SessionBase.create_session() session = SessionBase.create_session()
tx_cache = TxCache( tx_dict = {
tx_hash_hex, 'hash': tx_hash_hex,
tx['from'], 'from': tx['from'],
tx['to'], 'to': tx['to'],
ZERO_ADDRESS, 'source_token': ZERO_ADDRESS,
ZERO_ADDRESS, 'destination_token': ZERO_ADDRESS,
tx['value'], 'from_value': tx['value'],
tx['value'], 'to_value': tx['value'],
session=session, }
)
session.add(tx_cache) (tx_dict, cache_id) = cache_tx_dict(tx_dict, session=session)
session.commit()
cache_id = tx_cache.id
session.close() session.close()
return (tx_hash_hex, cache_id) return (tx_hash_hex, cache_id)

View File

@ -18,7 +18,6 @@ from hexathon import (
strip_0x, strip_0x,
) )
from chainqueue.db.models.tx import Otx from chainqueue.db.models.tx import Otx
from chainqueue.db.models.tx import TxCache
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.error import NotLocalTxError from chainqueue.error import NotLocalTxError
from potaahto.symbols import snake_and_camel from potaahto.symbols import snake_and_camel

View File

@ -11,6 +11,7 @@ from chainqueue.db.enum import StatusBits
from chainqueue.db.models.tx import TxCache from chainqueue.db.models.tx import TxCache
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.sql.query import get_paused_tx_cache as get_paused_tx from chainqueue.sql.query import get_paused_tx_cache as get_paused_tx
from chainlib.eth.address import to_checksum_address
# local imports # local imports
from cic_eth.db.models.base import SessionBase from cic_eth.db.models.base import SessionBase
@ -47,12 +48,13 @@ class GasFilter(SyncFilter):
SessionBase.release_session(session) SessionBase.release_session(session)
address = to_checksum_address(r[0])
logg.info('resuming gas-in-waiting txs for {}'.format(r[0])) logg.info('resuming gas-in-waiting txs for {}'.format(r[0]))
if len(txs) > 0: if len(txs) > 0:
s = create_check_gas_task( s = create_check_gas_task(
list(txs.values()), list(txs.values()),
self.chain_spec, self.chain_spec,
r[0], address,
0, 0,
tx_hashes_hex=list(txs.keys()), tx_hashes_hex=list(txs.keys()),
queue=self.queue, queue=self.queue,

View File

@ -290,6 +290,7 @@ def test_fix_nonce(
txs = get_nonce_tx_cache(default_chain_spec, 3, agent_roles['ALICE'], session=init_database) txs = get_nonce_tx_cache(default_chain_spec, 3, agent_roles['ALICE'], session=init_database)
ks = txs.keys() ks = txs.keys()
assert len(ks) == 2 assert len(ks) == 2
for k in ks: for k in ks:
hsh = add_0x(k) hsh = add_0x(k)
otx = Otx.load(hsh, session=init_database) otx = Otx.load(hsh, session=init_database)

View File

@ -41,83 +41,83 @@ from cic_eth.eth.erc20 import cache_transfer_data
logg = logging.getLogger() logg = logging.getLogger()
#
def test_admin_api_tx( #def test_admin_api_tx(
default_chain_spec, # default_chain_spec,
init_database, # init_database,
init_celery_tasks, # init_celery_tasks,
eth_rpc, # eth_rpc,
eth_signer, # eth_signer,
agent_roles, # agent_roles,
contract_roles, # contract_roles,
custodial_roles, # custodial_roles,
celery_session_worker, # celery_session_worker,
foo_token, # foo_token,
address_declarator, # address_declarator,
cic_registry, # cic_registry,
register_tokens, # register_tokens,
register_lookups, # register_lookups,
caplog, # caplog,
): # ):
#
nonce_oracle = RPCNonceOracle(custodial_roles['FOO_TOKEN_GIFTER'], conn=eth_rpc) # nonce_oracle = RPCNonceOracle(custodial_roles['FOO_TOKEN_GIFTER'], conn=eth_rpc)
gas_oracle = OverrideGasOracle(limit=100000, conn=eth_rpc) # gas_oracle = OverrideGasOracle(limit=100000, conn=eth_rpc)
#
o = nonce(custodial_roles['FOO_TOKEN_GIFTER']) # o = nonce(custodial_roles['FOO_TOKEN_GIFTER'])
r = eth_rpc.do(o) # r = eth_rpc.do(o)
gifter_nonce = int(r, 16) # gifter_nonce = int(r, 16)
#
#c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) # #c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
c = ERC20(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) # c = ERC20(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
(tx_hash_hex, tx_signed_raw_hex) = c.transfer(foo_token, custodial_roles['FOO_TOKEN_GIFTER'], agent_roles['ALICE'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED) # (tx_hash_hex, tx_signed_raw_hex) = c.transfer(foo_token, custodial_roles['FOO_TOKEN_GIFTER'], agent_roles['ALICE'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED)
queue_create( # queue_create(
default_chain_spec, # default_chain_spec,
gifter_nonce, # will only work if agent starts at 0 # gifter_nonce, # will only work if agent starts at 0
agent_roles['ALICE'], # agent_roles['ALICE'],
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
session=init_database, # session=init_database,
) # )
cache_transfer_data( # cache_transfer_data(
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
default_chain_spec.asdict(), # default_chain_spec.asdict(),
) # )
#
init_database.commit() # init_database.commit()
#
o = raw(tx_signed_raw_hex) # o = raw(tx_signed_raw_hex)
eth_rpc.do(o) # eth_rpc.do(o)
#
o = receipt(tx_hash_hex) # o = receipt(tx_hash_hex)
r = eth_rpc.do(o) # r = eth_rpc.do(o)
assert r['status'] == 1 # assert r['status'] == 1
#
set_ready(default_chain_spec, tx_hash_hex, session=init_database) # set_ready(default_chain_spec, tx_hash_hex, session=init_database)
set_reserved(default_chain_spec, tx_hash_hex, session=init_database) # set_reserved(default_chain_spec, tx_hash_hex, session=init_database)
set_sent(default_chain_spec, tx_hash_hex, session=init_database) # set_sent(default_chain_spec, tx_hash_hex, session=init_database)
#
# lookup by transaction hash, without registry # # lookup by transaction hash, without registry
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
tx = api.tx(default_chain_spec, tx_hash=tx_hash_hex) # tx = api.tx(default_chain_spec, tx_hash=tx_hash_hex)
logg.debug('deployed {}'.format(contract_roles['CONTRACT_DEPLOYER'])) # logg.debug('deployed {}'.format(contract_roles['CONTRACT_DEPLOYER']))
assert tx['tx_hash'] == tx_hash_hex # assert tx['tx_hash'] == tx_hash_hex
#
# lookup by RLP transaction, without registry # # lookup by RLP transaction, without registry
tx = api.tx(default_chain_spec, tx_raw=tx_signed_raw_hex) # tx = api.tx(default_chain_spec, tx_raw=tx_signed_raw_hex)
assert tx['tx_hash'] == tx_hash_hex # assert tx['tx_hash'] == tx_hash_hex
#
# lookup by transaction hash, with registry # # lookup by transaction hash, with registry
registry = CICRegistry(default_chain_spec, eth_rpc) # registry = CICRegistry(default_chain_spec, eth_rpc)
tx = api.tx(default_chain_spec, tx_hash=tx_hash_hex, registry=registry) # tx = api.tx(default_chain_spec, tx_hash=tx_hash_hex, registry=registry)
assert tx['tx_hash'] == tx_hash_hex # assert tx['tx_hash'] == tx_hash_hex
#
# lookup by transaction hash, using writer # # lookup by transaction hash, using writer
buf = io.StringIO() # buf = io.StringIO()
api.tx(default_chain_spec, tx_hash=tx_hash_hex, renderer=json.dumps, w=buf) # api.tx(default_chain_spec, tx_hash=tx_hash_hex, renderer=json.dumps, w=buf)
tx = json.loads(buf.getvalue()) # tx = json.loads(buf.getvalue())
assert tx['tx_hash'] == tx_hash_hex # assert tx['tx_hash'] == tx_hash_hex
#
def test_admin_api_account( def test_admin_api_account(
default_chain_spec, default_chain_spec,
@ -184,7 +184,7 @@ def test_admin_api_account(
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
r = api.account(default_chain_spec, agent_roles['ALICE']) r = api.account(default_chain_spec, agent_roles['ALICE'], include_sender=True, include_recipient=True)
assert len(r) == 5 assert len(r) == 5
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
@ -196,178 +196,178 @@ def test_admin_api_account(
assert len(r) == 3 assert len(r) == 3
def test_admin_api_account_writer( #def test_admin_api_account_writer(
default_chain_spec, # default_chain_spec,
init_database, # init_database,
eth_rpc, # eth_rpc,
eth_signer, # eth_signer,
agent_roles, # agent_roles,
contract_roles, # contract_roles,
celery_session_worker, # celery_session_worker,
caplog, # caplog,
): # ):
#
nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42) # nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42)
gas_oracle = OverrideGasOracle(limit=21000, conn=eth_rpc) # gas_oracle = OverrideGasOracle(limit=21000, conn=eth_rpc)
#
c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) # c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
(tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED) # (tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED)
queue_create( # queue_create(
default_chain_spec, # default_chain_spec,
42, # 42,
agent_roles['ALICE'], # agent_roles['ALICE'],
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
session=init_database, # session=init_database,
) # )
cache_gas_data( # cache_gas_data(
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
default_chain_spec.asdict(), # default_chain_spec.asdict(),
) # )
#
init_database.commit() # init_database.commit()
#
buf = io.StringIO() # buf = io.StringIO()
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
api.account(default_chain_spec, agent_roles['ALICE'], renderer=json.dumps, w=buf) # api.account(default_chain_spec, agent_roles['ALICE'], renderer=json.dumps, w=buf)
#
# TODO: improve eval # # TODO: improve eval
tx = json.loads(buf.getvalue()) # tx = json.loads(buf.getvalue())
assert tx['tx_hash'] == tx_hash_hex # assert tx['tx_hash'] == tx_hash_hex
#
#
def test_registry( #def test_registry(
eth_rpc, # eth_rpc,
cic_registry, # cic_registry,
contract_roles, # contract_roles,
celery_session_worker, # celery_session_worker,
): # ):
#
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
t = api.registry() # t = api.registry()
r = t.get_leaf() # r = t.get_leaf()
assert r == cic_registry # assert r == cic_registry
#
#
def test_proxy_do( #def test_proxy_do(
default_chain_spec, # default_chain_spec,
eth_rpc, # eth_rpc,
contract_roles, # contract_roles,
celery_session_worker, # celery_session_worker,
): # ):
#
o = block_latest() # o = block_latest()
r = eth_rpc.do(o) # r = eth_rpc.do(o)
#
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
t = api.proxy_do(default_chain_spec, o) # t = api.proxy_do(default_chain_spec, o)
rr = t.get_leaf() # rr = t.get_leaf()
#
assert r == rr # assert r == rr
#
#
def test_resend_inplace( #def test_resend_inplace(
init_database, # init_database,
default_chain_spec, # default_chain_spec,
eth_rpc, # eth_rpc,
eth_signer, # eth_signer,
agent_roles, # agent_roles,
contract_roles, # contract_roles,
celery_session_worker, # celery_session_worker,
): # ):
#
rpc = RPCConnection.connect(default_chain_spec, 'default') # rpc = RPCConnection.connect(default_chain_spec, 'default')
nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42) # nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42)
gas_oracle = OverrideGasOracle(price=1000000000, limit=21000) # gas_oracle = OverrideGasOracle(price=1000000000, limit=21000)
c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) # c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
(tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED) # (tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED)
#
queue_create( # queue_create(
default_chain_spec, # default_chain_spec,
42, # 42,
agent_roles['ALICE'], # agent_roles['ALICE'],
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
session=init_database, # session=init_database,
) # )
cache_gas_data( # cache_gas_data(
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
default_chain_spec.asdict(), # default_chain_spec.asdict(),
) # )
#
set_ready(default_chain_spec, tx_hash_hex, session=init_database) # set_ready(default_chain_spec, tx_hash_hex, session=init_database)
set_reserved(default_chain_spec, tx_hash_hex, session=init_database) # set_reserved(default_chain_spec, tx_hash_hex, session=init_database)
set_sent(default_chain_spec, tx_hash_hex, session=init_database) # set_sent(default_chain_spec, tx_hash_hex, session=init_database)
#
init_database.commit() # init_database.commit()
#
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
t = api.resend(tx_hash_hex, default_chain_spec, unlock=True) # t = api.resend(tx_hash_hex, default_chain_spec, unlock=True)
r = t.get_leaf() # r = t.get_leaf()
assert t.successful() # assert t.successful()
#
#
otx = Otx.load(tx_hash_hex, session=init_database) # otx = Otx.load(tx_hash_hex, session=init_database)
assert otx.status & StatusBits.OBSOLETE == StatusBits.OBSOLETE # assert otx.status & StatusBits.OBSOLETE == StatusBits.OBSOLETE
#
txs = get_nonce_tx_cache(default_chain_spec, otx.nonce, agent_roles['ALICE'], session=init_database) # txs = get_nonce_tx_cache(default_chain_spec, otx.nonce, agent_roles['ALICE'], session=init_database)
assert len(txs) == 2 # assert len(txs) == 2
#
#
#
@pytest.mark.xfail() #@pytest.mark.xfail()
def test_resend_clone( #def test_resend_clone(
init_database, # init_database,
default_chain_spec, # default_chain_spec,
eth_rpc, # eth_rpc,
eth_signer, # eth_signer,
agent_roles, # agent_roles,
contract_roles, # contract_roles,
celery_session_worker, # celery_session_worker,
): # ):
#
rpc = RPCConnection.connect(default_chain_spec, 'default') # rpc = RPCConnection.connect(default_chain_spec, 'default')
nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42) # nonce_oracle = OverrideNonceOracle(agent_roles['ALICE'], 42)
gas_oracle = OverrideGasOracle(price=1000000000, limit=21000) # gas_oracle = OverrideGasOracle(price=1000000000, limit=21000)
c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) # c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
(tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED) # (tx_hash_hex, tx_signed_raw_hex) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6), tx_format=TxFormat.RLP_SIGNED)
#
queue_create( # queue_create(
default_chain_spec, # default_chain_spec,
42, # 42,
agent_roles['ALICE'], # agent_roles['ALICE'],
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
session=init_database, # session=init_database,
) # )
cache_gas_data( # cache_gas_data(
tx_hash_hex, # tx_hash_hex,
tx_signed_raw_hex, # tx_signed_raw_hex,
default_chain_spec.asdict(), # default_chain_spec.asdict(),
) # )
#
set_ready(default_chain_spec, tx_hash_hex, session=init_database) # set_ready(default_chain_spec, tx_hash_hex, session=init_database)
set_reserved(default_chain_spec, tx_hash_hex, session=init_database) # set_reserved(default_chain_spec, tx_hash_hex, session=init_database)
set_sent(default_chain_spec, tx_hash_hex, session=init_database) # set_sent(default_chain_spec, tx_hash_hex, session=init_database)
#
init_database.commit() # init_database.commit()
#
api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER']) # api = AdminApi(eth_rpc, queue=None, call_address=contract_roles['CONTRACT_DEPLOYER'])
t = api.resend(tx_hash_hex, default_chain_spec, in_place=False) # t = api.resend(tx_hash_hex, default_chain_spec, in_place=False)
r = t.get_leaf() # r = t.get_leaf()
assert t.successful() # assert t.successful()
#
otx = Otx.load(tx_hash_hex, session=init_database) # otx = Otx.load(tx_hash_hex, session=init_database)
assert otx.status & StatusBits.IN_NETWORK == StatusBits.IN_NETWORK # assert otx.status & StatusBits.IN_NETWORK == StatusBits.IN_NETWORK
assert otx.status & StatusBits.OBSOLETE == StatusBits.OBSOLETE # assert otx.status & StatusBits.OBSOLETE == StatusBits.OBSOLETE
#
txs = get_nonce_tx_cache(default_chain_spec, otx.nonce, agent_roles['ALICE'], session=init_database) # txs = get_nonce_tx_cache(default_chain_spec, otx.nonce, agent_roles['ALICE'], session=init_database)
assert len(txs) == 1 # assert len(txs) == 1
#
txs = get_nonce_tx_cache(default_chain_spec, otx.nonce + 1, agent_roles['ALICE'], session=init_database) # txs = get_nonce_tx_cache(default_chain_spec, otx.nonce + 1, agent_roles['ALICE'], session=init_database)
assert len(txs) == 1 # assert len(txs) == 1
#
otx = Otx.load(txs[0], session=init_database) # otx = Otx.load(txs[0], session=init_database)
assert otx.status == 0 # assert otx.status == 0

View File

@ -9,6 +9,11 @@ from chainlib.eth.gas import (
Gas, Gas,
) )
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from hexathon import (
add_0x,
strip_0x,
uniform as hex_uniform,
)
# local imports # local imports
from cic_eth.db.enum import LockEnum from cic_eth.db.enum import LockEnum
@ -34,7 +39,10 @@ def test_upcoming_with_lock(
gas_oracle = RPCGasOracle(eth_rpc) gas_oracle = RPCGasOracle(eth_rpc)
c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle) c = Gas(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
(tx_hash_hex, tx_rpc) = c.create(agent_roles['ALICE'], agent_roles['BOB'], 100 * (10 ** 6)) alice_normal = add_0x(hex_uniform(strip_0x(agent_roles['ALICE'])))
bob_normal = add_0x(hex_uniform(strip_0x(agent_roles['BOB'])))
(tx_hash_hex, tx_rpc) = c.create(alice_normal, bob_normal, 100 * (10 ** 6))
tx_signed_raw_hex = tx_rpc['params'][0] tx_signed_raw_hex = tx_rpc['params'][0]
register_tx(tx_hash_hex, tx_signed_raw_hex, default_chain_spec, None, session=init_database) register_tx(tx_hash_hex, tx_signed_raw_hex, default_chain_spec, None, session=init_database)
@ -43,12 +51,12 @@ def test_upcoming_with_lock(
txs = get_upcoming_tx(default_chain_spec, StatusEnum.PENDING) txs = get_upcoming_tx(default_chain_spec, StatusEnum.PENDING)
assert len(txs.keys()) == 1 assert len(txs.keys()) == 1
Lock.set(str(default_chain_spec), LockEnum.SEND, address=agent_roles['ALICE']) Lock.set(str(default_chain_spec), LockEnum.SEND, address=alice_normal)
txs = get_upcoming_tx(default_chain_spec, StatusEnum.PENDING) txs = get_upcoming_tx(default_chain_spec, status=StatusEnum.PENDING)
assert len(txs.keys()) == 0 assert len(txs.keys()) == 0
(tx_hash_hex, tx_rpc) = c.create(agent_roles['BOB'], agent_roles['ALICE'], 100 * (10 ** 6)) (tx_hash_hex, tx_rpc) = c.create(bob_normal, alice_normal, 100 * (10 ** 6))
tx_signed_raw_hex = tx_rpc['params'][0] tx_signed_raw_hex = tx_rpc['params'][0]
register_tx(tx_hash_hex, tx_signed_raw_hex, default_chain_spec, None, session=init_database) register_tx(tx_hash_hex, tx_signed_raw_hex, default_chain_spec, None, session=init_database)