/** * Copyright 2012 Google Inc. * * 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 com.google.devcoin.core; import com.google.devcoin.core.AbstractBlockChain.NewBlockType; import com.google.devcoin.core.Wallet.BalanceType; import com.google.devcoin.params.MainNetParams; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; /** * Test that an example production coinbase transactions can be added to a wallet ok. */ public class CoinbaseBlockTest { static final NetworkParameters params = MainNetParams.get(); // The address for this private key is 1GqtGtn4fctXuKxsVzRPSLmYWN1YioLi9y. private static final String MINING_PRIVATE_KEY = "5JDxPrBRghF1EvSBjDigywqfmAjpHPmTJxYtQTYJxJRHLLQA4mG"; private static final int BLOCK_OF_INTEREST = 169482; private static final int BLOCK_LENGTH_AS_HEX = 37357; private static final long BLOCK_NONCE = 3973947400L; private static final BigInteger BALANCE_AFTER_BLOCK = BigInteger.valueOf(22223642); @Test public void testReceiveCoinbaseTransaction() throws Exception { // Block 169482 (hash 0000000000000756935f1ee9d5987857b604046f846d3df56d024cdb5f368665) // contains coinbase transactions that are mining pool shares. // The private key MINERS_KEY is used to check transactions are received by a wallet correctly. byte[] blockAsBytes = getBytes(getClass().getResourceAsStream("block169482.dat")); // Create block 169482. Block block = new Block(params, blockAsBytes); // Check block. assertNotNull(block); block.verify(); assertEquals(BLOCK_NONCE, block.getNonce()); StoredBlock storedBlock = new StoredBlock(block, BigInteger.ONE, BLOCK_OF_INTEREST); // Nonsense work - not used in test. // Create a wallet contain the miner's key that receives a spend from a coinbase. ECKey miningKey = (new DumpedPrivateKey(params, MINING_PRIVATE_KEY)).getKey(); assertNotNull(miningKey); Wallet wallet = new Wallet(params); wallet.addKey(miningKey); // Initial balance should be zero by construction. assertEquals(BigInteger.ZERO, wallet.getBalance()); // Give the wallet the first transaction in the block - this is the coinbase tx. List<Transaction> transactions = block.getTransactions(); assertNotNull(transactions); wallet.receiveFromBlock(transactions.get(0), storedBlock, NewBlockType.BEST_CHAIN, 0); // Coinbase transaction should have been received successfully but be unavailable to spend (too young). assertEquals(BALANCE_AFTER_BLOCK, wallet.getBalance(BalanceType.ESTIMATED)); assertEquals(BigInteger.ZERO, wallet.getBalance(BalanceType.AVAILABLE)); } /** * Returns the contents of the InputStream as a byte array. */ private byte[] getBytes(InputStream inputStream) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int numberRead; byte[] data = new byte[BLOCK_LENGTH_AS_HEX]; while ((numberRead = inputStream.read(data, 0, data.length)) != -1) { buffer.write(data, 0, numberRead); } buffer.flush(); return buffer.toByteArray(); } }