internal static void SaveList(List <CheckPointBlock> list, Stream stream, Stream indexStream) { List <uint> offsets = new List <uint>(); foreach (var item in list) { long pos = stream.Position; offsets.Add((uint)pos); item.SaveToStream(stream); if (item.BlockNumber % 100 == 0) { CheckPointBuilding?.Invoke(new object(), new CheckPointBuildingEventArgs { BlocksDone = (int)(item.BlockNumber), BlocksNeeded = (int)(list.Count) }); } } using (BinaryWriter bw = new BinaryWriter(indexStream, Encoding.Default, true)) { foreach (uint u in offsets) { bw.Write(u); } } }
internal static List <CheckPointBlock> BuildFromBlockChain(BlockChain blockChain) { List <CheckPointBlock> checkPoint = new List <CheckPointBlock>(blockChain.BlockHeight() + 1); uint accNumber = 0; ulong accWork = 0; for (int block = 0; block < 100 * ((blockChain.GetLastBlock().BlockNumber + 1) / 100); block++) { Block currentBlock = blockChain.Get(block); if (currentBlock == null) { var h = blockChain.GetLastBlock().BlockNumber; Block currentBlock1 = blockChain.Get((int)block); continue; } CheckPointBlock checkPointBlock = new CheckPointBlock { AccountKey = currentBlock.AccountKey }; for (int i = 0; i < 5; i++) { checkPointBlock.Accounts.Add(new Account { AccountNumber = accNumber, Balance = (i == 0 ? 1000000ul + (ulong)currentBlock.Fee : 0ul), BlockNumber = currentBlock.BlockNumber, UpdatedBlock = currentBlock.BlockNumber, NumberOfOperations = 0, AccountType = 0, Name = "", UpdatedByBlock = currentBlock.BlockNumber, AccountInfo = new AccountInfo { AccountKey = currentBlock.AccountKey, State = AccountState.Normal } }); accNumber++; } accWork += currentBlock.CompactTarget; checkPointBlock.AccumulatedWork = accWork; checkPointBlock.AvailableProtocol = currentBlock.AvailableProtocol; checkPointBlock.BlockNumber = currentBlock.BlockNumber; checkPointBlock.BlockSignature = 2; //b.BlockSignature; checkPointBlock.CheckPointHash = currentBlock.CheckPointHash; checkPointBlock.CompactTarget = currentBlock.CompactTarget; checkPointBlock.Fee = currentBlock.Fee; checkPointBlock.Nonce = currentBlock.Nonce; checkPointBlock.Payload = currentBlock.Payload; checkPointBlock.ProofOfWork = currentBlock.ProofOfWork; checkPointBlock.ProtocolVersion = currentBlock.ProtocolVersion; checkPointBlock.Reward = currentBlock.Reward; checkPointBlock.Timestamp = currentBlock.Timestamp; checkPointBlock.TransactionHash = currentBlock.TransactionHash; WorkSum += currentBlock.CompactTarget; foreach (var t in currentBlock.Transactions) { Account account; var signer = checkPoint.FirstOrDefault(p => p.Accounts.Count(a => a.AccountNumber == t.SignerAccount) > 0); var target = checkPoint.FirstOrDefault(p => p.Accounts.Count(a => a.AccountNumber == t.TargetAccount) > 0); if (t.Fee != 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } switch (t.TransactionType) { case TransactionType.Transaction: TransferTransaction transfer = (TransferTransaction)t; if (signer != null && target != null) { if (t.Fee == 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).Balance -= (transfer.Fee + transfer.Amount); target.Accounts.First(p => p.AccountNumber == t.TargetAccount).Balance += transfer.Amount; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).UpdatedBlock = currentBlock.BlockNumber; target.Accounts.First(p => p.AccountNumber == t.TargetAccount).UpdatedBlock = currentBlock.BlockNumber; } break; case TransactionType.BuyAccount: TransferTransaction transferTransaction = (TransferTransaction)t; // TODO: be kell fejezni if (t.Fee == 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).Balance -= (transferTransaction.Fee + transferTransaction.Amount); CheckPointBlock seller = checkPoint.FirstOrDefault(p => p.Accounts.Count(a => a.AccountNumber == transferTransaction.SellerAccount) > 0); seller.Accounts.First(p => p.AccountNumber == transferTransaction.SellerAccount).Balance += transferTransaction.Amount; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).UpdatedBlock = currentBlock.BlockNumber; target.Accounts.First(p => p.AccountNumber == t.TargetAccount).UpdatedBlock = currentBlock.BlockNumber; seller.Accounts.First(p => p.AccountNumber == transferTransaction.SellerAccount) .UpdatedBlock = currentBlock.BlockNumber; account = target.Accounts.First(p => p.AccountNumber == t.TargetAccount); account.AccountInfo.AccountKey = transferTransaction.NewAccountKey; account.AccountInfo.Price = 0; account.AccountInfo.LockedUntilBlock = 0; account.AccountInfo.State = AccountState.Normal; account.AccountInfo.AccountToPayPrice = 0; account.AccountInfo.NewPublicKey = null; break; case TransactionType.DeListAccountForSale: case TransactionType.ListAccountForSale: ListAccountTransaction listAccountTransaction = (ListAccountTransaction)t; account = target.Accounts.First(p => p.AccountNumber == t.TargetAccount); signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).Balance -= listAccountTransaction.Fee; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).UpdatedBlock = currentBlock.BlockNumber; target.Accounts.First(p => p.AccountNumber == t.TargetAccount).UpdatedBlock = currentBlock.BlockNumber; if (t.Fee == 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } if (listAccountTransaction.TransactionType == TransactionType.ListAccountForSale) { account.AccountInfo.Price = listAccountTransaction.AccountPrice; account.AccountInfo.LockedUntilBlock = listAccountTransaction.LockedUntilBlock; account.AccountInfo.State = AccountState.Sale; account.AccountInfo.Price = listAccountTransaction.AccountPrice; account.AccountInfo.NewPublicKey = listAccountTransaction.NewPublicKey; account.AccountInfo.AccountToPayPrice = listAccountTransaction.AccountToPay; } else { account.AccountInfo.State = AccountState.Normal; account.AccountInfo.Price = 0; account.AccountInfo.NewPublicKey = null; account.AccountInfo.LockedUntilBlock = 0; account.AccountInfo.AccountToPayPrice = 0; } break; case TransactionType.ChangeAccountInfo: ChangeAccountInfoTransaction changeAccountInfoTransaction = (ChangeAccountInfoTransaction)t; account = target.Accounts.First(p => p.AccountNumber == t.TargetAccount); if ((changeAccountInfoTransaction.ChangeType & 1) == 1) { account.AccountInfo.AccountKey = changeAccountInfoTransaction.NewAccountKey; } if ((changeAccountInfoTransaction.ChangeType & 4) == 4) { account.AccountType = changeAccountInfoTransaction.NewType; } if ((changeAccountInfoTransaction.ChangeType & 2) == 2) { account.Name = changeAccountInfoTransaction.NewName; } signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).Balance -= changeAccountInfoTransaction.Fee; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).UpdatedBlock = currentBlock.BlockNumber; account.UpdatedBlock = currentBlock.BlockNumber; if (t.Fee == 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } break; case TransactionType.ChangeKey: case TransactionType.ChangeKeySigned: ChangeKeyTransaction changeKeyTransaction = (ChangeKeyTransaction)t; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).Balance -= changeKeyTransaction.Fee; account = target.Accounts.First(p => p.AccountNumber == t.TargetAccount); account.AccountInfo.AccountKey = changeKeyTransaction.NewAccountKey; account.UpdatedBlock = currentBlock.BlockNumber; signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).UpdatedBlock = currentBlock.BlockNumber; if (t.Fee == 0) { signer.Accounts.First(p => p.AccountNumber == t.SignerAccount).NumberOfOperations++; } break; } } checkPoint.Add(checkPointBlock); if (block % 100 == 0) { CheckPointBuilding?.Invoke(new object(), new CheckPointBuildingEventArgs { BlocksDone = block, BlocksNeeded = (int)(100 * ((blockChain.GetLastBlock().BlockNumber + 1) / 100)) * 2 }); } } foreach (var p in checkPoint) { p.BlockHash = p.CalculateBlockHash(); if (p.BlockNumber % 100 == 0) { CheckPointBuilding?.Invoke(new object(), new CheckPointBuildingEventArgs { BlocksDone = (int)(p.BlockNumber + checkPoint.Count), BlocksNeeded = (int)(checkPoint.Count * 2) }); } } return(checkPoint); }