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.
*/