/* * Copyright 2015 Ross Nicoll. * * 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.utils; import org.bitcoinj.core.BlockChain; import org.bitcoinj.core.Context; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.StoredBlock; import org.bitcoinj.params.UnitTestParams; import org.bitcoinj.store.BlockStore; import org.bitcoinj.store.BlockStoreException; import org.bitcoinj.store.MemoryBlockStore; import org.bitcoinj.testing.FakeTxBuilder; import org.junit.Test; import static org.junit.Assert.*; import org.junit.Before; public class VersionTallyTest { private static final NetworkParameters PARAMS = UnitTestParams.get(); public VersionTallyTest() { } @Before public void setUp() throws Exception { BriefLogFormatter.initVerbose(); Context context = new Context(PARAMS); } /** * Verify that the version tally returns null until it collects enough data. */ @Test public void testNullWhileEmpty() { VersionTally instance = new VersionTally(PARAMS); for (int i = 0; i < PARAMS.getMajorityWindow(); i++) { assertNull(instance.getCountAtOrAbove(1)); instance.add(1); } assertEquals(PARAMS.getMajorityWindow(), instance.getCountAtOrAbove(1).intValue()); } /** * Verify that the size of the version tally matches the network parameters. */ @Test public void testSize() { VersionTally instance = new VersionTally(PARAMS); assertEquals(PARAMS.getMajorityWindow(), instance.size()); } /** * Verify that version count and substitution works correctly. */ @Test public void testVersionCounts() { VersionTally instance = new VersionTally(PARAMS); // Fill the tally with 1s for (int i = 0; i < PARAMS.getMajorityWindow(); i++) { assertNull(instance.getCountAtOrAbove(1)); instance.add(1); } assertEquals(PARAMS.getMajorityWindow(), instance.getCountAtOrAbove(1).intValue()); // Check the count updates as we replace with 2s for (int i = 0; i < PARAMS.getMajorityWindow(); i++) { assertEquals(i, instance.getCountAtOrAbove(2).intValue()); instance.add(2); } // Inject a rogue 1 instance.add(1); assertEquals(PARAMS.getMajorityWindow() - 1, instance.getCountAtOrAbove(2).intValue()); // Check we accept high values as well instance.add(10); assertEquals(PARAMS.getMajorityWindow() - 1, instance.getCountAtOrAbove(2).intValue()); } @Test public void testInitialize() throws BlockStoreException { final BlockStore blockStore = new MemoryBlockStore(PARAMS); final BlockChain chain = new BlockChain(PARAMS, blockStore); // Build a historical chain of version 2 blocks long timeSeconds = 1231006505; StoredBlock chainHead = null; for (int height = 0; height < PARAMS.getMajorityWindow(); height++) { chainHead = FakeTxBuilder.createFakeBlock(blockStore, 2, timeSeconds, height).storedBlock; assertEquals(2, chainHead.getHeader().getVersion()); timeSeconds += 60; } VersionTally instance = new VersionTally(PARAMS); instance.initialize(blockStore, chainHead); assertEquals(PARAMS.getMajorityWindow(), instance.getCountAtOrAbove(2).intValue()); } }