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

[RFC] Solidity snapps doc #9123

Merged
merged 2 commits into from
Jan 23, 2024
Merged

[RFC] Solidity snapps doc #9123

merged 2 commits into from
Jan 23, 2024

Conversation

mrmr1993
Copy link
Member

No description provided.

stack of parties (`parties`) and the current state of the stack when a
transaction is reached in the stack (`remaining_parties`).

**Proposal:** pass `parties`, the stack of parties, as part of the snapp input.
Copy link
Member

@imeckler imeckler Jun 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the implementation, the snapp public input currently consists of

  • the full party stack (hash)
  • the party stack at the point of the current party (hash)

party, current_stack, call_stack
```

This increases the number of stack operations per party from 1 to 4.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not trouble us much as a push/pop is just one hash, which is pretty cheap (and will be even cheaper in the new proof system)

- Not applicable, we don't have a gas model.
* `msg.data`
- Available as part of the snapp input
* `msg.sender`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is as easy as changing the "transaction commitment" used for the public input to include the fee_payer.

I will note that there is a bit of a trade-off here, as we'd lose the ability to have transactions that were proved independently and then sent off by someone. We could do both by including a bit for each party that says whether it wants to be verified against the public input that includes the fee-payer or the one that doesn't... but that adds some complexity

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to have it as a predicate then? This means its still accessible by querying the party if you want it, but otherwise gives separability.

Should we consider doing the equivalent for parties and the stack below the current party, so that a snapp can always be proved in isolation if it doesn't depend on these?

Copy link
Member

@imeckler imeckler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing, left a few comments

@mrmr1993
Copy link
Member Author

mrmr1993 commented Jul 9, 2021

Option for on-chain delayed roll-up: accumulate the pending updates for the current block, and hold onto the updates for the previous 5 blocks (15 minutes to do the roll-up). Then, a roll-up can trigger on any of those updates.
This would be something like

type state =
  { last_updated_slot: Slot.t
  ; pending_updates: Update.t Stack.t
  ; prev_updates1: Update.t Stack.t Stack.t
  ; prev_updates2: Update.t Stack.t Stack.t
  ; prev_updates3: Update.t Stack.t Stack.t
  ; prev_updates4: Update.t Stack.t Stack.t
  ; prev_updates5: Update.t Stack.t Stack.t }

where prev_updates_n = Stack.push prev_updates_{n+1} updates_for_some_block

I think this is pretty cheap in the circuit:

let push_update update state now =
  let is_empty = Update.is_empty update in
  let state =
    let update = not (is_empty || Slot.equal state.last_updated_slot now) in
    let
      { last_updated_slot
      ; pending_updates
      ; prev_updates1
      ; prev_updates2
      ; prev_updates3
      ; prev_updates4
      ; prev_updates5 } = state in
    let new_prev_updates = Stack.push prev_updates1 pending_updates in
    { last_updated_slot= if update then now else last_updated_slot
    ; pending_updates= if update then Stack.empty else pending_updates
    ; prev_updates1= if update then new_prev_updates else prev_updates1
    ; prev_updates2= if update then prev_updates1 else prev_updates2
    ; prev_updates3= if update then prev_updates2 else prev_updates3
    ; prev_updates4= if update then prev_updates3 else prev_updates4
    ; prev_updates5= if update then prev_updates4 else prev_updates5 }
  in
  let new_pending_updates = Stack.push state.pending_updates update in
  {state with pending_updates= if is_empty then state.pending_updates else new_pending_updates}

let check_update_predicate update_predicate state =
  List.any
    [ Stack.equal update_pedicate state.prev_updates1
    ; Stack.equal update_pedicate state.prev_updates2
    ; Stack.equal update_pedicate state.prev_updates3
    ; Stack.equal update_pedicate state.prev_updates4
    ; Stack.equal update_pedicate state.prev_updates5 ]

This comes out as

  • 2 hashes
  • 6 equality checks
  • 7 if statements
  • snapp account size increases by 6 field elements + 1 slot = 6*32 + 1*8 = 200 bytes

Note that rolling-up after a delay complicates cross-snapp calls, since updates involving roll-ups are no longer atomic.

@mrmr1993 mrmr1993 changed the base branch from compatible to develop January 23, 2024 22:11
@mrmr1993
Copy link
Member Author

!ci-build-me

@mrmr1993 mrmr1993 merged commit 30b545a into develop Jan 23, 2024
12 checks passed
@mrmr1993 mrmr1993 deleted the rfcs/solidity-snapps branch January 23, 2024 22:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants