Skip to content

Commit

Permalink
FAB-9777 Trans not handled correctly in non trans
Browse files Browse the repository at this point in the history
Change-Id: Id882debc3ffe87e9bbecd6da94adc02b67ee29df
Signed-off-by: rickr <cr22rc@gmail.com>
  • Loading branch information
cr22rc committed Apr 29, 2018
1 parent f5f7043 commit 3eaa57d
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 11 deletions.
35 changes: 26 additions & 9 deletions src/main/java/org/hyperledger/fabric/sdk/BlockEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,18 @@ boolean isBlockEvent() {
}

TransactionEvent getTransactionEvent(int index) throws InvalidProtocolBufferException {
TransactionEvent ret = null;

EnvelopeInfo envelopeInfo = getEnvelopeInfo(index);
if (envelopeInfo.getType() == EnvelopeType.TRANSACTION_ENVELOPE) {
if (isFiltered()) {
ret = new TransactionEvent(getEnvelopeInfo(index).filteredTx);
} else {
ret = new TransactionEvent((TransactionEnvelopeInfo) getEnvelopeInfo(index));
}
}

return isFiltered() ? new TransactionEvent(getEnvelopeInfo(index).filteredTx) :
new TransactionEvent((TransactionEnvelopeInfo) getEnvelopeInfo(index));
return ret;
}

