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 (
|
||||
txHash text,
|
||||
to_addr text,
|
||||
from_addr text,
|
||||
blockhash text,
|
||||
txHash text primary key,
|
||||
to_addr text references accounts(addr),
|
||||
from_addr text references accounts(addr),
|
||||
blockhash text references blocks(hash),
|
||||
amount numeric,
|
||||
gasprice numeric,
|
||||
gas numeric,
|
||||
nonce numeric,
|
||||
data bytea,
|
||||
block text references blocks(hash)
|
||||
data bytea
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS accounts (
|
||||
addr text primary key unique,
|
||||
balance numeric
|
||||
);
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
package shyftdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
|
||||
"database/sql"
|
||||
|
||||
|
|
@ -62,17 +58,22 @@ type ShyftTxEntryPretty struct {
|
|||
}
|
||||
|
||||
type ShyftAccountEntry struct {
|
||||
Balance *big.Int
|
||||
Balance string
|
||||
Txs []string
|
||||
}
|
||||
|
||||
type ShyftSenderEntry struct {
|
||||
Address string
|
||||
Balance *big.Int
|
||||
}
|
||||
|
||||
//WriteBlock writes to block info to sql db
|
||||
func WriteBlock(sqldb *sql.DB, block *types.Block) error {
|
||||
coinbase := block.Header().Coinbase.String()
|
||||
number := block.Header().Number.String()
|
||||
|
||||
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 {
|
||||
panic(qerr)
|
||||
}
|
||||
|
|
@ -80,7 +81,7 @@ func WriteBlock(sqldb *sql.DB, block *types.Block) error {
|
|||
if block.Transactions().Len() > 0 {
|
||||
for _, tx := range block.Transactions() {
|
||||
WriteTransactions(sqldb, tx, block.Header().Hash())
|
||||
//tx_bytes[i] = tx.Hash().Bytes()
|
||||
WriteFromBalance(sqldb, tx)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
@ -118,127 +119,142 @@ func WriteTransactions(sqldb *sql.DB, tx *types.Transaction, blockHash common.Ha
|
|||
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)
|
||||
// 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
|
||||
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||
// 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())
|
||||
// // 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)
|
||||
// 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 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:
|
||||
// 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.
|
||||
// @TODO: Calculate reward if there are uncles
|
||||
// @TODO: Calculate mining reward (most likely retrieve higher up in the operations)
|
||||
// @TODO: Calculate reorg
|
||||
func WriteMinerReward(db *leveldb.DB, block *types.Block) {
|
||||
var totalGas *big.Int
|
||||
var txs []string
|
||||
key := append([]byte("acc-")[:], block.Coinbase().Hash().Bytes()[:]...)
|
||||
for _, tx := range block.Transactions() {
|
||||
totalGas.Add(totalGas, new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())))
|
||||
}
|
||||
retrievedData, err := db.Get(key, nil)
|
||||
if err != nil {
|
||||
// Assume time this account has had a tx
|
||||
// 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
|
||||
// @TODO: Calc mining reward
|
||||
//balance := totalGas.Add(totalGas, MINING_REWARD)
|
||||
balance := totalGas
|
||||
accData := ShyftAccountEntry{
|
||||
Balance: balance,
|
||||
Txs: txs,
|
||||
}
|
||||
var encodedData bytes.Buffer
|
||||
encoder := gob.NewEncoder(&encodedData)
|
||||
if err := encoder.Encode(accData); err != nil {
|
||||
log.Crit("Faild to encode Miner Account data", "err", err)
|
||||
}
|
||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||
log.Crit("Could not write the miner's first tx", "err", err)
|
||||
}
|
||||
} else {
|
||||
// The account has already have previous data stored due to activity in the EVM
|
||||
// Decode the data to update balance
|
||||
var decodedData ShyftAccountEntry
|
||||
d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||
if err := d.Decode(&decodedData); err != nil {
|
||||
log.Crit("Failed to decode miner data:", "err", err)
|
||||
}
|
||||
// Write new balance
|
||||
// @TODO: Calc mining reward
|
||||
// decodedData.Balance.Add(decodedData.Balance, totalGas.Add(totalGas, MINING_REWARD)))
|
||||
decodedData.Balance.Add(decodedData.Balance, totalGas)
|
||||
// Encode the data to be written back to the db
|
||||
var encodedData bytes.Buffer
|
||||
encoder := gob.NewEncoder(&encodedData)
|
||||
if err := encoder.Encode(decodedData); err != nil {
|
||||
log.Crit("Faild to encode Miner Account data", "err", err)
|
||||
}
|
||||
// Write newly encoded data back to the db
|
||||
if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||
log.Crit("Could not update miner account data", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// func WriteMinerReward(db *leveldb.DB, block *types.Block) {
|
||||
// var totalGas *big.Int
|
||||
// var txs []string
|
||||
// key := append([]byte("acc-")[:], block.Coinbase().Hash().Bytes()[:]...)
|
||||
// for _, tx := range block.Transactions() {
|
||||
// totalGas.Add(totalGas, new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())))
|
||||
// }
|
||||
// retrievedData, err := db.Get(key, nil)
|
||||
// if err != nil {
|
||||
// // Assume time this account has had a tx
|
||||
// // 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
|
||||
// // @TODO: Calc mining reward
|
||||
// //balance := totalGas.Add(totalGas, MINING_REWARD)
|
||||
// balance := totalGas
|
||||
// accData := ShyftAccountEntry{
|
||||
// Balance: balance,
|
||||
// Txs: txs,
|
||||
// }
|
||||
// var encodedData bytes.Buffer
|
||||
// encoder := gob.NewEncoder(&encodedData)
|
||||
// if err := encoder.Encode(accData); err != nil {
|
||||
// log.Crit("Faild to encode Miner Account data", "err", err)
|
||||
// }
|
||||
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||
// log.Crit("Could not write the miner's first tx", "err", err)
|
||||
// }
|
||||
// } else {
|
||||
// // The account has already have previous data stored due to activity in the EVM
|
||||
// // Decode the data to update balance
|
||||
// var decodedData ShyftAccountEntry
|
||||
// d := gob.NewDecoder(bytes.NewBuffer(retrievedData))
|
||||
// if err := d.Decode(&decodedData); err != nil {
|
||||
// log.Crit("Failed to decode miner data:", "err", err)
|
||||
// }
|
||||
// // Write new balance
|
||||
// // @TODO: Calc mining reward
|
||||
// // decodedData.Balance.Add(decodedData.Balance, totalGas.Add(totalGas, MINING_REWARD)))
|
||||
// decodedData.Balance.Add(decodedData.Balance, totalGas)
|
||||
// // Encode the data to be written back to the db
|
||||
// var encodedData bytes.Buffer
|
||||
// encoder := gob.NewEncoder(&encodedData)
|
||||
// if err := encoder.Encode(decodedData); err != nil {
|
||||
// log.Crit("Faild to encode Miner Account data", "err", err)
|
||||
// }
|
||||
// // Write newly encoded data back to the db
|
||||
// if err := db.Put(key, encodedData.Bytes(), nil); err != nil {
|
||||
// log.Crit("Could not update miner account data", "err", err)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
///////////
|
||||
// Getters
|
||||
|
|
|
|||
Loading…
Reference in a new issue