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

            var simulator = new ChainSimulator(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, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("energy", "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            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, () =>
                                                     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 = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);

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

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

            var testUser = KeyPair.Generate();

            var accountBalance = BaseEnergyRatioDivisor * 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 stakeAmount         = BaseEnergyRatioDivisor;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

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

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

            Assert.IsTrue(stakedAmount == stakeAmount);

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

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

            //-----------
            //Upload a file: should fail due to exceeding available space
            var filename    = "notAVirus.exe";
            var headerSize  = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "CalculateRequiredSize", filename, 0);
            var contentSize = (long)(stakeAmount * KilobytesPerStake * 1024) - (long)headerSize;
            var content     = new byte[contentSize];

            Assert.ThrowsException <Exception>(() =>
            {
                simulator.BeginBlock();
                tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                         ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                         .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize * 2, content, ArchiveFlags.None).
                                                         SpendGas(testUser.Address).EndScript());
                simulator.EndBlock();
            })
            ;
            var usedSpace = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);

            Assert.IsTrue(usedSpace == 0);
        }
예제 #3
0
 private void TopUpChannel(ChainSimulator simulator, KeyPair from, BigInteger amount)
 {
     simulator.BeginBlock();
     simulator.GenerateCustomTransaction(from, ProofOfWork.None, () =>
                                         ScriptUtils.BeginScript().AllowGas(from.Address, Address.Null, 1, 9999)
                                         .CallContract("relay", "TopUpChannel", from.Address, amount).
                                         SpendGas(from.Address).EndScript());
     simulator.EndBlock();
 }
예제 #4
0
        public void TransferToAccountName()
        {
            var owner     = KeyPair.Generate();
            var simulator = new ChainSimulator(owner, 1234);

            var nexus  = simulator.Nexus;
            var symbol = Nexus.FuelTokenSymbol;

            Func <KeyPair, string, bool> registerName = (keypair, name) =>
            {
                bool result = true;

                try
                {
                    simulator.BeginBlock();
                    var tx        = simulator.GenerateAccountRegistration(keypair, name);
                    var lastBlock = simulator.EndBlock().FirstOrDefault();

                    if (lastBlock != null)
                    {
                        Assert.IsTrue(tx != null);

                        var evts = lastBlock.GetEventsForTransaction(tx.Hash);
                        Assert.IsTrue(evts.Any(x => x.Kind == Blockchain.Contracts.EventKind.AddressRegister));
                    }
                }
                catch (Exception)
                {
                    result = false;
                }

                return(result);
            };

            var targetName = "hello";
            var testUser   = KeyPair.Generate();
            var token      = nexus.GetTokenInfo(symbol);
            var amount     = UnitConversion.ToBigInteger(10, token.Decimals);

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, symbol, amount);
            simulator.EndBlock();

            Assert.IsTrue(registerName(testUser, targetName));

            // Send from Genesis address to test user
            var transferAmount = 1;

            var initialFuelBalance = simulator.Nexus.RootChain.GetTokenBalance(symbol, testUser.Address);

            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(owner, () =>
                                                ScriptUtils.BeginScript().AllowGas(owner.Address, Address.Null, 1, 9999)
                                                .CallContract("token", "TransferTokens", owner.Address, targetName, token.Symbol, transferAmount)
                                                .SpendGas(owner.Address).EndScript());
            simulator.EndBlock();

            var finalFuelBalance = simulator.Nexus.RootChain.GetTokenBalance(symbol, testUser.Address);

            Assert.IsTrue(finalFuelBalance - initialFuelBalance == transferAmount);
        }
