예제 #1
0
        public DosTests(RegTestFixture regTestFixture)
        {
            RegTestFixture = regTestFixture;

            BackendHttpClient = new ClearnetHttpClient(() => new Uri(RegTestFixture.BackendEndPoint));
            SatoshiClient     = new SatoshiClient(BackendHttpClient);
        }
예제 #2
0
        public static async Task <(string password, IRPCClient rpc, Network network, Coordinator coordinator, ServiceConfiguration serviceConfiguration, BitcoinStore bitcoinStore, Backend.Global global)> InitializeTestEnvironmentAsync(
            RegTestFixture regTestFixture,
            int numberOfBlocksToGenerate,
            [CallerFilePath] string callerFilePath     = "",
            [CallerMemberName] string callerMemberName = "")
        {
            var global = regTestFixture.Global;

            await AssertFiltersInitializedAsync(regTestFixture, global);             // Make sure filters are created on the server side.

            if (numberOfBlocksToGenerate != 0)
            {
                await global.RpcClient.GenerateAsync(numberOfBlocksToGenerate);                 // Make sure everything is confirmed.
            }
            global.Coordinator.UtxoReferee.Clear();

            var network = global.RpcClient.Network;
            var serviceConfiguration = new ServiceConfiguration(MixUntilAnonymitySet.PrivacyLevelSome.ToString(), 2, 21, 50, regTestFixture.BackendRegTestNode.P2pEndPoint, Money.Coins(Constants.DefaultDustThreshold));

            var dir              = Tests.Common.GetWorkDir(callerFilePath, callerMemberName);
            var indexStore       = new IndexStore(Path.Combine(dir, "indexStore"), network, new SmartHeaderChain());
            var transactionStore = new AllTransactionStore(Path.Combine(dir, "transactionStore"), network);
            var mempoolService   = new MempoolService();
            var blocks           = new FileSystemBlockRepository(Path.Combine(dir, "blocks"), network);
            var bitcoinStore     = new BitcoinStore(indexStore, transactionStore, mempoolService, blocks);
            await bitcoinStore.InitializeAsync();

            return("password", global.RpcClient, network, global.Coordinator, serviceConfiguration, bitcoinStore, global);
        }
예제 #3
0
    public DosTests(RegTestFixture regTestFixture)
    {
        RegTestFixture = regTestFixture;

        BackendHttpClient = regTestFixture.BackendHttpClient;
        SatoshiClient     = new SatoshiClient(BackendHttpClient);
    }
예제 #4
0
        private static async Task AssertFiltersInitializedAsync(RegTestFixture regTestFixture, Backend.Global global)
        {
            var firstHash = await global.RpcClient.GetBlockHashAsync(0);

            while (true)
            {
                using var client = new WasabiClient(new Uri(regTestFixture.BackendEndPoint), null);
                FiltersResponse filtersResponse = await client.GetFiltersAsync(firstHash, 1000);

                Assert.NotNull(filtersResponse);

                var filterCount = filtersResponse.Filters.Count();
                if (filterCount >= 101)
                {
                    break;
                }
                else
                {
                    await Task.Delay(100);
                }
            }
        }
예제 #5
0
        public static async Task <(string password, IRPCClient rpc, Network network, Coordinator coordinator, ServiceConfiguration serviceConfiguration, BitcoinStore bitcoinStore, Backend.Global global)> InitializeTestEnvironmentAsync(
            RegTestFixture regTestFixture,
            int numberOfBlocksToGenerate,
            [CallerFilePath] string callerFilePath     = null,
            [CallerMemberName] string callerMemberName = null)
        {
            var global = regTestFixture.Global;

            await AssertFiltersInitializedAsync(regTestFixture, global);             // Make sure filters are created on the server side.

            if (numberOfBlocksToGenerate != 0)
            {
                await global.RpcClient.GenerateAsync(numberOfBlocksToGenerate);                 // Make sure everything is confirmed.
            }
            global.Coordinator.UtxoReferee.Clear();

            var network = global.RpcClient.Network;
            var serviceConfiguration = new ServiceConfiguration(MixUntilAnonymitySet.PrivacyLevelSome.ToString(), 2, 21, 50, regTestFixture.BackendRegTestNode.P2pEndPoint, Money.Coins(Constants.DefaultDustThreshold));
            var bitcoinStore         = new BitcoinStore();
            var dir = GetWorkDir(callerFilePath, callerMemberName);
            await bitcoinStore.InitializeAsync(dir, network);

            return("password", global.RpcClient, network, global.Coordinator, serviceConfiguration, bitcoinStore, global);
        }
