mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-16 18:00:46 +00:00
parent
ba9fa91375
commit
99e2885b03
15 changed files with 32 additions and 32 deletions
|
|
@ -822,13 +822,13 @@ var (
|
||||||
// XDC settings
|
// XDC settings
|
||||||
Enable0xPrefixFlag = &cli.BoolFlag{
|
Enable0xPrefixFlag = &cli.BoolFlag{
|
||||||
Name: "enable-0x-prefix",
|
Name: "enable-0x-prefix",
|
||||||
Usage: "Addres use 0x-prefix (Deprecated: this is on by default, to use xdc prefix use --enable-xdc-prefix)",
|
Usage: "Address use 0x-prefix (Deprecated: this is on by default, to use xdc prefix use --enable-xdc-prefix)",
|
||||||
Value: true,
|
Value: true,
|
||||||
Category: flags.XdcCategory,
|
Category: flags.XdcCategory,
|
||||||
}
|
}
|
||||||
EnableXDCPrefixFlag = &cli.BoolFlag{
|
EnableXDCPrefixFlag = &cli.BoolFlag{
|
||||||
Name: "enable-xdc-prefix",
|
Name: "enable-xdc-prefix",
|
||||||
Usage: "Addres use xdc-prefix (default = false)",
|
Usage: "Address use xdc-prefix (default = false)",
|
||||||
Value: false,
|
Value: false,
|
||||||
Category: flags.XdcCategory,
|
Category: flags.XdcCategory,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -818,7 +818,7 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
|
||||||
|
|
||||||
_, round, _, err := x.getExtraFields(parentBlock)
|
_, round, _, err := x.getExtraFields(parentBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to execute first DecodeBytesExtraFields for commiting block", "ProposedBlockHash", proposedBlockHeader.Hash())
|
log.Error("Fail to execute first DecodeBytesExtraFields for committing block", "ProposedBlockHash", proposedBlockHeader.Hash())
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if *proposedBlockRound-1 != round {
|
if *proposedBlockRound-1 != round {
|
||||||
|
|
@ -830,7 +830,7 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
|
||||||
grandParentBlock := blockChainReader.GetHeaderByHash(parentBlock.ParentHash)
|
grandParentBlock := blockChainReader.GetHeaderByHash(parentBlock.ParentHash)
|
||||||
_, round, _, err = x.getExtraFields(grandParentBlock)
|
_, round, _, err = x.getExtraFields(grandParentBlock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to execute second DecodeBytesExtraFields for commiting block", "parentBlockHash", parentBlock.Hash())
|
log.Error("Fail to execute second DecodeBytesExtraFields for committing block", "parentBlockHash", parentBlock.Hash())
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
if *proposedBlockRound-2 != round {
|
if *proposedBlockRound-2 != round {
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC types.Quo
|
||||||
/*
|
/*
|
||||||
Entry point for processing forensics.
|
Entry point for processing forensics.
|
||||||
Triggered once processQC is successfully.
|
Triggered once processQC is successfully.
|
||||||
Forensics runs in a seperate go routine as its no system critical
|
Forensics runs in a separate go routine as its no system critical
|
||||||
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
|
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
|
||||||
*/
|
*/
|
||||||
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error {
|
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_v2, incomingQC types.QuorumCert) error {
|
||||||
|
|
@ -105,8 +105,8 @@ func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if isOnTheChain {
|
if isOnTheChain {
|
||||||
// Passed the checking, nothing suspecious.
|
// Passed the checking, nothing suspicious.
|
||||||
log.Debug("[ProcessForensics] Passed forensics checking, nothing suspecious need to be reported", "incomingQcProposedBlockHash", incomingQC.ProposedBlockInfo.Hash, "incomingQcProposedBlockNumber", incomingQC.ProposedBlockInfo.Number.Uint64(), "incomingQcProposedBlockRound", incomingQC.ProposedBlockInfo.Round)
|
log.Debug("[ProcessForensics] Passed forensics checking, nothing suspicious need to be reported", "incomingQcProposedBlockHash", incomingQC.ProposedBlockInfo.Hash, "incomingQcProposedBlockNumber", incomingQC.ProposedBlockInfo.Number.Uint64(), "incomingQcProposedBlockRound", incomingQC.ProposedBlockInfo.Round)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Trigger the safety Alarm if failed
|
// Trigger the safety Alarm if failed
|
||||||
|
|
@ -391,7 +391,7 @@ func generateVoteEquivocationId(signer common.Address, round1, round2 types.Roun
|
||||||
/*
|
/*
|
||||||
Entry point for processing vote equivocation.
|
Entry point for processing vote equivocation.
|
||||||
Triggered once handle vote is successfully.
|
Triggered once handle vote is successfully.
|
||||||
Forensics runs in a seperate go routine as its no system critical
|
Forensics runs in a separate go routine as its no system critical
|
||||||
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/99516417/Vote+Equivocation+detection+specification
|
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/99516417/Vote+Equivocation+detection+specification
|
||||||
*/
|
*/
|
||||||
func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine *XDPoS_v2, incomingVote *types.Vote) error {
|
func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine *XDPoS_v2, incomingVote *types.Vote) error {
|
||||||
|
|
@ -413,7 +413,7 @@ func (f *Forensics) ProcessVoteEquivocation(chain consensus.ChainReader, engine
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if isOnTheChain {
|
if isOnTheChain {
|
||||||
// Passed the checking, nothing suspecious.
|
// Passed the checking, nothing suspicious.
|
||||||
log.Debug("[ProcessVoteEquivocation] Passed forensics checking, nothing suspecious need to be reported", "incomingVoteProposedBlockHash", incomingVote.ProposedBlockInfo.Hash, "incomingVoteProposedBlockNumber", incomingVote.ProposedBlockInfo.Number.Uint64(), "incomingVoteProposedBlockRound", incomingVote.ProposedBlockInfo.Round)
|
log.Debug("[ProcessVoteEquivocation] Passed forensics checking, nothing suspecious need to be reported", "incomingVoteProposedBlockHash", incomingVote.ProposedBlockInfo.Hash, "incomingVoteProposedBlockNumber", incomingVote.ProposedBlockInfo.Number.Uint64(), "incomingVoteProposedBlockRound", incomingVote.ProposedBlockInfo.Round)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return consensus.ErrUnknownAncestor
|
return consensus.ErrUnknownAncestor
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify this is truely a v2 block first
|
// Verify this is truly a v2 block first
|
||||||
quorumCert, round, _, err := x.getExtraFields(header)
|
quorumCert, round, _, err := x.getExtraFields(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("[verifyHeader] decode extra field error", "err", err)
|
log.Warn("[verifyHeader] decode extra field error", "err", err)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
|
||||||
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
||||||
if signers[acc3Addr.Hex()] != true {
|
if signers[acc3Addr.Hex()] != true {
|
||||||
debugMessage(backend, signers, t)
|
debugMessage(backend, signers, t)
|
||||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
t.Fatalf("account 3 should sit in the signer list as previous block result")
|
||||||
}
|
}
|
||||||
if (signers[acc1Addr.Hex()] == true) || (signers[acc2Addr.Hex()] == true) {
|
if (signers[acc1Addr.Hex()] == true) || (signers[acc2Addr.Hex()] == true) {
|
||||||
debugMessage(backend, signers, t)
|
debugMessage(backend, signers, t)
|
||||||
|
|
@ -457,7 +457,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
|
||||||
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
||||||
if signers[acc3Addr.Hex()] != true {
|
if signers[acc3Addr.Hex()] != true {
|
||||||
debugMessage(backend, signers, t)
|
debugMessage(backend, signers, t)
|
||||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
t.Fatalf("account 3 should sit in the signer list as previous block result")
|
||||||
}
|
}
|
||||||
|
|
||||||
//Insert block 451 parent is 451 B
|
//Insert block 451 parent is 451 B
|
||||||
|
|
@ -641,6 +641,6 @@ func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
|
||||||
// Should run the `updateM1` for forked chain, but it should not be affected by the voted block 451A which is not on the mainchain anymore
|
// Should run the `updateM1` for forked chain, but it should not be affected by the voted block 451A which is not on the mainchain anymore
|
||||||
if signers[acc3Addr.Hex()] != true {
|
if signers[acc3Addr.Hex()] != true {
|
||||||
debugMessage(backend, signers, t)
|
debugMessage(backend, signers, t)
|
||||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
t.Fatalf("account 3 should sit in the signer list as previous block result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.S
|
||||||
}
|
}
|
||||||
|
|
||||||
func transferTx(t *testing.T, to common.Address, transferAmount int64) *types.Transaction {
|
func transferTx(t *testing.T, to common.Address, transferAmount int64) *types.Transaction {
|
||||||
t.Logf("Transfering %v to address: %v", transferAmount, to.String())
|
t.Logf("Transferring %v to address: %v", transferAmount, to.String())
|
||||||
data := []byte{}
|
data := []byte{}
|
||||||
gasPrice := big.NewInt(int64(0))
|
gasPrice := big.NewInt(int64(0))
|
||||||
gasLimit := uint64(21000)
|
gasLimit := uint64(21000)
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,7 @@ type ForkedBlockOptions struct {
|
||||||
signersKey []*ecdsa.PrivateKey
|
signersKey []*ecdsa.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// V2 concensus engine
|
// V2 consensus engine
|
||||||
func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, forkedBlockOptions *ForkedBlockOptions) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error), *types.Block) {
|
func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, forkedBlockOptions *ForkedBlockOptions) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error), *types.Block) {
|
||||||
// Preparation
|
// Preparation
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -523,7 +523,7 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
|
||||||
return blockchain, backend, currentBlock, signer, signFn, currentForkBlock
|
return blockchain, backend, currentBlock, signer, signFn, currentForkBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// V2 concensus engine, compared to PrepareXDCTestBlockChainForV2Engine: (1) no forking (2) add penalty
|
// V2 consensus engine, compared to PrepareXDCTestBlockChainForV2Engine: (1) no forking (2) add penalty
|
||||||
func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error)) {
|
func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error)) {
|
||||||
// Preparation
|
// Preparation
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -578,7 +578,7 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in
|
||||||
return blockchain, backend, currentBlock, signer, signFn
|
return blockchain, backend, currentBlock, signer, signFn
|
||||||
}
|
}
|
||||||
|
|
||||||
// V2 concensus engine, compared to PrepareXDCTestBlockChainForV2Engine: (1) no forking (2) add penalty
|
// V2 consensus engine, compared to PrepareXDCTestBlockChainForV2Engine: (1) no forking (2) add penalty
|
||||||
func PrepareXDCTestBlockChainWithPenaltyCustomized(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, penaltyOrNot []bool) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error)) {
|
func PrepareXDCTestBlockChainWithPenaltyCustomized(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, penaltyOrNot []bool) (*core.BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error)) {
|
||||||
// Preparation
|
// Preparation
|
||||||
var err error
|
var err error
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,7 @@ func TestRewardHalvingVanishing(t *testing.T) {
|
||||||
r := new(big.Int).Add(util.RewardHalving(epochReward1, epochRewardTotal, halvingSupply, i), util.RewardHalving(epochReward2, epochRewardTotal, halvingSupply, i))
|
r := new(big.Int).Add(util.RewardHalving(epochReward1, epochRewardTotal, halvingSupply, i), util.RewardHalving(epochReward2, epochRewardTotal, halvingSupply, i))
|
||||||
r.Add(r, util.RewardHalving(epochReward3, epochRewardTotal, halvingSupply, i))
|
r.Add(r, util.RewardHalving(epochReward3, epochRewardTotal, halvingSupply, i))
|
||||||
if r.BitLen() == 0 {
|
if r.BitLen() == 0 {
|
||||||
t.Log("reward be 0 at i=", i) // reward be 0 at i= 11225088, wich is more than 200 years in the future
|
t.Log("reward be 0 at i=", i) // reward be 0 at i= 11225088, which is more than 200 years in the future
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
sum.Add(sum, r)
|
sum.Add(sum, r)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
const maxBlockDist = 7 // Maximum allowed backward distance from the chain head, 7 is just a magic number indicate very close block
|
const maxBlockDist = 7 // Maximum allowed backward distance from the chain head, 7 is just a magic number indicate very close block
|
||||||
|
|
||||||
// Define Boradcast Group functions
|
// Define Broadcast Group functions
|
||||||
type broadcastVoteFn func(*types.Vote)
|
type broadcastVoteFn func(*types.Vote)
|
||||||
type broadcastTimeoutFn func(*types.Timeout)
|
type broadcastTimeoutFn func(*types.Timeout)
|
||||||
type broadcastSyncInfoFn func(*types.SyncInfo)
|
type broadcastSyncInfoFn func(*types.SyncInfo)
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ func TestSequentialVotes(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that avoid boardcast if there is bad vote
|
// Test that avoid broadcast if there is bad vote
|
||||||
func TestNotBoardcastInvalidVote(t *testing.T) {
|
func TestNotBoardcastInvalidVote(t *testing.T) {
|
||||||
tester := newTester()
|
tester := newTester()
|
||||||
handlerCounter := uint32(0)
|
handlerCounter := uint32(0)
|
||||||
|
|
|
||||||
|
|
@ -1427,7 +1427,7 @@ func testFakedSyncProgress(t *testing.T, protocol int, mode SyncMode) {
|
||||||
// This test reproduces an issue where unexpected deliveries would
|
// This test reproduces an issue where unexpected deliveries would
|
||||||
// block indefinitely if they arrived at the right time.
|
// block indefinitely if they arrived at the right time.
|
||||||
func TestDeliverHeadersHang(t *testing.T) {
|
func TestDeliverHeadersHang(t *testing.T) {
|
||||||
t.Skip("This test failed sometimes and is inconsistant result. Disable for now.")
|
t.Skip("This test failed sometimes and is inconsistent result. Disable for now.")
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,11 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
round = r
|
round = r
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
log.Info("[V2 Hook Penalty] parentHeader is nil, wait block to be writen in disk", "parentNumber", parentNumber)
|
log.Info("[V2 Hook Penalty] parentHeader is nil, wait block to be written in disk", "parentNumber", parentNumber)
|
||||||
time.Sleep(time.Second) // 1s
|
time.Sleep(time.Second) // 1s
|
||||||
|
|
||||||
if timeout > 30 { // wait over 30s
|
if timeout > 30 { // wait over 30s
|
||||||
log.Error("[V2 Hook Penalty] parentHeader is nil, wait too long not writen in to disk", "parentNumber", parentNumber)
|
log.Error("[V2 Hook Penalty] parentHeader is nil, wait too long not written in to disk", "parentNumber", parentNumber)
|
||||||
return []common.Address{}, errors.New("parentHeader is nil")
|
return []common.Address{}, errors.New("parentHeader is nil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ type contractTracerConfig struct {
|
||||||
OpCode string `json:"opCode"` // Target opcode to trace
|
OpCode string `json:"opCode"` // Target opcode to trace
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContractTracer returns a native go tracer which tracks the contracr was created
|
// NewContractTracer returns a native go tracer which tracks the contractor was created
|
||||||
func NewContractTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
func NewContractTracer(ctx *tracers.Context, cfg json.RawMessage) (*tracers.Tracer, error) {
|
||||||
var config contractTracerConfig
|
var config contractTracerConfig
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,7 @@ func (w *worker) update() {
|
||||||
defer w.chainHeadSub.Unsubscribe()
|
defer w.chainHeadSub.Unsubscribe()
|
||||||
defer w.chainSideSub.Unsubscribe()
|
defer w.chainSideSub.Unsubscribe()
|
||||||
|
|
||||||
// timeout waiting for v1 inital value
|
// timeout waiting for v1 initial value
|
||||||
minePeriod := 2
|
minePeriod := 2
|
||||||
MinePeriodCh := w.engine.(*XDPoS.XDPoS).MinePeriodCh
|
MinePeriodCh := w.engine.(*XDPoS.XDPoS).MinePeriodCh
|
||||||
defer close(MinePeriodCh)
|
defer close(MinePeriodCh)
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,12 @@
|
||||||
Package protocols is an extension to p2p. It offers a user friendly simple way to define
|
Package protocols is an extension to p2p. It offers a user friendly simple way to define
|
||||||
devp2p subprotocols by abstracting away code standardly shared by protocols.
|
devp2p subprotocols by abstracting away code standardly shared by protocols.
|
||||||
|
|
||||||
* automate assigments of code indexes to messages
|
* automate assignments of code indexes to messages
|
||||||
* automate RLP decoding/encoding based on reflecting
|
* automate RLP decoding/encoding based on reflecting
|
||||||
* provide the forever loop to read incoming messages
|
* provide the forever loop to read incoming messages
|
||||||
* standardise error handling related to communication
|
* standardise error handling related to communication
|
||||||
* standardised handshake negotiation
|
* standardised handshake negotiation
|
||||||
* TODO: automatic generation of wire protocol specification for peers
|
* TODO: automatic generation of wire protocol specification for peers
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package protocols
|
package protocols
|
||||||
|
|
||||||
|
|
@ -65,11 +64,11 @@ var errorToString = map[int]string{
|
||||||
Error implements the standard go error interface.
|
Error implements the standard go error interface.
|
||||||
Use:
|
Use:
|
||||||
|
|
||||||
errorf(code, format, params ...interface{})
|
errorf(code, format, params ...interface{})
|
||||||
|
|
||||||
Prints as:
|
Prints as:
|
||||||
|
|
||||||
<description>: <details>
|
<description>: <details>
|
||||||
|
|
||||||
where description is given by code in errorToString
|
where description is given by code in errorToString
|
||||||
and details is fmt.Sprintf(format, params...)
|
and details is fmt.Sprintf(format, params...)
|
||||||
|
|
@ -265,9 +264,10 @@ func (p *Peer) handleIncoming(handle func(msg interface{}) error) error {
|
||||||
|
|
||||||
// Handshake negotiates a handshake on the peer connection
|
// Handshake negotiates a handshake on the peer connection
|
||||||
// * arguments
|
// * arguments
|
||||||
// * context
|
// - context
|
||||||
// * the local handshake to be sent to the remote peer
|
// - the local handshake to be sent to the remote peer
|
||||||
// * funcion to be called on the remote handshake (can be nil)
|
// - funcion to be called on the remote handshake (can be nil)
|
||||||
|
//
|
||||||
// * expects a remote handshake back of the same type
|
// * expects a remote handshake back of the same type
|
||||||
// * the dialing peer needs to send the handshake first and then waits for remote
|
// * the dialing peer needs to send the handshake first and then waits for remote
|
||||||
// * the listening peer waits for the remote handshake and then sends it
|
// * the listening peer waits for the remote handshake and then sends it
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue