Liquid 使用方法

三个节点,测试一下p2p广播功能,点到点消息发送功能和节点发现功能

  1. 场景模拟node1 发送广播,node2和node3 订阅,
  2. node1 点对点 发送数据给node2和node3
  3. node2连接node1 , node3连接node2,node1发现node3 节点

代码分别如下

node1

/*
Copyright (C) BABEC. All rights reserved.

SPDX-License-Identifier: Apache-2.0
*/

package main

import (
    "chainmaker.org/chainmaker/common/v2/crypto/asym"
    cmTls "chainmaker.org/chainmaker/common/v2/crypto/tls"
    cmx509 "chainmaker.org/chainmaker/common/v2/crypto/x509"
    "chainmaker.org/chainmaker/common/v2/helper"
    "chainmaker.org/chainmaker/net-liquid/core/host"
    "chainmaker.org/chainmaker/net-liquid/core/peer"
    "chainmaker.org/chainmaker/net-liquid/core/protocol"
    "chainmaker.org/chainmaker/net-liquid/core/util"
    "chainmaker.org/chainmaker/net-liquid/discovery/protocoldiscovery"
    nethost "chainmaker.org/chainmaker/net-liquid/host"
    "chainmaker.org/chainmaker/net-liquid/logger"
    "chainmaker.org/chainmaker/net-liquid/pubsub"
    "context"
    "fmt"
    ma "github.com/multiformats/go-multiaddr"
    "strconv"
    "time"
)

const msg = "Hello!My first LIQUID program demo."
const testProtocolID = "/test"
var (
    addrsTcp = []ma.Multiaddr{
        ma.StringCast("/ip4/127.0.0.1/tcp/7081"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7084"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7085"),
    }


    keyPEMs = [][]byte{
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIDc16StWEUNF0W7iXrT/k0Niy1ZWKbheI2wkjMqJ3WcaoAoGCCqGSM49\nAwEHoUQDQgAEmung19cBCguCaWeyf/nnARHRISTxtaxxf3Zqn+EQxxeYsXqa8oAg\ncalmJaGcmk9kTc0aJwpi7bKvJQdrRg1vFw==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIGLbfX/EvXQtyO+GJvj5rFB0gyTqO3g4gO/gHX2A/BgNoAoGCCqGSM49\nAwEHoUQDQgAE0nVVBXfDQp+EaRbXXfXjn3QG+KYKqApi13+aeNMO7hvS4FlS3B5Z\nMRUCS2oBICwDgLf2q6ef1T5by1u9+IKK7w==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIEUG3DFeXHVr5WjTRfpuSou30zEy2DMmzmyxuSd7F7K9oAoGCCqGSM49\nAwEHoUQDQgAEF+Tvi0fMzJOT9DLS+SFKPIo8kb3ouM54dJ9ibbohpR7FC8Iiid4g\nJ1QNguDjxEmwMV7Q1YiAuighKEmvtb4R+Q==\n-----END EC PRIVATE KEY-----"),
    }

    certPEMs = [][]byte{
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIFPWUuqixxuAwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU2MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTYwHhcNMjEx\nMDI4MDgyMzU3WhcNNDExMDIzMDgyMzU3WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTYx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTYtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAASa6eDX1wEKC4JpZ7J/+ecBEdEhJPG1rHF/\ndmqf4RDHF5ixeprygCBxqWYloZyaT2RNzRonCmLtsq8lB2tGDW8Xo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIOTdkAJ/Fe7PiOnSFe5Fa95mreAwpX2OiK2sB3+Bd86jMCsGA1UdIwQk\nMCKAIKUCNBAgGIS+Af0ucVsMq9ZGS6S2GLlbcDyrtghnqnAnMBkGA1UdEQQSMBCC\nDmhjLW9yZzU2LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQDH+9IoSsBPE33ZRuog\ng9FBCAVj30uuxB08b+eUjbdDGgIhANZ7yABDBk4z9r+gEYtVdFPZdjkEmPa9dYVG\n1u9tUvFy\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcDCCAhegAwIBAgIIJY/rNMZhQFwwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU3MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTcwHhcNMjEx\nMDI4MDgzMDI5WhcNNDExMDIzMDgzMDI5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTcx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTctbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAATSdVUFd8NCn4RpFtdd9eOfdAb4pgqoCmLX\nf5p40w7uG9LgWVLcHlkxFQJLagEgLAOAt/arp5/VPlvLW734gorvo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEII/jHW2D+EGmFFPJupqBoCubnOwYiEF30VGIZjngZIfwMCsGA1UdIwQk\nMCKAIJ6svKRzGIGG9O0Qh0xEizT54wjh7HivJPiATX5h7ZahMBkGA1UdEQQSMBCC\nDmhjLW9yZzU3LW5vZGUxMAoGCCqGSM49BAMCA0cAMEQCIDES1Cz+VE1uiwSDQYDO\noUD9O51G+a3NMnELPp3GZudUAiBe4jJKk1xPU8jIM6yG5B9q3A7CeASpbbISV0tW\nRDLVYw==\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIJFu2YffFkwMwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzY1MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNjUwHhcNMjEx\nMTE1MDUzMjQ5WhcNNDExMTEwMDUzMjQ5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNjUx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNjUtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQX5O+LR8zMk5P0MtL5IUo8ijyRvei4znh0\nn2JtuiGlHsULwiKJ3iAnVA2C4OPESbAxXtDViIC6KCEoSa+1vhH5o4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIGMwbIbdCt+HSL/t2+51nJNAhvH705W8/NnKCj7naO53MCsGA1UdIwQk\nMCKAIIMGhjkBj8VD2+2zAscpecisB5b7dlRdLCJwpce55MSIMBkGA1UdEQQSMBCC\nDmhjLW9yZzY1LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQCSA05P68pGYBCrFoTF\nsPrjx7XN7x1EdFzKb7jnqIc6SQIhAOJYgKkwQQwrXV+yqQJ9XmGRM9I3Ghdvs+Ew\nN4dM580M\n-----END CERTIFICATE-----\n"),
    }

    pidList = []peer.ID{
        "QmVGwL6VXMab7HubwkheZQpJkKKxutqGseJnjg4upWhvDo",
        "Qmav9PUgzrdaLTgJ68XzX9gb4eKLzTonMUpAEsyJRFqV63",
        "QmNQTmmZj8STcDhpKK3izd6q9DT42EuXu7oJyH7Tk1czga",
    }
)