예제 #6
0
 public BackendTests(RegTestFixture regTestFixture)
 {
     RegTestFixture = regTestFixture;
 }
예제 #7
0
    public async Task BanningTestsAsync()
    {
        (_, IRPCClient rpc, Network network, Coordinator coordinator, _, _, _) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1);

        Money   denomination                  = Money.Coins(0.1m);
        decimal coordinatorFeePercent         = 0.1m;
        int     anonymitySet                  = 3;
        int     connectionConfirmationTimeout = 120;
        var     roundConfig = RegTestFixture.CreateRoundConfig(denomination, 140, 0.7, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, true, 11);

        coordinator.RoundConfig.UpdateOrDefault(roundConfig, toFile: true);
        coordinator.AbortAllRoundsInInputRegistration("");

        await rpc.GenerateAsync(3);         // So to make sure we have enough money.

        Uri baseUri        = new(RegTestFixture.BackendEndPoint);
        var fundingTxCount = 0;
        List <(Requester requester, BlindedOutputWithNonceIndex blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData)> inputRegistrationUsers = new();
        CoordinatorRound?round = null;

        for (int i = 0; i < roundConfig.AnonymitySet; i++)
        {
            List <(Key key, BitcoinAddress inputAddress, uint256 txHash, Transaction tx, OutPoint input)> userInputData = new();
            var activeOutputAddress = new Key().GetAddress(ScriptPubKeyType.Segwit, network);
            var changeOutputAddress = new Key().GetAddress(ScriptPubKeyType.Segwit, network);
            Assert.True(coordinator.TryGetCurrentInputRegisterableRound(out round));
            Requester requester = new();
            var       nonce     = round !.NonceProvider.GetNextNonce();

            BlindedOutputWithNonceIndex blinded = new(nonce.N, requester.BlindScript(round.MixingLevels.GetBaseLevel().SignerKey.PubKey, nonce.R, activeOutputAddress.ScriptPubKey));
            uint256 blindedOutputScriptsHash    = new(Hashes.SHA256(blinded.BlindedOutput.ToBytes()));

            List <InputProofModel> inputProofModels = new();
            int numberOfInputs    = CryptoHelpers.RandomInt(1, 6);
            var receiveSatoshiSum = 0;
            for (int j = 0; j < numberOfInputs; j++)
            {
                Key key            = new();
                var receiveSatoshi = CryptoHelpers.RandomInt(1000, 100000000);
                receiveSatoshiSum += receiveSatoshi;
                if (j == numberOfInputs - 1)
                {
                    receiveSatoshi = 100000000;
                }
                var     inputAddress = key.PubKey.GetAddress(ScriptPubKeyType.Segwit, network);
                uint256 txHash       = await rpc.SendToAddressAsync(inputAddress, Money.Satoshis(receiveSatoshi));

                fundingTxCount++;
                Assert.NotNull(txHash);
                Transaction transaction = await rpc.GetRawTransactionAsync(txHash);

                var coin = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single();

                OutPoint input      = coin.Outpoint;
                var      inputProof = new InputProofModel {
                    Input = input, Proof = key.SignCompact(blindedOutputScriptsHash)
                };
                inputProofModels.Add(inputProof);

                GetTxOutResponse?getTxOutResponse = await rpc.GetTxOutAsync(input.Hash, (int)input.N, includeMempool : true);

                // Check if inputs are unspent.
                Assert.NotNull(getTxOutResponse);

                userInputData.Add((key, inputAddress, txHash, transaction, input));
            }

            inputRegistrationUsers.Add((requester, blinded, activeOutputAddress, changeOutputAddress, inputProofModels, userInputData));
        }

        var mempool = await rpc.GetRawMempoolAsync();

        Assert.Equal(inputRegistrationUsers.SelectMany(x => x.userInputData).Count(), mempool.Length);

        while ((await rpc.GetRawMempoolAsync()).Length != 0)
        {
            await rpc.GenerateAsync(1);
        }

        List <Task <AliceClient4> > aliceClients = new();

        foreach (var user in inputRegistrationUsers)
        {
            aliceClients.Add(AliceClientBase.CreateNewAsync(round !.RoundId, new[] { user.activeOutputAddress }, new[] { round !.MixingLevels.GetBaseLevel().SignerKey.PubKey }, new[] { user.requester }, network, user.changeOutputAddress, new[] { user.blinded }, user.inputProofModels, BackendHttpClient));
예제 #8
0
 public SendTests(RegTestFixture regTestFixture)
 {
     RegTestFixture = regTestFixture;
 }
예제 #9
0
 public WalletTests(RegTestFixture regTestFixture)
 {
     RegTestFixture = regTestFixture;
 }
예제 #10
0
 public BuildTests(RegTestFixture regTestFixture)
 {
     RegTestFixture = regTestFixture;
 }
예제 #11
0
        public async Task BanningTestsAsync()
        {
            (_, IRPCClient rpc, Network network, Coordinator coordinator, _, _, _) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1);

            Money   denomination                  = Money.Coins(0.1m);
            decimal coordinatorFeePercent         = 0.1m;
            int     anonymitySet                  = 3;
            int     connectionConfirmationTimeout = 120;
            var     roundConfig = RegTestFixture.CreateRoundConfig(denomination, 140, 0.7, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, true, 11);

            coordinator.RoundConfig.UpdateOrDefault(roundConfig, toFile: true);
            coordinator.AbortAllRoundsInInputRegistration("");

            await rpc.GenerateAsync(3);             // So to make sure we have enough money.

            Uri baseUri                = new Uri(RegTestFixture.BackendEndPoint);
            var fundingTxCount         = 0;
            var inputRegistrationUsers = new List <(Requester requester, BlindedOutputWithNonceIndex blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData)>();
            CoordinatorRound round     = null;

            for (int i = 0; i < roundConfig.AnonymitySet; i++)
            {
                var userInputData       = new List <(Key key, BitcoinWitPubKeyAddress inputAddress, uint256 txHash, Transaction tx, OutPoint input)>();
                var activeOutputAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Segwit, network);
                var changeOutputAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Segwit, network);
                round = coordinator.GetCurrentInputRegisterableRoundOrDefault();
                Requester requester = new Requester();
                var       nonce     = round.NonceProvider.GetNextNonce();

                var     blinded = new BlindedOutputWithNonceIndex(nonce.N, requester.BlindScript(round.MixingLevels.GetBaseLevel().SignerKey.PubKey, nonce.R, activeOutputAddress.ScriptPubKey));
                uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blinded.BlindedOutput.ToBytes()));

                var inputProofModels  = new List <InputProofModel>();
                int numberOfInputs    = CryptoHelpers.RandomInt(1, 6);
                var receiveSatoshiSum = 0;
                for (int j = 0; j < numberOfInputs; j++)
                {
                    var key            = new Key();
                    var receiveSatoshi = CryptoHelpers.RandomInt(1000, 100000000);
                    receiveSatoshiSum += receiveSatoshi;
                    if (j == numberOfInputs - 1)
                    {
                        receiveSatoshi = 100000000;
                    }
                    BitcoinWitPubKeyAddress inputAddress = key.PubKey.GetSegwitAddress(network);
                    uint256 txHash = await rpc.SendToAddressAsync(inputAddress, Money.Satoshis(receiveSatoshi));

                    fundingTxCount++;
                    Assert.NotNull(txHash);
                    Transaction transaction = await rpc.GetRawTransactionAsync(txHash);

                    var coin = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single();

                    OutPoint input      = coin.Outpoint;
                    var      inputProof = new InputProofModel {
                        Input = input, Proof = key.SignCompact(blindedOutputScriptsHash)
                    };
                    inputProofModels.Add(inputProof);

                    GetTxOutResponse getTxOutResponse = await rpc.GetTxOutAsync(input.Hash, (int)input.N, includeMempool : true);

                    // Check if inputs are unspent.
                    Assert.NotNull(getTxOutResponse);

                    userInputData.Add((key, inputAddress, txHash, transaction, input));
                }

                inputRegistrationUsers.Add((requester, blinded, activeOutputAddress, changeOutputAddress, inputProofModels, userInputData));
            }

            var mempool = await rpc.GetRawMempoolAsync();

            Assert.Equal(inputRegistrationUsers.SelectMany(x => x.userInputData).Count(), mempool.Length);

            while ((await rpc.GetRawMempoolAsync()).Length != 0)
            {
                await rpc.GenerateAsync(1);
            }

            var aliceClients = new List <Task <AliceClient4> >();

            foreach (var user in inputRegistrationUsers)
            {
                aliceClients.Add(AliceClientBase.CreateNewAsync(round.RoundId, new[] { user.activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SignerKey.PubKey }, new[] { user.requester }, network, user.changeOutputAddress, new[] { user.blinded }, user.inputProofModels, BackendHttpClient));
            }

            long roundId = 0;
            var  users   = new List <(Requester requester, BlindedOutputWithNonceIndex blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData, AliceClient4 aliceClient, UnblindedSignature unblindedSignature)>();

            for (int i = 0; i < inputRegistrationUsers.Count; i++)
            {
                var user    = inputRegistrationUsers[i];
                var request = aliceClients[i];

                var aliceClient = await request;

                if (roundId == 0)
                {
                    roundId = aliceClient.RoundId;
                }
                else
                {
                    Assert.Equal(roundId, aliceClient.RoundId);
                }

                // Because it's valuetuple.
                users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, aliceClient, null));
            }

            Assert.Equal(users.Count, roundConfig.AnonymitySet);

            var confirmationRequests = new List <Task <(RoundPhase currentPhase, IEnumerable <ActiveOutput>)> >();

            foreach (var user in users)
            {
                confirmationRequests.Add(user.aliceClient.PostConfirmationAsync());
            }

            RoundPhase roundPhase = RoundPhase.InputRegistration;
            int        k          = 0;

            foreach (var request in confirmationRequests)
            {
                var resp = await request;
                if (roundPhase == RoundPhase.InputRegistration)
                {
                    roundPhase = resp.currentPhase;
                }
                else
                {
                    Assert.Equal(roundPhase, resp.currentPhase);
                }

                var user = users.ElementAt(k);
                user.unblindedSignature = resp.Item2.First().Signature;
            }

            {
                var times = 0;
                while (!(await SatoshiClient.GetAllRoundStatesAsync()).All(x => x.Phase == RoundPhase.InputRegistration))
                {
                    await Task.Delay(100);

                    if (times > 50)                     // 5 sec, 3 should be enough
                    {
                        throw new TimeoutException("Not all rounds were in InputRegistration.");
                    }
                    times++;
                }
            }

            int bannedCount = coordinator.UtxoReferee.CountBanned(false);

            Assert.Equal(0, bannedCount);

            aliceClients.Clear();
            round = coordinator.GetCurrentInputRegisterableRoundOrDefault();
            foreach (var user in inputRegistrationUsers)
            {
                aliceClients.Add(AliceClientBase.CreateNewAsync(round.RoundId, new[] { user.activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SignerKey.PubKey }, new[] { user.requester }, network, user.changeOutputAddress, new[] { user.blinded }, user.inputProofModels, BackendHttpClient));
            }

            roundId = 0;
            users   = new List <(Requester requester, BlindedOutputWithNonceIndex blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData, AliceClient4 aliceClient, UnblindedSignature unblindedSignature)>();
            for (int i = 0; i < inputRegistrationUsers.Count; i++)
            {
                var user    = inputRegistrationUsers[i];
                var request = aliceClients[i];

                var aliceClient = await request;
                if (roundId == 0)
                {
                    roundId = aliceClient.RoundId;
                }
                else
                {
                    Assert.Equal(roundId, aliceClient.RoundId);
                }

                // Because it's valuetuple.
                users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, aliceClient, null));
            }

            Assert.Equal(users.Count, roundConfig.AnonymitySet);

            confirmationRequests = new List <Task <(RoundPhase currentPhase, IEnumerable <ActiveOutput>)> >();

            foreach (var user in users)
            {
                confirmationRequests.Add(user.aliceClient.PostConfirmationAsync());
            }

            {
                var times = 0;
                while (!(await SatoshiClient.GetAllRoundStatesAsync()).All(x => x.Phase == RoundPhase.InputRegistration))
                {
                    await Task.Delay(100);

                    if (times > 50)                     // 5 sec, 3 should be enough
                    {
                        throw new TimeoutException("Not all rounds were in InputRegistration.");
                    }
                    times++;
                }
            }

            bannedCount = coordinator.UtxoReferee.CountBanned(false);
            Assert.True(bannedCount >= roundConfig.AnonymitySet);

            foreach (var aliceClient in aliceClients)
            {
                aliceClient?.Dispose();
            }
        }
