Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
143 changes: 143 additions & 0 deletions gherkin/sbcp/publisher/instances.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
Feature: Publisher Instance Scheduling
The SP initiates multiple composability instances during a period.
It should maintain a queue with incoming XTRequests from users
(either sent directly from the user, or relayed by sequencers).
It follows the constraint that no chain can participate in more than one
active instance at the same time.
Thus, parallel instances are allowed at the publisher level
as long as their participant sets are disjoint.
Moreover, each instance is assigned a sequence number that increases
monotonically within a period, starting from 1.
Once a new period starts, the sequence number resets to 1.
When an instance is decided, its participant chains are freed
and can be included in future instances.

Background:
Given the participating chains are "1,2,3,4"
And SP is currently at period ID "20" targeting superblock "8"

@publisher @sbcp @instances
Scenario: Starts an instance with valid XTRequest and starts from sequence number 1
Given SP has not started any instance in period "20"
And chains "1,2" are inactive
When SP attempts to start an instance with XTRequest:
"""
1: [tx1_a, tx1_b]
2: [tx2]
"""
Then SP should create an instance:
| field | value |
| sequence_number | 1 |
| period_id | 20 |
| xt_request | "1: [tx1_a, tx1_b] 2: [tx2]" |
And chains "1,2" should be marked as active

@publisher @sbcp @instances
Scenario: Starts multiple instances with disjoint participants
Given SP started an instance:
| field | value |
| sequence_number | 1 |
| period_id | 20 |
| xt_request | "1: [tx1_a, tx1_b] 2: [tx2]" |
And chains "3,4" are inactive
When SP attempts to start an instance with XTRequest:
"""
3: [tx3]
4: [tx4]
"""
Then SP should create an instance:
| field | value |
| sequence_number | 2 |
| period_id | 20 |
| xt_request | "3: [tx3] 4: [tx4]" |
And chains "1,2" should be marked as active
And chains "3,4" should be marked as active

@publisher @sbcp @instances
Scenario: Rejects XTRequests that overlap with active participants
Given SP started an instance:
| field | value |
| sequence_number | 1 |
| period_id | 20 |
| xt_request | "1: [tx1_a, tx1_b] 2: [tx2]" |
And chains "1,2" are active
When SP attempts to start an instance with XTRequest:
"""
2: [tx2]
3: [tx3]
"""
Then the attempt should fail with error:
"""
cannot start instance: overlapping active participants
"""
And chains "1,2" should be marked as active
And chain "3" should be marked as inactive
And the following XTRequest should remain in the queue:
"""
2: [tx2]
3: [tx3]
"""

@publisher @sbcp @instances
Scenario: Validates that requests span at least two chains
Given chains "1" are inactive
When SP attempts to start an instance with XTRequest:
"""
1: [tx]
"""
Then the attempt should fail with error:
"""
invalid request: must span at least two chains
"""
And chain "1" should be marked as inactive

@publisher @sbcp @instances
Scenario Outline: Sequence numbers increase monotonically within the same period
Given the last instance SP started was in period "20" with sequence number <last>
And chains "3,4" are inactive
When SP attempts to start an instance with XTRequest:
"""
3: [tx3]
4: [tx4]
"""
Then SP should create an instance:
| field | value |
| sequence_number | <new> |
| period_id | 20 |
| xt_request | "3: [tx3] 4: [tx4]" |
And chains "3,4" should be marked as active

Examples:
| last | new |
| 1 | 2 |
| 2 | 3 |
| 5 | 6 |

@publisher @sbcp @instances
Scenario Outline: Sequence numbers reset at the start of a new period
Given the last instance SP started was in period "20" with sequence number <last>
And SP is currently at period ID "21" targeting superblock "9"
And chains "1,2" are inactive
When SP attempts to start an instance with XTRequest:
"""
1: [tx1]
2: [tx2]
"""
Then SP should create an instance:
| field | value |
| sequence_number | 1 |
| period_id | 21 |
| xt_request | "1: [tx1] 2: [tx2]" |
And chains "1,2" should be marked as active

Examples:
| last |
| 1 |
| 3 |
| 10 |

@publisher @sbcp @instances
Scenario: Deciding an instance frees its chains for future requests
Given chains "1,2" are active for instance "0xabc"
When SP decides instance "0xabc"
Then chains "1,2" should be marked as inactive
59 changes: 59 additions & 0 deletions gherkin/sbcp/publisher/periods.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Feature: Publisher Period Management
Copy link
Contributor

Choose a reason for hiding this comment

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

publisher is sending rollback messages, right?
Maybe we need tio add tests for this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we have this in proofs.feature

The SP is responsible for managing time into periods, defining the target
superblock number to be built, and notifying all sequencers.
Each StartPeriod happy flow call increments both the period ID and the target superblock number,
closing the previous period.
Once a period ends, sequencers will produce zk proofs and submit them to the publisher,
who will aggregate them via a superblock proof and publish to L1.
For liveness, there is a proof window constraint that limits how many periods
can elapse without a superblock proof being published to L1.
In case a StartPeriod is called but a proof window exceedance is detected,
the publisher broadcasts a Rollback, resetting the network state to the last finalized superblock,
Comment on lines +10 to +11
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to discuss how much slack we give the prover

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what do you mean by slack?

and clearing all ongoing activities.
The proof window is exceeded when:
new_target_superblock > (last_finalized_superblock_number + 1) + proof_window

Background:
Given the participating chains are "1,2,3,4"

