Exemplo n.º 1
0
        public bool ApplyDiff(Dictionary <byte[], Tuple <long, LargeInteger> > diff)
        {
            var ret = true;

            foreach (var kvp in diff)
            {
                if (kvp.Value.Item2 < 0)
                {
                    ret = false;
                    break;
                }
            }

            if (ret)
            {
                foreach (var kvp in diff)
                {
                    //update balances
                    if (balanceCoder.ContainsKey(kvp.Key))
                    {
                        balanceCoder.Replace(kvp.Key, kvp.Value.Item2.GetBytes());
                    }
                    else
                    {
                        balanceCoder.Add(kvp.Key, kvp.Value.Item2.GetBytes());
                    }

                    //update nonces
                    if (nonceCoder.ContainsKey(kvp.Key))
                    {
                        if (kvp.Value.Item1 >= 0)
                        {
                            nonceCoder.Replace(kvp.Key, ByteManipulator.GetBytes((uint)kvp.Value.Item1));
                        }
                        else
                        {
                            nonceCoder.Remove(kvp.Key);
                        }
                    }
                    else
                    {
                        if (kvp.Value.Item1 >= 0)
                        {
                            nonceCoder.Add(kvp.Key, ByteManipulator.GetBytes((uint)kvp.Value.Item1));
                        }
                    }
                }
            }

            return(ret);
        }
Exemplo n.º 2
0
        public async Task <bool> AddContact(string url)
        {
            var ret = false;

            if (url != null)
            {
                var hostnameBytes = ToBytes(url);

                if ((hostnameBytes != null) && (url != Program.Settings.url))
                {
                    if (!coder.ContainsKey(ByteManipulator.BigEndianTruncate(hostnameBytes, 128)))
                    {
                        if (await Handshake(url))
                        {
                            coder.Add(hostnameBytes, ByteManipulator.GetBytes((uint)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds));
                            ret = true;
                        }
                    }
                }
            }

            return(ret);
        }
Exemplo n.º 3
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);
        }