func CreateHostTCP(idx int, seeds map[peer.ID]ma.Multiaddr) (host.Host, error) {
    certPool := cmx509.NewCertPool()
    for i := range certPEMs {
        certPool.AppendCertsFromPEM(certPEMs[i])
    }
    sk, err := asym.PrivateKeyFromPEM(keyPEMs[idx], nil)
    if err != nil {
        return nil, err
    }
    tlsCert, err := cmTls.X509KeyPair(certPEMs[idx], keyPEMs[idx])
    if err != nil {
        return nil, err
    }
    hostCfg := &nethost.HostConfig{
        TlsCfg: &cmTls.Config{
            Certificates:       []cmTls.Certificate{tlsCert},
            InsecureSkipVerify: true,
            ClientAuth:         cmTls.RequireAnyClientCert,
            VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*cmx509.Certificate) error {
                tlsCertBytes := rawCerts[0]
                cert, err := cmx509.ParseCertificate(tlsCertBytes)
                if err != nil {
                    return err
                }
                _, err = cert.Verify(cmx509.VerifyOptions{Roots: certPool})
                if err != nil {
                    return err
                }
                return nil
            },
        },
        LoadPidFunc: func(certificates []*cmx509.Certificate) (peer.ID, error) {
            pid, err := helper.GetLibp2pPeerIdFromCertDer(certificates[0].Raw)
            if err != nil {
                return "", err
            }
            return peer.ID(pid), err
        },
        SendStreamPoolInitSize:    10,
        SendStreamPoolCap:         50,
        PeerReceiveStreamMaxCount: 100,
        ListenAddresses:           []ma.Multiaddr{addrsTcp[idx]},
        DirectPeers:               seeds,
        MsgCompress:               false,
        Insecurity:                false,
        PrivateKey:                sk,
    }

    return hostCfg.NewHost(nethost.TcpNetwork, context.Background(), logger.NewLogPrinter("HOST"+strconv.Itoa(idx)))
}

