@@ -7,7 +7,7 @@ use super::Client;
7
7
use crate :: ledger:: Ledger ;
8
8
use bitcoin:: {
9
9
address:: NetworkChecked , consensus:: encode, hashes:: Hash , params:: Params , Address , Amount ,
10
- BlockHash , SignedAmount , Transaction , TxIn , Wtxid ,
10
+ BlockHash , SignedAmount , Transaction , Wtxid ,
11
11
} ;
12
12
use bitcoincore_rpc:: {
13
13
json:: {
@@ -16,7 +16,6 @@ use bitcoincore_rpc::{
16
16
} ,
17
17
RpcApi ,
18
18
} ;
19
- use std:: io:: Error ;
20
19
21
20
impl RpcApi for Client {
22
21
/// This function normally talks with Bitcoin network. Therefore, other
@@ -130,6 +129,8 @@ impl RpcApi for Client {
130
129
Ok ( res)
131
130
}
132
131
132
+ /// Warning `send_to_address` won't check anything. It will only send funds
133
+ /// to specified address. This means: Unlimited free money.
133
134
fn send_to_address (
134
135
& self ,
135
136
address : & Address < NetworkChecked > ,
@@ -141,42 +142,13 @@ impl RpcApi for Client {
141
142
_confirmation_target : Option < u32 > ,
142
143
_estimate_mode : Option < json:: EstimateMode > ,
143
144
) -> bitcoincore_rpc:: Result < bitcoin:: Txid > {
144
- let balance = self . ledger . calculate_balance ( ) ?;
145
- if balance < amount {
146
- return Err ( bitcoincore_rpc:: Error :: Io ( Error :: other ( format ! (
147
- "Output larger than current balance: {amount} > {balance}"
148
- ) ) ) ) ;
149
- }
150
-
151
- // Get latest address of the user. Change will be sent to this address.
152
- let user_address = self
153
- . ledger
154
- . get_credentials ( )
155
- . last ( )
156
- . ok_or ( bitcoincore_rpc:: Error :: Io ( Error :: other (
157
- "No user address found!" . to_string ( ) ,
158
- ) ) ) ?
159
- . address
160
- . to_owned ( ) ;
161
-
162
- let ( utxos, total_value) = self . ledger . combine_utxos ( amount) ?;
163
- let txins: Vec < TxIn > = utxos
164
- . iter ( )
165
- . map ( |utxo| self . ledger . create_txin ( utxo. txid , utxo. vout ) )
166
- . collect ( ) ;
167
-
168
145
let target_txout = self
169
146
. ledger
170
147
. create_txout ( amount, Some ( address. script_pubkey ( ) ) ) ;
171
- let change = self
172
- . ledger
173
- . create_txout ( total_value - amount, Some ( user_address. script_pubkey ( ) ) ) ;
174
148
175
- let tx = self
176
- . ledger
177
- . create_transaction ( txins, vec ! [ target_txout, change] ) ;
149
+ let tx = self . ledger . create_transaction ( vec ! [ ] , vec ! [ target_txout] ) ;
178
150
179
- self . send_raw_transaction ( & tx )
151
+ Ok ( self . ledger . add_transaction_unconditionally ( tx . clone ( ) ) ? )
180
152
}
181
153
182
154
fn get_new_address (
@@ -274,14 +246,14 @@ mod tests {
274
246
let txid = rpc. ledger . add_transaction_unconditionally ( tx) . unwrap ( ) ;
275
247
276
248
// Create a new raw transactions that is valid.
277
- let txin = rpc. ledger . create_txin ( txid, 0 ) ;
249
+ let txin = rpc. ledger . _create_txin ( txid, 0 ) ;
278
250
let txout = rpc
279
251
. ledger
280
252
. create_txout ( Amount :: from_sat ( 0x45 ) , Some ( address. script_pubkey ( ) ) ) ;
281
253
let inserted_tx1 = rpc. ledger . create_transaction ( vec ! [ txin] , vec ! [ txout] ) ;
282
254
rpc. send_raw_transaction ( & inserted_tx1) . unwrap ( ) ;
283
255
284
- let txin = rpc. ledger . create_txin ( inserted_tx1. compute_txid ( ) , 0 ) ;
256
+ let txin = rpc. ledger . _create_txin ( inserted_tx1. compute_txid ( ) , 0 ) ;
285
257
let txout = rpc. ledger . create_txout (
286
258
Amount :: from_sat ( 0x45 ) ,
287
259
Some (
@@ -323,7 +295,7 @@ mod tests {
323
295
let txid = rpc. ledger . add_transaction_unconditionally ( tx) . unwrap ( ) ;
324
296
325
297
// Insert raw transactions to Bitcoin.
326
- let txin = rpc. ledger . create_txin ( txid, 0 ) ;
298
+ let txin = rpc. ledger . _create_txin ( txid, 0 ) ;
327
299
let txout = rpc
328
300
. ledger
329
301
. create_txout ( Amount :: from_sat ( 0x1F ) , Some ( address. script_pubkey ( ) ) ) ;
@@ -338,6 +310,7 @@ mod tests {
338
310
}
339
311
340
312
#[ test]
313
+ #[ ignore = "Not necessary after the send_to_address simplification" ]
341
314
fn send_to_address ( ) {
342
315
let rpc = Client :: new ( "" , bitcoincore_rpc:: Auth :: None ) . unwrap ( ) ;
343
316
@@ -389,6 +362,35 @@ mod tests {
389
362
) ;
390
363
}
391
364
365
+ #[ test]
366
+ fn send_to_address_without_balance_check ( ) {
367
+ let rpc = Client :: new ( "" , bitcoincore_rpc:: Auth :: None ) . unwrap ( ) ;
368
+
369
+ let credential = Ledger :: generate_credential_from_witness ( ) ;
370
+ let receiver_address = credential. address ;
371
+
372
+ // send_to_address should send `amount` to `address`, regardless of the
373
+ // user's balance.
374
+ let txid = rpc
375
+ . send_to_address (
376
+ & receiver_address,
377
+ Amount :: from_sat ( 0x45 ) ,
378
+ None ,
379
+ None ,
380
+ None ,
381
+ None ,
382
+ None ,
383
+ None ,
384
+ )
385
+ . unwrap ( ) ;
386
+
387
+ let tx = rpc. get_raw_transaction ( & txid, None ) . unwrap ( ) ;
388
+
389
+ // Receiver should have this.
390
+ assert_eq ! ( tx. output[ 0 ] . value. to_sat( ) , 0x45 ) ;
391
+ assert_eq ! ( tx. output[ 0 ] . script_pubkey, receiver_address. script_pubkey( ) ) ;
392
+ }
393
+
392
394
#[ test]
393
395
fn get_new_address ( ) {
394
396
let rpc = Client :: new ( "" , bitcoincore_rpc:: Auth :: None ) . unwrap ( ) ;
@@ -442,7 +444,7 @@ mod tests {
442
444
rpc. generate_to_address ( 101 , & address) . unwrap ( ) ;
443
445
444
446
// Wallet has funds now. It should not be rejected.
445
- let txin = rpc. ledger . create_txin (
447
+ let txin = rpc. ledger . _create_txin (
446
448
rpc. ledger
447
449
. _get_transactions ( )
448
450
. get ( 0 )
0 commit comments