mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-23 17:51:39 +00:00
Fixed issues from review with Ethan
This commit is contained in:
@ -120,12 +120,15 @@ func (t *IAVLTree) Save() []byte {
|
||||
return t.root.save(t)
|
||||
}
|
||||
|
||||
// Sets the root node by reading from db.
|
||||
// If the hash is empty, then sets root to nil.
|
||||
func (t *IAVLTree) Load(hash []byte) {
|
||||
if len(hash) == 0 {
|
||||
panic("IAVLTree.Load() hash was nil")
|
||||
}
|
||||
t.root = nil
|
||||
} else {
|
||||
t.root = t.ndb.GetNode(t, hash)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *IAVLTree) Get(key interface{}) (index uint64, value interface{}) {
|
||||
if t.root == nil {
|
||||
|
@ -320,7 +320,7 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
|
||||
err error = nil
|
||||
caller *vm.Account = toVMAccount(inAcc)
|
||||
callee *vm.Account = nil
|
||||
appState = NewVMAppState(s)
|
||||
appState = NewVMAppState(s) // TODO: confusing.
|
||||
params = vm.Params{
|
||||
BlockHeight: uint64(s.LastBlockHeight),
|
||||
BlockHash: vm.BytesToWord(s.LastBlockHash),
|
||||
@ -340,11 +340,12 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
|
||||
}
|
||||
}
|
||||
|
||||
appState.AddAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
|
||||
appState.AddAccount(callee) // because we adjusted by input above.
|
||||
appState.UpdateAccount(caller) // because we adjusted by input above, and bumped nonce maybe.
|
||||
appState.UpdateAccount(callee) // because we adjusted by input above.
|
||||
vmach := vm.NewVM(appState, params, caller.Address)
|
||||
ret, err_ := vmach.Call(caller, callee, outAcc.Code, tx.Data, value, &gas)
|
||||
if err_ != nil {
|
||||
// NOTE: Call() transfers the value from caller to callee iff call succeeds.
|
||||
ret, err := vmach.Call(caller, callee, outAcc.Code, tx.Data, value, &gas)
|
||||
if err != nil {
|
||||
// Failure. Charge the gas fee. The 'value' was otherwise not transferred.
|
||||
inAcc.Balance -= tx.Fee
|
||||
s.UpdateAccount(inAcc)
|
||||
@ -357,7 +358,7 @@ func (s *State) ExecTx(tx_ blk.Tx, runCall bool) error {
|
||||
appState.Sync()
|
||||
}
|
||||
// Create a receipt from the ret and whether errored.
|
||||
log.Info("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err_)
|
||||
log.Info("VM call complete", "caller", caller, "callee", callee, "return", ret, "err", err)
|
||||
} else {
|
||||
// The mempool does not call txs until
|
||||
// the proposer determines the order of txs.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package state
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sort"
|
||||
|
||||
ac "github.com/tendermint/tendermint/account"
|
||||
@ -61,16 +62,6 @@ func unpack(accInfo AccountInfo) (*vm.Account, bool) {
|
||||
return accInfo.account, accInfo.deleted
|
||||
}
|
||||
|
||||
// Used to add the origin of the tx to VMAppState.
|
||||
func (vas *VMAppState) AddAccount(account *vm.Account) error {
|
||||
if _, ok := vas.accounts[account.Address.String()]; ok {
|
||||
return Errorf("Account already exists: %X", account.Address)
|
||||
} else {
|
||||
vas.accounts[account.Address.String()] = AccountInfo{account, false}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (vas *VMAppState) GetAccount(addr vm.Word) (*vm.Account, error) {
|
||||
account, deleted := unpack(vas.accounts[addr.String()])
|
||||
if deleted {
|
||||
@ -175,6 +166,7 @@ func (vas *VMAppState) SetStorage(addr vm.Word, key vm.Word, value vm.Word) (boo
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// CONTRACT the updates are in deterministic order.
|
||||
func (vas *VMAppState) Sync() {
|
||||
|
||||
// Determine order for accounts
|
||||
@ -200,18 +192,36 @@ func (vas *VMAppState) Sync() {
|
||||
}
|
||||
}
|
||||
|
||||
// Update or delete storage items.
|
||||
// Determine order for storage updates
|
||||
// The address comes first so it'll be grouped.
|
||||
storageKeyStrs := []string{}
|
||||
for keyStr := range vas.storage {
|
||||
storageKeyStrs = append(storageKeyStrs, keyStr)
|
||||
}
|
||||
sort.Strings(storageKeyStrs)
|
||||
|
||||
// Update storage for all account/key.
|
||||
storage := merkle.NewIAVLTree(
|
||||
binary.BasicCodec, // TODO change
|
||||
binary.BasicCodec, // TODO change
|
||||
1024, // TODO change.
|
||||
vas.state.DB,
|
||||
)
|
||||
|
||||
for addrKey, value := range vas.storage {
|
||||
addrKeyBytes := []byte(addrKey)
|
||||
var currentAccount *vm.Account
|
||||
var deleted bool
|
||||
for _, storageKey := range storageKeyStrs {
|
||||
value := vas.storage[storageKey]
|
||||
addrKeyBytes := []byte(storageKey)
|
||||
addr := addrKeyBytes[:32]
|
||||
key := addrKeyBytes[32:]
|
||||
if currentAccount == nil || !bytes.Equal(currentAccount.Address[:], addr) {
|
||||
currentAccount, deleted = unpack(vas.accounts[string(addr)])
|
||||
if deleted {
|
||||
continue
|
||||
}
|
||||
storageRoot := currentAccount.StorageRoot
|
||||
storage.Load(storageRoot.Bytes())
|
||||
}
|
||||
if value.IsZero() {
|
||||
_, removed := storage.Remove(key)
|
||||
if !removed {
|
||||
|
8
vm/vm.go
8
vm/vm.go
@ -530,7 +530,7 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value uint64, ga
|
||||
fmt.Printf(" => %v\n", log)
|
||||
|
||||
case CREATE: // 0xF0
|
||||
value := stack.Pop64()
|
||||
contractValue := stack.Pop64()
|
||||
offset, size := stack.Pop64(), stack.Pop64()
|
||||
input, ok := subslice(memory, offset, size)
|
||||
if !ok {
|
||||
@ -538,19 +538,19 @@ func (vm *VM) call(caller, callee *Account, code, input []byte, value uint64, ga
|
||||
}
|
||||
|
||||
// Check balance
|
||||
if caller.Balance < value {
|
||||
if callee.Balance < contractValue {
|
||||
return nil, firstErr(err, ErrInsufficientBalance)
|
||||
}
|
||||
|
||||
// TODO charge for gas to create account _ the code length * GasCreateByte
|
||||
|
||||
newAccount, err := vm.appState.CreateAccount(caller)
|
||||
newAccount, err := vm.appState.CreateAccount(callee)
|
||||
if err != nil {
|
||||
stack.Push(Zero)
|
||||
fmt.Printf(" (*) 0x0 %v\n", err)
|
||||
} else {
|
||||
// Run the input to get the contract code.
|
||||
ret, err_ := vm.Call(callee, newAccount, input, input, value, gas)
|
||||
ret, err_ := vm.Call(callee, newAccount, input, input, contractValue, gas)
|
||||
if err_ != nil {
|
||||
stack.Push(Zero)
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user