예제 #1
0
        public void Submit(Transaction tx)
        {
            Throw.IfNull(tx, nameof(tx));

            var chain = Nexus.FindChainByName(tx.ChainName);

            Throw.IfNull(chain, nameof(chain));

            if (_hashMap.ContainsKey(tx.Hash))
            {
                throw new MempoolSubmissionException("already in mempool");
            }

            var currentTime = Timestamp.Now;

            if (tx.Expiration <= currentTime)
            {
                throw new MempoolSubmissionException("already expired");
            }

            var diff = tx.Expiration - currentTime;

            if (diff > MaxExpirationTimeDifferenceInSeconds)
            {
                throw new MempoolSubmissionException("expire date too big");
            }

            if (tx.NexusName != this.Nexus.Name)
            {
                throw new MempoolSubmissionException("invalid nexus name");
            }

            var entry = new MempoolEntry()
            {
                transaction = tx, timestamp = Timestamp.Now
            };

            List <MempoolEntry> list;

            lock (_entries)
            {
                if (_entries.ContainsKey(chain.Name))
                {
                    list = _entries[chain.Name];
                }
                else
                {
                    list = new List <MempoolEntry>();
                    _entries[chain.Name] = list;
                }

                list.Add(entry);
                _hashMap[tx.Hash] = chain.Name;
            }

            Interlocked.Increment(ref _size);
            OnTransactionAdded?.Invoke(tx);
        }
예제 #2
0
        public bool Submit(Transaction tx)
        {
            lock (_txMap)
            {
                var requiredPoW = (uint)CalculateCurrentPoW() + Mempool.DefaultPoW;

                if (requiredPoW > 0 && tx.Hash.GetDifficulty() < requiredPoW)
                {
                    Mempool.RejectTransaction(tx, $"should be mined with difficulty of {requiredPoW} or more");
                }

                if (_txMap.ContainsKey(tx.Hash))
                {
                    throw new MempoolSubmissionException("already in mempool");
                }

                var entry = new MempoolEntry()
                {
                    transaction = tx, timestamp = Timestamp.Now
                };
                _txMap[tx.Hash] = entry;
            }

            this.Mempool.OnTransactionAdded?.Invoke(tx.Hash);

            var lastBlockHash = Chain.GetLastBlockHash();
            var lastBlock     = Chain.GetBlockByHash(lastBlockHash);
            var lastBlockTime = lastBlock != null ? lastBlock.Timestamp : new Timestamp(0);
            var timeDiff      = TimeSpan.FromSeconds(Timestamp.Now - lastBlockTime).TotalSeconds;

            if (timeDiff >= Mempool.BlockTime / 2)
            {
                this.AwakeUp();
            }

            return(true);
        }
예제 #3
0
        public bool Submit(Transaction tx)
        {
            if (this.CurrentState != State.Running)
            {
                return(false);
            }

            Throw.IfNull(tx, nameof(tx));

            var chain = Nexus.FindChainByName(tx.ChainName);

            Throw.IfNull(chain, nameof(chain));

            if (tx.Signatures == null || tx.Signatures.Length < 1)
            {
                RejectTransaction(tx, "at least one signature required");
            }

            var currentTime = Timestamp.Now;

            if (tx.Expiration <= currentTime)
            {
                RejectTransaction(tx, "already expired");
            }

            var diff = tx.Expiration - currentTime;

            if (diff > MaxExpirationTimeDifferenceInSeconds)
            {
                RejectTransaction(tx, "expire date too big");
            }

            if (tx.NexusName != this.Nexus.Name)
            {
                RejectTransaction(tx, "invalid nexus name");
            }

            if (_hashMap.ContainsKey(tx.Hash))
            {
                throw new MempoolSubmissionException("already in mempool");
            }

            var entry = new MempoolEntry()
            {
                transaction = tx, timestamp = Timestamp.Now
            };

            List <MempoolEntry> list;

            lock (_entries)
            {
                if (_entries.ContainsKey(chain.Name))
                {
                    list = _entries[chain.Name];
                }
                else
                {
                    list = new List <MempoolEntry>();
                    _entries[chain.Name] = list;
                }

                list.Add(entry);
                _hashMap[tx.Hash] = chain.Name;
            }

            Interlocked.Increment(ref _size);
            OnTransactionAdded?.Invoke(tx);
            return(true);
        }