in src/js/wrap.cpp [1347:1628]
JSValue create_ccf_obj(
TxContext* txctx,
TxContext* historical_txctx,
enclave::RpcContext* rpc_ctx,
const std::optional<ccf::TxID>& transaction_id,
ccf::TxReceiptPtr receipt,
ccf::AbstractNodeState* node_state,
ccf::AbstractNodeState* host_node_state,
ccf::NetworkState* network_state,
ccf::historical::AbstractStateCache* historical_state,
ccf::BaseEndpointRegistry* endpoint_registry,
js::Context& ctx)
{
auto ccf = JS_NewObject(ctx);
JS_SetPropertyStr(
ctx, ccf, "strToBuf", JS_NewCFunction(ctx, js_str_to_buf, "strToBuf", 1));
JS_SetPropertyStr(
ctx, ccf, "bufToStr", JS_NewCFunction(ctx, js_buf_to_str, "bufToStr", 1));
JS_SetPropertyStr(
ctx,
ccf,
"jsonCompatibleToBuf",
JS_NewCFunction(
ctx, js_json_compatible_to_buf, "jsonCompatibleToBuf", 1));
JS_SetPropertyStr(
ctx,
ccf,
"bufToJsonCompatible",
JS_NewCFunction(
ctx, js_buf_to_json_compatible, "bufToJsonCompatible", 1));
JS_SetPropertyStr(
ctx,
ccf,
"generateAesKey",
JS_NewCFunction(ctx, js_generate_aes_key, "generateAesKey", 1));
JS_SetPropertyStr(
ctx,
ccf,
"generateRsaKeyPair",
JS_NewCFunction(ctx, js_generate_rsa_key_pair, "generateRsaKeyPair", 1));
JS_SetPropertyStr(
ctx, ccf, "wrapKey", JS_NewCFunction(ctx, js_wrap_key, "wrapKey", 3));
JS_SetPropertyStr(
ctx, ccf, "digest", JS_NewCFunction(ctx, js_digest, "digest", 2));
JS_SetPropertyStr(
ctx,
ccf,
"isValidX509CertBundle",
JS_NewCFunction(
ctx, js_is_valid_x509_cert_bundle, "isValidX509CertBundle", 1));
JS_SetPropertyStr(
ctx,
ccf,
"isValidX509CertChain",
JS_NewCFunction(
ctx, js_is_valid_x509_cert_chain, "isValidX509CertChain", 2));
JS_SetPropertyStr(
ctx, ccf, "pemToId", JS_NewCFunction(ctx, js_pem_to_id, "pemToId", 1));
JS_SetPropertyStr(
ctx,
ccf,
"refreshAppBytecodeCache",
JS_NewCFunction(
ctx, js_refresh_app_bytecode_cache, "refreshAppBytecodeCache", 0));
auto crypto = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, ccf, "crypto", crypto);
JS_SetPropertyStr(
ctx,
crypto,
"verifySignature",
JS_NewCFunction(ctx, js_verify_signature, "verifySignature", 4));
if (txctx != nullptr)
{
auto kv = JS_NewObjectClass(ctx, kv_class_id);
JS_SetOpaque(kv, txctx);
JS_SetPropertyStr(ctx, ccf, "kv", kv);
JS_SetPropertyStr(
ctx,
ccf,
"setJwtPublicSigningKeys",
JS_NewCFunction(
ctx,
js_gov_set_jwt_public_signing_keys,
"setJwtPublicSigningKeys",
3));
JS_SetPropertyStr(
ctx,
ccf,
"removeJwtPublicSigningKeys",
JS_NewCFunction(
ctx,
js_gov_remove_jwt_public_signing_keys,
"removeJwtPublicSigningKeys",
1));
}
// Historical queries
if (receipt != nullptr)
{
CCF_ASSERT(
transaction_id.has_value(),
"Expected receipt and transaction_id to both be passed");
auto state = JS_NewObject(ctx);
JS_SetPropertyStr(
ctx,
state,
"transactionId",
JS_NewString(ctx, transaction_id->to_str().c_str()));
auto js_receipt = ccf_receipt_to_js(ctx, receipt);
JS_SetPropertyStr(ctx, state, "receipt", js_receipt);
auto kv = JS_NewObjectClass(ctx, kv_class_id);
JS_SetOpaque(kv, historical_txctx);
JS_SetPropertyStr(ctx, state, "kv", kv);
JS_SetPropertyStr(ctx, ccf, "historicalState", state);
}
// Node state
if (node_state != nullptr)
{
if (txctx == nullptr)
{
throw std::logic_error("Tx should be set to set node context");
}
auto node = JS_NewObjectClass(ctx, node_class_id);
JS_SetOpaque(node, node_state);
JS_SetPropertyStr(ctx, ccf, "node", node);
JS_SetPropertyStr(
ctx,
node,
"triggerLedgerRekey",
JS_NewCFunction(
ctx, js_node_trigger_ledger_rekey, "triggerLedgerRekey", 0));
JS_SetPropertyStr(
ctx,
node,
"transitionServiceToOpen",
JS_NewCFunction(
ctx,
js_node_transition_service_to_open,
"transitionServiceToOpen",
0));
JS_SetPropertyStr(
ctx,
node,
"triggerRecoverySharesRefresh",
JS_NewCFunction(
ctx,
js_node_trigger_recovery_shares_refresh,
"triggerRecoverySharesRefresh",
0));
}
if (host_node_state != nullptr)
{
auto host = JS_NewObjectClass(ctx, host_class_id);
JS_SetOpaque(host, host_node_state);
JS_SetPropertyStr(ctx, ccf, "host", host);
JS_SetPropertyStr(
ctx,
host,
"triggerSubprocess",
JS_NewCFunction(
ctx, js_node_trigger_host_process_launch, "triggerSubprocess", 1));
}
if (network_state != nullptr)
{
if (txctx == nullptr)
{
throw std::logic_error("Tx should be set to set network context");
}
auto network = JS_NewObjectClass(ctx, network_class_id);
JS_SetOpaque(network, network_state);
JS_SetPropertyStr(ctx, ccf, "network", network);
JS_SetPropertyStr(
ctx,
network,
"getLatestLedgerSecretSeqno",
JS_NewCFunction(
ctx,
js_network_latest_ledger_secret_seqno,
"getLatestLedgerSecretSeqno",
0));
JS_SetPropertyStr(
ctx,
network,
"generateEndorsedCertificate",
JS_NewCFunction(
ctx,
js_network_generate_endorsed_certificate,
"generateEndorsedCertificate",
0));
JS_SetPropertyStr(
ctx,
network,
"generateNetworkCertificate",
JS_NewCFunction(
ctx,
js_network_generate_certificate,
"generateNetworkCertificate",
0));
}
if (rpc_ctx != nullptr)
{
auto rpc = JS_NewObjectClass(ctx, rpc_class_id);
JS_SetOpaque(rpc, rpc_ctx);
JS_SetPropertyStr(ctx, ccf, "rpc", rpc);
JS_SetPropertyStr(
ctx,
rpc,
"setApplyWrites",
JS_NewCFunction(ctx, js_rpc_set_apply_writes, "setApplyWrites", 1));
JS_SetPropertyStr(
ctx,
rpc,
"setClaimsDigest",
JS_NewCFunction(ctx, js_rpc_set_claims_digest, "setClaimsDigest", 1));
}
// All high-level public helper functions are exposed through
// ccf::BaseEndpointRegistry. Ideally, they should be
// exposed separately.
if (endpoint_registry != nullptr)
{
auto consensus = JS_NewObjectClass(ctx, consensus_class_id);
JS_SetOpaque(consensus, endpoint_registry);
JS_SetPropertyStr(ctx, ccf, "consensus", consensus);
JS_SetPropertyStr(
ctx,
consensus,
"getLastCommittedTxId",
JS_NewCFunction(
ctx,
js_consensus_get_last_committed_txid,
"getLastCommittedTxId",
0));
JS_SetPropertyStr(
ctx,
consensus,
"getStatusForTxId",
JS_NewCFunction(
ctx, js_consensus_get_status_for_txid, "getStatusForTxId", 2));
JS_SetPropertyStr(
ctx,
consensus,
"getViewForSeqno",
JS_NewCFunction(
ctx, js_consensus_get_view_for_seqno, "getViewForSeqno", 1));
}
if (historical_state != nullptr)
{
auto historical = JS_NewObjectClass(ctx, historical_class_id);
JS_SetOpaque(historical, historical_state);
JS_SetPropertyStr(ctx, ccf, "historical", historical);
JS_SetPropertyStr(
ctx,
historical,
"getStateRange",
JS_NewCFunction(
ctx, js_historical_get_state_range, "getStateRange", 4));
JS_SetPropertyStr(
ctx,
historical,
"dropCachedStates",
JS_NewCFunction(
ctx, js_historical_drop_cached_states, "dropCachedStates", 1));
}
return ccf;
}