Browse Source

Fix bugs handling client UTXO requests

Allow strings for ints - Electrum command line doesn't convert
Don't blow away hash168s from the DB
master
Neil Booth 8 years ago
parent
commit
892e9524e5
  1. 3
      server/block_processor.py
  2. 10
      server/cache.py
  3. 10
      server/protocol.py

3
server/block_processor.py

@ -767,7 +767,8 @@ class BlockProcessor(LoggedClass):
'''Returns the hash168 for a UTXO.''' '''Returns the hash168 for a UTXO.'''
hash168 = None hash168 = None
if 0 <= index <= 65535: if 0 <= index <= 65535:
hash168 = self.utxo_cache(tx_hash, struct.pack('<H', index)) idx_packed = struct.pack('<H', index)
hash168 = self.utxo_cache.hash168(tx_hash, idx_packed)
if hash168 == NO_CACHE_ENTRY: if hash168 == NO_CACHE_ENTRY:
hash168 = None hash168 = None
return hash168 return hash168

10
server/cache.py

@ -109,7 +109,7 @@ class UTXOCache(LoggedClass):
return value return value
# Oh well. Find and remove it from the DB. # Oh well. Find and remove it from the DB.
hash168 = self.hash168(prev_hash, idx_packed) hash168 = self.hash168(prev_hash, idx_packed, True)
if not hash168: if not hash168:
return NO_CACHE_ENTRY return NO_CACHE_ENTRY
@ -144,7 +144,7 @@ class UTXOCache(LoggedClass):
raise Exception('could not resolve UTXO key collision') raise Exception('could not resolve UTXO key collision')
def hash168(self, tx_hash, idx_packed): def hash168(self, tx_hash, idx_packed, delete=False):
'''Return the hash168 paid to by the given TXO. '''Return the hash168 paid to by the given TXO.
Refers to the database. Returns None if not found (which is Refers to the database. Returns None if not found (which is
@ -158,7 +158,8 @@ class UTXOCache(LoggedClass):
return None return None
if len(data) == 25: if len(data) == 25:
self.cache_delete(key) if delete:
self.cache_delete(key)
return data[:21] return data[:21]
assert len(data) % 25 == 0 assert len(data) % 25 == 0
@ -168,7 +169,8 @@ class UTXOCache(LoggedClass):
(tx_num, ) = struct.unpack('<I', data[n+21:n+25]) (tx_num, ) = struct.unpack('<I', data[n+21:n+25])
my_hash, height = self.parent.get_tx_hash(tx_num) my_hash, height = self.parent.get_tx_hash(tx_num)
if my_hash == tx_hash: if my_hash == tx_hash:
self.cache_write(key, data[:n] + data[n+25:]) if delete:
self.cache_write(key, data[:n] + data[n+25:])
return data[n:n+21] return data[n:n+21]
raise Exception('could not resolve hash168 collision') raise Exception('could not resolve hash168 collision')

10
server/protocol.py

@ -143,8 +143,14 @@ class JSONRPC(asyncio.Protocol, LoggedClass):
@classmethod @classmethod
def non_negative_integer_from_param(cls, param): def non_negative_integer_from_param(cls, param):
if isinstance(param, int) and param >= 0: try:
return param param = int(param)
except ValueError:
pass
else:
if param >= 0:
return param
raise RPCError('param should be a non-negative integer: {}' raise RPCError('param should be a non-negative integer: {}'
.format(param)) .format(param))

Loading…
Cancel
Save