JSValue create_ccf_obj()

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;
  }