Beispiel #1
0
        public async Task Initiator_sends_auth_on_channel_activation()
        {
            NettyHandshakeHandler handler = new NettyHandshakeHandler(_serializationService, _handshakeService, _session, HandshakeRole.Initiator, _logger, _group);

            handler.ChannelActive(_channelHandlerContext);

            _handshakeService.Received(1).Auth(_session.RemoteNodeId, Arg.Any <EncryptionHandshake>());
            await _channelHandlerContext.Received(1).WriteAndFlushAsync(Arg.Is <IByteBuffer>(b => Bytes.AreEqual(b.Array.Slice(b.ArrayOffset, NetTestVectors.AuthEip8.Length), NetTestVectors.AuthEip8)));
        }
Beispiel #2
0
 public void Test_roundtrip(byte[] bytes)
 {
     TestConverter(bytes, (before, after) => Bytes.AreEqual(before, after), new ByteArrayConverter());
 }
Beispiel #3
0
 public override bool Accepts(ref ValueKeccak topic) => Bytes.AreEqual(topic.BytesAsSpan, _topic.Bytes);
Beispiel #4
0
        private List <string> RunAssertions(BlockchainTest test, Block headBlock, IStorageProvider storageProvider, IStateProvider stateProvider)
        {
            if (test.PostStateRoot != null)
            {
                return(test.PostStateRoot != stateProvider.StateRoot ? new List <string> {
                    "state root mismatch"
                } : Enumerable.Empty <string>().ToList());
            }

            TestBlockHeaderJson testHeaderJson = (test.Blocks?
                                                  .Where(b => b.BlockHeader != null)
                                                  .SingleOrDefault(b => new Keccak(b.BlockHeader.Hash) == headBlock.Hash)?.BlockHeader) ?? test.GenesisBlockHeader;
            BlockHeader   testHeader  = JsonToEthereumTest.Convert(testHeaderJson);
            List <string> differences = new();

            IEnumerable <KeyValuePair <Address, AccountState> > deletedAccounts = test.Pre?
                                                                                  .Where(pre => !(test.PostState?.ContainsKey(pre.Key) ?? false)) ?? Array.Empty <KeyValuePair <Address, AccountState> >();

            foreach (KeyValuePair <Address, AccountState> deletedAccount in deletedAccounts)
            {
                if (stateProvider.AccountExists(deletedAccount.Key))
                {
                    differences.Add($"Pre state account {deletedAccount.Key} was not deleted as expected.");
                }
            }

            foreach ((Address acountAddress, AccountState accountState) in test.PostState)
            {
                int differencesBefore = differences.Count;

                if (differences.Count > 8)
                {
                    Console.WriteLine("More than 8 differences...");
                    break;
                }

                bool    accountExists = stateProvider.AccountExists(acountAddress);
                UInt256?balance       = accountExists ? stateProvider.GetBalance(acountAddress) : (UInt256?)null;
                UInt256?nonce         = accountExists ? stateProvider.GetNonce(acountAddress) : (UInt256?)null;

                if (accountState.Balance != balance)
                {
                    differences.Add($"{acountAddress} balance exp: {accountState.Balance}, actual: {balance}, diff: {(balance > accountState.Balance ? balance - accountState.Balance : accountState.Balance - balance)}");
                }

                if (accountState.Nonce != nonce)
                {
                    differences.Add($"{acountAddress} nonce exp: {accountState.Nonce}, actual: {nonce}");
                }

                byte[] code = accountExists ? stateProvider.GetCode(acountAddress) : new byte[0];
                if (!Bytes.AreEqual(accountState.Code, code))
                {
                    differences.Add($"{acountAddress} code exp: {accountState.Code?.Length}, actual: {code?.Length}");
                }

                if (differences.Count != differencesBefore)
                {
                    _logger.Info($"ACCOUNT STATE ({acountAddress}) HAS DIFFERENCES");
                }

                differencesBefore = differences.Count;

                KeyValuePair <UInt256, byte[]>[] clearedStorages = new KeyValuePair <UInt256, byte[]> [0];
                if (test.Pre.ContainsKey(acountAddress))
                {
                    clearedStorages = test.Pre[acountAddress].Storage.Where(s => !accountState.Storage.ContainsKey(s.Key)).ToArray();
                }

                foreach (KeyValuePair <UInt256, byte[]> clearedStorage in clearedStorages)
                {
                    byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : storageProvider.Get(new StorageCell(acountAddress, clearedStorage.Key));
                    if (!value.IsZero())
                    {
                        differences.Add($"{acountAddress} storage[{clearedStorage.Key}] exp: 0x00, actual: {value.ToHexString(true)}");
                    }
                }

                foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Storage)
                {
                    byte[] value = !stateProvider.AccountExists(acountAddress) ? Bytes.Empty : storageProvider.Get(new StorageCell(acountAddress, storageItem.Key)) ?? new byte[0];
                    if (!Bytes.AreEqual(storageItem.Value, value))
                    {
                        differences.Add($"{acountAddress} storage[{storageItem.Key}] exp: {storageItem.Value.ToHexString(true)}, actual: {value.ToHexString(true)}");
                    }
                }

                if (differences.Count != differencesBefore)
                {
                    _logger.Info($"ACCOUNT STORAGE ({acountAddress}) HAS DIFFERENCES");
                }
            }

            BigInteger gasUsed = headBlock.Header.GasUsed;

            if ((testHeader?.GasUsed ?? 0) != gasUsed)
            {
                differences.Add($"GAS USED exp: {testHeader?.GasUsed ?? 0}, actual: {gasUsed}");
            }

            if (headBlock.Transactions.Any() && testHeader.Bloom.ToString() != headBlock.Header.Bloom.ToString())
            {
                differences.Add($"BLOOM exp: {testHeader.Bloom}, actual: {headBlock.Header.Bloom}");
            }

            if (testHeader.StateRoot != stateProvider.StateRoot)
            {
                differences.Add($"STATE ROOT exp: {testHeader.StateRoot}, actual: {stateProvider.StateRoot}");
            }

            if (testHeader.TxRoot != headBlock.Header.TxRoot)
            {
                differences.Add($"TRANSACTIONS ROOT exp: {testHeader.TxRoot}, actual: {headBlock.Header.TxRoot}");
            }

            if (testHeader.ReceiptsRoot != headBlock.Header.ReceiptsRoot)
            {
                differences.Add($"RECEIPT ROOT exp: {testHeader.ReceiptsRoot}, actual: {headBlock.Header.ReceiptsRoot}");
            }

            if (test.LastBlockHash != headBlock.Hash)
            {
                differences.Add($"LAST BLOCK HASH exp: {test.LastBlockHash}, actual: {headBlock.Hash}");
            }

            foreach (string difference in differences)
            {
                _logger.Info(difference);
            }

            return(differences);
        }
