2018-03-09 15:55:25 +00:00
|
|
|
package core
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"sort"
|
|
|
|
|
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/storage"
|
2018-03-21 16:11:04 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/core/transaction"
|
2018-03-17 11:53:21 +00:00
|
|
|
"github.com/CityOfZion/neo-go/pkg/util"
|
|
|
|
)
|
2018-03-09 15:55:25 +00:00
|
|
|
|
|
|
|
// Utilities for quick bootstrapping blockchains. Normally we should
|
|
|
|
// create the genisis block. For now (to speed up development) we will add
|
|
|
|
// The hashes manually.
|
|
|
|
|
|
|
|
func GenesisHashPrivNet() util.Uint256 {
|
|
|
|
hash, _ := util.Uint256DecodeString("996e37358dc369912041f966f8c5d8d3a8255ba5dcbd3447f8a82b55db869099")
|
|
|
|
return hash
|
|
|
|
}
|
2018-03-10 12:04:06 +00:00
|
|
|
|
|
|
|
func GenesisHashTestNet() util.Uint256 {
|
|
|
|
hash, _ := util.Uint256DecodeString("b3181718ef6167105b70920e4a8fbbd0a0a56aacf460d70e10ba6fa1668f1fef")
|
|
|
|
return hash
|
|
|
|
}
|
|
|
|
|
|
|
|
func GenesisHashMainNet() util.Uint256 {
|
|
|
|
hash, _ := util.Uint256DecodeString("d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf")
|
|
|
|
return hash
|
|
|
|
}
|
2018-03-17 11:53:21 +00:00
|
|
|
|
|
|
|
// headerSliceReverse reverses the given slice of *Header.
|
|
|
|
func headerSliceReverse(dest []*Header) {
|
|
|
|
for i, j := 0, len(dest)-1; i < j; i, j = i+1, j-1 {
|
|
|
|
dest[i], dest[j] = dest[j], dest[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// storeAsCurrentBlock stores the given block witch prefix
|
|
|
|
// SYSCurrentBlock.
|
|
|
|
func storeAsCurrentBlock(batch storage.Batch, block *Block) {
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
buf.Write(block.Hash().BytesReverse())
|
|
|
|
b := make([]byte, 4)
|
|
|
|
binary.LittleEndian.PutUint32(b, block.Index)
|
|
|
|
buf.Write(b)
|
|
|
|
batch.Put(storage.SYSCurrentBlock.Bytes(), buf.Bytes())
|
|
|
|
}
|
|
|
|
|
|
|
|
// storeAsBlock stores the given block as DataBlock.
|
|
|
|
func storeAsBlock(batch storage.Batch, block *Block, sysFee uint32) error {
|
|
|
|
var (
|
|
|
|
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
|
|
|
|
buf = new(bytes.Buffer)
|
|
|
|
)
|
|
|
|
|
|
|
|
b := make([]byte, 4)
|
|
|
|
binary.LittleEndian.PutUint32(b, sysFee)
|
|
|
|
|
|
|
|
b, err := block.Trim()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
buf.Write(b)
|
|
|
|
batch.Put(key, buf.Bytes())
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-03-21 16:11:04 +00:00
|
|
|
// storeAsTransaction stores the given TX as DataTransaction.
|
|
|
|
func storeAsTransaction(batch storage.Batch, tx *transaction.Transaction, index uint32) error {
|
|
|
|
key := storage.AppendPrefix(storage.DataTransaction, tx.Hash().BytesReverse())
|
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
if err := tx.EncodeBinary(buf); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
dest := make([]byte, buf.Len()+4)
|
|
|
|
binary.LittleEndian.PutUint32(dest[:4], index)
|
|
|
|
copy(dest[4:], buf.Bytes())
|
|
|
|
batch.Put(key, dest)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-03-17 11:53:21 +00:00
|
|
|
// readStoredHeaderHashes returns a sorted list of header hashes
|
|
|
|
// retrieved from the given Store.
|
|
|
|
func readStoredHeaderHashes(store storage.Store) ([]util.Uint256, error) {
|
|
|
|
hashMap := make(map[uint32][]util.Uint256)
|
|
|
|
store.Seek(storage.IXHeaderHashList.Bytes(), func(k, v []byte) {
|
|
|
|
storedCount := binary.LittleEndian.Uint32(k[1:])
|
|
|
|
hashes, err := util.Read2000Uint256Hashes(v)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
hashMap[storedCount] = hashes
|
|
|
|
})
|
|
|
|
|
|
|
|
var (
|
|
|
|
i = 0
|
|
|
|
sortedKeys = make([]int, len(hashMap))
|
|
|
|
)
|
|
|
|
|
|
|
|
for k, _ := range hashMap {
|
|
|
|
sortedKeys[i] = int(k)
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
sort.Ints(sortedKeys)
|
|
|
|
|
|
|
|
hashes := []util.Uint256{}
|
|
|
|
for _, key := range sortedKeys {
|
|
|
|
values := hashMap[uint32(key)]
|
|
|
|
for _, hash := range values {
|
|
|
|
hashes = append(hashes, hash)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return hashes, nil
|
|
|
|
}
|