This is the code that puts a post-quantum validator certificate under the block hash. It is the thing this project exists to do, and it is published so that the claim can be checked rather than believed. What it is. In QBFT the block hash is computed over a re-encoding of the decoded extraData with the seals removed, so anything the decoder does not know about is dropped before hashing. Appending a certificate as a new element gives you a certificate that is stored, gossiped, and entirely absent from the hash. The design that works instead puts a 32-byte digest of the certificate into vanityData, which is already under keccak. anchor/README.md sets out the four designs that died before this one and why. Scope, stated in the README and repeated here because it matters: consensus on chain 2800 is classical secp256k1 ECDSA. This binds a post-quantum certificate to the block hash. It does not make consensus post-quantum and is never described as such. What is here: the anchor, the validation rules, the wiring, and the tests, including the negative controls. Applied to upstream d2032017bb, the pinned base named in anchor/BASE.txt. One build file changes, by one line, and the README says which and why. No cryptography is implemented here; Falcon verification calls Bouncy Castle. What is not here: no keys, no fleet configuration, and nothing about what is armed on any running network. Measured before publishing, on upstream d2032017bb with this overlay applied: consensus:common and consensus:qbft, 605 tests, 0 failures, identical to the same tree before this work, class by class. Three things were found while preparing it, and all three are fixed here: - the code spoke Romanian in 134 comment lines and 43 strings, 37 of them on production paths, which is to say in the messages a node prints when it refuses to start. An auditor given the code to check the guards could not read the guards. - ten test classes carried internal issue numbers in their names. They now say what they test. - the suite was green partly by ordering luck. One class cleared its system properties but not the configuration PqAnchorProducer remembers, so it left the anchor armed for whichever class ran next. Renaming the classes changed the order and four tests began failing on a guard that was firing correctly. Fixed where it leaks, with the negative control measured: remove the line and the pair goes red, restore it and it goes green.
82 lines
2.8 KiB
Groovy
82 lines
2.8 KiB
Groovy
/*
|
|
* Copyright ConsenSys AG.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations under the License.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
apply plugin: 'java-library'
|
|
|
|
jar {
|
|
archiveBaseName = calculateArtifactId(project)
|
|
manifest {
|
|
attributes(
|
|
'Specification-Title': archiveBaseName,
|
|
'Specification-Version': project.version,
|
|
'Implementation-Title': archiveBaseName,
|
|
'Implementation-Version': calculateVersion(),
|
|
'Commit-Hash': getGitCommitDetails(40).hash
|
|
)
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
api project(':plugin-api')
|
|
|
|
implementation project(':config')
|
|
implementation project(':crypto:services')
|
|
implementation project(':datatypes')
|
|
implementation project(':ethereum:api')
|
|
implementation project(':ethereum:blockcreation')
|
|
implementation project(':ethereum:core')
|
|
implementation project(':ethereum:eth')
|
|
implementation project(':ethereum:p2p')
|
|
implementation project(':ethereum:rlp')
|
|
implementation project(':evm')
|
|
implementation project(':util')
|
|
|
|
compileOnly 'org.jspecify:jspecify'
|
|
|
|
implementation 'com.fasterxml.jackson.core:jackson-databind'
|
|
implementation 'com.google.guava:guava'
|
|
implementation 'org.bouncycastle:bcprov-jdk18on'
|
|
implementation 'io.consensys.tuweni:tuweni-bytes'
|
|
|
|
testImplementation project(':config')
|
|
testImplementation project(':crypto:algorithms')
|
|
testImplementation project(':testutil')
|
|
testImplementation project( path: ':ethereum:core', configuration: 'testSupportArtifacts')
|
|
testImplementation project( path: ':crypto:services', configuration: 'testSupportArtifacts')
|
|
testImplementation project(':metrics:core')
|
|
|
|
testImplementation 'org.assertj:assertj-core'
|
|
testImplementation 'org.awaitility:awaitility'
|
|
testImplementation 'org.junit.jupiter:junit-jupiter'
|
|
testImplementation 'org.mockito:mockito-core'
|
|
testImplementation 'org.mockito:mockito-junit-jupiter'
|
|
|
|
testSupportImplementation project( path: ':crypto:services', configuration: 'testSupportArtifacts')
|
|
testSupportImplementation project( path: ':ethereum:core', configuration: 'testSupportArtifacts')
|
|
testSupportImplementation 'org.mockito:mockito-core'
|
|
testSupportImplementation 'org.assertj:assertj-core'
|
|
}
|
|
|
|
configurations { testArtifacts }
|
|
task testJar (type: Jar) {
|
|
archiveBaseName = calculateArtifactId(project) + '-test'
|
|
from sourceSets.test.output
|
|
}
|
|
|
|
artifacts {
|
|
testArtifacts testJar
|
|
testSupportArtifacts testSupportJar
|
|
}
|