Skip to content

Instantly share code, notes, and snippets.

@WietseWind
Created April 6, 2023 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save WietseWind/ff8c1693c434507d37badc74d33b249b to your computer and use it in GitHub Desktop.
Save WietseWind/ff8c1693c434507d37badc74d33b249b to your computer and use it in GitHub Desktop.
HookScript (Typescript) Hooks Firewall
class ByteSet {
@lazy
static readonly dataSize: u32 = 32;
constructor(public bytes: ByteArray) {
if (bytes.length != ByteSet.dataSize)
rollback("", pack_error_code(bytes.length));
}
has(n: u8): bool {
let idx = n >> 3, flag = n & 7
return !!(this.bytes[ByteSet.dataSize - 1 - idx] & (1 << flag))
}
}
function hook(reserved: i32)
{
console.log("Firewall: started")
const hook_accid = hook_account();
const account_field = Tx.Account;
const outgoing_flag = account_field == hook_accid
const side_name = outgoing_flag ? 'outgoing' : 'incoming'
const side = new HookParam<ByteSet>({
name: side_name
})
const allow_all = new ByteArray(32)
for (let i = 0; i < allow_all.length; ++i) {
max_iterations(32)
allow_all[i] = 0
}
const filter = side.get(new ByteSet(allow_all))
const transaction_type = <u8>Tx.TransactionType
if (filter.has(transaction_type))
rollback(`Firewall: Blocking ${side_name} transaction of type ${transaction_type}.`)
const amount = Tx.Amount
const xrp_flag = amount.isXrp()
let threshold_name: ByteView
if (xrp_flag) {
const xrp_threshold_name = Amount.makeCurrency("XRP")
threshold_name = new ByteView(xrp_threshold_name, 0, xrp_threshold_name.length)
} else {
threshold_name = amount.currencyCode
}
const threshold = new HookParam<u32>({
name: threshold_name.toString()
})
let min_incoming = 0
if (!outgoing_flag)
min_incoming = threshold.value(0)
if (min_incoming > 0) {
if (xrp_flag) {
let otxn_drops = amount.drops
if (otxn_drops < min_incoming)
rollback(`Firewall: Blocking ${<u32>otxn_drops} drops as too small.`)
} else {
let otxn_tokens = float_int(amount.tokenAmount, 0, 0)
if (otxn_tokens < min_incoming)
rollback(`Firewall: Blocking ${<u32>otxn_tokens} tokens as too small.`)
}
}
const limit = new HookParam<u32>({
name: "memo-max"
})
let max_memo = limit.value(0)
if ((max_memo > 0) && !otxn_field_fits(sfMemo, max_memo))
rollback(`Firewall: Blocking transaction with memo larger than ${max_memo}.`)
accept("Firewall: Allowing transaction.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment