From 3acbbee23416e24cc07b33de91a46c2ecc1a8ade Mon Sep 17 00:00:00 2001 From: Captain Date: Fri, 4 Mar 2022 15:05:04 +0000 Subject: [PATCH] DERO-HE STARGATE Mainnet HardFork-2 Release48 --- blockchain/blockchain.go | 69 +++++++++++++++++++++++++------ blockchain/hardcoded_contracts.go | 11 ++--- blockchain/transaction_execute.go | 3 +- cmd/dero-miner/miner.go | 2 + cmd/derod/main.go | 2 +- config/config.go | 7 ++++ config/seed_nodes.go | 2 +- config/version.go | 2 +- dvm/sc.go | 26 ++++++++---- dvm/sc_test.go | 25 +++++++++++ hardfork.md | 3 -- p2p/rpc_handshake.go | 3 +- 12 files changed, 116 insertions(+), 39 deletions(-) create mode 100644 dvm/sc_test.go delete mode 100644 hardfork.md diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 75fa4ae..dcb7c10 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -58,7 +58,6 @@ import "github.com/deroproject/graviton" // this structure must be update while mutex type Blockchain struct { Store storage // interface to storage layer - Height int64 // chain height is always 1 more than block Top_ID crypto.Hash // id of the top block Pruned int64 // until where the chain has been pruned MiniBlocks *block.MiniBlocksCollection // used for consensus @@ -210,6 +209,42 @@ func Blockchain_Start(params map[string]interface{}) (*Blockchain, error) { logger.Info("Chain Pruned till", "topoheight", chain.Pruned) } + // detect case if chain was corrupted earlier,so as it can be deleted and resynced + if chain.Pruned < globals.Config.HF1_HEIGHT && globals.IsMainnet() && chain.Get_Height() >= globals.Config.HF1_HEIGHT+1 { + toporecord, err := chain.Store.Topo_store.Read(globals.Config.HF1_HEIGHT + 1) + if err != nil { + panic(err) + } + var ss *graviton.Snapshot + ss, err = chain.Store.Balance_store.LoadSnapshot(toporecord.State_Version) + if err != nil { + panic(err) + } + + var namehash_scid crypto.Hash + namehash_scid[31] = 1 + sc_data_tree, err := ss.GetTree(string(namehash_scid[:])) + if err != nil { + panic(err) + } + + if code_bytes, err := sc_data_tree.Get(dvm.SC_Code_Key(namehash_scid)); err == nil { + var v dvm.Variable + if err = v.UnmarshalBinary(code_bytes); err != nil { + panic("Unmarshal error") + } + if !strings.Contains(v.ValueString, "UpdateCode") { + logger.Error(nil, "Chain corruption detected") + logger.Error(nil, "You need to delete existing mainnet folder and resync chain again") + os.Exit(-1) + return nil, err + } + + } else { + panic(err) + } + } + metrics.Version = config.Version.String() go metrics.Dump_metrics_data_directly(logger, globals.Arguments["--node-tag"]) // enable metrics if someone needs them @@ -294,7 +329,6 @@ func (chain *Blockchain) Initialise_Chain_From_DB() { // then downgrading to top-10 height // then reworking the chain to get the tip best_height := chain.Load_TOP_HEIGHT() - chain.Height = best_height chain.Tips = map[crypto.Hash]crypto.Hash{} // reset the map // reload top tip from disk @@ -302,7 +336,7 @@ func (chain *Blockchain) Initialise_Chain_From_DB() { chain.Tips[top] = top // we only can load a single tip from db - logger.V(1).Info("Reloaded Chain from disk", "Tips", chain.Tips, "Height", chain.Height) + logger.V(1).Info("Reloaded Chain from disk", "Tips", chain.Tips, "Height", best_height) } // before shutdown , make sure p2p is confirmed stopped @@ -807,9 +841,9 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro if height > chain.Get_Height() || height == 0 { // exception for genesis block //atomic.StoreInt64(&chain.Height, height) height_changed = true - block_logger.Info("Chain extended", "new height", chain.Height) + block_logger.Info("Chain extended", "new height", height) } else { - block_logger.Info("Chain extended but height is same", "new height", chain.Height) + block_logger.Info("Chain extended but height is same", "new height", height) } { @@ -916,15 +950,24 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro } var meta dvm.SC_META_DATA // the meta contains metadata about SC - if err := meta.UnmarshalBinary(meta_bytes); err != nil { - panic(err) - } - if meta.DataHash, err = v.Hash(); err != nil { // encode data tree hash - panic(err) + if bl_current.Height < uint64(globals.Config.HF2_HEIGHT) { + if err := meta.UnmarshalBinary(meta_bytes); err != nil { + panic(err) + } + if meta.DataHash, err = v.Hash(); err != nil { // encode data tree hash + panic(err) + } + sc_meta.Put(dvm.SC_Meta_Key(scid), meta.MarshalBinary()) + } else { + if err := meta.UnmarshalBinaryGood(meta_bytes); err != nil { + panic(err) + } + if meta.DataHash, err = v.Hash(); err != nil { // encode data tree hash + panic(err) + } + sc_meta.Put(dvm.SC_Meta_Key(scid), meta.MarshalBinaryGood()) } - - sc_meta.Put(dvm.SC_Meta_Key(scid), meta.MarshalBinary()) data_trees = append(data_trees, v) /*fmt.Printf("will commit tree name %x \n", v.GetName()) @@ -1039,7 +1082,7 @@ func (chain *Blockchain) Add_Complete_Block(cbl *block.Complete_Block) (err erro // every 2000 block print a line if chain.Get_Height()%2000 == 0 { - block_logger.Info(fmt.Sprintf("Chain Height %d", chain.Height)) + block_logger.Info(fmt.Sprintf("Chain Height %d", chain.Get_Height())) } purge_count := chain.MiniBlocks.PurgeHeight(chain.Get_Stable_Height()) // purge all miniblocks upto this height diff --git a/blockchain/hardcoded_contracts.go b/blockchain/hardcoded_contracts.go index b30fd9e..07694c1 100644 --- a/blockchain/hardcoded_contracts.go +++ b/blockchain/hardcoded_contracts.go @@ -22,6 +22,7 @@ import _ "embed" import "github.com/deroproject/graviton" import "github.com/deroproject/derohe/dvm" +import "github.com/deroproject/derohe/globals" import "github.com/deroproject/derohe/cryptography/crypto" //go:embed hardcoded_sc/nameservice.bas @@ -34,35 +35,29 @@ var source_nameservice_updateable string func (chain *Blockchain) install_hardcoded_contracts(cache map[crypto.Hash]*graviton.Tree, ss *graviton.Snapshot, balance_tree *graviton.Tree, sc_tree *graviton.Tree, height uint64) (err error) { if height == 0 { - if _, _, err = dvm.ParseSmartContract(source_nameservice); err != nil { logger.Error(err, "error Parsing hard coded sc") panic(err) - return } var name crypto.Hash name[31] = 1 if err = chain.install_hardcoded_sc(cache, ss, balance_tree, sc_tree, source_nameservice, name); err != nil { panic(err) - return } - - return } - if height == 21480 { // update SC at specific height + // it is updated at 0 height for testnets + if height == uint64(globals.Config.HF1_HEIGHT) { // update SC at specific height if _, _, err = dvm.ParseSmartContract(source_nameservice_updateable); err != nil { logger.Error(err, "error Parsing hard coded sc") panic(err) - return } var name crypto.Hash name[31] = 1 if err = chain.install_hardcoded_sc(cache, ss, balance_tree, sc_tree, source_nameservice_updateable, name); err != nil { panic(err) - return } } diff --git a/blockchain/transaction_execute.go b/blockchain/transaction_execute.go index 669c606..f8e9d32 100644 --- a/blockchain/transaction_execute.go +++ b/blockchain/transaction_execute.go @@ -250,7 +250,6 @@ func (chain *Blockchain) process_transaction(changed map[crypto.Hash]*graviton.T default: panic("unknown transaction, do not know how to process it") - return 0 } } @@ -277,7 +276,7 @@ func (chain *Blockchain) process_transaction_sc(cache map[crypto.Hash]*graviton. defer func() { if r := recover(); r != nil { - logger.V(1).Error(nil, "Recover while executing SC ", "txid", txhash, "error", r, "stack", fmt.Sprintf("%s", string(debug.Stack()))) + logger.V(2).Error(nil, "Recover while executing SC ", "txid", txhash, "error", r, "stack", fmt.Sprintf("%s", string(debug.Stack()))) } }() diff --git a/cmd/dero-miner/miner.go b/cmd/dero-miner/miner.go index 3b69a8d..9d1d713 100644 --- a/cmd/dero-miner/miner.go +++ b/cmd/dero-miner/miner.go @@ -446,6 +446,8 @@ func mineblock(tid int) { var diff big.Int var work [block.MINIBLOCK_SIZE]byte + time.Sleep(5*time.Second) + nonce_buf := work[block.MINIBLOCK_SIZE-5:] //since slices are linked, it modifies parent runtime.LockOSThread() threadaffinity() diff --git a/cmd/derod/main.go b/cmd/derod/main.go index 1b25385..46a6c51 100644 --- a/cmd/derod/main.go +++ b/cmd/derod/main.go @@ -678,7 +678,7 @@ restart_loop: panic(err) } if r.BLOCK_ID != current_blid { - fmt.Printf("corruption due to XYZ r %+v , current_blid %s current_blid_height\n", r, current_blid, height) + fmt.Printf("corruption due to XYZ r %+v , current_blid %s current_blid_height %d\n", r, current_blid, height) fix_commit_version, err := chain.ReadBlockSnapshotVersion(current_blid) if err != nil { diff --git a/config/config.go b/config/config.go index 5f389d8..bfa48f9 100644 --- a/config/config.go +++ b/config/config.go @@ -85,6 +85,9 @@ type CHAIN_CONFIG struct { RPC_Default_Port int Wallet_RPC_Default_Port int + HF1_HEIGHT int64 // first HF applied here + HF2_HEIGHT int64 // second HF applie here + Dev_Address string // to which address the integrator rewatd will go, if user doesn't specify integrator address' Genesis_Tx string Genesis_Block_Hash crypto.Hash @@ -96,6 +99,8 @@ var Mainnet = CHAIN_CONFIG{Name: "mainnet", RPC_Default_Port: 10102, Wallet_RPC_Default_Port: 10103, Dev_Address: "dero1qykyta6ntpd27nl0yq4xtzaf4ls6p5e9pqu0k2x4x3pqq5xavjsdxqgny8270", + HF1_HEIGHT: 21480, + HF2_HEIGHT: 29000, Genesis_Tx: "" + "01" + // version @@ -114,6 +119,8 @@ var Testnet = CHAIN_CONFIG{Name: "testnet", // testnet will always have last 3 b Wallet_RPC_Default_Port: 40403, Dev_Address: "deto1qy0ehnqjpr0wxqnknyc66du2fsxyktppkr8m8e6jvplp954klfjz2qqdzcd8p", + HF1_HEIGHT: 0, // on testnet apply at genesis + HF2_HEIGHT: 0, // on testnet apply at genesis Genesis_Tx: "" + "01" + // version diff --git a/config/seed_nodes.go b/config/seed_nodes.go index 4f7f73d..cafa509 100644 --- a/config/seed_nodes.go +++ b/config/seed_nodes.go @@ -22,7 +22,7 @@ package config // only version 2 var Mainnet_seed_nodes = []string{ "185.132.176.174:11011", - "190.2.135.218:11011", + "45.82.66.54:8080", "185.107.69.12:11011", "89.38.97.110:11011", } diff --git a/config/version.go b/config/version.go index a2255da..86af828 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.130-0.DEROHE.STARGATE+26022022") +var Version = semver.MustParse("3.4.133-48.DEROHE.STARGATE+26022022") diff --git a/dvm/sc.go b/dvm/sc.go index b34661d..977dee4 100644 --- a/dvm/sc.go +++ b/dvm/sc.go @@ -56,6 +56,23 @@ func (meta *SC_META_DATA) UnmarshalBinary(buf []byte) (err error) { return nil } +// serialize the structure +func (meta SC_META_DATA) MarshalBinaryGood() (buf []byte) { + buf = make([]byte, 0, 33) + buf = append(buf, meta.Type) + buf = append(buf, meta.DataHash[:]...) + return +} + +func (meta *SC_META_DATA) UnmarshalBinaryGood(buf []byte) (err error) { + if len(buf) != 1+32 { + return fmt.Errorf("input buffer should be of 33 bytes in length") + } + meta.Type = buf[0] + copy(meta.DataHash[:], buf[1:]) + return nil +} + func SC_Meta_Key(scid crypto.Hash) []byte { return scid[:] } @@ -277,15 +294,6 @@ func Execute_sc_function(w_sc_tree *Tree_Wrapper, data_tree *Tree_Wrapper, scid // reads SC, balance func ReadSC(w_sc_tree *Tree_Wrapper, data_tree *Tree_Wrapper, scid crypto.Hash) (balance uint64, sc SmartContract, found bool) { - meta_bytes, err := w_sc_tree.Get(SC_Meta_Key(scid)) - if err != nil { - return - } - - var meta SC_META_DATA // the meta contains the link to the SC bytes - if err := meta.UnmarshalBinary(meta_bytes); err != nil { - return - } var zerohash crypto.Hash balance, _ = LoadSCAssetValue(data_tree, scid, zerohash) diff --git a/dvm/sc_test.go b/dvm/sc_test.go new file mode 100644 index 0000000..054ed4d --- /dev/null +++ b/dvm/sc_test.go @@ -0,0 +1,25 @@ +package dvm + +import "time" +import "testing" +import "math/rand" + +func TestSC_META_DATA(t *testing.T) { + rand.Seed(time.Now().UnixNano()) + for i := 0; i < 256; i++ { + sctype := byte(i) + var meta, meta2 SC_META_DATA + for j := 0; j < 10000; j++ { + meta.Type = sctype + rand.Read(meta.DataHash[:]) + + ser := meta.MarshalBinaryGood() + if err := meta2.UnmarshalBinaryGood(ser[:]); err != nil { + t.Fatalf("marshallling unmarshalling failed") + } + if meta != meta2 { + t.Fatalf("marshallling unmarshalling failed") + } + } + } +} diff --git a/hardfork.md b/hardfork.md deleted file mode 100644 index a5d8240..0000000 --- a/hardfork.md +++ /dev/null @@ -1,3 +0,0 @@ -21400 First HardFork - - diff --git a/p2p/rpc_handshake.go b/p2p/rpc_handshake.go index a4da23d..3bec6ca 100644 --- a/p2p/rpc_handshake.go +++ b/p2p/rpc_handshake.go @@ -58,7 +58,8 @@ func (connection *Connection) dispatch_test_handshake() { //scan our peer list and send peers which have been recently communicated request.PeerList = get_peer_list_specific(Address(connection)) - ctx, _ := context.WithTimeout(context.Background(), 4*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 4*time.Second) + defer cancel() if err := connection.Client.CallWithContext(ctx, "Peer.Handshake", request, &response); err != nil { connection.logger.V(4).Error(err, "cannot handshake") connection.exit()