Skip to content

tashigg/tashi-vertex-c

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

27 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Tashi Vertex for C

License

C interface for Tashi Vertex, an embedded Byzantine fault-tolerant consensus engine based on the Hashgraph algorithm.

Tashi Vertex uses a DAG (Directed Acyclic Graph) of cryptographically signed events and virtual voting to achieve consensus finality in under 100 milliseconds β€” without exchanging explicit vote messages. For a detailed explanation, see the Vertex whitepaper.

Features

  • Fast BFT Consensus β€” sub-100ms finality with tolerance up to f = ⌊(n-1)/3βŒ‹ Byzantine participants
  • Callback-based async β€” socket binding and message receiving use non-blocking callbacks
  • Minimal API surface β€” single header include (tashi-vertex/tashi-vertex.h) exposes the full API
  • Opaque handle design β€” resource lifetime managed through opaque pointers and tv_free()
  • Configurable β€” 15+ tunable engine parameters (heartbeat, latency thresholds, epoch sizing, etc.)
  • Base58 utilities β€” encode/decode keys and binary data

Installation

Build Requirements

  • CMake >= 4.0
  • A C99-compatible compiler

CMake (Recommended)

Use CMake's FetchContent to automatically download the pre-built library from GitHub releases:

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()

Then link against it in your target:

target_include_directories(my_app PRIVATE "${tashi_vertex_SOURCE_DIR}/include")
target_link_libraries(my_app PRIVATE TASHI_VERTEX)

Manual

Download the latest .zip release from GitHub Releases and extract it. The archive contains include/ and lib/ directories that you can integrate into your build system of choice.

Quick Start

Generate a keypair for your node:

#include <stdio.h>
#include <tashi-vertex/tashi-vertex.h>

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

Run a minimal consensus network (simplified from examples/pingback.c):

#include <stdio.h>
#include <string.h>
#include <tashi-vertex/tashi-vertex.h>

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

API Overview

Type Description
TVEngine Starts and drives the consensus engine β€” send transactions and receive ordered messages
TVContext Runtime context managing async operations and resources
TVSocket Async network socket bound to a local address
TVOptions Engine configuration (heartbeat, latency, epoch size, threading, etc.)
TVMessage Received message type β€” either TV_MESSAGE_EVENT or TV_MESSAGE_SYNC_POINT
TVEvent A finalized event carrying consensus-ordered transactions
TVKeySecret Ed25519 secret key for signing (Base58/DER serializable)
TVKeyPublic Ed25519 public key for verification (Base58/DER serializable)
TVPeers Set of network participants with addresses and capabilities
TVSyncPoint Session management decision from the consensus layer
TVResult Error code returned by all fallible functions (TV_OK on success)
tv_free() Releases memory for all Tashi Vertex-allocated objects

Examples

The examples/ directory contains runnable demos:

  • key-generate β€” Generate a new keypair
  • key-parse β€” Parse Base58-encoded keys
  • pingback β€” Full multi-peer consensus network with transaction exchange

Build all examples:

cd examples
make

Running the Pingback Example

The pingback example runs a 3-node consensus network where each node sends a PING transaction. First, generate a keypair for each node:

make run-key-generate  # run 3 times, save each secret/public key

Then start each node in a separate terminal, passing the other two nodes as peers:

make run-pingback ARGS="-B 127.0.0.1:8001 -K <secret_key> -P <peer2_public_key> 127.0.0.1:8002 -P <peer3_public_key> 127.0.0.1:8003"

Once all three nodes are running, each will reach consensus and print the ordered events:

 :: Configured network for 3 peers
 :: Initialized runtime
 :: Bound local socket
 :: Started the consensus engine
 > Received SYNC POINT
 > Received EVENT with 1 transaction(s)
 > Received EVENT with 1 transaction(s)
 > Received EVENT with 1 transaction(s)

License

This project is licensed under the Apache License, Version 2.0 (LICENSE).

Dynamic Linking to Tashi Vertex

This project dynamically links to the Tashi Vertex binary library (proprietary). Its origin and licensing details are provided in the NOTICE file.

Disclaimer: The Apache 2.0 license applies only to the source code of this project. The Tashi Vertex binary is not part of this open-source distribution and is governed by its own commercial license.

About

Provides access to Tashi Vertex through a C interface.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •