diff --git a/core/src/test/java/org/bitcoinj/core/StoredBlockTest.java b/core/src/test/java/org/bitcoinj/core/StoredBlockTest.java new file mode 100644 index 00000000000..5ee3c146d79 --- /dev/null +++ b/core/src/test/java/org/bitcoinj/core/StoredBlockTest.java @@ -0,0 +1,80 @@ +/* + * Copyright by the original author or authors. + * + * 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. + */ + +package org.bitcoinj.core; + +import org.junit.Test; + +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.time.Instant; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class StoredBlockTest { + + // Max chain work to fit in 12 bytes + private static final BigInteger VERY_LARGE_WORK = new BigInteger(/* 12 bytes */ "ffffffffffffffffffffffff", 16); + // Chain work too large to fit in 12 bytes + private static final BigInteger TOO_LARGE_WORK = new BigInteger(/* 13 bytes */ "ffffffffffffffffffffffffff", 16); + // Just an arbitrary block + private static final Block BLOCK = Block.createGenesis(Instant.now(), Block.EASIEST_DIFFICULTY_TARGET); + + @Test + public void roundtripSerializeCompact_zeroChainWork() { + roundtripSerializeCompact(BigInteger.ZERO); + } + + @Test + public void roundtripSerializeCompact_largeChainWork() { + roundtripSerializeCompact(BigInteger.valueOf(Long.MAX_VALUE)); + } + + @Test + public void roundtripSerializeCompact_veryLargeChainWork() { + roundtripSerializeCompact(VERY_LARGE_WORK); + } + + @Test(expected = RuntimeException.class) + public void roundtripSerializeCompact_tooLargeChainWork_shouldFail() { + roundtripSerializeCompact(TOO_LARGE_WORK); + } + + @Test(expected = RuntimeException.class) + public void roundtripSerializeCompact_negativeChainWork_shouldFail() { + roundtripSerializeCompact(BigInteger.valueOf(-1)); + } + + @Test + public void moreWorkThan() { + StoredBlock noWorkBlock = new StoredBlock(BLOCK, BigInteger.ZERO, 0); + StoredBlock smallWorkBlock = new StoredBlock(BLOCK, BigInteger.ONE, 0); + StoredBlock veryLargeWorkBlock = new StoredBlock(BLOCK, VERY_LARGE_WORK, 0); + + assertTrue(smallWorkBlock.moreWorkThan(noWorkBlock)); + assertTrue(veryLargeWorkBlock.moreWorkThan(noWorkBlock)); + assertTrue(veryLargeWorkBlock.moreWorkThan(smallWorkBlock)); + } + + private void roundtripSerializeCompact(BigInteger chainWork) { + StoredBlock block = new StoredBlock(BLOCK, chainWork, 0); + ByteBuffer buf = ByteBuffer.allocate(StoredBlock.COMPACT_SERIALIZED_SIZE); + block.serializeCompact(buf); + buf.rewind(); + assertEquals(StoredBlock.deserializeCompact(buf), block); + } +}