Skip to content

Commit

Permalink
Merge pull request #1724 from jatelReview/feature-mainnet-launch
Browse files Browse the repository at this point in the history
fix wasm external function platon_block_hash get too low block hash.
  • Loading branch information
benbaley authored Mar 12, 2021
2 parents 06196d0 + 4fa60b2 commit b8e68fe
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
14 changes: 13 additions & 1 deletion core/vm/wagon_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,19 @@ func GasPrice(proc *exec.Process, gasPrice uint32) uint32 {
func BlockHash(proc *exec.Process, num uint64, dst uint32) {
ctx := proc.HostCtx().(*VMContext)
checkGas(ctx, GasExtStep)
blockHash := ctx.evm.GetHash(num)

// Add get block height limit, same as evm opBlockhash
var upper, lower uint64
upper = ctx.evm.BlockNumber.Uint64()
if upper < 257 {
lower = 0
} else {
lower = upper - 256
}
var blockHash common.Hash
if num >= lower && num < upper {
blockHash = ctx.evm.GetHash(num)
}
_, err := proc.WriteAt(blockHash.Bytes(), int64(dst))
if nil != err {
panic(err)
Expand Down
55 changes: 55 additions & 0 deletions core/vm/wagon_runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"crypto/sha256"
"encoding/binary"
"github.com/PlatONnetwork/PlatON-Go/common/hexutil"
"hash/fnv"
"io/ioutil"
"math/big"
Expand Down Expand Up @@ -50,6 +51,7 @@ var testCase = []*Case{
{
ctx: &VMContext{
evm: &EVM{Context: Context{
BlockNumber: big.NewInt(99),
GetHash: func(u uint64) common.Hash {
return common.Hash{1, 2, 3}
}},
Expand Down Expand Up @@ -1367,6 +1369,23 @@ var testCase = []*Case{
},
}

var initExternalGas = uint64(10000000)

type testContract struct{}

func (testContract) Address() common.Address {
return common.Address{}
}

func newTestVM(evm *EVM) *exec.VM {
code := "0x0061736d010000000108026000006000017f03030200010405017001010105030100020615037f01418088040b7f00418088040b7f004180080b072c04066d656d6f727902000b5f5f686561705f6261736503010a5f5f646174615f656e640302046d61696e00010a090202000b0400412a0b004d0b2e64656275675f696e666f3d0000000400000000000401000000000c0023000000000000004300000005000000040000000205000000040000005c000000010439000000036100000005040000100e2e64656275675f6d6163696e666f0000400d2e64656275675f616262726576011101250e1305030e10171b0e110112060000022e0011011206030e3a0b3b0b49133f190000032400030e3e0b0b0b000000005e0b2e64656275675f6c696e654e000000040037000000010101fb0e0d0001010101000000010000012f746d702f6275696c645f7664717864336f336f316c2e24000066696c652e630001000000000502050000001505030a3d020100010100700a2e64656275675f737472636c616e672076657273696f6e20382e302e3020287472756e6b2033343139363029002f746d702f6275696c645f7664717864336f336f316c2e242f66696c652e63002f746d702f6275696c645f7664717864336f336f316c2e24006d61696e00696e74000021046e616d65011a0200115f5f7761736d5f63616c6c5f63746f727301046d61696e"
module, _ := ReadWasmModule(hexutil.MustDecode(code), false)

vm, _ := exec.NewVM(module.RawModule)
vm.SetHostCtx(&VMContext{evm: evm, contract: NewContract(&testContract{}, &testContract{}, big.NewInt(0), initExternalGas)})
return vm
}

func TestExternalFunction(t *testing.T) {
buf, err := ioutil.ReadFile("./testdata/external.wasm")
assert.Nil(t, err)
Expand Down Expand Up @@ -1557,3 +1576,39 @@ func checkContractRet(ret []byte) bool {
}
return true
}

func TestGetBlockHash(t *testing.T) {

testBlockHash := common.BytesToHash([]byte{1, 2, 3, 4})
newProc := func(blockNumber int64) *exec.Process {
return exec.NewProcess(newTestVM(&EVM{
Context: Context{
GetHash: func(u uint64) common.Hash {
return testBlockHash
},
BlockNumber: big.NewInt(blockNumber),
},
}))
}

type TestCase struct {
blockNumber int64
getNumber uint64
expect common.Hash
}
cases := []TestCase{
{1, 123, common.Hash{}},
{123, 123, common.Hash{}},
{123, 122, testBlockHash},
{1024, 122, common.Hash{}},
{1024, 1024 - 256, testBlockHash},
}
for _, c := range cases {
proc := newProc(c.blockNumber)
BlockHash(proc, c.getNumber, 1024)
res := common.Hash{}
proc.ReadAt(res[:], 1024)
assert.Equal(t, c.expect, res)
assert.Equal(t, initExternalGas-GasExtStep, proc.HostCtx().(*VMContext).contract.Gas)
}
}

0 comments on commit b8e68fe

Please sign in to comment.