From 534a029ef505d60038a31f70aab2eaed46848212 Mon Sep 17 00:00:00 2001 From: Artem Barger Date: Mon, 21 May 2018 17:16:05 +0300 Subject: [PATCH] [FAB-10248] add ledger height while sending pvt tx While answering pull message for missing private data we need to distiguish and choose most recent collection configuration. This commits adds ledger height while distributing pvt with collection config, hence while answering pull request we can pick most updated one. Change-Id: Id50e0e9e8910f33f154cd95f7adc84dc91deb28b Signed-off-by: Artem Barger --- core/endorser/endorser.go | 9 ++++ core/endorser/support.go | 17 +++++++ core/mocks/endorser/support.go | 5 ++ gossip/privdata/dataretriever.go | 8 ++-- protos/transientstore/transientstore.pb.go | 53 +++++++++++++--------- protos/transientstore/transientstore.proto | 5 +- 6 files changed, 70 insertions(+), 27 deletions(-) diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index b8b5ac4fb30..720b267cdf7 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -83,6 +83,9 @@ type Support interface { // EndorseWithPlugin endorses the response with a plugin EndorseWithPlugin(ctx Context) (*pb.ProposalResponse, error) + + // GetLedgerHeight returns ledger height for given channelID + GetLedgerHeight(channelID string) (uint64, error) } // Endorser provides the Endorser service ProcessProposal @@ -285,6 +288,12 @@ func (e *Endorser) SimulateProposal(ctx context.Context, chainID string, txid st if err != nil { return nil, nil, nil, nil, errors.WithMessage(err, "failed to obtain collections config") } + endosedAt, err := e.s.GetLedgerHeight(chainID) + if err != nil { + return nil, nil, nil, nil, errors.WithMessage(err, fmt.Sprint("failed to obtain ledger height for channel", chainID)) + } + // Add ledger height at which transaction was endorsed + pvtDataWithConfig.EndorsedAt = endosedAt if err := e.distributePrivateData(chainID, txid, pvtDataWithConfig, simResult.SimulationBlkHt); err != nil { return nil, nil, nil, nil, err } diff --git a/core/endorser/support.go b/core/endorser/support.go index 3b77271adee..e339b359bc3 100644 --- a/core/endorser/support.go +++ b/core/endorser/support.go @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package endorser import ( + "fmt" + "github.com/hyperledger/fabric/common/channelconfig" "github.com/hyperledger/fabric/common/crypto" "github.com/hyperledger/fabric/core/aclmgmt" @@ -89,6 +91,21 @@ func (s *SupportImpl) GetTransactionByID(chid, txID string) (*pb.ProcessedTransa return tx, nil } +// GetLedgerHeight returns ledger height for given channelID +func (s *SupportImpl) GetLedgerHeight(channelID string) (uint64, error) { + lgr := s.Peer.GetLedger(channelID) + if lgr == nil { + return 0, errors.Errorf("failed to look up the ledger for Channel %s", channelID) + } + + info, err := lgr.GetBlockchainInfo() + if err != nil { + return 0, errors.Wrap(err, fmt.Sprintf("failed to obtain information for Channel %s", channelID)) + } + + return info.Height, nil +} + // IsSysCC returns true if the name matches a system chaincode's // system chaincode names are system, chain wide func (s *SupportImpl) IsSysCC(name string) bool { diff --git a/core/mocks/endorser/support.go b/core/mocks/endorser/support.go index cece9f035d7..a44c1c8e046 100644 --- a/core/mocks/endorser/support.go +++ b/core/mocks/endorser/support.go @@ -77,6 +77,11 @@ func (s *MockSupport) GetTransactionByID(chid, txID string) (*pb.ProcessedTransa return nil, s.GetTransactionByIDErr } +func (s *MockSupport) GetLedgerHeight(channelID string) (uint64, error) { + args := s.Called(channelID) + return args.Get(0).(uint64), args.Error(1) +} + func (s *MockSupport) IsSysCC(name string) bool { if s.SysCCMap != nil { _, in := s.SysCCMap[name] diff --git a/gossip/privdata/dataretriever.go b/gossip/privdata/dataretriever.go index fbb4fdbbe4d..a7e1bd12f3f 100644 --- a/gossip/privdata/dataretriever.go +++ b/gossip/privdata/dataretriever.go @@ -136,6 +136,7 @@ func (dr *dataRetriever) fromTransientStore(dig *gossip2.PvtDataDigest, filter m } defer it.Close() + maxEndorsedAt := uint64(0) for { res, err := it.NextWithConfig() if err != nil { @@ -171,9 +172,10 @@ func (dr *dataRetriever) fromTransientStore(dig *gossip2.PvtDataDigest, filter m } pvtRWSet := dr.extractPvtRWsets(txPvtRWSet.NsPvtRwset, dig.Namespace, dig.Collection) - // TODO: Next CR will extend TxPvtReadWriteSetWithConfigInfo to have ledger height of - // endorsement time to be used here in order to select most updated collection config. - results.CollectionConfig = configs + if rws.EndorsedAt >= maxEndorsedAt { + maxEndorsedAt = rws.EndorsedAt + results.CollectionConfig = configs + } results.RWSet = append(results.RWSet, pvtRWSet...) } } diff --git a/protos/transientstore/transientstore.pb.go b/protos/transientstore/transientstore.pb.go index f985c2642f3..541d7ddfdca 100644 --- a/protos/transientstore/transientstore.pb.go +++ b/protos/transientstore/transientstore.pb.go @@ -33,8 +33,9 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package // read-write set and additional information about the configurations such as // the latest collection config when the transaction is simulated type TxPvtReadWriteSetWithConfigInfo struct { - PvtRwset *rwset.TxPvtReadWriteSet `protobuf:"bytes,1,opt,name=pvt_rwset,json=pvtRwset" json:"pvt_rwset,omitempty"` - CollectionConfigs map[string]*common2.CollectionConfigPackage `protobuf:"bytes,2,rep,name=collection_configs,json=collectionConfigs" json:"collection_configs,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + EndorsedAt uint64 `protobuf:"varint,1,opt,name=endorsed_at,json=endorsedAt" json:"endorsed_at,omitempty"` + PvtRwset *rwset.TxPvtReadWriteSet `protobuf:"bytes,2,opt,name=pvt_rwset,json=pvtRwset" json:"pvt_rwset,omitempty"` + CollectionConfigs map[string]*common2.CollectionConfigPackage `protobuf:"bytes,3,rep,name=collection_configs,json=collectionConfigs" json:"collection_configs,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` } func (m *TxPvtReadWriteSetWithConfigInfo) Reset() { *m = TxPvtReadWriteSetWithConfigInfo{} } @@ -42,6 +43,13 @@ func (m *TxPvtReadWriteSetWithConfigInfo) String() string { return pr func (*TxPvtReadWriteSetWithConfigInfo) ProtoMessage() {} func (*TxPvtReadWriteSetWithConfigInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (m *TxPvtReadWriteSetWithConfigInfo) GetEndorsedAt() uint64 { + if m != nil { + return m.EndorsedAt + } + return 0 +} + func (m *TxPvtReadWriteSetWithConfigInfo) GetPvtRwset() *rwset.TxPvtReadWriteSet { if m != nil { return m.PvtRwset @@ -63,24 +71,25 @@ func init() { func init() { proto.RegisterFile("transientstore/transientstore.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 299 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x51, 0xc1, 0x4b, 0xfb, 0x30, - 0x18, 0x65, 0x1d, 0xbf, 0x1f, 0x2e, 0x03, 0xd1, 0x1c, 0xb4, 0xec, 0xb2, 0xa1, 0x97, 0x1d, 0x24, - 0x81, 0x8d, 0x81, 0x78, 0x74, 0x28, 0x78, 0x1b, 0x51, 0x18, 0x78, 0x19, 0x59, 0xf6, 0xad, 0x0d, - 0xeb, 0x92, 0x92, 0x7c, 0xad, 0xf6, 0x1f, 0xf3, 0xef, 0x93, 0x36, 0xa0, 0xae, 0x13, 0xbc, 0x94, - 0xe6, 0x7d, 0xdf, 0x7b, 0x2f, 0xef, 0x85, 0x5c, 0xa3, 0x93, 0xc6, 0x6b, 0x30, 0xe8, 0xd1, 0x3a, - 0xe0, 0x87, 0x47, 0x96, 0x3b, 0x8b, 0x96, 0x9e, 0x1e, 0xa2, 0x83, 0x38, 0x83, 0x4d, 0x02, 0x8e, - 0xbb, 0x37, 0x0f, 0x18, 0xbe, 0x61, 0x73, 0x70, 0xa9, 0xec, 0x7e, 0x6f, 0x0d, 0x57, 0x36, 0xcb, - 0x40, 0xa1, 0xb6, 0x26, 0x0c, 0xae, 0x3e, 0x22, 0x32, 0x7c, 0x79, 0x5f, 0x94, 0x28, 0x40, 0x6e, - 0x96, 0x4e, 0x23, 0x3c, 0x03, 0x2e, 0x35, 0xa6, 0x73, 0x6b, 0xb6, 0x3a, 0x79, 0x32, 0x5b, 0x4b, - 0x67, 0xa4, 0x97, 0x97, 0xb8, 0x6a, 0xf4, 0xe2, 0xce, 0xa8, 0x33, 0xee, 0x4f, 0x62, 0x16, 0xd4, - 0x8f, 0xa8, 0xe2, 0x24, 0x2f, 0x51, 0xd4, 0x33, 0x5a, 0x10, 0xfa, 0x6d, 0xb7, 0x52, 0x8d, 0x9e, - 0x8f, 0xa3, 0x51, 0x77, 0xdc, 0x9f, 0x3c, 0xb2, 0x56, 0xa0, 0x3f, 0xee, 0xc0, 0xe6, 0x5f, 0x4a, - 0x01, 0xf4, 0x0f, 0x06, 0x5d, 0x25, 0xce, 0x55, 0x1b, 0x1f, 0x00, 0xb9, 0xf8, 0x7d, 0x99, 0x9e, - 0x91, 0xee, 0x0e, 0xaa, 0x26, 0x41, 0x4f, 0xd4, 0xbf, 0x74, 0x46, 0xfe, 0x95, 0x32, 0x2b, 0x20, - 0x8e, 0x9a, 0x54, 0x43, 0x16, 0x6a, 0x3a, 0x72, 0x5b, 0x48, 0xb5, 0x93, 0x09, 0x88, 0xb0, 0x7d, - 0x17, 0xdd, 0x76, 0xee, 0x15, 0xb9, 0xb1, 0x2e, 0x61, 0x69, 0x95, 0x83, 0x0b, 0xb5, 0xb3, 0xad, - 0x5c, 0x3b, 0xad, 0x42, 0xb1, 0xbe, 0x15, 0xf0, 0x75, 0x9a, 0x68, 0x4c, 0x8b, 0x75, 0xed, 0xc0, - 0x7f, 0x90, 0x78, 0x20, 0xf1, 0x40, 0x6a, 0x3d, 0xf3, 0xfa, 0x7f, 0x03, 0x4f, 0x3f, 0x03, 0x00, - 0x00, 0xff, 0xff, 0x43, 0x79, 0x87, 0x0d, 0x0e, 0x02, 0x00, 0x00, + // 320 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x52, 0x4f, 0x4b, 0x3b, 0x31, + 0x10, 0x65, 0xdb, 0xdf, 0x4f, 0x6c, 0x0a, 0xa2, 0x39, 0xe8, 0xd2, 0x4b, 0x8b, 0x5e, 0x7a, 0x90, + 0x04, 0x5a, 0x0a, 0xe2, 0x4d, 0x8b, 0x82, 0xb7, 0x12, 0x85, 0x82, 0x97, 0x92, 0x66, 0xa7, 0xdb, + 0xd0, 0x6d, 0xb2, 0x24, 0xd3, 0xd5, 0x7e, 0x52, 0xbf, 0x8e, 0xec, 0xc6, 0x7f, 0xdd, 0x0a, 0x5e, + 0x96, 0xcd, 0x9b, 0xf7, 0xe6, 0xcd, 0x9b, 0x84, 0x5c, 0xa0, 0x93, 0xc6, 0x6b, 0x30, 0xe8, 0xd1, + 0x3a, 0xe0, 0xbb, 0x47, 0x96, 0x3b, 0x8b, 0x96, 0x1e, 0xed, 0xa2, 0x9d, 0x38, 0x83, 0x24, 0x05, + 0xc7, 0xdd, 0x8b, 0x07, 0x0c, 0xdf, 0xc0, 0xec, 0x9c, 0x29, 0xbb, 0x5e, 0x5b, 0xc3, 0x95, 0xcd, + 0x32, 0x50, 0xa8, 0xad, 0x09, 0x85, 0xf3, 0xb7, 0x06, 0xe9, 0x3e, 0xbd, 0x4e, 0x0a, 0x14, 0x20, + 0x93, 0xa9, 0xd3, 0x08, 0x8f, 0x80, 0x53, 0x8d, 0xcb, 0xb1, 0x35, 0x0b, 0x9d, 0x3e, 0x98, 0x85, + 0xa5, 0x5d, 0xd2, 0x06, 0x93, 0x58, 0xe7, 0x21, 0x99, 0x49, 0x8c, 0xa3, 0x5e, 0xd4, 0xff, 0x27, + 0xc8, 0x27, 0x74, 0x83, 0x74, 0x44, 0x5a, 0x79, 0x81, 0xb3, 0xca, 0x30, 0x6e, 0xf4, 0xa2, 0x7e, + 0x7b, 0x10, 0xb3, 0x60, 0xbf, 0xd7, 0x5b, 0x1c, 0xe6, 0x05, 0x8a, 0xb2, 0x46, 0x37, 0x84, 0x7e, + 0xcf, 0x33, 0x53, 0x95, 0xa1, 0x8f, 0x9b, 0xbd, 0x66, 0xbf, 0x3d, 0xb8, 0x67, 0xb5, 0xc4, 0x7f, + 0x0c, 0xc9, 0xc6, 0x5f, 0x9d, 0x02, 0xe8, 0xef, 0x0c, 0xba, 0xad, 0x38, 0x51, 0x75, 0xbc, 0x03, + 0xe4, 0xf4, 0x77, 0x32, 0x3d, 0x26, 0xcd, 0x15, 0x6c, 0xab, 0x80, 0x2d, 0x51, 0xfe, 0xd2, 0x11, + 0xf9, 0x5f, 0xc8, 0x6c, 0x03, 0x1f, 0xa9, 0xba, 0x2c, 0xec, 0x71, 0xcf, 0x6d, 0x22, 0xd5, 0x4a, + 0xa6, 0x20, 0x02, 0xfb, 0xba, 0x71, 0x15, 0xdd, 0x2a, 0x72, 0x69, 0x5d, 0xca, 0x96, 0xdb, 0x1c, + 0x5c, 0xb8, 0x17, 0xb6, 0x90, 0x73, 0xa7, 0x55, 0xd8, 0xbc, 0xaf, 0x05, 0x7c, 0x1e, 0xa6, 0x1a, + 0x97, 0x9b, 0x79, 0xe9, 0xc0, 0x7f, 0x88, 0x78, 0x10, 0xf1, 0x20, 0xaa, 0xbd, 0x83, 0xf9, 0x41, + 0x05, 0x0f, 0xdf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x60, 0x8a, 0xb4, 0xba, 0x2f, 0x02, 0x00, 0x00, } diff --git a/protos/transientstore/transientstore.proto b/protos/transientstore/transientstore.proto index b7dbffbc580..04089a2bd0f 100644 --- a/protos/transientstore/transientstore.proto +++ b/protos/transientstore/transientstore.proto @@ -29,6 +29,7 @@ import "common/collection.proto"; // read-write set and additional information about the configurations such as // the latest collection config when the transaction is simulated message TxPvtReadWriteSetWithConfigInfo { - rwset.TxPvtReadWriteSet pvt_rwset = 1; - map collection_configs = 2; + uint64 endorsed_at = 1; + rwset.TxPvtReadWriteSet pvt_rwset = 2; + map collection_configs = 3; }