@@ -1135,40 +1135,41 @@ public void TransactionBuilderFeeRateSideCase()
11351135
11361136 [ Fact ]
11371137 [ Trait ( "UnitTest" , "UnitTest" ) ]
1138- public void TransactionBuilderRefundsFeeAfterMergingOutputs ( )
1139- {
1140- var sender = new Key ( ) . PubKey . GetScriptPubKey ( ScriptPubKeyType . Segwit ) ;
1141- var destination = new Key ( ) ;
1142- var c1 = new Coin ( new OutPoint ( uint256 . Zero , 0 ) , new TxOut ( Money . Coins ( 1.0m ) , sender ) ) ;
1143- var c2 = new Coin ( new OutPoint ( uint256 . Zero , 1 ) , new TxOut ( Money . Coins ( 2.0m ) , sender ) ) ;
1144- var selector = new SpyCoinSelector ( ) ;
1145- selector . AddSelections ( new [ ] { c1 , c2 } ) ;
1146- selector . AddSelections ( new [ ] { c1 } ) ;
1147-
1148- var feeRate = new FeeRate ( 5.0m ) ;
1149- var builder = Network . Main . CreateTransactionBuilder ( )
1150- . AddCoins ( c1 , c2 )
1151- . SetCoinSelector ( selector )
1152- . Send ( destination , Money . Coins ( 0.5m ) )
1153- . SetChange ( destination )
1154- . SendEstimatedFees ( feeRate ) ;
1155-
1156- var tx = builder . BuildTransaction ( false ) ;
1157- var expectedFee = feeRate . GetFee ( builder . EstimateSize ( tx , true ) ) ;
1158-
1159- Assert . Single ( tx . Outputs ) ;
1160- Assert . Equal ( expectedFee , tx . GetFee ( builder . FindSpentCoins ( tx ) ) ) ;
1161- Assert . Equal ( c1 . Amount - expectedFee , tx . Outputs [ 0 ] . Value ) ;
1162- }
1163-
1164- [ Fact ]
1165- [ Trait ( "UnitTest" , "UnitTest" ) ]
1138+ public void TransactionBuilderRefundsFeeAfterMergingOutputs ( )
1139+ {
1140+ var sender = new Key ( ) . PubKey . GetScriptPubKey ( ScriptPubKeyType . Segwit ) ;
1141+ var destination = new Key ( ) ;
1142+ var c1 = new Coin ( new OutPoint ( uint256 . Zero , 0 ) , new TxOut ( Money . Coins ( 1.0m ) , sender ) ) ;
1143+ var c2 = new Coin ( new OutPoint ( uint256 . Zero , 1 ) , new TxOut ( Money . Coins ( 2.0m ) , sender ) ) ;
1144+ var selector = new SpyCoinSelector ( ) ;
1145+ selector . AddSelections ( new [ ] { c1 , c2 } ) ;
1146+ selector . AddSelections ( new [ ] { c1 } ) ;
1147+
1148+ var feeRate = new FeeRate ( 5.0m ) ;
1149+ var builder = Network . Main . CreateTransactionBuilder ( )
1150+ . AddCoins ( c1 , c2 )
1151+ . SetCoinSelector ( selector )
1152+ . Send ( destination , Money . Coins ( 0.5m ) )
1153+ . SetChange ( destination )
1154+ . SendEstimatedFees ( feeRate ) ;
1155+
1156+ var tx = builder . BuildTransaction ( false ) ;
1157+ var expectedFee = feeRate . GetFee ( builder . EstimateSize ( tx , true ) ) ;
1158+
1159+ Assert . Single ( tx . Outputs ) ;
1160+ Assert . Equal ( expectedFee , tx . GetFee ( builder . FindSpentCoins ( tx ) ) ) ;
1161+ Assert . Equal ( c1 . Amount - expectedFee , tx . Outputs [ 0 ] . Value ) ;
1162+ }
1163+
1164+ [ Fact ]
1165+ [ Trait ( "UnitTest" , "UnitTest" ) ]
11661166 public void TransactionBuilderFuzzying ( )
11671167 {
11681168 var seed = RandomUtils . GetInt32 ( ) ;
11691169 log . WriteLine ( "Seed " + seed ) ;
11701170 TransactionBuilderFuzzyingCore ( seed ) ;
11711171 TransactionBuilderFuzzyingCore ( 659623968 ) ;
1172+ TransactionBuilderFuzzyingCore ( 503175992 ) ;
11721173 }
11731174
11741175 private void TransactionBuilderFuzzyingCore ( int seed )
@@ -1250,10 +1251,18 @@ private void TransactionBuilderFuzzyingCore(int seed)
12501251 {
12511252 var tx = builder . BuildTransaction ( false ) ;
12521253 var actualFee = tx . GetFee ( builder . FindSpentCoins ( tx ) ) ;
1253- if ( fee != null )
1254- {
1255- Assert . Equal ( fee , actualFee ) ;
1256- }
1254+ if ( fee != null )
1255+ {
1256+ if ( tx . Outputs . Any ( o => o . ScriptPubKey == carolScript ) )
1257+ {
1258+ Assert . Equal ( fee , actualFee ) ;
1259+ }
1260+ // It is possible that no change was calculated, and thus the actual fee ends up more than expected
1261+ else
1262+ {
1263+ Assert . True ( fee <= actualFee ) ;
1264+ }
1265+ }
12571266 if ( feeRate != null )
12581267 {
12591268 var actualFeeRate = new FeeRate ( actualFee , builder . EstimateSize ( tx , true ) ) ;
@@ -2286,8 +2295,8 @@ public void AssertCanSendBackSmallSegwitChange(PSBTVersion version)
22862295 // Because it would be above 100K, this would fail to pass policy rules of bitcoin.
22872296 // This test check that if this is the case, the transaction builder is correctly excluding
22882297 // small inputs from the selection in an attempt to keep transaction small.
2289- public void DoNotBuildTooBigTransaction ( )
2290- {
2298+ public void DoNotBuildTooBigTransaction ( )
2299+ {
22912300 var k = new Key ( ) ;
22922301 var addr = k . PubKey . GetAddress ( ScriptPubKeyType . Segwit , Network . Main ) ;
22932302 int coinsCount = 5000 ;
@@ -2313,28 +2322,28 @@ public void DoNotBuildTooBigTransaction()
23132322 var rate = tx . GetFeeRate ( builder . FindSpentCoins ( tx ) ) ;
23142323 // We can overshoot slightly, never undershoot
23152324 Assert . True ( new FeeRate ( 1.0m ) . SatoshiPerByte <= rate . SatoshiPerByte ) ;
2316- Assert . Equal ( new FeeRate ( 1.0m ) . SatoshiPerByte , rate . SatoshiPerByte , 1 ) ;
2317- }
2318-
2319- [ Fact ]
2320- [ Trait ( "UnitTest" , "UnitTest" ) ]
2321- public void OversizedColoredTransactionThrowsNotEnoughFundsException ( )
2322- {
2323- var destination = new Key ( ) ;
2324- var asset = new AssetId ( new Key ( ) ) ;
2325- var coins = Enumerable . Range ( 0 , 5000 )
2326- . Select ( i => new ColoredCoin (
2327- new AssetMoney ( asset , 1 ) ,
2328- new Coin ( new OutPoint ( uint256 . Zero , i ) , new TxOut ( Money . Satoshis ( 1000 ) , destination ) ) ) )
2329- . ToArray ( ) ;
2330- var builder = Network . Main . CreateTransactionBuilder ( )
2331- . AddCoins ( coins )
2332- . SendAsset ( destination , new AssetMoney ( asset , coins . Length ) )
2333- . SetChange ( destination ) ;
2334-
2335- var exception = Assert . Throws < NotEnoughFundsException > ( ( ) => builder . BuildTransaction ( false ) ) ;
2336- Assert . Contains ( "transaction's size would be too high" , exception . Message ) ;
2337- }
2325+ Assert . Equal ( new FeeRate ( 1.0m ) . SatoshiPerByte , rate . SatoshiPerByte , 1 ) ;
2326+ }
2327+
2328+ [ Fact ]
2329+ [ Trait ( "UnitTest" , "UnitTest" ) ]
2330+ public void OversizedColoredTransactionThrowsNotEnoughFundsException ( )
2331+ {
2332+ var destination = new Key ( ) ;
2333+ var asset = new AssetId ( new Key ( ) ) ;
2334+ var coins = Enumerable . Range ( 0 , 5000 )
2335+ . Select ( i => new ColoredCoin (
2336+ new AssetMoney ( asset , 1 ) ,
2337+ new Coin ( new OutPoint ( uint256 . Zero , i ) , new TxOut ( Money . Satoshis ( 1000 ) , destination ) ) ) )
2338+ . ToArray ( ) ;
2339+ var builder = Network . Main . CreateTransactionBuilder ( )
2340+ . AddCoins ( coins )
2341+ . SendAsset ( destination , new AssetMoney ( asset , coins . Length ) )
2342+ . SetChange ( destination ) ;
2343+
2344+ var exception = Assert . Throws < NotEnoughFundsException > ( ( ) => builder . BuildTransaction ( false ) ) ;
2345+ Assert . Contains ( "transaction's size would be too high" , exception . Message ) ;
2346+ }
23382347
23392348 [ Theory ]
23402349 [ InlineData ( PSBTVersion . PSBTv0 ) ]
@@ -3449,8 +3458,8 @@ public void CanCacheHashes()
34493458
34503459 [ Fact ]
34513460 [ Trait ( "UnitTest" , "UnitTest" ) ]
3452- public void CheckScriptCoinIsCoherent ( )
3453- {
3461+ public void CheckScriptCoinIsCoherent ( )
3462+ {
34543463 Key key = new Key ( ) ;
34553464 var c = RandomCoin ( Money . Zero , key . PubKey . ScriptPubKey . Hash ) ;
34563465
@@ -3482,23 +3491,23 @@ public void CheckScriptCoinIsCoherent()
34823491 Assert . True ( scriptCoin . GetHashVersion ( ) == HashVersion . WitnessV0 ) ;
34833492
34843493
3485- Assert . Throws < ArgumentException > ( ( ) => new ScriptCoin ( c , key . PubKey . ScriptPubKey . WitHash . ScriptPubKey ) ) ;
3486- }
3487-
3488- [ Fact ]
3489- [ Trait ( "UnitTest" , "UnitTest" ) ]
3490- public void TransactionOutputHelpersRejectInvalidOutputReferences ( )
3491- {
3492- var previous = Network . CreateTransaction ( ) ;
3493- var output = previous . Outputs . Add ( Money . Coins ( 1.0m ) , new Key ( ) ) ;
3494- var spending = Network . CreateTransaction ( ) ;
3495-
3496- Assert . Throws < InvalidOperationException > ( ( ) => spending . Inputs . Add ( previous , - 1 ) ) ;
3497- Assert . Throws < ArgumentException > ( ( ) => new Coin ( previous , output . Clone ( ) ) ) ;
3498- Assert . Same ( output , new Coin ( previous , output ) . TxOut ) ;
3499- }
3500-
3501- [ Fact ]
3494+ Assert . Throws < ArgumentException > ( ( ) => new ScriptCoin ( c , key . PubKey . ScriptPubKey . WitHash . ScriptPubKey ) ) ;
3495+ }
3496+
3497+ [ Fact ]
3498+ [ Trait ( "UnitTest" , "UnitTest" ) ]
3499+ public void TransactionOutputHelpersRejectInvalidOutputReferences ( )
3500+ {
3501+ var previous = Network . CreateTransaction ( ) ;
3502+ var output = previous . Outputs . Add ( Money . Coins ( 1.0m ) , new Key ( ) ) ;
3503+ var spending = Network . CreateTransaction ( ) ;
3504+
3505+ Assert . Throws < InvalidOperationException > ( ( ) => spending . Inputs . Add ( previous , - 1 ) ) ;
3506+ Assert . Throws < ArgumentException > ( ( ) => new Coin ( previous , output . Clone ( ) ) ) ;
3507+ Assert . Same ( output , new Coin ( previous , output ) . TxOut ) ;
3508+ }
3509+
3510+ [ Fact ]
35023511 [ Trait ( "UnitTest" , "UnitTest" ) ]
35033512 public void CheckWitnessSize ( )
35043513 {
0 commit comments