예제 #1
0
        public void SingleUploadSuccessMaxFileSize()
        {
            var owner = KeyPair.Generate();

            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            BigInteger accountBalance = (Archive.MaxSize / 1024) / KilobytesPerStake;  //provide enough account balance for max file size available space

            accountBalance *= UnitConversion.GetUnitValue(Nexus.StakingTokenDecimals);

            Transaction tx = null;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000);
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance);
            simulator.EndBlock();

            //-----------
            //Perform a valid Stake call
            var stakeAmount         = accountBalance;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract(Nexus.StakeContractName, "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            BigInteger stakedAmount = simulator.Nexus.RootChain.InvokeContract(Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();

            Assert.IsTrue(stakedAmount == stakeAmount);

            var finalSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            Assert.IsTrue(stakeAmount == startingSoulBalance - finalSoulBalance);

            //-----------
            //Upload a file: should succeed
            var filename      = "notAVirus.exe";
            var headerSize    = CalculateRequiredSize(filename, 0);
            var contentSize   = (long)(Archive.MaxSize) - (long)headerSize;
            var content       = new byte[contentSize];
            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]).
                                                     SpendGas(testUser.Address).EndScript());
            System.IO.File.WriteAllText(@"D:\Repos\bug_vm.txt", string.Join('\n', new VM.Disassembler(tx.Script).Instructions));
            simulator.EndBlock();

            var usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == contentSize + headerSize);
        }
예제 #2
0
        public void OracleTestWithTooMuchData()
        {
            var owner  = PhantasmaKeys.Generate();
            var wallet = PhantasmaKeys.Generate();
            var nexus  = new Nexus("simnet", null, null);

            nexus.SetOracleReader(new OracleSimulator(nexus));
            var simulator = new NexusSimulator(nexus, owner, 1234);

            for (int i = 0; i < DomainSettings.MaxOracleEntriesPerBlock + 1; i++)
            {
                var url    = DomainExtensions.GetOracleBlockURL("neo", "neo", new BigInteger(i));
                var iBlock = nexus.GetOracleReader().Read <InteropBlock>(DateTime.Now, url);
            }

            Assert.ThrowsException <ChainException>(() =>
            {
                simulator.BeginBlock();
                simulator.GenerateTransfer(owner, wallet.Address, nexus.RootChain, "SOUL", 100);
                simulator.EndBlock().First();
            });
        }
예제 #3
0
        public void OracleTestWithData()
        {
            var owner  = PhantasmaKeys.Generate();
            var wallet = PhantasmaKeys.Generate();
            var nexus  = new Nexus("simnet", null, null);

            nexus.SetOracleReader(new OracleSimulator(nexus));
            var simulator = new NexusSimulator(nexus, owner, 1234);

            //for (var i = 0; i < 65536; i++)
            for (var i = 0; i < 100; i++)
            {
                var url    = DomainExtensions.GetOracleBlockURL("neo", "neo", new BigInteger(i));
                var iBlock = nexus.GetOracleReader().Read <InteropBlock>(DateTime.Now, url);
            }

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, wallet.Address, nexus.RootChain, "SOUL", 100);
            var block = simulator.EndBlock().First();

            Console.WriteLine("block oracle data: " + block.OracleData.Count());
            Assert.IsTrue(block.OracleData.Count() == 100);
        }
