diff --git a/scripts/gen_bytecode.lua b/scripts/gen_bytecode.lua new file mode 100644 index 000000000..e135f5349 --- /dev/null +++ b/scripts/gen_bytecode.lua @@ -0,0 +1,72 @@ +function gen_bytecode() + pay_contract = function(param) + from, to, value, sequence, sig = string.unpack("c32 c32 I8 I8 c64", param) + + function get_account_key(name) + account_prefix = "account_" + account_key = account_prefix .. name + return account_key + end + + function get_account(name) + account_key = get_account_key(name) + account_data = coroutine.yield(account_key) + if string.len(account_data) > 0 then + account_balance, account_sequence + = string.unpack("I8 I8", account_data) + return account_balance, account_sequence + end + return 0, 0 + end + + function pack_account(updates, name, balance, seq) + updates[get_account_key(name)] = string.pack("I8 I8", balance, seq) + end + + function update_accounts(from_acc, from_bal, from_seq, to_acc, to_bal, to_seq) + ret = {} + pack_account(ret, from_acc, from_bal, from_seq) + if to_acc ~= nil then + pack_account(ret, to_acc, to_bal, to_seq) + end + return ret + end + + function sig_payload(to_acc, value, seq) + return string.pack("c32 I8 I8", to_acc, value, seq) + end + + from_balance, from_seq = get_account(from) + payload = sig_payload(to, value, sequence) + check_sig(from, sig, payload) + if sequence < from_seq then + error("sequence number too low") + end + + if value > from_balance then + error("insufficient balance") + end + + if value > 0 then + to_balance, to_seq = get_account(to) + to_balance = to_balance + value + from_balance = from_balance - value + else + to = nil + end + + from_seq = sequence + 1 + return update_accounts(from, from_balance, from_seq, to, to_balance, to_seq) + end + c = string.dump(pay_contract, true) + tot = "" + for i = 1, string.len(c) do + hex = string.format("%x", string.byte(c, i)) + if string.len(hex) < 2 then + hex = "0" .. hex + end + tot = tot .. hex + end + + return tot +end diff --git a/tests/unit/3pc/agent/runners/lua/account_test.cpp b/tests/unit/3pc/agent/runners/lua/account_test.cpp index b11c8edd4..ff5acb781 100644 --- a/tests/unit/3pc/agent/runners/lua/account_test.cpp +++ b/tests/unit/3pc/agent/runners/lua/account_test.cpp @@ -16,6 +16,7 @@ #include "util/serialization/format.hpp" #include +#include #include #include #include @@ -24,53 +25,16 @@ class account_test : public ::testing::Test { protected: void SetUp() override { m_pay_contract_key.append("pay", 3); - m_pay_contract - = cbdc::buffer::from_hex( - "1b4c7561540019930d0a1a0a04080878560000000000000000000000287" - "74001808ac4010008d48b0000058e0001060381030080010000c4000306" - "0f0004050f0003040f0002030f0001020f000001cf0000000f000801cf8" - "000000f000901cf0001000f000a01cf8001000f000b01cf0002000f000c" - "018b0000090b010000c40002030f000e020f000d018b00000c0b0100018" - "b0100020b020003c40004020f000f018b0000100b0100008b0100040b02" - "000fc40004018b0000030b01000eba000200380100808b0000110301090" - "0c40002018b0000020b01000d3a010100380100808b00001103810900c4" - "0002018b000002c0007f00b80700808b0000090b010001c40002030f001" - "5020f0014018b0000140b010002a2000102ae0002060f0014018b00000d" - "0b010002a3000102ae0002070f000d01380000800f8001168b000003950" - "00180af0080060f000e018b00000b0b0100008b01000d0b02000e8b0200" - "010b0300148b030015c5000700c6000000c700010097048566726f6d048" - "3746f048676616c7565048973657175656e636504847369670487737472" - "696e670487756e7061636b0492633332206333322049382049382063363" - "404906765745f6163636f756e745f6b6579048c6765745f6163636f756e" - "74048d7061636b5f6163636f756e7404907570646174655f6163636f756" - "e7473048c7369675f7061796c6f6164048d66726f6d5f62616c616e6365" - "048966726f6d5f73657104887061796c6f6164048a636865636b5f73696" - "704866572726f72049873657175656e6365206e756d62657220746f6f20" - "6c6f770495696e73756666696369656e742062616c616e6365048b746f5" - "f62616c616e63650487746f5f736571008100000085808d91010003880f" - "8000018b00000000010000b50002000f0002018b000002c8000200c7000" - "10083048f6163636f756e745f70726566697804896163636f756e745f04" - "8c6163636f756e745f6b657981000000808080808080939c0100049d8b0" - "0000100010000c40002020f0000018b0000038e0001040b010000c40002" - "020f0002018b0000058e0001060b010002c4000202c0007f00b80400808" - "b0000058e000109030105008b010002c40003030f0008020f0007018b00" - "00070b010008c60003008180ff7f0181ff7fc6000300c70001008b048c6" - "163636f756e745f6b657904906765745f6163636f756e745f6b6579048d" - "6163636f756e745f64617461048a636f726f7574696e6504867969656c6" - "40487737472696e6704846c656e04906163636f756e745f62616c616e63" - "6504916163636f756e745f73657175656e63650487756e7061636b04864" - "938204938810000008080808080809ea00400098b0b0200008002010044" - "0202028b0200018e020502038301008003020000040300c402040210000" - "405470201008404906765745f6163636f756e745f6b6579048773747269" - "6e6704857061636b0486493820493881000000808080808080a2a906000" - "b9413030000520000000f0000060b0300018b0300000004000080040100" - "0005020044030501bc810200b80200800b0300018b03000000040300800" - "4040000050500440305010b030000480302004703010083048472657404" - "8d7061636b5f6163636f756e740081000000808080808080abad0300088" - "98b0100008e01030103020100800200000003010080030200c5010500c6" - "010000c7010100830487737472696e6704857061636b048a63333220493" - "820493881000000808080808080808080") - .value(); + + lua_State* L = luaL_newstate(); + luaL_openlibs(L); + luaL_dofile( + L, + "../tests/unit/3pc/agent/runners/lua/gen_pay_contract.lua"); + lua_getglobal(L, "gen_bytecode"); + ASSERT_EQ(lua_pcall(L, 0, 1, 0), 0); + m_pay_contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); + cbdc::test::add_to_shard(m_broker, m_pay_contract_key, m_pay_contract); m_init_account_key.append("account_", 8); diff --git a/tests/unit/3pc/agent/runners/lua/gen_pay_contract.lua b/tests/unit/3pc/agent/runners/lua/gen_pay_contract.lua new file mode 100644 index 000000000..e135f5349 --- /dev/null +++ b/tests/unit/3pc/agent/runners/lua/gen_pay_contract.lua @@ -0,0 +1,72 @@ +function gen_bytecode() + pay_contract = function(param) + from, to, value, sequence, sig = string.unpack("c32 c32 I8 I8 c64", param) + + function get_account_key(name) + account_prefix = "account_" + account_key = account_prefix .. name + return account_key + end + + function get_account(name) + account_key = get_account_key(name) + account_data = coroutine.yield(account_key) + if string.len(account_data) > 0 then + account_balance, account_sequence + = string.unpack("I8 I8", account_data) + return account_balance, account_sequence + end + return 0, 0 + end + + function pack_account(updates, name, balance, seq) + updates[get_account_key(name)] = string.pack("I8 I8", balance, seq) + end + + function update_accounts(from_acc, from_bal, from_seq, to_acc, to_bal, to_seq) + ret = {} + pack_account(ret, from_acc, from_bal, from_seq) + if to_acc ~= nil then + pack_account(ret, to_acc, to_bal, to_seq) + end + return ret + end + + function sig_payload(to_acc, value, seq) + return string.pack("c32 I8 I8", to_acc, value, seq) + end + + from_balance, from_seq = get_account(from) + payload = sig_payload(to, value, sequence) + check_sig(from, sig, payload) + if sequence < from_seq then + error("sequence number too low") + end + + if value > from_balance then + error("insufficient balance") + end + + if value > 0 then + to_balance, to_seq = get_account(to) + to_balance = to_balance + value + from_balance = from_balance - value + else + to = nil + end + + from_seq = sequence + 1 + return update_accounts(from, from_balance, from_seq, to, to_balance, to_seq) + end + c = string.dump(pay_contract, true) + tot = "" + for i = 1, string.len(c) do + hex = string.format("%x", string.byte(c, i)) + if string.len(hex) < 2 then + hex = "0" .. hex + end + tot = tot .. hex + end + + return tot +end diff --git a/tools/bench/3pc/lua/gen_bytecode.lua b/tools/bench/3pc/lua/gen_bytecode.lua deleted file mode 100644 index d1f70b2f2..000000000 --- a/tools/bench/3pc/lua/gen_bytecode.lua +++ /dev/null @@ -1,71 +0,0 @@ -f = function (param) - from, to, value, sequence, sig = string.unpack("c32 c32 I8 I8 c64", param) - - function get_account_key(name) - account_prefix = "account_" - account_key = account_prefix .. name - return account_key - end - - function get_account(name) - account_key = get_account_key(name) - account_data = coroutine.yield(account_key) - if string.len(account_data) > 0 then - account_balance, account_sequence - = string.unpack("I8 I8", account_data) - return account_balance, account_sequence - end - return 0, 0 - end - - function pack_account(updates, name, balance, seq) - updates[get_account_key(name)] = string.pack("I8 I8", balance, seq) - end - - function update_accounts(from_acc, from_bal, from_seq, to_acc, to_bal, to_seq) - ret = {} - pack_account(ret, from_acc, from_bal, from_seq) - if to_acc ~= nil then - pack_account(ret, to_acc, to_bal, to_seq) - end - return ret - end - - function sig_payload(to_acc, value, seq) - return string.pack("c32 I8 I8", to_acc, value, seq) - end - - from_balance, from_seq = get_account(from) - payload = sig_payload(to, value, sequence) - check_sig(from, sig, payload) - if sequence < from_seq then - error("sequence number too low") - end - - if value > from_balance then - error("insufficient balance") - end - - if value > 0 then - to_balance, to_seq = get_account(to) - to_balance = to_balance + value - from_balance = from_balance - value - else - to = nil - end - - from_seq = sequence + 1 - return update_accounts(from, from_balance, from_seq, to, to_balance, to_seq) -end - -c = string.dump(f, true) -tot = "" -for i = 1, string.len(c) do - hex = string.format("%x", string.byte(c, i)) - if string.len(hex) < 2 then - hex = "0" .. hex - end - tot = tot .. hex -end - -print(tot) diff --git a/tools/bench/3pc/lua/lua_bench.cpp b/tools/bench/3pc/lua/lua_bench.cpp index 7f877c198..8ccecca00 100644 --- a/tools/bench/3pc/lua/lua_bench.cpp +++ b/tools/bench/3pc/lua/lua_bench.cpp @@ -12,6 +12,7 @@ #include "crypto/sha256.h" #include "wallet.hpp" +#include #include #include @@ -26,7 +27,7 @@ auto main(int argc, char** argv) -> int { log->error("Not enough arguments"); return 1; } - auto cfg = cbdc::threepc::read_config(argc - 1, argv); + auto cfg = cbdc::threepc::read_config(argc - 2, argv); if(!cfg.has_value()) { log->error("Error parsing options"); return 1; @@ -74,51 +75,18 @@ auto main(int argc, char** argv) -> int { directory, log); + auto contract_file = args[args.size() - 2]; auto pay_contract = cbdc::buffer(); - pay_contract - = cbdc::buffer::from_hex( - "1b4c7561540019930d0a1a0a040808785600000000000000000000002877400" - "1808ac4010008d48b0000058e0001060381030080010000c40003060f000405" - "0f0003040f0002030f0001020f000001cf0000000f000801cf8000000f00090" - "1cf0001000f000a01cf8001000f000b01cf0002000f000c018b0000090b0100" - "00c40002030f000e020f000d018b00000c0b0100018b0100020b020003c4000" - "4020f000f018b0000100b0100008b0100040b02000fc40004018b0000030b01" - "000eba000200380100808b00001103010900c40002018b0000020b01000d3a0" - "10100380100808b00001103810900c40002018b000002c0007f00b80700808b" - "0000090b010001c40002030f0015020f0014018b0000140b010002a2000102a" - "e0002060f0014018b00000d0b010002a3000102ae0002070f000d0138000080" - "0f8001168b00000395000180af0080060f000e018b00000b0b0100008b01000" - "d0b02000e8b0200010b0300148b030015c5000700c6000000c7000100970485" - "66726f6d0483746f048676616c7565048973657175656e63650484736967048" - "7737472696e670487756e7061636b0492633332206333322049382049382063" - "363404906765745f6163636f756e745f6b6579048c6765745f6163636f756e7" - "4048d7061636b5f6163636f756e7404907570646174655f6163636f756e7473" - "048c7369675f7061796c6f6164048d66726f6d5f62616c616e6365048966726" - "f6d5f73657104887061796c6f6164048a636865636b5f73696704866572726f" - "72049873657175656e6365206e756d62657220746f6f206c6f770495696e737" - "56666696369656e742062616c616e6365048b746f5f62616c616e6365048774" - "6f5f736571008100000085808d91010003880f8000018b00000000010000b50" - "002000f0002018b000002c8000200c700010083048f6163636f756e745f7072" - "6566697804896163636f756e745f048c6163636f756e745f6b6579810000008" - "08080808080939c0100049d8b00000100010000c40002020f0000018b000003" - "8e0001040b010000c40002020f0002018b0000058e0001060b010002c400020" - "2c0007f00b80400808b0000058e000109030105008b010002c40003030f0008" - "020f0007018b0000070b010008c60003008180ff7f0181ff7fc6000300c7000" - "1008b048c6163636f756e745f6b657904906765745f6163636f756e745f6b65" - "79048d6163636f756e745f64617461048a636f726f7574696e6504867969656" - "c640487737472696e6704846c656e04906163636f756e745f62616c616e6365" - "04916163636f756e745f73657175656e63650487756e7061636b04864938204" - "938810000008080808080809ea00400098b0b02000080020100440202028b02" - "00018e020502038301008003020000040300c40204021000040547020100840" - "4906765745f6163636f756e745f6b65790487737472696e6704857061636b04" - "86493820493881000000808080808080a2a906000b9413030000520000000f0" - "000060b0300018b03000000040000800401000005020044030501bc810200b8" - "0200800b0300018b030000000403008004040000050500440305010b0300004" - "803020047030100830484726574048d7061636b5f6163636f756e7400810000" - "00808080808080abad030008898b0100008e010301030201008002000000030" - "10080030200c5010500c6010000c7010100830487737472696e670485706163" - "6b048a63333220493820493881000000808080808080808080") - .value(); + lua_State* L = luaL_newstate(); + luaL_openlibs(L); + luaL_dofile(L, contract_file.c_str()); + lua_getglobal(L, "gen_bytecode"); + if(lua_pcall(L, 0, 1, 0) != 0) { + log->error("Contract bytecode generation failed, with error:", + lua_tostring(L, -1)); + return 1; + } + pay_contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); auto pay_keys = std::vector(); auto init_count = std::atomic();