//////////////////////////////////////////////////////////////////////////////// // // // //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // The body of this function lends itself to something like // // ConsensusParticipant::BuildAndPropagateNewBlock() // // Before doing so, ConsensusParticipant would need to accumulate // transactions, possibly negotiate with others as to who makes blocks // etc. FOR NOW, any node can make (and publish) blocks. // func propagate_hash_from_node( h cipher.SHA256, nodePtr *consensus.ConsensusParticipant, external_use bool, external_seqno uint64) { // // WARNING: Do NOT use this code for obtaining any research // results. This file is only an illustration. A realistic // simulation require to have nonzero latencies for event // propagation and to have an event queueu inside the // implementation of MeshNetworkInterface. // o := external_seqno // HACK for DEBUGGING if !external_use { o = nodePtr.GetNextBlockSeqNo() // So that blocks are ordered. } b := consensus.BlockBase{} b.Init( nodePtr.SignatureOf(h), // Signature of hash. h, o) nodePtr.OnBlockHeaderArrived(&b) }
//////////////////////////////////////////////////////////////////////////////// // // main // //////////////////////////////////////////////////////////////////////////////// func main() { var X []*MinimalConnectionManager // Create nodes for i := 0; i < Cfg_simu_num_node; i++ { cm := MinimalConnectionManager{} // Reason for mutual registration: (1) when conn man receives // messages, it needs to notify the node; (2) when node has // processed a mesage, it might need to use conn man to send // some data out. nodePtr := consensus.NewConsensusParticipantPtr(&cm) cm.theNodePtr = nodePtr X = append(X, &cm) } // Contemplate connecting nodes into a thick circle: n := len(X) for i := 0; i < n; i++ { cm := X[i] c_left := int(Cfg_simu_fanout_per_node / 2) c_right := Cfg_simu_fanout_per_node - c_left for c := 0; c < c_left; c++ { j := (i - 1 - c + n) % n cm.RegisterPublisher(X[j]) } for c := 0; c < c_right; c++ { j := (i + 1 + c) % n cm.RegisterPublisher(X[j]) } } // // Request connections // for i := 0; i < n; i++ { X[i].RequestConnectionToAllMyPublisher() } { // // Choose a node to be a block-maker // index := mathrand.Intn(Cfg_simu_num_node) nodePtr := X[index].GetNode() // // Make a block (actually, only a header) // x := secp256k1.RandByte(888) // Random data. h := cipher.SumSHA256(x) // Its hash. b := consensus.BlockBase{} b.Init( nodePtr.SignatureOf(h), h, 0) // // Send it to subscribers. The subscribers are also publishers; // they send (forward, to be exact) the header to thire respective // listeners etc. // nodePtr.OnBlockHeaderArrived(&b) } // // Print the state of each node for a review or debugging. // for i, _ := range X { fmt.Printf("FILE_FinalState.txt|NODE i=%d ", i) X[i].GetNode().Print() fmt.Printf("\n") } }