Ejemplo n.º 1
0
func (blockchain *blockchain) addPersistenceChangesForNewBlock(ctx context.Context,
	block *protos.Block, stateHash []byte, writeBatch *gorocksdb.WriteBatch) (uint64, error) {
	block = blockchain.buildBlock(block, stateHash)
	if block.NonHashData == nil {
		block.NonHashData = &protos.NonHashData{LocalLedgerCommitTimestamp: util.CreateUtcTimestamp()}
	} else {
		block.NonHashData.LocalLedgerCommitTimestamp = util.CreateUtcTimestamp()
	}
	blockNumber := blockchain.size
	blockHash, err := block.GetHash()
	if err != nil {
		return 0, err
	}
	blockBytes, blockBytesErr := block.Bytes()
	if blockBytesErr != nil {
		return 0, blockBytesErr
	}
	writeBatch.PutCF(db.GetDBHandle().BlockchainCF, encodeBlockNumberDBKey(blockNumber), blockBytes)
	writeBatch.PutCF(db.GetDBHandle().BlockchainCF, blockCountKey, encodeUint64(blockNumber+1))
	if blockchain.indexer.isSynchronous() {
		blockchain.indexer.createIndexesSync(block, blockNumber, blockHash, writeBatch)
	}
	blockchain.lastProcessedBlock = &lastProcessedBlock{block, blockNumber, blockHash}
	return blockNumber, nil
}
Ejemplo n.º 2
0
func TestBlockNonHashData(t *testing.T) {
	block1 := NewBlock(nil, nil)
	block2 := NewBlock(nil, nil)
	time1 := util.CreateUtcTimestamp()
	time.Sleep(100 * time.Millisecond)
	time2 := util.CreateUtcTimestamp()
	block1.NonHashData = &NonHashData{LocalLedgerCommitTimestamp: time1}
	block2.NonHashData = &NonHashData{LocalLedgerCommitTimestamp: time2}
	hash1, err := block1.GetHash()
	if err != nil {
		t.Fatalf("Error generating block1 hash: %s", err)
	}
	hash2, err := block2.GetHash()
	if err != nil {
		t.Fatalf("Error generating block2 hash: %s", err)
	}
	if bytes.Compare(hash1, hash2) != 0 {
		t.Fatalf("Expected block hashes to be equal, but there were not")
	}
	if time1 != block1.NonHashData.LocalLedgerCommitTimestamp {
		t.Fatalf("Expected time1 and block1 times to be equal, but there were not")
	}
	if time2 != block2.NonHashData.LocalLedgerCommitTimestamp {
		t.Fatalf("Expected time2 and block2 times to be equal, but there were not")
	}
}
Ejemplo n.º 3
0
// NewChaincodeDeployTransaction is used to deploy chaincode.
func NewChaincodeDeployTransaction(chaincodeDeploymentSpec *ChaincodeDeploymentSpec, uuid string) (*Transaction, error) {
	transaction := new(Transaction)
	transaction.Type = Transaction_CHAINCODE_DEPLOY
	transaction.Uuid = uuid
	transaction.Timestamp = util.CreateUtcTimestamp()
	cID := chaincodeDeploymentSpec.ChaincodeSpec.GetChaincodeID()
	if cID != nil {
		data, err := proto.Marshal(cID)
		if err != nil {
			return nil, fmt.Errorf("Could not marshal chaincode : %s", err)
		}
		transaction.ChaincodeID = data
	}
	//if chaincodeDeploymentSpec.ChaincodeSpec.GetCtorMsg() != nil {
	//	transaction.Function = chaincodeDeploymentSpec.ChaincodeSpec.GetCtorMsg().Function
	//	transaction.Args = chaincodeDeploymentSpec.ChaincodeSpec.GetCtorMsg().Args
	//}
	data, err := proto.Marshal(chaincodeDeploymentSpec)
	if err != nil {
		logger.Errorf("Error mashalling payload for chaincode deployment: %s", err)
		return nil, fmt.Errorf("Could not marshal payload for chaincode deployment: %s", err)
	}
	transaction.Payload = data
	return transaction, nil
}
Ejemplo n.º 4
0
// NewTransaction creates a new transaction. It defines the function to call,
// the chaincodeID on which the function should be called, and the arguments
// string. The arguments could be a string of JSON, but there is no strict
// requirement.
func NewTransaction(chaincodeID ChaincodeID, uuid string, function string, arguments []string) (*Transaction, error) {
	data, err := proto.Marshal(&chaincodeID)
	if err != nil {
		return nil, fmt.Errorf("Could not marshal chaincode : %s", err)
	}
	transaction := new(Transaction)
	transaction.ChaincodeID = data
	transaction.Uuid = uuid
	transaction.Timestamp = util.CreateUtcTimestamp()
	/*
		// Build the spec
		spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG,
			ChaincodeID: chaincodeID, ChaincodeInput: &pb.ChaincodeInput{Function: function, Args: arguments}}

		// Build the ChaincodeInvocationSpec message
		invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}

		data, err := proto.Marshal(invocation)
		if err != nil {
			return nil, fmt.Errorf("Could not marshal payload for chaincode invocation: %s", err)
		}
		transaction.Payload = data
	*/
	return transaction, nil
}
Ejemplo n.º 5
0
func (i *Noops) notifyBlockAdded(block *pb.Block, delta *statemgmt.StateDelta) error {
	//make Payload nil to reduce block size..
	//anything else to remove .. do we need StateDelta ?
	for _, tx := range block.Transactions {
		tx.Payload = nil
	}
	data, err := proto.Marshal(&pb.BlockState{Block: block, StateDelta: delta.Marshal()})
	if err != nil {
		return fmt.Errorf("Fail to marshall BlockState structure: %v", err)
	}
	if logger.IsEnabledFor(logging.DEBUG) {
		logger.Debug("Broadcasting Message_SYNC_BLOCK_ADDED to non-validators")
	}

	// Broadcast SYNC_BLOCK_ADDED to connected NVPs
	// VPs already know about this newly added block since they participate
	// in the execution. That is, they can compare their current block with
	// the network block
	msg := &pb.Message{Type: pb.Message_SYNC_BLOCK_ADDED,
		Payload: data, Timestamp: util.CreateUtcTimestamp()}
	if errs := i.stack.Broadcast(msg, pb.PeerEndpoint_NON_VALIDATOR); nil != errs {
		return fmt.Errorf("Failed to broadcast with errors: %v", errs)
	}
	return nil
}
Ejemplo n.º 6
0
func (i *Noops) processTransactions() error {
	timestamp := util.CreateUtcTimestamp()
	if logger.IsEnabledFor(logging.DEBUG) {
		logger.Debugf("Starting TX batch with timestamp: %v", timestamp)
	}
	if err := i.stack.BeginTxBatch(timestamp); err != nil {
		return err
	}

	// Grab all transactions from the FIFO queue and run them in order
	txarr := i.txQ.getTXs()
	if logger.IsEnabledFor(logging.DEBUG) {
		logger.Debugf("Executing batch of %d transactions with timestamp %v", len(txarr), timestamp)
	}
	_, err := i.stack.ExecTxs(timestamp, txarr)

	//consensus does not need to understand transaction errors, errors here are
	//actual ledger errors, and often irrecoverable
	if err != nil {
		logger.Debugf("Rolling back TX batch with timestamp: %v", timestamp)
		i.stack.RollbackTxBatch(timestamp)
		return fmt.Errorf("Fail to execute transactions: %v", err)
	}
	if logger.IsEnabledFor(logging.DEBUG) {
		logger.Debugf("Committing TX batch with timestamp: %v", timestamp)
	}
	if _, err := i.stack.CommitTxBatch(timestamp, nil); err != nil {
		logger.Debugf("Rolling back TX batch with timestamp: %v", timestamp)
		i.stack.RollbackTxBatch(timestamp)
		return err
	}
	return nil
}
Ejemplo n.º 7
0
// sendTransactionsToLocalEngine send the transaction to the local engine (This Peer is a validator)
func (p *PeerImpl) sendTransactionsToLocalEngine(transaction *pb.Transaction) *pb.Response {

	peerLogger.Debugf("Marshalling transaction %s to send to local engine", transaction.Type)
	data, err := proto.Marshal(transaction)
	if err != nil {
		return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(fmt.Sprintf("Error sending transaction to local engine: %s", err))}
	}

	var response *pb.Response
	msg := &pb.Message{Type: pb.Message_CHAIN_TRANSACTION, Payload: data, Timestamp: util.CreateUtcTimestamp()}
	peerLogger.Debugf("Sending message %s with timestamp %v to local engine", msg.Type, msg.Timestamp)
	response = p.engine.ProcessTransactionMsg(msg, transaction)

	return response
}
Ejemplo n.º 8
0
func TestBlockchainBlockLedgerCommitTimestamp(t *testing.T) {
	testDBWrapper.CleanDB(t)
	blockchainTestWrapper := newTestBlockchainWrapper(t)
	block1 := protos.NewBlock(nil, nil)
	startTime := util.CreateUtcTimestamp()
	time.Sleep(2 * time.Second)
	blockchainTestWrapper.addNewBlock(block1, []byte("stateHash1"))
	lastBlock := blockchainTestWrapper.getLastBlock()
	if lastBlock.NonHashData == nil {
		t.Fatal("Expected block to have non-hash-data, but it was nil")
	}
	if lastBlock.NonHashData.LocalLedgerCommitTimestamp == nil {
		t.Fatal("Expected block to have non-hash-data timestamp, but it was nil")
	}
	if startTime.Seconds >= lastBlock.NonHashData.LocalLedgerCommitTimestamp.Seconds {
		t.Fatal("Expected block time to be after start time")
	}
}
Ejemplo n.º 9
0
// NewChaincodeExecute is used to deploy chaincode.
func NewChaincodeExecute(chaincodeInvocationSpec *ChaincodeInvocationSpec, uuid string, typ Transaction_Type) (*Transaction, error) {
	transaction := new(Transaction)
	transaction.Type = typ
	transaction.Uuid = uuid
	transaction.Timestamp = util.CreateUtcTimestamp()
	cID := chaincodeInvocationSpec.ChaincodeSpec.GetChaincodeID()
	if cID != nil {
		data, err := proto.Marshal(cID)
		if err != nil {
			return nil, fmt.Errorf("Could not marshal chaincode : %s", err)
		}
		transaction.ChaincodeID = data
	}
	data, err := proto.Marshal(chaincodeInvocationSpec)
	if err != nil {
		return nil, fmt.Errorf("Could not marshal payload for chaincode invocation: %s", err)
	}
	transaction.Payload = data
	return transaction, nil
}
Ejemplo n.º 10
0
// NewOpenchainDiscoveryHello constructs a new HelloMessage for sending
func (p *PeerImpl) NewOpenchainDiscoveryHello() (*pb.Message, error) {
	helloMessage, err := p.newHelloMessage()
	if err != nil {
		return nil, fmt.Errorf("Error getting new HelloMessage: %s", err)
	}
	data, err := proto.Marshal(helloMessage)
	if err != nil {
		return nil, fmt.Errorf("Error marshalling HelloMessage: %s", err)
	}
	// Need to sign the Discovery Hello message
	newDiscoveryHelloMsg := &pb.Message{Type: pb.Message_DISC_HELLO, Payload: data, Timestamp: util.CreateUtcTimestamp()}
	err = p.signMessageMutating(newDiscoveryHelloMsg)
	if err != nil {
		return nil, fmt.Errorf("Error signing new HelloMessage: %s", err)
	}
	return newDiscoveryHelloMsg, nil
}