github.com/kaituanwang/hyperledger@v2.0.1+incompatible/core/ledger/pvtdatastorage/kv_encoding.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package pvtdatastorage
     8  
     9  import (
    10  	"bytes"
    11  	"math"
    12  
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/hyperledger/fabric-protos-go/ledger/rwset"
    15  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
    16  	"github.com/hyperledger/fabric/core/ledger/util"
    17  	"github.com/pkg/errors"
    18  	"github.com/willf/bitset"
    19  )
    20  
    21  var (
    22  	pendingCommitKey               = []byte{0}
    23  	lastCommittedBlkkey            = []byte{1}
    24  	pvtDataKeyPrefix               = []byte{2}
    25  	expiryKeyPrefix                = []byte{3}
    26  	eligibleMissingDataKeyPrefix   = []byte{4}
    27  	ineligibleMissingDataKeyPrefix = []byte{5}
    28  	collElgKeyPrefix               = []byte{6}
    29  	lastUpdatedOldBlocksKey        = []byte{7}
    30  
    31  	nilByte    = byte(0)
    32  	emptyValue = []byte{}
    33  )
    34  
    35  func getDataKeysForRangeScanByBlockNum(blockNum uint64) (startKey, endKey []byte) {
    36  	startKey = append(pvtDataKeyPrefix, version.NewHeight(blockNum, 0).ToBytes()...)
    37  	endKey = append(pvtDataKeyPrefix, version.NewHeight(blockNum+1, 0).ToBytes()...)
    38  	return
    39  }
    40  
    41  func getExpiryKeysForRangeScan(minBlkNum, maxBlkNum uint64) (startKey, endKey []byte) {
    42  	startKey = append(expiryKeyPrefix, version.NewHeight(minBlkNum, 0).ToBytes()...)
    43  	endKey = append(expiryKeyPrefix, version.NewHeight(maxBlkNum+1, 0).ToBytes()...)
    44  	return
    45  }
    46  
    47  func encodeLastCommittedBlockVal(blockNum uint64) []byte {
    48  	return proto.EncodeVarint(blockNum)
    49  }
    50  
    51  func decodeLastCommittedBlockVal(blockNumBytes []byte) uint64 {
    52  	s, _ := proto.DecodeVarint(blockNumBytes)
    53  	return s
    54  }
    55  
    56  func encodeDataKey(key *dataKey) []byte {
    57  	dataKeyBytes := append(pvtDataKeyPrefix, version.NewHeight(key.blkNum, key.txNum).ToBytes()...)
    58  	dataKeyBytes = append(dataKeyBytes, []byte(key.ns)...)
    59  	dataKeyBytes = append(dataKeyBytes, nilByte)
    60  	return append(dataKeyBytes, []byte(key.coll)...)
    61  }
    62  
    63  func encodeDataValue(collData *rwset.CollectionPvtReadWriteSet) ([]byte, error) {
    64  	return proto.Marshal(collData)
    65  }
    66  
    67  func encodeExpiryKey(expiryKey *expiryKey) []byte {
    68  	// reusing version encoding scheme here
    69  	return append(expiryKeyPrefix, version.NewHeight(expiryKey.expiringBlk, expiryKey.committingBlk).ToBytes()...)
    70  }
    71  
    72  func encodeExpiryValue(expiryData *ExpiryData) ([]byte, error) {
    73  	return proto.Marshal(expiryData)
    74  }
    75  
    76  func decodeExpiryKey(expiryKeyBytes []byte) (*expiryKey, error) {
    77  	height, _, err := version.NewHeightFromBytes(expiryKeyBytes[1:])
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	return &expiryKey{expiringBlk: height.BlockNum, committingBlk: height.TxNum}, nil
    82  }
    83  
    84  func decodeExpiryValue(expiryValueBytes []byte) (*ExpiryData, error) {
    85  	expiryData := &ExpiryData{}
    86  	err := proto.Unmarshal(expiryValueBytes, expiryData)
    87  	return expiryData, err
    88  }
    89  
    90  func decodeDatakey(datakeyBytes []byte) (*dataKey, error) {
    91  	v, n, err := version.NewHeightFromBytes(datakeyBytes[1:])
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	blkNum := v.BlockNum
    96  	tranNum := v.TxNum
    97  	remainingBytes := datakeyBytes[n+1:]
    98  	nilByteIndex := bytes.IndexByte(remainingBytes, nilByte)
    99  	ns := string(remainingBytes[:nilByteIndex])
   100  	coll := string(remainingBytes[nilByteIndex+1:])
   101  	return &dataKey{nsCollBlk{ns, coll, blkNum}, tranNum}, nil
   102  }
   103  
   104  func decodeDataValue(datavalueBytes []byte) (*rwset.CollectionPvtReadWriteSet, error) {
   105  	collPvtdata := &rwset.CollectionPvtReadWriteSet{}
   106  	err := proto.Unmarshal(datavalueBytes, collPvtdata)
   107  	return collPvtdata, err
   108  }
   109  
   110  func encodeMissingDataKey(key *missingDataKey) []byte {
   111  	if key.isEligible {
   112  		keyBytes := append(eligibleMissingDataKeyPrefix, util.EncodeReverseOrderVarUint64(key.blkNum)...)
   113  		keyBytes = append(keyBytes, []byte(key.ns)...)
   114  		keyBytes = append(keyBytes, nilByte)
   115  		return append(keyBytes, []byte(key.coll)...)
   116  	}
   117  
   118  	keyBytes := append(ineligibleMissingDataKeyPrefix, []byte(key.ns)...)
   119  	keyBytes = append(keyBytes, nilByte)
   120  	keyBytes = append(keyBytes, []byte(key.coll)...)
   121  	keyBytes = append(keyBytes, nilByte)
   122  	return append(keyBytes, []byte(util.EncodeReverseOrderVarUint64(key.blkNum))...)
   123  }
   124  
   125  func decodeMissingDataKey(keyBytes []byte) *missingDataKey {
   126  	key := &missingDataKey{nsCollBlk: nsCollBlk{}}
   127  	if keyBytes[0] == eligibleMissingDataKeyPrefix[0] {
   128  		blkNum, numBytesConsumed := util.DecodeReverseOrderVarUint64(keyBytes[1:])
   129  
   130  		splittedKey := bytes.Split(keyBytes[numBytesConsumed+1:], []byte{nilByte})
   131  		key.ns = string(splittedKey[0])
   132  		key.coll = string(splittedKey[1])
   133  		key.blkNum = blkNum
   134  		key.isEligible = true
   135  		return key
   136  	}
   137  
   138  	splittedKey := bytes.SplitN(keyBytes[1:], []byte{nilByte}, 3) //encoded bytes for blknum may contain empty bytes
   139  	key.ns = string(splittedKey[0])
   140  	key.coll = string(splittedKey[1])
   141  	key.blkNum, _ = util.DecodeReverseOrderVarUint64(splittedKey[2])
   142  	key.isEligible = false
   143  	return key
   144  }
   145  
   146  func encodeMissingDataValue(bitmap *bitset.BitSet) ([]byte, error) {
   147  	return bitmap.MarshalBinary()
   148  }
   149  
   150  func decodeMissingDataValue(bitmapBytes []byte) (*bitset.BitSet, error) {
   151  	bitmap := &bitset.BitSet{}
   152  	if err := bitmap.UnmarshalBinary(bitmapBytes); err != nil {
   153  		return nil, err
   154  	}
   155  	return bitmap, nil
   156  }
   157  
   158  func encodeCollElgKey(blkNum uint64) []byte {
   159  	return append(collElgKeyPrefix, util.EncodeReverseOrderVarUint64(blkNum)...)
   160  }
   161  
   162  func decodeCollElgKey(b []byte) uint64 {
   163  	blkNum, _ := util.DecodeReverseOrderVarUint64(b[1:])
   164  	return blkNum
   165  }
   166  
   167  func encodeCollElgVal(m *CollElgInfo) ([]byte, error) {
   168  	return proto.Marshal(m)
   169  }
   170  
   171  func decodeCollElgVal(b []byte) (*CollElgInfo, error) {
   172  	m := &CollElgInfo{}
   173  	if err := proto.Unmarshal(b, m); err != nil {
   174  		return nil, errors.WithStack(err)
   175  	}
   176  	return m, nil
   177  }
   178  
   179  func createRangeScanKeysForEligibleMissingDataEntries(blkNum uint64) (startKey, endKey []byte) {
   180  	startKey = append(eligibleMissingDataKeyPrefix, util.EncodeReverseOrderVarUint64(blkNum)...)
   181  	endKey = append(eligibleMissingDataKeyPrefix, util.EncodeReverseOrderVarUint64(0)...)
   182  
   183  	return startKey, endKey
   184  }
   185  
   186  func createRangeScanKeysForIneligibleMissingData(maxBlkNum uint64, ns, coll string) (startKey, endKey []byte) {
   187  	startKey = encodeMissingDataKey(
   188  		&missingDataKey{
   189  			nsCollBlk:  nsCollBlk{ns: ns, coll: coll, blkNum: maxBlkNum},
   190  			isEligible: false,
   191  		},
   192  	)
   193  	endKey = encodeMissingDataKey(
   194  		&missingDataKey{
   195  			nsCollBlk:  nsCollBlk{ns: ns, coll: coll, blkNum: 0},
   196  			isEligible: false,
   197  		},
   198  	)
   199  	return
   200  }
   201  
   202  func createRangeScanKeysForCollElg() (startKey, endKey []byte) {
   203  	return encodeCollElgKey(math.MaxUint64),
   204  		encodeCollElgKey(0)
   205  }
   206  
   207  func datakeyRange(blockNum uint64) (startKey, endKey []byte) {
   208  	startKey = append(pvtDataKeyPrefix, version.NewHeight(blockNum, 0).ToBytes()...)
   209  	endKey = append(pvtDataKeyPrefix, version.NewHeight(blockNum, math.MaxUint64).ToBytes()...)
   210  	return
   211  }
   212  
   213  func eligibleMissingdatakeyRange(blkNum uint64) (startKey, endKey []byte) {
   214  	startKey = append(eligibleMissingDataKeyPrefix, util.EncodeReverseOrderVarUint64(blkNum)...)
   215  	endKey = append(eligibleMissingDataKeyPrefix, util.EncodeReverseOrderVarUint64(blkNum-1)...)
   216  	return
   217  }