Skip to content

Commit

Permalink
Delta encode Rune IDs in edicts (#2532)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Oct 15, 2023
1 parent 3c021f8 commit 1d6a242
Showing 1 changed file with 57 additions and 11 deletions.
68 changes: 57 additions & 11 deletions src/runes/runestone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ impl Runestone {

let mut edicts = Vec::new();
let mut etching = None;

let mut id = 0u128;
for chunk in integers.chunks(3) {
match *chunk {
[id, amount, output] => edicts.push(Edict { id, amount, output }),
[id_delta, amount, output] => {
id = id.saturating_add(id_delta);
edicts.push(Edict { id, amount, output });
}
[rune] => {
etching = Some(Etching {
divisibility: 0,
Expand All @@ -56,10 +59,15 @@ impl Runestone {
pub(crate) fn encipher(&self) -> ScriptBuf {
let mut payload = Vec::new();

for edict in &self.edicts {
varint::encode_to_vec(edict.id, &mut payload);
let mut edicts = self.edicts.clone();
edicts.sort_by_key(|edict| edict.id);

let mut id = 0;
for edict in edicts {
varint::encode_to_vec(edict.id - id, &mut payload);
varint::encode_to_vec(edict.amount, &mut payload);
varint::encode_to_vec(edict.output, &mut payload);
id = edict.id;
}

if let Some(etching) = self.etching {
Expand Down Expand Up @@ -529,7 +537,7 @@ mod tests {

#[test]
fn runestone_may_contain_multiple_edicts() {
let payload = payload(&[1, 2, 3, 4, 5, 6]);
let payload = payload(&[1, 2, 3, 3, 5, 6]);

let payload: &PushBytes = payload.as_slice().try_into().unwrap();

Expand Down Expand Up @@ -565,6 +573,44 @@ mod tests {
);
}

#[test]
fn id_deltas_saturate_to_max() {
let payload = payload(&[1, 2, 3, u128::max_value(), 5, 6]);

let payload: &PushBytes = payload.as_slice().try_into().unwrap();

assert_eq!(
Runestone::decipher(&Transaction {
input: Vec::new(),
output: vec![TxOut {
script_pubkey: script::Builder::new()
.push_opcode(opcodes::all::OP_RETURN)
.push_slice(b"RUNE_TEST")
.push_slice(payload)
.into_script(),
value: 0
}],
lock_time: locktime::absolute::LockTime::ZERO,
version: 0,
}),
Ok(Some(Runestone {
edicts: vec![
Edict {
id: 1,
amount: 2,
output: 3,
},
Edict {
id: u128::max_value(),
amount: 5,
output: 6,
},
],
etching: None,
}))
);
}

#[test]
fn payload_pushes_are_concatenated() {
assert_eq!(
Expand Down Expand Up @@ -768,7 +814,7 @@ mod tests {
},
],
None,
54,
49,
);

case(
Expand Down Expand Up @@ -802,7 +848,7 @@ mod tests {
},
],
None,
81,
70,
);

case(
Expand All @@ -819,7 +865,7 @@ mod tests {
4
],
None,
70,
55,
);

case(
Expand All @@ -836,7 +882,7 @@ mod tests {
5
],
None,
88,
67,
);

case(
Expand All @@ -853,7 +899,7 @@ mod tests {
5
],
None,
72,
64,
);

case(
Expand All @@ -870,7 +916,7 @@ mod tests {
5
],
None,
83,
62,
);
}
}

0 comments on commit 1d6a242

Please sign in to comment.