Exemple #1
0
 public RuleTests()
 {
     this.property = new PropertyId(3);
     this.address  = new ReceivingAddress(
         Guid.NewGuid(),
         TestAddress.Regtest1,
         true,
         new Collection <ReceivingAddressReservation>());
     this.reservation = new ReceivingAddressReservation(Guid.NewGuid(), this.address, DateTime.Now, null);
     this.address.Reservations.Add(this.reservation);
     this.targetAmount       = new PropertyAmount(100);
     this.targetConfirmation = 6;
     this.timeout            = TimeSpan.FromHours(1);
     this.callback           = new TokenReceivingCallback(
         new Callback(
             Guid.NewGuid(),
             IPAddress.Parse("192.168.1.2"),
             DateTime.Now,
             false,
             new Uri("http://localhost")),
         "timeout");
     this.id      = Guid.NewGuid();
     this.subject = new Rule(
         this.property,
         this.reservation,
         this.targetAmount,
         this.targetConfirmation,
         this.timeout,
         this.callback,
         this.id);
 }
Exemple #2
0
        public void Construct_WithValidArgsAndNotNullReleasedTime_ShouldBeSet()
        {
            // Arrange.
            var id      = Guid.NewGuid();
            var address = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Mainnet1,
                false,
                new Collection <ReceivingAddressReservation>());
            var reserved = DateTime.UtcNow;
            var released = reserved.Add(TimeSpan.FromHours(10));

            // Act.
            var r = new ReceivingAddressReservation
                    (
                id,
                address,
                reserved,
                released
                    );

            // Assert.
            Assert.Equal(id, r.Id);
            Assert.Equal(address, r.Address);
            Assert.Equal(reserved, r.ReservedDate);
            Assert.Equal(released, r.ReleasedDate);
        }
Exemple #3
0
        public async Task <Guid> StartWatchAsync(
            ReceivingAddressReservation address,
            PropertyAmount targetAmount,
            int targetConfirmation,
            TimeSpan timeout,
            TokenReceivingCallback callback,
            CancellationToken cancellationToken)
        {
            Rule rule;

            if (address == null)
            {
                throw new ArgumentNullException(nameof(address));
            }

            if (address.ReleasedDate != null)
            {
                throw new ArgumentException("The reservation is already released.", nameof(address));
            }

            if (!this.timerScheduler.IsValidDuration(timeout))
            {
                throw new ArgumentOutOfRangeException(nameof(timeout), timeout, "The value is not valid.");
            }

            if (callback != null && callback.Completed)
            {
                throw new ArgumentException("The callback is already completed.", nameof(callback));
            }

            await this.semaphore.WaitAsync(cancellationToken);

            try
            {
                if (this.stopped)
                {
                    throw new InvalidOperationException("The watcher is already stopped.");
                }

                rule = new Rule(this.property, address, targetAmount, targetConfirmation, timeout, callback);

                await this.rules.AddAsync(rule, cancellationToken);

                StartTimer(rule, timeout);
            }
            finally
            {
                this.semaphore.Release();
            }

            return(rule.Id);
        }
