@@ -19,11 +19,13 @@ import (
1919 util2 "github.com/hyperledger/fabric/common/util"
2020 "github.com/hyperledger/fabric/core/common/privdata"
2121 "github.com/hyperledger/fabric/core/ledger"
22+ "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
2223 "github.com/hyperledger/fabric/core/transientstore"
2324 "github.com/hyperledger/fabric/gossip/util"
2425 "github.com/hyperledger/fabric/protos/common"
2526 proto "github.com/hyperledger/fabric/protos/gossip"
2627 "github.com/hyperledger/fabric/protos/ledger/rwset"
28+ "github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
2729 "github.com/hyperledger/fabric/protos/msp"
2830 "github.com/spf13/viper"
2931 "github.com/stretchr/testify/assert"
@@ -748,7 +750,7 @@ func TestCoordinatorToFilterOutPvtRWSetsWithWrongHash(t *testing.T) {
748750 channelID : "test" ,
749751 }
750752
751- block := bf .AddTxnWithEndorsement ("tx1" , "ns1" , hash , "org1" , "c1" ).create ()
753+ block := bf .AddTxnWithEndorsement ("tx1" , "ns1" , hash , "org1" , true , "c1" ).create ()
752754 store .On ("GetTxPvtRWSetByTxid" , "tx1" , mock .Anything ).Return ((& mockRWSetScanner {}).withRWSet ("ns1" , "c1" ), nil )
753755
754756 coordinator := NewCoordinator (Support {
@@ -837,7 +839,8 @@ func TestCoordinatorStoreBlock(t *testing.T) {
837839 bf := & blockFactory {
838840 channelID : "test" ,
839841 }
840- block := bf .AddTxnWithEndorsement ("tx1" , "ns1" , hash , "org1" , "c1" , "c2" ).AddTxnWithEndorsement ("tx2" , "ns2" , hash , "org2" , "c1" ).create ()
842+ block := bf .AddTxnWithEndorsement ("tx1" , "ns1" , hash , "org1" , true , "c1" , "c2" ).
843+ AddTxnWithEndorsement ("tx2" , "ns2" , hash , "org2" , true , "c1" ).create ()
841844
842845 // Scenario I: Block we got has sufficient private data alongside it.
843846 // If the coordinator tries fetching from the transientstore, or peers it would result in panic,
@@ -1223,3 +1226,71 @@ func TestCoordinatorStorePvtData(t *testing.T) {
12231226 assert .Error (t , err )
12241227 assert .Contains (t , err .Error (), "I/O error: file system full" )
12251228}
1229+
1230+ func TestContainsWrites (t * testing.T ) {
1231+ // Scenario I: Nil HashedRwSet in collection
1232+ col := & rwsetutil.CollHashedRwSet {
1233+ CollectionName : "col1" ,
1234+ }
1235+ assert .False (t , containsWrites ("tx" , "ns" , col ))
1236+
1237+ // Scenario II: No writes in collection
1238+ col .HashedRwSet = & kvrwset.HashedRWSet {}
1239+ assert .False (t , containsWrites ("tx" , "ns" , col ))
1240+
1241+ // Scenario III: Some writes in collection
1242+ col .HashedRwSet .HashedWrites = append (col .HashedRwSet .HashedWrites , & kvrwset.KVWriteHash {})
1243+ assert .True (t , containsWrites ("tx" , "ns" , col ))
1244+ }
1245+
1246+ func TestIgnoreReadOnlyColRWSets (t * testing.T ) {
1247+ // Scenario: The transaction has some ColRWSets that have only reads and no writes,
1248+ // These should be ignored and not considered as missing private data that needs to be retrieved
1249+ // from the transient store or other peers.
1250+ // The gossip and transient store mocks in this test aren't initialized with
1251+ // actions, so if the coordinator attempts to fetch private data from the
1252+ // transient store or other peers, the test would fail.
1253+ // Also - we check that at commit time - the coordinator concluded that
1254+ // no missing private data was found.
1255+ peerSelfSignedData := common.SignedData {
1256+ Identity : []byte {0 , 1 , 2 },
1257+ Signature : []byte {3 , 4 , 5 },
1258+ Data : []byte {6 , 7 , 8 },
1259+ }
1260+ cs := createcollectionStore (peerSelfSignedData ).thatAcceptsAll ()
1261+ var commitHappened bool
1262+ assertCommitHappened := func () {
1263+ assert .True (t , commitHappened )
1264+ commitHappened = false
1265+ }
1266+ committer := & committerMock {}
1267+ committer .On ("CommitWithPvtData" , mock .Anything ).Run (func (args mock.Arguments ) {
1268+ blockAndPrivateData := args .Get (0 ).(* ledger.BlockAndPvtData )
1269+ // Ensure there is no private data to commit
1270+ assert .Empty (t , blockAndPrivateData .BlockPvtData )
1271+ // Ensure there is no missing private data
1272+ assert .Empty (t , blockAndPrivateData .Missing )
1273+ commitHappened = true
1274+ }).Return (nil )
1275+ store := & mockTransientStore {t : t }
1276+
1277+ fetcher := & fetcherMock {t : t }
1278+ hash := util2 .ComputeSHA256 ([]byte ("rws-pre-image" ))
1279+ bf := & blockFactory {
1280+ channelID : "test" ,
1281+ }
1282+ // The block contains a read only private data transaction
1283+ block := bf .AddReadOnlyTxn ("tx1" , "ns3" , hash , "c3" , "c2" ).create ()
1284+ coordinator := NewCoordinator (Support {
1285+ CollectionStore : cs ,
1286+ Committer : committer ,
1287+ Fetcher : fetcher ,
1288+ TransientStore : store ,
1289+ Validator : & validatorMock {},
1290+ }, peerSelfSignedData )
1291+ // We pass a nil private data slice to indicate no pre-images though the block contains
1292+ // private data reads.
1293+ err := coordinator .StoreBlock (block , nil )
1294+ assert .NoError (t , err )
1295+ assertCommitHappened ()
1296+ }
0 commit comments