예제 #5
0
        public void MultiSigReceive2Test()
        {
            var owner = KeyPair.Generate();

            var multiAddr = KeyPair.Generate();
            var signee1   = KeyPair.Generate();
            var signee2   = KeyPair.Generate();
            var signee3   = KeyPair.Generate();
            var signee4   = KeyPair.Generate();

            var target = KeyPair.Generate();

            List <KeyPair> signees = new List <KeyPair>()
            {
                signee1, signee2, signee3
            };

            var simulator = new ChainSimulator(owner, 1234);

            var minSignees = 4;

            List <Address> addressList = new List <Address>()
            {
                multiAddr.Address,
                signee1.Address,
                signee2.Address,
                signee3.Address,
                signee4.Address
            };

            MultisigSettings settings = new MultisigSettings
            {
                addressCount = addressList.Count,
                signeeCount  = minSignees,
                addressArray = addressList.ToArray()
            };

            var script = GenerateMultisigScript(settings);

            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, multiAddr.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 2);

            simulator.GenerateTransfer(owner, target.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, target.Address, simulator.Nexus.RootChain, "SOUL", 2);

            simulator.GenerateTransfer(owner, signee1.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, signee1.Address, simulator.Nexus.RootChain, "SOUL", 2);

            simulator.GenerateTransfer(owner, signee2.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, signee2.Address, simulator.Nexus.RootChain, "SOUL", 2);

            simulator.GenerateTransfer(owner, signee3.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, signee3.Address, simulator.Nexus.RootChain, "SOUL", 2);

            // register script
            simulator.GenerateCustomTransaction(multiAddr,
                                                () => ScriptUtils.BeginScript().AllowGas(multiAddr.Address, Address.Null, 1, 9999)
                                                .CallContract("account", "RegisterScript", multiAddr.Address, script).SpendGas(multiAddr.Address)
                                                .EndScript());
            simulator.EndBlock();

            var balance = simulator.Nexus.RootChain.GetTokenBalance("SOUL", multiAddr.Address);

            Assert.IsTrue(balance == 2);

            var accountScript = simulator.Nexus.LookUpAddressScript(multiAddr.Address);

            Assert.IsTrue(accountScript != null && accountScript.Length > 0);

            simulator.BeginBlock();

            // send to multisig address
            simulator.GenerateTransfer(target, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 1);
            simulator.GenerateTransfer(signee1, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 1);
            simulator.GenerateTransfer(signee2, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 1);
            simulator.GenerateTransfer(signee3, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 1);

            simulator.EndBlock();

            var sourceBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", multiAddr.Address);

            Console.WriteLine("BALANCE: " + sourceBalanceSOUL);
            Assert.IsTrue(sourceBalanceSOUL == 6);

            var targetBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", target.Address);

            Assert.IsTrue(targetBalanceSOUL == 1);

            targetBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", signee1.Address);
            Assert.IsTrue(targetBalanceSOUL == 1);

            targetBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", signee2.Address);
            Assert.IsTrue(targetBalanceSOUL == 1);
        }
예제 #6
0
        public void MultiSigFail3Test()
        {
            var owner     = KeyPair.Generate();
            var multiAddr = KeyPair.Generate();

            var signee1 = KeyPair.Generate();
            var signee2 = KeyPair.Generate();

            var target = KeyPair.Generate();

            List <KeyPair> signees = new List <KeyPair>()
            {
                signee1, signee2
            };

            var simulator  = new ChainSimulator(owner, 1234);
            var minSignees = 4;

            List <Address> addressList = new List <Address>()
            {
                multiAddr.Address,
                signee1.Address,
                signee2.Address
            };

            MultisigSettings settings = new MultisigSettings
            {
                addressCount = addressList.Count,
                signeeCount  = minSignees,
                addressArray = addressList.ToArray()
            };

            var script = GenerateMultisigScript(settings);

            simulator.BeginBlock();

            simulator.GenerateTransfer(owner, multiAddr.Address, simulator.Nexus.RootChain, "KCAL", 100000000);
            simulator.GenerateTransfer(owner, multiAddr.Address, simulator.Nexus.RootChain, "SOUL", 2);

            // register script
            simulator.GenerateCustomTransaction(multiAddr,
                                                () => ScriptUtils.BeginScript().AllowGas(multiAddr.Address, Address.Null, 1, 9999)
                                                .CallContract("account", "RegisterScript", multiAddr.Address, script).SpendGas(multiAddr.Address)
                                                .EndScript());
            simulator.EndBlock();

            var balance = simulator.Nexus.RootChain.GetTokenBalance("SOUL", multiAddr.Address);

            Assert.IsTrue(balance == 2);

            var accountScript = simulator.Nexus.LookUpAddressScript(multiAddr.Address);

            Assert.IsTrue(accountScript != null && accountScript.Length > 0);

            Assert.ThrowsException <Exception>(() =>
            {
                simulator.BeginBlock();
                // do multisig tx --> will fail with Phantasma.VM.VMDebugException: transfer failed
                simulator.GenerateTransfer(multiAddr, target.Address, simulator.Nexus.RootChain, "SOUL", 1, signees);
                simulator.EndBlock();
            });

            var sourceBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", multiAddr.Address);

            Console.WriteLine("SOUL: " + sourceBalanceSOUL);
            Assert.IsTrue(sourceBalanceSOUL == 2);

            var targetBalanceKCAL = simulator.Nexus.RootChain.GetTokenBalance("KCAL", target.Address);

            Assert.IsTrue(targetBalanceKCAL == 0);

            var targetBalanceSOUL = simulator.Nexus.RootChain.GetTokenBalance("SOUL", target.Address);

            Assert.IsTrue(targetBalanceSOUL == 0);
        }
