@@ -1,205 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package main | |||
import "os" | |||
import "fmt" | |||
import "time" | |||
import "testing" | |||
import "path/filepath" | |||
import "runtime/pprof" | |||
//import "encoding/hex" | |||
import "github.com/deroproject/derosuite/simulator" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
//import "github.com/deroproject/derosuite/globals" | |||
import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
import "github.com/deroproject/derosuite/blockchain" | |||
func main() { | |||
var t testing.T | |||
f, err := os.Create("cpu.prof") | |||
if err != nil { | |||
fmt.Printf("%s\n", err) | |||
return | |||
} | |||
pprof.StartCPUProfile(f) | |||
defer pprof.StopCPUProfile() | |||
QTest_Basic_Simulator(&t) | |||
} | |||
// testing basic functionality of block chain, whether the chain can be extended and balances decoded | |||
// mem pool okay etc | |||
func QTest_Basic_Simulator(t *testing.T) { | |||
/*// override simulation hard fork | |||
blockchain.Simulation_hard_forks = []blockchain.Hard_fork{ | |||
{1, 0, 0, 0, 0, true}, // version 1 hard fork where genesis block landed | |||
{6, 1, 0, 0, 0, true}, // version 6 hard fork where we started , it's mandatory | |||
{7, 40, 31, 60, 00, false}, // version 7 hard fork where we started , threshold is 60 % means atleast 18 votes should be in favor, from block 10 till block 40 | |||
}*/ | |||
// start the simulator ( mine genesis block ) | |||
sim, _ := simulator.Init_Simulator(config.Testnet) | |||
//defer sim.Stop() | |||
// create 3 wallets, w1,w2,w3 | |||
temp_db := filepath.Join(os.TempDir(), "test_w1.db") | |||
os.Remove(temp_db) | |||
w1, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", crypto.HexToKey("366c28ae6fcdf4885c6c830de792e630ec5c2e61c4dc5cca9259ab2006ee1b05")) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w2.db") | |||
os.Remove(temp_db) | |||
w2, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", crypto.HexToKey("f3abe1ad37402b6f026e2ced1fd44d6eea692d68c43ae9886752ee62752d5706")) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w3.db") | |||
os.Remove(temp_db) | |||
w3, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", crypto.HexToKey("108059799dcd40b9a9f91d9f1dda5710ae0a10d7b355adf04f751788a813100e")) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
_ = w2 | |||
_ = w3 | |||
// mine the first block and get reward | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
*/ | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
for i := 0; i < 70; i++ { | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance_Rescan() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
// */ | |||
// add a random block to random miner | |||
// random insert 3 ( so called orphan blocks in blockchain tech) | |||
if i%5 == 0 { | |||
sim.Mine_New_Block_Address_Alternate(w1.GetAddress(), 3) | |||
} else { | |||
sim.Mine_New_Block() // mine block after genesis block | |||
} | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
} | |||
t.Logf("Chain height %d done", sim.Chain.Get_Height()) | |||
// now lets rescan a wallet and build a TX | |||
// sync the wallets | |||
w1.Sync_Wallet_With_Daemon() | |||
tx, _, _, _, err := w1.Transfer([]address.Address{w3.GetAddress()}, []uint64{1000000000000}, 0, "", 25037535000, 0) | |||
if err != nil { | |||
t.Fatalf("Error creating transaction err %s", err) | |||
} | |||
if !sim.Chain.Mempool.Mempool_Add_TX(tx, 0) { | |||
t.Fatalf("Add TX to pool failed ") | |||
} | |||
sim.Mine_New_Block_Address_Alternate(w1.GetAddress(), 2) // mine the TX in 2 alt blocks | |||
sim.Mine_New_Block() // lets join the tips together | |||
sim.Mine_New_Block() // lets mine another block to trigger client_protocol in reverse and then fix it up | |||
/* for i := 0; i <100; i++{ | |||
sim.Mine_New_Block() | |||
} | |||
*/ | |||
w3.Sync_Wallet_With_Daemon() | |||
time.Sleep(10 * time.Second) | |||
unlocked, locked := w3.Get_Balance_Rescan() | |||
fmt.Printf("Balance %d locked %d unlocked ", locked, unlocked) | |||
/* blocks := sim.Chain.Get_Blocks_At_Height(3) | |||
past := sim.Chain.Get_Past_Unsettled(blocks[0]) | |||
// past := sim.Chain.Get_Past_Unsettled(crypto.HashHexToHash("78845caac717c18e34682c2390b49de7e73e69633cc5f7eb2ce3f62948ddb8cd")) | |||
t.Logf("Past of %s is %+v\n", blocks[0],past) | |||
for k,_ := range past { | |||
t.Logf("Past %s\n", k) | |||
} | |||
*/ | |||
//blocks = sim.Chain.Get_Blocks_At_Height(7) | |||
/* | |||
future := sim.Chain.Get_Future_Unsettled(blocks[0]) | |||
t.Logf("Future of %s is %+v\n", blocks[0],future) | |||
for k,_ := range future { | |||
t.Logf("Future %s\n", k) | |||
} | |||
dag := sim.Chain.Get_DAG_Unsettled_Cached() | |||
for k,_ := range dag { // for all nodes find the anticone | |||
dag_copy := sim.Chain.Get_AntiCone_Unsettled(k) | |||
fmt.Printf("Anticone of %s is %d\n", k, len(dag_copy)) | |||
if len(dag_copy) == 0 { | |||
// order := sim.Chain.Generate_Full_Order(k,0) | |||
// | |||
//for i := range order { | |||
// t.Logf("%2d %s", i,order[i]) | |||
//} | |||
} | |||
} | |||
*/ | |||
if sim.Chain.Get_Height() < 100 { | |||
blockchain.WriteBlockChainTree(sim.Chain, "/tmp/graph.dot") | |||
t.Logf("Written graph") | |||
} | |||
time.Sleep(500 * time.Second) | |||
} |
@@ -1,235 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
// this package builds up a testnet/mainnet simulator with temporary databases for wide variety of simulation and testing | |||
// this is required for further development and testing of blockchain,smart-contracts and related DAPPs | |||
// the simulator will have hard-coded difficulty set to 1 | |||
// the simulator will expose the RPC interface, so as the explorer and other programs can be developed/tested | |||
package simulator | |||
//import "fmt" | |||
//import _ "unsafe" // enable golink to enable difficulty package in simulation mode | |||
//import mrand "math/rand" | |||
//import "crypto/rand" | |||
//import "encoding/binary" | |||
import "github.com/sirupsen/logrus" | |||
//import "github.com/vmihailenco/msgpack" | |||
import "github.com/deroproject/derosuite/block" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/globals" | |||
import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
import "github.com/deroproject/derosuite/blockchain" | |||
//import "github.com/deroproject/derosuite/block" | |||
import "github.com/deroproject/derosuite/blockchain/rpcserver" | |||
type Simulator struct { | |||
Chain *blockchain.Blockchain | |||
rpc *rpcserver.RPCServer | |||
} | |||
// use unsafe to bring difficulty in simulation mode | |||
////go:linkname difficulty_simulation_mode github.com/deroproject/derosuite/difficulty.simulation | |||
//var difficulty_simulation_mode bool | |||
// initialize a simulator instance | |||
func Init_Simulator(c config.CHAIN_CONFIG) (*Simulator, error) { | |||
var sim Simulator | |||
// manually initialize globals ( simulator does not need socks proxy ) | |||
globals.Config = c | |||
globals.Logger = logrus.New() | |||
globals.Logger.SetLevel(logrus.DebugLevel) | |||
// enable difficulty over-ride to hard-code value 1 | |||
//difficulty_simulation_mode = true // set difficulty to simulation mode | |||
params := map[string]interface{}{} | |||
params["--disable-checkpoints"] = true // do NOT enforce checkpoints while simulating | |||
params["--simulator"] = true | |||
chain, _ := blockchain.Blockchain_Start(params) | |||
params["chain"] = chain | |||
sim.Chain = chain | |||
sim.rpc, _ = rpcserver.RPCServer_Start(params) | |||
return &sim, nil | |||
} | |||
// this will mine a new block with random miner address ( miner reward cannot be claimed ) | |||
func (sim *Simulator) Mine_New_Block() bool { | |||
account, _ := walletapi.Generate_Keys_From_Random() // create a random address | |||
return sim.Mine_New_Block_Address(account.GetAddress()) // mine new block at that address | |||
} | |||
// this will mine a new block with specific miner address | |||
func (sim *Simulator) Mine_New_Block_Address(addr address.Address) bool { | |||
junk := block.Block{} | |||
_ = junk | |||
tips := sim.Chain.Get_TIPS() | |||
height := sim.Chain.Calculate_Height_At_Tips(nil, tips) | |||
_ = height | |||
cbl, bl := sim.Chain.Create_new_miner_block(addr) | |||
cbl.Bl = &bl | |||
/* | |||
// bl.Major_Version = uint64(sim.Chain.Get_Current_Version_at_Height(height)) | |||
//bl.Minor_Version = uint64(sim.Chain.Get_Ideal_Version_at_Height(height)) | |||
//bl.Timestamp = 0 // first block timestamp | |||
bl.Tips = bl.Tips[:0] | |||
b := make([]byte, 4) | |||
switch len(tips) { | |||
case 1 : | |||
bl.Tips = append(bl.Tips,tips[0]) | |||
// add a random nonce | |||
rand.Read(b) // assumming it will never fail | |||
mrand.Read(b) | |||
cbl.Bl.Nonce = binary.LittleEndian.Uint32(b) | |||
sim.Chain.Add_Complete_Block(cbl) // add 1 block | |||
var err error | |||
bl.Miner_TX,err = blockchain.Create_Miner_TX2(int64(bl.Major_Version),height,addr) | |||
if err != nil { | |||
fmt.Printf("Error while creating miner tx , err %s", err) | |||
} | |||
case 2 : // randomly include one or the tips | |||
if mrand.Intn(3) == 0 { | |||
bl.Tips = tips | |||
}else{ | |||
bl.Tips = append(bl.Tips,tips[mrand.Intn(len(tips))]) | |||
// also choose another tip from other nodes past | |||
for i := range tips{ | |||
if tips[i] != bl.Tips[0] { | |||
// load tips from pasts tips | |||
bl2,err := sim.Chain.Load_BL_FROM_ID(nil,tips[i]) | |||
if err != nil { | |||
panic(fmt.Sprintf("Block NOT found %s", tips[i])) | |||
} | |||
bl.Tips = append(bl.Tips,bl2.Tips[0]) | |||
} | |||
} | |||
} | |||
case 3: | |||
bl.Tips = tips | |||
} | |||
//cbl, _ := sim.Chain.Create_new_miner_block(sim.Chain.Get_Top_ID(), addr, 0) // create a new block with | |||
// TODO enable mechanisms to patch the block here | |||
// TODO add any tx from the pool if required | |||
rand.Read(b) // assumming it will never fail | |||
mrand.Read(b) | |||
cbl.Bl.Nonce = binary.LittleEndian.Uint32(b) | |||
*/ | |||
// mine the block means extend the chain , simulator mode difficulty is always 1 so everything passes thorough | |||
_, status := sim.Chain.Add_Complete_Block(cbl) | |||
return status | |||
} | |||
// this function will attach alt count blocks with the current tip | |||
// this gives the oppurtunity for easier testing | |||
// all the blocks except first one will be alt blocks | |||
// mempool will be processed and will be common while building the blocks | |||
func (sim *Simulator) Mine_New_Block_Address_Alternate(addr address.Address, alt_count int) bool { | |||
var cbl_array []*block.Complete_Block | |||
for i := 0; i < alt_count; i++ { | |||
cbl, _ := sim.Chain.Create_new_miner_block(addr) | |||
cbl_array = append(cbl_array, cbl) | |||
} | |||
for i := range cbl_array { | |||
sim.Chain.Add_Complete_Block(cbl_array[i]) | |||
} | |||
return true | |||
} | |||
// stop the simulator instance freeing resource | |||
func (sim *Simulator) Stop() { | |||
sim.rpc.RPCServer_Stop() // stop rpc server | |||
sim.Chain.Shutdown() // shutdown chain subsysem | |||
} | |||
// rescan entire blockchain, locate and parse outputs | |||
// this scans the chain from the restart everytime, so can be slow | |||
func (sim *Simulator) Rescan_Wallet(w *walletapi.Wallet) { | |||
if w == nil { | |||
return | |||
} | |||
/* | |||
// load output indices limit of top block | |||
top_id := sim.Chain.Get_Top_ID() | |||
biggest_output_index := sim.Chain.Block_Count_Vout(nil,top_id) + sim.Chain.Get_Block_Output_Index(nil,top_id) | |||
for i := uint64(0); i < biggest_output_index; i++ { | |||
data, err := sim.Chain.Read_output_index(nil,i) | |||
if err != nil { | |||
fmt.Printf("err while reading output %d err: %s\n", i, err) | |||
break | |||
} | |||
var output globals.TX_Output_Data | |||
err = msgpack.Unmarshal(data, &output) | |||
if err != nil { | |||
fmt.Printf("err while decoding output %d err: %s\n", i, err) | |||
} | |||
// feed to wallet | |||
w.Add_Transaction_Record_Funds(&output) | |||
} | |||
*/ | |||
} |
@@ -1,289 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package simulator | |||
import "os" | |||
import "fmt" | |||
import "time" | |||
import "bufio" | |||
import "testing" | |||
import "path/filepath" | |||
import "github.com/romana/rlog" | |||
//import "encoding/hex" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/globals" | |||
import "github.com/deroproject/derosuite/crypto" | |||
import "github.com/deroproject/derosuite/blockchain" | |||
import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
//import "github.com/deroproject/derosuite/blockchain" | |||
// testing basic functionality of wallet in case of chain forks | |||
// mem pool okay etc | |||
func Test_Chain_Fork_Test(t *testing.T) { | |||
// start the simulator ( mine genesis block ) | |||
sim, _ := Init_Simulator(config.Testnet) | |||
defer sim.Stop() | |||
// create 3 wallets, w1,w2,w3 | |||
temp_db := filepath.Join(os.TempDir(), "test_w1.db") | |||
os.Remove(temp_db) | |||
w1, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w2.db") | |||
os.Remove(temp_db) | |||
w2, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w3.db") | |||
os.Remove(temp_db) | |||
w3, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
// first chain splits into 2 parts | |||
_ = w2 | |||
_ = w3 | |||
// mine the first block and get reward | |||
// w1 wallet has 5 rewards | |||
for i := 0; i < 10; i++ { | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
sim.Mine_New_Block_Address(w2.GetAddress()) | |||
} | |||
//sim.Mine_New_Block_Address(w2.GetAddress()) | |||
//sim.Mine_New_Block_Address(w3.GetAddress()) | |||
//t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
for i := 0; i < 60; i++ { | |||
sim.Mine_New_Block() // add a random block to random miner | |||
} | |||
// lets do a transaction now | |||
w1.Sync_Wallet_With_Daemon() | |||
tx, _, _, _, err := w1.Transfer([]address.Address{w3.GetAddress()}, []uint64{1000}, 0, "", 25037535000, 0) | |||
if err != nil { | |||
t.Fatalf("Error creating transaction err %s", err) | |||
} | |||
if !sim.Chain.Mempool.Mempool_Add_TX(tx, 0) { | |||
t.Fatalf("Add TX to pool failed ") | |||
} | |||
sim.Chain.Mempool.Mempool_Print() | |||
sim.Mine_New_Block() | |||
first_mined_block := sim.Chain.Get_Top_ID() | |||
for i := 0; i < 4; i++ { | |||
sim.Mine_New_Block() // add a random block to random miner | |||
} | |||
first_top := sim.Chain.Get_Top_ID() | |||
// now lets fork the chain, before the TX was mined | |||
pre_fork_top := sim.Chain.Get_Top_ID() // get top id before forking | |||
// start a fork with 30 blocks at suitable height | |||
block_hash, _ := sim.Chain.Load_BL_ID_at_Height(sim.Chain.Get_Height() - 8) // fork starts at this block | |||
for { | |||
cbl, _ := sim.Chain.Create_new_miner_block(block_hash, w1.GetAddress(), 0) // create a new block with | |||
sim.Chain.Add_Complete_Block(cbl) // add the block to alt-chain, at some point, alt-chain will become main chain | |||
block_hash = cbl.Bl.GetHash() | |||
if pre_fork_top != sim.Chain.Get_Top_ID() { // if the chain has flipped, check the balances | |||
rlog.Infof("Chain has forked") | |||
break | |||
} | |||
} | |||
// the tx must be orphan at this point | |||
if !sim.Chain.Is_TX_Orphan(tx.GetHash()) { | |||
t.Fatalf("TX must be orphan but it is not") | |||
} | |||
sim.Mine_New_Block() // add a random block to random miner, this will mine popped tx | |||
if sim.Chain.Is_TX_Orphan(tx.GetHash()) { | |||
t.Fatalf("TX must NOT be orphan but it is still orphan") | |||
} | |||
second_mined_block := sim.Chain.Get_Top_ID() | |||
// lets fork the current chain 2 blocks back | |||
second_fork_top := sim.Chain.Get_Top_ID() // get top id before forking | |||
// start a fork with 30 blocks at suitable height | |||
block_hash, _ = sim.Chain.Load_BL_ID_at_Height(sim.Chain.Get_Height() - 4) // fork starts at this block | |||
for { | |||
cbl, _ := sim.Chain.Create_new_miner_block(block_hash, w1.GetAddress(), 0) // create a new block with | |||
sim.Chain.Add_Complete_Block(cbl) // add the block to alt-chain, at some point, alt-chain will become main chain | |||
block_hash = cbl.Bl.GetHash() | |||
if second_fork_top != sim.Chain.Get_Top_ID() { // if the chain has flipped, check the balances | |||
rlog.Infof("Chain has forked") | |||
break | |||
} | |||
} | |||
// the tx will now move to another alt chain | |||
sim.Mine_New_Block() // add a random block to random miner, this will mine popped tx | |||
third_mined_block := sim.Chain.Get_Top_ID() | |||
rlog.Infof("TX %s mined in block FIRST %s firsttop %s", tx.GetHash(), first_mined_block, first_top) | |||
rlog.Infof("TX %s mined in block SECOND %s", tx.GetHash(), second_mined_block) | |||
rlog.Infof("TX %s mined in block THIRD %s", tx.GetHash(), third_mined_block) | |||
// letss jump back to original chain | |||
//block_hash, _ = sim.Chain.Load_BL_ID_at_Height(first_mined_block) // fork starts at this block | |||
block_hash = first_top | |||
for { | |||
cbl, _ := sim.Chain.Create_new_miner_block(block_hash, w1.GetAddress(), 0) // create a new block with | |||
sim.Chain.Add_Complete_Block(cbl) // add the block to alt-chain, at some point, alt-chain will become main chain | |||
block_hash = cbl.Bl.GetHash() | |||
if third_mined_block != sim.Chain.Get_Top_ID() { // if the chain has flipped, check the balances | |||
rlog.Infof("Chain has forked, we should be at the top block") | |||
break | |||
} | |||
} | |||
first_top = sim.Chain.Get_Top_ID() | |||
WriteBlockChainTree(sim.Chain, "/tmp/sim.dot") | |||
if !sim.Chain.Is_Block_Orphan(third_mined_block) { | |||
t.Fatalf("Third block should be marked orphan !!! but is NOT") | |||
} | |||
if !sim.Chain.Is_Block_Orphan(second_mined_block) { | |||
t.Fatalf("Second block should be marked orphan !!! but is NOT") | |||
} | |||
if sim.Chain.Is_Block_Orphan(first_mined_block) { | |||
t.Fatalf("First block should NOT be marked orphan !!! but it is orphan") | |||
} | |||
if sim.Chain.Is_TX_Orphan(tx.GetHash()) { | |||
t.Fatalf("TX is marked orphan, it should actually be no longer orphan") | |||
} | |||
sim.Chain.Mempool.Mempool_Print() | |||
// lets jump back to Alt-Alt Chain | |||
block_hash = second_mined_block | |||
for { | |||
cbl, _ := sim.Chain.Create_new_miner_block(block_hash, w1.GetAddress(), 0) // create a new block with | |||
sim.Chain.Add_Complete_Block(cbl) // add the block to alt-chain, at some point, alt-chain will become main chain | |||
block_hash = cbl.Bl.GetHash() | |||
if first_top != sim.Chain.Get_Top_ID() { // if the chain has flipped, check the balances | |||
rlog.Infof("Chain has forked, we should be at the top block") | |||
break | |||
} | |||
} | |||
WriteBlockChainTree(sim.Chain, "/tmp/sim2.dot") | |||
if !sim.Chain.Is_Block_Orphan(first_mined_block) { | |||
t.Fatalf("First block should be marked orphan !!! but it is NOT orphan") | |||
} | |||
if sim.Chain.Is_Block_Orphan(second_mined_block) { | |||
t.Fatalf("Second block should NOT be marked orphan !!! but is ") | |||
} | |||
if !sim.Chain.Is_Block_Orphan(third_mined_block) { | |||
t.Fatalf("Third block should be marked orphan !!! but is NOT") | |||
} | |||
if sim.Chain.Is_TX_Orphan(tx.GetHash()) { | |||
t.Fatalf("TX is marked orphan, it should actually be no longer orphan") | |||
} | |||
time.Sleep(1 * time.Second) | |||
} | |||
func writenode(chain *blockchain.Blockchain, w *bufio.Writer, blid crypto.Hash, chain_name string) { // process a node, recursively | |||
children := chain.Load_Block_Children(blid) | |||
block_name := blid.String() // embed TX | |||
// orphan = "" | |||
if chain.Is_Block_Orphan(blid) { | |||
block_name = "ORPHAN" + `\n` + block_name | |||
} | |||
bl, _ := chain.Load_BL_FROM_ID(blid) | |||
for j := range bl.Tx_hashes { | |||
block_name = block_name + `\n` + bl.Tx_hashes[j].String() | |||
} | |||
//test [label="line 1\nline 2"] | |||
w.WriteString(fmt.Sprintf("L%s [label = \"%s\"]\n", blid.String(), block_name)) | |||
for i := range children { | |||
cdiff := chain.Load_Block_Cumulative_Difficulty(children[i]) | |||
connected_how := chain_name + " main" | |||
if i != 0 { | |||
connected_how = chain_name + " alt" | |||
} | |||
if len(children) >= 1 { | |||
w.WriteString(fmt.Sprintf("L%s -> L%s [ label = \"%s %d height %d %d\" ];\n", blid.String(), children[i].String(), connected_how, cdiff, chain.Load_Height_for_BL_ID(children[i]), i)) | |||
} | |||
if len(children) == 1 { | |||
writenode(chain, w, children[i], chain_name) | |||
} else { | |||
writenode(chain, w, children[i], connected_how) | |||
} | |||
} | |||
} | |||
func WriteBlockChainTree(chain *blockchain.Blockchain, filename string) (err error) { | |||
f, err := os.Create(filename) | |||
if err != nil { | |||
return | |||
} | |||
defer f.Close() | |||
w := bufio.NewWriter(f) | |||
defer w.Flush() | |||
w.WriteString("digraph dero_blockchain_graph { \n") | |||
writenode(chain, w, globals.Config.Genesis_Block_Hash, "") | |||
w.WriteString("}\n") | |||
return | |||
} |
@@ -1,189 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package main | |||
import "os" | |||
import "fmt" | |||
import "time" | |||
import "testing" | |||
import "path/filepath" | |||
import "runtime/pprof" | |||
//import "encoding/hex" | |||
import "github.com/deroproject/derosuite/simulator" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
//import "github.com/deroproject/derosuite/globals" | |||
//import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
import "github.com/deroproject/derosuite/blockchain" | |||
func main(){ | |||
var t testing.T | |||
f, err := os.Create("cpu.prof") | |||
if err != nil { | |||
fmt.Printf("%s\n",err) | |||
return | |||
} | |||
pprof.StartCPUProfile(f) | |||
defer pprof.StopCPUProfile() | |||
QTest_Basic_Simulator(&t) | |||
} | |||
// testing basic functionality of block chain, whether the chain can be extended and balances decoded | |||
// mem pool okay etc | |||
// this also does the double spending test, which executes double spend, however the chain client protocol must be able to handle that | |||
func QTest_Basic_Simulator(t *testing.T) { | |||
/*// override simulation hard fork | |||
blockchain.Simulation_hard_forks = []blockchain.Hard_fork{ | |||
{1, 0, 0, 0, 0, true}, // version 1 hard fork where genesis block landed | |||
{6, 1, 0, 0, 0, true}, // version 6 hard fork where we started , it's mandatory | |||
{7, 40, 31, 60, 00, false}, // version 7 hard fork where we started , threshold is 60 % means atleast 18 votes should be in favor, from block 10 till block 40 | |||
}*/ | |||
// start the simulator ( mine genesis block ) | |||
sim, _ := simulator.Init_Simulator(config.Testnet) | |||
defer sim.Stop() | |||
// create 3 wallets, w1,w2,w3 | |||
temp_db := filepath.Join(os.TempDir(), "test_w1.db") | |||
os.Remove(temp_db) | |||
w1, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w2.db") | |||
os.Remove(temp_db) | |||
w2, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w3.db") | |||
os.Remove(temp_db) | |||
w3, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
_ = w2 | |||
_ = w3 | |||
// mine the first block and get reward | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
*/ | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
for i := 0; i < 70; i++ { | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance_Rescan() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
// */ | |||
// add a random block to random miner | |||
sim.Mine_New_Block() // mine block after genesis block | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
} | |||
t.Logf("Chain height %d done", sim.Chain.Get_Height()) | |||
// sync the wallets | |||
w1.Sync_Wallet_With_Daemon() | |||
w2.Sync_Wallet_With_Daemon() | |||
w3.Sync_Wallet_With_Daemon() | |||
tx, _, _, _, err := w1.Transfer([]address.Address{w3.GetAddress()}, []uint64{1000}, 0, "", 25037535000, 0) | |||
if err != nil { | |||
t.Fatalf("Error creating transaction err %s", err) | |||
} | |||
if !sim.Chain.Mempool.Mempool_Add_TX(tx, 0) { | |||
t.Fatalf("Add TX to pool failed ") | |||
} | |||
sim.Chain.Mempool.Mempool_Print() | |||
sim.Mine_New_Block() | |||
/* blocks := sim.Chain.Get_Blocks_At_Height(3) | |||
past := sim.Chain.Get_Past_Unsettled(blocks[0]) | |||
// past := sim.Chain.Get_Past_Unsettled(crypto.HashHexToHash("78845caac717c18e34682c2390b49de7e73e69633cc5f7eb2ce3f62948ddb8cd")) | |||
t.Logf("Past of %s is %+v\n", blocks[0],past) | |||
for k,_ := range past { | |||
t.Logf("Past %s\n", k) | |||
} | |||
*/ | |||
//blocks = sim.Chain.Get_Blocks_At_Height(7) | |||
/* | |||
future := sim.Chain.Get_Future_Unsettled(blocks[0]) | |||
t.Logf("Future of %s is %+v\n", blocks[0],future) | |||
for k,_ := range future { | |||
t.Logf("Future %s\n", k) | |||
} | |||
dag := sim.Chain.Get_DAG_Unsettled_Cached() | |||
for k,_ := range dag { // for all nodes find the anticone | |||
dag_copy := sim.Chain.Get_AntiCone_Unsettled(k) | |||
fmt.Printf("Anticone of %s is %d\n", k, len(dag_copy)) | |||
if len(dag_copy) == 0 { | |||
// order := sim.Chain.Generate_Full_Order(k,0) | |||
// | |||
//for i := range order { | |||
// t.Logf("%2d %s", i,order[i]) | |||
//} | |||
} | |||
} | |||
*/ | |||
if sim.Chain.Get_Height() < 100 { | |||
blockchain.WriteBlockChainTree(sim.Chain, "/tmp/graph.dot") | |||
t.Logf("Written graph") | |||
} | |||
time.Sleep(1000 * time.Second) | |||
} |
@@ -1,152 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package simulator | |||
import "os" | |||
//import "fmt" | |||
import "time" | |||
import "testing" | |||
import "path/filepath" | |||
//import "encoding/hex" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
//import "github.com/deroproject/derosuite/globals" | |||
//import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
import "github.com/deroproject/derosuite/blockchain" | |||
// testing basic functionality of block chain, whether the chain can be extended and balances decoded | |||
// mem pool okay etc | |||
func Test_Basic_Simulator(t *testing.T) { | |||
/*// override simulation hard fork | |||
blockchain.Simulation_hard_forks = []blockchain.Hard_fork{ | |||
{1, 0, 0, 0, 0, true}, // version 1 hard fork where genesis block landed | |||
{6, 1, 0, 0, 0, true}, // version 6 hard fork where we started , it's mandatory | |||
{7, 40, 31, 60, 00, false}, // version 7 hard fork where we started , threshold is 60 % means atleast 18 votes should be in favor, from block 10 till block 40 | |||
}*/ | |||
// start the simulator ( mine genesis block ) | |||
sim, _ := Init_Simulator(config.Testnet) | |||
defer sim.Stop() | |||
// create 3 wallets, w1,w2,w3 | |||
temp_db := filepath.Join(os.TempDir(), "test_w1.db") | |||
os.Remove(temp_db) | |||
w1, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w2.db") | |||
os.Remove(temp_db) | |||
w2, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w3.db") | |||
os.Remove(temp_db) | |||
w3, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
_ = w2 | |||
_ = w3 | |||
// mine the first block and get reward | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
*/ | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
for i := 0; i < 40; i++ { | |||
/*sim.Rescan_Wallet(w1) | |||
unlocked, locked := w1.Get_Balance_Rescan() | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
// */ | |||
// add a random block to random miner | |||
sim.Mine_New_Block() // mine block after genesis block | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
} | |||
t.Logf("Chain height %d done", sim.Chain.Get_Height()) | |||
blocks := sim.Chain.Get_Blocks_At_Height(3) | |||
past := sim.Chain.Get_Past_Unsettled(blocks[0]) | |||
// past := sim.Chain.Get_Past_Unsettled(crypto.HashHexToHash("78845caac717c18e34682c2390b49de7e73e69633cc5f7eb2ce3f62948ddb8cd")) | |||
t.Logf("Past of %s is %+v\n", blocks[0], past) | |||
for k, _ := range past { | |||
t.Logf("Past %s\n", k) | |||
} | |||
blocks = sim.Chain.Get_Blocks_At_Height(7) | |||
future := sim.Chain.Get_Future_Unsettled(blocks[0]) | |||
t.Logf("Future of %s is %+v\n", blocks[0], future) | |||
for k, _ := range future { | |||
t.Logf("Future %s\n", k) | |||
} | |||
dag := sim.Chain.Get_DAG_Unsettled() | |||
for k, _ := range dag { // for all nodes find the anticone | |||
dag_copy := sim.Chain.Get_DAG_Unsettled() | |||
delete(dag_copy, k) // delete self | |||
past := sim.Chain.Get_Past_Unsettled(k) | |||
for k1, _ := range past { | |||
delete(dag_copy, k1) | |||
} | |||
future := sim.Chain.Get_Future_Unsettled(k) | |||
for k1, _ := range future { | |||
delete(dag_copy, k1) | |||
} | |||
t.Logf("Anticone of %s is %d\n", k, len(dag_copy)) | |||
if len(dag_copy) == 0 { | |||
order := sim.Chain.Generate_Full_Order(k, 0) | |||
for i := range order { | |||
t.Logf("%2d %s", i, order[i]) | |||
} | |||
} | |||
} | |||
blockchain.WriteBlockChainTree(sim.Chain, "/tmp/graph.dot") | |||
time.Sleep(1 * time.Second) | |||
} |
@@ -1,143 +0,0 @@ | |||
// Copyright 2017-2018 DERO Project. All rights reserved. | |||
// Use of this source code in any form is governed by RESEARCH license. | |||
// license can be found in the LICENSE file. | |||
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 | |||
// | |||
// | |||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY | |||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF | |||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
package simulator | |||
import "os" | |||
//import "fmt" | |||
//import "time" | |||
import "testing" | |||
import "path/filepath" | |||
//import "encoding/hex" | |||
import "github.com/deroproject/derosuite/config" | |||
import "github.com/deroproject/derosuite/crypto" | |||
import "github.com/deroproject/derosuite/globals" | |||
//import "github.com/deroproject/derosuite/address" | |||
import "github.com/deroproject/derosuite/walletapi" | |||
//import "github.com/deroproject/derosuite/blockchain" | |||
// testing basic functionality of wallet in case of chain forks | |||
// mem pool okay etc | |||
func Test_Basic_Wallet_Fork_Test(t *testing.T) { | |||
// start the simulator ( mine genesis block ) | |||
sim, _ := Init_Simulator(config.Testnet) | |||
defer sim.Stop() | |||
// create 3 wallets, w1,w2,w3 | |||
temp_db := filepath.Join(os.TempDir(), "test_w1.db") | |||
os.Remove(temp_db) | |||
w1, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w2.db") | |||
os.Remove(temp_db) | |||
w2, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
temp_db = filepath.Join(os.TempDir(), "test_w3.db") | |||
os.Remove(temp_db) | |||
w3, err := walletapi.Create_Encrypted_Wallet(temp_db, "QWER", *crypto.RandomScalar()) | |||
if err != nil { | |||
t.Fatalf("Cannot create encrypted wallet, err %s", err) | |||
} | |||
_ = w2 | |||
_ = w3 | |||
// mine the first block and get reward | |||
// all wallets have 1 reward each | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
sim.Mine_New_Block_Address(w2.GetAddress()) | |||
sim.Mine_New_Block_Address(w3.GetAddress()) | |||
t.Logf("Chain height %d", sim.Chain.Get_Height()) | |||
for i := 0; i < 64; i++ { | |||
sim.Mine_New_Block() // add a random block to random miner | |||
} | |||
// all wallets have 2 reward each | |||
sim.Mine_New_Block_Address(w1.GetAddress()) | |||
sim.Mine_New_Block_Address(w2.GetAddress()) | |||
sim.Mine_New_Block_Address(w3.GetAddress()) | |||
// sync the wallets | |||
w1.Sync_Wallet_With_Daemon() | |||
w2.Sync_Wallet_With_Daemon() | |||
w3.Sync_Wallet_With_Daemon() | |||
unlocked, locked := w1.Get_Balance_Rescan() | |||
w1_unlocked := unlocked | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
unlocked, locked = w2.Get_Balance_Rescan() | |||
w2_unlocked := unlocked | |||
globals.Logger.Infof("W2 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
unlocked, locked = w3.Get_Balance_Rescan() | |||
w3_unlocked := unlocked | |||
globals.Logger.Infof("W3 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
pre_fork_top := sim.Chain.Get_Top_ID() // get top id before forking | |||
// start a fork with 30 blocks at height 50 | |||
block_hash, _ := sim.Chain.Load_BL_ID_at_Height(50) // fork starts at this block | |||
for { | |||
account, _ := walletapi.Generate_Keys_From_Random() // create a random address | |||
cbl, _ := sim.Chain.Create_new_miner_block(block_hash, account.GetAddress(), 0) // create a new block with | |||
sim.Chain.Add_Complete_Block(cbl) // add the block to alt-chain, at some point, alt-chain will become main chain | |||
block_hash = cbl.Bl.GetHash() | |||
if pre_fork_top != sim.Chain.Get_Top_ID() { // if the chain has flipped, check the balances | |||
break | |||
} | |||
} | |||
// sync the wallets | |||
w1.Sync_Wallet_With_Daemon() | |||
w2.Sync_Wallet_With_Daemon() | |||
w3.Sync_Wallet_With_Daemon() | |||
unlocked, locked = w1.Get_Balance_Rescan() | |||
if unlocked != w1_unlocked || locked != 0 { | |||
t.Fatalf("Wallet1 Failed to syncronise with dameon") | |||
} | |||
globals.Logger.Infof("W1 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
unlocked, locked = w2.Get_Balance_Rescan() | |||
if unlocked != w2_unlocked || locked != 0 { | |||
t.Fatalf("Wallet2 Failed to syncronise with dameon") | |||
} | |||
globals.Logger.Infof("W2 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
unlocked, locked = w3.Get_Balance_Rescan() | |||
if unlocked != w3_unlocked || locked != 0 { | |||
t.Fatalf("Wallet3 Failed to syncronise with dameon") | |||
} | |||
globals.Logger.Infof("W3 balances %s : %s locked", globals.FormatMoney(unlocked), globals.FormatMoney(locked)) | |||
} |