public void Mine(object skp) { while (IsMining) { DateTime started = Date.Now(); Log.NewLine($"Started at {started}. Attempting to solve block {Blockchain.GetLastBlock().Index + 1}."); Block b = Miner.Solve((SharpKeyPair)skp, Blockchain, IsMining); if (b != null) { Log.NewLine($"Solved block {b.Index} with nonce {b.Nonce} ({b.Hash.Substring(0, 10)}) in {(int)Date.Now().Subtract(started).TotalMinutes} mins! Target diff was: {b.GetPrettyDifficulty(true)}."); } try { Blockchain.AddBlock(b); } catch { Log.NewLine($"Adding mined block failed. Skipping."); } } Log.NewLine($"Stopped at {Date.Now()}."); }
public Core(string[] args) { Log.NewLine("sharpcoin (core) v0.1.1 -- by aal89"); // Configure the ip address to bind on if (args.Length == 1 && IPAddress.Parse(args[0]) != null) { IpAddr.Set(args[0]); } Log.NewLine($"Attempting to bind tcp servers to address: {IpAddr.Mine()}."); // Load blockchain Log.NewLine($"Initializing blockchain."); Blockchain = new Blockchain(new Logger("Blockchain")); // Setup event listeners Log.Line("Setting up event listeners..."); Blockchain.BlockAdded += Blockchain_BlockAdded; Blockchain.QueuedTransactionAdded += Blockchain_QueuedTransactionAdded; Log.Append("Done."); // Setup api Log.Line($"Setting up client management..."); _ = new ClientManager(this, new Logger("ClientManager")); Log.Append("Done."); // Setup mine operator Log.Line($"Setting up mine operator..."); Operator = new Operator(Blockchain, new Logger("Miner")); Log.Append("Done."); // Setup peer manager (server&client) Log.NewLine($"Setting up peer manager."); PeerManager = new PeerManager(this, new Logger("PeerManager")); }
public static void Push(Transaction data) { Log.NewLine($"Pushing transaction {data.Id} to the client."); if (client != null) { client.Push(data); } }
public PeerManager(Core core, ILoggable log = null) { Log = log ?? new NullLogger(); Core = core; if (!File.Exists(peersPath)) { File.Create(peersPath).Dispose(); } Log.NewLine($"Creating UPnP port mapping."); CreateUPnPMapping(); Log.NewLine("Setting up server and accepting connections..."); // Take some unique random ips from all the saved peers to connect to initially. string[] ips = File.ReadAllLines(peersPath) .Distinct() .ToArray() .Shuffle() .Take(Config.MaximumConnections) .ToArray(); foreach (string ip in ips) { AddPeer(ip); } PeerInterval = new Timer(Config.PeerInterval); PeerInterval.Elapsed += PeerInterval_Elapsed; PeerInterval.AutoReset = true; PeerInterval.Enabled = true; KeepAliveInterval = new Timer(Config.PeerKeepAliveInterval); KeepAliveInterval.Elapsed += KeepAliveInterval_Elapsed; KeepAliveInterval.AutoReset = true; KeepAliveInterval.Enabled = true; // Final step: initiate the server _ = new PeerServer(Config.TcpPort); }
public Blockchain(ILoggable Log = null) { this.Log = Log ?? new NullLogger(); if (!File.Exists(BlockchainDirectory)) { Directory.CreateDirectory(BlockchainDirectory); } Log.NewLine($"Loading tx index."); Transactions = new Indexes.Transactions(this, Config.BlockchainDirectory); Transactions.Read(); Log.NewLine($"Loading utxo index."); UnspentOutputs = new Indexes.UnspentOutputs(Config.BlockchainDirectory); UnspentOutputs.Read(); Log.NewLine($"Validating blockchain."); Validate(); Log.NewLine($"Valid!"); }
private void CreateUPnPMapping() { try { var discoverer = new NatDiscoverer(); var cts = new CancellationTokenSource(3000); NatDevice device = Task.Run(async() => await discoverer.DiscoverDeviceAsync(PortMapper.Upnp, cts)).Result; // set nat device to ipaddr so that we can our external ip elsewhere in the application IpAddr.Set(device); // int.MaxValue so that a Session object is created internally in the lib, only session objects // are properly renewed, lib has bug (10min intervals)... _ = Task.Run(async() => await device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 18910, 18910, int.MaxValue, "sc.Nat"))); Log.NewLine("Successfully created UPnP port mapping."); } catch { Log.NewLine("Could not create UPnP port mapping. Decreased network connectivity."); } }
public void Validate() { // In order to validate we have to continuously build up the index as it was written at the time // of the block mined was added to the chain. So we clear the indexes if we have any loaded. // As an addition we also save this index when the last block got processed. ClearIndexes(); // Keep track of the blockchain size. int BcSize = Size(); for (var i = 1; i < BcSize; i++) { // Get the block to be checked Block CurrentBlock = ReadBlock(i); // Is it valid? IsValidBlock(CurrentBlock, i == 1 ? Genesis : ReadBlock(i - 1)); // If so create the indexes for that block, but save them only at the last iteration processed. CreateIndexes(CurrentBlock, i == BcSize - 1); Log.NewLine($"Block {i}/{BcSize - 1} is valid!"); } }
private void Peer_ClosedConn(object sender, EventArgs e) { Log.NewLine($"Disconnected."); }