Example #1
0
        public DeltaBuilderTests()
        {
            _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("blake2b-256"));

            _random = new Random();

            _randomFactory = Substitute.For <IDeterministicRandomFactory>();
            _randomFactory.GetDeterministicRandomFromSeed(Arg.Any <byte[]>())
            .Returns(ci => new IsaacRandom(((byte[])ci[0]).ToHex()));

            _producerId   = PeerIdHelper.GetPeerId("producer");
            _peerSettings = _producerId.ToSubstitutedPeerSettings();

            _previousDeltaHash = _hashProvider.ComputeUtf8MultiHash("previousDelta").CreateCid();
            _zeroCoinbaseEntry = new CoinbaseEntry
            {
                Amount            = UInt256.Zero.ToUint256ByteString(),
                ReceiverPublicKey = _producerId.PublicKey.ToByteString()
            };

            _logger = Substitute.For <ILogger>();

            _cache = Substitute.For <IDeltaCache>();

            _dateTimeProvider = new DateTimeProvider();
        }
Example #2
0
        public void Init()
        {
            _hashProvider = new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256"));

            _random = new Random(1);

            _randomFactory = Substitute.For <IDeterministicRandomFactory>();
            _randomFactory.GetDeterministicRandomFromSeed(Arg.Any <byte[]>())
            .Returns(ci => new IsaacRandom(((byte[])ci[0]).ToHex()));

            _producerId   = PeerIdHelper.GetPeerId("producer");
            _peerSettings = _producerId.ToSubstitutedPeerSettings();

            _previousDeltaHash = _hashProvider.ComputeUtf8MultiHash("previousDelta").ToCid();
            _zeroCoinbaseEntry = new CoinbaseEntry
            {
                Amount            = UInt256.Zero.ToUint256ByteString(),
                ReceiverPublicKey = _producerId.PublicKey.ToByteString()
            };

            _logger = Substitute.For <ILogger>();

            _cache = Substitute.For <IDeltaCache>();

            Delta previousDelta = new Delta();

            previousDelta.StateRoot = ByteString.CopyFrom(Keccak.EmptyTreeHash.Bytes);
            _cache.TryGetOrAddConfirmedDelta(Arg.Any <Cid>(), out Arg.Any <Delta>()).Returns(x =>
            {
                x[1] = previousDelta;
                return(true);
            });

            _dateTimeProvider = new DateTimeProvider();

            IDb             codeDb       = new MemDb();
            ISnapshotableDb stateDb      = new StateDb();
            ISpecProvider   specProvider = new CatalystSpecProvider();

            _cryptoContext = new FfiWrapper();
            _stateProvider = new StateProvider(stateDb, codeDb, LimboLogs.Instance);
            IStorageProvider  storageProvider = new StorageProvider(stateDb, _stateProvider, LimboLogs.Instance);
            KatVirtualMachine virtualMachine  = new KatVirtualMachine(_stateProvider,
                                                                      storageProvider,
                                                                      new StateUpdateHashProvider(),
                                                                      specProvider,
                                                                      new HashProvider(HashingAlgorithm.GetAlgorithmMetadata("keccak-256")),
                                                                      new FfiWrapper(),
                                                                      LimboLogs.Instance);

            _deltaExecutor = new DeltaExecutor(specProvider,
                                               _stateProvider,
                                               storageProvider,
                                               virtualMachine,
                                               _cryptoContext,
                                               _logger);
        }
        public void BuildDeltaCheckForAccuracy()
        {
            var transactions = Enumerable.Range(0, 20).Select(i =>
            {
                var transaction = TransactionHelper.GetPublicTransaction(
                    amount: (uint)i,
                    receiverPublicKey: i.ToString(),
                    transactionFees: (ulong)_random.Next(),
                    timestamp: _random.Next(),
                    signature: i.ToString());
                return(transaction);
            }).ToList();

            var transactionRetriever = Substitute.For <IDeltaTransactionRetriever>();

            transactionRetriever.GetMempoolTransactionsByPriority().Returns(transactions);

            var selectedTransactions = transactions.Where(t => t.IsPublicTransaction && t.HasValidEntries()).ToArray();

            var expectedCoinBase = new CoinbaseEntry
            {
                Amount            = selectedTransactions.Sum(t => t.SummedEntryFees()).ToUint256ByteString(),
                ReceiverPublicKey = _producerId.PublicKey.ToByteString()
            };

            var salt = BitConverter.GetBytes(
                _randomFactory.GetDeterministicRandomFromSeed(_previousDeltaHash.ToArray()).NextInt());

            var rawAndSaltedEntriesBySignature = selectedTransactions.SelectMany(
                t => t.PublicEntries.Select(e => new
            {
                RawEntry             = e,
                SaltedAndHashedEntry = _hashProvider.ComputeMultiHash(e.ToByteArray().Concat(salt))
            }));

            var shuffledEntriesBytes = rawAndSaltedEntriesBySignature
                                       .OrderBy(v => v.SaltedAndHashedEntry.ToArray(), ByteUtil.ByteListComparer.Default)
                                       .SelectMany(v => v.RawEntry.ToByteArray())
                                       .ToArray();

            var signaturesInOrder = selectedTransactions
                                    .Select(p => p.Signature.ToByteArray())
                                    .OrderBy(s => s, ByteUtil.ByteListComparer.Default)
                                    .SelectMany(b => b)
                                    .ToArray();

            var expectedBytesToHash = shuffledEntriesBytes.Concat(signaturesInOrder)
                                      .Concat(expectedCoinBase.ToByteArray()).ToArray();

            var deltaBuilder = new DeltaBuilder(transactionRetriever, _randomFactory, _hashProvider, _peerSettings, _cache, _dateTimeProvider, _logger);
            var candidate    = deltaBuilder.BuildCandidateDelta(_previousDeltaHash);

            ValidateDeltaCandidate(candidate, expectedBytesToHash);

            _cache.Received(1).AddLocalDelta(Arg.Is(candidate), Arg.Any <Delta>());
        }
