### Run Pingback Example (Shell) Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Starts the pingback example, demonstrating a multi-node consensus network. It requires arguments for binding address, secret key, and peer public keys. ```shell make run-pingback ARGS="-B 127.0.0.1:8001 -K -P 127.0.0.1:8002 -P 127.0.0.1:8003" ``` -------------------------------- ### Build Tashi Vertex Examples (Shell) Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Compiles all example programs included in the Tashi Vertex project. This command is typically run from the 'examples' directory. ```shell cd examples make ``` -------------------------------- ### Configure Peer Network with TVPeers Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Demonstrates how to initialize a peer set and register participants with specific network addresses, public keys, and capability flags. This setup is required before starting the consensus engine. ```c #include int setup_peer_network(const char* peer1_addr, const TVKeyPublic* peer1_key, const char* peer2_addr, const TVKeyPublic* peer2_key, const char* self_addr, const TVKeyPublic* self_key) { TVPeers* peers = NULL; TVResult result = tv_peers_new(3, &peers); if (result != TV_OK) { printf("Failed to create peer set: %d\n", result); return -1; } result = tv_peers_insert(peers, peer1_addr, peer1_key, 0); if (result != TV_OK) { printf("Failed to add peer1: %d\n", result); tv_free(peers); return -1; } result = tv_peers_insert(peers, peer2_addr, peer2_key, TV_PEER_PUBLIC); if (result != TV_OK) { printf("Failed to add peer2: %d\n", result); tv_free(peers); return -1; } result = tv_peers_insert(peers, self_addr, self_key, 0); if (result != TV_OK) { printf("Failed to add self: %d\n", result); tv_free(peers); return -1; } printf("Configured network for 3 peers\n"); return 0; } ``` -------------------------------- ### Run Key Generation Example (Shell) Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Executes the key generation example, which is used to create cryptographic keypairs for Tashi Vertex nodes. This command should be run multiple times to generate keys for different nodes. ```shell make run-key-generate # run 3 times, save each secret/public key ``` -------------------------------- ### Start Consensus Engine - C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Illustrates how to start the Tashi Vertex consensus engine (`TVEngine`). This process involves setting up engine options, providing cryptographic keys, and peer information. Ownership of the socket, options, and peers is transferred to the engine upon successful startup. ```c #include #include TVContext* context = NULL; TVEngine* engine = NULL; TVPeers* peers = NULL; TVKeySecret secret; void on_socket_bound(TVResult result, TVSocket* socket, void* user_data) { if (result != TV_OK) { printf("Socket bind failed: %d\n", result); return; } // Configure engine options TVOptions* options = NULL; tv_options_new(&options); tv_options_set_report_gossip_events(options, true); tv_options_set_fallen_behind_kick_s(options, 10); // Start the consensus engine // Ownership of socket, options, and peers is transferred to engine // These pointers will be zeroed after this call result = tv_engine_start(context, &socket, &options, &secret, &peers, &engine); if (result != TV_OK) { printf("Failed to start engine: %d\n", result); return; } printf("Consensus engine started\n"); // socket, options, peers are now NULL - do not use them } int main() { // Generate key for this node tv_key_secret_generate(&secret); // Setup peers (in real app, parse from config/args) tv_peers_new(3, &peers); TVKeyPublic public; tv_key_secret_to_public(&secret, &public); tv_peers_insert(peers, "127.0.0.1:9000", &public, 0); // Initialize context and bind socket tv_context_new(&context); tv_socket_bind(context, "127.0.0.1:9000", on_socket_bound, NULL); // Block until completion tv_free(context); return 0; } ``` -------------------------------- ### Run Minimal Consensus Network (C) Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Sets up and runs a minimal Tashi Vertex consensus network. It binds a local socket, starts the consensus engine, sends a 'hello' transaction, and begins receiving network messages. ```c #include #include #include TVContext* context = NULL; TVEngine* engine = NULL; void handle_message_recv(TVResult result, TVMessage message, void* data, void* user_data) { switch (message) { case TV_MESSAGE_NONE: return; // shutting down case TV_MESSAGE_EVENT: { TVEvent* event = (TVEvent*)data; size_t transactions = 0; tv_event_get_transaction_count(event, &transactions); if (transactions != 0) { printf(" > Received EVENT with %zu transaction(s)\n", transactions); } tv_free(event); break; } case TV_MESSAGE_SYNC_POINT: { TVSyncPoint* sync_point = (TVSyncPoint*)data; tv_free(sync_point); printf(" > Received SYNC POINT\n"); break; } } // listen for the next message tv_message_recv(engine, handle_message_recv, NULL); } void handle_socket_bound(TVResult result, TVSocket* socket, void* user_data) { TVOptions* options = NULL; tv_options_new(&options); TVKeySecret secret = /* ... */; TVPeers* peers = /* ... */; // start the consensus engine // ownership of socket, options, and peers is transferred to the engine tv_engine_start(context, &socket, &options, &secret, &peers, &engine); // send a transaction uint8_t* buffer = NULL; size_t size = 5; tv_transaction_allocate(size, &buffer); memcpy(buffer, "hello", size); tv_transaction_send(engine, buffer, size); // start receiving messages tv_message_recv(engine, handle_message_recv, NULL); } int main() { tv_context_new(&context); tv_socket_bind(context, "127.0.0.1:9000", handle_socket_bound, NULL); // blocks until all async operations complete tv_free(context); return 0; } ``` -------------------------------- ### Example Function with Tashi Vertex Error Handling in C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Demonstrates how to use the TV_CHECK macro for error handling within a Tashi Vertex C function. This example shows the pattern of initializing context, generating keys, and performing operations while ensuring that any errors are caught and returned. It includes cleanup of allocated resources. ```c TVResult example_with_error_handling() { TVContext* ctx = NULL; TV_CHECK(tv_context_new(&ctx)); TVKeySecret secret; TV_CHECK(tv_key_secret_generate(&secret)); // ... more operations ... tv_free(ctx); return TV_OK; } ``` -------------------------------- ### Integrate Tashi Vertex with CMake Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Demonstrates how to use CMake's FetchContent to download and link the Tashi Vertex library. It handles platform-specific library paths for Windows, macOS, and Linux. ```cmake include(FetchContent) set(TASHI_VERTEX_VERSION "0.12.0") set(TASHI_VERTEX_URL "https://github.com/tashigg/tashi-vertex-c/releases/download/v${TASHI_VERTEX_VERSION}/tashi-vertex-${TASHI_VERTEX_VERSION}.zip") FetchContent_Declare( TASHI_VERTEX URL ${TASHI_VERTEX_URL} DOWNLOAD_EXTRACT_TIMESTAMP TRUE ) FetchContent_MakeAvailable(TASHI_VERTEX) # Create an imported library target add_library(TASHI_VERTEX SHARED IMPORTED GLOBAL) set(TASHI_VERTEX_LIB_DIR "${tashi_vertex_SOURCE_DIR}/lib") if(WIN32) set_target_properties(TASHI_VERTEX PROPERTIES IMPORTED_LOCATION "${TASHI_VERTEX_LIB_DIR}/tashi-vertex.dll") elseif(APPLE) set_target_properties(TASHI_VERTEX PROPERTIES IMPORTED_LOCATION "${TASHI_VERTEX_LIB_DIR}/libtashi-vertex.dylib") else() set_target_properties(TASHI_VERTEX PROPERTIES IMPORTED_LOCATION "${TASHI_VERTEX_LIB_DIR}/libtashi-vertex.so") endif() ``` ```cmake target_include_directories(my_app PRIVATE "${tashi_vertex_SOURCE_DIR}/include") target_link_libraries(my_app PRIVATE TASHI_VERTEX) ``` -------------------------------- ### Initialize and Free Tashi Vertex Context (C) Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Demonstrates the initialization of the main runtime context (`TVContext`) required for Tashi Vertex operations and its subsequent release. The `tv_context_new()` function creates the context, and `tv_free()` blocks until all asynchronous operations are completed before releasing resources. ```c #include int main() { TVContext* context = NULL; // Initialize a new runtime context TVResult result = tv_context_new(&context); if (result != TV_OK) { printf("Failed to create context: %d\n", result); return 1; } // ... perform async operations ... // Release context - blocks until all operations complete tv_free(context); return 0; } ``` -------------------------------- ### Implement Consensus Node with Tashi Vertex C SDK Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Demonstrates the lifecycle of a consensus node, including network configuration, socket binding, transaction submission, and event processing. It utilizes the Tashi Vertex engine to manage peer communication and consensus-ordered events. ```c #include #include #include #include TVContext* context = NULL; TVEngine* engine = NULL; TVPeers* peers = NULL; TVKeySecret secret; void on_message(TVResult result, TVMessage message, void* data, void* user_data) { if (result != TV_OK) { printf("Error receiving message: %d\n", result); return; } switch (message) { case TV_MESSAGE_NONE: return; // Shutdown case TV_MESSAGE_EVENT: { TVEvent* event = (TVEvent*)data; size_t tx_count = 0; tv_event_get_transaction_count(event, &tx_count); if (tx_count > 0) { printf(" > Received EVENT with %zu transaction(s)\n", tx_count); for (size_t i = 0; i < tx_count; i++) { uint8_t* tx_data; size_t tx_size; tv_event_get_transaction(event, i, &tx_data, &tx_size); printf(" Transaction %zu: %.*s\n", i, (int)tx_size, tx_data); } } tv_free(event); break; } case TV_MESSAGE_SYNC_POINT: { TVSyncPoint* sync_point = (TVSyncPoint*)data; printf(" > Received SYNC POINT\n"); tv_free(sync_point); break; } } tv_message_recv(engine, on_message, NULL); } void on_socket_bound(TVResult result, TVSocket* socket, void* user_data) { if (result != TV_OK) { printf("Socket bind failed: %d\n", result); exit(1); } printf(" :: Bound local socket\n"); TVOptions* options = NULL; tv_options_new(&options); tv_options_set_report_gossip_events(options, true); tv_options_set_fallen_behind_kick_s(options, 10); result = tv_engine_start(context, &socket, &options, &secret, &peers, &engine); if (result != TV_OK) { printf("Engine start failed: %d\n", result); exit(1); } printf(" :: Started the consensus engine\n"); uint8_t* buffer = NULL; const char* msg = "PING"; size_t size = strlen(msg); tv_transaction_allocate(size, &buffer); memcpy(buffer, msg, size); tv_transaction_send(engine, buffer, size); printf(" :: Sent PING transaction\n"); tv_message_recv(engine, on_message, NULL); } int main(int argc, char** argv) { const char* bind_address = "127.0.0.1:9000"; tv_peers_new(3, &peers); tv_key_secret_generate(&secret); TVKeyPublic public; tv_key_secret_to_public(&secret, &public); tv_peers_insert(peers, bind_address, &public, 0); printf(" :: Configured network\n"); tv_context_new(&context); printf(" :: Initialized runtime\n"); tv_socket_bind(context, bind_address, on_socket_bound, NULL); tv_free(context); return 0; } ``` -------------------------------- ### Tune Consensus Engine Options Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Shows how to customize engine behavior using the TVOptions structure, including heartbeat intervals, latency thresholds, and network features like NAT hole punching. ```c #include TVOptions* configure_engine_options() { TVOptions* options = NULL; TVResult result = tv_options_new(&options); if (result != TV_OK) { return NULL; } tv_options_set_heartbeat_us(options, 500000); tv_options_set_base_min_event_interval_us(options, 10000); tv_options_set_report_gossip_events(options, true); tv_options_set_fallen_behind_kick_s(options, 10); tv_options_set_target_ack_latency_ms(options, 400); tv_options_set_max_ack_latency_ms(options, 600); tv_options_set_throttle_ack_latency_ms(options, 900); tv_options_set_reset_ack_latency_ms(options, 2000); tv_options_set_enable_dynamic_epoch_size(options, true); tv_options_set_transaction_channel_size(options, 64); tv_options_set_max_unacknowledged_bytes(options, 500 * 1024 * 1024); tv_options_set_enable_hole_punching(options, true); tv_options_set_enable_state_sharing(options, false); tv_options_set_epoch_states_to_cache(options, 3); return options; } ``` -------------------------------- ### Parse Ed25519 Keys from Base58 (C) Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Illustrates how to decode Base58 encoded strings back into DER format and then parse them into `TVKeySecret` and `TVKeyPublic` structures. This functionality is crucial for loading existing keys for use within the Tashi Vertex consensus engine. ```c #include #include #include void parse_secret_key(const char* secret_b58) { TVKeySecret secret; TVKeyPublic public; // Decode Base58 to DER format uint8_t secret_der[TV_KEY_SECRET_DER_LENGTH]; size_t secret_der_len = TV_KEY_SECRET_DER_LENGTH; TVResult result = tv_base58_decode(secret_b58, strlen(secret_b58), secret_der, &secret_der_len); if (result != TV_OK) { printf("Failed to decode Base58: %d\n", result); return; } // Parse DER into secret key structure result = tv_key_secret_from_der(secret_der, secret_der_len, &secret); if (result != TV_OK) { printf("Failed to parse secret key: %d\n", result); return; } // Derive public key from secret tv_key_secret_to_public(&secret, &public); printf("Successfully parsed secret key and derived public key\n"); } void parse_public_key(const char* public_b58) { TVKeyPublic public; // Decode Base58 to DER format uint8_t public_der[TV_KEY_PUBLIC_DER_LENGTH]; size_t public_der_len = TV_KEY_PUBLIC_DER_LENGTH; TVResult result = tv_base58_decode(public_b58, strlen(public_b58), public_der, &public_der_len); if (result != TV_OK) { printf("Failed to decode Base58: %d\n", result); return; } // Parse DER into public key structure result = tv_key_public_from_der(public_der, public_der_len, &public); if (result != TV_OK) { printf("Failed to parse public key: %d\n", result); return; } printf("Successfully parsed public key\n"); } ``` -------------------------------- ### Bind Network Socket Asynchronously - C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Demonstrates how to bind a network socket asynchronously using the TVSocket API. It uses a callback function `on_socket_bound` to handle the result of the binding operation. The binding address is specified as an IP address and port, and DNS lookup is not performed. ```c #include #include TVContext* context = NULL; void on_socket_bound(TVResult result, TVSocket* socket, void* user_data) { if (result != TV_OK) { printf("Failed to bind socket: %d\n", result); return; } printf("Socket bound successfully\n"); // Socket is now ready - proceed with engine startup // Ownership of socket will transfer to engine via tv_engine_start() } int main() { tv_context_new(&context); // Bind socket to local address (IPv4 or IPv6 with port) // DNS lookup is NOT performed - must be a valid IP address const char* bind_address = "127.0.0.1:9000"; TVResult result = tv_socket_bind(context, bind_address, on_socket_bound, NULL); if (result != TV_OK) { printf("Failed to initiate socket bind: %d\n", result); tv_free(context); return 1; } // Block until all async operations complete tv_free(context); return 0; } ``` -------------------------------- ### Generate and Serialize Ed25519 Keys (C) Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Shows how to generate a new Ed25519 secret key, derive the corresponding public key, and then serialize both keys into DER format and encode them into Base58 strings for easier handling and storage. This is essential for transaction signing and identity management within the Tashi Vertex network. ```c #include #include #include int main() { // Generate a new secret key TVKeySecret secret; tv_key_secret_generate(&secret); // Derive the corresponding public key TVKeyPublic public; tv_key_secret_to_public(&secret, &public); // Serialize secret key to DER format uint8_t secret_der[TV_KEY_SECRET_DER_LENGTH]; tv_key_secret_to_der(&secret, secret_der, TV_KEY_SECRET_DER_LENGTH); // Encode to Base58 for display/storage size_t b58_len = tv_base58_encode_length(TV_KEY_SECRET_DER_LENGTH) + 1; char secret_b58[b58_len]; tv_base58_encode(secret_der, TV_KEY_SECRET_DER_LENGTH, secret_b58, &b58_len); secret_b58[b58_len] = '\0'; printf("Secret Key (Base58): %s\n", secret_b58); // Serialize public key to DER and Base58 uint8_t public_der[TV_KEY_PUBLIC_DER_LENGTH]; tv_key_public_to_der(&public, public_der, TV_KEY_PUBLIC_DER_LENGTH); size_t pub_b58_len = tv_base58_encode_length(TV_KEY_PUBLIC_DER_LENGTH) + 1; char public_b58[pub_b58_len]; tv_base58_encode(public_der, TV_KEY_PUBLIC_DER_LENGTH, public_b58, &pub_b58_len); public_b58[pub_b58_len] = '\0'; printf("Public Key (Base58): %s\n", public_b58); return 0; } ``` -------------------------------- ### Encode and Decode Base58 Data in C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Provides utility functions to convert binary data into Base58 encoded strings and back. This is essential for creating human-readable representations of cryptographic keys and transaction data. ```c #include #include #include void base58_example() { uint8_t data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05}; size_t data_len = sizeof(data); size_t encoded_max_len = tv_base58_encode_length(data_len) + 1; char encoded[encoded_max_len]; size_t encoded_len = encoded_max_len; TVResult result = tv_base58_encode(data, data_len, encoded, &encoded_len); if (result == TV_OK) { encoded[encoded_len] = '\0'; printf("Encoded: %s\n", encoded); } size_t decoded_max_len = tv_base58_decode_length(encoded_len); uint8_t decoded[decoded_max_len]; size_t decoded_len = decoded_max_len; result = tv_base58_decode(encoded, encoded_len, decoded, &decoded_len); if (result == TV_OK) { printf("Decoded %zu bytes\n", decoded_len); } } ``` -------------------------------- ### Generate Node Keypair (C) Source: https://github.com/tashigit/tashi-vertex-c/blob/main/README.md Generates a secret and public keypair for a Tashi Vertex node. The secret key is encoded to Base58 for display. This is a fundamental step for network participation. ```c #include #include int main() { TVKeySecret secret; tv_key_secret_generate(&secret); TVKeyPublic public; tv_key_secret_to_public(&secret, &public); // encode to Base58 for display uint8_t der[TV_KEY_SECRET_DER_LENGTH]; tv_key_secret_to_der(&secret, der, TV_KEY_SECRET_DER_LENGTH); char b58[tv_base58_encode_length(TV_KEY_SECRET_DER_LENGTH) + 1]; size_t b58_len = sizeof(b58); tv_base58_encode(der, TV_KEY_SECRET_DER_LENGTH, b58, &b58_len); b58[b58_len] = '\0'; printf("Secret: %s\n", b58); return 0; } ``` -------------------------------- ### Receive and Process Consensus Messages (C) Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt This C code snippet demonstrates how to set up a callback function to receive consensus messages from the Tashi Vertex engine. It handles different message types like `TV_MESSAGE_EVENT` and `TV_MESSAGE_SYNC_POINT`, processes event data including transactions, and ensures proper memory management by freeing received data. The `tv_message_recv()` function is crucial for continuing the message loop. ```c #include #include TVEngine* engine = NULL; void on_message_received(TVResult result, TVMessage message, void* data, void* user_data) { if (result != TV_OK) { printf("Message receive error: %d\n", result); return; } switch (message) { case TV_MESSAGE_NONE: // Engine is shutting down printf("Engine shutdown signaled\n"); return; case TV_MESSAGE_EVENT: { TVEvent* event = (TVEvent*)data; // Get consensus timestamp printf("Event consensus at: %lu\n", event->consensus_at); // Get creation timestamp uint64_t created_at; tv_event_get_created_at(event, &created_at); printf("Event created at: %lu\n", created_at); // Process transactions in the event size_t tx_count = 0; tv_event_get_transaction_count(event, &tx_count); printf("Event contains %zu transaction(s)\n", tx_count); for (size_t i = 0; i < tx_count; i++) { uint8_t* tx_data = NULL; size_t tx_size = 0; tv_event_get_transaction(event, i, &tx_data, &tx_size); printf(" Transaction %zu: %zu bytes\n", i, tx_size); // Process transaction data... } // Get whitened signature (useful for consensus-driven randomness) uint8_t* sig = NULL; size_t sig_size = 0; tv_event_get_whitened_signature(event, 0, &sig, &sig_size); // Release event memory tv_free(event); break; } case TV_MESSAGE_SYNC_POINT: { TVSyncPoint* sync_point = (TVSyncPoint*)data; printf("Received sync point (session management decision)\n"); // Release sync point memory tv_free(sync_point); break; } } // Continue listening for next message tv_message_recv(engine, on_message_received, NULL); } // Start message receive loop after engine is started void start_receiving_messages() { tv_message_recv(engine, on_message_received, NULL); } ``` -------------------------------- ### Send Transactions - C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Provides functions for sending transactions through the consensus engine. Transactions can be arbitrary byte arrays. Memory for transactions must be allocated using `tv_transaction_allocate()`, and ownership is transferred to the engine upon sending via `tv_transaction_send()`. ```c #include #include #include // Helper function to send a string as transaction TVResult send_string_transaction(const TVEngine* engine, const char* message) { uint8_t* buffer = NULL; size_t size = strlen(message); // Allocate transaction buffer TVResult result = tv_transaction_allocate(size, &buffer); if (result != TV_OK) { printf("Failed to allocate transaction buffer: %d\n", result); return result; } // Copy data into buffer memcpy(buffer, message, size); // Send transaction - ownership of buffer transfers to engine // Do not use buffer after this call result = tv_transaction_send(engine, buffer, size); if (result != TV_OK) { printf("Failed to send transaction: %d\n", result); return result; } printf("Transaction sent: %s\n", message); return TV_OK; } // Example: Send binary data as transaction TVResult send_binary_transaction(const TVEngine* engine, const uint8_t* data, size_t data_len) { uint8_t* buffer = NULL; TVResult result = tv_transaction_allocate(data_len, &buffer); if (result != TV_OK) { return result; } memcpy(buffer, data, data_len); return tv_transaction_send(engine, buffer, data_len); } ``` -------------------------------- ### Error Checking Macro for Tashi Vertex in C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt A macro for robust error checking in Tashi Vertex C functions. It evaluates an expression, checks if the result is TV_OK, and prints an error message with details if it's not. This macro simplifies error handling by ensuring that errors are caught and reported immediately. It returns the error code if an error occurs. ```c // Macro for error checking (similar to examples/result.h) #define TV_CHECK(expr) do { \ TVResult _res = (expr); \ if (_res != TV_OK) { \ printf("Error at %s: %s (%d)\n", #expr, tv_result_to_string(_res), _res); \ return _res; \ } \ } while(0) ``` -------------------------------- ### Convert TVResult to String in C Source: https://context7.com/tashigit/tashi-vertex-c/llms.txt Converts a TVResult enum value to a human-readable string representation. This function is essential for debugging and logging, mapping specific error codes to descriptive messages. It takes a TVResult as input and returns a const char pointer. ```c #include #include const char* tv_result_to_string(TVResult result) { switch (result) { case TV_OK: return "Success"; case TV_ERROR_ARGUMENT: return "Invalid argument"; case TV_ERROR_ARGUMENT_NULL: return "Null argument"; case TV_ERROR_KEY_FROM_DER: return "Failed to parse key from DER"; case TV_ERROR_CONTEXT: return "Context initialization failed"; case TV_ERROR_BUFFER_TOO_SMALL: return "Buffer too small"; case TV_ERROR_BASE58_DECODE: return "Base58 decode failed"; case TV_ERROR_SOCKET_BIND: return "Socket bind failed"; default: return "Unknown error"; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.