@publisher @sbcp @periods
Scenario: Broadcasts the next StartPeriod
Given SP is currently at period ID "10" targeting superblock "6"
And the last finalized superblock is:
| field | value |
| number | 5 |
| hash | 0xabc |
When SP starts a new period
Then SP should broadcast StartPeriod with:
| field | value |
| period_id | 11 |
| target_superblock | 7 |

@publisher @sbcp @periods @rollback
Scenario Outline: Rejects StartPeriod when the proof window would be exceeded
Given SP is currently at period ID "30" targeting superblock "<current_superblock>"
And SP enforces a proof window of <proof_window> periods
And the last finalized superblock is:
| field | value |
| number | <last_finalized_superblock> |
| hash | 0xabc |
When SP attempts to start a new period
Then the attempt should fail with error:
"""
proof window exceeded
"""
And no StartPeriod for period "31" should be emitted
And SP should broadcast a Rollback with:
| field | value |
| period_id | 31 |
| superblock | <last_finalized_superblock> |
| hash | 0xabc |
And all active instances should be cleared
And the target superblock should reset to "<superblock_reset>"

Examples:
| proof_window | current_superblock | last_finalized_superblock | superblock_reset |
| 1 | 12 | 10 | 11 |
| 2 | 13 | 10 | 11 |
| 10 | 21 | 10 | 11 |
| 10 | 20 | 9 | 10 |
116 changes: 116 additions & 0 deletions gherkin/sbcp/publisher/proofs.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
Feature: Publisher Settlement Proofs
Once a period ends, sequencers produce zk proofs for their respective chains and
submit them to the SP
The SP collects the proofs in a sequential manner, respecting the order of superblocks.
Thus, only proofs for the next superblock to be proven (the one after the last finalized superblock) are accepted.
Once all proofs for the next superblock to be proven are collected, the SP requests
a superblock proof from the prover, and publishes it to L1.
A request error triggers a rollback to the last finalized superblock.

Background:
Given the participating chains are "1,2"
And the last finalized superblock is:
| field | value |
| number | 5 |
| hash | 0x999 |
And SP is currently at period ID "10" targeting superblock "7"

@publisher @sbcp @proofs
Scenario: Request proof once all per-chain proofs are collected
Given SP received Proof from chain "1" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xaa |
When SP receives Proof from chain "2" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xbb |
Then SP should request the superblock proof:
| field | value |
| superblock_number | 6 |
| last_finalized_hash | 0x999 |
| proofs | "1:0xaa, 2:0xbb" |
And it should publish the resulting proof to L1 for superblock "6"
And the cached per-chain proofs for superblock "6" should be discarded

@publisher @sbcp @proofs
Scenario: Duplicate proofs from the same chain are ignored
Given SP received Proof from chain "1" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xaa |
When SP receives Proof from chain "1" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xbb |
Then the proof should be ignored
Comment on lines +38 to +50
Copy link
Contributor

Choose a reason for hiding this comment

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

hmmm
don't understand the value of this test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

here it means that the sequencer should submit only one proof. If tries to submit another proof for the same period it should be invalid. Do you agree?


@publisher @sbcp @proofs
Scenario: Upon successful request, the superblock proof is published to L1
Given SP requested a superblock proof for superblock "6"
When SP receives a successful response with a superblock proof "0xabc" for superblock "6"
Then SP should publish the proof "0xabc" to L1 for superblock "6"

@publisher @sbcp @proofs
Scenario Outline: Ignores proofs that do not belong to the next superblock to be proven
When SP receives Proof from chain "1" for:
| field | value |
| period_id | <period_id> |
| superblock_number | <superblock> |
| proof_data | 0xcc |
Then the proof should be ignored

Examples:
| period_id | superblock |
| 7 | 4 |
| 10 | 7 |
| 8 | 5 |
| 8 | 6 |

@publisher @sbcp @proofs @rollback
Scenario: Rolls back when the proof request fails
Given SP requested a superblock proof for superblock "6"
When the prover fails to generate the superblock proof for superblock "6"
Then SP should broadcast a Rollback with:
| field | value |
| period_id | 10 |
| superblock | 5 |
| hash | 0x999 |
And the target superblock should reset to "6"

@publisher @sbcp @proofs @rollback
Scenario: Proof timeout clears cached proofs and active instances
Given chains "1,2" are active
And SP received Proof from chain "1" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xaa |
And SP received Proof from chain "2" for:
| field | value |
| period_id | 9 |
| superblock_number | 6 |
| proof_data | 0xbb |
When SP triggers a proof timeout
Then SP should broadcast a Rollback with:
| field | value |
| period_id | 10 |
| superblock | 5 |
| hash | 0x999 |
And chains "1,2" should be marked as inactive
And the target superblock should reset to "6"
Copy link
Contributor

Choose a reason for hiding this comment

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

wait... I am confused
the target superblock is what we are trying to prove?
Then nothing makes sense... why currently we target 7?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

target superblock is the one being built in the current period

And the cached per-chain proofs for superblock "6" should be discarded

@publisher @sbcp @proofs
Scenario: Advances the settled state monotonically
When SP receives the event that superblock "6" with hash "0x777" has been finalized
Then the last finalized superblock should update to "6" with hash "0x777"

@publisher @sbcp @proofs
Scenario: Settlement event for old superblock is ignored
When SP receives the event that superblock "5" with hash "0x999" has been finalized
Then the event should be ignored
Loading
Loading