You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/core/src/apps/eos/actions/__init__.py

124 lines
5.1 KiB

from trezor.crypto.hashlib import sha256
from trezor.messages import EosTxActionAck, EosTxActionRequest
from trezor.utils import HashWriter
from .. import helpers, writers
from . import layout
if False:
from trezor import wire
from trezor.utils import Writer
async def process_action(
ctx: wire.Context, sha: HashWriter, action: EosTxActionAck
) -> None:
name = helpers.eos_name_to_string(action.common.name)
account = helpers.eos_name_to_string(action.common.account)
if not check_action(action, name, account):
raise ValueError("Invalid action")
w = bytearray()
if account == "eosio":
if name == "buyram":
await layout.confirm_action_buyram(ctx, action.buy_ram)
writers.write_action_buyram(w, action.buy_ram)
elif name == "buyrambytes":
await layout.confirm_action_buyrambytes(ctx, action.buy_ram_bytes)
writers.write_action_buyrambytes(w, action.buy_ram_bytes)
elif name == "sellram":
await layout.confirm_action_sellram(ctx, action.sell_ram)
writers.write_action_sellram(w, action.sell_ram)
elif name == "delegatebw":
await layout.confirm_action_delegate(ctx, action.delegate)
writers.write_action_delegate(w, action.delegate)
elif name == "undelegatebw":
await layout.confirm_action_undelegate(ctx, action.undelegate)
writers.write_action_undelegate(w, action.undelegate)
elif name == "refund":
await layout.confirm_action_refund(ctx, action.refund)
writers.write_action_refund(w, action.refund)
elif name == "voteproducer":
await layout.confirm_action_voteproducer(ctx, action.vote_producer)
writers.write_action_voteproducer(w, action.vote_producer)
elif name == "updateauth":
await layout.confirm_action_updateauth(ctx, action.update_auth)
writers.write_action_updateauth(w, action.update_auth)
elif name == "deleteauth":
await layout.confirm_action_deleteauth(ctx, action.delete_auth)
writers.write_action_deleteauth(w, action.delete_auth)
elif name == "linkauth":
await layout.confirm_action_linkauth(ctx, action.link_auth)
writers.write_action_linkauth(w, action.link_auth)
elif name == "unlinkauth":
await layout.confirm_action_unlinkauth(ctx, action.unlink_auth)
writers.write_action_unlinkauth(w, action.unlink_auth)
elif name == "newaccount":
await layout.confirm_action_newaccount(ctx, action.new_account)
writers.write_action_newaccount(w, action.new_account)
else:
raise ValueError("Unrecognized action type for eosio")
elif name == "transfer":
await layout.confirm_action_transfer(ctx, action.transfer, account)
writers.write_action_transfer(w, action.transfer)
else:
await process_unknown_action(ctx, w, action)
writers.write_action_common(sha, action.common)
writers.write_bytes_prefixed(sha, w)
async def process_unknown_action(
ctx: wire.Context, w: Writer, action: EosTxActionAck
) -> None:
checksum = HashWriter(sha256())
writers.write_uvarint(checksum, action.unknown.data_size)
checksum.extend(action.unknown.data_chunk)
writers.write_bytes_unchecked(w, action.unknown.data_chunk)
bytes_left = action.unknown.data_size - len(action.unknown.data_chunk)
while bytes_left != 0:
action = await ctx.call(
EosTxActionRequest(data_size=bytes_left), EosTxActionAck
)
if action.unknown is None:
raise ValueError("Bad response. Unknown struct expected.")
checksum.extend(action.unknown.data_chunk)
writers.write_bytes_unchecked(w, action.unknown.data_chunk)
bytes_left -= len(action.unknown.data_chunk)
if bytes_left < 0:
raise ValueError("Bad response. Buffer overflow.")
await layout.confirm_action_unknown(ctx, action.common, checksum.get_digest())
def check_action(action: EosTxActionAck, name: str, account: str) -> bool:
if account == "eosio":
return (
(name == "buyram" and action.buy_ram is not None)
or (name == "buyrambytes" and action.buy_ram_bytes is not None)
or (name == "sellram" and action.sell_ram is not None)
or (name == "delegatebw" and action.delegate is not None)
or (name == "undelegatebw" and action.undelegate is not None)
or (name == "refund" and action.refund is not None)
or (name == "voteproducer" and action.vote_producer is not None)
or (name == "updateauth" and action.update_auth is not None)
or (name == "deleteauth" and action.delete_auth is not None)
or (name == "linkauth" and action.link_auth is not None)
or (name == "unlinkauth" and action.unlink_auth is not None)
or (name == "newaccount" and action.new_account is not None)
)
elif name == "transfer":
return action.transfer is not None
elif action.unknown is not None:
return True
return False