예제 #4
0
        public void TestNachoPurchaseBonus()
        {
            var owner     = KeyPair.Generate();
            var simulator = new NexusSimulator(owner, 1234);

            var tokenSupply = ToBigInteger(69931640.63m, NACHO_TOKEN_DECIMALS);

            simulator.BeginBlock();
            simulator.GenerateToken(owner, NACHO_SYMBOL, NACHO_SYMBOL, Nexus.PlatformName, Hash.FromString(NACHO_SYMBOL), tokenSupply, NACHO_TOKEN_DECIMALS, Fungible | Transferable | Finite | Divisible);
            simulator.MintTokens(owner, owner.Address, NACHO_SYMBOL, tokenSupply);
            simulator.EndBlock();

            var buyer    = KeyPair.Generate();
            var receiver = KeyPair.Generate();
            var nexus    = simulator.Nexus;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, FuelTokenSymbol, 100000000);
            simulator.MintTokens(owner, owner.Address, FiatTokenSymbol,
                                 new BigInteger("1000000000000000000000000000000000000000000000000", 10) * GetUnitValue(FiatTokenDecimals));
            //simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, Nexus.FiatTokenSymbol, 1000000 * UnitConversion.GetUnitValue(Nexus.FiatTokenDecimals));
            simulator.EndBlock();

            var ownerFiat = simulator.Nexus.RootChain.GetTokenBalance(Nexus.FiatTokenSymbol, owner.Address);

            decimal milestoneRequiredMoney = 0;

            decimal[] purchaseAmounts = { 1, 2, 5, 10, 20, 50, 100, 250, 500 };
            decimal[] purchaseBonus   = { 0, 5, 10, 15, 20, 25, 30, 35, 40 };

            for (int stage = 0; stage < stageCount; stage++)
            {
                for (int milestone = 1; milestone <= milestoneCount; milestone++)
                {
                    decimal milestoneTokens = stageTokenAmount[stage] * milestone / 10m;
                    milestoneTokens = Math.Round(milestoneTokens, 2, AwayFromZero);

                    decimal milestoneTokensPerUsd = stageTokensPerUsd[stage] * tokenDecreaseFactor[stage];
                    milestoneTokensPerUsd = Math.Round(milestoneTokensPerUsd, 3, AwayFromZero);

                    for (int purchase = 0; purchase < purchaseAmounts.Length; purchase++)
                    {
                        var purchaseCoef = purchaseBonus[purchase] / 100;

                        var expectedPurchasedTokens =
                            purchaseAmounts[purchase] * milestoneTokensPerUsd * (1 + purchaseCoef);
                        var expectedPurchasedTokensBigint = ToBigInteger(expectedPurchasedTokens, NACHO_TOKEN_DECIMALS);

                        var purchaseAmountsBigint =
                            ToBigInteger(purchaseAmounts[purchase], FiatTokenDecimals);

                        simulator.BeginBlock();
                        simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, FiatTokenSymbol, purchaseAmountsBigint);
                        simulator.EndBlock();

                        var initialNachos = simulator.Nexus.RootChain.GetTokenBalance(NACHO_SYMBOL, receiver.Address);
                        var initialFiat   = simulator.Nexus.RootChain.GetTokenBalance(FiatTokenSymbol, receiver.Address);

                        simulator.BeginBlock();
                        simulator.GenerateCustomTransaction(buyer, ProofOfWork.None, () =>
                                                            ScriptUtils.BeginScript().AllowGas(buyer.Address, Address.Null, 1, 9999)
                                                            .CallContract("nacho", "BuyInApp", buyer.Address, FiatTokenSymbol, purchaseAmountsBigint).
                                                            SpendGas(buyer.Address).EndScript());
                        simulator.EndBlock();

                        var finalNachos = simulator.Nexus.RootChain.GetTokenBalance(NACHO_SYMBOL, receiver.Address);
                        var finalFiat   = simulator.Nexus.RootChain.GetTokenBalance(Nexus.FiatTokenSymbol, receiver.Address);

                        Assert.IsTrue(finalNachos == initialNachos + expectedPurchasedTokensBigint);
                        Assert.IsTrue(finalFiat == initialFiat - purchaseAmountsBigint);

                        milestoneTokens -= expectedPurchasedTokens;
                    }

                    //do a single order to clean up the rest of the current milestone
                    var requiredMoney = milestoneTokens / milestoneTokensPerUsd;

                    Assert.IsTrue(requiredMoney >= 500, "unexpected order size: not enough for 40% bonus");

                    requiredMoney = requiredMoney / 1.4m;

                    var bigintMoney = ToBigInteger(requiredMoney, FiatTokenDecimals);

                    simulator.BeginBlock();
                    simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, FiatTokenSymbol, bigintMoney);
                    simulator.EndBlock();

                    simulator.BeginBlock();
                    simulator.GenerateCustomTransaction(buyer, ProofOfWork.None, () =>
                                                        ScriptUtils.BeginScript().AllowGas(buyer.Address, Address.Null, 1, 9999)
                                                        .CallContract("nacho", "BuyInApp", buyer.Address, FiatTokenSymbol, bigintMoney).
                                                        SpendGas(buyer.Address).EndScript());
                    simulator.EndBlock();
                }
            }
        }
