public RoundParameterFactory(WabiSabiConfig config, Network network)
 {
     Config  = config;
     Network = network;
     MaxSuggestedAmountProvider = new (Config);
 }
示例#2
0
        public async Task FullCoinjoinAsyncTest()
        {
            var config = new WabiSabiConfig {
                MaxInputCountByRound = 1
            };
            var round = WabiSabiFactory.CreateRound(config);

            using Arena arena = await WabiSabiFactory.CreateAndStartArenaAsync(config, round);

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            using var key = new Key();
            var outpoint = BitcoinFactory.CreateOutPoint();

            var mockRpc = new Mock <IRPCClient>();

            mockRpc.Setup(rpc => rpc.GetTxOutAsync(outpoint.Hash, (int)outpoint.N, true))
            .ReturnsAsync(new NBitcoin.RPC.GetTxOutResponse
            {
                IsCoinBase    = false,
                Confirmations = 200,
                TxOut         = new TxOut(Money.Coins(1m), key.PubKey.WitHash.GetAddress(Network.Main)),
            });
            await using var coordinator = new ArenaRequestHandler(config, new Prison(), arena, mockRpc.Object);

            CredentialPool amountCredentials = new();
            CredentialPool vsizeCredentials  = new();
            var            aliceArenaClient  = new ArenaClient(round.AmountCredentialIssuerParameters, round.VsizeCredentialIssuerParameters, amountCredentials, vsizeCredentials, coordinator, new InsecureRandom());

            var aliceId = await aliceArenaClient.RegisterInputAsync(Money.Coins(1m), outpoint, key, round.Id, round.Hash);

            Assert.NotEqual(Guid.Empty, aliceId);
            Assert.Empty(amountCredentials.Valuable);

            var reissuanceAmounts = new[]
            {
                Money.Coins(.75m) - round.FeeRate.GetFee(Constants.P2wpkhInputVirtualSize),
                Money.Coins(.25m)
            };

            var inputVsize           = Constants.P2wpkhInputVirtualSize;
            var inputRemainingVsizes = new[] { ProtocolConstants.MaxVsizePerAlice - inputVsize };

            // Phase: Input Registration
            Assert.Equal(Phase.InputRegistration, round.Phase);

            await aliceArenaClient.ConfirmConnectionAsync(
                round.Id,
                aliceId,
                inputRemainingVsizes,
                amountCredentials.ZeroValue.Take(ProtocolConstants.CredentialNumber),
                reissuanceAmounts);

            Assert.Empty(amountCredentials.Valuable);

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            Assert.Equal(Phase.ConnectionConfirmation, round.Phase);

            // Phase: Connection Confirmation
            await aliceArenaClient.ConfirmConnectionAsync(
                round.Id,
                aliceId,
                inputRemainingVsizes,
                amountCredentials.ZeroValue.Take(ProtocolConstants.CredentialNumber),
                reissuanceAmounts);

            Assert.Single(amountCredentials.Valuable, x => x.Amount.ToMoney() == reissuanceAmounts.First());
            Assert.Single(amountCredentials.Valuable, x => x.Amount.ToMoney() == reissuanceAmounts.Last());

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            Assert.Equal(Phase.OutputRegistration, round.Phase);

            var bobArenaClient = new ArenaClient(round.AmountCredentialIssuerParameters, round.VsizeCredentialIssuerParameters, amountCredentials, vsizeCredentials, coordinator, new InsecureRandom());

            Assert.Equal(4, amountCredentials.ZeroValue.Count());

            // Phase: Output Registration
            using var destinationKey1 = new Key();
            using var destinationKey2 = new Key();

            var result = await bobArenaClient.ReissueCredentialAsync(
                round.Id,
                reissuanceAmounts[0],
                destinationKey1.PubKey.WitHash.ScriptPubKey,
                reissuanceAmounts[1],
                destinationKey2.PubKey.WitHash.ScriptPubKey,
                amountCredentials.Valuable,
                vsizeCredentials.Valuable);

            Assert.Equal(6, amountCredentials.ZeroValue.Count());
            Assert.Equal(6, vsizeCredentials.ZeroValue.Count());

            Credential amountCred1 = result.RealAmountCredentials.ElementAt(0);
            Credential amountCred2 = result.RealAmountCredentials.ElementAt(1);

            Credential vsizeCred1 = result.RealVsizeCredentials.ElementAt(0);
            Credential vsizeCred2 = result.RealVsizeCredentials.ElementAt(1);

            await bobArenaClient.RegisterOutputAsync(
                round.Id,
                reissuanceAmounts[0],
                destinationKey1.PubKey.WitHash.ScriptPubKey,
                new[] { amountCred1 },
                new[] { vsizeCred1 });

            await bobArenaClient.RegisterOutputAsync(
                round.Id,
                reissuanceAmounts[1],
                destinationKey2.PubKey.WitHash.ScriptPubKey,
                new[] { amountCred2 },
                new[] { vsizeCred2 });

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            Assert.Equal(Phase.TransactionSigning, round.Phase);

            Assert.Equal(1, round.Coinjoin.Inputs.Count);
            Assert.Equal(2, round.Coinjoin.Outputs.Count);
        }
