Ejemplo n.º 1
0
// ValidateAndPrepareBatch implements method in Validator interface
func (v *Validator) ValidateAndPrepareBatch(block *common.Block, doMVCCValidation bool) (*statedb.UpdateBatch, error) {
	logger.Debugf("New block arrived for validation:%#v, doMVCCValidation=%t", block, doMVCCValidation)
	var valid bool
	updates := statedb.NewUpdateBatch()
	logger.Debugf("Validating a block with [%d] transactions", len(block.Data.Data))
	txsFilter := util.NewFilterBitArrayFromBytes(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
	for txIndex, envBytes := range block.Data.Data {
		if txsFilter.IsSet(uint(txIndex)) {
			// Skiping invalid transaction
			logger.Debug("Skipping transaction marked as invalid, txIndex=", txIndex)
			continue
		}

		// extract actions from the envelope message
		respPayload, err := putils.GetActionFromEnvelope(envBytes)
		if err != nil {
			return nil, err
		}

		//preparation for extracting RWSet from transaction
		txRWSet := &rwset.TxReadWriteSet{}

		// Get the Result from the Action
		// and then Unmarshal it into a TxReadWriteSet using custom unmarshalling
		if err = txRWSet.Unmarshal(respPayload.Results); err != nil {
			return nil, err
		}

		// trace the first 2000 characters of RWSet only, in case it is huge
		if logger.IsEnabledFor(logging.DEBUG) {
			txRWSetString := txRWSet.String()
			if len(txRWSetString) < 2000 {
				logger.Debugf("validating txRWSet:[%s]", txRWSetString)
			} else {
				logger.Debugf("validating txRWSet:[%s...]", txRWSetString[0:2000])
			}
		}

		if !doMVCCValidation {
			valid = true
		} else if valid, err = v.validateTx(txRWSet, updates); err != nil {
			return nil, err
		}

		if valid {
			committingTxHeight := version.NewHeight(block.Header.Number, uint64(txIndex+1))
			addWriteSetToBatch(txRWSet, committingTxHeight, updates)
		} else {
			// Unset bit in byte array corresponded to the invalid transaction
			txsFilter.Set(uint(txIndex))
		}
	}
	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter.ToBytes()
	return updates, nil
}
Ejemplo n.º 2
0
func printBlocksInfo(block *common.Block) {
	// Read invalid transactions filter
	txsFltr := util.NewFilterBitArrayFromBytes(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
	numOfInvalid := 0
	// Count how many transaction indeed invalid
	for i := 0; i < len(block.Data.Data); i++ {
		if txsFltr.IsSet(uint(i)) {
			numOfInvalid++
		}
	}
	fmt.Printf("Num txs in rawBlock = [%d], num invalidTxs = [%d]\n",
		len(block.Data.Data), numOfInvalid)
}
Ejemplo n.º 3
0
func (h *txMgrTestHelper) checkRWsetInvalid(txRWSet []byte) {
	block := h.bg.NextBlock([][]byte{txRWSet}, false)
	err := h.txMgr.ValidateAndPrepare(block, true)
	testutil.AssertNoError(h.t, err, "")
	txsFltr := util.NewFilterBitArrayFromBytes(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
	invalidTxNum := 0
	for i := 0; i < len(block.Data.Data); i++ {
		if txsFltr.IsSet(uint(i)) {
			invalidTxNum++
		}
	}
	testutil.AssertEquals(h.t, invalidTxNum, 1)
}
func checkValidation(t *testing.T, validator *Validator, rwsets []*rwset.RWSet, invalidTxIndexes []int) {
	simulationResults := [][]byte{}
	for _, rwset := range rwsets {
		sr, err := rwset.GetTxReadWriteSet().Marshal()
		testutil.AssertNoError(t, err, "")
		simulationResults = append(simulationResults, sr)
	}
	block := testutil.ConstructBlock(t, simulationResults, false)
	_, err := validator.ValidateAndPrepareBatch(block, true)
	txsFltr := util.NewFilterBitArrayFromBytes(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])
	invalidTxNum := 0
	for i := 0; i < len(block.Data.Data); i++ {
		if txsFltr.IsSet(uint(i)) {
			invalidTxNum++
		}
	}

	testutil.AssertNoError(t, err, "")
	testutil.AssertEquals(t, invalidTxNum, len(invalidTxIndexes))
	//TODO Add the check for exact txnum that is marked invlid when bitarray is in place
}
Ejemplo n.º 5
0
// ValidateAndPrepare implements method in interface `txmgmt.TxMgr`
func (txmgr *CouchDBTxMgr) ValidateAndPrepare(block *common.Block, doMVCCValidation bool) error {
	if doMVCCValidation == true {
		logger.Debugf("===COUCHDB=== Entering CouchDBTxMgr.ValidateAndPrepare()")
		logger.Debugf("Validating a block with [%d] transactions", len(block.Data.Data))
	} else {
		logger.Debugf("New block arrived for write set computation:%#v", block)
		logger.Debugf("Computing write set for a block with [%d] transactions", len(block.Data.Data))
	}
	var valid bool
	txmgr.updateSet = newUpdateSet()
	txmgr.blockNum = block.Header.Number
	txsFilter := util.NewFilterBitArrayFromBytes(block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER])

	for txIndex, envBytes := range block.Data.Data {
		if txsFilter.IsSet(uint(txIndex)) {
			// Skiping invalid transaction
			logger.Debug("Skipping transaction marked as invalid, txIndex=", txIndex)
			continue
		}

		// extract actions from the envelope message
		respPayload, err := putils.GetActionFromEnvelope(envBytes)
		if err != nil {
			return err
		}

		//preparation for extracting RWSet from transaction
		txRWSet := &rwset.TxReadWriteSet{}

		// Get the Result from the Action
		// and then Unmarshal it into a TxReadWriteSet using custom unmarshalling
		if err = txRWSet.Unmarshal(respPayload.Results); err != nil {
			return err
		}

		// trace the first 2000 characters of RWSet only, in case it is huge
		if logger.IsEnabledFor(logging.DEBUG) {
			txRWSetString := txRWSet.String()
			operation := "validating"
			if doMVCCValidation == false {
				operation = "computing write set from"
			}
			if len(txRWSetString) < 2000 {
				logger.Debugf(operation+" txRWSet:[%s]", txRWSetString)
			} else {
				logger.Debugf(operation+" txRWSet:[%s...]", txRWSetString[0:2000])
			}
		}
		if doMVCCValidation == true {
			if valid, err = txmgr.validateTx(txRWSet); err != nil {
				return err
			}
		} else {
			valid = true
		}

		if valid {
			if err := txmgr.addWriteSetToBatch(txRWSet, version.NewHeight(block.Header.Number, uint64(txIndex+1))); err != nil {
				return err
			}
		} else {
			// Unset bit in byte array corresponded to the invalid transaction
			txsFilter.Set(uint(txIndex))
		}
	}

	block.Metadata.Metadata[common.BlockMetadataIndex_TRANSACTIONS_FILTER] = txsFilter.ToBytes()
	logger.Debugf("===COUCHDB=== Exiting CouchDBTxMgr.ValidateAndPrepare()")
	return nil
}