Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions src/consolidations/main.eas
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
#define FEE_UPDATE_FRACTION 17
#define EXCESS_INHIBITOR 1181

#define INPUT_SIZE 96 ;; the size of (source ++ target)
#define RECORD_SIZE 116 ;; the size of (address ++ source ++ target)
#define INPUT_SIZE 96 ;; source ++ target
#define LOG_RECORD_SIZE 116 ;; address ++ source ++ target)
#define OUT_RECORD_SIZE 77 ;; type ++ address ++ source ++ target
#define OUT_RECORD_TYPE 0x02

;; -----------------------------------------------------------------------------
;; PROGRAM START ---------------------------------------------------------------
;; -----------------------------------------------------------------------------

.start:
;; Protect the system subroutine by checking if the caller is the system
;; address.
;; address.
caller ;; [caller]
push20 SYSTEM_ADDR ;; [sysaddr, caller]
eq ;; [sysaddr == caller]
Expand Down Expand Up @@ -141,7 +143,6 @@ check_input:
swap1 ;; [slot, target[16:48], ..]
sstore ;; [..]


;; Assemble log data.
caller ;; [caller, ..]
push1 96 ;; [96, caller, ..]
Expand All @@ -154,7 +155,7 @@ check_input:
calldatacopy ;; [..]

;; Log record.
push1 RECORD_SIZE ;; [size, ..]
push1 LOG_RECORD_SIZE ;; [size, ..]
push0 ;; [idx, size, ..]
log0 ;; [..]

Expand All @@ -174,10 +175,10 @@ check_input:
;; This is the logic executed by the protocol each block. It reads as many
;; requests as available from the queue, until the max request per
;; block is reached. The requests are returned as a contiguous array of bytes
;; with each record being exactly RECORD_SIZE bytes.
;; with each record being exactly OUT_RECORD_SIZE bytes.
;;
;; Consolidation request record:
;;
;;
;; +------+--------+--------+
;; | addr | source | target |
;; +------+--------+--------+
Expand Down Expand Up @@ -216,19 +217,24 @@ begin_loop:
push0 ;; [i, count, head_idx, tail_idx]

accum_loop:
;; This loop will read each request and byte bang it into a RECORD_SIZE byte chunk.
;; This loop will read each request and byte bang it into a OUT_RECORD_SIZE byte chunk.

;; Bounds check, ensure i < count.
dup2 ;; [count, i, count, head_idx, tail_idx]
dup2 ;; [i, count, i, count, head_idx, tail_idx]
eq ;; [i == count, i, count, head_idx, tail_idx]
jumpi @update_head ;; [i, count, head_idx, tail_idx]

;; Precompute record_offset = i*RECORD_SIZE.
;; Precompute record_offset = i*OUT_RECORD_SIZE.
dup1 ;; [i, i, count, head_idx, tail_idx]
push RECORD_SIZE ;; [size, i, i, count, head_idx, tail_idx]
push OUT_RECORD_SIZE ;; [size, i, i, count, head_idx, tail_idx]
mul ;; [record_offset, i, count, head_idx, tail_idx]

;; Store request type to output.
push OUT_RECORD_TYPE ;; [type, record_offset, i, ..]
dup2 ;; [record_offset, type, record_offset, i, ..]
mstore8 ;; [record_offset, i, ..]

;; Determine the storage slot of the address for this iteration. This value is
;; also the base for the other storage slots containing the source and the target
;; public keys. The base slot will be (queue_offset + (queue_head + i)*SLOTS_PER_ITEM).
Expand Down Expand Up @@ -273,28 +279,28 @@ accum_loop:
swap3 ;; [addr, src[32:48] ++ tgt[0:16], source[0:32], target[16:32], record_offset, i, ..]
push 12*8 ;; [96, addr, src[32:48] ++ tgt[0:16], source[0:32], target[16:32], record_offset, i, ..]
shl ;; [addr<<96, src[32:48] ++ tgt[0:16], source[0:32], target[16:32], record_offset, i, ..]
;; Store addr at offset = i*RECORD_SIZE.

