@@ -49,6 +49,28 @@ BOOST_AUTO_TEST_CASE(electrum__blockchain_address_get_history__no_address_index_
4949 BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), not_implemented.value ());
5050}
5151
52+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__no_address_index__not_implemented)
53+ {
54+ BOOST_REQUIRE (!query_.address_enabled ());
55+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
56+
57+ const auto request = R"( {"id":1001,"method":"blockchain.address.get_mempool","params":["%1%"]})" " \n " ;
58+ const auto response = get ((boost::format (request) % " 1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn" ).str ());
59+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
60+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), not_implemented.value ());
61+ }
62+
63+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__no_address_index__not_implemented)
64+ {
65+ BOOST_REQUIRE (!query_.address_enabled ());
66+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
67+
68+ const auto request = R"( {"id":1001,"method":"blockchain.address.listunspent","params":["%1%"]})" " \n " ;
69+ const auto response = get ((boost::format (request) % " 1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn" ).str ());
70+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
71+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), not_implemented.value ());
72+ }
73+
5274BOOST_AUTO_TEST_SUITE_END ()
5375
5476BOOST_FIXTURE_TEST_SUITE(electrum_tests, electrum_ten_block_setup_fixture)
@@ -158,7 +180,7 @@ BOOST_AUTO_TEST_CASE(electrum__blockchain_address_get_history__not_found_address
158180 REQUIRE_NO_THROW_TRUE (response.at (" result" ).as_array ().empty ());
159181}
160182
161- BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_history__confirmed_address__expected )
183+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_history__confirmed_and_unconfirmed_address__expected )
162184{
163185 BOOST_REQUIRE (handshake (electrum::version::v1_0));
164186
@@ -179,26 +201,184 @@ BOOST_AUTO_TEST_CASE(electrum__blockchain_address_get_history__confirmed_address
179201 const auto & tx1 = history.at (0 ).as_object ();
180202 REQUIRE_NO_THROW_TRUE (tx1.at (" height" ).is_int64 ());
181203 REQUIRE_NO_THROW_TRUE (tx1.at (" tx_hash" ).is_string ());
182- BOOST_CHECK_EQUAL (tx1.at (" height" ).as_int64 (), 10 );
183- BOOST_CHECK_EQUAL (tx1.at (" tx_hash" ).as_string (), encode_hash (hash1));
204+ BOOST_REQUIRE_EQUAL (tx1.at (" height" ).as_int64 (), 10 );
205+ BOOST_REQUIRE_EQUAL (tx1.at (" tx_hash" ).as_string (), encode_hash (hash1));
184206
185207 const auto hash2 = test::bogus_block11.transactions_ptr ()->at (0 )->hash (false );
186208 const auto & tx2 = history.at (1 ).as_object ();
187209 REQUIRE_NO_THROW_TRUE (tx2.at (" height" ).is_int64 ());
188210 REQUIRE_NO_THROW_TRUE (tx2.at (" tx_hash" ).is_string ());
189- BOOST_CHECK_EQUAL (tx2.at (" height" ).as_int64 (), 0 ); // rooted
190- BOOST_CHECK_EQUAL (tx2.at (" tx_hash" ).as_string (), encode_hash (hash2));
211+ BOOST_REQUIRE_EQUAL (tx2.at (" height" ).as_int64 (), 0 ); // rooted
212+ BOOST_REQUIRE_EQUAL (tx2.at (" tx_hash" ).as_string (), encode_hash (hash2));
191213
192214 const auto hash3 = test::bogus_block12.transactions_ptr ()->at (0 )->hash (false );
193215 const auto & tx3 = history.at (2 ).as_object ();
194216 REQUIRE_NO_THROW_TRUE (tx3.at (" height" ).is_int64 ());
195217 REQUIRE_NO_THROW_TRUE (tx3.at (" tx_hash" ).is_string ());
196- BOOST_CHECK_EQUAL (tx3.at (" height" ).as_int64 (), -1 ); // not rooted
197- BOOST_CHECK_EQUAL (tx3.at (" tx_hash" ).as_string (), encode_hash (hash3));
218+ BOOST_REQUIRE_EQUAL (tx3.at (" height" ).as_int64 (), -1 ); // not rooted
219+ BOOST_REQUIRE_EQUAL (tx3.at (" tx_hash" ).as_string (), encode_hash (hash3));
198220}
199221
200222// blockchain.address.get_mempool
223+
224+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__missing_arguments__dropped)
225+ {
226+ BOOST_REQUIRE (query_.address_enabled ());
227+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
228+
229+ const auto response = get (R"( {"id":1002,"method":"blockchain.address.get_mempool","params":[]})" " \n " );
230+ REQUIRE_NO_THROW_TRUE (response.at (" dropped" ).as_bool ());
231+ }
232+
233+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__empty_v1_3__wrong_version)
234+ {
235+ BOOST_REQUIRE (handshake (electrum::version::v1_3));
236+
237+ const auto response = get (R"( {"id":1003,"method":"blockchain.address.get_mempool","params":[""]})" " \n " );
238+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
239+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), wrong_version.value ());
240+ }
241+
242+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__invalid_address__invalid_argument)
243+ {
244+ BOOST_REQUIRE (handshake (electrum::version::v1_1));
245+
246+ const auto response = get (R"( {"id":1004,"method":"blockchain.address.get_mempool","params":["invalid"]})" " \n " );
247+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
248+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), invalid_argument.value ());
249+ }
250+
251+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__not_found_address__empty)
252+ {
253+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
254+
255+ const auto request = R"( {"id":1005,"method":"blockchain.address.get_mempool","params":["%1%"]})" " \n " ;
256+ const auto response = get ((boost::format (request) % " 1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn" ).str ());
257+ REQUIRE_NO_THROW_TRUE (response.at (" result" ).as_array ().empty ());
258+ }
259+
260+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_get_mempool__confirmed_and_unconfirmed_address__expected)
261+ {
262+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
263+
264+ // Add one confirmed p2sh/p2kh block and one unconfirmed (mirrors the get_balance confirmed test).
265+ BOOST_REQUIRE (query_.set (test::bogus_block10, database::context{ 0 , 10 , 0 }, false , false ));
266+ BOOST_REQUIRE (query_.set (test::bogus_block11, database::context{ 0 , 11 , 0 }, false , false ));
267+ BOOST_REQUIRE (query_.set (test::bogus_block12, database::context{ 0 , 12 , 0 }, false , false ));
268+ BOOST_REQUIRE (query_.push_confirmed (query_.to_header (test::bogus_block10.hash ()), true ));
269+
270+ const auto request = R"( {"id":1006,"method":"blockchain.address.get_mempool","params":["%1%"]})" " \n " ;
271+ const auto response = get ((boost::format (request) % " 1BaMPFdqMUQ46BV8iRcwbVfsam57oBLMM" ).str ());
272+ REQUIRE_NO_THROW_TRUE (response.at (" result" ).is_array ());
273+
274+ const auto & history = response.at (" result" ).as_array ();
275+ BOOST_REQUIRE_EQUAL (history.size (), 2u );
276+
277+ const auto hash1 = test::bogus_block11.transactions_ptr ()->at (0 )->hash (false );
278+ const auto & tx1 = history.at (0 ).as_object ();
279+ REQUIRE_NO_THROW_TRUE (tx1.at (" height" ).is_int64 ());
280+ REQUIRE_NO_THROW_TRUE (tx1.at (" tx_hash" ).is_string ());
281+ BOOST_REQUIRE_EQUAL (tx1.at (" height" ).as_int64 (), 0 ); // rooted
282+ BOOST_REQUIRE_EQUAL (tx1.at (" tx_hash" ).as_string (), encode_hash (hash1));
283+
284+ const auto hash2 = test::bogus_block12.transactions_ptr ()->at (0 )->hash (false );
285+ const auto & tx2 = history.at (1 ).as_object ();
286+ REQUIRE_NO_THROW_TRUE (tx2.at (" height" ).is_int64 ());
287+ REQUIRE_NO_THROW_TRUE (tx2.at (" tx_hash" ).is_string ());
288+ BOOST_REQUIRE_EQUAL (tx2.at (" height" ).as_int64 (), -1 ); // not rooted
289+ BOOST_REQUIRE_EQUAL (tx2.at (" tx_hash" ).as_string (), encode_hash (hash2));
290+ }
291+
201292// blockchain.address.list_unspent
293+
294+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__missing_arguments__dropped)
295+ {
296+ BOOST_REQUIRE (query_.address_enabled ());
297+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
298+
299+ const auto response = get (R"( {"id":1002,"method":"blockchain.address.listunspent","params":[]})" " \n " );
300+ REQUIRE_NO_THROW_TRUE (response.at (" dropped" ).as_bool ());
301+ }
302+
303+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__empty_v1_3__wrong_version)
304+ {
305+ BOOST_REQUIRE (handshake (electrum::version::v1_3));
306+
307+ const auto response = get (R"( {"id":1003,"method":"blockchain.address.listunspent","params":[""]})" " \n " );
308+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
309+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), wrong_version.value ());
310+ }
311+
312+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__invalid_address__invalid_argument)
313+ {
314+ BOOST_REQUIRE (handshake (electrum::version::v1_1));
315+
316+ const auto response = get (R"( {"id":1004,"method":"blockchain.address.listunspent","params":["invalid"]})" " \n " );
317+ REQUIRE_NO_THROW_TRUE (response.at (" error" ).as_object ().at (" code" ).is_int64 ());
318+ BOOST_REQUIRE_EQUAL (response.at (" error" ).as_object ().at (" code" ).as_int64 (), invalid_argument.value ());
319+ }
320+
321+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__not_found_address__empty)
322+ {
323+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
324+
325+ const auto request = R"( {"id":1005,"method":"blockchain.address.listunspent","params":["%1%"]})" " \n " ;
326+ const auto response = get ((boost::format (request) % " 1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn" ).str ());
327+ REQUIRE_NO_THROW_TRUE (response.at (" result" ).as_array ().empty ());
328+ }
329+
330+ BOOST_AUTO_TEST_CASE (electrum__blockchain_address_list_unspent__confirmed_and_unconfirmed_address__expected)
331+ {
332+ BOOST_REQUIRE (handshake (electrum::version::v1_0));
333+
334+ // Add one confirmed p2sh/p2kh block and one unconfirmed (mirrors the get_balance confirmed test).
335+ BOOST_REQUIRE (query_.set (test::bogus_block10, database::context{ 0 , 10 , 0 }, false , false ));
336+ BOOST_REQUIRE (query_.set (test::bogus_block11, database::context{ 0 , 11 , 0 }, false , false ));
337+ BOOST_REQUIRE (query_.set (test::bogus_block12, database::context{ 0 , 12 , 0 }, false , false ));
338+ BOOST_REQUIRE (query_.push_confirmed (query_.to_header (test::bogus_block10.hash ()), true ));
339+
340+ const auto request = R"( {"id":1006,"method":"blockchain.address.listunspent","params":["%1%"]})" " \n " ;
341+ const auto response = get ((boost::format (request) % " 1BaMPFdqMUQ46BV8iRcwbVfsam57oBLMM" ).str ());
342+ REQUIRE_NO_THROW_TRUE (response.at (" result" ).is_array ());
343+
344+ const auto & unspent = response.at (" result" ).as_array ();
345+ BOOST_REQUIRE_EQUAL (unspent.size (), 4u );
346+
347+ const auto hash10 = test::bogus_block10.transactions_ptr ()->at (1 )->hash (false );
348+ const auto & tx1 = unspent.at (0 ).as_object ();
349+ BOOST_REQUIRE_EQUAL (tx1.at (" tx_hash" ).as_string (), encode_hash (hash10));
350+ BOOST_REQUIRE_EQUAL (tx1.at (" tx_pos" ).as_int64 (), 0 ); // tx.output.index(0)
351+ BOOST_REQUIRE_EQUAL (tx1.at (" height" ).as_int64 (), 10 ); // confirmed
352+ BOOST_REQUIRE_EQUAL (tx1.at (" value" ).as_int64 (), 0x09 );
353+
354+ const auto hash11 = test::bogus_block11.transactions_ptr ()->at (0 )->hash (false );
355+ const auto & tx2 = unspent.at (1 ).as_object ();
356+ BOOST_REQUIRE_EQUAL (tx2.at (" tx_hash" ).as_string (), encode_hash (hash11));
357+ BOOST_REQUIRE_EQUAL (tx2.at (" tx_pos" ).as_int64 (), 0 ); // tx.output.index(0)
358+ BOOST_REQUIRE_EQUAL (tx2.at (" height" ).as_int64 (), 0 ); // unconfirmed
359+ BOOST_REQUIRE_EQUAL (tx2.at (" value" ).as_int64 (), 0x10 );
360+
361+ const auto hash12 = test::bogus_block12.transactions_ptr ()->at (0 )->hash (false );
362+ const auto & tx4 = unspent.at (2 ).as_object ();
363+ BOOST_REQUIRE_EQUAL (tx4.at (" tx_hash" ).as_string (), encode_hash (hash12));
364+ BOOST_REQUIRE_EQUAL (tx4.at (" tx_pos" ).as_int64 (), 0 ); // tx.output.index(0)
365+ BOOST_REQUIRE_EQUAL (tx4.at (" height" ).as_int64 (), 0 ); // unconfirmed
366+ BOOST_REQUIRE_EQUAL (tx4.at (" value" ).as_int64 (), 0x10 );
367+
368+ const auto & tx3 = unspent.at (3 ).as_object ();
369+ BOOST_REQUIRE_EQUAL (tx3.at (" tx_hash" ).as_string (), encode_hash (hash11));
370+ BOOST_REQUIRE_EQUAL (tx3.at (" tx_pos" ).as_int64 (), 1 ); // tx.output.index(1)
371+ BOOST_REQUIRE_EQUAL (tx3.at (" height" ).as_int64 (), 0 ); // unconfirmed
372+ BOOST_REQUIRE_EQUAL (tx3.at (" value" ).as_int64 (), 0x11 );
373+
374+ // Index is point arbitrary sort priority.
375+ const auto point11_0 = chain::point{ hash11, 0 };
376+ const auto point11_1 = chain::point{ hash11, 1 };
377+ const auto point12_0 = chain::point{ hash12, 0 };
378+ BOOST_REQUIRE (point11_0 < point12_0);
379+ BOOST_REQUIRE (point12_0 < point11_1);
380+ }
381+
202382// blockchain.address.subscribe
203383
204384BOOST_AUTO_TEST_SUITE_END ()
0 commit comments