Merge pull request #21 from ShyftNetwork/writeGenesis

Write genesis
This commit is contained in:
greg 2018-05-10 12:39:32 -04:00 committed by GitHub
commit e1bdc1640c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 147 additions and 95 deletions

View file

@ -8,7 +8,7 @@ import (
_ "github.com/lib/pq" _ "github.com/lib/pq"
shyftdb "github.com/ethereum/go-ethereum/shyftdb" "github.com/ethereum/go-ethereum/shyftdb"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
@ -48,6 +48,7 @@ func GetAllTransactions(w http.ResponseWriter, r *http.Request) {
return return
} }
w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)

View file

@ -37,7 +37,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
cli "gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
) )
var runCommand = cli.Command{ var runCommand = cli.Command{

View file

@ -168,7 +168,7 @@ func initGenesis(ctx *cli.Context) error {
if err != nil { if err != nil {
utils.Fatalf("Failed to open database: %v", err) utils.Fatalf("Failed to open database: %v", err)
} }
_, hash, err := core.SetupGenesisBlock(chaindb, genesis) _, hash, err := core.SetupGenesisBlock(chaindb, genesis, nil)
if err != nil { if err != nil {
utils.Fatalf("Failed to write genesis block: %v", err) utils.Fatalf("Failed to write genesis block: %v", err)
} }

View file

@ -1219,7 +1219,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
var err error var err error
chainDb = MakeChainDatabase(ctx, stack) chainDb = MakeChainDatabase(ctx, stack)
config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx)) config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx), nil)
if err != nil { if err != nil {
Fatalf("%v", err) Fatalf("%v", err)
} }

View file