示例#3
0
 public static Round CreateRound(WabiSabiConfig cfg)
 => new(new RoundParameters(
示例#4
0
        public async Task RegisterOutputTestAsync()
        {
            var config = new WabiSabiConfig {
                MaxInputCountByRound = 1
            };
            var round = WabiSabiFactory.CreateRound(config);

            using Arena arena = await WabiSabiFactory.CreateAndStartArenaAsync(config, round);

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            var       km       = ServiceFactory.CreateKeyManager("");
            var       key      = BitcoinFactory.CreateHdPubKey(km);
            SmartCoin coin1    = BitcoinFactory.CreateSmartCoin(key, Money.Coins(2m));
            var       outpoint = coin1.OutPoint;

            var mockRpc = new Mock <IRPCClient>();

            mockRpc.Setup(rpc => rpc.GetTxOutAsync(outpoint.Hash, (int)outpoint.N, true))
            .ReturnsAsync(new NBitcoin.RPC.GetTxOutResponse
            {
                IsCoinBase    = false,
                Confirmations = coin1.Height,
                TxOut         = coin1.TxOut,
            });

            CredentialPool amountCredential = new();
            CredentialPool weightCredential = new();

            await using var coordinator = new ArenaRequestHandler(config, new Prison(), arena, mockRpc.Object);
            var aliceArenaClient = new ArenaClient(round.AmountCredentialIssuerParameters, round.WeightCredentialIssuerParameters, amountCredential, weightCredential, coordinator, new InsecureRandom());
            var bobArenaClient   = new ArenaClient(round.AmountCredentialIssuerParameters, round.WeightCredentialIssuerParameters, amountCredential, weightCredential, coordinator, new InsecureRandom());

            Assert.Equal(Phase.InputRegistration, round.Phase);

            var bitcoinSecret = km.GetSecrets("", coin1.ScriptPubKey).Single().PrivateKey.GetBitcoinSecret(Network.Main);
            var aliceClient   = await AliceClient.CreateNewAsync(aliceArenaClient, new[] { coin1.Coin }, bitcoinSecret, round.Id, round.Hash, round.FeeRate);

            Task confirmationTask = aliceClient.ConfirmConnectionAsync(TimeSpan.FromSeconds(3), CancellationToken.None);

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            await confirmationTask;

            Assert.Equal(Phase.ConnectionConfirmation, round.Phase);

            await arena.TriggerAndWaitRoundAsync(TimeSpan.FromMinutes(1));

            Assert.Equal(Phase.OutputRegistration, round.Phase);

            using var destinationKey1 = new Key();
            using var destinationKey2 = new Key();
            using var destinationKey3 = new Key();
            using var destinationKey4 = new Key();

            var bobClient = new BobClient(round.Id, bobArenaClient);
            await bobClient.RegisterOutputAsync(Money.Coins(0.25m), destinationKey1.PubKey.WitHash.ScriptPubKey);

            await bobClient.RegisterOutputAsync(Money.Coins(0.25m), destinationKey2.PubKey.WitHash.ScriptPubKey);

            await bobClient.RegisterOutputAsync(Money.Coins(0.25m), destinationKey3.PubKey.WitHash.ScriptPubKey);

            await bobClient.RegisterOutputAsync(Money.Coins(0.25m), destinationKey4.PubKey.WitHash.ScriptPubKey);

            Assert.Equal(4, round.Bobs.Count);
        }