Skip to content

Commit 1f5fc40

Browse files
committed
Make protocol extensible for external verification backends
1 parent 4417d39 commit 1f5fc40

4 files changed

Lines changed: 179 additions & 10 deletions

File tree

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,28 @@ Initial protocol scaffold for TaskForest: a proof-first task network where human
4141
- settlement requires valid status + proof where applicable
4242
- timeout expiration can force fail settlement with reason `DEADLINE_EXPIRED`
4343

44+
## Extension-ready design (Arcium + MagicBlock)
45+
46+
This scaffold is intentionally not fixed to a single verification/execution path.
47+
48+
- `VerificationBackend` enum supports:
49+
- `Native`
50+
- `Arcium`
51+
- `MagicBlock`
52+
- `Hybrid`
53+
- `Custom(String)` for forward-compatible providers
54+
- Settlement records backend metadata:
55+
- `verification_backend`
56+
- `verification_ref` (attestation/proof/receipt URI)
57+
- Proof submissions accept extensible evidence vectors:
58+
- `evidence_refs: Vec<String>`
59+
- Protocol capabilities are runtime-configurable:
60+
- `allow_confidential_verification`
61+
- `allow_realtime_execution`
62+
- `extension_flags: HashMap<String, String>`
63+
64+
This means Arcium confidential attestations and MagicBlock real-time session receipts can be added without changing the core job lifecycle model.
65+
4466
### Instruction payload format (current scaffold)
4567

4668
Current decoder uses simple pipe-delimited payloads for rapid iteration:
@@ -53,6 +75,12 @@ settle_job|<job_id>|<pass|fail|needs_judge>|<reason_code>|<now>
5375
open_dispute|<job_id>
5476
cancel_job|<job_id>|<poster>
5577
expire_claim|<job_id>|<now>
78+
79+
# optional backend metadata on settle
80+
settle_job|<job_id>|<pass|fail|needs_judge>|<reason_code>|<now>|<backend>|<verification_ref>
81+
82+
# optional evidence refs on submit_proof
83+
submit_proof|<job_id>|<submitter>|<proof_hash>|<now>|<evidence_ref_1>|<evidence_ref_2>|...
5684
```
5785

5886
This will be replaced by compact binary instruction encoding in the on-chain Pinocchio layer.

src/instruction.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
ActorId, CancelJobParams, ClaimJobParams, CreateJobParams, ExpireClaimParams, JobId,
3-
SettleJobParams, SubmitProofParams, Verdict,
3+
SettleJobParams, SubmitProofParams, Verdict, VerificationBackend,
44
};
55

66
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -60,25 +60,38 @@ impl TaskForestInstruction {
6060
}))
6161
}
6262
"submit_proof" => {
63-
if parts.len() != 5 {
63+
if parts.len() < 5 {
6464
return Err(InstructionDecodeError::InvalidFormat);
6565
}
6666
Ok(Self::SubmitProof(SubmitProofParams {
6767
job_id: parse_u64(parts[1])?,
6868
submitter: parse_actor(parts[2]),
6969
proof_hash: parts[3].to_string(),
7070
now_epoch_secs: parse_u64(parts[4])?,
71+
evidence_refs: parts[5..].iter().map(|v| (*v).to_string()).collect(),
7172
}))
7273
}
7374
"settle_job" => {
74-
if parts.len() != 5 {
75+
if parts.len() != 5 && parts.len() != 6 && parts.len() != 7 {
7576
return Err(InstructionDecodeError::InvalidFormat);
7677
}
78+
let backend = if parts.len() >= 6 {
79+
parse_backend(parts[5])
80+
} else {
81+
VerificationBackend::Native
82+
};
83+
let verification_ref = if parts.len() == 7 {
84+
Some(parts[6].to_string())
85+
} else {
86+
None
87+
};
7788
Ok(Self::SettleJob(SettleJobParams {
7889
job_id: parse_u64(parts[1])?,
7990
verdict: parse_verdict(parts[2])?,
8091
reason_code: parts[3].to_string(),
8192
now_epoch_secs: parse_u64(parts[4])?,
93+
verification_backend: backend,
94+
verification_ref,
8295
}))
8396
}
8497
"open_dispute" => {
@@ -129,6 +142,16 @@ fn parse_verdict(value: &str) -> Result<Verdict, InstructionDecodeError> {
129142
}
130143
}
131144

145+
fn parse_backend(value: &str) -> VerificationBackend {
146+
match value {
147+
"native" => VerificationBackend::Native,
148+
"arcium" => VerificationBackend::Arcium,
149+
"magicblock" => VerificationBackend::MagicBlock,
150+
"hybrid" => VerificationBackend::Hybrid,
151+
other => VerificationBackend::Custom(other.to_string()),
152+
}
153+
}
154+
132155
#[cfg(test)]
133156
mod tests {
134157
use super::*;
@@ -161,4 +184,24 @@ mod tests {
161184
let result = TaskForestInstruction::unpack(b"submit_proof|1|proof-hash-only|2000");
162185
assert_eq!(result, Err(InstructionDecodeError::InvalidFormat));
163186
}
187+
188+
#[test]
189+
fn settle_instruction_supports_backend_and_ref() {
190+
let instruction = TaskForestInstruction::unpack(
191+
b"settle_job|77|pass|CHECKS_PASS_ALL|1000|arcium|arcium://proof/77",
192+
)
193+
.expect("settle should unpack");
194+
195+
match instruction {
196+
TaskForestInstruction::SettleJob(params) => {
197+
assert_eq!(params.job_id, 77);
198+
assert_eq!(params.verification_backend, VerificationBackend::Arcium);
199+
assert_eq!(
200+
params.verification_ref,
201+
Some("arcium://proof/77".to_string())
202+
);
203+
}
204+
_ => panic!("expected settle instruction"),
205+
}
206+
}
164207
}

0 commit comments

Comments
 (0)