add fee-aware mining, coinbase validation, and reorg-safe orphan handling
Mining: blocks now include mempool txs, select spendable txs by fee, and pay coinbase as base reward + fees in main.c. - Consensus: block validation now enforces coinbase accounting and rejects invalid coinbase placement, including coinbase on amount2, in block.c and transaction.c. - Chain state: rollback now rebuilds currentSupply/currentReward, and block addition preflights spendability before mutating balances in chain.c. - Orphans/reorgs: orphan retry is safer, rollback-triggered sync reattaches orphans immediately, and transient orphan failures no longer drop blocks in orphan_pool.c and main.c. - Networking/mempool: node lifecycle now initializes the mempool, broadcasts can exclude one peer, and mempool snapshotting supports mining selection in net_node.c and txmempool.c. - Ledger simulation: added non-mutating spendable-transaction selection for block assembly in balance_sheet.c.
This commit is contained in:
+19
-4
@@ -177,6 +177,20 @@ static node_block_accept_result_t Node_ParseAndAcceptBlock(const unsigned char*
|
||||
return NODE_BLOCK_REJECTED;
|
||||
}
|
||||
|
||||
uint64_t coinbaseAmount = 0;
|
||||
if (blk->transactions) {
|
||||
for (size_t i = 0; i < DynArr_size(blk->transactions); ++i) {
|
||||
signed_transaction_t* tx = (signed_transaction_t*)DynArr_at(blk->transactions, i);
|
||||
if (tx && Address_IsCoinbase(tx->transaction.senderAddress)) {
|
||||
coinbaseAmount = tx->transaction.amount1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)uint256_add_u64(¤tSupply, coinbaseAmount);
|
||||
currentReward = CalculateBlockReward(currentSupply, currentChain);
|
||||
|
||||
// Persist on accept if requested
|
||||
if (persist) {
|
||||
Chain_SaveToFile(currentChain, chainDataDir, currentSupply, currentReward);
|
||||
@@ -387,7 +401,7 @@ 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) {
|
||||
int Node_BroadcastTransaction(net_node_t* node, signed_transaction_t* tx, tcp_connection_t* excludeNode) {
|
||||
if (!node || !tx) {
|
||||
return -1;
|
||||
}
|
||||
@@ -403,8 +417,9 @@ int Node_BroadcastTransaction(net_node_t* node, signed_transaction_t* tx) {
|
||||
// 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);
|
||||
tcp_connection_t* connection = node->outboundClients[i].connection;
|
||||
if (connection && connection != excludeNode) {
|
||||
(void)Node_SendPacket(node, connection, PACKET_TYPE_BROADCAST_TX, payload, payloadLen);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&node->outboundLock);
|
||||
@@ -646,7 +661,7 @@ void Node_Server_OnData(tcp_connection_t* client) {
|
||||
// Broadcast to other peers
|
||||
net_node_t* node = Node_FromConnection(client);
|
||||
if (node) {
|
||||
Node_BroadcastTransaction(node, &tx);
|
||||
Node_BroadcastTransaction(node, &tx, client);
|
||||
}
|
||||
} else {
|
||||
printf("Failed to add transaction %s from node %u to mempool\n", txHashHex, client ? client->connectionId : 0U);
|
||||
|
||||
Reference in New Issue
Block a user