@@ -508,6 +508,102 @@ test('onauthentication hook', async t => {
508508 t . end ( )
509509} )
510510
511+ test . only ( 'onfeedauthentication hook blocks replication in either direction' , async t => {
512+ const keyPair1 = HypercoreProtocol . keyPair ( )
513+ const keyPair2 = HypercoreProtocol . keyPair ( )
514+ const { increment, done : allAuthenticationDone } = countTo ( 6 )
515+ const passedAuthentications = { }
516+ const { networker : networker1 , store : store1 } = await create ( {
517+ keyPair : keyPair1 ,
518+ onfeedauthenticate
519+ } )
520+ const { networker : networker2 , store : store2 } = await create ( {
521+ keyPair : keyPair2 ,
522+ onfeedauthenticate
523+ } )
524+ const core1a = store1 . get ( )
525+ await append ( core1a , 'a' )
526+ const core1b = store1 . get ( )
527+ await append ( core1b , 'b' )
528+ const core1c = store1 . get ( )
529+ await append ( core1c , 'c' )
530+ const core2a = store2 . get ( { key : core1a . key } )
531+ const core2b = store2 . get ( { key : core1b . key } )
532+ const core2c = store2 . get ( { key : core1c . key } )
533+
534+ await networker1 . configure ( core1a . discoveryKey )
535+ await networker1 . configure ( core1b . discoveryKey )
536+ await networker1 . configure ( core1c . discoveryKey )
537+ await networker2 . configure ( core2a . discoveryKey )
538+ await networker2 . configure ( core2b . discoveryKey )
539+ await networker2 . configure ( core2c . discoveryKey )
540+
541+ await allAuthenticationDone
542+ await new Promise ( resolve => setTimeout ( resolve , 100 ) )
543+
544+ t . equals ( core2a . length , 1 , 'replicated core2a' )
545+ t . equals ( core2b . length , 0 , 'blocked replication of core2b' )
546+ t . equals ( core2c . length , 0 , 'blocked replication of core2c' )
547+ await cleanup ( [ networker1 , networker2 ] )
548+ t . end ( )
549+
550+ function onfeedauthenticate ( feed , peerPublicKey , cb ) {
551+ const remotePeer =
552+ Buffer . compare ( peerPublicKey , keyPair1 . publicKey ) === 0 ? 1 :
553+ Buffer . compare ( peerPublicKey , keyPair2 . publicKey ) === 0 ? 2 :
554+ 0
555+
556+ if ( remotePeer === 0 ) {
557+ t . fail ( 'unexpeced key:' + peerPublicKey )
558+ return
559+ }
560+
561+ const core =
562+ remotePeer === 2 ? (
563+ feed === core1a ? 'a' :
564+ feed === core1b ? 'b' :
565+ feed === core1c ? 'c' :
566+ null
567+ ) :
568+ remotePeer === 1 ? (
569+ feed === core2a ? 'a' :
570+ feed === core2b ? 'b' :
571+ feed === core2c ? 'c' :
572+ null
573+ ) :
574+ null
575+
576+ if ( core === null ) {
577+ t . fail ( 'unexpected feed:' + feed + ' for key ' + peerPublicKey )
578+ return
579+ }
580+ const id = `core${ remotePeer } ${ core } `
581+ const error = ( id === 'core1b' || id === 'core2c' ) ? new Error ( 'prevent replication' ) : null
582+ if ( ! passedAuthentications [ id ] ) {
583+ passedAuthentications [ id ] = true
584+ t . pass ( `${ id } : ${ error ? 'error' : 'ok' } ` )
585+ increment ( )
586+ }
587+ cb ( error )
588+ }
589+
590+ function countTo ( amount ) {
591+ let counted = 0
592+ let _resolve
593+ return {
594+ done : new Promise ( resolve => { _resolve = resolve } ) ,
595+ increment : ( ) => {
596+ counted += 1
597+ if ( counted === amount ) {
598+ _resolve ( )
599+ } else if ( counted > amount ) {
600+ t . fail ( 'unexpected amount of calls' )
601+ }
602+ }
603+ }
604+ }
605+ } )
606+
511607async function create ( opts = { } ) {
512608 if ( ! bootstrap ) {
513609 bootstrap = dht ( {
0 commit comments