// GetBlock returns a block from the chainfunc(h *Helper)GetBlock(blockNumberuint64)(block*pb.Block,errerror){ledger,err:=ledger.GetLedger()iferr!=nil{returnnil,fmt.Errorf("Failed to get the ledger :%v",err)}returnledger.GetBlockByNumber(blockNumber)}
Executor is intended to eventually supplant the old Executor interface. The problem with invoking the calls directly above, is that they must be coordinated with state transfer, to eliminate possible races and ledger corruption.
// PartialStack contains the ledger features required by the executor.Coordinator
type PartialStack interface {
consensus.LegacyExecutor
GetBlockchainInfo() *pb.BlockchainInfo
}
func (h *Helper) BeginTxBatch(id interface{}) error {
ledger, err := ledger.GetLedger()
if err != nil {
return fmt.Errorf("Failed to get the ledger: %v", err)
}
if err := ledger.BeginTxBatch(id); err != nil {
return fmt.Errorf("Failed to begin transaction with the ledger: %v", err)
}
...
}
type Executor interface {
Start() // Bring up the resources needed to use this interface
Halt() // Tear down the resources needed to use this interface
Execute(tag interface{}, txs []*pb.Transaction) // Executes a set of transactions, this may be called in succession
Commit(tag interface{}, metadata []byte) // Commits whatever transactions have been executed
Rollback(tag interface{}) // Rolls back whatever transactions have been executed
UpdateState(tag interface{}, target *pb.BlockchainInfo, peers []*pb.PeerID) // Attempts to synchronize state to a particular target, implicitly calls rollback if needed
}
func (co *coordinatorImpl) ProcessEvent(event events.Event) events.Event {
switch et := event.(type) {
case executeEvent:
...
co.rawExecutor.ExecTxs(co, et.txs)
co.consumer.Executed(et.tag)
case commitEvent:
...
_, err := co.rawExecutor.CommitTxBatch(co, et.metadata)
...
info := co.rawExecutor.GetBlockchainInfo()
...
co.consumer.Committed(et.tag, info)
case rollbackEvent:
...
case stateUpdateEvent:
...
default:
logger.Errorf("Unknown event type %s", et)
}
return nil
}
type LedgerManager interface {
InvalidateState() // Invalidate informs the ledger that it is out of date and should reject queries
ValidateState() // Validate informs the ledger that it is back up to date and should resume replying to queries
}