Persistance (#53)

* added publish TX for backwards compat.

* lowered the prototick for faster block syncing

* print useragent on startup

* added createMultiRedeemScript for genesis block generation.

* building genesis block from scratch.

* implemented merkle tree.

* starting blockhain with generated genesis hash

* Fixed bug in unspent coin state.

* fixed broken tests after genesis block.

* removed log line.

* bumped version -> 0.34.0
This commit is contained in:
Anthony De Meulemeester 2018-03-25 12:45:54 +02:00 committed by GitHub
parent ad9333c74c
commit 94672cb9cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 955 additions and 187 deletions

View file

@ -4,29 +4,176 @@ import (
"bytes"
"encoding/binary"
"sort"
"time"
"github.com/CityOfZion/neo-go/config"
"github.com/CityOfZion/neo-go/pkg/core/storage"
"github.com/CityOfZion/neo-go/pkg/core/transaction"
"github.com/CityOfZion/neo-go/pkg/crypto"
"github.com/CityOfZion/neo-go/pkg/smartcontract"
"github.com/CityOfZion/neo-go/pkg/util"
"github.com/CityOfZion/neo-go/pkg/vm"
)
// Utilities for quick bootstrapping blockchains. Normally we should
// create the genisis block. For now (to speed up development) we will add
// The hashes manually.
// Creates a genesis block based on the given configuration.
func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) {
validators, err := getValidators(cfg)
if err != nil {
return nil, err
}
func GenesisHashPrivNet() util.Uint256 {
hash, _ := util.Uint256DecodeString("996e37358dc369912041f966f8c5d8d3a8255ba5dcbd3447f8a82b55db869099")
return hash
nextConsensus, err := getNextConsensusAddress(validators)
if err != nil {
return nil, err
}
base := BlockBase{
Version: 0,
PrevHash: util.Uint256{},
Timestamp: uint32(time.Date(2016, 7, 15, 15, 8, 21, 0, time.UTC).Unix()),
Index: 0,
ConsensusData: 2083236893,
NextConsensus: nextConsensus,
Script: &transaction.Witness{
InvocationScript: []byte{},
VerificationScript: []byte{byte(vm.Opusht)},
},
}
governingTX := governingTokenTX()
utilityTX := utilityTokenTX()
rawScript, err := smartcontract.CreateMultiSigRedeemScript(
len(cfg.StandbyValidators)/2+1,
validators,
)
if err != nil {
return nil, err
}
scriptOut, err := util.Uint160FromScript(rawScript)
if err != nil {
return nil, err
}
block := &Block{
BlockBase: base,
Transactions: []*transaction.Transaction{
{
Type: transaction.MinerType,
Data: &transaction.MinerTX{
Nonce: 2083236893,
},
Attributes: []*transaction.Attribute{},
Inputs: []*transaction.Input{},
Outputs: []*transaction.Output{},
Scripts: []*transaction.Witness{},
},
governingTX,
utilityTX,
{
Type: transaction.IssueType,
Data: &transaction.IssueTX{}, // no fields.
Inputs: []*transaction.Input{},
Outputs: []*transaction.Output{
{
AssetID: governingTX.Hash(),
Amount: governingTX.Data.(*transaction.RegisterTX).Amount,
ScriptHash: scriptOut,
},
},
Scripts: []*transaction.Witness{
{
InvocationScript: []byte{},
VerificationScript: []byte{byte(vm.Opusht)},
},
},
},
},
}
block.rebuildMerkleRoot()
return block, nil
}
func GenesisHashTestNet() util.Uint256 {
hash, _ := util.Uint256DecodeString("b3181718ef6167105b70920e4a8fbbd0a0a56aacf460d70e10ba6fa1668f1fef")
return hash
func governingTokenTX() *transaction.Transaction {
admin, _ := util.Uint160FromScript([]byte{byte(vm.Opusht)})
adminB, _ := crypto.Uint160DecodeAddress("Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt")
if !admin.Equals(adminB) {
panic("kdjdkljfkdjfkdjf")
}
registerTX := &transaction.RegisterTX{
AssetType: transaction.GoverningToken,
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]",
Amount: util.NewFixed8(100000000),
Precision: 0,
Owner: &crypto.PublicKey{},
Admin: admin,
}
tx := &transaction.Transaction{
Type: transaction.RegisterType,
Data: registerTX,
Attributes: []*transaction.Attribute{},
Inputs: []*transaction.Input{},
Outputs: []*transaction.Output{},
Scripts: []*transaction.Witness{},
}
return tx
}
func GenesisHashMainNet() util.Uint256 {
hash, _ := util.Uint256DecodeString("d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf")
return hash
func utilityTokenTX() *transaction.Transaction {
admin, _ := util.Uint160FromScript([]byte{byte(vm.Opushf)})
registerTX := &transaction.RegisterTX{
AssetType: transaction.UtilityToken,
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
Amount: calculateUtilityAmount(),
Precision: 8,
Owner: &crypto.PublicKey{},
Admin: admin,
}
tx := &transaction.Transaction{
Type: transaction.RegisterType,
Data: registerTX,
Attributes: []*transaction.Attribute{},
Inputs: []*transaction.Input{},
Outputs: []*transaction.Output{},
Scripts: []*transaction.Witness{},
}
return tx
}
func getValidators(cfg config.ProtocolConfiguration) ([]*crypto.PublicKey, error) {
validators := make([]*crypto.PublicKey, len(cfg.StandbyValidators))
for i, pubKeyStr := range cfg.StandbyValidators {
pubKey, err := crypto.NewPublicKeyFromString(pubKeyStr)
if err != nil {
return nil, err
}
validators[i] = pubKey
}
return validators, nil
}
func getNextConsensusAddress(validators []*crypto.PublicKey) (val util.Uint160, err error) {
vlen := len(validators)
raw, err := smartcontract.CreateMultiSigRedeemScript(
vlen-(vlen-1)/3,
validators,
)
if err != nil {
return val, err
}
return util.Uint160FromScript(raw)
}
func calculateUtilityAmount() util.Fixed8 {
sum := 0
for i := 0; i < len(genAmount); i++ {
sum += genAmount[i]
}
return util.NewFixed8(sum * decrementInterval)
}
// headerSliceReverse reverses the given slice of *Header.