public void Can_calculate_signers_count() { BlockHeader header = BuildCliqueBlock(); for (int i = 0; i < 5; i++) { int signersCount = header.CalculateSignersCount(); Assert.AreEqual(i, signersCount); byte[] newExtraData = new byte[header.ExtraData.Length + Address.ByteLength]; header.ExtraData = newExtraData; } }
internal Snapshot GetOrCreateSnapshot(UInt256 number, Keccak hash) { // Search for a snapshot in memory or on disk for checkpoints List <BlockHeader> headers = new List <BlockHeader>(); Snapshot snapshot; while (true) { snapshot = GetSnapshot(number, hash); if (snapshot != null) { break; } // If we're at an checkpoint block, make a snapshot if it's known BlockHeader header = _blockTree.FindHeader(hash); if (header == null) { throw new InvalidOperationException("Unknown ancestor"); } if (header.Hash == null) { throw new InvalidOperationException("Block tree block without hash set"); } Keccak parentHash = header.ParentHash; if (number == 0 || (IsEpochTransition(number) && _blockTree.FindHeader(parentHash) == null)) { int signersCount = header.CalculateSignersCount(); SortedList <Address, UInt256> signers = new SortedList <Address, UInt256>(signersCount, CliqueAddressComparer.Instance); for (int i = 0; i < signersCount; i++) { Address signer = new Address(header.ExtraData.Slice(Clique.ExtraVanityLength + i * AddressLength, AddressLength)); signers.Add(signer, UInt256.Zero); } snapshot = new Snapshot(_config, _signatures, number, header.Hash, signers); snapshot.Store(_blocksDb); break; } // No snapshot for this header, gather the header and move backward headers.Add(header); number = number - 1; hash = header.ParentHash; } // Previous snapshot found, apply any pending headers on top of it for (int i = 0; i < headers.Count / 2; i++) { BlockHeader temp = headers[headers.Count - 1 - i]; headers[headers.Count - 1 - i] = headers[i]; headers[i] = temp; } for (int i = 0; i < headers.Count; i++) { headers[i].Author = headers[i].Author ?? GetBlockSealer(headers[i]); } snapshot = snapshot.Apply(headers); _recent.Set(snapshot.Hash, snapshot); // If we've generated a new checkpoint snapshot, save to disk if ((ulong)snapshot.Number % Clique.CheckpointInterval == 0 && headers.Count > 0) { snapshot.Store(_blocksDb); } return(snapshot); }