예제 #1
0
 public StoreMetaDataCache(IReadOnlyStore store, byte prefix, Func <T> factory = null)
     : base(factory)
 {
     this.store    = store;
     this.snapshot = store as ISnapshot;
     this.prefix   = prefix;
 }
예제 #2
0
        public static void RegisterHandlers(IReadOnlyStore readOnlyStore, IServiceBus serviceBus)
        {
            _serviceBus = serviceBus;

            RegisterCommandHandler(new ProductListCommandHandlers());
            RegisterEventHandler(new ProductListEventHandlers(readOnlyStore));
        }
예제 #3
0
        public static void Integrate <A, B>(IReadOnlyStore <A> source, IStore <B> destination, IdMap <A, B> idMap)
        {
            var listA = source.List();

            foreach (var id in listA)
            {
                if (!idMap.ContainsKey(id))
                {
                    TextReader reader = source.Get(id);
                    B          newId  = destination.Store(reader);
                    idMap.Add(id, newId);
                }
            }

            var syncA = idMap.Keys;

            foreach (var syncId in syncA)
            {
                if (!listA.Contains(syncId))
                {
                    B idB = idMap[syncId];
                    destination.Delete(idB);
                    idMap.Remove(syncId);
                }
            }
        }
예제 #4
0
        public bool IsSameStore(IReadOnlyStore other)
        {
            if (other is DiskReadOnlyStore dros)
            {
                return(dros.Path == Path);
            }

            return(false);
        }
예제 #5
0
        public static byte[]? TryGet(this TrackingMap trackingMap, IReadOnlyStore store, byte[]?key)
        {
            key ??= Array.Empty <byte>();
            if (trackingMap.TryGetValue(key, out var mapValue))
            {
                return(mapValue.Match <byte[]?>(v => v.ToArray(), _ => null));
            }

            return(store.TryGet(key));
        }
예제 #6
0
        /// <summary>
        /// Copies blobs from <paramref name="source"/> store to <paramref name="destination"/> store.
        /// Also, this checks that the blobs exist, and that there is no error in the hash of those blobs.
        /// When these checks fail, an exception is raised, and the task fails.
        /// </summary>
        /// <param name="hashes">designates the blobs to be copied</param>
        /// <param name="accountId">the account of <paramref name="source"/> store. only helps with error messages</param>
        /// <returns></returns>
        public static async Task <WrittenBlob[]> ImportBlobs(
            this IWriteOnlyStore destination,
            IReadOnlyStore source,
            IReadOnlyCollection <Hash> hashes,
            long?accountId           = null,
            CancellationToken cancel = default)
        {
            var checkExistTasks = hashes.Select(
                h => source[h].ExistsAsync(cancel)
                ).ToArray();

            bool[] exist = await Task.WhenAll(checkExistTasks);

            int i = 0;

            foreach (var h in hashes)
            {
                if (!exist[i])
                {
                    throw new NoSuchBlobException(accountId?.ToString() ?? "<unknown>", h);
                }
            }

            var copyTasks = hashes.Select(
                h => destination.ImportBlobUnchecked(source[h], cancel)).ToArray();

            var writtenBlobs = await Task.WhenAll(copyTasks).ConfigureAwait(false);

            List <(Hash orig, Hash result)> badHashes = null;

            i = 0;
            foreach (var orig in hashes)
            {
                var blob = writtenBlobs[i++];
                if (!blob.Hash.Equals(orig))
                {
                    badHashes = badHashes ?? new List <(Hash orig, Hash result)>();
                    badHashes.Add((orig, blob.Hash));
                }
            }

            if (badHashes != null)
            {
                string details = string.Join("\n", badHashes.Select(_ => $"  {accountId}/{_.orig}: {_.result}"));
                throw new Exception("Bad hash(es) detected: " + details);
            }

            return(writtenBlobs);
        }
예제 #7
0
파일: SnapshotCache.cs 프로젝트: zhmkof/neo
 /// <summary>
 /// Initializes a new instance of the <see cref="SnapshotCache"/> class.
 /// </summary>
 /// <param name="store">An <see cref="IReadOnlyStore"/> to create a readonly cache; or an <see cref="ISnapshot"/> to create a snapshot cache.</param>
 public SnapshotCache(IReadOnlyStore store)
 {
     this.store    = store;
     this.snapshot = store as ISnapshot;
 }
예제 #8
0
 public StoreDataCache(IReadOnlyStore store, byte prefix)
 {
     this.store    = store;
     this.snapshot = store as ISnapshot;
     this.prefix   = prefix;
 }
 public Snapshot(IReadOnlyStore store, TrackingMap trackingMap, Action <TrackingMap> commitAction)
 {
     this.store        = store;
     this.trackingMap  = trackingMap;
     this.commitAction = commitAction;
 }
예제 #10
0
 public static IEnumerable <DebugInfo> Find(IReadOnlyStore store)
 {
     return(store
            .Seek(DEBUG_INFO_PREFIX, Array.Empty <byte>(), Neo.IO.Caching.SeekDirection.Forward)
            .Select(t => t.Value.AsSerializable <DebugInfo>()));
 }
예제 #11
0
        public static DebugInfo?TryGet(IReadOnlyStore store, UInt160 scriptHash)
        {
            var value = store.TryGet(DEBUG_INFO_PREFIX, scriptHash.ToArray());

            return(value == null ? null : value.AsSerializable <DebugInfo>());
        }
예제 #12
0
 public bool IsSameStore(IReadOnlyStore other) => ReferenceEquals(other, this);
예제 #13
0
        public static IEnumerable <(byte[] Key, byte[] Value)> Seek(this TrackingMap trackingMap, IReadOnlyStore store, byte[]?key, SeekDirection direction)
        {
            key ??= Array.Empty <byte>();

            if (key.Length == 0 && direction == SeekDirection.Backward)
            {
                return(Enumerable.Empty <(byte[] key, byte[] value)>());
            }

            var comparer = direction == SeekDirection.Forward
                ? ReadOnlyMemoryComparer.Default
                : ReadOnlyMemoryComparer.Reverse;

            var memoryItems = trackingMap
                              .Where(kvp => kvp.Value.IsT0)
                              .Where(kvp => key.Length == 0 || comparer.Compare(kvp.Key, key) >= 0)
                              .Select(kvp => (Key: kvp.Key.ToArray(), Value: kvp.Value.AsT0.ToArray()));

            var storeItems = store
                             .Seek(key, direction)
                             .Where <(byte[] Key, byte[] Value)>(kvp => !trackingMap.ContainsKey(kvp.Key));

            return(memoryItems.Concat(storeItems).OrderBy(kvp => kvp.Key, comparer));
        }
예제 #14
0
 public ReadOnlyView(IReadOnlyStore store)
 {
     this.store = store;
 }
예제 #15
0
 public MemoryTrackingStore(IReadOnlyStore store)
 {
     this.store = store;
 }
예제 #16
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));
                }
            }
        }