Repository navigation
Expand file tree
/
Copy pathnested_migration.cell
More file actions
69 lines (64 loc) · 3 KB
/
Copy pathnested_migration.cell
File metadata and controls
69 lines (64 loc) · 3 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
// 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. No creation, burn or merge.
module cellscript::language::batches::nested_migration
data_shape Messages {
element: Vec<u8>,
limits { items: 8, payload_bytes: 256, encoded_bytes: 2120 }
}
resource Document has store { messages: Messages, 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_message(before: Messages::Item, after: Messages::Item) -> bool {
if before.len() != after.len() { return false }
for i in 0..before.len() {
if before[i] != after[i] { return false }
}
return true
}
fn migrate_document(before: InputView<Document>, after: OutputView<Document>, note: Messages::Item, 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 !same_message(old[i], updated[i]) { return false }
}
if !same_message(note, updated[old.len()]) { return false }
return true
}
action migrate(witness release_note: Messages) -> 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
// 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
}