mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
modified write accounts
This commit is contained in:
parent
7e9aa2c8bd
commit
14b29696a3
2 changed files with 130 additions and 110 deletions
|
|
@ -5,14 +5,18 @@ CREATE TABLE IF NOT EXISTS blocks (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS txs (
|
CREATE TABLE IF NOT EXISTS txs (
|
||||||
txHash text,
|
txHash text primary key,
|
||||||
to_addr text,
|
to_addr text references accounts(addr),
|
||||||
from_addr text,
|
from_addr text references accounts(addr),
|
||||||
blockhash text,
|
blockhash text references blocks(hash),
|
||||||
amount numeric,
|
amount numeric,
|
||||||
gasprice numeric,
|
gasprice numeric,
|
||||||
gas numeric,
|
gas numeric,
|
||||||
nonce numeric,
|
nonce numeric,
|
||||||
data bytea,
|
data bytea
|
||||||
block text references blocks(hash)
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS accounts (
|
||||||
|
addr text primary key unique,
|
||||||
|
balance numeric
|
||||||
);
|
);
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
package shyftdb
|
package shyftdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/gob"
|
|
||||||
"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"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
|
||||||
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
|
|
@ -62,17 +58,22 @@ type ShyftTxEntryPretty struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ShyftAccountEntry struct {
|
type ShyftAccountEntry struct {
|
||||||
Balance *big.Int
|
Balance string
|
||||||
Txs []string
|
Txs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ShyftSenderEntry struct {
|
||||||
|
Address string
|
||||||
|
Balance *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
//WriteBlock writes to block info to sql db
|
//WriteBlock writes to block info to sql db
|
||||||
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) //.Scan(&fun)
|
qerr := sqldb.QueryRow(sqlStatement, block.Header().Hash().Hex(), coinbase, number).Scan(&number)
|
||||||
if qerr != nil {
|
if qerr != nil {
|
||||||
panic(qerr)
|
panic(qerr)
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +81,7 @@ func WriteBlock(sqldb *sql.DB, block *types.Block) error {
|
||||||
if block.Transactions().Len() > 0 {
|
if block.Transactions().Len() > 0 {
|
||||||
for _, tx := range block.Transactions() {
|
for _, tx := range block.Transactions() {
|
||||||
WriteTransactions(sqldb, tx, block.Header().Hash())
|
WriteTransactions(sqldb, tx, block.Header().Hash())
|
||||||
//tx_bytes[i] = tx.Hash().Bytes()
|
WriteFromBalance(sqldb, tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -118,127 +119,142 @@ func WriteTransactions(sqldb *sql.DB, tx *types.Transaction, blockHash common.Ha
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//WriteAccountBalances(db, tx)
|
//WriteSenderBalance writes senders balance to accounts db
|
||||||
|
func WriteFromBalance(sqldb *sql.DB, tx *types.Transaction) error {
|
||||||
|
sender := ShyftSenderEntry{
|
||||||
|
Address: tx.From().Hex(),
|
||||||
|
Balance: tx.Value(),
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := sender.Address
|
||||||
|
balance := sender.Balance.String()
|
||||||
|
fmt.Println("++++++++++++++++++++++", addr)
|
||||||
|
fmt.Println("++++++++++++++++++++++", balance)
|
||||||
|
sqlStatement := `INSERT INTO accounts(addr, balance) VALUES(($1), ($2)) RETURNING addr`
|
||||||
|
qerr := sqldb.QueryRow(sqlStatement, addr, balance).Scan(&addr)
|
||||||
|
if qerr != nil {
|
||||||
|
panic(qerr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// key := append([]byte("acc-")[:], tx.From().Hash().Bytes()[:]...)
|
||||||
|
// // The from (sender) addr must have balance. If it fails to retrieve there is a bigger issue.
|
||||||
|
// retrievedData, err := db.Get(key, nil)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Crit("From MUST have eth and no record found", "err", err)
|
||||||
|
// }
|
||||||
|
// var decodedData ShyftAccountEntry
|
||||||
|
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||||
|
// if err := d.Decode(&decodedData); err != nil {
|
||||||
|
// log.Crit("Failed to decode From data:", "err", err)
|
||||||
|
// }
|
||||||
|
// decodedData.Balance.Sub(decodedData.Balance, tx.Value())
|
||||||
|
// decodedData.Txs = append(decodedData.Txs, tx.Hash().String())
|
||||||
|
// // Encode updated data
|
||||||
|
// var encodedData bytes.Buffer
|
||||||
|
// encoder := gob.NewEncoder(&encodedData)
|
||||||
|
// if err := encoder.Encode(decodedData); err != nil {
|
||||||
|
// log.Crit("Faild to encode From Account data", "err", err)
|
||||||
|
// }
|
||||||
|
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||||
|
// log.Crit("Could not write the From account data", "err", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func WriteToBalance(db *leveldb.DB, tx *types.Transaction) {
|
||||||
|
// key := append([]byte("acc-")[:], tx.To().Hash().Bytes()[:]...)
|
||||||
|
// var txs []string
|
||||||
|
|
||||||
// func WriteFromBalance(db *leveldb.DB, tx *types.Transaction) {
|
|
||||||
// key := append([]byte("acc-")[:], tx.From().Hash().Bytes()[:]...)
|
|
||||||
// // The from (sender) addr must have balance. If it fails to retrieve there is a bigger issue.
|
|
||||||
// retrievedData, err := db.Get(key, nil)
|
// retrievedData, err := db.Get(key, nil)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// log.Crit("From MUST have eth and no record found", "err", err)
|
// accData := ShyftAccountEntry{
|
||||||
|
// Balance: tx.Value(),
|
||||||
|
// Txs: append(txs, tx.Hash().String()),
|
||||||
|
// }
|
||||||
|
// var encodedData bytes.Buffer
|
||||||
|
// encoder := gob.NewEncoder(&encodedData)
|
||||||
|
// if err := encoder.Encode(accData); err != nil {
|
||||||
|
// log.Crit("Faild to encode To Account data", "err", err)
|
||||||
|
// }
|
||||||
|
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||||
|
// log.Crit("Could not write the TO account's first tx", "err", err)
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
// var decodedData ShyftAccountEntry
|
// var decodedData ShyftAccountEntry
|
||||||
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||||
// if err := d.Decode(&decodedData); err != nil {
|
// if err := d.Decode(&decodedData); err != nil {
|
||||||
// log.Crit("Failed to decode From data:", "err", err)
|
// log.Crit("Failed to decode To account data:", "err", err)
|
||||||
// }
|
// }
|
||||||
// decodedData.Balance.Sub(decodedData.Balance, tx.Value())
|
// decodedData.Balance.Add(decodedData.Balance, tx.Value())
|
||||||
// decodedData.Txs = append(decodedData.Txs, tx.Hash().String())
|
// decodedData.Txs = append(decodedData.Txs, tx.Hash().String())
|
||||||
// // Encode updated data
|
// // Encode updated data
|
||||||
// var encodedData bytes.Buffer
|
// var encodedData bytes.Buffer
|
||||||
// encoder := gob.NewEncoder(&encodedData)
|
// encoder := gob.NewEncoder(&encodedData)
|
||||||
// if err := encoder.Encode(decodedData); err != nil {
|
// if err := encoder.Encode(decodedData); err != nil {
|
||||||
// log.Crit("Faild to encode From Account data", "err", err)
|
// log.Crit("Faild to encode To Account data", "err", err)
|
||||||
// }
|
// }
|
||||||
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||||
// log.Crit("Could not write the From account data", "err", err)
|
// log.Crit("Could not write the To account data", "err", err)
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
func WriteToBalance(db *leveldb.DB, tx *types.Transaction) {
|
|
||||||
key := append([]byte("acc-")[:], tx.To().Hash().Bytes()[:]...)
|
|
||||||
var txs []string
|
|
||||||
|
|
||||||
retrievedData, err := db.Get(key, nil)
|
|
||||||
if err != nil {
|
|
||||||
accData := ShyftAccountEntry{
|
|
||||||
Balance: tx.Value(),
|
|
||||||
Txs: append(txs, tx.Hash().String()),
|
|
||||||
}
|
|
||||||
var encodedData bytes.Buffer
|
|
||||||
encoder := gob.NewEncoder(&encodedData)
|
|
||||||
if err := encoder.Encode(accData); err != nil {
|
|
||||||
log.Crit("Faild to encode To Account data", "err", err)
|
|
||||||
}
|
|
||||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
|
||||||
log.Crit("Could not write the TO account's first tx", "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var decodedData ShyftAccountEntry
|
|
||||||
d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
|
||||||
if err := d.Decode(&decodedData); err != nil {
|
|
||||||
log.Crit("Failed to decode To account data:", "err", err)
|
|
||||||
}
|
|
||||||
decodedData.Balance.Add(decodedData.Balance, tx.Value())
|
|
||||||
decodedData.Txs = append(decodedData.Txs, tx.Hash().String())
|
|
||||||
// Encode updated data
|
|
||||||
var encodedData bytes.Buffer
|
|
||||||
encoder := gob.NewEncoder(&encodedData)
|
|
||||||
if err := encoder.Encode(decodedData); err != nil {
|
|
||||||
log.Crit("Faild to encode To Account data", "err", err)
|
|
||||||
}
|
|
||||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
|
||||||
log.Crit("Could not write the To account data", "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// @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
|
||||||
// Txs would be empty because they have not had any transactions on the EVM
|
// // Txs would be empty because they have not had any transactions on the EVM
|
||||||
// @TODO: Calc mining reward
|
// // @TODO: Calc mining reward
|
||||||
//balance := totalGas.Add(totalGas, MINING_REWARD)
|
// //balance := totalGas.Add(totalGas, MINING_REWARD)
|
||||||
balance := totalGas
|
// balance := totalGas
|
||||||
accData := ShyftAccountEntry{
|
// accData := ShyftAccountEntry{
|
||||||
Balance: balance,
|
// Balance: balance,
|
||||||
Txs: txs,
|
// Txs: txs,
|
||||||
}
|
// }
|
||||||
var encodedData bytes.Buffer
|
// var encodedData bytes.Buffer
|
||||||
encoder := gob.NewEncoder(&encodedData)
|
// encoder := gob.NewEncoder(&encodedData)
|
||||||
if err := encoder.Encode(accData); err != nil {
|
// if err := encoder.Encode(accData); err != nil {
|
||||||
log.Crit("Faild to encode Miner Account data", "err", err)
|
// log.Crit("Faild to encode Miner Account data", "err", err)
|
||||||
}
|
// }
|
||||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||||
log.Crit("Could not write the miner's first tx", "err", err)
|
// log.Crit("Could not write the miner's first tx", "err", err)
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
// The account has already have previous data stored due to activity in the EVM
|
// // The account has already have previous data stored due to activity in the EVM
|
||||||
// Decode the data to update balance
|
// // Decode the data to update balance
|
||||||
var decodedData ShyftAccountEntry
|
// var decodedData ShyftAccountEntry
|
||||||
d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||||
if err := d.Decode(&decodedData); err != nil {
|
// if err := d.Decode(&decodedData); err != nil {
|
||||||
log.Crit("Failed to decode miner data:", "err", err)
|
// log.Crit("Failed to decode miner data:", "err", err)
|
||||||
}
|
// }
|
||||||
// Write new balance
|
// // Write new balance
|
||||||
// @TODO: Calc mining reward
|
// // @TODO: Calc mining reward
|
||||||
// decodedData.Balance.Add(decodedData.Balance, totalGas.Add(totalGas, MINING_REWARD)))
|
// // decodedData.Balance.Add(decodedData.Balance, totalGas.Add(totalGas, MINING_REWARD)))
|
||||||
decodedData.Balance.Add(decodedData.Balance, totalGas)
|
// decodedData.Balance.Add(decodedData.Balance, totalGas)
|
||||||
// Encode the data to be written back to the db
|
// // Encode the data to be written back to the db
|
||||||
var encodedData bytes.Buffer
|
// var encodedData bytes.Buffer
|
||||||
encoder := gob.NewEncoder(&encodedData)
|
// encoder := gob.NewEncoder(&encodedData)
|
||||||
if err := encoder.Encode(decodedData); err != nil {
|
// if err := encoder.Encode(decodedData); err != nil {
|
||||||
log.Crit("Faild to encode Miner Account data", "err", err)
|
// log.Crit("Faild to encode Miner Account data", "err", err)
|
||||||
}
|
// }
|
||||||
// Write newly encoded data back to the db
|
// // Write newly encoded data back to the db
|
||||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||||
log.Crit("Could not update miner account data", "err", err)
|
// log.Crit("Could not update miner account data", "err", err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// Getters
|
// Getters
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue