mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-02 21:47:18 +00:00
Wallet extensions: log errors when deserializing a non-mandatory extension and remove it from the wallet if deserialization throws.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
package org.bitcoinj.core;
|
||||
|
||||
import com.google.common.annotations.*;
|
||||
import com.google.common.base.*;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.*;
|
||||
import com.google.common.collect.*;
|
||||
@@ -4457,7 +4458,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
|
||||
/**
|
||||
* Deserialize the wallet extension with the supplied data and then install it, replacing any existing extension
|
||||
* that may have existed with the same ID.
|
||||
* that may have existed with the same ID. If an exception is thrown then the extension is removed from the wallet,
|
||||
* if already present.
|
||||
*/
|
||||
public void deserializeExtension(WalletExtension extension, byte[] data) throws Exception {
|
||||
lock.lock();
|
||||
@@ -4465,6 +4467,10 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// This method exists partly to establish a lock ordering of wallet > extension.
|
||||
extension.deserializeWalletExtension(this, data);
|
||||
extensions.put(extension.getWalletExtensionID(), extension);
|
||||
} catch (Throwable throwable) {
|
||||
log.error("Error during extension deserialization", throwable);
|
||||
extensions.remove(extension.getWalletExtensionID());
|
||||
Throwables.propagate(throwable);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
@@ -519,10 +519,8 @@ public class WalletProtobufSerializer {
|
||||
wallet.deserializeExtension(extension, extProto.getData().toByteArray());
|
||||
} catch (Exception e) {
|
||||
if (extProto.getMandatory() && requireMandatoryExtensions) {
|
||||
log.error("Error whilst reading extension {}, failing to read wallet", id, e);
|
||||
log.error("Error whilst reading mandatory extension {}, failing to read wallet", id);
|
||||
throw new UnreadableWalletException("Could not parse mandatory extension in wallet: " + id);
|
||||
} else {
|
||||
log.error("Error whilst reading extension {}, ignoring", id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ public class WalletProtobufSerializerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtensions() throws Exception {
|
||||
public void extensions() throws Exception {
|
||||
myWallet.addExtension(new FooWalletExtension("com.whatever.required", true));
|
||||
Protos.Wallet proto = new WalletProtobufSerializer().walletToProto(myWallet);
|
||||
// Initial extension is mandatory: try to read it back into a wallet that doesn't know about it.
|
||||
@@ -355,6 +355,35 @@ public class WalletProtobufSerializerTest {
|
||||
assertEquals(0, wallet5.getExtensions().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extensionsWithError() throws Exception {
|
||||
WalletExtension extension = new WalletExtension() {
|
||||
@Override
|
||||
public String getWalletExtensionID() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalletExtensionMandatory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serializeWalletExtension() {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeWalletExtension(Wallet containingWallet, byte[] data) throws Exception {
|
||||
throw new NullPointerException(); // Something went wrong!
|
||||
}
|
||||
};
|
||||
myWallet.addExtension(extension);
|
||||
Protos.Wallet proto = new WalletProtobufSerializer().walletToProto(myWallet);
|
||||
Wallet wallet = new WalletProtobufSerializer().readWallet(params, new WalletExtension[]{extension}, proto);
|
||||
assertEquals(0, wallet.getExtensions().size());
|
||||
}
|
||||
|
||||
@Test(expected = UnreadableWalletException.FutureVersion.class)
|
||||
public void versions() throws Exception {
|
||||
Protos.Wallet.Builder proto = Protos.Wallet.newBuilder(new WalletProtobufSerializer().walletToProto(myWallet));
|
||||
|
||||
Reference in New Issue
Block a user