func TestHostTCP() {
    // create host1 pidList[1]: ma.Join(addr2TargetTcp, ma.StringCast("/p2p/"+pidList[1].ToString()))
    host1, err := CreateHostTCP(0, map[peer.ID]ma.Multiaddr{})
    // register notifee
    notifyBundle := &host.NotifieeBundle{
        PeerConnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已连接,节点ID:%s\n", id)
        },
        PeerDisconnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已断开,节点ID:%s\n", id)
        },
        PeerProtocolSupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s新支持协议%s\n", pid, protocolID)
        },
        PeerProtocolUnsupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s取消支持协议%s\n", pid, protocolID)
        },
    }
    host1.Notify(notifyBundle)
    ps := pubsub.NewChainPubSub("c1635410037173", logger.NewLogPrinter("PubSub"))
    err = ps.AttachHost(host1)
    if err != nil {
        // do something
        panic(err)
    }
    // start hosts
    err = host1.Start()

    err = host1.RegisterMsgPayloadHandler(testProtocolID, func(senderPID peer.ID, msgPayload []byte) {
        fmt.Println(string(msgPayload))
    })


    testTopic := "topic"
    go func() {
        i:=0
        for  {
            i++
            // host1 send msg to host2
            time.Sleep(time.Second)
            err = host1.SendMsg(testProtocolID, pidList[1], []byte(msg))
            err = host1.SendMsg(testProtocolID, pidList[2], []byte(msg))
            ps.Publish(testTopic,[]byte("广播的消息"+strconv.Itoa(i)))
        }
    }()
    // 节点发现服务
    // 10. 开启节点发现服务
    log := logger.NewLogPrinter("TEST")
    discoveryService, err := protocoldiscovery.NewProtocolBasedDiscovery(host1, protocoldiscovery.WithLogger(log))
    if err != nil {
        // do something
        panic(err)
    }
    ctx := context.Background()
    // 11. 宣布自己支持的服务
    err = discoveryService.Announce(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }

    // 12. 搜寻其他节点
    findC, err := discoveryService.FindPeers(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }
    go listenFindingC(ctx,0,host1,findC)
    select {

    }

}

func listenFindingC(ctx context.Context, idx int, h host.Host, c <-chan ma.Multiaddr) {
    for {
        select {
        case <-ctx.Done():
            return
        case ai := <-c:
            fmt.Printf("发现新节点,地址:%s\n", ai.String())
            addr, pid := util.GetNetAddrAndPidFromNormalMultiAddr(ai)
            if pid == "" {
                fmt.Errorf("[Discovery%d] peer id not contains in addr", idx)
                continue
            }
            if h.ConnMgr().PeerCount() >= h.ConnMgr().MaxPeerCountAllowed() || h.ID() == pid || h.ConnMgr().IsConnected(pid) {
                continue
            }
            fmt.Printf("[Discovery%d] find new peer.(pid: %s, addr: %s)", idx, pid, addr.String())
            _, err := h.Dial(ai)
            if err!=nil{
                fmt.Errorf("连接出现错误")
                continue
            }

        }
    }
}

node 2

/*
Copyright (C) BABEC. All rights reserved.

SPDX-License-Identifier: Apache-2.0
*/

package main

import (
    "chainmaker.org/chainmaker/common/v2/crypto/asym"
    cmTls "chainmaker.org/chainmaker/common/v2/crypto/tls"
    cmx509 "chainmaker.org/chainmaker/common/v2/crypto/x509"
    "chainmaker.org/chainmaker/common/v2/helper"
    "chainmaker.org/chainmaker/net-liquid/core/handler"
    "chainmaker.org/chainmaker/net-liquid/core/host"
    "chainmaker.org/chainmaker/net-liquid/core/peer"
    "chainmaker.org/chainmaker/net-liquid/core/protocol"
    "chainmaker.org/chainmaker/net-liquid/core/util"
    "chainmaker.org/chainmaker/net-liquid/discovery/protocoldiscovery"
    nethost "chainmaker.org/chainmaker/net-liquid/host"
    "chainmaker.org/chainmaker/net-liquid/logger"
    "chainmaker.org/chainmaker/net-liquid/pubsub"
    "context"
    "fmt"
    ma "github.com/multiformats/go-multiaddr"
    "strconv"
)