Exemple #4
0
        public Rule(
            PropertyId property,
            ReceivingAddressReservation addressReservation,
            PropertyAmount targetAmount,
            int targetConfirmation,
            TimeSpan originalTimeout,
            TokenReceivingCallback callback,
            Guid id)
        {
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }

            if (addressReservation == null)
            {
                throw new ArgumentNullException(nameof(addressReservation));
            }

            if (targetAmount <= PropertyAmount.Zero)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(targetAmount),
                          targetAmount,
                          "The value is not a valid target amount.");
            }

            if (targetConfirmation < 1)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(targetConfirmation),
                          targetConfirmation,
                          "The value is not a valid target confirmation.");
            }

            if (originalTimeout < TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(originalTimeout),
                          originalTimeout,
                          "The value is not a valid timeout.");
            }

            Property           = property;
            AddressReservation = addressReservation;
            TargetAmount       = targetAmount;
            TargetConfirmation = targetConfirmation;
            OriginalTimeout    = originalTimeout;
            Callback           = callback;
            Id = id;
        }
        public Task TryLockAddressAsync_AndHaveAnAvailable_ShouldSuccess()
        {
            return(AsynchronousTesting.WithCancellationTokenAsync(async cancellationToken =>
            {
                // Arrange.
                var address = new ReceivingAddress(
                    Guid.NewGuid(),
                    TestAddress.Regtest1,
                    false,
                    new Collection <ReceivingAddressReservation>());

                var addresses = new[] { address };

                this.repository
                .Setup(r => r.ListAsync(AddressFilter.Available, It.IsAny <CancellationToken>()))
                .ReturnsAsync(addresses);

                this.choser
                .Setup(c => c.Choose(addresses))
                .Returns(address);

                this.repository
                .Setup(r => r.TryLockAsync(address.Id, It.IsAny <CancellationToken>()))
                .ReturnsAsync(() =>
                {
                    var reservation = new ReceivingAddressReservation(Guid.NewGuid(), address, DateTime.Now, null);

                    address.Reservations.Add(reservation);

                    return reservation;
                });

                // Act.
                var recv = await this.subject.TryLockAddressAsync(cancellationToken);

                // Assert.
                Assert.NotNull(recv);
                Assert.Equal(address, recv.Address);
                Assert.NotEqual(Guid.Empty, recv.Id);
                Assert.Null(recv.ReleasedDate);
                Assert.Equal(DateTime.Now, recv.ReservedDate, TimeSpan.FromSeconds(1));

                this.repository.Verify(
                    r => r.ListAsync(It.Is <AddressFilter>(f => f.HasFlag(AddressFilter.Available)), cancellationToken),
                    Times.Once());

                this.choser.Verify(c => c.Choose(addresses), Times.Once());
                this.repository.Verify(r => r.TryLockAsync(address.Id, cancellationToken), Times.Once());
            }));
        }
        public EntityRuleRepositoryTests()
        {
            this.property = new PropertyId(3);
            this.address  = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());
            this.reservation = new ReceivingAddressReservation(Guid.NewGuid(), address, DateTime.Now, null);
            this.address.Reservations.Add(this.reservation);
            this.callback = new Callback(
                Guid.NewGuid(),
                IPAddress.Parse("192.168.1.2"),
                DateTime.Now,
                false,
                new Uri("http://localhost/a"));
            this.rule = new Rule(
                this.property,
                this.reservation,
                new PropertyAmount(100),
                6,
                TimeSpan.FromHours(1),
                new TokenReceivingCallback(this.callback, "timeout"));

            this.db = new TestMainDatabaseFactory();

            try
            {
                this.callbacks = new Mock <ICallbackRepository>();
                this.addresses = new Mock <IReceivingAddressRepository>();

                this.callbacks
                .Setup(r => r.GetAsync(this.callback.Id, It.IsAny <CancellationToken>()))
                .ReturnsAsync(this.callback);

                this.addresses
                .Setup(r => r.GetReservationAsync(this.reservation.Id, It.IsAny <CancellationToken>()))
                .ReturnsAsync(this.reservation);

                this.subject = new EntityRuleRepository(this.db, this.callbacks.Object, this.addresses.Object);
            }
            catch
            {
                this.db.Dispose();
                throw;
            }
        }
        async Task CreateAddressReservationAsync(ReceivingAddressReservation reservation)
        {
            var entity = new Ztm.Data.Entity.Contexts.Main.ReceivingAddressReservation()
            {
                Id         = reservation.Id,
                AddressId  = reservation.Address.Id,
                LockedAt   = reservation.ReservedDate.ToUniversalTime(),
                ReleasedAt = null,
            };

            using (var db = this.db.CreateDbContext())
            {
                await db.ReceivingAddressReservations.AddAsync(entity);

                await db.SaveChangesAsync();
            }
        }
Exemple #8
0
 public Rule(
     PropertyId property,
     ReceivingAddressReservation addressReservation,
     PropertyAmount targetAmount,
     int targetConfirmation,
     TimeSpan originalTimeout,
     TokenReceivingCallback callback)
     : this(
         property,
         addressReservation,
         targetAmount,
         targetConfirmation,
         originalTimeout,
         callback,
         Guid.NewGuid())
 {
 }
