Exemple #1
0
        private void Persist(Block block)
        {
            using (SnapshotCache snapshot = system.GetSnapshot())
            {
                List <ApplicationExecuted> all_application_executed = new List <ApplicationExecuted>();
                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, block))
                {
                    engine.LoadScript(onPersistScript);
                    if (engine.Execute() != VMState.HALT)
                    {
                        throw new InvalidOperationException();
                    }
                    ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                    Context.System.EventStream.Publish(application_executed);
                    all_application_executed.Add(application_executed);
                }
                DataCache clonedSnapshot = snapshot.CreateSnapshot();
                // Warning: Do not write into variable snapshot directly. Write into variable clonedSnapshot and commit instead.
                foreach (Transaction tx in block.Transactions)
                {
                    using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, tx, clonedSnapshot, block, tx.SystemFee))
                    {
                        engine.LoadScript(tx.Script);
                        if (engine.Execute() == VMState.HALT)
                        {
                            clonedSnapshot.Commit();
                        }
                        else
                        {
                            clonedSnapshot = snapshot.CreateSnapshot();
                        }
                        ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                        Context.System.EventStream.Publish(application_executed);
                        all_application_executed.Add(application_executed);
                    }
                }
                using (ApplicationEngine engine = ApplicationEngine.Create(TriggerType.PostPersist, null, snapshot, block))
                {
                    engine.LoadScript(postPersistScript);
                    if (engine.Execute() != VMState.HALT)
                    {
                        throw new InvalidOperationException();
                    }
                    ApplicationExecuted application_executed = new ApplicationExecuted(engine);
                    Context.System.EventStream.Publish(application_executed);
                    all_application_executed.Add(application_executed);
                }
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    plugin.OnPersist(block, snapshot, all_application_executed);
                }
                snapshot.Commit();
                List <Exception> commitExceptions = null;
                foreach (IPersistencePlugin plugin in Plugin.PersistencePlugins)
                {
                    try
                    {
                        plugin.OnCommit(block, snapshot);
                    }
                    catch (Exception ex)
                    {
                        if (plugin.ShouldThrowExceptionFromCommit(ex))
                        {
                            if (commitExceptions == null)
                            {
                                commitExceptions = new List <Exception>();
                            }

                            commitExceptions.Add(ex);
                        }
                    }
                }
                if (commitExceptions != null)
                {
                    throw new AggregateException(commitExceptions);
                }
                system.MemPool.UpdatePoolForBlockPersisted(block, snapshot);
            }
            extensibleWitnessWhiteList = null;
            block_cache.Remove(block.PrevHash);
            Context.System.EventStream.Publish(new PersistCompleted {
                Block = block
            });
            if (system.HeaderCache.TryRemoveFirst(out Header header))
            {
                Debug.Assert(header.Index == block.Index);
            }
        }