Open3

XRPL Hooksでemitとcbakを同時に利用する

tequtequ

Cで記述したHookにおいてemitcbakを同時に使う場合、次のようなコードだとエラーになる。

#include "hookapi.h"

int64_t hook(uint32_t reserved) {
    _g(1, 1);
    etxn_reserve(1);
    // ...
    uint8_t tx_result[32];
    int64_t result = emit(SBUF(tx_result), tx, PREPARE_PAYMENT_SIMPLE_SIZE);
    REQUIRE(result > 0, "failed.");
    DONE("success");
    return 0;
}

int64_t cbak(uint32_t what) {
    return 0;
}
tequtequ

このエラーの原因はPREPARE_PAYMENT_SIMPLE_SIZEの値が想定される値を呼び出していないことが原因。

#include "hookapi.h"の前に一行#define HAS_CALLBACKを付け加えることで解決する。

つまり次のようなコードにすれば良い。

#define HAS_CALLBACK`
#include "hookapi.h"

int64_t hook(uint32_t reserved) {
    _g(1, 1);
    etxn_reserve(1);
    // ...
    uint8_t tx_result[32];
    int64_t result = emit(SBUF(tx_result), tx, PREPARE_PAYMENT_SIMPLE_SIZE);
    REQUIRE(result > 0, "failed.");
    DONE("success");
    return 0;
}

int64_t cbak(uint32_t what) {
    return 0;
}

この一行を付け加えることでPREPARE_PAYMENT_SIMPLE_SIZEの値が248Uから270Uに変化する。

これはhookapi.hの中で呼び出されるmacro.hの次の箇所で分かる。

#ifdef HAS_CALLBACK
#define PREPARE_PAYMENT_SIMPLE_SIZE 270U
#else
#define PREPARE_PAYMENT_SIMPLE_SIZE 248U
#endif
tequtequ

PREPARE_PAYMENT_SIMPLE_SIZEの差分はどこから生まれるのか?

それはextn_detailsが関係している。

cbakが存在している場合、extn_detailscbakがない場合と比べて追加で22バイトのデータを返す。

https://xrpl-hooks.readme.io/reference/etxn_details

cbakが存在する場合にのみEmitCallbackフィールドが存在することが確認できる。

cbakが存在する場合

https://hooks-testnet-v3-explorer.xrpl-labs.com/tx/C6C717FBC94307CCEABA3527F25A1BAA56635FB1A1ACC114E2F8BC0FC6DA4251

cbakが存在しない場合

https://hooks-testnet-v3-explorer.xrpl-labs.com/tx/41BB0281FBE0D9B1B3140F165BF4CF952A4A631A96B04F06E38236D62B484A7B