@ -25,6 +25,7 @@ import (
"math/big" "math/big"
"strings" "strings"
_ "github.com/lib/pq"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
@ -34,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"database/sql"
) )
//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
@ -136,6 +138,36 @@ func (e *GenesisMismatchError) Error() string {
return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8]) return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8])
} }
//WriteShyftGen writes the genesis block to Shyft db
//@NOTE:SHYFT
func WriteShyftGen(sqldb *sql.DB, gen *Genesis) {
if sqldb == nil {
log.Info("Initializing Shyft Postgres DB")
connStr := "user=postgres dbname=shyftdb sslmode=disable"
blockExplorerDb, _ := sql.Open("postgres", connStr)
sqldb = blockExplorerDb
}
for k := range gen.Alloc {
addr := k.String()
var response string
sqlExistsStatement := `SELECT balance from accounts WHERE addr = ($1)`
err := sqldb.QueryRow(sqlExistsStatement, addr).Scan(&response)
switch {
case err == sql.ErrNoRows:
for k, v := range gen.Alloc {
addr := k.String()
sqlStatement := `INSERT INTO accounts(addr, balance) VALUES(($1), ($2)) RETURNING addr`
insertErr := sqldb.QueryRow(sqlStatement, addr, v.Balance.String()).Scan(&addr)
if insertErr != nil {
panic(insertErr)
}
}
default:
log.Info("Found Genesis Block")
}}}
// SetupGenesisBlock writes or updates the genesis block in db. // SetupGenesisBlock writes or updates the genesis block in db.
// The block that will be used is: // The block that will be used is:
// //
@ -149,7 +181,7 @@ func (e *GenesisMismatchError) Error() string {
// error is a *params.ConfigCompatError and the new, unwritten config is returned. // error is a *params.ConfigCompatError and the new, unwritten config is returned.
// //
// The returned chain configuration is never nil. // The returned chain configuration is never nil.
func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { func SetupGenesisBlock(db ethdb.Database, genesis *Genesis, sqldb *sql.DB) (*params.ChainConfig, common.Hash, error) {
if genesis != nil && genesis.Config == nil { if genesis != nil && genesis.Config == nil {
return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
} }
@ -162,6 +194,8 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
genesis = DefaultGenesisBlock() genesis = DefaultGenesisBlock()
} else { } else {
log.Info("Writing custom genesis block") log.Info("Writing custom genesis block")
//@NOTE:SHYFT WRITE TO DB
WriteShyftGen(sqldb, genesis)
} }
block, err := genesis.Commit(db) block, err := genesis.Commit(db)
return genesis.Config, block.Hash(), err return genesis.Config, block.Hash(), err
@ -218,7 +252,6 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
return params.AllEthashProtocolChanges return params.AllEthashProtocolChanges
} }
} }
// ToBlock creates the genesis block and writes state of a genesis specification // ToBlock creates the genesis block and writes state of a genesis specification
// to the given database (or discards it if nil). // to the given database (or discards it if nil).
func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
@ -343,7 +376,6 @@ func DefaultRinkebyGenesisBlock() *Genesis {
Alloc: decodePrealloc(rinkebyAllocData), Alloc: decodePrealloc(rinkebyAllocData),
} }
} }
// DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must // DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must
// be seeded with the // be seeded with the
func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {

View file

@ -62,7 +62,7 @@ func TestSetupGenesis(t *testing.T) {
{ {
name: "genesis without ChainConfig", name: "genesis without ChainConfig",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
return SetupGenesisBlock(db, new(Genesis)) return SetupGenesisBlock(db, new(Genesis), nil)
}, },
wantErr: errGenesisNoConfig, wantErr: errGenesisNoConfig,
wantConfig: params.AllEthashProtocolChanges, wantConfig: params.AllEthashProtocolChanges,
@ -70,7 +70,7 @@ func TestSetupGenesis(t *testing.T) {
{ {
name: "no block in DB, genesis == nil", name: "no block in DB, genesis == nil",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
return SetupGenesisBlock(db, nil) return SetupGenesisBlock(db, nil, nil)
}, },
wantHash: params.MainnetGenesisHash, wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig, wantConfig: params.MainnetChainConfig,
@ -79,7 +79,7 @@ func TestSetupGenesis(t *testing.T) {
name: "mainnet block in DB, genesis == nil", name: "mainnet block in DB, genesis == nil",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
DefaultGenesisBlock().MustCommit(db) DefaultGenesisBlock().MustCommit(db)
return SetupGenesisBlock(db, nil) return SetupGenesisBlock(db, nil, nil)
}, },
wantHash: params.MainnetGenesisHash, wantHash: params.MainnetGenesisHash,
wantConfig: params.MainnetChainConfig, wantConfig: params.MainnetChainConfig,
@ -88,7 +88,7 @@ func TestSetupGenesis(t *testing.T) {
name: "custom block in DB, genesis == nil", name: "custom block in DB, genesis == nil",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
customg.MustCommit(db) customg.MustCommit(db)
return SetupGenesisBlock(db, nil) return SetupGenesisBlock(db, nil, nil)
}, },
wantHash: customghash, wantHash: customghash,
wantConfig: customg.Config, wantConfig: customg.Config,
@ -97,7 +97,7 @@ func TestSetupGenesis(t *testing.T) {
name: "custom block in DB, genesis == testnet", name: "custom block in DB, genesis == testnet",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
customg.MustCommit(db) customg.MustCommit(db)
return SetupGenesisBlock(db, DefaultTestnetGenesisBlock()) return SetupGenesisBlock(db, DefaultTestnetGenesisBlock(), nil)
}, },
wantErr: &GenesisMismatchError{Stored: customghash, New: params.TestnetGenesisHash}, wantErr: &GenesisMismatchError{Stored: customghash, New: params.TestnetGenesisHash},
wantHash: params.TestnetGenesisHash, wantHash: params.TestnetGenesisHash,
@ -107,7 +107,7 @@ func TestSetupGenesis(t *testing.T) {
name: "compatible config in DB", name: "compatible config in DB",
fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
oldcustomg.MustCommit(db) oldcustomg.MustCommit(db)
return SetupGenesisBlock(db, &customg) return SetupGenesisBlock(db, &customg, nil)
}, },
wantHash: customghash, wantHash: customghash,
wantConfig: customg.Config, wantConfig: customg.Config,
@ -126,7 +126,7 @@ func TestSetupGenesis(t *testing.T) {
bc.InsertChain(blocks) bc.InsertChain(blocks)
bc.CurrentBlock() bc.CurrentBlock()
// This should return a compatibility error. // This should return a compatibility error.
return SetupGenesisBlock(db, &customg) return SetupGenesisBlock(db, &customg, nil)
}, },
wantHash: customghash, wantHash: customghash,
wantConfig: customg.Config, wantConfig: customg.Config,

View file

@ -125,7 +125,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return nil, err return nil, err
} }
stopDbUpgrade := upgradeDeduplicateData(chainDb) stopDbUpgrade := upgradeDeduplicateData(chainDb)
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis, blockExplorerDb)
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
return nil, genesisErr return nil, genesisErr
} }

View file

@ -84,7 +84,7 @@ func New(ctx *node.ServiceContext, config *eth.Config) (*LightEthereum, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis) chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis, nil)
if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat { if _, isCompat := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !isCompat {
return nil, genesisErr return nil, genesisErr
} }

View file

