@ -10,12 +10,12 @@ from electrum import storage, bitcoin, keystore, bip32, slip39, wallet
from electrum import Transaction
from electrum import SimpleConfig
from electrum import util
from electrum . address_synchronizer import TX_HEIGHT_UNCONFIRMED , TX_HEIGHT_UNCONF_PARENT
from electrum . address_synchronizer import TX_HEIGHT_UNCONFIRMED , TX_HEIGHT_UNCONF_PARENT , TX_HEIGHT_LOCAL
from electrum . wallet import ( sweep , Multisig_Wallet , Standard_Wallet , Imported_Wallet ,
restore_wallet_from_text , Abstract_Wallet , CannotBumpFee , BumpFeeStrategy ,
TransactionPotentiallyDangerousException , TransactionDangerousException ,
TxSighashRiskLevel )
from electrum . util import bfh , NotEnoughFunds , UnrelatedTransactionException , UserFacingException
from electrum . util import bfh , NotEnoughFunds , UnrelatedTransactionException , UserFacingException , TxMinedInfo
from electrum . transaction import Transaction , PartialTxOutput , tx_from_any , Sighash
from electrum . mnemonic import calc_seed_type
from electrum . network import Network
@ -4183,6 +4183,70 @@ class TestWalletHistory_DoubleSpend(ElectrumTestCase):
self . assertEqual ( 999890 , sum ( w . get_balance ( ) ) )
class TestWalletHistory_HelperFns ( ElectrumTestCase ) :
TESTNET = True
def setUp ( self ) :
super ( ) . setUp ( )
self . config = SimpleConfig ( { ' electrum_path ' : self . electrum_path } )
@mock . patch . object ( wallet . Abstract_Wallet , ' save_db ' )
async def test_get_tx_status_feerate_for_local_2of3_multisig_partial_tx ( self , mock_save_db ) :
wallet1 = WalletIntegrityHelper . create_multisig_wallet (
[
keystore . from_seed ( ' bitter grass shiver impose acquire brush forget axis eager alone wine silver ' , passphrase = ' ' , for_multisig = True ) ,
keystore . from_xpub ( ' Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf ' ) ,
keystore . from_xpub ( ' Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra ' )
] ,
' 2of3 ' , gap_limit = 2 ,
config = self . config ,
)
# bootstrap wallet1
funding_tx = Transaction ( ' 01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300 ' )
wallet1 . adb . receive_tx_callback ( funding_tx , TX_HEIGHT_UNCONFIRMED )
# wallet1 -> wallet2
outputs = [ PartialTxOutput . from_address_and_value ( " 2MuUcGmQ2mLN3vjTuqDSgZpk4LPKDsuPmhN " , 165000 ) ]
tx = wallet1 . create_transaction ( outputs = outputs , password = None , fee = 5000 , tx_version = 1 , rbf = False , sign = False )
self . assertEqual (
" wsh(sortedmulti(2,[b2e35a7d/1h]tpubD9aPYLPPYw8MxU3cD57LwpV5v7GomHxdv62MSbPcRkp47zwXx69ACUFsKrj8xzuzRrij9FWVhfvkvNqtqsr8ZtefkDsGZ9GLuHzoS6bXyk1/0/0,[53b77ddb/1h]tpubD8spLJysN7v7V1KHvkZ7AwjnXShKafopi7Vu3Ahs2S46FxBPTode8DgGxDo55k4pJvETGScZFwnM5f2Y31EUjteJdhxR73sjr9ieydgah2U/0/0,[43067d63/1h]tpubD8khd1g1tzFeKeaU59QV811hyvhwn9KDfy5sqFJ5m2wJLw6rUt4AZviqutRPXTUAK4SpU2we3y2WBP916Ma8Em4qFGcbYkFvXVfpGYV3oZR/0/0)) " ,
tx . inputs ( ) [ 0 ] . script_descriptor . to_string_no_checksum ( ) )
partial_tx = tx . serialize_as_bytes ( ) . hex ( )
self . assertEqual ( " 70736274ff01007e0100000001213e1012a461e056752fab5a6414a2fb63f950cd21a50ac5e2b82d339d6cbdd20000000000feffffff023075000000000000220020cc5e4cc05a76d0648cd0742768556317e9f8cc729aed077134287909035dba88888402000000000017a914187842cea9c15989a51ce7ca889a08b824bf874387000000000001012b400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c0100eb01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c1130001056952210223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa210273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e2102aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae94153ae22060223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa10b2e35a7d01000080000000000000000022060273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e1053b77ddb010000800000000000000000220602aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae9411043067d6301000080000000000000000000010169522102174696a58a8dcd6c6455bd25e0749e9a6fc7d84ee09e192ab37b0d0b18c2de1a2102c807a19ca6783261f8c198ffcc437622e7ecba8d6c5692f3a5e7f1e45af53fd52102eee40c7e24d89639182db32f5e9188613e4bc212da2ee9b4ccc85d9b82e1a98053ae220202174696a58a8dcd6c6455bd25e0749e9a6fc7d84ee09e192ab37b0d0b18c2de1a1053b77ddb010000800100000000000000220202c807a19ca6783261f8c198ffcc437622e7ecba8d6c5692f3a5e7f1e45af53fd51043067d63010000800100000000000000220202eee40c7e24d89639182db32f5e9188613e4bc212da2ee9b4ccc85d9b82e1a98010b2e35a7d0100008001000000000000000000 " ,
partial_tx )
tx = tx_from_any ( partial_tx ) # simulates moving partial txn between cosigners
self . assertFalse ( tx . is_complete ( ) )
wallet1 . adb . add_transaction ( tx )
# let's see if the calculated feerate correct:
self . assertEqual ( ( 3 , ' Local [26.3 sat/vB] ' ) ,
wallet1 . get_tx_status ( tx . txid ( ) , TxMinedInfo ( height = TX_HEIGHT_LOCAL , conf = 0 ) ) )
@mock . patch . object ( wallet . Abstract_Wallet , ' save_db ' )
async def test_get_tx_status_feerate_for_local_2of3_multisig_signed_tx ( self , mock_save_db ) :
wallet1 = WalletIntegrityHelper . create_multisig_wallet (
[
keystore . from_seed ( ' bitter grass shiver impose acquire brush forget axis eager alone wine silver ' , passphrase = ' ' , for_multisig = True ) ,
keystore . from_xpub ( ' Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf ' ) ,
keystore . from_xpub ( ' Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra ' )
] ,
' 2of3 ' , gap_limit = 2 ,
config = self . config ,
)
# bootstrap wallet1
funding_tx = Transaction ( ' 01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300 ' )
wallet1 . adb . receive_tx_callback ( funding_tx , TX_HEIGHT_UNCONFIRMED )
# wallet1 -> wallet2
tx = tx_from_any ( " 01000000000101213e1012a461e056752fab5a6414a2fb63f950cd21a50ac5e2b82d339d6cbdd20000000000feffffff023075000000000000220020cc5e4cc05a76d0648cd0742768556317e9f8cc729aed077134287909035dba88888402000000000017a914187842cea9c15989a51ce7ca889a08b824bf8743870400473044022055cb04fa71c4b5955724d7ac5da90436d75212e7847fc121cb588f54bcdffdc4022064eca1ad639b7c748101059dc69f2893abb3b396bcf9c13f670415076f93ddbf01473044022009230e456724f2a4c10d886c836eeec599b21db0bf078aa8fc8c95868b8920ec02200dfda835a66acb5af50f0d95fcc4b76c6e8f4789a7184c182275b087d1efe556016952210223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa210273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e2102aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae94153ae00000000 " )
wallet1 . adb . add_transaction ( tx )
# let's see if the calculated feerate correct:
self . assertEqual ( ( 3 , ' Local [26.3 sat/vB] ' ) ,
wallet1 . get_tx_status ( tx . txid ( ) , TxMinedInfo ( height = TX_HEIGHT_LOCAL , conf = 0 ) ) )
class TestImportedWallet ( ElectrumTestCase ) :
TESTNET = True
transactions = {