Compare commits

...

1 Commits

Author SHA1 Message Date
Denis Angell
bedde782c6 hook tools 2024-01-24 17:05:37 +01:00
7 changed files with 323 additions and 5 deletions

1
.env Normal file
View File

@@ -0,0 +1 @@
C2WASM_CLI_HOST=http://localhost:9000

127
hook/genesis/callback.c Normal file
View File

@@ -0,0 +1,127 @@
/**
* Payment Txn
*/
#include "hookapi.h"
#include <stdint.h>
// clang-format off
uint8_t txn[305] =
{
/* size,upto */
/* 3, 0 */ 0x12U, 0x00U, 0x00U, /* tt = Payment */
/* 5, 3*/ 0x22U, 0x80U, 0x00U, 0x00U, 0x00U, /* flags = tfCanonical */
/* 5, 8 */ 0x24U, 0x00U, 0x00U, 0x00U, 0x00U, /* sequence = 0 */
/* 5, 13 */ 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, /* dtag, flipped */
/* 6, 18 */ 0x20U, 0x1AU, 0x00U, 0x00U, 0x00U, 0x00U, /* first ledger seq */
/* 6, 24 */ 0x20U, 0x1BU, 0x00U, 0x00U, 0x00U, 0x00U, /* last ledger seq */
/* 49, 30 */ 0x61U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, /* amount field 9 or 49 bytes */
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99,
/* 9, 79 */ 0x68U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, /* fee */
/* 35, 88 */ 0x73U, 0x21U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* pubkey */
/* 22,123 */ 0x81U, 0x14U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* src acc */
/* 22,145 */ 0x83U, 0x14U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* dst acc */
/* 138,167 */ /* emit details */
/* 0,305 */
};
// clang-format on
// TX BUILDER
#define FLS_OUT (txn + 20U)
#define LLS_OUT (txn + 26U)
#define DTAG_OUT (txn + 14U)
#define AMOUNT_OUT (txn + 30U)
#define FEE_OUT (txn + 80U)
#define HOOK_ACC (txn + 125U)
#define OTX_ACC (txn + 147U)
#define EMIT_OUT (txn + 167U)
int64_t cbak(uint32_t f)
{
uint8_t f_buf[4];
UINT32_TO_BUF(f_buf, f);
accept(SBUF(f_buf), __LINE__);
return 0;
}
int64_t hook(uint32_t reserved)
{
TRACESTR("callback.c: Called.");
// ACCOUNT: Hook Account
uint8_t hook_acc[20];
hook_account(HOOK_ACC, 20);
// TXN: PREPARE: Init
etxn_reserve(2);
for (int64_t i = 0; GUARD(2), i < 2; i++)
{
TRACEVAR(i);
switch (i)
{
case 0:
util_accid(OTX_ACC, 20, SBUF("rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK"));
case 1:
util_accid(OTX_ACC, 20, SBUF("rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW"));
default:
break;
}
uint32_t fls = (uint32_t)ledger_seq() + 1;
*((uint32_t *)(FLS_OUT)) = FLIP_ENDIAN(fls);
// TXN PREPARE: LastLedgerSequense
uint32_t lls = fls + 4;
*((uint32_t *)(LLS_OUT)) = FLIP_ENDIAN(lls);
// TXN PREPARE: Amount
uint64_t drops = 1000000;
uint8_t *b = AMOUNT_OUT + 1;
*b++ = 0b01000000 + ((drops >> 56) & 0b00111111);
*b++ = (drops >> 48) & 0xFFU;
*b++ = (drops >> 40) & 0xFFU;
*b++ = (drops >> 32) & 0xFFU;
*b++ = (drops >> 24) & 0xFFU;
*b++ = (drops >> 16) & 0xFFU;
*b++ = (drops >> 8) & 0xFFU;
*b++ = (drops >> 0) & 0xFFU;
// TXN PREPARE: Dest Tag <- Source Tag
if (otxn_field(DTAG_OUT, 4, sfSourceTag) == 4)
*(DTAG_OUT - 1) = 0x2EU;
// TXN PREPARE: Emit Metadata
etxn_details(EMIT_OUT, 138U);
// TXN PREPARE: Fee
{
int64_t fee = etxn_fee_base(SBUF(txn));
uint8_t *b = FEE_OUT;
*b++ = 0b01000000 + ((fee >> 56) & 0b00111111);
*b++ = (fee >> 48) & 0xFFU;
*b++ = (fee >> 40) & 0xFFU;
*b++ = (fee >> 32) & 0xFFU;
*b++ = (fee >> 24) & 0xFFU;
*b++ = (fee >> 16) & 0xFFU;
*b++ = (fee >> 8) & 0xFFU;
*b++ = (fee >> 0) & 0xFFU;
}
TRACEHEX(txn); // <- final tx blob
// TXN: Emit/Send Txn
uint8_t emithash[32];
int64_t emit_result = emit(SBUF(emithash), SBUF(txn));
TRACEVAR(emit_result);
}
accept(SBUF("callback.c: Successful."), __LINE__);
// unreachable
return 0;
}

32
hook/genesis/tsh.c Normal file
View File

@@ -0,0 +1,32 @@
#include "hookapi.h"
int64_t hook(uint32_t reserved) {
TRACESTR("tsh.c: Start.");
uint8_t aaw_buffer[1];
if (otxn_param(SBUF(aaw_buffer), "AAW", 3) == 1)
hook_again();
switch (reserved)
{
case 0:
TRACESTR("tsh.c: Strong. Execute BEFORE transaction is applied to ledger");
break;
case 1:
TRACESTR("tsh.c: Weak. Execute AFTER transaction is applied to ledger");
break;
case 2:
TRACESTR("tsh.c: Weak Again. Execute AFTER transaction is applied to ledger");
break;
default:
break;
}
TRACESTR("tsh.c: End.");
uint8_t r_buf[4];
UINT32_TO_BUF(r_buf, reserved);
accept(SBUF(r_buf), __LINE__);
_g(1,1);
// unreachable
return 0;
}

View File

@@ -9,6 +9,34 @@
#ifndef HOOKMACROS_INCLUDED
#define HOOKMACROS_INCLUDED 1
#define DONEEMPTY()\
accept(0,0,__LINE__)
#define DONEMSG(msg)\
accept(msg, sizeof(msg),__LINE__)
#define DONE(x)\
accept(SVAR(x),(uint32_t)__LINE__);
#define SVAR(x) &x, sizeof(x)
#define ASSERT(x)\
{\
if (!(x))\
rollback(0,0,__LINE__);\
}
#define NOPE(x)\
{\
return rollback((x), sizeof(x), __LINE__);\
}
#define FLIP_ENDIAN(n) ((uint32_t) (((n & 0xFFU) << 24U) | \
((n & 0xFF00U) << 8U) | \
((n & 0xFF0000U) >> 8U) | \
((n & 0xFF000000U) >> 24U)))
#ifdef NDEBUG
#define DEBUG 0
@@ -138,6 +166,18 @@ int out_len = 0;\
*(((uint64_t*)(buf1)) + 2) == *(((uint64_t*)(buf2)) + 2) &&\
*(((uint64_t*)(buf1)) + 3) == *(((uint64_t*)(buf2)) + 3))
#define BUFFER_EQUAL_64(buf1, buf2) \
( \
(*((uint64_t*)(buf1) + 0) == *((uint64_t*)(buf2) + 0)) && \
(*((uint64_t*)(buf1) + 1) == *((uint64_t*)(buf2) + 1)) && \
(*((uint64_t*)(buf1) + 2) == *((uint64_t*)(buf2) + 2)) && \
(*((uint64_t*)(buf1) + 3) == *((uint64_t*)(buf2) + 3)) && \
(*((uint64_t*)(buf1) + 4) == *((uint64_t*)(buf2) + 4)) && \
(*((uint64_t*)(buf1) + 5) == *((uint64_t*)(buf2) + 5)) && \
(*((uint64_t*)(buf1) + 6) == *((uint64_t*)(buf2) + 6)) && \
(*((uint64_t*)(buf1) + 7) == *((uint64_t*)(buf2) + 7)) \
)
// when using this macro buf1len may be dynamic but buf2len must be static
// provide n >= 1 to indicate how many times the macro will be hit on the line of code
@@ -483,11 +523,16 @@ int out_len = 0;\
#define _07_03_ENCODE_SIGNING_PUBKEY(buf_out, pkey )\
ENCODE_SIGNING_PUBKEY(buf_out, pkey );
#define ENCODE_SIGNING_PUBKEY_NULL_SIZE 2
#define ENCODE_SIGNING_PUBKEY_NULL_SIZE 35
#define ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
{\
*buf_out++ = 0x73U;\
*buf_out++ = 0x00U;\
buf_out[0] = 0x73U;\
buf_out[1] = 0x21U;\
*(uint64_t*)(buf_out+2) = 0;\
*(uint64_t*)(buf_out+10) = 0;\
*(uint64_t*)(buf_out+18) = 0;\
*(uint64_t*)(buf_out+25) = 0;\
buf_out += ENCODE_SIGNING_PUBKEY_NULL_SIZE;\
}
#define _07_03_ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
@@ -516,8 +561,7 @@ int out_len = 0;\
}\
else\
{\
*buf_out++ = 0x50U; /* HookHash */\
*buf_out++ = 0x1FU;\
*buf_out++ = 0x1FU; /* HookHash */\
uint64_t* d = (uint64_t*)buf_out;\
uint64_t* s = (uint64_t*)hook0;\
*d++ = *s++;\

35
hook/wasm_from_carray.py Normal file
View File

@@ -0,0 +1,35 @@
import re
import sys
# Check if the file name is provided as a command-line argument
if len(sys.argv) < 2:
print("Usage: python script.py <filename>")
sys.exit(1)
# Read the .h file content
file_name = sys.argv[1] # Get the file name from command-line arguments
try:
with open(file_name, "r") as file:
content = file.read()
# Find the C array using a regular expression
match = re.search(r'\{(.+?)\};', content, re.DOTALL)
if match:
c_array = match.group(1)
# Extract the hexadecimal values and remove the 'U' suffix
hex_values = re.findall(r'0x([0-9A-F]+)U', c_array)
# Convert the list of hex values to a byte array
byte_array = bytearray.fromhex(''.join(hex_values))
# Convert the byte array to a hex string
hex_string = byte_array.hex().upper()
print(hex_string)
else:
print("C array not found in the file.")
except FileNotFoundError:
print(f"File not found: {file_name}")
except Exception as e:
print(f"An error occurred: {e}")

33
hook/wasm_to_carray.py Normal file
View File

@@ -0,0 +1,33 @@
import sys
import binascii
# Check if the name is provided as a command-line argument
if len(sys.argv) != 2:
print("Usage: python script.py <name>")
sys.exit(1)
name: str = sys.argv[1]
try:
with open(f"build/{name}.wasm", "rb") as file:
wasm = file.read()
except FileNotFoundError:
print(f"Error: File build/{name}.wasm not found.")
sys.exit(1)
data = wasm.hex().upper()
# Convert hexadecimal data to bytes
binary_data = binascii.unhexlify(data)
# Generate C array
c_array = ', '.join([f"0x{b:02X}U" for b in binary_data])
try:
with open(f"hook/{name}_a.h", "w") as file:
file.write(f'static const std::vector<uint8_t> {name.capitalize()}Hook = {"{"}')
file.write(c_array)
file.write("};\n")
except IOError as e:
print(f"Error: Unable to write to file {name}_a.h. {e}")
sys.exit(1)

46
hook/wasm_verify.py Normal file
View File

@@ -0,0 +1,46 @@
import re
import sys
# Function to extract hexadecimal values from a C array in a .h file
def extract_hex_values(file_name):
try:
with open(file_name, "r") as file:
content = file.read()
except FileNotFoundError:
print(f"File {file_name} not found.")
return None
# Find the C array using a regular expression
match = re.search(r'\{(.+?)\};', content, re.DOTALL)
if match:
c_array = match.group(1)
# Extract the hexadecimal values and remove the 'U' suffix
hex_values = re.findall(r'0x([0-9A-F]+)U', c_array)
return hex_values
else:
print(f"C array not found in the file {file_name}.")
return None
# Check if the correct number of arguments are provided
if len(sys.argv) != 3:
print("Usage: python script.py <file1.h> <file2.h>")
sys.exit(1)
# File names of the .h files to compare
file_name1 = sys.argv[1]
file_name2 = sys.argv[2]
# Extract hexadecimal values from both files
hex_values1 = extract_hex_values(file_name1)
hex_values2 = extract_hex_values(file_name2)
print(len(hex_values1))
print(len(hex_values2))
# Compare the hexadecimal values if both files have been read successfully
if hex_values1 is not None and hex_values2 is not None:
if hex_values1 == hex_values2:
print("The hexadecimal values in both files match.")
else:
print("The hexadecimal values in both files do not match.")