makeGenesisError := genesis.MakeGenesis()
if makeGenesisError != nil {
return makeGenesisError
}
func MakeGenesis() error {
once.Do(func() {
ledger, err := ledger.GetLedger()
if err != nil {
makeGenesisError = err
return
}
if ledger.GetBlockchainSize() == 0 {
genesisLogger.Info("Creating genesis block.")
if makeGenesisError = ledger.BeginTxBatch(0); makeGenesisError == nil {
makeGenesisError = ledger.CommitTxBatch(0, nil, nil, nil)
}
}
})
return makeGenesisError
}
func GetLedger() (*Ledger, error) {
once.Do(func() {
ledger, ledgerError = GetNewLedger()
})
return ledger, ledgerError
}
func GetNewLedger() (*Ledger, error) {
blockchain, err := newBlockchain()
if err != nil {
return nil, err
}
state := state.NewState()
return &Ledger{blockchain, state, nil}, nil
}
func (ledger *Ledger) GetBlockchainSize() uint64 {
return ledger.blockchain.getSize()
}
func (ledger *Ledger) CommitTxBatch(id interface{}, transactions []*protos.Transaction, transactionResults []*protos.TransactionResult, metadata []byte) error {
err := ledger.checkValidIDCommitORRollback(id)
if err != nil {
return err
}
stateHash, err := ledger.state.GetHash()
if err != nil {
ledger.resetForNextTxGroup(false)
ledger.blockchain.blockPersistenceStatus(false)
return err
}
writeBatch := gorocksdb.NewWriteBatch()
defer writeBatch.Destroy()
block := protos.NewBlock(transactions, metadata)
ccEvents := []*protos.ChaincodeEvent{}
if transactionResults != nil {
ccEvents = make([]*protos.ChaincodeEvent, len(transactionResults))
for i := 0; i < len(transactionResults); i++ {
if transactionResults[i].ChaincodeEvent != nil {
ccEvents[i] = transactionResults[i].ChaincodeEvent
} else {
ccEvents[i] = &protos.ChaincodeEvent{}
}
}
}
// 直接在NonHashData存储chaincode事件。这可能会在新共识中改变,我们可以将其移动到交易
block.NonHashData = &protos.NonHashData{ChaincodeEvents: ccEvents}
newBlockNumber, err := ledger.blockchain.addPersistenceChangesForNewBlock(context.TODO(), block, stateHash, writeBatch)
if err != nil {
ledger.resetForNextTxGroup(false)
ledger.blockchain.blockPersistenceStatus(false)
return err
}
ledger.state.AddChangesForPersistence(newBlockNumber, writeBatch)
opt := gorocksdb.NewDefaultWriteOptions()
defer opt.Destroy()
dbErr := db.GetDBHandle().DB.Write(opt, writeBatch)
if dbErr != nil {
ledger.resetForNextTxGroup(false)
ledger.blockchain.blockPersistenceStatus(false)
return dbErr
}
ledger.resetForNextTxGroup(true)
ledger.blockchain.blockPersistenceStatus(true)
sendProducerBlockEvent(block)
//send chaincode events from transaction results
// 从交易结果发送链上代码事件
sendChaincodeEvents(transactionResults)
if len(transactionResults) != 0 {
ledgerLogger.Debug("There were some erroneous transactions. We need to send a 'TX rejected' message here.")
}
return nil
}