/* * Copyright (c) [2016] [ <ether.camp> ] * This file is part of the ethereumJ library. * * The ethereumJ library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ethereumJ library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>. */ package org.ethereum.net.eth.message; import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; import org.ethereum.util.RLPList; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; /** * Wrapper for Ethereum STATUS message. <br> * * @see EthMessageCodes#STATUS */ public class StatusMessage extends EthMessage { protected byte protocolVersion; protected int networkId; /** * Total difficulty of the best chain as found in block header. */ protected byte[] totalDifficulty; /** * The hash of the best (i.e. highest TD) known block. */ protected byte[] bestHash; /** * The hash of the Genesis block */ protected byte[] genesisHash; public StatusMessage(byte[] encoded) { super(encoded); } public StatusMessage(byte protocolVersion, int networkId, byte[] totalDifficulty, byte[] bestHash, byte[] genesisHash) { this.protocolVersion = protocolVersion; this.networkId = networkId; this.totalDifficulty = totalDifficulty; this.bestHash = bestHash; this.genesisHash = genesisHash; this.parsed = true; } protected synchronized void parse() { if (parsed) return; RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0); this.protocolVersion = paramsList.get(0).getRLPData()[0]; byte[] networkIdBytes = paramsList.get(1).getRLPData(); this.networkId = networkIdBytes == null ? 0 : ByteUtil.byteArrayToInt(networkIdBytes); byte[] diff = paramsList.get(2).getRLPData(); this.totalDifficulty = (diff == null) ? ByteUtil.ZERO_BYTE_ARRAY : diff; this.bestHash = paramsList.get(3).getRLPData(); this.genesisHash = paramsList.get(4).getRLPData(); parsed = true; } protected void encode() { byte[] protocolVersion = RLP.encodeByte(this.protocolVersion); byte[] networkId = RLP.encodeInt(this.networkId); byte[] totalDifficulty = RLP.encodeElement(this.totalDifficulty); byte[] bestHash = RLP.encodeElement(this.bestHash); byte[] genesisHash = RLP.encodeElement(this.genesisHash); this.encoded = RLP.encodeList( protocolVersion, networkId, totalDifficulty, bestHash, genesisHash); } @Override public byte[] getEncoded() { if (encoded == null) encode(); return encoded; } @Override public Class<?> getAnswerMessage() { return null; } public byte getProtocolVersion() { parse(); return protocolVersion; } public int getNetworkId() { parse(); return networkId; } public byte[] getTotalDifficulty() { parse(); return totalDifficulty; } public BigInteger getTotalDifficultyAsBigInt() { return new BigInteger(1, getTotalDifficulty()); } public byte[] getBestHash() { parse(); return bestHash; } public byte[] getGenesisHash() { parse(); return genesisHash; } @Override public EthMessageCodes getCommand() { return EthMessageCodes.STATUS; } @Override public String toString() { parse(); return "[" + this.getCommand().name() + " protocolVersion=" + this.protocolVersion + " networkId=" + this.networkId + " totalDifficulty=" + ByteUtil.toHexString(this.totalDifficulty) + " bestHash=" + Hex.toHexString(this.bestHash) + " genesisHash=" + Hex.toHexString(this.genesisHash) + "]"; } }