Skip to content

Instantly share code, notes, and snippets.

@heikoheiko
Last active August 29, 2015 14:07
Show Gist options
  • Save heikoheiko/76c959e7ef80efff0e48 to your computer and use it in GitHub Desktop.
Save heikoheiko/76c959e7ef80efff0e48 to your computer and use it in GitHub Desktop.
ALARM Proposal
==== ALARM ====
Description:
- contracts can schedule future calls to themself, by specifying:
- block height
- gas
- msgdata
- scheduled calls are sorted by (gas, hash(account, msgdata)) # prevent DOS
and executed in this stable sorted order before any other tx
- on OOG: # includes no more existent account, balance
reverted, gas deducted
- on ALERT_GAS_LIMIT: # i.e. scheduled MSGs may only use a fraction of the max gas per block
- rescheduled for the next block
Notes:
- alerts are executed as if they were regular messages
- it is up to the contract
- to detect calls by an alarm (e.g. by a flag in msgdata)
- to expect and deal with delayed (later than scheduled) calls
- to check the gas price and decicide whether to exit or continue
- gas is payed from the contracts balance
- value is 0
- ALERT cost should depend on the block height difference (now, scheduled) * (c + len(calldata))
DATA STRUCTURES:
block.ALERT_GAS_LIMIT = block.GAS_LIMIT / 4 # whatever
state_trie stores:
alarms:
key = sha3('alarm:<blockheight>|<alarm_num>')
data = rlp(account, gas, msgdata)
num_alarms_by_blockheight:
key = sha3('num_alarms:<blockheight>')
data = num_alarms
CODE:
block.num_alarms_by_blockheight(blockheight):
return state.get(sha3('num_alarms:<blockheight>'))
block.add_alarm(blockheight, account, gas, msgdata):
assert blockheight > block.number
num = block.num_alarms_by_blockheight(blockheight)
key = sha3('alarm:<blockheight>|<num>')
data = rlp(account, gas, msgdata)
state.update(key, data)
state.update(sha3('num_alarms:<blockheight>'), num+1)
block.get_alarms(blockheight):
return [rlp.decode(state.get(sha3('alarm:<blockheight>|<num>')))
for num in range(block.num_alarms_by_blockheight(blockheight))]
miner.add_scheduled(self):
alarms = block.get_alarms(blockheight)
alarms.sort(key=gas)
for account, gas, msgdata in alarms:
msg = Message(sender=account, to=account, value=0, gas, msgdata)
try:
success, output = processblock.apply_msg(msg)
except processblock.GasLimitReached:
# reschedule, if there is a chance to get executed
if account.balance >= gas * block.gasprice:
if gas <= block.ALERT_GAS_LIMIT:
block.add_alarm(block.number+1, account, gas, msgdata)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment