migrations: Enable deployment and data seeding to Bloxberg
This commit is contained in:
@@ -136,7 +136,7 @@ def register(self, account_address, chain_spec_dict, writer_address=None):
|
||||
# Generate and sign transaction
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
nonce_oracle = CustodialTaskNonceOracle(writer_address, self.request.root_id, session=session) #, default_nonce)
|
||||
gas_oracle = self.create_gas_oracle(rpc, AccountRegistry.gas)
|
||||
gas_oracle = self.create_gas_oracle(rpc, code_callback=AccountRegistry.gas)
|
||||
account_registry = AccountsIndex(chain_spec, signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
|
||||
(tx_hash_hex, tx_signed_raw_hex) = account_registry.add(account_registry_address, writer_address, account_address, tx_format=TxFormat.RLP_SIGNED)
|
||||
rpc_signer.disconnect()
|
||||
@@ -192,7 +192,7 @@ def gift(self, account_address, chain_spec_dict):
|
||||
# Generate and sign transaction
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
nonce_oracle = CustodialTaskNonceOracle(account_address, self.request.root_id, session=session) #, default_nonce)
|
||||
gas_oracle = self.create_gas_oracle(rpc, MinterFaucet.gas)
|
||||
gas_oracle = self.create_gas_oracle(rpc, code_callback=MinterFaucet.gas)
|
||||
faucet = Faucet(chain_spec, signer=rpc_signer, nonce_oracle=nonce_oracle, gas_oracle=gas_oracle)
|
||||
(tx_hash_hex, tx_signed_raw_hex) = faucet.give_to(faucet_address, account_address, account_address, tx_format=TxFormat.RLP_SIGNED)
|
||||
rpc_signer.disconnect()
|
||||
@@ -266,19 +266,46 @@ def set_role(self, tag, address, chain_spec_dict):
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def role(self, address, chain_spec_dict):
|
||||
"""Return account role for address
|
||||
"""Return account role for address and/or role
|
||||
|
||||
:param account: Account to check
|
||||
:type account: str, 0x-hex
|
||||
:param chain_str: Chain spec string representation
|
||||
:type chain_str: str
|
||||
:param chain_spec_dict: Chain spec dict representation
|
||||
:type chain_spec_dict: dict
|
||||
:returns: Account, or None if not exists
|
||||
:rtype: Varies
|
||||
"""
|
||||
session = self.create_session()
|
||||
role_tag = AccountRole.role_for(address, session=session)
|
||||
session.close()
|
||||
return role_tag
|
||||
return [(address, role_tag,)]
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=BaseTask)
|
||||
def role_account(self, role_tag, chain_spec_dict):
|
||||
"""Return address for role.
|
||||
|
||||
If the role parameter is None, will return addresses for all roles.
|
||||
|
||||
:param role_tag: Role to match
|
||||
:type role_tag: str
|
||||
:param chain_spec_dict: Chain spec dict representation
|
||||
:type chain_spec_dict: dict
|
||||
:returns: List with a single account/tag pair for a single tag, or a list of account and tag pairs for all tags
|
||||
:rtype: list
|
||||
"""
|
||||
session = self.create_session()
|
||||
|
||||
pairs = None
|
||||
if role_tag != None:
|
||||
addr = AccountRole.get_address(role_tag, session=session)
|
||||
pairs = [(addr, role_tag,)]
|
||||
else:
|
||||
pairs = AccountRole.all(session=session)
|
||||
|
||||
session.close()
|
||||
|
||||
return pairs
|
||||
|
||||
|
||||
@celery_app.task(bind=True, base=CriticalSQLAlchemyTask)
|
||||
|
||||
@@ -10,6 +10,9 @@ from chainlib.eth.tx import (
|
||||
TxFormat,
|
||||
unpack,
|
||||
)
|
||||
from chainlib.eth.contract import (
|
||||
ABIContractEncoder,
|
||||
)
|
||||
from cic_eth_registry import CICRegistry
|
||||
from cic_eth_registry.erc20 import ERC20Token
|
||||
from hexathon import (
|
||||
@@ -31,10 +34,8 @@ from cic_eth.error import (
|
||||
YouAreBrokeError,
|
||||
)
|
||||
from cic_eth.queue.tx import register_tx
|
||||
from cic_eth.eth.gas import (
|
||||
create_check_gas_task,
|
||||
MaxGasOracle,
|
||||
)
|
||||
from cic_eth.eth.gas import create_check_gas_task
|
||||
from cic_eth.eth.util import CacheGasOracle
|
||||
from cic_eth.ext.address import translate_address
|
||||
from cic_eth.task import (
|
||||
CriticalSQLAlchemyTask,
|
||||
@@ -154,8 +155,12 @@ def transfer_from(self, tokens, holder_address, receiver_address, value, chain_s
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
|
||||
session = self.create_session()
|
||||
|
||||
nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session)
|
||||
gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas)
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('transferFrom')
|
||||
method = enc.get()
|
||||
gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session, min_price=self.min_fee_price)
|
||||
c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
|
||||
try:
|
||||
(tx_hash_hex, tx_signed_raw_hex) = c.transfer_from(t['address'], spender_address, holder_address, receiver_address, value, tx_format=TxFormat.RLP_SIGNED)
|
||||
@@ -225,8 +230,12 @@ def transfer(self, tokens, holder_address, receiver_address, value, chain_spec_d
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
|
||||
session = self.create_session()
|
||||
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('transfer')
|
||||
method = enc.get()
|
||||
gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session, min_price=self.min_fee_price)
|
||||
nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session)
|
||||
gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas)
|
||||
c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
|
||||
try:
|
||||
(tx_hash_hex, tx_signed_raw_hex) = c.transfer(t['address'], holder_address, receiver_address, value, tx_format=TxFormat.RLP_SIGNED)
|
||||
@@ -294,8 +303,12 @@ def approve(self, tokens, holder_address, spender_address, value, chain_spec_dic
|
||||
rpc_signer = RPCConnection.connect(chain_spec, 'signer')
|
||||
|
||||
session = self.create_session()
|
||||
|
||||
nonce_oracle = CustodialTaskNonceOracle(holder_address, self.request.root_id, session=session)
|
||||
gas_oracle = self.create_gas_oracle(rpc, MaxGasOracle.gas)
|
||||
enc = ABIContractEncoder()
|
||||
enc.method('approve')
|
||||
method = enc.get()
|
||||
gas_oracle = self.create_gas_oracle(rpc, t['address'], method=method, session=session)
|
||||
c = ERC20(chain_spec, signer=rpc_signer, gas_oracle=gas_oracle, nonce_oracle=nonce_oracle)
|
||||
try:
|
||||
(tx_hash_hex, tx_signed_raw_hex) = c.approve(t['address'], holder_address, spender_address, value, tx_format=TxFormat.RLP_SIGNED)
|
||||
|
||||
@@ -41,6 +41,7 @@ from chainqueue.db.models.tx import TxCache
|
||||
from chainqueue.db.models.otx import Otx
|
||||
|
||||
# local imports
|
||||
from cic_eth.db.models.gas_cache import GasCache
|
||||
from cic_eth.db.models.role import AccountRole
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
from cic_eth.error import (
|
||||
@@ -65,17 +66,56 @@ from cic_eth.encode import (
|
||||
ZERO_ADDRESS_NORMAL,
|
||||
unpack_normal,
|
||||
)
|
||||
from cic_eth.error import SeppukuError
|
||||
from cic_eth.eth.util import MAXIMUM_FEE_UNITS
|
||||
|
||||
celery_app = celery.current_app
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
MAXIMUM_FEE_UNITS = 8000000
|
||||
|
||||
class MaxGasOracle:
|
||||
@celery_app.task(base=CriticalSQLAlchemyTask)
|
||||
def apply_gas_value_cache(address, method, value, tx_hash):
|
||||
return apply_gas_value_cache_local(address, method, value, tx_hash)
|
||||
|
||||
def gas(code=None):
|
||||
return MAXIMUM_FEE_UNITS
|
||||
|
||||
def apply_gas_value_cache_local(address, method, value, tx_hash, session=None):
|
||||
address = tx_normalize.executable_address(address)
|
||||
tx_hash = tx_normalize.tx_hash(tx_hash)
|
||||
value = int(value)
|
||||
|
||||
session = SessionBase.bind_session(session)
|
||||
q = session.query(GasCache)
|
||||
q = q.filter(GasCache.address==address)
|
||||
q = q.filter(GasCache.method==method)
|
||||
o = q.first()
|
||||
|
||||
if o == None:
|
||||
o = GasCache(address, method, value, tx_hash)
|
||||
elif tx.gas_used > o.value:
|
||||
o.value = value
|
||||
o.tx_hash = strip_0x(tx_hash)
|
||||
|
||||
session.add(o)
|
||||
session.commit()
|
||||
|
||||
SessionBase.release_session(session)
|
||||
|
||||
|
||||
def have_gas_minimum(chain_spec, address, min_gas, session=None, rpc=None):
|
||||
if rpc == None:
|
||||
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||
o = balance(add_0x(address))
|
||||
r = rpc.do(o)
|
||||
try:
|
||||
r = int(r)
|
||||
except ValueError:
|
||||
r = strip_0x(r)
|
||||
r = int(r, 16)
|
||||
logg.debug('have gas minimum {} have gas {} minimum is {}'.format(address, r, min_gas))
|
||||
if r < min_gas:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def create_check_gas_task(tx_signed_raws_hex, chain_spec, holder_address, gas=None, tx_hashes_hex=None, queue=None):
|
||||
@@ -357,6 +397,13 @@ def refill_gas(self, recipient_address, chain_spec_dict):
|
||||
# set up evm RPC connection
|
||||
rpc = RPCConnection.connect(chain_spec, 'default')
|
||||
|
||||
# check the gas balance of the gifter
|
||||
if not have_gas_minimum(chain_spec, gas_provider, self.safe_gas_refill_amount):
|
||||
raise SeppukuError('Noooooooooooo; gas gifter {} is broke!'.format(gas_provider))
|
||||
|
||||
if not have_gas_minimum(chain_spec, gas_provider, self.safe_gas_gifter_balance):
|
||||
logg.error('Gas gifter {} gas balance is below the safe level to operate!'.format(gas_provider))
|
||||
|
||||
# set up transaction builder
|
||||
nonce_oracle = CustodialTaskNonceOracle(gas_provider, self.request.root_id, session=session)
|
||||
gas_oracle = self.create_gas_oracle(rpc)
|
||||
|
||||
54
apps/cic-eth/cic_eth/eth/util.py
Normal file
54
apps/cic-eth/cic_eth/eth/util.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# standard imports
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
from chainlib.eth.gas import RPCGasOracle
|
||||
from hexathon import strip_0x
|
||||
|
||||
# local imports
|
||||
from cic_eth.db.models.gas_cache import GasCache
|
||||
from cic_eth.encode import tx_normalize
|
||||
from cic_eth.db.models.base import SessionBase
|
||||
|
||||
MAXIMUM_FEE_UNITS = 8000000
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MaxGasOracle(RPCGasOracle):
|
||||
|
||||
def get_fee_units(self, code=None):
|
||||
return MAXIMUM_FEE_UNITS
|
||||
|
||||
|
||||
class CacheGasOracle(MaxGasOracle):
|
||||
"""Returns a previously recorded value for fee unit expenditure for a contract call, if it exists. Otherwise returns max units.
|
||||
|
||||
:todo: instead of max units, connect a pluggable gas heuristics engine.
|
||||
"""
|
||||
|
||||
def __init__(self, conn, address, method=None, session=None, min_price=None, id_generator=None):
|
||||
super(CacheGasOracle, self).__init__(conn, code_callback=self.get_fee_units, min_price=min_price, id_generator=id_generator)
|
||||
self.value = None
|
||||
self.address = address
|
||||
self.method = method
|
||||
|
||||
address = tx_normalize.executable_address(address)
|
||||
session = SessionBase.bind_session(session)
|
||||
q = session.query(GasCache)
|
||||
q = q.filter(GasCache.address==address)
|
||||
if method != None:
|
||||
method = strip_0x(method)
|
||||
q = q.filter(GasCache.method==method)
|
||||
o = q.first()
|
||||
if o != None:
|
||||
self.value = int(o.value)
|
||||
|
||||
SessionBase.release_session(session)
|
||||
|
||||
|
||||
def get_fee_units(self, code=None):
|
||||
if self.value != None:
|
||||
logg.debug('found stored gas unit value {} for address {} method {}'.format(self.value, self.address, self.method))
|
||||
return self.value
|
||||
return super(CacheGasOracle, self).get_fee_units(code=code)
|
||||
Reference in New Issue
Block a user