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;
|
package org.bitcoinj.core;
|
||||||
|
|
||||||
import com.google.common.annotations.*;
|
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.base.Objects.*;
|
import com.google.common.base.Objects.*;
|
||||||
import com.google.common.collect.*;
|
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
|
* 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 {
|
public void deserializeExtension(WalletExtension extension, byte[] data) throws Exception {
|
||||||
lock.lock();
|
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.
|
// This method exists partly to establish a lock ordering of wallet > extension.
|
||||||
extension.deserializeWalletExtension(this, data);
|
extension.deserializeWalletExtension(this, data);
|
||||||
extensions.put(extension.getWalletExtensionID(), extension);
|
extensions.put(extension.getWalletExtensionID(), extension);
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
log.error("Error during extension deserialization", throwable);
|
||||||
|
extensions.remove(extension.getWalletExtensionID());
|
||||||
|
Throwables.propagate(throwable);
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -519,10 +519,8 @@ public class WalletProtobufSerializer {
|
|||||||
wallet.deserializeExtension(extension, extProto.getData().toByteArray());
|
wallet.deserializeExtension(extension, extProto.getData().toByteArray());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (extProto.getMandatory() && requireMandatoryExtensions) {
|
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);
|
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
|
@Test
|
||||||
public void testExtensions() throws Exception {
|
public void extensions() throws Exception {
|
||||||
myWallet.addExtension(new FooWalletExtension("com.whatever.required", true));
|
myWallet.addExtension(new FooWalletExtension("com.whatever.required", true));
|
||||||
Protos.Wallet proto = new WalletProtobufSerializer().walletToProto(myWallet);
|
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.
|
// 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());
|
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)
|
@Test(expected = UnreadableWalletException.FutureVersion.class)
|
||||||
public void versions() throws Exception {
|
public void versions() throws Exception {
|
||||||
Protos.Wallet.Builder proto = Protos.Wallet.newBuilder(new WalletProtobufSerializer().walletToProto(myWallet));
|
Protos.Wallet.Builder proto = Protos.Wallet.newBuilder(new WalletProtobufSerializer().walletToProto(myWallet));
|
||||||
|
|||||||
Reference in New Issue
Block a user