Exemple #9
0
        public ReceivingControllerTests()
        {
            this.address = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());

            this.reservation = new ReceivingAddressReservation(Guid.NewGuid(), this.address, DateTime.Now, null);

            this.address.Reservations.Add(this.reservation);

            this.config = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary <string, string>()
            {
                { "Api:Default:RequiredConfirmation", "6" },
                { "Api:Default:TransactionTimeout", "1:00:00" },
            }).Build();

            this.pool    = new Mock <IReceivingAddressPool>();
            this.watcher = new Mock <ITokenReceivingWatcher>();
        }
Exemple #10
0
        public WatchingTests()
        {
            var address = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());
            var reservation = new ReceivingAddressReservation(Guid.NewGuid(), address, DateTime.Now, null);

            address.Reservations.Add(reservation);

            this.rule = new Rule(
                new PropertyId(3),
                reservation,
                new PropertyAmount(100),
                6,
                TimeSpan.FromHours(1),
                null);

            this.timer = new Timer();

            this.subject = new Watching(this.rule, this.timer);
        }
        public virtual Task <ReceivingAddressReservation> TryLockAsync(Guid id, CancellationToken cancellationToken)
        {
            if (this.receivingAddresses.TryGetValue(id, out var recv))
            {
                if (recv.IsLocked)
                {
                    throw new InvalidOperationException();
                }

                var lockedAt     = DateTime.UtcNow;
                var reservation  = new ReceivingAddressReservation(Guid.NewGuid(), recv, lockedAt, DateTime.MinValue);
                var reservations = recv.Reservations;

                reservations.Add(reservation);
                var updated = new ReceivingAddress(recv.Id, recv.Address, true, reservations);

                this.receivingAddresses.Remove(id);
                this.receivingAddresses.Add(id, updated);

                return(Task.FromResult(reservation));
            }

            return(Task.FromResult <ReceivingAddressReservation>(null));
        }
Exemple #12
0
        public WatchingTests()
        {
            var address = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());
            var reservation = new ReceivingAddressReservation(Guid.NewGuid(), address, DateTime.Now, null);

            address.Reservations.Add(reservation);

            this.rule = new Rule(
                new PropertyId(3),
                reservation,
                new PropertyAmount(100),
                6,
                TimeSpan.FromHours(1),
                "timeout",
                new Callback(Guid.NewGuid(), IPAddress.Loopback, DateTime.Now, false, new Uri("http://localhost")));

            this.timer = new Timer();

            this.subject = new Watching(this.rule, this.timer);
        }
