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:
parent
5f3d3a7f84
commit
044c98e096
@ -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()
|
||||||
|
24
tools/src/main/java/org/bitcoinj/tools/NetworkEnum.java
Normal file
24
tools/src/main/java/org/bitcoinj/tools/NetworkEnum.java
Normal 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
|
||||||
|
}
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user