/*
* 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 org.bitcoinj.core;
import org.bitcoinj.params.*;
import org.bitcoinj.testing.*;
import org.bitcoinj.utils.*;
import org.junit.*;
import java.net.*;
import static org.bitcoinj.core.Coin.*;
import static org.junit.Assert.*;
public class TxConfidenceTableTest {
private static final NetworkParameters PARAMS = UnitTestParams.get();
private Transaction tx1, tx2;
private PeerAddress address1, address2, address3;
private TxConfidenceTable table;
@Before
public void setup() throws Exception {
BriefLogFormatter.init();
Context context = new Context(PARAMS);
table = context.getConfidenceTable();
Address to = new ECKey().toAddress(PARAMS);
Address change = new ECKey().toAddress(PARAMS);
tx1 = FakeTxBuilder.createFakeTxWithChangeAddress(PARAMS, COIN, to, change);
tx2 = FakeTxBuilder.createFakeTxWithChangeAddress(PARAMS, COIN, to, change);
assertEquals(tx1.getHash(), tx2.getHash());
address1 = new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }));
address2 = new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[] { 127, 0, 0, 2 }));
address3 = new PeerAddress(PARAMS, InetAddress.getByAddress(new byte[] { 127, 0, 0, 3 }));
}
@Test
public void pinHandlers() throws Exception {
Transaction tx = PARAMS.getDefaultSerializer().makeTransaction(tx1.bitcoinSerialize());
Sha256Hash hash = tx.getHash();
table.seen(hash, address1);
assertEquals(1, tx.getConfidence().numBroadcastPeers());
final int[] seen = new int[1];
tx.getConfidence().addEventListener(Threading.SAME_THREAD, new TransactionConfidence.Listener() {
@Override
public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
seen[0] = confidence.numBroadcastPeers();
}
});
tx = null;
System.gc();
table.seen(hash, address2);
assertEquals(2, seen[0]);
}
@Test
public void events() throws Exception {
final TransactionConfidence.Listener.ChangeReason[] run = new TransactionConfidence.Listener.ChangeReason[1];
tx1.getConfidence().addEventListener(Threading.SAME_THREAD, new TransactionConfidence.Listener() {
@Override
public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) {
run[0] = reason;
}
});
table.seen(tx1.getHash(), address1);
assertEquals(TransactionConfidence.Listener.ChangeReason.SEEN_PEERS, run[0]);
run[0] = null;
table.seen(tx1.getHash(), address1);
assertNull(run[0]);
}
@Test
public void invAndDownload() throws Exception {
// Base case: we see a transaction announced twice and then download it. The count is in the confidence object.
assertEquals(0, table.numBroadcastPeers(tx1.getHash()));
table.seen(tx1.getHash(), address1);
assertEquals(1, table.numBroadcastPeers(tx1.getHash()));
table.seen(tx1.getHash(), address2);
assertEquals(2, table.numBroadcastPeers(tx1.getHash()));
assertEquals(2, tx2.getConfidence().numBroadcastPeers());
// And now we see another inv.
table.seen(tx1.getHash(), address3);
assertEquals(3, tx2.getConfidence().numBroadcastPeers());
assertEquals(3, table.numBroadcastPeers(tx1.getHash()));
}
}