public void UnstakeWithStoredFilesFailure() { 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); 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("energy", "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("energy", "Unstake", testUser.Address, stakeReduction). SpendGas(testUser.Address).EndScript()); simulator.EndBlock(); }); var finalStakedAmount = simulator.Nexus.RootChain.InvokeContract("energy", "GetStake", testUser.Address).AsNumber(); Assert.IsTrue(initialStakedAmount == finalStakedAmount); usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUser.Address).AsNumber(); Assert.IsTrue(usedSpace == oldSpace); }
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); }
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, 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 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); } }
public void UploadDuplicateFileDifferentOwner() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var testUserA = KeyPair.Generate(); var testUserB = KeyPair.Generate(); var accountBalance = MinimumValidStake * 100; Transaction tx = null; simulator.BeginBlock(); simulator.GenerateTransfer(owner, testUserA.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000); simulator.GenerateTransfer(owner, testUserA.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance); simulator.GenerateTransfer(owner, testUserB.Address, nexus.RootChain, Nexus.FuelTokenSymbol, 100000000); simulator.GenerateTransfer(owner, testUserB.Address, nexus.RootChain, Nexus.StakingTokenSymbol, accountBalance); simulator.EndBlock(); //----------- //Perform a valid Stake call for userA var stakeAmount = MinimumValidStake * 2; var startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUserA.Address); simulator.BeginBlock(); tx = simulator.GenerateCustomTransaction(testUserA, ProofOfWork.None, () => ScriptUtils.BeginScript().AllowGas(testUserA.Address, Address.Null, 1, 9999) .CallContract("energy", "Stake", testUserA.Address, stakeAmount). SpendGas(testUserA.Address).EndScript()); simulator.EndBlock(); BigInteger stakedAmount = simulator.Nexus.RootChain.InvokeContract("energy", "GetStake", testUserA.Address).AsNumber(); Assert.IsTrue(stakedAmount == stakeAmount); var finalSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUserA.Address); Assert.IsTrue(stakeAmount == startingSoulBalance - finalSoulBalance); //---------- //Perform a valid Stake call for userB startingSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUserB.Address); simulator.BeginBlock(); tx = simulator.GenerateCustomTransaction(testUserB, ProofOfWork.None, () => ScriptUtils.BeginScript().AllowGas(testUserB.Address, Address.Null, 1, 9999) .CallContract("energy", "Stake", testUserB.Address, stakeAmount). SpendGas(testUserB.Address).EndScript()); simulator.EndBlock(); stakedAmount = simulator.Nexus.RootChain.InvokeContract("energy", "GetStake", testUserB.Address).AsNumber(); Assert.IsTrue(stakedAmount == stakeAmount); finalSoulBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUserB.Address); Assert.IsTrue(stakeAmount == startingSoulBalance - finalSoulBalance); //----------- //User A uploads 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(testUserA, ProofOfWork.None, () => ScriptUtils.BeginScript().AllowGas(testUserA.Address, Address.Null, 1, 9999) .CallContract("storage", "UploadFile", testUserA.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]). SpendGas(testUserA.Address).EndScript()); simulator.EndBlock(); var usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUserA.Address).AsNumber(); Assert.IsTrue(usedSpace == contentSize + headerSize); //---------- //User B uploads the same file: should succeed contentMerkle = new MerkleTree(content); simulator.BeginBlock(); tx = simulator.GenerateCustomTransaction(testUserB, ProofOfWork.None, () => ScriptUtils.BeginScript().AllowGas(testUserB.Address, Address.Null, 1, 9999) .CallContract("storage", "UploadFile", testUserB.Address, filename, contentSize, contentMerkle, ArchiveFlags.None, new byte[0]). SpendGas(testUserB.Address).EndScript()); simulator.EndBlock(); usedSpace = simulator.Nexus.RootChain.InvokeContract("storage", "GetUsedSpace", testUserB.Address).AsNumber(); Assert.IsTrue(usedSpace == contentSize + headerSize); }
public void SidechainNftTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var targetChain = nexus.FindChainByName("privacy"); var nftSymbol = "COOL"; var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); var fullAmount = UnitConversion.ToBigInteger(10, Nexus.FuelTokenDecimals); var smallAmount = fullAmount / 2; Assert.IsTrue(smallAmount > 0); // Send some SOUL to the test user (required for gas used in "transfer" transaction) simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, sourceChain, Nexus.FuelTokenSymbol, fullAmount); simulator.EndBlock(); // Create the token CoolToken as an NFT simulator.BeginBlock(); simulator.GenerateToken(owner, nftSymbol, "CoolToken", 0, 0, TokenFlags.Transferable); simulator.EndBlock(); var token = simulator.Nexus.GetTokenInfo(nftSymbol); var tokenData = new byte[] { 0x1, 0x3, 0x3, 0x7 }; Assert.IsTrue(nexus.TokenExists(nftSymbol), "Can't find the token symbol"); // verify nft presence on the sender pre-mint var ownerships = new OwnershipSheet(nftSymbol); var ownedTokenList = ownerships.Get(sourceChain.Storage, sender.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the sender already have a CoolToken?"); // Mint a new CoolToken directly on the sender simulator.BeginBlock(); simulator.MintNonFungibleToken(owner, sender.Address, nftSymbol, tokenData, new byte[0], 0); simulator.EndBlock(); // verify nft presence on the sender post-mint ownedTokenList = ownerships.Get(sourceChain.Storage, sender.Address); Assert.IsTrue(ownedTokenList.Count() == 1, "How does the sender not have one now?"); //verify that the present nft is the same we actually tried to create var tokenId = ownedTokenList.ElementAt(0); var nft = nexus.GetNFT(nftSymbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenData) || nft.RAM.SequenceEqual(tokenData), "And why is this NFT different than expected? Not the same data"); // verify nft presence on the receiver pre-transfer ownedTokenList = ownerships.Get(targetChain.Storage, receiver.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the receiver already have a CoolToken?"); var extraFee = UnitConversion.ToBigInteger(0.001m, Nexus.FuelTokenDecimals); // transfer that nft from sender to receiver simulator.BeginBlock(); simulator.GenerateSideChainSend(sender, Nexus.FuelTokenSymbol, sourceChain, receiver.Address, targetChain, smallAmount, extraFee); var txA = simulator.GenerateNftSidechainTransfer(sender, receiver.Address, sourceChain, targetChain, nftSymbol, tokenId); simulator.EndBlock(); var blockA = nexus.RootChain.LastBlock; // finish the chain transfer simulator.BeginBlock(); simulator.GenerateSideChainSettlement(receiver, nexus.RootChain, targetChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // verify the sender no longer has it ownedTokenList = ownerships.Get(sourceChain.Storage, sender.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the sender still have one?"); // verify nft presence on the receiver post-transfer ownedTokenList = ownerships.Get(targetChain.Storage, receiver.Address); Assert.IsTrue(ownedTokenList.Count() == 1, "How does the receiver not have one now?"); //verify that the transfered nft is the same we actually tried to create tokenId = ownedTokenList.ElementAt(0); nft = nexus.GetNFT(nftSymbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenData) || nft.RAM.SequenceEqual(tokenData), "And why is this NFT different than expected? Not the same data"); }
public void NoGasTestSideChainTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var targetChain = nexus.FindChainByName("privacy"); var symbol = Nexus.FuelTokenSymbol; var token = nexus.GetTokenInfo(symbol); var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); var originalAmount = UnitConversion.ToBigInteger(10, token.Decimals); var sideAmount = originalAmount / 2; Assert.IsTrue(sideAmount > 0); // Send from Genesis address to "sender" user simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, symbol, originalAmount); simulator.EndBlock(); // verify test user balance var balance = nexus.RootChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == originalAmount); Transaction txA = null, txB = null; try { // do a side chain send using test user balance from root to account chain simulator.BeginBlock(); txA = simulator.GenerateSideChainSend(sender, symbol, sourceChain, receiver.Address, targetChain, originalAmount, 1); simulator.EndBlock(); } catch (Exception e) { Assert.IsNotNull(e); } try { var blockA = nexus.RootChain.LastBlock; // finish the chain transfer simulator.BeginBlock(); txB = simulator.GenerateSideChainSettlement(sender, nexus.RootChain, targetChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); } catch (Exception e) { Assert.IsNotNull(e); } // verify balances, receiver should have 0 balance balance = targetChain.GetTokenBalance(symbol, receiver.Address); Assert.IsTrue(balance == 0); }
public void SideChainTransferMultipleSteps() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var sideChain = nexus.FindChainByName("bank"); var symbol = Nexus.FuelTokenSymbol; var token = nexus.GetTokenInfo(symbol); var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); var originalAmount = UnitConversion.ToBigInteger(10, token.Decimals); var sideAmount = originalAmount / 2; Assert.IsTrue(sideAmount > 0); var newChainName = "testing"; // Send from Genesis address to "sender" user simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, symbol, originalAmount); simulator.GenerateChain(owner, sideChain, newChainName); simulator.EndBlock(); var targetChain = nexus.FindChainByName(newChainName); // verify test user balance var balance = nexus.RootChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == originalAmount); // do a side chain send using test user balance from root to apps chain simulator.BeginBlock(); var txA = simulator.GenerateSideChainSend(sender, symbol, sourceChain, sender.Address, sideChain, sideAmount, 0); var blockA = simulator.EndBlock().FirstOrDefault(); var evtsA = blockA.GetEventsForTransaction(txA.Hash); // finish the chain transfer simulator.BeginBlock(); var txB = simulator.GenerateSideChainSettlement(sender, nexus.RootChain, sideChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // we cant transfer the full side amount due to fees // TODO calculate the proper fee values instead of this var txCostA = simulator.Nexus.RootChain.GetTransactionFee(txA); var txCostB = sideChain.GetTransactionFee(txB); sideAmount = sideAmount - txCostB; balance = sideChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == sideAmount); var extraFree = UnitConversion.ToBigInteger(0.01m, token.Decimals); sideAmount -= extraFree * 10; // do another side chain send using test user balance from apps to target chain simulator.BeginBlock(); var txC = simulator.GenerateSideChainSend(sender, symbol, sideChain, receiver.Address, targetChain, sideAmount, extraFree); var blockC = simulator.EndBlock().FirstOrDefault(); var evtsC = blockC.GetEventsForTransaction(txC.Hash); var appSupplies = new SupplySheet(symbol, sideChain, nexus); var childBalance = appSupplies.GetChildBalance(sideChain.Storage, targetChain.Name); var expectedChildBalance = sideAmount + extraFree; // finish the chain transfer simulator.BeginBlock(); var txD = simulator.GenerateSideChainSettlement(receiver, sideChain, targetChain, blockC.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // TODO verify balances }
public void NftTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var chain = nexus.RootChain; var nftKey = KeyPair.Generate(); var nftSymbol = "COOL"; var nftName = "CoolToken"; var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); // Send some SOUL to the test user (required for gas used in "transfer" transaction) simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, chain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals)); simulator.EndBlock(); // Create the token CoolToken as an NFT simulator.BeginBlock(); simulator.GenerateToken(owner, nftSymbol, nftName, 0, 0, TokenFlags.Transferable); simulator.EndBlock(); var token = simulator.Nexus.GetTokenInfo(nftSymbol); var tokenData = new byte[] { 0x1, 0x3, 0x3, 0x7 }; Assert.IsTrue(nexus.TokenExists(nftSymbol), "Can't find the token symbol"); // verify nft presence on the sender pre-mint var ownerships = new OwnershipSheet(nftSymbol); var ownedTokenList = ownerships.Get(chain.Storage, sender.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the sender already have a CoolToken?"); // Mint a new CoolToken directly on the sender simulator.BeginBlock(); simulator.MintNonFungibleToken(owner, sender.Address, nftSymbol, tokenData, new byte[0], 0); simulator.EndBlock(); // verify nft presence on the sender post-mint ownedTokenList = ownerships.Get(chain.Storage, sender.Address); Assert.IsTrue(ownedTokenList.Count() == 1, "How does the sender not have one now?"); //verify that the present nft is the same we actually tried to create var tokenId = ownedTokenList.ElementAt(0); var nft = nexus.GetNFT(nftSymbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenData) || nft.RAM.SequenceEqual(tokenData), "And why is this NFT different than expected? Not the same data"); // verify nft presence on the receiver pre-transfer ownedTokenList = ownerships.Get(chain.Storage, receiver.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the receiver already have a CoolToken?"); // transfer that nft from sender to receiver simulator.BeginBlock(); var txA = simulator.GenerateNftTransfer(sender, receiver.Address, chain, nftSymbol, tokenId); simulator.EndBlock(); // verify nft presence on the receiver post-transfer ownedTokenList = ownerships.Get(chain.Storage, receiver.Address); Assert.IsTrue(ownedTokenList.Count() == 1, "How does the receiver not have one now?"); //verify that the transfered nft is the same we actually tried to create tokenId = ownedTokenList.ElementAt(0); nft = nexus.GetNFT(nftSymbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenData) || nft.RAM.SequenceEqual(tokenData), "And why is this NFT different than expected? Not the same data"); }
public void SideChainTransferSameAccount() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var targetChain = nexus.FindChainByName("privacy"); var symbol = Nexus.FuelTokenSymbol; var sender = KeyPair.Generate(); var token = nexus.GetTokenInfo(symbol); var originalAmount = UnitConversion.ToBigInteger(10, token.Decimals); var sideAmount = originalAmount / 2; Assert.IsTrue(sideAmount > 0); // Send from Genesis address to "sender" user simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, symbol, originalAmount); simulator.EndBlock(); // verify test user balance var balance = nexus.RootChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == originalAmount); // do a side chain send using test user balance from root to account chain simulator.BeginBlock(); var txA = simulator.GenerateSideChainSend(sender, symbol, sourceChain, sender.Address, targetChain, sideAmount, 0); var blockA = simulator.EndBlock().FirstOrDefault(); Assert.IsTrue(blockA != null); // finish the chain transfer from parent to child simulator.BeginBlock(); var txB = simulator.GenerateSideChainSettlement(sender, sourceChain, targetChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // verify balances var feeB = targetChain.GetTransactionFee(txB); balance = targetChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == sideAmount - feeB); var feeA = sourceChain.GetTransactionFee(txA); var leftoverAmount = originalAmount - (sideAmount + feeA); balance = sourceChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == leftoverAmount); sideAmount /= 2; simulator.BeginBlock(); var txC = simulator.GenerateSideChainSend(sender, symbol, targetChain, sender.Address, sourceChain, sideAmount, 0); var blockC = simulator.EndBlock().FirstOrDefault(); Assert.IsTrue(blockC != null); // finish the chain transfer from child to parent simulator.BeginBlock(); var txD = simulator.GenerateSideChainSettlement(sender, targetChain, sourceChain, blockC.Hash); Assert.IsTrue(simulator.EndBlock().Any()); }
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); }
public void AccountRegister() { 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 testUser = KeyPair.Generate(); var token = nexus.GetTokenInfo(symbol); var amount = UnitConversion.ToBigInteger(10, token.Decimals); // Send from Genesis address to test user simulator.BeginBlock(); simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, symbol, amount); simulator.EndBlock(); // verify test user balance var balance = nexus.RootChain.GetTokenBalance(symbol, testUser.Address); Assert.IsTrue(balance == amount); var targetName = "hello"; Assert.IsTrue(targetName == targetName.ToLower()); Assert.IsFalse(registerName(testUser, targetName.Substring(3))); Assert.IsFalse(registerName(testUser, targetName.ToUpper())); Assert.IsFalse(registerName(testUser, targetName + "!")); Assert.IsTrue(registerName(testUser, targetName)); var currentName = nexus.LookUpAddressName(testUser.Address); Assert.IsTrue(currentName == targetName); var someAddress = nexus.LookUpName(targetName); Assert.IsTrue(someAddress == testUser.Address); Assert.IsFalse(registerName(testUser, "other")); }
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); } } }
public void SideChainTransferMultipleSteps() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234, -1); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var appsChain = nexus.FindChainByName("apps"); var token = nexus.FuelToken; var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); var originalAmount = UnitConversion.ToBigInteger(10, token.Decimals); var sideAmount = originalAmount / 2; Assert.IsTrue(sideAmount > 0); var newChainName = "testing"; // Send from Genesis address to "sender" user simulator.BeginBlock(); simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, token, originalAmount); simulator.GenerateChain(owner, appsChain, newChainName); simulator.EndBlock(); var targetChain = nexus.FindChainByName(newChainName); // verify test user balance var balance = nexus.RootChain.GetTokenBalance(token, sender.Address); Assert.IsTrue(balance == originalAmount); // do a side chain send using test user balance from root to apps chain simulator.BeginBlock(); var txA = simulator.GenerateSideChainSend(sender, token, sourceChain, sender.Address, appsChain, sideAmount, 0); var blockA = simulator.EndBlock().FirstOrDefault(); // finish the chain transfer simulator.BeginBlock(); var txB = simulator.GenerateSideChainSettlement(sender, nexus.RootChain, appsChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // we cant transfer the full side amount due to fees // TODO calculate the proper fee values instead of this sideAmount /= 2; var extraFree = UnitConversion.ToBigInteger(0.01m, token.Decimals); // do another side chain send using test user balance from apps to target chain simulator.BeginBlock(); var txC = simulator.GenerateSideChainSend(sender, token, appsChain, receiver.Address, targetChain, sideAmount, extraFree); var blockC = simulator.EndBlock().FirstOrDefault(); // finish the chain transfer simulator.BeginBlock(); var txD = simulator.GenerateSideChainSettlement(sender, appsChain, targetChain, blockC.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // TODO verify balances }