Beispiel #5
0
        /// <summary>
        /// Validates all the header elements (usually in relation to parent). Difficulty calculation is validated in <see cref="ISealValidator"/>
        /// </summary>
        /// <param name="header">Block header to validate</param>
        /// <param name="isOmmer"><value>True</value> if the <paramref name="header"/> is an ommer, otherwise <value>False</value></param>
        /// <returns><value>True</value> if <paramref name="header"/> is valid, otherwise <value>False</value></returns>
        public bool Validate(BlockHeader header, bool isOmmer = false)
        {
            // the rule here is to validate the seal first (avoid any cheap attacks on validation logic)
            // then validate whatever does not need to load parent from disk (the most expensive operation)

            bool areNonceValidAndMixHashValid = header.Number == 0 || header.SealEngineType == SealEngineType.None || _sealValidator.ValidateSeal(header);

            if (!areNonceValidAndMixHashValid)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - invalid mix hash / nonce");
                }
            }

            bool hashAsExpected = header.Hash == BlockHeader.CalculateHash(header);

            if (!hashAsExpected)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - invalid block hash");
                }
            }

            bool extraDataValid = isOmmer ||
                                  _daoBlockNumber == null ||
                                  header.Number < _daoBlockNumber ||
                                  header.Number >= _daoBlockNumber + 10 ||
                                  Bytes.AreEqual(header.ExtraData, DaoExtraData);

            if (!extraDataValid)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - DAO extra data not valid");
            }

            BlockHeader parent = _blockTree.FindHeader(header.ParentHash, false);

            if (parent == null)
            {
                if (header.Number == 0)
                {
                    var isGenesisValid = ValidateGenesis(header);;
                    if (!isGenesisValid)
                    {
                        if (_logger.IsWarn)
                        {
                            _logger.Warn($"Invalid genesis block header ({header.Hash})");
                        }
                    }

                    return(isGenesisValid);
                }

                if (_logger.IsWarn)
                {
                    _logger.Warn($"Orphan block, could not find parent ({header.Hash})");
                }
                return(false);
            }

            // seal is validated when synchronizing so we can remove it from here - review and test
            bool sealParamsCorrect = _sealValidator.ValidateParams(parent, header);

            if (!sealParamsCorrect)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - seal parameters incorrect");
            }

            bool gasUsedBelowLimit = header.GasUsed <= header.GasLimit;

            if (!gasUsedBelowLimit)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - gas used above gas limit");
            }

            long maxGasLimitDifference = parent.GasLimit / 1024;
            bool gasLimitNotTooHigh    = header.GasLimit < parent.GasLimit + maxGasLimitDifference;

            if (!gasLimitNotTooHigh)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - gas limit too high");
            }

            bool gasLimitNotTooLow = header.GasLimit > parent.GasLimit - maxGasLimitDifference;

            if (!gasLimitNotTooLow)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - invalid mix hash / nonce");
            }

            // bool gasLimitAboveAbsoluteMinimum = header.GasLimit >= 125000; // described in the YellowPaper but not followed
            bool timestampMoreThanAtParent = header.Timestamp > parent.Timestamp;

            if (!timestampMoreThanAtParent)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - timestamp before parent");
            }

            bool numberIsParentPlusOne = header.Number == parent.Number + 1;

            if (!numberIsParentPlusOne)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - block number is not parent + 1");
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Validating block {header.ToString(BlockHeader.Format.Short)}, extraData {header.ExtraData.ToHexString(true)}");
            }

            return
                (areNonceValidAndMixHashValid &&
                 gasUsedBelowLimit &&
                 gasLimitNotTooLow &&
                 gasLimitNotTooHigh &&
                 sealParamsCorrect &&
                 // gasLimitAboveAbsoluteMinimum && // described in the YellowPaper but not followed
                 timestampMoreThanAtParent &&
                 numberIsParentPlusOne &&
                 hashAsExpected &&
                 extraDataValid);
        }
Beispiel #6
0
        public async Task Initiator_sends_auth_on_channel_activation()
        {
            NettyHandshakeHandler handler = new NettyHandshakeHandler(_service, _ip2PSession, HandshakeRole.Initiator, _remotePublicKey, _logger);

            handler.ChannelActive(_channelHandlerContext);

            _service.Received(1).Auth(_remotePublicKey, Arg.Any <EncryptionHandshake>());
            await _channelHandlerContext.Received(1).WriteAndFlushAsync(Arg.Is <IByteBuffer>(b => Bytes.AreEqual(b.Array.Slice(0, NetTestVectors.AuthEip8.Length), NetTestVectors.AuthEip8)));
        }
Beispiel #7
0
        protected void RunTest(VirtualMachineTest test)
        {
            TestContext.WriteLine($"Running {test.GetType().FullName}");

            VirtualMachine       machine     = new VirtualMachine(_stateProvider, _storageProvider, _blockhashProvider, _specProvider, _logManager);
            ExecutionEnvironment environment = new ExecutionEnvironment();

            environment.Value            = test.Execution.Value;
            environment.CallDepth        = 0;
            environment.Sender           = test.Execution.Caller;
            environment.ExecutingAccount = test.Execution.Address;


            BlockHeader header = new BlockHeader(
                Keccak.OfAnEmptyString,
                Keccak.OfAnEmptySequenceRlp,
                test.Environment.CurrentCoinbase,
                test.Environment.CurrentDifficulty,
                test.Environment.CurrentNumber,
                (long)test.Environment.CurrentGasLimit,
                test.Environment.CurrentTimestamp, Bytes.Empty);

            environment.CurrentBlock = header;

            environment.GasPrice   = test.Execution.GasPrice;
            environment.InputData  = test.Execution.Data;
            environment.CodeInfo   = new CodeInfo(test.Execution.Code);
            environment.Originator = test.Execution.Origin;

            foreach (KeyValuePair <Address, AccountState> accountState in test.Pre)
            {
                foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage)
                {
                    _storageProvider.Set(new StorageAddress(accountState.Key, storageItem.Key), storageItem.Value);
                    if (accountState.Key.Equals(test.Execution.Address))
                    {
                        _storageProvider.Set(new StorageAddress(accountState.Key, storageItem.Key), storageItem.Value);
                    }
                }

                _stateProvider.UpdateCode(accountState.Value.Code);

                _stateProvider.CreateAccount(accountState.Key, accountState.Value.Balance);
                Keccak codeHash = _stateProvider.UpdateCode(accountState.Value.Code);
                _stateProvider.UpdateCodeHash(accountState.Key, codeHash, Olympic.Instance);
                for (int i = 0; i < accountState.Value.Nonce; i++)
                {
                    _stateProvider.IncrementNonce(accountState.Key);
                }
            }

            EvmState state = new EvmState((long)test.Execution.Gas, environment, ExecutionType.Transaction, false, true, false);

            _storageProvider.Commit();
            _stateProvider.Commit(Olympic.Instance);

            TransactionSubstate substate = machine.Run(state, NullTxTracer.Instance);

            if (test.Out == null)
            {
                Assert.NotNull(substate.Error);
                return;
            }

            Assert.True(Bytes.AreEqual(test.Out, substate.Output),
                        $"Exp: {test.Out.ToHexString(true)} != Actual: {substate.Output.ToHexString(true)}");
            Assert.AreEqual((long)test.Gas, state.GasAvailable, "gas available");
            foreach (KeyValuePair <Address, AccountState> accountState in test.Post)
            {
                bool    accountExists = _stateProvider.AccountExists(accountState.Key);
                UInt256 balance       = accountExists ? _stateProvider.GetBalance(accountState.Key) : 0;
                UInt256 nonce         = accountExists ? _stateProvider.GetNonce(accountState.Key) : 0;
                Assert.AreEqual(accountState.Value.Balance, balance, $"{accountState.Key} Balance");
                Assert.AreEqual(accountState.Value.Nonce, nonce, $"{accountState.Key} Nonce");

                // TODO: not testing properly 0 balance accounts
                if (accountExists)
                {
                    byte[] code = _stateProvider.GetCode(accountState.Key);
                    Assert.AreEqual(accountState.Value.Code, code, $"{accountState.Key} Code");
                }

                foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage)
                {
                    byte[] value = _storageProvider.Get(new StorageAddress(accountState.Key, storageItem.Key));
                    Assert.True(Bytes.AreEqual(storageItem.Value, value),
                                $"Storage[{accountState.Key}_{storageItem.Key}] Exp: {storageItem.Value.ToHexString(true)} != Actual: {value.ToHexString(true)}");
                }
            }
        }
