Browse Source

Fixed code compilation.

master
Captain Dero 2 years ago
parent
commit
71e795273c
6 changed files with 0 additions and 1213 deletions
  1. +0
    -205
      simulator/build/simulator_basic_test_bin.go
  2. +0
    -235
      simulator/simulator.go
  3. +0
    -289
      simulator/simulator_alt_alt_chain_test.go1
  4. +0
    -189
      simulator/simulator_basic_orphan_tx.go1
  5. +0
    -152
      simulator/simulator_basic_test.go1
  6. +0
    -143
      simulator/simulator_wallet_fork_test.go1

+ 0
- 205
simulator/build/simulator_basic_test_bin.go View File

@@ -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)

}

+ 0
- 235
simulator/simulator.go View File

@@ -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)

}
*/
}

+ 0
- 289
simulator/simulator_alt_alt_chain_test.go1 View File

@@ -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
}

+ 0
- 189
simulator/simulator_basic_orphan_tx.go1 View File

@@ -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)

}

+ 0
- 152
simulator/simulator_basic_test.go1 View File

@@ -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)

}

+ 0
- 143
simulator/simulator_wallet_fork_test.go1 View File

@@ -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))

}

Loading…
Cancel
Save