diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 9c184a4..a56ffe8 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -425,7 +425,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro for _, mbl := range bl.MiniBlocks { var miner_hash crypto.Hash copy(miner_hash[:], mbl.KeyHash[:]) - if !chain.IsAddressHashValid(miner_hash) { + if !chain.IsAddressHashValid(true, miner_hash) { err = fmt.Errorf("miner address not registered") return err, false } diff --git a/blockchain/miner_block.go b/blockchain/miner_block.go index 1144b9a..73bcc7a 100644 --- a/blockchain/miner_block.go +++ b/blockchain/miner_block.go @@ -467,12 +467,12 @@ func (chain *Blockchain) Create_new_block_template_mining(miniblock_miner_addres var miner_hash crypto.Hash copy(miner_hash[:], mbl.KeyHash[:]) - if !chain.IsAddressHashValid(miner_hash) { + if !chain.IsAddressHashValid(false, miner_hash) { logger.V(3).Error(err, "unregistered miner %s", miner_hash) err = fmt.Errorf("unregistered miner or you need to wait 15 mins") return } - + miniblock_blob = fmt.Sprintf("%x", mbl.Serialize()) return @@ -527,14 +527,6 @@ func (chain *Blockchain) Accept_new_block(tstamp uint64, miniblock_blob []byte) return } - var miner_hash crypto.Hash - copy(miner_hash[:], mbl.KeyHash[:]) - if !chain.IsAddressHashValid(miner_hash) { - logger.V(3).Error(err, "unregistered miner %s", miner_hash) - err = fmt.Errorf("unregistered miner or you need to wait 15 mins") - return - } - //fmt.Printf("received miniblock %x block %x\n", miniblock_blob, bl.Serialize()) // lets try to check pow to detect whether the miner is cheating @@ -544,6 +536,14 @@ func (chain *Blockchain) Accept_new_block(tstamp uint64, miniblock_blob []byte) return } + var miner_hash crypto.Hash + copy(miner_hash[:], mbl.KeyHash[:]) + if !chain.IsAddressHashValid(true, miner_hash) { + logger.V(3).Error(err, "unregistered miner %s", miner_hash) + err = fmt.Errorf("unregistered miner or you need to wait 15 mins") + return + } + // if we reach here, everything looks ok bl.MiniBlocks = append(bl.MiniBlocks, mbl) @@ -675,14 +675,16 @@ func (chain *Blockchain) ExpandMiniBlockTip(hash crypto.Hash) (result crypto.Has } // it is USED by consensus and p2p whether the miners has is valid -func (chain *Blockchain) IsAddressHashValid(hashes ...crypto.Hash) (found bool) { +func (chain *Blockchain) IsAddressHashValid(skip_cache bool, hashes ...crypto.Hash) (found bool) { - for _, hash := range hashes { // check whether everything could be satisfied via cache - if _, found := chain.cache_IsAddressHashValid.Get(fmt.Sprintf("%s", hash)); found { - goto hard_way // do things the hard way + if skip_cache { + for _, hash := range hashes { // check whether everything could be satisfied via cache + if _, found := chain.cache_IsAddressHashValid.Get(fmt.Sprintf("%s", hash)); !found { + goto hard_way // do things the hard way + } } + return true } - return true hard_way: // the block may just have been mined, so we evaluate roughly 25 past blocks to cross check diff --git a/blockchain/miniblocks_consensus.go b/blockchain/miniblocks_consensus.go index 9ccde08..229f254 100644 --- a/blockchain/miniblocks_consensus.go +++ b/blockchain/miniblocks_consensus.go @@ -197,7 +197,7 @@ func (chain *Blockchain) InsertMiniBlock(mbl block.MiniBlock) (err error, result var miner_hash crypto.Hash copy(miner_hash[:], mbl.KeyHash[:]) - if !chain.IsAddressHashValid(miner_hash) { + if !chain.IsAddressHashValid(true, miner_hash) { logger.V(1).Error(err, "Invalid miner address") err = fmt.Errorf("Invalid miner address") return err, false diff --git a/config/config.go b/config/config.go index d2d827f..ddb4c07 100644 --- a/config/config.go +++ b/config/config.go @@ -52,12 +52,12 @@ const MAX_RINGSIZE = 128 // <= 128, ringsize will be accepted // Minimum FEE calculation constants are here const FEE_PER_KB = uint64(100) // .00100 dero per kb -const MAINNET_BOOTSTRAP_DIFFICULTY = uint64(800) // atlantis mainnet botstrapped at 200 MH/s -const MAINNET_MINIMUM_DIFFICULTY = uint64(800) // 800 H/s +const MAINNET_BOOTSTRAP_DIFFICULTY = uint64(80000000) // atlantis mainnet botstrapped at 80 MH/s +const MAINNET_MINIMUM_DIFFICULTY = uint64(800000000) // 80 MH/s // testnet bootstraps at 1 MH -const TESTNET_BOOTSTRAP_DIFFICULTY = uint64(10000) // testnet bootstrap at 100 H/s -const TESTNET_MINIMUM_DIFFICULTY = uint64(10000) // 100 H/s +const TESTNET_BOOTSTRAP_DIFFICULTY = uint64(50000) // testnet bootstrap at 50KH/s +const TESTNET_MINIMUM_DIFFICULTY = uint64(10000) // 10KH/s // this single parameter controls lots of various parameters // within the consensus, it should never go below 7 @@ -97,7 +97,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, 0x40, 0x00, 0x00, 0x00}), + Network_ID: uuid.FromBytesOrNil([]byte{0x59, 0xd7, 0xf7, 0xe9, 0xdd, 0x48, 0xd5, 0xfd, 0x13, 0x0a, 0xf6, 0xe0, 0x44, 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 a3349c8..9378c67 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.38-1.DEROHE.STARGATE+08112021") +var Version = semver.MustParse("3.4.45-1.DEROHE.STARGATE+08112021") diff --git a/dvm/dvm_functions_test.go b/dvm/dvm_functions_test.go index 1f31a2e..3223e89 100644 --- a/dvm/dvm_functions_test.go +++ b/dvm/dvm_functions_test.go @@ -179,6 +179,46 @@ var execution_tests_functions = []struct { nil, Variable{Type: String, ValueString: string(decodeHex("41FB"))}, }, + { + "substr()", + `Function TestRun(input String) String + 30 return substr(input,0,5) + End Function`, + "TestRun", + map[string]interface{}{"input": string("0123456789")}, + nil, + Variable{Type: String, ValueString: string("01234")}, + }, + { + "substr()", + `Function TestRun(input String) String + 30 return substr(input,1,5) + End Function`, + "TestRun", + map[string]interface{}{"input": string("0123456789")}, + nil, + Variable{Type: String, ValueString: string("12345")}, + }, + { + "substr()", + `Function TestRun(input String) String + 30 return substr(input,1,129) + End Function`, + "TestRun", + map[string]interface{}{"input": string("0123456789")}, + nil, + Variable{Type: String, ValueString: string("123456789")}, + }, + { + "substr()", + `Function TestRun(input String) String + 30 return substr(input,13,129) + End Function`, + "TestRun", + map[string]interface{}{"input": string("0123456789")}, + nil, + Variable{Type: String, ValueString: string("")}, + }, } func decodeHex(s string) []byte { diff --git a/p2p/chain_sync.go b/p2p/chain_sync.go index 1074d37..edd229d 100644 --- a/p2p/chain_sync.go +++ b/p2p/chain_sync.go @@ -173,6 +173,8 @@ func (connection *Connection) process_object_response(response Objects, sent int processing_complete <- true }() + defer globals.Recover(2) + for i := 0; i < len(response.CBlocks); i++ { // process incoming full blocks var cbl block.Complete_Block // parse incoming block and deserialize it var bl block.Block diff --git a/p2p/chunk_server.go b/p2p/chunk_server.go index ec791bf..24f7c07 100644 --- a/p2p/chunk_server.go +++ b/p2p/chunk_server.go @@ -104,37 +104,36 @@ func (connection *Connection) feed_chunk(chunk *Block_Chunk, sent int64) error { var bl block.Block - if err := bl.Deserialize(chunk.BLOCK); err != nil { - logger.V(1).Error(err, "error deserializing block") - return nil - } - if bl.GetHash() != chunk.BLID { - return fmt.Errorf("Corrupted Chunk. bad block data") - } - - // we must check the Pow now - if int64(bl.Height) >= chain.Get_Height()-3 && int64(bl.Height) <= chain.Get_Height()+3 { - - } else { - return nil // we need not broadcast - } - - if len(bl.Tips) == 0 || len(bl.MiniBlocks) < 5 { - return nil - } - - for _, mbl := range bl.MiniBlocks { - if !chain.VerifyMiniblockPoW(&bl, mbl) { - return errormsg.ErrInvalidPoW - } - } - - broadcast_Chunk(chunk, 0, sent) // broadcast chunk INV - var chunks *Chunks_Per_Block_Data if chunksi, ok := chunk_map.Load(chunk.HHash); ok { chunks = chunksi.(*Chunks_Per_Block_Data) } else { + + if err := bl.Deserialize(chunk.BLOCK); err != nil { + logger.V(1).Error(err, "error deserializing block") + return nil + } + if bl.GetHash() != chunk.BLID { + return fmt.Errorf("Corrupted Chunk. bad block data") + } + + // we must check the Pow now + if int64(bl.Height) >= chain.Get_Height()-3 && int64(bl.Height) <= chain.Get_Height()+3 { + + } else { + return nil // we need not broadcast + } + + if len(bl.Tips) == 0 || len(bl.MiniBlocks) < 5 { + return nil + } + + for _, mbl := range bl.MiniBlocks { + if !chain.VerifyMiniblockPoW(&bl, mbl) { + return errormsg.ErrInvalidPoW + } + } + chunks = new(Chunks_Per_Block_Data) chunks.Created = time.Now() chunk_map.Store(chunk.HHash, chunks) @@ -144,6 +143,10 @@ func (connection *Connection) feed_chunk(chunk *Block_Chunk, sent int64) error { return nil } + if chunks.Chunks[chunk.CHUNK_ID] == nil { + broadcast_Chunk(chunk, 0, sent) // broadcast chunk INV + } + chunks.Lock() defer chunks.Unlock() diff --git a/p2p/connection_pool.go b/p2p/connection_pool.go index 920a417..0baa183 100644 --- a/p2p/connection_pool.go +++ b/p2p/connection_pool.go @@ -803,8 +803,6 @@ func (connection *Connection) isConnectionSyncing() (count int) { func trigger_sync() { defer globals.Recover(3) - topoheight := chain.Load_Block_Topological_order(chain.Get_Top_ID()) - unique_map := UniqueConnections() var clist []*Connection @@ -822,12 +820,14 @@ func trigger_sync() { for _, connection := range clist { + height := chain.Get_Height() + //connection.Lock() recursive mutex are not suported // only choose highest available peers for syncing - if atomic.LoadUint32(&connection.State) != HANDSHAKE_PENDING && topoheight <= atomic.LoadInt64(&connection.TopoHeight) { // skip pre-handshake connections + if atomic.LoadUint32(&connection.State) != HANDSHAKE_PENDING && height < atomic.LoadInt64(&connection.Height) { // skip pre-handshake connections // check whether we are lagging with this connection //connection.Lock() - islagging := topoheight < atomic.LoadInt64(&connection.TopoHeight) + islagging := height < atomic.LoadInt64(&connection.Height) //fmt.Printf("checking cdiff is lagging %+v topoheight %d peer topoheight %d \n", islagging, topoheight, connection.TopoHeight) @@ -840,15 +840,18 @@ func trigger_sync() { continue } - if connection.Height >= (chain.Get_Height() + 1) { // give ourselves one sec, maybe the block is just being written + if connection.Height > chain.Get_Height() { // give ourselves one sec, maybe the block is just being written time.Sleep(time.Second) - islagging = topoheight < atomic.LoadInt64(&connection.TopoHeight) // we only use topoheight, since pruned chain might not have full cdiff + height := chain.Get_Height() + islagging = height < atomic.LoadInt64(&connection.Height) // we only use topoheight, since pruned chain might not have full cdiff + } else { + continue } if islagging { //connection.Lock() - connection.logger.V(1).Info("We need to resync with the peer", "height", connection.Height, "pruned", connection.Pruned) + connection.logger.V(1).Info("We need to resync with the peer", "our_height", height, "height", connection.Height, "pruned", connection.Pruned) //connection.Unlock() // set mode to syncronising diff --git a/p2p/rpc_notifications.go b/p2p/rpc_notifications.go index f5cc2ea..db0ba20 100644 --- a/p2p/rpc_notifications.go +++ b/p2p/rpc_notifications.go @@ -202,7 +202,7 @@ func (c *Connection) NotifyMiniBlock(request Objects, response *Dummy) (err erro var miner_hash crypto.Hash copy(miner_hash[:], mbl.KeyHash[:]) - if !chain.IsAddressHashValid(miner_hash) { + if !chain.IsAddressHashValid(false, miner_hash) { // this will use cache c.logger.V(3).Error(err, "unregistered miner") return fmt.Errorf("unregistered miner") } diff --git a/vendor/github.com/deroproject/graviton/node_leaf.go b/vendor/github.com/deroproject/graviton/node_leaf.go index 148bbe2..6855895 100644 --- a/vendor/github.com/deroproject/graviton/node_leaf.go +++ b/vendor/github.com/deroproject/graviton/node_leaf.go @@ -105,7 +105,7 @@ func (l *leaf) Get(store *Store, keyhash [HASHSIZE]byte) ([]byte, error) { return l.value, nil } - return nil, xerrors.Errorf("%w: collision, keyhash %x not found", ErrNotFound, keyhash) + return nil, xerrors.Errorf("%w: collision, keyhash %x not found, keyhash in ram %x", ErrNotFound, keyhash,l.keyhash) } func (l *leaf) Delete(store *Store, keyhash [HASHSIZE]byte) (bool, bool, error) { diff --git a/vendor/github.com/deroproject/graviton/special.go b/vendor/github.com/deroproject/graviton/special.go index de99784..54fc5e6 100644 --- a/vendor/github.com/deroproject/graviton/special.go +++ b/vendor/github.com/deroproject/graviton/special.go @@ -77,7 +77,7 @@ func (l *leaf) GetKeyValue(store *Store, keyhash [HASHSIZE]byte, valid_bit_count return used_bit_count, l.key, l.value, nil } - return used_bit_count, nil, nil, xerrors.Errorf("%w: collision, keyhash %x not found", ErrNotFound, keyhash) + return used_bit_count, nil, nil, xerrors.Errorf("%w: collision, keyhash %x not found, inram hash %x, used_bit_count %d", ErrNotFound, keyhash,l.keyhash,used_bit_count) } // sets a root for the cursor, so the cursor visits only a specific prefix keys