Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consolidations, withdrawals: output request type #22

Closed
wants to merge 18 commits into from
Closed
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)
fjl marked this conversation as resolved.
Show resolved Hide resolved
#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.
lightclient marked this conversation as resolved.
Show resolved Hide resolved

;; 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