good morning!!!!

Skip to content
Snippets Groups Projects
Commit 2f614900 authored by Jeffrey Wilcke's avatar Jeffrey Wilcke
Browse files

Updated GHOST

parent 4db4ec16
Branches
Tags
No related merge requests found
......@@ -31,11 +31,22 @@ func (bi *BlockInfo) RlpEncode() []byte {
return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent})
}
type Blocks []*Block
func (self Blocks) AsSet() ethutil.UniqueSet {
set := make(ethutil.UniqueSet)
for _, block := range self {
set.Insert(block.Hash())
}
return set
}
type Block struct {
// Hash to the previous block
PrevHash []byte
// Uncles of this block
Uncles []*Block
Uncles Blocks
UncleSha []byte
// The coin base address
Coinbase []byte
......
......@@ -60,7 +60,7 @@ func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
if bc.CurrentBlock != nil {
var mul *big.Int
if block.Time < lastBlockTime+42 {
if block.Time < lastBlockTime+5 {
mul = big.NewInt(1)
} else {
mul = big.NewInt(-1)
......
......@@ -25,6 +25,24 @@ func IsParentErr(err error) bool {
return ok
}
type UncleErr struct {
Message string
}
func (err *UncleErr) Error() string {
return err.Message
}
func UncleError(str string) error {
return &UncleErr{Message: str}
}
func IsUncleErr(err error) bool {
_, ok := err.(*UncleErr)
return ok
}
// Block validation error. If any validation fails, this error will be thrown
type ValidationErr struct {
Message string
......
......@@ -219,7 +219,7 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// I'm not sure, but I don't know if there should be thrown
// any errors at this time.
if err = sm.AccumelateRewards(state, block); err != nil {
if err = sm.AccumelateRewards(state, block, parent); err != nil {
statelogger.Errorln("Error accumulating reward", err)
return err
}
......@@ -334,36 +334,44 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
return nil
}
func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
base := new(big.Int)
for i := 0; i < uncleLength; i++ {
base.Add(base, UncleInclusionReward)
func (sm *StateManager) AccumelateRewards(state *ethstate.State, block, parent *Block) error {
reward := new(big.Int)
knownUncles := ethutil.Set(parent.Uncles)
nonces := ethutil.NewSet(block.Nonce)
for _, uncle := range block.Uncles {
if nonces.Include(uncle.Nonce) {
// Error not unique
return UncleError("Uncle not unique")
}
return base.Add(base, BlockReward)
uncleParent := sm.bc.GetBlock(uncle.PrevHash)
if uncleParent == nil {
return UncleError("Uncle's parent unknown")
}
func CalculateUncleReward(block *Block) *big.Int {
return UncleReward
if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
return UncleError("Uncle too old")
}
func (sm *StateManager) AccumelateRewards(state *ethstate.State, block *Block) error {
// Get the account associated with the coinbase
account := state.GetAccount(block.Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(CalculateBlockReward(block, len(block.Uncles)))
if knownUncles.Include(uncle.Hash()) {
return UncleError("Uncle in chain")
}
addr := make([]byte, len(block.Coinbase))
copy(addr, block.Coinbase)
state.UpdateStateObject(account)
r := new(big.Int)
r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
for _, uncle := range block.Uncles {
uncleAccount := state.GetAccount(uncle.Coinbase)
uncleAccount.AddAmount(CalculateUncleReward(uncle))
uncleAccount.AddAmount(r)
state.UpdateStateObject(uncleAccount)
reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
}
// Get the account associated with the coinbase
account := state.GetAccount(block.Coinbase)
// Reward amount of ether to the coinbase address
account.AddAmount(reward)
return nil
}
......@@ -375,14 +383,6 @@ func (sm *StateManager) Stop() {
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
bloomf := NewBloomFilter(nil)
/*
for addr, stateObject := range state.Manifest().ObjectChanges {
// Set the bloom filter's bin
bloomf.Set([]byte(addr))
sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
}
*/
for _, msg := range state.Manifest().Messages {
bloomf.Set(msg.To)
bloomf.Set(msg.From)
......@@ -390,17 +390,6 @@ func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
sm.Ethereum.Reactor().Post("messages", state.Manifest().Messages)
/*
for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
for addr, value := range mappedObjects {
// Set the bloom filter's bin
bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))
sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
}
}
*/
return bloomf
}
......@@ -420,7 +409,7 @@ func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message,
sm.ApplyDiff(state, parent, block)
sm.AccumelateRewards(state, block)
sm.AccumelateRewards(state, block, parent)
return state.Manifest().Messages, nil
}
......@@ -187,7 +187,7 @@ func (self *Miner) mineNewBlock() {
self.block.SetReceipts(receipts, txs)
// Accumulate the rewards included for this block
stateManager.AccumelateRewards(self.block.State(), self.block)
stateManager.AccumelateRewards(self.block.State(), self.block, parent)
self.block.State().Update()
......
......@@ -3,7 +3,6 @@ package ethvm
import (
"container/list"
"fmt"
"math"
"math/big"
"github.com/ethereum/eth-go/ethcrypto"
......@@ -67,6 +66,19 @@ func New(env Environment) *Vm {
return &Vm{env: env, logTy: lt, Recoverable: true, queue: list.New()}
}
func calcMemSize(off, l *big.Int) *big.Int {
if l.Cmp(ethutil.Big0) == 0 {
return ethutil.Big0
}
return new(big.Int).Add(off, l)
}
// Simple helper
func u256(n int64) *big.Int {
return big.NewInt(n)
}
func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
if self.Recoverable {
// Recover from any require exception
......@@ -147,7 +159,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
addStepGasUsage(GasStep)
var newMemSize uint64 = 0
var newMemSize *big.Int = ethutil.Big0
switch op {
case STOP:
gas.Set(ethutil.Big0)
......@@ -171,57 +183,62 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
gas.Set(GasBalance)
case MSTORE:
require(2)
newMemSize = stack.Peek().Uint64() + 32
newMemSize = calcMemSize(stack.Peek(), u256(32))
case MLOAD:
require(1)
newMemSize = stack.Peek().Uint64() + 32
newMemSize = calcMemSize(stack.Peek(), u256(32))
case MSTORE8:
require(2)
newMemSize = stack.Peek().Uint64() + 1
newMemSize = calcMemSize(stack.Peek(), u256(1))
case RETURN:
require(2)
newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
case SHA3:
require(2)
gas.Set(GasSha)
newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-2].Uint64()
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
case CALLDATACOPY:
require(3)
newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
case CODECOPY:
require(3)
newMemSize = stack.Peek().Uint64() + stack.data[stack.Len()-3].Uint64()
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-3])
case EXTCODECOPY:
require(4)
newMemSize = stack.data[stack.Len()-1].Uint64() + stack.data[stack.Len()-4].Uint64()
newMemSize = calcMemSize(stack.data[stack.Len()-1], stack.data[stack.Len()-4])
case CALL, CALLSTATELESS:
require(7)
gas.Set(GasCall)
addStepGasUsage(stack.data[stack.Len()-1])
x := stack.data[stack.Len()-6].Uint64() + stack.data[stack.Len()-7].Uint64()
y := stack.data[stack.Len()-4].Uint64() + stack.data[stack.Len()-5].Uint64()
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
y := calcMemSize(stack.data[stack.Len()-4], stack.data[stack.Len()-5])
newMemSize = uint64(math.Max(float64(x), float64(y)))
newMemSize = ethutil.BigMax(x, y)
case CREATE:
require(3)
gas.Set(GasCreate)
newMemSize = stack.data[stack.Len()-2].Uint64() + stack.data[stack.Len()-3].Uint64()
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
}
// BUG This will break on overflows. https://github.com/ethereum/eth-go/issues/47
newMemSize = (newMemSize + 31) / 32 * 32
if newMemSize > uint64(mem.Len()) {
m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
addStepGasUsage(big.NewInt(int64(m)))
if newMemSize.Cmp(ethutil.Big0) > 0 {
//newMemSize = (newMemSize + 31) / 32 * 32
newMemSize = newMemSize.Add(newMemSize, u256(31)).Div(newMemSize, u256(32)).Mul(newMemSize, u256(32))
//if newMemSize > uint64(mem.Len()) {
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
newMemSize = newMemSize.Sub(newMemSize, u256(int64(mem.Len())))
memGasUsage := newMemSize.Mul(GasMemory, newMemSize).Div(newMemSize, u256(32))
//m := GasMemory.Uint64() * (newMemSize - uint64(mem.Len())) / 32
addStepGasUsage(memGasUsage)
}
}
if !closure.UseGas(gas) {
......@@ -235,7 +252,7 @@ func (self *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
self.Printf(" (g) %-3v (%v)", gas, closure.Gas)
mem.Resize(newMemSize)
mem.Resize(newMemSize.Uint64())
switch op {
case LOG:
......
......@@ -675,7 +675,7 @@ func (self *Peer) handleStatus(msg *ethwire.Msg) {
func (p *Peer) pushHandshake() error {
pubkey := p.ethereum.KeyManager().PublicKey()
msg := ethwire.NewMessage(ethwire.MsgHandshakeTy, []interface{}{
P2PVersion, []byte(p.version), []interface{}{"eth"}, uint32(30303) /*p.port*/, pubkey[1:],
P2PVersion, []byte(p.version), []interface{}{"eth"}, p.port, pubkey[1:],
})
p.QueueMessage(msg)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment