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); }
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); }
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); }