const msg = "Hello!My first LIQUID program demo."
const testProtocolID = "/test"
var (
    addrsTcp = []ma.Multiaddr{
        ma.StringCast("/ip4/127.0.0.1/tcp/7081"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7084"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7085"),
    }


    keyPEMs = [][]byte{
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIDc16StWEUNF0W7iXrT/k0Niy1ZWKbheI2wkjMqJ3WcaoAoGCCqGSM49\nAwEHoUQDQgAEmung19cBCguCaWeyf/nnARHRISTxtaxxf3Zqn+EQxxeYsXqa8oAg\ncalmJaGcmk9kTc0aJwpi7bKvJQdrRg1vFw==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIGLbfX/EvXQtyO+GJvj5rFB0gyTqO3g4gO/gHX2A/BgNoAoGCCqGSM49\nAwEHoUQDQgAE0nVVBXfDQp+EaRbXXfXjn3QG+KYKqApi13+aeNMO7hvS4FlS3B5Z\nMRUCS2oBICwDgLf2q6ef1T5by1u9+IKK7w==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIEUG3DFeXHVr5WjTRfpuSou30zEy2DMmzmyxuSd7F7K9oAoGCCqGSM49\nAwEHoUQDQgAEF+Tvi0fMzJOT9DLS+SFKPIo8kb3ouM54dJ9ibbohpR7FC8Iiid4g\nJ1QNguDjxEmwMV7Q1YiAuighKEmvtb4R+Q==\n-----END EC PRIVATE KEY-----"),
    }

    certPEMs = [][]byte{
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIFPWUuqixxuAwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU2MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTYwHhcNMjEx\nMDI4MDgyMzU3WhcNNDExMDIzMDgyMzU3WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTYx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTYtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAASa6eDX1wEKC4JpZ7J/+ecBEdEhJPG1rHF/\ndmqf4RDHF5ixeprygCBxqWYloZyaT2RNzRonCmLtsq8lB2tGDW8Xo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIOTdkAJ/Fe7PiOnSFe5Fa95mreAwpX2OiK2sB3+Bd86jMCsGA1UdIwQk\nMCKAIKUCNBAgGIS+Af0ucVsMq9ZGS6S2GLlbcDyrtghnqnAnMBkGA1UdEQQSMBCC\nDmhjLW9yZzU2LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQDH+9IoSsBPE33ZRuog\ng9FBCAVj30uuxB08b+eUjbdDGgIhANZ7yABDBk4z9r+gEYtVdFPZdjkEmPa9dYVG\n1u9tUvFy\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcDCCAhegAwIBAgIIJY/rNMZhQFwwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU3MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTcwHhcNMjEx\nMDI4MDgzMDI5WhcNNDExMDIzMDgzMDI5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTcx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTctbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAATSdVUFd8NCn4RpFtdd9eOfdAb4pgqoCmLX\nf5p40w7uG9LgWVLcHlkxFQJLagEgLAOAt/arp5/VPlvLW734gorvo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEII/jHW2D+EGmFFPJupqBoCubnOwYiEF30VGIZjngZIfwMCsGA1UdIwQk\nMCKAIJ6svKRzGIGG9O0Qh0xEizT54wjh7HivJPiATX5h7ZahMBkGA1UdEQQSMBCC\nDmhjLW9yZzU3LW5vZGUxMAoGCCqGSM49BAMCA0cAMEQCIDES1Cz+VE1uiwSDQYDO\noUD9O51G+a3NMnELPp3GZudUAiBe4jJKk1xPU8jIM6yG5B9q3A7CeASpbbISV0tW\nRDLVYw==\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIJFu2YffFkwMwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzY1MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNjUwHhcNMjEx\nMTE1MDUzMjQ5WhcNNDExMTEwMDUzMjQ5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNjUx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNjUtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQX5O+LR8zMk5P0MtL5IUo8ijyRvei4znh0\nn2JtuiGlHsULwiKJ3iAnVA2C4OPESbAxXtDViIC6KCEoSa+1vhH5o4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIGMwbIbdCt+HSL/t2+51nJNAhvH705W8/NnKCj7naO53MCsGA1UdIwQk\nMCKAIIMGhjkBj8VD2+2zAscpecisB5b7dlRdLCJwpce55MSIMBkGA1UdEQQSMBCC\nDmhjLW9yZzY1LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQCSA05P68pGYBCrFoTF\nsPrjx7XN7x1EdFzKb7jnqIc6SQIhAOJYgKkwQQwrXV+yqQJ9XmGRM9I3Ghdvs+Ew\nN4dM580M\n-----END CERTIFICATE-----\n"),
    }

    pidList = []peer.ID{
        "QmVGwL6VXMab7HubwkheZQpJkKKxutqGseJnjg4upWhvDo",
        "Qmav9PUgzrdaLTgJ68XzX9gb4eKLzTonMUpAEsyJRFqV63",
        "QmNQTmmZj8STcDhpKK3izd6q9DT42EuXu7oJyH7Tk1czga",
    }
)

