import { BitField } from "@node-lightning/core" ; import { ILogger } from "@node-lightning/logger" ; import { expect } from "chai" ; import sinon , { stub } from "sinon" ; import { Duplex } from "stream" ; import { GossipFilter , GossipMemoryStore , GossipPeer , MessageFactory , WireError , WireErrorCode , } from "../../lib" ; import { IWireMessage } from "../../lib" ; import { InitFeatureFlags } from "../../lib/flags/InitFeatureFlags" ; import { GossipError , GossipErrorCode } from "../../lib/gossip/GossipError" ; import { Peer } from "../../lib/Peer" ; import { PeerState } from "../../lib/PeerState" ; import { PingPongState } from "../../lib/PingPongState" ; import { createFakeLogger } from "../_test-utils" ; class FakeSocket extends Duplex { [ x ] : any ; public outgoing : Buffer [ ] = [ ] ; constructor ( ) { super ( { objectMode : true } ) ; this . pipe = sinon . spy ( this . pipe . bind ( this ) ) ; this . end = sinon . spy ( this . end . bind ( this ) ) ; this . rpk = Buffer . alloc ( 33 ) ; } public _write ( data , encoding , cb ) { this . outgoing . push ( data ) ; cb ( ) ; } public _read ( ) { } public simReceive ( data ) { this . push ( data ) ; } } describe ( "GossipPeer" , ( ) => { let sut ; let chainHashes ; let peer ; let ls ; let rpk ; let logger ; let sandbox ; let socket ; let localFeatures ; let remoteFeatures ; let filter ; beforeEach ( ( ) => { chainHashes = [ Buffer . alloc ( 32 , 0xff ) ] ; localFeatures = new BitField < InitFeatureFlags > ( ) ; localFeatures . set ( InitFeatureFlags . optionDataLossProtectOptional ) ; remoteFeatures = new BitField < InitFeatureFlags > ( ) ; remoteFeatures . set ( InitFeatureFlags . optionDataLossProtectOptional ) ; remoteFeatures . set ( InitFeatureFlags . gossipQueriesOptional ) ; ls = Buffer . alloc ( 32 , 0 ) ; rpk = Buffer . alloc ( 32 , 1 ) ; logger = createFakeLogger ( ) ; peer = new Peer ( ls , localFeatures , chainHashes , logger , 1 ) ; socket = new FakeSocket ( ) ; peer . attach ( socket as any ) ; peer . pingPongState = sinon . createStubInstance ( PingPongState ) as any ; peer . state = PeerState . Ready ; peer . remoteFeatures = remoteFeatures ; sandbox = sinon . createSandbox ( ) ; const gossipStore = new GossipMemoryStore ( ) ; const pendingStore = new GossipMemoryStore ( ) ; filter = new GossipFilter ( gossipStore , pendingStore ) ; sut = new GossipPeer ( peer , filter , logger ) ; } ) ; afterEach ( ( ) => { sandbox . restore ( ) ; } ) ; describe ( "integation - wire messages" , ( ) => { it ( "it should process all valid messages" , done => { const hexMsgs = [ "0100ce1d69dbb62e86ad28157f4c24705e325f069d5158b91b28bdf55e508afcc1b554a498f4bda8a3d34a206ddb617ad0e945ecadc9a61086bac5afae3e19976242d464e8d305772f29021a4d07617c4159e7e0634bd53991c0e0577c0e9c3d3ee61d7311e6773275335c12f17e573e2813391a71050ab58c03c17d06c0d841db2ec6c6514c2156713651dfbee13d491559764c95343386218ab904173742dde6ca3118d303967e073a44e94f16eef4d878d4d74f1ff1f6924109421cf9c41e8e5c961cf1c7e2316e61a952c7caad056fea1d13d2f4bf855bd3f06d019a33814bc70ea99fa79f026c791b87040e781e8493f5165dafbfc23fabe2912c3ed0ab7e0f000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a9090000030000036b96e4713c5f84dcb8030592e1bd42a2d9a43d91fa2e535b9bfd05f2c5def9b9039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad303ca63b9acbadf5b644c11d0a9dd65b82b14e0d26fc5e0bcf071a90879f603d46203a0ee0a716f4a436864fe53bb788a003321aee63150bf63fd5529e4e1da93481d" , "01024e6eac97124742ba6a033612c8009945c0d52568756a885692b4adbf202666503b56ecb6f5758ea450dda940b2a6853b8e1706c3bd4f38a347be91b08c5e5c4743497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a90900000300005cdd9d780002009000000000000003e8000003e800000001" , "01015254ffbc21374af9d998355151515933de1d998e9cb124aa4d65a7aa6b473e75201420c58f2414f4fb7461f3f133ab529cbbf9a57365ed6bcf775172826fdc7500005ae86dba039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad3f8e71c79616c6c732e6f7267000000000000000000000000000000000000000000000000070122c8fc922607" , "0102fcd0d7af22e815879e2ba0c2422bc812d04f8b286fd53e631fe18bb6ed5aecc06a0b96fceb352509656f2b121b76cc808fe02e62ff42edc600bd6e196fe2af9b43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a90900000300005ae7cc490001009000000000000003e8000003e800000001" , "010105d3b12aacb824409ce8724609fe453fdcd33a498ecca170784985c4a6a2765657c4ef9e1170d3a5795ec86021c3a081c84a9f3a02e2ca66d17b683baacae08000005cddd5e5036b96e4713c5f84dcb8030592e1bd42a2d9a43d91fa2e535b9bfd05f2c5def9b9b6d43364656d6f312e6c6e646578706c6f7265722e636f6d0000000000000000000000000701265736a32611" , ] ; const msgs = [ ] ; sut . on ( "readable" , ( ) => { while ( true ) { const msg = sut . read ( ) as IWireMessage ; if ( ! msg ) break ; msgs . push ( msg ) ; } if ( msgs . length === hexMsgs . length ) done ( ) ; } ) ; for ( const hexMsg of hexMsgs ) { const buffer = Buffer . from ( hexMsg , "hex" ) ; socket . simReceive ( buffer ) ; } } ) ; it ( "it should continue processing after errors" , done => { const hexMsgs = [ "0100ce1d69dbb62e86ad28157f4c24705e325f069d5158b91b28bdf55e508afcc1b554a498f4bda8a3d34a206ddb617ad0e945ecadc9a61086bac5afae3e19976242d464e8d305772f29021a4d07617c4159e7e0634bd53991c0e0577c0e9c3d3ee61d7311e6773275335c12f17e573e2813391a71050ab58c03c17d06c0d841db2ec6c6514c2156713651dfbee13d491559764c95343386218ab904173742dde6ca3118d303967e073a44e94f16eef4d878d4d74f1ff1f6924109421cf9c41e8e5c961cf1c7e2316e61a952c7caad056fea1d13d2f4bf855bd3f06d019a33814bc70ea99fa79f026c791b87040e781e8493f5165dafbfc23fabe2912c3ed0ab7e0f000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a9090000030000036b96e4713c5f84dcb8030592e1bd42a2d9a43d91fa2e535b9bfd05f2c5def9b9039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad303ca63b9acbadf5b644c11d0a9dd65b82b14e0d26fc5e0bcf071a90879f603d46203a0ee0a716f4a436864fe53bb788a003321aee63150bf63fd5529e4e1da93481d" , "01024e6eac97124742ba6a033612c8009945c0d52568756a885692b4adbf202666503b56ecb6f5758ea450dda940b2a6853b8e1706c3bd4f38a347be91b08c5e5c4743497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a90900000300005cdd9d780002009000000000000003e8000003e800000001" , "01010254ffbc21374af9d998355151515933de1d998e9cb124aa4d65a7aa6b473e75201420c58f2414f4fb7461f3f133ab529cbbf9a57365ed6bcf775172826fdc7500005ae86dba039cc950286a8fa99218283d1adc2456e0d5e81be558da77dd6e85ba9a1fff5ad3f8e71c79616c6c732e6f7267000000000000000000000000000000000000000000000000070122c8fc922607" , "0102fcd0d7af22e815879e2ba0c2422bc812d04f8b286fd53e631fe18bb6ed5aecc06a0b96fceb352509656f2b121b76cc808fe02e62ff42edc600bd6e196fe2af9b43497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea33090000000013a90900000300005ae7cc490001009000000000000003e8000003e800000001" , "010105d3b12aacb824409ce8724609fe453fdcd33a498ecca170784985c4a6a2765657c4ef9e1170d3a5795ec86021c3a081c84a9f3a02e2ca66d17b683baacae08000005cddd5e5036b96e4713c5f84dcb8030592e1bd42a2d9a43d91fa2e535b9bfd05f2c5def9b9b6d43364656d6f312e6c6e646578706c6f7265722e636f6d0000000000000000000000000701265736a32611" , ] ; const msgs = [ ] ; const errors = [ ] ; function validate ( ) { if ( msgs . length + errors . length === hexMsgs . length ) { expect ( errors [ 0 ] . code == WireErrorCode . nodeAnnSigFailed ) ; done ( ) ; } } sut . on ( "readable" , ( ) => { while ( true ) { const msg = sut . read ( ) as IWireMessage ; if ( ! msg ) break ; msgs . push ( msg ) ; } validate ( ) ; } ) ; sut . on ( "gossip_error" , error => { errors . push ( error ) ; validate ( ) ; } ) ; for ( const hexMsg of hexMsgs ) { const buffer = Buffer . from ( hexMsg , "hex" ) ; socket . simReceive ( buffer ) ; } } ) ; } ) ; } ) ;