-
Notifications
You must be signed in to change notification settings - Fork 1
/
utils.go
141 lines (114 loc) · 3.31 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"github.com/chain-lab/go-norn/common"
"github.com/chain-lab/go-norn/crypto"
"github.com/chain-lab/go-norn/node"
"github.com/libp2p/go-libp2p"
dht "github.com/libp2p/go-libp2p-kad-dht"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
"github.com/multiformats/go-multiaddr"
log "github.com/sirupsen/logrus"
karmem "karmem.org/golang"
"time"
)
func NewKDHT(ctx context.Context, host host.Host, bootstrapPeers []multiaddr.Multiaddr) (*dht.IpfsDHT, error) {
// fixed(230918): 和 bootstrap 建立连接后不再创建新的流
// dht 的配置项
var options []dht.Option
// 如果没有引导节点,以服务器模式 ModeServer 启动
//if len(bootstrapPeers) == 0 {
options = append(options, dht.Mode(dht.ModeServer))
//log.Infoln("Start node as a bootstrap server.")
//}
// 生成一个 DHT 实例
kdht, err := dht.New(ctx, host, options...)
if err != nil {
return nil, err
}
// 启动 DHT 服务
if err = kdht.Bootstrap(ctx); err != nil {
return nil, err
}
// 遍历引导节点数组并尝试连接
for _, peerAddr := range bootstrapPeers {
peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)
if err := host.Connect(ctx, *peerinfo); err != nil {
log.Printf("Error while connecting to node %q: %-v", peerinfo, err)
continue
} else {
log.Infof("Connection established with bootstrap node: %q",
*peerinfo)
}
}
return kdht, nil
}
func sendTransaction(pm *node.P2PManager) {
//log.Infof("Start send transactions.")
prv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
//ticket := time.NewTicker(1 * time.Millisecond)
for {
//select {
//case <-ticket.C:
tx := buildTransaction(prv)
pm.AddTransaction(tx)
//}
}
}
func buildResourceManager() *network.ResourceManager {
scalingLimits := rcmgr.DefaultLimits
libp2p.SetDefaultServiceLimits(&scalingLimits)
scaledDefaultLimits := scalingLimits.AutoScale()
cfg := rcmgr.PartialLimitConfig{
System: rcmgr.ResourceLimits{
//Conns: 20,
Streams: 50,
},
}
limits := cfg.Build(scaledDefaultLimits)
limiter := rcmgr.NewFixedLimiter(limits)
rm, err := rcmgr.NewResourceManager(limiter)
if err != nil {
log.Errorln("Build resource manager failed.")
return nil
}
return &rm
}
func buildTransaction(key *ecdsa.PrivateKey) *common.Transaction {
data := make([]byte, 32)
rand.Read(data)
timestamp := time.Now().UnixMilli()
txBody := common.TransactionBody{
Data: data,
Timestamp: timestamp,
Expire: timestamp + 3000,
}
txBody.Public = [33]byte(crypto.PublicKey2Bytes(&key.PublicKey))
txBody.Address = crypto.PublicKeyBytes2Address(txBody.Public)
txBody.Hash = [32]byte{}
txBody.Signature = []byte{}
writer := karmem.NewWriter(1024)
txBody.WriteAsRoot(writer)
txBodyBytes := writer.Bytes()
hash := sha256.New()
hash.Write(txBodyBytes)
txHashBytes := hash.Sum(nil)
txSignatureBytes, err := ecdsa.SignASN1(rand.Reader, key, txHashBytes)
if err != nil {
log.WithField("error", err).Errorln("Sign transaction failed.")
return nil
}
txBody.Hash = [32]byte(txHashBytes)
txBody.Signature = txSignatureBytes
tx := common.Transaction{
Body: txBody,
}
return &tx
}