Skip to content

Commit c725db9

Browse files
committed
Add confirmed tx properties to electrum tx serialize/test.
1 parent 8c36449 commit c725db9

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

src/protocols/protocol_electrum.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ void protocol_electrum::handle_blockchain_transaction_get(const code& ec,
464464
}
465465

466466
const auto& query = archive();
467-
const auto tx = query.get_transaction(query.to_tx(hash), true);
467+
const auto link = query.to_tx(hash);
468+
const auto tx = query.get_transaction(link, true);
468469
if (!tx)
469470
{
470471
send_code(error::not_found);
@@ -474,9 +475,41 @@ void protocol_electrum::handle_blockchain_transaction_get(const code& ec,
474475
const auto size = tx->serialized_size(true);
475476
if (verbose)
476477
{
477-
// TODO: inject contextual tx properties.
478+
auto value = value_from(bitcoind(*tx));
479+
if (!value.is_object())
480+
{
481+
send_code(error::server_error);
482+
return;
483+
}
484+
485+
if (const auto header = query.to_strong(link); !header.is_terminal())
486+
{
487+
using namespace system;
488+
const auto top = query.get_top_confirmed();
489+
const auto height = query.get_height(header);
490+
const auto block_hash = query.get_header_key(header);
491+
492+
uint32_t timestamp{};
493+
if (height.is_terminal() || (block_hash == null_hash) ||
494+
!query.get_timestamp(timestamp, header))
495+
{
496+
send_code(error::server_error);
497+
return;
498+
}
499+
500+
// Floor manages race between getting confirmed top and height.
501+
const auto confirmations = add1(floored_subtract(top, height.value));
502+
503+
auto& transaction = value.as_object();
504+
transaction["in_active_chain"] = true;
505+
transaction["blockhash"] = encode_hash(block_hash);
506+
transaction["confirmations"] = confirmations;
507+
transaction["blocktime"] = timestamp;
508+
transaction["time"] = timestamp;
509+
}
510+
478511
// Verbose means whatever bitcoind returns for getrawtransaction, lolz.
479-
send_result(value_from(bitcoind(*tx)), two * size, BIND(complete, _1));
512+
send_result(std::move(value), two * size, BIND(complete, _1));
480513
}
481514
else
482515
{

test/protocols/electrum/electrum_transactions.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ BOOST_AUTO_TEST_CASE(electrum__blockchain_transaction_get__genesis_coinbase_verb
126126
BOOST_CHECK_EQUAL(response.at("result").as_string(), encode_base16(coinbase.to_data(true)));
127127
}
128128

129-
// TODO: the expectation doesn't acocunt for contextual tx properties.
130129
BOOST_AUTO_TEST_CASE(electrum__blockchain_transaction_get__genesis_coinbase_verbose_true__expected)
131130
{
132131
BOOST_CHECK(handshake());
@@ -135,7 +134,19 @@ BOOST_AUTO_TEST_CASE(electrum__blockchain_transaction_get__genesis_coinbase_verb
135134
const auto tx_hash = encode_hash(coinbase.hash(false));
136135
const auto request = R"({"id":83,"method":"blockchain.transaction.get","params":["%1%",true]})" "\n";
137136
const auto response = get((boost::format(request) % tx_hash).str());
138-
BOOST_CHECK_EQUAL(response.at("result").as_object(), value_from(bitcoind(coinbase)));
137+
138+
auto expected = value_from(bitcoind(coinbase));
139+
BOOST_CHECK(expected.is_object());
140+
141+
// The test store is ten confirmed blocks, so top height of nine.
142+
constexpr auto top = 9u;
143+
auto& tx = expected.as_object();
144+
tx["in_active_chain"] = true;
145+
tx["blockhash"] = encode_hash(genesis.hash());
146+
tx["confirmations"] = add1(top);
147+
tx["blocktime"] = genesis.header().timestamp();
148+
tx["time"] = genesis.header().timestamp();
149+
BOOST_CHECK_EQUAL(response.at("result").as_object(), expected);
139150
}
140151

141152
// blockchain.transaction.get_merkle

0 commit comments

Comments
 (0)