Skip to content

Commit

Permalink
Fixed blocking=True in TheBDM
Browse files Browse the repository at this point in the history
  • Loading branch information
etotheipi committed Dec 16, 2012
1 parent fcf8d25 commit 90b8910
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 23 deletions.
34 changes: 24 additions & 10 deletions armoryengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ def str2coin(coinStr):
UNKNOWN = -2
MIN_TX_FEE = 50000
MIN_RELAY_TX_FEE = 10000
MT_WAIT_TIME_SEC = 10;
MT_WAIT_TIMEOUT_SEC = 10;

UINT8_MAX = 2**8-1
UINT16_MAX = 2**16-1
Expand Down Expand Up @@ -10276,11 +10276,12 @@ def __init__(self, isOffline=False, blocking=False):

# Flags
self.startBDM = False
self.alwaysBlock = blocking
self.doShutdown = False
self.aboutToRescan = False
self.errorOut = 0

self.setBlocking(blocking)

self.currentActivity = 'None'

# Lists of wallets that should be checked after blockchain updates
Expand Down Expand Up @@ -10346,10 +10347,10 @@ def passthruFunc(*args, **kwargs):

if waitForReturn:
try:
out = self.outputQueue.get(True, MT_WAIT_TIME_SEC)
out = self.outputQueue.get(True, self.mtWaitSec)
return out
except Queue.Empty:
LOGERROR('BDM was not ready for your request! Waited %d sec.' % MT_WAIT_TIME_SEC)
LOGERROR('BDM was not ready for your request! Waited %d sec.' % self.mtWaitSec)
LOGERROR(' getattr name: %s', name)
LOGERROR('BDM currently doing: %s (%d)', self.currentActivity,self.currentID )
LOGERROR('Waiting for completion: ID= %d', rndID)
Expand All @@ -10371,11 +10372,11 @@ def waitForOutputIfNecessary(self, expectOutput, rndID=0):
# won't extend our wait time for this request
if expectOutput:
try:
return self.outputQueue.get(True, MT_WAIT_TIME_SEC)
return self.outputQueue.get(True, self.mtWaitSec)
except Queue.Empty:
stkOneUp = traceback.extract_stack()[-2]
filename,method = stkOneUp[0], stkOneUp[1]
LOGERROR('Waiting for BDM output that didn\'t come after %ds.' % MT_WAIT_TIME_SEC)
LOGERROR('Waiting for BDM output that didn\'t come after %ds.' % self.mtWaitSec)
LOGERROR('BDM state is currently: %s', self.getBDMState())
LOGERROR('Called from: %s:%d (%d)', os.path.basename(filename), method, rndID)
LOGERROR('BDM currently doing: %s (%d)', self.currentActivity, self.currentID)
Expand All @@ -10388,8 +10389,21 @@ def waitForOutputIfNecessary(self, expectOutput, rndID=0):


#############################################################################
def setBlocking(self, doblock=True):
self.alwaysBlock = doblock
def setBlocking(self, doblock=True, newTimeout=MT_WAIT_TIMEOUT_SEC):
"""
If we want TheBDM to behave as a single-threaded app, we need to disable
the timeouts so that long operations (such as reading the blockchain) do
not crash the process.
So setting wait=True is NOT identical to setBlocking(True), since using
wait=True with blocking=False will break when the timeout has been reached
"""
if doblock:
self.alwaysBlock = True
self.mtWaitSec = None
else:
self.alwaysBlock = False
self.mtWaitSec = newTimeout


#############################################################################
Expand Down Expand Up @@ -10721,10 +10735,10 @@ def getAddressBook(self, wlt):
self.inputQueue.put([BDMINPUTTYPE.AddrBookRequested, rndID, True, wlt])

try:
result = self.outputQueue.get(True, MT_WAIT_TIME_SEC)
result = self.outputQueue.get(True, self.mtWaitSec)
return result
except Queue.Empty:
LOGERROR('Waited %ds for addrbook to be returned. Abort' % MT_WAIT_TIME_SEC)
LOGERROR('Waited %ds for addrbook to be returned. Abort' % self.mtWaitSec)
LOGERROR('ID: getTxByHash (%d)', rndID)
#LOGERROR('Going to block until we get something...')
#return self.outputQueue.get(True)
Expand Down
52 changes: 40 additions & 12 deletions extras/sample_armory_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

from armoryengine import *
from math import sqrt
from time import sleep