예제 #7
0
        public void UploadDuplicateFilename()
        {
            var owner = KeyPair.Generate();

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

            var testUser = KeyPair.Generate();

            var accountBalance = BaseEnergyRatioDivisor * 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, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("energy", "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            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 * KilobytesPerStake * 1024 / 2) - (long)headerSize;
            var content     = new byte[contentSize];

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                     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 = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);

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

            var oldSpace = contentSize + headerSize;

            //----------
            //Upload a file with the same name: should fail
            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                     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 ChainSimulator(owner, 1234);
            var nexus     = simulator.Nexus;

            var testUser = KeyPair.Generate();

            var accountBalance = BaseEnergyRatioDivisor * 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        = BaseEnergyRatioDivisor;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("energy", "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 * KilobytesPerStake * 1024) - (long)headerSize;
            var content     = new byte[contentSize];

            var contentMerkle = new MerkleTree(content);

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                     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 = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);

            Assert.IsTrue(usedSpace == contentSize);

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

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

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

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

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

            Assert.IsTrue(initialStakedAmount == finalStakedAmount);

            usedSpace = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);
        }
예제 #9
0
        public void SingleUploadSuccess()
        {
            var owner = KeyPair.Generate();

            var simulator = new ChainSimulator(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, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("energy", "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            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)(((UnitConversion.ToDecimal(stakedAmount, Nexus.StakingTokenDecimals)) * 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, () =>
                                                     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 = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address);

            Assert.IsTrue(usedSpace == 0);

            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 TestMarketContract()
        {
            var owner = KeyPair.Generate();

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

            var chain = nexus.RootChain;

            var nftSymbol = "COOL";

            var testUser = KeyPair.Generate();

            // Create the token CoolToken as an NFT
            simulator.BeginBlock();
            simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, nexus.FuelToken, 1000000);
            simulator.GenerateToken(owner, nftSymbol, "CoolToken", 0, 0, Blockchain.Tokens.TokenFlags.Transferable);
            simulator.EndBlock();

            var token = simulator.Nexus.FindTokenBySymbol(nftSymbol);

            Assert.IsTrue(token != null, "Can't find the token symbol");

            // verify nft presence on the user pre-mint
            var ownedTokenList = chain.GetTokenOwnerships(token).Get(testUser.Address);

            Assert.IsTrue(!ownedTokenList.Any(), "How does the sender already have a CoolToken?");

            var tokenROM = new byte[] { 0x1, 0x3, 0x3, 0x7 };
            var tokenRAM = new byte[] { 0x1, 0x4, 0x4, 0x6 };

            // Mint a new CoolToken directly on the user
            simulator.BeginBlock();
            simulator.GenerateNft(owner, testUser.Address, chain, token, tokenROM, tokenRAM);
            simulator.EndBlock();

            var auctions             = (MarketAuction[])simulator.Nexus.RootChain.InvokeContract("market", "GetAuctions");
            var previousAuctionCount = auctions.Length;

            // verify nft presence on the user post-mint
            ownedTokenList = chain.GetTokenOwnerships(token).Get(testUser.Address);
            Assert.IsTrue(ownedTokenList.Count() == 1, "How does the sender not have one now?");
            var tokenID = ownedTokenList.First();

            var price = 1000;

            Timestamp endDate = Timestamp.Now + TimeSpan.FromDays(2);

            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(testUser, () =>
                                                ScriptUtils.
                                                BeginScript().
                                                AllowGas(testUser.Address, Address.Null, 1, 9999).
                                                CallContract("market", "SellToken", testUser.Address, token.Symbol, Nexus.FuelTokenSymbol, tokenID, price, endDate).
                                                SpendGas(testUser.Address).
                                                EndScript()
                                                );
            simulator.EndBlock();

            auctions = (MarketAuction[])simulator.Nexus.RootChain.InvokeContract("market", "GetAuctions");
            Assert.IsTrue(auctions.Length == 1 + previousAuctionCount, "auction ids missing");

            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(owner, () =>
                                                ScriptUtils.
                                                BeginScript().
                                                AllowGas(owner.Address, Address.Null, 1, 9999).
                                                CallContract("market", "BuyToken", owner.Address, token.Symbol, auctions[previousAuctionCount].TokenID).
                                                SpendGas(owner.Address).
                                                EndScript()
                                                );
            simulator.EndBlock();

            auctions = (MarketAuction[])simulator.Nexus.RootChain.InvokeContract("market", "GetAuctions");
            Assert.IsTrue(auctions.Length == previousAuctionCount, "auction ids should be empty at this point");

            // verify that the nft was really moved
            ownedTokenList = chain.GetTokenOwnerships(token).Get(testUser.Address);
            Assert.IsTrue(ownedTokenList.Count() == 0, "How does the seller still have one?");

            ownedTokenList = chain.GetTokenOwnerships(token).Get(owner.Address);
            Assert.IsTrue(ownedTokenList.Count() == 1, "How does the buyer does not have what he bought?");
        }
예제 #11
0
        public void ReduceAvailableSpace()
        {
            var owner = KeyPair.Generate();

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

            var testUser = KeyPair.Generate();

            var accountBalance = BaseEnergyRatioDivisor * 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        = BaseEnergyRatioDivisor * 5;
            var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUser.Address);

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

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

            var headerSize  = (BigInteger)simulator.Nexus.RootChain.InvokeContract("storage", "CalculateRequiredSize", filename, 0);
            var contentSize = (long)(stakedAmount * KilobytesPerStake * 1024 / 5) - (long)headerSize;
            var content     = new byte[contentSize];

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "UploadFile", testUser.Address, filename, contentSize, content, ArchiveFlags.None).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            Assert.IsTrue(usedSpace == contentSize);

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

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

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

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

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

            Assert.IsTrue(finalStakedAmount == 0);
        }
