Repository navigation
Expand file tree
/
Copy pathrecord_migration_explicit.cell
More file actions
79 lines (72 loc) · 3.62 KB
/
Copy pathrecord_migration_explicit.cell
File metadata and controls
79 lines (72 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Explicit-bound authoring comparison; business predicates match the named example.
// Experimental Edition 2027. Hashes below are illustrative deployment inputs.
// Preserve each document and its history, append one release note, and advance
// every document to the registry's next revision. History revision identities
// are positive, unique and strictly increasing. No creation, burn or merge.
module cellscript::language::batches::record_migration
struct Message { revision: u64, payload: Vec<u8> }
resource Document has store { messages: NestedValues<Message, 8, 256, 2280>, id: u64, revision: u64 }
resource Registry has store { id: u64, revision: u64 }
cell_roles Migration {
limits { input_scan: 32, output_scan: 32, selected_per_side: 9, aggregate_bytes: 32768 }
documents: Document {
type_hash: "0x1111111111111111111111111111111111111111111111111111111111111111",
lock_hash: "0x3333333333333333333333333333333333333333333333333333333333333333",
identity: id, authority: local_type, correspondence: preserve,
inputs: 1..=8, outputs: 1..=8
}
registry: Registry {
type_hash: "0x2222222222222222222222222222222222222222222222222222222222222222",
lock_hash: "0x3333333333333333333333333333333333333333333333333333333333333333",
identity: id, authority: observe, correspondence: preserve,
inputs: 1..=1, outputs: 1..=1
}
}
fn same_payload(before: NestedBytesView<256>, after: NestedBytesView<256>) -> bool {
if before.len() != after.len() { return false }
for i in 0..before.len() {
if before[i] != after[i] { return false }
}
return true
}
fn same_message(before: NestedRecordView<Message, 256>, after: NestedRecordView<Message, 256>) -> bool {
if before.revision != after.revision { return false }
return same_payload(before.payload, after.payload)
}
fn migrate_document(before: InputView<Document>, after: OutputView<Document>, note: NestedRecordView<Message, 256>, revision: u64) -> bool {
if before.data.id != after.data.id { return false }
if before.data.revision != revision { return false }
if after.data.revision != revision + 1 { return false }
if after.capacity < before.capacity { return false }
if after.capacity < ckb::cell_occupied_capacity(after) { return false }
let old = before.data.messages
let updated = after.data.messages
if old.len() >= 8 { return false }
if updated.len() != old.len() + 1 { return false }
for i in 0..old.len() {
if old[i].revision == 0 || old[i].revision > revision { return false }
if i > 0 {
if old[i - 1].revision >= old[i].revision { return false }
}
if !same_message(old[i], updated[i]) { return false }
}
if !same_message(note, updated[old.len()]) { return false }
return true
}
action migrate(witness release_note: NestedValues<Message, 8, 256, 2280>) -> u64 {
verification
require release_note.len() == 1
let selected = ckb::select_cell_roles<Migration>()
let registry_before = selected.registry.input(0)
let registry_after = selected.registry.successor(0)
let revision = registry_before.data.revision
require revision < 18446744073709551615
require registry_after.data.revision == revision + 1
require release_note[0].revision == revision + 1
// The registry Type and every spending Lock must also accept this same
// transaction. Observing their Cells does not grant lifecycle authority.
for i in 0..selected.documents.input_count() {
require migrate_document(selected.documents.input(i), selected.documents.successor(i), release_note[0], revision)
}
return 0
}