func NewExistingBlock(layerIndex LayerID, data []byte, txs []TransactionID) *Block {
	b := Block{
		MiniBlock: MiniBlock{
			BlockHeader: BlockHeader{
				LayerIndex: layerIndex,
				Data:       data,
			},
			TxIDs: txs,
		},
	}
	b.Signature = signing.NewEdSigner().Sign(b.Bytes())
	b.Initialize()
	return &b
}
NewExistingBlock returns a block in the given layer with the given arbitrary data. The block is signed with a random
keypair that isn't stored anywhere. This method should be phased out of use in production code (it's currently used
in tests and the temporary genesis flow).
package types
import (
	"bytes"
	"fmt"
	"sort"
	"strconv"
	"strings"
	"sync/atomic"
	"github.com/spacemeshos/ed25519"
	"github.com/spacemeshos/go-spacemesh/common/util"
	"github.com/spacemeshos/go-spacemesh/log"
	"github.com/spacemeshos/go-spacemesh/signing"
)
const (
	LayerIDSize = 4
	BlockIDSize = Hash32Length
)
type BlockID Hash20
func (id BlockID) String() string {
	return id.AsHash32().ShortString()
}
func (id BlockID) Field() log.Field {
	return log.String("block_id", id.AsHash32().ShortString())
}
func (id BlockID) Compare(other BlockID) bool {
	return bytes.Compare(id.Bytes(), other.Bytes()) < 0
}
func (id BlockID) AsHash32() Hash32 {
	return Hash20(id).ToHash32()
}
var (
	layersPerEpoch uint32
	effectiveGenesis uint32
	EmptyLayerHash = Hash32{}
)
func SetLayersPerEpoch(layers uint32) {
	atomic.StoreUint32(&layersPerEpoch, layers)
	atomic.StoreUint32(&effectiveGenesis, layers*2-1)
}
func getLayersPerEpoch() uint32 {
	return atomic.LoadUint32(&layersPerEpoch)
}
func GetEffectiveGenesis() LayerID {
	return NewLayerID(atomic.LoadUint32(&effectiveGenesis))
}
func NewLayerID(value uint32) LayerID {
	return LayerID{Value: value}
}
type LayerID struct {
	Value uint32
}
func (l LayerID) GetEpoch() EpochID {
	return EpochID(l.Value / getLayersPerEpoch())
}
func (l LayerID) Add(layers uint32) LayerID {
	nl := l.Value + layers
	if nl < l.Value {
		panic("layer_id wraparound")
	}
	l.Value = nl
	return l
}
func (l LayerID) Sub(layers uint32) LayerID {
	if layers > l.Value {
		panic("layer_id wraparound")
	}
	l.Value -= layers
	return l
}
func (l LayerID) OrdinalInEpoch() uint32 {
	return l.Value % getLayersPerEpoch()
}
func (l LayerID) FirstInEpoch() bool {
	return l.OrdinalInEpoch() == 0
}
func (l LayerID) Mul(layers uint32) LayerID {
	if l.Value == 0 {
		return l
	}
	nl := l.Value * layers
	if nl/l.Value != layers {
		panic("layer_id wraparound")
	}
	l.Value = nl
	return l
}
func (l LayerID) Uint32() uint32 {
	return l.Value
}
func (l LayerID) Before(other LayerID) bool {
	return l.Value < other.Value
}
func (l LayerID) After(other LayerID) bool {
	return l.Value > other.Value
}
func (l LayerID) Difference(other LayerID) uint32 {
	if other.Value > l.Value {
		panic(fmt.Sprintf("other (%d) must be before or equal to this layer (%d)", other.Value, l.Value))
	}
	return l.Value - other.Value
}
func (l LayerID) Field() log.Field { return log.Uint32("layer_id", l.Value) }
func (l LayerID) String() string {
	return strconv.FormatUint(uint64(l.Value), 10)
}
type NodeID struct {
	Key string
	VRFPublicKey []byte
}
func (id NodeID) String() string {
	return id.Key + string(id.VRFPublicKey)
}
func (id NodeID) ToBytes() []byte {
	return util.Hex2Bytes(id.String())
}
func (id NodeID) ShortString() string {
	name := id.Key
	return Shorten(name, 5)
}
func BytesToNodeID(b []byte) (*NodeID, error) {
	if len(b) < 32 {
		return nil, fmt.Errorf("invalid input length, input too short")
	}
	if len(b) > 64 {
		return nil, fmt.Errorf("invalid input length, input too long")
	}
	pubKey := b[0:32]
	vrfKey := b[32:]
	return &NodeID{
		Key:          util.Bytes2Hex(pubKey),
		VRFPublicKey: []byte(util.Bytes2Hex(vrfKey)),
	}, nil
}
func StringToNodeID(s string) (*NodeID, error) {
	strLen := len(s)
	if strLen < 64 {
		return nil, fmt.Errorf("invalid length, input too short")
	}
	if strLen > 128 {
		return nil, fmt.Errorf("invalid length, input too long")
	}
	pubKey := s[:64]
	vrfKey := s[64:]
	return &NodeID{
		Key:          pubKey,
		VRFPublicKey: []byte(vrfKey),
	}, nil
}
func (id NodeID) Field() log.Field { return log.String("node_id", id.Key) }
type BlockEligibilityProof struct {
	J uint32
	Sig []byte
}
type BlockHeader struct {
	LayerIndex       LayerID
	ATXID            ATXID
	EligibilityProof BlockEligibilityProof
	Data             []byte
	BaseBlock BlockID
	AgainstDiff []BlockID  
	ForDiff     []BlockID  
	NeutralDiff []BlockID  
}
func (b BlockHeader) Layer() LayerID {
	return b.LayerIndex
}
type MiniBlock struct {
	BlockHeader
	TxIDs          []TransactionID
	ActiveSet      *[]ATXID
	RefBlock       *BlockID
	TortoiseBeacon []byte
}
type Block struct {
	MiniBlock
	id        BlockID             
	minerID   *signing.PublicKey  
	Signature []byte
}
func (b *Block) Bytes() []byte {
	blkBytes, err := InterfaceToBytes(b.MiniBlock)
	if err != nil {
		log.Panic(fmt.Sprintf("could not extract block bytes, %v", err))
	}
	return blkBytes
}
func (b *Block) Fields() []log.LoggableField {
	activeSet := 0
	if b.ActiveSet != nil {
		activeSet = len(*b.ActiveSet)
	}
	return []log.LoggableField{
		b.ID(),
		b.LayerIndex,
		b.LayerIndex.GetEpoch(),
		log.FieldNamed("miner_id", b.MinerID()),
		log.String("base_block", b.BaseBlock.String()),
		log.Int("supports", len(b.ForDiff)),
		log.Int("againsts", len(b.AgainstDiff)),
		log.Int("abstains", len(b.NeutralDiff)),
		b.ATXID,
		log.Uint32("eligibility_counter", b.EligibilityProof.J),
		log.FieldNamed("ref_block", b.RefBlock),
		log.Int("active_set_size", activeSet),
		log.Int("tx_count", len(b.TxIDs)),
	}
}
func (b *Block) ID() BlockID {
	return b.id
}
func (b *Block) Initialize() {
	blockBytes, err := InterfaceToBytes(b.MiniBlock)
	if err != nil {
		panic("failed to marshal block: " + err.Error())
	}
	b.id = BlockID(CalcHash32(blockBytes).ToHash20())
	pubkey, err := ed25519.ExtractPublicKey(blockBytes, b.Signature)
	if err != nil {
		panic("failed to extract public key: " + err.Error())
	}
	b.minerID = signing.NewPublicKey(pubkey)
}
func (b Block) Hash32() Hash32 {
	return b.id.AsHash32()
}
func (b Block) ShortString() string {
	return b.id.AsHash32().ShortString()
}
func (b *Block) MinerID() *signing.PublicKey {
	return b.minerID
}
type DBBlock struct {
	MiniBlock
	ID        BlockID
	Signature []byte
	MinerID   []byte  
}
func (b *DBBlock) ToBlock() *Block {
	return &Block{
		id:        b.ID,
		MiniBlock: b.MiniBlock,
		Signature: b.Signature,
		minerID:   signing.NewPublicKey(b.MinerID),
	}
}
func BlockIDs(blocks []*Block) []BlockID {
	ids := make([]BlockID, 0, len(blocks))
	for _, block := range blocks {
		ids = append(ids, block.ID())
	}
	return ids
}
func BlockIdsField(ids []BlockID) log.Field {
	var strs []string
	for _, a := range ids {
		strs = append(strs, a.String())
	}
	return log.String("block_ids", strings.Join(strs, ", "))
}
type Layer struct {
	blocks []*Block
	index  LayerID
}
func (l *Layer) Field() log.Field {
	return log.String("layer",
		fmt.Sprintf("layerhash %s layernum %d numblocks %d", l.Hash().String(), l.index, len(l.blocks)))
}
func (l *Layer) Index() LayerID {
	return l.index
}
func (l *Layer) Blocks() []*Block {
	return l.blocks
}
func (l *Layer) BlocksIDs() []BlockID {
	blockIDs := make([]BlockID, len(l.blocks))
	for i := range l.blocks {
		blockIDs[i] = l.blocks[i].ID()
	}
	return blockIDs
}
func (l Layer) Hash() Hash32 {
	if len(l.blocks) == 0 {
		return EmptyLayerHash
	}
	return CalcBlocksHash32(SortBlockIDs(BlockIDs(l.blocks)), nil)
}
func (l *Layer) AddBlock(block *Block) {
	if block.LayerIndex != l.index {
		log.Panic("add block with wrong layer number act %v exp %v", block.LayerIndex, l.index)
	}
	l.blocks = append(l.blocks, block)
}
func (l *Layer) SetBlocks(blocks []*Block) {
	l.blocks = blocks
}
func NewExistingLayer(idx LayerID, blocks []*Block) *Layer {
	l := Layer{
		blocks: blocks,
		index:  idx,
	}
	return &l
}