From a807994b9a96b5aab4833210b18d35370cd33f07 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 8 Apr 2014 14:40:43 +0200 Subject: [PATCH] Bump wallet version and add missing check (!) to detect wallets from the future. The absence/incompleteness of this feature had not been noticed before, and it means that old apps will fail to read HD wallets due to the new key enum value rather than a more sensible error (but there's still no chance of an old app accepting an HD wallet, so it should still be safe). --- .../google/bitcoin/store/UnreadableWalletException.java | 4 ++++ .../com/google/bitcoin/store/WalletProtobufSerializer.java | 3 +++ .../google/bitcoin/store/WalletProtobufSerializerTest.java | 7 +++++++ core/src/wallet.proto | 2 +- 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/bitcoin/store/UnreadableWalletException.java b/core/src/main/java/com/google/bitcoin/store/UnreadableWalletException.java index 4c00bb2dc..0c9d31bcf 100644 --- a/core/src/main/java/com/google/bitcoin/store/UnreadableWalletException.java +++ b/core/src/main/java/com/google/bitcoin/store/UnreadableWalletException.java @@ -18,4 +18,8 @@ public class UnreadableWalletException extends Exception { super("Password incorrect"); } } + + public static class FutureVersion extends UnreadableWalletException { + public FutureVersion() { super("Unknown wallet version from the future."); } + } } diff --git a/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java b/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java index 98532bcdf..434bd2609 100644 --- a/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java +++ b/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java @@ -362,6 +362,9 @@ public class WalletProtobufSerializer { */ public Wallet readWallet(NetworkParameters params, @Nullable WalletExtension[] extensions, Protos.Wallet walletProto) throws UnreadableWalletException { + if (walletProto.getVersion() > 1) + throw new UnreadableWalletException.FutureVersion(); + // Read the scrypt parameters that specify how encryption and decryption is performed. KeyChainGroup chain; if (walletProto.hasEncryptionParameters()) { diff --git a/core/src/test/java/com/google/bitcoin/store/WalletProtobufSerializerTest.java b/core/src/test/java/com/google/bitcoin/store/WalletProtobufSerializerTest.java index f2a3a5a64..8905b3399 100644 --- a/core/src/test/java/com/google/bitcoin/store/WalletProtobufSerializerTest.java +++ b/core/src/test/java/com/google/bitcoin/store/WalletProtobufSerializerTest.java @@ -332,6 +332,13 @@ public class WalletProtobufSerializerTest { assertEquals(0, wallet5.getExtensions().size()); } + @Test(expected = UnreadableWalletException.FutureVersion.class) + public void versions() throws Exception { + Protos.Wallet.Builder proto = Protos.Wallet.newBuilder(new WalletProtobufSerializer().walletToProto(myWallet)); + proto.setVersion(2); + new WalletProtobufSerializer().readWallet(params, null, proto.build()); + } + private static class SomeFooExtension implements WalletExtension { private final byte[] data = new byte[]{1, 2, 3}; diff --git a/core/src/wallet.proto b/core/src/wallet.proto index 2352dd759..2847f1f1f 100644 --- a/core/src/wallet.proto +++ b/core/src/wallet.proto @@ -322,7 +322,7 @@ message Wallet { // The version number of the wallet - used to detect wallets that were produced in the future // (i.e the wallet may contain some future format this protobuf/ code does not know about) - optional int32 version = 7; + optional int32 version = 7 [default = 1]; // deprecated - do not recycle this numeric identifier // optional int32 minor_version = 8;