Author: toad
Date: 2008-04-12 15:48:26 +0000 (Sat, 12 Apr 2008)
New Revision: 19245

Modified:
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
Log:
For corrupt blocks found in fetch, blank the key in the .keys file, create a 
random key, and insert into the index at the bottom of the LRU.
(The free blocks list is lost on restart)

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2008-04-12 15:48:11 UTC (rev 
19244)
+++ trunk/freenet/src/freenet/node/Node.java    2008-04-12 15:48:26 UTC (rev 
19245)
@@ -1468,33 +1468,33 @@
                        System.out.println("Initializing CHK Datastore 
("+maxStoreKeys+" keys)");
                        chkDatastore = new CHKStore();
                        BerkeleyDBFreenetStore.construct(storeDir, true, 
suffix, maxStoreKeys, FreenetStore.TYPE_CHK, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, chkDatastore);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, chkDatastore, random);
                        Logger.normal(this, "Initializing CHK Datacache");
                        System.out.println("Initializing CHK Datacache 
("+maxCacheKeys+ ':' +maxCacheKeys+" keys)");
                        chkDatacache = new CHKStore();
                        BerkeleyDBFreenetStore.construct(storeDir, false, 
suffix, maxCacheKeys, FreenetStore.TYPE_CHK, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, chkDatacache);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, chkDatacache, random);
                        Logger.normal(this, "Initializing pubKey Datastore");
                        System.out.println("Initializing pubKey Datastore");
                        pubKeyDatastore = new PubkeyStore();
                        BerkeleyDBFreenetStore.construct(storeDir, true, 
suffix, maxStoreKeys, FreenetStore.TYPE_PUBKEY, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, pubKeyDatastore);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, pubKeyDatastore, random);
                        Logger.normal(this, "Initializing pubKey Datacache");
                        System.out.println("Initializing pubKey Datacache 
("+maxCacheKeys+" keys)");
                        pubKeyDatacache = new PubkeyStore();
                        BerkeleyDBFreenetStore.construct(storeDir, false, 
suffix, maxCacheKeys, FreenetStore.TYPE_PUBKEY, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, pubKeyDatacache);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, pubKeyDatacache, random);
                        // FIXME can't auto-fix SSK stores.
                        Logger.normal(this, "Initializing SSK Datastore");
                        System.out.println("Initializing SSK Datastore");
                        sskDatastore = new SSKStore(this);
                        BerkeleyDBFreenetStore.construct(storeDir, true, 
suffix, maxStoreKeys, FreenetStore.TYPE_SSK, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, sskDatastore);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, sskDatastore, random);
                        Logger.normal(this, "Initializing SSK Datacache");
                        System.out.println("Initializing SSK Datacache 
("+maxCacheKeys+" keys)");
                        sskDatacache = new SSKStore(this);
                        BerkeleyDBFreenetStore.construct(storeDir, false, 
suffix, maxStoreKeys, FreenetStore.TYPE_SSK, 
-                                       storeEnvironment, storeShutdownHook, 
reconstructFile, sskDatacache);
+                                       storeEnvironment, storeShutdownHook, 
reconstructFile, sskDatacache, random);
                } catch (FileNotFoundException e1) {
                        String msg = "Could not open datastore: "+e1;
                        Logger.error(this, msg, e1);

Modified: trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
===================================================================
--- trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2008-04-12 
15:48:11 UTC (rev 19244)
+++ trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2008-04-12 
15:48:26 UTC (rev 19245)
@@ -30,6 +30,8 @@
 import com.sleepycat.je.Transaction;
 import com.sleepycat.je.log.DbChecksumException;
 import com.sleepycat.je.log.LogFileNotFoundException;
+
+import freenet.crypt.RandomSource;
 import freenet.keys.KeyVerifyException;
 import freenet.node.NodeInitException;
 import freenet.node.SemiOrderedShutdownHook;
@@ -55,6 +57,7 @@
        private final File reconstructFile;
        private final int dataBlockSize; 
        private final int headerBlockSize;
+       private final RandomSource random;

        private final Environment environment;
        private final TupleBinding storeBlockTupleBinding;
@@ -98,7 +101,7 @@
        public static FreenetStore construct(File baseStoreDir, boolean 
isStore, String suffix,
                        long maxStoreKeys, short type, 
                        Environment storeEnvironment, SemiOrderedShutdownHook 
storeShutdownHook, File reconstructFile, 
-                       StoreCallback callback) throws DatabaseException, 
IOException {
+                       StoreCallback callback, RandomSource random) throws 
DatabaseException, IOException {
                // Location of new store file
                String newStoreFileName = typeName(type) + suffix + '.' + 
(isStore ? "store" : "cache");
                File newStoreFile = new File(baseStoreDir, newStoreFileName);
@@ -116,17 +119,17 @@

                System.err.println("Opening database using "+newStoreFile);
                return openStore(storeEnvironment, newDBPrefix, newStoreFile, 
lruFile, keysFile, newFixSecondaryFile, maxStoreKeys, storeShutdownHook,
-                               reconstructFile, callback);
+                               reconstructFile, callback, random);
        }

        private static FreenetStore openStore(Environment storeEnvironment, 
String newDBPrefix, File newStoreFile, File lruFile,
                        File keysFile, File newFixSecondaryFile, long 
maxStoreKeys, SemiOrderedShutdownHook storeShutdownHook, 
-                       File reconstructFile, StoreCallback callback) throws 
DatabaseException, IOException {
+                       File reconstructFile, StoreCallback callback, 
RandomSource random) throws DatabaseException, IOException {
                try {
                        // First try just opening it.
                        return new BerkeleyDBFreenetStore(storeEnvironment, 
newDBPrefix, newStoreFile, lruFile, keysFile, newFixSecondaryFile,
                                        maxStoreKeys, false, storeShutdownHook, 
reconstructFile, 
-                                       callback);
+                                       callback, random);
                } catch (DatabaseException e) {

                        // Try a reconstruct
@@ -140,7 +143,7 @@
                        // Reconstruct

                        return new BerkeleyDBFreenetStore(storeEnvironment, 
newDBPrefix, newStoreFile, lruFile, keysFile, newFixSecondaryFile, 
-                                       maxStoreKeys, storeShutdownHook, 
reconstructFile, callback);
+                                       maxStoreKeys, storeShutdownHook, 
reconstructFile, callback, random);
                }
        }

