diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 3598bdd..3852ade 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -347,6 +347,13 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro return errormsg.ErrAlreadyExists, false } + for k := range chain.Tips { + if block_hash == k { + block_logger.Debugf("block already in chain skipping it ") + return errormsg.ErrAlreadyExists, false + } + } + // only 3 tips allowed in block if len(bl.Tips) >= 4 { rlog.Warnf("More than 3 tips present in block %s rejecting", block_hash) @@ -677,11 +684,12 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro } // any blocks which have not changed their topo will be skipped using graviton trick + skip := true for i := int64(0); i < int64(len(full_order)); i++ { // check whether the new block is at the same position at the last position current_topo_block := i + base_topo_index - if current_topo_block < chain.Store.Topo_store.Count() { + if skip && current_topo_block < chain.Store.Topo_store.Count() { toporecord, err := chain.Store.Topo_store.Read(current_topo_block) if err != nil { panic(err) @@ -690,6 +698,8 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro continue } + skip = false // if one block processed, process every higher block + } // TODO we must run smart contracts and TXs in this order @@ -806,7 +816,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro // their transactions are ignored //chain.Store.Topo_store.Write(i+base_topo_index, full_order[i],0, int64(bl_current.Height)) // write entry so as sideblock could work - if !chain.isblock_SideBlock_internal(full_order[i], i+base_topo_index, int64(bl_current.Height)) { + if !chain.isblock_SideBlock_internal(full_order[i], i+base_topo_index, int64(bl_current.Height)) { for _, txhash := range bl_current.Tx_hashes { // execute all the transactions @@ -825,7 +835,9 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro } + chain.process_miner_transaction(bl_current.Miner_TX, bl_current.Height == 0, balance_tree, fees_collected) + } else { rlog.Debugf("this block is a side block block height %d blid %s ", chain.Load_Block_Height(full_order[i]), full_order[i]) @@ -1270,12 +1282,13 @@ func (chain *Blockchain) isblock_SideBlock(blid crypto.Hash) bool { return chain.isblock_SideBlock_internal(blid, block_topoheight, block_height) } +// todo optimize/ run more checks func (chain *Blockchain) isblock_SideBlock_internal(blid crypto.Hash, block_topoheight int64, block_height int64) (result bool) { if block_topoheight == 0 { return false } counter := int64(0) - for i := block_topoheight - 1; i >= 0 && counter < 3*config.STABLE_LIMIT; i-- { + for i := block_topoheight - 1; i >= 0 && counter < 16*config.STABLE_LIMIT; i-- { counter++ toporecord, err := chain.Store.Topo_store.Read(i) if err != nil { @@ -1552,20 +1565,25 @@ func (chain *Blockchain) buildReachability(blid crypto.Hash) map[crypto.Hash]boo // this is part of consensus rule, 2 tips cannot refer to their common parent func (chain *Blockchain) VerifyNonReachability(bl *block.Block) bool { + return chain.verifyNonReachabilitytips(bl.Tips) +} - reachmaps := make([]map[crypto.Hash]bool, len(bl.Tips), len(bl.Tips)) - for i := range bl.Tips { - reachmaps[i] = chain.buildReachability(bl.Tips[i]) +// this is part of consensus rule, 2 tips cannot refer to their common parent +func (chain *Blockchain) verifyNonReachabilitytips(tips []crypto.Hash) bool { + + reachmaps := make([]map[crypto.Hash]bool, len(tips), len(tips)) + for i := range tips { + reachmaps[i] = chain.buildReachability(tips[i]) } // bruteforce all reachability combinations, max possible 3x3 = 9 combinations - for i := range bl.Tips { - for j := range bl.Tips { + for i := range tips { + for j := range tips { if i == j { // avoid self test continue } - if _, ok := reachmaps[j][bl.Tips[i]]; ok { // if a tip can be referenced as another's past, this is not a tip , probably malicious, discard block + if _, ok := reachmaps[j][tips[i]]; ok { // if a tip can be referenced as another's past, this is not a tip , probably malicious, discard block return false } diff --git a/blockchain/miner_block.go b/blockchain/miner_block.go index 76fa8d2..d58b41b 100644 --- a/blockchain/miner_block.go +++ b/blockchain/miner_block.go @@ -100,7 +100,12 @@ func (chain *Blockchain) Create_new_miner_block(miner_address address.Address, t if len(bl.Tips) >= 3 { break } - bl.Tips = append(bl.Tips, tips[i]) + if !chain.verifyNonReachabilitytips(append([]crypto.Hash{tips[i]}, bl.Tips...) ) { // avoid any tips which fail reachability test + continue + } + if len(bl.Tips) == 0 || (len(bl.Tips)>=1 && chain.Load_Height_for_BL_ID(bl.Tips[0]) >= chain.Load_Height_for_BL_ID(tips[i]) && chain.Load_Height_for_BL_ID(bl.Tips[0]) - chain.Load_Height_for_BL_ID(tips[i]) <= config.STABLE_LIMIT/2) { + bl.Tips = append(bl.Tips, tips[i]) + } } //fmt.Printf("miner block placing tips %+v\n", bl.Tips) diff --git a/blockchain/storetopo.go b/blockchain/storetopo.go index 83b3fc6..922a465 100644 --- a/blockchain/storetopo.go +++ b/blockchain/storetopo.go @@ -38,6 +38,10 @@ type storetopofs struct { topomapping *os.File } +func (s TopoRecord)String() string { + return fmt.Sprintf("blid %x state version %d height %d",s.BLOCK_ID[:],s.State_Version, s.Height) +} + func (s *storetopofs) Open(basedir string) (err error) { s.topomapping, err = os.OpenFile(filepath.Join(basedir, "topo.map"), os.O_RDWR|os.O_CREATE, 0700) return err diff --git a/cmd/explorer/templates.go b/cmd/explorer/templates.go index b2b084d..9ca0a4a 100644 --- a/cmd/explorer/templates.go +++ b/cmd/explorer/templates.go @@ -463,7 +463,7 @@ var txpool_template string = `{{define "txpool"}} - + @@ -473,7 +473,7 @@ var txpool_template string = `{{define "txpool"}} {{range .mempool}} - + diff --git a/config/config.go b/config/config.go index c73e019..2239fc9 100644 --- a/config/config.go +++ b/config/config.go @@ -113,7 +113,7 @@ var Mainnet = CHAIN_CONFIG{Name: "mainnet", } var Testnet = CHAIN_CONFIG{Name: "testnet", // testnet will always have last 3 bytes 0 - Network_ID: uuid.FromBytesOrNil([]byte{0x59, 0xd7, 0xf7, 0xe9, 0xdd, 0x48, 0xd5, 0xfd, 0x13, 0x0a, 0xf6, 0xe0, 0x22, 0x00, 0x00, 0x00}), + Network_ID: uuid.FromBytesOrNil([]byte{0x59, 0xd7, 0xf7, 0xe9, 0xdd, 0x48, 0xd5, 0xfd, 0x13, 0x0a, 0xf6, 0xe0, 0x23, 0x00, 0x00, 0x00}), P2P_Default_Port: 40401, RPC_Default_Port: 40402, Wallet_RPC_Default_Port: 40403, diff --git a/config/version.go b/config/version.go index a810507..281eb96 100644 --- a/config/version.go +++ b/config/version.go @@ -20,4 +20,4 @@ import "github.com/blang/semver" // right now it has to be manually changed // do we need to include git commitsha?? -var Version = semver.MustParse("3.0.0-10.DEROHE.alpha+20122020") +var Version = semver.MustParse("3.0.0-11.DEROHE.alpha+20122020") diff --git a/p2p/chain_response.go b/p2p/chain_response.go index da9f4e9..78555a6 100644 --- a/p2p/chain_response.go +++ b/p2p/chain_response.go @@ -101,7 +101,7 @@ func (connection *Connection) Handle_ChainResponse(buf []byte) { rlog.Tracef(2, "Queuing block %x height %d %s", response.Block_list[i], response.Start_height+int64(i), connection.logid) } } else { - logger.Warnf("We must have queued %x, but we skipped it at height %d", response.Block_list[i], response.Start_height+int64(i)) + rlog.Tracef(3, "We must have queued %x, but we skipped it at height %d", response.Block_list[i], response.Start_height+int64(i)) } } diff --git a/walletapi/balance_decoder.go b/walletapi/balance_decoder.go index f19668a..e76a7b5 100644 --- a/walletapi/balance_decoder.go +++ b/walletapi/balance_decoder.go @@ -69,7 +69,7 @@ func Initialize_LookupTable(count int, table_size int) *LookupTable { for i := range t { t[i] = make([]uint64, table_size, table_size) - bar := pb.New(TABLE_SIZE) + bar := pb.New(table_size) if terminal { bar.Start() } diff --git a/walletapi/daemon_communication.go b/walletapi/daemon_communication.go index f1cc547..f68ba97 100644 --- a/walletapi/daemon_communication.go +++ b/walletapi/daemon_communication.go @@ -483,8 +483,9 @@ func (w *Wallet) GetEncryptedBalanceAtTopoHeight(topoheight int64, accountaddr s var result structures.GetEncryptedBalance_Result // Issue a call with a response. - if err := rpc_client.Call("DERO.GetEncryptedBalance", structures.GetEncryptedBalance_Params{Address: accountaddr, TopoHeight: topoheight}, &result); err != nil { - fmt.Printf("Call failed: %v", err) + if err = rpc_client.Call("DERO.GetEncryptedBalance", structures.GetEncryptedBalance_Params{Address: accountaddr, TopoHeight: topoheight}, &result); err != nil { + rlog.Errorf("Call failed: %v", err) + return } // fmt.Printf("encrypted_balance %+v\n", result) @@ -568,7 +569,7 @@ func (w *Wallet) random_ring_members() { // Issue a call with a response. if err := rpc_client.Call("DERO.GetRandomAddress", nil, &result); err != nil { - fmt.Printf("Call failed: %v", err) + rlog.Errorf("GetRandomAddress Call failed: %v", err) return } //fmt.Printf("ring members %+v\n", result) @@ -613,7 +614,7 @@ func (w *Wallet) SyncHistory() (balance uint64) { // Issue a call with a response. if err := rpc_client.Call("DERO.GetBlockHeaderByTopoHeight", structures.GetBlockHeaderByTopoHeight_Params{TopoHeight: uint64(w.account.Entries[i].TopoHeight)}, &result); err != nil { - fmt.Printf("Call failed: %v", err) + rlog.Errorf("GetBlockHeaderByTopoHeight Call failed: %v", err) return 0 } diff --git a/walletapi/wallet.go b/walletapi/wallet.go index 1321cd4..d1fd2f2 100644 --- a/walletapi/wallet.go +++ b/walletapi/wallet.go @@ -232,7 +232,7 @@ func (w *Wallet) Show_Transfers(available bool, in bool, out bool, pool bool, fa } continue } - if out && !e.Incoming { + if out && !(e.Incoming || e.Coinbase) { if payment_id && len(e.PaymentID) >= 8 { entries = append(entries, e) } else {
age [h:m:s]height built transaction hash fee ring size
{{.HeightBuilt}} {{.Hash}} {{.Fee}} {{.Ring_size}}