Beispiel #8
0
 public bool Equals(ForkId other)
 {
     return(Bytes.AreEqual(ForkHash, other.ForkHash) && Next == other.Next);
 }
Beispiel #9
0
        public (PrivateKey PrivateKey, Result Result) GetKey(Address address, SecureString password)
        {
            var serializedKey = ReadKey(address.ToString());

            if (serializedKey == null)
            {
                return(null, Result.Fail("Cannot find key"));
            }
            var keyStoreItem = _jsonSerializer.Deserialize <KeyStoreItem>(serializedKey);

            if (keyStoreItem?.Crypto == null)
            {
                return(null, Result.Fail("Cannot deserialize key"));
            }

            var validationResult = Validate(keyStoreItem);

            if (validationResult.ResultType != ResultType.Success)
            {
                return(null, validationResult);
            }

            byte[] mac    = Bytes.FromHexString(keyStoreItem.Crypto.MAC);
            byte[] iv     = Bytes.FromHexString(keyStoreItem.Crypto.CipherParams.IV);
            byte[] cipher = Bytes.FromHexString(keyStoreItem.Crypto.CipherText);
            byte[] salt   = Bytes.FromHexString(keyStoreItem.Crypto.KDFParams.Salt);

            var kdfParams = keyStoreItem.Crypto.KDFParams;
            var passBytes = password.ToByteArray(_keyStoreEncoding);

            byte[] derivedKey;
            var    kdf = keyStoreItem.Crypto.KDF.Trim();

            switch (kdf)
            {
            case "scrypt":
                derivedKey = SCrypt.ComputeDerivedKey(passBytes, salt, kdfParams.N, kdfParams.R, kdfParams.P, null, kdfParams.DkLen);
                break;

            case "pbkdf2":
                var deriveBytes = new Rfc2898DeriveBytes(passBytes, salt, kdfParams.C, HashAlgorithmName.SHA256);
                derivedKey = deriveBytes.GetBytes(256);
                break;

            default:
                return(null, Result.Fail($"Unsupported algoritm: {kdf}"));
            }

            var restoredMac = Keccak.Compute(derivedKey.Slice(kdfParams.DkLen - 16, 16).Concat(cipher).ToArray()).Bytes;

            if (!Bytes.AreEqual(mac, restoredMac))
            {
                return(null, Result.Fail("Incorrect MAC"));
            }

            var cipherType = keyStoreItem.Crypto.Cipher.Trim();

            byte[] decryptKey;
            if (kdf == "scrypt" && cipherType == "aes-128-cbc")
            {
                decryptKey = Keccak.Compute(derivedKey.Slice(0, 16)).Bytes.Slice(0, 16);
            }
            else
            {
                decryptKey = derivedKey.Slice(0, 16);
            }

            byte[] key = _symmetricEncrypter.Decrypt(cipher, decryptKey, iv, cipherType);
            if (key == null)
            {
                return(null, Result.Fail("Error during decryption"));
            }

            // TODO: maybe only allow to sign here so the key never leaves the area?
            return(new PrivateKey(key), Result.Success());
        }
