Advance forge rollout, Ethereum rails, and NBC sources
This commit is contained in:
parent
be26313225
commit
7d84510eac
88 changed files with 11230 additions and 302 deletions
158
contracts/test/ObservationLedger.t.sol
Normal file
158
contracts/test/ObservationLedger.t.sol
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
pragma solidity ^0.8.24;
|
||||
|
||||
import {EveryChannelObservationLedger} from "../EveryChannelObservationLedger.sol";
|
||||
import {EveryChannelWitnessRegistry} from "../EveryChannelWitnessRegistry.sol";
|
||||
|
||||
contract WitnessActor {
|
||||
function propose(
|
||||
EveryChannelObservationLedger ledger,
|
||||
EveryChannelObservationLedger.ObservationHeader calldata header
|
||||
) external returns (bytes32) {
|
||||
return ledger.proposeObservation(header);
|
||||
}
|
||||
|
||||
function attest(
|
||||
EveryChannelObservationLedger ledger,
|
||||
bytes32 observationHash
|
||||
) external {
|
||||
ledger.attestObservation(observationHash);
|
||||
}
|
||||
}
|
||||
|
||||
contract ObservationLedgerTest {
|
||||
function _header(
|
||||
bytes32 streamHash,
|
||||
bytes32 epochHash,
|
||||
uint64 sequence,
|
||||
bytes32 dataRoot
|
||||
) internal pure returns (EveryChannelObservationLedger.ObservationHeader memory) {
|
||||
return EveryChannelObservationLedger.ObservationHeader({
|
||||
streamHash: streamHash,
|
||||
epochHash: epochHash,
|
||||
parentObservationHash: bytes32(0),
|
||||
dataRoot: dataRoot,
|
||||
locatorHash: keccak256(abi.encodePacked(streamHash, epochHash, sequence)),
|
||||
observedUnixMs: 1_772_001_256_329,
|
||||
sequence: sequence
|
||||
});
|
||||
}
|
||||
|
||||
function test_finalizes_when_quorum_is_reached() public {
|
||||
EveryChannelWitnessRegistry registry = new EveryChannelWitnessRegistry(address(this));
|
||||
WitnessActor witnessA = new WitnessActor();
|
||||
WitnessActor witnessB = new WitnessActor();
|
||||
registry.addWitness(address(witnessA));
|
||||
registry.addWitness(address(witnessB));
|
||||
|
||||
EveryChannelObservationLedger ledger = new EveryChannelObservationLedger(
|
||||
address(registry),
|
||||
2
|
||||
);
|
||||
|
||||
EveryChannelObservationLedger.ObservationHeader memory header = _header(
|
||||
keccak256("la-cbs:video0.m4s"),
|
||||
keccak256("epoch-229"),
|
||||
229,
|
||||
keccak256("58cd13f693debd000d995c9a5574e8b9274cc4d3399eb6f1f22393af1ba7407d")
|
||||
);
|
||||
|
||||
bytes32 observationHash = witnessA.propose(ledger, header);
|
||||
bytes32 slot = ledger.observationSlot(header.streamHash, header.epochHash);
|
||||
|
||||
assert(ledger.finalizedObservationBySlot(slot) == bytes32(0));
|
||||
|
||||
witnessB.attest(ledger, observationHash);
|
||||
|
||||
assert(ledger.finalizedObservationBySlot(slot) == observationHash);
|
||||
EveryChannelObservationLedger.ObservationHeader memory storedHeader = ledger
|
||||
.getObservationHeader(observationHash);
|
||||
assert(storedHeader.streamHash == header.streamHash);
|
||||
assert(storedHeader.epochHash == header.epochHash);
|
||||
assert(storedHeader.dataRoot == header.dataRoot);
|
||||
assert(storedHeader.sequence == header.sequence);
|
||||
}
|
||||
|
||||
function test_rejects_duplicate_attestation() public {
|
||||
EveryChannelWitnessRegistry registry = new EveryChannelWitnessRegistry(address(this));
|
||||
WitnessActor witnessA = new WitnessActor();
|
||||
registry.addWitness(address(witnessA));
|
||||
|
||||
EveryChannelObservationLedger ledger = new EveryChannelObservationLedger(
|
||||
address(registry),
|
||||
1
|
||||
);
|
||||
|
||||
EveryChannelObservationLedger.ObservationHeader memory header = _header(
|
||||
keccak256("la-nbc:catalog.json"),
|
||||
keccak256("epoch-5"),
|
||||
5,
|
||||
keccak256("f6ea0793fd00e29ced670d586e0e5f7f3d0f5edfc016c03f80710bd4bed587ec")
|
||||
);
|
||||
|
||||
bytes32 observationHash = witnessA.propose(ledger, header);
|
||||
assert(
|
||||
ledger.finalizedObservationBySlot(
|
||||
ledger.observationSlot(header.streamHash, header.epochHash)
|
||||
) == observationHash
|
||||
);
|
||||
|
||||
(bool ok, ) = address(witnessA).call(
|
||||
abi.encodeWithSelector(
|
||||
WitnessActor.attest.selector,
|
||||
ledger,
|
||||
observationHash
|
||||
)
|
||||
);
|
||||
assert(!ok);
|
||||
}
|
||||
|
||||
function test_competing_candidates_only_one_slot_can_finalize() public {
|
||||
EveryChannelWitnessRegistry registry = new EveryChannelWitnessRegistry(address(this));
|
||||
WitnessActor witnessA = new WitnessActor();
|
||||
WitnessActor witnessB = new WitnessActor();
|
||||
WitnessActor witnessC = new WitnessActor();
|
||||
registry.addWitness(address(witnessA));
|
||||
registry.addWitness(address(witnessB));
|
||||
registry.addWitness(address(witnessC));
|
||||
|
||||
EveryChannelObservationLedger ledger = new EveryChannelObservationLedger(
|
||||
address(registry),
|
||||
2
|
||||
);
|
||||
|
||||
bytes32 streamHash = keccak256("la-cbs:video0.m4s");
|
||||
bytes32 epochHash = keccak256("epoch-230");
|
||||
EveryChannelObservationLedger.ObservationHeader memory candidateA = _header(
|
||||
streamHash,
|
||||
epochHash,
|
||||
230,
|
||||
keccak256("1130c51b3ce428505dbc3c3294678f76e3200221d853fc9b02c8ed603ecc8b8c")
|
||||
);
|
||||
EveryChannelObservationLedger.ObservationHeader memory candidateB = _header(
|
||||
streamHash,
|
||||
epochHash,
|
||||
230,
|
||||
keccak256("deadbeef")
|
||||
);
|
||||
|
||||
bytes32 hashA = witnessA.propose(ledger, candidateA);
|
||||
bytes32 hashB = witnessB.propose(ledger, candidateB);
|
||||
bytes32 slot = ledger.observationSlot(streamHash, epochHash);
|
||||
|
||||
assert(hashA != hashB);
|
||||
assert(ledger.finalizedObservationBySlot(slot) == bytes32(0));
|
||||
|
||||
witnessC.attest(ledger, hashA);
|
||||
assert(ledger.finalizedObservationBySlot(slot) == hashA);
|
||||
|
||||
(bool ok, ) = address(witnessB).call(
|
||||
abi.encodeWithSelector(
|
||||
WitnessActor.attest.selector,
|
||||
ledger,
|
||||
hashB
|
||||
)
|
||||
);
|
||||
assert(!ok);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue