ledger_result Enum

#include <keychain/defines.hpp>

Namespace: kc

Overview

The ledger_result enum indicates the result of ledger consensus operations, specifically what action is required after processing a received consensus transaction.

Since: v3.0

Values

Value Numeric Description

no_response_needed

0

No response is required from the receiving participant

response_needed

1

A response should be sent by the receiving participant

protocol_level_rejected

2

Transaction rejected at the protocol level (invalid format, signatures, etc.)

application_level_rejected

3

Transaction rejected at the application level (business logic rejection)

Usage

#include <keychain/keychain_headers.hpp>

// Process a received consensus transaction
void handle_consensus_transaction(kc::gateway& gateway,
                                  const kc::persona& persona,
                                  kc::transaction& received_tx) {
    // Verify and process the transaction
    kc::ledger_result result = gateway.ledger_receive(persona, received_tx);

    switch (result) {
        case kc::ledger_result::no_response_needed:
            // Transaction processed successfully, no action required
            std::cout << "Transaction processed, waiting for more signatures" << std::endl;
            break;

        case kc::ledger_result::response_needed:
            // Need to send a response (approval or rejection)
            std::cout << "Response required, preparing signature..." << std::endl;

            // Check transaction state and determine approval
            bool should_approve = evaluate_transaction_for_approval(received_tx);

            // Sign the transaction with approval/rejection
            gateway.ledger_sign(persona, received_tx, should_approve);

            // Send the signed transaction back to participants
            // (application-specific networking code)
            break;

        case kc::ledger_result::protocol_level_rejected:
            // Invalid transaction format, signatures, or protocol violation
            std::cerr << "Transaction rejected: protocol violation" << std::endl;
            // Log error details and possibly alert administrators
            break;

        case kc::ledger_result::application_level_rejected:
            // Business logic rejected the transaction
            std::cout << "Transaction rejected by application logic" << std::endl;
            // The rejection is already recorded in the transaction
            break;
    }
}

// Helper function to evaluate transaction for approval
bool evaluate_transaction_for_approval(const kc::transaction& tx) {
    // Access transaction variables to make decision
    kc::tag_set variables = tx.variables();

    // Example: Check transaction amount
    if (variables.has_tag("amount")) {
        int64_t amount = variables.get_tag("amount").int64();
        if (amount > MAX_ALLOWED_AMOUNT) {
            return false; // Reject due to amount limit
        }
    }

    // Example: Check recipient authorization
    if (variables.has_tag("recipient")) {
        std::string recipient = variables.get_tag("recipient").utf8_string();
        if (!is_authorized_recipient(recipient)) {
            return false; // Reject due to unauthorized recipient
        }
    }

    return true; // Approve transaction
}

Consensus Flow Integration

// Complete consensus participant implementation
class ConsensusParticipant {
private:
    kc::gateway& gateway_;
    kc::persona persona_;
    std::vector<kc::contact> peers_;

public:
    void process_received_transaction(kc::transaction received_tx) {
        // Step 1: Verify and process transaction
        kc::ledger_result result = gateway_.ledger_receive(persona_, received_tx);

        // Step 2: Handle result
        switch (result) {
            case kc::ledger_result::response_needed:
                handle_response_needed(received_tx);
                break;

            case kc::ledger_result::no_response_needed:
                // Check if consensus stage changed
                gateway_.ledger_check_state_transition(persona_, received_tx);
                break;

            case kc::ledger_result::protocol_level_rejected:
            case kc::ledger_result::application_level_rejected:
                handle_rejection(received_tx, result);
                break;
        }
    }

private:
    void handle_response_needed(kc::transaction& tx) {
        // Evaluate transaction based on business logic
        bool approval = evaluate_business_logic(tx);

        // Add tags/variables if needed
        kc::tag_set response_tags;
        response_tags.set_tag("evaluator", "node_id",
                              kc::serialized_data(get_node_id()));
        response_tags.set_tag("evaluation", "timestamp",
                              kc::serialized_data(time(nullptr)));

        // Sign the transaction
        gateway_.ledger_sign(persona_, tx, approval, response_tags);

        // Broadcast to other participants
        broadcast_to_peers(tx);

        // Check if this completed the consensus stage
        gateway_.ledger_check_state_transition(persona_, tx);
    }

    void handle_rejection(const kc::transaction& tx, kc::ledger_result reason) {
        // Log the rejection
        std::string reason_str = (reason == kc::ledger_result::protocol_level_rejected)
                                 ? "protocol" : "application";
        std::cerr << "Transaction rejected (" << reason_str << "): "
                  << tx.base_hash() << std::endl;

        // Optionally notify other participants about the rejection
        notify_peers_of_rejection(tx, reason);
    }
};

State Machine Integration

The ledger_result values integrate with the consensus state machine:

// Consensus state tracking
void track_consensus_progress(kc::transaction& tx, kc::ledger_result result) {
    kc::consensus_stage current_stage = tx.consensus_stage();

    switch (result) {
        case kc::ledger_result::response_needed:
            std::cout << "Stage " << static_cast<int>(current_stage)
                      << ": signature required" << std::endl;
            break;

        case kc::ledger_result::no_response_needed:
            // Check if we advanced to next stage
            if (tx.is_consensus_complete()) {
                std::cout << "Consensus completed successfully!" << std::endl;
            } else {
                std::cout << "Stage " << static_cast<int>(current_stage)
                          << ": waiting for more signatures" << std::endl;
            }
            break;

        case kc::ledger_result::protocol_level_rejected:
        case kc::ledger_result::application_level_rejected:
            std::cout << "Consensus terminated due to rejection" << std::endl;
            break;
    }
}

Error Handling

// Robust error handling for ledger operations
class LedgerManager {
public:
    bool process_transaction_safely(kc::transaction& tx) {
        try {
            kc::ledger_result result = gateway_.ledger_receive(persona_, tx);

            switch (result) {
                case kc::ledger_result::response_needed:
                    return handle_response_with_validation(tx);

                case kc::ledger_result::no_response_needed:
                    gateway_.ledger_check_state_transition(persona_, tx);
                    return true;

                case kc::ledger_result::protocol_level_rejected:
                    log_protocol_error(tx);
                    return false;

                case kc::ledger_result::application_level_rejected:
                    log_application_rejection(tx);
                    return false;
            }

        } catch (const kc::exception& e) {
            std::cerr << "Ledger operation failed: " << e.what() << std::endl;
            return false;
        }

        return false;
    }

private:
    bool handle_response_with_validation(kc::transaction& tx) {
        // Validate transaction thoroughly before signing
        if (!validate_transaction_integrity(tx)) {
            return false;
        }

        if (!validate_business_rules(tx)) {
            // Sign with rejection
            gateway_.ledger_sign(persona_, tx, false);
            return true; // Successfully rejected
        }

        // Sign with approval
        gateway_.ledger_sign(persona_, tx, true);
        return true;
    }
};

See Also