Skip to content

Commit d0330b3

Browse files
committed
Add host-functions cost for wasmi
1 parent 9285cb7 commit d0330b3

File tree

10 files changed

+378
-171
lines changed

10 files changed

+378
-171
lines changed

src/test/app/EscrowSmart_test.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ struct EscrowSmart_test : public beast::unit_test::suite
390390
// Tests whether the ledger index is >= 5
391391
// getLedgerSqn() >= 5}
392392
auto const& wasmHex = ledgerSqnWasmHex;
393-
std::uint32_t const allowance = 5;
393+
std::uint32_t const allowance = 65;
394394
auto escrowCreate = escrow::create(alice, carol, XRP(1000));
395395
auto [createFee, finishFee] = [&]() {
396396
Env env(*this, features);
@@ -683,7 +683,7 @@ struct EscrowSmart_test : public beast::unit_test::suite
683683
{
684684
env.require(balance(alice, XRP(4000) - txnFees));
685685

686-
auto const allowance = 14;
686+
auto const allowance = 1014;
687687
XRPAmount const finishFee = env.current()->fees().base +
688688
(allowance * env.current()->fees().gasPrice) /
689689
MICRO_DROPS_PER_DROP +
@@ -778,7 +778,7 @@ struct EscrowSmart_test : public beast::unit_test::suite
778778
auto const txMeta = env.meta();
779779
if (BEAST_EXPECT(txMeta && txMeta->isFieldPresent(sfGasUsed)))
780780
BEAST_EXPECTS(
781-
txMeta->getFieldU32(sfGasUsed) == 794,
781+
txMeta->getFieldU32(sfGasUsed) == 38'554,
782782
std::to_string(txMeta->getFieldU32(sfGasUsed)));
783783
if (BEAST_EXPECT(txMeta->isFieldPresent(sfWasmReturnCode)))
784784
BEAST_EXPECT(txMeta->getFieldI32(sfWasmReturnCode) == 1);
@@ -863,7 +863,11 @@ struct EscrowSmart_test : public beast::unit_test::suite
863863
env.close();
864864
env.close();
865865

866-
auto const allowance = 2'985;
866+
BEAST_EXPECTS(
867+
env.ownerCount(alice) == 34,
868+
std::to_string(env.ownerCount(alice)));
869+
870+
auto const allowance = 138'485;
867871
auto const finishFee = env.current()->fees().base +
868872
(allowance * env.current()->fees().gasPrice) /
869873
MICRO_DROPS_PER_DROP +

src/test/app/Wasm_test.cpp

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct Wasm_test : public beast::unit_test::suite
6767
// clang-format on
6868
auto& vm = WasmEngine::instance();
6969

70-
std::vector<WasmImportFunc> imports;
70+
ImportVec imports;
7171
WasmImpFunc<Add_proto>(
7272
imports, "func-add", reinterpret_cast<void*>(&Add));
7373

@@ -98,7 +98,7 @@ struct Wasm_test : public beast::unit_test::suite
9898
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
9999
std::string funcName("mock_escrow");
100100

101-
auto re = runEscrowWasm(wasm, funcName, {}, &hfs, 15, env.journal);
101+
auto re = runEscrowWasm(wasm, hfs, funcName, {}, 15);
102102
BEAST_EXPECT(!re);
103103
}
104104

@@ -108,8 +108,7 @@ struct Wasm_test : public beast::unit_test::suite
108108
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
109109
std::string funcName("mock_escrow");
110110

111-
auto const re =
112-
preflightEscrowWasm(wasm, funcName, {}, &hfs, env.journal);
111+
auto const re = preflightEscrowWasm(wasm, hfs, funcName);
113112
BEAST_EXPECT(!isTesSuccess(re));
114113
}
115114

@@ -132,8 +131,8 @@ struct Wasm_test : public beast::unit_test::suite
132131
auto wasmStr = boost::algorithm::unhex(std::string(badWasmHex));
133132
std::vector<uint8_t> wasm(wasmStr.begin(), wasmStr.end());
134133

135-
auto const re = preflightEscrowWasm(
136-
wasm, ESCROW_FUNCTION_NAME, {}, &hfs, env.journal);
134+
auto const re =
135+
preflightEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME);
137136
BEAST_EXPECT(!isTesSuccess(re));
138137
}
139138
}
@@ -151,7 +150,7 @@ struct Wasm_test : public beast::unit_test::suite
151150
Env env{*this};
152151
TestLedgerDataProvider hf(&env);
153152

