1 module tagion.testbench.malformed_contract;
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.actor;
10 import tagion.basic.Types : FileExtension;
11 import tagion.behaviour.Behaviour;
12 import tagion.logger.Logger;
13 import tagion.services.options;
14 import tagion.testbench.services;
15 import tagion.testbench.tools.Environment;
16 import tagion.tools.Basic;
17 import neuewelle = tagion.tools.neuewelle;
18 import tagion.utils.pretend_safe_concurrency;
19 
20 mixin Main!(_main);
21 
22 void wrap_neuewelle(immutable(string)[] args) {
23     neuewelle._main(cast(string[]) args);
24 }
25 
26 int _main(string[] args) {
27     auto module_path = env.bdd_log.buildPath(__MODULE__);
28 
29     if (module_path.exists) {
30         rmdirRecurse(module_path);
31     }
32     mkdirRecurse(module_path);
33     string config_file = buildPath(module_path, "tagionwave.json");
34 
35     scope Options local_options = Options.defaultOptions;
36     local_options.dart.folder_path = buildPath(module_path);
37     local_options.replicator.folder_path = buildPath(module_path, "recorders");
38     local_options.wave.prefix_format = "Malformed Contract Node_%s_";
39     local_options.subscription.address = contract_sock_addr("MALFORMED_SUBSCRIPTION");
40 
41     local_options.save(config_file);
42 
43     import std.algorithm;
44     import std.array;
45     import std.format;
46     import std.range;
47     import std.stdio;
48     import tagion.crypto.SecureInterfaceNet;
49     import tagion.crypto.SecureNet : StdSecureNet;
50     import tagion.dart.DART;
51     import tagion.dart.DARTBasic;
52     import tagion.dart.DARTFile;
53     import tagion.dart.Recorder;
54     import tagion.hibon.Document;
55     import tagion.hibon.HiBON;
56     import tagion.script.TagionCurrency;
57     import tagion.script.common : TagionBill;
58     import tagion.testbench.services.sendcontract;
59     import tagion.wallet.SecureWallet;
60 
61     StdSecureWallet[] wallets;
62     // create the wallets
63     foreach (i; 0 .. 20) {
64         StdSecureWallet secure_wallet;
65         secure_wallet = StdSecureWallet(
66                 iota(0, 5).map!(n => format("%dquestion%d", i, n)).array,
67                 iota(0, 5).map!(n => format("%danswer%d", i, n)).array,
68                 4,
69                 format("%04d", i),
70         );
71         wallets ~= secure_wallet;
72     }
73 
74     // bills for the dart on startup
75 
76     TagionBill requestAndForce(ref StdSecureWallet w, TagionCurrency amount) {
77         auto b = w.requestBill(amount);
78         w.addBill(b);
79         return b;
80     }
81 
82     TagionBill[] bills;
83     foreach (ref wallet; wallets) {
84         foreach (i; 0 .. 3) {
85             bills ~= requestAndForce(wallet, 1000.TGN);
86         }
87     }
88 
89     SecureNet net = new StdSecureNet();
90     net.generateKeyPair("very_secret");
91 
92     auto factory = RecordFactory(net);
93     auto recorder = factory.recorder;
94     recorder.insert(bills, Archive.Type.ADD);
95 
96     // put a random archive in that is not a bill.
97 
98     auto random_data = new HiBON;
99     random_data["wowo"] = "test";
100 
101     const random_doc = Document(random_data);
102     recorder.insert(random_doc, Archive.Type.ADD);
103 
104     immutable(DARTIndex) random_fingerprint = wallets[0].net.dartIndex(random_doc);
105     writefln("RANDOM FINGERPRINT %(%02x%)", random_fingerprint);
106 
107     foreach (i; 0 .. local_options.wave.number_of_nodes) {
108         immutable prefix = format(local_options.wave.prefix_format, i);
109         const path = buildPath(local_options.dart.folder_path, prefix ~ local_options.dart.dart_filename);
110         writeln(path);
111         DARTFile.create(path, net);
112         auto db = new DART(net, path);
113         db.modify(recorder);
114     }
115 
116     immutable neuewelle_args = ["malformed_contract_test", config_file, "--nodeopts", module_path]; // ~ args;
117     auto tid = spawn(&wrap_neuewelle, neuewelle_args);
118 
119     import tagion.utils.JSONCommon : load;
120 
121     Options[] node_opts;
122 
123     Thread.sleep(5.seconds);
124     foreach (i; 0 .. local_options.wave.number_of_nodes) {
125         const filename = buildPath(module_path, format(local_options.wave.prefix_format ~ "opts", i).setExtension(FileExtension
126                 .json));
127         writeln(filename);
128         Options node_opt = load!(Options)(filename);
129         node_opts ~= node_opt;
130     }
131 
132     auto name = "malformed_testing";
133     register(name, thisTid);
134     log.registerSubscriptionTask(name);
135 
136     writefln("INPUT SOCKET ADDRESS %s", node_opts[0].inputvalidator.sock_addr);
137 
138     auto feature = automation!(malformed_contract);
139     feature.ContractTypeWithoutCorrectInformation(node_opts[0], wallets[0]);
140     auto feature_context = feature.run;
141 
142 
143     bool epoch_on_startup = feature_context[0].epoch_on_startup;
144 
145     feature.InputsAreNotBillsInDart(node_opts[1], wallets[1], random_doc, epoch_on_startup);
146     feature.NegativeAmountAndZeroAmountOnOutputBills(node_opts[2], wallets[2], epoch_on_startup);
147     feature.ContractWhereInputIsSmallerThanOutput(node_opts[3], wallets[3], epoch_on_startup);
148 
149     feature.run;
150     Thread.sleep(15.seconds);
151 
152     stopsignal.set;
153     Thread.sleep(6.seconds);
154     return 0;
155 }