3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 02: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.params.MainNetParams;
import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.MemoryBlockStore;
import org.bitcoinj.utils.BriefLogFormatter;
import org.bitcoinj.utils.Threading;
import com.google.common.base.Charsets;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import java.io.DataOutputStream;
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.
*/
public class BuildCheckpoints {
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");
private static NetworkParameters params;
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();
// 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
// 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 BlockChain chain = new BlockChain(PARAMS, store);
final PeerGroup peerGroup = new PeerGroup(PARAMS, chain);
final BlockStore store = new MemoryBlockStore(params);
final BlockChain chain = new BlockChain(params, store);
final PeerGroup peerGroup = new PeerGroup(params, chain);
final InetAddress peerAddress = InetAddress.getLocalHost();
System.out.println("Connecting to " + peerAddress + "...");
peerGroup.addAddress(peerAddress);
long now = new Date().getTime() / 1000;
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() {
@Override
public void notifyNewBestBlock(StoredBlock block) throws VerificationException {
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",
block.getHeader().getHash(), block.getHeight()));
checkpoints.put(height, block);
@ -87,16 +113,19 @@ public class BuildCheckpoints {
checkState(checkpoints.size() > 0);
final File plainFile = new File("checkpoints" + suffix);
final File textFile = new File("checkpoints" + suffix + ".txt");
// Write checkpoint data out.
writeBinaryCheckpoints(checkpoints, PLAIN_CHECKPOINTS_FILE);
writeTextualCheckpoints(checkpoints, TEXTUAL_CHECKPOINTS_FILE);
writeBinaryCheckpoints(checkpoints, plainFile);
writeTextualCheckpoints(checkpoints, textFile);
peerGroup.stop();
store.close();
// Sanity check the created files.
sanityCheck(PLAIN_CHECKPOINTS_FILE, checkpoints.size());
sanityCheck(TEXTUAL_CHECKPOINTS_FILE, checkpoints.size());
sanityCheck(plainFile, checkpoints.size());
sanityCheck(textFile, checkpoints.size());
}
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 {
CheckpointManager manager = new CheckpointManager(PARAMS, new FileInputStream(file));
CheckpointManager manager = new CheckpointManager(params, new FileInputStream(file));
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
checkState(test.getHeight() == 280224);
checkState(test.getHeader().getHashAsString()
.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
checkState(test.getHeight() == 167328);
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
}
public enum NetworkEnum {
MAIN,
PROD, // alias for MAIN
TEST,
REGTEST
}
public enum ValidationMode {
FULL,
SPV
@ -203,7 +196,7 @@ public class WalletTool {
OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet");
seedFlag = parser.accepts("seed").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)
.withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd"));
OptionSpec<WaitForEnum> waitForFlag = parser.accepts("waitfor").withRequiredArg().ofType(WaitForEnum.class);