fixing block template submittal for protocol_tx

This commit is contained in:
Matt Hess
2025-11-16 02:18:09 +00:00
parent b69fd42df8
commit e8c7b703f3
3 changed files with 94 additions and 28 deletions

View File

@@ -596,6 +596,32 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const
m_minerTxOffsetInTemplate = m_blockHeader.size();
m_minerTxSize = m_minerTx.size();
m_blockTemplateBlob.insert(m_blockTemplateBlob.end(), m_minerTx.begin(), m_minerTx.end());
// Add protocol_tx for Salvium Carrot v1+
if (data.major_version >= 10) {
writeVarint(4, m_blockTemplateBlob); // version = TRANSACTION_VERSION_CARROT
writeVarint(60, m_blockTemplateBlob); // unlock_time = 60
// vin (1 txin_gen)
writeVarint(1, m_blockTemplateBlob); // vin.size() = 1
m_blockTemplateBlob.push_back(TXIN_GEN);
writeVarint(data.height, m_blockTemplateBlob);
// vout (empty)
writeVarint(0, m_blockTemplateBlob); // vout.size() = 0
// extra (2 bytes: 0x02 0x00)
writeVarint(2, m_blockTemplateBlob); // extra.size() = 2
m_blockTemplateBlob.push_back(0x02);
m_blockTemplateBlob.push_back(0x00);
// type = PROTOCOL
writeVarint(2, m_blockTemplateBlob); // transaction_type::PROTOCOL = 2
// rct_signatures (null)
m_blockTemplateBlob.push_back(0); // RCTTypeNull
}
writeVarint(m_numTransactionHashes, m_blockTemplateBlob);
// Miner tx hash is skipped here because it's not a part of block template

View File

@@ -228,31 +228,6 @@ std::vector<uint8_t> PoolBlock::serialize_mainchain_data(size_t* header_size, si
*miner_tx_size = data.size() - header_size0;
}
// Protocol tx (required for Salvium)
if (m_majorVersion >= 10) {
data.push_back(4); // version = TRANSACTION_VERSION_CARROT
writeVarint(60, data); // unlock_time = 60
// vin (1 txin_gen)
data.push_back(1); // vin.size() = 1
data.push_back(TXIN_GEN);
writeVarint(m_txinGenHeight, data);
// vout (empty)
data.push_back(0); // vout.size() = 0
// extra (2 bytes: 0x02 0x00)
data.push_back(2); // extra.size() = 2
data.push_back(0x02);
data.push_back(0x00);
// type = PROTOCOL
writeVarint(2, data); // transaction_type::PROTOCOL = 2
// rct_signatures (null)
data.push_back(0); // RCTTypeNull
}
writeVarint(m_transactions.size() - 1, data);
#ifdef WITH_INDEXED_HASHES

View File

@@ -219,9 +219,74 @@ int PoolBlock::deserialize(const uint8_t* data, size_t size, const SideChain& si
if (static_cast<uint64_t>(data - tx_extra_begin) != tx_extra_size) return __LINE__;
EXPECT_BYTE(0);
uint64_t num_transactions;
READ_VARINT(num_transactions);
// Protocol TX (Salvium Carrot v1+) - parse if present
if (m_majorVersion >= 10) {
// Save position in case we need to backtrack
const uint8_t* saved_pos = data;
uint64_t next_val;
const uint8_t* peek = readVarint(data, data_end, next_val);
// Check if this looks like protocol_tx (version 4) or num_transactions
// num_transactions is typically 0-100, protocol version is 4
if (peek && next_val == 4) {
// Likely protocol_tx, try to parse it
data = peek; // Consume the version varint
uint64_t protocol_unlock_time;
data = readVarint(data, data_end, protocol_unlock_time);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
uint64_t protocol_vin_size;
data = readVarint(data, data_end, protocol_vin_size);
if (!data || protocol_vin_size != 1) { data = saved_pos; goto skip_protocol_tx; }
uint8_t txin_type;
READ_BYTE(txin_type);
if (txin_type != TXIN_GEN) { data = saved_pos; goto skip_protocol_tx; }
uint64_t protocol_height;
data = readVarint(data, data_end, protocol_height);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
uint64_t protocol_vout_size;
data = readVarint(data, data_end, protocol_vout_size);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
// Skip vout if any
for (uint64_t i = 0; i < protocol_vout_size; ++i) {
uint64_t amount;
data = readVarint(data, data_end, amount);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
uint8_t type;
READ_BYTE(type);
// Skip output data based on type
if (!read_buf(nullptr, 32)) { data = saved_pos; goto skip_protocol_tx; }
}
uint64_t protocol_extra_size;
data = readVarint(data, data_end, protocol_extra_size);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
for (uint64_t i = 0; i < protocol_extra_size; ++i) {
uint8_t tmp;
READ_BYTE(tmp);
}
uint64_t protocol_type;
data = readVarint(data, data_end, protocol_type);
if (!data) { data = saved_pos; goto skip_protocol_tx; }
uint8_t rct;
READ_BYTE(rct);
if (rct != 0) { data = saved_pos; goto skip_protocol_tx; }
}
}
skip_protocol_tx:
uint64_t num_transactions;
READ_VARINT(num_transactions);
const int transactions_offset = static_cast<int>(data - data_begin);