コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: Block.cs プロジェクト: Simonzicek/pancoin-wallet
        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");
            }
        }
コード例 #3
0
        private uint?GetOffset(byte[] key)
        {
            uint?ret    = null;
            var  offset = LinearDictionaryCoder.Get(key);

            if (offset != null)
            {
                ret = ByteManipulator.GetUInt32(offset);
            }

            return(ret);
        }
コード例 #4
0
        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 };
        }
コード例 #5
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);
        }
コード例 #6
0
        public uint GetTransactionCount(byte[] publicKey)
        {
            var nonceBytes = nonceCoder.Get(publicKey);

            uint ret = 0;

            if (nonceBytes != null)
            {
                ret = ByteManipulator.GetUInt32(nonceBytes) + 1;
            }

            return(ret);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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();
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
 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));
 }
コード例 #12
0
        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;
            }
        }