diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index a56ffe8..4a729b5 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -184,6 +184,10 @@ func Blockchain_Start(params map[string]interface{}) (*Blockchain, error) { chain.Initialise_Chain_From_DB() // load the chain from the disk + if chain.Pruned >= 1 { + logger.Info("Chain Pruned till", "topoheight", chain.Pruned) + } + metrics.Version = config.Version.String() go metrics.Dump_metrics_data_directly(logger, globals.Arguments["--node-tag"]) // enable metrics if someone needs them @@ -245,7 +249,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro // safety so if anything wrong happens, verification fails if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while adding new block", "blid", block_hash, "stack", fmt.Sprintf("%s", string(debug.Stack()))) + logger.V(1).Error(nil, "Recovered while adding new block", "blid", block_hash, "r", r, "stack", fmt.Sprintf("%s", string(debug.Stack()))) result = false err = errormsg.ErrPanic } @@ -257,7 +261,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro func() { defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while instrumenting", "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while instrumenting", "r", r, "stack", debug.Stack()) } }() metrics.Set.GetOrCreateCounter("blockchain_tx_total").Add(len(cbl.Bl.Tx_hashes)) @@ -869,7 +873,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro func() { if r := recover(); r != nil { - logger.Error(r.(error), "Mempool House Keeping triggered panic", "height", block_height) + logger.Error(nil, "Mempool House Keeping triggered panic", "r", r, "height", block_height) } purge_count := chain.MiniBlocks.PurgeHeight(chain.Get_Stable_Height()) // purge all miniblocks upto this height @@ -934,9 +938,6 @@ func (chain *Blockchain) Initialise_Chain_From_DB() { defer chain.Unlock() chain.Pruned = chain.LocatePruneTopo() - if chain.Pruned >= 1 { - logger.Info("Chain Pruned till", "topoheight", chain.Pruned) - } // find the tips from the chain , first by reaching top height // then downgrading to top-10 height @@ -992,11 +993,20 @@ func (chain *Blockchain) Get_Stable_Height() int64 { func (chain *Blockchain) Get_TIPS() (tips []crypto.Hash) { for _, x := range chain.Tips { tips = append(tips, x) - } return tips } +// check whether the block is a tip +func (chain *Blockchain) Is_Block_Tip(blid crypto.Hash) (result bool) { + for k := range chain.Tips { + if blid == k { + return true + } + } + return false +} + func (chain *Blockchain) Get_Difficulty() uint64 { return chain.Get_Difficulty_At_Tips(chain.Get_TIPS()).Uint64() } diff --git a/blockchain/miner_block.go b/blockchain/miner_block.go index 73bcc7a..62bdf32 100644 --- a/blockchain/miner_block.go +++ b/blockchain/miner_block.go @@ -505,7 +505,7 @@ func (chain *Blockchain) Accept_new_block(tstamp uint64, miniblock_blob []byte) // safety so if anything wrong happens, verification fails defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while accepting new block", "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while accepting new block", "r", r, "stack", debug.Stack()) err = fmt.Errorf("Error while parsing block") } }() diff --git a/blockchain/transaction_verify.go b/blockchain/transaction_verify.go index 613dc33..e7a8b27 100644 --- a/blockchain/transaction_verify.go +++ b/blockchain/transaction_verify.go @@ -115,7 +115,7 @@ func (chain *Blockchain) Verify_Transaction_NonCoinbase_CheckNonce_Tips(hf_versi var tx_hash crypto.Hash defer func() { // safety so if anything wrong happens, verification fails if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while verifying tx", "txid", tx_hash, "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while verifying tx", "txid", tx_hash, "r", r, "stack", debug.Stack()) err = fmt.Errorf("Stack Trace %s", debug.Stack()) } }() @@ -277,7 +277,7 @@ func (chain *Blockchain) Verify_Transaction_NonCoinbase(hf_version int64, tx *tr var tx_hash crypto.Hash defer func() { // safety so if anything wrong happens, verification fails if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while verifying tx", "txid", tx_hash, "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while verifying tx", "txid", tx_hash, "r", r, "stack", debug.Stack()) err = fmt.Errorf("Stack Trace %s", debug.Stack()) } }() diff --git a/cmd/derod/rpc/rpc_dero_getsc.go b/cmd/derod/rpc/rpc_dero_getsc.go index 41d47d1..8d2d53d 100644 --- a/cmd/derod/rpc/rpc_dero_getsc.go +++ b/cmd/derod/rpc/rpc_dero_getsc.go @@ -42,6 +42,10 @@ func GetSC(ctx context.Context, p rpc.GetSC_Params) (result rpc.GetSC_Result, er } }() + result.VariableStringKeys = map[string]interface{}{} + result.VariableUint64Keys = map[uint64]interface{}{} + result.Balances = map[string]uint64{} + scid := crypto.HashHexToHash(p.SCID) topoheight := chain.Load_TOPO_HEIGHT() @@ -71,7 +75,9 @@ func GetSC(ctx context.Context, p rpc.GetSC_Params) (result rpc.GetSC_Result, er } */ - if sc_data_tree, err := ss.GetTree(string(scid[:])); err == nil { + var sc_data_tree *graviton.Tree + sc_data_tree, err = ss.GetTree(string(scid[:])) + if err == nil { var zerohash crypto.Hash if balance_bytes, err := sc_data_tree.Get(zerohash[:]); err == nil { if len(balance_bytes) == 8 { @@ -89,6 +95,37 @@ func GetSC(ctx context.Context, p rpc.GetSC_Params) (result rpc.GetSC_Result, er } } } + if p.Variables { // user requested all variables + cursor := sc_data_tree.Cursor() + var k, v []byte + for k, v, err = cursor.First(); err == nil; k, v, err = cursor.Next() { + var vark, varv dvm.Variable + + if nil == vark.UnmarshalBinary(k) && nil == varv.UnmarshalBinary(v) { + switch vark.Type { + case dvm.Uint64: + if varv.Type == dvm.Uint64 { + result.VariableUint64Keys[vark.ValueUint64] = varv.ValueUint64 + } else { + result.VariableUint64Keys[vark.ValueUint64] = fmt.Sprintf("%x", []byte(varv.ValueString)) + } + + case dvm.String: + if varv.Type == dvm.Uint64 { + result.VariableStringKeys[vark.ValueString] = varv.ValueUint64 + } else { + result.VariableStringKeys[vark.ValueString] = fmt.Sprintf("%x", []byte(varv.ValueString)) + } + default: + err = fmt.Errorf("UNKNOWN Data type") + return + } + + } else if len(k) == 32 && len(v) == 8 { // it's SC balance + result.Balances[fmt.Sprintf("%x", k)] = binary.BigEndian.Uint64(v) + } + } + } // give any uint64 keys data if any for _, value := range p.KeysUint64 { @@ -108,7 +145,7 @@ func GetSC(ctx context.Context, p rpc.GetSC_Params) (result rpc.GetSC_Result, er case dvm.Uint64: result.ValuesUint64 = append(result.ValuesUint64, fmt.Sprintf("%d", v.ValueUint64)) case dvm.String: - result.ValuesUint64 = append(result.ValuesUint64, fmt.Sprintf("%s", v.ValueString)) + result.ValuesUint64 = append(result.ValuesUint64, fmt.Sprintf("%x", []byte(v.ValueString))) default: result.ValuesUint64 = append(result.ValuesUint64, "UNKNOWN Data type") } @@ -131,7 +168,7 @@ func GetSC(ctx context.Context, p rpc.GetSC_Params) (result rpc.GetSC_Result, er case dvm.Uint64: result.ValuesString = append(result.ValuesUint64, fmt.Sprintf("%d", v.ValueUint64)) case dvm.String: - result.ValuesString = append(result.ValuesString, fmt.Sprintf("%s", v.ValueString)) + result.ValuesString = append(result.ValuesString, fmt.Sprintf("%x", []byte(v.ValueString))) default: result.ValuesString = append(result.ValuesString, "UNKNOWN Data type") } diff --git a/cmd/derod/rpc/websocket_server.go b/cmd/derod/rpc/websocket_server.go index 83c793d..9b8ab70 100644 --- a/cmd/derod/rpc/websocket_server.go +++ b/cmd/derod/rpc/websocket_server.go @@ -256,7 +256,7 @@ func ws_handler(w http.ResponseWriter, r *http.Request) { // safety so if anything wrong happens, verification fails if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while processing websocket request", "stack", debug.Stack()) + logger.V(2).Error(nil, "Recovered while processing websocket request", "r", r, "stack", debug.Stack()) } if ws_server != nil { client_connections.Delete(ws_server) diff --git a/cmd/derod/update.go b/cmd/derod/update.go index a411b02..d53af08 100644 --- a/cmd/derod/update.go +++ b/cmd/derod/update.go @@ -85,7 +85,7 @@ func (d *socks_dialer) DialContext(ctx context.Context, network, address string) func dial_random_read_response(in []byte) (out []byte, err error) { defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while checking updates", "stack", debug.Stack()) + logger.V(2).Error(nil, "Recovered while checking updates", "r", r, "stack", debug.Stack()) } }() @@ -154,7 +154,7 @@ func check_update() { // add panic handler, in case DNS acts rogue and tries to attack defer func() { if r := recover(); r != nil { - logger.V(2).Error(r.(error), "Recovered while checking updates", "stack", debug.Stack()) + logger.V(2).Error(nil, "Recovered while checking updates", r, "r", "stack", debug.Stack()) } }() diff --git a/cmd/explorer/explorerlib/explorerlib.go b/cmd/explorer/explorerlib/explorerlib.go index 373bd09..47d2078 100644 --- a/cmd/explorer/explorerlib/explorerlib.go +++ b/cmd/explorer/explorerlib/explorerlib.go @@ -270,6 +270,8 @@ type txinfo struct { SC_Keys map[string]string // SC key value of SC_Args rpc.Arguments // rpc.Arguments SC_Code string // install SC + SC_State rpc.GetSC_Result // current SC state + SC_Install bool Assets []Asset } @@ -576,6 +578,22 @@ func load_tx_from_rpc(info *txinfo, txhash string) (err error) { info.SC_Balance = tx_result.Txs[0].Balance info.SC_Balance_string = fmt.Sprintf("%.05f", float64(uint64(info.SC_Balance)/100000)) info.SC_Code = tx_result.Txs[0].Code + + if tx.TransactionType == transaction.SC_TX && len(info.SC_Code) >= 1 { + + if len(info.SC_Code) >= 1 { + info.SC_Install = true + } + var p = rpc.GetSC_Params{SCID: txhash, Variables: true} + var r rpc.GetSC_Result + + if err = rpc_client.Call("DERO.GetSC", p, &r); err != nil { + return fmt.Errorf("gettransa rpc failed err %s", err) + } else { + info.SC_State = r + } + } + //info.Ring = strings.Join(info.OutAddress, " ") //fmt.Printf("tx_result %+v\n",tx_result.Txs) diff --git a/cmd/explorer/explorerlib/templates/tx.tmpl b/cmd/explorer/explorerlib/templates/tx.tmpl index a8b1562..2b8f3c3 100644 --- a/cmd/explorer/explorerlib/templates/tx.tmpl +++ b/cmd/explorer/explorerlib/templates/tx.tmpl @@ -31,16 +31,54 @@ {{end}} + +{{if .info.SC_Install }} + +
+
SCID current reserves
+ + + + + + + {{range $k, $v := .info.SC_State.Balances}} + + + + {{end}} +
SCID Amount(in atomic units)
{{ $k }} {{ $v }}
+ +
SCID string variables
+ + + + + {{range $k, $v := .info.SC_State.VariableStringKeys}} + + + + {{end}} +
key value
{{ $k }} {{ $v }}
+
SCID uint64 variables
+ + + + + {{range $k, $v := .info.SC_State.VariableUint64Keys}} + + + + {{end}} +
key value
{{ $k }} {{ $v }}
+ +
+{{end}} + {{if or (eq .info.TransactionType "NORMAL") (eq .info.TransactionType "BURN") (eq .info.TransactionType "SC") }}
Tx RootHash: {{.info.RootHash}} built height : {{.info.HeightBuilt}}
- {{if .info.PayID32}} -
PaymentID: {{.info.PayID32}}
- {{end}} - {{if .info.PayID8}} -
Encrypted PaymentID: {{.info.PayID8}}
- {{end}} diff --git a/config/config.go b/config/config.go index ddb4c07..0569178 100644 --- a/config/config.go +++ b/config/config.go @@ -53,7 +53,7 @@ const MAX_RINGSIZE = 128 // <= 128, ringsize will be accepted const FEE_PER_KB = uint64(100) // .00100 dero per kb const MAINNET_BOOTSTRAP_DIFFICULTY = uint64(80000000) // atlantis mainnet botstrapped at 80 MH/s -const MAINNET_MINIMUM_DIFFICULTY = uint64(800000000) // 80 MH/s +const MAINNET_MINIMUM_DIFFICULTY = uint64(800000000) // 80 MH/s // testnet bootstraps at 1 MH const TESTNET_BOOTSTRAP_DIFFICULTY = uint64(50000) // testnet bootstrap at 50KH/s diff --git a/config/version.go b/config/version.go index 695567b..a735233 100644 --- a/config/version.go +++ b/config/version.go @@ -20,4 +20,4 @@ import "github.com/blang/semver/v4" // right now it has to be manually changed // do we need to include git commitsha?? -var Version = semver.MustParse("3.4.46-1.DEROHE.STARGATE+08112021") +var Version = semver.MustParse("3.4.49-1.DEROHE.STARGATE+09112021") diff --git a/p2p/chain_sync.go b/p2p/chain_sync.go index edd229d..766ef63 100644 --- a/p2p/chain_sync.go +++ b/p2p/chain_sync.go @@ -153,29 +153,13 @@ try_again: func (connection *Connection) process_object_response(response Objects, sent int64, syncing bool) error { var err error - - // make sure connection does not timeout and be killed while processing huge blocks - processing_complete := make(chan bool) - go func() { - ticker := time.NewTicker(500 * time.Millisecond) - defer ticker.Stop() - for { - select { - case <-processing_complete: - return // complete the loop - case <-ticker.C: // give the chain some more time to respond - atomic.StoreInt64(&connection.LastObjectRequestTime, time.Now().Unix()) - } - } - }() - - defer func() { - processing_complete <- true - }() - defer globals.Recover(2) for i := 0; i < len(response.CBlocks); i++ { // process incoming full blocks + // make sure connection does not timeout and be killed while processing huge blocks + + atomic.StoreInt64(&connection.LastObjectRequestTime, time.Now().Unix()) + var cbl block.Complete_Block // parse incoming block and deserialize it var bl block.Block // lets deserialize block first and see whether it is the requested object @@ -190,6 +174,10 @@ func (connection *Connection) process_object_response(response Objects, sent int // give the chain some more time to respond atomic.StoreInt64(&connection.LastObjectRequestTime, time.Now().Unix()) + // do not try to add blocks too much into future + if syncing && int64(bl.Height) > chain.Get_Height()+4 { + continue + } // check whether the object was requested one // complete the txs diff --git a/p2p/connection_pool.go b/p2p/connection_pool.go index 0baa183..7ed2ce0 100644 --- a/p2p/connection_pool.go +++ b/p2p/connection_pool.go @@ -734,7 +734,7 @@ func broadcast_Tx(tx *transaction.Transaction, PeerID uint64, sent int64) (relay go func(connection *Connection) { defer func() { if r := recover(); r != nil { - connection.logger.V(1).Error(r.(error), "Recovere3d while sending tx", "stack", debug.Stack()) + connection.logger.V(1).Error(nil, "Recovere3d while sending tx", "r", r, "stack", debug.Stack()) } }() diff --git a/p2p/controller.go b/p2p/controller.go index 720e19d..40207c5 100644 --- a/p2p/controller.go +++ b/p2p/controller.go @@ -219,11 +219,7 @@ func P2P_engine() { // will block until the connection dies or is killed func connect_with_endpoint(endpoint string, sync_node bool) { - defer func() { - if r := recover(); r != nil { - logger.V(2).Error(r.(error), "Recovered while connecting", "stack", fmt.Sprintf("%s", string(debug.Stack()))) - } - }() + defer globals.Recover(2) remote_ip, err := net.ResolveTCPAddr("tcp", endpoint) if err != nil { @@ -415,7 +411,7 @@ func P2P_Server_v2() { func handle_connection_panic(c *Connection) { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while handling connection", "stack", debug.Stack()) + logger.V(2).Error(nil, "Recovered while handling connection", "r", r, "stack", debug.Stack()) c.exit() } } @@ -442,10 +438,9 @@ func process_connection(conn net.Conn, remote_addr *net.TCPAddr, incoming, sync_ c.logger = logger.WithName("outgoing").WithName(remote_addr.String()) } go func() { - //defer globals.Recover() defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while handling connection", "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while handling connection", "r", r, "stack", debug.Stack()) conn.Close() } }() diff --git a/p2p/rpc_notifications.go b/p2p/rpc_notifications.go index db0ba20..63a30c5 100644 --- a/p2p/rpc_notifications.go +++ b/p2p/rpc_notifications.go @@ -307,7 +307,7 @@ func (c *Connection) processChunkedBlock(request Objects, isnotified bool, wasch } // object is already is in our chain, we need not relay it - if chain.Is_Block_Topological_order(blid) { + if chain.Is_Block_Topological_order(blid) || chain.Is_Block_Tip(blid) { return nil } @@ -396,24 +396,7 @@ func (c *Connection) processChunkedBlock(request Objects, isnotified bool, wasch } // make sure connection does not timeout and be killed while processing huge blocks - processing_complete := make(chan bool) - go func() { - ticker := time.NewTicker(500 * time.Millisecond) - defer ticker.Stop() - for { - select { - case <-processing_complete: - return // complete the loop - case <-ticker.C: // give the chain some more time to respond - atomic.StoreInt64(&c.LastObjectRequestTime, time.Now().Unix()) - } - } - }() - - defer func() { - processing_complete <- true - }() - + atomic.StoreInt64(&c.LastObjectRequestTime, time.Now().Unix()) // check if we can add ourselves to chain if err, ok := chain.Add_Complete_Block(&cbl); ok { // if block addition was successfil // notify all peers diff --git a/rpc/daemon_rpc.go b/rpc/daemon_rpc.go index a54d3ae..a8cd517 100644 --- a/rpc/daemon_rpc.go +++ b/rpc/daemon_rpc.go @@ -226,18 +226,22 @@ type ( GetSC_Params struct { SCID string `json:"scid"` Code bool `json:"code,omitempty"` // if true code will be returned + Variables bool `json:"variables,omitempty"` // if true all SC variables will be returned TopoHeight int64 `json:"topoheight,omitempty"` // all queries are related to this topoheight KeysUint64 []uint64 `json:"keysuint64,omitempty"` KeysString []string `json:"keysstring,omitempty"` KeysBytes [][]byte `json:"keysbytes,omitempty"` // all keys can also be represented as bytes } GetSC_Result struct { - ValuesUint64 []string `json:"valuesuint64,omitempty"` - ValuesString []string `json:"valuesstring,omitempty"` - ValuesBytes []string `json:"valuesbytes,omitempty"` - Balance uint64 `json:"balance"` - Code string `json:"code"` - Status string `json:"status"` + ValuesUint64 []string `json:"valuesuint64,omitempty"` + ValuesString []string `json:"valuesstring,omitempty"` + ValuesBytes []string `json:"valuesbytes,omitempty"` + VariableStringKeys map[string]interface{} `json:"stringkeys,omitempty"` + VariableUint64Keys map[uint64]interface{} `json:"uint64keys,omitempty"` + Balances map[string]uint64 `json:"balances,omitempty"` + Balance uint64 `json:"balance"` + Code string `json:"code"` + Status string `json:"status"` } ) diff --git a/walletapi/daemon_communication.go b/walletapi/daemon_communication.go index 86cf180..df90e94 100644 --- a/walletapi/daemon_communication.go +++ b/walletapi/daemon_communication.go @@ -282,7 +282,7 @@ func (w *Wallet_Memory) DecodeEncryptedBalanceNow(el *crypto.ElGamal) uint64 { func (w *Wallet_Memory) GetSelfEncryptedBalanceAtTopoHeight(scid crypto.Hash, topoheight int64) (r rpc.GetEncryptedBalance_Result, err error) { defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while connecting", "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while connecting", "r", r, "stack", debug.Stack()) err = fmt.Errorf("Recovered while connecting", "stack", debug.Stack()) } }() @@ -301,7 +301,7 @@ func (w *Wallet_Memory) GetEncryptedBalanceAtTopoHeight(scid crypto.Hash, topohe defer func() { if r := recover(); r != nil { - logger.V(1).Error(r.(error), "Recovered while connecting", "stack", debug.Stack()) + logger.V(1).Error(nil, "Recovered while connecting", "r", r, "stack", debug.Stack()) err = fmt.Errorf("Recovered while connecting", "stack", debug.Stack()) } }() @@ -437,6 +437,12 @@ func (w *Wallet_Memory) Random_ring_members(scid crypto.Hash) (alist []string) { // sync history of wallet from blockchain func (w *Wallet_Memory) SyncHistory(scid crypto.Hash) (balance uint64) { + defer func() { + if r := recover(); r != nil { + logger.V(1).Error(nil, "Recovered while syncing connecting", "r", r, "stack", debug.Stack()) + } + }() + if w.getEncryptedBalanceresult(scid).Registration < 0 { // unregistered so skip return } @@ -707,6 +713,11 @@ func (w *Wallet_Memory) synchistory_block(scid crypto.Hash, topo int64) (err err continue } + // if daemon was syncing/or disk corrupption, it may not give data, so skip + if len(tx_result.Txs) == 0 { + return fmt.Errorf("Daemon did not expandd tx %s", bl.Tx_hashes[i].String()) + } + // since balance might change with tx, we track within tx using this previous_balance_e_tx := new(crypto.ElGamal).Deserialize(previous_balance_e.Serialize()) diff --git a/walletapi/rpcserver/rpc_websocket_server.go b/walletapi/rpcserver/rpc_websocket_server.go index c08ad51..f5c6f79 100644 --- a/walletapi/rpcserver/rpc_websocket_server.go +++ b/walletapi/rpcserver/rpc_websocket_server.go @@ -138,7 +138,7 @@ func (rpcserver *RPCServer) Run(wallet *walletapi.Wallet_Disk) { var ws_server *jrpc2.Server defer func() { if r := recover(); r != nil { // safety so if anything wrong happens, verification fails - rpcserver.logger.V(1).Error(r.(error), "Recovered while processing websocket request", "stack", debug.Stack()) + rpcserver.logger.V(1).Error(nil, "Recovered while processing websocket request", "r", r, "stack", debug.Stack()) } if ws_server != nil { client_connections.Delete(ws_server)