Working on interop

* Receipts after each transaction
* Fee structure
* Applying fees to miners
This commit is contained in:
obscuren 2014-05-22 17:35:26 +02:00
parent 14787ac148
commit 230aafbf66
11 changed files with 203 additions and 88 deletions

View File

@ -55,6 +55,7 @@ type Block struct {
Nonce []byte Nonce []byte
// List of transactions and/or contracts // List of transactions and/or contracts
transactions []*Transaction transactions []*Transaction
receipts []*Receipt
TxSha []byte TxSha []byte
} }
@ -84,24 +85,20 @@ func CreateBlock(root interface{},
base []byte, base []byte,
Difficulty *big.Int, Difficulty *big.Int,
Nonce []byte, Nonce []byte,
extra string, extra string) *Block {
txes []*Transaction) *Block {
block := &Block{ block := &Block{
// Slice of transactions to include in this block PrevHash: prevHash,
transactions: txes, Coinbase: base,
PrevHash: prevHash, Difficulty: Difficulty,
Coinbase: base, Nonce: Nonce,
Difficulty: Difficulty, Time: time.Now().Unix(),
Nonce: Nonce, Extra: extra,
Time: time.Now().Unix(), UncleSha: EmptyShaList,
Extra: extra, GasUsed: new(big.Int),
UncleSha: EmptyShaList, MinGasPrice: new(big.Int),
GasUsed: new(big.Int), GasLimit: new(big.Int),
MinGasPrice: new(big.Int),
GasLimit: new(big.Int),
} }
block.SetTransactions(txes)
block.SetUncles([]*Block{}) block.SetUncles([]*Block{})
block.state = NewState(ethutil.NewTrie(ethutil.Config.Db, root)) block.state = NewState(ethutil.NewTrie(ethutil.Config.Db, root))
@ -115,7 +112,10 @@ func (block *Block) Hash() []byte {
} }
func (block *Block) HashNoNonce() []byte { func (block *Block) HashNoNonce() []byte {
return ethutil.Sha3Bin(ethutil.Encode([]interface{}{block.PrevHash, block.UncleSha, block.Coinbase, block.state.trie.Root, block.TxSha, block.Difficulty, block.Time, block.Extra})) return ethutil.Sha3Bin(ethutil.Encode([]interface{}{block.PrevHash,
block.UncleSha, block.Coinbase, block.state.trie.Root,
block.TxSha, block.Difficulty, block.Number, block.MinGasPrice,
block.GasLimit, block.GasUsed, block.Time, block.Extra}))
} }
func (block *Block) State() *State { func (block *Block) State() *State {
@ -172,15 +172,15 @@ func (block *Block) Undo() {
} }
/////// Block Encoding /////// Block Encoding
func (block *Block) rlpTxs() interface{} { func (block *Block) rlpReceipts() interface{} {
// Marshal the transactions of this block // Marshal the transactions of this block
encTx := make([]interface{}, len(block.transactions)) encR := make([]interface{}, len(block.receipts))
for i, tx := range block.transactions { for i, r := range block.receipts {
// Cast it to a string (safe) // Cast it to a string (safe)
encTx[i] = tx.RlpData() encR[i] = r.RlpData()
} }
return encTx return encR
} }
func (block *Block) rlpUncles() interface{} { func (block *Block) rlpUncles() interface{} {
@ -201,7 +201,12 @@ func (block *Block) SetUncles(uncles []*Block) {
block.UncleSha = ethutil.Sha3Bin(ethutil.Encode(block.rlpUncles())) block.UncleSha = ethutil.Sha3Bin(ethutil.Encode(block.rlpUncles()))
} }
func (block *Block) SetTransactions(txs []*Transaction) { func (self *Block) SetReceipts(receipts []*Receipt, txs []*Transaction) {
self.receipts = receipts
self.setTransactions(txs)
}
func (block *Block) setTransactions(txs []*Transaction) {
block.transactions = txs block.transactions = txs
trie := ethutil.NewTrie(ethutil.Config.Db, "") trie := ethutil.NewTrie(ethutil.Config.Db, "")
@ -221,7 +226,7 @@ func (block *Block) SetTransactions(txs []*Transaction) {
} }
func (block *Block) Value() *ethutil.Value { func (block *Block) Value() *ethutil.Value {
return ethutil.NewValue([]interface{}{block.header(), block.rlpTxs(), block.rlpUncles()}) return ethutil.NewValue([]interface{}{block.header(), block.rlpReceipts(), block.rlpUncles()})
} }
func (block *Block) RlpEncode() []byte { func (block *Block) RlpEncode() []byte {
@ -245,6 +250,7 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
block.TxSha = header.Get(4).Bytes() block.TxSha = header.Get(4).Bytes()
block.Difficulty = header.Get(5).BigInt() block.Difficulty = header.Get(5).BigInt()
block.Number = header.Get(6).BigInt() block.Number = header.Get(6).BigInt()
//fmt.Printf("#%v : %x\n", block.Number, block.Coinbase)
block.MinGasPrice = header.Get(7).BigInt() block.MinGasPrice = header.Get(7).BigInt()
block.GasLimit = header.Get(8).BigInt() block.GasLimit = header.Get(8).BigInt()
block.GasUsed = header.Get(9).BigInt() block.GasUsed = header.Get(9).BigInt()
@ -255,12 +261,13 @@ func (block *Block) RlpValueDecode(decoder *ethutil.Value) {
// Tx list might be empty if this is an uncle. Uncles only have their // Tx list might be empty if this is an uncle. Uncles only have their
// header set. // header set.
if decoder.Get(1).IsNil() == false { // Yes explicitness if decoder.Get(1).IsNil() == false { // Yes explicitness
txes := decoder.Get(1) receipts := decoder.Get(1)
block.transactions = make([]*Transaction, txes.Len()) block.transactions = make([]*Transaction, receipts.Len())
for i := 0; i < txes.Len(); i++ { block.receipts = make([]*Receipt, receipts.Len())
tx := NewTransactionFromValue(txes.Get(i)) for i := 0; i < receipts.Len(); i++ {
receipt := NewRecieptFromValue(receipts.Get(i))
block.transactions[i] = tx block.transactions[i] = receipt.Tx
block.receipts[i] = receipt
} }
} }
@ -299,6 +306,10 @@ func (block *Block) GetRoot() interface{} {
return block.state.trie.Root return block.state.trie.Root
} }
func (self *Block) Receipts() []*Receipt {
return self.receipts
}
func (block *Block) header() []interface{} { func (block *Block) header() []interface{} {
return []interface{}{ return []interface{}{
// Sha of the previous block // Sha of the previous block
@ -346,6 +357,7 @@ func (block *Block) String() string {
Time: %v Time: %v
Extra: %v Extra: %v
Nonce: %x Nonce: %x
NumTx: %v
`, `,
block.Hash(), block.Hash(),
block.PrevHash, block.PrevHash,
@ -360,5 +372,7 @@ func (block *Block) String() string {
block.GasUsed, block.GasUsed,
block.Time, block.Time,
block.Extra, block.Extra,
block.Nonce) block.Nonce,
len(block.transactions),
)
} }

View File

@ -36,7 +36,7 @@ func (bc *BlockChain) Genesis() *Block {
return bc.genesisBlock return bc.genesisBlock
} }
func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block { func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
var root interface{} var root interface{}
var lastBlockTime int64 var lastBlockTime int64
hash := ZeroHash256 hash := ZeroHash256
@ -53,8 +53,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte, txs []*Transaction) *Block {
coinbase, coinbase,
ethutil.BigPow(2, 32), ethutil.BigPow(2, 32),
nil, nil,
"", "")
txs)
if bc.CurrentBlock != nil { if bc.CurrentBlock != nil {
var mul *big.Int var mul *big.Int
@ -272,16 +271,18 @@ func (bc *BlockChain) GetChain(hash []byte, amount int) []*Block {
func AddTestNetFunds(block *Block) { func AddTestNetFunds(block *Block) {
for _, addr := range []string{ for _, addr := range []string{
"8a40bfaa73256b60764c1bf40675a99083efb075", // Gavin "8a40bfaa73256b60764c1bf40675a99083efb075",
"e6716f9544a56c530d868e4bfbacb172315bdead", // Jeffrey "e4157b34ea9615cfbde6b4fda419828124b70c78",
"1e12515ce3e0f817a4ddef9ca55788a1d66bd2df", // Vit "1e12515ce3e0f817a4ddef9ca55788a1d66bd2df",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // Alex "6c386a4b26f73c802f34673f7248bb118f97424a",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // Maran "cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826", // Roman "2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
} { } {
codedAddr := ethutil.FromHex(addr) codedAddr := ethutil.FromHex(addr)
account := block.state.GetAccount(codedAddr) account := block.state.GetAccount(codedAddr)
account.Amount = ethutil.BigPow(2, 200) account.Amount = ethutil.Big("1606938044258990275541962092341162602522202993782792835301376") //ethutil.BigPow(2, 200)
block.state.UpdateStateObject(account) block.state.UpdateStateObject(account)
} }
log.Printf("%x\n", block.RlpEncode()) log.Printf("%x\n", block.RlpEncode())

View File

@ -23,7 +23,7 @@ var GenesisHeader = []interface{}{
// Root state // Root state
"", "",
// tx sha // tx sha
ZeroHash256, "",
// Difficulty // Difficulty
ethutil.BigPow(2, 22), ethutil.BigPow(2, 22),
// Number // Number

View File

@ -97,40 +97,56 @@ func (sm *StateManager) MakeContract(state *State, tx *Transaction) *StateObject
// Apply transactions uses the transaction passed to it and applies them onto // Apply transactions uses the transaction passed to it and applies them onto
// the current processing state. // the current processing state.
func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) { func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Transaction) ([]*Receipt, []*Transaction) {
// Process each transaction/contract // Process each transaction/contract
var receipts []*Receipt
var validTxs []*Transaction
totalUsedGas := big.NewInt(0)
for _, tx := range txs { for _, tx := range txs {
sm.ApplyTransaction(state, block, tx) usedGas, err := sm.ApplyTransaction(state, block, tx)
if err != nil {
ethutil.Config.Log.Infoln(err)
continue
}
accumelative := new(big.Int).Set(totalUsedGas.Add(totalUsedGas, usedGas))
receipt := &Receipt{tx, ethutil.CopyBytes(state.Root().([]byte)), accumelative}
receipts = append(receipts, receipt)
validTxs = append(validTxs, tx)
} }
return receipts, txs
} }
func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) error { func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (*big.Int, error) {
// If there's no recipient, it's a contract // If there's no recipient, it's a contract
// Check if this is a contract creation traction and if so // Check if this is a contract creation traction and if so
// create a contract of this tx. // create a contract of this tx.
totalGasUsed := big.NewInt(0)
if tx.IsContract() { if tx.IsContract() {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
if err == nil { if err == nil {
contract := sm.MakeContract(state, tx) contract := sm.MakeContract(state, tx)
if contract != nil { if contract != nil {
sm.EvalScript(state, contract.Init(), contract, tx, block) sm.EvalScript(state, contract.Init(), contract, tx, block)
} else { } else {
return fmt.Errorf("[STATE] Unable to create contract") return nil, fmt.Errorf("[STATE] Unable to create contract")
} }
} else { } else {
return fmt.Errorf("[STATE] contract create:", err) return nil, fmt.Errorf("[STATE] contract create:", err)
} }
} else { } else {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, block, false) err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
contract := state.GetStateObject(tx.Recipient) contract := state.GetStateObject(tx.Recipient)
if err == nil && contract != nil && len(contract.Script()) > 0 { if err == nil && contract != nil && len(contract.Script()) > 0 {
sm.EvalScript(state, contract.Script(), contract, tx, block) sm.EvalScript(state, contract.Script(), contract, tx, block)
} else if err != nil { } else if err != nil {
return fmt.Errorf("[STATE] process:", err) return nil, fmt.Errorf("[STATE] process:", err)
} }
} }
return nil return totalGasUsed, nil
} }
func (sm *StateManager) Process(block *Block, dontReact bool) error { func (sm *StateManager) Process(block *Block, dontReact bool) error {
@ -276,6 +292,14 @@ func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
for i := 0; i < uncleLength; i++ { for i := 0; i < uncleLength; i++ {
base.Add(base, UncleInclusionReward) base.Add(base, UncleInclusionReward)
} }
lastCumulGasUsed := big.NewInt(0)
for _, r := range block.Receipts() {
usedGas := new(big.Int).Sub(r.CumulativeGasUsed, lastCumulGasUsed)
usedGas.Add(usedGas, r.Tx.GasPrice)
base.Add(base, usedGas)
}
return base.Add(base, BlockReward) return base.Add(base, BlockReward)
} }

View File

@ -146,7 +146,7 @@ func (c *StateObject) RlpEncode() []byte {
if c.state != nil { if c.state != nil {
root = c.state.trie.Root root = c.state.trie.Root
} else { } else {
root = ZeroHash256 root = ""
} }
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)}) return ethutil.Encode([]interface{}{c.Amount, c.Nonce, root, ethutil.Sha3Bin(c.script)})

View File

@ -1,6 +1,7 @@
package ethchain package ethchain
import ( import (
"fmt"
"github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethutil"
"github.com/obscuren/secp256k1-go" "github.com/obscuren/secp256k1-go"
"math/big" "math/big"
@ -46,11 +47,13 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
} }
func (tx *Transaction) Hash() []byte { func (tx *Transaction) Hash() []byte {
data := []interface{}{tx.Nonce, tx.Value, tx.GasPrice, tx.Gas, tx.Recipient, tx.Data} data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
if tx.contractCreation { /*
data = append(data, tx.Init) if tx.contractCreation {
} data = append(data, tx.Init)
}
*/
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode()) return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
} }
@ -138,18 +141,87 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.Recipient = decoder.Get(3).Bytes() tx.Recipient = decoder.Get(3).Bytes()
tx.Value = decoder.Get(4).BigInt() tx.Value = decoder.Get(4).BigInt()
tx.Data = decoder.Get(5).Bytes() tx.Data = decoder.Get(5).Bytes()
tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes()
// If the list is of length 10 it's a contract creation tx /*
if decoder.Len() == 10 { // If the list is of length 10 it's a contract creation tx
tx.contractCreation = true if decoder.Len() == 10 {
tx.Init = decoder.Get(6).Bytes() tx.contractCreation = true
tx.Init = decoder.Get(6).Bytes()
tx.v = byte(decoder.Get(7).Uint()) tx.v = byte(decoder.Get(7).Uint())
tx.r = decoder.Get(8).Bytes() tx.r = decoder.Get(8).Bytes()
tx.s = decoder.Get(9).Bytes() tx.s = decoder.Get(9).Bytes()
} else { } else {
tx.v = byte(decoder.Get(6).Uint()) tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes() tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes() tx.s = decoder.Get(8).Bytes()
} }
*/
}
func (tx *Transaction) String() string {
return fmt.Sprintf(`
TX(%x)
Contract: %v
From: %x
Nonce: %v
GasPrice: %v
Gas: %v
To: %x
Value: %v
Data: 0x%x
V: 0x%x
R: 0x%x
S: 0x%x
`,
tx.Hash(),
len(tx.Recipient) > 1,
tx.Sender(),
tx.Nonce,
tx.GasPrice,
tx.Gas,
tx.Recipient,
tx.Value,
tx.Data,
tx.v,
tx.r,
tx.s)
}
type Receipt struct {
Tx *Transaction
PostState []byte
CumulativeGasUsed *big.Int
}
func NewRecieptFromValue(val *ethutil.Value) *Receipt {
r := &Receipt{}
r.RlpValueDecode(val)
return r
}
func (self *Receipt) RlpValueDecode(decoder *ethutil.Value) {
self.Tx = NewTransactionFromValue(decoder.Get(0))
self.PostState = decoder.Get(1).Bytes()
self.CumulativeGasUsed = decoder.Get(2).BigInt()
}
func (self *Receipt) RlpData() interface{} {
return []interface{}{self.Tx.RlpData(), self.PostState, self.CumulativeGasUsed}
}
func (self *Receipt) String() string {
return fmt.Sprintf(`
R
Tx:[ %v]
PostState: 0x%x
CumulativeGasUsed: %v
`,
self.Tx,
self.PostState,
self.CumulativeGasUsed)
} }

View File

@ -91,15 +91,15 @@ func (pool *TxPool) addTransaction(tx *Transaction) {
// Process transaction validates the Tx and processes funds from the // Process transaction validates the Tx and processes funds from the
// sender to the recipient. // sender to the recipient.
func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract bool) (err error) { func (pool *TxPool) ProcessTransaction(tx *Transaction, state *State, toContract bool) (err error) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
log.Println(r) ethutil.Config.Log.Infoln(r)
err = fmt.Errorf("%v", r) err = fmt.Errorf("%v", r)
} }
}() }()
// Get the sender // Get the sender
sender := block.state.GetAccount(tx.Sender()) sender := state.GetAccount(tx.Sender())
if sender.Nonce != tx.Nonce { if sender.Nonce != tx.Nonce {
return fmt.Errorf("[TXPL] Invalid account nonce, state nonce is %d transaction nonce is %d instead", sender.Nonce, tx.Nonce) return fmt.Errorf("[TXPL] Invalid account nonce, state nonce is %d transaction nonce is %d instead", sender.Nonce, tx.Nonce)
@ -107,19 +107,21 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// Make sure there's enough in the sender's account. Having insufficient // Make sure there's enough in the sender's account. Having insufficient
// funds won't invalidate this transaction but simple ignores it. // funds won't invalidate this transaction but simple ignores it.
totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(TxFee, TxFeeRat)) //totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(TxFee, TxFeeRat))
totAmount := new(big.Int).Add(tx.Value, new(big.Int).Mul(tx.Gas, tx.GasPrice))
if sender.Amount.Cmp(totAmount) < 0 { if sender.Amount.Cmp(totAmount) < 0 {
return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender()) return fmt.Errorf("[TXPL] Insufficient amount in sender's (%x) account", tx.Sender())
} }
//fmt.Println(tx)
// Get the receiver // Get the receiver
receiver := block.state.GetAccount(tx.Recipient) receiver := state.GetAccount(tx.Recipient)
sender.Nonce += 1 sender.Nonce += 1
// Send Tx to self // Send Tx to self
if bytes.Compare(tx.Recipient, tx.Sender()) == 0 { if bytes.Compare(tx.Recipient, tx.Sender()) == 0 {
// Subtract the fee // Subtract the fee
sender.SubAmount(new(big.Int).Mul(TxFee, TxFeeRat)) sender.SubAmount(new(big.Int).Mul(GasTx, tx.GasPrice))
} else { } else {
// Subtract the amount from the senders account // Subtract the amount from the senders account
sender.SubAmount(totAmount) sender.SubAmount(totAmount)
@ -127,10 +129,10 @@ func (pool *TxPool) ProcessTransaction(tx *Transaction, block *Block, toContract
// Add the amount to receivers account which should conclude this transaction // Add the amount to receivers account which should conclude this transaction
receiver.AddAmount(tx.Value) receiver.AddAmount(tx.Value)
block.state.UpdateStateObject(receiver) state.UpdateStateObject(receiver)
} }
block.state.UpdateStateObject(sender) state.UpdateStateObject(sender)
ethutil.Config.Log.Infof("[TXPL] Processed Tx %x\n", tx.Hash()) ethutil.Config.Log.Infof("[TXPL] Processed Tx %x\n", tx.Hash())

View File

@ -18,6 +18,7 @@ var (
GasCreate = big.NewInt(100) GasCreate = big.NewInt(100)
GasCall = big.NewInt(20) GasCall = big.NewInt(20)
GasMemory = big.NewInt(1) GasMemory = big.NewInt(1)
GasTx = big.NewInt(500)
) )
func CalculateTxGas(initSize, scriptSize *big.Int) *big.Int { func CalculateTxGas(initSize, scriptSize *big.Int) *big.Int {

View File

@ -48,7 +48,7 @@ func NewDefaultMiner(coinbase []byte, ethereum ethchain.EthManager) Miner {
// Insert initial TXs in our little miner 'pool' // Insert initial TXs in our little miner 'pool'
miner.txs = ethereum.TxPool().Flush() miner.txs = ethereum.TxPool().Flush()
miner.block = ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) miner.block = ethereum.BlockChain().NewBlock(miner.coinbase)
return miner return miner
} }
@ -86,7 +86,7 @@ out:
miner.txs = newtxs miner.txs = newtxs
// Setup a fresh state to mine on // Setup a fresh state to mine on
miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs) //miner.block = miner.ethereum.BlockChain().NewBlock(miner.coinbase, miner.txs)
} else { } else {
if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 { if bytes.Compare(block.PrevHash, miner.ethereum.BlockChain().CurrentBlock.PrevHash) == 0 {
@ -125,7 +125,7 @@ func (self *Miner) Stop() {
func (self *Miner) mineNewBlock() { func (self *Miner) mineNewBlock() {
stateManager := self.ethereum.StateManager() stateManager := self.ethereum.StateManager()
self.block = self.ethereum.BlockChain().NewBlock(self.coinbase, self.txs) self.block = self.ethereum.BlockChain().NewBlock(self.coinbase)
// Apply uncles // Apply uncles
if len(self.uncles) > 0 { if len(self.uncles) > 0 {
@ -133,15 +133,10 @@ func (self *Miner) mineNewBlock() {
} }
// Accumulate all valid transaction and apply them to the new state // Accumulate all valid transaction and apply them to the new state
var txs []*ethchain.Transaction receipts, txs := stateManager.ApplyTransactions(self.block.State(), self.block, self.txs)
for _, tx := range self.txs {
if err := stateManager.ApplyTransaction(self.block.State(), self.block, tx); err == nil {
txs = append(txs, tx)
}
}
self.txs = txs self.txs = txs
// Set the transactions to the block so the new SHA3 can be calculated // Set the transactions to the block so the new SHA3 can be calculated
self.block.SetTransactions(self.txs) self.block.SetReceipts(receipts, txs)
// Accumulate the rewards included for this block // Accumulate the rewards included for this block
stateManager.AccumelateRewards(self.block.State(), self.block) stateManager.AccumelateRewards(self.block.State(), self.block)

View File

@ -19,6 +19,7 @@ type config struct {
Ver string Ver string
ClientString string ClientString string
Pubkey []byte Pubkey []byte
Identifier string
} }
var Config *config var Config *config
@ -26,7 +27,7 @@ var Config *config
// Read config // Read config
// //
// Initialize the global Config variable with default settings // Initialize the global Config variable with default settings
func ReadConfig(base string, logTypes LoggerType) *config { func ReadConfig(base string, logTypes LoggerType, id string) *config {
if Config == nil { if Config == nil {
usr, _ := user.Current() usr, _ := user.Current()
path := path.Join(usr.HomeDir, base) path := path.Join(usr.HomeDir, base)
@ -43,6 +44,7 @@ func ReadConfig(base string, logTypes LoggerType) *config {
} }
Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC8"} Config = &config{ExecPath: path, Debug: true, Ver: "0.5.0 RC8"}
Config.Identifier = id
Config.Log = NewLogger(logTypes, LogLevelDebug) Config.Log = NewLogger(logTypes, LogLevelDebug)
Config.SetClientString("/Ethereum(G)") Config.SetClientString("/Ethereum(G)")
} }
@ -53,7 +55,11 @@ func ReadConfig(base string, logTypes LoggerType) *config {
// Set client string // Set client string
// //
func (c *config) SetClientString(str string) { func (c *config) SetClientString(str string) {
Config.ClientString = fmt.Sprintf("%s nv%s/%s", str, c.Ver, runtime.GOOS) id := runtime.GOOS
if len(c.Identifier) > 0 {
id = c.Identifier
}
Config.ClientString = fmt.Sprintf("%s nv%s/%s", str, c.Ver, id)
} }
type LoggerType byte type LoggerType byte

View File

@ -16,7 +16,7 @@ type Value struct {
} }
func (val *Value) String() string { func (val *Value) String() string {
return fmt.Sprintf("%q", val.Val) return fmt.Sprintf("%x", val.Val)
} }
func NewValue(val interface{}) *Value { func NewValue(val interface{}) *Value {