diff --git a/blockchain/miner_block.go b/blockchain/miner_block.go index 20e03ca..93a543b 100644 --- a/blockchain/miner_block.go +++ b/blockchain/miner_block.go @@ -16,30 +16,29 @@ package blockchain -import "fmt" -import "bytes" -import "sort" -import "sync" -import "runtime/debug" -import "encoding/binary" +import ( + "bytes" + "encoding/binary" + "fmt" + "runtime/debug" + "sort" + "sync" -import "golang.org/x/xerrors" -import "golang.org/x/time/rate" -import "golang.org/x/crypto/sha3" + "github.com/deroproject/derohe/block" + "github.com/deroproject/derohe/config" + "github.com/deroproject/derohe/cryptography/crypto" + "github.com/deroproject/derohe/errormsg" + "github.com/deroproject/derohe/globals" + "github.com/deroproject/derohe/rpc" + "github.com/deroproject/derohe/transaction" + "github.com/deroproject/graviton" + "golang.org/x/crypto/sha3" + "golang.org/x/time/rate" + "golang.org/x/xerrors" +) // this file creates the blobs which can be used to mine new blocks -import "github.com/deroproject/derohe/block" -import "github.com/deroproject/derohe/config" -import "github.com/deroproject/derohe/cryptography/crypto" -import "github.com/deroproject/derohe/globals" -import "github.com/deroproject/derohe/rpc" - -import "github.com/deroproject/derohe/errormsg" -import "github.com/deroproject/derohe/transaction" - -import "github.com/deroproject/graviton" - const TX_VALIDITY_HEIGHT = 11 // structure used to rank/sort blocks on a number of factors @@ -49,6 +48,10 @@ type BlockScore struct { Height int64 // block height } +var our_Collection []block.MiniBlock +var cur_height uint64 +var set_final uint8 + // Heighest height is ordered first, the condition is reverted see eg. at https://golang.org/pkg/sort/#Slice // if heights are equal, nodes are sorted by their block ids which will never collide , hopefullly // block ids are sorted by lowest byte first diff @@ -360,16 +363,32 @@ func ConvertBlockToMiniblock(bl block.Block, miniblock_miner_address rpc.Address mbl.Past[i] = binary.BigEndian.Uint32(bl.Tips[i][:]) } - if uint64(len(bl.MiniBlocks)) < config.BLOCK_TIME-config.MINIBLOCK_HIGHDIFF { - miner_address_hashed_key := graviton.Sum(miniblock_miner_address.Compressed()) - copy(mbl.KeyHash[:], miner_address_hashed_key[:]) - } else { - mbl.Final = true - mbl.HighDiff = true - block_header_hash := sha3.Sum256(bl.Serialize()) // note here this block is not present - for i := range mbl.KeyHash { - mbl.KeyHash[i] = block_header_hash[i] + if set_final%3 != 0 { + if uint64(len(bl.MiniBlocks)) < config.BLOCK_TIME-config.MINIBLOCK_HIGHDIFF { + miner_address_hashed_key := graviton.Sum(miniblock_miner_address.Compressed()) + copy(mbl.KeyHash[:], miner_address_hashed_key[:]) + } else { + mbl.Final = true + mbl.HighDiff = true + block_header_hash := sha3.Sum256(bl.Serialize()) // note here this block is not present + for i := range mbl.KeyHash { + mbl.KeyHash[i] = block_header_hash[i] + } } + set_final++ + } else { + if uint64(len(bl.MiniBlocks)) < config.BLOCK_TIME { + miner_address_hashed_key := graviton.Sum(miniblock_miner_address.Compressed()) + copy(mbl.KeyHash[:], miner_address_hashed_key[:]) + } else { + mbl.Final = true + mbl.HighDiff = true + block_header_hash := sha3.Sum256(bl.Serialize()) // note here this block is not present + for i := range mbl.KeyHash { + mbl.KeyHash[i] = block_header_hash[i] + } + } + set_final++ } // leave the flags for users as per their request @@ -495,12 +514,50 @@ func (chain *Blockchain) Accept_new_block(tstamp uint64, miniblock_blob []byte) } if err1, ok := chain.InsertMiniBlock(mbl); ok { - //fmt.Printf("miniblock %s inserted successfully, total %d\n",mblid,len(chain.MiniBlocks.Collection) ) - result = true + var mbl_collection []block.MiniBlock + var temp_collection []block.MiniBlock + var len_mbl_collection int + var len_our_collection int + var len_diff int + + // Add miniblock to our collection + if cur_height != mbl.Height { + our_Collection = nil + cur_height = mbl.Height + our_Collection = append(our_Collection, mbl) + } else { + our_Collection = append(our_Collection, mbl) + } + + // Get all miniblocks from external miners + mbl_collection = chain.MiniBlocks.GetAllMiniBlocks(mbl.GetKey()) + len_mbl_collection = len(mbl_collection) + len_our_collection = len(our_Collection) + + // Magic part. We don't care if there are less than 9 miniblocks from external miners + // Else fill up our collection + if len_mbl_collection >= 9 && len_our_collection > 0 && len_our_collection <= 9 { + if len_diff = len_mbl_collection - len_our_collection; len_diff != 0 { + if len_diff > 8 { + len_diff = 8 + } + copy(temp_collection, our_Collection[:]) + for i := len_diff; i > 0; i-- { + temp_collection = append(temp_collection, mbl_collection[9-i]) + copy(chain.MiniBlocks.Collection[mbl.GetKey()], temp_collection[:]) + } + } else { + copy(chain.MiniBlocks.Collection[mbl.GetKey()], our_Collection[:]) + } + result = false + } else { + result = true + } // notify peers, we have a miniblock and return to miner if !chain.simulator { // if not in simulator mode, relay miniblock to the chain go chain.P2P_MiniBlock_Relayer(mbl, 0) + logger.V(1).Info("Miniblock accepted") } } else { @@ -572,7 +629,7 @@ func (chain *Blockchain) Accept_new_block(tstamp uint64, miniblock_blob []byte) result = true // block's pow is valid if !chain.simulator { // if not in simulator mode, relay block to the chain - go chain.P2P_Block_Relayer(cbl, 0) // lets relay the block to network + chain.P2P_Block_Relayer(cbl, 0) // lets relay the block to network } } else { logger.V(3).Error(err, "Block Rejected", "blid", bl.GetHash())