예제 #12
0
        public async Task NotingTestsAsync()
        {
            (_, IRPCClient rpc, Network network, Coordinator coordinator, _, _, _) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1);

            Money   denomination                  = Money.Coins(1m);
            decimal coordinatorFeePercent         = 0.1m;
            int     anonymitySet                  = 2;
            int     connectionConfirmationTimeout = 1;
            bool    doesNoteBeforeBan             = true;
            CoordinatorRoundConfig roundConfig    = RegTestFixture.CreateRoundConfig(denomination, 140, 0.7, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, doesNoteBeforeBan, 11);

            coordinator.RoundConfig.UpdateOrDefault(roundConfig, toFile: true);
            coordinator.AbortAllRoundsInInputRegistration("");

            Uri baseUri = new Uri(RegTestFixture.BackendEndPoint);

            var              registerRequests  = new List <(BitcoinWitPubKeyAddress changeOutputAddress, BlindedOutputWithNonceIndex blindedData, InputProofModel[] inputsProofs)>();
            AliceClient4     aliceClientBackup = null;
            CoordinatorRound round             = coordinator.GetCurrentInputRegisterableRoundOrDefault();

            for (int i = 0; i < roundConfig.AnonymitySet; i++)
            {
                BitcoinWitPubKeyAddress activeOutputAddress = new Key().PubKey.GetSegwitAddress(network);
                BitcoinWitPubKeyAddress changeOutputAddress = new Key().PubKey.GetSegwitAddress(network);
                Key inputKey = new Key();
                BitcoinWitPubKeyAddress inputAddress = inputKey.PubKey.GetSegwitAddress(network);

                var requester = new Requester();
                var nonce     = round.NonceProvider.GetNextNonce();

                var     blinded = new BlindedOutputWithNonceIndex(nonce.N, requester.BlindScript(round.MixingLevels.GetBaseLevel().SignerKey.PubKey, nonce.R, activeOutputAddress.ScriptPubKey));
                uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blinded.BlindedOutput.ToBytes()));

                uint256 txHash = await rpc.SendToAddressAsync(inputAddress, Money.Coins(2));

                await rpc.GenerateAsync(1);

                Transaction transaction = await rpc.GetRawTransactionAsync(txHash);

                Coin     coin  = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single();
                OutPoint input = coin.Outpoint;

                InputProofModel inputProof = new InputProofModel {
                    Input = input, Proof = inputKey.SignCompact(blindedOutputScriptsHash)
                };
                InputProofModel[] inputsProofs = new InputProofModel[] { inputProof };
                registerRequests.Add((changeOutputAddress, blinded, inputsProofs));
                aliceClientBackup = await AliceClientBase.CreateNewAsync(round.RoundId, new[] { activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SignerKey.PubKey }, new[] { requester }, network, changeOutputAddress, new[] { blinded }, inputsProofs, BackendHttpClient);
            }

            await WaitForTimeoutAsync();

            int bannedCount = coordinator.UtxoReferee.CountBanned(false);

            Assert.Equal(0, bannedCount);
            int notedCount = coordinator.UtxoReferee.CountBanned(true);

            Assert.Equal(anonymitySet, notedCount);

            round = coordinator.GetCurrentInputRegisterableRoundOrDefault();

            foreach (var registerRequest in registerRequests)
            {
                await AliceClientBase.CreateNewAsync(round.RoundId, aliceClientBackup.RegisteredAddresses, round.MixingLevels.GetAllLevels().Select(x => x.SignerKey.PubKey), aliceClientBackup.Requesters, network, registerRequest.changeOutputAddress, new[] { registerRequest.blindedData }, registerRequest.inputsProofs, BackendHttpClient);
            }

            await WaitForTimeoutAsync();

            bannedCount = coordinator.UtxoReferee.CountBanned(false);
            Assert.Equal(anonymitySet, bannedCount);
            notedCount = coordinator.UtxoReferee.CountBanned(true);
            Assert.Equal(anonymitySet, notedCount);
        }
예제 #13
0
 public DosTests(RegTestFixture regTestFixture)
 {
     RegTestFixture = regTestFixture;
 }
예제 #14
0
 public BackendTests(RegTestFixture regTestFixture)
 {
     RegTestFixture       = regTestFixture;
     BackendHttpClient    = regTestFixture.BackendHttpClient;
     BackendApiHttpClient = new ClearnetHttpClient(regTestFixture.HttpClient, () => RegTestFixture.BackendEndPointApiUri);
 }
예제 #15
0
 public BackendTests(RegTestFixture regTestFixture)
 {
     RegTestFixture    = regTestFixture;
     BackendHttpClient = new BackendHttpClient(new ClearnetHttpClient(() => RegTestFixture.BackendEndPointApiUri));
 }