public long DataGasCost(ReadOnlyMemory <byte> inputData, IReleaseSpec releaseSpec) { try { Span <byte> extendedInput = stackalloc byte[96]; inputData.Slice(0, Math.Min(96, inputData.Length)).Span .CopyTo(extendedInput.Slice(0, Math.Min(96, inputData.Length))); UInt256 baseLength = new(extendedInput.Slice(0, 32), true); UInt256 expLength = new(extendedInput.Slice(32, 32), true); UInt256 modulusLength = new(extendedInput.Slice(64, 32), true); UInt256 complexity = MultComplexity(UInt256.Max(baseLength, modulusLength)); byte[] expSignificantBytes = inputData.Span.SliceWithZeroPaddingEmptyOnError(96 + (int)baseLength, (int)UInt256.Min(expLength, 32)); UInt256 lengthOver32 = expLength <= 32 ? 0 : expLength - 32; UInt256 adjusted = AdjustedExponentLength(lengthOver32, expSignificantBytes); UInt256 gas = complexity * UInt256.Max(adjusted, UInt256.One) / 20; return(gas > long.MaxValue ? long.MaxValue : (long)gas); } catch (OverflowException) { return(long.MaxValue); } }
protected virtual Block PrepareBlock(BlockHeader parent) { UInt256 timestamp = UInt256.Max(parent.Timestamp + 1, _timestamper.UnixTime.Seconds); UInt256 difficulty = CalculateDifficulty(parent, timestamp); BlockHeader header = new BlockHeader( parent.Hash, Keccak.OfAnEmptySequenceRlp, _sealer.Address, difficulty, parent.Number + 1, _gasLimitCalculator.GetGasLimit(parent), timestamp, Encoding.UTF8.GetBytes("Nethermind")) { TotalDifficulty = parent.TotalDifficulty + difficulty, Author = _sealer.Address }; if (Logger.IsDebug) { Logger.Debug($"Setting total difficulty to {parent.TotalDifficulty} + {difficulty}."); } var transactions = _txSource.GetTransactions(parent, header.GasLimit); Block block = new Block(header, transactions, Array.Empty <BlockHeader>()); header.TxRoot = new TxTrie(block.Transactions).RootHash; return(block); }
/// <summary> /// def calculate_iteration_count(exponent_length, exponent): /// iteration_count = 0 /// if exponent_length <= 32 and exponent == 0: iteration_count = 0 /// elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 /// elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) /// return max(iteration_count, 1) /// </summary> /// <param name="exponentLength"></param> /// <param name="exponent"></param> /// <returns></returns> private static UInt256 CalculateIterationCount(UInt256 exponentLength, UInt256 exponent) { try { UInt256 iterationCount; if (exponentLength <= 32) { if (!exponent.IsZero) { iterationCount = (UInt256)(exponent.BitLen - 1); } else { iterationCount = UInt256.Zero; } } else { int bitLength = (exponent & UInt256.MaxValue).BitLen; if (bitLength > 0) { bitLength--; } iterationCount = 8 * (exponentLength - 32) + (UInt256)bitLength; } return(UInt256.Max(iterationCount, UInt256.One)); } catch (OverflowException) { return(UInt256.MaxValue); } }
protected virtual Block PrepareBlock(BlockHeader parent) { UInt256 timestamp = _timestamper.EpochSeconds; UInt256 difficulty = CalculateDifficulty(parent, timestamp); BlockHeader header = new BlockHeader( parent.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, difficulty, parent.Number + 1, GetGasLimit(parent), UInt256.Max(parent.Timestamp + 1, _timestamper.EpochSeconds), Encoding.UTF8.GetBytes("Nethermind")) { TotalDifficulty = parent.TotalDifficulty + difficulty }; if (Logger.IsDebug) { Logger.Debug($"Setting total difficulty to {parent.TotalDifficulty} + {difficulty}."); } var transactions = _txSource.GetTransactions(parent, header.GasLimit); Block block = new Block(header, transactions, new BlockHeader[0]); header.TxRoot = new TxTrie(block.Transactions).RootHash; return(block); }
public BlockchainBridge.CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { ReadOnlyTxProcessingEnv txProcessingEnv = new(_dbProvider, _trieStore, _blockTree, _specProvider, _logManager); ITransactionProcessor transactionProcessor = txProcessingEnv.Build(_stateProvider.StateRoot); EstimateGasTracer estimateGasTracer = new(); (bool Success, string Error)tryCallResult = TryCallAndRestore( transactionProcessor, txProcessingEnv, header, UInt256.Max(header.Timestamp + 1, _timestamper.UnixTime.Seconds), tx, true, estimateGasTracer.WithCancellation(cancellationToken)); GasEstimator gasEstimator = new(transactionProcessor, _stateProvider, _specProvider); long estimate = gasEstimator.Estimate(tx, header, estimateGasTracer); return(new BlockchainBridge.CallOutput { Error = tryCallResult.Success ? estimateGasTracer.Error : tryCallResult.Error, GasSpent = estimate, InputError = !tryCallResult.Success }); }
public ValueTask <Keccak> SendTransaction(Transaction tx, TxHandlingOptions txHandlingOptions) { UInt256 minGasPrice = CurrentMinGasPrice(); UInt256 txGasPrice = minGasPrice * _percentDelta / 100; tx.GasPrice = UInt256.Max(txGasPrice, _miningConfig.MinGasPrice); return(_txSender.SendTransaction(tx, txHandlingOptions)); }
/// <summary> /// def calculate_multiplication_complexity(base_length, modulus_length): /// max_length = max(base_length, modulus_length) /// words = math.ceil(max_length / 8) /// return words**2 /// </summary> /// <returns></returns> private static UInt256 MultComplexity(UInt256 baseLength, UInt256 modulusLength) { UInt256 maxLength = UInt256.Max(baseLength, modulusLength); UInt256.Mod(maxLength, 8, out UInt256 mod8); UInt256 words = (maxLength / 8) + ((mod8.IsZero) ? UInt256.Zero : UInt256.One); return(words * words); }
public CallOutput EstimateGas(BlockHeader header, Transaction tx) { EstimateGasTracer estimateGasTracer = new EstimateGasTracer(_cancellationToken); CallAndRestore(header, tx, UInt256.Max(header.Timestamp + 1, _timestamper.EpochSeconds), estimateGasTracer); long estimate = estimateGasTracer.CalculateEstimate(tx); return(new CallOutput { Error = estimateGasTracer.Error, GasSpent = estimate }); }
public ValueTask <Keccak> SendTransaction(Transaction tx, TxHandlingOptions txHandlingOptions) { (UInt256 minFeeCap, UInt256 minGasPremium) = CurrentMinGas(); UInt256 txFeeCap = minFeeCap * _percentDelta / 100; UInt256 txGasPremium = minGasPremium * _percentDelta / 100; tx.DecodedFeeCap = UInt256.Max(txFeeCap, _miningConfig.MinGasPrice); tx.GasPrice = txGasPremium; tx.Type = TxType.EIP1559; return(_txSender.SendTransaction(tx, txHandlingOptions)); }
public void HintBlock(Keccak hash, UInt256 number, NodeId receivedFrom) { if (!_peers.TryGetValue(receivedFrom, out PeerInfo peerInfo)) { if (_logger.IsTrace) { _logger.Trace($"Received a block hint from an unknown peer {receivedFrom}, ignoring"); } return; } peerInfo.NumberAvailable = UInt256.Max(number, peerInfo.NumberAvailable); }
public static UInt256 CalculateBaseFee(BlockHeader parent, IReleaseSpec spec) { UInt256 expectedBaseFee = UInt256.Zero; if (spec.IsEip1559Enabled) { UInt256 parentBaseFee = parent.BaseFee; long gasDelta; UInt256 feeDelta; long parentGasTarget = parent.GasLimit; // # check if the base fee is correct // if parent_gas_used == parent_gas_target: // expected_base_fee = parent_base_fee // elif parent_gas_used > parent_gas_target: // gas_delta = parent_gas_used - parent_gas_target // fee_delta = max(parent_base_fee * gas_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1) // expected_base_fee = parent_base_fee + fee_delta // else: // gas_delta = parent_gas_target - parent_gas_used // fee_delta = parent_base_fee * gas_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR // expected_base_fee = parent_base_fee - fee_delta // assert expected_base_fee == block.base_fee, 'invalid block: base fee not correct' if (parent.GasUsed == parentGasTarget) { expectedBaseFee = parent.BaseFee; } else if (parent.GasUsed > parentGasTarget) { gasDelta = parent.GasUsed - parentGasTarget; feeDelta = UInt256.Max( parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / BaseFeeMaxChangeDenominator, UInt256.One); expectedBaseFee = parentBaseFee + feeDelta; } else { gasDelta = parentGasTarget - parent.GasUsed; feeDelta = parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / BaseFeeMaxChangeDenominator; expectedBaseFee = parentBaseFee - feeDelta; } if (spec.Eip1559TransitionBlock == parent.Number + 1) { expectedBaseFee = 1.GWei(); } } return(expectedBaseFee); }
public static UInt256 Calculate(BlockHeader parent, IReleaseSpec spec) { UInt256 expectedBaseFee = parent.BaseFeePerGas; if (spec.IsEip1559Enabled) { UInt256 parentBaseFee = parent.BaseFeePerGas; long gasDelta; UInt256 feeDelta; bool isForkBlockNumber = spec.Eip1559TransitionBlock == parent.Number + 1; long parentGasTarget = parent.GasLimit / Eip1559Constants.ElasticityMultiplier; if (isForkBlockNumber) { parentGasTarget = parent.GasLimit; } if (parent.GasUsed == parentGasTarget) { expectedBaseFee = parent.BaseFeePerGas; } else if (parent.GasUsed > parentGasTarget) { gasDelta = parent.GasUsed - parentGasTarget; feeDelta = UInt256.Max( parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / Eip1559Constants.BaseFeeMaxChangeDenominator, UInt256.One); expectedBaseFee = parentBaseFee + feeDelta; } else { gasDelta = parentGasTarget - parent.GasUsed; feeDelta = parentBaseFee * (UInt256)gasDelta / (UInt256)parentGasTarget / Eip1559Constants.BaseFeeMaxChangeDenominator; expectedBaseFee = UInt256.Max(parentBaseFee - feeDelta, 0); } if (isForkBlockNumber) { expectedBaseFee = Eip1559Constants.ForkBaseFee; } if (spec.Eip1559BaseFeeMinValue.HasValue) { expectedBaseFee = UInt256.Max(expectedBaseFee, spec.Eip1559BaseFeeMinValue.Value); } } return(expectedBaseFee); }
protected override UInt256 CalculateDifficulty(BlockHeader parent, UInt256 timestamp) { UInt256 difficulty; if (_miningConfig.RandomizedBlocks) { UInt256 change = new UInt256((ulong)(_random.Next(100) + 50)); difficulty = UInt256.Max(1000, UInt256.Max(parent.Difficulty, 1000) / 100 * change); } else { difficulty = UInt256.One; } return(difficulty); }
public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { EstimateGasTracer estimateGasTracer = new EstimateGasTracer(); CallAndRestore( header, header.Number + 1, UInt256.Max(header.Timestamp + 1, _timestamper.UnixTime.Seconds), tx, estimateGasTracer.WithCancellation(cancellationToken)); long estimate = estimateGasTracer.CalculateEstimate(tx); return(new CallOutput { Error = estimateGasTracer.Error, GasSpent = estimate }); }
public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { EstimateGasTracer estimateGasTracer = new(); (bool Success, string Error)tryCallResult = TryCallAndRestore( header, header.Number + 1, UInt256.Max(header.Timestamp + 1, _timestamper.UnixTime.Seconds), tx, estimateGasTracer.WithCancellation(cancellationToken)); long estimate = estimateGasTracer.CalculateEstimate(tx); return(new CallOutput { Error = tryCallResult.Success ? estimateGasTracer.Error : tryCallResult.Error, GasSpent = estimate, InputError = !tryCallResult.Success }); }
/// <summary> /// def calculate_iteration_count(exponent_length, exponent): /// iteration_count = 0 /// if exponent_length <= 32 and exponent == 0: iteration_count = 0 /// elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 /// elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) /// return max(iteration_count, 1) /// </summary> /// <param name="exponentLength"></param> /// <param name="exponent"></param> /// <returns></returns> private static UInt256 CalculateIterationCount(int exponentLength, UInt256 exponent) { UInt256 iterationCount = UInt256.Zero; if (exponentLength <= 32) { if (exponent != 0) { iterationCount = (UInt256)(exponent.BitLen - 1); } } else { iterationCount = (UInt256)(8 * (exponentLength - 32)) + (UInt256)((exponent & UInt256.MaxValue).BitLen - 1); } return(UInt256.Max(iterationCount, UInt256.One)); }
public CallOutput EstimateGas(BlockHeader header, Transaction tx, CancellationToken cancellationToken) { EstimateGasTracer estimateGasTracer = new(); (bool Success, string Error)tryCallResult = TryCallAndRestore( header, UInt256.Max(header.Timestamp + 1, _timestamper.UnixTime.Seconds), tx, true, estimateGasTracer.WithCancellation(cancellationToken)); GasEstimator gasEstimator = new(_transactionProcessor, _stateProvider, _specProvider); long estimate = gasEstimator.Estimate(tx, header, estimateGasTracer); return(new CallOutput { Error = tryCallResult.Success ? estimateGasTracer.Error : tryCallResult.Error, GasSpent = estimate, InputError = !tryCallResult.Success }); }
public void AddNewBlock(Block block, NodeId receivedFrom) { // TODO: validation _peers.TryGetValue(receivedFrom, out PeerInfo peerInfo); if (peerInfo == null) { string errorMessage = $"Received a new block from an unknown peer {receivedFrom}"; _logger.Error(errorMessage); return; } peerInfo.NumberAvailable = UInt256.Max(block.Number, peerInfo.NumberAvailable); // peerInfo.Difficulty = UInt256.Max(block.Difficulty, peerInfo.Difficulty); lock (_isSyncingLock) { if (_isSyncing) { if (_logger.IsTrace) { _logger.Trace($"Ignoring new block {block.Hash} while syncing"); } return; } } if (_logger.IsTrace) { _logger.Trace($"Adding new block {block.Hash} ({block.Number}) from {receivedFrom}"); } if (block.Number <= _blockTree.BestSuggested.Number + 1) { if (_logger.IsTrace) { _logger.Trace($"Suggesting a block {block.Hash} ({block.Number}) from {receivedFrom} with {block.Transactions.Length} transactions"); } if (_logger.IsTrace) { _logger.Trace($"{block}"); } AddBlockResult result = _blockTree.SuggestBlock(block); if (_logger.IsInfo) { _logger.Info($"{block.Hash} ({block.Number}) adding result is {result}"); } if (result == AddBlockResult.UnknownParent) { /* here we want to cover scenario when our peer is reorganizing and sends us a head block * from a new branch and we need to sync previous blocks as we do not know this block's parent */ RequestSync(); } else { peerInfo.NumberReceived = block.Number; } } else { if (_logger.IsTrace) { _logger.Trace($"Received a block {block.Hash} ({block.Number}) from {receivedFrom} - need to resync"); } RequestSync(); } }
// [DataRow(uint.MaxValue, uint.MaxValue)] // [DataRow(ulong.MaxValue, ulong.MaxValue)] public void UInt256Test(ulong factorMax, ulong modulusMax) { var random = new MersenneTwister(0).Create <ulong>(); for (int i = 0; i < 10000; i++) { var n = random.Next(modulusMax - 1) + 1; var a = random.Next(factorMax) % n; var b = random.Next(factorMax) % n; var c = random.Next(factorMax) % n; var d = random.Next(factorMax) % n; var s = (int)(b % 32); var value = (UInt256)0; Assert.AreEqual((BigInteger)a << s, (UInt256)a << s); Assert.AreEqual((BigInteger)a >> s, (UInt256)a >> s); Assert.AreEqual((BigInteger)a & b, (UInt256)a & b); Assert.AreEqual((BigInteger)a & b, a & (UInt256)b); Assert.AreEqual((BigInteger)a & b, (UInt256)a & (UInt256)b); Assert.AreEqual((BigInteger)a | b, (UInt256)a | b); Assert.AreEqual((BigInteger)a | b, a | (UInt256)b); Assert.AreEqual((BigInteger)a | b, (UInt256)a | (UInt256)b); Assert.AreEqual((BigInteger)a ^ b, (UInt256)a ^ b); Assert.AreEqual((BigInteger)a ^ b, a ^ (UInt256)b); Assert.AreEqual((BigInteger)a ^ b, (UInt256)a ^ (UInt256)b); if (a <= long.MaxValue) { Assert.AreEqual(~(BigInteger)a, (long)~(UInt256)a); } Assert.AreEqual((BigInteger)a + b, (UInt256)a + b); Assert.AreEqual((BigInteger)a + b, a + (UInt256)b); Assert.AreEqual((BigInteger)a + b, (UInt256)a + (UInt256)b); Assert.AreEqual(((BigInteger)a * n + (BigInteger)b * n) % ((BigInteger)1 << 128), (UInt256)a * n + (UInt256)b * n); if (a >= b) { Assert.AreEqual((BigInteger)a - b, (UInt256)a - b); Assert.AreEqual((BigInteger)a - b, a - (UInt256)b); Assert.AreEqual((BigInteger)a - b, (UInt256)a - (UInt256)b); Assert.AreEqual((BigInteger)a * n - (BigInteger)b * n, (UInt256)a * n - (UInt256)b * n); } Assert.AreEqual(+(BigInteger)a, +(Int128)a); value = a; Assert.AreEqual((BigInteger)a + 1, ++value); value = a; Assert.AreEqual((BigInteger)a, value++); value = (UInt256)a * b; Assert.AreEqual((BigInteger)a * b + 1, ++value); value = (UInt256)a * b; Assert.AreEqual((BigInteger)a * b, value++); if (a > 0) { value = a; Assert.AreEqual((BigInteger)a - 1, --value); value = a; Assert.AreEqual((BigInteger)a, value--); } if (a > 0 && b > 0) { value = (UInt256)a * b; Assert.AreEqual((BigInteger)a * b - 1, --value); value = (UInt256)a * b; Assert.AreEqual((BigInteger)a * b, value--); } if (n <= uint.MaxValue) { Assert.AreEqual((BigInteger)a * n, (UInt256)a * (uint)n); Assert.AreEqual((BigInteger)b * n, (UInt256)b * (uint)n); Assert.AreEqual((BigInteger)a * b * n % ((BigInteger)1 << 128), (UInt256)a * b * (uint)n); Assert.AreEqual((BigInteger)n * a, (uint)n * (UInt256)a); Assert.AreEqual((BigInteger)n * b, (uint)n * (UInt256)b); Assert.AreEqual((BigInteger)n * a * b % ((BigInteger)1 << 128), (uint)n * ((UInt256)a * (UInt256)b)); } Assert.AreEqual((BigInteger)a * b, a * (UInt256)b); Assert.AreEqual((BigInteger)a * b, (UInt256)a * b); Assert.AreEqual((BigInteger)a * b, a * (UInt256)b); Assert.AreEqual((BigInteger)a * b, (UInt256)a * (UInt256)b); if (b > 0) { Assert.AreEqual((BigInteger)a % b, (UInt256)a % b); Assert.AreEqual((BigInteger)a % b, a % (UInt256)b); Assert.AreEqual((BigInteger)a % b, (UInt256)a % (UInt256)b); } Assert.AreEqual((BigInteger)a * b % n, (UInt256)a * b % n); Assert.AreEqual((BigInteger)a * b % n, a * (UInt256)b % n); Assert.AreEqual((BigInteger)a * b % n, (UInt256)a * (UInt256)b % (UInt256)n); if (c > 0 && d > 0) { Assert.AreEqual((BigInteger)a * b / ((BigInteger)c * d), (UInt256)a * (UInt256)b / ((UInt256)c * (UInt256)d)); Assert.AreEqual((BigInteger)a * b % ((BigInteger)c * d), (UInt256)a * (UInt256)b % ((UInt256)c * (UInt256)d)); } if (b > 0) { Assert.AreEqual((BigInteger)a / b, (UInt256)a / b); Assert.AreEqual((BigInteger)a / b, a / (UInt256)b); Assert.AreEqual((BigInteger)a / b, (UInt256)a / (UInt256)b); } Assert.AreEqual((BigInteger)a * b / n, (UInt256)a * b / n); Assert.AreEqual((BigInteger)a * b / n, a * (UInt256)b / n); Assert.AreEqual((BigInteger)a * b / n, (UInt256)a * (UInt256)b / (UInt256)n); Assert.AreEqual((BigInteger)a < b, (UInt256)a < b); Assert.AreEqual((BigInteger)a < b, a < (UInt256)b); Assert.AreEqual((BigInteger)a < b, (UInt256)a < (UInt256)b); Assert.AreEqual((BigInteger)a <= b, (UInt256)a <= b); Assert.AreEqual((BigInteger)a <= b, a <= (UInt256)b); Assert.AreEqual((BigInteger)a <= b, (UInt256)a <= (UInt256)b); Assert.AreEqual((BigInteger)a > b, (UInt256)a > b); Assert.AreEqual((BigInteger)a > b, a > (UInt256)b); Assert.AreEqual((BigInteger)a > b, (UInt256)a > (UInt256)b); Assert.AreEqual((BigInteger)a >= b, (UInt256)a >= b); Assert.AreEqual((BigInteger)a >= b, a >= (UInt256)b); Assert.AreEqual((BigInteger)a >= b, (UInt256)a >= (UInt256)b); Assert.AreEqual((BigInteger)a == b, (UInt256)a == b); Assert.AreEqual((BigInteger)a == b, a == (UInt256)b); Assert.AreEqual((BigInteger)a == b, (UInt256)a == (UInt256)b); Assert.AreEqual((BigInteger)a != b, (UInt256)a != b); Assert.AreEqual((BigInteger)a != b, a != (UInt256)b); Assert.AreEqual((BigInteger)a != b, (UInt256)a != (UInt256)b); Assert.AreEqual((BigInteger)a * a, UInt256.Square(a)); Assert.AreEqual(BigInteger.Abs(a), UInt256.Abs(a)); Assert.AreEqual(BigInteger.Abs((BigInteger)a * b), UInt256.Abs((UInt256)a * b)); Assert.AreEqual(BigInteger.Min(a, b), UInt256.Min(a, b)); Assert.AreEqual(BigInteger.Min((BigInteger)a * n, (BigInteger)b * n), UInt256.Min((UInt256)a * n, (UInt256)b * n)); Assert.AreEqual(BigInteger.Max(a, b), UInt256.Max(a, b)); Assert.AreEqual(BigInteger.Max((BigInteger)a * n, (BigInteger)b * n), UInt256.Max((UInt256)a * n, (UInt256)b * n)); for (var j = 0; j < 2; j++) { var m = UInt256.Abs(j == 0 ? (UInt256)a * (UInt256)b : (UInt256)n * (UInt256)n); var floorsqrt = UInt256.FloorSqrt(m); Assert.IsTrue((BigInteger)floorsqrt * floorsqrt <= m && (BigInteger)(floorsqrt + 1) * (floorsqrt + 1) > m); var ceilingsqrt = UInt256.CeilingSqrt(m); Assert.IsTrue((BigInteger)(ceilingsqrt - 1) * (ceilingsqrt - 1) < m && (BigInteger)ceilingsqrt * ceilingsqrt >= m); } for (var j = 0; j < 2; j++) { var m = j == 0 ? (UInt256)a * (UInt256)b : (UInt256)BigInteger.Pow((BigInteger)Math.Floor(Math.Pow((double)((BigInteger)a * b), (double)1 / 3)), 3); var floorcbrt = UInt256.FloorCbrt(m); Assert.IsTrue((BigInteger)floorcbrt * floorcbrt * floorcbrt <= m && (BigInteger)(floorcbrt + 1) * (floorcbrt + 1) * (floorcbrt + 1) > m); var ceilingcbrt = UInt256.CeilingCbrt(m); Assert.IsTrue((BigInteger)(ceilingcbrt - 1) * (ceilingcbrt - 1) * (ceilingcbrt - 1) < m && (BigInteger)ceilingcbrt * ceilingcbrt * ceilingcbrt >= m); } Assert.AreEqual(BigInteger.GreatestCommonDivisor((BigInteger)a, (BigInteger)b), UInt256.GreatestCommonDivisor((UInt256)a, (UInt256)b)); Assert.AreEqual(BigInteger.GreatestCommonDivisor((BigInteger)a * b, (BigInteger)c * d), UInt256.GreatestCommonDivisor((UInt256)a * b, (UInt256)c * d)); Assert.AreEqual(0, 0); } }
public byte[]? this[byte[] key] { get { lock (_diffLock) { RequiredPeerDifficulty = UInt256.Max(RequiredPeerDifficulty, BeamSyncContext.MinimumDifficulty.Value); } // it is not possible for the item to be requested from the DB and missing in the DB unless the DB is corrupted // if it is missing in the MemDb then it must exist somewhere on the web (unless the block is corrupted / invalid) // we grab the node from the web through requests // if the block is invalid then we will be timing out for a long time // in such case it would be good to have some gossip about corrupted blocks // but such gossip would be cheap // if we keep timing out then we would finally reject the block (but only shelve it instead of marking invalid) bool wasInDb = true; while (true) { if (_isDisposed) { throw new ObjectDisposedException("Beam Sync DB disposed"); } // shall I leave test logic forever? if (BeamSyncContext.LoopIterationsToFailInTest.Value != null) { int?currentValue = BeamSyncContext.LoopIterationsToFailInTest.Value--; if (currentValue == 0) { throw new Exception(); } } byte[]? fromMem = _tempDb[key] ?? _stateDb[key]; if (fromMem == null) { if (_logger.IsTrace) { _logger.Trace($"Beam sync miss - {key.ToHexString()} - retrieving"); } if (BeamSyncContext.Cancelled.Value.IsCancellationRequested) { throw new BeamCanceledException("Beam cancellation requested"); } if (Bytes.AreEqual(key, Keccak.Zero.Bytes)) { // we store sync progress data at Keccak.Zero; return(null); } TimeSpan expiry = _contextExpiryTimeSpan; if (BeamSyncContext.Description.Value?.Contains("preProcess") ?? false) { expiry = _preProcessExpiryTimeSpan; } if (DateTime.UtcNow - (BeamSyncContext.LastFetchUtc.Value ?? DateTime.UtcNow) > expiry) { string message = $"Beam sync request {BeamSyncContext.Description.Value} for key {key.ToHexString()} with last update on {BeamSyncContext.LastFetchUtc.Value:hh:mm:ss.fff} has expired"; if (_logger.IsDebug) { _logger.Debug(message); } throw new BeamSyncException(message); } wasInDb = false; // _logger.Info($"BEAM SYNC Asking for {key.ToHexString()} - resolved keys so far {_resolvedKeysCount}"); lock (_requestedNodes) { _requestedNodes.Add(new Keccak(key)); } // _logger.Error($"Requested {key.ToHexString()}"); Activate(); _autoReset.WaitOne(50); } else { if (!wasInDb) { BeamSyncContext.ResolvedInContext.Value++; Interlocked.Increment(ref Metrics.BeamedTrieNodes); if (_logger.IsDebug) { _logger.Debug( $"Resolved key {key.ToHexString()} of context {BeamSyncContext.Description.Value} - resolved ctx {BeamSyncContext.ResolvedInContext.Value} | total {Metrics.BeamedTrieNodes}"); } } else { if (VerifiedModeEnabled && !Bytes.AreEqual(Keccak.Compute(fromMem).Bytes, key)) { if (_logger.IsWarn) { _logger.Warn($"DB had an entry with a hash mismatch {key.ToHexString()} vs {Keccak.Compute(fromMem).Bytes.ToHexString()}"); } _tempDb[key] = null; _stateDb[key] = null; continue; } } BeamSyncContext.LastFetchUtc.Value = DateTime.UtcNow; return(fromMem); } } } set { if (_logger.IsTrace) { _logger.Trace($"Saving to temp - {key.ToHexString()}"); } _targetDbForSaves[key] = value; } }
public byte[] this[byte[] key] { get { lock (_diffLock) { RequiredPeerDifficulty = UInt256.Max(RequiredPeerDifficulty, BeamSyncContext.MinimumDifficulty.Value); } // it is not possible for the item to be requested from the DB and missing in the DB unless the DB is corrupted // if it is missing in the MemDb then it must exist somewhere on the web (unless the block is corrupted / invalid) // we grab the node from the web through requests // if the block is invalid then we will be timing out for a long time // in such case it would be good to have some gossip about corrupted blocks // but such gossip would be cheap // if we keep timing out then we would finally reject the block (but only shelve it instead of marking invalid) bool wasInDb = true; while (true) { if (BeamSyncContext.Cancelled.Value.IsCancellationRequested) { throw new TaskCanceledException("Beam Sync task cancelled by a new block."); } if (_isDisposed) { throw new ObjectDisposedException("Beam Sync DB disposed"); } // shall I leave test logic forever? if (BeamSyncContext.LoopIterationsToFailInTest.Value != null) { int?currentValue = BeamSyncContext.LoopIterationsToFailInTest.Value--; if (currentValue == 0) { throw new Exception(); } } var fromMem = _db[key]; if (fromMem == null) { if (Bytes.AreEqual(key, Keccak.Zero.Bytes)) { // we store sync progress data at Keccak.Zero; return(null); } TimeSpan expiry = _contextExpiryTimeSpan; if (BeamSyncContext.Description.Value?.Contains("preProcess") ?? false) { expiry = _preProcessExpiryTimeSpan; } if (DateTime.UtcNow - (BeamSyncContext.LastFetchUtc.Value ?? DateTime.UtcNow) > expiry) { string message = $"Beam sync request {BeamSyncContext.Description.Value} with last update on {BeamSyncContext.LastFetchUtc.Value:hh:mm:ss.fff} has expired"; if (_logger.IsDebug) { _logger.Debug(message); } throw new BeamSyncException(message); } wasInDb = false; // _logger.Info($"BEAM SYNC Asking for {key.ToHexString()} - resolved keys so far {_resolvedKeysCount}"); int count; lock (_requestedNodes) { _requestedNodes.Add(new Keccak(key)); count = _requestedNodes.Count; } // _logger.Error($"Requested {key.ToHexString()}"); NeedMoreData?.Invoke(this, EventArgs.Empty); _autoReset.WaitOne(50); } else { if (!wasInDb) { BeamSyncContext.ResolvedInContext.Value++; Interlocked.Increment(ref _resolvedKeysCount); // if (_logger.IsInfo) _logger.Info($"{_description} Resolved key {key.ToHexString()} of context {BeamSyncContext.Description.Value} - resolved ctx {BeamSyncContext.ResolvedInContext.Value} | total {_resolvedKeysCount}"); } BeamSyncContext.LastFetchUtc.Value = DateTime.UtcNow; return(fromMem); } } } set => _db[key] = value;