@ -4,10 +4,10 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"database/sql" "database/sql"
"log" "log"
@ -87,15 +87,15 @@ type SendAndReceive struct {
func WriteBlock(sqldb *sql.DB, block *types.Block) error { func WriteBlock(sqldb *sql.DB, block *types.Block) error {
coinbase := block.Header().Coinbase.String() coinbase := block.Header().Coinbase.String()
number := block.Header().Number.String() number := block.Header().Number.String()
sqlStatement := `INSERT INTO blocks(hash, coinbase, number) VALUES(($1), ($2), ($3)) RETURNING number` sqlStatement := `INSERT INTO blocks(hash, coinbase, number) VALUES(($1), ($2), ($3)) RETURNING number`
qerr := sqldb.QueryRow(sqlStatement, block.Header().Hash().Hex(), coinbase, number).Scan(&number) qerr := sqldb.QueryRow(sqlStatement, block.Header().Hash().Hex(), coinbase, number).Scan(&number)
if qerr != nil { if qerr != nil {
panic(qerr) panic(qerr)
} }
if block.Transactions().Len() > 0 { if block.Transactions().Len() > 0 && block.Transactions()[0].To() != nil {
for _, tx := range block.Transactions() { for _, tx := range block.Transactions() {
//WriteMinerRewards(sqldb, block)
WriteTransactions(sqldb, tx, block.Header().Hash()) WriteTransactions(sqldb, tx, block.Header().Hash())
WriteFromBalance(sqldb, tx) WriteFromBalance(sqldb, tx)
} }
@ -161,7 +161,6 @@ func WriteFromBalance(sqldb *sql.DB, tx *types.Transaction) error {
err := sqldb.QueryRow(sqlExistsStatement, toAddr).Scan(&response) err := sqldb.QueryRow(sqlExistsStatement, toAddr).Scan(&response)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
fmt.Println("No rows error :)")
sqlStatement := `INSERT INTO accounts(addr, balance) VALUES(($1), ($2)) RETURNING addr` sqlStatement := `INSERT INTO accounts(addr, balance) VALUES(($1), ($2)) RETURNING addr`
insertErr := sqldb.QueryRow(sqlStatement, toAddr, amount).Scan(&toAddr) insertErr := sqldb.QueryRow(sqlStatement, toAddr, amount).Scan(&toAddr)
@ -233,20 +232,34 @@ func WriteBalanceHelper(sqldb *sql.DB, tx *types.Transaction) (SendAndReceive, s
return sendAndReceiveData, balanceReceiver, balanceSender return sendAndReceiveData, balanceReceiver, balanceSender
} }
//func WriteMinerRewards(sqldb *sql.DB, block *types.Block) {
// var totalGas big.Int
// //var txs []string
//
// fmt.Println("this is BLOCK.UNCLE", block.Uncles())
// fmt.Println("this is BLOCK UNCLE HASH", block.UncleHash().String())
// fmt.Println("this is BLOCK.TRANSACTIONS", block.Transactions())
// fmt.Println("this is BLOCK TOTAL GAS", block.GasUsed())
//
// for _, tx := range block.Transactions() {
// totalGas.Add(&totalGas, new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())))
// }
//}
// @NOTE: This function is extremely complex and requires heavy testing and knowdlege of edge cases: // @NOTE: This function is extremely complex and requires heavy testing and knowdlege of edge cases:
// uncle blocks, account balance updates based on reorgs, diverges that get dropped. // uncle blocks, account balance updates based on reorgs, diverges that get dropped.
// Reason for this is because the accounts are not deterministic like the block and tx hashes. // Reason for this is because the accounts are not deterministic like the block and tx hashes.
// @TODO: Calculate reward if there are uncles // @TODO: Calculate reward if there are uncles
// @TODO: Calculate mining reward (most likely retrieve higher up in the operations) // @TODO: Calculate mining reward (most likely retrieve higher up in the operations)
// @TODO: Calculate reorg // @TODO: Calculate reorg
// func WriteMinerReward(db *leveldb.DB, block *types.Block) { //func WriteMinerReward(db *leveldb.DB, block *types.Block) {
// var totalGas *big.Int // var totalGas *big.Int
// var txs []string // var txs []string
// key := append([]byte("acc-")[:], block.Coinbase().Hash().Bytes()[:]...) // key := append([]byte("acc-")[:], block.Coinbase().Hash().Bytes()[:]...)
// for _, tx := range block.Transactions() { // for _, tx := range block.Transactions() {
// totalGas.Add(totalGas, new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas()))) // totalGas.Add(totalGas, new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())))
// } // }
// retrievedData, err := db.Get(key, nil) //// retrievedData, err := db.Get(key, nil)
// if err != nil { // if err != nil {
// // Assume time this account has had a tx // // Assume time this account has had a tx
// // Balacne is exclusively minerreward + total gas from the block b/c no prior evm activity // // Balacne is exclusively minerreward + total gas from the block b/c no prior evm activity
@ -289,7 +302,9 @@ func WriteBalanceHelper(sqldb *sql.DB, tx *types.Transaction) (SendAndReceive, s
// log.Crit("Could not update miner account data", "err", err) // log.Crit("Could not update miner account data", "err", err)
// } // }
// } // }
// } //}
/////////// ///////////
// Getters // Getters
@ -477,7 +492,7 @@ func GetAllAccounts(sqldb *sql.DB) string {
} }
defer accs.Close() defer accs.Close()
////
for accs.Next() { for accs.Next() {
var addr string var addr string
var balance string var balance string

View file

@ -2,28 +2,28 @@ var firstAccount = web3.eth.accounts[0]
var secondAccount = web3.eth.accounts[1] var secondAccount = web3.eth.accounts[1]
var thirdAccount = web3.eth.accounts[2] var thirdAccount = web3.eth.accounts[2]
for (var i = 0; i < 10; i++) { for (var i = 0; i < 1; i++) {
console.log('\t\t' + (i + 1) + ' - Transactions') console.log('\t\t' + (i + 1) + ' - Transactions')
web3.eth.sendTransaction({ web3.eth.sendTransaction({
from: web3.eth.accounts[2], from: web3.eth.accounts[1],
to: web3.eth.accounts[0], to: web3.eth.accounts[2],
value: 5, value: 5,
gas: 50000, gas: 50000,
gasPrice: 20 gasPrice: 20
}); });
web3.eth.sendTransaction({ // web3.eth.sendTransaction({
from: web3.eth.accounts[1], // from: web3.eth.accounts[1],
to: web3.eth.accounts[2], // to: web3.eth.accounts[2],
value: 291, // value: 291,
gas: 50000, // gas: 50000,
gasPrice: 20 // gasPrice: 20
}); // });
//
web3.eth.sendTransaction({ // web3.eth.sendTransaction({
from: web3.eth.accounts[0], // from: web3.eth.accounts[0],
to: web3.eth.accounts[1], // to: web3.eth.accounts[1],
value: 53039, // value: 53039,
gas: 50000, // gas: 50000,
gasPrice: 20 // gasPrice: 20
}); // });
} }

View file

@ -1,2 +1,2 @@
#!/bin/sh #!/bin/sh
./build/bin/geth --config config.toml --nat=none --mine --minerthreads 4 --targetgaslimit 80000000 --unlock "0x43EC6d0942f7fAeF069F7F63D0384a27f529B062,0x9e602164C5826ebb5A6B68E4AFD9Cd466043dc4A,0x5Bd738164C61FB50eb12E227846CbaeF2dE965Aa,0xC04eE4131895F1d0C294D508AF65D94060AA42BB,0x07D899C4aC0c1725C35C5f816e60273B33a964F7" --password ./unlockPasswords.txt ./build/bin/geth --config config.toml --ws --wsaddr="0.0.0.0" --wsorigins "*" --nat=none --mine --minerthreads 4 --targetgaslimit 80000000 --unlock "0x43EC6d0942f7fAeF069F7F63D0384a27f529B062,0x9e602164C5826ebb5A6B68E4AFD9Cd466043dc4A,0x5Bd738164C61FB50eb12E227846CbaeF2dE965Aa,0xC04eE4131895F1d0C294D508AF65D94060AA42BB,0x07D899C4aC0c1725C35C5f816e60273B33a964F7" --password ./unlockPasswords.txt

4
vendor/vendor.json vendored
View file

@ -417,6 +417,10 @@
"revision": "ed27b6fd65218132ee50cd95f38474a3d8a2cd12", "revision": "ed27b6fd65218132ee50cd95f38474a3d8a2cd12",
"revisionTime": "2016-06-18T19:32:21Z" "revisionTime": "2016-06-18T19:32:21Z"
}, },
{
"path": "github.com/shyft/shyft_go-ethereum/core",
"revision": ""
},
{ {
"checksumSHA1": "mGbTYZ8dHVTiPTTJu3ktp+84pPI=", "checksumSHA1": "mGbTYZ8dHVTiPTTJu3ktp+84pPI=",
"path": "github.com/stretchr/testify/assert", "path": "github.com/stretchr/testify/assert",