예제 #5
0
        private void CreateValidators()
        {
            simulator.blockTimeSkip = TimeSpan.FromSeconds(10);

            var fuelAmount  = UnitConversion.ToBigInteger(10, FuelTokenDecimals);
            var stakeAmount = UnitConversion.ToBigInteger(50000, StakingTokenDecimals);

            for (int i = 1; i < validatorKeyPairs.Length; i++)
            {
                var validator = validatorKeyPairs[i];
                simulator.BeginBlock();
                simulator.GenerateTransfer(owner, validator.Address, nexus.RootChain, FuelTokenSymbol, fuelAmount);
                simulator.GenerateTransfer(owner, validator.Address, nexus.RootChain, StakingTokenSymbol, stakeAmount);
                simulator.EndBlock();
            }

            // make first validator allocate 5 validator spots
            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(owner, ProofOfWork.None, () =>
                                                ScriptUtils.BeginScript().
                                                AllowGas(owner.Address, Address.Null, 1, 9999).
                                                CallContract(GovernanceContractName, nameof(GovernanceContract.SetValue), ValidatorCountTag, new BigInteger(5)).
                                                SpendGas(owner.Address).
                                                EndScript());
            simulator.EndBlock();

            // make validator candidates stake enough for stake master status
            for (int i = 1; i < validatorKeyPairs.Length; i++)
            {
                var validator = validatorKeyPairs[i];

                simulator.BeginBlock();
                simulator.GenerateCustomTransaction(validator, ProofOfWork.None, () =>
                                                    ScriptUtils.BeginScript().
                                                    AllowGas(validator.Address, Address.Null, 1, 9999).
                                                    CallContract(StakeContractName, nameof(StakeContract.Stake), validator.Address, stakeAmount).
                                                    SpendGas(validator.Address).
                                                    EndScript());
                simulator.EndBlock();
            }

            var secondValidator = validatorKeyPairs[1];

            // set a second validator, no election required because theres only one validator for now
            simulator.BeginBlock();
            var tx = simulator.GenerateCustomTransaction(owner, ProofOfWork.None, () =>
                                                         ScriptUtils.BeginScript().
                                                         AllowGas(owner.Address, Address.Null, 1, 9999).
                                                         CallContract(ValidatorContractName, nameof(ValidatorContract.SetValidator), secondValidator.Address, 1, Primary).
                                                         SpendGas(owner.Address).
                                                         EndScript());

            simulator.EndBlock().First();

            for (int i = 2; i < validatorKeyPairs.Length; i++)
            {
                var newValidator = validatorKeyPairs[i];
                AddNewValidator(newValidator);

                var validatorType = simulator.Nexus.RootChain
                                    .InvokeContract(simulator.Nexus.RootStorage, ValidatorContractName, nameof(ValidatorContract.GetValidatorType),
                                                    newValidator.Address).AsEnum <ValidatorType>();

                Assert.IsTrue(validatorType != Invalid);
            }
        }
