Author: toad
Date: 2006-06-10 17:02:44 +0000 (Sat, 10 Jun 2006)
New Revision: 9135

Modified:
   trunk/freenet/src/freenet/node/Version.java
   trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
Log:
798: Automatically replace corrupt pubkeys, when we have the replacement.

Modified: trunk/freenet/src/freenet/node/Version.java
===================================================================
--- trunk/freenet/src/freenet/node/Version.java 2006-06-10 17:00:20 UTC (rev 
9134)
+++ trunk/freenet/src/freenet/node/Version.java 2006-06-10 17:02:44 UTC (rev 
9135)
@@ -18,7 +18,7 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 797;
+       private static final int buildNumber = 798;

        /** Oldest build of Fred we will talk to */
        private static final int lastGoodBuild = 765;

Modified: trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
===================================================================
--- trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2006-06-10 
17:00:20 UTC (rev 9134)
+++ trunk/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 2006-06-10 
17:02:44 UTC (rev 9135)
@@ -419,12 +419,17 @@

     // FIXME do this with interfaces etc.

+    public DSAPublicKey fetchPubKey(byte[] hash, boolean dontPromote) throws 
IOException {
+       return fetchPubKey(hash, null, dontPromote);
+    }
+    
        /**
      * Retrieve a block.
      * @param dontPromote If true, don't promote data if fetched.
+     * @param replacement If non-null, and the data exists but is corrupt, 
replace it with this.
      * @return null if there is no such block stored, otherwise the block.
      */
-    public DSAPublicKey fetchPubKey(byte[] hash, boolean dontPromote) throws 
IOException
+    public DSAPublicKey fetchPubKey(byte[] hash, DSAPublicKey replacement, 
boolean dontPromote) throws IOException
     {
        if(closed)
                return null;
@@ -436,7 +441,8 @@
        try{
                t = environment.beginTransaction(null,null);
                c = chkDB.openCursor(t,null);
-               
+
+               // Lock the records as soon as we find them.
                if(c.getSearchKey(routingkeyDBE,blockDBE,LockMode.RMW)
                                !=OperationStatus.SUCCESS) {
                        c.close();
@@ -445,7 +451,17 @@
                }

                StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(blockDBE);
-                               
+               
+               // Promote the key (we can always demote it later; promoting it 
here means it shouldn't be deallocated
+               // FIXME the locking/concurrency in this class is a bit dodgy!
+               
+               if(!dontPromote) {
+                       storeBlock.updateRecentlyUsed();
+                       DatabaseEntry updateDBE = new DatabaseEntry();
+                       storeBlockTupleBinding.objectToEntry(storeBlock, 
updateDBE);
+                       c.putCurrent(updateDBE);
+               }
+               
                DSAPublicKey block = null;

                        byte[] data = new byte[dataBlockSize];
@@ -464,31 +480,32 @@
                                t.abort();
                                return null;
                        }
-                       
+
                        if(!Arrays.equals(block.asBytesHash(), hash)) {
-                               Logger.error(this, "DSAPublicKey: Does not 
verify (unequal hashes), setting accessTime to 0 for : 
"+HexUtil.bytesToHex(hash));
-                               storeBlock.setRecentlyUsedToZero();
-                               DatabaseEntry updateDBE = new DatabaseEntry();
-                               
storeBlockTupleBinding.objectToEntry(storeBlock, updateDBE);
-                               c.putCurrent(updateDBE);
-                               c.close();
-                               t.commit();
-                           return null;
+                               
+                               if(replacement != null) {
+                                       Logger.normal(this, "Replacing corrupt 
DSAPublicKey ("+HexUtil.bytesToHex(hash));
+                                       synchronized(chkStore) {
+                                               
chkStore.seek(storeBlock.offset*(long)(dataBlockSize+headerBlockSize));
+                                               byte[] toWrite = 
block.asPaddedBytes();
+                                               chkStore.write(toWrite);
+                                       }
+                               } else {
+                                       Logger.error(this, "DSAPublicKey: Does 
not verify (unequal hashes), setting accessTime to 0 for : 
"+HexUtil.bytesToHex(hash));
+                                       storeBlock.setRecentlyUsedToZero();
+                                       DatabaseEntry updateDBE = new 
DatabaseEntry();
+                                       
storeBlockTupleBinding.objectToEntry(storeBlock, updateDBE);
+                                       c.putCurrent(updateDBE);
+                                       c.close();
+                                       t.commit();
+                                       return null;
+                               }
                        }
+
+                       // Finished, commit.
+                       c.close();
+                       t.commit();

-                       if(!dontPromote)
-                       {
-                               storeBlock.updateRecentlyUsed();
-                               DatabaseEntry updateDBE = new DatabaseEntry();
-                               
storeBlockTupleBinding.objectToEntry(storeBlock, updateDBE);
-                               c.putCurrent(updateDBE);
-                               c.close();
-                               t.commit();
-                       }else{
-                               c.close();
-                               t.abort();
-                       }
-                       
                        Logger.minor(this, "Get key: 
"+HexUtil.bytesToHex(hash));
                    Logger.minor(this, "Data: "+data.length+" bytes, hash 
"+data);

@@ -686,11 +703,11 @@
      * Store a pubkey.
      */
     public void put(byte[] hash, DSAPublicKey key) throws IOException {
-               DSAPublicKey k = fetchPubKey(hash, true);
+               DSAPublicKey k = fetchPubKey(hash, key, true);
                if(k == null)
                        innerPut(hash, key);
     }
-    
+
        /**
      * Store a block.
      */


Reply via email to