@@ -189,10 +192,11 @@
        private BerkeleyDBFreenetStore(Environment env, String prefix, File 
storeFile, File lruFile, File keysFile,
                        File fixSecondaryFile, long maxChkBlocks, boolean wipe, 
SemiOrderedShutdownHook storeShutdownHook,
                        File reconstructFile,
-                       StoreCallback callback) throws IOException, 
DatabaseException {
+                       StoreCallback callback, RandomSource random) throws 
IOException, DatabaseException {
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
                logDEBUG = Logger.shouldLog(Logger.DEBUG, this);

+               this.random = random;
                this.environment = env;
                this.name = prefix;
                this.fixSecondaryFile = fixSecondaryFile;
@@ -854,9 +858,9 @@
         */
        private BerkeleyDBFreenetStore(Environment env, String prefix, File 
storeFile, File lruFile, File keysFile,
                        File fixSecondaryFile, long maxChkBlocks, 
SemiOrderedShutdownHook storeShutdownHook, File reconstructFile,
-                       StoreCallback callback) throws DatabaseException, 
IOException {
+                       StoreCallback callback, RandomSource random) throws 
DatabaseException, IOException {
                this(env, prefix, storeFile, lruFile, keysFile, 
fixSecondaryFile, maxChkBlocks, true, storeShutdownHook,
-                               reconstructFile, callback);
+                               reconstructFile, callback, random);
        }

        private static void wipeOldDatabases(Environment env, String prefix) {
@@ -1143,15 +1147,51 @@

                        } catch(KeyVerifyException ex) {
                                Logger.normal(this, "Does not verify ("+ex+"), 
setting accessTime to 0 for : "+HexUtil.bytesToHex(routingkey), ex);
+                               synchronized(this) {
+                                       misses++;
+                               }
+                               synchronized(storeRAF) {
+                                       // Clear the key in the keys file.
+                                       byte[] buf = new byte[fullKey.length];
+                                       for(int i=0;i<buf.length;i++) buf[i] = 
0; // FIXME unnecessary?
+                                       if(keysRAF != null) {
+                                               keysRAF.seek(storeBlock.offset 
* keyLength);
+                                               keysRAF.write(buf);
+                                       }
+                               }
+
                                keysDB.delete(t, routingkeyDBE);
+                               
+                               // Insert the block into the index with a 
random key, so that it's part of the LRU.
+                               // Set the LRU to minimum - 1.
+                               
+                               long lru = getMinRecentlyUsed(t) - 1;
+                               
+                               byte[] randomKey = new byte[fullKey.length];
+                               random.nextBytes(randomKey);
+                               
+                               storeBlock = new StoreBlock(storeBlock.offset, 
lru);
+                               
+                               routingkeyDBE = new DatabaseEntry(randomKey);
+                               
+                               blockDBE = new DatabaseEntry();
+                               
storeBlockTupleBinding.objectToEntry(storeBlock, blockDBE);
+                               try {
+                                       keysDB.put(t,routingkeyDBE,blockDBE);
+                               } catch (DatabaseException e) {
+                                       Logger.error(this, "Caught database 
exception "+e+" while adding corrupt element to LRU");
+                                       addFreeBlock(storeBlock.offset, true, 
"Bogus key");
+                                       c.close();
+                                       c = null;
+                                       t.commit();
+                                       t = null;
+                                       return null;
+                               }
+
                                c.close();
                                c = null;
                                t.commit();
                                t = null;
-                               addFreeBlock(storeBlock.offset, true, "Key does 
not verify");
-                               synchronized(this) {
-                                       misses++;
-                               }
                                return null;
                        }
                        synchronized(this) {


Reply via email to