You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

487 lines
11 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package main
  2. import (
  3. "container/heap"
  4. "fmt"
  5. "math/rand"
  6. "strings"
  7. )
  8. const seed = 0
  9. const numNodes = 30000 // Total number of nodes to simulate
  10. const minNumPeers = 7 // Each node should be connected to at least this many peers
  11. const maxNumPeers = 10 // ... and at most this many
  12. const latencyMS = int32(500) // One way packet latency
  13. const partTxMS = int32(100) // Transmission time per peer of 4KB of data.
  14. const sendQueueCapacity = 5 // Amount of messages to queue between peers.
  15. func init() {
  16. rand.Seed(seed)
  17. }
  18. //-----------------------------------------------------------------------------
  19. type Peer struct {
  20. node *Node // Pointer to node
  21. sent int32 // Time of last packet send, including transmit time.
  22. remote int // SomeNode.peers[x].node.peers[remote].node is SomeNode for all x.
  23. parts []byte // [32]byte{} bitarray of received block pieces.
  24. }
  25. // Send a data event to the peer, or return false if queue is "full".
  26. // Depending on how many event packets are "queued" for peer,
  27. // the actual recvTime may be adjusted to be later.
  28. func (p *Peer) sendEventData(event EventData) bool {
  29. desiredRecvTime := event.RecvTime()
  30. minRecvTime := p.sent + partTxMS + latencyMS
  31. if desiredRecvTime >= minRecvTime {
  32. p.node.sendEvent(event)
  33. // p.sent + latencyMS == desiredRecvTime
  34. // when desiredRecvTime == minRecvTime,
  35. // p.sent += partTxMS
  36. p.sent = desiredRecvTime - latencyMS
  37. return true
  38. } else {
  39. if (minRecvTime-desiredRecvTime)/partTxMS > sendQueueCapacity {
  40. return false
  41. } else {
  42. event.time = minRecvTime // Adjust recvTime
  43. p.node.sendEvent(event)
  44. p.sent += partTxMS
  45. return true
  46. }
  47. }
  48. }
  49. // Returns true if the sendQueue is not "full"
  50. func (p *Peer) canSendData(now int32) bool {
  51. return (p.sent - now) < sendQueueCapacity
  52. }
  53. // Since EventPart events are much smaller, we don't consider the transmit time,
  54. // and assume that the sendQueue is always free.
  55. func (p *Peer) sendEventParts(event EventParts) {
  56. p.node.sendEvent(event)
  57. }
  58. // Does the peer's .parts (as received by an EventParts event) contain part?
  59. func (p *Peer) knownToHave(part uint8) bool {
  60. return p.parts[part/8]&(1<<(part%8)) > 0
  61. }
  62. //-----------------------------------------------------------------------------
  63. type Node struct {
  64. index int
  65. peers []*Peer
  66. parts []byte
  67. events *Heap
  68. }
  69. func (n *Node) sendEvent(event Event) {
  70. n.events.Push(event, event.RecvTime())
  71. }
  72. func (n *Node) recvEvent() Event {
  73. return n.events.Pop().(Event)
  74. }
  75. func (n *Node) receive(part uint8) bool {
  76. x := n.parts[part/8]
  77. nx := x | (1 << (part % 8))
  78. if x == nx {
  79. return false
  80. } else {
  81. n.parts[part/8] = nx
  82. return true
  83. }
  84. }
  85. // returns false if already connected, or remote node has too many connections.
  86. func (n *Node) canConnectTo(node *Node) bool {
  87. if len(n.peers) > maxNumPeers {
  88. return false
  89. }
  90. for _, peer := range n.peers {
  91. if peer.node == node {
  92. return false
  93. }
  94. }
  95. return true
  96. }
  97. func (n *Node) isFull() bool {
  98. for _, part := range n.parts {
  99. if part != byte(0xff) {
  100. return false
  101. }
  102. }
  103. return true
  104. }
  105. func (n *Node) pickRandomForPeer(peer *Peer) (part uint8, ok bool) {
  106. peerParts := peer.parts
  107. nodeParts := n.parts
  108. randStart := rand.Intn(32)
  109. for i := 0; i < 32; i++ {
  110. bytei := uint8((i + randStart) % 32)
  111. nByte := nodeParts[bytei]
  112. pByte := peerParts[bytei]
  113. iHas := nByte & ^pByte
  114. if iHas > 0 {
  115. randBitStart := rand.Intn(8)
  116. //fmt.Println("//--")
  117. for j := 0; j < 8; j++ {
  118. biti := uint8((j + randBitStart) % 8)
  119. //fmt.Printf("%X %v %v %v\n", iHas, j, biti, randBitStart)
  120. if (iHas & (1 << biti)) > 0 {
  121. return 8*bytei + biti, true
  122. }
  123. }
  124. panic("should not happen")
  125. }
  126. }
  127. return 0, false
  128. }
  129. func (n *Node) debug() {
  130. lines := []string{}
  131. lines = append(lines, n.String())
  132. lines = append(lines, fmt.Sprintf("events: %v, parts: %X", n.events.Len(), n.parts))
  133. for _, p := range n.peers {
  134. part, ok := n.pickRandomForPeer(p)
  135. lines = append(lines, fmt.Sprintf("peer sent: %v, parts: %X, (%v/%v)", p.sent, p.parts, part, ok))
  136. }
  137. fmt.Println("//---------------")
  138. fmt.Println(strings.Join(lines, "\n"))
  139. fmt.Println("//---------------")
  140. }
  141. func (n *Node) String() string {
  142. return fmt.Sprintf("{N:%d}", n.index)
  143. }
  144. //-----------------------------------------------------------------------------
  145. type Event interface {
  146. RecvTime() int32
  147. }
  148. type EventData struct {
  149. time int32 // time of receipt.
  150. src int // src node's peer index on destination node
  151. part uint8
  152. }
  153. func (e EventData) RecvTime() int32 {
  154. return e.time
  155. }
  156. func (e EventData) String() string {
  157. return fmt.Sprintf("[%d:%d:%d]", e.time, e.src, e.part)
  158. }
  159. type EventParts struct {
  160. time int32 // time of receipt.
  161. src int // src node's peer index on destination node.
  162. parts []byte
  163. }
  164. func (e EventParts) RecvTime() int32 {
  165. return e.time
  166. }
  167. func (e EventParts) String() string {
  168. return fmt.Sprintf("[%d:%d:%d]", e.time, e.src, e.parts)
  169. }
  170. //-----------------------------------------------------------------------------
  171. func createNetwork() []*Node {
  172. nodes := make([]*Node, numNodes)
  173. for i := 0; i < numNodes; i++ {
  174. n := &Node{
  175. index: i,
  176. peers: []*Peer{},
  177. parts: make([]byte, 32),
  178. events: NewHeap(),
  179. }
  180. nodes[i] = n
  181. }
  182. for i := 0; i < numNodes; i++ {
  183. n := nodes[i]
  184. for j := 0; j < minNumPeers; j++ {
  185. if len(n.peers) > j {
  186. // Already set, continue
  187. continue
  188. }
  189. pidx := rand.Intn(numNodes)
  190. for !n.canConnectTo(nodes[pidx]) {
  191. pidx = rand.Intn(numNodes)
  192. }
  193. // connect to nodes[pidx]
  194. remote := nodes[pidx]
  195. remote_j := len(remote.peers)
  196. n.peers = append(n.peers, &Peer{node: remote, remote: remote_j, parts: make([]byte, 32)})
  197. remote.peers = append(remote.peers, &Peer{node: n, remote: j, parts: make([]byte, 32)})
  198. }
  199. }
  200. return nodes
  201. }
  202. func printNodes(nodes []*Node) {
  203. for _, node := range nodes {
  204. peerStr := ""
  205. for _, peer := range node.peers {
  206. peerStr += fmt.Sprintf(" %v", peer.node.index)
  207. }
  208. fmt.Printf("[%v] peers: %v\n", node.index, peerStr)
  209. }
  210. }
  211. func countFull(nodes []*Node) (fullCount int) {
  212. for _, node := range nodes {
  213. if node.isFull() {
  214. fullCount += 1
  215. }
  216. }
  217. return fullCount
  218. }
  219. func main() {
  220. // Global vars
  221. nodes := createNetwork()
  222. timeMS := int32(0)
  223. proposer := nodes[0]
  224. for i := 0; i < 32; i++ {
  225. proposer.parts[i] = byte(0xff)
  226. }
  227. //printNodes(nodes[:])
  228. // The proposer sends parts to all of its peers.
  229. for i := 0; i < len(proposer.peers); i++ {
  230. timeMS := int32(0) // scoped
  231. peer := proposer.peers[i]
  232. for j := 0; j < 256; j++ {
  233. // Send each part to a peer, but each peer starts at a different offset.
  234. part := uint8((j + i*(256/len(proposer.peers))) % 256)
  235. recvTime := timeMS + latencyMS + partTxMS
  236. event := EventData{
  237. time: recvTime,
  238. src: peer.remote,
  239. part: part,
  240. }
  241. peer.sendEventData(event)
  242. timeMS += partTxMS
  243. }
  244. }
  245. // Run simulation
  246. for {
  247. // Lets run the simulation for each user until endTimeMS
  248. // We use latencyMS/2 since causality has at least this much lag.
  249. endTimeMS := timeMS + latencyMS/2
  250. fmt.Printf("simulating until %v\n", endTimeMS)
  251. // Print out the network for debugging
  252. if true {
  253. for i := 0; i < 40; i++ {
  254. node := nodes[i]
  255. fmt.Printf("[%v] parts: %X\n", node.index, node.parts)
  256. }
  257. }
  258. for _, node := range nodes {
  259. // Iterate over the events of this node until event.time >= endTimeMS
  260. for {
  261. _event, ok := node.events.Peek().(Event)
  262. if !ok || _event.RecvTime() >= endTimeMS {
  263. break
  264. } else {
  265. node.events.Pop()
  266. }
  267. switch _event.(type) {
  268. case EventData:
  269. event := _event.(EventData)
  270. // Process this event
  271. if !node.receive(event.part) {
  272. // Already has this part, ignore this event.
  273. continue
  274. }
  275. // Let's iterate over peers & see which needs this piece.
  276. for _, peer := range node.peers {
  277. if !peer.knownToHave(event.part) {
  278. peer.sendEventData(EventData{
  279. time: event.time + latencyMS + partTxMS,
  280. src: peer.remote,
  281. part: event.part,
  282. })
  283. } else {
  284. continue
  285. }
  286. }
  287. case EventParts:
  288. event := _event.(EventParts)
  289. node.peers[event.src].parts = event.parts
  290. peer := node.peers[event.src]
  291. // Lets blast the peer with random parts.
  292. randomSent := 0
  293. randomSentErr := 0
  294. for peer.canSendData(event.time) {
  295. part, ok := node.pickRandomForPeer(peer)
  296. if ok {
  297. randomSent += 1
  298. sent := peer.sendEventData(EventData{
  299. time: event.time + latencyMS + partTxMS,
  300. src: peer.remote,
  301. part: part,
  302. })
  303. if !sent {
  304. randomSentErr += 1
  305. }
  306. } else {
  307. break
  308. }
  309. }
  310. /*
  311. if randomSent > 0 {
  312. fmt.Printf("radom sent: %v %v", randomSent, randomSentErr)
  313. }
  314. */
  315. }
  316. }
  317. }
  318. // If network is full, quit.
  319. if countFull(nodes) == numNodes {
  320. fmt.Printf("Done! took %v ms", timeMS)
  321. break
  322. }
  323. // Lets increment the timeMS now
  324. timeMS += latencyMS / 2
  325. // Debug
  326. if timeMS >= 25000 {
  327. nodes[1].debug()
  328. for e := nodes[1].events.Pop(); e != nil; e = nodes[1].events.Pop() {
  329. fmt.Println(e)
  330. }
  331. return
  332. }
  333. // Send EventParts rather frequently. It's cheap.
  334. for _, node := range nodes {
  335. for _, peer := range node.peers {
  336. peer.sendEventParts(EventParts{
  337. time: timeMS + latencyMS,
  338. src: peer.remote,
  339. parts: node.parts,
  340. })
  341. }
  342. newParts := make([]byte, 32)
  343. copy(newParts, node.parts)
  344. node.parts = newParts
  345. }
  346. }
  347. }
  348. // ----------------------------------------------------------------------------
  349. type Heap struct {
  350. pq priorityQueue
  351. }
  352. func NewHeap() *Heap {
  353. return &Heap{pq: make([]*pqItem, 0)}
  354. }
  355. func (h *Heap) Len() int {
  356. return len(h.pq)
  357. }
  358. func (h *Heap) Peek() interface{} {
  359. if len(h.pq) == 0 {
  360. return nil
  361. }
  362. return h.pq[0].value
  363. }
  364. func (h *Heap) Push(value interface{}, priority int32) {
  365. heap.Push(&h.pq, &pqItem{value: value, priority: priority})
  366. }
  367. func (h *Heap) Pop() interface{} {
  368. item := heap.Pop(&h.pq).(*pqItem)
  369. return item.value
  370. }
  371. /*
  372. func main() {
  373. h := NewHeap()
  374. h.Push(String("msg1"), 1)
  375. h.Push(String("msg3"), 3)
  376. h.Push(String("msg2"), 2)
  377. fmt.Println(h.Pop())
  378. fmt.Println(h.Pop())
  379. fmt.Println(h.Pop())
  380. }
  381. */
  382. ///////////////////////
  383. // From: http://golang.org/pkg/container/heap/#example__priorityQueue
  384. type pqItem struct {
  385. value interface{}
  386. priority int32
  387. index int
  388. }
  389. type priorityQueue []*pqItem
  390. func (pq priorityQueue) Len() int { return len(pq) }
  391. func (pq priorityQueue) Less(i, j int) bool {
  392. return pq[i].priority < pq[j].priority
  393. }
  394. func (pq priorityQueue) Swap(i, j int) {
  395. pq[i], pq[j] = pq[j], pq[i]
  396. pq[i].index = i
  397. pq[j].index = j
  398. }
  399. func (pq *priorityQueue) Push(x interface{}) {
  400. n := len(*pq)
  401. item := x.(*pqItem)
  402. item.index = n
  403. *pq = append(*pq, item)
  404. }
  405. func (pq *priorityQueue) Pop() interface{} {
  406. old := *pq
  407. n := len(old)
  408. item := old[n-1]
  409. item.index = -1 // for safety
  410. *pq = old[0 : n-1]
  411. return item
  412. }
  413. func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority int32) {
  414. heap.Remove(pq, item.index)
  415. item.value = value
  416. item.priority = priority
  417. heap.Push(pq, item)
  418. }