public class TransactionEvent extends TransactionEnvelopeInfo {
Expand Down Expand Up @@ -147,7 +156,7 @@ public Peer getPeer() {

List<TransactionEvent> getTransactionEventsList() {

ArrayList<TransactionEvent> ret = new ArrayList<TransactionEvent>(getEnvelopeCount());
ArrayList<TransactionEvent> ret = new ArrayList<TransactionEvent>(getTransactionCount());
for (TransactionEvent transactionEvent : getTransactionEvents()) {
ret.add(transactionEvent);
}
Expand All @@ -165,29 +174,37 @@ public Iterable<TransactionEvent> getTransactionEvents() {
class TransactionEventIterator implements Iterator<TransactionEvent> {
final int max;
int ci = 0;
int returned = 0;

TransactionEventIterator() {
max = getEnvelopeCount();

max = getTransactionCount();
}

@Override
public boolean hasNext() {
return ci < max;
return returned < max;

}

@Override
public TransactionEvent next() {

TransactionEvent ret = null;
// Filter for only transactions but today it's not really needed.
// Blocks with transactions only has transactions or a single pdate.
try {
return getTransactionEvent(ci++);
do {

ret = getTransactionEvent(ci++);

} while (ret == null);

} catch (InvalidProtocolBufferException e) {
throw new InvalidProtocolBufferRuntimeException(e);
}

++returned;
return ret;
}

}

class TransactionEventIterable implements Iterable<TransactionEvent> {
Expand Down
47 changes: 47 additions & 0 deletions src/main/java/org/hyperledger/fabric/sdk/BlockInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import static java.lang.String.format;
import static org.hyperledger.fabric.protos.peer.FabricProposalResponse.Endorsement;
import static org.hyperledger.fabric.sdk.BlockInfo.EnvelopeType.TRANSACTION_ENVELOPE;

/**
* BlockInfo contains the data from a {@link Block}
Expand Down Expand Up @@ -140,6 +141,52 @@ public int getEnvelopeCount() {
return isFiltered() ? filteredBlock.getFilteredTransactionsCount() : block.getData().getDataCount();
}

private int transactionCount = -1;

/**
* Number of endorser transaction found in the block.
*
* @return Number of endorser transaction found in the block.
*/

public int getTransactionCount() {
if (isFiltered()) {

int ltransactionCount = transactionCount;
if (ltransactionCount < 0) {
ltransactionCount = 0;

for (int i = filteredBlock.getFilteredTransactionsCount() - 1; i >= 0; --i) {
FilteredTransaction filteredTransactions = filteredBlock.getFilteredTransactions(i);
Common.HeaderType type = filteredTransactions.getType();
if (type == Common.HeaderType.ENDORSER_TRANSACTION) {
++ltransactionCount;
}
}
transactionCount = ltransactionCount;
}

return transactionCount;
}
int ltransactionCount = transactionCount;
if (ltransactionCount < 0) {

ltransactionCount = 0;
for (int i = getEnvelopeCount() - 1; i >= 0; --i) {
try {
EnvelopeInfo envelopeInfo = getEnvelopeInfo(i);
if (envelopeInfo.getType() == TRANSACTION_ENVELOPE) {
++ltransactionCount;
}
} catch (InvalidProtocolBufferException e) {
throw new InvalidProtocolBufferRuntimeException(e);
}
}
transactionCount = ltransactionCount;
}
return transactionCount;
}

/**
* Wrappers Envelope
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ void blockWalker(HFClient client, Channel channel) throws InvalidArgumentExcepti
assertEquals(1, envelopeCount);
out("current block number %d has %d envelope count:", blockNumber, returnedBlock.getEnvelopeCount());
int i = 0;
int transactionCount = 0;
for (BlockInfo.EnvelopeInfo envelopeInfo : returnedBlock.getEnvelopeInfos()) {
++i;

Expand All @@ -929,6 +930,7 @@ void blockWalker(HFClient client, Channel channel) throws InvalidArgumentExcepti
out(" Transaction number %d has submitter mspid: %s, certificate: %s", i, envelopeInfo.getCreator().getMspid(), envelopeInfo.getCreator().getId());

if (envelopeInfo.getType() == TRANSACTION_ENVELOPE) {
++transactionCount;
BlockInfo.TransactionEnvelopeInfo transactionEnvelopeInfo = (BlockInfo.TransactionEnvelopeInfo) envelopeInfo;

out(" Transaction number %d has %d actions", i, transactionEnvelopeInfo.getTransactionActionInfoCount());
Expand Down Expand Up @@ -1037,6 +1039,9 @@ void blockWalker(HFClient client, Channel channel) throws InvalidArgumentExcepti
}
}
}

assertEquals(transactionCount, returnedBlock.getTransactionCount());

}
}
if (!TX_EXPECTED.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.hyperledger.fabric.sdk.BlockEvent.TransactionEvent;
import org.hyperledger.fabric.sdk.BlockInfo;
import org.hyperledger.fabric.sdk.Channel;
import org.hyperledger.fabric.sdk.EventHub;
import org.hyperledger.fabric.sdk.HFClient;
Expand All @@ -49,6 +51,8 @@
import static org.hyperledger.fabric.sdk.Channel.PeerOptions.createPeerOptions;
import static org.hyperledger.fabric.sdk.testutils.TestUtils.resetConfig;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
Expand Down Expand Up @@ -216,6 +220,11 @@ public void setup() {

out("\n");

Thread.sleep(3000); // give time for events to happen

assertTrue(eventCountFilteredBlock > 0); // make sure we got blockevent that were tested.
assertTrue(eventCountBlock > 0); // make sure we got blockevent that were tested.

out("That's all folks!");

} catch (Exception e) {
Expand All @@ -224,6 +233,9 @@ public void setup() {
}
}

int eventCountFilteredBlock = 0;
int eventCountBlock = 0;

private Channel reconstructChannel(String name, HFClient client, SampleOrg sampleOrg) throws Exception {

client.setUserContext(sampleOrg.getPeerAdmin());
Expand All @@ -234,6 +246,9 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
testConfig.getOrdererProperties(orderName)));
}

assertTrue(sampleOrg.getPeerNames().size() > 1); // need at least two for testing.

int i = 0;
for (String peerName : sampleOrg.getPeerNames()) {
String peerLocation = sampleOrg.getPeerLocation(peerName);
Peer peer = client.newPeer(peerName, peerLocation, testConfig.getPeerProperties(peerName));
Expand All @@ -243,9 +258,17 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
if (!channels.contains(name)) {
throw new AssertionError(format("Peer %s does not appear to belong to channel %s", peerName, name));
}
Channel.PeerOptions peerOptions = createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.CHAINCODE_QUERY,
Peer.PeerRole.ENDORSING_PEER, Peer.PeerRole.LEDGER_QUERY, Peer.PeerRole.EVENT_SOURCE));

if (i % 2 == 0) {
peerOptions.registerEventsForFilteredBlocks(); // we need a mix of each type for testing.
} else {
peerOptions.registerEventsForBlocks();
}
++i;

newChannel.addPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.CHAINCODE_QUERY,
Peer.PeerRole.ENDORSING_PEER, Peer.PeerRole.LEDGER_QUERY)));
newChannel.addPeer(peer, peerOptions);
}

for (String eventHubName : sampleOrg.getEventHubNames()) {
Expand All @@ -254,6 +277,40 @@ private Channel reconstructChannel(String name, HFClient client, SampleOrg sampl
newChannel.addEventHub(eventHub);
}

//For testing of blocks which are not transactions.
newChannel.registerBlockListener(blockEvent -> {
// Note peer eventing will always start with sending the last block so this will get the last endorser block
int transactions = 0;
int nonTransactions = 0;
for (BlockInfo.EnvelopeInfo envelopeInfo : blockEvent.getEnvelopeInfos()) {

if (BlockInfo.EnvelopeType.TRANSACTION_ENVELOPE == envelopeInfo.getType()) {
++transactions;
} else {
assertEquals(BlockInfo.EnvelopeType.ENVELOPE, envelopeInfo.getType());
++nonTransactions;
}

}
assertTrue(format("nontransactions %d, transactions %d", nonTransactions, transactions), nonTransactions < 2); // non transaction blocks only have one envelope
assertTrue(format("nontransactions %d, transactions %d", nonTransactions, transactions), nonTransactions + transactions > 0); // has to be one.
assertFalse(format("nontransactions %d, transactions %d", nonTransactions, transactions), nonTransactions > 0 && transactions > 0); // can't have both.

if (nonTransactions > 0) { // this is an update block -- don't care about others here.

if (blockEvent.isFiltered()) {
++eventCountFilteredBlock; // make sure we're seeing non transaction events.
} else {
++eventCountBlock;
}
assertEquals(0, blockEvent.getTransactionCount());
assertEquals(1, blockEvent.getEnvelopeCount());
for (TransactionEvent transactionEvent : blockEvent.getTransactionEvents()) {
fail("Got transaction event in a block update"); // only events for update should not have transactions.
}
}
});

newChannel.initialize();

return newChannel;
Expand Down

0 comments on commit 3eaa57d

Please sign in to comment.