public void SimpleTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var testUserA = KeyPair.Generate(); var testUserB = KeyPair.Generate(); var fuelAmount = UnitConversion.ToBigInteger(10, Nexus.FuelTokenDecimals); var transferAmount = UnitConversion.ToBigInteger(10, Nexus.StakingTokenDecimals); simulator.BeginBlock(); simulator.GenerateTransfer(owner, testUserA.Address, nexus.RootChain, Nexus.FuelTokenSymbol, fuelAmount); simulator.GenerateTransfer(owner, testUserA.Address, nexus.RootChain, Nexus.StakingTokenSymbol, transferAmount); simulator.EndBlock(); // Send from user A to user B simulator.BeginBlock(); simulator.GenerateTransfer(testUserA, testUserB.Address, nexus.RootChain, Nexus.StakingTokenSymbol, transferAmount); simulator.EndBlock(); var finalBalance = simulator.Nexus.RootChain.GetTokenBalance(Nexus.StakingTokenSymbol, testUserB.Address); Assert.IsTrue(finalBalance == transferAmount); }
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); }
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); }
public void NftBurn() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var chain = nexus.RootChain; var symbol = "COOL"; var testUser = KeyPair.Generate(); // Create the token CoolToken as an NFT simulator.BeginBlock(); simulator.GenerateToken(owner, symbol, "CoolToken", 0, 0, Blockchain.Tokens.TokenFlags.None); simulator.EndBlock(); // Send some SOUL to the test user (required for gas used in "burn" transaction) simulator.BeginBlock(); simulator.GenerateTransfer(owner, testUser.Address, chain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals)); simulator.EndBlock(); var token = simulator.Nexus.GetTokenInfo(symbol); var tokenData = new byte[] { 0x1, 0x3, 0x3, 0x7 }; Assert.IsTrue(nexus.TokenExists(symbol), "Can't find the token symbol"); // verify nft presence on the user pre-mint var ownedTokenList = chain.GetTokenOwnerships(symbol).Get(chain.Storage, testUser.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the user already have a CoolToken?"); // Mint a new CoolToken directly on the user simulator.BeginBlock(); simulator.GenerateNft(owner, testUser.Address, chain, symbol, tokenData, new byte[0]); simulator.EndBlock(); // verify nft presence on the user post-mint ownedTokenList = chain.GetTokenOwnerships(symbol).Get(chain.Storage, testUser.Address); Assert.IsTrue(ownedTokenList.Count() == 1, "How does the user 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(symbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenData) || nft.RAM.SequenceEqual(tokenData), "And why is this NFT different than expected? Not the same data"); // burn the token simulator.BeginBlock(); simulator.GenerateNftBurn(testUser, chain, symbol, tokenId); simulator.EndBlock(); //verify the user no longer has the token ownedTokenList = chain.GetTokenOwnerships(symbol).Get(chain.Storage, testUser.Address); Assert.IsTrue(!ownedTokenList.Any(), "How does the user still have it post-burn?"); }
public void SideChainTransferDifferentAccounts() { 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 receiver = 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); var crossFee = UnitConversion.ToBigInteger(0.001m, token.Decimals); // do a side chain send using test user balance from root to account chain simulator.BeginBlock(); var txA = simulator.GenerateSideChainSend(sender, symbol, sourceChain, receiver.Address, targetChain, sideAmount, crossFee); simulator.EndBlock(); var blockA = nexus.RootChain.LastBlock; // finish the chain transfer simulator.BeginBlock(); var txB = simulator.GenerateSideChainSettlement(receiver, nexus.RootChain, targetChain, blockA.Hash); Assert.IsTrue(simulator.EndBlock().Any()); // verify balances var feeB = targetChain.GetTransactionFee(txB); balance = targetChain.GetTokenBalance(symbol, receiver.Address); Assert.IsTrue(balance == sideAmount - feeB); var feeA = sourceChain.GetTransactionFee(txA); var leftoverAmount = originalAmount - (sideAmount + feeA + crossFee); balance = sourceChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(balance == leftoverAmount); }
public void NftMint() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var chain = nexus.RootChain; var symbol = "COOL"; var testUser = KeyPair.Generate(); // Create the token CoolToken as an NFT simulator.BeginBlock(); simulator.GenerateToken(owner, symbol, "CoolToken", 0, 0, Blockchain.Tokens.TokenFlags.None); simulator.EndBlock(); var token = simulator.Nexus.GetTokenInfo(symbol); Assert.IsTrue(nexus.TokenExists(symbol), "Can't find the token symbol"); // verify nft presence on the user pre-mint var ownerships = new OwnershipSheet(symbol); var ownedTokenList = ownerships.Get(chain.Storage, 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, symbol, tokenROM, tokenRAM); simulator.EndBlock(); // verify nft presence on the user post-mint ownedTokenList = ownerships.Get(chain.Storage, testUser.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(symbol, tokenId); Assert.IsTrue(nft.ROM.SequenceEqual(tokenROM) && nft.RAM.SequenceEqual(tokenRAM), "And why is this NFT different than expected? Not the same data"); var currentSupply = nexus.GetTokenSupply(chain.Storage, symbol); Assert.IsTrue(currentSupply == 1, "why supply did not increase?"); }
public void TestNoGasSameChainTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var accountChain = nexus.FindChainByName("account"); var symbol = Nexus.FuelTokenSymbol; var token = nexus.GetTokenInfo(symbol); var sender = KeyPair.Generate(); var receiver = KeyPair.Generate(); var amount = UnitConversion.ToBigInteger(400, token.Decimals); var oldBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); // Send from Genesis address to test user simulator.BeginBlock(); var tx = simulator.GenerateTransfer(owner, sender.Address, nexus.RootChain, symbol, amount); simulator.EndBlock(); // verify test user balance var transferBalance = nexus.RootChain.GetTokenBalance(symbol, sender.Address); Assert.IsTrue(transferBalance == amount); var newBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); var gasFee = nexus.RootChain.GetTransactionFee(tx); Assert.IsTrue(transferBalance + newBalance + gasFee == oldBalance); //Try to send the entire balance without affording fees from sender to receiver try { simulator.BeginBlock(); tx = simulator.GenerateTransfer(sender, receiver.Address, nexus.RootChain, symbol, transferBalance); simulator.EndBlock(); } catch (Exception e) { Assert.IsNotNull(e); } // verify balances, receiver should have 0 balance transferBalance = nexus.RootChain.GetTokenBalance(symbol, receiver.Address); Assert.IsTrue(transferBalance == 0, "Transaction failed completely as expected"); }
public void FungibleTokenTransfer() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var accountChain = nexus.FindChainByName("account"); var symbol = Nexus.FuelTokenSymbol; var token = nexus.GetTokenInfo(symbol); var testUser = KeyPair.Generate(); var amount = UnitConversion.ToBigInteger(2, token.Decimals); var oldBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); Assert.IsTrue(oldBalance > amount); // Send from Genesis address to test user simulator.BeginBlock(); var tx = simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, symbol, amount); simulator.EndBlock(); // verify test user balance var transferBalance = nexus.RootChain.GetTokenBalance(symbol, testUser.Address); Assert.IsTrue(transferBalance == amount); var newBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); var gasFee = nexus.RootChain.GetTransactionFee(tx); Assert.IsTrue(transferBalance + newBalance + gasFee == oldBalance); }
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(); }
public void CreateNonDivisibleToken() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var accountChain = nexus.FindChainByName("account"); var symbol = "BLA"; var tokenSupply = UnitConversion.ToBigInteger(100000000, 18); simulator.BeginBlock(); simulator.GenerateToken(owner, symbol, "BlaToken", tokenSupply, 0, TokenFlags.Transferable | TokenFlags.Fungible | TokenFlags.Finite); simulator.MintTokens(owner, symbol, tokenSupply); simulator.EndBlock(); var token = nexus.GetTokenInfo(symbol); var testUser = KeyPair.Generate(); var amount = UnitConversion.ToBigInteger(2, token.Decimals); var oldBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); Assert.IsTrue(oldBalance > amount); // Send from Genesis address to test user simulator.BeginBlock(); var tx = simulator.GenerateTransfer(owner, testUser.Address, nexus.RootChain, symbol, amount); simulator.EndBlock(); // verify test user balance var transferBalance = nexus.RootChain.GetTokenBalance(symbol, testUser.Address); Assert.IsTrue(transferBalance == amount); var newBalance = nexus.RootChain.GetTokenBalance(symbol, owner.Address); Assert.IsTrue(transferBalance + newBalance == oldBalance); }
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); }
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.GenerateNft(owner, sender.Address, nftSymbol, tokenData, new byte[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 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 SideChainTransferMultipleSteps() { var owner = KeyPair.Generate(); var simulator = new ChainSimulator(owner, 1234); var nexus = simulator.Nexus; var sourceChain = nexus.RootChain; var appsChain = nexus.FindChainByName("apps"); 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, appsChain, 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, 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, symbol, 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 }
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?"); }
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 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); }
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.LookUpAddress(testUser.Address); Assert.IsTrue(currentName == targetName); var someAddress = nexus.LookUpName(targetName); Assert.IsTrue(someAddress == testUser.Address); Assert.IsFalse(registerName(testUser, "other")); }
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, simulator.Nexus.FuelToken, UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals)); simulator.EndBlock(); // Create the token CoolToken as an NFT simulator.BeginBlock(); simulator.GenerateToken(owner, nftSymbol, nftName, 0, 0, Blockchain.Tokens.TokenFlags.None); simulator.EndBlock(); var token = simulator.Nexus.FindTokenBySymbol(nftSymbol); var tokenData = new byte[] { 0x1, 0x3, 0x3, 0x7 }; Assert.IsTrue(token != null, "Can't find the token symbol"); // verify nft presence on the sender pre-mint var ownedTokenList = chain.GetTokenOwnerships(token).Get(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.GenerateNft(owner, sender.Address, chain, token, tokenData, new byte[0]); simulator.EndBlock(); // verify nft presence on the sender post-mint ownedTokenList = chain.GetTokenOwnerships(token).Get(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(token, 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 = chain.GetTokenOwnerships(token).Get(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, token, tokenId); simulator.EndBlock(); // verify nft presence on the receiver post-transfer ownedTokenList = chain.GetTokenOwnerships(token).Get(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(token, 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 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); }
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 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); }
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); } }
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 CLI(string[] args) { var culture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentCulture = culture; var seeds = new List <string>(); var settings = new Arguments(args); /* * for (int i = 0; i < 20; i++) * { * var k = KeyPair.Generate(); * Console.WriteLine(k.ToWIF() + " => " + k.Address.Text); * }*/ var useGUI = settings.GetBool("gui.enabled", true); if (useGUI) { gui = new ConsoleGUI(); logger = gui; } else { gui = null; logger = new ConsoleLogger(); } string mode = settings.GetString("node.mode", "validator"); bool hasRPC = settings.GetBool("rpc.enabled", false); bool hasREST = settings.GetBool("rest.enabled", false); string wif = settings.GetString("node.wif"); var nexusName = settings.GetString("nexus.name", "simnet"); switch (mode) { case "sender": string host = settings.GetString("sender.host"); int threadCount = settings.GetInt("sender.threads", 8); int addressesPerSender = settings.GetInt("sender.addressCount", 100); RunSender(wif, host, threadCount, addressesPerSender); Console.WriteLine("Sender finished operations."); return; case "validator": break; default: { logger.Error("Unknown mode: " + mode); return; } } int defaultPort = 0; for (int i = 0; i < validatorWIFs.Length; i++) { if (validatorWIFs[i] == wif) { defaultPort = (7073 + i); } } if (defaultPort == 0) { defaultPort = (7073 + validatorWIFs.Length); } int port = settings.GetInt("node.port", defaultPort); var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage"; var storagePath = settings.GetString("storage.path", defaultStoragePath); storagePath = storagePath.Replace("\\", "/"); if (!storagePath.EndsWith('/')) { storagePath += '/'; } var storageFix = settings.GetBool("storage.fix", false); // TODO remove this later if (storageFix) { if (Directory.Exists(storagePath)) { logger.Warning("Storage fix enabled... Cleaning up all storage..."); var di = new DirectoryInfo(storagePath); foreach (FileInfo file in di.EnumerateFiles()) { file.Delete(); } } } logger.Message("Storage path: " + storagePath); var node_keys = KeyPair.FromWIF(wif); nexus = new Nexus(logger, (name) => new BasicDiskStore(storagePath + name + ".txt")); bool bootstrap = false; if (wif == validatorWIFs[0]) { if (!nexus.Ready) { logger.Debug("Boostraping nexus..."); bootstrap = true; if (!nexus.CreateGenesisBlock(nexusName, node_keys, Timestamp.Now)) { throw new ChainException("Genesis block failure"); } logger.Debug("Genesis block created: " + nexus.GenesisHash); } } else { //nexus = new Nexus(nexusName, genesisAddress, logger); nexus = new Nexus(logger); seeds.Add("127.0.0.1:7073"); } // TODO this should be later optional to enable nexus.AddPlugin(new ChainAddressesPlugin()); nexus.AddPlugin(new TokenTransactionsPlugin()); nexus.AddPlugin(new AddressTransactionsPlugin()); nexus.AddPlugin(new UnclaimedTransactionsPlugin()); running = true; // mempool setup int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime); this.mempool = new Mempool(node_keys, nexus, blockTime, ReadFromOracle); mempool.Start(ThreadPriority.AboveNormal); mempool.OnTransactionFailed += Mempool_OnTransactionFailed; api = new NexusAPI(nexus, mempool); // RPC setup if (hasRPC) { int rpcPort = settings.GetInt("rpc.port", 7077); logger.Message($"RPC server listening on port {rpcPort}..."); var rpcServer = new RPCServer(api, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text)); rpcServer.Start(ThreadPriority.AboveNormal); } // REST setup if (hasREST) { int restPort = settings.GetInt("rest.port", 7078); logger.Message($"REST server listening on port {restPort}..."); var restServer = new RESTServer(api, "/api", restPort, (level, text) => WebLogMapper("rest", level, text)); restServer.Start(ThreadPriority.AboveNormal); } cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", ""); if (!string.IsNullOrEmpty(cryptoCompareAPIKey)) { logger.Message($"CryptoCompare API enabled..."); } // node setup this.node = new Node(nexus, mempool, node_keys, port, seeds, logger); node.Start(); if (gui != null) { int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds RegisterPlugin(new TPSPlugin(logger, pluginPeriod)); RegisterPlugin(new RAMPlugin(logger, pluginPeriod)); RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod)); } Console.CancelKeyPress += delegate { Terminate(); }; var dispatcher = new CommandDispatcher(); SetupCommands(dispatcher); bool useSimulator = settings.GetBool("simulator.enabled", false); if (useSimulator && bootstrap) { new Thread(() => { logger.Message("Initializing simulator..."); var simulator = new ChainSimulator(this.nexus, node_keys, 1234); logger.Message("Bootstrapping validators"); simulator.BeginBlock(); for (int i = 1; i < validatorWIFs.Length; i++) { simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, Nexus.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, Nexus.StakingTokenDecimals)); } simulator.EndBlock(); for (int i = 0; i < 3; i++) { logger.Message("Generating sim block #" + i); simulator.GenerateRandomBlock(); } NachoServer.InitNachoServer(nexus, simulator, node_keys, logger); MakeReady(dispatcher); }).Start(); } else { MakeReady(dispatcher); } this.Run(); }
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); }
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); }