Skip to content

Commit 839d6ec

Browse files
authored
fix: appeals implement sequential appeals fail (#637)
* feat: add rollup transaction db table * fix: drop audit table, change id and nonce of rollup, only make one finalized rollup transaction * create rollup transaction for every validator * add function to mock in consensus test * feat: add appeal window, accepted queue, basic test * fix: old tests were stuck on accepted state, add usage of thread * refactor consensus into states * feat: added appeal flow when transaction is accepted including the loop when appeal failed and succeeded * fix: adding tests for appeals and fixing minor bugs * refactor: merge main and PR #573 into this branch * feat: add appeal_failed in db, select new validators when appealed based on formula * docs: cleanup consensus mechanism base file * test: checking the number of validators for different appeals * refactor: merge 593-appeals-add-validators-when-appealed into 604-appeals-implement-sequential-appeals-fail * refactor: merging changed file permissions * fix: appealing a write method gave a KeyError because of wrong conversation of transaction * docs: update transaction_processor argument description * fix: all appeals disagreed because of pending_transactions type * docs: describe calculation of get_extra_validators * refactor: make calculation in get_extra_validators clearer * refactor: make get_extra_validators more clear
1 parent 09c6c11 commit 839d6ec

File tree

9 files changed

+1003
-130
lines changed

9 files changed

+1003
-130
lines changed

.env.example

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ BACKEND_BUILD_TARGET = 'debug' # change to 'prod' or remove to run in pro
6060
HARDHAT_URL = 'http://hardhat'
6161
HARDHAT_PORT = '8545'
6262
HARDHAT_PRIVATE_KEY = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
63+
6364
# LLM Providers Configuration
6465
# If you want to use OpenAI LLMs, add your key here
6566
OPENAIKEY = '<add_your_openai_api_key_here>'

backend/consensus/base.py

+458-58
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""appeal_failed
2+
3+
Revision ID: 2a4ac5eb9455
4+
Revises: b9421e9f12aa
5+
Create Date: 2024-11-22 09:48:50.048787
6+
7+
"""
8+
9+
from typing import Sequence, Union
10+
11+
from alembic import op
12+
import sqlalchemy as sa
13+
14+
15+
# revision identifiers, used by Alembic.
16+
revision: str = "2a4ac5eb9455"
17+
down_revision: Union[str, None] = "b9421e9f12aa"
18+
branch_labels: Union[str, Sequence[str], None] = None
19+
depends_on: Union[str, Sequence[str], None] = None
20+
21+
22+
def upgrade() -> None:
23+
# ### commands auto generated by Alembic - please adjust! ###
24+
op.add_column(
25+
"transactions", sa.Column("appeal_failed", sa.Integer(), nullable=True)
26+
)
27+
# Set all existing 'appeal_failed' values to 0
28+
op.execute("UPDATE transactions SET appeal_failed = 0 WHERE appeal_failed IS NULL")
29+
# ### end Alembic commands ###
30+
31+
32+
def downgrade() -> None:
33+
# ### commands auto generated by Alembic - please adjust! ###
34+
op.drop_column("transactions", "appeal_failed")
35+
# ### end Alembic commands ###

backend/database_handler/models.py

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Transactions(Base):
9595
s: Mapped[Optional[int]] = mapped_column(Integer)
9696
v: Mapped[Optional[int]] = mapped_column(Integer)
9797
ghost_contract_address: Mapped[Optional[str]] = mapped_column(String(255))
98+
appeal_failed: Mapped[Optional[int]] = mapped_column(Integer)
9899

99100
# Relationship for triggered transactions
100101
triggered_by_hash: Mapped[Optional[str]] = mapped_column(

backend/database_handler/transactions_processor.py

+10
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def _parse_transaction_data(transaction_data: Transactions) -> dict:
6262
"ghost_contract_address": transaction_data.ghost_contract_address,
6363
"appealed": transaction_data.appealed,
6464
"timestamp_accepted": transaction_data.timestamp_accepted,
65+
"appeal_failed": transaction_data.appeal_failed,
6566
}
6667

6768
@staticmethod
@@ -225,6 +226,7 @@ def insert_transaction(
225226
ghost_contract_address=ghost_contract_address,
226227
appealed=False,
227228
timestamp_accepted=None,
229+
appeal_failed=0,
228230
)
229231

230232
self.session.add(new_transaction)
@@ -356,3 +358,11 @@ def set_transaction_timestamp_accepted(
356358
transaction.timestamp_accepted = timestamp_accepted
357359
else:
358360
transaction.timestamp_accepted = int(time.time())
361+
362+
def set_transaction_appeal_failed(self, transaction_hash: str, appeal_failed: int):
363+
if appeal_failed < 0:
364+
raise ValueError("appeal_failed must be a non-negative integer")
365+
transaction = (
366+
self.session.query(Transactions).filter_by(hash=transaction_hash).one()
367+
)
368+
transaction.appeal_failed = appeal_failed

backend/domain/types.py

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class Transaction:
8484
ghost_contract_address: str | None = None
8585
appealed: bool = False
8686
timestamp_accepted: int | None = None
87+
appeal_failed: int = 0
8788

8889
def to_dict(self):
8990
return {
@@ -106,6 +107,7 @@ def to_dict(self):
106107
"ghost_contract_address": self.ghost_contract_address,
107108
"appealed": self.appealed,
108109
"timestamp_accepted": self.timestamp_accepted,
110+
"appeal_failed": self.appeal_failed,
109111
}
110112

111113
@classmethod
@@ -130,4 +132,5 @@ def from_dict(cls, input: dict) -> "Transaction":
130132
ghost_contract_address=input.get("ghost_contract_address"),
131133
appealed=input.get("appealed"),
132134
timestamp_accepted=input.get("timestamp_accepted"),
135+
appeal_failed=input.get("appeal_failed", 0),
133136
)

backend/node/types.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ def from_dict(cls, input: dict) -> Optional["Receipt"]:
182182
mode=ExecutionMode.from_string(input.get("mode")),
183183
contract_state=input.get("contract_state"),
184184
node_config=input.get("node_config"),
185-
eq_outputs=input.get("eq_outputs"),
186-
pending_transactions=tuple(
185+
eq_outputs={int(k): v for k, v in input.get("eq_outputs", {}).items()},
186+
pending_transactions=[
187187
PendingTransaction.from_dict(pending_transaction)
188188
for pending_transaction in input.get("pending_transactions", [])
189-
),
189+
],
190190
)
191191
else:
192192
return None

0 commit comments

Comments
 (0)