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))); }
public void Test_roundtrip(byte[] bytes) { TestConverter(bytes, (before, after) => Bytes.AreEqual(before, after), new ByteArrayConverter()); }
public override bool Accepts(ref ValueKeccak topic) => Bytes.AreEqual(topic.BytesAsSpan, _topic.Bytes);
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); }
/// <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); }
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))); }
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)}"); } } }
public bool Equals(ForkId other) { return(Bytes.AreEqual(ForkHash, other.ForkHash) && Next == other.Next); }
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()); }
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"); }
/// <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); } }
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); }
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); }
public static Sha256 DecodeSha256(Span <byte> span) { return(Bytes.AreEqual(Bytes.Zero32, span) ? null : new Sha256(DecodeBytes(span).ToArray())); }
public bool Equals(Attestation other) { return(Bytes.AreEqual(AggregationBits, other.AggregationBits) && Equals(Data, other.Data) && Equals(Signature, other.Signature)); }
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; } }
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))); }
private bool Equals(PrivateKey other) { return(Bytes.AreEqual(KeyBytes, other.KeyBytes)); }
/// <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); }
/// <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); }
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); }); }
// 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); } } }