Beispiel #10
0
        public bool Equals(BeaconBlockBody other)
        {
            bool basicEquality = Equals(RandaoReversal, other.RandaoReversal) &&
                                 Equals(Eth1Data, other.Eth1Data) &&
                                 Bytes.AreEqual(Graffiti, other.Graffiti) &&
                                 (ProposerSlashings?.Length ?? 0) == (other.ProposerSlashings?.Length ?? 0) &&
                                 (AttesterSlashings?.Length ?? 0) == (other.AttesterSlashings?.Length ?? 0) &&
                                 (Attestations?.Length ?? 0) == (other.Attestations?.Length ?? 0) &&
                                 (Deposits?.Length ?? 0) == (other.Deposits?.Length ?? 0) &&
                                 (VoluntaryExits?.Length ?? 0) == (other.VoluntaryExits?.Length ?? 0);

            if (!basicEquality)
            {
                return(false);
            }

            if (!(AttesterSlashings is null) && !(other.AttesterSlashings is null))
            {
                for (int i = 0; i < AttesterSlashings.Length; i++)
                {
                    if (!Equals(AttesterSlashings[i], other.AttesterSlashings[i]))
                    {
                        return(false);
                    }
                }
            }

            if (!(ProposerSlashings is null) && !(other.ProposerSlashings is null))
            {
                for (int i = 0; i < ProposerSlashings.Length; i++)
                {
                    if (!Equals(ProposerSlashings[i], other.ProposerSlashings[i]))
                    {
                        return(false);
                    }
                }
            }

            if (!(Attestations is null) && !(other.Attestations is null))
            {
                for (int i = 0; i < Attestations.Length; i++)
                {
                    if (!Equals(Attestations[i], other.Attestations[i]))
                    {
                        return(false);
                    }
                }
            }

            if (!(Deposits is null) && !(other.Deposits is null))
            {
                for (int i = 0; i < Deposits.Length; i++)
                {
                    if (!Equals(Deposits[i], other.Deposits[i]))
                    {
                        return(false);
                    }
                }
            }

            if (!(VoluntaryExits is null) && !(other.VoluntaryExits is null))
            {
                for (int i = 0; i < VoluntaryExits.Length; i++)
                {
                    if (!Equals(VoluntaryExits[i], other.VoluntaryExits[i]))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        private void RunAssertions(BlockchainTest test, Block headBlock, IStorageProvider storageProvider, IStateProvider stateProvider)
        {
            TestBlockHeaderJson testHeaderJson = test.Blocks
                                                 .Where(b => b.BlockHeader != null)
                                                 .SingleOrDefault(b => new Keccak(b.BlockHeader.Hash) == headBlock.Hash)?.BlockHeader ?? test.GenesisBlockHeader;
            BlockHeader   testHeader  = Convert(testHeaderJson);
            List <string> differences = new List <string>();

            foreach (KeyValuePair <Address, AccountState> accountState in test.PostState)
            {
                int differencesBefore = differences.Count;

                if (differences.Count > 8)
                {
                    Console.WriteLine("More than 8 differences...");
                    break;
                }

                bool       accountExists = stateProvider.AccountExists(accountState.Key);
                BigInteger?balance       = accountExists ? stateProvider.GetBalance(accountState.Key) : (BigInteger?)null;
                BigInteger?nonce         = accountExists ? stateProvider.GetNonce(accountState.Key) : (BigInteger?)null;

                if (accountState.Value.Balance != balance)
                {
                    differences.Add($"{accountState.Key} balance exp: {accountState.Value.Balance}, actual: {balance}, diff: {balance - accountState.Value.Balance}");
                }

                if (accountState.Value.Nonce != nonce)
                {
                    differences.Add($"{accountState.Key} nonce exp: {accountState.Value.Nonce}, actual: {nonce}");
                }

                byte[] code = accountExists ? stateProvider.GetCode(accountState.Key) : new byte[0];
                if (!Bytes.AreEqual(accountState.Value.Code, code))
                {
                    differences.Add($"{accountState.Key} code exp: {accountState.Value.Code?.Length}, actual: {code?.Length}");
                }

                if (differences.Count != differencesBefore)
                {
                    _logger.Info($"ACCOUNT STATE ({accountState.Key}) HAS DIFFERENCES");
                }

                differencesBefore = differences.Count;

                foreach (KeyValuePair <UInt256, byte[]> storageItem in accountState.Value.Storage)
                {
                    byte[] value = storageProvider.Get(new StorageAddress(accountState.Key, storageItem.Key)) ?? new byte[0];
                    if (!Bytes.AreEqual(storageItem.Value, value))
                    {
                        differences.Add($"{accountState.Key} storage[{storageItem.Key}] exp: {storageItem.Value.ToHexString(true)}, actual: {value.ToHexString(true)}");
                    }
                }

                if (differences.Count != differencesBefore)
                {
                    _logger.Info($"ACCOUNT STORAGE ({accountState.Key}) HAS DIFFERENCES");
                }
            }


            BigInteger gasUsed = headBlock.Header.GasUsed;

            if ((testHeader?.GasUsed ?? 0) != gasUsed)
            {
                differences.Add($"GAS USED exp: {testHeader?.GasUsed ?? 0}, actual: {gasUsed}");
            }

            if (headBlock.Transactions.Any() && testHeader.Bloom.ToString() != headBlock.Header.Bloom.ToString())
            {
                differences.Add($"BLOOM exp: {testHeader.Bloom}, actual: {headBlock.Header.Bloom}");
            }

            if (testHeader.StateRoot != stateProvider.StateRoot)
            {
                differences.Add($"STATE ROOT exp: {testHeader.StateRoot}, actual: {stateProvider.StateRoot}");
            }

            if (testHeader.TransactionsRoot != headBlock.Header.TransactionsRoot)
            {
                differences.Add($"TRANSACTIONS ROOT exp: {testHeader.TransactionsRoot}, actual: {headBlock.Header.TransactionsRoot}");
            }

            if (testHeader.ReceiptsRoot != headBlock.Header.ReceiptsRoot)
            {
                differences.Add($"RECEIPT ROOT exp: {testHeader.ReceiptsRoot}, actual: {headBlock.Header.ReceiptsRoot}");
            }

            if (test.LastBlockHash != headBlock.Hash)
            {
                differences.Add($"LAST BLOCK HASH exp: {test.LastBlockHash}, actual: {headBlock.Hash}");
            }

            foreach (string difference in differences)
            {
                _logger.Info(difference);
            }

            Assert.Zero(differences.Count, "differences");
        }
Beispiel #12
0
        /// <summary>
        /// Loads this Ole2Document object from the provided stream (e.g. a FileStream to load
        /// from a File).  This is only preliminarily supported and tested for Excel
        /// files.
        /// </summary>
        /// <param name="stream">Stream to load the document from.</param>
        public void Load(System.IO.Stream stream)
        {
            if (stream.Length == 0)
            {
                throw new Exception("No data (or zero-length) found!");
            }

            if (stream.Length < 512)
            {
                throw new Exception(string.Format("File length {0} < 512 bytes", stream.Length));
            }

            byte[] head = new byte[512];
            stream.Read(head, 0, 512);

            bool isLE = false;

            if (head[28] == 254 && head[29] == 255)
            {
                isLE = true;
            }

            if (!isLE)
            {
                throw new NotSupportedException("File is not Little-Endian");
            }
            _isLittleEndian = isLE;

            ushort sectorSize = BitConverter.ToUInt16(MidByteArray(head, 30, 2), 0);

            if (sectorSize < 7 || sectorSize > 32)
            {
                throw new Exception(string.Format("Invalid Sector Size [{0}] (should be 7 <= sectorSize <= 32", sectorSize));
            }
            _sectorSize = sectorSize;

            ushort shortSectorSize = BitConverter.ToUInt16(MidByteArray(head, 32, 2), 0);

            if (shortSectorSize > sectorSize)
            {
                throw new Exception(
                          string.Format("Invalid Short Sector Size [{0}] (should be < sectorSize; {1})", shortSectorSize, sectorSize));
            }
            _shortSectorSize = shortSectorSize;

            //if (readError) ExitFunction;

            uint satSectorCount = BitConverter.ToUInt32(MidByteArray(head, 44, 4), 0);

            if (satSectorCount < 0)
            {
                throw new Exception(string.Format("Invalid SAT Sector Count [{0}] (should be > 0)", satSectorCount));
            }

            int dirSID0 = BitConverter.ToInt32(MidByteArray(head, 48, 4), 0);

            if (dirSID0 < 0)
            {
                throw new Exception(string.Format("Invalid Directory SID0 [{0}] (should be > 0)", dirSID0));
            }

            uint minStandardStreamSize = BitConverter.ToUInt32(MidByteArray(head, 56, 4), 0);

            if ((minStandardStreamSize < (Math.Pow(2, sectorSize))) || (minStandardStreamSize % (Math.Pow(2, sectorSize)) > 0))
            {
                throw new Exception(string.Format("Invalid MinStdStreamSize [{0}] (should be multiple of (2^SectorSize)", minStandardStreamSize));
            }
            _standardStreamMinBytes = minStandardStreamSize;

            int  ssatSID0        = BitConverter.ToInt32(MidByteArray(head, 60, 4), 0);
            uint ssatSectorCount = BitConverter.ToUInt32(MidByteArray(head, 64, 4), 0);

            if (ssatSID0 < 0 && ssatSID0 != -2)
            {
                throw new Exception(string.Format("Invalid SSAT SID0 [{0}] (must be >=0 or -2", ssatSID0));
            }
            if (ssatSectorCount > 0 && ssatSID0 < 0)
            {
                throw new Exception(
                          string.Format("Invalid SSAT SID0 [{0}] (must be >=0 when SSAT Sector Count > 0)", ssatSID0));
            }
            if (ssatSectorCount < 0)
            {
                throw new Exception(string.Format("Invalid SSAT Sector Count [{0}] (must be >= 0)", ssatSectorCount));
            }

            int msatSID0 = BitConverter.ToInt32(MidByteArray(head, 68, 4), 0);

            if (msatSID0 < 1 && msatSID0 != -2)
            {
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}]", msatSID0));
            }

            uint msatSectorCount = BitConverter.ToUInt32(MidByteArray(head, 72, 4), 0);

            if (msatSectorCount < 0)
            {
                throw new Exception(string.Format("Invalid MSAT Sector Count [{0}]", msatSectorCount));
            }
            else if (msatSectorCount == 0 && msatSID0 != -2)
            {
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}] (should be -2)", msatSID0));
            }

            int i = 0;
            int k = ((int)Math.Pow(2, sectorSize) / 4) - 1;

            int[] msat = new int[108 + (k * msatSectorCount) + 1];         //add 1 compared to VBScript version due to C#/VBS array declaration diff
            for (int j = 0; j < 109; j++)
            {
                msat[j] = BitConverter.ToInt32(MidByteArray(head, 76 + (j * 4), 4), 0);
            }
            int msatSidNext = msatSID0;

            while (i < msatSectorCount)
            {
                Bytes sector = GetSector(stream, sectorSize, msatSidNext);
                if (sector.Length == 0)
                {
                    throw new Exception(string.Format("MSAT SID Chain broken - SID [{0}] not found / EOF reached", msatSidNext));
                }
                for (int j = 0; j < k; j++)
                {
                    msat[109 + (i * k) + j] = BitConverter.ToInt32(sector.Get(j * 4, 4).ByteArray, 0);
                }
                msatSidNext = BitConverter.ToInt32(sector.Get(k * 4, 4).ByteArray, 0);
                i++;
            }

            //if (re) Exit Function;

            //Find number of Sectors in SAT --> i
            i = msat.Length;
            while (msat[i - 1] < 0)
            {
                i--;
            }

            //Size and fill SAT SID array
            int[] sat = new int[(uint)(i * (Math.Pow(2, sectorSize) / 4))];
            int   m   = (int)(Math.Pow(2, sectorSize) / 4);

            for (int j = 0; j < i; j++)
            {
                Bytes sector = GetSector(stream, sectorSize, msat[j]);
                if (sector.Length == 0)
                {
                    throw new Exception(string.Format("SAT SID Chain broken - SAT Sector SID{0} not found / EOF reached", msat[j]));
                }
                for (k = 0; k < m; k++)
                {
                    sat[(j * m) + k] = BitConverter.ToInt32(sector.Get(k * 4, 4).ByteArray, 0);
                }
            }

            //Size and fill SSAT SID array
            i = 0;
            int ssatSidNext = ssatSID0;

