From 91d7bfa4e7bc54bf2c8ed9647405433cc7a6fdfc Mon Sep 17 00:00:00 2001 From: DcruBro Date: Fri, 29 May 2026 12:45:22 +0200 Subject: [PATCH] start adding tx system - test broadcast --- include/nets/net_node.h | 1 + src/main.c | 19 +++++++++- src/nets/net_node.c | 77 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/include/nets/net_node.h b/include/nets/net_node.h index 0ddb9b4..5ccbca0 100644 --- a/include/nets/net_node.h +++ b/include/nets/net_node.h @@ -57,6 +57,7 @@ int Node_ConnectPeer(net_node_t* node, const char* ip, unsigned short port); int Node_ConnectStartupPeers(net_node_t* node, const char** ips, const unsigned short* ports, size_t peersCount); int Node_SendPacket(net_node_t* node, tcp_connection_t* conn, packet_type_t packetType, const void* payload, size_t payloadLen); +int Node_BroadcastTransaction(net_node_t* node, signed_transaction_t* tx); // Helpers for outbound peer selection and block broadcast int Node_GetBestOutboundPeer(net_node_t* node, tcp_connection_t** outConn, uint64_t* outHeight); diff --git a/src/main.c b/src/main.c index dac21bd..363c8ec 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,7 @@ #include #include #include - +#include #include #include @@ -836,6 +836,7 @@ int main(int argc, char* argv[]) { memcpy(spendTx.transaction.compressedPublicKey, minerCompressedPubkey, sizeof(minerCompressedPubkey)); Transaction_Sign(&spendTx, minerPrivateKey); + /* Block_AddTransaction(block, &spendTx); printf("Created transaction sending %llu pebble(s) to ", (unsigned long long)amount); char recipientHex[65]; @@ -854,6 +855,22 @@ int main(int argc, char* argv[]) { Node_BroadcastChainRange(node, Chain_Size(chain) - 1, NULL); } printf("send committed in mined block\n"); + */ + + // Insert into txmempool + if (!TxMempool_Insert(spendTx)) { + printf("failed to add transaction to mempool, transaction rejected\n"); + continue; + } + + printf("transaction added to mempool, broadcasting...\n"); + + if (Node_BroadcastTransaction(node, &spendTx) == 0) { + printf("transaction broadcast to peers\n"); + } else { + printf("failed to broadcast transaction to peers\n"); + } + continue; } diff --git a/src/nets/net_node.c b/src/nets/net_node.c index 60997a8..2448bf4 100644 --- a/src/nets/net_node.c +++ b/src/nets/net_node.c @@ -11,6 +11,7 @@ #include #include #include +#include static net_node_t* Node_FromConnection(tcp_connection_t* conn) { if (!conn) { @@ -384,6 +385,32 @@ int Node_SendPacket(net_node_t* node, tcp_connection_t* conn, packet_type_t pack return rc; } +int Node_BroadcastTransaction(net_node_t* node, signed_transaction_t* tx) { + if (!node || !tx) { + return -1; + } + + // Serialize transaction into payload + size_t payloadLen = sizeof(signed_transaction_t); + unsigned char* payload = (unsigned char*)malloc(payloadLen); + if (!payload) { + return -1; + } + memcpy(payload, tx, sizeof(signed_transaction_t)); + + // Broadcast to all outbound peers + pthread_mutex_lock(&node->outboundLock); + for (size_t i = 0; i < MAX_CONS; ++i) { + if (node->outboundClients[i].connection) { + (void)Node_SendPacket(node, node->outboundClients[i].connection, PACKET_TYPE_BROADCAST_TX, payload, payloadLen); + } + } + pthread_mutex_unlock(&node->outboundLock); + + free(payload); + return 0; +} + void Node_Server_OnConnect(tcp_connection_t* client) { net_node_t* node = Node_FromConnection(client); Node_ForwardConnect(node, client); @@ -593,7 +620,48 @@ void Node_Server_OnData(tcp_connection_t* client) { break; } case PACKET_TYPE_ACK_BLOCK: - case PACKET_TYPE_BROADCAST_TX: + case PACKET_TYPE_BROADCAST_TX: { + // Decode the block or transaction data inside + if (payloadLen == sizeof(signed_transaction_t)) { + signed_transaction_t tx; + memcpy(&tx, payload, sizeof(tx)); + uint8_t txHash[32]; + char txHashHex[65]; + Transaction_CalculateHash(&tx, txHash); + to_hex(txHash, txHashHex); + printf("Received packet type %u from node %u with transaction sending %llu pebble(s)\n", + (unsigned int)packetType, client ? client->connectionId : 0U, (unsigned long long)tx.transaction.amount1); + + if (!Transaction_Verify(&tx)) { + printf("Received invalid transaction from node %u\n", client ? client->connectionId : 0U); + return; + } + + // Push to mempool if it's not already present + if (!TxMempool_Lookup(txHash, &tx)) { + if (TxMempool_Insert(tx) > 0) { + printf("Added transaction %s from node %u to mempool\n", txHashHex, client ? client->connectionId : 0U); + // Broadcast to other peers + net_node_t* node = Node_FromConnection(client); + if (node) { + Node_BroadcastTransaction(node, &tx); + } + } else { + printf("Failed to add transaction %s from node %u to mempool\n", txHashHex, client ? client->connectionId : 0U); + } + } else { + printf("Transaction %s from node %u already seen!\n", txHashHex, client ? client->connectionId : 0U); + } + + } else { + printf("Received packet type %u from node %u with invalid payload length %zu\n", + (unsigned int)packetType, client ? client->connectionId : 0U, payloadLen); + + // TODO: Ignoring for now, might error node later if we want to be strict about malformed messages + } + + break; + } case PACKET_TYPE_ACK_TX: case PACKET_TYPE_ERROR: { // Decode the message inside as text @@ -765,7 +833,12 @@ void Node_Client_OnData(tcp_connection_t* client) { break; } case PACKET_TYPE_ACK_BLOCK: - case PACKET_TYPE_BROADCAST_TX: + case PACKET_TYPE_BROADCAST_TX: { + // Client can't receive these! + printf("Received unexpected packet type %u from node %u\n", (unsigned int)packetType, client ? client->connectionId : 0U); + + break; + } case PACKET_TYPE_ACK_TX: case PACKET_TYPE_ERROR: { // Decode the message inside as text