public byte[] ReadNext() { byte[] ret = null; if (offset < FileLength) { var dataLengthBuffer = new byte[LengthBytes]; fileStream.Position = offset; fileStream.Read(dataLengthBuffer); fileStream.Flush(); offset += LengthBytes; var dataLength = ByteManipulator.GetUInt32(dataLengthBuffer); ret = new byte[dataLength]; fileStream.Position = offset; fileStream.Read(ret); fileStream.Flush(); offset += ret.Length; } return(ret); }
public Block(byte[] rlp) { var decoded = RLP.Decode(rlp); if (decoded.Count == 7 && decoded[1] != null) { Height = (int)(decoded[0] != null ? ByteManipulator.GetUInt32(decoded[0]) : 0); Timestamp = ByteManipulator.GetUInt32(decoded[1]); Difficulty = new LargeInteger(decoded[2] ?? new byte[32]); Nonce = decoded[3] != null?ByteManipulator.BigEndianTruncate(decoded[3], 32) : new byte[32]; MinerAddress = decoded[4] != null?ByteManipulator.BigEndianTruncate(decoded[4], 33) : new byte[33]; PreviousBlockHash = decoded[5] != null?ByteManipulator.BigEndianTruncate(decoded[5], 32) : new byte[32]; var decodedTransactions = RLP.Decode(decoded[6]); Transactions = new List <Transaction>(); if (decodedTransactions != null) { foreach (var rlpTransaction in decodedTransactions) { var tx = new Transaction(rlpTransaction); Transactions.Add(tx); } } } else { throw new Exception("Invalid block"); } }
private uint?GetOffset(byte[] key) { uint?ret = null; var offset = LinearDictionaryCoder.Get(key); if (offset != null) { ret = ByteManipulator.GetUInt32(offset); } return(ret); }
private void Deserialize(byte[] rlp) { var data = RLP.Decode(rlp); Nonce = ByteManipulator.GetUInt32(data[0] ?? new byte[] { 0 }); Ammount = new LargeInteger(data[1] ?? new byte[] { 0 }); Fee = new LargeInteger(data[2] ?? new byte[] { 0 }); Source = ByteManipulator.BigEndianTruncate(data[3], 33) ?? new byte[33]; Destination = ByteManipulator.BigEndianTruncate(data[4], 33) ?? new byte[33]; Signature = ByteManipulator.BigEndianTruncate(data[5], 64) ?? new byte[64]; Network = data[6] ?? new byte[] { 0 }; }
public long NextOffset(long start) { var buffer = new byte[LengthBytes]; fileStream.Position = start; fileStream.Read(buffer); fileStream.Flush(); var length = ByteManipulator.GetUInt32(buffer); return(start + length + LengthBytes); }
public uint GetTransactionCount(byte[] publicKey) { var nonceBytes = nonceCoder.Get(publicKey); uint ret = 0; if (nonceBytes != null) { ret = ByteManipulator.GetUInt32(nonceBytes) + 1; } return(ret); }
public uint GetTransactionCount(byte[] publicKey) { publicKey = ByteManipulator.BigEndianTruncate(publicKey, 33); var nonceBytes = nonceCoder.Get(publicKey); uint ret = 0; if (nonceBytes != null) { ret = ByteManipulator.GetUInt32(nonceBytes) + 1; } else { ret = 0; } return(ret); }
public void ChangeValueByOffset(long offset, byte[] value) { this.offset = offset; var dataLengthBuffer = new byte[LengthBytes]; fileStream.Position = offset; fileStream.Read(dataLengthBuffer); fileStream.Flush(); if (ByteManipulator.GetUInt32(dataLengthBuffer) != value.Length) { throw new Exception("Value length does not match data length"); } fileStream.Position = offset + LengthBytes; fileStream.Write(value); fileStream.Flush(); }
public Dictionary <byte[], Tuple <long, LargeInteger> > RewardMiner(byte[] publicKey, Direction direction, Dictionary <byte[], Tuple <long, LargeInteger> > initialDiff = null) { Dictionary <byte[], Tuple <long, LargeInteger> > ret; if (initialDiff == null) { ret = new Dictionary <byte[], Tuple <long, LargeInteger> >(new ByteArrayComparer()); } else { ret = initialDiff; } LargeInteger balance; long nonce; if (ret.ContainsKey(publicKey)) { var record = ret[publicKey]; nonce = record.Item1; balance = record.Item2; if (direction == Direction.Forward) { balance = balance + Program.MinerReward; } else { balance = balance - Program.MinerReward; } ret[publicKey] = new Tuple <long, LargeInteger>(nonce, balance); } else { var balanceBytes = balanceCoder.Get(publicKey); if (!((balanceBytes == null) && (direction == Direction.Reverse))) //balance is not found on disk and direction is reverse -> invalid reward { var newBalance = new LargeInteger(balanceBytes); if (direction == Direction.Forward) { newBalance = newBalance + Program.MinerReward; } else { newBalance = newBalance - Program.MinerReward; } if (newBalance < 0) { ret = null; } else { var nonceBytes = nonceCoder.Get(publicKey); if (nonceBytes == null) { ret.Add(publicKey, new Tuple <long, LargeInteger>(-1, newBalance)); } else { ret.Add(publicKey, new Tuple <long, LargeInteger>(ByteManipulator.GetUInt32(nonceBytes), newBalance)); } } } else { ret = null; } } return(ret); }
public Dictionary <byte[], Tuple <long, LargeInteger> > CreateDiff(List <Transaction> transactions, Direction direction, Dictionary <byte[], Tuple <long, LargeInteger> > initialDiff = null) { Dictionary <byte[], Tuple <long, LargeInteger> > ret; var nonces = new Dictionary <byte[], List <long> >(new ByteArrayComparer()); var balances = new Dictionary <byte[], LargeInteger>(new ByteArrayComparer()); if (initialDiff == null) { ret = new Dictionary <byte[], Tuple <long, LargeInteger> >(new ByteArrayComparer()); } else { ret = initialDiff; } foreach (var kvp in ret) { balances.Add(kvp.Key, kvp.Value.Item2); } foreach (var transaction in transactions) //perform transactions { if (transaction.Verify()) { if (nonces.ContainsKey(transaction.Source)) { nonces[transaction.Source].Add(transaction.Nonce); } else { nonces.Add(transaction.Source, new List <long>() { transaction.Nonce }); } byte[] sourceBalanceBytes; LargeInteger sourceBalance; LargeInteger destinationBalance; if (!balances.ContainsKey(transaction.Source)) { sourceBalanceBytes = balanceCoder.Get(transaction.Source); if (sourceBalanceBytes == null) { sourceBalanceBytes = new byte[] { 0 }; } sourceBalance = new LargeInteger(sourceBalanceBytes); balances.Add(transaction.Source, sourceBalance); } else { sourceBalance = balances[transaction.Source]; } var totalAmmount = transaction.Ammount + transaction.Fee; if (direction == Direction.Forward) { sourceBalance = sourceBalance - totalAmmount; } else { sourceBalance = sourceBalance + totalAmmount; } if (balances.ContainsKey(transaction.Destination)) { destinationBalance = balances[transaction.Destination]; if (direction == Direction.Forward) { destinationBalance += transaction.Ammount; } else { destinationBalance -= transaction.Ammount; } } else { if (balanceCoder.ContainsKey(transaction.Destination)) { destinationBalance = new LargeInteger(balanceCoder.Get(transaction.Destination)); if (direction == Direction.Forward) { destinationBalance += transaction.Ammount; } else { destinationBalance -= transaction.Ammount; } balances.Add(transaction.Destination, destinationBalance); } else if (direction == Direction.Forward) { destinationBalance = transaction.Ammount; balances.Add(transaction.Destination, destinationBalance); } else { ret = null; destinationBalance = null; } } if (ret == null || sourceBalance == null || destinationBalance == null) { ret = null; } else { balances[transaction.Source] = sourceBalance; balances[transaction.Destination] = destinationBalance; } } else { ret = null; break; } } //check balance validity if (ret != null) { foreach (var kvp in balances) { if (kvp.Value < 0) { ret = null; break; } } } //check nonce continuity if (ret != null) { foreach (var kvp in nonces) { long startNonce = 0; if (ret.ContainsKey(kvp.Key)) { startNonce = ret[kvp.Key].Item1; } else { var nonceBytes = nonceCoder.Get(kvp.Key); if (nonceBytes == null) { startNonce = -1; } else { startNonce = ByteManipulator.GetUInt32(nonceBytes); } } kvp.Value.Sort(); if (direction == Direction.Reverse) { kvp.Value.Reverse(); } var noncesCount = kvp.Value.Count; for (int i = 0; i < noncesCount; i++) { if (direction == Direction.Forward) { if ((startNonce + i + 1) != kvp.Value[i]) { ret = null; } } else { long currentNonce = startNonce - i; if (currentNonce != kvp.Value[0]) { ret = null; } else { kvp.Value.Remove(currentNonce); if (i == noncesCount - 1) { kvp.Value.Add(currentNonce - 1); } } } } if (ret == null) { break; } } } //create new diff if (ret != null) { foreach (var kvp in balances) { long nonce; long initalNonce = -1; //-1 means that nonce does not exist -> nothing will be stored on disk, it is account which only recieved payments/mining reward if (initialDiff.ContainsKey(kvp.Key)) { initalNonce = initialDiff[kvp.Key].Item1; } if (nonces.ContainsKey(kvp.Key)) { var nonceList = nonces[kvp.Key]; if (nonceList.Count == 0) { nonce = initalNonce; } else if (direction == Direction.Forward) { nonce = nonceList[nonceList.Count - 1]; } else { nonce = nonceList[0]; } } else { nonce = initalNonce; } var record = new Tuple <long, LargeInteger>(nonce, kvp.Value); if (ret.ContainsKey(kvp.Key)) { ret[kvp.Key] = record; } else { ret.Add(kvp.Key, record); } } } return(ret); }
private Tuple <string, DateTime> DecodeEntry(byte[] entry) { return(new Tuple <string, DateTime>(Encoding.UTF8.GetString(ByteManipulator.TruncateMostSignificatZeroBytes(entry.Take(entry.Length - 4).ToArray())), DateTimeOffset.FromUnixTimeSeconds(ByteManipulator.GetUInt32(entry.Skip(128).ToArray())).DateTime)); }
private static void Decode(RLPMessage msg) { var firstByte = msg.Remainder.Array[msg.Remainder.Offset]; if (firstByte == 0x80) { msg.Decoded.Add(null); msg.Remainder = msg.Remainder.Slice(1); return; } // single byte if (firstByte <= 0x7f) { msg.Decoded.Add(new byte[] { firstByte }); msg.Remainder = msg.Remainder.Slice(1); return; } // string <55 bytes if (firstByte <= 0xb7) { var itemLength = Math.Abs(128 - firstByte); var data = firstByte == 0x80 ? new ArraySegment <byte>(new byte[0]) : msg.Remainder.Slice(1, itemLength); msg.Decoded.Add(ArrayManipulator.SubArray(data.Array, data.Offset, data.Count)); msg.Remainder = msg.Remainder.Slice(data.Count + 1); return; } // string >55 bytes if (firstByte <= 0xbf) { var lengthBytesCount = Math.Abs(LargeItemOffset - firstByte); var lengthBytes = new byte[4]; var startIndex = Math.Abs(lengthBytesCount - 5) - 1; for (int i = 0; i < lengthBytesCount; i++) { lengthBytes[startIndex + i] = msg.Remainder.Array[msg.Remainder.Offset + i + 1]; } var itemLength = ByteManipulator.GetUInt32(lengthBytes); var data = msg.Remainder.Slice(lengthBytesCount + 1, (int)itemLength); msg.Decoded.Add(ArrayManipulator.SubArray(msg.Remainder.Array, data.Offset, data.Count)); msg.Remainder = msg.Remainder.Slice(data.Count + lengthBytesCount + 1); return; } // collection <55 bytes if (firstByte <= 0xf7) { var itemLength = Math.Abs(192 - firstByte); var data = msg.Remainder.Slice(1, itemLength).ToArray(); while (msg.Remainder.Offset < msg.Remainder.Array.Length) { var decoded = Decode(data); msg.Decoded.AddRange(decoded); msg.Remainder = msg.Remainder.Slice(msg.Remainder.Count); } return; } // collection >55 bytes if (firstByte <= 0xff) { var lengthBytesCount = Math.Abs(247 - firstByte); var lengthBytes = new byte[4]; var startIndex = Math.Abs(lengthBytesCount - 5) - 1; for (int i = 0; i < lengthBytesCount; i++) { lengthBytes[startIndex + i] = msg.Remainder.Array[msg.Remainder.Offset + i + 1]; } var itemLength = ByteManipulator.GetUInt32(lengthBytes); var data = msg.Remainder.Slice(lengthBytesCount + 1, (int)itemLength).ToArray(); while (msg.Remainder.Offset < msg.Remainder.Array.Length) { var decoded = Decode(data); msg.Decoded.AddRange(decoded); msg.Remainder = msg.Remainder.Slice(msg.Remainder.Count); } return; } }