예제 #12
0
        public void CumulativeUploadMoreThanAvailable()
        {
            var owner = KeyPair.Generate();

            var simulator = new ChainSimulator(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 stakeAmount         = 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("energy", "Stake", testUser.Address, stakeAmount).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

            BigInteger stakedAmount = simulator.Nexus.RootChain.InvokeContract("energy", "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 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: should fail due to exceeding available storage capacity

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

            Assert.ThrowsException <ChainException>(() =>
            {
                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();
            });

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

            var simulator = new ChainSimulator(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("energy", "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);

            //-----------
            //Delete the file

            simulator.BeginBlock();
            tx = simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                     ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                     .CallContract("storage", "DeleteFile", testUser.Address, filename).
                                                     SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            Assert.IsTrue(usedSpace == 0);

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

            //-----------
            //Try to unstake everything: should succeed
            simulator.BeginBlock();
            simulator.GenerateCustomTransaction(testUser, ProofOfWork.None, () =>
                                                ScriptUtils.BeginScript().AllowGas(testUser.Address, Address.Null, 1, 9999)
                                                .CallContract("energy", "Unstake", testUser.Address, stakedAmount).
                                                SpendGas(testUser.Address).EndScript());
            simulator.EndBlock();

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

            Assert.IsTrue(finalStakedAmount == 0);
        }
예제 #14
0
        public void TestNachoPurchase()
        {
            var owner     = KeyPair.Generate();
            var simulator = new ChainSimulator(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 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(NACHO_SYMBOL, receiver.Address);
                    var initialFiat   = simulator.Nexus.RootChain.GetTokenBalance(Nexus.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(NACHO_SYMBOL, receiver.Address);
                    var finalFiat   = simulator.Nexus.RootChain.GetTokenBalance(Nexus.FiatTokenSymbol, receiver.Address);

                    var milestoneTokensBigInt = ToBigInteger(milestoneTokens, NACHO_TOKEN_DECIMALS);

                    Assert.IsTrue(finalNachos == initialNachos + milestoneTokensBigInt);
                    Assert.IsTrue(finalFiat == initialFiat - bigintMoney);
                }
            }
        }