proto.eth.tx.base: check serialized data integrity
This commit is contained in:
parent
835914ca3e
commit
856058941c
5 changed files with 57 additions and 7 deletions
|
|
@ -1 +1 @@
|
|||
15.1.dev29
|
||||
15.1.dev30
|
||||
|
|
|
|||
|
|
@ -89,9 +89,49 @@ class Base(TxBase):
|
|||
tx = tx,
|
||||
rx = rx)
|
||||
|
||||
def check_serialized_integrity(self): # TODO
|
||||
return True
|
||||
def check_serialized_integrity(self):
|
||||
if self.signed:
|
||||
from .. import rlp
|
||||
o = self.txobj
|
||||
d = rlp.decode(bytes.fromhex(self.serialized))
|
||||
to_key = 'token_addr' if self.is_token else 'to'
|
||||
|
||||
if o['nonce'] == 0:
|
||||
assert d[0] == b'', f'{d[0]}: invalid nonce in serialized data'
|
||||
else:
|
||||
assert int(d[0].hex(), 16) == o['nonce'], f'{d[0]}: invalid nonce in serialized data'
|
||||
if o.get(to_key):
|
||||
assert d[3].hex() == o[to_key], f'{d[3].hex()}: invalid ‘to’ address in serialized data'
|
||||
if not self.is_token:
|
||||
if o['amt']:
|
||||
assert int(d[4].hex(), 16) == o['amt'].to_unit('wei'), (
|
||||
f'{d[4].hex()}: invalid amt in serialized data')
|
||||
if self.is_swap:
|
||||
assert d[5] == self.swap_memo.encode(), (
|
||||
f'{d[5]}: invalid swap memo in serialized data')
|
||||
|
||||
class TokenBase(Base):
|
||||
dfl_gas = 52000
|
||||
contract_desc = 'token contract'
|
||||
|
||||
def check_serialized_integrity(self):
|
||||
if self.signed:
|
||||
super().check_serialized_integrity()
|
||||
|
||||
from .. import rlp
|
||||
from ....amt import TokenAmt
|
||||
d = rlp.decode(bytes.fromhex(self.serialized))
|
||||
o = self.txobj
|
||||
|
||||
assert d[4] == b'', f'{d[4]}: non-empty amount field in token transaction in serialized data'
|
||||
|
||||
data = d[5].hex()
|
||||
assert data[:8] == 'a9059cbb', (
|
||||
f'{data[:8]}: invalid MethodID for op ‘transfer’ in serialized data')
|
||||
assert data[32:72] == o['token_to'], (
|
||||
f'{data[32:72]}: invalid ‘token_to‘ address in serialized data')
|
||||
assert TokenAmt(
|
||||
int(data[72:], 16),
|
||||
decimals = o['decimals'],
|
||||
from_unit = 'atomic') == o['amt'], (
|
||||
f'{data[72:]}: invalid amt in serialized data')
|
||||
|
|
|
|||
|
|
@ -94,7 +94,9 @@ class Unsigned(Completed, TxBase.Unsigned):
|
|||
await self.do_sign(o, keys[0].sec.wif)
|
||||
msg('OK')
|
||||
from ....tx import SignedTX
|
||||
return await SignedTX(cfg=self.cfg, data=self.__dict__, automount=self.automount)
|
||||
tx = await SignedTX(cfg=self.cfg, data=self.__dict__, automount=self.automount)
|
||||
tx.check_serialized_integrity()
|
||||
return tx
|
||||
except Exception as e:
|
||||
msg(f'{e}: transaction signing failed!')
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ class Base(MMGenObject):
|
|||
self.name = type(self).__name__
|
||||
self.proto = kwargs['proto']
|
||||
self.twctl = kwargs.get('twctl')
|
||||
self.is_token = 'Token' in self.name
|
||||
|
||||
@property
|
||||
def coin(self):
|
||||
|
|
|
|||
|
|
@ -31,9 +31,16 @@ class Completed(Base):
|
|||
self.name = type(self).__name__
|
||||
else:
|
||||
from .file import MMGenTxFile
|
||||
MMGenTxFile(self).parse(str(filename), quiet_open=quiet_open)
|
||||
|
||||
self.check_serialized_integrity()
|
||||
try:
|
||||
MMGenTxFile(self).parse(str(filename), quiet_open=quiet_open)
|
||||
self.check_serialized_integrity()
|
||||
except Exception as e:
|
||||
from ..color import orange
|
||||
from ..util import msg
|
||||
msg(orange(
|
||||
f'Something is wrong with transaction file ‘{filename}’\n'
|
||||
'To fix this problem, please move or delete the file'))
|
||||
raise e
|
||||
|
||||
# repeat with sign and send, because coin daemon could be restarted
|
||||
self.check_correct_chain()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue