// CommitTxBatch - gets invoked when the current transaction-batch needs to be committed // This function returns successfully iff the transactions details and state changes (that // may have happened during execution of this transaction-batch) have been committed to permanent storage func (ledger *Ledger) CommitTxBatch(id interface{}, transactions []*protos.Transaction, proof []byte) error { err := ledger.checkValidIDCommitORRollback(id) if err != nil { return err } success := true defer ledger.resetForNextTxGroup(success) defer ledger.blockchain.blockPersistenceStatus(success) stateHash, err := ledger.state.GetHash() if err != nil { success = false return err } writeBatch := gorocksdb.NewWriteBatch() block := protos.NewBlock(transactions) newBlockNumber, err := ledger.blockchain.addPersistenceChangesForNewBlock(context.TODO(), block, stateHash, writeBatch) if err != nil { success = false return err } ledger.state.AddChangesForPersistence(newBlockNumber, writeBatch) opt := gorocksdb.NewDefaultWriteOptions() dbErr := db.GetDBHandle().DB.Write(opt, writeBatch) if dbErr != nil { success = false return dbErr } producer.Send(producer.CreateBlockEvent(block)) return nil }
func BenchmarkMessages(b *testing.B) { numMessages := 10000 adapter.count = numMessages var err error //b.ResetTimer() for i := 0; i < numMessages; i++ { go func() { emsg := createTestBlock() if err = producer.Send(emsg); err != nil { b.Fail() b.Logf("Error sending message %s", err) } }() } select { case <-adapter.notfy: case <-time.After(5 * time.Second): b.Fail() b.Logf("timed out on messge") } }
func sendProducerBlockEvent(block *protos.Block) { // Remove payload from deploy transactions. This is done to make block // events more lightweight as the payload for these types of transactions // can be very large. blockTransactions := block.GetTransactions() for _, transaction := range blockTransactions { if transaction.Type == protos.Transaction_CHAINCODE_NEW { deploymentSpec := &protos.ChaincodeDeploymentSpec{} err := proto.Unmarshal(transaction.Payload, deploymentSpec) if err != nil { ledgerLogger.Error(fmt.Sprintf("Error unmarshalling deployment transaction for block event: %s", err)) continue } deploymentSpec.CodePackage = nil deploymentSpecBytes, err := proto.Marshal(deploymentSpec) if err != nil { ledgerLogger.Error(fmt.Sprintf("Error marshalling deployment transaction for block event: %s", err)) continue } transaction.Payload = deploymentSpecBytes } } producer.Send(producer.CreateBlockEvent(block)) }
// PutRawBlock puts a raw block on the chain. This function should only be // used for synchronization between peers. func (ledger *Ledger) PutRawBlock(block *protos.Block, blockNumber uint64) error { err := ledger.blockchain.persistRawBlock(block, blockNumber) if err != nil { return err } producer.Send(producer.CreateBlockEvent(block)) return nil }
// Test the invocation of a transaction. func TestReceiveMessage(t *testing.T) { var err error adapter.count = 1 emsg := createTestBlock() if err = producer.Send(emsg); err != nil { t.Fail() t.Logf("Error sending message %s", err) } select { case <-adapter.notfy: case <-time.After(5 * time.Second): t.Fail() t.Logf("timed out on messge") } }