1 module tagion.testbench.genesis_test; 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 import tagion.hibon.BigNumber; 20 21 mixin Main!(_main); 22 23 void wrap_neuewelle(immutable(string)[] args) { 24 neuewelle._main(cast(string[]) args); 25 } 26 27 int _main(string[] args) { 28 29 auto module_path = env.bdd_log.buildPath(__MODULE__); 30 31 if (module_path.exists) { 32 rmdirRecurse(module_path); 33 } 34 mkdirRecurse(module_path); 35 string config_file = buildPath(module_path, "tagionwave.json"); 36 37 scope Options local_options = Options.defaultOptions; 38 local_options.dart.folder_path = buildPath(module_path); 39 local_options.replicator.folder_path = buildPath(module_path, "recorders"); 40 local_options.wave.prefix_format = "Genesis Node_%s_"; 41 local_options.subscription.address = contract_sock_addr("GENESIS_SUBSCRIPTION"); 42 local_options.save(config_file); 43 44 import std.algorithm; 45 import std.array; 46 import std.format; 47 import std.range; 48 import std.stdio; 49 import tagion.crypto.SecureInterfaceNet; 50 import tagion.crypto.SecureNet : StdSecureNet; 51 import tagion.dart.DART; 52 import tagion.dart.DARTBasic; 53 import tagion.dart.DARTFile; 54 import tagion.dart.Recorder; 55 import tagion.hibon.Document; 56 import tagion.hibon.HiBON; 57 import tagion.script.TagionCurrency; 58 import tagion.script.common : TagionBill; 59 import tagion.testbench.services.genesis_test; 60 import tagion.wallet.SecureWallet; 61 62 StdSecureWallet[] wallets; 63 // create the wallets 64 foreach (i; 0 .. 2) { 65 StdSecureWallet secure_wallet; 66 secure_wallet = StdSecureWallet( 67 iota(0, 5).map!(n => format("%dquestion%d", i, n)).array, 68 iota(0, 5).map!(n => format("%danswer%d", i, n)).array, 69 4, 70 format("%04d", i), 71 ); 72 wallets ~= secure_wallet; 73 } 74 75 // bills for the dart on startup 76 77 TagionBill requestAndForce(ref StdSecureWallet w, TagionCurrency amount) { 78 auto b = w.requestBill(amount); 79 w.addBill(b); 80 return b; 81 } 82 83 TagionBill[] bills; 84 BigNumber total_start_amount; 85 foreach (ref wallet; wallets) { 86 foreach (i; 0 .. 3) { 87 auto bill = requestAndForce(wallet, 1000.TGN); 88 bills ~= bill; 89 total_start_amount += bill.value.units; 90 } 91 } 92 93 SecureNet net = new StdSecureNet(); 94 net.generateKeyPair("very_secret"); 95 96 auto factory = RecordFactory(net); 97 auto recorder = factory.recorder; 98 recorder.insert(bills, Archive.Type.ADD); 99 100 // create the tagion head and genesis epoch 101 import tagion.crypto.Types; 102 import tagion.hibon.HiBON; 103 import tagion.hibon.HiBONtoText; 104 import tagion.script.common : GenesisEpoch, TagionGlobals, TagionHead; 105 import tagion.script.standardnames; 106 import tagion.utils.StdTime; 107 108 // const total_amount = BigNumber(bills.map!(b => b.value).sum); 109 const number_of_bills = long(bills.length); 110 111 112 113 Pubkey[] keys; 114 foreach (i; 0 .. local_options.wave.number_of_nodes) { 115 auto _net = new StdSecureNet(); 116 const pswd = format(local_options.wave.prefix_format, i) ~ "supervisor"; 117 writefln("bdd: %s", pswd); 118 _net.generateKeyPair(pswd); 119 keys ~= _net.pubkey; 120 writefln("pkey: %s", _net.pubkey.encodeBase64); 121 } 122 123 HiBON testamony = new HiBON; 124 testamony["hola"] = "Hallo ich bin philip. VERY OFFICIAL TAGION GENESIS BLOCK; DO NOT ALTER IN ANY WAYS"; 125 126 auto globals = TagionGlobals(total_start_amount, const BigNumber(0), number_of_bills, const long(0)); 127 const genesis_epoch = GenesisEpoch(0, keys, Document(testamony), currentTime, globals); 128 const tagion_head = TagionHead(TagionDomain, 0); 129 writefln("total start_amount: %s, HEAD: %s \n genesis_epoch: %s",total_start_amount, tagion_head.toPretty, genesis_epoch.toPretty); 130 131 recorder.add(tagion_head); 132 recorder.add(genesis_epoch); 133 134 135 foreach (i; 0 .. local_options.wave.number_of_nodes) { 136 immutable prefix = format(local_options.wave.prefix_format, i); 137 const path = buildPath(local_options.dart.folder_path, prefix ~ local_options.dart.dart_filename); 138 writeln(path); 139 DARTFile.create(path, net); 140 auto db = new DART(net, path); 141 db.modify(recorder); 142 } 143 144 immutable neuewelle_args = ["genesis_test", config_file, "--nodeopts", module_path]; // ~ args; 145 auto tid = spawn(&wrap_neuewelle, neuewelle_args); 146 147 import tagion.utils.JSONCommon : load; 148 149 Options[] node_opts; 150 151 Thread.sleep(5.seconds); 152 foreach (i; 0 .. local_options.wave.number_of_nodes) { 153 const filename = buildPath(module_path, format(local_options.wave.prefix_format ~ "opts", i).setExtension(FileExtension 154 .json)); 155 writeln(filename); 156 Options node_opt = load!(Options)(filename); 157 node_opts ~= node_opt; 158 } 159 160 Thread.sleep(15.seconds); 161 auto name = "genesis_testing"; 162 register(name, thisTid); 163 log.registerSubscriptionTask(name); 164 165 166 auto feature = automation!(genesis_test); 167 feature.NetworkRunningWithGenesisBlockAndEpochChain(node_opts, wallets[0], genesis_epoch); 168 feature.run; 169 170 stopsignal.set; 171 Thread.sleep(6.seconds); 172 return 0; 173 }