1 module tagion.testbench.spam_double_spend; 2 3 import core.thread; 4 import core.time; 5 import std.file; 6 import std.path : buildPath, setExtension; 7 import std.stdio; 8 import tagion.GlobalSignals; 9 import tagion.basic.Types : FileExtension; 10 import tagion.behaviour.Behaviour; 11 import tagion.services.options; 12 import tagion.testbench.services; 13 import tagion.testbench.tools.Environment; 14 import tagion.tools.Basic; 15 import neuewelle = tagion.tools.neuewelle; 16 import tagion.utils.pretend_safe_concurrency; 17 18 mixin Main!(_main); 19 20 void wrap_neuewelle(immutable(string)[] args) { 21 neuewelle._main(cast(string[]) args); 22 } 23 24 int _main(string[] args) { 25 auto module_path = env.bdd_log.buildPath(__MODULE__); 26 27 if (module_path.exists) { 28 rmdirRecurse(module_path); 29 } 30 mkdirRecurse(module_path); 31 string config_file = buildPath(module_path, "tagionwave.json"); 32 33 scope Options local_options = Options.defaultOptions; 34 local_options.dart.folder_path = buildPath(module_path); 35 local_options.replicator.folder_path = buildPath(module_path, "recorders"); 36 local_options.wave.prefix_format = "Spam_DoubleSpend_Node_%s_"; 37 local_options.subscription.address = contract_sock_addr("SPAM_SUBSCRIPTION"); 38 39 local_options.save(config_file); 40 41 import std.algorithm; 42 import std.array; 43 import std.format; 44 import std.range; 45 import std.stdio; 46 import tagion.crypto.SecureInterfaceNet; 47 import tagion.crypto.SecureNet : StdSecureNet; 48 import tagion.dart.DART; 49 import tagion.dart.DARTFile; 50 import tagion.dart.Recorder; 51 import tagion.script.TagionCurrency; 52 import tagion.script.common : TagionBill; 53 import tagion.testbench.services.sendcontract; 54 import tagion.wallet.SecureWallet; 55 56 StdSecureWallet[] wallets; 57 // create the wallets 58 foreach (i; 0 .. 20) { 59 StdSecureWallet secure_wallet; 60 secure_wallet = StdSecureWallet( 61 iota(0, 5).map!(n => format("%dquestion%d", i, n)).array, 62 iota(0, 5).map!(n => format("%danswer%d", i, n)).array, 63 4, 64 format("%04d", i), 65 ); 66 wallets ~= secure_wallet; 67 } 68 69 // bills for the dart on startup 70 71 TagionBill requestAndForce(ref StdSecureWallet w, TagionCurrency amount) { 72 auto b = w.requestBill(amount); 73 w.addBill(b); 74 return b; 75 } 76 77 TagionBill[] bills; 78 foreach (ref wallet; wallets) { 79 foreach (i; 0 .. 3) { 80 bills ~= requestAndForce(wallet, 1000.TGN); 81 } 82 } 83 84 SecureNet net = new StdSecureNet(); 85 net.generateKeyPair("very_secret"); 86 87 auto factory = RecordFactory(net); 88 auto recorder = factory.recorder; 89 recorder.insert(bills, Archive.Type.ADD); 90 91 foreach (i; 0 .. local_options.wave.number_of_nodes) { 92 immutable prefix = format(local_options.wave.prefix_format, i); 93 const path = buildPath(local_options.dart.folder_path, prefix ~ local_options.dart.dart_filename); 94 writeln(path); 95 DARTFile.create(path, net); 96 auto db = new DART(net, path); 97 db.modify(recorder); 98 db.close; 99 } 100 101 immutable neuewelle_args = ["spam_double_spend_test", config_file, "--nodeopts", module_path]; // ~ args; 102 auto tid = spawn(&wrap_neuewelle, neuewelle_args); 103 104 import tagion.utils.JSONCommon : load; 105 106 Options[] node_opts; 107 108 Thread.sleep(15.seconds); 109 foreach (i; 0 .. local_options.wave.number_of_nodes) { 110 const filename = buildPath(module_path, format(local_options.wave.prefix_format ~ "opts", i).setExtension(FileExtension 111 .json)); 112 writeln(filename); 113 Options node_opt = load!(Options)(filename); 114 node_opts ~= node_opt; 115 } 116 117 writefln("INPUT SOCKET ADDRESS %s", node_opts[0].inputvalidator.sock_addr); 118 119 auto feature = automation!(spam_double_spend); 120 feature.SpamOneNodeUntil10EpochsHaveOccured(node_opts, wallets[0], wallets[1]); 121 feature.SpamMultipleNodesUntil10EpochsHaveOccured(node_opts, wallets[2], wallets[3]); 122 123 feature.run(); 124 125 stopsignal.set; 126 Thread.sleep(6.seconds); 127 return 0; 128 }