@@ -6,6 +6,7 @@ import "../lib/openzeppelin/contracts/utils/cryptography/ECDSA.sol";
6
6
import "../Constants.sol " ;
7
7
import "../DataRootTuple.sol " ;
8
8
import "../QuantumGravityBridge.sol " ;
9
+ import "../lib/tree/binary/BinaryMerkleProof.sol " ;
9
10
10
11
import "ds-test/test.sol " ;
11
12
@@ -93,6 +94,61 @@ contract RelayerTest is DSTest {
93
94
assertEq (bridge.state_dataRootTupleRoots (nonce), newTupleRoot);
94
95
}
95
96
97
+ /*
98
+ the values used in the verify attestation test are in the format `<height padded to 32 bytes || data root>`, which
99
+ represent an encoded `abi.encode(DataRootTuple)`:
100
+
101
+ 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
102
+ 0x00000000000000000000000000000000000000000000000000000000000000010101010101010101010101010101010101010101010101010101010101010101
103
+ 0x00000000000000000000000000000000000000000000000000000000000000020202020202020202020202020202020202020202020202020202020202020202
104
+ 0x00000000000000000000000000000000000000000000000000000000000000030303030303030303030303030303030303030303030303030303030303030303
105
+ */
106
+ function testVerifyAttestation () public {
107
+ uint256 initialVelsetNonce = 0 ;
108
+ // data root tuple root nonce.
109
+ uint256 nonce = 1 ;
110
+ // commitment to a set of roots.
111
+ // these values were generated using the tendermint implementation of binary merkle trees:
112
+ // https://github.com/celestiaorg/celestia-core/blob/60310e7aa554bb76b735a010847a6613bcfe06e8/crypto/merkle/proof.go#L33-L48
113
+ bytes32 newTupleRoot = 0x82dc1607d84557d3579ce602a45f5872e821c36dbda7ec926dfa17ebc8d5c013 ;
114
+ // a data root committed to by the above tuple root.
115
+ bytes32 newTuple = 0x0101010101010101010101010101010101010101010101010101010101010101 ;
116
+ // the height of the data root.
117
+ uint256 height = 1 ;
118
+ // the binary merkle proof of the data root to the data root tuple root.
119
+ bytes32 [] memory sideNodes = new bytes32 [](2 );
120
+ sideNodes[0 ] = 0x98ce42deef51d40269d542f5314bef2c7468d401ad5d85168bfab4c0108f75f7 ;
121
+ sideNodes[1 ] = 0x575664048c9e64260eca2304d177b11d1566d0c954f1417fc76a4f9f27350063 ;
122
+ BinaryMerkleProof memory newTupleProof;
123
+ newTupleProof.sideNodes = sideNodes;
124
+ newTupleProof.key = 1 ;
125
+ newTupleProof.numLeaves = 4 ;
126
+
127
+ bytes32 newDataRootTupleRoot = domainSeparateDataRootTupleRoot (nonce, newTupleRoot);
128
+
129
+ // Signature for the update.
130
+ Signature[] memory sigs = new Signature [](1 );
131
+ bytes32 digest_eip191 = ECDSA.toEthSignedMessageHash (newDataRootTupleRoot);
132
+ (uint8 v , bytes32 r , bytes32 s ) = cheats.sign (testPriv1, digest_eip191);
133
+ sigs[0 ] = Signature (v, r, s);
134
+
135
+ Validator[] memory valSet = new Validator [](1 );
136
+ valSet[0 ] = Validator (cheats.addr (testPriv1), votingPower);
137
+
138
+ bridge.submitDataRootTupleRoot (nonce, initialVelsetNonce, newTupleRoot, valSet, sigs);
139
+
140
+ assertEq (bridge.state_eventNonce (), nonce);
141
+ assertEq (bridge.state_dataRootTupleRoots (nonce), newTupleRoot);
142
+
143
+ DataRootTuple memory t;
144
+ t.height = height;
145
+ t.dataRoot = newTuple;
146
+
147
+ // verify that the tuple was committed to
148
+ bool committedTo = bridge.verifyAttestation (nonce, t, newTupleProof);
149
+ assertTrue (committedTo);
150
+ }
151
+
96
152
function computeValidatorSetHash (Validator[] memory _validators ) private pure returns (bytes32 ) {
97
153
return keccak256 (abi.encode (_validators));
98
154
}
0 commit comments