@@ -171,6 +171,7 @@ module.exports = class Core {
171
171
key : opts . key || ( compat ? manifest . signers [ 0 ] . publicKey : Verifier . manifestHash ( manifest ) ) ,
172
172
manifest,
173
173
keyPair : keyPair ? { publicKey : keyPair . publicKey , secretKey : keyPair . secretKey || null } : null ,
174
+ frozen : false ,
174
175
userData : [ ] ,
175
176
tree : {
176
177
fork : 0 ,
@@ -190,6 +191,7 @@ module.exports = class Core {
190
191
key : header . key ,
191
192
manifest,
192
193
keyPair,
194
+ frozen : false ,
193
195
discoveryKey,
194
196
userData : opts . userData || [ ] ,
195
197
alias : opts . alias || null
@@ -494,6 +496,11 @@ module.exports = class Core {
494
496
return false
495
497
}
496
498
499
+ // sanity check -> no manifest, no way to verify
500
+ if ( ! this . header . manifest ) {
501
+ return false
502
+ }
503
+
497
504
const batch = MerkleTree . verifyFullyRemote ( this . state , proof )
498
505
499
506
try {
@@ -502,24 +509,57 @@ module.exports = class Core {
502
509
return true
503
510
}
504
511
512
+ const roots = await MerkleTree . getRootsFromStorage ( this . storage , proof . upgrade . length )
513
+ const remoteTreeHash = crypto . tree ( proof . upgrade . nodes )
514
+ const localTreeHash = crypto . tree ( roots )
515
+
516
+ try {
517
+ const rx = this . state . storage . read ( )
518
+ const treeProofPromise = MerkleTree . proof ( this . state , rx , {
519
+ block : null ,
520
+ hash : null ,
521
+ seek : null ,
522
+ upgrade : {
523
+ start : 0 ,
524
+ length : proof . upgrade . length
525
+ }
526
+ } )
527
+
528
+ rx . tryFlush ( )
529
+
530
+ const treeProof = await treeProofPromise
531
+
532
+ const verifyBatch = MerkleTree . verifyFullyRemote ( this . state , await treeProof . settle ( ) )
533
+ this . _verifyBatchUpgrade ( verifyBatch , this . header . manifest )
534
+ } catch {
535
+ return true
536
+ }
537
+
538
+ // both proofs are valid, now check if they forked
539
+ if ( b4a . equals ( localTreeHash , remoteTreeHash ) ) return false
540
+
505
541
await this . state . mutex . lock ( )
506
542
507
543
try {
508
544
const tx = this . state . createWriteBatch ( )
509
- if ( this . header . manifest === null && proof . manifest ) {
510
- this . _setManifest ( tx , proof . manifest , null )
511
- }
545
+
546
+ this . header . frozen = true
547
+
548
+ tx . setAuth ( {
549
+ key : this . header . key ,
550
+ discoveryKey : this . discoveryKey ,
551
+ manifest : this . header . manifest ,
552
+ keyPair : this . header . keyPair ,
553
+ frozen : true
554
+ } )
512
555
513
556
await this . state . flush ( )
514
557
} finally {
515
558
this . state . mutex . unlock ( )
516
559
}
517
560
518
- const remoteTreeHash = crypto . tree ( proof . upgrade . nodes )
519
- const localTreeHash = crypto . tree ( await MerkleTree . getRootsFromStorage ( this . storage , proof . upgrade . length ) )
520
-
521
- if ( b4a . equals ( localTreeHash , remoteTreeHash ) ) return false
522
-
561
+ // tmp log so we can see these
562
+ console . log ( '[hypercore] conflict detected in ' + this . id + ' (writable=' + ! ! this . header . keyPair + ',quorum=' + this . header . manifest . quorum + ')' )
523
563
await this . _onconflict ( proof )
524
564
return true
525
565
}
0 commit comments