code: func (m *KeyLevelValidationParameterManagerImpl) ExtractValidationParameterDependency(blockNum, txNum uint64, rwsetBytes []byte) {
  	vCtx := m.validationCtx.forBlock(blockNum)
  
  	// this object represents the dependency that transaction (blockNum, txNum) introduces
  	dep := vCtx.getOrCreateDependencyByTxnum(txNum)
  
  	rwset := &rwsetutil.TxRwSet{}
  	err := rwset.FromProtoBytes(rwsetBytes)
  	// note that we silently discard broken read-write
  	// sets - ledger will invalidate them anyway
  	if err == nil {
  		// here we cycle through all metadata updates generated by this transaction
  		// and signal that transaction (blockNum, txNum) modifies them so that
  		// all subsequent transaction know they have to wait for validation of
  		// transaction (blockNum, txNum) before they can continue
  		for _, rws := range rwset.NsRwSets {
  			for _, mw := range rws.KvRwSet.MetadataWrites {
  				// record the fact that this key has a dependency on our tx
  				vCtx.addDependency(newLedgerKeyID(rws.NameSpace, "", mw.Key), txNum, dep)
  			}
  
  			for _, cw := range rws.CollHashedRwSets {
  				for _, mw := range cw.HashedRwSet.MetadataWrites {
  					// record the fact that this (pvt) key has a dependency on our tx
  					vCtx.addDependency(newLedgerKeyID(rws.NameSpace, cw.CollectionName, string(mw.KeyHash)), txNum, dep)
  				}
  			}
  		}
  	} else {
  		logger.Warningf("unmarshalling the read write set returned error '%s', skipping", err)
  	}
  
  	// signal that we have introduced all dependencies for this transaction
  	dep.signalDepInserted()
  }
docs: // ExtractValidationParameterDependency implements the method of
  // the same name of the KeyLevelValidationParameterManager interface
  // Note that this function doesn't take any namespace argument. This is
  // because we want to inspect all namespaces for which this transaction
  // modifies metadata.