func CreateHostTCP(idx int, seeds map[peer.ID]ma.Multiaddr) (host.Host, error) {
    certPool := cmx509.NewCertPool()
    for i := range certPEMs {
        certPool.AppendCertsFromPEM(certPEMs[i])
    }
    sk, err := asym.PrivateKeyFromPEM(keyPEMs[idx], nil)
    if err != nil {
        return nil, err
    }
    tlsCert, err := cmTls.X509KeyPair(certPEMs[idx], keyPEMs[idx])
    if err != nil {
        return nil, err
    }
    hostCfg := &nethost.HostConfig{
        TlsCfg: &cmTls.Config{
            Certificates:       []cmTls.Certificate{tlsCert},
            InsecureSkipVerify: true,
            ClientAuth:         cmTls.RequireAnyClientCert,
            VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*cmx509.Certificate) error {
                tlsCertBytes := rawCerts[0]
                cert, err := cmx509.ParseCertificate(tlsCertBytes)
                if err != nil {
                    return err
                }
                _, err = cert.Verify(cmx509.VerifyOptions{Roots: certPool})
                if err != nil {
                    return err
                }
                return nil
            },
        },
        LoadPidFunc: func(certificates []*cmx509.Certificate) (peer.ID, error) {
            pid, err := helper.GetLibp2pPeerIdFromCertDer(certificates[0].Raw)
            if err != nil {
                return "", err
            }
            return peer.ID(pid), err
        },
        SendStreamPoolInitSize:    10,
        SendStreamPoolCap:         50,
        PeerReceiveStreamMaxCount: 100,
        ListenAddresses:           []ma.Multiaddr{addrsTcp[idx]},
        DirectPeers:               seeds,
        MsgCompress:               false,
        Insecurity:                false,
        PrivateKey:                sk,
    }
    return hostCfg.NewHost(nethost.TcpNetwork, context.Background(), logger.NewLogPrinter("HOST"+strconv.Itoa(idx)))
}
func TestHostTCP() {
    // create host2 pidList[0]: ma.Join(addrsTcp[0], ma.StringCast("/p2p/"+pidList[0].ToString()))
    host1, _ := CreateHostTCP(1, map[peer.ID]ma.Multiaddr{pidList[0]: ma.Join(addrsTcp[0], ma.StringCast("/p2p/"+pidList[0].ToString()))})

    notifyBundle := &host.NotifieeBundle{
        PeerConnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已连接,节点ID:%s\n", id)
        },
        PeerDisconnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已断开,节点ID:%s\n", id)
        },
        PeerProtocolSupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s新支持协议%s\n", pid, protocolID)
        },
        PeerProtocolUnsupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s取消支持协议%s\n", pid, protocolID)
        },
    }
    host1.Notify(notifyBundle)

    ps := pubsub.NewChainPubSub("c1635410037173", logger.NewLogPrinter("PubSub"))
    err := ps.AttachHost(host1)
    if err != nil {
        // do something
        panic(err)
    }
    testTopic := "topic"
    var subHandler handler.SubMsgHandler = func(publisher peer.ID, topic string, msg []byte) {
        fmt.Printf("收到节点%s向频道%s发布的消息:%s\n", publisher, topic, string(msg))
    }
    ps.Subscribe(testTopic, subHandler)
    // start hosts
    _ = host1.Start()
    // wait for connection established between host1 and host2

    // register msg payload handler
    _ = host1.RegisterMsgPayloadHandler(testProtocolID, func(senderPID peer.ID, msgPayload []byte) {
        fmt.Println("收到Message"+string(msgPayload))
    })

    // 节点发现服务
    // 10. 开启节点发现服务
    log := logger.NewLogPrinter("TEST")
    discoveryService, err := protocoldiscovery.NewProtocolBasedDiscovery(host1, protocoldiscovery.WithLogger(log))
    if err != nil {
        // do something
        panic(err)
    }
    ctx := context.Background()
    // 11. 宣布自己支持的服务
    err = discoveryService.Announce(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }

    // 12. 搜寻其他节点
    findC, err := discoveryService.FindPeers(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }
    go listenFindingC(ctx,1,host1,findC)
    select {

    }

}