Exemple #13
0
        public EntityWatchRepositoryTests()
        {
            var network = ZcoinNetworks.Instance.Regtest;

            this.block1 = Block.CreateBlock(network);
            this.block2 = Block.CreateBlock(network);

            this.tx1 = Transaction.Create(network);
            this.tx1.Inputs.Add(TxIn.CreateCoinbase(102));
            this.tx1.Outputs.Add(Money.Coins(30), TestAddress.Regtest1);
            this.tx1.Outputs.Add(Money.Coins(10), TestAddress.Regtest2);

            this.tx2 = Transaction.Create(network);
            this.tx2.Inputs.Add(TxIn.CreateCoinbase(103));
            this.tx2.Outputs.Add(Money.Coins(40), TestAddress.Regtest2);

            this.tx3 = Transaction.Create(network);
            this.tx3.Inputs.Add(this.tx1, 0).ScriptSig = new Script(OpcodeType.OP_0);
            this.tx3.Outputs.Add(Money.Cents(1), TestAddress.Regtest2);

            this.tx4 = Transaction.Create(network);
            this.tx4.Inputs.Add(this.tx1, 1).ScriptSig = new Script(OpcodeType.OP_0);
            this.tx4.Outputs.Add(Money.Cents(1), TestAddress.Regtest2);

            this.block1.AddTransaction(this.tx1);
            this.block2.AddTransaction(this.tx2);
            this.block2.AddTransaction(this.tx3);
            this.block2.AddTransaction(this.tx4);

            this.block1.UpdateMerkleRoot();
            this.block2.UpdateMerkleRoot();

            this.address1 = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());

            this.address2 = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest2,
                true,
                new Collection <ReceivingAddressReservation>());

            this.reservation1 = new ReceivingAddressReservation(Guid.NewGuid(), this.address1, DateTime.Now, null);
            this.reservation2 = new ReceivingAddressReservation(Guid.NewGuid(), this.address2, DateTime.Now, null);

            this.rule1 = new Rule(
                new PropertyId(3),
                this.reservation1,
                new PropertyAmount(100),
                6,
                TimeSpan.FromHours(1),
                new TokenReceivingCallback(
                    new Callback(
                        Guid.NewGuid(),
                        IPAddress.Parse("192.168.1.2"),
                        DateTime.Now,
                        false,
                        new Uri("http://localhost/a")),
                    "timeout"));

            this.rule2 = new Rule(
                new PropertyId(4),
                this.reservation2,
                new PropertyAmount(40),
                3,
                TimeSpan.FromMinutes(30),
                null);

            this.watch1 = new DomainModel(
                this.rule1,
                this.block1.GetHash(),
                this.tx1.GetHash(),
                this.rule1.AddressReservation.Address.Address,
                new PropertyAmount(100));

            this.watch2 = new DomainModel(
                this.rule2,
                this.block1.GetHash(),
                this.tx1.GetHash(),
                this.rule2.AddressReservation.Address.Address,
                new PropertyAmount(10));

            this.watch3 = new DomainModel(
                this.rule2,
                this.block2.GetHash(),
                this.tx2.GetHash(),
                this.rule2.AddressReservation.Address.Address,
                new PropertyAmount(10));

            this.watch4 = new DomainModel(
                this.rule2,
                this.block2.GetHash(),
                this.tx3.GetHash(),
                this.rule2.AddressReservation.Address.Address,
                new PropertyAmount(10));

            this.watch5 = new DomainModel(
                this.rule2,
                this.block2.GetHash(),
                this.tx4.GetHash(),
                this.rule2.AddressReservation.Address.Address,
                new PropertyAmount(10));

            this.db = new TestMainDatabaseFactory();

            try
            {
                this.rules = new Mock <IRuleRepository>();
                this.rules
                .Setup(r => r.GetAsync(this.rule1.Id, It.IsAny <CancellationToken>()))
                .ReturnsAsync(this.rule1);
                this.rules
                .Setup(r => r.GetAsync(this.rule2.Id, It.IsAny <CancellationToken>()))
                .ReturnsAsync(this.rule2);

                this.subject = new EntityWatchRepository(this.db, this.rules.Object);
            }
            catch
            {
                this.db.Dispose();
                throw;
            }
        }
        public async Task ListUncompletedAsync_WithNonNullProperty_ShouldReturnUncompletedForThatProperty()
        {
            // Arrange.
            var property1 = new PropertyId(3);
            var property2 = new PropertyId(4);

            var address1 = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest1,
                true,
                new Collection <ReceivingAddressReservation>());

            var address2 = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest2,
                true,
                new Collection <ReceivingAddressReservation>());

            var address3 = new ReceivingAddress(
                Guid.NewGuid(),
                TestAddress.Regtest3,
                true,
                new Collection <ReceivingAddressReservation>());

            var reservation1 = new ReceivingAddressReservation(Guid.NewGuid(), address1, DateTime.Now, null);
            var reservation2 = new ReceivingAddressReservation(Guid.NewGuid(), address2, DateTime.Now, DateTime.Now);
            var reservation3 = new ReceivingAddressReservation(Guid.NewGuid(), address2, DateTime.Now, DateTime.Now);
            var reservation4 = new ReceivingAddressReservation(Guid.NewGuid(), address2, DateTime.Now, null);
            var reservation5 = new ReceivingAddressReservation(Guid.NewGuid(), address3, DateTime.Now, null);

            address1.Reservations.Add(reservation1);
            address2.Reservations.Add(reservation2);
            address2.Reservations.Add(reservation3);
            address2.Reservations.Add(reservation4);
            address3.Reservations.Add(reservation5);

            var callback1 = new Callback(
                Guid.NewGuid(),
                IPAddress.Parse("192.168.1.2"),
                DateTime.Now,
                false,
                new Uri("http://localhost/a"));

            var rule1 = new Rule(
                property1,
                reservation1,
                new PropertyAmount(1),
                1,
                TimeSpan.FromMinutes(1),
                null);

            var rule2 = new Rule(
                property2,
                reservation2,
                new PropertyAmount(2),
                2,
                TimeSpan.FromMinutes(2),
                null);

            var rule3 = new Rule(
                property2,
                reservation3,
                new PropertyAmount(3),
                3,
                TimeSpan.FromMinutes(3),
                null);

            var rule4 = new Rule(
                property2,
                reservation4,
                new PropertyAmount(4),
                4,
                TimeSpan.FromMinutes(4),
                new TokenReceivingCallback(callback1, "1"));

            var rule5 = new Rule(
                property2,
                reservation5,
                new PropertyAmount(5),
                5,
                TimeSpan.FromMinutes(5),
                null);

            await CreateAddressAsync(address1);
            await CreateAddressAsync(address2);
            await CreateAddressAsync(address3);

            await CreateAddressReservationAsync(reservation1);
            await CreateAddressReservationAsync(reservation2);
            await CreateAddressReservationAsync(reservation3);
            await CreateAddressReservationAsync(reservation4);
            await CreateAddressReservationAsync(reservation5);

            await CreateCallbackAsync(callback1);

            await this.subject.AddAsync(rule1, CancellationToken.None);

            await this.subject.AddAsync(rule2, CancellationToken.None);

            await this.subject.AddAsync(rule3, CancellationToken.None);

            await this.subject.AddAsync(rule4, CancellationToken.None);

            await this.subject.AddAsync(rule5, CancellationToken.None);

            await this.subject.SetSucceededAsync(rule2.Id, CancellationToken.None);

            await this.subject.SetTimedOutAsync(rule3.Id, CancellationToken.None);

            this.addresses
            .Setup(r => r.GetReservationAsync(reservation1.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(reservation1);

            this.addresses
            .Setup(r => r.GetReservationAsync(reservation2.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(reservation2);

            this.addresses
            .Setup(r => r.GetReservationAsync(reservation3.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(reservation3);

            this.addresses
            .Setup(r => r.GetReservationAsync(reservation4.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(reservation4);

            this.addresses
            .Setup(r => r.GetReservationAsync(reservation5.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(reservation5);

            this.callbacks
            .Setup(r => r.GetAsync(callback1.Id, It.IsAny <CancellationToken>()))
            .ReturnsAsync(callback1);

            // Act.
            var result = await this.subject.ListUncompletedAsync(property2, CancellationToken.None);

            // Assert.
            Assert.Collection(
                result,
                r =>
            {
                Assert.Equal(rule4.AddressReservation, r.AddressReservation);
                Assert.Equal(rule4.Callback, r.Callback);
                Assert.Equal(rule4.Id, r.Id);
                Assert.Equal(rule4.OriginalTimeout, r.OriginalTimeout);
                Assert.Equal(rule4.Property, r.Property);
                Assert.Equal(rule4.TargetAmount, r.TargetAmount);
                Assert.Equal(rule4.TargetConfirmation, r.TargetConfirmation);
            },
                r =>
            {
                Assert.Equal(rule5.AddressReservation, r.AddressReservation);
                Assert.Null(r.Callback);
                Assert.Equal(rule5.Id, r.Id);
                Assert.Equal(rule5.OriginalTimeout, r.OriginalTimeout);
                Assert.Equal(rule5.Property, r.Property);
                Assert.Equal(rule5.TargetAmount, r.TargetAmount);
                Assert.Equal(rule5.TargetConfirmation, r.TargetConfirmation);
            });
        }