From 53e3701b94b11cedbd57b5a6fc9c9f58e0a10932 Mon Sep 17 00:00:00 2001 From: Cameron Dale Date: Fri, 29 Feb 2008 13:10:46 -0800 Subject: [PATCH] Move the normalization of key lengths from the HashObject to the DHT. --- apt_dht/Hash.py | 48 ----------------------------------------- apt_dht/apt_dht.py | 4 ++-- apt_dht/interfaces.py | 7 +++++- apt_dht_Khashmir/DHT.py | 28 ++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 51 deletions(-) diff --git a/apt_dht/Hash.py b/apt_dht/Hash.py index a7a8e40..c0f73e3 100644 --- a/apt_dht/Hash.py +++ b/apt_dht/Hash.py @@ -63,18 +63,6 @@ class HashObject: self.done = True self.result = None - def _norm_hash(self, hashString, bits=None, bytes=None): - if bits is not None: - bytes = (bits - 1) // 8 + 1 - else: - if bytes is None: - raise HashError, "you must specify one of bits or bytes" - if len(hashString) < bytes: - hashString = hashString + '\000'*(bytes - len(hashString)) - elif len(hashString) > bytes: - hashString = hashString[:bytes] - return hashString - #### Methods for returning the expected hash def expected(self): """Get the expected hash.""" @@ -86,15 +74,6 @@ class HashObject: self.expHex = b2a_hex(self.expHash) return self.expHex - def normexpected(self, bits=None, bytes=None): - """Normalize the binary hash for the given length. - - You must specify one of bits or bytes. - """ - if self.expNormHash is None and self.expHash is not None: - self.expNormHash = self._norm_hash(self.expHash, bits, bytes) - return self.expNormHash - #### Methods for hashing data def new(self, force = False): """Generate a new hashing object suitable for hashing a file. @@ -186,15 +165,6 @@ class HashObject: self.fileHex = b2a_hex(self.digest()) return self.fileHex - def norm(self, bits=None, bytes=None): - """Normalize the binary hash for the given length. - - You must specify one of bits or bytes. - """ - if self.fileNormHash is None: - self.fileNormHash = self._norm_hash(self.digest(), bits, bytes) - return self.fileNormHash - def verify(self): """Verify that the added file data hash matches the expected hash.""" if self.result is None and self.fileHash is not None and self.expHash is not None: @@ -280,27 +250,9 @@ class TestHashObject(unittest.TestCase): if sys.version_info < (2, 4): skip = "skippingme" - def test_normalize(self): - h = HashObject() - h.set(h.ORDER[0], b2a_hex('12345678901234567890'), '0') - self.failUnless(h.normexpected(bits = 160) == '12345678901234567890') - h = HashObject() - h.set(h.ORDER[0], b2a_hex('12345678901234567'), '0') - self.failUnless(h.normexpected(bits = 160) == '12345678901234567\000\000\000') - h = HashObject() - h.set(h.ORDER[0], b2a_hex('1234567890123456789012345'), '0') - self.failUnless(h.normexpected(bytes = 20) == '12345678901234567890') - h = HashObject() - h.set(h.ORDER[0], b2a_hex('1234567890123456789'), '0') - self.failUnless(h.normexpected(bytes = 20) == '1234567890123456789\000') - h = HashObject() - h.set(h.ORDER[0], b2a_hex('123456789012345678901'), '0') - self.failUnless(h.normexpected(bits = 160) == '12345678901234567890') - def test_failure(self): h = HashObject() h.set(h.ORDER[0], b2a_hex('12345678901234567890'), '0') - self.failUnlessRaises(HashError, h.normexpected) self.failUnlessRaises(HashError, h.digest) self.failUnlessRaises(HashError, h.hexdigest) self.failUnlessRaises(HashError, h.update, 'gfgf') diff --git a/apt_dht/apt_dht.py b/apt_dht/apt_dht.py index 94260bd..9fa79cd 100644 --- a/apt_dht/apt_dht.py +++ b/apt_dht/apt_dht.py @@ -152,7 +152,7 @@ class AptDHT: def lookupHash(self, hash, path, d): log.msg('Looking up hash in DHT for file: %s' % path) - key = hash.normexpected(bits = config.getint(config.get('DEFAULT', 'DHT'), 'HASH_LENGTH')) + key = hash.expected() lookupDefer = self.dht.getValue(key) lookupDefer.addCallback(self.lookupHash_done, hash, path, d) @@ -195,7 +195,7 @@ class AptDHT: def store(self, hash): """Add a file to the DHT.""" - key = hash.norm(bits = config.getint(config.get('DEFAULT', 'DHT'), 'HASH_LENGTH')) + key = hash.digest() value = {'c': self.my_contact} pieces = hash.pieceDigests() if len(pieces) <= 1: diff --git a/apt_dht/interfaces.py b/apt_dht/interfaces.py index 446cd02..8cb2e69 100644 --- a/apt_dht/interfaces.py +++ b/apt_dht/interfaces.py @@ -32,10 +32,15 @@ class IDHT(Interface): def getValue(self, key): """Get a value from the DHT for the specified key. + + The length of the key may be adjusted for use with the DHT. @rtype: C{Deferred} @return: a deferred that will fire with the stored values """ def storeValue(self, key, value): - """Store a value in the DHT for the specified key.""" + """Store a value in the DHT for the specified key. + + The length of the key may be adjusted for use with the DHT. + """ diff --git a/apt_dht_Khashmir/DHT.py b/apt_dht_Khashmir/DHT.py index 48ae1f4..5f08dae 100644 --- a/apt_dht_Khashmir/DHT.py +++ b/apt_dht_Khashmir/DHT.py @@ -125,12 +125,27 @@ class DHT: self.joined = False self.khashmir.shutdown() + def _normKey(self, key, bits=None, bytes=None): + bits = self.config["HASH_LENGTH"] + if bits is not None: + bytes = (bits - 1) // 8 + 1 + else: + if bytes is None: + raise DHTError, "you must specify one of bits or bytes for normalization" + if len(key) < bytes: + key = key + '\000'*(bytes - len(key)) + elif len(key) > bytes: + key = key[:bytes] + return key + def getValue(self, key): """See L{apt_dht.interfaces.IDHT}.""" if self.config is None: raise DHTError, "configuration not loaded" if not self.joined: raise DHTError, "have not joined a network yet" + + key = self._normKey(key) d = defer.Deferred() if key not in self.retrieving: @@ -158,6 +173,7 @@ class DHT: if not self.joined: raise DHTError, "have not joined a network yet" + key = self._normKey(key) bvalue = bencode(value) if key in self.storing and bvalue in self.storing[key]: @@ -217,6 +233,18 @@ class TestSimpleDHT(unittest.TestCase): d.addCallback(self.lastDefer.callback) return self.lastDefer + def test_normKey(self): + h = self.a._normKey('12345678901234567890') + self.failUnless(h == '12345678901234567890') + h = self.a._normKey('12345678901234567') + self.failUnless(h == '12345678901234567\000\000\000') + h = self.a._normKey('1234567890123456789012345') + self.failUnless(h == '12345678901234567890') + h = self.a._normKey('1234567890123456789') + self.failUnless(h == '1234567890123456789\000') + h = self.a._normKey('123456789012345678901') + self.failUnless(h == '12345678901234567890') + def value_stored(self, result, value): self.stored -= 1 if self.stored == 0: -- 2.39.2