public ProtocolSpec getByBlockNumberOrTimestamp(final long number, final long timestamp) {
    checkArgument(number >= 0, "number must be non-negative");
    checkArgument(
        !protocolSpecs.isEmpty(), "At least 1 milestone must be provided to the protocol schedule");
    checkArgument(
        protocolSpecs.last().fork().milestone() == 0,
        "There must be a milestone starting from block 0");
    // protocolSpecs is sorted in descending block order, so the first one we find that's lower than
    // the requested level will be the most appropriate spec
    ProtocolSpec theSpec = null;
    for (final ScheduledProtocolSpec s : protocolSpecs) {
      if ((s instanceof ScheduledProtocolSpec.BlockNumberProtocolSpec)
          && (number >= s.fork().milestone())) {
        theSpec = s.spec();
        break;
      } else if ((s instanceof ScheduledProtocolSpec.TimestampProtocolSpec)
          && (timestamp >= s.fork().milestone())) {
        theSpec = s.spec();
        break;
      }
    }
    return theSpec;
  }
Look up ProtocolSpec by block number or timestamp

@param number block number
@param timestamp block timestamp
@return the protocol spec for that block number or timestamp
consensus/common/src/main/java/org/hyperledger/besu/consensus/common/bft/BftProtocolSchedule.java