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 c60f7f93..66c42488 100644 --- a/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java +++ b/core/src/main/java/com/google/bitcoin/store/WalletProtobufSerializer.java @@ -62,6 +62,11 @@ public class WalletProtobufSerializer { private Map txMap; private WalletExtensionSerializer helper; + // Temporary hack for migrating 0.5 wallets to 0.6 wallets. In 0.5 transactions stored the height at which they + // appeared in the block chain (for the current best chain) but not the depth. In 0.6 we store both and update + // every transaction every time we receive a block, so we need to fill out depth from best chain height. + private int chainHeight; + public WalletProtobufSerializer() { txMap = new HashMap(); helper = new WalletExtensionSerializer(); @@ -136,8 +141,6 @@ public class WalletProtobufSerializer { return walletBuilder.build(); } - - private static Protos.Transaction makeTxProto(WalletTransaction wtx) { Transaction tx = wtx.getTransaction(); Protos.Transaction.Builder txBuilder = Protos.Transaction.newBuilder(); @@ -231,6 +234,16 @@ public class WalletProtobufSerializer { return new Sha256Hash(bs.toByteArray()); } + /** + * TEMPORARY API: Used for migrating 0.5 wallets to 0.6 - during deserialization we need to know the chain height + * so the depth field of transaction confidence objects can be filled out correctly. Set this before loading a + * wallet. It's only used for older wallets that lack the data already. + * + * @param chainHeight + */ + public void setChainHeight(int chainHeight) { + this.chainHeight = chainHeight; + } /** * Parses a wallet from the given stream. The stream is expected to contain a binary serialization of a @@ -242,7 +255,6 @@ public class WalletProtobufSerializer { */ public Wallet readWallet(InputStream input) throws IOException { // TODO: This method should throw more specific exception types than IllegalArgumentException. - WalletProtobufSerializer serializer = new WalletProtobufSerializer(); Protos.Wallet walletProto = parseToProto(input); // System.out.println(TextFormat.printToString(walletProto)); @@ -267,12 +279,12 @@ public class WalletProtobufSerializer { // Read all transactions and insert into the txMap. for (Protos.Transaction txProto : walletProto.getTransactionList()) { - serializer.readTransaction(txProto, params); + readTransaction(txProto, params); } // Update transaction outputs to point to inputs that spend them for (Protos.Transaction txProto : walletProto.getTransactionList()) { - WalletTransaction wtx = serializer.connectTransactionOutputs(txProto); + WalletTransaction wtx = connectTransactionOutputs(txProto); wallet.addWalletTransaction(wtx); } @@ -389,6 +401,11 @@ public class WalletProtobufSerializer { return; } confidence.setDepthInBlocks(confidenceProto.getDepth()); + } else { + // TEMPORARY CODE FOR MIGRATING 0.5 WALLETS TO 0.6 + if (chainHeight != 0) { + confidence.setDepthInBlocks(chainHeight - confidence.getAppearedAtChainHeight()); + } } if (confidenceProto.hasWorkDone()) { if (confidence.getConfidenceType() != ConfidenceType.BUILDING) { @@ -411,7 +428,7 @@ public class WalletProtobufSerializer { confidence.setOverridingTransaction(overridingTransaction); } for (Protos.PeerAddress proto : confidenceProto.getBroadcastByList()) { - InetAddress ip = null; + InetAddress ip; try { ip = InetAddress.getByAddress(proto.getIpAddress().toByteArray()); } catch (UnknownHostException e) { diff --git a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java index b1abd9ba..b4ab8a06 100644 --- a/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java +++ b/tools/src/main/java/com/google/bitcoin/tools/WalletTool.java @@ -33,6 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.spongycastle.util.encoders.Hex; +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -298,7 +299,16 @@ public class WalletTool { } try { - wallet = Wallet.loadFromFile(walletFile); + WalletProtobufSerializer loader = new WalletProtobufSerializer(); + if (chainFileName.exists()) { + // TEMPORARY MIGRATION CODE FOR 0.5 -> 0.6 TRANSITION. This will ensure the depth (but NOT workDone) + // fields gets set correctly for older wallets. + store = new BoundedOverheadBlockStore(params, chainFileName); + loader.setChainHeight(store.getChainHead().getHeight()); + System.out.println("Setting chain height for import to " + store.getChainHead().getHeight()); + store = null; + } + wallet = loader.readWallet(new BufferedInputStream(new FileInputStream(walletFile))); if (!wallet.getParams().equals(params)) { System.err.println("Wallet does not match requested network parameters: " + wallet.getParams().getId() + " vs " + params.getId());