public void contains_false_for_missing_key()
        {
            var memoryStore   = new MemoryStore();
            var trackingStore = new MemoryTrackingStore(memoryStore);

            trackingStore.Contains(Bytes("invalid-key")).Should().BeFalse();
        }
        public void doesnt_disposes_underlying_store_if_not_disposable()
        {
            var underStore = new NonDisposableStore();

            using (var store = new MemoryTrackingStore(underStore))
            {
            }
        }
        public void disposes_underlying_store_if_disposable()
        {
            var underStore = new DisposableStore();

            using (var store = new MemoryTrackingStore(underStore))
            {
            }
            underStore.Disposed.Should().BeTrue();
        }
        public void can_put_new_value()
        {
            var key   = Bytes(0);
            var store = new MemoryTrackingStore(NullStore.Instance);

            store.Put(key, helloValue);
            var actual = store.TryGet(key);

            Assert.Equal(helloValue, actual);
        }
        public void update_key_array_doesnt_affect_store()
        {
            var store = new MemoryTrackingStore(NullStore.Instance);
            var key   = Bytes(0);

            store.Put(key, helloValue);

            key[0] = 0xff;
            Assert.Equal(helloValue, store.TryGet(Bytes(0)));
            Assert.Null(store.TryGet(key));
        }
        public void can_get_value_from_underlying_store()
        {
            var key         = Bytes(0);
            var memoryStore = new MemoryStore();

            memoryStore.Put(key, helloValue);

            var trackingStore = new MemoryTrackingStore(memoryStore);
            var actual        = trackingStore.TryGet(key);

            Assert.Equal(helloValue, actual);
        }
        static IStore GetSeekStore()
        {
            var memoryStore = new MemoryStore();

            memoryStore.PutSeekData((0, 2), (1, 2));

            var store = new MemoryTrackingStore(memoryStore);

            store.PutSeekData((0, 2), (3, 4));

            return(store);
        }
        public void snapshot_doesnt_see_store_changes()
        {
            var store = new MemoryTrackingStore(NullStore.Instance);

            using var snapshot = store.GetSnapshot();

            var key = Bytes(0);

            store.Put(key, helloValue);

            Assert.Null(snapshot.TryGet(key));
            Assert.Equal(helloValue, store.TryGet(key));
        }
        public void can_overwrite_existing_value()
        {
            var key         = Bytes(0);
            var memoryStore = new MemoryStore();

            memoryStore.Put(key, helloValue);

            var trackingStore = new MemoryTrackingStore(memoryStore);

            trackingStore.Put(key, worldValue);
            var actual = trackingStore.TryGet(key);

            Assert.Equal(worldValue, actual);
        }
        public void can_delete_via_snapshot()
        {
            var store = new MemoryTrackingStore(NullStore.Instance);
            var key   = Bytes(0);

            store.Put(key, helloValue);

            using var snapshot = store.GetSnapshot();
            snapshot.Delete(key);

            Assert.Equal(helloValue, store.TryGet(key));
            snapshot.Commit();
            Assert.Null(store.TryGet(key));
        }
        public void can_delete_existing_value()
        {
            var key         = Bytes(0);
            var memoryStore = new MemoryStore();

            memoryStore.Put(key, helloValue);

            var trackingStore = new MemoryTrackingStore(memoryStore);

            trackingStore.Delete(key);
            var actual = trackingStore.TryGet(key);

            Assert.Null(actual);
        }
        static async Task <IApplicationEngine> CreateDebugEngineAsync(ConfigProps config, JToken jsonInvocation)
        {
            var program        = ParseProgram(config);
            var launchNefFile  = LoadNefFile(program);
            var launchManifest = await LoadContractManifestAsync(program).ConfigureAwait(false);

            var chain      = LoadNeoExpress(config);
            var invocation = ParseInvocation(jsonInvocation);

            var checkpoint = LoadBlockchainCheckpoint(config, chain?.Network, chain?.AddressVersion);

            var(trigger, witnessChecker) = ParseRuntime(config, chain, checkpoint.Settings.AddressVersion);
            if (trigger != TriggerType.Application)
            {
                throw new Exception($"Trigger Type {trigger} not supported");
            }

            var signers = ParseSigners(config, chain, checkpoint.Settings.AddressVersion).ToArray();

            var store = new MemoryTrackingStore(checkpoint);

            store.EnsureLedgerInitialized(checkpoint.Settings);

            Script invokeScript;
            var    attributes = Array.Empty <TransactionAttribute>();

            if (invocation.IsT3) // T3 == ContractDeploymentInvocation
            {
                if ((signers.Length == 0 || (signers.Length == 1 && signers[0].Account == UInt160.Zero)) &&
                    TryGetDeploymentSigner(config, chain, checkpoint.Settings.AddressVersion, out var deploySigner))
                {
                    signers = new[] { deploySigner };
                }

                using var builder = new ScriptBuilder();
                builder.EmitDynamicCall(NativeContract.ContractManagement.Hash, "deploy", launchNefFile.ToArray(), launchManifest.ToJson().ToString());
                invokeScript = builder.ToArray();
            }
            else
            {
                var paramParser  = CreateContractParameterParser(checkpoint.Settings.AddressVersion, store, chain);
                var deploySigner = TryGetDeploymentSigner(config, chain, checkpoint.Settings.AddressVersion, out var _deploySigner)
                    ? _deploySigner
                    : new Signer {
                    Account = UInt160.Zero
                };

                var(launchContractId, launchContractHash) = EnsureContractDeployed(store, launchNefFile, launchManifest, deploySigner, checkpoint.Settings);
                UpdateContractStorage(store, launchContractId, ParseStorage(config, paramParser));
                invokeScript = await CreateInvokeScriptAsync(invocation, program, launchContractHash, paramParser);

                if (invocation.IsT1) // T1 == OracleResponseInvocation
                {
                    attributes = GetTransactionAttributes(invocation.AsT1, store, launchContractHash, paramParser);
                }
            }

            // TODO: load other contracts
            //          Not sure supporting other contracts is a good idea anymore. Since there's no way to calculate the
            //          contract id hash prior to deployment in Neo 3, I'm thinking the better approach would be to simply
            //          deploy whatever contracts you want and take a snapshot rather than deploying multiple contracts
            //          during launch configuration.

            var tx = new Transaction
            {
                Version         = 0,
                Nonce           = (uint)new Random().Next(),
                Script          = invokeScript,
                Signers         = signers,
                ValidUntilBlock = checkpoint.Settings.MaxValidUntilBlockIncrement,
                Attributes      = attributes,
                Witnesses       = Array.Empty <Witness>()
            };

            var block  = CreateDummyBlock(store, tx);
            var engine = new DebugApplicationEngine(tx, store, checkpoint.Settings, block, witnessChecker);

            engine.LoadScript(invokeScript);
            return(engine);
Esempio n. 13
0
        static void TraceBlock(Uri uri, Block block, ProtocolSettings settings, IConsole console, UInt256?txHash = null)
        {
            IReadOnlyStore roStore = block.Index > 0
                ? new StateServiceStore(uri, block.Index - 1)
                : NullStore.Instance;

            using var store    = new MemoryTrackingStore(roStore);
            using var snapshot = new SnapshotCache(store.GetSnapshot());

            using (var engine = ApplicationEngine.Create(TriggerType.OnPersist, null, snapshot, block, settings, 0))
            {
                using var sb = new ScriptBuilder();
                sb.EmitSysCall(ApplicationEngine.System_Contract_NativeOnPersist);
                engine.LoadScript(sb.ToArray());
                if (engine.Execute() != VMState.HALT)
                {
                    throw new InvalidOperationException("NativeOnPersist operation failed", engine.FaultException);
                }
            }

            var clonedSnapshot = snapshot.CreateSnapshot();

            for (int i = 0; i < block.Transactions.Length; i++)
            {
                Transaction tx = block.Transactions[i];

                using var engine = GetEngine(tx, clonedSnapshot);
                if (engine is TraceApplicationEngine)
                {
                    console.Out.WriteLine($"Tracing Transaction #{i} ({tx.Hash})");
                }
                else
                {
                    console.Out.WriteLine($"Executing Transaction #{i} ({tx.Hash})");
                }

                engine.LoadScript(tx.Script);
                if (engine.Execute() == VMState.HALT)
                {
                    clonedSnapshot.Commit();
                }
                else
                {
                    clonedSnapshot = snapshot.CreateSnapshot();
                }
            }

            ApplicationEngine GetEngine(Transaction tx, DataCache snapshot)
            {
                if (txHash == null || txHash == tx.Hash)
                {
                    var path = SysIO.Path.Combine(Environment.CurrentDirectory, $"{tx.Hash}.neo-trace");
                    var sink = new TraceDebugStream(SysIO.File.OpenWrite(path));
                    return(new TraceApplicationEngine(sink, TriggerType.Application, tx, snapshot, block, settings, tx.SystemFee));
                }
                else
                {
                    return(ApplicationEngine.Create(TriggerType.Application, tx, snapshot, block, settings, tx.SystemFee));
                }
            }
        }