package main import ( "blockchain/attacker" "blockchain/config" "blockchain/p2p" "fmt" "math" "math/rand" "time" ) func main() { cfg := &config.Default numNodes := cfg.Sim.NumNodes hashDelay := cfg.Sim.HashDelay expectedBlock := time.Duration(float64(hashDelay) * math.Pow(16, float64(cfg.Chain.Difficulty)) / float64(numNodes)) cfg.P2P.NetDelay = expectedBlock / 300 fmt.Printf("Starting honest network: %d nodes, difficulty=%d\n", numNodes, cfg.Chain.Difficulty) // 1. Start honest network stop := make(chan struct{}) nodes := make([]*p2p.Node, numNodes) for i := range nodes { nodes[i] = p2p.NewNode() nodes[i].HashDelay = hashDelay for _, j := range rand.Perm(i)[:min(cfg.P2P.OutboundPeers, i)] { nodes[i].AddPeer(nodes[j]) nodes[j].AddPeer(nodes[i]) } go nodes[i].Run(stop) } // Let the network mine a few blocks first fmt.Println("Waiting for network to mine some blocks...") time.Sleep(5 * time.Second) // 2. Create attacker node and connect to network evil := attacker.NewNode() evil.HashDelay = hashDelay // Connect to a few honest nodes (like joining the network) for _, j := range rand.Perm(len(nodes))[:min(3, len(nodes))] { evil.AddPeer(nodes[j]) nodes[j].AddPeer(evil) } fmt.Printf("\n[ATTACKER] Joined network as %s\n", evil.ShortID()) fmt.Printf("[ATTACKER] Modify attacker/node.go Run() to implement your attack!\n\n") go evil.Run(stop) // Wait select {} }