MCPcopy
hub / github.com/canopy-network/canopy / ApplyTransactions

Method ApplyTransactions

fsm/state.go:204–304  ·  view source on GitHub ↗

ApplyTransactions() 1. Batch validate signatures for every transaction provided 2. Processes all transactions provided against the state machine 3. Allows ephemeral 'oversize' transaction processing without applying 'oversize txn' changes to the state 4. Returns the following for successful transact

(ctx context.Context, txs [][]byte, r *lib.ApplyBlockResults, allowOversize bool)

Source from the content-addressed store, hash-verified

202// 4. Returns the following for successful transactions within a block: <results, tx-list, root, count>
203// 5. Returns all transactions that failed during processing
204func (s *StateMachine) ApplyTransactions(ctx context.Context, txs [][]byte, r *lib.ApplyBlockResults, allowOversize bool) lib.ErrorI {
205 // use a map to check for 'same-block' duplicate transactions
206 deDuplicator := lib.NewDeDuplicator[string]()
207 // use a batch verifier for signatures
208 batchVerifier := crypto.NewBatchVerifier()
209 // get the governance parameter for max block size
210 maxBlockSize, err := s.GetMaxBlockSize()
211 if err != nil {
212 return err
213 }
214 // keep a map to track transactions that failed 'check'
215 failedCheckTxs := map[int]error{}
216 // first batch validate signatures over the entire set
217 for i, tx := range txs {
218 if _, checkErr := s.CheckTx(tx, "", batchVerifier); checkErr != nil {
219 failedCheckTxs[i] = checkErr
220 }
221 }
222 // execute batch verification of the signatures in the block
223 for _, failedIdx := range batchVerifier.Verify() {
224 failedCheckTxs[failedIdx] = ErrInvalidSignature()
225 }
226 // set the store back to the original at the end of processing
227 originalStore := s.Store().(lib.StoreI)
228 defer s.SetStore(originalStore)
229 // create a variable to track if the block is over size
230 var oversize bool
231 // iterates over each transaction in the block
232 for i, tx := range txs {
233 // if interrupt signal
234 if ctx.Err() != nil {
235 return lib.ErrMempoolStopSignal()
236 }
237 // if already failed check tx or signature
238 if e, found := failedCheckTxs[i]; found {
239 r.AddFailed(lib.NewFailedTx(tx, e))
240 continue
241 }
242 // calculate the hash of the transaction and convert it to a hex string
243 hashString := crypto.HashString(tx)
244 // check if the transaction is a 'same block' duplicate
245 if found := deDuplicator.Found(hashString); found {
246 return lib.ErrDuplicateTx(hashString)
247 }
248 // get the tx size
249 txSize := uint64(len(tx))
250 // if the max block size is exceeded and we're not yet marked as 'oversize'
251 if txSize+r.BlockSize > maxBlockSize && !oversize {
252 // if validating a block - oversize shouldn't happen
253 if !allowOversize {
254 return ErrMaxBlockSize()
255 }
256 // set oversize to 'true'
257 oversize = true
258 // wrap the store in a 'database transaction' to rollback all the 'oversize transactions'
259 if _, e := s.TxnWrap(); e != nil {
260 return e
261 }

Callers 2

ApplyBlockMethod · 0.95

Calls 15

GetMaxBlockSizeMethod · 0.95
CheckTxMethod · 0.95
VerifyMethod · 0.95
StoreMethod · 0.95
SetStoreMethod · 0.95
TxnWrapMethod · 0.95
ApplyTransactionMethod · 0.95
ResetCachesMethod · 0.95
NewBatchVerifierFunction · 0.92
ErrMempoolStopSignalFunction · 0.92
NewFailedTxFunction · 0.92
HashStringFunction · 0.92