예제 #6
0
        public void TestNachoPurchase()
        {
            var owner     = KeyPair.Generate();
            var simulator = new NexusSimulator(owner, 1234);

            var tokenSupply = ToBigInteger(69931640.63m, NACHO_TOKEN_DECIMALS);

            simulator.BeginBlock();
            simulator.GenerateToken(owner, NACHO_SYMBOL, NACHO_SYMBOL, DomainSettings.PlatformName, Hash.FromString(NACHO_SYMBOL), tokenSupply, NACHO_TOKEN_DECIMALS, Fungible | Transferable | Finite | Divisible);
            simulator.MintTokens(owner, owner.Address, NACHO_SYMBOL, tokenSupply);
            simulator.EndBlock();

            var buyer    = KeyPair.Generate();
            var receiver = KeyPair.Generate();
            var nexus    = simulator.Nexus;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, FuelTokenSymbol, 100000000);
            simulator.MintTokens(owner, owner.Address, FiatTokenSymbol,
                                 new BigInteger("1000000000000000000000000000000000000000000000000", 10) * GetUnitValue(FiatTokenDecimals));
            //simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, DomainSettings.FiatTokenSymbol, 1000000 * UnitConversion.GetUnitValue(DomainSettings.FiatTokenDecimals));
            simulator.EndBlock();

            var ownerFiat = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, DomainSettings.FiatTokenSymbol, owner.Address);

            decimal requiredMoney = 0;

            for (int stage = 0; stage < stageCount; stage++)
            {
                for (int milestone = 1; milestone <= milestoneCount; milestone++)
                {
                    decimal milestoneTokens = stageTokenAmount[stage] * milestone / 10m;
                    milestoneTokens = Math.Round(milestoneTokens, 2, AwayFromZero);

                    decimal milestoneTokensPerUsd = stageTokensPerUsd[stage] * tokenDecreaseFactor[stage];
                    milestoneTokensPerUsd = Math.Round(milestoneTokensPerUsd, 3, AwayFromZero);

                    requiredMoney += milestoneTokens / milestoneTokensPerUsd;

                    Assert.IsTrue(requiredMoney >= 500, "unexpected order size: not enough for 40% bonus");

                    requiredMoney = requiredMoney / 1.4m;

                    var bigintMoney = ToBigInteger(requiredMoney, FiatTokenDecimals);

                    simulator.BeginBlock();
                    simulator.GenerateTransfer(owner, buyer.Address, nexus.RootChain, FiatTokenSymbol, bigintMoney);
                    simulator.EndBlock();

                    var initialNachos = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, NACHO_SYMBOL, receiver.Address);
                    var initialFiat   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, DomainSettings.FiatTokenSymbol, receiver.Address);

                    simulator.BeginBlock();
                    simulator.GenerateCustomTransaction(buyer, ProofOfWork.None, () =>
                                                        ScriptUtils.BeginScript().AllowGas(buyer.Address, Address.Null, 1, 9999)
                                                        .CallContract("nacho", "BuyInApp", buyer.Address, FiatTokenSymbol, bigintMoney).
                                                        SpendGas(buyer.Address).EndScript());
                    simulator.EndBlock();

                    var finalNachos = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, NACHO_SYMBOL, receiver.Address);
                    var finalFiat   = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, DomainSettings.FiatTokenSymbol, receiver.Address);

                    var milestoneTokensBigInt = ToBigInteger(milestoneTokens, NACHO_TOKEN_DECIMALS);

                    Assert.IsTrue(finalNachos == initialNachos + milestoneTokensBigInt);
                    Assert.IsTrue(finalFiat == initialFiat - bigintMoney);
                }
            }
        }
예제 #7
0
        public void UploadDuplicateFilename()
        {
            var owner = KeyPair.Generate();

            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            var accountBalance = MinimumValidStake * 100;

            Transaction tx = null;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000);
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance);
            simulator.EndBlock();

            //-----------
            //Perform a valid Stake call
            var stakeAmount         = MinimumValidStake * 2;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract(Nexus.StakeContractName, "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            BigInteger stakedAmount = simulator.Nexus.RootChain.InvokeContract(Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();

            Assert.IsTrue(stakedAmount == stakeAmount);

            var finalSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            Assert.IsTrue(stakeAmount == startingSoulBalance - finalSoulBalance);

            //-----------
            //Upload a file: should succeed
            var filename    = "notAVirus.exe";
            var headerSize  = CalculateRequiredSize(filename, 0);
            var contentSize = (long)(stakeAmount / MinimumValidStake * KilobytesPerStake * 1024 / 2) - (long)headerSize;
            var content     = new byte[contentSize];

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            var usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == contentSize + headerSize);

            var oldSpace = contentSize + headerSize;

            //----------
            //Upload a file with the same name: should fail
            Assert.ThrowsException <ChainException>(() =>
            {
                simulator.BeginBlock();
                tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                         ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                         .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, content, ArchiveFlags.None, new byte[0]).
                                                         SpendGas(testUser.Address).EndScript());
                simulator.EndBlock();
            });

            Assert.IsTrue(usedSpace == oldSpace);
        }
예제 #8
0
        public void UnstakeWithStoredFilesFailure()
        {
            var owner = KeyPair.Generate();

            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            var accountBalance = MinimumValidStake * 100;

            Transaction tx = null;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000);
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance);
            simulator.EndBlock();

            //-----------
            //Perform a valid Stake call for minimum staking amount
            var stakedAmount        = MinimumValidStake;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract(Nexus.StakeContractName, "Stake", testUser.Address, stakedAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            //-----------
            //Upload a file
            var filename = "notAVirus.exe";

            var headerSize  = CalculateRequiredSize(filename, 0);
            var contentSize = (long)(stakedAmount / MinimumValidStake * KilobytesPerStake * 1024) - (long)headerSize;
            var content     = new byte[contentSize];

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            var usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == contentSize + headerSize);

            var oldSpace = usedSpace;

            //-----------
            //Time skip 1 day
            simulator.TimeSkipDays(1);

            //-----------
            //Try to unstake everything: should fail due to files still existing for this user
            var initialStakedAmount = simulator.Nexus.RootChain.InvokeContract(Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();
            var stakeReduction      = initialStakedAmount - MinimumValidStake;

            startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            Assert.ThrowsException <ChainException>(() =>
            {
                simulator.BeginBlock();
                simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                    ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                    .CallContract(Nexus.StakeContractName, "Unstake", testUser.Address, stakeReduction).
                                                    SpendGas(testUser.Address).EndScript());
                simulator.EndBlock();
            });

            var finalStakedAmount = simulator.Nexus.RootChain.InvokeContract(Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();

            Assert.IsTrue(initialStakedAmount == finalStakedAmount);

            usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == oldSpace);
        }