154-
std::vector<WasmImportFunc> imports;
153+
ImportVec imports;
155154
WASM_IMPORT_FUNC2(imports, getLedgerSqn, "get_ledger_sqn", &hf, 33);
156155
auto& engine = WasmEngine::instance();
157156

@@ -164,11 +163,10 @@ struct Wasm_test : public beast::unit_test::suite
164163
1'000'000,
165164
env.journal);
166165

167-
// code takes 11 gas + 1 getLedgerSqn call
168166
if (BEAST_EXPECT(re.has_value()))
169167
{
170168
BEAST_EXPECTS(re->result == 0, std::to_string(re->result));
171-
BEAST_EXPECTS(re->cost == 5, std::to_string(re->cost));
169+
BEAST_EXPECTS(re->cost == 38, std::to_string(re->cost));
172170
}
173171

174172
env.close();
@@ -178,11 +176,10 @@ struct Wasm_test : public beast::unit_test::suite
178176
re = engine.run(
179177
{}, ESCROW_FUNCTION_NAME, {}, imports, &hf, 1'000'000, env.journal);
180178

181-
// code takes 22 gas + 2 getLedgerSqn calls
182179
if (BEAST_EXPECT(re.has_value()))
183180
{
184181
BEAST_EXPECTS(re->result == 5, std::to_string(re->result));
185-
BEAST_EXPECTS(re->cost == 10, std::to_string(re->cost));
182+
BEAST_EXPECTS(re->cost == 76, std::to_string(re->cost));
186183
}
187184
}
188185

@@ -299,9 +296,9 @@ struct Wasm_test : public beast::unit_test::suite
299296
auto& engine = WasmEngine::instance();
300297

301298
TestHostFunctions hfs(env, 0);
302-
std::vector<WasmImportFunc> imp = createWasmImport(&hfs);
299+
ImportVec imp = createWasmImport(hfs);
303300
for (auto& i : imp)
304-
i.gas = 0;
301+
i.second.gas = 0;
305302

306303
auto re = engine.run(
307304
wasm,
@@ -335,7 +332,7 @@ struct Wasm_test : public beast::unit_test::suite
335332
auto& engine = WasmEngine::instance();
336333

337334
TestHostFunctions hfs(env, 0);
338-
std::vector<WasmImportFunc> const imp = createWasmImport(&hfs);
335+
ImportVec const imp = createWasmImport(hfs);
339336

340337
auto re = engine.run(
341338
wasm,
@@ -349,7 +346,7 @@ struct Wasm_test : public beast::unit_test::suite
349346
if (BEAST_EXPECT(re.has_value()))
350347
{
351348
BEAST_EXPECTS(re->result == 1, std::to_string(re->result));
352-
BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost));
349+
BEAST_EXPECTS(re->cost == 40'102, std::to_string(re->cost));
353350
}
354351

355352
env.close();
@@ -370,11 +367,11 @@ struct Wasm_test : public beast::unit_test::suite
370367
{
371368
TestHostFunctions nfs(env, 0);
372369
auto re =
373-
runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000);
370+
runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000);
374371
if (BEAST_EXPECT(re.has_value()))
375372
{
376373
BEAST_EXPECTS(re->result == 1, std::to_string(re->result));
377-
BEAST_EXPECTS(re->cost == 842, std::to_string(re->cost));
374+
BEAST_EXPECTS(re->cost == 40'102, std::to_string(re->cost));
378375
}
379376
}
380377

@@ -392,11 +389,11 @@ struct Wasm_test : public beast::unit_test::suite
392389
};
393390
BadTestHostFunctions nfs(env);
394391
auto re =
395-
runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000);
392+
runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000);
396393
if (BEAST_EXPECT(re.has_value()))
397394
{
398395
BEAST_EXPECTS(re->result == -201, std::to_string(re->result));
399-
BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost));
396+
BEAST_EXPECTS(re->cost == 5'012, std::to_string(re->cost));
400397
}
401398
}
402399

