Correct value resolution for token send list

This commit is contained in:
nolash 2021-09-08 08:50:38 +02:00
parent 7b3cefc2ad
commit 6de77825fd
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
3 changed files with 76 additions and 20 deletions

View File

@ -24,6 +24,7 @@ class Processor:
self.source = source self.source = source
self.processor = [] self.processor = []
self.content = [] self.content = []
self.token = []
self.token_resolver = resolver self.token_resolver = resolver
self.cursor = 0 self.cursor = 0
self.gas_oracle = gas_oracle self.gas_oracle = gas_oracle
@ -54,7 +55,8 @@ class Processor:
# 0: recipient # 0: recipient
# 1: amount # 1: amount
# 2: token identifier # 2: token identifier (optional, when not specified network gas token will be used)
# 3: gas amount (optional)
def process(self): def process(self):
txs = [] txs = []
for i, r in enumerate(self.content): for i, r in enumerate(self.content):
@ -68,10 +70,11 @@ class Processor:
self.content[i][1] = int(strip_0x(r[1]), 16) self.content[i][1] = int(strip_0x(r[1]), 16)
native_token_value = 0 native_token_value = 0
if self.token_resolver == None: if self.token_resolver == None:
self.content[i][2] = None self.token.append(None)
else: else:
k = r[2] #self.content[i][2] = self.token_resolver.lookup(k)
self.content[i][2] = self.token_resolver.lookup(k) token = self.token_resolver.lookup(r[2])
self.token.append(token)
if len(self.content[i]) == 3: if len(self.content[i]) == 3:
self.content[i].append(native_token_value) self.content[i].append(native_token_value)
@ -94,27 +97,53 @@ class Processor:
token_factory = None token_factory = None
r = self.content[self.cursor] r = self.content[self.cursor]
logg.debug('rrrr {} '.format(r)) token = self.token[self.cursor]
if r[2] == None: if token == None:
token_factory = Gas(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle) token_factory = Gas(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle)
else: else:
token_factory = ERC20(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle) token_factory = ERC20(self.chain_spec, signer=self.signer, gas_oracle=self.gas_oracle, nonce_oracle=self.nonce_oracle)
value = 0 value = 0
gas_value = 0
data = '0x' data = '0x'
debug_destination = (r[2], token)
if debug_destination[1] == None:
debug_destination = (None, 'network gas token')
if isinstance(token_factory, ERC20): if isinstance(token_factory, ERC20):
(tx_hash_hex, o) = token_factory.transfer(r[2], self.sender, r[0], r[1]) (tx_hash_hex, o) = token_factory.transfer(token, self.sender, r[0], r[1])
logg.debug('tx {}'.format(o)) logg.debug('tx {}'.format(o))
# TODO: allow chainlib to return args only # TODO: allow chainlib to return data args only (TxFormat)
tx = unpack(bytes.fromhex(strip_0x(o['params'][0])), self.chain_spec) tx = unpack(bytes.fromhex(strip_0x(o['params'][0])), self.chain_spec)
data = tx['data'] data = tx['data']
try:
value = int(r[1])
except ValueError:
value = int(strip_0x(r[1]), 16)
try:
gas_value = int(r[3])
except:
gas_value = int(strip_0x(r[3]), 16)
else: else:
value = r[1] try:
value = int(r[1])
except ValueError:
value = int(strip_0x(r[1]), 16)
gas_value = value
logg.debug('token factory {} resolved sender {} recipient {} gas value {} token value {} token {}'.format(
str(token_factory),
self.sender,
r[0],
gas_value,
value,
debug_destination,
)
)
tx = { tx = {
'from': self.sender, 'from': self.sender,
'to': r[0], 'to': r[0],
'value': value, 'value': gas_value,
'data': data, 'data': data,
'nonce': nonce, 'nonce': nonce,
'gasPrice': self.gas_price_start, 'gasPrice': self.gas_price_start,

View File

@ -24,13 +24,13 @@ class DefaultResolver:
def lookup(self, k): def lookup(self, k):
if k == '' or k == None:
return None
for i, lookup in enumerate(self.lookups): for i, lookup in enumerate(self.lookups):
address = self.lookup_pointers[i] address = self.lookup_pointers[i]
o = lookup.address_of(address, k, sender_address=self.sender_address) o = lookup.address_of(address, k, sender_address=self.sender_address)
r = self.rpc.do(o) r = self.rpc.do(o)
address = lookup.parse_address_of(r) address = lookup.parse_address_of(r)
if address == ZERO_ADDRESS: if address != ZERO_ADDRESS:
address = None return address
return address
raise FileNotFoundError(k) raise FileNotFoundError(k)

View File

@ -6,6 +6,7 @@ import datetime
import enum import enum
import re import re
import stat import stat
import socket
# external imports # external imports
import chainlib.eth.cli import chainlib.eth.cli
@ -53,12 +54,14 @@ conn = rpc.connect_by_config(config)
chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC')) chain_spec = ChainSpec.from_chain_str(config.get('CHAIN_SPEC'))
class OpMode(enum.Enum): class OpMode(enum.Enum):
STDOUT = 'standard output' STDOUT = 'standard_output'
UNIX = 'unix socket' UNIX = 'unix_socket'
mode = OpMode.STDOUT mode = OpMode.STDOUT
re_unix = r'^ipc:///.+' re_unix = r'^ipc://(/.+)'
if re.match(re_unix, config.get('_SOCKET', '')): m = re.match(re_unix, config.get('_SOCKET', ''))
if m != None:
config.add(m.group(1), '_SOCKET', exists_ok=True)
r = 0 r = 0
try: try:
stat_info = os.stat(config.get('_SOCKET')) stat_info = os.stat(config.get('_SOCKET'))
@ -70,7 +73,7 @@ if re.match(re_unix, config.get('_SOCKET', '')):
if r > 0: if r > 0:
sys.stderr.write('{} is not a socket\n'.format(config.get('_SOCKET'))) sys.stderr.write('{} is not a socket\n'.format(config.get('_SOCKET')))
sys.exit(1) sys.exit(1)
mode = OpMode.UNIX mode = OpMode.UNIX
logg.info('using mode {}'.format(mode.value)) logg.info('using mode {}'.format(mode.value))
@ -92,9 +95,31 @@ class TokenIndexLookupAdapter(TokenUniqueSymbolIndex):
return self.address_of(self.index_address, v, sender_address=sender) return self.address_of(self.index_address, v, sender_address=sender)
class Outputter:
def __init__(self, mode):
self.out = getattr(self, 'do_' + mode.value)
def do(self, hx):
self.out(hx)
def do_standard_output(self, hx):
sys.stdout.write(hx + '\n')
def do_unix_socket(self, hx):
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(config.get('_SOCKET'))
s.send(hx.encode('utf-8'))
s.close()
def main(): def main():
signer = rpc.get_signer() signer = rpc.get_signer()
# TODO: make resolvers pluggable
token_resolver = DefaultResolver(chain_spec, conn, sender_address=rpc.get_sender_address()) token_resolver = DefaultResolver(chain_spec, conn, sender_address=rpc.get_sender_address())
token_index_lookup = TokenUniqueSymbolIndex(chain_spec, signer=signer, gas_oracle=rpc.get_gas_oracle(), nonce_oracle=rpc.get_nonce_oracle()) token_index_lookup = TokenUniqueSymbolIndex(chain_spec, signer=signer, gas_oracle=rpc.get_gas_oracle(), nonce_oracle=rpc.get_nonce_oracle())
token_resolver.add_lookup(token_index_lookup, config.get('_TOKEN_INDEX')) token_resolver.add_lookup(token_index_lookup, config.get('_TOKEN_INDEX'))
@ -111,13 +136,15 @@ def main():
tx_iter = iter(processor) tx_iter = iter(processor)
out = Outputter(mode)
while True: while True:
tx = None tx = None
try: try:
tx_bytes = next(tx_iter) tx_bytes = next(tx_iter)
except StopIteration: except StopIteration:
break break
print(tx_bytes.hex()) tx_hex = tx_bytes.hex()
out.do(tx_hex)
if __name__ == '__main__': if __name__ == '__main__':