;; Store addr at offset = i*OUT_RECORD_SIZE + 1.
dup5 ;; [record_offset, addr<<96, src[32:48] ++ tgt[0:16], source[0:32], target[16:32], record_offset, i, ..]
mstore ;; [src[32:48] ++ tgt[0:16], source[0:32], target[16:32], record_offset, i, ..]

;; Store source[0:32] at offset = i*RECORD_SIZE + 20.
;; Store source[0:32] at offset = i*OUT_RECORD_SIZE + 21.
swap1 ;; [source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
dup4 ;; [record_offset, source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
push 20 ;; [20, record_offset, source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
add ;; [record_offset+20, source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
push 21 ;; [21, record_offset, source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
add ;; [record_offset+21, source[0:32], src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
mstore ;; [src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]

;; Store src[32:48] ++ tgt[0:16] at offset = i*RECORD_SIZE + 52.
;; Store src[32:48] ++ tgt[0:16] at offset = i*OUT_RECORD_SIZE + 53.
dup3 ;; [record_offset, src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
push 52 ;; [52, record_offset, src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
add ;; [record_offset+52, src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
push 53 ;; [53, record_offset, src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
add ;; [record_offset+53, src[32:48] ++ tgt[0:16], target[16:32], record_offset, i, ..]
mstore ;; [target[16:32], record_offset, i, ..]

;; Store target[16:48] at offset = i*RECORD_SIZE + 84.
;; Store target[16:48] at offset = i*OUT_RECORD_SIZE + 85.
swap1 ;; [record_offset, target[16:32], i, ..]
push 84 ;; [84, record_offset, target[16:32], i, ..]
add ;; [record_offset+84, target[16:32], i, ..]
push 85 ;; [85, record_offset, target[16:32], i, ..]
add ;; [record_offset+85, target[16:32], i, ..]
mstore ;; [i, ..]

;; Increment i.
Expand Down Expand Up @@ -339,7 +345,7 @@ update_excess:
;; Update the new excess withdrawal requests.
push SLOT_EXCESS ;; [excess_slot, count]
sload ;; [excess, count]

;; Check if excess needs to be reset to 0 for first iteration after
;; activation.
dup1 ;; [excess, excess, count]
Expand All @@ -365,11 +371,11 @@ skip_reset:
add ;; [count+excess, target, count, excess, count]
gt ;; [count+excess > target, count, excess, count]
jumpi @compute_excess ;; [count, excess, count]

;; Zero out excess.
pop ;; [excess, count]
pop ;; [count]
push0
push0
jump @store_excess

compute_excess:
Expand All @@ -388,7 +394,7 @@ store_excess:
sstore ;; [count]

;; Return the requests.
push RECORD_SIZE ;; [record_size, count]
push OUT_RECORD_SIZE ;; [record_size, count]
mul ;; [size]
push0 ;; [0, size]
return ;; []
Expand Down
41 changes: 24 additions & 17 deletions src/withdrawals/main.eas
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#define FEE_UPDATE_FRACTION 17
#define EXCESS_INHIBITOR 1181

#define INPUT_SIZE 56 ;; the size of (pubkey ++ amount)
#define RECORD_SIZE 76 ;; the size of (address ++ pubkey ++ amount)
#define INPUT_SIZE 56 ;; pubkey ++ amount
#define LOG_RECORD_SIZE 76 ;; address ++ pubkey ++ amount
#define OUT_RECORD_SIZE 77 ;; type ++ address ++ pubkey ++ amount
#define OUT_RECORD_TYPE 0x01

;; -----------------------------------------------------------------------------
;; PROGRAM START ---------------------------------------------------------------
Expand Down Expand Up @@ -154,7 +156,7 @@ check_input:
calldatacopy ;; [..]

;; Log record.
push1 RECORD_SIZE ;; [size, ..]
push1 LOG_RECORD_SIZE ;; [size, ..]
push0 ;; [idx, size, ..]
log0 ;; [..]

Expand Down Expand Up @@ -216,19 +218,24 @@ begin_loop:
push0 ;; [i, count, head_idx, tail_idx]

accum_loop:
;; This loop will read each request and byte bang it into a 76 byte chunk.
;; This loop will read each request and stores them to the return buffer.

;; Bounds check, ensure i < count.
dup2 ;; [count, i, count, head_idx, tail_idx]
dup2 ;; [i, count, i, count, head_idx, tail_idx]
eq ;; [i == count, i, count, head_idx, tail_idx]
jumpi @update_head ;; [i, count, head_idx, tail_idx]

;; Precompute record_offset = i*RECORD_SIZE.
;; Precompute record_offset = i*OUT_RECORD_SIZE.
dup1 ;; [i, i, count, head_idx, tail_idx]
push RECORD_SIZE ;; [size, i, i, count, head_idx, tail_idx]
push OUT_RECORD_SIZE ;; [size, i, i, count, head_idx, tail_idx]
mul ;; [record_offset, i, count, head_idx, tail_idx]

;; Store request type to output buffer.
push OUT_RECORD_TYPE ;; [type, record_offset, i, ..]
dup2 ;; [record_offset, type, record_offset, i, ..]
mstore8 ;; [record_offset, i, ..]

;; Determine the storage slot of the address for this iteration. This value is
;; also the base for the other two storage slots containing the public key and
;; amount. The base slot will be (queue_offset + queue_head*3 + i*3).
Expand Down Expand Up @@ -284,35 +291,35 @@ accum_loop:
push 12*8 ;; [96, addr, pk[0:32], pk2_am, record_offset, i, ..]
shl ;; [addr<<96, pk[0:32], pk2_am, record_offset, i, ..]

;; Store addr at offset = i*RECORD_SIZE.
;; Store addr at offset = i*OUT_RECORD_SIZE + 1.
dup4 ;; [record_offset, addr<<96, pk[0:32], pk2_am, record_offset, i, ..]
mstore ;; [pk[0:32], pk2_am, record_offset, i, ..]

;; Store pk[0:32] at offset = i*RECORD_SIZE + 20.
;; Store pk[0:32] at offset = i*OUT_RECORD_SIZE + 21.
dup3 ;; [record_offset, pk[0:32], pk2_am, record_offset, i, ..]
push 20 ;; [20, record_offset, pk[0:32], pk2_am, record_offset, i, ..]
add ;; [record_offset+20, pk[0:32], pk2_am, record_offset, i, ..]
push 21 ;; [21, record_offset, pk[0:32], pk2_am, record_offset, i, ..]
add ;; [record_offset+21, pk[0:32], pk2_am, record_offset, i, ..]
mstore ;; [pk2_am, record_offset, i, ..]

;; Extract pk2 from pk2_am.
dup1 ;; [pk2_am, pk2_am, record_offset, i, ..]
push pk2_mask ;; [mask, pk2_am, pk2_am, record_offset, i, ..]
and ;; [pk2, pk2_am, record_offset, i, ..]

;; Store pk2 at offset = i*RECORD_SIZE + 52.
;; Store pk2 at offset = i*OUT_RECORD_SIZE + 53.
dup3 ;; [record_offset, pk2, pk2_am, record_offset, i, ..]
push 52 ;; [52, record_offset, pk2, pk2_am, record_offset, i, ..]
add ;; [record_offset+52, pk2, pk2_am, record_offset, i, ..]
push 53 ;; [53, record_offset, pk2, pk2_am, record_offset, i, ..]
add ;; [record_offset+53, pk2, pk2_am, record_offset, i, ..]
mstore ;; [pk2_am, record_offset, i, ..]

;; Extract am from pk2_am.
push 8*8 ;; [shft, pk2_am, record_offset, i, ..]
shr ;; [am, record_offset, i, ..]

;; Store am at offset = i*RECORD_SIZE + 68.
;; Store am at offset = i*OUT_RECORD_SIZE + 69.
swap1 ;; [record_offset, am, i, ..]
push 68 ;; [68, record_offset, am, i, ..]
add ;; [record_offset+68, am, i, ..]
push 69 ;; [69, record_offset, am, i, ..]
add ;; [record_offset+69, am, i, ..]
%mstore_uint64_le() ;; [i, ..]

;; Increment i.
Expand Down Expand Up @@ -406,7 +413,7 @@ store_excess:
sstore ;; [count]

;; Return the withdrawal requests.
push RECORD_SIZE ;; [record_size, count]
push OUT_RECORD_SIZE ;; [record_size, count]
mul ;; [size]
push0 ;; [0, size]
return ;; []
Expand Down