Example #4
0
        private byte[] BuildExpectedBytesToHash(PublicEntry[] selectedTransactions, byte[] shuffledEntriesBytes)
        {
            var signaturesInOrder = selectedTransactions
                                    .Select(p => p.Signature.ToByteArray())
                                    .OrderBy(s => s, ByteUtil.ByteListComparer.Default)
                                    .SelectMany(b => b)
                                    .ToArray();

            var expectedCoinBase = new CoinbaseEntry
            {
                Amount            = selectedTransactions.Sum(t => t.GasPrice.ToUInt256() * t.GasLimit).ToUint256ByteString(),
                ReceiverPublicKey = _producerId.PublicKey.ToByteString()
            };

            var expectedBytesToHash = shuffledEntriesBytes.Concat(signaturesInOrder)
                                      .Concat(expectedCoinBase.ToByteArray()).ToArray();

            return(expectedBytesToHash);
        }
Example #5
0
        public void CoinbaseEntryDao_CoinbaseEntry_Should_Be_Convertible()
        {
            var pubKeyBytes = new byte[30];

            new Random().NextBytes(pubKeyBytes);

            var original = new CoinbaseEntry
            {
                ReceiverPublicKey = pubKeyBytes.ToByteString(),
                Amount            = 271314.ToUint256ByteString()
            };

            var messageDao = original.ToDao <CoinbaseEntry, CoinbaseEntryDao>(_mapperProvider);

            messageDao.ReceiverPublicKey.Should().Be(pubKeyBytes.KeyToString());

            var reconverted = messageDao.ToProtoBuff <CoinbaseEntryDao, CoinbaseEntry>(_mapperProvider);

            reconverted.Should().Be(original);
        }
        ///<inheritdoc />
        public CandidateDeltaBroadcast BuildCandidateDelta(MultiHash previousDeltaHash)
        {
            _logger.Debug("Building candidate delta locally");

            var allTransactions = _transactionRetriever.GetMempoolTransactionsByPriority();

            Guard.Argument(allTransactions, nameof(allTransactions))
            .NotNull("Mempool content returned null, check the mempool is actively running");

            var includedTransactions = GetValidTransactionsForDelta(allTransactions);
            var salt = GetSaltFromPreviousDelta(previousDeltaHash);

            var rawAndSaltedEntriesBySignature = includedTransactions.SelectMany(
                t => t.PublicEntries.Select(e => new RawEntryWithSaltedAndHashedEntry(e, salt, _hashProvider)));

            // (Eα;Oα)
            var shuffledEntriesBytes = rawAndSaltedEntriesBySignature
                                       .OrderBy(v => v.SaltedAndHashedEntry, ByteUtil.ByteListComparer.Default)
                                       .SelectMany(v => v.RawEntry.ToByteArray())
                                       .ToArray();

            // dn
            var signaturesInOrder = includedTransactions
                                    .Select(p => p.Signature.ToByteArray())
                                    .OrderBy(s => s, ByteUtil.ByteListComparer.Default)
                                    .SelectMany(b => b)
                                    .ToArray();

            // xf
            var summedFees = includedTransactions.Sum(t => t.SummedEntryFees());

            //∆Ln,j = L(f/E) + dn + E(xf, j)
            var coinbaseEntry = new CoinbaseEntry
            {
                Amount            = summedFees.ToUint256ByteString(),
                ReceiverPublicKey = _producerUniqueId.PublicKey.ToByteString()
            };
            var globalLedgerStateUpdate = shuffledEntriesBytes
                                          .Concat(signaturesInOrder)
                                          .Concat(coinbaseEntry.ToByteArray())
                                          .ToArray();

            //hj
            var candidate = new CandidateDeltaBroadcast
            {
                // h∆j
                Hash = _hashProvider.ComputeMultiHash(globalLedgerStateUpdate).ToArray().ToByteString(),

                // Idj
                ProducerId           = _producerUniqueId,
                PreviousDeltaDfsHash = previousDeltaHash.ToArray().ToByteString()
            };

            _logger.Debug("Building full delta locally");

            var producedDelta = new Delta
            {
                PreviousDeltaDfsHash = previousDeltaHash.ToArray().ToByteString(),
                MerkleRoot           = candidate.Hash,
                CoinbaseEntries      = { coinbaseEntry },
                PublicEntries        = { includedTransactions.SelectMany(t => t.PublicEntries) },
                TimeStamp            = Timestamp.FromDateTime(_dateTimeProvider.UtcNow)
            };

            _logger.Debug("Adding local candidate delta");

            _deltaCache.AddLocalDelta(candidate, producedDelta);

            return(candidate);
        }