public void SetUp() { _wallet = new Wallet(_params); _blockStore = new MemoryBlockStore(_params); var chain = new BlockChain(_params, _wallet, _blockStore); _peerGroup = new PeerGroup(_blockStore, _params, chain); }
public static void Run(string[] args) { var file = new FileInfo(args[0]); var wallet = Wallet.LoadFromFile(file); Console.WriteLine(wallet.ToString()); // Set up the components and link them together. var @params = NetworkParameters.TestNet(); using (var blockStore = new MemoryBlockStore(@params)) { var chain = new BlockChain(@params, wallet, blockStore); var peerGroup = new PeerGroup(blockStore, @params, chain); peerGroup.AddAddress(new PeerAddress(IPAddress.Loopback)); peerGroup.Start(); wallet.CoinsReceived += (sender, e) => { Console.WriteLine(); Console.WriteLine("Received tx " + e.Tx.HashAsString); Console.WriteLine(e.Tx.ToString()); }; // Now download and process the block chain. peerGroup.DownloadBlockChain(); peerGroup.Stop(); } wallet.SaveToFile(file); Console.WriteLine(); Console.WriteLine("Done!"); Console.WriteLine(); Console.WriteLine(wallet.ToString()); }
public void SetUp() { _unitTestParams = NetworkParameters.UnitTests(); _wallet = new Wallet(_unitTestParams); _wallet.AddKey(new EcKey()); _chainBlockStore = new MemoryBlockStore(_unitTestParams); _chain = new BlockChain(_unitTestParams, _wallet, _chainBlockStore); _coinbaseTo = _wallet.Keychain[0].ToAddress(_unitTestParams); _someOtherGuy = new EcKey().ToAddress(_unitTestParams); }
public static void Run(string[] args) { // TODO: Assumes production network not testnet. Make it selectable. var networkParams = NetworkParameters.ProdNet(); try { // Decode the private key from Satoshi's Base58 variant. If 51 characters long then it's from BitCoins // "dumpprivkey" command and includes a version byte and checksum. Otherwise assume it's a raw key. EcKey key; if (args[0].Length == 51) { var dumpedPrivateKey = new DumpedPrivateKey(networkParams, args[0]); key = dumpedPrivateKey.Key; } else { var privKey = Base58.DecodeToBigInteger(args[0]); key = new EcKey(privKey); } Console.WriteLine("Address from private key is: " + key.ToAddress(networkParams)); // And the address ... var destination = new Address(networkParams, args[1]); // Import the private key to a fresh wallet. var wallet = new Wallet(networkParams); wallet.AddKey(key); // Find the transactions that involve those coins. using (var blockStore = new MemoryBlockStore(networkParams)) { var chain = new BlockChain(networkParams, wallet, blockStore); var peerGroup = new PeerGroup(blockStore, networkParams, chain); peerGroup.AddAddress(new PeerAddress(IPAddress.Loopback)); peerGroup.Start(); peerGroup.DownloadBlockChain(); peerGroup.Stop(); // And take them! Console.WriteLine("Claiming " + Utils.BitcoinValueToFriendlystring(wallet.GetBalance()) + " coins"); wallet.SendCoins(peerGroup, destination, wallet.GetBalance()); // Wait a few seconds to let the packets flush out to the network (ugly). Thread.Sleep(5000); } } catch (IndexOutOfRangeException) { Console.WriteLine("First arg should be private key in Base58 format. Second argument should be address to send to."); } }
public static void Run(string[] args) { var file = new FileInfo(args[0]); var wallet = Wallet.LoadFromFile(file); Console.WriteLine(wallet.ToString()); // Set up the components and link them together. var @params = NetworkParameters.TestNet(); var blockStore = new MemoryBlockStore(@params); var conn = new NetworkConnection(IPAddress.Loopback, @params, blockStore.GetChainHead().Height, 60000); var chain = new BlockChain(@params, wallet, blockStore); var peer = new Peer(@params, conn, chain); peer.Start(); wallet.CoinsReceived += (sender, e) => { Console.WriteLine(); Console.WriteLine("Received tx " + e.Tx.HashAsString); Console.WriteLine(e.Tx.ToString()); }; // Now download and process the block chain. var progress = peer.StartBlockChainDownload(); var max = progress.Count; // Racy but no big deal. if (max > 0) { Console.WriteLine("Downloading block chain. " + (max > 1000 ? "This may take a while." : "")); var current = max; while (current > 0) { var pct = 100.0 - (100.0*(current/(double) max)); Console.WriteLine(string.Format("Chain download {0}% done", (int) pct)); progress.Await(TimeSpan.FromSeconds(1)); current = progress.Count; } } peer.Disconnect(); wallet.SaveToFile(file); Console.WriteLine(); Console.WriteLine("Done!"); Console.WriteLine(); Console.WriteLine(wallet.ToString()); }
static public void synchronize() { // Clear everything and force a resynchronization Logging.info("\n\n\tSynchronizing to network...\n"); blockProcessor.stopOperation(); blockProcessor = new BlockProcessor(); blockChain = new BlockChain(); walletState.clear(); TransactionPool.clear(); NetworkQueue.stop(); NetworkQueue.start(); // Finally, reconnect to the network CoreNetworkUtils.reconnect(); }
private void ReplaceLocalChainFromGlobalChain(Chain localChain, Chain globalChain) { if (globalChain == null || localChain == null) { throw new InvalidBlockException("Глобальная цепочка блоков не может быть равна null."); } var countNewBlocks = globalChain.Length - localChain.Length; // blockSubscriber.Clear(); var newBlocks = globalChain.BlockChain.AsEnumerable().Reverse().Take(countNewBlocks).ToList(); foreach (var block in newBlocks) { BlockChain.Add(block); } }
private async Task <Task> StartAsync <T>( Swarm swarm, BlockChain <T> blockChain, CancellationToken cancellationToken = default ) where T : IAction, new() { Task task = Task.Run( async() => await swarm.StartAsync( blockChain, 200, cancellationToken ) ); await swarm.WaitForRunningAsync(); return(task); }
static void Main(string[] args) { var blockchain = new BlockChain <StringData>(2); Console.WriteLine("Welcome to blockchain console!"); while (true) { Console.WriteLine("Write new block value: "); var value = Console.ReadLine(); blockchain.Add(new Block(DateTime.Now, new StringData(value))); Console.WriteLine("Block added!"); Console.WriteLine($"Blockchain is {(blockchain.IsValid() ? "valid" : "invalid")}"); Console.WriteLine(JsonConvert.SerializeObject(blockchain.Chain, Formatting.Indented)); } }
// TODO: This only supports BIP0032 accounts currently (NOT the imported account). // Results are indexed by their account number. // TODO: set locked balances public Balances[] CalculateBalances(int requiredConfirmations) { // Initial balances. Unspendable outputs are subtracted from the totals. // TODO: set locked balance var balances = _bip0032Accounts.Select(a => new Balances(a.TotalBalance, a.TotalBalance, 0)).ToArray(); if (requiredConfirmations == 0) { return(balances); } var controlledUnminedOutputs = RecentTransactions.UnminedTransactions .SelectMany(kvp => kvp.Value.Outputs) .OfType <WalletTransaction.Output.ControlledOutput>() .Where(a => a.Account.AccountNumber != ImportedAccountNumber); // Imported is not reported currently. foreach (var unminedOutput in controlledUnminedOutputs) { var accountNumber = unminedOutput.Account.AccountNumber; balances[checked ((int)accountNumber)].SpendableBalance -= unminedOutput.Amount; } if (requiredConfirmations == 1) { return(balances); } var confHeight = BlockChain.ConfirmationHeight(ChainTip.Height, requiredConfirmations); foreach (var block in RecentTransactions.MinedTransactions.ReverseList().TakeWhile(b => b.Height >= confHeight)) { var controlledMinedOutputs = block.Transactions .SelectMany(tx => tx.Outputs) .OfType <WalletTransaction.Output.ControlledOutput>() .Where(a => a.Account.AccountNumber != ImportedAccountNumber); // Imported is not reported currently. foreach (var output in controlledMinedOutputs) { var accountNumber = output.Account.AccountNumber; balances[checked ((int)accountNumber)].SpendableBalance -= output.Amount; } } return(balances); }
public async Task InitialBlockDownloadStates() { Swarm <DumbAction> minerSwarm = CreateSwarm(); Swarm <DumbAction> receiverSwarm = CreateSwarm(); BlockChain <DumbAction> minerChain = minerSwarm.BlockChain; BlockChain <DumbAction> receiverChain = receiverSwarm.BlockChain; var key = new PrivateKey(); var address1 = key.ToAddress(); var address2 = new PrivateKey().ToAddress(); var action = new DumbAction( address1, "foo", transfer: Tuple.Create <Address, Address, BigInteger>(address1, address2, 10)); minerChain.MakeTransaction(key, new[] { action }); await minerChain.MineBlock(minerSwarm.Address); minerChain.MakeTransaction(key, new[] { new DumbAction(address1, "bar") }); await minerChain.MineBlock(minerSwarm.Address); minerChain.MakeTransaction(key, new[] { new DumbAction(address1, "baz") }); await minerChain.MineBlock(minerSwarm.Address); try { await StartAsync(minerSwarm); await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer }, null); await receiverSwarm.PreloadAsync(); var state = receiverChain.GetState(address1); Assert.Equal((Text)"foo,bar,baz", state); Assert.Equal(minerChain.BlockHashes, receiverChain.BlockHashes); } finally { await StopAsync(minerSwarm); } }
public async Task GetTx() { Swarm <DumbAction> swarmA = _swarms[0]; Swarm <DumbAction> swarmB = _swarms[1]; BlockChain <DumbAction> chainB = _blockchains[1]; Transaction <DumbAction> tx = Transaction <DumbAction> .Create( 0, new PrivateKey(), new DumbAction[0] ); chainB.StageTransactions( new Dictionary <Transaction <DumbAction>, bool> { { tx, true } }); chainB.MineBlock(_fx1.Address1); try { await StartAsync(swarmA); await StartAsync(swarmB); Assert.Throws <PeerNotFoundException>( () => swarmB.GetTxsAsync( swarmA.AsPeer, new[] { tx.Id })); await swarmA.AddPeersAsync(new[] { swarmB.AsPeer }); List <Transaction <DumbAction> > txs = await swarmA.GetTxsAsync( swarmB.AsPeer, new[] { tx.Id } ).ToListAsync(); Assert.Equal(new[] { tx }, txs); } finally { await Task.WhenAll( swarmA.StopAsync(), swarmB.StopAsync()); } }
public void DoesTransactionFollowsPolicyWithAuthorizedMiners() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy<PolymorphicAction<ActionBase>> policy = blockPolicySource.GetPolicy(10000, 100); Block<PolymorphicAction<ActionBase>> genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), new AuthorizedMinersState( new[] { authorizedMinerPrivateKey.ToAddress() }, 5, 10 ), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null), new DefaultKeyValueStore(null)); var blockChain = new BlockChain<PolymorphicAction<ActionBase>>( policy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Transaction<PolymorphicAction<ActionBase>> txFromAuthorizedMiner = Transaction<PolymorphicAction<ActionBase>>.Create( 0, authorizedMinerPrivateKey, genesis.Hash, new PolymorphicAction<ActionBase>[] { ak.CreateActivateAccount(new byte[] { 0x00, 0x01 }) } ); // Deny tx even if contains valid activation key. Assert.False(policy.DoesTransactionFollowsPolicy(txFromAuthorizedMiner, blockChain)); }
public string Run(int inputId, int targetId, List <GridConfiguration> configurations, MonoBehaviour owner) { Debug.Log("Grid.Run"); var inputTensor = controller.floatTensorFactory.Get(inputId); var targetTensor = controller.floatTensorFactory.Get(targetId); // write the input and target tensors to Ipfs var inputJob = new Ipfs(); var targetJob = new Ipfs(); var inputIpfsResponse = inputJob.Write(inputTensor.GetConfig()); var targetIpfsResponse = targetJob.Write(targetTensor.GetConfig()); Debug.Log("Input Hash: " + inputIpfsResponse.Hash); Debug.Log("Target Hash: " + targetIpfsResponse.Hash); var jobs = new string[configurations.Count]; for (var i = 0; i < configurations.Count; ++i) { var config = configurations[i]; var model = controller.GetModel(config.model) as Sequential; var serializedModel = model.GetConfig(); var configJob = new Ipfs(); var ipfsJobConfig = new IpfsJobConfig(config.lr, config.criterion, config.iters); var response = configJob.Write(new IpfsJob(inputIpfsResponse.Hash, targetIpfsResponse.Hash, serializedModel, ipfsJobConfig)); jobs[i] = response.Hash; } var experiment = new IpfsExperiment(jobs); var experimentWriteJob = new Ipfs(); var experimentResult = experimentWriteJob.Write(experiment); BlockChain chain = Camera.main.GetComponent <BlockChain>(); owner.StartCoroutine(chain.AddExperiment(experimentResult.Hash, jobs)); experiments.Add(experimentResult.Hash); return(experimentResult.Hash); }
private async Task <Transaction> GenerateTransactionAsync(string methodName, List <byte[]> parameters) { try { _logger?.Trace("Entered generating tx."); var bn = await BlockChain.GetCurrentBlockHeightAsync(); bn = bn > 4 ? bn - 4 : 0; var bh = bn == 0 ? Hash.Genesis : (await BlockChain.GetHeaderByHeightAsync(bn)).GetHash(); var bhPref = bh.Value.Where((x, i) => i < 4).ToArray(); var tx = new Transaction { From = _nodeKeyPair.Address, To = ContractAddress, RefBlockNumber = bn, RefBlockPrefix = ByteString.CopyFrom(bhPref), MethodName = methodName, Sig = new Signature { P = ByteString.CopyFrom(_nodeKeyPair.NonCompressedEncodedPublicKey) }, Type = TransactionType.DposTransaction, Params = ByteString.CopyFrom(ParamsPacker.Pack(parameters.Select(p => (object)p).ToArray())) }; var signer = new ECSigner(); var signature = signer.Sign(_nodeKeyPair, tx.GetHash().DumpByteArray()); // Update the signature tx.Sig.R = ByteString.CopyFrom(signature.R); tx.Sig.S = ByteString.CopyFrom(signature.S); _logger?.Trace("Leaving generating tx."); MessageHub.Instance.Publish(StateEvent.ConsensusTxGenerated); return(tx); } catch (Exception e) { _logger?.Trace(e, "Error while during generating DPoS tx."); } return(null); }
public ActionResult Index() { var Result = new List <string>(); const string minerAddress = "miner1"; const string user1Address = "A"; const string user2Address = "B"; BlockChain blockChain = new BlockChain() { ProofOfWorkDifficulty = 2, MiningReward = 10 }; blockChain.CreateTransaction(new Transaction() { From = user1Address, To = user2Address, Amount = 200 }); blockChain.CreateTransaction(new Transaction() { From = user2Address, To = user1Address, Amount = 10 }); Result.Add(string.Format("Est valide: {0}", blockChain.IsValidChain())); Result.Add("--------- Démarrer l'extraction ---------"); blockChain.MineBlock(minerAddress); Result.Add(string.Format("ÉQUILIBRE du mineur: {0}", blockChain.GetBalance(minerAddress))); blockChain.CreateTransaction(new Transaction() { From = user1Address, To = user2Address, Amount = 5 }); Result.Add("--------- Démarrer l'extraction ---------"); blockChain.MineBlock(minerAddress); Result.Add(string.Format("ÉQUILIBRE du mineur: {0}", blockChain.GetBalance(minerAddress))); Result.AddRange(PrintChain(blockChain, Result)); Result.Add("Piratage de la blockchain ..."); blockChain.Bloks[1].Transactions = new List <Transaction> { new Transaction() { From = user1Address, To = minerAddress, Amount = 150 } }; Result.Add(string.Format("Est valide: {0}", blockChain.IsValidChain())); Result.Add("----------------- End Blockchain -----------------"); ViewBag.Result = Result; return(View()); }
public void PrintChain(BlockChain blockChain) { Console.WriteLine("----------------- Start Blockchain -----------------"); foreach (Block block in blockChain.Chain) { Console.WriteLine(); Console.WriteLine("------ Start Block ------"); Console.WriteLine("Hash: {0}", block.Hash); Console.WriteLine("Previous Hash: {0}", block.PreviousHash); Console.WriteLine("--- Start Transactions ---"); foreach (Transaction transaction in block.Transactions) { Console.WriteLine("From: {0} To {1} Amount {2}", transaction.From, transaction.To, transaction.Amount); } Console.WriteLine("--- End Transactions ---"); Console.WriteLine("------ End Block ------"); } Console.WriteLine("----------------- End Blockchain -----------------"); }
public async Task Proof() { using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); var blockPolicySource = new BlockPolicySource(Logger.None); var genesis = BlockChain <NCAction> .MakeGenesisBlock(HashAlgorithmType.Of <SHA256>()); var blockChain = new BlockChain <NCAction>( blockPolicySource.GetPolicy(10_000, null, null, null, null, null, null), new VolatileStagePolicy <NCAction>(), store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); var minerKey = new PrivateKey(); var miner = new Miner(blockChain, null, minerKey, false); Block <NCAction> mined = await miner.MineBlockAsync(default);
public async Task NodeStatusStagedTxIds() { var apvPrivateKey = new PrivateKey(); var apv = AppProtocolVersion.Sign(apvPrivateKey, 0); var genesis = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock(); var service = ServiceBuilder.CreateNineChroniclesNodeService(genesis); StandaloneServices.ConfigureStandaloneContext(service, StandaloneContextFx); var result = await ExecuteQueryAsync("query { nodeStatus { stagedTxIds } }"); var expectedResult = new Dictionary <string, object>() { ["nodeStatus"] = new Dictionary <string, object>() { ["stagedTxIds"] = new List <object>() }, }; Assert.Null(result.Errors); Assert.Equal(expectedResult, result.Data); var tx = StandaloneContextFx.BlockChain.MakeTransaction( new PrivateKey(), new PolymorphicAction <ActionBase>[] { } ); result = await ExecuteQueryAsync("query { nodeStatus { stagedTxIds } }"); expectedResult = new Dictionary <string, object>() { ["nodeStatus"] = new Dictionary <string, object>() { ["stagedTxIds"] = new List <object> { tx.Id.ToString(), } }, }; Assert.Null(result.Errors); Assert.Equal(expectedResult, result.Data); }
public IntegerSet( IReadOnlyList <BigInteger?> initialStates, IBlockPolicy <Arithmetic> policy = null, IEnumerable <IRenderer <Arithmetic> > renderers = null ) { PrivateKeys = initialStates.Select(_ => new PrivateKey()).ToImmutableArray(); Addresses = PrivateKeys.Select(AddressExtensions.ToAddress).ToImmutableArray(); Txs = initialStates .Select((state, index) => new { State = state, Key = PrivateKeys[index] }) .Where(pair => !(pair.State is null)) .Select(pair => new { State = (BigInteger)pair.State, pair.Key }) .Select(pair => new { Action = Arithmetic.Add(pair.State), pair.Key }) .Select(pair => Transaction <Arithmetic> .Create( 0, pair.Key, null, new[] { pair.Action }, ImmutableHashSet <Address> .Empty.Add(pair.Key.ToAddress()) ) ) .ToImmutableArray(); Miner = new PrivateKey(); policy = policy ?? new NullBlockPolicy <Arithmetic>(); Store = new MemoryStore(); KVStore = new MemoryKeyValueStore(); StateStore = new TrieStateStore(KVStore); Genesis = new BlockContent <Arithmetic> { PublicKey = Miner.PublicKey, Timestamp = DateTimeOffset.UtcNow, Transactions = Txs, }.Mine(policy.GetHashAlgorithm(0)).Evaluate(Miner, policy.BlockAction, StateStore); Chain = new BlockChain <Arithmetic>( policy, new VolatileStagePolicy <Arithmetic>(), Store, StateStore, Genesis, renderers ); }
private NineChroniclesNodeService MakeMineChroniclesNodeService(PrivateKey privateKey) { var goldCurrency = new Currency("NCG", 2, minter: null); var blockPolicy = NineChroniclesNodeService.GetTestBlockPolicy(); Block <PolymorphicAction <ActionBase> > genesis = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock( HashAlgorithmType.Of <SHA256>(), new PolymorphicAction <ActionBase>[] { new InitializeStates( rankingState: new RankingState(), shopState: new ShopState(), gameConfigState: new GameConfigState(_sheets[nameof(GameConfigSheet)]), redeemCodeState: new RedeemCodeState(Bencodex.Types.Dictionary.Empty .Add("address", RedeemCodeState.Address.Serialize()) .Add("map", Bencodex.Types.Dictionary.Empty) ), adminAddressState: new AdminState(default, 0),
public void MoveToICTxPool(HashSet activeContracts) { foreach (var item in this.ToList()) { byte[] contractHash; if (BlockChain.IsContractGeneratedTx(item.Value, out contractHash) == BlockChain.IsContractGeneratedTxResult.ContractGenerated && !activeContracts.Contains(contractHash)) { BlockChainTrace.Information("inactive contract-generated tx moved to ICTxPool", contractHash); Remove(item.Key); ICTxPool.Add(item.Key, item.Value); GetDependencies(item.Key) .Where(t => t.Item1 is KnownTxPool) .ToList().ForEach(t => ((KnownTxPool)t.Item1).MoveToOrphansWithDependencies(t.Item2)); } } }
public void Should_be_invalid_if_blocks_chain_is_corrupted() { var blockChain = new BlockChain <TestData>(2); var data1 = new TestData("AAA000", 2020); var data2 = new TestData("AAA001", 2020); var block1 = new Block(DateTime.UtcNow, data1); var block2 = new Block(DateTime.UtcNow, data2); blockChain.Add(block1); blockChain.Add(block2); var newChain = new List <Block> { block2, block1 }; blockChain.ForceSet(newChain); blockChain.IsValid().Should().Be.False(); }
public void ForkBlockIndex(int branchPointIndex) { var store = Fx.Store; var blocks = new BlockChain <DumbAction>( new NullPolicy <DumbAction>(), new VolatileStagePolicy <DumbAction>(), store, Fx.StateStore, Fx.GenesisBlock ); blocks.Append(Fx.Block1); blocks.Append(Fx.Block2); blocks.Append(Fx.Block3); var forked = new BlockChain <DumbAction>( new NullPolicy <DumbAction>(), new VolatileStagePolicy <DumbAction>(), store, Fx.StateStore, Guid.NewGuid(), Fx.GenesisBlock, renderers: null ); Logger.CompareBothChains( LogEventLevel.Debug, nameof(blocks), blocks, nameof(forked), forked ); store.ForkBlockIndexes(blocks.Id, forked.Id, blocks[branchPointIndex].Hash); Assert.Equal( store.IterateIndexes(blocks.Id, 0, branchPointIndex + 1).ToList(), store.IterateIndexes(forked.Id).ToList() ); Assert.Equal(branchPointIndex + 1, store.CountIndex(forked.Id)); }
public async Task CanGetTx() { Swarm swarmA = _swarms[0]; Swarm swarmB = _swarms[1]; BlockChain <BaseAction> chainA = _blockchains[0]; BlockChain <BaseAction> chainB = _blockchains[1]; Transaction <BaseAction> tx = Transaction <BaseAction> .Make( new PrivateKey(), new PrivateKey().PublicKey.ToAddress(), new BaseAction[] { }, DateTimeOffset.UtcNow ); chainB.StageTransactions(new[] { tx }.ToHashSet()); chainB.MineBlock(_fx1.Address1); try { await StartAsync(swarmA, chainA); await StartAsync(swarmB, chainB); Assert.Throws <PeerNotFoundException>( () => swarmB.GetTxsAsync <BaseAction>( swarmA.AsPeer, new[] { tx.Id })); await swarmA.AddPeersAsync(new[] { swarmB.AsPeer }); List <Transaction <BaseAction> > txs = await swarmA.GetTxsAsync <BaseAction>( swarmB.AsPeer, new[] { tx.Id } ).ToListAsync(); Assert.Equal(new[] { tx }, txs); } finally { await Task.WhenAll( swarmA.StopAsync(), swarmB.StopAsync()); } }
private Swarm <T> CreateSwarm <T>( BlockChain <T> blockChain, PrivateKey privateKey = null, AppProtocolVersion?appProtocolVersion = null, int tableSize = Kademlia.TableSize, int bucketSize = Kademlia.BucketSize, string host = null, int?listenPort = null, DateTimeOffset?createdAt = null, IEnumerable <IceServer> iceServers = null, DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null, IEnumerable <PublicKey> trustedAppProtocolVersionSigners = null, SwarmOptions options = null ) where T : IAction, new() { if (host is null && !(iceServers?.Any() ?? false)) { host = IPAddress.Loopback.ToString(); } var swarm = new Swarm <T>( blockChain, privateKey ?? new PrivateKey(), appProtocolVersion ?? DefaultAppProtocolVersion, tableSize, bucketSize, 5, host, listenPort, createdAt, iceServers, differentAppProtocolVersionEncountered, trustedAppProtocolVersionSigners, options); _finalizers.Add(async() => { await StopAsync(swarm); swarm.Dispose(); }); return(swarm); }
public void Should_natural_transactions_be_valid(int transactionCount) { const int blockSize = 5; var consense = new NetworkConsense(1, blockSize, 0); var bc = new BlockChain(Guid.NewGuid(), consense); var transactions = Enumerable.Repeat(new Transaction(Guid.NewGuid(), Guid.NewGuid(), 1), transactionCount) .ToArray(); bc.CreateTransaction(transactions); while (bc.PenddingTransactions.Count > 1) { bc.MiningPedingTransactions(); } bc.IsChainValid().Should().BeTrue(); }
private IEnumerable <Block <T> > GetTopmostBlocks <T>(BlockChain <T> blockChain) where T : IAction, new() { Block <T> block = blockChain.Tip; while (true) { yield return(block); if (block.PreviousHash is HashDigest <SHA256> prev) { block = blockChain[prev]; } else { break; } } }
private async Task <Task> StartAsync <T>( Swarm swarm, BlockChain <T> blockChain, int millisecondsDistributeInterval = 1500, CancellationToken cancellationToken = default ) where T : IAction { Task task = Task.Run( async() => await swarm.StartAsync( blockChain, millisecondsDistributeInterval, cancellationToken ) ); await swarm.WaitForRunningAsync(); return(task); }
public void AddMultipleEntriesOK() { BlockChain bc = new BlockChain(); int count = 10; for (int i = 0; i < count; ++i) { BlockChain.Entry e = new BlockChain.Entry(Guid.NewGuid().ToString()); bc.AddEntry(e); } Assert.NotEqual("0", bc.Head); Assert.Equal(count, bc.Entries.Count); Tuple <bool, BlockChain.Entry> valid = bc.IsValid(); Assert.True(valid.Item1); Assert.Null(valid.Item2); }
public async Task StopAsync() { Swarm <DumbAction> swarm = _swarms[0]; BlockChain <DumbAction> chain = _blockchains[0]; await swarm.StopAsync(); var task = await StartAsync(swarm); Assert.True(swarm.Running); await swarm.StopAsync(); Assert.False(swarm.Running); Assert.False( task.IsFaulted, $"A task was faulted due to an exception: {task.Exception}" ); }
public void MustNotIncludeBlockActionAtTransaction() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy(10000, 100); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), new AuthorizedMinersState( new[] { authorizedMinerPrivateKey.ToAddress() }, 5, 10 ), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null), new DefaultKeyValueStore(null)); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Assert.Throws <MissingActionTypeException>(() => { blockChain.MakeTransaction( adminPrivateKey, new PolymorphicAction <ActionBase>[] { new RewardGold() } ); }); }
public async Task InitialBlockDownloadStates() { Swarm <DumbAction> minerSwarm = _swarms[0]; Swarm <DumbAction> receiverSwarm = _swarms[1]; BlockChain <DumbAction> minerChain = _blockchains[0]; BlockChain <DumbAction> receiverChain = _blockchains[1]; var key = new PrivateKey(); var address = key.ToAddress(); minerChain.MakeTransaction(key, new[] { new DumbAction(address, "foo") }); await minerChain.MineBlock(_fx1.Address1); minerChain.MakeTransaction(key, new[] { new DumbAction(address, "bar") }); await minerChain.MineBlock(_fx1.Address1); minerChain.MakeTransaction(key, new[] { new DumbAction(address, "baz") }); await minerChain.MineBlock(_fx1.Address1); try { await StartAsync(minerSwarm); await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer }, null); var trustedStateValidators = new[] { minerSwarm.Address }.ToImmutableHashSet(); await receiverSwarm.PreloadAsync(trustedStateValidators : trustedStateValidators); await receiverSwarm.PreloadAsync(); var state = receiverChain.GetState(address); Assert.Equal((Text)"foo,bar,baz", state); Assert.Equal(minerChain.BlockHashes, receiverChain.BlockHashes); } finally { await StopAsync(minerSwarm); } }
public async Task BroadcastIgnoreFromDifferentGenesisHash() { var receiverKey = new PrivateKey(); Swarm <DumbAction> receiverSwarm = CreateSwarm(receiverKey); BlockChain <DumbAction> receiverChain = receiverSwarm.BlockChain; var seedStateStore = new TrieStateStore(new MemoryKeyValueStore()); IBlockPolicy <DumbAction> policy = receiverChain.Policy; Block <DumbAction> mismatchedGenesis = new BlockContent <DumbAction> { PublicKey = receiverKey.PublicKey, Timestamp = DateTimeOffset.MinValue, } .Mine(policy.GetHashAlgorithm(0)) .Evaluate(receiverKey, policy.BlockAction, seedStateStore); BlockChain <DumbAction> seedChain = MakeBlockChain( policy, new MemoryStore(), seedStateStore, genesisBlock: mismatchedGenesis); var seedMiner = new PrivateKey(); Swarm <DumbAction> seedSwarm = CreateSwarm(seedChain, seedMiner); try { await StartAsync(receiverSwarm); await StartAsync(seedSwarm); await receiverSwarm.AddPeersAsync(new[] { seedSwarm.AsPeer }, null); Block <DumbAction> block = await seedChain.MineBlock(seedMiner); seedSwarm.BroadcastBlock(block); Assert.NotEqual(seedChain.Tip, receiverChain.Tip); } finally { await StopAsync(seedSwarm); await StopAsync(receiverSwarm); seedSwarm.Dispose(); } }
private Block<PolymorphicAction<ActionBase>> MakeGenesisBlock( Address adminAddress, IImmutableSet<Address> activatedAddresses, AuthorizedMinersState authorizedMinersState = null, DateTimeOffset? timestamp = null, PendingActivationState[] pendingActivations = null ) { if (pendingActivations is null) { var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; var privateKey = new PrivateKey(); (ActivationKey activationKey, PendingActivationState pendingActivation) = ActivationKey.Create(privateKey, nonce); pendingActivations = new[] { pendingActivation }; } return BlockChain<PolymorphicAction<ActionBase>>.MakeGenesisBlock( new PolymorphicAction<ActionBase>[] { new InitializeStates( rankingState: new RankingState(), shopState: new ShopState(), tableSheets: TableSheetsImporter.ImportSheets(), gameConfigState: new GameConfigState(), redeemCodeState: new RedeemCodeState(Dictionary.Empty .Add("address", RedeemCodeState.Address.Serialize()) .Add("map", Dictionary.Empty) ), adminAddressState: new AdminState(adminAddress, 1500000), activatedAccountsState: new ActivatedAccountsState(activatedAddresses), goldCurrencyState: new GoldCurrencyState( new Currency("NCG", 2, minter: null) ), goldDistributions: new GoldDistribution[0], pendingActivationStates: pendingActivations, authorizedMinersState: authorizedMinersState ), }, timestamp: timestamp ?? DateTimeOffset.MinValue ); }
public static void Run(string[] args) { Console.WriteLine("Connecting to node"); var networkParams = NetworkParameters.ProdNet(); using (var blockStore = new MemoryBlockStore(networkParams)) { var chain = new BlockChain(networkParams, blockStore); var peer = new Peer(networkParams, new PeerAddress(IPAddress.Loopback), chain); peer.Connect(); new Thread(() => peer.Run(CancellationToken.None)).Start(); var blockHash = new Sha256Hash(args[0]); var future = peer.BeginGetBlock(blockHash, null, null); Console.WriteLine("Waiting for node to send us the requested block: " + blockHash); var block = peer.EndGetBlock(future); Console.WriteLine(block); peer.Disconnect(); } }
//BlockChainのテスト(分岐がない場合・採掘・順番通りに追加されなかった場合) public static void Test19() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[8]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; Console.WriteLine("block" + i.ToString() + " mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks2[2]); if (type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_1"); if (blockchain.blocksCurrent.value != 0) throw new Exception("test19_2"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 3) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test19_3"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test19_4"); if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[2].Id)) throw new Exception("test19_5"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test19_6"); } if (blockchain.rejectedBlocks[i] != null) throw new Exception("test19_7"); } BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks2[1]); if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_8"); if (blockchain.blocksCurrent.value != 0) throw new Exception("test19_9"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test19_10"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test19_11"); if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[1].Id)) throw new Exception("test19_12"); } else if (i == 3) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test19_13"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test19_14"); if (!blockchain.pendingBlocks[i].Keys.Contains(blks2[2].Id)) throw new Exception("test19_15"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test19_16"); } if (blockchain.rejectedBlocks[i] != null) throw new Exception("test19_17"); } BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blks2[0]); if (type3 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test19_18"); if (blockchain.headBlockIndex != 2) throw new Exception("test19_19"); if (blockchain.blocksCurrent.value != 3) throw new Exception("test19_20"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2 || i == 3) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test19_21"); if (blockchain.pendingBlocks[i].Count != 0) throw new Exception("test19_22"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test19_23"); } if (blockchain.rejectedBlocks[i] != null) throw new Exception("test19_24"); } BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blks2[6]); BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blks2[7]); BlockChain.UpdateChainReturnType type6 = blockchain.UpdateChain(blks2[4]); BlockChain.UpdateChainReturnType type7 = blockchain.UpdateChain(blks2[5]); BlockChain.UpdateChainReturnType type8 = blockchain.UpdateChain(blks2[3]); if (type4 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_25"); if (type5 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_26"); if (type6 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_27"); if (type7 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test19_28"); if (type8 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test19_29"); if (blockchain.headBlockIndex != 7) throw new Exception("test19_30"); utxodb.Open(); foreach (var address in blkCons[7].unspentTxOuts.Keys) foreach (var toc in blkCons[7].unspentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null) throw new Exception("test19_31"); foreach (var address in blkCons[7].spentTxOuts.Keys) foreach (var toc in blkCons[7].spentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null) throw new Exception("test19_32"); utxodb.Close(); Console.WriteLine("test19_succeeded"); }
public static void Run(string[] args) { var testNet = args.Length > 0 && string.Equals(args[0], "testnet", StringComparison.InvariantCultureIgnoreCase); var @params = testNet ? NetworkParameters.TestNet() : NetworkParameters.ProdNet(); var filePrefix = testNet ? "pingservice-testnet" : "pingservice-prodnet"; // Try to read the wallet from storage, create a new one if not possible. Wallet wallet; var walletFile = new FileInfo(filePrefix + ".wallet"); try { wallet = Wallet.LoadFromFile(walletFile); } catch (IOException) { wallet = new Wallet(@params); wallet.Keychain.Add(new EcKey()); wallet.SaveToFile(walletFile); } // Fetch the first key in the wallet (should be the only key). var key = wallet.Keychain[0]; Console.WriteLine(wallet); // Load the block chain, if there is one stored locally. Console.WriteLine("Reading block store from disk"); using (var blockStore = new BoundedOverheadBlockStore(@params, new FileInfo(filePrefix + ".blockchain"))) { // Connect to the localhost node. One minute timeout since we won't try any other peers Console.WriteLine("Connecting ..."); var chain = new BlockChain(@params, wallet, blockStore); var peerGroup = new PeerGroup(blockStore, @params, chain); peerGroup.AddAddress(new PeerAddress(IPAddress.Loopback)); peerGroup.Start(); // We want to know when the balance changes. wallet.CoinsReceived += (sender, e) => { // Running on a peer thread. Debug.Assert(!e.NewBalance.Equals(0)); // It's impossible to pick one specific identity that you receive coins from in BitCoin as there // could be inputs from many addresses. So instead we just pick the first and assume they were all // owned by the same person. var input = e.Tx.Inputs[0]; var from = input.FromAddress; var value = e.Tx.GetValueSentToMe(wallet); Console.WriteLine("Received " + Utils.BitcoinValueToFriendlyString(value) + " from " + from); // Now send the coins back! var sendTx = wallet.SendCoins(peerGroup, from, value); Debug.Assert(sendTx != null); // We should never try to send more coins than we have! Console.WriteLine("Sent coins back! Transaction hash is " + sendTx.HashAsString); wallet.SaveToFile(walletFile); }; peerGroup.DownloadBlockChain(); Console.WriteLine("Send coins to: " + key.ToAddress(@params)); Console.WriteLine("Waiting for coins to arrive. Press Ctrl-C to quit."); // The PeerGroup thread keeps us alive until something kills the process. } }
public void StartSystem() { if (isSystemStarted) throw new InvalidOperationException("core_started"); ahdb = new AccountHoldersDatabase(databaseBasepath); thdb = new TransactionHistoriesDatabase(databaseBasepath); bcadb = new BlockchainAccessDB(databaseBasepath); bmdb = new BlockManagerDB(databaseBasepath); bdb = new BlockDB(databaseBasepath); bfpdb = new BlockFilePointersDB(databaseBasepath); ufadb = new UtxoFileAccessDB(databaseBasepath); ufpdb = new UtxoFilePointersDB(databaseBasepath); ufptempdb = new UtxoFilePointersTempDB(databaseBasepath); utxodb = new UtxoDB(databaseBasepath); accountHolders = new AccountHolders(); accountHoldersFactory = new AccountHoldersFactory(); byte[] ahDataBytes = ahdb.GetData(); if (ahDataBytes.Length != 0) accountHolders.FromBinary(ahDataBytes); else accountHolders.LoadVersion0(); transactionHistories = thdb.GetData().Pipe((data) => data.Length == 0 ? new TransactionHistories() : SHAREDDATA.FromBinary<TransactionHistories>(data)); transactionHistories.UnconfirmedTransactionAdded += (sender, e) => { foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) foreach (var prevTxOut in e.senders) if (account.Address.Equals(prevTxOut.Address)) account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount + prevTxOut.Amount.rawAmount); }; transactionHistories.UnconfirmedTransactionRemoved += (sender, e) => { foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) foreach (var prevTxOut in e.receivers) if (account.Address.Equals(prevTxOut.Address)) account.accountStatus.unconfirmedAmount = new CurrencyUnit(account.accountStatus.unconfirmedAmount.rawAmount - prevTxOut.Amount.rawAmount); }; usableBalanceCache = new CachedData<CurrencyUnit>(() => { long rawAmount = 0; foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) rawAmount += account.accountStatus.usableAmount.rawAmount; return new CurrencyUnit(rawAmount); }); unusableBalanceCache = new CachedData<CurrencyUnit>(() => { long rawAmount = 0; foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) rawAmount += account.accountStatus.unusableAmount.rawAmount; return new CurrencyUnit(rawAmount); }); unconfirmedBalanceCache = new CachedData<CurrencyUnit>(() => { long rawAmount = 0; foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) rawAmount += account.accountStatus.unconfirmedAmount.rawAmount; return new CurrencyUnit(rawAmount); }); usableBalanceWithUnconfirmedCache = new CachedData<CurrencyUnit>(() => new CurrencyUnit(usableBalanceCache.Data.rawAmount - unconfirmedBalanceCache.Data.rawAmount)); unusableBalanceWithUnconformedCache = new CachedData<CurrencyUnit>(() => new CurrencyUnit(unusableBalanceCache.Data.rawAmount + unconfirmedBalanceCache.Data.rawAmount)); blockChain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); blockChain.LoadTransactionHistories(transactionHistories); //<未改良>暫定? if (blockChain.headBlockIndex == -1) { blockChain.UpdateChain(new GenesisBlock()); this.RaiseNotification("genesis_block_generated", 5); } Dictionary<Account, EventHandler<Tuple<CurrencyUnit, CurrencyUnit>>> changeAmountDict = new Dictionary<Account, EventHandler<Tuple<CurrencyUnit, CurrencyUnit>>>(); Action<bool> _UpdateBalance = (isOnlyUnconfirmed) => { if (!isOnlyUnconfirmed) { usableBalanceCache.IsModified = true; unusableBalanceCache.IsModified = true; } unconfirmedBalanceCache.IsModified = true; usableBalanceWithUnconfirmedCache.IsModified = true; unusableBalanceWithUnconformedCache.IsModified = true; BalanceUpdated(this, EventArgs.Empty); }; Action<Account, bool> _AddAddressEvent = (account, isUpdatebalance) => { EventHandler<Tuple<CurrencyUnit, CurrencyUnit>> eh = (sender, e) => { account.accountStatus.usableAmount = e.Item1; account.accountStatus.unusableAmount = e.Item2; }; changeAmountDict.Add(account, eh); AddressEvent addressEvent = new AddressEvent(account.Address.Hash); addressEvent.BalanceUpdated += eh; blockChain.AddAddressEvent(addressEvent); long rawAmount = 0; foreach (var unconfirmedTh in transactionHistories.unconfirmedTransactionHistories.ToArray()) foreach (var prevTxOut in unconfirmedTh.senders) if (prevTxOut.Address.Equals(account.Address)) rawAmount += prevTxOut.Amount.rawAmount; account.accountStatus.unconfirmedAmount = new CurrencyUnit(rawAmount); if (isUpdatebalance) _UpdateBalance(false); }; EventHandler<Account> _AccountAdded = (sender, e) => { utxodb.Open(); _AddAddressEvent(e, true); utxodb.Close(); }; EventHandler<Account> _AccountRemoved = (sender, e) => { EventHandler<Tuple<CurrencyUnit, CurrencyUnit>> eh = changeAmountDict[e]; changeAmountDict.Remove(e); AddressEvent addressEvent = blockChain.RemoveAddressEvent(e.Address.Hash); addressEvent.BalanceUpdated -= eh; _UpdateBalance(false); }; utxodb.Open(); foreach (var accountHolder in accountHolders.AllAccountHolders) { foreach (var account in accountHolder.Accounts) _AddAddressEvent(account, false); accountHolder.AccountAdded += _AccountAdded; accountHolder.AccountRemoved += _AccountRemoved; } utxodb.Close(); accountHolders.AccountHolderAdded += (sender, e) => { e.AccountAdded += _AccountAdded; e.AccountRemoved += _AccountRemoved; }; accountHolders.AccountHolderRemoved += (semder, e) => { e.AccountAdded -= _AccountAdded; e.AccountRemoved -= _AccountRemoved; }; blockChain.BalanceUpdated += (sender, e) => _UpdateBalance(false); _UpdateBalance(false); unconfirmedTtxs = new Dictionary<TransferTransaction, TransactionOutput[]>(); mining = new Mining(); mining.FoundNonce += (sender, e) => creaNodeTest.DiffuseNewBlock(e); blockChain.Updated += (sender, e) => { foreach (var block in e) foreach (var tx in block.Transactions) foreach (var txIn in tx.TxInputs) { TransferTransaction contradiction = null; foreach (var unconfirmedTx in unconfirmedTtxs) { foreach (var unconfirmedTxIn in unconfirmedTx.Key.TxInputs) if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex) { contradiction = unconfirmedTx.Key; break; } if (contradiction != null) break; } if (contradiction != null) unconfirmedTtxs.Remove(contradiction); } Mine(); }; Mine(); //creaNodeTest = new CreaNode(ps.NodePort, creaVersion, appnameWithVersion, new FirstNodeInfosDatabase(p2pDirectory)); creaNodeTest = new CreaNodeTest(blockChain, ps.NodePort, creaVersion, appnameWithVersion); creaNodeTest.ConnectionKeeped += (sender, e) => creaNodeTest.SyncronizeBlockchain(); creaNodeTest.ReceivedNewTransaction += (sender, e) => { TransferTransaction ttx = e as TransferTransaction; if (ttx == null) return; TransactionOutput[] prevTxOuts = new TransactionOutput[ttx.TxInputs.Length]; for (int i = 0; i < prevTxOuts.Length; i++) prevTxOuts[i] = blockChain.GetMainBlock(ttx.TxInputs[i].PrevTxBlockIndex).Transactions[ttx.TxInputs[i].PrevTxIndex].TxOutputs[ttx.TxInputs[i].PrevTxOutputIndex]; if (!ttx.Verify(prevTxOuts)) return; List<TransactionOutput> senders = new List<TransactionOutput>(); List<TransactionOutput> receivers = new List<TransactionOutput>(); long sentAmount = 0; long receivedAmount = 0; for (int i = 0; i < ttx.txInputs.Length; i++) foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) if (prevTxOuts[i].Address.Equals(account.Address.Hash)) { sentAmount += prevTxOuts[i].Amount.rawAmount; senders.Add(prevTxOuts[i]); } for (int i = 0; i < ttx.TxOutputs.Length; i++) foreach (var accountHolder in accountHolders.AllAccountHolders) foreach (var account in accountHolder.Accounts) if (ttx.TxOutputs[i].Address.Equals(account.Address.Hash)) { receivedAmount += ttx.TxOutputs[i].Amount.rawAmount; receivers.Add(ttx.TxOutputs[i]); } if (senders.Count > 0 || receivers.Count > 0) { TransactionHistoryType type = TransactionHistoryType.transfered; if (receivers.Count < ttx.TxOutputs.Length) type = TransactionHistoryType.sent; else if (senders.Count < ttx.TxInputs.Length) type = TransactionHistoryType.received; transactionHistories.AddTransactionHistory(new TransactionHistory(true, false, type, DateTime.MinValue, 0, ttx.Id, senders.ToArray(), receivers.ToArray(), ttx, prevTxOuts, new CurrencyUnit(sentAmount), new CurrencyUnit(receivedAmount - sentAmount))); } utxodb.Open(); for (int i = 0; i < ttx.TxInputs.Length; i++) if (blockChain.FindUtxo(prevTxOuts[i].Address, ttx.TxInputs[i].PrevTxBlockIndex, ttx.TxInputs[i].PrevTxIndex, ttx.TxInputs[i].PrevTxOutputIndex) == null) return; utxodb.Close(); foreach (var txIn in ttx.TxInputs) foreach (var unconfirmedTtx in unconfirmedTtxs) foreach (var unconfirmedTxIn in unconfirmedTtx.Key.TxInputs) if (txIn.PrevTxBlockIndex == unconfirmedTxIn.PrevTxBlockIndex && txIn.PrevTxIndex == unconfirmedTxIn.PrevTxIndex && txIn.PrevTxOutputIndex == unconfirmedTxIn.PrevTxOutputIndex) return; unconfirmedTtxs.Add(ttx, prevTxOuts); Mine(); }; creaNodeTest.ReceivedNewBlock += (sender, e) => blockChain.UpdateChain(e).Pipe((ret) => this.RaiseResult("blockchain_update", 5, ret.ToString())); //creaNodeTest.Start(); isSystemStarted = true; }
//BlockChainのテスト(分岐がない場合・採掘) public static void Test17() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[100]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; Console.WriteLine("block" + i.ToString() + " mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < blks.Length; i++) blockchain.UpdateChain(blks2[i]); stopwatch.Stop(); Console.WriteLine(string.Join(":", "test17_1", stopwatch.ElapsedMilliseconds.ToString() + "ms")); Console.WriteLine("test17_succeeded"); }
//2014/12/17追加 BlockChainの試験(口座残高) public static void Test25() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; Console.WriteLine("block" + i.ToString() + " mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } if (blockchain.registeredAddresses.Count != 0) throw new Exception("test25_1"); AddressEvent ae = new AddressEvent(new Sha256Ripemd160Hash()); blockchain.AddAddressEvent(ae); if (blockchain.registeredAddresses.Count != 1) throw new Exception("test25_2"); if (!blockchain.registeredAddresses.Keys.Contains(ae)) throw new Exception("test25_3"); if (blockchain.registeredAddresses[ae].Count != 0) throw new Exception("test25_4"); AddressEvent aeret = blockchain.RemoveAddressEvent(new Sha256Ripemd160Hash()); if (ae != aeret) throw new Exception("test25_5"); if (blockchain.registeredAddresses.Count != 0) throw new Exception("test25_6"); blockchain.AddAddressEvent(ae); Dictionary<Sha256Ripemd160Hash, Tuple<CurrencyUnit, CurrencyUnit>> balances = new Dictionary<Sha256Ripemd160Hash, Tuple<CurrencyUnit, CurrencyUnit>>(); foreach (var address in bg.addresses) { AddressEvent addressEvent = new AddressEvent(address); addressEvent.BalanceUpdated += (sender, e) => { balances[addressEvent.address] = e; }; blockchain.AddAddressEvent(addressEvent); } int counter = 0; blockchain.BalanceUpdated += (sender, e) => { counter++; }; for (int i = 0; i < blks.Length; i++) { blockchain.UpdateChain(blks2[i]); if (counter != i) throw new Exception("test25_7"); foreach (var address in bg.addresses) { long usable = 0; long unusable = 0; foreach (var txoutcon in blkCons[i].unspentTxOuts[address]) if (txoutcon.bIndex + 6 > i) unusable += txoutcon.amount.rawAmount; else usable += txoutcon.amount.rawAmount; if (balances[address].Item1.rawAmount != usable) throw new Exception("test25_2"); if (balances[address].Item2.rawAmount != unusable) throw new Exception("test25_2"); } } Console.WriteLine("test25_succeeded"); }
//BlockChainのテスト(分岐がある場合・採掘・後ろが無効な場合) public static void Test24() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb, 100, 300, 1000, 1000); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; double cumulativeDiff1 = 0.0; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } TransactionalBlock tblk2_1 = blks2[1] as TransactionalBlock; TransactionalBlock tblk2_2 = blks2[2] as TransactionalBlock; TransactionalBlock blk3_2 = TransactionalBlock.GetBlockTemplate(2, tblk2_2.coinbaseTxToMiner, tblk2_2.transferTxs, _indexToBlock, 0); while (true) { blk3_2.UpdateTimestamp(DateTime.Now); blk3_2.UpdateNonce(nonce); if (blk3_2.Id.CompareTo(blk3_2.header.difficulty.Target) <= 0) { Console.WriteLine("block3_2 mined. " + blk3_2.Difficulty.Diff.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } BlockHeader bh3 = new BlockHeader(); bh3.LoadVersion0(3, blk3_2.Id, DateTime.Now, blks2[1].Difficulty, new byte[10]); NormalBlock blk3_3 = new NormalBlock(); blk3_3.LoadVersion0(bh3, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs); blk3_3.UpdateMerkleRootHash(); int forkLength = (int)Math.Floor(cumulativeDiff1 / blks2[1].Difficulty.Diff + 10); TransactionalBlock[] blks3 = new TransactionalBlock[forkLength]; blks3[0] = blk3_3; for (int i = 1; i < blks3.Length; i++) { BlockHeader bh = new BlockHeader(); bh.LoadVersion0(i + 3, blks3[i - 1].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]); NormalBlock blk3 = new NormalBlock(); blk3.LoadVersion0(bh, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs); blk3.UpdateMerkleRootHash(); blks3[i] = blk3; } BlockHeader bh4 = new BlockHeader(); bh4.LoadVersion0(4, blk3_3.Id, DateTime.Now, blks2[1].Difficulty, new byte[10]); NormalBlock blk4 = new NormalBlock(); blk4.LoadVersion0(bh4, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs); blk4.UpdateMerkleRootHash(); BlockHeader bh10 = new BlockHeader(); bh10.LoadVersion0(10, blks2[9].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]); NormalBlock blk5_10 = new NormalBlock(); blk5_10.LoadVersion0(bh10, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs); blk5_10.UpdateMerkleRootHash(); TransactionalBlock[] blks5 = new TransactionalBlock[5]; blks5[0] = blk5_10; for (int i = 1; i < blks5.Length; i++) { BlockHeader bh = new BlockHeader(); bh.LoadVersion0(i + 10, blks5[i - 1].Id, DateTime.Now, blks2[1].Difficulty, new byte[10]); NormalBlock blk5 = new NormalBlock(); blk5.LoadVersion0(bh, tblk2_1.coinbaseTxToMiner, tblk2_1.transferTxs); blk5.UpdateMerkleRootHash(); blks5[i] = blk5; } BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blks2[0]); if (type5 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test24_5"); BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blk4); if (type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test24_1"); for (int i = 2; i < blks2.Length; i++) { BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks2[i]); if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test24_2"); } for (int i = 0; i < blks5.Length; i++) { BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks5[i]); if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test24_3"); } BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blk3_2); if (type3 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test24_1"); for (int i = 0; i < blks3.Length; i++) { BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks3[i]); if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test24_4"); } BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blks2[1]); if (type4 != BlockChain.UpdateChainReturnType.updatedAndRejected) throw new Exception("test24_6"); if (blockchain.blocksCurrent.value != 10) throw new Exception("test19_2"); Console.WriteLine("test24_succeeded"); }
//BlockChainのテスト(分岐がない場合・無効ブロックなどを追加しようとした場合) public static void Test18() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; Console.WriteLine("block" + i.ToString() + " mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } if (blockchain.blocksCurrent.value != 0) throw new Exception("test18_1"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_2"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_3"); } TransactionalBlock blk1 = blks2[1] as TransactionalBlock; TransactionalBlock blk2 = blks2[2] as TransactionalBlock; Creahash hashzero = new Creahash(); BlockHeader bh5 = new BlockHeader(); bh5.LoadVersion0(100, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]); BlockHeader bh6 = new BlockHeader(); bh6.LoadVersion0(101, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]); TransactionalBlock blk100 = new NormalBlock(); blk100.LoadVersion0(bh5, blk1.coinbaseTxToMiner, blk1.transferTxs); blk100.UpdateMerkleRootHash(); TransactionalBlock blk101 = new NormalBlock(); blk101.LoadVersion0(bh6, blk1.coinbaseTxToMiner, blk1.transferTxs); blk101.UpdateMerkleRootHash(); blockchain.pendingBlocks[101] = new Dictionary<Creahash, Block>(); blockchain.rejectedBlocks[101] = new Dictionary<Creahash, Block>(); BlockChain.UpdateChainReturnType type1 = blockchain.UpdateChain(blks[0]); if (type1 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test18_5"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_6"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_7"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_8"); } bool flag2 = false; try { blockchain.UpdateChain(blk101); } catch (InvalidOperationException) { flag2 = true; } if (!flag2) throw new Exception("test18_9"); BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blk100); if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test18_10"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_11"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_12"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_13"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_14"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_15"); } if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_16"); } BlockHeader bh1 = new BlockHeader(); bh1.LoadVersion0(1, hashzero, DateTime.Now, blk1.Difficulty, new byte[10]); TransactionalBlock blk1_2 = new NormalBlock(); blk1_2.LoadVersion0(bh1, blk1.coinbaseTxToMiner, blk1.transferTxs); blk1_2.UpdateMerkleRootHash(); BlockChain.UpdateChainReturnType type3 = blockchain.UpdateChain(blk1_2); if (type3 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test18_17"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_18"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_19"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_20"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id)) throw new Exception("test18_21"); } else if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_22"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_23"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_24"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_25"); } if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_26"); } BlockHeader bh2 = new BlockHeader(); bh2.LoadVersion0(1, blks[0].Id, DateTime.Now, blk1.Difficulty, new byte[10]); TransactionalBlock blk1_3 = new NormalBlock(); blk1_3.LoadVersion0(bh2, blk1.coinbaseTxToMiner, blk1.transferTxs); blk1_3.UpdateMerkleRootHash(); BlockChain.UpdateChainReturnType type4 = blockchain.UpdateChain(blk1_3); if (type4 != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test18_27"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_28"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_29"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_30"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id)) throw new Exception("test18_31"); if (blockchain.rejectedBlocks[i] == null) throw new Exception("test18_32"); if (blockchain.rejectedBlocks[i].Count != 1) throw new Exception("test18_33"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id)) throw new Exception("test18_34"); } else if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_35"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_36"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_37"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_38"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_39"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_40"); } } TransactionalBlock blk1_4 = TransactionalBlock.GetBlockTemplate(1, blk1.coinbaseTxToMiner, blk2.transferTxs, _indexToBlock, 0); while (true) { blk1_4.UpdateTimestamp(DateTime.Now); blk1_4.UpdateNonce(nonce); if (blk1_4.Id.CompareTo(blk1_4.header.difficulty.Target) <= 0) { Console.WriteLine("block1_4 mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } BlockChain.UpdateChainReturnType type5 = blockchain.UpdateChain(blk1_4); if (type5 != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test18_41"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_42"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_43"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_44"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id)) throw new Exception("test18_45"); if (blockchain.rejectedBlocks[i] == null) throw new Exception("test18_46"); if (blockchain.rejectedBlocks[i].Count != 2) throw new Exception("test18_47"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id)) throw new Exception("test18_48"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id)) throw new Exception("test18_49"); } else if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_50"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_51"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_52"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_53"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_54"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_55"); } } BlockChain.UpdateChainReturnType type8 = blockchain.UpdateChain(blk1_3); if (type8 != BlockChain.UpdateChainReturnType.invariable) throw new Exception("test18_56"); if (blockchain.blocksCurrent.value != 1) throw new Exception("test18_57"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_58"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_59"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id)) throw new Exception("test18_60"); if (blockchain.rejectedBlocks[i] == null) throw new Exception("test18_61"); if (blockchain.rejectedBlocks[i].Count != 2) throw new Exception("test18_62"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id)) throw new Exception("test18_63"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id)) throw new Exception("test18_64"); } else if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_65"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_66"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_67"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_68"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_69"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_70"); } } BlockChain.UpdateChainReturnType type6 = blockchain.UpdateChain(blk1); if (type6 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test18_71"); BlockChain.UpdateChainReturnType type7 = blockchain.UpdateChain(blk1_3); if (type7 != BlockChain.UpdateChainReturnType.invariable) throw new Exception("test18_72"); if (blockchain.blocksCurrent.value != 2) throw new Exception("test18_73"); for (int i = 0; i < blockchain.pendingBlocks.Length; i++) { if (i == 2) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_74"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_75"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk1_2.Id)) throw new Exception("test18_76"); if (blockchain.rejectedBlocks[i] == null) throw new Exception("test18_77"); if (blockchain.rejectedBlocks[i].Count != 2) throw new Exception("test18_78"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_3.Id)) throw new Exception("test18_79"); if (!blockchain.rejectedBlocks[i].Keys.Contains(blk1_4.Id)) throw new Exception("test18_80"); } else if (i == 101) { if (blockchain.pendingBlocks[i] == null) throw new Exception("test18_81"); if (blockchain.pendingBlocks[i].Count != 1) throw new Exception("test18_82"); if (!blockchain.pendingBlocks[i].Keys.Contains(blk100.Id)) throw new Exception("test18_83"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_84"); } else { if (blockchain.pendingBlocks[i] != null) throw new Exception("test18_85"); if (blockchain.rejectedBlocks[i] != null) throw new Exception("test18_86"); } } BlockHeader bh3 = new BlockHeader(); bh3.LoadVersion0(2, hashzero, DateTime.Now, blk2.Difficulty, new byte[10]); TransactionalBlock blk2_2 = new NormalBlock(); blk2_2.LoadVersion0(bh3, blk2.coinbaseTxToMiner, blk2.transferTxs); blk2_2.UpdateMerkleRootHash(); BlockChain.UpdateChainReturnType type9 = blockchain.UpdateChain(blk2_2); if (type9 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test18_87"); BlockHeader bh4 = new BlockHeader(); bh4.LoadVersion0(2, blk1_2.Id, DateTime.Now, blk2.Difficulty, new byte[10]); TransactionalBlock blk2_3 = new NormalBlock(); blk2_3.LoadVersion0(bh4, blk2.coinbaseTxToMiner, blk2.transferTxs); blk2_3.UpdateMerkleRootHash(); BlockChain.UpdateChainReturnType type10 = blockchain.UpdateChain(blk2_3); if (type10 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test18_88"); BlockHeader bh7 = new BlockHeader(); bh7.LoadVersion0(2, blk1_3.Id, DateTime.Now, blk2.Difficulty, new byte[10]); TransactionalBlock blk2_4 = new NormalBlock(); blk2_4.LoadVersion0(bh7, blk2.coinbaseTxToMiner, blk2.transferTxs); blk2_4.UpdateMerkleRootHash(); BlockChain.UpdateChainReturnType type13 = blockchain.UpdateChain(blk2_4); if (type13 != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test18_91"); for (int i = 2; i < blks2.Length; i++) { BlockChain.UpdateChainReturnType type11 = blockchain.UpdateChain(blks2[i]); if (type11 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test18_89"); } TransactionalBlock blk10 = TransactionalBlock.GetBlockTemplate(10, blk2.coinbaseTxToMiner, blk2.transferTxs, _indexToBlock, 0); while (true) { blk10.UpdateTimestamp(DateTime.Now); blk10.UpdateNonce(nonce); if (blk10.Id.CompareTo(blk10.header.difficulty.Target) <= 0) { Console.WriteLine("block10 mined."); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } BlockChain.UpdateChainReturnType type12 = blockchain.UpdateChain(blk10); if (type12 != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test18_90"); Console.WriteLine("test18_succeeded"); }
/// <summary> /// Creates a PeerGroup with the given parameters. The connectionDelayMillis parameter controls how long the /// PeerGroup will wait between attempts to connect to nodes or read from any added peer discovery sources. /// </summary> public PeerGroup(IBlockStore blockStore, NetworkParameters networkParameters, BlockChain blockChain, int connectionDelayMillis) { _blockStore = blockStore; _networkParameters = networkParameters; _blockChain = blockChain; _connectionDelayMillis = connectionDelayMillis; _inactives = new BlockingCollection<PeerAddress>(); _peers = new BlockingCollection<Peer>(); _peerDiscoverers = new BlockingCollection<IPeerDiscovery>(); }
public void SetUp() { _testNetChainBlockStore = new MemoryBlockStore(_testNet); _testNetChain = new BlockChain(_testNet, new Wallet(_testNet), _testNetChainBlockStore); _unitTestParams = NetworkParameters.UnitTests(); _wallet = new Wallet(_unitTestParams); _wallet.AddKey(new EcKey()); ResetBlockStore(); _chain = new BlockChain(_unitTestParams, _wallet, _blockStore); _coinbaseTo = _wallet.Keychain[0].ToAddress(_unitTestParams); }
//BlockChainのテスト(分岐がある場合・採掘・交互に追加していく場合) public static void Test21() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; double cumulativeDiff1 = 0.0; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } Console.WriteLine(); Block[] blks3 = new Block[blks.Length]; double cumulativeDiff2 = 0.0; Func<long, TransactionalBlock> _indexToBlock2 = (index) => blks3[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks3[i] = blks[i]; cumulativeDiff2 += blks3[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_2 " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0); nonce = new byte[10]; while (true) { tblk3.UpdateTimestamp(DateTime.Now); tblk3.UpdateNonce(nonce); if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0) { blks3[i] = tblk3; cumulativeDiff2 += blks3[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } cumulativeDiff1 = 0.0; cumulativeDiff2 = 0.0; blockchain.UpdateChain(blks2[0]); for (int i = 1; i < blks.Length; i++) { cumulativeDiff1 += blks2[i].Difficulty.Diff; BlockChain.UpdateChainReturnType type1 = blockchain.UpdateChain(blks2[i]); if (cumulativeDiff1 > cumulativeDiff2) { if (type1 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test21_1"); } else { if (type1 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test21_3"); } cumulativeDiff2 += blks3[i].Difficulty.Diff; BlockChain.UpdateChainReturnType type2 = blockchain.UpdateChain(blks3[i]); if (cumulativeDiff2 > cumulativeDiff1) { if (type2 != BlockChain.UpdateChainReturnType.updated) throw new Exception("test21_2"); } else { if (type2 != BlockChain.UpdateChainReturnType.pending) throw new Exception("test21_4"); } } utxodb.Open(); foreach (var address in blkCons[9].unspentTxOuts.Keys) foreach (var toc in blkCons[9].unspentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null) throw new Exception("test21_5"); foreach (var address in blkCons[9].spentTxOuts.Keys) foreach (var toc in blkCons[9].spentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null) throw new Exception("test21_6"); utxodb.Close(); Console.WriteLine("test21_succeeded"); }
//BlockChainのテスト(分岐がある場合・採掘・順番通りに追加されなかった場合) public static void Test22() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; double[] cumulativeDiffs0 = new double[blks.Length]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; cumulativeDiffs0[i] = i == 0 ? blks[i].Difficulty.Diff : cumulativeDiffs0[i - 1] + blks[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; double[] cumulativeDiffs1 = new double[blks.Length]; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; cumulativeDiffs1[i] = blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs1[i].ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; cumulativeDiffs1[i] = cumulativeDiffs1[i - 1] + blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs1[i].ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } int forkIndex1 = 0; int forkIndex2 = 0; int[] forkIndexes = (blks.Length - 1).RandomNums(); if (forkIndexes[0] < forkIndexes[1]) { forkIndex1 = forkIndexes[0] + 1; forkIndex2 = forkIndexes[1] + 1; } else { forkIndex1 = forkIndexes[1] + 1; forkIndex2 = forkIndexes[0] + 1; } Block[] blks3 = new Block[blks.Length]; double[] cumulativeDiffs2 = new double[blks.Length]; Func<long, TransactionalBlock> _indexToBlock2 = (index) => index >= forkIndex1 ? blks3[index] as TransactionalBlock : blks2[index] as TransactionalBlock; for (int i = forkIndex1; i < blks.Length; i++) { TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0); nonce = new byte[10]; while (true) { tblk3.UpdateTimestamp(DateTime.Now); tblk3.UpdateNonce(nonce); if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0) { blks3[i] = tblk3; if (i == forkIndex1) cumulativeDiffs2[i] = cumulativeDiffs1[i - 1] + blks3[i].Difficulty.Diff; else cumulativeDiffs2[i] = cumulativeDiffs2[i - 1] + blks3[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs2[i].ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } Block[] blks4 = new Block[blks.Length]; double[] cumulativeDiffs3 = new double[blks.Length]; Func<long, TransactionalBlock> _indexToBlock3 = (index) => index >= forkIndex2 ? blks4[index] as TransactionalBlock : blks2[index] as TransactionalBlock; for (int i = forkIndex2; i < blks.Length; i++) { TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock3, 0); nonce = new byte[10]; while (true) { tblk3.UpdateTimestamp(DateTime.Now); tblk3.UpdateNonce(nonce); if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0) { blks4[i] = tblk3; if (i == forkIndex2) cumulativeDiffs3[i] = cumulativeDiffs1[i - 1] + blks4[i].Difficulty.Diff; else cumulativeDiffs3[i] = cumulativeDiffs3[i - 1] + blks4[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_3 mined. " + blks4[i].Difficulty.Diff.ToString() + " " + cumulativeDiffs3[i].ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } bool?[] map1 = new bool?[blks.Length]; bool?[] map2 = new bool?[blks.Length]; bool?[] map3 = new bool?[blks.Length]; bool?[] map4 = new bool?[blks.Length]; for (int i = 0; i < blks.Length; i++) { map1[i] = i == 0 ? (bool?)null : false; map2[i] = i == 0 ? (bool?)null : false; map3[i] = i < forkIndex1 ? (bool?)null : false; map4[i] = i < forkIndex2 ? (bool?)null : false; } blockchain.UpdateChain(blks[0]); int[] randomnums = (4 * blks.Length).RandomNums(); double cumulativeDiff = 0.0; int main = 0; int rejectedIndex = 0; for (int i = 0; i < randomnums.Length; i++) { int keiretsu = randomnums[i] / blks.Length; int index = randomnums[i] % blks.Length; if ((keiretsu == 0 && map1[index] == null) || (keiretsu == 1 && map2[index] == null) || (keiretsu == 2 && map3[index] == null) || (keiretsu == 3 && map4[index] == null)) continue; if (keiretsu == 0) { BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks[index]); bool flag = false; for (int j = index - 1; j > 0; j--) if (!map1[j].Value) { flag = true; break; } if (!flag && index != 1) { if (type != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test22_1"); } else { if (!flag) { int headIndex = index; for (int j = index + 1; j < blks.Length; j++) if (map1[j].Value) headIndex = j; else break; if (cumulativeDiff >= cumulativeDiffs0[headIndex]) flag = true; else rejectedIndex = headIndex; } if (flag && type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test22_2"); if (!flag && type != BlockChain.UpdateChainReturnType.updatedAndRejected) throw new Exception("test22_3"); } map1[index] = true; } else if (keiretsu == 1) { BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks2[index]); bool flag = false; for (int j = index - 1; j > 0; j--) if (!map2[j].Value) { flag = true; break; } if (!flag) { int headIndex1 = index; for (int j = index + 1; j < blks.Length; j++) if (map2[j].Value) headIndex1 = j; else break; double cdiff = cumulativeDiffs1[headIndex1]; int m = 1; if (headIndex1 + 1 >= forkIndex1 && map3[forkIndex1].Value) { int headIndex2 = forkIndex1; for (int j = forkIndex1 + 1; j < blks.Length; j++) if (map3[j].Value) headIndex2 = j; else break; //<未実装>等しい場合の対処 if (cumulativeDiffs2[headIndex2] > cdiff) { cdiff = cumulativeDiffs2[headIndex2]; m = 2; } else if (cumulativeDiffs2[headIndex2] == cdiff) { Console.WriteLine("not_implemented_test_case"); return; } } if (headIndex1 + 1 >= forkIndex2 && map4[forkIndex2].Value) { int headIndex3 = forkIndex2; for (int j = forkIndex2 + 1; j < blks.Length; j++) if (map4[j].Value) headIndex3 = j; else break; //<未実装>等しい場合の対処 if (cumulativeDiffs3[headIndex3] > cdiff) { cdiff = cumulativeDiffs3[headIndex3]; m = 3; } else if (cumulativeDiffs3[headIndex3] == cdiff) { Console.WriteLine("not_implemented_test_case"); return; } } if (cumulativeDiff >= cdiff) flag = true; else { cumulativeDiff = cdiff; main = m; } } if (flag && type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test22_4"); if (!flag && type != BlockChain.UpdateChainReturnType.updated) throw new Exception("test22_5"); map2[index] = true; } else if (keiretsu == 2) { BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks3[index]); bool flag = false; for (int j = index - 1; j >= forkIndex1; j--) if (!map3[j].Value) { flag = true; break; } if (!flag) for (int j = forkIndex1 - 1; j > 0; j--) if (!map2[j].Value) { flag = true; break; } if (!flag) { int headIndex = index; for (int j = index + 1; j < blks.Length; j++) if (map3[j].Value) headIndex = j; else break; if (cumulativeDiff >= cumulativeDiffs2[headIndex]) flag = true; else { cumulativeDiff = cumulativeDiffs2[headIndex]; main = 2; } } if (flag && type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test22_6"); if (!flag && type != BlockChain.UpdateChainReturnType.updated) throw new Exception("test22_7"); map3[index] = true; } else if (keiretsu == 3) { BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks4[index]); bool flag = false; for (int j = index - 1; j >= forkIndex2; j--) if (!map4[j].Value) { flag = true; break; } if (!flag) for (int j = forkIndex2 - 1; j > 0; j--) if (!map2[j].Value) { flag = true; break; } if (!flag) { int headIndex = index; for (int j = index + 1; j < blks.Length; j++) if (map4[j].Value) headIndex = j; else break; if (cumulativeDiff >= cumulativeDiffs3[headIndex]) flag = true; else { cumulativeDiff = cumulativeDiffs3[headIndex]; main = 3; } } if (flag && type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test22_8"); if (!flag && type != BlockChain.UpdateChainReturnType.updated) throw new Exception("test22_9"); map4[index] = true; } bool flag2 = true; for (int j = 1; j < blks.Length; j++) { if (map1[j].Value) { if (flag2 && j <= rejectedIndex) { if (blockchain.rejectedBlocks[j + 1] == null || !blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_10"); if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_11"); } else { if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_12"); if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_13"); } } else { flag2 = false; if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_14"); if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks[j].Id)) throw new Exception("test22_15"); } } bool flag3 = true; for (int j = 1; j < blks.Length; j++) { if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks2[j].Id)) throw new Exception("test22_16"); if (map2[j].Value) { if (flag3 && (main == 1 || (main == 2 && j < forkIndex1) || (main == 3 && j < forkIndex2))) { if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id)) throw new Exception("test22_17"); } else { if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id)) throw new Exception("test22_18"); } } else { flag3 = false; if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks2[j].Id)) throw new Exception("test22_19"); } } bool flag4 = true; for (int j = forkIndex1; j < blks.Length; j++) { if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks3[j].Id)) throw new Exception("test22_20"); if (map3[j].Value) { if (flag4 && main == 2) { if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id)) throw new Exception("test22_21"); } else { if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id)) throw new Exception("test22_22"); } } else { flag4 = false; if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks3[j].Id)) throw new Exception("test22_23"); } } bool flag5 = true; for (int j = forkIndex2; j < blks.Length; j++) { if (blockchain.rejectedBlocks[j + 1] != null && blockchain.rejectedBlocks[j + 1].Keys.Contains(blks4[j].Id)) throw new Exception("test22_24"); if (map4[j].Value) { if (flag5 && main == 3) { if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id)) throw new Exception("test22_25"); } else { if (blockchain.pendingBlocks[j + 1] == null || !blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id)) throw new Exception("test22_26"); } } else { flag5 = false; if (blockchain.pendingBlocks[j + 1] != null && blockchain.pendingBlocks[j + 1].Keys.Contains(blks4[j].Id)) throw new Exception("test22_27"); } } } Block headBlock = blockchain.GetHeadBlock(); if (main == 1) { if (!headBlock.Id.Equals(blks2[9].Id)) throw new Exception("test22_28"); } else if (main == 2) { if (!headBlock.Id.Equals(blks3[9].Id)) throw new Exception("test22_29"); } else if (main == 3) { if (!headBlock.Id.Equals(blks4[9].Id)) throw new Exception("test22_30"); } else throw new InvalidOperationException(); utxodb.Open(); foreach (var address in blkCons[9].unspentTxOuts.Keys) foreach (var toc in blkCons[9].unspentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) == null) throw new Exception("test22_31"); foreach (var address in blkCons[9].spentTxOuts.Keys) foreach (var toc in blkCons[9].spentTxOuts[address]) if (blockchain.FindUtxo(address, toc.bIndex, toc.txIndex, toc.txOutIndex) != null) throw new Exception("test22_32"); utxodb.Close(); Console.WriteLine("test22_succeeded"); }
//BlockChainのテスト(分岐がある場合・採掘・長過ぎる場合) public static void Test23() { string basepath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); BlockchainAccessDB bcadb = new BlockchainAccessDB(basepath); string bcadbPath = bcadb.GetPath(); if (File.Exists(bcadbPath)) File.Delete(bcadbPath); BlockManagerDB bmdb = new BlockManagerDB(basepath); string bmdbPath = bmdb.GetPath(); if (File.Exists(bmdbPath)) File.Delete(bmdbPath); BlockDB bdb = new BlockDB(basepath); string bdbPath = bdb.GetPath(0); if (File.Exists(bdbPath)) File.Delete(bdbPath); BlockFilePointersDB bfpdb = new BlockFilePointersDB(basepath); string bfpPath = bfpdb.GetPath(); if (File.Exists(bfpPath)) File.Delete(bfpPath); UtxoFileAccessDB ufadb = new UtxoFileAccessDB(basepath); string ufadbPath = ufadb.GetPath(); if (File.Exists(ufadbPath)) File.Delete(ufadbPath); UtxoFilePointersDB ufpdb = new UtxoFilePointersDB(basepath); string ufpdbPath = ufpdb.GetPath(); if (File.Exists(ufpdbPath)) File.Delete(ufpdbPath); UtxoFilePointersTempDB ufptempdb = new UtxoFilePointersTempDB(basepath); string ufptempdbPath = ufptempdb.GetPath(); if (File.Exists(ufptempdbPath)) File.Delete(ufptempdbPath); UtxoDB utxodb = new UtxoDB(basepath); string utxodbPath = utxodb.GetPath(); if (File.Exists(utxodbPath)) File.Delete(utxodbPath); BlockChain blockchain = new BlockChain(bcadb, bmdb, bdb, bfpdb, ufadb, ufpdb, ufptempdb, utxodb, 100, 3, 1000, 1000); BlockGenerator bg = new BlockGenerator(); Block[] blks = new Block[10]; BlockContext[] blkCons = new BlockContext[blks.Length]; for (int i = 0; i < blks.Length; i++) { blkCons[i] = bg.CreateNextValidBlock(); blks[i] = blkCons[i].block; Console.WriteLine("block" + i.ToString() + " created."); } Block[] blks2 = new Block[blks.Length]; double cumulativeDiff1 = 0.0; byte[] nonce = null; Func<long, TransactionalBlock> _indexToBlock = (index) => blks2[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks2[i] = blks[i]; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk2 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock, 0); nonce = new byte[10]; while (true) { tblk2.UpdateTimestamp(DateTime.Now); tblk2.UpdateNonce(nonce); if (tblk2.Id.CompareTo(tblk2.header.difficulty.Target) <= 0) { blks2[i] = tblk2; cumulativeDiff1 += blks2[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_1 mined. " + blks2[i].Difficulty.Diff.ToString() + " " + cumulativeDiff1.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } Console.WriteLine(); Block[] blks3 = new Block[blks.Length]; double cumulativeDiff2 = 0.0; Func<long, TransactionalBlock> _indexToBlock2 = (index) => blks3[index] as TransactionalBlock; for (int i = 0; i < blks.Length; i++) { if (i == 0) { blks3[i] = blks[i]; cumulativeDiff2 += blks3[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_2 " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString()); continue; } TransactionalBlock tblk = blks[i] as TransactionalBlock; TransactionalBlock tblk3 = TransactionalBlock.GetBlockTemplate(tblk.Index, tblk.coinbaseTxToMiner, tblk.transferTxs, _indexToBlock2, 0); nonce = new byte[10]; while (true) { tblk3.UpdateTimestamp(DateTime.Now); tblk3.UpdateNonce(nonce); if (tblk3.Id.CompareTo(tblk3.header.difficulty.Target) <= 0) { blks3[i] = tblk3; cumulativeDiff2 += blks3[i].Difficulty.Diff; Console.WriteLine("block" + i.ToString() + "_2 mined. " + blks3[i].Difficulty.Diff.ToString() + " " + cumulativeDiff2.ToString()); break; } int index = nonce.Length.RandomNum(); int value = 256.RandomNum(); nonce[index] = (byte)value; } } for (int i = 0; i < blks.Length; i++) blockchain.UpdateChain(blks2[i]); for (int i = blks.Length - 1; i >= blks.Length - 3; i--) { BlockChain.UpdateChainReturnType type = blockchain.UpdateChain(blks3[i]); if (i == blks.Length - 3) { if (type != BlockChain.UpdateChainReturnType.rejected) throw new Exception("test23_1"); for (int j = 0; j < blks.Length - 3; j++) if (blockchain.rejectedBlocks[j + 1] != null) throw new Exception("test23_2"); for (int j = blks.Length - 3; j < blks.Length; j++) if (blockchain.rejectedBlocks[j + 1] == null || !blockchain.rejectedBlocks[j + 1].Keys.Contains(blks3[j].Id)) throw new Exception("test23_3"); for (int j = 0; j <= blks.Length - 3; j++) if (blockchain.pendingBlocks[j + 1] != null) throw new Exception("test23_4"); for (int j = blks.Length - 3 + 1; j < blks.Length; j++) if (blockchain.pendingBlocks[j + 1] == null || blockchain.pendingBlocks[j + 1].Keys.Count != 0) throw new Exception("test23_5"); } else { if (type != BlockChain.UpdateChainReturnType.pending) throw new Exception("test23_6"); } } Console.WriteLine("test23_succeeded"); }
public static void Run(string[] args) { var testNet = args.Length > 0 && string.Equals(args[0], "testnet", StringComparison.InvariantCultureIgnoreCase); var @params = testNet ? NetworkParameters.TestNet() : NetworkParameters.ProdNet(); var filePrefix = testNet ? "pingservice-testnet" : "pingservice-prodnet"; // Try to read the wallet from storage, create a new one if not possible. Wallet wallet; var walletFile = new FileInfo(filePrefix + ".wallet"); try { wallet = Wallet.LoadFromFile(walletFile); } catch (IOException) { wallet = new Wallet(@params); wallet.Keychain.Add(new EcKey()); wallet.SaveToFile(walletFile); } // Fetch the first key in the wallet (should be the only key). var key = wallet.Keychain[0]; // Load the block chain, if there is one stored locally. Console.WriteLine("Reading block store from disk"); using (var blockStore = new BoundedOverheadBlockStore(@params, new FileInfo(filePrefix + ".blockchain"))) { // Connect to the localhost node. One minute timeout since we won't try any other peers Console.WriteLine("Connecting ..."); using (var conn = new NetworkConnection(IPAddress.Loopback, @params, blockStore.GetChainHead().Height, 60000)) { var chain = new BlockChain(@params, wallet, blockStore); var peer = new Peer(@params, conn, chain); peer.Start(); // We want to know when the balance changes. wallet.CoinsReceived += (sender, e) => { // Running on a peer thread. Debug.Assert(!e.NewBalance.Equals(0)); // It's impossible to pick one specific identity that you receive coins from in BitCoin as there // could be inputs from many addresses. So instead we just pick the first and assume they were all // owned by the same person. var input = e.Tx.Inputs[0]; var from = input.FromAddress; var value = e.Tx.GetValueSentToMe(wallet); Console.WriteLine("Received " + Utils.BitcoinValueToFriendlyString(value) + " from " + from); // Now send the coins back! var sendTx = wallet.SendCoins(peer, from, value); Debug.Assert(sendTx != null); // We should never try to send more coins than we have! Console.WriteLine("Sent coins back! Transaction hash is " + sendTx.HashAsString); wallet.SaveToFile(walletFile); }; var progress = peer.StartBlockChainDownload(); var max = progress.Count; // Racy but no big deal. if (max > 0) { Console.WriteLine("Downloading block chain. " + (max > 1000 ? "This may take a while." : "")); var current = max; var lastPercent = 0; while (current > 0) { var pct = 100.0 - (100.0*(current/(double) max)); if ((int) pct != lastPercent) { Console.WriteLine(string.Format("Chain download {0}% done", (int) pct)); lastPercent = (int) pct; } progress.Await(TimeSpan.FromSeconds(1)); current = progress.Count; } } Console.WriteLine("Send coins to: " + key.ToAddress(@params)); Console.WriteLine("Waiting for coins to arrive. Press Ctrl-C to quit."); // The peer thread keeps us alive until something kills the process. } } }
// Peer discovery sources, will be polled occasionally if there aren't enough in-actives. /// <summary> /// Creates a PeerGroup with the given parameters and a default 5 second connection timeout. /// </summary> public PeerGroup(IBlockStore blockStore, NetworkParameters networkParameters, BlockChain blockChain) : this(blockStore, networkParameters, blockChain, DefaultConnectionDelayMillis) { }