//		    m = (int) (Math.Pow(2, sectorSize) / 4);
            //Dictionary<int, int> ssat = new Dictionary<int, int>();
            int[] ssat = new int[(ssatSectorCount + 1) * m];
            while (ssatSidNext > -2)
            {
                Bytes sector = GetSector(stream, sectorSize, ssatSidNext);
                if (sector.Length == 0)
                {
                    throw new Exception(string.Format("SSAT Sector SID{0} not found", ssatSidNext));
                }
                for (int j = 0; j < m; j++)
                {
                    ssat[(i * m) + j] = BitConverter.ToInt32(sector.Get(j * 4, 4).ByteArray, 0);
                }
                ssatSidNext = sat[ssatSidNext];
                i++;
            }
            if (i < ssatSectorCount)
            {
                throw new Exception(string.Format("SSAT Sector chain broken: {0} found, header indicates {1}", i, ssatSectorCount));
            }

            //Size and fill Directory byte array array
            int dirSectorCount = 0;
            int dirSidNext     = dirSID0;

            m = (int)(Math.Pow(2, sectorSize) / 128);
            Dictionary <int, byte[]> dir = new Dictionary <int, byte[]>();

            while (dirSidNext > -2)
            {
                Bytes sector = GetSector(stream, sectorSize, dirSidNext);
                if (sector.Length == 0)
                {
                    throw new Exception(string.Format("Directory Sector SID{0} not found", dirSidNext));
                }
                for (int j = 0; j < m; j++)
                {
                    dir[(dirSectorCount * m) + j] = sector.Get(j * 128, 128).ByteArray;
                }
                dirSidNext = sat[dirSidNext];
                dirSectorCount++;
            }

            for (i = 0; i < dir.Count; i++)
            {
                byte[] dirEntry      = dir[i];
                int    nameLength    = BitConverter.ToInt16(MidByteArray(dirEntry, 64, 2), 0);
                byte[] docStreamName = MidByteArray(dirEntry, 0, nameLength);
                bool   overwrite     = false;
                if (Bytes.AreEqual(docStreamName, Directory.RootName))
                {
                    overwrite = true;
                }
                Bytes docStream =
                    GetStream(stream, i, dir, sectorSize, sat, shortSectorSize, ssat, minStandardStreamSize);
                if (docStreamName.Length == 0 && docStream.Length == 0)
                {
                    continue; //don't add streams for directory padding entries
                }
                Streams.AddNamed(docStream, docStreamName, overwrite);
            }
        }
Beispiel #13
0
 public static Hash32 DecodeSha256(Span <byte> span)
 {
     return(Bytes.AreEqual(Hash32.Zero.Bytes, span) ? Hash32.Zero : new Hash32(DecodeBytes(span).ToArray()));
 }
        public void Beacon_state_there_and_back()
        {
            Eth1Data eth1Data = new Eth1Data();

            eth1Data.BlockHash    = Sha256.OfAnEmptyString;
            eth1Data.DepositCount = 1;
            eth1Data.DepositRoot  = Sha256.OfAnEmptyString;

            BeaconBlockHeader beaconBlockHeader = new BeaconBlockHeader();

            beaconBlockHeader.Signature  = BlsSignature.TestSig1;
            beaconBlockHeader.Slot       = new Slot(14);
            beaconBlockHeader.BodyRoot   = Sha256.OfAnEmptyString;
            beaconBlockHeader.ParentRoot = Sha256.OfAnEmptyString;
            beaconBlockHeader.StateRoot  = Sha256.OfAnEmptyString;

            BeaconBlockBody beaconBlockBody = new BeaconBlockBody();

            beaconBlockBody.RandaoReversal    = BlsSignature.TestSig1;
            beaconBlockBody.Eth1Data          = eth1Data;
            beaconBlockBody.Graffiti          = new byte[32];
            beaconBlockBody.ProposerSlashings = new ProposerSlashing[2];
            beaconBlockBody.AttesterSlashings = new AttesterSlashing[3];
            beaconBlockBody.Attestations      = new Attestation[4];
            beaconBlockBody.Deposits          = new Deposit[5];
            beaconBlockBody.VoluntaryExits    = new VoluntaryExit[6];

            BeaconBlock beaconBlock = new BeaconBlock();

            beaconBlock.Body       = beaconBlockBody;
            beaconBlock.Signature  = BlsSignature.TestSig1;
            beaconBlock.Slot       = new Slot(1);
            beaconBlock.ParentRoot = Sha256.OfAnEmptyString;
            beaconBlock.StateRoot  = Sha256.OfAnEmptyString;

            BeaconState container = new BeaconState();

            container.Balances      = new Gwei[3];
            container.Fork          = new Fork(new ForkVersion(5), new ForkVersion(7), new Epoch(3));
            container.Slashings     = new Gwei[Time.EpochsPerSlashingsVector];
            container.Slot          = new Slot(1);
            container.Validators    = new Validator[7];
            container.BlockRoots    = new Sha256[Time.SlotsPerHistoricalRoot];
            container.StateRoots    = new Sha256[Time.SlotsPerHistoricalRoot];
            container.Eth1Data      = eth1Data;
            container.Eth1DataVotes = new Eth1Data[2];
            container.PreviousJustifiedCheckpoint = new Checkpoint(new Epoch(3), Sha256.OfAnEmptyString);
            container.CurrentJustifiedCheckpoint  = new Checkpoint(new Epoch(5), Sha256.OfAnEmptyString);
            container.FinalizedCheckpoint         = new Checkpoint(new Epoch(7), Sha256.OfAnEmptyString);
            container.GenesisTime               = 123;
            container.HistoricalRoots           = new Sha256[13];
            container.JustificationBits         = 9;
            container.RandaoMixes               = new Sha256[Time.EpochsPerHistoricalVector];
            container.PreviousEpochAttestations = new PendingAttestation[1];
            container.CurrentEpochAttestations  = new PendingAttestation[11];
            container.Eth1DepositIndex          = 1234;
            container.LatestBlockHeader         = beaconBlockHeader;

            Span <byte> encoded = new byte[BeaconState.SszLength(container)];

            Ssz.Encode(encoded, container);
            BeaconState decoded = Ssz.DecodeBeaconState(encoded);

            Assert.AreEqual(container, decoded);

            Span <byte> encodedAgain = new byte[BeaconState.SszLength(decoded)];

            Ssz.Encode(encodedAgain, decoded);
            Assert.True(Bytes.AreEqual(encodedAgain, encoded));

            Merkle.Ize(out UInt256 root, container);
        }
