Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
destream-blockchain
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
2
Issues
2
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DeStream-public
destream-blockchain
Commits
c30cdaab
Commit
c30cdaab
authored
Jan 16, 2019
by
Sergei Zubov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge wallet
parent
3854e8a3
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
141 additions
and
118 deletions
+141
-118
DeStreamWalletController.cs
...n.Features.Wallet/Controllers/DeStreamWalletController.cs
+45
-20
WalletController.cs
...s.Bitcoin.Features.Wallet/Controllers/WalletController.cs
+1
-1
DeStreamWalletManager.cs
.../Stratis.Bitcoin.Features.Wallet/DeStreamWalletManager.cs
+20
-42
DeStreamWalletSyncManager.cs
...atis.Bitcoin.Features.Wallet/DeStreamWalletSyncManager.cs
+4
-3
DeStreamWalletTransactionHandler.cs
...tcoin.Features.Wallet/DeStreamWalletTransactionHandler.cs
+42
-35
WalletManager.cs
Sources/Stratis.Bitcoin.Features.Wallet/WalletManager.cs
+6
-6
WalletSyncManager.cs
Sources/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs
+1
-1
WalletTransactionHandler.cs
...ratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs
+22
-10
No files found.
Sources/Stratis.Bitcoin.Features.Wallet/Controllers/DeStreamWalletController.cs
View file @
c30cdaab
...
@@ -9,6 +9,7 @@ using Stratis.Bitcoin.Features.Wallet.Interfaces;
...
@@ -9,6 +9,7 @@ using Stratis.Bitcoin.Features.Wallet.Interfaces;
using
Stratis.Bitcoin.Features.Wallet.Models
;
using
Stratis.Bitcoin.Features.Wallet.Models
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities.JsonErrors
;
using
Stratis.Bitcoin.Utilities.JsonErrors
;
using
Stratis.Bitcoin.Utilities.ModelStateErrors
;
namespace
Stratis.Bitcoin.Features.Wallet.Controllers
namespace
Stratis.Bitcoin.Features.Wallet.Controllers
{
{
...
@@ -19,15 +20,16 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -19,15 +20,16 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
public
class
DeStreamWalletController
:
Controller
public
class
DeStreamWalletController
:
Controller
{
{
private
readonly
ILogger
_logger
;
private
readonly
ILogger
_logger
;
private
readonly
Network
_network
;
private
readonly
DeStream
Network
_network
;
private
readonly
IWalletTransactionHandler
_walletTransactionHandler
;
private
readonly
IWalletTransactionHandler
_walletTransactionHandler
;
public
DeStreamWalletController
(
Network
network
,
IWalletTransactionHandler
walletTransactionHandler
,
public
DeStreamWalletController
(
Network
network
,
IWalletTransactionHandler
walletTransactionHandler
,
ILoggerFactory
loggerFactory
)
ILoggerFactory
loggerFactory
)
{
{
this
.
_network
=
network
;
this
.
_network
=
(
DeStreamNetwork
)
network
??
throw
new
NotSupportedException
(
$"Network must be
{
nameof
(
NBitcoin
.
DeStreamNetwork
)}
"
);
this
.
_walletTransactionHandler
=
walletTransactionHandler
;
this
.
_walletTransactionHandler
=
walletTransactionHandler
;
this
.
_logger
=
loggerFactory
.
CreateLogger
(
this
.
GetType
().
FullName
);
this
.
_logger
=
loggerFactory
.
CreateLogger
(
GetType
().
FullName
);
}
}
/// <summary>
/// <summary>
...
@@ -42,24 +44,36 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -42,24 +44,36 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
Guard
.
NotNull
(
request
,
nameof
(
request
));
Guard
.
NotNull
(
request
,
nameof
(
request
));
// checks the request is valid
// checks the request is valid
if
(!
this
.
ModelState
.
IsValid
)
return
WalletController
.
BuildErrorResponse
(
this
.
ModelState
);
if
(!
this
.
ModelState
.
IsValid
)
return
ModelStateErrors
.
BuildErrorResponse
(
this
.
ModelState
);
try
try
{
{
Script
destination
=
BitcoinAddress
.
Create
(
request
.
DestinationAddress
,
this
.
_network
).
ScriptPubKey
;
var
recipients
=
new
List
<
Recipient
>();
var
context
=
new
TransactionBuildContext
(
foreach
(
RecipientModel
recipientModel
in
request
.
Recipients
)
new
WalletAccountReference
(
request
.
WalletName
,
request
.
AccountName
),
recipients
.
Add
(
new
Recipient
new
[]
{
new
Recipient
{
Amount
=
request
.
Amount
,
ScriptPubKey
=
destination
}}.
ToList
(),
{
request
.
Password
,
request
.
OpReturnData
)
ScriptPubKey
=
BitcoinAddress
.
Create
(
recipientModel
.
DestinationAddress
,
this
.
_network
)
.
ScriptPubKey
,
Amount
=
recipientModel
.
Amount
});
var
context
=
new
DeStreamTransactionBuildContext
(
new
DeStreamTransactionBuilder
(
this
.
_network
))
{
{
AccountReference
=
new
WalletAccountReference
(
request
.
WalletName
,
request
.
AccountName
),
TransactionFee
=
string
.
IsNullOrEmpty
(
request
.
FeeAmount
)
?
null
:
Money
.
Parse
(
request
.
FeeAmount
),
TransactionFee
=
string
.
IsNullOrEmpty
(
request
.
FeeAmount
)
?
null
:
Money
.
Parse
(
request
.
FeeAmount
),
MinConfirmations
=
request
.
AllowUnconfirmed
?
0
:
1
,
MinConfirmations
=
request
.
AllowUnconfirmed
?
0
:
1
,
Shuffle
=
Shuffle
=
request
.
ShuffleOutputs
??
request
.
ShuffleOutputs
??
true
// We shuffle transaction outputs by default as it's better for anonymity.
true
,
// We shuffle transaction outputs by default as it's better for anonymity.
OpReturnData
=
request
.
OpReturnData
,
WalletPassword
=
request
.
Password
,
SelectedInputs
=
request
.
Outpoints
?.
Select
(
u
=>
new
OutPoint
(
uint256
.
Parse
(
u
.
TransactionId
),
u
.
Index
)).
ToList
(),
AllowOtherInputs
=
false
,
Recipients
=
recipients
};
};
this
.
ProcessFeeType
(
request
.
FeeType
,
context
.
Recipients
);
ProcessFeeType
(
request
.
FeeType
,
context
.
Recipients
);
Transaction
transactionResult
=
this
.
_walletTransactionHandler
.
BuildTransaction
(
context
);
Transaction
transactionResult
=
this
.
_walletTransactionHandler
.
BuildTransaction
(
context
);
...
@@ -70,7 +84,7 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -70,7 +84,7 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
TransactionId
=
transactionResult
.
GetHash
()
TransactionId
=
transactionResult
.
GetHash
()
};
};
return
this
.
Json
(
model
);
return
Json
(
model
);
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
...
@@ -93,21 +107,30 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -93,21 +107,30 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
Guard
.
NotNull
(
request
,
nameof
(
request
));
Guard
.
NotNull
(
request
,
nameof
(
request
));
// checks the request is valid
// checks the request is valid
if
(!
this
.
ModelState
.
IsValid
)
return
WalletController
.
BuildErrorResponse
(
this
.
ModelState
);
if
(!
this
.
ModelState
.
IsValid
)
return
ModelStateErrors
.
BuildErrorResponse
(
this
.
ModelState
);
try
try
{
{
Script
destination
=
BitcoinAddress
.
Create
(
request
.
DestinationAddress
,
this
.
_network
).
ScriptPubKey
;
var
recipients
=
new
List
<
Recipient
>();
var
context
=
new
TransactionBuildContext
(
foreach
(
RecipientModel
recipientModel
in
request
.
Recipients
)
new
WalletAccountReference
(
request
.
WalletName
,
request
.
AccountName
),
recipients
.
Add
(
new
Recipient
new
[]
{
new
Recipient
{
Amount
=
request
.
Amount
,
ScriptPubKey
=
destination
}}.
ToList
())
{
ScriptPubKey
=
BitcoinAddress
.
Create
(
recipientModel
.
DestinationAddress
,
this
.
_network
)
.
ScriptPubKey
,
Amount
=
recipientModel
.
Amount
});
var
context
=
new
TransactionBuildContext
(
this
.
_network
)
{
{
MinConfirmations
=
request
.
AllowUnconfirmed
?
0
:
1
AccountReference
=
new
WalletAccountReference
(
request
.
WalletName
,
request
.
AccountName
),
FeeType
=
FeeParser
.
Parse
(
request
.
FeeType
),
MinConfirmations
=
request
.
AllowUnconfirmed
?
0
:
1
,
Recipients
=
recipients
};
};
this
.
ProcessFeeType
(
request
.
FeeType
,
context
.
Recipients
);
ProcessFeeType
(
request
.
FeeType
,
context
.
Recipients
);
return
this
.
Json
(
this
.
_walletTransactionHandler
.
EstimateFee
(
context
));
return
Json
(
this
.
_walletTransactionHandler
.
EstimateFee
(
context
));
}
}
catch
(
Exception
e
)
catch
(
Exception
e
)
{
{
...
@@ -134,7 +157,9 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -134,7 +157,9 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
recipient
.
Amount
=
this
.
_network
.
SubtractFee
(
recipient
.
Amount
);
recipient
.
Amount
=
this
.
_network
.
SubtractFee
(
recipient
.
Amount
);
}
}
else
else
{
throw
new
FormatException
(
$"FeeType
{
requestFeeType
}
is not a valid DeStreamFeeType"
);
throw
new
FormatException
(
$"FeeType
{
requestFeeType
}
is not a valid DeStreamFeeType"
);
}
}
}
}
}
}
}
\ No newline at end of file
Sources/Stratis.Bitcoin.Features.Wallet/Controllers/WalletController.cs
View file @
c30cdaab
...
@@ -34,7 +34,7 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
...
@@ -34,7 +34,7 @@ namespace Stratis.Bitcoin.Features.Wallet.Controllers
private
readonly
CoinType
coinType
;
private
readonly
CoinType
coinType
;
/// <summary>Specification of the network the node runs on - regtest/testnet/mainnet.</summary>
/// <summary>Specification of the network the node runs on - regtest/testnet/mainnet.</summary>
summary
private
readonly
Network
network
;
private
readonly
Network
network
;
private
readonly
IConnectionManager
connectionManager
;
private
readonly
IConnectionManager
connectionManager
;
...
...
Sources/Stratis.Bitcoin.Features.Wallet/DeStreamWalletManager.cs
View file @
c30cdaab
...
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
...
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
using
NBitcoin
;
using
NBitcoin
;
using
Stratis.Bitcoin.Configuration
;
using
Stratis.Bitcoin.Configuration
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Interfaces
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities
;
namespace
Stratis.Bitcoin.Features.Wallet
namespace
Stratis.Bitcoin.Features.Wallet
...
@@ -13,12 +14,11 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -13,12 +14,11 @@ namespace Stratis.Bitcoin.Features.Wallet
public
class
DeStreamWalletManager
:
WalletManager
,
IDeStreamWalletManager
public
class
DeStreamWalletManager
:
WalletManager
,
IDeStreamWalletManager
{
{
public
DeStreamWalletManager
(
ILoggerFactory
loggerFactory
,
Network
network
,
ConcurrentChain
chain
,
public
DeStreamWalletManager
(
ILoggerFactory
loggerFactory
,
Network
network
,
ConcurrentChain
chain
,
NodeSettings
settings
,
WalletSettings
walletSettings
,
WalletSettings
walletSettings
,
DataFolder
dataFolder
,
IWalletFeePolicy
walletFeePolicy
,
DataFolder
dataFolder
,
IWalletFeePolicy
walletFeePolicy
,
IAsyncLoopFactory
asyncLoopFactory
,
IAsyncLoopFactory
asyncLoopFactory
,
INodeLifetime
nodeLifetime
,
IDateTimeProvider
dateTimeProvider
,
INodeLifetime
nodeLifetime
,
IDateTimeProvider
dateTimeProvider
,
IScriptAddressReader
scriptAddressReader
,
IBroadcasterManager
broadcasterManager
=
null
)
:
base
(
IBroadcasterManager
broadcasterManager
=
null
)
:
loggerFactory
,
network
,
chain
,
walletSettings
,
dataFolder
,
walletFeePolicy
,
asyncLoopFactory
,
nodeLifetime
,
base
(
loggerFactory
,
network
,
chain
,
settings
,
walletSettings
,
dataFolder
,
walletFeePolicy
,
asyncLoopFactory
,
dateTimeProvider
,
scriptAddressReader
,
broadcasterManager
)
nodeLifetime
,
dateTimeProvider
,
broadcasterManager
)
{
{
}
}
...
@@ -27,7 +27,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -27,7 +27,7 @@ namespace Stratis.Bitcoin.Features.Wallet
{
{
Wallet
result
=
base
.
LoadWallet
(
password
,
name
);
Wallet
result
=
base
.
LoadWallet
(
password
,
name
);
this
.
LoadKeysLookupLock
();
LoadKeysLookupLock
();
return
result
;
return
result
;
}
}
...
@@ -37,11 +37,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -37,11 +37,9 @@ namespace Stratis.Bitcoin.Features.Wallet
{
{
foreach
(
var
transactionWithOutput
in
this
.
network
.
GetGenesis
().
Transactions
.
SelectMany
(
p
=>
foreach
(
var
transactionWithOutput
in
this
.
network
.
GetGenesis
().
Transactions
.
SelectMany
(
p
=>
p
.
Outputs
.
Select
(
q
=>
new
{
Transaction
=
p
,
Output
=
q
}).
Where
(
q
=>
p
.
Outputs
.
Select
(
q
=>
new
{
Transaction
=
p
,
Output
=
q
}).
Where
(
q
=>
this
.
keysLookup
.
TryGetValue
(
q
.
Output
.
ScriptPubKey
,
out
HdAddress
_
))))
this
.
scriptToAddressLookup
.
TryGetValue
(
q
.
Output
.
ScriptPubKey
,
out
HdAddress
_
))))
{
AddTransactionToWallet
(
transactionWithOutput
.
Transaction
,
transactionWithOutput
.
Output
,
0
,
this
.
AddTransactionToWallet
(
transactionWithOutput
.
Transaction
,
transactionWithOutput
.
Output
,
0
,
this
.
network
.
GetGenesis
());
this
.
network
.
GetGenesis
());
}
}
}
protected
override
void
AddSpendingTransactionToWallet
(
Transaction
transaction
,
protected
override
void
AddSpendingTransactionToWallet
(
Transaction
transaction
,
...
@@ -51,12 +49,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -51,12 +49,9 @@ namespace Stratis.Bitcoin.Features.Wallet
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
Guard
.
NotNull
(
paidToOutputs
,
nameof
(
paidToOutputs
));
Guard
.
NotNull
(
paidToOutputs
,
nameof
(
paidToOutputs
));
this
.
logger
.
LogTrace
(
"({0}:'{1}',{2}:'{3}',{4}:{5},{6}:'{7}')"
,
nameof
(
transaction
),
transaction
.
GetHash
(),
nameof
(
spendingTransactionId
),
spendingTransactionId
,
nameof
(
spendingTransactionIndex
),
spendingTransactionIndex
,
nameof
(
blockHeight
),
blockHeight
);
// Get the transaction being spent.
// Get the transaction being spent.
TransactionData
spentTransaction
=
this
.
keysLookup
.
Values
.
Distinct
().
SelectMany
(
v
=>
v
.
Transactions
)
TransactionData
spentTransaction
=
this
.
scriptToAddressLookup
.
Values
.
Distinct
()
.
SelectMany
(
v
=>
v
.
Transactions
)
.
SingleOrDefault
(
t
=>
t
.
Id
==
spendingTransactionId
&&
t
.
Index
==
spendingTransactionIndex
);
.
SingleOrDefault
(
t
=>
t
.
Id
==
spendingTransactionId
&&
t
.
Index
==
spendingTransactionIndex
);
if
(
spentTransaction
==
null
)
if
(
spentTransaction
==
null
)
{
{
...
@@ -64,35 +59,20 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -64,35 +59,20 @@ namespace Stratis.Bitcoin.Features.Wallet
this
.
logger
.
LogTrace
(
"(-)[TX_NULL]"
);
this
.
logger
.
LogTrace
(
"(-)[TX_NULL]"
);
return
;
return
;
}
}
this
.
logger
.
LogTrace
(
spentTransaction
.
SpendingDetails
==
null
?
$"Spending UTXO '
{
spendingTransactionId
}
-
{
spendingTransactionIndex
}
' is new."
this
.
logger
.
LogTrace
(
spentTransaction
.
SpendingDetails
==
null
:
$"Spending transaction ID '
{
spendingTransactionId
}
' is being confirmed, updating."
);
?
$"Spending UTXO '
{
spendingTransactionId
}
-
{
spendingTransactionIndex
}
' is new."
:
$"Spending transaction ID '
{
spendingTransactionId
}
' is being confirmed, updating."
);
var
payments
=
new
List
<
PaymentDetails
>();
var
payments
=
new
List
<
PaymentDetails
>();
foreach
(
TxOut
paidToOutput
in
paidToOutputs
)
foreach
(
TxOut
paidToOutput
in
paidToOutputs
)
{
{
// Figure out how to retrieve the destination address.
// Figure out how to retrieve the destination address.
string
destinationAddress
=
string
.
Empty
;
string
destinationAddress
=
ScriptTemplate
scriptTemplate
=
paidToOutput
.
ScriptPubKey
.
FindTemplate
(
this
.
network
);
this
.
scriptAddressReader
.
GetAddressFromScriptPubKey
(
this
.
network
,
paidToOutput
.
ScriptPubKey
);
switch
(
scriptTemplate
.
Type
)
if
(
destinationAddress
==
string
.
Empty
)
{
if
(
this
.
scriptToAddressLookup
.
TryGetValue
(
paidToOutput
.
ScriptPubKey
,
out
HdAddress
destination
))
// Pay to PubKey can be found in outputs of staking transactions.
destinationAddress
=
destination
.
Address
;
case
TxOutType
.
TX_PUBKEY
:
PubKey
pubKey
=
PayToPubkeyTemplate
.
Instance
.
ExtractScriptPubKeyParameters
(
paidToOutput
.
ScriptPubKey
);
destinationAddress
=
pubKey
.
GetAddress
(
this
.
network
).
ToString
();
break
;
// Pay to PubKey hash is the regular, most common type of output.
case
TxOutType
.
TX_PUBKEYHASH
:
destinationAddress
=
paidToOutput
.
ScriptPubKey
.
GetDestinationAddress
(
this
.
network
).
ToString
();
break
;
case
TxOutType
.
TX_NONSTANDARD
:
case
TxOutType
.
TX_SCRIPTHASH
:
case
TxOutType
.
TX_MULTISIG
:
case
TxOutType
.
TX_NULL_DATA
:
case
TxOutType
.
TX_SEGWIT
:
break
;
}
payments
.
Add
(
new
PaymentDetails
payments
.
Add
(
new
PaymentDetails
{
{
...
@@ -114,8 +94,6 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -114,8 +94,6 @@ namespace Stratis.Bitcoin.Features.Wallet
spentTransaction
.
SpendingDetails
=
spendingDetails
;
spentTransaction
.
SpendingDetails
=
spendingDetails
;
spentTransaction
.
MerkleProof
=
null
;
spentTransaction
.
MerkleProof
=
null
;
this
.
logger
.
LogTrace
(
"(-)"
);
}
}
}
}
}
}
\ No newline at end of file
Sources/Stratis.Bitcoin.Features.Wallet/DeStreamWalletSyncManager.cs
View file @
c30cdaab
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
using
NBitcoin
;
using
NBitcoin
;
using
Stratis.Bitcoin.Features.BlockStore
;
using
Stratis.Bitcoin.Features.BlockStore
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Interfaces
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities
;
namespace
Stratis.Bitcoin.Features.Wallet
namespace
Stratis.Bitcoin.Features.Wallet
...
@@ -11,9 +12,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -11,9 +12,9 @@ namespace Stratis.Bitcoin.Features.Wallet
private
readonly
IDeStreamWalletManager
_deStreamWalletManager
;
private
readonly
IDeStreamWalletManager
_deStreamWalletManager
;
public
DeStreamWalletSyncManager
(
ILoggerFactory
loggerFactory
,
IDeStreamWalletManager
walletManager
,
public
DeStreamWalletSyncManager
(
ILoggerFactory
loggerFactory
,
IDeStreamWalletManager
walletManager
,
ConcurrentChain
chain
,
Network
network
,
IBlockStore
Cache
blockStoreCach
e
,
StoreSettings
storeSettings
,
ConcurrentChain
chain
,
Network
network
,
IBlockStore
blockStor
e
,
StoreSettings
storeSettings
,
INodeLifetime
nodeLifetime
)
:
base
(
loggerFactory
,
walletManager
,
chain
,
network
,
blockStore
Cache
,
INodeLifetime
nodeLifetime
)
:
base
(
loggerFactory
,
walletManager
,
chain
,
network
,
blockStore
,
storeSettings
,
storeSettings
,
nodeLifetime
)
nodeLifetime
)
{
{
this
.
_deStreamWalletManager
=
walletManager
;
this
.
_deStreamWalletManager
=
walletManager
;
}
}
...
...
Sources/Stratis.Bitcoin.Features.Wallet/DeStreamWalletTransactionHandler.cs
View file @
c30cdaab
...
@@ -5,7 +5,7 @@ using System.Security;
...
@@ -5,7 +5,7 @@ using System.Security;
using
Microsoft.Extensions.Caching.Memory
;
using
Microsoft.Extensions.Caching.Memory
;
using
Microsoft.Extensions.Logging
;
using
Microsoft.Extensions.Logging
;
using
NBitcoin
;
using
NBitcoin
;
using
Stratis.Bitcoin.Features.Consensus
;
using
NBitcoin.Policy
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Features.Wallet.Interfaces
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities
;
using
Stratis.Bitcoin.Utilities.Extensions
;
using
Stratis.Bitcoin.Utilities.Extensions
;
...
@@ -15,15 +15,25 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -15,15 +15,25 @@ namespace Stratis.Bitcoin.Features.Wallet
public
class
DeStreamWalletTransactionHandler
:
WalletTransactionHandler
public
class
DeStreamWalletTransactionHandler
:
WalletTransactionHandler
{
{
public
DeStreamWalletTransactionHandler
(
ILoggerFactory
loggerFactory
,
IWalletManager
walletManager
,
public
DeStreamWalletTransactionHandler
(
ILoggerFactory
loggerFactory
,
IWalletManager
walletManager
,
IWalletFeePolicy
walletFeePolicy
,
Network
network
)
:
base
(
loggerFactory
,
walletManager
,
walletFeePolicy
,
IWalletFeePolicy
walletFeePolicy
,
Network
network
,
StandardTransactionPolicy
transactionPolicy
)
:
base
(
network
)
loggerFactory
,
walletManager
,
walletFeePolicy
,
network
,
transactionPolicy
)
{
{
}
}
private
DeStreamNetwork
DeStreamNetwork
{
get
{
if
(!(
this
.
network
is
DeStreamNetwork
))
throw
new
NotSupportedException
(
$"Network must be
{
nameof
(
NBitcoin
.
DeStreamNetwork
)}
"
);
return
(
DeStreamNetwork
)
this
.
network
;
}
}
/// <inheritdoc />
/// <inheritdoc />
protected
override
void
AddFee
(
TransactionBuildContext
context
)
protected
override
void
AddFee
(
TransactionBuildContext
context
)
{
{
long
fee
=
Convert
.
ToInt64
(
context
.
Recipients
.
Sum
(
p
=>
p
.
Amount
)
*
this
.
Network
.
FeeRate
);
long
fee
=
Convert
.
ToInt64
(
context
.
Recipients
.
Sum
(
p
=>
p
.
Amount
)
*
this
.
DeStream
Network
.
FeeRate
);
context
.
TransactionFee
=
fee
;
context
.
TransactionFee
=
fee
;
context
.
TransactionBuilder
.
SendFees
(
fee
);
context
.
TransactionBuilder
.
SendFees
(
fee
);
}
}
...
@@ -56,16 +66,16 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -56,16 +66,16 @@ namespace Stratis.Bitcoin.Features.Wallet
// Here we try to create a transaction that contains all the spendable coins, leaving no room for the fee.
// Here we try to create a transaction that contains all the spendable coins, leaving no room for the fee.
// When the transaction builder throws an exception informing us that we have insufficient funds,
// When the transaction builder throws an exception informing us that we have insufficient funds,
// we use the amount we're missing as the fee.
// we use the amount we're missing as the fee.
var
context
=
new
TransactionBuildContext
(
accountReference
,
recipients
,
null
)
var
context
=
{
new
DeStreamTransactionBuildContext
(
new
DeStreamTransactionBuilder
(
this
.
DeStreamNetwork
))
FeeType
=
feeType
,
{
MinConfirmations
=
allowUnconfirmed
?
0
:
1
,
FeeType
=
feeType
,
TransactionBuilder
=
new
DeStreamTransactionBuilder
(
this
.
Network
)
MinConfirmations
=
allowUnconfirmed
?
0
:
1
};
};
this
.
AddRecipients
(
context
);
AddRecipients
(
context
);
this
.
AddCoins
(
context
);
AddCoins
(
context
);
this
.
AddFee
(
context
);
AddFee
(
context
);
// Throw an exception if this code is reached, as building a transaction without any funds for the fee should always throw an exception.
// Throw an exception if this code is reached, as building a transaction without any funds for the fee should always throw an exception.
throw
new
WalletException
(
throw
new
WalletException
(
...
@@ -97,6 +107,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -97,6 +107,9 @@ namespace Stratis.Bitcoin.Features.Wallet
}
}
else
else
{
{
if
(
string
.
IsNullOrEmpty
(
context
.
WalletPassword
))
return
;
privateKey
=
Key
.
Parse
(
wallet
.
EncryptedSeed
,
context
.
WalletPassword
,
wallet
.
Network
);
privateKey
=
Key
.
Parse
(
wallet
.
EncryptedSeed
,
context
.
WalletPassword
,
wallet
.
Network
);
this
.
privateKeyCache
.
Set
(
cacheKey
,
privateKey
.
ToString
(
wallet
.
Network
).
ToSecureString
(),
this
.
privateKeyCache
.
Set
(
cacheKey
,
privateKey
.
ToString
(
wallet
.
Network
).
ToSecureString
(),
new
TimeSpan
(
0
,
5
,
0
));
new
TimeSpan
(
0
,
5
,
0
));
...
@@ -143,8 +156,8 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -143,8 +156,8 @@ namespace Stratis.Bitcoin.Features.Wallet
// Add all coinstake transactions with enough confirmations
// Add all coinstake transactions with enough confirmations
context
.
UnspentOutputs
.
AddRange
(
this
.
walletManager
context
.
UnspentOutputs
.
AddRange
(
this
.
walletManager
.
GetSpendableTransactionsInAccount
(
context
.
AccountReference
,
.
GetSpendableTransactionsInAccount
(
context
.
AccountReference
,
this
.
Network
.
Consensus
.
Option
<
PosConsensusOptions
>(
)
((
PosConsensusOptions
)
this
.
DeStreamNetwork
.
Consensus
.
Options
)
.
GetStakeMinConfirmations
(
this
.
walletManager
.
LastBlockHeight
(),
this
.
Network
))
.
GetStakeMinConfirmations
(
this
.
walletManager
.
LastBlockHeight
(),
this
.
DeStream
Network
))
.
Where
(
p
=>
p
.
Transaction
.
IsCoinStake
??
false
)
.
Where
(
p
=>
p
.
Transaction
.
IsCoinStake
??
false
)
.
ToList
());
.
ToList
());
...
@@ -154,6 +167,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -154,6 +167,9 @@ namespace Stratis.Bitcoin.Features.Wallet
.
FirstOrDefault
(
p
=>
p
.
Transaction
.
IsCoinStake
??
false
)
.
FirstOrDefault
(
p
=>
p
.
Transaction
.
IsCoinStake
??
false
)
?.
Address
.
Pubkey
;
?.
Address
.
Pubkey
;
context
.
UnspentOutputs
=
this
.
walletManager
.
GetSpendableTransactionsInAccount
(
context
.
AccountReference
,
context
.
MinConfirmations
).
ToList
();
if
(
context
.
UnspentOutputs
.
Count
==
0
)
throw
new
WalletException
(
"No spendable transactions found."
);
if
(
context
.
UnspentOutputs
.
Count
==
0
)
throw
new
WalletException
(
"No spendable transactions found."
);
// Get total spendable balance in the account.
// Get total spendable balance in the account.
...
@@ -162,7 +178,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -162,7 +178,7 @@ namespace Stratis.Bitcoin.Features.Wallet
if
(
balance
<
totalToSend
)
if
(
balance
<
totalToSend
)
throw
new
WalletException
(
"Not enough funds."
);
throw
new
WalletException
(
"Not enough funds."
);
if
(
context
.
SelectedInputs
.
Any
())
if
(
context
.
SelectedInputs
!=
null
&&
context
.
SelectedInputs
.
Any
())
{
{
// 'SelectedInputs' are inputs that must be included in the
// 'SelectedInputs' are inputs that must be included in the
// current transaction. At this point we check the given
// current transaction. At this point we check the given
...
@@ -176,13 +192,9 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -176,13 +192,9 @@ namespace Stratis.Bitcoin.Features.Wallet
throw
new
WalletException
(
"Not all the selected inputs were found on the wallet."
);
throw
new
WalletException
(
"Not all the selected inputs were found on the wallet."
);
if
(!
context
.
AllowOtherInputs
)
if
(!
context
.
AllowOtherInputs
)
{
foreach
(
KeyValuePair
<
OutPoint
,
UnspentOutputReference
>
unspentOutputsItem
in
availableHashList
)
foreach
(
KeyValuePair
<
OutPoint
,
UnspentOutputReference
>
unspentOutputsItem
in
availableHashList
)
{
if
(!
context
.
SelectedInputs
.
Contains
(
unspentOutputsItem
.
Key
))
if
(!
context
.
SelectedInputs
.
Contains
(
unspentOutputsItem
.
Key
))
context
.
UnspentOutputs
.
Remove
(
unspentOutputsItem
.
Value
);
context
.
UnspentOutputs
.
Remove
(
unspentOutputsItem
.
Value
);
}
}
}
}
Money
sum
=
0
;
Money
sum
=
0
;
...
@@ -197,7 +209,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -197,7 +209,7 @@ namespace Stratis.Bitcoin.Features.Wallet
// If threshold is reached and the total value is above the target
// If threshold is reached and the total value is above the target
// then its safe to stop adding UTXOs to the coin list.
// then its safe to stop adding UTXOs to the coin list.
// The prim
e
ry goal is to reduce the time it takes to build a trx
// The prim
a
ry goal is to reduce the time it takes to build a trx
// when the wallet is bloated with UTXOs.
// when the wallet is bloated with UTXOs.
if
(
index
>
SendCountThresholdLimit
&&
sum
>
totalToSend
)
if
(
index
>
SendCountThresholdLimit
&&
sum
>
totalToSend
)
break
;
break
;
...
@@ -211,22 +223,17 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -211,22 +223,17 @@ namespace Stratis.Bitcoin.Features.Wallet
context
.
TransactionBuilder
.
AddCoins
(
coins
);
context
.
TransactionBuilder
.
AddCoins
(
coins
);
}
}
}
/// <inheritdoc />
public
class
DeStreamTransactionBuildContext
:
TransactionBuildContext
protected
override
void
InitializeTransactionBuilder
(
TransactionBuildContext
context
)
{
private
DeStreamTransactionBuildContext
(
Network
network
)
:
base
(
network
)
{
this
.
TransactionBuilder
=
new
DeStreamTransactionBuilder
(
network
);
}
public
DeStreamTransactionBuildContext
(
TransactionBuilder
transactionBuilder
)
:
base
(
transactionBuilder
)
{
{
Guard
.
NotNull
(
context
,
nameof
(
context
));
Guard
.
NotNull
(
context
.
Recipients
,
nameof
(
context
.
Recipients
));
Guard
.
NotNull
(
context
.
AccountReference
,
nameof
(
context
.
AccountReference
));
context
.
TransactionBuilder
=
new
DeStreamTransactionBuilder
(
this
.
Network
);
this
.
AddRecipients
(
context
);
this
.
AddOpReturnOutput
(
context
);
this
.
AddCoins
(
context
);
this
.
FindChangeAddress
(
context
);
this
.
AddSecrets
(
context
);
this
.
AddFee
(
context
);
}
}
}
}
}
}
\ No newline at end of file
Sources/Stratis.Bitcoin.Features.Wallet/WalletManager.cs
View file @
c30cdaab
...
@@ -63,7 +63,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -63,7 +63,7 @@ namespace Stratis.Bitcoin.Features.Wallet
private
readonly
INodeLifetime
nodeLifetime
;
private
readonly
INodeLifetime
nodeLifetime
;
/// <summary>Instance logger.</summary>
/// <summary>Instance logger.</summary>
pr
ivate
readonly
ILogger
logger
;
pr
otected
readonly
ILogger
logger
;
/// <summary>An object capable of storing <see cref="Wallet"/>s to the file system.</summary>
/// <summary>An object capable of storing <see cref="Wallet"/>s to the file system.</summary>
private
readonly
FileStorage
<
Wallet
>
fileStorage
;
private
readonly
FileStorage
<
Wallet
>
fileStorage
;
...
@@ -75,10 +75,10 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -75,10 +75,10 @@ namespace Stratis.Bitcoin.Features.Wallet
private
readonly
IDateTimeProvider
dateTimeProvider
;
private
readonly
IDateTimeProvider
dateTimeProvider
;
/// <summary>The settings for the wallet feature.</summary>
/// <summary>The settings for the wallet feature.</summary>
pr
ivate
readonly
WalletSettings
walletSettings
;
pr
otected
readonly
WalletSettings
walletSettings
;
/// <summary>The settings for the wallet feature.</summary>
/// <summary>The settings for the wallet feature.</summary>
pr
ivate
readonly
IScriptAddressReader
scriptAddressReader
;
pr
otected
readonly
IScriptAddressReader
scriptAddressReader
;
public
uint256
WalletTipHash
{
get
;
set
;
}
public
uint256
WalletTipHash
{
get
;
set
;
}
...
@@ -268,7 +268,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -268,7 +268,7 @@ namespace Stratis.Bitcoin.Features.Wallet
}
}
/// <inheritdoc />
/// <inheritdoc />
public
Wallet
LoadWallet
(
string
password
,
string
name
)
public
virtual
Wallet
LoadWallet
(
string
password
,
string
name
)
{
{
Guard
.
NotEmpty
(
password
,
nameof
(
password
));
Guard
.
NotEmpty
(
password
,
nameof
(
password
));
Guard
.
NotEmpty
(
name
,
nameof
(
name
));
Guard
.
NotEmpty
(
name
,
nameof
(
name
));
...
@@ -938,7 +938,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -938,7 +938,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// <param name="blockHeight">Height of the block.</param>
/// <param name="blockHeight">Height of the block.</param>
/// <param name="block">The block containing the transaction to add.</param>
/// <param name="block">The block containing the transaction to add.</param>
/// <param name="isPropagated">Propagation state of the transaction.</param>
/// <param name="isPropagated">Propagation state of the transaction.</param>
pr
ivate
void
AddTransactionToWallet
(
Transaction
transaction
,
TxOut
utxo
,
int
?
blockHeight
=
null
,
Block
block
=
null
,
bool
isPropagated
=
true
)
pr
otected
void
AddTransactionToWallet
(
Transaction
transaction
,
TxOut
utxo
,
int
?
blockHeight
=
null
,
Block
block
=
null
,
bool
isPropagated
=
true
)
{
{
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
Guard
.
NotNull
(
utxo
,
nameof
(
utxo
));
Guard
.
NotNull
(
utxo
,
nameof
(
utxo
));
...
@@ -1022,7 +1022,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -1022,7 +1022,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// <param name="spendingTransactionIndex">The index of the output in the transaction being referenced, if this is a spending transaction.</param>
/// <param name="spendingTransactionIndex">The index of the output in the transaction being referenced, if this is a spending transaction.</param>
/// <param name="blockHeight">Height of the block.</param>
/// <param name="blockHeight">Height of the block.</param>
/// <param name="block">The block containing the transaction to add.</param>
/// <param name="block">The block containing the transaction to add.</param>
pr
ivate
void
AddSpendingTransactionToWallet
(
Transaction
transaction
,
IEnumerable
<
TxOut
>
paidToOutputs
,
pr
otected
virtual
void
AddSpendingTransactionToWallet
(
Transaction
transaction
,
IEnumerable
<
TxOut
>
paidToOutputs
,
uint256
spendingTransactionId
,
int
?
spendingTransactionIndex
,
int
?
blockHeight
=
null
,
Block
block
=
null
)
uint256
spendingTransactionId
,
int
?
spendingTransactionIndex
,
int
?
blockHeight
=
null
,
Block
block
=
null
)
{
{
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
Guard
.
NotNull
(
transaction
,
nameof
(
transaction
));
...
...
Sources/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs
View file @
c30cdaab
...
@@ -19,7 +19,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -19,7 +19,7 @@ namespace Stratis.Bitcoin.Features.Wallet
private
readonly
ConcurrentChain
chain
;
private
readonly
ConcurrentChain
chain
;
/// <summary>Instance logger.</summary>
/// <summary>Instance logger.</summary>
pr
ivate
readonly
ILogger
logger
;
pr
otected
readonly
ILogger
logger
;
private
readonly
IBlockStore
blockStore
;
private
readonly
IBlockStore
blockStore
;
...
...
Sources/Stratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs
View file @
c30cdaab
...
@@ -30,17 +30,17 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -30,17 +30,17 @@ namespace Stratis.Bitcoin.Features.Wallet
/// 500 is a safe number that if reached ensures the coin selector will not take too long to complete,
/// 500 is a safe number that if reached ensures the coin selector will not take too long to complete,
/// most regular wallets will never reach such a high number of UTXO.
/// most regular wallets will never reach such a high number of UTXO.
/// </remarks>
/// </remarks>
pr
ivate
const
int
SendCountThresholdLimit
=
500
;
pr
otected
const
int
SendCountThresholdLimit
=
500
;
private
readonly
ILogger
logger
;
private
readonly
ILogger
logger
;
pr
ivate
readonly
Network
network
;
pr
otected
readonly
Network
network
;
pr
ivate
readonly
MemoryCache
privateKeyCache
;
pr
otected
readonly
MemoryCache
privateKeyCache
;
protected
readonly
StandardTransactionPolicy
TransactionPolicy
;
protected
readonly
StandardTransactionPolicy
TransactionPolicy
;
pr
ivate
readonly
IWalletManager
walletManager
;
pr
otected
readonly
IWalletManager
walletManager
;
private
readonly
IWalletFeePolicy
walletFeePolicy
;
private
readonly
IWalletFeePolicy
walletFeePolicy
;
...
@@ -129,7 +129,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -129,7 +129,7 @@ namespace Stratis.Bitcoin.Features.Wallet
}
}
/// <inheritdoc />
/// <inheritdoc />
public
(
Money
maximumSpendableAmount
,
Money
Fee
)
GetMaximumSpendableAmount
(
WalletAccountReference
accountReference
,
FeeType
feeType
,
bool
allowUnconfirmed
)
public
virtual
(
Money
maximumSpendableAmount
,
Money
Fee
)
GetMaximumSpendableAmount
(
WalletAccountReference
accountReference
,
FeeType
feeType
,
bool
allowUnconfirmed
)
{
{
Guard
.
NotNull
(
accountReference
,
nameof
(
accountReference
));
Guard
.
NotNull
(
accountReference
,
nameof
(
accountReference
));
Guard
.
NotEmpty
(
accountReference
.
WalletName
,
nameof
(
accountReference
.
WalletName
));
Guard
.
NotEmpty
(
accountReference
.
WalletName
,
nameof
(
accountReference
.
WalletName
));
...
@@ -235,8 +235,8 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -235,8 +235,8 @@ namespace Stratis.Bitcoin.Features.Wallet
this
.
AddRecipients
(
context
);
this
.
AddRecipients
(
context
);
this
.
AddOpReturnOutput
(
context
);
this
.
AddOpReturnOutput
(
context
);
this
.
AddCoins
(
context
);
this
.
AddCoins
(
context
);
this
.
AddSecrets
(
context
);
this
.
FindChangeAddress
(
context
);
this
.
FindChangeAddress
(
context
);
this
.
AddSecrets
(
context
);
this
.
AddFee
(
context
);
this
.
AddFee
(
context
);
}
}
...
@@ -244,7 +244,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -244,7 +244,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// Load's all the private keys for each of the <see cref="HdAddress"/> in <see cref="TransactionBuildContext.UnspentOutputs"/>
/// Load's all the private keys for each of the <see cref="HdAddress"/> in <see cref="TransactionBuildContext.UnspentOutputs"/>
/// </summary>
/// </summary>
/// <param name="context">The context associated with the current transaction being built.</param>
/// <param name="context">The context associated with the current transaction being built.</param>
protected
void
AddSecrets
(
TransactionBuildContext
context
)
protected
v
irtual
v
oid
AddSecrets
(
TransactionBuildContext
context
)
{
{
if
(!
context
.
Sign
)
if
(!
context
.
Sign
)
return
;
return
;
...
@@ -303,7 +303,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -303,7 +303,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// Then add them to the <see cref="TransactionBuildContext.UnspentOutputs"/>.
/// Then add them to the <see cref="TransactionBuildContext.UnspentOutputs"/>.
/// </summary>
/// </summary>
/// <param name="context">The context associated with the current transaction being built.</param>
/// <param name="context">The context associated with the current transaction being built.</param>
protected
void
AddCoins
(
TransactionBuildContext
context
)
protected
v
irtual
v
oid
AddCoins
(
TransactionBuildContext
context
)
{
{
context
.
UnspentOutputs
=
this
.
walletManager
.
GetSpendableTransactionsInAccount
(
context
.
AccountReference
,
context
.
MinConfirmations
).
ToList
();
context
.
UnspentOutputs
=
this
.
walletManager
.
GetSpendableTransactionsInAccount
(
context
.
AccountReference
,
context
.
MinConfirmations
).
ToList
();
...
@@ -389,7 +389,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -389,7 +389,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// Use the <see cref="FeeRate"/> from the <see cref="walletFeePolicy"/>.
/// Use the <see cref="FeeRate"/> from the <see cref="walletFeePolicy"/>.
/// </summary>
/// </summary>
/// <param name="context">The context associated with the current transaction being built.</param>
/// <param name="context">The context associated with the current transaction being built.</param>
protected
void
AddFee
(
TransactionBuildContext
context
)
protected
v
irtual
v
oid
AddFee
(
TransactionBuildContext
context
)
{
{
Money
fee
;
Money
fee
;
Money
minTrxFee
=
new
Money
(
this
.
network
.
MinTxFee
,
MoneyUnit
.
Satoshi
);
Money
minTrxFee
=
new
Money
(
this
.
network
.
MinTxFee
,
MoneyUnit
.
Satoshi
);
...
@@ -449,6 +449,18 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -449,6 +449,18 @@ namespace Stratis.Bitcoin.Features.Wallet
this
.
Sign
=
true
;
this
.
Sign
=
true
;
}
}
protected
TransactionBuildContext
(
TransactionBuilder
transactionBuilder
)
{
this
.
TransactionBuilder
=
transactionBuilder
;
this
.
Recipients
=
new
List
<
Recipient
>();
this
.
WalletPassword
=
string
.
Empty
;
this
.
FeeType
=
FeeType
.
Medium
;
this
.
MinConfirmations
=
1
;
this
.
SelectedInputs
=
new
List
<
OutPoint
>();
this
.
AllowOtherInputs
=
false
;
this
.
Sign
=
true
;
}
/// <summary>
/// <summary>
/// The wallet account to use for building a transaction.
/// The wallet account to use for building a transaction.
/// </summary>
/// </summary>
...
@@ -480,7 +492,7 @@ namespace Stratis.Bitcoin.Features.Wallet
...
@@ -480,7 +492,7 @@ namespace Stratis.Bitcoin.Features.Wallet
/// <summary>
/// <summary>
/// The builder used to build the current transaction.
/// The builder used to build the current transaction.
/// </summary>
/// </summary>
public
readonly
TransactionBuilder
TransactionBuilder
;
public
TransactionBuilder
TransactionBuilder
;
/// <summary>
/// <summary>
/// The change address, where any remaining funds will be sent to.
/// The change address, where any remaining funds will be sent to.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment