github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/blockchain/v2/io.go (about) 1 package v2 2 3 import ( 4 "fmt" 5 6 "github.com/franono/tendermint/p2p" 7 "github.com/franono/tendermint/state" 8 "github.com/franono/tendermint/types" 9 ) 10 11 type iIO interface { 12 sendBlockRequest(peerID p2p.ID, height int64) error 13 sendBlockToPeer(block *types.Block, peerID p2p.ID) error 14 sendBlockNotFound(height int64, peerID p2p.ID) error 15 sendStatusResponse(height int64, peerID p2p.ID) error 16 17 broadcastStatusRequest(base int64, height int64) 18 19 trySwitchToConsensus(state state.State, skipWAL bool) bool 20 } 21 22 type switchIO struct { 23 sw *p2p.Switch 24 } 25 26 func newSwitchIo(sw *p2p.Switch) *switchIO { 27 return &switchIO{ 28 sw: sw, 29 } 30 } 31 32 const ( 33 // BlockchainChannel is a channel for blocks and status updates (`BlockStore` height) 34 BlockchainChannel = byte(0x40) 35 ) 36 37 type consensusReactor interface { 38 // for when we switch from blockchain reactor and fast sync to 39 // the consensus machine 40 SwitchToConsensus(state state.State, skipWAL bool) 41 } 42 43 func (sio *switchIO) sendBlockRequest(peerID p2p.ID, height int64) error { 44 peer := sio.sw.Peers().Get(peerID) 45 if peer == nil { 46 return fmt.Errorf("peer not found") 47 } 48 49 msgBytes := cdc.MustMarshalBinaryBare(&bcBlockRequestMessage{Height: height}) 50 queued := peer.TrySend(BlockchainChannel, msgBytes) 51 if !queued { 52 return fmt.Errorf("send queue full") 53 } 54 return nil 55 } 56 57 func (sio *switchIO) sendStatusResponse(height int64, peerID p2p.ID) error { 58 peer := sio.sw.Peers().Get(peerID) 59 if peer == nil { 60 return fmt.Errorf("peer not found") 61 } 62 msgBytes := cdc.MustMarshalBinaryBare(&bcStatusResponseMessage{Height: height}) 63 64 if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { 65 return fmt.Errorf("peer queue full") 66 } 67 68 return nil 69 } 70 71 func (sio *switchIO) sendBlockToPeer(block *types.Block, peerID p2p.ID) error { 72 peer := sio.sw.Peers().Get(peerID) 73 if peer == nil { 74 return fmt.Errorf("peer not found") 75 } 76 if block == nil { 77 panic("trying to send nil block") 78 } 79 msgBytes := cdc.MustMarshalBinaryBare(&bcBlockResponseMessage{Block: block}) 80 if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { 81 return fmt.Errorf("peer queue full") 82 } 83 84 return nil 85 } 86 87 func (sio *switchIO) sendBlockNotFound(height int64, peerID p2p.ID) error { 88 peer := sio.sw.Peers().Get(peerID) 89 if peer == nil { 90 return fmt.Errorf("peer not found") 91 } 92 msgBytes := cdc.MustMarshalBinaryBare(&bcNoBlockResponseMessage{Height: height}) 93 if queued := peer.TrySend(BlockchainChannel, msgBytes); !queued { 94 return fmt.Errorf("peer queue full") 95 } 96 97 return nil 98 } 99 100 func (sio *switchIO) trySwitchToConsensus(state state.State, skipWAL bool) bool { 101 conR, ok := sio.sw.Reactor("CONSENSUS").(consensusReactor) 102 if ok { 103 conR.SwitchToConsensus(state, skipWAL) 104 } 105 return ok 106 } 107 108 func (sio *switchIO) broadcastStatusRequest(base int64, height int64) { 109 if height == 0 && base > 0 { 110 base = 0 111 } 112 msgBytes := cdc.MustMarshalBinaryBare(&bcStatusRequestMessage{ 113 Base: base, 114 Height: height, 115 }) 116 // XXX: maybe we should use an io specific peer list here 117 sio.sw.Broadcast(BlockchainChannel, msgBytes) 118 }