func listenFindingC(ctx context.Context, idx int, h host.Host, c <-chan ma.Multiaddr) {
    for {
        select {
        case <-ctx.Done():
            return
        case ai := <-c:
            fmt.Printf("发现新节点,地址:%s\n", ai.String())
            addr, pid := util.GetNetAddrAndPidFromNormalMultiAddr(ai)
            if pid == "" {
                fmt.Errorf("[Discovery%d] peer id not contains in addr", idx)
                continue
            }
            if h.ConnMgr().PeerCount() >= h.ConnMgr().MaxPeerCountAllowed() || h.ID() == pid || h.ConnMgr().IsConnected(pid) {
                continue
            }
            fmt.Printf("[Discovery%d] find new peer.(pid: %s, addr: %s)", idx, pid, addr.String())
            _, _ = h.Dial(ai)
        }
    }
}

node3

/*
Copyright (C) BABEC. All rights reserved.

SPDX-License-Identifier: Apache-2.0
*/

package main

import (
    "chainmaker.org/chainmaker/common/v2/crypto/asym"
    cmTls "chainmaker.org/chainmaker/common/v2/crypto/tls"
    cmx509 "chainmaker.org/chainmaker/common/v2/crypto/x509"
    "chainmaker.org/chainmaker/common/v2/helper"
    "chainmaker.org/chainmaker/net-liquid/core/handler"
    "chainmaker.org/chainmaker/net-liquid/core/host"
    "chainmaker.org/chainmaker/net-liquid/core/peer"
    "chainmaker.org/chainmaker/net-liquid/core/protocol"
    "chainmaker.org/chainmaker/net-liquid/core/util"
    "chainmaker.org/chainmaker/net-liquid/discovery/protocoldiscovery"
    nethost "chainmaker.org/chainmaker/net-liquid/host"
    "chainmaker.org/chainmaker/net-liquid/logger"
    "chainmaker.org/chainmaker/net-liquid/pubsub"
    "context"
    "fmt"
    ma "github.com/multiformats/go-multiaddr"
    "strconv"
)