Beispiel #15
0
        public bool Validate(BlockHeader header, bool isOmmer = false)
        {
            Block parent = _blockTree.FindBlock(header.ParentHash, false);

            if (parent == null)
            {
                if (header.Number == 0)
                {
                    var isGenesisValid = IsGenesisHeaderValid(header);;
                    if (!isGenesisValid)
                    {
                        _logger.Warn($"Invalid genesis block header ({header.Hash})");
                    }

                    return(isGenesisValid);
                }

                _logger.Warn($"Orphan block, could not find parent ({header.Hash})");
                return(false);
            }

            bool areNonceValidAndMixHashValid = header.SealEngineType == SealEngineType.None || _sealEngine.Validate(header);

            if (!areNonceValidAndMixHashValid)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - invalid mix hash / nonce");
            }

            BigInteger difficulty          = _difficultyCalculator.Calculate(parent.Header.Difficulty, parent.Header.Timestamp, header.Timestamp, header.Number, parent.Ommers.Length > 0);
            bool       isDifficultyCorrect = difficulty == header.Difficulty;

            if (!isDifficultyCorrect)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - difficulty value incorrect");
            }

            // difficulty check
            bool gasUsedBelowLimit = header.GasUsed <= header.GasLimit;

            if (!gasUsedBelowLimit)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - gas used above gas limit");
            }

            bool gasLimitNotTooHigh = header.GasLimit < parent.Header.GasLimit + BigInteger.Divide(parent.Header.GasLimit, 1024);

            if (!gasLimitNotTooHigh)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - gas limit too high");
            }

            bool gasLimitNotTooLow = header.GasLimit > parent.Header.GasLimit - BigInteger.Divide(parent.Header.GasLimit, 1024);

            if (!gasLimitNotTooLow)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - invalid mix hash / nonce");
            }

//            bool gasLimitAboveAbsoluteMinimum = header.GasLimit >= 125000; // TODO: tests are consistently not following this rule
            bool timestampMoreThanAtParent = header.Timestamp > parent.Header.Timestamp;

            if (!timestampMoreThanAtParent)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - timestamp before parent");
            }

            bool numberIsParentPlusOne = header.Number == parent.Header.Number + 1;

            if (!numberIsParentPlusOne)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - block number is not parent + 1");
            }

            bool extraDataNotTooLong = header.ExtraData.Length <= 32;

            if (!extraDataNotTooLong)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - extra data too long");
            }

            bool hashAsExpected = header.Hash == BlockHeader.CalculateHash(header);

            if (!hashAsExpected)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - invalid block hash");
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Validating block {header.Hash} ({header.Number}) - DAO block {_daoBlockNumber}, extraData {header.ExtraData.ToHexString(true)}");
            }

            bool extraDataValid = isOmmer ||
                                  _daoBlockNumber == null ||
                                  header.Number < _daoBlockNumber ||
                                  header.Number >= _daoBlockNumber + 10 ||
                                  Bytes.AreEqual(header.ExtraData, DaoExtraData);

            if (!extraDataValid)
            {
                _logger.Warn($"Invalid block header ({header.Hash}) - DAO extra data not valid");
            }

            return
                (areNonceValidAndMixHashValid &&
                 gasUsedBelowLimit &&
                 gasLimitNotTooLow &&
                 gasLimitNotTooHigh &&
                 isDifficultyCorrect &&
//                   gasLimitAboveAbsoluteMinimum && // TODO: tests are consistently not following this rule
                 timestampMoreThanAtParent &&
                 numberIsParentPlusOne &&
                 extraDataNotTooLong &&
                 hashAsExpected &&
                 extraDataValid);
        }
Beispiel #16
0
 public static Sha256 DecodeSha256(Span <byte> span)
 {
     return(Bytes.AreEqual(Bytes.Zero32, span) ? null : new Sha256(DecodeBytes(span).ToArray()));
 }
Beispiel #17
0
 public bool Equals(Attestation other)
 {
     return(Bytes.AreEqual(AggregationBits, other.AggregationBits) &&
            Equals(Data, other.Data) &&
            Equals(Signature, other.Signature));
 }
Beispiel #18
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.IsWarn)
                            {
                                _logger.Warn($"Resolved key {key.ToHexString()} of context {BeamSyncContext.Description.Value} - resolved ctx {BeamSyncContext.ResolvedInContext.Value} | total {Metrics.BeamedTrieNodes}");
                            }
                        }

                        BeamSyncContext.LastFetchUtc.Value = DateTime.UtcNow;

                        // if (!Bytes.AreEqual(Keccak.Compute(fromMem).Bytes, key))
                        // {
                        //     throw new Exception("DB had an entry with a hash mismatch {key}");
                        // }

                        return(fromMem);
                    }
                }
            }

            set
            {
                if (_logger.IsTrace)
                {
                    _logger.Trace($"Saving to temp - {key.ToHexString()}");
                }
                _targetDbForSaves[key] = value;
            }
        }
Beispiel #19
0
        public async Task Recipient_sends_ack_on_receiving_auth()
        {
            NettyHandshakeHandler handler = new NettyHandshakeHandler(_service, _ip2PSession, HandshakeRole.Recipient, _remotePublicKey, _logger);

            handler.ChannelRead(_channelHandlerContext, Unpooled.Buffer(0, 0));

            _service.Received(1).Ack(Arg.Any <EncryptionHandshake>(), Arg.Any <Packet>());
            await _channelHandlerContext.Received(1).WriteAndFlushAsync(Arg.Is <IByteBuffer>(b => Bytes.AreEqual(b.Array.Slice(0, NetTestVectors.AckEip8.Length), NetTestVectors.AckEip8)));
        }
Beispiel #20
0
 private bool Equals(PrivateKey other)
 {
     return(Bytes.AreEqual(KeyBytes, other.KeyBytes));
 }
