ForkId.java
/*
* Copyright ConsenSys AG.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.forkid;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;
import org.hyperledger.besu.util.EndianUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public class ForkId {
final Bytes hash;
final Bytes next;
Bytes forkIdRLP;
public ForkId(final Bytes hash, final Bytes next) {
this.hash = hash;
this.next = next;
createForkIdRLP();
}
public ForkId(final Bytes hash, final long next) {
this(hash, Bytes.wrap(EndianUtils.longToBigEndian(next)).trimLeadingZeros());
}
public static Optional<ForkId> fromRawForkId(final Object rawForkId) {
if (rawForkId != null) {
try {
@SuppressWarnings("unchecked")
final List<List<Bytes>> typedRawForkId = (List<List<Bytes>>) rawForkId;
return Optional.of(new ForkId(typedRawForkId.get(0).get(0), typedRawForkId.get(0).get(1)));
} catch (final Exception e) {
return Optional.empty();
}
}
return Optional.empty();
}
public long getNext() {
return next.toLong();
}
public Bytes getHash() {
return hash;
}
public List<Bytes> getForkIdAsBytesList() {
final List<Bytes> bytesList = new ArrayList<>();
bytesList.add(hash);
bytesList.add(next);
return bytesList;
}
void createForkIdRLP() {
final BytesValueRLPOutput out = new BytesValueRLPOutput();
writeTo(out);
forkIdRLP = out.encoded();
}
public void writeTo(final RLPOutput out) {
out.startList();
out.writeBytes(hash);
out.writeBytes(next);
out.endList();
}
public static ForkId readFrom(final RLPInput in) {
in.enterList();
final Bytes hash = in.readBytes();
final long next = in.readLongScalar();
in.leaveList();
return new ForkId(hash, next);
}
public List<ForkId> asList() {
final ArrayList<ForkId> forRLP = new ArrayList<>();
forRLP.add(this);
return forRLP;
}
@Override
public String toString() {
return "ForkId(hash=" + this.hash + ", next=" + next.toLong() + ")";
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof ForkId) {
final ForkId other = (ForkId) obj;
final long thisNext = next.toLong();
return other.getHash().equals(this.hash) && thisNext == other.getNext();
}
return false;
}
@Override
public int hashCode() {
return 31 * this.hash.hashCode() * this.next.hashCode();
}
}