@@ -338,9 +338,12 @@ public async Task CanEasilySpendUTXOs()
338
338
}
339
339
}
340
340
341
- [ FactWithTimeout ]
342
- public async Task CanCreatePSBT ( )
341
+ [ TheoryWithTimeout ]
342
+ [ InlineData ( PSBTVersion . PSBTv0 ) ]
343
+ [ InlineData ( PSBTVersion . PSBTv2 ) ]
344
+ public async Task CanCreatePSBT ( PSBTVersion v )
343
345
{
346
+ var version = v == PSBTVersion . PSBTv0 ? 0 : 2 ;
344
347
using ( var tester = ServerTester . Create ( ) )
345
348
{
346
349
// We need to check if we can get utxo information of segwit utxos
@@ -359,15 +362,15 @@ public async Task CanCreatePSBT()
359
362
. BuildTransaction ( false ) ;
360
363
var spendingPSBT = ( await tester . Client . UpdatePSBTAsync ( new UpdatePSBTRequest ( )
361
364
{
362
- PSBT = PSBT . FromTransaction ( spending , tester . Network )
365
+ PSBT = PSBT . FromTransaction ( spending , tester . Network , v )
363
366
} ) ) . PSBT ;
364
367
Assert . NotNull ( spendingPSBT . Inputs [ 0 ] . WitnessUtxo ) ;
365
368
///////////////////////////
366
369
367
- CanCreatePSBTCore ( tester , ScriptPubKeyType . SegwitP2SH ) ;
368
- CanCreatePSBTCore ( tester , ScriptPubKeyType . Segwit ) ;
369
- CanCreatePSBTCore ( tester , ScriptPubKeyType . Legacy ) ;
370
- CanCreatePSBTCore ( tester , ScriptPubKeyType . TaprootBIP86 ) ;
370
+ CanCreatePSBTCore ( tester , version , ScriptPubKeyType . SegwitP2SH ) ;
371
+ CanCreatePSBTCore ( tester , version , ScriptPubKeyType . Segwit ) ;
372
+ CanCreatePSBTCore ( tester , version , ScriptPubKeyType . Legacy ) ;
373
+ CanCreatePSBTCore ( tester , version , ScriptPubKeyType . TaprootBIP86 ) ;
371
374
372
375
// If we build a list of unconf transaction which is too long, the CreatePSBT should
373
376
// fail rather than create a transaction that can't be broadcasted.
@@ -389,6 +392,7 @@ public async Task CanCreatePSBT()
389
392
{
390
393
var psbt = await tester . Client . CreatePSBTAsync ( userDerivationScheme , new CreatePSBTRequest ( )
391
394
{
395
+ PSBTVersion = version ,
392
396
Destinations = {
393
397
new CreatePSBTDestination ( )
394
398
{
@@ -415,7 +419,7 @@ public async Task CanCreatePSBT()
415
419
}
416
420
}
417
421
418
- private static void CanCreatePSBTCore ( ServerTester tester , ScriptPubKeyType type )
422
+ private static void CanCreatePSBTCore ( ServerTester tester , int psbtVersion , ScriptPubKeyType type )
419
423
{
420
424
var userExtKey = new ExtKey ( ) ;
421
425
var userDerivationScheme = tester . Client . Network . DerivationStrategyFactory . CreateDirectDerivationStrategy ( userExtKey . Neuter ( ) , new DerivationStrategyOptions ( )
@@ -447,6 +451,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
447
451
{
448
452
var req = new CreatePSBTRequest ( )
449
453
{
454
+ PSBTVersion = psbtVersion ,
450
455
Destinations =
451
456
{
452
457
new CreatePSBTDestination ( )
@@ -487,6 +492,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
487
492
var explicitFee = i == 2 ;
488
493
var psbt = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
489
494
{
495
+ PSBTVersion = psbtVersion ,
490
496
Destinations =
491
497
{
492
498
new CreatePSBTDestination ( )
@@ -525,6 +531,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
525
531
var balance = tester . Client . GetUTXOs ( userDerivationScheme ) . GetUnspentCoins ( ) . Select ( c => c . Amount ) . Sum ( ) ;
526
532
var psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
527
533
{
534
+ PSBTVersion = psbtVersion ,
528
535
Destinations =
529
536
{
530
537
new CreatePSBTDestination ( )
@@ -544,6 +551,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
544
551
Logs . Tester . LogInformation ( "Let's check that if ReserveChangeAddress is false, all call to CreatePSBT send the same change address" ) ;
545
552
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
546
553
{
554
+ PSBTVersion = psbtVersion ,
547
555
Destinations =
548
556
{
549
557
new CreatePSBTDestination ( )
@@ -562,6 +570,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
562
570
563
571
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
564
572
{
573
+ PSBTVersion = psbtVersion ,
565
574
Destinations =
566
575
{
567
576
new CreatePSBTDestination ( )
@@ -580,6 +589,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
580
589
Logs . Tester . LogInformation ( "Let's check that if ReserveChangeAddress is true, next call to CreatePSBT will create a new change address" ) ;
581
590
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
582
591
{
592
+ PSBTVersion = psbtVersion ,
583
593
Destinations =
584
594
{
585
595
new CreatePSBTDestination ( )
@@ -598,6 +608,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
598
608
var dest = new Key ( ) . PubKey . GetAddress ( ScriptPubKeyType . Legacy , tester . Network ) ;
599
609
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
600
610
{
611
+ PSBTVersion = psbtVersion ,
601
612
RBF = false ,
602
613
Seed = 0 ,
603
614
Destinations =
@@ -620,6 +631,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
620
631
Logs . Tester . LogInformation ( "Let's check that we can use the reserved change as explicit change and end up with the same psbt" ) ;
621
632
var psbt3 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
622
633
{
634
+ PSBTVersion = psbtVersion ,
623
635
RBF = false ,
624
636
Seed = 0 ,
625
637
Destinations =
@@ -641,6 +653,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
641
653
Logs . Tester . LogInformation ( "Let's change that if ReserveChangeAddress is true, but the transaction fails to build, no address get reserverd" ) ;
642
654
var ex = Assert . Throws < NBXplorerException > ( ( ) => psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
643
655
{
656
+ PSBTVersion = psbtVersion ,
644
657
Destinations =
645
658
{
646
659
new CreatePSBTDestination ( )
@@ -655,10 +668,11 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
655
668
} ,
656
669
ReserveChangeAddress = true
657
670
} ) ) ;
658
- Assert . False ( psbt2 . PSBT . GetOriginalTransaction ( ) . RBF ) ;
671
+ Assert . False ( psbt2 . PSBT . GetGlobalTransaction ( ) . RBF ) ;
659
672
Assert . Equal ( "not-enough-funds" , ex . Error . Code ) ;
660
673
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
661
674
{
675
+ PSBTVersion = psbtVersion ,
662
676
RBF = true ,
663
677
Destinations =
664
678
{
@@ -674,7 +688,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
674
688
} ,
675
689
ReserveChangeAddress = false
676
690
} ) ;
677
- Assert . True ( psbt2 . PSBT . GetOriginalTransaction ( ) . RBF ) ;
691
+ Assert . True ( psbt2 . PSBT . GetGlobalTransaction ( ) . RBF ) ;
678
692
Assert . Equal ( changeAddress , psbt2 . ChangeAddress ) ;
679
693
foreach ( var input in psbt2 . PSBT . GetGlobalTransaction ( ) . Inputs )
680
694
{
@@ -685,6 +699,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
685
699
Logs . Tester . LogInformation ( "We have no confirmation, so we should not have enough money if asking for min 1 conf" ) ;
686
700
ex = Assert . Throws < NBXplorerException > ( ( ) => psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
687
701
{
702
+ PSBTVersion = psbtVersion ,
688
703
Destinations =
689
704
{
690
705
new CreatePSBTDestination ( )
@@ -707,6 +722,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
707
722
tester . WaitSynchronized ( ) ;
708
723
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
709
724
{
725
+ PSBTVersion = psbtVersion ,
710
726
Destinations =
711
727
{
712
728
new CreatePSBTDestination ( )
@@ -730,6 +746,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
730
746
tester . Notifications . WaitForTransaction ( userDerivationScheme , txId ) ;
731
747
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
732
748
{
749
+ PSBTVersion = psbtVersion ,
733
750
Destinations =
734
751
{
735
752
new CreatePSBTDestination ( )
@@ -744,11 +761,12 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
744
761
} ,
745
762
ReserveChangeAddress = false
746
763
} ) ;
747
- var outpoints = psbt2 . PSBT . GetOriginalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
764
+ var outpoints = psbt2 . PSBT . GetGlobalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
748
765
Assert . Equal ( 2 , outpoints . Length ) ;
749
766
750
767
var request = new CreatePSBTRequest ( )
751
768
{
769
+ PSBTVersion = psbtVersion ,
752
770
IncludeOnlyOutpoints = new List < OutPoint > ( ) { outpoints [ 0 ] } ,
753
771
Destinations =
754
772
{
@@ -767,7 +785,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
767
785
} ;
768
786
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , request ) ;
769
787
770
- var actualOutpoints = psbt2 . PSBT . GetOriginalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
788
+ var actualOutpoints = psbt2 . PSBT . GetGlobalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
771
789
Assert . Single ( actualOutpoints ) ;
772
790
Assert . Equal ( outpoints [ 0 ] , actualOutpoints [ 0 ] ) ;
773
791
request . MinValue = Money . Coins ( 0.1m ) ;
@@ -776,6 +794,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
776
794
777
795
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
778
796
{
797
+ PSBTVersion = psbtVersion ,
779
798
ExcludeOutpoints = new List < OutPoint > ( ) { outpoints [ 0 ] } ,
780
799
Destinations =
781
800
{
@@ -792,14 +811,15 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
792
811
ReserveChangeAddress = false
793
812
} ) ;
794
813
795
- actualOutpoints = psbt2 . PSBT . GetOriginalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
814
+ actualOutpoints = psbt2 . PSBT . GetGlobalTransaction ( ) . Inputs . Select ( i => i . PrevOut ) . ToArray ( ) ;
796
815
Assert . Single ( actualOutpoints ) ;
797
816
Assert . Equal ( outpoints [ 1 ] , actualOutpoints [ 0 ] ) ;
798
817
799
818
Logs . Tester . LogInformation ( "Let's check nLocktime and version" ) ;
800
819
801
820
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
802
821
{
822
+ PSBTVersion = psbtVersion ,
803
823
Version = 2 ,
804
824
RBF = false ,
805
825
LockTime = new LockTime ( 1_000_000 ) ,
@@ -818,7 +838,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
818
838
} ,
819
839
ReserveChangeAddress = false
820
840
} ) ;
821
- var txx = psbt2 . PSBT . GetOriginalTransaction ( ) ;
841
+ var txx = psbt2 . PSBT . GetGlobalTransaction ( ) ;
822
842
Assert . Equal ( new LockTime ( 1_000_000 ) , txx . LockTime ) ;
823
843
Assert . Equal ( 2U , txx . Version ) ;
824
844
Assert . False ( txx . RBF ) ;
@@ -831,6 +851,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
831
851
832
852
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
833
853
{
854
+ PSBTVersion = psbtVersion ,
834
855
Destinations =
835
856
{
836
857
new CreatePSBTDestination ( )
@@ -886,6 +907,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
886
907
var rootHD = new HDFingerprint ( new byte [ ] { 0x04 , 0x01 , 0x02 , 0x04 } ) ;
887
908
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
888
909
{
910
+ PSBTVersion = psbtVersion ,
889
911
Destinations =
890
912
{
891
913
new CreatePSBTDestination ( )
@@ -931,6 +953,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
931
953
Logs . Tester . LogInformation ( "Let's check that if the explicit change is one of the destination, fee are calculated correctly" ) ;
932
954
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
933
955
{
956
+ PSBTVersion = psbtVersion ,
934
957
Destinations =
935
958
{
936
959
new CreatePSBTDestination ( )
@@ -955,6 +978,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
955
978
{
956
979
ex = Assert . Throws < NBXplorerException > ( ( ) => tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
957
980
{
981
+ PSBTVersion = psbtVersion ,
958
982
Destinations =
959
983
{
960
984
new CreatePSBTDestination ( )
@@ -1004,6 +1028,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
1004
1028
Logs . Tester . LogInformation ( "Let's check that if we can create or update a psbt with non_witness_utxo filled even for segwit inputs" ) ;
1005
1029
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
1006
1030
{
1031
+ PSBTVersion = psbtVersion ,
1007
1032
Destinations =
1008
1033
{
1009
1034
new CreatePSBTDestination ( )
@@ -1029,6 +1054,7 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
1029
1054
// Can we send to no destination?
1030
1055
psbt2 = tester . Client . CreatePSBT ( userDerivationScheme , new CreatePSBTRequest ( )
1031
1056
{
1057
+ PSBTVersion = psbtVersion ,
1032
1058
SpendAllMatchingOutpoints = true ,
1033
1059
IncludeOnlyOutpoints = psbt2 . PSBT . Inputs . Select ( t => t . PrevOut ) . ToList ( ) ,
1034
1060
FeePreference = new FeePreference ( )
@@ -1037,6 +1063,8 @@ private static void CanCreatePSBTCore(ServerTester tester, ScriptPubKeyType type
1037
1063
} ,
1038
1064
AlwaysIncludeNonWitnessUTXO = true
1039
1065
} ) ;
1066
+ var expectedPSBTVersion = psbtVersion == 0 ? PSBTVersion . PSBTv0 : PSBTVersion . PSBTv2 ;
1067
+ Assert . Equal ( expectedPSBTVersion , psbt2 . PSBT . Version ) ;
1040
1068
}
1041
1069
1042
1070
private static PSBTOutput AssertHasOutput ( ScriptPubKeyType type , KeyPath keyPath , CreatePSBTResponse psbt2 )
@@ -1163,6 +1191,7 @@ public async Task ShowRBFedTransaction4()
1163
1191
// b' shouldn't have any output belonging to our wallets.
1164
1192
var bp = b . Clone ( ) ;
1165
1193
bp . Outputs [ 0 ] . Value -= Money . Satoshis ( 5000 ) ; // Add some fee to bump the tx
1194
+ bp . RemoveSignatures ( ) ;
1166
1195
var psbt2 = PSBT . FromTransaction ( bp , tester . Network ) ;
1167
1196
psbt2 . UpdateFrom ( preSignedPsbt ) ;
1168
1197
psbt2 . SignAll ( ScriptPubKeyType . Segwit , bobW . AccountHDKey , bobW . AccountKeyPath ) ;
0 commit comments