Beispiel #21
0
        /// <summary>
        /// Note that this does not validate seal which is the responsibility of <see cref="ISealValidator"/>>
        /// </summary>
        /// <param name="header">BlockHeader to validate</param>
        /// <param name="parent">BlockHeader which is the parent of <paramref name="header"/></param>
        /// <param name="isOmmer"><value>True</value> if uncle block, otherwise <value>False</value></param>
        /// <returns></returns>
        public bool Validate(BlockHeader header, BlockHeader parent, bool isOmmer = false)
        {
            bool hashAsExpected = ValidateHash(header);

            IReleaseSpec spec           = _specProvider.GetSpec(header.Number);
            bool         extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize &&
                                          (isOmmer ||
                                           _daoBlockNumber == null ||
                                           header.Number < _daoBlockNumber ||
                                           header.Number >= _daoBlockNumber + 10 ||
                                           Bytes.AreEqual(header.ExtraData, DaoExtraData));

            if (!extraDataValid)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - DAO extra data not valid");
                }
            }

            if (parent == null)
            {
                if (header.Number == 0)
                {
                    bool isGenesisValid = ValidateGenesis(header);
                    if (!isGenesisValid)
                    {
                        if (_logger.IsWarn)
                        {
                            _logger.Warn($"Invalid genesis block header ({header.Hash})");
                        }
                    }

                    return(isGenesisValid);
                }

                if (_logger.IsDebug)
                {
                    _logger.Debug($"Orphan block, could not find parent ({header.ParentHash}) of ({header.Hash})");
                }
                return(false);
            }

            bool totalDifficultyCorrect = true;

            if (header.TotalDifficulty != null)
            {
                if (parent.TotalDifficulty + header.Difficulty != header.TotalDifficulty)
                {
                    if (_logger.IsDebug)
                    {
                        _logger.Debug($"Invalid total difficulty");
                    }
                    totalDifficultyCorrect = false;
                }
            }

            // seal is validated when synchronizing so we can remove it from here - review and test
            bool sealParamsCorrect = _sealValidator.ValidateParams(parent, header);

            if (!sealParamsCorrect)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - seal parameters incorrect");
                }
            }

            bool gasUsedBelowLimit = header.GasUsed <= header.GetGasTarget1559(spec) * 2 + header.GetGasTargetLegacy(spec);

            if (!gasUsedBelowLimit)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - gas used above gas limit");
                }
            }

            var gasLimitInRange = ValidateGasLimitRange(header, parent, spec);

            // bool gasLimitAboveAbsoluteMinimum = header.GasLimit >= 125000; // described in the YellowPaper but not followed
            bool timestampMoreThanAtParent = header.Timestamp > parent.Timestamp;

            if (!timestampMoreThanAtParent)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - timestamp before parent");
                }
            }

            bool numberIsParentPlusOne = header.Number == parent.Number + 1;

            if (!numberIsParentPlusOne)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - block number is not parent + 1");
                }
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Validating block {header.ToString(BlockHeader.Format.Short)}, extraData {header.ExtraData.ToHexString(true)}");
            }

            bool baseFeeIsCorrect = true;

            if (spec.IsEip1559Enabled)
            {
                UInt256?expectedBaseFee = BlockHeader.CalculateBaseFee(parent, spec);
                baseFeeIsCorrect = expectedBaseFee == header.BaseFee;
            }

            return
                (totalDifficultyCorrect &&
                 gasUsedBelowLimit &&
                 gasLimitInRange &&
                 sealParamsCorrect &&
                 // gasLimitAboveAbsoluteMinimum && // described in the YellowPaper but not followed
                 timestampMoreThanAtParent &&
                 numberIsParentPlusOne &&
                 hashAsExpected &&
                 extraDataValid &&
                 baseFeeIsCorrect);
        }
Beispiel #22
0
        /// <summary>
        /// Note that this does not validate seal which is the responsibility of <see cref="ISealValidator"/>>
        /// </summary>
        /// <param name="header">BlockHeader to validate</param>
        /// <param name="parent">BlockHeader which is the parent of <paramref name="header"/></param>
        /// <param name="isOmmer"><value>True</value> if uncle block, otherwise <value>False</value></param>
        /// <returns></returns>
        public bool Validate(BlockHeader header, BlockHeader parent, bool isOmmer = false)
        {
            bool hashAsExpected = ValidateHash(header);

            IReleaseSpec spec           = _specProvider.GetSpec(header.Number);
            bool         extraDataValid = header.ExtraData.Length <= spec.MaximumExtraDataSize &&
                                          (isOmmer ||
                                           _daoBlockNumber == null ||
                                           header.Number < _daoBlockNumber ||
                                           header.Number >= _daoBlockNumber + 10 ||
                                           Bytes.AreEqual(header.ExtraData, DaoExtraData));

            if (!extraDataValid)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - DAO extra data not valid");
                }
            }

            if (parent == null)
            {
                if (header.Number == 0)
                {
                    var isGenesisValid = ValidateGenesis(header);
                    ;
                    if (!isGenesisValid)
                    {
                        if (_logger.IsWarn)
                        {
                            _logger.Warn($"Invalid genesis block header ({header.Hash})");
                        }
                    }

                    return(isGenesisValid);
                }

                if (_logger.IsDebug)
                {
                    _logger.Debug($"Orphan block, could not find parent ({header.Hash})");
                }
                return(false);
            }

            // seal is validated when synchronizing so we can remove it from here - review and test
            bool sealParamsCorrect = _sealValidator.ValidateParams(parent, header);

            if (!sealParamsCorrect)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - seal parameters incorrect");
                }
            }

            bool gasUsedBelowLimit = header.GasUsed <= header.GasLimit;

            if (!gasUsedBelowLimit)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - gas used above gas limit");
                }
            }

            long maxGasLimitDifference = parent.GasLimit / spec.GasLimitBoundDivisor;
            bool gasLimitNotTooHigh    = header.GasLimit <= parent.GasLimit + maxGasLimitDifference;

            if (!gasLimitNotTooHigh)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - gas limit too high");
                }
            }

            bool gasLimitNotTooLow = header.GasLimit >= parent.GasLimit - maxGasLimitDifference &&
                                     header.GasLimit >= spec.MinGasLimit;

            if (!gasLimitNotTooLow)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - gas limit too low");
                }
            }

            // bool gasLimitAboveAbsoluteMinimum = header.GasLimit >= 125000; // described in the YellowPaper but not followed
            bool timestampMoreThanAtParent = header.Timestamp > parent.Timestamp;

            if (!timestampMoreThanAtParent)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - timestamp before parent");
                }
            }

            bool numberIsParentPlusOne = header.Number == parent.Number + 1;

            if (!numberIsParentPlusOne)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - block number is not parent + 1");
                }
            }

            if (_logger.IsTrace)
            {
                _logger.Trace($"Validating block {header.ToString(BlockHeader.Format.Short)}, extraData {header.ExtraData.ToHexString(true)}");
            }

            return
                (gasUsedBelowLimit &&
                 gasLimitNotTooLow &&
                 gasLimitNotTooHigh &&
                 sealParamsCorrect &&
                 // gasLimitAboveAbsoluteMinimum && // described in the YellowPaper but not followed
                 timestampMoreThanAtParent &&
                 numberIsParentPlusOne &&
                 hashAsExpected &&
                 extraDataValid);
        }
Beispiel #23
0
 private static void SetPriority(
     IDictionaryContractDataStore <TxPriorityContract.Destination> priorities,
     BlockHeader blockHeader,
     Address target,
     byte[] prioritizedFnSignature,
     UInt256 value)
 {
     priorities.TryGetValue(blockHeader,
                            Arg.Is <TxPriorityContract.Destination>(d => d.Target == target && Bytes.AreEqual(d.FnSignature, prioritizedFnSignature)),
                            out Arg.Any <TxPriorityContract.Destination>())
     .Returns(x =>
     {
         x[2] = new TxPriorityContract.Destination(target, prioritizedFnSignature, value);
         return(true);
     });
 }
