Skip to content

Commit

Permalink
protomessage tests that forward, deposit, and refund
Browse files Browse the repository at this point in the history
clean up IncomingRune, add tests for mixture and refund

add fixtures for multiple protoburns
  • Loading branch information
clothic authored and clothic committed Aug 25, 2024
1 parent 07cbe2c commit cbfd9ea
Show file tree
Hide file tree
Showing 18 changed files with 7,127 additions and 2,249 deletions.
43 changes: 31 additions & 12 deletions assembly/indexer/protomessage/IncomingRune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ProtoruneTable } from "../tables/protorune";
import { fromArrayBuffer, toArrayBuffer } from "metashrew-runes/assembly/utils";
import { console } from "metashrew-as/assembly/utils";
import { encodeHexFromBuffer } from "metashrew-as/assembly/utils/hex";
import { logArrayBuffer } from "../../utils";

export class IncomingRune {
runeId: RuneId;
Expand Down Expand Up @@ -38,6 +39,12 @@ export class IncomingRune {
this.refundDeposit(this.depositAmount)
);
}
/**
* Refunds an amount from the pointer. If nothing has been forwarded,
* (ie this context pointer balance is 0), then returns false
* @param value amount to refund
* @returns true if refund value successful, false if not refunded
*/
refund(value: u128): bool {
const refundPtr = this.table.OUTPOINT_TO_RUNES.select(
this.context.refund_pointer.toArrayBuffer(),
Expand All @@ -46,22 +53,30 @@ export class IncomingRune {
this.context.pointer.toArrayBuffer(),
).keyword("/balances");
if (this.pointer_index == -1) return false;
const index = ptr.selectIndex(this.pointer_index).unwrap();
const currentValue = fromArrayBuffer(this.context.runtime.get(index));
const pointerIndex = ptr.selectIndex(this.pointer_index).unwrap();
const currentValue = fromArrayBuffer(
this.context.runtime.get(pointerIndex),
);
if (value > currentValue || currentValue + value > this.initialAmount)
return false;
const newValue: u128 = currentValue - value;
if (newValue > u128.Zero) {
this.context.runtime.set(index, toArrayBuffer(newValue));
this.context.runtime.set(pointerIndex, toArrayBuffer(newValue));
} else {
this.context.runtime.set(index, new ArrayBuffer(0));
this.context.runtime.set(pointerIndex, new ArrayBuffer(0));
}
let toSet: ArrayBuffer;
toSet = refundPtr.selectIndex(this.refund_pointer_index).unwrap();
this.amount += value;
this.context.runtime.set(toSet, toArrayBuffer(value));
return true;
}
/**
* Refunds an amount from the RUNTIME Balance. If nothing has been deposited,
* (ie this RUNTIME is 0), then returns false
* @param value amount to refund
* @returns true if refund value successful, false if not refunded
*/
refundDeposit(value: u128): bool {
if (this.refund_pointer_index == -1) return false;
const refundPtr = this.table.OUTPOINT_TO_RUNES.select(
Expand Down Expand Up @@ -101,17 +116,19 @@ export class IncomingRune {
this.context.pointer.toArrayBuffer(),
).keyword("/runes");
if (this.refund_pointer_index == -1) return false;
const index = refundPtr.selectIndex(this.refund_pointer_index).unwrap();
const refundIndex = refundPtr
.selectIndex(this.refund_pointer_index)
.unwrap();
const runeName = this.context.runtime.get(
refundRunesPtr.selectIndex(this.refund_pointer_index).unwrap(),
);
const currentValue = fromArrayBuffer(this.context.runtime.get(index));
const currentValue = fromArrayBuffer(this.context.runtime.get(refundIndex));
if (value > this.amount || value > currentValue) return false;
const newValue: u128 = currentValue - value;
if (newValue > u128.Zero) {
this.context.runtime.set(index, toArrayBuffer(newValue));
this.context.runtime.set(refundIndex, toArrayBuffer(newValue));
} else {
this.context.runtime.set(index, new ArrayBuffer(0));
this.context.runtime.set(refundIndex, new ArrayBuffer(0));
}
let toSet: ArrayBuffer;
if (this.pointer_index == -1) {
Expand Down Expand Up @@ -139,17 +156,19 @@ export class IncomingRune {
this.context.refund_pointer.toArrayBuffer(),
).keyword("/runes");
if (this.refund_pointer_index == -1) return false;
const index = refundPtr.selectIndex(this.refund_pointer_index).unwrap();
const refundIndex = refundPtr
.selectIndex(this.refund_pointer_index)
.unwrap();
const runeId = this.context.runtime.get(
runePtr.selectIndex(this.refund_pointer_index).unwrap(),
);
const currentValue = fromArrayBuffer(this.context.runtime.get(index));
const currentValue = fromArrayBuffer(this.context.runtime.get(refundIndex));
if (value > this.amount || value > currentValue) return false;
const newValue: u128 = currentValue - value;
if (newValue > u128.Zero) {
this.context.runtime.set(index, toArrayBuffer(newValue));
this.context.runtime.set(refundIndex, toArrayBuffer(newValue));
} else {
this.context.runtime.set(index, new ArrayBuffer(0));
this.context.runtime.set(refundIndex, new ArrayBuffer(0));
}
let toSet = this.context.table.RUNTIME_BALANCE.select(runeId);
this.context.runtimeBalance.increase(runeId, value);
Expand Down
63 changes: 63 additions & 0 deletions assembly/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,40 @@ class ForwardAllContext extends MessageContext {
}
}

// forwards half of each rune, deposits 1/4, refunds 1/4
class SimpleMessageContext extends MessageContext {
handle(): bool {
this.runes.map<IncomingRune>((rune) => {
const initAmount = rune.amount;
rune.forward(u128.div(initAmount, u128.from(2)));
rune.deposit(u128.div(initAmount, u128.from(4)));
// no action for the rest, by default should be refunded
return rune;
});
return true;
}
}

// tests refunding existing deposts and forwards
class RefundMessageContext extends MessageContext {
handle(): bool {
this.runes.map<IncomingRune>((rune) => {
const initAmount = rune.amount;
rune.forward(u128.div(initAmount, u128.from(2)));
rune.deposit(u128.div(initAmount, u128.from(4)));
rune.refund(u128.div(initAmount, u128.from(8)));
rune.refund(u128.div(initAmount, u128.from(4)));
rune.refundDeposit(u128.div(initAmount, u128.from(8)));
return rune;
});
return true;
}
}

class DepositAllProtorune extends Protorune<DepositAllContext> {}
class ForwardAllProtorune extends Protorune<ForwardAllContext> {}
class SimpleProtorune extends Protorune<SimpleMessageContext> {}
class RefundProtorune extends Protorune<RefundMessageContext> {}

function _test_ProtoruneRuneId(runeId: ProtoruneRuneId): void {
console.log(runeId.block.toString());
Expand Down Expand Up @@ -136,6 +168,37 @@ export function testProtomessageForwardAll(): void {
_flush();
}

export function testSimpleProtorune(): void {
const data = input();
const box = Box.from(data);
const height = parsePrimitive<u32>(box);
if (height < GENESIS - 6) {
_flush();
return;
}
const block = new Block(box);
if (height >= GENESIS) {
new SpendablesIndex().indexBlock(height, block);
}
new SimpleProtorune().indexBlock(height, block);
_flush();
}
export function testRefundProtorune(): void {
const data = input();
const box = Box.from(data);
const height = parsePrimitive<u32>(box);
if (height < GENESIS - 6) {
_flush();
return;
}
const block = new Block(box);
if (height >= GENESIS) {
new SpendablesIndex().indexBlock(height, block);
}
new RefundProtorune().indexBlock(height, block);
_flush();
}

export function testEtching(): void {
const data = input();
const box = Box.from(data);
Expand Down
21 changes: 11 additions & 10 deletions assembly/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { readULEB128ToU128 } from "metashrew-runes/assembly/leb128";
import { toArrayBuffer } from "metashrew-runes/assembly/utils";
import { u128 } from "as-bignum/assembly";
import { reverse } from "metashrew-as/assembly/utils";
import { console } from "metashrew-as/assembly/utils/logging"

import { console } from "metashrew-as/assembly/utils/logging";

export function alignArrayBuffer(v: ArrayBuffer): Box {
const box = Box.from(v);
Expand Down Expand Up @@ -48,7 +47,7 @@ export function concatByteArrayTruncateZeros(v: Array<u128>): ArrayBuffer {
} else {
result.push(alignU128ToArrayBuffer(value));
foundFirstNonZero = true; // Mark the first nonzero element
continue
continue;
}
}
result.push(Box.from(reverse(toArrayBuffer(value))));
Expand Down Expand Up @@ -87,19 +86,19 @@ export function fieldToArrayBuffer15Bytes(data: Array<u128>): ArrayBuffer {
export function toLEB128(data: u128): ArrayBuffer {
let result: Array<u8> = [];
let tempValue = data;
const sevenBitMask = u128.from(0x7F);
const sevenBitMask = u128.from(0x7f);
const continuationBit = u128.from(0x80);
// Encode the u128 value using LEB128
while (tempValue > sevenBitMask) {
// Extract 7 bits and add continuation bit (0x80)
const extracted: u128 = ((tempValue & sevenBitMask) | continuationBit)
const extracted: u128 = (tempValue & sevenBitMask) | continuationBit;
result.push(<u8>extracted.lo);
// Shift the value right by 7 bits for the next byte
tempValue = tempValue >> <i32>7;
tempValue = tempValue >> (<i32>7);
}

// Add the final byte without continuation bit
const lastByte = <u8>((tempValue & sevenBitMask).lo)
const lastByte = <u8>(tempValue & sevenBitMask).lo;
result.push(lastByte);

const final = changetype<ArrayBuffer>(StaticArray.fromArray<u8>(result));
Expand All @@ -111,6 +110,8 @@ export function logArrayBuffer(arr: ArrayBuffer): void {
const tempArray = Uint8Array.wrap(arr);
console.log("Got arraybuffer of size " + tempArray.length.toString());
tempArray.forEach((val, i) => {
console.log("byte[" + i.toString() + "] = " + val.toString());
})
}
console.log(
`byte[${i}] = 0x${val.toString(16).padStart(2, "0")} (${String.fromCharCode(val)})`,
);
});
}
Binary file modified build/debug.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion build/debug.wasm.map

Large diffs are not rendered by default.

Loading

0 comments on commit cbfd9ea

Please sign in to comment.