001package org.consensusj.bitcoin.json.pojo;
002
003import com.fasterxml.jackson.annotation.JsonCreator;
004import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
005import com.fasterxml.jackson.annotation.JsonProperty;
006import org.bitcoinj.base.BitcoinNetwork;
007import org.bitcoinj.base.Network;
008import org.bitcoinj.base.Sha256Hash;
009
010import java.math.BigDecimal;
011
012/**
013 * POJO for `getblockchaininfo` RPC response.
014 */
015public class BlockChainInfo {
016    private final String      chain;
017    private final int         blocks;
018    private final int         headers;
019    private final Sha256Hash  bestBlockHash;
020    private final BigDecimal  difficulty;
021    private final BigDecimal  verificationProgress;
022    private final byte[]      chainWork;
023
024    @JsonCreator
025    public BlockChainInfo(@JsonProperty("chain")            String chain,
026                          @JsonProperty("blocks")           int blocks,
027                          @JsonProperty("headers")          int headers,
028                          @JsonProperty("bestblockhash")        Sha256Hash bestBlockHash,
029                          @JsonProperty("difficulty")           BigDecimal difficulty,
030                          @JsonProperty("verificationprogress") BigDecimal verificationProgress,
031                          @JsonProperty("chainwork")            byte[] chainWork) {
032        this.chain = chain;
033        this.blocks = blocks;
034        this.headers = headers;
035        this.bestBlockHash = bestBlockHash;
036        this.difficulty = difficulty;
037        this.verificationProgress = verificationProgress;
038        this.chainWork = chainWork;
039    }
040
041    /**
042     *
043     * @return a short string identifying which chain (Note: this differs from {@link BitcoinNetwork#toString()}
044     */
045    public String getChain() {
046        return chain;
047    }
048
049    public int getBlocks() {
050        return blocks;
051    }
052
053    public int getHeaders() {
054        return headers;
055    }
056
057    public Sha256Hash getBestBlockHash() {
058        return bestBlockHash;
059    }
060
061    public BigDecimal getDifficulty() {
062        return difficulty;
063    }
064
065    public BigDecimal getVerificationProgress() {
066        return verificationProgress;
067    }
068
069    public byte[] getChainWork() {
070        return chainWork;
071    }
072
073    /**
074     * Map a BlockChainInfo chain string to a Network. These strings are different from the standard values
075     * in {@link BitcoinNetwork#toString()}.
076     * @param info {@code BlockChainInfo}
077     * @return the matching network.
078     */
079    public static Network chainToNetwork(BlockChainInfo info) {
080        Network network;
081        switch(info.getChain()) {
082            case "main":
083                network = BitcoinNetwork.MAINNET;
084                break;
085            case "test":
086                network = BitcoinNetwork.TESTNET;
087                break;
088            case "signet":
089                network = BitcoinNetwork.SIGNET;
090                break;
091            case "regtest":
092                network = BitcoinNetwork.REGTEST;
093                break;
094            default:
095                throw new RuntimeException("BlockChainInfo contains unrecognized Bitcoin network");
096        }
097        return network;
098    }
099
100    /**
101     * Map {@link BitcoinNetwork} to a chain-id string.
102     * Bitcoin Core returns strings that differ from {@link BitcoinNetwork#toString()}.
103     * @param network bitcoinj enum type
104     * @return Bitcoin Core-compatible <q>chain</q> string
105     */
106    public static String networkToChainName(BitcoinNetwork network) {
107        String name;
108        switch(network) {
109            case MAINNET:
110                name = "main";
111                break;
112            case TESTNET:
113                name = "test";
114                break;
115            default:
116                name = network.toString();
117                break;
118        };
119        return name;
120    }
121}