Beispiel #24
0
        // Token: 0x06000276 RID: 630 RVA: 0x0000B40C File Offset: 0x0000A40C
        public void Load(System.IO.Stream stream)
        {
            if (stream.Length == 0L)
            {
                throw new Exception("No data (or zero-length) found!");
            }
            if (stream.Length < 512L)
            {
                throw new Exception(string.Format("File length {0} < 512 bytes", stream.Length));
            }
            byte[] array = new byte[512];
            stream.Read(array, 0, 512);
            bool flag = false;

            if (array[28] == 254 && array[29] == 255)
            {
                flag = true;
            }
            if (!flag)
            {
                throw new NotSupportedException("File is not Little-Endian");
            }
            this._isLittleEndian = flag;
            ushort num = BitConverter.ToUInt16(Ole2Document.MidByteArray(array, 30, 2), 0);

            if (num < 7 || num > 32)
            {
                throw new Exception(string.Format("Invalid Sector Size [{0}] (should be 7 <= sectorSize <= 32", num));
            }
            this._sectorSize = num;
            ushort num2 = BitConverter.ToUInt16(Ole2Document.MidByteArray(array, 32, 2), 0);

            if (num2 > num)
            {
                throw new Exception(string.Format("Invalid Short Sector Size [{0}] (should be < sectorSize; {1})", num2, num));
            }
            this._shortSectorSize = num2;
            uint num3 = BitConverter.ToUInt32(Ole2Document.MidByteArray(array, 44, 4), 0);

            if (num3 < 0U)
            {
                throw new Exception(string.Format("Invalid SAT Sector Count [{0}] (should be > 0)", num3));
            }
            int num4 = BitConverter.ToInt32(Ole2Document.MidByteArray(array, 48, 4), 0);

            if (num4 < 0)
            {
                throw new Exception(string.Format("Invalid Directory SID0 [{0}] (should be > 0)", num4));
            }
            uint num5 = BitConverter.ToUInt32(Ole2Document.MidByteArray(array, 56, 4), 0);

            if (num5 < Math.Pow(2.0, (double)num) || num5 % Math.Pow(2.0, (double)num) > 0.0)
            {
                throw new Exception(string.Format("Invalid MinStdStreamSize [{0}] (should be multiple of (2^SectorSize)", num5));
            }
            this._standardStreamMinBytes = num5;
            int  num6 = BitConverter.ToInt32(Ole2Document.MidByteArray(array, 60, 4), 0);
            uint num7 = BitConverter.ToUInt32(Ole2Document.MidByteArray(array, 64, 4), 0);

            if (num6 < 0 && num6 != -2)
            {
                throw new Exception(string.Format("Invalid SSAT SID0 [{0}] (must be >=0 or -2", num6));
            }
            if (num7 > 0U && num6 < 0)
            {
                throw new Exception(string.Format("Invalid SSAT SID0 [{0}] (must be >=0 when SSAT Sector Count > 0)", num6));
            }
            if (num7 < 0U)
            {
                throw new Exception(string.Format("Invalid SSAT Sector Count [{0}] (must be >= 0)", num7));
            }
            int num8 = BitConverter.ToInt32(Ole2Document.MidByteArray(array, 68, 4), 0);

            if (num8 < 1 && num8 != -2)
            {
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}]", num8));
            }
            uint num9 = BitConverter.ToUInt32(Ole2Document.MidByteArray(array, 72, 4), 0);

            if (num9 < 0U)
            {
                throw new Exception(string.Format("Invalid MSAT Sector Count [{0}]", num9));
            }
            if (num9 == 0U && num8 != -2)
            {
                throw new Exception(string.Format("Invalid MSAT SID0 [{0}] (should be -2)", num8));
            }
            int i = 0;
            int j = (int)Math.Pow(2.0, (double)num) / 4 - 1;

            int[] array2 = new int[108L + (long)j * (long)((ulong)num9) + 1L];
            for (int k = 0; k < 109; k++)
            {
                array2[k] = BitConverter.ToInt32(Ole2Document.MidByteArray(array, 76 + k * 4, 4), 0);
            }
            int num10 = num8;

            while ((long)i < (long)((ulong)num9))
            {
                Bytes sector = Ole2Document.GetSector(stream, (int)num, num10);
                if (sector.Length == 0)
                {
                    throw new Exception(string.Format("MSAT SID Chain broken - SID [{0}] not found / EOF reached", num10));
                }
                for (int l = 0; l < j; l++)
                {
                    array2[109 + i * j + l] = BitConverter.ToInt32(sector.Get(l * 4, 4).ByteArray, 0);
                }
                num10 = BitConverter.ToInt32(sector.Get(j * 4, 4).ByteArray, 0);
                i++;
            }
            i = array2.Length;
            while (array2[i - 1] < 0)
            {
                i--;
            }
            int[] array3 = new int[(uint)((double)i * (Math.Pow(2.0, (double)num) / 4.0))];
            int   num11  = (int)(Math.Pow(2.0, (double)num) / 4.0);

            for (int m = 0; m < i; m++)
            {
                Bytes sector2 = Ole2Document.GetSector(stream, (int)num, array2[m]);
                if (sector2.Length == 0)
                {
                    throw new Exception(string.Format("SAT SID Chain broken - SAT Sector SID{0} not found / EOF reached", array2[m]));
                }
                for (j = 0; j < num11; j++)
                {
                    array3[m * num11 + j] = BitConverter.ToInt32(sector2.Get(j * 4, 4).ByteArray, 0);
                }
            }
            i = 0;
            int n = num6;

            int[] array4 = new int[(ulong)(num7 + 1U) * (ulong)((long)num11)];
            while (n > -2)
            {
                Bytes sector3 = Ole2Document.GetSector(stream, (int)num, n);
                if (sector3.Length == 0)
                {
                    throw new Exception(string.Format("SSAT Sector SID{0} not found", n));
                }
                for (int num12 = 0; num12 < num11; num12++)
                {
                    array4[i * num11 + num12] = BitConverter.ToInt32(sector3.Get(num12 * 4, 4).ByteArray, 0);
                }
                n = array3[n];
                i++;
            }
            if ((long)i < (long)((ulong)num7))
            {
                throw new Exception(string.Format("SSAT Sector chain broken: {0} found, header indicates {1}", i, num7));
            }
            int num13 = 0;
            int num14 = num4;

            num11 = (int)(Math.Pow(2.0, (double)num) / 128.0);
            Dictionary <int, byte[]> dictionary = new Dictionary <int, byte[]>();

            while (num14 > -2)
            {
                Bytes sector4 = Ole2Document.GetSector(stream, (int)num, num14);
                if (sector4.Length == 0)
                {
                    throw new Exception(string.Format("Directory Sector SID{0} not found", num14));
                }
                for (int num15 = 0; num15 < num11; num15++)
                {
                    dictionary[num13 * num11 + num15] = sector4.Get(num15 * 128, 128).ByteArray;
                }
                num14 = array3[num14];
                num13++;
            }
            for (i = 0; i < dictionary.Count; i++)
            {
                byte[] byteArray = dictionary[i];
                int    length    = (int)BitConverter.ToInt16(Ole2Document.MidByteArray(byteArray, 64, 2), 0);
                byte[] array5    = Ole2Document.MidByteArray(byteArray, 0, length);
                bool   overwrite = false;
                if (Bytes.AreEqual(array5, Directory.RootName))
                {
                    overwrite = true;
                }
                Bytes stream2 = this.GetStream(stream, i, dictionary, num, array3, num2, array4, num5);
                if (array5.Length != 0 || stream2.Length != 0)
                {
                    this.Streams.AddNamed(stream2, array5, overwrite);
                }
            }
        }