예제 #9
0
        public void SingleUploadSuccess()
        {
            var owner = KeyPair.Generate();

            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            var accountBalance = MinimumValidStake * 5;

            Transaction tx = null;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000);
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance);
            simulator.EndBlock();

            //-----------
            //Perform a valid Stake call for minimum staking amount
            var stakeAmount         = accountBalance / 2;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract(Nexus.StakeContractName, "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            BigInteger stakedAmount = simulator.Nexus.RootChain.InvokeContract(Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();

            Assert.IsTrue(stakedAmount == stakeAmount);

            var finalSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            Assert.IsTrue(stakeAmount == startingSoulBalance - finalSoulBalance);

            //-----------
            //Upload a file: should succeed
            var filename    = "notAVirus.exe";
            var headerSize  = CalculateRequiredSize(filename, 0);
            var contentSize = (long)((stakedAmount / MinimumValidStake * KilobytesPerStake) * 1024) - (long)headerSize;
            var content     = new byte[contentSize];
            var rnd         = new Random();

            for (int i = 0; i < content.Length; i++)
            {
                content[i] = (byte)rnd.Next();
            }

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]).
                                                     SpendGas(testUser.Address).EndScript());

            //System.IO.File.WriteAllText(@"c:\code\bug_vm.txt", string.Join('\n', new VM.Disassembler(tx.Script).Instructions));
            simulator.EndBlock();

            var usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == contentSize + headerSize);

            Assert.IsTrue(simulator.Nexus.ArchiveExists(contentMerkle.Root));
            var archive = simulator.Nexus.FindArchive(contentMerkle.Root);

            for (int i = 0; i < archive.BlockCount; i++)
            {
                int ofs          = (int)(i * Archive.BlockSize);
                var blockContent = content.Skip(ofs).Take((int)Archive.BlockSize).ToArray();
                simulator.Nexus.WriteArchiveBlock(archive, blockContent, i);
            }
        }
예제 #10
0
        public void ReduceAvailableSpace()
        {
            var owner = KeyPair.Generate();

            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            var accountBalance = MinimumValidStake * 100;

            Transaction tx = null;

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, DomainSettings.FuelTokenSymbol, 100000000);
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, DomainSettings.StakingTokenSymbol, accountBalance);
            simulator.EndBlock();

            //-----------
            //Perform a valid Stake call for minimum staking amount
            var stakedAmount        = MinimumValidStake * 5;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(simulator.Nexus.RootStorage, DomainSettings.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract(Nexus.StakeContractName, "Stake", testUser.Address, stakedAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            //-----------
            //Upload a file
            var filename = "notAVirus.exe";

            var headerSize  = CalculateRequiredSize(filename, 0);
            var contentSize = (long)(stakedAmount / MinimumValidStake * KilobytesPerStake * 1024 / 5) - (long)headerSize;
            var content     = new byte[contentSize];

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            var usedSpace = simulator.Nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, "storage", "GetUsedSpace", testUser.Address).AsNumber();

            Assert.IsTrue(usedSpace == contentSize + headerSize);

            //-----------
            //Time skip 1 day
            simulator.TimeSkipDays(1);

            //-----------
            //Try partial unstake: should succeed
            var initialStakedAmount = simulator.Nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();
            var stakeReduction      = stakedAmount / 5;

            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                .CallContract(Nexus.StakeContractName, "Unstake", testUser.Address, stakeReduction).
                                                SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            var finalStakedAmount = simulator.Nexus.RootChain.InvokeContract(simulator.Nexus.RootStorage, Nexus.StakeContractName, "GetStake", testUser.Address).AsNumber();

            Assert.IsTrue(finalStakedAmount == initialStakedAmount - stakeReduction);
        }