const msg = "Hello!My first LIQUID program demo."
const testProtocolID = "/test"
var (
    addrsTcp = []ma.Multiaddr{
        ma.StringCast("/ip4/127.0.0.1/tcp/7081"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7084"),
        ma.StringCast("/ip4/127.0.0.1/tcp/7085"),
    }


    keyPEMs = [][]byte{
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIDc16StWEUNF0W7iXrT/k0Niy1ZWKbheI2wkjMqJ3WcaoAoGCCqGSM49\nAwEHoUQDQgAEmung19cBCguCaWeyf/nnARHRISTxtaxxf3Zqn+EQxxeYsXqa8oAg\ncalmJaGcmk9kTc0aJwpi7bKvJQdrRg1vFw==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIGLbfX/EvXQtyO+GJvj5rFB0gyTqO3g4gO/gHX2A/BgNoAoGCCqGSM49\nAwEHoUQDQgAE0nVVBXfDQp+EaRbXXfXjn3QG+KYKqApi13+aeNMO7hvS4FlS3B5Z\nMRUCS2oBICwDgLf2q6ef1T5by1u9+IKK7w==\n-----END EC PRIVATE KEY-----\n"),
        []byte("-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIEUG3DFeXHVr5WjTRfpuSou30zEy2DMmzmyxuSd7F7K9oAoGCCqGSM49\nAwEHoUQDQgAEF+Tvi0fMzJOT9DLS+SFKPIo8kb3ouM54dJ9ibbohpR7FC8Iiid4g\nJ1QNguDjxEmwMV7Q1YiAuighKEmvtb4R+Q==\n-----END EC PRIVATE KEY-----"),
    }

    certPEMs = [][]byte{
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIFPWUuqixxuAwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU2MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTYwHhcNMjEx\nMDI4MDgyMzU3WhcNNDExMDIzMDgyMzU3WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTYx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTYtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAASa6eDX1wEKC4JpZ7J/+ecBEdEhJPG1rHF/\ndmqf4RDHF5ixeprygCBxqWYloZyaT2RNzRonCmLtsq8lB2tGDW8Xo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIOTdkAJ/Fe7PiOnSFe5Fa95mreAwpX2OiK2sB3+Bd86jMCsGA1UdIwQk\nMCKAIKUCNBAgGIS+Af0ucVsMq9ZGS6S2GLlbcDyrtghnqnAnMBkGA1UdEQQSMBCC\nDmhjLW9yZzU2LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQDH+9IoSsBPE33ZRuog\ng9FBCAVj30uuxB08b+eUjbdDGgIhANZ7yABDBk4z9r+gEYtVdFPZdjkEmPa9dYVG\n1u9tUvFy\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcDCCAhegAwIBAgIIJY/rNMZhQFwwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzU3MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNTcwHhcNMjEx\nMDI4MDgzMDI5WhcNNDExMDIzMDgzMDI5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNTcx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNTctbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAATSdVUFd8NCn4RpFtdd9eOfdAb4pgqoCmLX\nf5p40w7uG9LgWVLcHlkxFQJLagEgLAOAt/arp5/VPlvLW734gorvo4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEII/jHW2D+EGmFFPJupqBoCubnOwYiEF30VGIZjngZIfwMCsGA1UdIwQk\nMCKAIJ6svKRzGIGG9O0Qh0xEizT54wjh7HivJPiATX5h7ZahMBkGA1UdEQQSMBCC\nDmhjLW9yZzU3LW5vZGUxMAoGCCqGSM49BAMCA0cAMEQCIDES1Cz+VE1uiwSDQYDO\noUD9O51G+a3NMnELPp3GZudUAiBe4jJKk1xPU8jIM6yG5B9q3A7CeASpbbISV0tW\nRDLVYw==\n-----END CERTIFICATE-----\n"),
        []byte("-----BEGIN CERTIFICATE-----\nMIICcjCCAhegAwIBAgIIJFu2YffFkwMwCgYIKoZIzj0EAwIwZDELMAkGA1UEBhMC\nQ04xEDAOBgNVBAgTB0JlaWppbmcxEDAOBgNVBAcTB0JlaWppbmcxETAPBgNVBAoT\nCGhjLW9yZzY1MQswCQYDVQQLEwJjYTERMA8GA1UEAxMIaGMtb3JnNjUwHhcNMjEx\nMTE1MDUzMjQ5WhcNNDExMTEwMDUzMjQ5WjBxMQswCQYDVQQGEwJDTjEQMA4GA1UE\nCBMHQmVpamluZzEQMA4GA1UEBxMHQmVpamluZzERMA8GA1UEChMIaGMtb3JnNjUx\nEjAQBgNVBAsTCWNvbnNlbnN1czEXMBUGA1UEAxMOaGMtb3JnNjUtbm9kZTEwWTAT\nBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQX5O+LR8zMk5P0MtL5IUo8ijyRvei4znh0\nn2JtuiGlHsULwiKJ3iAnVA2C4OPESbAxXtDViIC6KCEoSa+1vhH5o4GlMIGiMA4G\nA1UdDwEB/wQEAwID+DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwKQYD\nVR0OBCIEIGMwbIbdCt+HSL/t2+51nJNAhvH705W8/NnKCj7naO53MCsGA1UdIwQk\nMCKAIIMGhjkBj8VD2+2zAscpecisB5b7dlRdLCJwpce55MSIMBkGA1UdEQQSMBCC\nDmhjLW9yZzY1LW5vZGUxMAoGCCqGSM49BAMCA0kAMEYCIQCSA05P68pGYBCrFoTF\nsPrjx7XN7x1EdFzKb7jnqIc6SQIhAOJYgKkwQQwrXV+yqQJ9XmGRM9I3Ghdvs+Ew\nN4dM580M\n-----END CERTIFICATE-----\n"),
    }

    pidList = []peer.ID{
        "QmVGwL6VXMab7HubwkheZQpJkKKxutqGseJnjg4upWhvDo",
        "Qmav9PUgzrdaLTgJ68XzX9gb4eKLzTonMUpAEsyJRFqV63",
        "QmNQTmmZj8STcDhpKK3izd6q9DT42EuXu7oJyH7Tk1czga",
    }
)

func CreateHostTCP(idx int, seeds map[peer.ID]ma.Multiaddr) (host.Host, error) {
    certPool := cmx509.NewCertPool()
    for i := range certPEMs {
        certPool.AppendCertsFromPEM(certPEMs[i])
    }
    sk, err := asym.PrivateKeyFromPEM(keyPEMs[idx], nil)
    if err != nil {
        return nil, err
    }
    tlsCert, err := cmTls.X509KeyPair(certPEMs[idx], keyPEMs[idx])
    if err != nil {
        return nil, err
    }
    hostCfg := &nethost.HostConfig{
        TlsCfg: &cmTls.Config{
            Certificates:       []cmTls.Certificate{tlsCert},
            InsecureSkipVerify: true,
            ClientAuth:         cmTls.RequireAnyClientCert,
            VerifyPeerCertificate: func(rawCerts [][]byte, _ [][]*cmx509.Certificate) error {
                tlsCertBytes := rawCerts[0]
                cert, err := cmx509.ParseCertificate(tlsCertBytes)
                if err != nil {
                    return err
                }
                _, err = cert.Verify(cmx509.VerifyOptions{Roots: certPool})
                if err != nil {
                    return err
                }
                return nil
            },
        },
        LoadPidFunc: func(certificates []*cmx509.Certificate) (peer.ID, error) {
            pid, err := helper.GetLibp2pPeerIdFromCertDer(certificates[0].Raw)
            if err != nil {
                return "", err
            }
            return peer.ID(pid), err
        },
        SendStreamPoolInitSize:    10,
        SendStreamPoolCap:         50,
        PeerReceiveStreamMaxCount: 100,
        ListenAddresses:           []ma.Multiaddr{addrsTcp[idx]},
        DirectPeers:               seeds,
        MsgCompress:               false,
        Insecurity:                false,
        PrivateKey:                sk,
    }
    return hostCfg.NewHost(nethost.TcpNetwork, context.Background(), logger.NewLogPrinter("HOST"+strconv.Itoa(idx)))
}
func TestHostTCP() {
    // create host2 pidList[0]: ma.Join(addrsTcp[0], ma.StringCast("/p2p/"+pidList[0].ToString()))
    host1, _ := CreateHostTCP(2, map[peer.ID]ma.Multiaddr{pidList[1]: ma.Join(addrsTcp[1], ma.StringCast("/p2p/"+pidList[1].ToString()))})

    notifyBundle := &host.NotifieeBundle{
        PeerConnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已连接,节点ID:%s\n", id)
        },
        PeerDisconnectedFunc: func(id peer.ID) {
            fmt.Printf("节点已断开,节点ID:%s\n", id)
        },
        PeerProtocolSupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s新支持协议%s\n", pid, protocolID)
        },
        PeerProtocolUnsupportedFunc: func(protocolID protocol.ID, pid peer.ID) {
            fmt.Printf("节点%s取消支持协议%s\n", pid, protocolID)
        },
    }
    host1.Notify(notifyBundle)

    ps := pubsub.NewChainPubSub("c1635410037173", logger.NewLogPrinter("PubSub"))
    err := ps.AttachHost(host1)
    if err != nil {
        // do something
        panic(err)
    }
    testTopic := "topic"
    var subHandler handler.SubMsgHandler = func(publisher peer.ID, topic string, msg []byte) {
        fmt.Printf("收到节点%s向频道%s发布的消息:%s\n", publisher, topic, string(msg))
    }
    ps.Subscribe(testTopic, subHandler)
    // start hosts
    _ = host1.Start()
    // wait for connection established between host1 and host2

    // register msg payload handler
    _ = host1.RegisterMsgPayloadHandler(testProtocolID, func(senderPID peer.ID, msgPayload []byte) {
        fmt.Println("收到Message"+string(msgPayload))
    })

    // 节点发现服务
    // 10. 开启节点发现服务
    log := logger.NewLogPrinter("TEST")
    discoveryService, err := protocoldiscovery.NewProtocolBasedDiscovery(host1, protocoldiscovery.WithLogger(log))
    if err != nil {
        // do something
        panic(err)
    }
    ctx := context.Background()
    // 11. 宣布自己支持的服务
    err = discoveryService.Announce(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }

    // 12. 搜寻其他节点
    findC, err := discoveryService.FindPeers(ctx, testProtocolID)
    if err != nil {
        // do something
        panic(err)
    }
    go listenFindingC(ctx,2,host1,findC)
    select {

    }

}

func listenFindingC(ctx context.Context, idx int, h host.Host, c <-chan ma.Multiaddr) {
    for {
        select {
        case <-ctx.Done():
            return
        case ai := <-c:
            fmt.Printf("发现新节点,地址:%s\n", ai.String())
            addr, pid := util.GetNetAddrAndPidFromNormalMultiAddr(ai)
            if pid == "" {
                fmt.Errorf("[Discovery%d] peer id not contains in addr", idx)
                continue
            }
            if h.ConnMgr().PeerCount() >= h.ConnMgr().MaxPeerCountAllowed() || h.ID() == pid || h.ConnMgr().IsConnected(pid) {
                continue
            }
            fmt.Printf("[Discovery%d] find new peer.(pid: %s, addr: %s)", idx, pid, addr.String())
            _, _ = h.Dial(ai)
        }
    }
}

你可能感兴趣的:(Liquid 使用方法)