tx mempool start, hello packet

This commit is contained in:
2026-04-24 17:14:40 +02:00
parent accdeebee8
commit 32b9a57366
12 changed files with 193 additions and 25 deletions

View File

@@ -3,6 +3,8 @@
#include <errno.h>
#include <sys/stat.h>
uint64_t currentBlockHeight = 0;
static bool EnsureDirectoryExists(const char* dirpath) {
if (!dirpath || dirpath[0] == '\0') {
return false;
@@ -176,6 +178,7 @@ bool Chain_AddBlock(blockchain_t* chain, block_t* block) {
return false;
}
chain->size++;
currentBlockHeight = (uint64_t)(chain->size - 1);
// Second pass: apply the ledger changes.
if (blk->transactions) {
@@ -269,6 +272,7 @@ bool Chain_IsValid(blockchain_t* chain) {
void Chain_Wipe(blockchain_t* chain) {
Chain_ClearBlocks(chain);
currentBlockHeight = 0;
}
bool Chain_SaveToFile(blockchain_t* chain, const char* dirpath, uint256_t currentSupply, uint64_t currentReward) {

View File

@@ -173,3 +173,7 @@ void DynArr_destroy(DynArr* p) {
free(p->data);
free(p);
}
void* DynArr_c_arr(DynArr* p) {
return p->data;
}

View File

@@ -561,8 +561,15 @@ int main(int argc, char* argv[]) {
}
free(block); // Chain stores block by value and owns copied transaction array.
if (i % 1000 == 0) {
// Mid-mine flush
(void)FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward);
}
}
if (minedAll) {
(void)FlushChainAndSheet(chain, chainDataDir, currentSupply, currentReward);
printf("mine finished and chain flushed\n");

View File

@@ -160,6 +160,7 @@ int Node_SendPacket(net_node_t* node, tcp_connection_t* conn, packet_type_t pack
return -1;
}
/*
if (conn->role == TCP_CONNECTION_ROLE_INBOUND && packetType != PACKET_TYPE_RESPONSE) {
return -1;
}
@@ -167,6 +168,7 @@ int Node_SendPacket(net_node_t* node, tcp_connection_t* conn, packet_type_t pack
if (conn->role == TCP_CONNECTION_ROLE_OUTBOUND && packetType != PACKET_TYPE_REQUEST) {
return -1;
}
*/
size_t framePayloadLen = payloadLen + 1;
unsigned char* framed = (unsigned char*)malloc(framePayloadLen);
@@ -200,9 +202,34 @@ void Node_Server_OnData(tcp_connection_t* client) {
return;
}
if (packetType != PACKET_TYPE_REQUEST) {
return;
}
switch (packetType) {
case PACKET_TYPE_HELLO: {
// Decode HELLO
if (payloadLen < sizeof(uint32_t) + sizeof(uint64_t)) {
return;
}
uint32_t protoVersion;
uint64_t blockHeight;
memcpy(&protoVersion, payload, sizeof(protoVersion));
memcpy(&blockHeight, payload + sizeof(protoVersion), sizeof(blockHeight));
// TODO: Save these somewhere and maybe respond
printf("Received HELLO from node %u: protoVersion=%u, blockHeight=%" PRIu64 "\n",
client ? client->connectionId : 0U, protoVersion, blockHeight);
break;
}
case PACKET_TYPE_FETCH_BLOCK:
case PACKET_TYPE_BLOCK_DATA:
case PACKET_TYPE_BROADCAST_BLOCK:
case PACKET_TYPE_ACK_BLOCK:
case PACKET_TYPE_BROADCAST_TX:
case PACKET_TYPE_ACK_TX:
break;
default:
return;
}
net_node_t* node = Node_FromConnection(client);
Node_ForwardData(node, client, payload, payloadLen);
@@ -218,6 +245,22 @@ void Node_Client_OnConnect(tcp_connection_t* client) {
net_node_t* node = Node_FromConnection(client);
Node_ForwardConnect(node, client);
printf("Outbound node connected: %u\n", client ? client->connectionId : 0U);
// Construct and send HELLO
if (node) {
uint8_t buf[100];
uint8_t* data = buf;
size_t offset = 0;
uint32_t protoVersion = 1; // little-endian
uint64_t blockHeight = currentBlockHeight;
memcpy((unsigned char*)data + offset, &protoVersion, sizeof(protoVersion)); // This is technically "unsafe", but I honestly just don't give a shit at this point
offset += sizeof(protoVersion);
memcpy((unsigned char*)data + offset, &blockHeight, sizeof(blockHeight));
offset += sizeof(blockHeight);
Node_SendPacket(node, client, PACKET_TYPE_HELLO, data, offset);
}
}
void Node_Client_OnData(tcp_connection_t* client) {
@@ -229,8 +272,17 @@ void Node_Client_OnData(tcp_connection_t* client) {
return;
}
if (packetType != PACKET_TYPE_RESPONSE) {
return;
switch (packetType) {
case PACKET_TYPE_HELLO:
case PACKET_TYPE_FETCH_BLOCK:
case PACKET_TYPE_BLOCK_DATA:
case PACKET_TYPE_BROADCAST_BLOCK:
case PACKET_TYPE_ACK_BLOCK:
case PACKET_TYPE_BROADCAST_TX:
case PACKET_TYPE_ACK_TX:
break;
default:
return;
}
net_node_t* node = Node_FromConnection(client);

71
src/txmempool.c Normal file
View File

@@ -0,0 +1,71 @@
#include <txmempool.h>
khash_t(tx_mempool_map_m)* txMempool = NULL;
void TxMempool_Init() {
txMempool = kh_init(tx_mempool_map_m);
}
int TxMempool_Insert(signed_transaction_t tx) {
if (!txMempool) { return -1; }
uint8_t txHash[32];
Transaction_CalculateHash(&tx.transaction, txHash);
key32_t key;
memcpy(key.bytes, txHash, 32);
int ret;
khiter_t k = kh_put(tx_mempool_map_m, txMempool, key, &ret);
if (k == kh_end(txMempool)) {
return -1;
}
kh_value(txMempool, k) = tx;
return ret;
}
bool TxMempool_Lookup(uint8_t* txHash, signed_transaction_t* out) {
if (!txMempool || !txHash || !out) { return false; }
key32_t key;
memcpy(key.bytes, txHash, 32);
khiter_t k = kh_get(tx_mempool_map_m, txMempool, key);
if (k != kh_end(txMempool)) {
signed_transaction_t tx = kh_value(txMempool, k);
memcpy(out, &tx, sizeof(signed_transaction_t));
return true;
}
return false;
}
void TxMempool_Print() {
if (!txMempool) { return; }
khiter_t k;
for (k = kh_begin(txMempool); k != kh_end(txMempool); ++k) {
if (kh_exist(txMempool, k)) {
signed_transaction_t tx = kh_val(txMempool, k);
char senderHex[65];
char recipient1Hex[65];
char recipient2Hex[65];
AddressToHexString(tx.transaction.senderAddress, senderHex);
AddressToHexString(tx.transaction.recipientAddress1, recipient1Hex);
AddressToHexString(tx.transaction.recipientAddress2, recipient2Hex);
printf("TX in mempool: sender=%s recipient1=%s recipient2=%s amount1=%llu amount2=%llu fee=%llu\n",
senderHex, recipient1Hex, recipient2Hex,
(unsigned long long)tx.transaction.amount1,
(unsigned long long)tx.transaction.amount2,
(unsigned long long)tx.transaction.fee);
}
}
}
void TxMempool_Destroy() {
if (txMempool) {
kh_destroy(tx_mempool_map_m, txMempool);
}
}