@@ -46,11 +46,6 @@ void protocol_electrum::handle_blockchain_transaction_broadcast(const code& ec,
4646 return ;
4747 }
4848
49- // TODO: implement error_object.
50- // Changed in version 1.1: return error vs. bitcoind result.
51- // Previously it returned text string (bitcoind message) in the error case.
52- // //const auto error_object = at_least(electrum::version::v1_1);
53-
5449 data_chunk tx_data{};
5550 if (!decode_base16 (tx_data, raw_tx))
5651 {
@@ -65,22 +60,40 @@ void protocol_electrum::handle_blockchain_transaction_broadcast(const code& ec,
6560 return ;
6661 }
6762
68- // TODO: handle just as any peer annoucement, validate and relay.
6963 // TODO: requires tx pool in order to validate against unconfirmed txs.
70- constexpr auto confirmable = false ;
71- if (!confirmable)
64+ const code fault{ error::unconfirmable_transaction };
65+
66+ // //const auto& query = archive();
67+ // //constexpr chain::context next_block_context{};
68+ // //fault = tx->check();
69+ // //fault = tx->guard_check();
70+ // //fault = tx->check(next_block_context);
71+ // //fault = tx->guard_check(next_block_context);
72+ // //query.populate_with_metadata(*tx);
73+ // //fault = tx->accept(next_block_context);
74+ // //fault = tx->guard_accept(next_block_context);
75+ // //fault = tx->confirm(next_block_context);
76+ // //fault = tx->connect(next_block_context);
77+
78+ if (!fault)
79+ {
80+ // TODO: broadcast tx to p2p.
81+ send_result (encode_hash (tx->hash (false )), 42 , BIND (complete, _1));
82+ return ;
83+ }
84+
85+ if (!at_least (electrum::version::v1_1))
7286 {
73- send_code (error::unconfirmable_transaction );
87+ send_result (fault. message (), 42 , BIND (complete, _1) );
7488 return ;
7589 }
7690
77- constexpr auto size = two * hash_size;
78- send_result (encode_base16 (tx->hash (false )), size, BIND (complete, _1));
91+ send_code (fault);
7992}
8093
8194void protocol_electrum::handle_blockchain_transaction_broadcast_package (
8295 const code& ec, rpc_interface::blockchain_transaction_broadcast_package,
83- const std::string & raw_txs, bool ) NOEXCEPT
96+ const interface:: value_t & raw_txs, bool verbose ) NOEXCEPT
8497{
8598 if (stopped (ec))
8699 return ;
@@ -91,22 +104,84 @@ void protocol_electrum::handle_blockchain_transaction_broadcast_package(
91104 return ;
92105 }
93106
94- data_chunk txs_data{};
95- if (!decode_base16 (txs_data, raw_txs))
107+ // Electrum documentation: "Exact structure depends on bitcoind impl and
108+ // version, and should not be relied upon... should be considered
109+ // experimental and better-suited for debugging." - do not support this.
110+ if (verbose)
111+ {
112+ send_code (error::unsupported_argument);
113+ return ;
114+ }
115+
116+ if (!std::holds_alternative<array_t >(raw_txs.value ()))
96117 {
97118 send_code (error::invalid_argument);
98119 return ;
99120 }
100121
101- // TODO: consider whether to support the lousy package p2p protocol.
102- constexpr auto confirmable = false ;
103- if (!confirmable)
122+ const auto & txs_hex = std::get<array_t >(raw_txs.value ());
123+ if (txs_hex.empty ())
104124 {
105- send_code (error::unconfirmable_transaction );
125+ send_code (error::invalid_argument );
106126 return ;
107127 }
108128
109- send_code (error::not_implemented);
129+ size_t error_size{};
130+ // //const auto& query = archive();
131+ // //constexpr chain::context next_block_context{};
132+ object_t result{ { " success" , true }, { " errors" , array_t {} } };
133+ auto & success = std::get<bool >(result[" success" ].value ());
134+ auto & errors = std::get<array_t >(result[" errors" ].value ());
135+
136+ for (const auto & tx_hex: txs_hex)
137+ {
138+ if (!std::holds_alternative<string_t >(tx_hex.value ()))
139+ {
140+ send_code (error::invalid_argument);
141+ return ;
142+ }
143+
144+ data_chunk tx_data{};
145+ if (!decode_base16 (tx_data, std::get<string_t >(tx_hex.value ())))
146+ {
147+ send_code (error::invalid_argument);
148+ return ;
149+ }
150+
151+ const auto tx = to_shared<chain::transaction>(tx_data, true );
152+ if (!tx->is_valid ())
153+ {
154+ send_code (error::invalid_argument);
155+ return ;
156+ }
157+
158+ // TODO: requires tx pool in order to validate against unconfirmed txs.
159+ const code fault{ error::unconfirmable_transaction };
160+
161+ // //fault = tx->check();
162+ // //fault = tx->guard_check();
163+ // //fault = tx->check(next_block_context);
164+ // //fault = tx->guard_check(next_block_context);
165+ // //query.populate_with_metadata(*tx);
166+ // //fault = tx->accept(next_block_context);
167+ // //fault = tx->guard_accept(next_block_context);
168+ // //fault = tx->confirm(next_block_context);
169+ // //fault = tx->connect(next_block_context);
170+
171+ if (fault)
172+ {
173+ const auto message = fault.message ();
174+ error_size += message.size ();
175+ errors.push_back (object_t
176+ {
177+ { " txid" , encode_hash (tx->hash (false )) },
178+ { " error" , message }
179+ });
180+ }
181+ }
182+
183+ success = errors.empty ();
184+ send_result (result, 42 + error_size, BIND (complete, _1));
110185}
111186
112187void protocol_electrum::handle_blockchain_transaction_get (const code& ec,
0 commit comments