3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-15 03:35:52 +00:00

Support testnet and regtest in BuildCheckpoints tool.

This commit is contained in:
Devrandom 2015-06-29 20:18:13 -07:00 committed by Andreas Schildbach
parent 5f3d3a7f84
commit 044c98e096
3 changed files with 70 additions and 24 deletions

View File

@ -19,11 +19,16 @@ package org.bitcoinj.tools;
import org.bitcoinj.core.*; import org.bitcoinj.core.*;
import org.bitcoinj.params.MainNetParams; import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.store.BlockStore; import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.MemoryBlockStore; import org.bitcoinj.store.MemoryBlockStore;
import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading; import org.bitcoinj.utils.Threading;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.File; import java.io.File;
@ -46,12 +51,32 @@ import static com.google.common.base.Preconditions.checkState;
* to a file which is then signed with your key. * to a file which is then signed with your key.
*/ */
public class BuildCheckpoints { public class BuildCheckpoints {
private static NetworkParameters params;
private static final NetworkParameters PARAMS = MainNetParams.get();
private static final File PLAIN_CHECKPOINTS_FILE = new File("checkpoints");
private static final File TEXTUAL_CHECKPOINTS_FILE = new File("checkpoints.txt");
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
OptionParser parser = new OptionParser();
OptionSpec<NetworkEnum> netFlag = parser.accepts("net").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.MAIN);
OptionSpec<Integer> daysFlag = parser.accepts("days").withRequiredArg().ofType(Integer.class).defaultsTo(30);
OptionSet options = parser.parse(args);
String suffix;
switch (netFlag.value(options)) {
case MAIN:
case PROD:
params = MainNetParams.get();
suffix = "";
break;
case TEST:
params = TestNet3Params.get();
suffix = "-testnet";
break;
case REGTEST:
params = RegTestParams.get();
suffix = "-regtest";
break;
default:
throw new RuntimeException("Unreachable.");
}
BriefLogFormatter.initWithSilentBitcoinJ(); BriefLogFormatter.initWithSilentBitcoinJ();
// Sorted map of block height to StoredBlock object. // Sorted map of block height to StoredBlock object.
@ -59,22 +84,23 @@ public class BuildCheckpoints {
// Configure bitcoinj to fetch only headers, not save them to disk, connect to a local fully synced/validated // Configure bitcoinj to fetch only headers, not save them to disk, connect to a local fully synced/validated
// node and to save block headers that are on interval boundaries, as long as they are <1 month old. // node and to save block headers that are on interval boundaries, as long as they are <1 month old.
final BlockStore store = new MemoryBlockStore(PARAMS); final BlockStore store = new MemoryBlockStore(params);
final BlockChain chain = new BlockChain(PARAMS, store); final BlockChain chain = new BlockChain(params, store);
final PeerGroup peerGroup = new PeerGroup(PARAMS, chain); final PeerGroup peerGroup = new PeerGroup(params, chain);
final InetAddress peerAddress = InetAddress.getLocalHost(); final InetAddress peerAddress = InetAddress.getLocalHost();
System.out.println("Connecting to " + peerAddress + "..."); System.out.println("Connecting to " + peerAddress + "...");
peerGroup.addAddress(peerAddress); peerGroup.addAddress(peerAddress);
long now = new Date().getTime() / 1000; long now = new Date().getTime() / 1000;
peerGroup.setFastCatchupTimeSecs(now); peerGroup.setFastCatchupTimeSecs(now);
final long oneMonthAgo = now - (86400 * 30); final long timeAgo = now - (86400 * options.valueOf(daysFlag));
System.out.println("Checkpointing up to " + Utils.dateTimeFormat(timeAgo * 1000));
chain.addListener(new AbstractBlockChainListener() { chain.addListener(new AbstractBlockChainListener() {
@Override @Override
public void notifyNewBestBlock(StoredBlock block) throws VerificationException { public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
int height = block.getHeight(); int height = block.getHeight();
if (height % PARAMS.getInterval() == 0 && block.getHeader().getTimeSeconds() <= oneMonthAgo) { if (height % params.getInterval() == 0 && block.getHeader().getTimeSeconds() <= timeAgo) {
System.out.println(String.format("Checkpointing block %s at height %d", System.out.println(String.format("Checkpointing block %s at height %d",
block.getHeader().getHash(), block.getHeight())); block.getHeader().getHash(), block.getHeight()));
checkpoints.put(height, block); checkpoints.put(height, block);
@ -87,16 +113,19 @@ public class BuildCheckpoints {
checkState(checkpoints.size() > 0); checkState(checkpoints.size() > 0);
final File plainFile = new File("checkpoints" + suffix);
final File textFile = new File("checkpoints" + suffix + ".txt");
// Write checkpoint data out. // Write checkpoint data out.
writeBinaryCheckpoints(checkpoints, PLAIN_CHECKPOINTS_FILE); writeBinaryCheckpoints(checkpoints, plainFile);
writeTextualCheckpoints(checkpoints, TEXTUAL_CHECKPOINTS_FILE); writeTextualCheckpoints(checkpoints, textFile);
peerGroup.stop(); peerGroup.stop();
store.close(); store.close();
// Sanity check the created files. // Sanity check the created files.
sanityCheck(PLAIN_CHECKPOINTS_FILE, checkpoints.size()); sanityCheck(plainFile, checkpoints.size());
sanityCheck(TEXTUAL_CHECKPOINTS_FILE, checkpoints.size()); sanityCheck(textFile, checkpoints.size());
} }
private static void writeBinaryCheckpoints(TreeMap<Integer, StoredBlock> checkpoints, File file) throws Exception { private static void writeBinaryCheckpoints(TreeMap<Integer, StoredBlock> checkpoints, File file) throws Exception {
@ -139,15 +168,15 @@ public class BuildCheckpoints {
} }
private static void sanityCheck(File file, int expectedSize) throws IOException { private static void sanityCheck(File file, int expectedSize) throws IOException {
CheckpointManager manager = new CheckpointManager(PARAMS, new FileInputStream(file)); CheckpointManager manager = new CheckpointManager(params, new FileInputStream(file));
checkState(manager.numCheckpoints() == expectedSize); checkState(manager.numCheckpoints() == expectedSize);
if (PARAMS.getId().equals(NetworkParameters.ID_MAINNET)) { if (params.getId().equals(NetworkParameters.ID_MAINNET)) {
StoredBlock test = manager.getCheckpointBefore(1390500000); // Thu Jan 23 19:00:00 CET 2014 StoredBlock test = manager.getCheckpointBefore(1390500000); // Thu Jan 23 19:00:00 CET 2014
checkState(test.getHeight() == 280224); checkState(test.getHeight() == 280224);
checkState(test.getHeader().getHashAsString() checkState(test.getHeader().getHashAsString()
.equals("00000000000000000b5d59a15f831e1c45cb688a4db6b0a60054d49a9997fa34")); .equals("00000000000000000b5d59a15f831e1c45cb688a4db6b0a60054d49a9997fa34"));
} else if (PARAMS.getId().equals(NetworkParameters.ID_TESTNET)) { } else if (params.getId().equals(NetworkParameters.ID_TESTNET)) {
StoredBlock test = manager.getCheckpointBefore(1390500000); // Thu Jan 23 19:00:00 CET 2014 StoredBlock test = manager.getCheckpointBefore(1390500000); // Thu Jan 23 19:00:00 CET 2014
checkState(test.getHeight() == 167328); checkState(test.getHeight() == 167328);
checkState(test.getHeader().getHashAsString() checkState(test.getHeader().getHashAsString()

View File

@ -0,0 +1,24 @@
package org.bitcoinj.tools;
/*
* Copyright 2014 Mike Hearn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public enum NetworkEnum {
MAIN,
PROD, // alias for MAIN
TEST,
REGTEST
}

View File

@ -183,13 +183,6 @@ public class WalletTool {
BALANCE BALANCE
} }
public enum NetworkEnum {
MAIN,
PROD, // alias for MAIN
TEST,
REGTEST
}
public enum ValidationMode { public enum ValidationMode {
FULL, FULL,
SPV SPV
@ -203,7 +196,7 @@ public class WalletTool {
OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet"); OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet");
seedFlag = parser.accepts("seed").withRequiredArg(); seedFlag = parser.accepts("seed").withRequiredArg();
watchFlag = parser.accepts("watchkey").withRequiredArg(); watchFlag = parser.accepts("watchkey").withRequiredArg();
OptionSpec<NetworkEnum> netFlag = parser.accepts("net").withOptionalArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.MAIN); OptionSpec<NetworkEnum> netFlag = parser.accepts("net").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.MAIN);
dateFlag = parser.accepts("date").withRequiredArg().ofType(Date.class) dateFlag = parser.accepts("date").withRequiredArg().ofType(Date.class)
.withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd")); .withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd"));
OptionSpec<WaitForEnum> waitForFlag = parser.accepts("waitfor").withRequiredArg().ofType(WaitForEnum.class); OptionSpec<WaitForEnum> waitForFlag = parser.accepts("waitfor").withRequiredArg().ofType(WaitForEnum.class);