MCPcopy Create free account
hub / github.com/CPChain/chain / traceChain

Method traceChain

protocols/cpc/api_tracer.go:134–348  ·  view source on GitHub ↗

traceChain configures a new tracer according to the provided configuration, and executes all the transactions contained within. The return value will be one item per transaction, dependent on the requestd tracer.

(ctx context.Context, start, end *types.Block, config *TraceConfig)

Source from the content-addressed store, hash-verified

132// executes all the transactions contained within. The return value will be one item
133// per transaction, dependent on the requestd tracer.
134func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Block, config *TraceConfig) (*rpc.Subscription, error) {
135 // Tracing a chain is a **long** operation, only do with subscriptions
136 notifier, supported := rpc.NotifierFromContext(ctx)
137 if !supported {
138 return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported
139 }
140 sub := notifier.CreateSubscription()
141
142 // Ensure we have a valid starting state before doing any work
143 origin := start.NumberU64()
144 database := state.NewDatabase(api.cpc.ChainDb())
145
146 if number := start.NumberU64(); number > 0 {
147 start = api.cpc.blockchain.GetBlock(start.ParentHash(), start.NumberU64()-1)
148 if start == nil {
149 return nil, fmt.Errorf("parent block #%d not found", number-1)
150 }
151 }
152 pubStateDB, err := state.New(start.StateRoot(), database)
153 if err != nil {
154 // If the starting state is missing, allow some number of blocks to be reexecuted
155 reexec := defaultTraceReexec
156 if config != nil && config.Reexec != nil {
157 reexec = *config.Reexec
158 }
159 // Find the most recent block that has the state available
160 for i := uint64(0); i < reexec; i++ {
161 start = api.cpc.blockchain.GetBlock(start.ParentHash(), start.NumberU64()-1)
162 if start == nil {
163 break
164 }
165 if pubStateDB, err = state.New(start.StateRoot(), database); err == nil {
166 break
167 }
168 }
169 // If we still don't have the state available, bail out
170 if err != nil {
171 switch err.(type) {
172 case *trie.MissingNodeError:
173 return nil, errors.New("required historical state unavailable")
174 default:
175 return nil, err
176 }
177 }
178 }
179 // Execute all the transaction contained within the chain concurrently for each block
180 blocks := int(end.NumberU64() - origin)
181
182 threads := runtime.NumCPU()
183 if threads > blocks {
184 threads = blocks
185 }
186 var (
187 pend = new(sync.WaitGroup)
188 tasks = make(chan *blockTraceTask, threads)
189 results = make(chan *blockTraceTask, threads)
190 )
191 for th := 0; th < threads; th++ {

Callers 1

TraceChainMethod · 0.95

Calls 15

traceTxMethod · 0.95
TrieDBMethod · 0.95
CreateSubscriptionMethod · 0.80
NumberU64Method · 0.80
ParentHashMethod · 0.80
StateRootMethod · 0.80
TransactionsMethod · 0.80
AsMessageMethod · 0.80
HeaderMethod · 0.80
FinaliseMethod · 0.80
WaitMethod · 0.80
ProcessorMethod · 0.80

Tested by

no test coverage detected