@@ -414,11 +411,11 @@ struct Wasm_test : public beast::unit_test::suite
414411
};
415412
BadTestHostFunctions nfs(env);
416413
auto re =
417-
runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs, 100'000);
414+
runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME, {}, 100'000);
418415
if (BEAST_EXPECT(re.has_value()))
419416
{
420417
BEAST_EXPECTS(re->result == -201, std::to_string(re->result));
421-
BEAST_EXPECTS(re->cost == 262, std::to_string(re->cost));
418+
BEAST_EXPECTS(re->cost == 5'012, std::to_string(re->cost));
422419
}
423420
}
424421

@@ -429,7 +426,7 @@ struct Wasm_test : public beast::unit_test::suite
429426

430427
TestHostFunctionsSink nfs(env);
431428
std::string funcName("recursive");
432-
auto re = runEscrowWasm(wasm, funcName, {}, &nfs, 1'000'000'000);
429+
auto re = runEscrowWasm(wasm, nfs, funcName, {}, 1'000'000'000);
433430
BEAST_EXPECT(!re && re.error());
434431
// std::cout << "bad case (deep recursion) result " << re.error()
435432
// << std::endl;
@@ -458,7 +455,7 @@ struct Wasm_test : public beast::unit_test::suite
458455
Bytes wasm(wasmStr.begin(), wasmStr.end());
459456
TestLedgerDataProvider ledgerDataProvider(&env);
460457

461-
std::vector<WasmImportFunc> imports;
458+
ImportVec imports;
462459
WASM_IMPORT_FUNC2(
463460
imports, getLedgerSqn, "get_ledger_sqn2", &ledgerDataProvider);
464461

@@ -469,7 +466,7 @@ struct Wasm_test : public beast::unit_test::suite
469466
ESCROW_FUNCTION_NAME,
470467
{},
471468
imports,
472-
nullptr,
469+
&ledgerDataProvider,
473470
1'000'000,
474471
env.journal);
475472

@@ -494,11 +491,11 @@ struct Wasm_test : public beast::unit_test::suite
494491
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
495492

496493
TestHostFunctions hf(env, 0);
497-
auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000);
494+
auto re = runEscrowWasm(wasm, hf, funcName, {}, 100'000);
498495
if (BEAST_EXPECT(re.has_value()))
499496
{
500497
BEAST_EXPECTS(re->result == 1, std::to_string(re->result));
501-
BEAST_EXPECTS(re->cost == 326, std::to_string(re->cost));
498+
BEAST_EXPECTS(re->cost == 97'356, std::to_string(re->cost));
502499
}
503500
env.close();
504501
}
@@ -509,11 +506,11 @@ struct Wasm_test : public beast::unit_test::suite
509506
std::vector<uint8_t> const wasm(wasmStr.begin(), wasmStr.end());
510507

511508
TestHostFunctions hf(env, 0);
512-
auto re = runEscrowWasm(wasm, funcName, {}, &hf, 100'000);
509+
auto re = runEscrowWasm(wasm, hf, funcName, {}, 100'000);
513510
if (BEAST_EXPECT(re.has_value()))
514511
{
515512
BEAST_EXPECTS(re->result == 1, std::to_string(re->result));
516-
BEAST_EXPECTS(re->cost == 34, std::to_string(re->cost));
513+
BEAST_EXPECTS(re->cost == 2'054, std::to_string(re->cost));
517514
}
518515
env.close();
519516
}
@@ -597,7 +594,7 @@ struct Wasm_test : public beast::unit_test::suite
597594

598595
PerfHostFunctions nfs(env, k, env.tx());
599596

600-
auto re = runEscrowWasm(wasm, ESCROW_FUNCTION_NAME, {}, &nfs);
597+
auto re = runEscrowWasm(wasm, nfs, ESCROW_FUNCTION_NAME);
601598
if (BEAST_EXPECT(re.has_value()))
602599
{
603600
BEAST_EXPECT(re->result);
@@ -627,9 +624,8 @@ struct Wasm_test : public beast::unit_test::suite
627624
Bytes const wasm(wasmStr.begin(), wasmStr.end());
628625
TestHostFunctions hfs(env, 0);
629626

630-
auto const allowance = 1'814;
631-
auto re = runEscrowWasm(
632-
wasm, ESCROW_FUNCTION_NAME, {}, &hfs, allowance, env.journal);
627+
auto const allowance = 153'534;
628+
auto re = runEscrowWasm(wasm, hfs, ESCROW_FUNCTION_NAME, {}, allowance);
633629

634630
if (BEAST_EXPECT(re.has_value()))
635631
{
@@ -653,8 +649,7 @@ struct Wasm_test : public beast::unit_test::suite
653649

654650
{
655651
// f32 set constant, opcode disabled exception
656-
auto const re =
657-
runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal);
652+
auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000);
658653
if (BEAST_EXPECT(!re.has_value()))
659654
{
660655
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);
@@ -664,8 +659,7 @@ struct Wasm_test : public beast::unit_test::suite
664659
{
665660
// f32 add, can't create module exception
666661
wasm[0x117] = 0x92;
667-
auto const re =
668-
runEscrowWasm(wasm, funcName, {}, &hfs, 1'000'000, env.journal);
662+
auto const re = runEscrowWasm(wasm, hfs, funcName, {}, 1'000'000);
669663
if (BEAST_EXPECT(!re.has_value()))
670664
{
671665
BEAST_EXPECT(re.error() == tecFAILED_PROCESSING);

src/xrpld/app/tx/detail/Escrow.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,7 @@ EscrowCreate::preflight(PreflightContext const& ctx)
224224
}
225225

226226
HostFunctions mock;
227-
auto const re =
228-
preflightEscrowWasm(code, ESCROW_FUNCTION_NAME, {}, &mock, ctx.j);
227+
auto const re = preflightEscrowWasm(code, mock, ESCROW_FUNCTION_NAME);
229228
if (!isTesSuccess(re))
230229
{
231230
JLOG(ctx.j.debug()) << "EscrowCreate.FinishFunction bad WASM";
@@ -1220,7 +1219,7 @@ EscrowFinish::doApply()
12201219
}
12211220
std::uint32_t allowance = ctx_.tx[sfComputationAllowance];
12221221
auto re = runEscrowWasm(
1223-
wasm, ESCROW_FUNCTION_NAME, {}, &ledgerDataProvider, allowance);
1222+
wasm, ledgerDataProvider, ESCROW_FUNCTION_NAME, {}, allowance);
12241223
JLOG(j_.trace()) << "Escrow WASM ran";
12251224

12261225
if (auto const& data = ledgerDataProvider.getData(); data.has_value())

src/xrpld/app/wasm/HostFunc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ enum class HostFunctionError : int32_t {
3434
INDEX_OUT_OF_BOUNDS = -18,
3535
FLOAT_INPUT_MALFORMED = -19,
3636
FLOAT_COMPUTATION_ERROR = -20,
37+
NO_RUNTIME = -21,
38+
OUT_OF_GAS = -22,
3739
};
3840

3941
inline int32_t
@@ -92,6 +94,18 @@ struct HostFunctions
9294
return nullptr;
9395
}
9496

97+
std::int64_t
98+
getGas()
99+
{
100+
return -1;
101+
}
102+
103+
void
104+
setGas(std::int64_t)
105+
{
106+
return;
107+
}
108+
95109
virtual beast::Journal
96110
getJournal()
97111
{

src/xrpld/app/wasm/ParamsHelper.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ struct WasmImportFunc
4141
std::string name;
4242
std::optional<WasmTypes> result;
4343
std::vector<WasmTypes> params;
44-
void* udata = nullptr;
44+
// void* udata = nullptr;
4545
// wasm_func_callback_with_env_t
4646
void* wrap = nullptr;
4747
uint32_t gas = 0;
4848
};
4949

50+
typedef std::pair<void*, WasmImportFunc> WasmUserData;
51+
typedef std::vector<WasmUserData> ImportVec;
52+
5053
#define WASM_IMPORT_FUNC(v, f, ...) \
5154
WasmImpFunc<f##_proto>( \
5255
v, #f, reinterpret_cast<void*>(&f##_wrap), ##__VA_ARGS__)
@@ -111,19 +114,18 @@ WasmImpFuncHelper(WasmImportFunc& e)
111114
template <typename F>
112115
void
113116
WasmImpFunc(
114-
std::vector<WasmImportFunc>& v,
117+
ImportVec& v,
115118
std::string_view imp_name,
116119
void* f_wrap,
117120
void* data = nullptr,
118121
uint32_t gas = 0)
119122
{
120123
WasmImportFunc e;
121124
e.name = imp_name;
122-
e.udata = data;
123125
e.wrap = f_wrap;
124126
e.gas = gas;
125127
WasmImpFuncHelper<F>(e);
126-
v.push_back(std::move(e));
128+
v.push_back(std::make_pair(data, std::move(e)));
127129
}
128130

129131
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)