run_WalletCreate = False
run_LoadBlockchain = True
run_WalletRescan = False
run_DiffChangeList = False
run_UniqueAddresses = False
run_SatoshiDice = True
run_WalletCreate = True
run_LoadBlockchain_Async = False
run_LoadBlockchain_Block = True
run_WalletRescan = True
run_DiffChangeList = False
run_UniqueAddresses = False
run_SatoshiDice = False


################################################################################
Expand All @@ -21,9 +23,9 @@

print '\n\nCreating a new C++ wallet, add a few addresses...'
cppWallet = Cpp.BtcWallet()
cppWallet.addAddress_1_( hex_to_binary('11b366edfc0a8b66feebae5c2e25a7b6a5d1cf31') ) # hash160
cppWallet.addAddress_1_( hex_to_binary('11b366edfc0a8b66feebae5c2e25a7b6a5d1cf31') ) # hash160 (hex)
cppWallet.addAddress_1_( addrStr_to_hash160('1EbAUHsitefy3rSECh8eK2fdAWTUbpVUDN') ) # addrStr
cppWallet.addAddress_1_('\x1b~\xa7*\x85\t\x12\xb7=\xd4G\xf3\xbd\xc1\x00\xf1\x00\x8b\xde\xb0') # binary
cppWallet.addAddress_1_('\x1b~\xa7*\x85\t\x12\xb7=\xd4G\xf3\xbd\xc1\x00\xf1\x00\x8b\xde\xb0') # hash160 (bin)

print 'Addresses in this wallet:'
for i in range(cppWallet.getNumAddr()):
Expand All @@ -34,11 +36,37 @@


################################################################################
if run_LoadBlockchain:
if run_LoadBlockchain_Async:
"""
By setting blocking=False, most calls to TheBDM will return immediately,
after queuing the BDM to execute the operation in the background. You have
to check back later to see when it's done. However, even when blocking is
false, any functions that return data must block so the data can be
returned. If you are in asynchronous mode, and don't want to ever wait
for anything, always check TheBDM.getBDMState()=='BlockchainReady' before
requesting data that will force blocking.
"""
start = RightNow()
BDM_LoadBlockchainFile() # optional argument to specify blk0001.dat location
TheBDM.setBlocking(False)
TheBDM.setOnlineMode(True)
print 'Waiting for blockchain loading to finish',
while not TheBDM.getBDMState()=='BlockchainReady':
print '.',
sys.stdout.flush()
sleep(2)
print 'Loading blockchain took %0.1f sec' % (RightNow() - start)

topBlock = TheBDM.getTopBlockHeight()
print '\n\nCurrent Top Block is:', topBlock
TheBDM.getTopBlockHeader().pprint()

################################################################################
if run_LoadBlockchain_Block:
start = RightNow()
TheBDM.setBlocking(True)
TheBDM.setOnlineMode(True)
# The setOnlineMode should block until blockchain loading is complete
print 'Loading blockchain took %0.1f sec' % (RightNow() - start)

topBlock = TheBDM.getTopBlockHeight()
print '\n\nCurrent Top Block is:', topBlock
Expand All @@ -47,15 +75,15 @@

################################################################################
if run_WalletRescan:
# Add new addresses -- will rescan (which will be super fast if you ahve a lot of RAM)
print 'Inducing a rescan by adding a new address and requesting...'
cppWallet.addAddress_1_( hex_to_binary('0cdcd0f388a31b11ff11b1d8d7a9f978b37bc7af') )
TheBDM.scanBlockchainForTx(cppWallet)

print '\n\nBalance of this wallet:', coin2str(cppWallet.getSpendableBalance())
print 'Unspent outputs:'
unspentTxOuts = cppWallet.getSpendableTxOutList(topBlock)
for utxo in unspentTxOuts:
utxo.pprintOneLine()
utxo.pprintOneLine(topBlock)

print '\n\nTransaction history of this wallet:'
ledger = cppWallet.getTxLedger()
Expand Down
5 changes: 4 additions & 1 deletion versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


#-------------------------------------------------------------------------------
VERSION 0.86.1
VERSION 0.86.2

- Right-click Ledger Options
Added right-click menu to ledger for quick access to transaction
Expand All @@ -26,6 +26,9 @@ VERSION 0.86.1
All fields in the primary ledger are sortable. Some fields become
unsortable as a side-effect of ledger optimizations in v0.85.

- Added Comments to Coin Control (Expert Mode)
Abbreviated comments are now show in the coin control selection
window, with full comments availble via mouse-over text.


#-------------------------------------------------------------------------------
Expand Down

0 comments on commit 90b8910

Please sign in to comment.